diff --git a/Userland/Libraries/LibWeb/DOM/Document.idl b/Userland/Libraries/LibWeb/DOM/Document.idl index 17ebc433dfa..23d0b76266a 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.idl +++ b/Userland/Libraries/LibWeb/DOM/Document.idl @@ -18,12 +18,6 @@ interface Document : Node { ArrayFromVector getElementsByTagName(DOMString tagName); ArrayFromVector getElementsByClassName(DOMString className); - readonly attribute Element? firstElementChild; - readonly attribute Element? lastElementChild; - - Element? querySelector(DOMString selectors); - ArrayFromVector querySelectorAll(DOMString selectors); - Element createElement(DOMString tagName); Element createElementNS(DOMString? namespace, DOMString qualifiedName); DocumentFragment createDocumentFragment(); @@ -48,6 +42,14 @@ interface Document : Node { attribute DOMString title; + // FIXME: These should all come from a ParentNode mixin + readonly attribute Element? firstElementChild; + readonly attribute Element? lastElementChild; + readonly attribute unsigned long childElementCount; + + Element? querySelector(DOMString selectors); + ArrayFromVector querySelectorAll(DOMString selectors); + // FIXME: These should all come from a GlobalEventHandlers mixin attribute EventHandler onabort; attribute EventHandler onauxclick; diff --git a/Userland/Libraries/LibWeb/DOM/DocumentFragment.idl b/Userland/Libraries/LibWeb/DOM/DocumentFragment.idl index fc18e968be6..0b21365d0d3 100644 --- a/Userland/Libraries/LibWeb/DOM/DocumentFragment.idl +++ b/Userland/Libraries/LibWeb/DOM/DocumentFragment.idl @@ -2,8 +2,10 @@ interface DocumentFragment : Node { Element? getElementById(DOMString id); + // FIXME: These should all come from a ParentNode mixin readonly attribute Element? firstElementChild; readonly attribute Element? lastElementChild; + readonly attribute unsigned long childElementCount; Element? querySelector(DOMString selectors); ArrayFromVector querySelectorAll(DOMString selectors); diff --git a/Userland/Libraries/LibWeb/DOM/Element.idl b/Userland/Libraries/LibWeb/DOM/Element.idl index 6d4a397c589..a6c2202165b 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.idl +++ b/Userland/Libraries/LibWeb/DOM/Element.idl @@ -11,12 +11,6 @@ interface Element : Node { ArrayFromVector getElementsByTagName(DOMString tagName); ArrayFromVector getElementsByClassName(DOMString className); - readonly attribute Element? firstElementChild; - readonly attribute Element? lastElementChild; - - Element? querySelector(DOMString selectors); - ArrayFromVector querySelectorAll(DOMString selectors); - [LegacyNullToEmptyString] attribute DOMString innerHTML; [Reflect] attribute DOMString id; [Reflect=class] attribute DOMString className; @@ -25,4 +19,12 @@ interface Element : Node { readonly attribute Element? previousElementSibling; [ImplementedAs=style_for_bindings] readonly attribute CSSStyleDeclaration style; + + // FIXME: These should all come from a ParentNode mixin + readonly attribute Element? firstElementChild; + readonly attribute Element? lastElementChild; + readonly attribute unsigned long childElementCount; + + Element? querySelector(DOMString selectors); + ArrayFromVector querySelectorAll(DOMString selectors); }; diff --git a/Userland/Libraries/LibWeb/DOM/Node.cpp b/Userland/Libraries/LibWeb/DOM/Node.cpp index e4e54294860..a784afd2420 100644 --- a/Userland/Libraries/LibWeb/DOM/Node.cpp +++ b/Userland/Libraries/LibWeb/DOM/Node.cpp @@ -204,7 +204,7 @@ ExceptionOr Node::ensure_pre_insertion_validity(NonnullRefPtr node, if (is(this)) { if (is(*node)) { - auto node_element_child_count = node->element_child_count(); + auto node_element_child_count = downcast(*node).child_element_count(); if ((node_element_child_count > 1 || node->has_child_of_type()) || (node_element_child_count == 1 && (has_child_of_type() || is(child.ptr()) /* FIXME: or child is non-null and a doctype is following child. */))) { return DOM::HierarchyRequestError::create("Invalid node type for insertion"); @@ -497,14 +497,4 @@ bool Node::is_host_including_inclusive_ancestor_of(const Node& other) const return is_inclusive_ancestor_of(other) || (is(other.root()) && downcast(other.root())->host() && is_inclusive_ancestor_of(*downcast(other.root())->host().ptr())); } -size_t Node::element_child_count() const -{ - size_t count = 0; - for (auto* child = first_child(); child; child = child->next_sibling()) { - if (is(child)) - ++count; - } - return count; -} - } diff --git a/Userland/Libraries/LibWeb/DOM/Node.h b/Userland/Libraries/LibWeb/DOM/Node.h index 0cb36d0113e..f399f88d7f0 100644 --- a/Userland/Libraries/LibWeb/DOM/Node.h +++ b/Userland/Libraries/LibWeb/DOM/Node.h @@ -175,8 +175,6 @@ public: bool is_host_including_inclusive_ancestor_of(const Node&) const; - size_t element_child_count() const; - protected: Node(Document&, NodeType); diff --git a/Userland/Libraries/LibWeb/DOM/ParentNode.cpp b/Userland/Libraries/LibWeb/DOM/ParentNode.cpp index 1f31c2938f7..090070c3489 100644 --- a/Userland/Libraries/LibWeb/DOM/ParentNode.cpp +++ b/Userland/Libraries/LibWeb/DOM/ParentNode.cpp @@ -80,4 +80,15 @@ RefPtr ParentNode::last_element_child() return last_child_of_type(); } +// https://dom.spec.whatwg.org/#dom-parentnode-childelementcount +u32 ParentNode::child_element_count() const +{ + u32 count = 0; + for (auto* child = first_child(); child; child = child->next_sibling()) { + if (is(child)) + ++count; + } + return count; +} + } diff --git a/Userland/Libraries/LibWeb/DOM/ParentNode.h b/Userland/Libraries/LibWeb/DOM/ParentNode.h index 0fa6e8f1fe4..ad07f3cb3c5 100644 --- a/Userland/Libraries/LibWeb/DOM/ParentNode.h +++ b/Userland/Libraries/LibWeb/DOM/ParentNode.h @@ -40,6 +40,7 @@ public: RefPtr first_element_child(); RefPtr last_element_child(); + u32 child_element_count() const; RefPtr query_selector(const StringView&); NonnullRefPtrVector query_selector_all(const StringView&);