diff --git a/lib/src/html/dom/node.dart b/lib/src/html/dom/node.dart index ee8546c..e9601b8 100644 --- a/lib/src/html/dom/node.dart +++ b/lib/src/html/dom/node.dart @@ -393,7 +393,7 @@ abstract class Node extends EventTarget { return sb.toString(); } - void remove() { + void _removeFromTree(Node? replaceWith) { final parent = _parent; if (parent == null) { assert(_previousNode == null); @@ -401,75 +401,52 @@ abstract class Node extends EventTarget { return; } - // Mark node as dirty - _markDirty(); - // Get previous and next final previous = _previousNode; final next = _nextNode; if (previous == null) { // This was the first sibling - parent._firstChild = next; + parent._firstChild = replaceWith ?? next; } else { // Mutate the previous sibling - previous._nextNode = next; + previous._nextNode = replaceWith ?? next; } if (next == null) { // This was the last sibling - parent._lastChild = previous; + parent._lastChild = replaceWith ?? previous; } else { // Mutate the next sibling - next._previousNode = previous; + next._previousNode = replaceWith ?? previous; + } + if (replaceWith != null) { + // move replaceWith + replaceWith._parent = parent; + replaceWith._previousNode = previous; + replaceWith._nextNode = next; } - // Set fields of this node _parent = null; _previousNode = null; _nextNode = null; - parent._mutated(); - _mutated(); } - void replaceWith(Node node) { + void remove() { final parent = _parent; - if (parent == null) { - assert(_previousNode == null); - assert(_nextNode == null); - return; - } + // Mark node as dirty + _markDirty(); + _removeFromTree(null); + parent?._mutated(); + _mutated(); + } + void replaceWith(Node node) { // Mark nodes as dirty _markDirty(); node._markDirty(); - - // Get previous and next - final previous = _previousNode; - final next = _nextNode; - - if (previous == null) { - // This was the first sibling - parent._firstChild = node; - } else { - // Mutate the previous sibling - previous._nextNode = node; - } - - if (next == null) { - // This was the last sibling - parent._lastChild = node; - } else { - // Mutate the next sibling - next._previousNode = node; - } - - node._parent = parent; - node._previousNode = previous; - node._nextNode = next; - _parent = null; - _previousNode = null; - _nextNode = null; + node._removeFromTree(null); + _removeFromTree(node); _mutated(); node._mutated(); } diff --git a/test/src/html/dom/node.dart b/test/src/html/dom/node.dart index 11a5d43..4ed53e7 100644 --- a/test/src/html/dom/node.dart +++ b/test/src/html/dom/node.dart @@ -37,7 +37,11 @@ void _testNode() { test('replaceWith', () { final e0 = Element.tag('e0')..appendText('e0-text'); final e1 = Element.tag('e1')..appendText('e1-text'); - final e2 = Element.tag('e2')..appendText('e2-text'); + final e2 = Element.tag('e2')..append( + Element.tag('e2c1') + )..append( + Element.tag('e2c2') + ); final root = Element.tag('sometag') ..setAttribute('k', 'v') ..append(e0) @@ -46,11 +50,9 @@ void _testNode() { // Initial tree expect( - root.outerHtml, - equals( - 'e0-texte1-texte2-text', - ), - ); + root.outerHtml, + equals( + 'e0-texte1-text')); // Replace child #1 of 'e1' { @@ -64,11 +66,9 @@ void _testNode() { expect(e1.firstChild, same(replacement)); expect(e1.firstChild!.parent, same(e1)); expect( - root.outerHtml, - equals( - 'e0-texte1-text-replacede2-text', - ), - ); + root.outerHtml, + equals( + 'e0-texte1-text-replaced')); } // Replace child #2 of root ('e1') @@ -84,12 +84,26 @@ void _testNode() { expect(e1.nextNode, isNull); expect(replacement.parent, same(root)); expect(replacement.nextNode, same(e2)); + expect( + root.outerHtml, + equals( + 'e0-texte1-replaced')); + } + // Replace with existing node to check if it moved properly + { + final replacement = e2.children.first; + e0.replaceWith(replacement); + + expect(e0.nextNode, isNull); + expect(e0.previousNode, isNull); + expect(e0.parent, isNull); + expect(replacement.parent, same(root)); + expect(replacement.previousNode, isNull); + expect(replacement.nextNode, isNotNull); expect( root.outerHtml, equals( - 'e0-texte1-replacede2-text', - ), - ); + 'e1-replaced')); } }); test('replaceWith when the node has no parent', () {