LibWeb+WebContent: Add node picker hit testing
Picking needs hit testing in the page process, where layout and event targeting state live. Expose a small page-level query and WebContent IPC entry point that returns the node id at a viewport position. This lets DevTools ask WebContent what the picker is pointing at without duplicating hit-test logic outside LibWeb.
This commit is contained in:
parent
97070f836c
commit
30632e2dcb
11 changed files with 44 additions and 0 deletions
|
|
@ -1490,6 +1490,15 @@ Optional<EventHandler::Target> EventHandler::target_for_mouse_position(CSSPixelP
|
|||
return {};
|
||||
}
|
||||
|
||||
GC::Ptr<DOM::Node> EventHandler::target_node_for_mouse_position(CSSPixelPoint position)
|
||||
{
|
||||
auto target = target_for_mouse_position(position);
|
||||
if (!target.has_value() || !target->paintable)
|
||||
return {};
|
||||
|
||||
return target->paintable->dom_node();
|
||||
}
|
||||
|
||||
GC::Ptr<DOM::Node> EventHandler::focus_candidate_for_position(CSSPixelPoint visual_viewport_position) const
|
||||
{
|
||||
auto exact_hit = paint_root()->hit_test(visual_viewport_position, Painting::HitTestType::Exact);
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ public:
|
|||
EventResult handle_mousewheel(CSSPixelPoint, CSSPixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers, double wheel_delta_x, double wheel_delta_y, bool async_scroll_performed_default_action = false, Optional<AsyncScrollOperation>* async_scroll_operation = nullptr);
|
||||
EventResult handle_mouseleave();
|
||||
void update_hover_after_scroll();
|
||||
GC::Ptr<DOM::Node> target_node_for_mouse_position(CSSPixelPoint);
|
||||
|
||||
EventResult handle_keydown(UIEvents::KeyCode, unsigned modifiers, u32 code_point, bool repeat);
|
||||
EventResult handle_keyup(UIEvents::KeyCode, unsigned modifiers, u32 code_point, bool repeat);
|
||||
|
|
|
|||
|
|
@ -327,6 +327,15 @@ EventResult Page::handle_mouseleave()
|
|||
return top_level_traversable()->event_handler().handle_mouseleave();
|
||||
}
|
||||
|
||||
UniqueNodeID Page::node_id_at_position(DevicePixelPoint position)
|
||||
{
|
||||
auto node = top_level_traversable()->event_handler().target_node_for_mouse_position(device_to_css_point(position));
|
||||
if (!node)
|
||||
return 0;
|
||||
|
||||
return node->unique_id();
|
||||
}
|
||||
|
||||
EventResult Page::handle_mousewheel(DevicePixelPoint position, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers, double wheel_delta_x, double wheel_delta_y, bool async_scroll_performed_default_action, Optional<AsyncScrollOperation>* async_scroll_operation)
|
||||
{
|
||||
return top_level_traversable()->event_handler().handle_mousewheel(device_to_css_point(position), device_to_css_point(screen_position), button, buttons, modifiers, wheel_delta_x, wheel_delta_y, async_scroll_performed_default_action, async_scroll_operation);
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ public:
|
|||
EventResult handle_mousedown(DevicePixelPoint, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers, int click_count);
|
||||
EventResult handle_mousemove(DevicePixelPoint, DevicePixelPoint screen_position, unsigned buttons, unsigned modifiers);
|
||||
EventResult handle_mouseleave();
|
||||
UniqueNodeID node_id_at_position(DevicePixelPoint);
|
||||
EventResult handle_mousewheel(DevicePixelPoint, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers, double wheel_delta_x, double wheel_delta_y, bool async_scroll_performed_default_action = false, Optional<AsyncScrollOperation>* async_scroll_operation = nullptr);
|
||||
|
||||
EventResult handle_drag_and_drop_event(DragEvent::Type, DevicePixelPoint, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers, Vector<HTML::SelectedFile> files);
|
||||
|
|
|
|||
|
|
@ -246,6 +246,7 @@ public:
|
|||
Function<void(Optional<JsonObject>)> on_received_current_flexbox;
|
||||
Function<void(JsonObject)> on_received_accessibility_tree;
|
||||
Function<void(Web::UniqueNodeID)> on_received_hovered_node_id;
|
||||
Function<void(u64 request_id, Web::UniqueNodeID)> on_received_node_id_at_position;
|
||||
Function<void(Mutation)> on_dom_mutation_received;
|
||||
Function<void(Optional<Web::UniqueNodeID> const& node_id)> on_finished_editing_dom_node;
|
||||
Function<void(String)> on_received_dom_node_html;
|
||||
|
|
|
|||
|
|
@ -749,6 +749,14 @@ void WebContentClient::did_get_hovered_node_id(u64 page_id, Web::UniqueNodeID no
|
|||
}
|
||||
}
|
||||
|
||||
void WebContentClient::did_get_node_id_at_position(u64 page_id, u64 request_id, Web::UniqueNodeID node_id)
|
||||
{
|
||||
if (auto view = view_for_page_id(page_id); view.has_value()) {
|
||||
if (view->on_received_node_id_at_position)
|
||||
view->on_received_node_id_at_position(request_id, node_id);
|
||||
}
|
||||
}
|
||||
|
||||
void WebContentClient::did_finish_editing_dom_node(u64 page_id, Optional<Web::UniqueNodeID> node_id)
|
||||
{
|
||||
if (auto view = view_for_page_id(page_id); view.has_value()) {
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ private:
|
|||
virtual void did_inspect_current_flexbox(u64 page_id, String) override;
|
||||
virtual void did_inspect_accessibility_tree(u64 page_id, String) override;
|
||||
virtual void did_get_hovered_node_id(u64 page_id, Web::UniqueNodeID node_id) override;
|
||||
virtual void did_get_node_id_at_position(u64 page_id, u64 request_id, Web::UniqueNodeID node_id) override;
|
||||
virtual void did_finish_editing_dom_node(u64 page_id, Optional<Web::UniqueNodeID> node_id) override;
|
||||
virtual void did_mutate_dom(u64 page_id, Mutation) override;
|
||||
virtual void did_get_dom_node_html(u64 page_id, String html) override;
|
||||
|
|
|
|||
|
|
@ -1122,6 +1122,17 @@ void ConnectionFromClient::get_hovered_node_id(u64 page_id)
|
|||
async_did_get_hovered_node_id(page_id, node_id);
|
||||
}
|
||||
|
||||
void ConnectionFromClient::get_node_id_at_position(u64 page_id, u64 request_id, Web::DevicePixelPoint position)
|
||||
{
|
||||
auto page = this->page(page_id);
|
||||
if (!page.has_value()) {
|
||||
async_did_get_node_id_at_position(page_id, request_id, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
async_did_get_node_id_at_position(page_id, request_id, page->page().node_id_at_position(position));
|
||||
}
|
||||
|
||||
void ConnectionFromClient::list_style_sheets(u64 page_id)
|
||||
{
|
||||
auto page = this->page(page_id);
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ private:
|
|||
virtual void clear_grid_highlight(u64 page_id, Web::UniqueNodeID node_id) override;
|
||||
virtual void inspect_accessibility_tree(u64 page_id) override;
|
||||
virtual void get_hovered_node_id(u64 page_id) override;
|
||||
virtual void get_node_id_at_position(u64 page_id, u64 request_id, Web::DevicePixelPoint position) override;
|
||||
|
||||
virtual void list_style_sheets(u64 page_id) override;
|
||||
virtual void request_style_sheet_source(u64 page_id, Web::CSS::StyleSheetIdentifier identifier) override;
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ endpoint WebContentClient
|
|||
did_inspect_current_flexbox(u64 page_id, String flexbox_layout) =|
|
||||
did_inspect_accessibility_tree(u64 page_id, String accessibility_tree) =|
|
||||
did_get_hovered_node_id(u64 page_id, Web::UniqueNodeID node_id) =|
|
||||
did_get_node_id_at_position(u64 page_id, u64 request_id, Web::UniqueNodeID node_id) =|
|
||||
did_finish_editing_dom_node(u64 page_id, Optional<Web::UniqueNodeID> node_id) =|
|
||||
did_mutate_dom(u64 page_id, WebView::Mutation mutation) =|
|
||||
did_get_dom_node_html(u64 page_id, String html) =|
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ endpoint WebContentServer
|
|||
clear_grid_highlight(u64 page_id, Web::UniqueNodeID node_id) =|
|
||||
inspect_accessibility_tree(u64 page_id) =|
|
||||
get_hovered_node_id(u64 page_id) =|
|
||||
get_node_id_at_position(u64 page_id, u64 request_id, Web::DevicePixelPoint position) =|
|
||||
|
||||
js_console_input(u64 page_id, String js_source) =|
|
||||
run_javascript(u64 page_id, String js_source) =|
|
||||
|
|
|
|||
Loading…
Reference in a new issue