mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 09:28:11 +00:00
Ladybird+LibWebView: Add an Inspector action to copy an attribute value
This commit is contained in:
parent
f7de1369d2
commit
51a0673b5c
7 changed files with 51 additions and 1 deletions
|
@ -23,6 +23,7 @@ static constexpr CGFloat const WINDOW_HEIGHT = 825;
|
||||||
|
|
||||||
static constexpr NSInteger CONTEXT_MENU_EDIT_NODE_TAG = 1;
|
static constexpr NSInteger CONTEXT_MENU_EDIT_NODE_TAG = 1;
|
||||||
static constexpr NSInteger CONTEXT_MENU_REMOVE_ATTRIBUTE_TAG = 2;
|
static constexpr NSInteger CONTEXT_MENU_REMOVE_ATTRIBUTE_TAG = 2;
|
||||||
|
static constexpr NSInteger CONTEXT_MENU_COPY_ATTRIBUTE_VALUE_TAG = 3;
|
||||||
|
|
||||||
@interface Inspector ()
|
@interface Inspector ()
|
||||||
{
|
{
|
||||||
|
@ -98,8 +99,13 @@ static constexpr NSInteger CONTEXT_MENU_REMOVE_ATTRIBUTE_TAG = 2;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static constexpr size_t MAX_ATTRIBUTE_VALUE_LENGTH = 32;
|
||||||
|
|
||||||
auto edit_attribute_text = MUST(String::formatted("Edit attribute \"{}\"", attribute.name));
|
auto edit_attribute_text = MUST(String::formatted("Edit attribute \"{}\"", attribute.name));
|
||||||
auto remove_attribute_text = MUST(String::formatted("Remove attribute \"{}\"", attribute.name));
|
auto remove_attribute_text = MUST(String::formatted("Remove attribute \"{}\"", attribute.name));
|
||||||
|
auto copy_attribute_value_text = MUST(String::formatted("Copy attribute value \"{:.{}}{}\"",
|
||||||
|
attribute.value, MAX_ATTRIBUTE_VALUE_LENGTH,
|
||||||
|
attribute.value.bytes_as_string_view().length() > MAX_ATTRIBUTE_VALUE_LENGTH ? "..."sv : ""sv));
|
||||||
|
|
||||||
auto* edit_node_menu_item = [strong_self.dom_node_attribute_context_menu itemWithTag:CONTEXT_MENU_EDIT_NODE_TAG];
|
auto* edit_node_menu_item = [strong_self.dom_node_attribute_context_menu itemWithTag:CONTEXT_MENU_EDIT_NODE_TAG];
|
||||||
[edit_node_menu_item setTitle:Ladybird::string_to_ns_string(edit_attribute_text)];
|
[edit_node_menu_item setTitle:Ladybird::string_to_ns_string(edit_attribute_text)];
|
||||||
|
@ -107,6 +113,9 @@ static constexpr NSInteger CONTEXT_MENU_REMOVE_ATTRIBUTE_TAG = 2;
|
||||||
auto* remove_attribute_menu_item = [strong_self.dom_node_attribute_context_menu itemWithTag:CONTEXT_MENU_REMOVE_ATTRIBUTE_TAG];
|
auto* remove_attribute_menu_item = [strong_self.dom_node_attribute_context_menu itemWithTag:CONTEXT_MENU_REMOVE_ATTRIBUTE_TAG];
|
||||||
[remove_attribute_menu_item setTitle:Ladybird::string_to_ns_string(remove_attribute_text)];
|
[remove_attribute_menu_item setTitle:Ladybird::string_to_ns_string(remove_attribute_text)];
|
||||||
|
|
||||||
|
auto* copy_attribute_value_menu_item = [strong_self.dom_node_attribute_context_menu itemWithTag:CONTEXT_MENU_COPY_ATTRIBUTE_VALUE_TAG];
|
||||||
|
[copy_attribute_value_menu_item setTitle:Ladybird::string_to_ns_string(copy_attribute_value_text)];
|
||||||
|
|
||||||
auto* event = Ladybird::create_context_menu_mouse_event(strong_self.web_view, position);
|
auto* event = Ladybird::create_context_menu_mouse_event(strong_self.web_view, position);
|
||||||
[NSMenu popUpContextMenu:strong_self.dom_node_attribute_context_menu withEvent:event forView:strong_self.web_view];
|
[NSMenu popUpContextMenu:strong_self.dom_node_attribute_context_menu withEvent:event forView:strong_self.web_view];
|
||||||
};
|
};
|
||||||
|
@ -172,6 +181,11 @@ static constexpr NSInteger CONTEXT_MENU_REMOVE_ATTRIBUTE_TAG = 2;
|
||||||
m_inspector_client->context_menu_remove_dom_node_attribute();
|
m_inspector_client->context_menu_remove_dom_node_attribute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)copyDOMAttributeValue:(id)sender
|
||||||
|
{
|
||||||
|
m_inspector_client->context_menu_copy_dom_node_attribute_value();
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - Properties
|
#pragma mark - Properties
|
||||||
|
|
||||||
- (NSMenu*)dom_node_text_context_menu
|
- (NSMenu*)dom_node_text_context_menu
|
||||||
|
@ -234,6 +248,12 @@ static constexpr NSInteger CONTEXT_MENU_REMOVE_ATTRIBUTE_TAG = 2;
|
||||||
[remove_attribute_menu_item setTag:CONTEXT_MENU_REMOVE_ATTRIBUTE_TAG];
|
[remove_attribute_menu_item setTag:CONTEXT_MENU_REMOVE_ATTRIBUTE_TAG];
|
||||||
[_dom_node_attribute_context_menu addItem:remove_attribute_menu_item];
|
[_dom_node_attribute_context_menu addItem:remove_attribute_menu_item];
|
||||||
|
|
||||||
|
auto* copy_attribute_value_menu_item = [[NSMenuItem alloc] initWithTitle:@"Copy attribute value"
|
||||||
|
action:@selector(copyDOMAttributeValue:)
|
||||||
|
keyEquivalent:@""];
|
||||||
|
[copy_attribute_value_menu_item setTag:CONTEXT_MENU_COPY_ATTRIBUTE_VALUE_TAG];
|
||||||
|
[_dom_node_attribute_context_menu addItem:copy_attribute_value_menu_item];
|
||||||
|
|
||||||
[_dom_node_attribute_context_menu addItem:[NSMenuItem separatorItem]];
|
[_dom_node_attribute_context_menu addItem:[NSMenuItem separatorItem]];
|
||||||
|
|
||||||
[_dom_node_attribute_context_menu addItem:[[NSMenuItem alloc] initWithTitle:@"Add attribute"
|
[_dom_node_attribute_context_menu addItem:[[NSMenuItem alloc] initWithTitle:@"Add attribute"
|
||||||
|
|
|
@ -39,6 +39,9 @@ InspectorWidget::InspectorWidget(QWidget* tab, WebContentView& content_view)
|
||||||
m_remove_attribute_action = new QAction("&Remove attribute", this);
|
m_remove_attribute_action = new QAction("&Remove attribute", this);
|
||||||
connect(m_remove_attribute_action, &QAction::triggered, [this]() { m_inspector_client->context_menu_remove_dom_node_attribute(); });
|
connect(m_remove_attribute_action, &QAction::triggered, [this]() { m_inspector_client->context_menu_remove_dom_node_attribute(); });
|
||||||
|
|
||||||
|
m_copy_attribute_value_action = new QAction("Copy attribute &value", this);
|
||||||
|
connect(m_copy_attribute_value_action, &QAction::triggered, [this]() { m_inspector_client->context_menu_copy_dom_node_attribute_value(); });
|
||||||
|
|
||||||
m_dom_node_text_context_menu = new QMenu("DOM text context menu", this);
|
m_dom_node_text_context_menu = new QMenu("DOM text context menu", this);
|
||||||
m_dom_node_text_context_menu->addAction(m_edit_node_action);
|
m_dom_node_text_context_menu->addAction(m_edit_node_action);
|
||||||
m_dom_node_text_context_menu->addSeparator();
|
m_dom_node_text_context_menu->addSeparator();
|
||||||
|
@ -52,6 +55,7 @@ InspectorWidget::InspectorWidget(QWidget* tab, WebContentView& content_view)
|
||||||
|
|
||||||
m_dom_node_attribute_context_menu = new QMenu("DOM attribute context menu", this);
|
m_dom_node_attribute_context_menu = new QMenu("DOM attribute context menu", this);
|
||||||
m_dom_node_attribute_context_menu->addAction(m_edit_node_action);
|
m_dom_node_attribute_context_menu->addAction(m_edit_node_action);
|
||||||
|
m_dom_node_attribute_context_menu->addAction(m_copy_attribute_value_action);
|
||||||
m_dom_node_attribute_context_menu->addAction(m_remove_attribute_action);
|
m_dom_node_attribute_context_menu->addAction(m_remove_attribute_action);
|
||||||
m_dom_node_attribute_context_menu->addSeparator();
|
m_dom_node_attribute_context_menu->addSeparator();
|
||||||
m_dom_node_attribute_context_menu->addAction(m_add_attribute_action);
|
m_dom_node_attribute_context_menu->addAction(m_add_attribute_action);
|
||||||
|
@ -69,9 +73,14 @@ InspectorWidget::InspectorWidget(QWidget* tab, WebContentView& content_view)
|
||||||
m_dom_node_tag_context_menu->exec(to_widget_position(position));
|
m_dom_node_tag_context_menu->exec(to_widget_position(position));
|
||||||
};
|
};
|
||||||
|
|
||||||
m_inspector_client->on_requested_dom_node_attribute_context_menu = [this](auto position, auto const&, auto const& attribute) {
|
m_inspector_client->on_requested_dom_node_attribute_context_menu = [this](auto position, auto const&, WebView::Attribute const& attribute) {
|
||||||
|
static constexpr size_t MAX_ATTRIBUTE_VALUE_LENGTH = 32;
|
||||||
|
|
||||||
m_edit_node_action->setText(qstring_from_ak_string(MUST(String::formatted("&Edit attribute \"{}\"", attribute.name))));
|
m_edit_node_action->setText(qstring_from_ak_string(MUST(String::formatted("&Edit attribute \"{}\"", attribute.name))));
|
||||||
m_remove_attribute_action->setText(qstring_from_ak_string(MUST(String::formatted("&Remove attribute \"{}\"", attribute.name))));
|
m_remove_attribute_action->setText(qstring_from_ak_string(MUST(String::formatted("&Remove attribute \"{}\"", attribute.name))));
|
||||||
|
m_copy_attribute_value_action->setText(qstring_from_ak_string(MUST(String::formatted("Copy attribute &value \"{:.{}}{}\"",
|
||||||
|
attribute.value, MAX_ATTRIBUTE_VALUE_LENGTH,
|
||||||
|
attribute.value.bytes_as_string_view().length() > MAX_ATTRIBUTE_VALUE_LENGTH ? "..."sv : ""sv))));
|
||||||
|
|
||||||
m_dom_node_attribute_context_menu->exec(to_widget_position(position));
|
m_dom_node_attribute_context_menu->exec(to_widget_position(position));
|
||||||
};
|
};
|
||||||
|
|
|
@ -47,6 +47,7 @@ private:
|
||||||
QAction* m_delete_node_action { nullptr };
|
QAction* m_delete_node_action { nullptr };
|
||||||
QAction* m_add_attribute_action { nullptr };
|
QAction* m_add_attribute_action { nullptr };
|
||||||
QAction* m_remove_attribute_action { nullptr };
|
QAction* m_remove_attribute_action { nullptr };
|
||||||
|
QAction* m_copy_attribute_value_action { nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ InspectorWidget::InspectorWidget(WebView::OutOfProcessWebView& content_view)
|
||||||
m_delete_node_action = GUI::Action::create("&Delete node"sv, [this](auto&) { m_inspector_client->context_menu_remove_dom_node(); });
|
m_delete_node_action = GUI::Action::create("&Delete node"sv, [this](auto&) { m_inspector_client->context_menu_remove_dom_node(); });
|
||||||
m_add_attribute_action = GUI::Action::create("&Add attribute"sv, [this](auto&) { m_inspector_client->context_menu_add_dom_node_attribute(); });
|
m_add_attribute_action = GUI::Action::create("&Add attribute"sv, [this](auto&) { m_inspector_client->context_menu_add_dom_node_attribute(); });
|
||||||
m_remove_attribute_action = GUI::Action::create("&Remove attribute"sv, [this](auto&) { m_inspector_client->context_menu_remove_dom_node_attribute(); });
|
m_remove_attribute_action = GUI::Action::create("&Remove attribute"sv, [this](auto&) { m_inspector_client->context_menu_remove_dom_node_attribute(); });
|
||||||
|
m_copy_attribute_value_action = GUI::Action::create("Copy attribute &value"sv, [this](auto&) { m_inspector_client->context_menu_copy_dom_node_attribute_value(); });
|
||||||
|
|
||||||
m_dom_node_text_context_menu = GUI::Menu::construct();
|
m_dom_node_text_context_menu = GUI::Menu::construct();
|
||||||
m_dom_node_text_context_menu->add_action(*m_edit_node_action);
|
m_dom_node_text_context_menu->add_action(*m_edit_node_action);
|
||||||
|
@ -47,6 +48,7 @@ InspectorWidget::InspectorWidget(WebView::OutOfProcessWebView& content_view)
|
||||||
|
|
||||||
m_dom_node_attribute_context_menu = GUI::Menu::construct();
|
m_dom_node_attribute_context_menu = GUI::Menu::construct();
|
||||||
m_dom_node_attribute_context_menu->add_action(*m_edit_node_action);
|
m_dom_node_attribute_context_menu->add_action(*m_edit_node_action);
|
||||||
|
m_dom_node_attribute_context_menu->add_action(*m_copy_attribute_value_action);
|
||||||
m_dom_node_attribute_context_menu->add_action(*m_remove_attribute_action);
|
m_dom_node_attribute_context_menu->add_action(*m_remove_attribute_action);
|
||||||
m_dom_node_attribute_context_menu->add_separator();
|
m_dom_node_attribute_context_menu->add_separator();
|
||||||
m_dom_node_attribute_context_menu->add_action(*m_add_attribute_action);
|
m_dom_node_attribute_context_menu->add_action(*m_add_attribute_action);
|
||||||
|
@ -65,8 +67,13 @@ InspectorWidget::InspectorWidget(WebView::OutOfProcessWebView& content_view)
|
||||||
};
|
};
|
||||||
|
|
||||||
m_inspector_client->on_requested_dom_node_attribute_context_menu = [this](auto position, auto const&, auto const& attribute) {
|
m_inspector_client->on_requested_dom_node_attribute_context_menu = [this](auto position, auto const&, auto const& attribute) {
|
||||||
|
static constexpr size_t MAX_ATTRIBUTE_VALUE_LENGTH = 32;
|
||||||
|
|
||||||
m_edit_node_action->set_text(DeprecatedString::formatted("&Edit attribute \"{}\"", attribute.name));
|
m_edit_node_action->set_text(DeprecatedString::formatted("&Edit attribute \"{}\"", attribute.name));
|
||||||
m_remove_attribute_action->set_text(DeprecatedString::formatted("&Remove attribute \"{}\"", attribute.name));
|
m_remove_attribute_action->set_text(DeprecatedString::formatted("&Remove attribute \"{}\"", attribute.name));
|
||||||
|
m_copy_attribute_value_action->set_text(DeprecatedString::formatted("Copy attribute &value \"{:.{}}{}\"",
|
||||||
|
attribute.value, MAX_ATTRIBUTE_VALUE_LENGTH,
|
||||||
|
attribute.value.bytes_as_string_view().length() > MAX_ATTRIBUTE_VALUE_LENGTH ? "..."sv : ""sv));
|
||||||
|
|
||||||
m_dom_node_attribute_context_menu->popup(to_widget_position(position));
|
m_dom_node_attribute_context_menu->popup(to_widget_position(position));
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,6 +43,7 @@ private:
|
||||||
RefPtr<GUI::Action> m_delete_node_action;
|
RefPtr<GUI::Action> m_delete_node_action;
|
||||||
RefPtr<GUI::Action> m_add_attribute_action;
|
RefPtr<GUI::Action> m_add_attribute_action;
|
||||||
RefPtr<GUI::Action> m_remove_attribute_action;
|
RefPtr<GUI::Action> m_remove_attribute_action;
|
||||||
|
RefPtr<GUI::Action> m_copy_attribute_value_action;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -268,6 +268,17 @@ void InspectorClient::context_menu_remove_dom_node_attribute()
|
||||||
m_context_menu_data.clear();
|
m_context_menu_data.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InspectorClient::context_menu_copy_dom_node_attribute_value()
|
||||||
|
{
|
||||||
|
VERIFY(m_context_menu_data.has_value());
|
||||||
|
VERIFY(m_context_menu_data->attribute.has_value());
|
||||||
|
|
||||||
|
if (m_content_web_view.on_insert_clipboard_entry)
|
||||||
|
m_content_web_view.on_insert_clipboard_entry(m_context_menu_data->attribute->value, "unspecified"_string, "text/plain"_string);
|
||||||
|
|
||||||
|
m_context_menu_data.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void InspectorClient::load_inspector()
|
void InspectorClient::load_inspector()
|
||||||
{
|
{
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
|
|
|
@ -30,6 +30,7 @@ public:
|
||||||
void context_menu_remove_dom_node();
|
void context_menu_remove_dom_node();
|
||||||
void context_menu_add_dom_node_attribute();
|
void context_menu_add_dom_node_attribute();
|
||||||
void context_menu_remove_dom_node_attribute();
|
void context_menu_remove_dom_node_attribute();
|
||||||
|
void context_menu_copy_dom_node_attribute_value();
|
||||||
|
|
||||||
Function<void(Gfx::IntPoint)> on_requested_dom_node_text_context_menu;
|
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_tag_context_menu;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue