@@ -748,6 +748,8 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint visual_viewport_positio
748748 return EventResult::Dropped;
749749
750750 auto & document = *m_navigable->active_document ();
751+ auto & page = m_navigable->page ();
752+
751753 auto viewport_position = document.visual_viewport ()->map_to_layout_viewport (visual_viewport_position);
752754
753755 m_navigable->active_document ()->update_layout (DOM::UpdateLayoutReason::EventHandlerHandleMouseMove);
@@ -756,8 +758,8 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint visual_viewport_positio
756758 return EventResult::Dropped;
757759
758760 bool hovered_node_changed = false ;
759- bool is_hovering_link = false ;
760761 Gfx::Cursor hovered_node_cursor = Gfx::StandardCursor::None;
762+ GC::Ptr<HTML::HTMLAnchorElement const > hovered_link_element;
761763
762764 GC::Ptr<Painting::Paintable> paintable;
763765 Optional<int > start_index;
@@ -769,11 +771,42 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint visual_viewport_positio
769771
770772 GC::Ptr<DOM::Node> node;
771773
772- ScopeGuard update_hovered_node_guard = [&node, &document ] {
774+ ScopeGuard update_hovered_node_and_ui_state_guard = [&] {
773775 document.set_hovered_node (node);
776+
777+ // FIXME: This check is only approximate. ImageCursors from the same CursorStyleValue share bitmaps, but may
778+ // repaint them. So comparing them does not tell you if they are the same image. Also, the image may
779+ // change even if the hovered node does not.
780+ if (page.current_cursor () != hovered_node_cursor || hovered_node_changed) {
781+ page.client ().page_did_request_cursor_change (hovered_node_cursor);
782+ page.set_current_cursor (hovered_node_cursor);
783+ }
784+
785+ if (hovered_node_changed) {
786+ GC::Ptr<HTML::HTMLElement const > hovered_html_element = node
787+ ? node->enclosing_html_element_with_attribute (HTML::AttributeNames::title)
788+ : nullptr ;
789+
790+ if (hovered_html_element && hovered_html_element->title ().has_value ()) {
791+ page.client ().page_did_enter_tooltip_area (hovered_html_element->title ()->to_byte_string ());
792+ page.set_is_in_tooltip_area (true );
793+ } else if (page.is_in_tooltip_area ()) {
794+ page.client ().page_did_leave_tooltip_area ();
795+ page.set_is_in_tooltip_area (false );
796+ }
797+
798+ if (hovered_link_element) {
799+ if (auto link_url = document.encoding_parse_url (hovered_link_element->href ()); link_url.has_value ()) {
800+ page.client ().page_did_hover_link (*link_url);
801+ page.set_is_hovering_link (true );
802+ }
803+ } else if (page.is_hovering_link ()) {
804+ page.client ().page_did_unhover_link ();
805+ page.set_is_hovering_link (false );
806+ }
807+ }
774808 };
775809
776- GC::Ptr<HTML::HTMLAnchorElement const > hovered_link_element;
777810 if (paintable) {
778811 if (paintable->wants_mouse_events ()) {
779812 if (paintable->handle_mousemove ({}, viewport_position, buttons, modifiers) == Painting::Paintable::DispatchEventOfSameName::No) {
@@ -782,7 +815,7 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint visual_viewport_positio
782815 }
783816
784817 // FIXME: It feels a bit aggressive to always update the cursor like this.
785- m_navigable-> page () .client ().page_did_request_cursor_change (Gfx::StandardCursor::None);
818+ page.client ().page_did_request_cursor_change (Gfx::StandardCursor::None);
786819 }
787820
788821 node = dom_node_for_event_dispatch (*paintable);
@@ -804,10 +837,9 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint visual_viewport_positio
804837 GC::Ptr<Layout::Node> layout_node;
805838 bool found_parent_element = parent_element_for_event_dispatch (*paintable, node, layout_node);
806839 hovered_node_changed = node.ptr () != document.hovered_node ();
840+
807841 if (found_parent_element) {
808842 hovered_link_element = node->enclosing_link_element ();
809- if (hovered_link_element)
810- is_hovering_link = true ;
811843
812844 if (paintable->layout_node ().is_text_node ()) {
813845 hovered_node_cursor = resolve_cursor (*paintable->layout_node ().parent (), cursor_data, Gfx::StandardCursor::IBeam);
@@ -856,38 +888,6 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint visual_viewport_positio
856888 }
857889 }
858890
859- auto & page = m_navigable->page ();
860-
861- // FIXME: This check is only approximate. ImageCursors from the same CursorStyleValue share bitmaps, but may repaint them.
862- // So comparing them does not tell you if they are the same image. Also, the image may change even if the hovered
863- // node does not.
864- if (page.current_cursor () != hovered_node_cursor || hovered_node_changed) {
865- page.set_current_cursor (hovered_node_cursor);
866- page.client ().page_did_request_cursor_change (hovered_node_cursor);
867- }
868-
869- if (hovered_node_changed) {
870- GC::Ptr<HTML::HTMLElement const > hovered_html_element = node ? node->enclosing_html_element_with_attribute (HTML::AttributeNames::title) : nullptr ;
871-
872- if (hovered_html_element && hovered_html_element->title ().has_value ()) {
873- page.set_is_in_tooltip_area (true );
874- page.client ().page_did_enter_tooltip_area (hovered_html_element->title ()->to_byte_string ());
875- } else if (page.is_in_tooltip_area ()) {
876- page.set_is_in_tooltip_area (false );
877- page.client ().page_did_leave_tooltip_area ();
878- }
879-
880- if (is_hovering_link) {
881- if (auto link_url = document.encoding_parse_url (hovered_link_element->href ()); link_url.has_value ()) {
882- page.set_is_hovering_link (true );
883- page.client ().page_did_hover_link (*link_url);
884- }
885- } else if (page.is_hovering_link ()) {
886- page.set_is_hovering_link (false );
887- page.client ().page_did_unhover_link ();
888- }
889- }
890-
891891 return EventResult::Handled;
892892}
893893
0 commit comments