diff --git a/Tests/LibWeb/Text/expected/DOM/Element-removeAttributeNode.txt b/Tests/LibWeb/Text/expected/DOM/Element-removeAttributeNode.txt new file mode 100644 index 00000000000..2227e6985e8 --- /dev/null +++ b/Tests/LibWeb/Text/expected/DOM/Element-removeAttributeNode.txt @@ -0,0 +1,2 @@ +true +OK: NotFoundError: Attribute not found diff --git a/Tests/LibWeb/Text/input/DOM/Element-removeAttributeNode.html b/Tests/LibWeb/Text/input/DOM/Element-removeAttributeNode.html new file mode 100644 index 00000000000..56a2904f21b --- /dev/null +++ b/Tests/LibWeb/Text/input/DOM/Element-removeAttributeNode.html @@ -0,0 +1,16 @@ + + diff --git a/Userland/Libraries/LibWeb/DOM/Element.cpp b/Userland/Libraries/LibWeb/DOM/Element.cpp index 3ac6ad6f6ba..33125182bb7 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.cpp +++ b/Userland/Libraries/LibWeb/DOM/Element.cpp @@ -305,6 +305,12 @@ void Element::remove_attribute_ns(Optional const& namespace_, FlyStri m_attributes->remove_attribute_ns(namespace_, name); } +// https://dom.spec.whatwg.org/#dom-element-removeattributenode +WebIDL::ExceptionOr> Element::remove_attribute_node(JS::NonnullGCPtr attr) +{ + return m_attributes->remove_attribute_node(attr); +} + // https://dom.spec.whatwg.org/#dom-element-hasattribute bool Element::has_attribute(FlyString const& name) const { diff --git a/Userland/Libraries/LibWeb/DOM/Element.h b/Userland/Libraries/LibWeb/DOM/Element.h index 8ccc83c0742..6f4d33db7b7 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.h +++ b/Userland/Libraries/LibWeb/DOM/Element.h @@ -112,6 +112,7 @@ public: void append_attribute(Attr&); void remove_attribute(FlyString const& name); void remove_attribute_ns(Optional const& namespace_, FlyString const& name); + WebIDL::ExceptionOr> remove_attribute_node(JS::NonnullGCPtr); WebIDL::ExceptionOr toggle_attribute(FlyString const& name, Optional force); size_t attribute_list_size() const; diff --git a/Userland/Libraries/LibWeb/DOM/Element.idl b/Userland/Libraries/LibWeb/DOM/Element.idl index 99710c3f4c6..e5180dadb26 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.idl +++ b/Userland/Libraries/LibWeb/DOM/Element.idl @@ -51,7 +51,7 @@ interface Element : Node { Attr? getAttributeNodeNS([FlyString] DOMString? namespace, [FlyString] DOMString localName); [CEReactions] Attr? setAttributeNode(Attr attr); [CEReactions] Attr? setAttributeNodeNS(Attr attr); - // FIXME: [CEReactions] Attr removeAttributeNode(Attr attr); + [CEReactions] Attr removeAttributeNode(Attr attr); ShadowRoot attachShadow(ShadowRootInit init); readonly attribute ShadowRoot? shadowRoot; diff --git a/Userland/Libraries/LibWeb/DOM/NamedNodeMap.cpp b/Userland/Libraries/LibWeb/DOM/NamedNodeMap.cpp index e95f2c967d1..e60a4c7b3b0 100644 --- a/Userland/Libraries/LibWeb/DOM/NamedNodeMap.cpp +++ b/Userland/Libraries/LibWeb/DOM/NamedNodeMap.cpp @@ -342,4 +342,19 @@ WebIDL::ExceptionOr NamedNodeMap::named_item_value(FlyString const& n return node; } +// https://dom.spec.whatwg.org/#dom-element-removeattributenode +WebIDL::ExceptionOr> NamedNodeMap::remove_attribute_node(JS::NonnullGCPtr attr) +{ + // 1. If this’s attribute list does not contain attr, then throw a "NotFoundError" DOMException. + auto index = m_attributes.find_first_index(attr); + if (!index.has_value()) + return WebIDL::NotFoundError::create(realm(), "Attribute not found"_fly_string); + + // 2. Remove attr. + remove_attribute_at_index(index.value()); + + // 3. Return attr. + return attr; +} + } diff --git a/Userland/Libraries/LibWeb/DOM/NamedNodeMap.h b/Userland/Libraries/LibWeb/DOM/NamedNodeMap.h index 34949c1e404..55760db5093 100644 --- a/Userland/Libraries/LibWeb/DOM/NamedNodeMap.h +++ b/Userland/Libraries/LibWeb/DOM/NamedNodeMap.h @@ -56,6 +56,8 @@ public: Attr const* get_attribute_with_lowercase_qualified_name(FlyString const&) const; + WebIDL::ExceptionOr> remove_attribute_node(JS::NonnullGCPtr); + private: explicit NamedNodeMap(Element&);