mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-07 08:39:22 +00:00
LibWeb: Dispatch pointer events to ::backdrop originating element
This commit is contained in:
parent
4b9f5c6fb8
commit
972547635f
Notes:
github-actions[bot]
2025-04-09 11:11:42 +00:00
Author: https://github.com/Gingeh
Commit: 972547635f
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4263
Reviewed-by: https://github.com/AtkinsSJ ✅
7 changed files with 47 additions and 13 deletions
|
@ -1002,13 +1002,9 @@
|
||||||
ladybird.sendMessage("restoreDefaultSettings");
|
ladybird.sendMessage("restoreDefaultSettings");
|
||||||
});
|
});
|
||||||
|
|
||||||
// FIXME: Once we support `dialog::backdrop`, this event listener should be on `siteSettings`.
|
// FIXME: This should be replaced once we support popover light dismissal.
|
||||||
document.addEventListener("click", event => {
|
document.querySelectorAll("dialog").forEach((dialog) =>
|
||||||
const close = dialog => {
|
dialog.addEventListener("click", event => {
|
||||||
if (!dialog.open) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const rect = dialog.getBoundingClientRect();
|
const rect = dialog.getBoundingClientRect();
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -1019,10 +1015,8 @@
|
||||||
) {
|
) {
|
||||||
dialog.close();
|
dialog.close();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
));
|
||||||
document.querySelectorAll("dialog").forEach(close);
|
|
||||||
});
|
|
||||||
|
|
||||||
document.addEventListener("WebUILoaded", () => {
|
document.addEventListener("WebUILoaded", () => {
|
||||||
ladybird.sendMessage("loadAvailableEngines");
|
ladybird.sendMessage("loadAvailableEngines");
|
||||||
|
|
|
@ -34,7 +34,8 @@
|
||||||
"is-generated": true
|
"is-generated": true
|
||||||
},
|
},
|
||||||
"backdrop": {
|
"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": {
|
"before": {
|
||||||
"spec": "https://drafts.csswg.org/css-pseudo-4/#selectordef-before",
|
"spec": "https://drafts.csswg.org/css-pseudo-4/#selectordef-before",
|
||||||
|
|
|
@ -48,6 +48,7 @@ public:
|
||||||
bool is_generated() const { return m_generated_for.has_value(); }
|
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_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_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)
|
void set_generated_for(CSS::GeneratedPseudoElement type, DOM::Element& element)
|
||||||
{
|
{
|
||||||
m_generated_for = type;
|
m_generated_for = type;
|
||||||
|
|
|
@ -584,6 +584,7 @@ void TreeBuilder::update_layout_tree(DOM::Node& dom_node, TreeBuilder::Context&
|
||||||
return;
|
return;
|
||||||
|
|
||||||
top_layer_element->set_pseudo_element_node({}, CSS::PseudoElement::Backdrop, pseudo_element_node);
|
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);
|
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);
|
update_layout_tree(top_layer_element, context, should_create_layout_node ? MustCreateSubtree::Yes : MustCreateSubtree::No);
|
||||||
|
|
|
@ -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<DOM::Node>& node, Layout::Node*& layout_node)
|
static bool parent_element_for_event_dispatch(Painting::Paintable& paintable, GC::Ptr<DOM::Node>& 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();
|
auto* current_ancestor_node = node.ptr();
|
||||||
do {
|
do {
|
||||||
if (is<HTML::FormAssociatedElement>(current_ancestor_node) && !dynamic_cast<HTML::FormAssociatedElement*>(current_ancestor_node)->enabled()) {
|
if (is<HTML::FormAssociatedElement>(current_ancestor_node) && !dynamic_cast<HTML::FormAssociatedElement*>(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()));
|
} while ((current_ancestor_node = current_ancestor_node->parent()));
|
||||||
|
|
||||||
layout_node = &paintable.layout_node();
|
|
||||||
while (layout_node && node && !node->is_element() && layout_node->parent()) {
|
while (layout_node && node && !node->is_element() && layout_node->parent()) {
|
||||||
layout_node = layout_node->parent();
|
layout_node = layout_node->parent();
|
||||||
if (layout_node->is_anonymous())
|
if (layout_node->is_anonymous())
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
PASS
|
|
@ -0,0 +1,31 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<script src="include.js"></script>
|
||||||
|
<!-- Adapted from https://wpt.live/html/semantics/interactive-elements/the-dialog-element/backdrop-receives-element-events.html -->
|
||||||
|
<style>
|
||||||
|
/* ::backdrop takes up whole screen, actual <dialog> is hidden */
|
||||||
|
dialog {
|
||||||
|
visibility: hidden;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog::backdrop {
|
||||||
|
visibility: visible;
|
||||||
|
pointer-events: initial;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<dialog></dialog>
|
||||||
|
<script>
|
||||||
|
asyncTest((done) => {
|
||||||
|
const dialog = document.querySelector("dialog");
|
||||||
|
dialog.showModal();
|
||||||
|
dialog.addEventListener("click", () => {
|
||||||
|
println("PASS");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
internals.click(0, 0);
|
||||||
|
});
|
||||||
|
</script>
|
Loading…
Add table
Add a link
Reference in a new issue