diff --git a/Libraries/LibWebView/Application.cpp b/Libraries/LibWebView/Application.cpp index 3f370512243..c3d28b17340 100644 --- a/Libraries/LibWebView/Application.cpp +++ b/Libraries/LibWebView/Application.cpp @@ -371,14 +371,9 @@ void Application::inspect_tab(DevTools::TabDescription const& description, DevTo return; } - view->on_received_dom_tree = [&view = *view, on_complete = move(on_complete)](String const& dom_tree) { + view->on_received_dom_tree = [&view = *view, on_complete = move(on_complete)](JsonObject dom_tree) { view.on_received_dom_tree = nullptr; - - if (auto parsed_tree = JsonValue::from_string(dom_tree); parsed_tree.is_error()) { - on_complete(parsed_tree.release_error()); - } else { - on_complete(parsed_tree.release_value()); - } + on_complete(move(dom_tree)); }; view->inspect_dom_tree(); diff --git a/Libraries/LibWebView/InspectorClient.cpp b/Libraries/LibWebView/InspectorClient.cpp index 1295fcb163e..ef46885e869 100644 --- a/Libraries/LibWebView/InspectorClient.cpp +++ b/Libraries/LibWebView/InspectorClient.cpp @@ -28,15 +28,6 @@ static constexpr auto INSPECTOR_HTML = "resource://ladybird/inspector.html"sv; static constexpr auto INSPECTOR_CSS = "resource://ladybird/inspector.css"sv; static constexpr auto INSPECTOR_JS = "resource://ladybird/inspector.js"sv; -static ErrorOr parse_json_tree(StringView json) -{ - auto parsed_tree = TRY(JsonValue::from_string(json)); - if (!parsed_tree.is_object()) - return Error::from_string_literal("Expected tree to be a JSON object"); - - return parsed_tree; -} - static String style_sheet_identifier_to_json(Web::CSS::StyleSheetIdentifier const& identifier) { return MUST(String::formatted("{{ type: '{}', domNodeId: {}, url: '{}' }}"sv, @@ -50,13 +41,7 @@ InspectorClient::InspectorClient(ViewImplementation& content_web_view, ViewImple , m_inspector_web_view(inspector_web_view) { m_content_web_view.on_received_dom_tree = [this](auto const& dom_tree) { - auto result = parse_json_tree(dom_tree); - if (result.is_error()) { - dbgln("Failed to load DOM tree: {}", result.error()); - return; - } - - auto dom_tree_html = generate_dom_tree(result.value().as_object()); + auto dom_tree_html = generate_dom_tree(dom_tree); auto dom_tree_base64 = MUST(encode_base64(dom_tree_html.bytes())); auto script = MUST(String::formatted("inspector.loadDOMTree(\"{}\");", dom_tree_base64)); @@ -70,44 +55,27 @@ InspectorClient::InspectorClient(ViewImplementation& content_web_view, ViewImple select_default_node(); }; - m_content_web_view.on_received_dom_node_properties = [this](auto const& inspected_node_properties) { + m_content_web_view.on_received_dom_node_properties = [this](auto const& properties) { StringBuilder builder; // FIXME: Support box model metrics and ARIA properties. - auto generate_property_script = [&](auto const& computed_style, auto const& resolved_style, auto const& custom_properties, auto const& fonts) { - builder.append("inspector.createPropertyTables(\""sv); - builder.append_escaped_for_json(computed_style); - builder.append("\", \""sv); - builder.append_escaped_for_json(resolved_style); - builder.append("\", \""sv); - builder.append_escaped_for_json(custom_properties); - builder.append("\");"sv); - builder.append("inspector.createFontList(\""sv); - builder.append_escaped_for_json(fonts); - builder.append("\");"sv); - }; + builder.append("inspector.createPropertyTables(\""sv); + builder.append_escaped_for_json(properties.computed_style.serialized()); + builder.append("\", \""sv); + builder.append_escaped_for_json(properties.resolved_style.serialized()); + builder.append("\", \""sv); + builder.append_escaped_for_json(properties.custom_properties.serialized()); + builder.append("\");"sv); - if (inspected_node_properties.has_value()) { - generate_property_script( - inspected_node_properties->computed_style_json, - inspected_node_properties->resolved_style_json, - inspected_node_properties->custom_properties_json, - inspected_node_properties->fonts_json); - } else { - generate_property_script("{}"sv, "{}"sv, "{}"sv, "{}"sv); - } + builder.append("inspector.createFontList(\""sv); + builder.append_escaped_for_json(properties.fonts.serialized()); + builder.append("\");"sv); m_inspector_web_view.run_javascript(builder.string_view()); }; m_content_web_view.on_received_accessibility_tree = [this](auto const& accessibility_tree) { - auto result = parse_json_tree(accessibility_tree); - if (result.is_error()) { - dbgln("Failed to load accessibility tree: {}", result.error()); - return; - } - - auto accessibility_tree_html = generate_accessibility_tree(result.value().as_object()); + auto accessibility_tree_html = generate_accessibility_tree(accessibility_tree); auto accessibility_tree_base64 = MUST(encode_base64(accessibility_tree_html.bytes())); auto script = MUST(String::formatted("inspector.loadAccessibilityTree(\"{}\");", accessibility_tree_base64)); diff --git a/Libraries/LibWebView/ViewImplementation.h b/Libraries/LibWebView/ViewImplementation.h index 67c6265f1aa..5ec51cbf85e 100644 --- a/Libraries/LibWebView/ViewImplementation.h +++ b/Libraries/LibWebView/ViewImplementation.h @@ -9,6 +9,8 @@ #include #include +#include +#include #include #include #include @@ -35,12 +37,12 @@ public: virtual ~ViewImplementation(); struct DOMNodeProperties { - String computed_style_json; - String resolved_style_json; - String custom_properties_json; - String node_box_sizing_json; - String aria_properties_state_json; - String fonts_json; + JsonObject computed_style; + JsonObject resolved_style; + JsonObject custom_properties; + JsonObject node_box_sizing; + JsonObject aria_properties_state; + JsonArray fonts; }; static void for_each_view(Function); @@ -200,9 +202,9 @@ public: Function on_request_accept_dialog; Function on_request_dismiss_dialog; Function on_received_source; - Function on_received_dom_tree; - Function)> on_received_dom_node_properties; - Function on_received_accessibility_tree; + Function on_received_dom_tree; + Function on_received_dom_node_properties; + Function on_received_accessibility_tree; Function)> on_received_style_sheet_list; Function on_inspector_requested_style_sheet_source; Function on_received_style_sheet_source; diff --git a/Libraries/LibWebView/WebContentClient.cpp b/Libraries/LibWebView/WebContentClient.cpp index 0c0cbb37d88..efa09cd418d 100644 --- a/Libraries/LibWebView/WebContentClient.cpp +++ b/Libraries/LibWebView/WebContentClient.cpp @@ -264,11 +264,39 @@ void WebContentClient::did_get_source(u64 page_id, URL::URL const& url, URL::URL } } +template +static JsonType parse_json(StringView json, StringView name) +{ + auto parsed_tree = JsonValue::from_string(json); + if (parsed_tree.is_error()) { + dbgln("Unable to parse {}: {}", name, parsed_tree.error()); + return {}; + } + + if constexpr (IsSame) { + if (!parsed_tree.value().is_object()) { + dbgln("Expected {} to be an object: {}", name, parsed_tree.value()); + return {}; + } + + return move(parsed_tree.release_value().as_object()); + } else if constexpr (IsSame) { + if (!parsed_tree.value().is_array()) { + dbgln("Expected {} to be an array: {}", name, parsed_tree.value()); + return {}; + } + + return move(parsed_tree.release_value().as_array()); + } else { + static_assert(DependentFalse); + } +} + void WebContentClient::did_inspect_dom_tree(u64 page_id, String const& dom_tree) { if (auto view = view_for_page_id(page_id); view.has_value()) { if (view->on_received_dom_tree) - view->on_received_dom_tree(dom_tree); + view->on_received_dom_tree(parse_json(dom_tree, "DOM tree"sv)); } } @@ -278,16 +306,16 @@ void WebContentClient::did_inspect_dom_node(u64 page_id, bool has_style, String if (!view.has_value() || !view->on_received_dom_node_properties) return; - Optional properties; + ViewImplementation::DOMNodeProperties properties; if (has_style) { properties = ViewImplementation::DOMNodeProperties { - .computed_style_json = computed_style, - .resolved_style_json = resolved_style, - .custom_properties_json = custom_properties, - .node_box_sizing_json = node_box_sizing, - .aria_properties_state_json = aria_properties_state, - .fonts_json = fonts, + .computed_style = parse_json(computed_style, "computed style"sv), + .resolved_style = parse_json(resolved_style, "resolved style"sv), + .custom_properties = parse_json(custom_properties, "custom properties"sv), + .node_box_sizing = parse_json(node_box_sizing, "node box sizing"sv), + .aria_properties_state = parse_json(aria_properties_state, "aria properties state"sv), + .fonts = parse_json(fonts, "fonts"sv), }; } @@ -298,7 +326,7 @@ void WebContentClient::did_inspect_accessibility_tree(u64 page_id, String const& { if (auto view = view_for_page_id(page_id); view.has_value()) { if (view->on_received_accessibility_tree) - view->on_received_accessibility_tree(accessibility_tree); + view->on_received_accessibility_tree(parse_json(accessibility_tree, "accessibility tree"sv)); } }