From ae50e9e01dfecd7d627493322a6cb0cca65fdcb9 Mon Sep 17 00:00:00 2001 From: FranklinDM Date: Mon, 1 May 2023 20:50:50 +0800 Subject: [PATCH] Issue #2225 - Implement Element.replaceChildren This accounts for refactoring changes (e.g. avoids RemoveChild* changes). Partially based on https://bugzilla.mozilla.org/show_bug.cgi?id=1626015 --- dom/base/nsINode.cpp | 34 ++++++++++++++++++++++++++++++++++ dom/base/nsINode.h | 1 + dom/webidl/ParentNode.webidl | 2 ++ 3 files changed, 37 insertions(+) diff --git a/dom/base/nsINode.cpp b/dom/base/nsINode.cpp index 735dfb16e5..d4129171cb 100644 --- a/dom/base/nsINode.cpp +++ b/dom/base/nsINode.cpp @@ -1963,6 +1963,40 @@ nsINode::Append(const Sequence& aNodes, AppendChild(*node, aRv); } +// https://dom.spec.whatwg.org/#dom-parentnode-replacechildren +void nsINode::ReplaceChildren(const Sequence& aNodes, + ErrorResult& aRv) { + nsCOMPtr doc = OwnerDoc(); + nsCOMPtr node = ConvertNodesOrStringsIntoNode(aNodes, doc, aRv); + if (aRv.Failed()) { + return; + } + + EnsurePreInsertionValidity(*node, nullptr, aRv); + if (aRv.Failed()) { + return; + } + + // Needed when used in combination with contenteditable (maybe) + mozAutoDocUpdate updateBatch(doc, UPDATE_CONTENT_MODEL, true); + + nsAutoMutationBatch mb(this, true, false); + + // Replace all with node within this. + while (mFirstChild) { + int32_t index = IndexOf(mFirstChild); + if (index == -1) { + NS_ASSERTION(index != -1, "First child must have an index"); + return; + } + RemoveChildAt(index, true); + } + mb.RemovalDone(); + + AppendChild(*node, aRv); + mb.NodesAdded(); +} + void nsINode::doRemoveChildAt(uint32_t aIndex, bool aNotify, nsIContent* aKid, nsAttrAndChildArray& aChildArray) diff --git a/dom/base/nsINode.h b/dom/base/nsINode.h index 3611a4074d..5268767a3e 100644 --- a/dom/base/nsINode.h +++ b/dom/base/nsINode.h @@ -1980,6 +1980,7 @@ public: void Prepend(const Sequence& aNodes, ErrorResult& aRv); void Append(const Sequence& aNodes, ErrorResult& aRv); + void ReplaceChildren(const Sequence& aNodes, ErrorResult& aRv); void GetBoxQuads(const BoxQuadOptions& aOptions, nsTArray >& aResult, diff --git a/dom/webidl/ParentNode.webidl b/dom/webidl/ParentNode.webidl index aa6ca5db2c..6aa555744e 100644 --- a/dom/webidl/ParentNode.webidl +++ b/dom/webidl/ParentNode.webidl @@ -22,4 +22,6 @@ interface ParentNode { void prepend((Node or DOMString)... nodes); [CEReactions, Throws, Unscopable] void append((Node or DOMString)... nodes); + [CEReactions, Throws, Unscopable] + void replaceChildren((Node or DOMString)... nodes); };