LibDevTools: Ensure the walker actor only displays nodes it created

The NodeIdentifier struct essentially contains the DOM node ID within
its WebContent process. These will repeat across multiple processes,
thus we cannot use them to search for node actors in the global actor
registry.

Instead, we can store a map of all node actors created by the walker
itself. The NodeIdentifier is then appropriate for actor lookups on
that map. This has the added benefit of not needing to search the entire
actor registry many times while forming the DOM node caches.

This fix allows us to inspect multiple tabs at once.
This commit is contained in:
Timothy Flynn 2025-03-13 16:59:38 -04:00 committed by Jelle Raaijmakers
parent 664c57af16
commit 80d7350ee5
Notes: github-actions[bot] 2025-03-14 08:05:00 +00:00
3 changed files with 25 additions and 7 deletions

View file

@ -6,7 +6,9 @@
#pragma once
#include <AK/HashFunctions.h>
#include <AK/NonnullRefPtr.h>
#include <AK/Traits.h>
#include <LibDevTools/Actor.h>
#include <LibWeb/CSS/Selector.h>
#include <LibWeb/Forward.h>
@ -30,6 +32,7 @@ public:
virtual ~NodeActor() override;
NodeIdentifier const& node_identifier() const { return m_node_identifier; }
WeakPtr<WalkerActor> const& walker() const { return m_walker; }
private:
NodeActor(DevToolsServer&, String name, NodeIdentifier, WeakPtr<WalkerActor>);
@ -42,3 +45,17 @@ private:
};
}
template<>
struct AK::Traits<DevTools::NodeIdentifier> : public AK::DefaultTraits<DevTools::NodeIdentifier> {
static bool equals(DevTools::NodeIdentifier const& lhs, DevTools::NodeIdentifier const& rhs)
{
return lhs == rhs;
}
static unsigned hash(DevTools::NodeIdentifier const& node_identifier)
{
auto pseudo_element = node_identifier.pseudo_element.value_or(Web::CSS::Selector::PseudoElement::Type::KnownPseudoElementCount);
return pair_int_hash(node_identifier.id.value(), to_underlying(pseudo_element));
}
};

View file

@ -728,16 +728,15 @@ NodeActor const& WalkerActor::actor_for_node(JsonObject const& node)
{
auto identifier = NodeIdentifier::for_node(node);
for (auto const& actor : devtools().actor_registry()) {
auto const* node_actor = as_if<NodeActor>(*actor.value);
if (!node_actor)
continue;
if (node_actor->node_identifier() == identifier)
if (auto it = m_node_actors.find(identifier); it != m_node_actors.end()) {
if (auto node_actor = it->value.strong_ref())
return *node_actor;
}
return devtools().register_actor<NodeActor>(move(identifier), *this);
auto& node_actor = devtools().register_actor<NodeActor>(move(identifier), *this);
m_node_actors.set(identifier, node_actor);
return node_actor;
}
}

View file

@ -68,6 +68,8 @@ private:
HashMap<JsonObject const*, JsonObject const*> m_dom_node_to_parent_map;
HashMap<String, JsonObject const*> m_actor_to_dom_node_map;
HashMap<Web::UniqueNodeID, String> m_dom_node_id_to_actor_map;
HashMap<NodeIdentifier, WeakPtr<NodeActor>> m_node_actors;
};
}