diff --git a/Userland/Libraries/LibWeb/DOM/CharacterData.idl b/Userland/Libraries/LibWeb/DOM/CharacterData.idl index 7d859fa8ce..c3aaf8e816 100644 --- a/Userland/Libraries/LibWeb/DOM/CharacterData.idl +++ b/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(); }; diff --git a/Userland/Libraries/LibWeb/DOM/ChildNode.h b/Userland/Libraries/LibWeb/DOM/ChildNode.h index 2eb70e4696..2f46285a64 100644 --- a/Userland/Libraries/LibWeb/DOM/ChildNode.h +++ b/Userland/Libraries/LibWeb/DOM/ChildNode.h @@ -81,6 +81,46 @@ public: return {}; } + // https://dom.spec.whatwg.org/#dom-childnode-replacewith + ExceptionOr replace_with(Vector, String>> const& nodes) + { + auto* node = static_cast(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() { diff --git a/Userland/Libraries/LibWeb/DOM/DocumentType.idl b/Userland/Libraries/LibWeb/DOM/DocumentType.idl index 0bfa494bca..2485d2431a 100644 --- a/Userland/Libraries/LibWeb/DOM/DocumentType.idl +++ b/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(); }; diff --git a/Userland/Libraries/LibWeb/DOM/Element.idl b/Userland/Libraries/LibWeb/DOM/Element.idl index ea82f8113c..7fb2ea6381 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.idl +++ b/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(); };