From 972547635ff32ceb255232bd0839855e31315c11 Mon Sep 17 00:00:00 2001 From: Gingeh <39150378+Gingeh@users.noreply.github.com> Date: Mon, 7 Apr 2025 19:33:53 +1000 Subject: [PATCH] LibWeb: Dispatch pointer events to ::backdrop originating element --- Base/res/ladybird/about-pages/settings.html | 16 +++------- Libraries/LibWeb/CSS/PseudoElements.json | 3 +- Libraries/LibWeb/Layout/Node.h | 1 + Libraries/LibWeb/Layout/TreeBuilder.cpp | 1 + Libraries/LibWeb/Page/EventHandler.cpp | 7 ++++- .../backdrop-receives-element-events.txt | 1 + .../backdrop-receives-element-events.html | 31 +++++++++++++++++++ 7 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/backdrop-receives-element-events.txt create mode 100644 Tests/LibWeb/Text/input/backdrop-receives-element-events.html diff --git a/Base/res/ladybird/about-pages/settings.html b/Base/res/ladybird/about-pages/settings.html index bd03eab20b0..d238ae383e0 100644 --- a/Base/res/ladybird/about-pages/settings.html +++ b/Base/res/ladybird/about-pages/settings.html @@ -1002,13 +1002,9 @@ ladybird.sendMessage("restoreDefaultSettings"); }); - // FIXME: Once we support `dialog::backdrop`, this event listener should be on `siteSettings`. - document.addEventListener("click", event => { - const close = dialog => { - if (!dialog.open) { - return; - } - + // FIXME: This should be replaced once we support popover light dismissal. + document.querySelectorAll("dialog").forEach((dialog) => + dialog.addEventListener("click", event => { const rect = dialog.getBoundingClientRect(); if ( @@ -1019,10 +1015,8 @@ ) { dialog.close(); } - }; - - document.querySelectorAll("dialog").forEach(close); - }); + } + )); document.addEventListener("WebUILoaded", () => { ladybird.sendMessage("loadAvailableEngines"); diff --git a/Libraries/LibWeb/CSS/PseudoElements.json b/Libraries/LibWeb/CSS/PseudoElements.json index ba7d3a75997..65c93fa6e6d 100644 --- a/Libraries/LibWeb/CSS/PseudoElements.json +++ b/Libraries/LibWeb/CSS/PseudoElements.json @@ -34,7 +34,8 @@ "is-generated": true }, "backdrop": { - "spec": "https://drafts.csswg.org/css-position-4/#selectordef-backdrop" + "spec": "https://drafts.csswg.org/css-position-4/#selectordef-backdrop", + "is-generated": true }, "before": { "spec": "https://drafts.csswg.org/css-pseudo-4/#selectordef-before", diff --git a/Libraries/LibWeb/Layout/Node.h b/Libraries/LibWeb/Layout/Node.h index fe535e2f87f..984bbb2975d 100644 --- a/Libraries/LibWeb/Layout/Node.h +++ b/Libraries/LibWeb/Layout/Node.h @@ -48,6 +48,7 @@ public: bool is_generated() const { return m_generated_for.has_value(); } bool is_generated_for_before_pseudo_element() const { return m_generated_for == CSS::GeneratedPseudoElement::Before; } bool is_generated_for_after_pseudo_element() const { return m_generated_for == CSS::GeneratedPseudoElement::After; } + bool is_generated_for_backdrop_pseudo_element() const { return m_generated_for == CSS::GeneratedPseudoElement::Backdrop; } void set_generated_for(CSS::GeneratedPseudoElement type, DOM::Element& element) { m_generated_for = type; diff --git a/Libraries/LibWeb/Layout/TreeBuilder.cpp b/Libraries/LibWeb/Layout/TreeBuilder.cpp index 40f0ba39143..a91f6f43a74 100644 --- a/Libraries/LibWeb/Layout/TreeBuilder.cpp +++ b/Libraries/LibWeb/Layout/TreeBuilder.cpp @@ -584,6 +584,7 @@ void TreeBuilder::update_layout_tree(DOM::Node& dom_node, TreeBuilder::Context& return; top_layer_element->set_pseudo_element_node({}, CSS::PseudoElement::Backdrop, pseudo_element_node); + pseudo_element_node->set_generated_for(CSS::GeneratedPseudoElement::Backdrop, top_layer_element); insert_node_into_inline_or_block_ancestor(*pseudo_element_node, pseudo_element_display, AppendOrPrepend::Append); }(); update_layout_tree(top_layer_element, context, should_create_layout_node ? MustCreateSubtree::Yes : MustCreateSubtree::No); diff --git a/Libraries/LibWeb/Page/EventHandler.cpp b/Libraries/LibWeb/Page/EventHandler.cpp index 1ab63958712..0b694386f3c 100644 --- a/Libraries/LibWeb/Page/EventHandler.cpp +++ b/Libraries/LibWeb/Page/EventHandler.cpp @@ -66,6 +66,12 @@ static DOM::Node* input_control_associated_with_ancestor_label_element(Painting: static bool parent_element_for_event_dispatch(Painting::Paintable& paintable, GC::Ptr& node, Layout::Node*& layout_node) { + layout_node = &paintable.layout_node(); + if (layout_node->is_generated_for_backdrop_pseudo_element()) { + node = layout_node->pseudo_element_generator(); + layout_node = node->layout_node(); + } + auto* current_ancestor_node = node.ptr(); do { if (is(current_ancestor_node) && !dynamic_cast(current_ancestor_node)->enabled()) { @@ -73,7 +79,6 @@ static bool parent_element_for_event_dispatch(Painting::Paintable& paintable, GC } } while ((current_ancestor_node = current_ancestor_node->parent())); - layout_node = &paintable.layout_node(); while (layout_node && node && !node->is_element() && layout_node->parent()) { layout_node = layout_node->parent(); if (layout_node->is_anonymous()) diff --git a/Tests/LibWeb/Text/expected/backdrop-receives-element-events.txt b/Tests/LibWeb/Text/expected/backdrop-receives-element-events.txt new file mode 100644 index 00000000000..7ef22e9a431 --- /dev/null +++ b/Tests/LibWeb/Text/expected/backdrop-receives-element-events.txt @@ -0,0 +1 @@ +PASS diff --git a/Tests/LibWeb/Text/input/backdrop-receives-element-events.html b/Tests/LibWeb/Text/input/backdrop-receives-element-events.html new file mode 100644 index 00000000000..e3b9256d9a1 --- /dev/null +++ b/Tests/LibWeb/Text/input/backdrop-receives-element-events.html @@ -0,0 +1,31 @@ + + + + + +