1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 15:07:45 +00:00

LibWeb+LibWebView+WebContent: Separate tag/attribute in Inspector menu

It was a bit short-sighted to combine the tag and attribute names into
one string when the Inspector requests a context menu. We will want both
values for some context menu actions. Send both names, as well as the
attribute value, when requesting the context menu.
This commit is contained in:
Timothy Flynn 2023-12-06 09:34:53 -05:00 committed by Andreas Kling
parent c9f0f0fc70
commit 8162dc5ee6
16 changed files with 80 additions and 58 deletions

View file

@ -81,23 +81,23 @@ 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_or_attribute_name) {
m_context_menu_dom_node_id = node_id;
m_context_menu_tag_or_attribute_name = tag_or_attribute_name;
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_context_menu_data = ContextMenuData { node_id, tag, attribute };
if (type.is_one_of("text"sv, "comment"sv)) {
if (on_requested_dom_node_text_context_menu)
on_requested_dom_node_text_context_menu(position);
} else if (type == "tag"sv) {
VERIFY(m_context_menu_tag_or_attribute_name.has_value());
VERIFY(tag.has_value());
if (on_requested_dom_node_tag_context_menu)
on_requested_dom_node_tag_context_menu(position, *m_context_menu_tag_or_attribute_name);
on_requested_dom_node_tag_context_menu(position, *tag);
} else if (type == "attribute"sv) {
VERIFY(m_context_menu_tag_or_attribute_name.has_value());
VERIFY(tag.has_value());
VERIFY(attribute.has_value());
if (on_requested_dom_node_attribute_context_menu)
on_requested_dom_node_attribute_context_menu(position, *m_context_menu_tag_or_attribute_name);
on_requested_dom_node_attribute_context_menu(position, *tag, *attribute);
}
};
@ -225,51 +225,47 @@ void InspectorClient::select_node(i32 node_id)
void InspectorClient::context_menu_edit_dom_node()
{
VERIFY(m_context_menu_dom_node_id.has_value());
VERIFY(m_context_menu_data.has_value());
auto script = MUST(String::formatted("inspector.editDOMNodeID({});", *m_context_menu_dom_node_id));
auto script = MUST(String::formatted("inspector.editDOMNodeID({});", m_context_menu_data->dom_node_id));
m_inspector_web_view.run_javascript(script);
m_context_menu_dom_node_id.clear();
m_context_menu_tag_or_attribute_name.clear();
m_context_menu_data.clear();
}
void InspectorClient::context_menu_remove_dom_node()
{
VERIFY(m_context_menu_dom_node_id.has_value());
VERIFY(m_context_menu_data.has_value());
m_content_web_view.remove_dom_node(*m_context_menu_dom_node_id);
m_content_web_view.remove_dom_node(m_context_menu_data->dom_node_id);
m_pending_selection = m_body_node_id;
inspect();
m_context_menu_dom_node_id.clear();
m_context_menu_tag_or_attribute_name.clear();
m_context_menu_data.clear();
}
void InspectorClient::context_menu_add_dom_node_attribute()
{
VERIFY(m_context_menu_dom_node_id.has_value());
VERIFY(m_context_menu_data.has_value());
auto script = MUST(String::formatted("inspector.addAttributeToDOMNodeID({});", *m_context_menu_dom_node_id));
auto script = MUST(String::formatted("inspector.addAttributeToDOMNodeID({});", m_context_menu_data->dom_node_id));
m_inspector_web_view.run_javascript(script);
m_context_menu_dom_node_id.clear();
m_context_menu_tag_or_attribute_name.clear();
m_context_menu_data.clear();
}
void InspectorClient::context_menu_remove_dom_node_attribute()
{
VERIFY(m_context_menu_dom_node_id.has_value());
VERIFY(m_context_menu_tag_or_attribute_name.has_value());
VERIFY(m_context_menu_data.has_value());
VERIFY(m_context_menu_data->attribute.has_value());
m_content_web_view.replace_dom_node_attribute(*m_context_menu_dom_node_id, *m_context_menu_tag_or_attribute_name, {});
m_content_web_view.replace_dom_node_attribute(m_context_menu_data->dom_node_id, m_context_menu_data->attribute->name, {});
m_pending_selection = m_context_menu_dom_node_id;
m_pending_selection = m_context_menu_data->dom_node_id;
inspect();
m_context_menu_dom_node_id.clear();
m_context_menu_tag_or_attribute_name.clear();
m_context_menu_data.clear();
}
void InspectorClient::load_inspector()
@ -465,14 +461,16 @@ 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();
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\" class=\"editable tag\">{}</span>", name.to_lowercase());
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([&builder](auto const& name, auto const& value) {
attributes->for_each_member([&](auto const& name, auto const& value) {
builder.append("&nbsp;"sv);
builder.appendff("<span data-node-type=\"attribute\" data-attribute-name=\"{}\" class=\"editable\">", name);
builder.appendff("<span data-node-type=\"attribute\" data-tag=\"{}\" data-attribute-name=\"{}\" data-attribute-value=\"{}\" class=\"editable\">", tag, name, value);
builder.appendff("<span class=\"attribute-name\">{}</span>", name);
builder.append('=');
builder.appendff("<span class=\"attribute-value\">\"{}\"</span>", value);

View file

@ -33,7 +33,7 @@ public:
Function<void(Gfx::IntPoint)> on_requested_dom_node_text_context_menu;
Function<void(Gfx::IntPoint, String const&)> on_requested_dom_node_tag_context_menu;
Function<void(Gfx::IntPoint, String const&)> on_requested_dom_node_attribute_context_menu;
Function<void(Gfx::IntPoint, String const&, Attribute const&)> on_requested_dom_node_attribute_context_menu;
private:
void load_inspector();
@ -61,8 +61,12 @@ private:
bool m_dom_tree_loaded { false };
Optional<i32> m_context_menu_dom_node_id;
Optional<String> m_context_menu_tag_or_attribute_name;
struct ContextMenuData {
i32 dom_node_id { 0 };
Optional<String> tag;
Optional<Attribute> attribute;
};
Optional<ContextMenuData> m_context_menu_data;
i32 m_highest_notified_message_index { -1 };
i32 m_highest_received_message_index { -1 };

View file

@ -159,7 +159,7 @@ public:
Function<void(i32, String const&)> on_inspector_set_dom_node_tag;
Function<void(i32, Vector<Attribute> const&)> on_inspector_added_dom_node_attributes;
Function<void(i32, String const&, Vector<Attribute> const&)> on_inspector_replaced_dom_node_attribute;
Function<void(i32, Gfx::IntPoint, String const&, Optional<String> const&)> on_inspector_requested_dom_tree_context_menu;
Function<void(i32, Gfx::IntPoint, String const&, Optional<String> const&, Optional<Attribute> const&)> on_inspector_requested_dom_tree_context_menu;
Function<void(String const&)> on_inspector_executed_console_script;
virtual Gfx::IntRect viewport_rect() const = 0;

View file

@ -438,10 +438,10 @@ void WebContentClient::inspector_did_replace_dom_node_attribute(i32 node_id, Str
m_view.on_inspector_replaced_dom_node_attribute(node_id, name, replacement_attributes);
}
void WebContentClient::inspector_did_request_dom_tree_context_menu(i32 node_id, Gfx::IntPoint position, String const& type, Optional<String> const& tag_or_attribute_name)
void WebContentClient::inspector_did_request_dom_tree_context_menu(i32 node_id, Gfx::IntPoint position, String const& type, Optional<String> const& tag, Optional<Attribute> const& attribute)
{
if (m_view.on_inspector_requested_dom_tree_context_menu)
m_view.on_inspector_requested_dom_tree_context_menu(node_id, m_view.to_widget_position(position), type, tag_or_attribute_name);
m_view.on_inspector_requested_dom_tree_context_menu(node_id, m_view.to_widget_position(position), type, tag, attribute);
}
void WebContentClient::inspector_did_execute_console_script(String const& script)

View file

@ -92,7 +92,7 @@ private:
virtual void inspector_did_set_dom_node_tag(i32 node_id, String const& tag) override;
virtual void inspector_did_add_dom_node_attributes(i32 node_id, Vector<Attribute> const& attributes) override;
virtual void inspector_did_replace_dom_node_attribute(i32 node_id, String const& name, Vector<Attribute> const& replacement_attributes) override;
virtual void inspector_did_request_dom_tree_context_menu(i32 node_id, Gfx::IntPoint position, String const& type, Optional<String> const& tag_or_attribute_name) override;
virtual void inspector_did_request_dom_tree_context_menu(i32 node_id, Gfx::IntPoint position, String const& type, Optional<String> const& tag, Optional<Attribute> const& attribute) override;
virtual void inspector_did_execute_console_script(String const& script) override;
ViewImplementation& m_view;