From 29c6aabf49df7fe8f113d5dd49f39ca8d80a15b4 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 23 Oct 2022 17:53:02 +0200 Subject: [PATCH] LibWeb: Try harder to find a suitable DOM node for mouse event dispatch Since our hit testing mechanism gives you the Paintable under the mouse cursor, we can't just give up if that paintable doesn't have a corresponding DOM node. That meant that generated content like pseudo- elements didn't generate mouse events at all. Fix this by making a dom_node_for_event_dispatch() helper function that finds a suitable DOM node when given a paintable. This first cut is very naive, and there's probably more we should do, but we have to start somewhere. :^) --- .../Libraries/LibWeb/Page/EventHandler.cpp | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/Userland/Libraries/LibWeb/Page/EventHandler.cpp b/Userland/Libraries/LibWeb/Page/EventHandler.cpp index 874543769e..2c66e72973 100644 --- a/Userland/Libraries/LibWeb/Page/EventHandler.cpp +++ b/Userland/Libraries/LibWeb/Page/EventHandler.cpp @@ -23,6 +23,17 @@ namespace Web { +static JS::GCPtr dom_node_for_event_dispatch(Painting::Paintable const& paintable) +{ + if (auto node = paintable.mouse_event_target()) + return node; + if (auto node = paintable.dom_node()) + return node; + if (auto* layout_parent = paintable.layout_node().parent()) + return layout_parent->dom_node(); + return nullptr; +} + static Gfx::StandardCursor cursor_css_to_gfx(Optional cursor) { if (!cursor.has_value()) { @@ -147,9 +158,7 @@ bool EventHandler::handle_mousewheel(Gfx::IntPoint const& position, unsigned but if (paintable) { paintable->handle_mousewheel({}, position, buttons, modifiers, wheel_delta_x, wheel_delta_y); - JS::GCPtr node = paintable->mouse_event_target(); - if (!node) - node = paintable->dom_node(); + auto node = dom_node_for_event_dispatch(*paintable); if (node) { // FIXME: Support wheel events in nested browsing contexts. @@ -211,9 +220,7 @@ bool EventHandler::handle_mouseup(Gfx::IntPoint const& position, unsigned button } if (paintable) { - JS::GCPtr node = paintable->mouse_event_target(); - if (!node) - node = paintable->dom_node(); + auto node = dom_node_for_event_dispatch(*paintable); if (node) { if (is(*node)) { @@ -328,9 +335,7 @@ bool EventHandler::handle_mousedown(Gfx::IntPoint const& position, unsigned butt // FIXME: Handle other values for pointer-events. VERIFY(pointer_events != CSS::PointerEvents::None); - node = paintable->mouse_event_target(); - if (!node) - node = paintable->dom_node(); + node = dom_node_for_event_dispatch(*paintable); document->set_hovered_node(node); if (paintable->wants_mouse_events()) { @@ -434,9 +439,7 @@ bool EventHandler::handle_mousemove(Gfx::IntPoint const& position, unsigned butt page->client().page_did_request_cursor_change(Gfx::StandardCursor::None); } - JS::GCPtr node = paintable->mouse_event_target(); - if (!node) - node = paintable->dom_node(); + auto node = dom_node_for_event_dispatch(*paintable); if (node && is(*node)) { if (auto* nested_browsing_context = static_cast(*node).nested_browsing_context()) @@ -543,9 +546,7 @@ bool EventHandler::handle_doubleclick(Gfx::IntPoint const& position, unsigned bu if (pointer_events == CSS::PointerEvents::None) return false; - JS::GCPtr node = paintable->mouse_event_target(); - if (!node) - node = paintable->dom_node(); + auto node = dom_node_for_event_dispatch(*paintable); if (paintable->wants_mouse_events()) { // FIXME: Handle double clicks.