Przeglądaj źródła

LibWeb: Implement ChildNode.replaceWith

Luke Wilde 3 lat temu
rodzic
commit
7431f6073b

+ 1 - 0
Userland/Libraries/LibWeb/DOM/CharacterData.idl

@@ -9,6 +9,7 @@ interface CharacterData : Node {
     // FIXME: These should come from a ChildNode mixin
     [CEReactions, Unscopable] undefined before((Node or DOMString)... nodes);
     [CEReactions, Unscopable] undefined after((Node or DOMString)... nodes);
+    [CEReactions, Unscopable] undefined replaceWith((Node or DOMString)... nodes);
     [CEReactions, Unscopable, ImplementedAs=remove_binding] undefined remove();
 
 };

+ 40 - 0
Userland/Libraries/LibWeb/DOM/ChildNode.h

@@ -81,6 +81,46 @@ public:
         return {};
     }
 
+    // https://dom.spec.whatwg.org/#dom-childnode-replacewith
+    ExceptionOr<void> replace_with(Vector<Variant<NonnullRefPtr<Node>, String>> const& nodes)
+    {
+        auto* node = static_cast<NodeType*>(this);
+
+        // 1. Let parent be this’s parent.
+        auto* parent = node->parent();
+
+        // 2. If parent is null, then return.
+        if (!parent)
+            return {};
+
+        // 3. Let viableNextSibling be this’s first following sibling not in nodes; otherwise null.
+        auto viable_next_sibling = viable_nest_sibling_for_insertion(nodes);
+
+        // 4. Let node be the result of converting nodes into a node, given nodes and this’s node document.
+        auto node_or_exception = convert_nodes_to_single_node(nodes, node->document());
+        if (node_or_exception.is_exception())
+            return node_or_exception.exception();
+
+        auto node_to_insert = node_or_exception.release_value();
+
+        // 5. If this’s parent is parent, replace this with node within parent.
+        // Note: This could have been inserted into node.
+        if (node->parent() == parent) {
+            auto result = parent->replace_child(node_to_insert, *node);
+            if (result.is_exception())
+                return result.exception();
+
+            return {};
+        }
+
+        // 6. Otherwise, pre-insert node into parent before viableNextSibling.
+        auto result = parent->pre_insert(node_to_insert, viable_next_sibling);
+        if (result.is_exception())
+            return result.exception();
+
+        return {};
+    }
+
     // https://dom.spec.whatwg.org/#dom-childnode-remove
     void remove_binding()
     {

+ 1 - 0
Userland/Libraries/LibWeb/DOM/DocumentType.idl

@@ -7,6 +7,7 @@ interface DocumentType : Node {
     // FIXME: These should come from a ChildNode mixin
     [CEReactions, Unscopable] undefined before((Node or DOMString)... nodes);
     [CEReactions, Unscopable] undefined after((Node or DOMString)... nodes);
+    [CEReactions, Unscopable] undefined replaceWith((Node or DOMString)... nodes);
     [CEReactions, Unscopable, ImplementedAs=remove_binding] undefined remove();
 
 };

+ 1 - 0
Userland/Libraries/LibWeb/DOM/Element.idl

@@ -57,6 +57,7 @@ interface Element : Node {
     // FIXME: These should come from a ChildNode mixin
     [CEReactions, Unscopable] undefined before((Node or DOMString)... nodes);
     [CEReactions, Unscopable] undefined after((Node or DOMString)... nodes);
+    [CEReactions, Unscopable] undefined replaceWith((Node or DOMString)... nodes);
     [CEReactions, Unscopable, ImplementedAs=remove_binding] undefined remove();
 
 };