LibWeb: Make Node::root return a reference

The root of a node can never be null, as "the root of an object is
itself, if its parent is null, or else it is the root of its parent."

https://dom.spec.whatwg.org/#concept-tree-root
This commit is contained in:
Luke Wilde 2021-09-02 19:27:42 +01:00 committed by Andreas Kling
parent 7f46022e66
commit f7f37eaa0f
Notes: sideshowbarker 2024-07-18 04:51:25 +09:00
5 changed files with 24 additions and 20 deletions

View file

@ -35,15 +35,15 @@ static EventTarget* retarget(EventTarget* left, EventTarget* right)
return left;
auto* left_node = verify_cast<Node>(left);
auto* left_root = left_node->root();
auto& left_root = left_node->root();
if (!is<ShadowRoot>(left_root))
return left;
if (is<Node>(right) && left_root->is_shadow_including_inclusive_ancestor_of(verify_cast<Node>(*right)))
if (is<Node>(right) && left_root.is_shadow_including_inclusive_ancestor_of(verify_cast<Node>(*right)))
return left;
auto* left_shadow_root = verify_cast<ShadowRoot>(left_root);
left = left_shadow_root->host();
auto& left_shadow_root = verify_cast<ShadowRoot>(left_root);
left = left_shadow_root.host();
}
}

View file

@ -157,25 +157,28 @@ String Node::child_text_content() const
return builder.build();
}
Node* Node::root()
// https://dom.spec.whatwg.org/#concept-tree-root
Node& Node::root()
{
Node* root = this;
while (root->parent())
root = root->parent();
return root;
return *root;
}
Node* Node::shadow_including_root()
// https://dom.spec.whatwg.org/#concept-shadow-including-root
Node& Node::shadow_including_root()
{
auto node_root = root();
auto& node_root = root();
if (is<ShadowRoot>(node_root))
return verify_cast<ShadowRoot>(node_root)->host()->shadow_including_root();
return verify_cast<ShadowRoot>(node_root).host()->shadow_including_root();
return node_root;
}
// https://dom.spec.whatwg.org/#connected
bool Node::is_connected() const
{
return shadow_including_root() && shadow_including_root()->is_document();
return shadow_including_root().is_document();
}
Element* Node::parent_element()
@ -608,7 +611,7 @@ u16 Node::compare_document_position(RefPtr<Node> other)
// FIXME: Once LibWeb supports attribute nodes fix to follow the specification.
VERIFY(node1->type() != NodeType::ATTRIBUTE_NODE && node2->type() != NodeType::ATTRIBUTE_NODE);
if ((node1 == nullptr || node2 == nullptr) || (node1->root() != node2->root()))
if ((node1 == nullptr || node2 == nullptr) || (&node1->root() != &node2->root()))
return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | (node1 > node2 ? DOCUMENT_POSITION_PRECEDING : DOCUMENT_POSITION_FOLLOWING);
if (node1->is_ancestor_of(*node2))
@ -626,7 +629,7 @@ u16 Node::compare_document_position(RefPtr<Node> other)
// https://dom.spec.whatwg.org/#concept-tree-host-including-inclusive-ancestor
bool Node::is_host_including_inclusive_ancestor_of(const Node& other) const
{
return is_inclusive_ancestor_of(other) || (is<DocumentFragment>(other.root()) && verify_cast<DocumentFragment>(other.root())->host() && is_inclusive_ancestor_of(*verify_cast<DocumentFragment>(other.root())->host().ptr()));
return is_inclusive_ancestor_of(other) || (is<DocumentFragment>(other.root()) && verify_cast<DocumentFragment>(other.root()).host() && is_inclusive_ancestor_of(*verify_cast<DocumentFragment>(other.root()).host().ptr()));
}
// https://dom.spec.whatwg.org/#dom-node-ownerdocument
@ -691,10 +694,10 @@ bool Node::is_shadow_including_descendant_of(Node const& other) const
if (!is<ShadowRoot>(root()))
return false;
auto shadow_root = verify_cast<ShadowRoot>(root());
auto& shadow_root = verify_cast<ShadowRoot>(root());
// NOTE: While host is nullable because of inheriting from DocumentFragment, shadow roots always have a host.
return shadow_root->host()->is_shadow_including_inclusive_descendant_of(other);
return shadow_root.host()->is_shadow_including_inclusive_descendant_of(other);
}
// https://dom.spec.whatwg.org/#concept-shadow-including-inclusive-descendant

View file

@ -113,14 +113,14 @@ public:
String child_text_content() const;
Node* root();
const Node* root() const
Node& root();
const Node& root() const
{
return const_cast<Node*>(this)->root();
}
Node* shadow_including_root();
const Node* shadow_including_root() const
Node& shadow_including_root();
const Node& shadow_including_root() const
{
return const_cast<Node*>(this)->shadow_including_root();
}

View file

@ -16,11 +16,12 @@ ShadowRoot::ShadowRoot(Document& document, Element& host)
set_host(host);
}
// https://dom.spec.whatwg.org/#ref-for-get-the-parent%E2%91%A6
EventTarget* ShadowRoot::get_parent(const Event& event)
{
if (!event.composed()) {
auto& events_first_invocation_target = verify_cast<Node>(*event.path().first().invocation_target);
if (events_first_invocation_target.root() == this)
if (&events_first_invocation_target.root() == this)
return nullptr;
}

View file

@ -72,7 +72,7 @@ bool Node::establishes_stacking_context() const
{
if (!has_style())
return false;
if (dom_node() == document().root())
if (dom_node() == &document().root())
return true;
auto position = computed_values().position();
if (position == CSS::Position::Absolute || position == CSS::Position::Relative || position == CSS::Position::Fixed || position == CSS::Position::Sticky)