mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 10:18:11 +00:00
LibWeb+WebContent: Do not embed attributes as data in the Inspector HTML
Attribute values may contain HTML, and may contain invalid HTML at that. If the latter occurs, let's not generate invalid Inspector HTML when we embed the attribute values as data attributes. Instead, cache the values in the InspectorClient, and embed just a lookup index into the HTML. This also nicely reduces the size of the generated HTML. The Inspector on https://github.com/SerenityOS/serenity reduces from 2.3MB to 1.9MB (about 318KB, or 13.8%).
This commit is contained in:
parent
939779cad3
commit
f07f5a2622
13 changed files with 60 additions and 52 deletions
|
@ -96,6 +96,7 @@ InspectorClient::InspectorClient(ViewImplementation& content_web_view, ViewImple
|
|||
m_content_web_view.on_finshed_editing_dom_node = [this](auto const& node_id) {
|
||||
m_pending_selection = node_id;
|
||||
m_dom_tree_loaded = false;
|
||||
m_dom_node_attributes.clear();
|
||||
|
||||
inspect();
|
||||
};
|
||||
|
@ -122,7 +123,11 @@ InspectorClient::InspectorClient(ViewImplementation& content_web_view, ViewImple
|
|||
m_content_web_view.js_console_request_messages(0);
|
||||
};
|
||||
|
||||
m_inspector_web_view.on_inspector_requested_dom_tree_context_menu = [this](auto node_id, auto position, auto const& type, auto const& tag, auto const& attribute) {
|
||||
m_inspector_web_view.on_inspector_requested_dom_tree_context_menu = [this](auto node_id, auto position, auto const& type, auto const& tag, auto const& attribute_index) {
|
||||
Optional<Attribute> attribute;
|
||||
if (attribute_index.has_value())
|
||||
attribute = m_dom_node_attributes.get(node_id)->at(*attribute_index);
|
||||
|
||||
m_context_menu_data = ContextMenuData { node_id, tag, attribute };
|
||||
|
||||
if (type.is_one_of("text"sv, "comment"sv)) {
|
||||
|
@ -158,8 +163,9 @@ InspectorClient::InspectorClient(ViewImplementation& content_web_view, ViewImple
|
|||
m_content_web_view.add_dom_node_attributes(node_id, attributes);
|
||||
};
|
||||
|
||||
m_inspector_web_view.on_inspector_replaced_dom_node_attribute = [this](auto node_id, auto const& name, auto const& replacement_attributes) {
|
||||
m_content_web_view.replace_dom_node_attribute(node_id, name, replacement_attributes);
|
||||
m_inspector_web_view.on_inspector_replaced_dom_node_attribute = [this](auto node_id, u32 attribute_index, auto const& replacement_attributes) {
|
||||
auto const& attribute = m_dom_node_attributes.get(node_id)->at(attribute_index);
|
||||
m_content_web_view.replace_dom_node_attribute(node_id, attribute.name, replacement_attributes);
|
||||
};
|
||||
|
||||
m_inspector_web_view.on_inspector_executed_console_script = [this](auto const& script) {
|
||||
|
@ -201,6 +207,8 @@ void InspectorClient::reset()
|
|||
m_pending_selection.clear();
|
||||
m_dom_tree_loaded = false;
|
||||
|
||||
m_dom_node_attributes.clear();
|
||||
|
||||
m_highest_notified_message_index = -1;
|
||||
m_highest_received_message_index = -1;
|
||||
m_waiting_for_messages = false;
|
||||
|
@ -461,13 +469,17 @@ String InspectorClient::generate_dom_tree(JsonObject const& dom_tree)
|
|||
data_attributes.appendff("data-{}=\"{}\"", name, value);
|
||||
};
|
||||
|
||||
i32 node_id = 0;
|
||||
|
||||
if (auto pseudo_element = node.get_integer<i32>("pseudo-element"sv); pseudo_element.has_value()) {
|
||||
append_data_attribute("id"sv, node.get_integer<i32>("parent-id"sv).value());
|
||||
node_id = node.get_integer<i32>("parent-id"sv).value();
|
||||
append_data_attribute("pseudo-element"sv, *pseudo_element);
|
||||
} else {
|
||||
append_data_attribute("id"sv, node.get_integer<i32>("id"sv).value());
|
||||
node_id = node.get_integer<i32>("id"sv).value();
|
||||
}
|
||||
|
||||
append_data_attribute("id"sv, node_id);
|
||||
|
||||
if (type == "text"sv) {
|
||||
auto deprecated_text = node.get_byte_string("text"sv).release_value();
|
||||
deprecated_text = escape_html_entities(deprecated_text);
|
||||
|
@ -513,7 +525,7 @@ String InspectorClient::generate_dom_tree(JsonObject const& dom_tree)
|
|||
}
|
||||
|
||||
if (name.equals_ignoring_ascii_case("BODY"sv))
|
||||
m_body_node_id = node.get_integer<i32>("id"sv).value();
|
||||
m_body_node_id = node_id;
|
||||
|
||||
auto tag = name.to_lowercase();
|
||||
|
||||
|
@ -523,14 +535,17 @@ String InspectorClient::generate_dom_tree(JsonObject const& dom_tree)
|
|||
|
||||
if (auto attributes = node.get_object("attributes"sv); attributes.has_value()) {
|
||||
attributes->for_each_member([&](auto const& name, auto const& value) {
|
||||
auto& dom_node_attributes = m_dom_node_attributes.ensure(node_id);
|
||||
auto value_string = value.as_string();
|
||||
|
||||
builder.append(" "sv);
|
||||
builder.appendff("<span data-node-type=\"attribute\" data-tag=\"{}\" data-attribute-name=\"{}\" data-attribute-value=\"{}\" class=\"editable\">", tag, name, value_string);
|
||||
builder.appendff("<span data-node-type=\"attribute\" data-tag=\"{}\" data-attribute-index={} class=\"editable\">", tag, dom_node_attributes.size());
|
||||
builder.appendff("<span class=\"attribute-name\">{}</span>", name);
|
||||
builder.append('=');
|
||||
builder.appendff("<span class=\"attribute-value\">\"{}\"</span>", value_string);
|
||||
builder.append("</span>"sv);
|
||||
|
||||
dom_node_attributes.empend(MUST(String::from_byte_string(name)), MUST(String::from_byte_string(value_string)));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue