diff --git a/Libraries/LibWeb/DOM/Document.cpp b/Libraries/LibWeb/DOM/Document.cpp index 80f3c9284cf..e8b53d91b1e 100644 --- a/Libraries/LibWeb/DOM/Document.cpp +++ b/Libraries/LibWeb/DOM/Document.cpp @@ -519,6 +519,7 @@ void Document::visit_edges(Cell::Visitor& visitor) visitor.visit(m_style_sheets); visitor.visit(m_hovered_node); visitor.visit(m_inspected_node); + visitor.visit(m_highlighted_node); visitor.visit(m_active_favicon); visitor.visit(m_focused_element); visitor.visit(m_active_element); @@ -1638,29 +1639,36 @@ Layout::Viewport* Document::layout_node() return static_cast(Node::layout_node()); } -void Document::set_inspected_node(Node* node, Optional pseudo_element) +void Document::set_inspected_node(GC::Ptr node) { - if (m_inspected_node.ptr() == node && m_inspected_pseudo_element == pseudo_element) + m_inspected_node = node; +} + +void Document::set_highlighted_node(GC::Ptr node, Optional pseudo_element) +{ + if (m_highlighted_node == node && m_highlighted_pseudo_element == pseudo_element) return; - if (auto layout_node = inspected_layout_node(); layout_node && layout_node->first_paintable()) + if (auto layout_node = highlighted_layout_node(); layout_node && layout_node->first_paintable()) layout_node->first_paintable()->set_needs_display(); - m_inspected_node = node; - m_inspected_pseudo_element = pseudo_element; + m_highlighted_node = node; + m_highlighted_pseudo_element = pseudo_element; - if (auto layout_node = inspected_layout_node(); layout_node && layout_node->first_paintable()) + if (auto layout_node = highlighted_layout_node(); layout_node && layout_node->first_paintable()) layout_node->first_paintable()->set_needs_display(); } -Layout::Node* Document::inspected_layout_node() +GC::Ptr Document::highlighted_layout_node() { - if (!m_inspected_node) + if (!m_highlighted_node) return nullptr; - if (!m_inspected_pseudo_element.has_value() || !m_inspected_node->is_element()) - return m_inspected_node->layout_node(); - auto& element = static_cast(*m_inspected_node); - return element.get_pseudo_element_node(m_inspected_pseudo_element.value()); + + if (!m_highlighted_pseudo_element.has_value() || !m_highlighted_node->is_element()) + return m_highlighted_node->layout_node(); + + auto const& element = static_cast(*m_highlighted_node); + return element.get_pseudo_element_node(m_highlighted_pseudo_element.value()); } static Node* find_common_ancestor(Node* a, Node* b) diff --git a/Libraries/LibWeb/DOM/Document.h b/Libraries/LibWeb/DOM/Document.h index f17818f198a..528873a459d 100644 --- a/Libraries/LibWeb/DOM/Document.h +++ b/Libraries/LibWeb/DOM/Document.h @@ -186,11 +186,13 @@ public: Node* hovered_node() { return m_hovered_node.ptr(); } Node const* hovered_node() const { return m_hovered_node.ptr(); } - void set_inspected_node(Node*, Optional); - Node* inspected_node() { return m_inspected_node.ptr(); } - Node const* inspected_node() const { return m_inspected_node.ptr(); } - Layout::Node* inspected_layout_node(); - Layout::Node const* inspected_layout_node() const { return const_cast(this)->inspected_layout_node(); } + void set_inspected_node(GC::Ptr); + GC::Ptr inspected_node() const { return m_inspected_node; } + + void set_highlighted_node(GC::Ptr, Optional); + GC::Ptr highlighted_node() const { return m_highlighted_node; } + GC::Ptr highlighted_layout_node(); + GC::Ptr highlighted_layout_node() const { return const_cast(this)->highlighted_layout_node(); } Element* document_element(); Element const* document_element() const; @@ -866,9 +868,6 @@ private: GC::Ref m_page; OwnPtr m_style_computer; GC::Ptr m_style_sheets; - GC::Ptr m_hovered_node; - GC::Ptr m_inspected_node; - Optional m_inspected_pseudo_element; GC::Ptr m_active_favicon; WeakPtr m_browsing_context; URL::URL m_url; @@ -877,6 +876,11 @@ private: GC::Ptr m_layout_root; + GC::Ptr m_hovered_node; + GC::Ptr m_inspected_node; + GC::Ptr m_highlighted_node; + Optional m_highlighted_pseudo_element; + Optional m_normal_link_color; Optional m_active_link_color; Optional m_visited_link_color; diff --git a/Libraries/LibWeb/Painting/PaintableBox.cpp b/Libraries/LibWeb/Painting/PaintableBox.cpp index e70c872799d..b88b3697307 100644 --- a/Libraries/LibWeb/Painting/PaintableBox.cpp +++ b/Libraries/LibWeb/Painting/PaintableBox.cpp @@ -475,7 +475,7 @@ void PaintableBox::paint(PaintContext& context, PaintPhase phase) const } } - if (phase == PaintPhase::Overlay && layout_node().document().inspected_layout_node() == &layout_node_with_style_and_box_metrics()) { + if (phase == PaintPhase::Overlay && layout_node().document().highlighted_layout_node() == &layout_node_with_style_and_box_metrics()) { auto content_rect = absolute_united_content_rect(); auto margin_rect = united_rect_for_continuation_chain(*this, [](PaintableBox const& box) { auto margin_box = box.box_model().margin_box(); @@ -759,7 +759,7 @@ void paint_text_fragment(PaintContext& context, TextPaintable const& paintable, auto fragment_absolute_rect = fragment.absolute_rect(); auto fragment_absolute_device_rect = context.enclosing_device_rect(fragment_absolute_rect); - if (paintable.document().inspected_layout_node() == &paintable.layout_node()) + if (paintable.document().highlighted_layout_node() == &paintable.layout_node()) context.display_list_recorder().draw_rect(fragment_absolute_device_rect.to_type(), Color::Magenta); auto text = paintable.text_for_rendering(); diff --git a/Libraries/LibWebView/InspectorClient.cpp b/Libraries/LibWebView/InspectorClient.cpp index ef46885e869..75f8baf94e9 100644 --- a/Libraries/LibWebView/InspectorClient.cpp +++ b/Libraries/LibWebView/InspectorClient.cpp @@ -161,6 +161,7 @@ InspectorClient::InspectorClient(ViewImplementation& content_web_view, ViewImple }; m_inspector_web_view.on_inspector_selected_dom_node = [this](auto node_id, auto const& pseudo_element) { + m_content_web_view.highlight_dom_node(node_id, pseudo_element); m_content_web_view.inspect_dom_node(node_id, pseudo_element); }; @@ -306,6 +307,7 @@ void InspectorClient::select_default_node() void InspectorClient::clear_selection() { + m_content_web_view.clear_highlighted_dom_node(); m_content_web_view.clear_inspected_dom_node(); static constexpr auto script = "inspector.clearInspectedDOMNode();"sv; diff --git a/Libraries/LibWebView/ViewImplementation.cpp b/Libraries/LibWebView/ViewImplementation.cpp index c77811fcced..122f6dcea71 100644 --- a/Libraries/LibWebView/ViewImplementation.cpp +++ b/Libraries/LibWebView/ViewImplementation.cpp @@ -303,24 +303,34 @@ void ViewImplementation::inspect_dom_tree() client().async_inspect_dom_tree(page_id()); } -void ViewImplementation::inspect_dom_node(Web::UniqueNodeID node_id, Optional pseudo_element) -{ - client().async_inspect_dom_node(page_id(), node_id, move(pseudo_element)); -} - void ViewImplementation::inspect_accessibility_tree() { client().async_inspect_accessibility_tree(page_id()); } +void ViewImplementation::get_hovered_node_id() +{ + client().async_get_hovered_node_id(page_id()); +} + +void ViewImplementation::inspect_dom_node(Web::UniqueNodeID node_id, Optional pseudo_element) +{ + client().async_inspect_dom_node(page_id(), node_id, move(pseudo_element)); +} + void ViewImplementation::clear_inspected_dom_node() { inspect_dom_node(0, {}); } -void ViewImplementation::get_hovered_node_id() +void ViewImplementation::highlight_dom_node(Web::UniqueNodeID node_id, Optional pseudo_element) { - client().async_get_hovered_node_id(page_id()); + client().async_highlight_dom_node(page_id(), node_id, move(pseudo_element)); +} + +void ViewImplementation::clear_highlighted_dom_node() +{ + highlight_dom_node(0, {}); } void ViewImplementation::set_dom_node_text(Web::UniqueNodeID node_id, String text) diff --git a/Libraries/LibWebView/ViewImplementation.h b/Libraries/LibWebView/ViewImplementation.h index 5ec51cbf85e..f87f8b9476c 100644 --- a/Libraries/LibWebView/ViewImplementation.h +++ b/Libraries/LibWebView/ViewImplementation.h @@ -103,11 +103,15 @@ public: void get_source(); void inspect_dom_tree(); - void inspect_dom_node(Web::UniqueNodeID node_id, Optional pseudo_element); void inspect_accessibility_tree(); - void clear_inspected_dom_node(); void get_hovered_node_id(); + void inspect_dom_node(Web::UniqueNodeID node_id, Optional pseudo_element); + void clear_inspected_dom_node(); + + void highlight_dom_node(Web::UniqueNodeID node_id, Optional pseudo_element); + void clear_highlighted_dom_node(); + void set_dom_node_text(Web::UniqueNodeID node_id, String text); void set_dom_node_tag(Web::UniqueNodeID node_id, String name); void add_dom_node_attributes(Web::UniqueNodeID node_id, Vector attributes); diff --git a/Services/WebContent/ConnectionFromClient.cpp b/Services/WebContent/ConnectionFromClient.cpp index 622e36aae62..d06a97fdb15 100644 --- a/Services/WebContent/ConnectionFromClient.cpp +++ b/Services/WebContent/ConnectionFromClient.cpp @@ -442,7 +442,7 @@ void ConnectionFromClient::inspect_dom_node(u64 page_id, Web::UniqueNodeID const for (auto& navigable : Web::HTML::all_navigables()) { if (navigable->active_document() != nullptr) { - navigable->active_document()->set_inspected_node(nullptr, {}); + navigable->active_document()->set_inspected_node(nullptr); } } @@ -453,7 +453,7 @@ void ConnectionFromClient::inspect_dom_node(u64 page_id, Web::UniqueNodeID const return; } - node->document().set_inspected_node(node, pseudo_element); + node->document().set_inspected_node(node); if (node->is_element()) { auto& element = as(*node); @@ -599,6 +599,25 @@ void ConnectionFromClient::inspect_dom_node(u64 page_id, Web::UniqueNodeID const async_did_inspect_dom_node(page_id, false, {}, {}, {}, {}, {}, {}); } +void ConnectionFromClient::highlight_dom_node(u64 page_id, Web::UniqueNodeID const& node_id, Optional const& pseudo_element) +{ + auto page = this->page(page_id); + if (!page.has_value()) + return; + + for (auto& navigable : Web::HTML::all_navigables()) { + if (navigable->active_document() != nullptr) { + navigable->active_document()->set_highlighted_node(nullptr, {}); + } + } + + auto* node = Web::DOM::Node::from_unique_id(node_id); + if (!node || !node->layout_node()) + return; + + node->document().set_highlighted_node(node, pseudo_element); +} + void ConnectionFromClient::inspect_accessibility_tree(u64 page_id) { if (auto page = this->page(page_id); page.has_value()) { diff --git a/Services/WebContent/ConnectionFromClient.h b/Services/WebContent/ConnectionFromClient.h index ca68ca511e9..61640740f1f 100644 --- a/Services/WebContent/ConnectionFromClient.h +++ b/Services/WebContent/ConnectionFromClient.h @@ -76,6 +76,7 @@ private: virtual void get_source(u64 page_id) override; virtual void inspect_dom_tree(u64 page_id) override; virtual void inspect_dom_node(u64 page_id, Web::UniqueNodeID const& node_id, Optional const& pseudo_element) override; + virtual void highlight_dom_node(u64 page_id, Web::UniqueNodeID const& node_id, Optional const& pseudo_element) override; virtual void inspect_accessibility_tree(u64 page_id) override; virtual void get_hovered_node_id(u64 page_id) override; diff --git a/Services/WebContent/ConsoleGlobalEnvironmentExtensions.cpp b/Services/WebContent/ConsoleGlobalEnvironmentExtensions.cpp index 8e58ed04653..950b46984b1 100644 --- a/Services/WebContent/ConsoleGlobalEnvironmentExtensions.cpp +++ b/Services/WebContent/ConsoleGlobalEnvironmentExtensions.cpp @@ -53,7 +53,7 @@ JS_DEFINE_NATIVE_FUNCTION(ConsoleGlobalEnvironmentExtensions::$0_getter) { auto* console_global_object = TRY(get_console(vm)); auto& window = *console_global_object->m_window_object; - auto* inspected_node = window.associated_document().inspected_node(); + auto inspected_node = window.associated_document().inspected_node(); if (!inspected_node) return JS::js_undefined(); diff --git a/Services/WebContent/WebContentServer.ipc b/Services/WebContent/WebContentServer.ipc index 30c275779ec..86ad895db53 100644 --- a/Services/WebContent/WebContentServer.ipc +++ b/Services/WebContent/WebContentServer.ipc @@ -45,6 +45,7 @@ endpoint WebContentServer get_source(u64 page_id) =| inspect_dom_tree(u64 page_id) =| inspect_dom_node(u64 page_id, Web::UniqueNodeID node_id, Optional pseudo_element) =| + highlight_dom_node(u64 page_id, Web::UniqueNodeID node_id, Optional pseudo_element) =| inspect_accessibility_tree(u64 page_id) =| get_hovered_node_id(u64 page_id) =| js_console_input(u64 page_id, ByteString js_source) =|