LibWebView: Display layouting information in devtools

Specifically, you can now see whether an element is visible,
scrollable or creates a stacking context in the devtools.
This commit is contained in:
Psychpsyo 2024-11-19 18:19:04 +01:00
parent c47d19d05a
commit ff2b49235d
2 changed files with 57 additions and 26 deletions

View file

@ -1409,6 +1409,18 @@ void Node::serialize_tree_as_json(JsonObjectSerializer<StringBuilder>& object) c
MUST(children.finish()); MUST(children.finish());
} }
} }
if (paintable_box()) {
if (paintable_box()->is_scrollable()) {
MUST(object.add("scrollable"sv, true));
}
if (!paintable_box()->is_visible()) {
MUST(object.add("invisible"sv, true));
}
if (paintable_box()->has_stacking_context()) {
MUST(object.add("stackingContext"sv, true));
}
}
} else if (is_text()) { } else if (is_text()) {
MUST(object.add("type"sv, "text")); MUST(object.add("type"sv, "text"));

View file

@ -629,36 +629,55 @@ String InspectorClient::generate_dom_tree(JsonObject const& dom_tree)
if (type != "element"sv) { if (type != "element"sv) {
builder.appendff("<span class=\"hoverable internal\" {}>", data_attributes.string_view()); builder.appendff("<span class=\"hoverable internal\" {}>", data_attributes.string_view());
builder.appendff(name); builder.appendff(name);
builder.append("</span>"sv); } else {
return; if (name.equals_ignoring_ascii_case("BODY"sv) || name.equals_ignoring_ascii_case("FRAMESET"sv))
m_body_or_frameset_node_id = node_id;
auto tag = name.to_lowercase();
builder.appendff("<span class=\"hoverable\" {}>", data_attributes.string_view());
builder.append("<span>&lt;</span>"sv);
builder.appendff("<span data-node-type=\"tag\" data-tag=\"{0}\" class=\"editable tag\">{0}</span>", tag);
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("&nbsp;"sv);
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>", escape_html_entities(name));
builder.append('=');
builder.appendff("<span class=\"attribute-value\">\"{}\"</span>", escape_html_entities(value_string));
builder.append("</span>"sv);
dom_node_attributes.empend(MUST(String::from_byte_string(name)), MUST(String::from_byte_string(value_string)));
});
}
builder.append("<span>&gt;</span>"sv);
} }
if (name.equals_ignoring_ascii_case("BODY"sv) || name.equals_ignoring_ascii_case("FRAMESET"sv)) // display miscellaneous extra bits of info about the element
m_body_or_frameset_node_id = node_id; Vector<String> extra;
if (node.get_bool("scrollable"sv).value_or(false)) {
auto tag = name.to_lowercase(); extra.append("scrollable"_string);
}
builder.appendff("<span class=\"hoverable\" {}>", data_attributes.string_view()); if (node.get_bool("invisible"sv).value_or(false)) {
builder.append("<span>&lt;</span>"sv); extra.append("invisible"_string);
builder.appendff("<span data-node-type=\"tag\" data-tag=\"{0}\" class=\"editable tag\">{0}</span>", tag); }
if (node.get_bool("stackingContext"sv).value_or(false)) {
if (auto attributes = node.get_object("attributes"sv); attributes.has_value()) { extra.append("stacking context"_string);
attributes->for_each_member([&](auto const& name, auto const& value) { }
auto& dom_node_attributes = m_dom_node_attributes.ensure(node_id); if (!extra.is_empty()) {
auto value_string = value.as_string(); builder.append(" <span>("sv);
builder.append(extra[0]);
builder.append("&nbsp;"sv); for (size_t i = 1; i < extra.size(); i++) {
builder.appendff("<span data-node-type=\"attribute\" data-tag=\"{}\" data-attribute-index={} class=\"editable\">", tag, dom_node_attributes.size()); builder.appendff(", {}", extra[i]);
builder.appendff("<span class=\"attribute-name\">{}</span>", escape_html_entities(name)); }
builder.append('='); builder.append(")</span>"sv);
builder.appendff("<span class=\"attribute-value\">\"{}\"</span>", escape_html_entities(value_string));
builder.append("</span>"sv);
dom_node_attributes.empend(MUST(String::from_byte_string(name)), MUST(String::from_byte_string(value_string)));
});
} }
builder.append("<span>&gt;</span>"sv);
builder.append("</span>"sv); builder.append("</span>"sv);
}); });