Ladybird+LibWebView: Add an Inspector action to insert a child DOM node

This commit is contained in:
Timothy Flynn 2023-12-07 11:05:34 -05:00 committed by Andreas Kling
parent c6a11a77b5
commit d5d6ff8bf1
Notes: sideshowbarker 2024-07-17 06:40:21 +09:00
7 changed files with 78 additions and 0 deletions

View file

@ -176,6 +176,16 @@ static constexpr NSInteger CONTEXT_MENU_COPY_ATTRIBUTE_VALUE_TAG = 3;
m_inspector_client->context_menu_screenshot_dom_node(); m_inspector_client->context_menu_screenshot_dom_node();
} }
- (void)createChildElement:(id)sender
{
m_inspector_client->context_menu_create_child_element();
}
- (void)createChildTextNode:(id)sender
{
m_inspector_client->context_menu_create_child_text_node();
}
- (void)deleteDOMNode:(id)sender - (void)deleteDOMNode:(id)sender
{ {
m_inspector_client->context_menu_remove_dom_node(); m_inspector_client->context_menu_remove_dom_node();
@ -198,6 +208,24 @@ static constexpr NSInteger CONTEXT_MENU_COPY_ATTRIBUTE_VALUE_TAG = 3;
#pragma mark - Properties #pragma mark - Properties
+ (NSMenuItem*)make_create_child_menu
{
auto* create_child_menu = [[NSMenu alloc] init];
[create_child_menu addItem:[[NSMenuItem alloc] initWithTitle:@"Create child element"
action:@selector(createChildElement:)
keyEquivalent:@""]];
[create_child_menu addItem:[[NSMenuItem alloc] initWithTitle:@"Create child text node"
action:@selector(createChildTextNode:)
keyEquivalent:@""]];
auto* create_child_menu_item = [[NSMenuItem alloc] initWithTitle:@"Create child"
action:nil
keyEquivalent:@""];
[create_child_menu_item setSubmenu:create_child_menu];
return create_child_menu_item;
}
- (NSMenu*)dom_node_text_context_menu - (NSMenu*)dom_node_text_context_menu
{ {
if (!_dom_node_text_context_menu) { if (!_dom_node_text_context_menu) {
@ -236,6 +264,7 @@ static constexpr NSInteger CONTEXT_MENU_COPY_ATTRIBUTE_VALUE_TAG = 3;
[_dom_node_tag_context_menu addItem:[[NSMenuItem alloc] initWithTitle:@"Add attribute" [_dom_node_tag_context_menu addItem:[[NSMenuItem alloc] initWithTitle:@"Add attribute"
action:@selector(addDOMAttribute:) action:@selector(addDOMAttribute:)
keyEquivalent:@""]]; keyEquivalent:@""]];
[_dom_node_tag_context_menu addItem:[Inspector make_create_child_menu]];
[_dom_node_tag_context_menu addItem:[[NSMenuItem alloc] initWithTitle:@"Delete node" [_dom_node_tag_context_menu addItem:[[NSMenuItem alloc] initWithTitle:@"Delete node"
action:@selector(deleteDOMNode:) action:@selector(deleteDOMNode:)
keyEquivalent:@""]]; keyEquivalent:@""]];
@ -281,6 +310,7 @@ static constexpr NSInteger CONTEXT_MENU_COPY_ATTRIBUTE_VALUE_TAG = 3;
[_dom_node_attribute_context_menu addItem:[[NSMenuItem alloc] initWithTitle:@"Add attribute" [_dom_node_attribute_context_menu addItem:[[NSMenuItem alloc] initWithTitle:@"Add attribute"
action:@selector(addDOMAttribute:) action:@selector(addDOMAttribute:)
keyEquivalent:@""]]; keyEquivalent:@""]];
[_dom_node_attribute_context_menu addItem:[Inspector make_create_child_menu]];
[_dom_node_attribute_context_menu addItem:[[NSMenuItem alloc] initWithTitle:@"Delete node" [_dom_node_attribute_context_menu addItem:[[NSMenuItem alloc] initWithTitle:@"Delete node"
action:@selector(deleteDOMNode:) action:@selector(deleteDOMNode:)
keyEquivalent:@""]]; keyEquivalent:@""]];

View file

@ -36,6 +36,12 @@ InspectorWidget::InspectorWidget(QWidget* tab, WebContentView& content_view)
m_screenshot_node_action = new QAction("Take node &screenshot", this); m_screenshot_node_action = new QAction("Take node &screenshot", this);
connect(m_screenshot_node_action, &QAction::triggered, [this]() { m_inspector_client->context_menu_screenshot_dom_node(); }); connect(m_screenshot_node_action, &QAction::triggered, [this]() { m_inspector_client->context_menu_screenshot_dom_node(); });
m_create_child_element_action = new QAction("Create child &element", this);
connect(m_create_child_element_action, &QAction::triggered, [this]() { m_inspector_client->context_menu_create_child_element(); });
m_create_child_text_node_action = new QAction("Create child &text node", this);
connect(m_create_child_text_node_action, &QAction::triggered, [this]() { m_inspector_client->context_menu_create_child_text_node(); });
m_delete_node_action = new QAction("&Delete node", this); m_delete_node_action = new QAction("&Delete node", this);
connect(m_delete_node_action, &QAction::triggered, [this]() { m_inspector_client->context_menu_remove_dom_node(); }); connect(m_delete_node_action, &QAction::triggered, [this]() { m_inspector_client->context_menu_remove_dom_node(); });
@ -54,10 +60,15 @@ InspectorWidget::InspectorWidget(QWidget* tab, WebContentView& content_view)
m_dom_node_text_context_menu->addSeparator(); m_dom_node_text_context_menu->addSeparator();
m_dom_node_text_context_menu->addAction(m_delete_node_action); m_dom_node_text_context_menu->addAction(m_delete_node_action);
auto* create_child_menu = new QMenu("Create child", this);
create_child_menu->addAction(m_create_child_element_action);
create_child_menu->addAction(m_create_child_text_node_action);
m_dom_node_tag_context_menu = new QMenu("DOM tag context menu", this); m_dom_node_tag_context_menu = new QMenu("DOM tag context menu", this);
m_dom_node_tag_context_menu->addAction(m_edit_node_action); m_dom_node_tag_context_menu->addAction(m_edit_node_action);
m_dom_node_tag_context_menu->addSeparator(); m_dom_node_tag_context_menu->addSeparator();
m_dom_node_tag_context_menu->addAction(m_add_attribute_action); m_dom_node_tag_context_menu->addAction(m_add_attribute_action);
m_dom_node_tag_context_menu->addMenu(create_child_menu);
m_dom_node_tag_context_menu->addAction(m_delete_node_action); m_dom_node_tag_context_menu->addAction(m_delete_node_action);
m_dom_node_tag_context_menu->addSeparator(); m_dom_node_tag_context_menu->addSeparator();
m_dom_node_tag_context_menu->addAction(m_copy_node_action); m_dom_node_tag_context_menu->addAction(m_copy_node_action);
@ -69,6 +80,7 @@ InspectorWidget::InspectorWidget(QWidget* tab, WebContentView& content_view)
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);
m_dom_node_attribute_context_menu->addMenu(create_child_menu);
m_dom_node_attribute_context_menu->addAction(m_delete_node_action); m_dom_node_attribute_context_menu->addAction(m_delete_node_action);
m_dom_node_attribute_context_menu->addSeparator(); m_dom_node_attribute_context_menu->addSeparator();
m_dom_node_attribute_context_menu->addAction(m_copy_node_action); m_dom_node_attribute_context_menu->addAction(m_copy_node_action);

View file

@ -46,6 +46,8 @@ private:
QAction* m_edit_node_action { nullptr }; QAction* m_edit_node_action { nullptr };
QAction* m_copy_node_action { nullptr }; QAction* m_copy_node_action { nullptr };
QAction* m_screenshot_node_action { nullptr }; QAction* m_screenshot_node_action { nullptr };
QAction* m_create_child_element_action { nullptr };
QAction* m_create_child_text_node_action { nullptr };
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 };

View file

@ -32,11 +32,19 @@ InspectorWidget::InspectorWidget(WebView::OutOfProcessWebView& content_view)
m_edit_node_action = GUI::Action::create("&Edit node"sv, [this](auto&) { m_inspector_client->context_menu_edit_dom_node(); }); m_edit_node_action = GUI::Action::create("&Edit node"sv, [this](auto&) { m_inspector_client->context_menu_edit_dom_node(); });
m_copy_node_action = GUI::Action::create("&Copy HTML"sv, [this](auto&) { m_inspector_client->context_menu_copy_dom_node(); }); m_copy_node_action = GUI::Action::create("&Copy HTML"sv, [this](auto&) { m_inspector_client->context_menu_copy_dom_node(); });
m_screenshot_node_action = GUI::Action::create("Take node &screenshot"sv, [this](auto&) { m_inspector_client->context_menu_screenshot_dom_node(); }); m_screenshot_node_action = GUI::Action::create("Take node &screenshot"sv, [this](auto&) { m_inspector_client->context_menu_screenshot_dom_node(); });
m_create_child_element_action = GUI::Action::create("Create child &element"sv, [this](auto&) { m_inspector_client->context_menu_create_child_element(); });
m_create_child_text_node_action = GUI::Action::create("Create child &text node"sv, [this](auto&) { m_inspector_client->context_menu_create_child_text_node(); });
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_copy_attribute_value_action = GUI::Action::create("Copy attribute &value"sv, [this](auto&) { m_inspector_client->context_menu_copy_dom_node_attribute_value(); });
auto add_create_child_menu = [&](auto& menu) {
auto create_child_menu = menu.add_submenu("Create child"_string);
create_child_menu->add_action(*m_create_child_element_action);
create_child_menu->add_action(*m_create_child_text_node_action);
};
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);
m_dom_node_text_context_menu->add_action(*m_copy_node_action); m_dom_node_text_context_menu->add_action(*m_copy_node_action);
@ -47,6 +55,7 @@ InspectorWidget::InspectorWidget(WebView::OutOfProcessWebView& content_view)
m_dom_node_tag_context_menu->add_action(*m_edit_node_action); m_dom_node_tag_context_menu->add_action(*m_edit_node_action);
m_dom_node_tag_context_menu->add_separator(); m_dom_node_tag_context_menu->add_separator();
m_dom_node_tag_context_menu->add_action(*m_add_attribute_action); m_dom_node_tag_context_menu->add_action(*m_add_attribute_action);
add_create_child_menu(*m_dom_node_tag_context_menu);
m_dom_node_tag_context_menu->add_action(*m_delete_node_action); m_dom_node_tag_context_menu->add_action(*m_delete_node_action);
m_dom_node_tag_context_menu->add_separator(); m_dom_node_tag_context_menu->add_separator();
m_dom_node_tag_context_menu->add_action(*m_copy_node_action); m_dom_node_tag_context_menu->add_action(*m_copy_node_action);
@ -58,6 +67,7 @@ InspectorWidget::InspectorWidget(WebView::OutOfProcessWebView& content_view)
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);
add_create_child_menu(*m_dom_node_attribute_context_menu);
m_dom_node_attribute_context_menu->add_action(*m_delete_node_action); m_dom_node_attribute_context_menu->add_action(*m_delete_node_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_copy_node_action); m_dom_node_attribute_context_menu->add_action(*m_copy_node_action);

View file

@ -42,6 +42,8 @@ private:
RefPtr<GUI::Action> m_edit_node_action; RefPtr<GUI::Action> m_edit_node_action;
RefPtr<GUI::Action> m_copy_node_action; RefPtr<GUI::Action> m_copy_node_action;
RefPtr<GUI::Action> m_screenshot_node_action; RefPtr<GUI::Action> m_screenshot_node_action;
RefPtr<GUI::Action> m_create_child_element_action;
RefPtr<GUI::Action> m_create_child_text_node_action;
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;

View file

@ -254,6 +254,26 @@ void InspectorClient::context_menu_screenshot_dom_node()
m_context_menu_data.clear(); m_context_menu_data.clear();
} }
void InspectorClient::context_menu_create_child_element()
{
VERIFY(m_context_menu_data.has_value());
m_pending_selection = m_content_web_view.create_child_element(m_context_menu_data->dom_node_id);
inspect();
m_context_menu_data.clear();
}
void InspectorClient::context_menu_create_child_text_node()
{
VERIFY(m_context_menu_data.has_value());
m_pending_selection = m_content_web_view.create_child_text_node(m_context_menu_data->dom_node_id);
inspect();
m_context_menu_data.clear();
}
void InspectorClient::context_menu_remove_dom_node() void InspectorClient::context_menu_remove_dom_node()
{ {
VERIFY(m_context_menu_data.has_value()); VERIFY(m_context_menu_data.has_value());

View file

@ -29,6 +29,8 @@ public:
void context_menu_edit_dom_node(); void context_menu_edit_dom_node();
void context_menu_copy_dom_node(); void context_menu_copy_dom_node();
void context_menu_screenshot_dom_node(); void context_menu_screenshot_dom_node();
void context_menu_create_child_element();
void context_menu_create_child_text_node();
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();