mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 18:27:42 +00:00
Browser+LibWeb+WebContent: Add variables display to Inspector
This allows us to see which custom properties apply to a given element, which previously wasn't shown.
This commit is contained in:
parent
53df13fed7
commit
54bbb97ac6
12 changed files with 65 additions and 24 deletions
|
@ -50,7 +50,7 @@ void InspectorWidget::set_inspected_node(GUI::ModelIndex const index)
|
||||||
auto maybe_inspected_node_properties = m_web_view->inspect_dom_node(m_inspected_node_id);
|
auto maybe_inspected_node_properties = m_web_view->inspect_dom_node(m_inspected_node_id);
|
||||||
if (maybe_inspected_node_properties.has_value()) {
|
if (maybe_inspected_node_properties.has_value()) {
|
||||||
auto inspected_node_properties = maybe_inspected_node_properties.value();
|
auto inspected_node_properties = maybe_inspected_node_properties.value();
|
||||||
load_style_json(inspected_node_properties.specified_values_json, inspected_node_properties.computed_values_json);
|
load_style_json(inspected_node_properties.specified_values_json, inspected_node_properties.computed_values_json, inspected_node_properties.custom_properties_json);
|
||||||
} else {
|
} else {
|
||||||
clear_style_json();
|
clear_style_json();
|
||||||
}
|
}
|
||||||
|
@ -87,6 +87,11 @@ InspectorWidget::InspectorWidget()
|
||||||
computed_style_table_container.layout()->set_margins({ 4, 4, 4, 4 });
|
computed_style_table_container.layout()->set_margins({ 4, 4, 4, 4 });
|
||||||
m_computed_style_table_view = computed_style_table_container.add<GUI::TableView>();
|
m_computed_style_table_view = computed_style_table_container.add<GUI::TableView>();
|
||||||
|
|
||||||
|
auto& custom_properties_table_container = bottom_tab_widget.add_tab<GUI::Widget>("Variables");
|
||||||
|
custom_properties_table_container.set_layout<GUI::VerticalBoxLayout>();
|
||||||
|
custom_properties_table_container.layout()->set_margins({ 4, 4, 4, 4 });
|
||||||
|
m_custom_properties_table_view = custom_properties_table_container.add<GUI::TableView>();
|
||||||
|
|
||||||
m_dom_tree_view->set_focus(true);
|
m_dom_tree_view->set_focus(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,30 +132,38 @@ void InspectorWidget::clear_dom_json()
|
||||||
clear_style_json();
|
clear_style_json();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InspectorWidget::set_dom_node_properties_json(i32 node_id, String specified_values_json, String computed_values_json)
|
void InspectorWidget::set_dom_node_properties_json(i32 node_id, String specified_values_json, String computed_values_json, String custom_properties_json)
|
||||||
{
|
{
|
||||||
if (node_id != m_inspected_node_id) {
|
if (node_id != m_inspected_node_id) {
|
||||||
dbgln("Got data for the wrong node id! Wanted {}, got {}", m_inspected_node_id, node_id);
|
dbgln("Got data for the wrong node id! Wanted {}, got {}", m_inspected_node_id, node_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
load_style_json(specified_values_json, computed_values_json);
|
load_style_json(specified_values_json, computed_values_json, custom_properties_json);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InspectorWidget::load_style_json(String specified_values_json, String computed_values_json)
|
void InspectorWidget::load_style_json(String specified_values_json, String computed_values_json, String custom_properties_json)
|
||||||
{
|
{
|
||||||
m_inspected_node_specified_values_json = specified_values_json;
|
m_inspected_node_specified_values_json = specified_values_json;
|
||||||
m_inspected_node_computed_values_json = computed_values_json;
|
|
||||||
m_style_table_view->set_model(Web::StylePropertiesModel::create(m_inspected_node_specified_values_json.value().view()));
|
m_style_table_view->set_model(Web::StylePropertiesModel::create(m_inspected_node_specified_values_json.value().view()));
|
||||||
|
|
||||||
|
m_inspected_node_computed_values_json = computed_values_json;
|
||||||
m_computed_style_table_view->set_model(Web::StylePropertiesModel::create(m_inspected_node_computed_values_json.value().view()));
|
m_computed_style_table_view->set_model(Web::StylePropertiesModel::create(m_inspected_node_computed_values_json.value().view()));
|
||||||
|
|
||||||
|
m_inspected_node_custom_properties_json = custom_properties_json;
|
||||||
|
m_custom_properties_table_view->set_model(Web::StylePropertiesModel::create(m_inspected_node_custom_properties_json.value().view()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InspectorWidget::clear_style_json()
|
void InspectorWidget::clear_style_json()
|
||||||
{
|
{
|
||||||
m_inspected_node_specified_values_json.clear();
|
m_inspected_node_specified_values_json.clear();
|
||||||
m_inspected_node_computed_values_json.clear();
|
|
||||||
m_style_table_view->set_model(nullptr);
|
m_style_table_view->set_model(nullptr);
|
||||||
|
|
||||||
|
m_inspected_node_computed_values_json.clear();
|
||||||
m_computed_style_table_view->set_model(nullptr);
|
m_computed_style_table_view->set_model(nullptr);
|
||||||
|
|
||||||
|
m_inspected_node_custom_properties_json.clear();
|
||||||
|
m_custom_properties_table_view->set_model(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ public:
|
||||||
void set_web_view(NonnullRefPtr<Web::OutOfProcessWebView> web_view) { m_web_view = web_view; }
|
void set_web_view(NonnullRefPtr<Web::OutOfProcessWebView> web_view) { m_web_view = web_view; }
|
||||||
void set_dom_json(String);
|
void set_dom_json(String);
|
||||||
void clear_dom_json();
|
void clear_dom_json();
|
||||||
void set_dom_node_properties_json(i32 node_id, String specified_values_json, String computed_values_json);
|
void set_dom_node_properties_json(i32 node_id, String specified_values_json, String computed_values_json, String custom_properties_json);
|
||||||
|
|
||||||
void set_inspected_node(i32 node_id);
|
void set_inspected_node(i32 node_id);
|
||||||
void select_default_node();
|
void select_default_node();
|
||||||
|
@ -29,7 +29,7 @@ private:
|
||||||
InspectorWidget();
|
InspectorWidget();
|
||||||
|
|
||||||
void set_inspected_node(GUI::ModelIndex);
|
void set_inspected_node(GUI::ModelIndex);
|
||||||
void load_style_json(String specified_values_json, String computed_values_json);
|
void load_style_json(String specified_values_json, String computed_values_json, String custom_properties_json);
|
||||||
void clear_style_json();
|
void clear_style_json();
|
||||||
|
|
||||||
RefPtr<Web::OutOfProcessWebView> m_web_view;
|
RefPtr<Web::OutOfProcessWebView> m_web_view;
|
||||||
|
@ -37,6 +37,7 @@ private:
|
||||||
RefPtr<GUI::TreeView> m_dom_tree_view;
|
RefPtr<GUI::TreeView> m_dom_tree_view;
|
||||||
RefPtr<GUI::TableView> m_style_table_view;
|
RefPtr<GUI::TableView> m_style_table_view;
|
||||||
RefPtr<GUI::TableView> m_computed_style_table_view;
|
RefPtr<GUI::TableView> m_computed_style_table_view;
|
||||||
|
RefPtr<GUI::TableView> m_custom_properties_table_view;
|
||||||
|
|
||||||
// Multi-process mode
|
// Multi-process mode
|
||||||
Optional<i32> m_pending_inspect_node_id;
|
Optional<i32> m_pending_inspect_node_id;
|
||||||
|
@ -44,6 +45,7 @@ private:
|
||||||
Optional<String> m_dom_json;
|
Optional<String> m_dom_json;
|
||||||
Optional<String> m_inspected_node_specified_values_json;
|
Optional<String> m_inspected_node_specified_values_json;
|
||||||
Optional<String> m_inspected_node_computed_values_json;
|
Optional<String> m_inspected_node_computed_values_json;
|
||||||
|
Optional<String> m_inspected_node_custom_properties_json;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -291,8 +291,8 @@ Tab::Tab(BrowserWindow& window)
|
||||||
m_dom_inspector_widget->set_dom_json(dom_tree);
|
m_dom_inspector_widget->set_dom_json(dom_tree);
|
||||||
};
|
};
|
||||||
|
|
||||||
hooks().on_get_dom_node_properties = [this](auto node_id, auto& specified, auto& computed) {
|
hooks().on_get_dom_node_properties = [this](auto node_id, auto& specified, auto& computed, auto& custom_properties) {
|
||||||
m_dom_inspector_widget->set_dom_node_properties_json(node_id, specified, computed);
|
m_dom_inspector_widget->set_dom_node_properties_json(node_id, specified, computed, custom_properties);
|
||||||
};
|
};
|
||||||
|
|
||||||
hooks().on_js_console_new_message = [this](auto message_index) {
|
hooks().on_js_console_new_message = [this](auto message_index) {
|
||||||
|
|
|
@ -118,6 +118,7 @@ public:
|
||||||
{
|
{
|
||||||
m_custom_properties.set(custom_property_name, style_property);
|
m_custom_properties.set(custom_property_name, style_property);
|
||||||
}
|
}
|
||||||
|
HashMap<String, CSS::StyleComputer::CustomPropertyResolutionTuple> const& custom_properties() const { return m_custom_properties; }
|
||||||
|
|
||||||
void queue_an_element_task(HTML::Task::Source, Function<void()>);
|
void queue_an_element_task(HTML::Task::Source, Function<void()>);
|
||||||
|
|
||||||
|
|
|
@ -354,10 +354,10 @@ void OutOfProcessWebView::notify_server_did_get_dom_tree(const String& dom_tree)
|
||||||
on_get_dom_tree(dom_tree);
|
on_get_dom_tree(dom_tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutOfProcessWebView::notify_server_did_get_dom_node_properties(i32 node_id, String const& specified_style, String const& computed_style)
|
void OutOfProcessWebView::notify_server_did_get_dom_node_properties(i32 node_id, String const& specified_style, String const& computed_style, String const& custom_properties)
|
||||||
{
|
{
|
||||||
if (on_get_dom_node_properties)
|
if (on_get_dom_node_properties)
|
||||||
on_get_dom_node_properties(node_id, specified_style, computed_style);
|
on_get_dom_node_properties(node_id, specified_style, computed_style, custom_properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutOfProcessWebView::notify_server_did_output_js_console_message(i32 message_index)
|
void OutOfProcessWebView::notify_server_did_output_js_console_message(i32 message_index)
|
||||||
|
@ -440,7 +440,8 @@ Optional<OutOfProcessWebView::DOMNodeProperties> OutOfProcessWebView::inspect_do
|
||||||
return {};
|
return {};
|
||||||
return DOMNodeProperties {
|
return DOMNodeProperties {
|
||||||
.specified_values_json = response.specified_style(),
|
.specified_values_json = response.specified_style(),
|
||||||
.computed_values_json = response.computed_style()
|
.computed_values_json = response.computed_style(),
|
||||||
|
.custom_properties_json = response.custom_properties()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ public:
|
||||||
struct DOMNodeProperties {
|
struct DOMNodeProperties {
|
||||||
String specified_values_json;
|
String specified_values_json;
|
||||||
String computed_values_json;
|
String computed_values_json;
|
||||||
|
String custom_properties_json;
|
||||||
};
|
};
|
||||||
Optional<DOMNodeProperties> inspect_dom_node(i32 node_id);
|
Optional<DOMNodeProperties> inspect_dom_node(i32 node_id);
|
||||||
void clear_inspected_dom_node();
|
void clear_inspected_dom_node();
|
||||||
|
@ -80,7 +81,7 @@ public:
|
||||||
String notify_server_did_request_prompt(Badge<WebContentClient>, const String& message, const String& default_);
|
String notify_server_did_request_prompt(Badge<WebContentClient>, const String& message, const String& default_);
|
||||||
void notify_server_did_get_source(const AK::URL& url, const String& source);
|
void notify_server_did_get_source(const AK::URL& url, const String& source);
|
||||||
void notify_server_did_get_dom_tree(const String& dom_tree);
|
void notify_server_did_get_dom_tree(const String& dom_tree);
|
||||||
void notify_server_did_get_dom_node_properties(i32 node_id, String const& specified_style, String const& computed_style);
|
void notify_server_did_get_dom_node_properties(i32 node_id, String const& specified_style, String const& computed_style, String const& custom_properties);
|
||||||
void notify_server_did_output_js_console_message(i32 message_index);
|
void notify_server_did_output_js_console_message(i32 message_index);
|
||||||
void notify_server_did_get_js_console_messages(i32 start_index, Vector<String> const& message_types, Vector<String> const& messages);
|
void notify_server_did_get_js_console_messages(i32 start_index, Vector<String> const& message_types, Vector<String> const& messages);
|
||||||
void notify_server_did_change_favicon(const Gfx::Bitmap& favicon);
|
void notify_server_did_change_favicon(const Gfx::Bitmap& favicon);
|
||||||
|
|
|
@ -146,9 +146,9 @@ void WebContentClient::did_get_dom_tree(String const& dom_tree)
|
||||||
m_view.notify_server_did_get_dom_tree(dom_tree);
|
m_view.notify_server_did_get_dom_tree(dom_tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContentClient::did_get_dom_node_properties(i32 node_id, String const& specified_style, String const& computed_style)
|
void WebContentClient::did_get_dom_node_properties(i32 node_id, String const& specified_style, String const& computed_style, String const& custom_properties)
|
||||||
{
|
{
|
||||||
m_view.notify_server_did_get_dom_node_properties(node_id, specified_style, computed_style);
|
m_view.notify_server_did_get_dom_node_properties(node_id, specified_style, computed_style, custom_properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContentClient::did_output_js_console_message(i32 message_index)
|
void WebContentClient::did_output_js_console_message(i32 message_index)
|
||||||
|
|
|
@ -51,7 +51,7 @@ private:
|
||||||
virtual void did_request_image_context_menu(Gfx::IntPoint const&, AK::URL const&, String const&, unsigned, Gfx::ShareableBitmap const&) override;
|
virtual void did_request_image_context_menu(Gfx::IntPoint const&, AK::URL const&, String const&, unsigned, Gfx::ShareableBitmap const&) override;
|
||||||
virtual void did_get_source(AK::URL const&, String const&) override;
|
virtual void did_get_source(AK::URL const&, String const&) override;
|
||||||
virtual void did_get_dom_tree(String const&) override;
|
virtual void did_get_dom_tree(String const&) override;
|
||||||
virtual void did_get_dom_node_properties(i32 node_id, String const& specified_style, String const& computed_style) override;
|
virtual void did_get_dom_node_properties(i32 node_id, String const& specified_style, String const& computed_style, String const& custom_properties) override;
|
||||||
virtual void did_output_js_console_message(i32 message_index) override;
|
virtual void did_output_js_console_message(i32 message_index) override;
|
||||||
virtual void did_get_js_console_messages(i32 start_index, Vector<String> const& message_types, Vector<String> const& messages) override;
|
virtual void did_get_js_console_messages(i32 start_index, Vector<String> const& message_types, Vector<String> const& messages) override;
|
||||||
virtual void did_change_favicon(Gfx::ShareableBitmap const&) override;
|
virtual void did_change_favicon(Gfx::ShareableBitmap const&) override;
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
Function<void(DOM::Document*)> on_set_document;
|
Function<void(DOM::Document*)> on_set_document;
|
||||||
Function<void(const AK::URL&, const String&)> on_get_source;
|
Function<void(const AK::URL&, const String&)> on_get_source;
|
||||||
Function<void(const String&)> on_get_dom_tree;
|
Function<void(const String&)> on_get_dom_tree;
|
||||||
Function<void(i32 node_id, String const& specified_style, String const& computed_style)> on_get_dom_node_properties;
|
Function<void(i32 node_id, String const& specified_style, String const& computed_style, String const& custom_properties)> on_get_dom_node_properties;
|
||||||
Function<void(i32 message_id)> on_js_console_new_message;
|
Function<void(i32 message_id)> on_js_console_new_message;
|
||||||
Function<void(i32 start_index, Vector<String> const& message_types, Vector<String> const& messages)> on_get_js_console_messages;
|
Function<void(i32 start_index, Vector<String> const& message_types, Vector<String> const& messages)> on_get_js_console_messages;
|
||||||
Function<String(const AK::URL& url, Cookie::Source source)> on_get_cookie;
|
Function<String(const AK::URL& url, Cookie::Source source)> on_get_cookie;
|
||||||
|
|
|
@ -241,7 +241,7 @@ Messages::WebContentServer::InspectDomNodeResponse ClientConnection::inspect_dom
|
||||||
|
|
||||||
Web::DOM::Node* node = Web::DOM::Node::from_id(node_id);
|
Web::DOM::Node* node = Web::DOM::Node::from_id(node_id);
|
||||||
if (!node) {
|
if (!node) {
|
||||||
return { false, "", "" };
|
return { false, "", "", "" };
|
||||||
}
|
}
|
||||||
|
|
||||||
node->document().set_inspected_node(node);
|
node->document().set_inspected_node(node);
|
||||||
|
@ -249,7 +249,7 @@ Messages::WebContentServer::InspectDomNodeResponse ClientConnection::inspect_dom
|
||||||
if (node->is_element()) {
|
if (node->is_element()) {
|
||||||
auto& element = verify_cast<Web::DOM::Element>(*node);
|
auto& element = verify_cast<Web::DOM::Element>(*node);
|
||||||
if (!element.specified_css_values())
|
if (!element.specified_css_values())
|
||||||
return { false, "", "" };
|
return { false, "", "", "" };
|
||||||
|
|
||||||
auto serialize_json = [](Web::CSS::StyleProperties const& properties) -> String {
|
auto serialize_json = [](Web::CSS::StyleProperties const& properties) -> String {
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
|
@ -263,12 +263,35 @@ Messages::WebContentServer::InspectDomNodeResponse ClientConnection::inspect_dom
|
||||||
return builder.to_string();
|
return builder.to_string();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto serialize_custom_properties_json = [](Web::DOM::Element const& element) -> String {
|
||||||
|
StringBuilder builder;
|
||||||
|
JsonObjectSerializer serializer(builder);
|
||||||
|
HashTable<String> seen_properties;
|
||||||
|
|
||||||
|
auto const* element_to_check = &element;
|
||||||
|
while (element_to_check) {
|
||||||
|
for (auto const& property : element_to_check->custom_properties()) {
|
||||||
|
if (!seen_properties.contains(property.key) && property.value.style.has_value()) {
|
||||||
|
seen_properties.set(property.key);
|
||||||
|
serializer.add(property.key, property.value.style.value().value->to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
element_to_check = element_to_check->parent_element();
|
||||||
|
}
|
||||||
|
|
||||||
|
serializer.finish();
|
||||||
|
|
||||||
|
return builder.to_string();
|
||||||
|
};
|
||||||
|
|
||||||
String specified_values_json = serialize_json(*element.specified_css_values());
|
String specified_values_json = serialize_json(*element.specified_css_values());
|
||||||
String computed_values_json = serialize_json(element.computed_style());
|
String computed_values_json = serialize_json(element.computed_style());
|
||||||
return { true, specified_values_json, computed_values_json };
|
String custom_properties_json = serialize_custom_properties_json(element);
|
||||||
|
return { true, specified_values_json, computed_values_json, custom_properties_json };
|
||||||
}
|
}
|
||||||
|
|
||||||
return { false, "", "" };
|
return { false, "", "", "" };
|
||||||
}
|
}
|
||||||
|
|
||||||
Messages::WebContentServer::GetHoveredNodeIdResponse ClientConnection::get_hovered_node_id()
|
Messages::WebContentServer::GetHoveredNodeIdResponse ClientConnection::get_hovered_node_id()
|
||||||
|
|
|
@ -29,7 +29,7 @@ endpoint WebContentClient
|
||||||
did_request_prompt(String message, String default_) => (String response)
|
did_request_prompt(String message, String default_) => (String response)
|
||||||
did_get_source(URL url, String source) =|
|
did_get_source(URL url, String source) =|
|
||||||
did_get_dom_tree(String dom_tree) =|
|
did_get_dom_tree(String dom_tree) =|
|
||||||
did_get_dom_node_properties(i32 node_id, String specified_style, String computed_style) =|
|
did_get_dom_node_properties(i32 node_id, String specified_style, String computed_style, String custom_properties) =|
|
||||||
did_change_favicon(Gfx::ShareableBitmap favicon) =|
|
did_change_favicon(Gfx::ShareableBitmap favicon) =|
|
||||||
did_request_cookie(URL url, u8 source) => (String cookie)
|
did_request_cookie(URL url, u8 source) => (String cookie)
|
||||||
did_set_cookie(URL url, Web::Cookie::ParsedCookie cookie, u8 source) =|
|
did_set_cookie(URL url, Web::Cookie::ParsedCookie cookie, u8 source) =|
|
||||||
|
|
|
@ -29,7 +29,7 @@ endpoint WebContentServer
|
||||||
debug_request(String request, String argument) =|
|
debug_request(String request, String argument) =|
|
||||||
get_source() =|
|
get_source() =|
|
||||||
inspect_dom_tree() =|
|
inspect_dom_tree() =|
|
||||||
inspect_dom_node(i32 node_id) => (bool has_style, String specified_style, String computed_style)
|
inspect_dom_node(i32 node_id) => (bool has_style, String specified_style, String computed_style, String custom_properties)
|
||||||
get_hovered_node_id() => (i32 node_id)
|
get_hovered_node_id() => (i32 node_id)
|
||||||
js_console_input(String js_source) =|
|
js_console_input(String js_source) =|
|
||||||
js_console_request_messages(i32 start_index) =|
|
js_console_request_messages(i32 start_index) =|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue