Skip to content

[Bug][Popover]: Popover не закрывается если кликнуть в iframe #9482

@some-dudes-work-account

Description

Описание

Popover с trigger="click" (и всё остальное что построено на базе useFloatingElement) устанавливают глобальный обработчик клика "снаружи" и пытаются закрываться по нему. Но этого недостаточно.

const handleClickOutside = React.useCallback(() => {
blockFocusRef.current = true;
commitShownLocalState(false, 'click-outside');
}, [commitShownLocalState]);
useGlobalOnClickOutside(
handleClickOutside,
handleCloseOnReferenceClickOutsideDisabled ? null : refs.reference,
handleCloseOnFloatingClickOutsideDisabled ? null : refs.floating,
);

Когда пользователь кликает не просто где-то в другой части страницы, а по айфрейму, хост страница не получает ни события click, ни mousedown, потому что там другой документ, и возможно другой ориджин.

С точки зрения пользователя границы фрейма могут быть неочевидны, особенно в случае мини-приложений, где содержимое фрейма старательно маскируется под основной сайт. Из-за этого различие в поведении скорее всего будет восприниматься как баг в поведении — клики в одной части страницы закрывают поповеры, клики в другой почему-то нет. Поведение интерфейса перестаёт соответствовать ожиданиям.

В момент клика по фрейму происходят две вещи:

  • document.activeElement начинает указывать на элемент iframe, документ из которого получил фокус,
  • на window верхнеуровневой страницы можно наблюдать событие "blur", как если бы всё окно браузера потеряло фокус

К счастью такое мы отследить можем и это единственным образом указывает на клик в айфрейм. Других ситуаций, когда активным элементом стал iframe и страница потеряла фокус быть не может — это всегда клик внутрь него, и если этот фрейм не лежит внутри нашего элемента — значит для нашего элемента это click outside:

window.addEventListener('blur', () => {
  if (
    document.activeElement.tagName === 'IFRAME' 
    && !contains(refs.floating.current, document.activeElement
  ) {
    commitShownLocalState(false, 'click-outside'); 
  }
});

Версия

7.10.2, 8.0.0-rc.4

В каких браузерах воспроизводится проблема?

Во всех.

Шаги воспроизведения

  1. Открыть страницу мини-приложения в контакте, например песочницу бриджа
  2. Открыть меню пользователя, кликом по аватарке в шапке
  3. Кликнуть в тело миниаппа

Ожидаемое поведение

Поповер закрывается по клику в миниапп.

Пример с воспроизведением

https://codesandbox.io/p/sandbox/strange-brook-srn7c2

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    Status

    🗃 Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions