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:
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,