Skip to content

Commit

Permalink
LibWeb: Pick the correct DOM node for mouse-move events
Browse files Browse the repository at this point in the history
This makes hovering over the link in the following HTML snippet work,
i.e. the tooltip is shown and the link target is shown at the bottom
of the browser window:

<html lang="en"><head><style>
.site-link{display:inline-block}
.site-link:before{content:"derp"}
.site-link::after{content:"";display:block}
</style></head><body><a class="site-link" href="#"
title="Tooltip, maybe!"></a>
  • Loading branch information
gunnarbeutner authored and awesomekling committed Nov 8, 2022
1 parent 3cc0d60 commit 892186d
Showing 1 changed file with 6 additions and 11 deletions.
17 changes: 6 additions & 11 deletions Userland/Libraries/LibWeb/Page/EventHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,9 +453,14 @@ bool EventHandler::handle_mousemove(Gfx::IntPoint const& position, unsigned butt
// FIXME: Handle other values for pointer-events.
VERIFY(pointer_events != CSS::PointerEvents::None);

// Search for the first parent of the hit target that's an element.
// "The click event type MUST be dispatched on the topmost event target indicated by the pointer." (https://www.w3.org/TR/uievents/#event-type-click)
// "The topmost event target MUST be the element highest in the rendering order which is capable of being an event target." (https://www.w3.org/TR/uievents/#topmost-event-target)
Layout::Node const* layout_node;
bool found_parent_element = parent_element_for_event_dispatch(*paintable, node, layout_node);
hovered_node_changed = node.ptr() != document.hovered_node();
document.set_hovered_node(node);
if (node) {
if (found_parent_element) {
hovered_link_element = node->enclosing_link_element();
if (hovered_link_element)
is_hovering_link = true;
Expand All @@ -474,22 +479,12 @@ bool EventHandler::handle_mousemove(Gfx::IntPoint const& position, unsigned butt
hovered_node_cursor = cursor_css_to_gfx(cursor);
}

// Search for the first parent of the hit target that's an element.
// "The click event type MUST be dispatched on the topmost event target indicated by the pointer." (https://www.w3.org/TR/uievents/#event-type-click)
// "The topmost event target MUST be the element highest in the rendering order which is capable of being an event target." (https://www.w3.org/TR/uievents/#topmost-event-target)
Layout::Node const* layout_node;
if (!parent_element_for_event_dispatch(*paintable, node, layout_node)) {
// FIXME: This is pretty ugly but we need to bail out here.
goto after_node_use;
}

auto offset = compute_mouse_event_offset(position, *layout_node);
node->dispatch_event(*UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mousemove, offset.x(), offset.y(), position.x(), position.y(), buttons));
// NOTE: Dispatching an event may have disturbed the world.
if (!paint_root() || paint_root() != node->document().paint_box())
return true;
}
after_node_use:
if (m_in_mouse_selection) {
auto hit = paint_root()->hit_test(position.to_type<float>(), Painting::HitTestType::TextCursor);
if (start_index.has_value() && hit.has_value() && hit->dom_node()) {
Expand Down

0 comments on commit 892186d

Please sign in to comment.