LibDevTools+LibWebView+WebContent: Implement moving DOM nodes

This allows for click-and-dragging DOM nodes in DevTools to move them.
This commit is contained in:
Timothy Flynn 2025-03-10 18:01:29 -04:00 committed by Tim Flynn
parent 01c44a5c66
commit cbefa797d4
Notes: github-actions[bot] 2025-03-11 13:51:48 +00:00
9 changed files with 88 additions and 0 deletions

View file

@ -232,6 +232,53 @@ void WalkerActor::handle_message(StringView type, JsonObject const& message)
return; return;
} }
if (type == "insertBefore"sv) {
auto node = message.get_string("node"sv);
if (!node.has_value()) {
send_missing_parameter_error("node"sv);
return;
}
auto parent = message.get_string("parent"sv);
if (!parent.has_value()) {
send_missing_parameter_error("parent"sv);
return;
}
auto dom_node = WalkerActor::dom_node_for(*this, *node);
auto parent_dom_node = WalkerActor::dom_node_for(*this, *parent);
Optional<Web::UniqueNodeID> sibling_node_id;
if (auto sibling = message.get_string("sibling"sv); sibling.has_value()) {
auto sibling_dom_node = WalkerActor::dom_node_for(*this, *sibling);
if (!sibling_dom_node.has_value())
return;
sibling_node_id = sibling_dom_node->identifier.id;
}
if (dom_node.has_value() && parent_dom_node.has_value()) {
auto block_token = block_responses();
devtools().delegate().insert_dom_node_before(
dom_node->tab->description(), dom_node->identifier.id, parent_dom_node->identifier.id, sibling_node_id,
[weak_self = make_weak_ptr<WalkerActor>(), block_token = move(block_token)](ErrorOr<Web::UniqueNodeID> node_id) mutable {
if (node_id.is_error()) {
dbgln_if(DEVTOOLS_DEBUG, "Unable to edit DOM node: {}", node_id.error());
return;
}
if (auto self = weak_self.strong_ref()) {
JsonObject message;
message.set("from"sv, self->name());
self->send_message(move(message), move(block_token));
}
});
}
return;
}
if (type == "isInDOMTree"sv) { if (type == "isInDOMTree"sv) {
auto node = message.get_string("node"sv); auto node = message.get_string("node"sv);
if (!node.has_value()) { if (!node.has_value()) {

View file

@ -51,6 +51,7 @@ public:
virtual void add_dom_node_attributes(TabDescription const&, Web::UniqueNodeID, ReadonlySpan<WebView::Attribute>, OnDOMNodeEditComplete) const { } virtual void add_dom_node_attributes(TabDescription const&, Web::UniqueNodeID, ReadonlySpan<WebView::Attribute>, OnDOMNodeEditComplete) const { }
virtual void replace_dom_node_attribute(TabDescription const&, Web::UniqueNodeID, String const&, ReadonlySpan<WebView::Attribute>, OnDOMNodeEditComplete) const { } virtual void replace_dom_node_attribute(TabDescription const&, Web::UniqueNodeID, String const&, ReadonlySpan<WebView::Attribute>, OnDOMNodeEditComplete) const { }
virtual void create_child_element(TabDescription const&, Web::UniqueNodeID, OnDOMNodeEditComplete) const { } virtual void create_child_element(TabDescription const&, Web::UniqueNodeID, OnDOMNodeEditComplete) const { }
virtual void insert_dom_node_before(TabDescription const&, Web::UniqueNodeID, Web::UniqueNodeID, Optional<Web::UniqueNodeID>, OnDOMNodeEditComplete) const { }
virtual void clone_dom_node(TabDescription const&, Web::UniqueNodeID, OnDOMNodeEditComplete) const { } virtual void clone_dom_node(TabDescription const&, Web::UniqueNodeID, OnDOMNodeEditComplete) const { }
virtual void remove_dom_node(TabDescription const&, Web::UniqueNodeID, OnDOMNodeEditComplete) const { } virtual void remove_dom_node(TabDescription const&, Web::UniqueNodeID, OnDOMNodeEditComplete) const { }

View file

@ -578,6 +578,13 @@ void Application::create_child_element(DevTools::TabDescription const& descripti
}); });
} }
void Application::insert_dom_node_before(DevTools::TabDescription const& description, Web::UniqueNodeID node_id, Web::UniqueNodeID parent_node_id, Optional<Web::UniqueNodeID> sibling_node_id, OnDOMNodeEditComplete on_complete) const
{
edit_dom_node(description, move(on_complete), [&](auto& view) {
view.insert_dom_node_before(node_id, parent_node_id, sibling_node_id);
});
}
void Application::clone_dom_node(DevTools::TabDescription const& description, Web::UniqueNodeID node_id, OnDOMNodeEditComplete on_complete) const void Application::clone_dom_node(DevTools::TabDescription const& description, Web::UniqueNodeID node_id, OnDOMNodeEditComplete on_complete) const
{ {
edit_dom_node(description, move(on_complete), [&](auto& view) { edit_dom_node(description, move(on_complete), [&](auto& view) {

View file

@ -108,6 +108,7 @@ private:
virtual void add_dom_node_attributes(DevTools::TabDescription const&, Web::UniqueNodeID, ReadonlySpan<Attribute>, OnDOMNodeEditComplete) const override; virtual void add_dom_node_attributes(DevTools::TabDescription const&, Web::UniqueNodeID, ReadonlySpan<Attribute>, OnDOMNodeEditComplete) const override;
virtual void replace_dom_node_attribute(DevTools::TabDescription const&, Web::UniqueNodeID, String const&, ReadonlySpan<Attribute>, OnDOMNodeEditComplete) const override; virtual void replace_dom_node_attribute(DevTools::TabDescription const&, Web::UniqueNodeID, String const&, ReadonlySpan<Attribute>, OnDOMNodeEditComplete) const override;
virtual void create_child_element(DevTools::TabDescription const&, Web::UniqueNodeID, OnDOMNodeEditComplete) const override; virtual void create_child_element(DevTools::TabDescription const&, Web::UniqueNodeID, OnDOMNodeEditComplete) const override;
virtual void insert_dom_node_before(DevTools::TabDescription const&, Web::UniqueNodeID, Web::UniqueNodeID, Optional<Web::UniqueNodeID>, OnDOMNodeEditComplete) const override;
virtual void clone_dom_node(DevTools::TabDescription const&, Web::UniqueNodeID, OnDOMNodeEditComplete) const override; virtual void clone_dom_node(DevTools::TabDescription const&, Web::UniqueNodeID, OnDOMNodeEditComplete) const override;
virtual void remove_dom_node(DevTools::TabDescription const&, Web::UniqueNodeID, OnDOMNodeEditComplete) const override; virtual void remove_dom_node(DevTools::TabDescription const&, Web::UniqueNodeID, OnDOMNodeEditComplete) const override;
virtual void evaluate_javascript(DevTools::TabDescription const&, String const&, OnScriptEvaluationComplete) const override; virtual void evaluate_javascript(DevTools::TabDescription const&, String const&, OnScriptEvaluationComplete) const override;

View file

@ -399,6 +399,11 @@ void ViewImplementation::create_child_text_node(Web::UniqueNodeID node_id)
client().async_create_child_text_node(page_id(), node_id); client().async_create_child_text_node(page_id(), node_id);
} }
void ViewImplementation::insert_dom_node_before(Web::UniqueNodeID node_id, Web::UniqueNodeID parent_node_id, Optional<Web::UniqueNodeID> sibling_node_id)
{
client().async_insert_dom_node_before(page_id(), node_id, parent_node_id, sibling_node_id);
}
void ViewImplementation::clone_dom_node(Web::UniqueNodeID node_id) void ViewImplementation::clone_dom_node(Web::UniqueNodeID node_id)
{ {
client().async_clone_dom_node(page_id(), node_id); client().async_clone_dom_node(page_id(), node_id);

View file

@ -124,6 +124,7 @@ public:
void replace_dom_node_attribute(Web::UniqueNodeID node_id, String const& name, ReadonlySpan<Attribute> replacement_attributes); void replace_dom_node_attribute(Web::UniqueNodeID node_id, String const& name, ReadonlySpan<Attribute> replacement_attributes);
void create_child_element(Web::UniqueNodeID node_id); void create_child_element(Web::UniqueNodeID node_id);
void create_child_text_node(Web::UniqueNodeID node_id); void create_child_text_node(Web::UniqueNodeID node_id);
void insert_dom_node_before(Web::UniqueNodeID node_id, Web::UniqueNodeID parent_node_id, Optional<Web::UniqueNodeID> sibling_node_id);
void clone_dom_node(Web::UniqueNodeID node_id); void clone_dom_node(Web::UniqueNodeID node_id);
void remove_dom_node(Web::UniqueNodeID node_id); void remove_dom_node(Web::UniqueNodeID node_id);

View file

@ -849,6 +849,30 @@ void ConnectionFromClient::create_child_text_node(u64 page_id, Web::UniqueNodeID
async_did_finish_editing_dom_node(page_id, text_node->unique_id()); async_did_finish_editing_dom_node(page_id, text_node->unique_id());
} }
void ConnectionFromClient::insert_dom_node_before(u64 page_id, Web::UniqueNodeID node_id, Web::UniqueNodeID parent_node_id, Optional<Web::UniqueNodeID> sibling_node_id)
{
auto* dom_node = Web::DOM::Node::from_unique_id(node_id);
auto* parent_dom_node = Web::DOM::Node::from_unique_id(parent_node_id);
if (!dom_node || !parent_dom_node) {
async_did_finish_editing_dom_node(page_id, {});
return;
}
GC::Ptr<Web::DOM::Node> sibling_dom_node;
if (sibling_node_id.has_value()) {
sibling_dom_node = Web::DOM::Node::from_unique_id(*sibling_node_id);
if (!sibling_dom_node) {
async_did_finish_editing_dom_node(page_id, {});
return;
}
}
parent_dom_node->insert_before(*dom_node, sibling_dom_node);
async_did_finish_editing_dom_node(page_id, dom_node->unique_id());
}
void ConnectionFromClient::clone_dom_node(u64 page_id, Web::UniqueNodeID node_id) void ConnectionFromClient::clone_dom_node(u64 page_id, Web::UniqueNodeID node_id)
{ {
auto* dom_node = Web::DOM::Node::from_unique_id(node_id); auto* dom_node = Web::DOM::Node::from_unique_id(node_id);

View file

@ -93,6 +93,7 @@ private:
virtual void replace_dom_node_attribute(u64 page_id, Web::UniqueNodeID node_id, String name, Vector<WebView::Attribute> replacement_attributes) override; virtual void replace_dom_node_attribute(u64 page_id, Web::UniqueNodeID node_id, String name, Vector<WebView::Attribute> replacement_attributes) override;
virtual void create_child_element(u64 page_id, Web::UniqueNodeID node_id) override; virtual void create_child_element(u64 page_id, Web::UniqueNodeID node_id) override;
virtual void create_child_text_node(u64 page_id, Web::UniqueNodeID node_id) override; virtual void create_child_text_node(u64 page_id, Web::UniqueNodeID node_id) override;
virtual void insert_dom_node_before(u64 page_id, Web::UniqueNodeID node_id, Web::UniqueNodeID parent_node_id, Optional<Web::UniqueNodeID> sibling_node_id) override;
virtual void clone_dom_node(u64 page_id, Web::UniqueNodeID node_id) override; virtual void clone_dom_node(u64 page_id, Web::UniqueNodeID node_id) override;
virtual void remove_dom_node(u64 page_id, Web::UniqueNodeID node_id) override; virtual void remove_dom_node(u64 page_id, Web::UniqueNodeID node_id) override;

View file

@ -66,6 +66,7 @@ endpoint WebContentServer
replace_dom_node_attribute(u64 page_id, Web::UniqueNodeID node_id, String name, Vector<WebView::Attribute> replacement_attributes) =| replace_dom_node_attribute(u64 page_id, Web::UniqueNodeID node_id, String name, Vector<WebView::Attribute> replacement_attributes) =|
create_child_element(u64 page_id, Web::UniqueNodeID node_id) =| create_child_element(u64 page_id, Web::UniqueNodeID node_id) =|
create_child_text_node(u64 page_id, Web::UniqueNodeID node_id) =| create_child_text_node(u64 page_id, Web::UniqueNodeID node_id) =|
insert_dom_node_before(u64 page_id, Web::UniqueNodeID node_id, Web::UniqueNodeID parent_node_id, Optional<Web::UniqueNodeID> sibling_node_id) =|
clone_dom_node(u64 page_id, Web::UniqueNodeID node_id) =| clone_dom_node(u64 page_id, Web::UniqueNodeID node_id) =|
remove_dom_node(u64 page_id, Web::UniqueNodeID node_id) =| remove_dom_node(u64 page_id, Web::UniqueNodeID node_id) =|