Bug 1878708 - Dialogs HideAllPopoversUntil nearest popover, not document. r=smaug

Given some markup like:

```html
<div id=popover popover>
  <button id="openDialog">Open Dialog</button>
  <dialog id=dialog>
    I'm a dialog!
  </dialog>
</div>
<button id="openPopover">Open Popover</button>
<button>I do nothing!</button>
```

With some JS like

```js
openDialog.onclick = () => {
  dialog.showModal();
}

openPopover.onclick = () => {
  popover.showPopover();
}
```

Clicking the "Open Popover" button followed by the "Open Dialog" button results in both the Dialog and Popover being hidden, however the dialog will still be open as modal, rendering the whole page inert, nothing is clickable and there seems to be no way to undo this (unless you use a CloseWatcher gesture such as the Esc key - if you have one available on your device).

It is expected that the popover should not close the dialog, as it causes the invisible Modal Dialog to make the whole page inert, and it is very difficult for users (and developers) to discover how to undo this action (pressing escape).

This was reported in https://github.com/whatwg/html/issues/9998, and WhatWG resolved to fix this, which in https://github.com/whatwg/html/pull/10116.

Differential Revision: https://phabricator.services.mozilla.com/D200686
This commit is contained in:
keithamus
2024-02-05 23:58:42 +00:00
parent 37e1960307
commit d5efc74a38
8 changed files with 23 additions and 35 deletions

View File

@@ -3418,7 +3418,7 @@ void nsGenericHTMLElement::ShowPopoverInternal(Element* aInvoker,
nsWeakPtr originallyFocusedElement;
if (IsAutoPopover()) {
auto originalState = GetPopoverAttributeState();
RefPtr<nsINode> ancestor = GetTopmostPopoverAncestor(aInvoker);
RefPtr<nsINode> ancestor = GetTopmostPopoverAncestor(aInvoker, true);
if (!ancestor) {
ancestor = document;
}