tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit de1ed576e723a562f4982d417dcf96adbdcbf575
parent fd0d03758de4db8e8a8e159d384af6f3e2b4d049
Author: Keith Cirkel <keithamus@users.noreply.github.com>
Date:   Mon, 15 Dec 2025 20:09:11 +0000

Bug 1867743 - Part 3: Split out CloseEntirePopoverList, HidePopoverStackUntil r=dom-core,smaug

This splits out the HidePopoverStackUntil function from HideAllPopoversUntil.
Splitting this out isn't strictly necessary as it's only called once at current,
but as we support popover=hint it'll need to be called twice, and having it
split out also makes it clearer when checking our code against the spec.

As a consequence of this split, the `closeAllOpenPopovers` lambda also
needs to be split into a function - `CloseEntirePopoverList`. This
is a separate algorithm in the spec, but also it's called from both
HidePopoverStackUntil and HideAllPopoversUntil.

Differential Revision: https://phabricator.services.mozilla.com/D276369

Diffstat:
Mdom/base/Document.cpp | 35++++++++++++++++++++---------------
Mdom/base/Document.h | 10++++++++++
2 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp @@ -16057,18 +16057,22 @@ bool Document::TopLayerContains(Element& aElement) const { return mTopLayer.Contains(weakElement); } +// https://html.spec.whatwg.org/#close-entire-popover-list +void Document::CloseEntirePopoverList(bool aFocusPreviousElement, + bool aFireEvents) { + // 1. While popoverList is not empty: + while (RefPtr<Element> topmost = GetTopmostAutoPopover()) { + // 1.1. Run the hide popover algorithm given popoverList's last item, + // focusPreviousElement, fireEvents, false, and null. + HidePopover(*topmost, aFocusPreviousElement, aFireEvents, + /* aSource */ nullptr, IgnoreErrors()); + } +} + // https://html.spec.whatwg.org/#hide-all-popovers-until void Document::HideAllPopoversUntil(nsINode& aEndpoint, bool aFocusPreviousElement, bool aFireEvents) { - auto closeAllOpenPopovers = [&aFocusPreviousElement, &aFireEvents, - this]() MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION { - while (RefPtr<Element> topmost = GetTopmostAutoPopover()) { - HidePopover(*topmost, aFocusPreviousElement, aFireEvents, - /* aSource */ nullptr, IgnoreErrors()); - } - }; - const auto* endpointHTMLEl = nsGenericHTMLElement::FromNodeOrNull(&aEndpoint); // 1. If endpoint is an HTML element and endpoint is not in the popover @@ -16090,7 +16094,7 @@ void Document::HideAllPopoversUntil(nsINode& aEndpoint, // list, focusPreviousElement, and fireEvents. // 5.2. Run close entire popover list given document's showing auto popover // list, focusPreviousElement, and fireEvents. - closeAllOpenPopovers(); + CloseEntirePopoverList(aFocusPreviousElement, aFireEvents); // 5.3. Return. return; } @@ -16109,18 +16113,19 @@ void Document::HideAllPopoversUntil(nsINode& aEndpoint, // 9. Run hide popover stack until given endpoint, document's showing auto // popover list, focusPreviousElement, and fireEvents. + HidePopoverStackUntil(aEndpoint, aFocusPreviousElement, aFireEvents); +} - // --------- - - // https://html.spec.whatwg.org/#hide-popover-stack-until +// https://html.spec.whatwg.org/#hide-popover-stack-until +void Document::HidePopoverStackUntil(nsINode& aEndpoint, + bool aFocusPreviousElement, + bool aFireEvents) { auto needRepeatingHide = [&]() { auto autoList = AutoPopoverList(); return autoList.Contains(&aEndpoint) && &aEndpoint != autoList.LastElement(); }; - MOZ_ASSERT(endpointHTMLEl && endpointHTMLEl->IsAutoPopover()); - // 1. Let repeatingHide be false. bool repeatingHide = false; bool fireEvents = aFireEvents; @@ -16145,7 +16150,7 @@ void Document::HideAllPopoversUntil(nsINode& aEndpoint, // 2.3. If lastToHide is null, then return. if (!foundEndpoint) { - closeAllOpenPopovers(); + CloseEntirePopoverList(aFocusPreviousElement, fireEvents); return; } diff --git a/dom/base/Document.h b/dom/base/Document.h @@ -3584,12 +3584,22 @@ class Document : public nsINode, MOZ_CAN_RUN_SCRIPT void GetWireframe(bool aIncludeNodes, Nullable<Wireframe>&); + // https://html.spec.whatwg.org/#close-entire-popover-list + MOZ_CAN_RUN_SCRIPT void CloseEntirePopoverList(bool aFocusPreviousElement, + bool aFireEvents); + // Hides all popovers until the given end point, see // https://html.spec.whatwg.org/multipage/popover.html#hide-all-popovers-until MOZ_CAN_RUN_SCRIPT void HideAllPopoversUntil(nsINode& aEndpoint, bool aFocusPreviousElement, bool aFireEvents); + // Hides all popovers, until the given end point, see + // https://html.spec.whatwg.org/#hide-popover-stack-until + MOZ_CAN_RUN_SCRIPT void HidePopoverStackUntil(nsINode& aEndpoint, + bool aFocusPreviousElement, + bool aFireEvents); + // Hides the given popover element, see // https://html.spec.whatwg.org/multipage/popover.html#hide-popover-algorithm MOZ_CAN_RUN_SCRIPT void HidePopover(Element& popover,