diff --git a/Libraries/LibWeb/DOM/Document.cpp b/Libraries/LibWeb/DOM/Document.cpp index 2abdf43b8f..7a2e8be09e 100644 --- a/Libraries/LibWeb/DOM/Document.cpp +++ b/Libraries/LibWeb/DOM/Document.cpp @@ -1779,7 +1779,11 @@ void Document::update_layout(UpdateLayoutReason reason) for (size_t layout_pass = 0; layout_pass < max_container_query_layout_passes; ++layout_pass) { update_style(); - if (layout_is_up_to_date()) + auto const should_collect_devtools_layout_data = page().client().has_active_devtools_client(); + auto const force_devtools_layout_data_collection = should_collect_devtools_layout_data + && reason == UpdateLayoutReason::InspectDevToolsLayoutData; + + if (layout_is_up_to_date() && !force_devtools_layout_data_collection) return; auto svg_roots_to_relayout = move(m_svg_roots_needing_relayout); @@ -1866,6 +1870,7 @@ void Document::update_layout(UpdateLayoutReason reason) Layout::LayoutState layout_state; layout_state.ensure_capacity(layout_index_counter); + layout_state.set_should_collect_devtools_layout_data(should_collect_devtools_layout_data); { auto& viewport = static_cast(*m_layout_root); @@ -1963,6 +1968,22 @@ void Document::update_layout(UpdateLayoutReason reason) VERIFY(layout_is_up_to_date()); } +void Document::clear_devtools_layout_inspection_data() +{ + clear_grid_highlighted_node(nullptr); + clear_flexbox_highlighted_node(nullptr); + + auto paintable = this->paintable(); + if (!paintable) + return; + + paintable->for_each_in_subtree_of_type([](auto& paintable_box) { + paintable_box.set_grid_layout_data(nullptr); + paintable_box.set_flex_layout_data(nullptr); + return TraversalDecision::Continue; + }); +} + bool Document::layout_is_up_to_date() const { if (!navigable() || navigable()->active_document() != this) diff --git a/Libraries/LibWeb/DOM/Document.h b/Libraries/LibWeb/DOM/Document.h index d4691a2429..0bc3627cc6 100644 --- a/Libraries/LibWeb/DOM/Document.h +++ b/Libraries/LibWeb/DOM/Document.h @@ -126,8 +126,7 @@ enum class InvalidateLayoutTreeReason { X(HostedDocumentBeforePaint) \ X(InspectAccessibilityTree) \ X(InspectDOMTree) \ - X(InspectFlexboxLayout) \ - X(InspectGridLayout) \ + X(InspectDevToolsLayoutData) \ X(InternalsHitTest) \ X(MediaQueryListMatches) \ X(NavigableSelectedText) \ @@ -400,6 +399,7 @@ public: void update_layout(UpdateLayoutReason); void update_layout_if_needed_for_node(Node const&, UpdateLayoutReason); [[nodiscard]] bool layout_is_up_to_date() const; + void clear_devtools_layout_inspection_data(); void update_paint_and_hit_testing_properties_if_needed(); void update_animated_style_if_needed(); diff --git a/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Libraries/LibWeb/Layout/FlexFormattingContext.cpp index c6f45b8428..8958f4f112 100644 --- a/Libraries/LibWeb/Layout/FlexFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/FlexFormattingContext.cpp @@ -247,7 +247,8 @@ void FlexFormattingContext::run(AvailableSpace const& available_space) resolve_baseline_aligned_items(); } - save_flex_layout_data(); + if (m_state.should_collect_devtools_layout_data()) + save_flex_layout_data(); } void FlexFormattingContext::parent_context_did_dimension_child_root_box() diff --git a/Libraries/LibWeb/Layout/GridFormattingContext.cpp b/Libraries/LibWeb/Layout/GridFormattingContext.cpp index 5302bebded..bcd2facd71 100644 --- a/Libraries/LibWeb/Layout/GridFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/GridFormattingContext.cpp @@ -2420,6 +2420,9 @@ void GridFormattingContext::resolve_track_spacing(GridDimension dimension) void GridFormattingContext::save_grid_layout_data() { + if (!m_state.should_collect_devtools_layout_data()) + return; + auto data = make(); data->direction = grid_container().computed_values().direction(); data->is_subgrid = is_subgridded_axis(GridDimension::Column) || is_subgridded_axis(GridDimension::Row); diff --git a/Libraries/LibWeb/Layout/LayoutState.h b/Libraries/LibWeb/Layout/LayoutState.h index 0212a80078..02cf143a1c 100644 --- a/Libraries/LibWeb/Layout/LayoutState.h +++ b/Libraries/LibWeb/Layout/LayoutState.h @@ -392,6 +392,9 @@ struct LayoutState { void ensure_capacity(u32 node_count); + void set_should_collect_devtools_layout_data(bool should_collect) { m_should_collect_devtools_layout_data = should_collect; } + bool should_collect_devtools_layout_data() const { return m_should_collect_devtools_layout_data; } + UsedValues& get_mutable(NodeWithStyle const&); UsedValues const& get(NodeWithStyle const&) const; @@ -408,6 +411,7 @@ private: PagedStore m_used_values_store; GC::Ptr m_subtree_root; + bool m_should_collect_devtools_layout_data { false }; }; inline CSSPixels clamp_to_max_dimension_value(CSSPixels value) diff --git a/Libraries/LibWeb/Page/Page.h b/Libraries/LibWeb/Page/Page.h index d49923a59c..a8b6af2879 100644 --- a/Libraries/LibWeb/Page/Page.h +++ b/Libraries/LibWeb/Page/Page.h @@ -414,6 +414,7 @@ public: virtual Page& page() = 0; virtual Page const& page() const = 0; virtual bool is_connection_open() const = 0; + virtual bool has_active_devtools_client() const { return false; } virtual bool is_url_suitable_for_same_process_navigation([[maybe_unused]] URL::URL const& current_url, [[maybe_unused]] URL::URL const& target_url) const { return true; } virtual void request_new_process_for_navigation(URL::URL const&) { } virtual Gfx::Palette palette() const = 0; diff --git a/Services/WebContent/ConnectionFromClient.cpp b/Services/WebContent/ConnectionFromClient.cpp index 2e94aaffac..a8439c939d 100644 --- a/Services/WebContent/ConnectionFromClient.cpp +++ b/Services/WebContent/ConnectionFromClient.cpp @@ -902,7 +902,7 @@ static void append_grid_layouts_for_node_and_frame_descendants(Web::DOM::Node& r if (!content_document->origin().is_same_origin_domain(navigable_container->document().origin())) return Web::TraversalDecision::Continue; - content_document->update_layout(Web::DOM::UpdateLayoutReason::InspectGridLayout); + content_document->update_layout(Web::DOM::UpdateLayoutReason::Debugging); append_grid_layouts_for_node_and_frame_descendants(*content_document, grid_layouts); return Web::TraversalDecision::Continue; }); @@ -920,7 +920,7 @@ void ConnectionFromClient::inspect_grid_layouts(u64 page_id, Web::UniqueNodeID r return; } - root_node->document().update_layout(Web::DOM::UpdateLayoutReason::InspectGridLayout); + root_node->document().update_layout(Web::DOM::UpdateLayoutReason::Debugging); JsonArray grid_layouts; append_grid_layouts_for_node_and_frame_descendants(*root_node, grid_layouts); @@ -940,7 +940,7 @@ void ConnectionFromClient::inspect_current_grid(u64 page_id, Web::UniqueNodeID n return; } - node->document().update_layout(Web::DOM::UpdateLayoutReason::InspectGridLayout); + node->document().update_layout(Web::DOM::UpdateLayoutReason::Debugging); for (auto const* current = node; current; current = current->parent_or_shadow_host_node()) { if (auto grid_layout = grid_layout_for_node(*current); grid_layout.has_value()) { @@ -964,7 +964,7 @@ void ConnectionFromClient::inspect_current_flexbox(u64 page_id, Web::UniqueNodeI return; } - node->document().update_layout(Web::DOM::UpdateLayoutReason::InspectFlexboxLayout); + node->document().update_layout(Web::DOM::UpdateLayoutReason::Debugging); for (auto const* current = only_look_at_parents ? node->parent_or_shadow_host_node() : node; current; current = current->parent_or_shadow_host_node()) { if (auto flex_layout = flex_layout_for_node(*current); flex_layout.has_value()) { @@ -1062,10 +1062,15 @@ void ConnectionFromClient::highlight_flexbox(u64 page_id, Web::UniqueNodeID node return; auto* node = Web::DOM::Node::from_unique_id(node_id); - if (!node || !node->layout_node()) + if (!node) return; - node->document().set_flexbox_highlighted_node(node, flexbox_inspector_overlay_options_from_json(options)); + auto& document = node->document(); + document.update_layout(Web::DOM::UpdateLayoutReason::Debugging); + if (!node->layout_node()) + return; + + document.set_flexbox_highlighted_node(node, flexbox_inspector_overlay_options_from_json(options)); } void ConnectionFromClient::clear_flexbox_highlight(u64 page_id, Web::UniqueNodeID node_id) @@ -1094,10 +1099,15 @@ void ConnectionFromClient::highlight_grid(u64 page_id, Web::UniqueNodeID node_id return; auto* node = Web::DOM::Node::from_unique_id(node_id); - if (!node || !node->layout_node()) + if (!node) return; - node->document().set_grid_highlighted_node(node, grid_inspector_overlay_options_from_json(options)); + auto& document = node->document(); + document.update_layout(Web::DOM::UpdateLayoutReason::Debugging); + if (!node->layout_node()) + return; + + document.set_grid_highlighted_node(node, grid_inspector_overlay_options_from_json(options)); } void ConnectionFromClient::clear_grid_highlight(u64 page_id, Web::UniqueNodeID node_id) diff --git a/Services/WebContent/PageClient.cpp b/Services/WebContent/PageClient.cpp index b6db20a14a..8873e83591 100644 --- a/Services/WebContent/PageClient.cpp +++ b/Services/WebContent/PageClient.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -935,13 +936,34 @@ void PageClient::page_did_receive_network_response_body(u64 request_id, Readonly void PageClient::did_connect_devtools_client() { + auto was_first_devtools_client = !has_devtools_client(); ++m_devtools_client_count; + + if (!was_first_devtools_client) + return; + + for (auto& navigable : Web::HTML::all_navigables()) { + if (&navigable->page() != &page()) + continue; + if (auto active_document = navigable->active_document()) + active_document->update_layout(Web::DOM::UpdateLayoutReason::InspectDevToolsLayoutData); + } } void PageClient::did_disconnect_devtools_client() { VERIFY(m_devtools_client_count > 0); --m_devtools_client_count; + + if (has_devtools_client()) + return; + + for (auto& navigable : Web::HTML::all_navigables()) { + if (&navigable->page() != &page()) + continue; + if (auto active_document = navigable->active_document()) + active_document->clear_devtools_layout_inspection_data(); + } } void PageClient::page_did_finish_network_request(u64 request_id, u64 body_size, Requests::RequestTimingInfo const& timing_info, Optional const& network_error) diff --git a/Services/WebContent/PageClient.h b/Services/WebContent/PageClient.h index f04c9ad000..a2d6fb0307 100644 --- a/Services/WebContent/PageClient.h +++ b/Services/WebContent/PageClient.h @@ -87,6 +87,7 @@ public: void did_connect_devtools_client(); void did_disconnect_devtools_client(); bool has_devtools_client() const { return m_devtools_client_count > 0; } + virtual bool has_active_devtools_client() const override { return has_devtools_client(); } void initialize_js_console(Web::DOM::Document& document); void js_console_input(StringView js_source);