Skip to content

Commit 91e4fb2

Browse files
Gingehtcl3
authored andcommitted
LibWeb: Hide unrelated popovers when showing popovers
Also hides decendant popovers when hiding. Also hides unrelated popovers when showing dialogs.
1 parent bc0729f commit 91e4fb2

15 files changed

Lines changed: 609 additions & 58 deletions

Libraries/LibWeb/DOM/Document.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,8 @@ void Document::visit_edges(Cell::Visitor& visitor)
574574

575575
visitor.visit(m_top_layer_elements);
576576
visitor.visit(m_top_layer_pending_removals);
577+
visitor.visit(m_showing_auto_popover_list);
578+
visitor.visit(m_showing_hint_popover_list);
577579
visitor.visit(m_console_client);
578580
visitor.visit(m_editing_host_manager);
579581
visitor.visit(m_local_storage_holder);

Libraries/LibWeb/DOM/Document.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,13 @@ class Document
712712

713713
OrderedHashTable<GC::Ref<Element>> const& top_layer_elements() const { return m_top_layer_elements; }
714714

715+
// AD-HOC: These lists are managed dynamically instead of being generated as needed.
716+
// Spec issue: https://github.com/whatwg/html/issues/11007
717+
Vector<GC::Ref<HTML::HTMLElement>>& showing_auto_popover_list() { return m_showing_auto_popover_list; }
718+
Vector<GC::Ref<HTML::HTMLElement>>& showing_hint_popover_list() { return m_showing_hint_popover_list; }
719+
Vector<GC::Ref<HTML::HTMLElement>> const& showing_auto_popover_list() const { return m_showing_auto_popover_list; }
720+
Vector<GC::Ref<HTML::HTMLElement>> const& showing_hint_popover_list() const { return m_showing_hint_popover_list; }
721+
715722
size_t transition_generation() const { return m_transition_generation; }
716723

717724
// Does document represent an embedded svg img
@@ -1101,6 +1108,9 @@ class Document
11011108
OrderedHashTable<GC::Ref<Element>> m_top_layer_elements;
11021109
OrderedHashTable<GC::Ref<Element>> m_top_layer_pending_removals;
11031110

1111+
Vector<GC::Ref<HTML::HTMLElement>> m_showing_auto_popover_list;
1112+
Vector<GC::Ref<HTML::HTMLElement>> m_showing_hint_popover_list;
1113+
11041114
// https://dom.spec.whatwg.org/#document-allow-declarative-shadow-roots
11051115
bool m_allow_declarative_shadow_roots { false };
11061116

Libraries/LibWeb/HTML/HTMLDialogElement.cpp

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,23 @@ WebIDL::ExceptionOr<void> HTMLDialogElement::show()
135135
// 9. Set the dialog close watcher with this.
136136
set_close_watcher();
137137
// FIXME: 10. Set this's previously focused element to the focused element.
138-
// FIXME: 11. Let document be this's node document.
139-
// FIXME: 12. Let hideUntil be the result of running topmost popover ancestor given this, document's showing hint popover list, null, and false.
140-
// FIXME: 13. If hideUntil is null, then set hideUntil to the result of running topmost popover ancestor given this, document's showing auto popover list, null, and false.
141-
// FIXME: 14. If hideUntil is null, then set hideUntil to document.
142-
// FIXME: 15. Run hide all popovers until given hideUntil, false, and true.
138+
139+
// 11. Let document be this's node document.
140+
auto document = m_document;
141+
142+
// 12. Let hideUntil be the result of running topmost popover ancestor given this, document's showing hint popover list, null, and false.
143+
Variant<GC::Ptr<HTMLElement>, GC::Ptr<DOM::Document>> hide_until = topmost_popover_ancestor(this, document->showing_hint_popover_list(), nullptr, IsPopover::No);
144+
145+
// 13. If hideUntil is null, then set hideUntil to the result of running topmost popover ancestor given this, document's showing auto popover list, null, and false.
146+
if (!hide_until.get<GC::Ptr<HTMLElement>>())
147+
hide_until = topmost_popover_ancestor(this, document->showing_auto_popover_list(), nullptr, IsPopover::No);
148+
149+
// 14. If hideUntil is null, then set hideUntil to document.
150+
if (!hide_until.get<GC::Ptr<HTMLElement>>())
151+
hide_until = document;
152+
153+
// 15. Run hide all popovers until given hideUntil, false, and true.
154+
hide_all_popovers_until(hide_until, FocusPreviousElement::No, FireEvents::Yes);
143155

144156
// 16. Run the dialog focusing steps given this.
145157
run_dialog_focusing_steps();
@@ -224,11 +236,23 @@ WebIDL::ExceptionOr<void> HTMLDialogElement::show_a_modal_dialog(HTMLDialogEleme
224236
subject.set_close_watcher();
225237

226238
// FIXME: 18. Set subject's previously focused element to the focused element.
227-
// FIXME: 19. Let document be subject's node document.
228-
// FIXME: 20. Let hideUntil be the result of running topmost popover ancestor given subject, document's showing hint popover list, null, and false.
229-
// FIXME: 21. If hideUntil is null, then set hideUntil to the result of running topmost popover ancestor given subject, document's showing auto popover list, null, and false.
230-
// FIXME: 22. If hideUntil is null, then set hideUntil to document.
231-
// FIXME: 23. Run hide all popovers until given hideUntil, false, and true.
239+
240+
// 19. Let document be subject's node document.
241+
auto& document = subject.document();
242+
243+
// 20. Let hideUntil be the result of running topmost popover ancestor given subject, document's showing hint popover list, null, and false.
244+
Variant<GC::Ptr<HTMLElement>, GC::Ptr<DOM::Document>> hide_until = topmost_popover_ancestor(subject, document.showing_hint_popover_list(), nullptr, IsPopover::No);
245+
246+
// 21. If hideUntil is null, then set hideUntil to the result of running topmost popover ancestor given subject, document's showing auto popover list, null, and false.
247+
if (!hide_until.get<GC::Ptr<HTMLElement>>())
248+
hide_until = topmost_popover_ancestor(subject, document.showing_auto_popover_list(), nullptr, IsPopover::No);
249+
250+
// 22. If hideUntil is null, then set hideUntil to document.
251+
if (!hide_until.get<GC::Ptr<HTMLElement>>())
252+
hide_until = GC::Ptr(document);
253+
254+
// 23. Run hide all popovers until given hideUntil, false, and true.
255+
hide_all_popovers_until(hide_until, FocusPreviousElement::No, FireEvents::Yes);
232256

233257
// 24. Run the dialog focusing steps given subject.
234258
subject.run_dialog_focusing_steps();

0 commit comments

Comments
 (0)