Loading dom/base/Element.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -3962,7 +3962,6 @@ void Element::InsertAdjacentHTML(const nsAString& aPosition, // listeners on the fragment that comes from the parser. nsAutoScriptBlockerSuppressNodeRemoved scriptBlocker; nsAutoMutationBatch mb(destination, true, false); switch (position) { case eBeforeBegin: destination->InsertBefore(*fragment, this, aError); Loading dom/base/nsINode.cpp +7 −3 Original line number Diff line number Diff line Loading @@ -2143,7 +2143,7 @@ void nsINode::ReplaceChildren(nsINode* aNode, ErrorResult& aRv) { // Needed when used in combination with contenteditable (maybe) mozAutoDocUpdate updateBatch(OwnerDoc(), true); nsAutoMutationBatch mb(this, true, false); nsAutoMutationBatch mb(this, true, true); // Replace all with node within this. while (mFirstChild) { Loading Loading @@ -2731,10 +2731,14 @@ nsINode* nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild, */ nsINode* result = aReplace ? aRefChild : aNewChild; if (nodeType == DOCUMENT_FRAGMENT_NODE) { if (!aReplace) { nsAutoMutationBatch* mutationBatch = nsAutoMutationBatch::GetCurrentBatch(); if (mutationBatch && mutationBatch != &mb) { mutationBatch = nullptr; } else if (!aReplace) { mb.Init(this, true, true); mutationBatch = nsAutoMutationBatch::GetCurrentBatch(); } nsAutoMutationBatch* mutationBatch = nsAutoMutationBatch::GetCurrentBatch(); if (mutationBatch) { mutationBatch->RemovalDone(); mutationBatch->SetPrevSibling( Loading testing/web-platform/tests/dom/nodes/ParentNode-replaceChildren.html +79 −0 Original line number Diff line number Diff line Loading @@ -121,6 +121,85 @@ test_replacechildren(document.createElement('div'), 'Element'); test_replacechildren(document.createDocumentFragment(), 'DocumentFragment'); async_test(t => { let root = document.createElement("div"); root.innerHTML = "<div id='a'>text<div id='b'>text2</div></div>"; const a = root.firstChild; const b = a.lastChild; const txt = b.previousSibling; const txt2 = b.firstChild; const observer = new MutationObserver((mutations) => { assert_equals(mutations.length, 2, "mutations.length"); assert_equals(mutations[0].target.id, "a", "Target of the removal"); assert_equals(mutations[0].addedNodes.length, 0, "Should not have added nodes"); assert_equals(mutations[0].removedNodes.length, 1, "Should have 1 removed node"); assert_equals(mutations[0].removedNodes[0], txt, "Should have removed txt node"); assert_equals(mutations[1].target.id, "b", "Target of the replaceChildren"); assert_equals(mutations[1].removedNodes.length, 1, "Should have removed 1 node"); assert_equals(mutations[1].removedNodes[0], txt2, "Should have removed txt2 node"); assert_equals(mutations[1].addedNodes.length, 1, "Should have added a node"); assert_equals(mutations[1].addedNodes[0], txt, "Should have added txt node"); observer.disconnect(); t.done(); }); observer.observe(a, { subtree: true, childList: true }); b.replaceChildren(txt); }, "There should be a MutationRecord for the node removed from another parent node."); async_test(t => { // This is almost the same test as above, but passes two nodes to replaceChildren. let root = document.createElement("div"); root.innerHTML = "<div id='a'><div id='c'></div>text<div id='b'>text2</div></div>"; const a = root.firstChild; const b = a.lastChild; const c = a.firstChild; const txt = b.previousSibling; const txt2 = b.firstChild; const observer = new MutationObserver((mutations) => { assert_equals(mutations.length, 3, "mutations.length"); assert_equals(mutations[0].target.id, "a", "Target of the removal"); assert_equals(mutations[0].addedNodes.length, 0, "Should not have added nodes"); assert_equals(mutations[0].removedNodes.length, 1, "Should have 1 removed node"); assert_equals(mutations[0].removedNodes[0], c, "Should have removed c node"); assert_equals(mutations[1].target.id, "a", "Target of the removal"); assert_equals(mutations[1].addedNodes.length, 0, "Should not have added nodes"); assert_equals(mutations[1].removedNodes.length, 1, "Should have 1 removed node"); assert_equals(mutations[1].removedNodes[0], txt, "Should have removed txt node"); assert_equals(mutations[2].target.id, "b", "Target of the replaceChildren"); assert_equals(mutations[2].removedNodes.length, 1, "Should have removed 1 node"); assert_equals(mutations[2].removedNodes[0], txt2, "Should have removed txt2 node"); assert_equals(mutations[2].addedNodes.length, 2, "Should have added a node"); assert_equals(mutations[2].addedNodes[0], c, "Should have added c node"); assert_equals(mutations[2].addedNodes[1], txt, "Should have added txt node"); observer.disconnect(); t.done(); }); observer.observe(a, { subtree: true, childList: true }); b.replaceChildren(c, txt); }, "There should be MutationRecords for the nodes removed from another parent node."); </script> </html> Loading
dom/base/Element.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -3962,7 +3962,6 @@ void Element::InsertAdjacentHTML(const nsAString& aPosition, // listeners on the fragment that comes from the parser. nsAutoScriptBlockerSuppressNodeRemoved scriptBlocker; nsAutoMutationBatch mb(destination, true, false); switch (position) { case eBeforeBegin: destination->InsertBefore(*fragment, this, aError); Loading
dom/base/nsINode.cpp +7 −3 Original line number Diff line number Diff line Loading @@ -2143,7 +2143,7 @@ void nsINode::ReplaceChildren(nsINode* aNode, ErrorResult& aRv) { // Needed when used in combination with contenteditable (maybe) mozAutoDocUpdate updateBatch(OwnerDoc(), true); nsAutoMutationBatch mb(this, true, false); nsAutoMutationBatch mb(this, true, true); // Replace all with node within this. while (mFirstChild) { Loading Loading @@ -2731,10 +2731,14 @@ nsINode* nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild, */ nsINode* result = aReplace ? aRefChild : aNewChild; if (nodeType == DOCUMENT_FRAGMENT_NODE) { if (!aReplace) { nsAutoMutationBatch* mutationBatch = nsAutoMutationBatch::GetCurrentBatch(); if (mutationBatch && mutationBatch != &mb) { mutationBatch = nullptr; } else if (!aReplace) { mb.Init(this, true, true); mutationBatch = nsAutoMutationBatch::GetCurrentBatch(); } nsAutoMutationBatch* mutationBatch = nsAutoMutationBatch::GetCurrentBatch(); if (mutationBatch) { mutationBatch->RemovalDone(); mutationBatch->SetPrevSibling( Loading
testing/web-platform/tests/dom/nodes/ParentNode-replaceChildren.html +79 −0 Original line number Diff line number Diff line Loading @@ -121,6 +121,85 @@ test_replacechildren(document.createElement('div'), 'Element'); test_replacechildren(document.createDocumentFragment(), 'DocumentFragment'); async_test(t => { let root = document.createElement("div"); root.innerHTML = "<div id='a'>text<div id='b'>text2</div></div>"; const a = root.firstChild; const b = a.lastChild; const txt = b.previousSibling; const txt2 = b.firstChild; const observer = new MutationObserver((mutations) => { assert_equals(mutations.length, 2, "mutations.length"); assert_equals(mutations[0].target.id, "a", "Target of the removal"); assert_equals(mutations[0].addedNodes.length, 0, "Should not have added nodes"); assert_equals(mutations[0].removedNodes.length, 1, "Should have 1 removed node"); assert_equals(mutations[0].removedNodes[0], txt, "Should have removed txt node"); assert_equals(mutations[1].target.id, "b", "Target of the replaceChildren"); assert_equals(mutations[1].removedNodes.length, 1, "Should have removed 1 node"); assert_equals(mutations[1].removedNodes[0], txt2, "Should have removed txt2 node"); assert_equals(mutations[1].addedNodes.length, 1, "Should have added a node"); assert_equals(mutations[1].addedNodes[0], txt, "Should have added txt node"); observer.disconnect(); t.done(); }); observer.observe(a, { subtree: true, childList: true }); b.replaceChildren(txt); }, "There should be a MutationRecord for the node removed from another parent node."); async_test(t => { // This is almost the same test as above, but passes two nodes to replaceChildren. let root = document.createElement("div"); root.innerHTML = "<div id='a'><div id='c'></div>text<div id='b'>text2</div></div>"; const a = root.firstChild; const b = a.lastChild; const c = a.firstChild; const txt = b.previousSibling; const txt2 = b.firstChild; const observer = new MutationObserver((mutations) => { assert_equals(mutations.length, 3, "mutations.length"); assert_equals(mutations[0].target.id, "a", "Target of the removal"); assert_equals(mutations[0].addedNodes.length, 0, "Should not have added nodes"); assert_equals(mutations[0].removedNodes.length, 1, "Should have 1 removed node"); assert_equals(mutations[0].removedNodes[0], c, "Should have removed c node"); assert_equals(mutations[1].target.id, "a", "Target of the removal"); assert_equals(mutations[1].addedNodes.length, 0, "Should not have added nodes"); assert_equals(mutations[1].removedNodes.length, 1, "Should have 1 removed node"); assert_equals(mutations[1].removedNodes[0], txt, "Should have removed txt node"); assert_equals(mutations[2].target.id, "b", "Target of the replaceChildren"); assert_equals(mutations[2].removedNodes.length, 1, "Should have removed 1 node"); assert_equals(mutations[2].removedNodes[0], txt2, "Should have removed txt2 node"); assert_equals(mutations[2].addedNodes.length, 2, "Should have added a node"); assert_equals(mutations[2].addedNodes[0], c, "Should have added c node"); assert_equals(mutations[2].addedNodes[1], txt, "Should have added txt node"); observer.disconnect(); t.done(); }); observer.observe(a, { subtree: true, childList: true }); b.replaceChildren(c, txt); }, "There should be MutationRecords for the nodes removed from another parent node."); </script> </html>