Jelajahi Sumber

LibWeb: Implement Element.removeAttributeNode()

Andreas Kling 1 tahun lalu
induk
melakukan
20bdda7f02

+ 2 - 0
Tests/LibWeb/Text/expected/DOM/Element-removeAttributeNode.txt

@@ -0,0 +1,2 @@
+true
+OK: NotFoundError: Attribute not found

+ 16 - 0
Tests/LibWeb/Text/input/DOM/Element-removeAttributeNode.html

@@ -0,0 +1,16 @@
+<script src="../include.js"></script>
+<script>
+    test(() => {
+        let e = document.createElement("div");
+        e.setAttribute("foo", "bar");
+        let a = e.getAttributeNode("foo");
+        let removed = e.removeAttributeNode(a);
+        println(a === removed);
+        try {
+            e.removeAttributeNode(a);
+            println("FAIL");
+        } catch (e) {
+            println("OK: " + e);
+        }
+    });
+</script>

+ 6 - 0
Userland/Libraries/LibWeb/DOM/Element.cpp

@@ -305,6 +305,12 @@ void Element::remove_attribute_ns(Optional<FlyString> const& namespace_, FlyStri
     m_attributes->remove_attribute_ns(namespace_, name);
 }
 
+// https://dom.spec.whatwg.org/#dom-element-removeattributenode
+WebIDL::ExceptionOr<JS::NonnullGCPtr<Attr>> Element::remove_attribute_node(JS::NonnullGCPtr<Attr> attr)
+{
+    return m_attributes->remove_attribute_node(attr);
+}
+
 // https://dom.spec.whatwg.org/#dom-element-hasattribute
 bool Element::has_attribute(FlyString const& name) const
 {

+ 1 - 0
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<FlyString> const& namespace_, FlyString const& name);
+    WebIDL::ExceptionOr<JS::NonnullGCPtr<Attr>> remove_attribute_node(JS::NonnullGCPtr<Attr>);
 
     WebIDL::ExceptionOr<bool> toggle_attribute(FlyString const& name, Optional<bool> force);
     size_t attribute_list_size() const;

+ 1 - 1
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;

+ 15 - 0
Userland/Libraries/LibWeb/DOM/NamedNodeMap.cpp

@@ -342,4 +342,19 @@ WebIDL::ExceptionOr<JS::Value> NamedNodeMap::named_item_value(FlyString const& n
     return node;
 }
 
+// https://dom.spec.whatwg.org/#dom-element-removeattributenode
+WebIDL::ExceptionOr<JS::NonnullGCPtr<Attr>> NamedNodeMap::remove_attribute_node(JS::NonnullGCPtr<Attr> 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;
+}
+
 }

+ 2 - 0
Userland/Libraries/LibWeb/DOM/NamedNodeMap.h

@@ -56,6 +56,8 @@ public:
 
     Attr const* get_attribute_with_lowercase_qualified_name(FlyString const&) const;
 
+    WebIDL::ExceptionOr<JS::NonnullGCPtr<Attr>> remove_attribute_node(JS::NonnullGCPtr<Attr>);
+
 private:
     explicit NamedNodeMap(Element&);