diff --git a/lib/src/html/dom/node.dart b/lib/src/html/dom/node.dart index a57ceee..7523ee0 100644 --- a/lib/src/html/dom/node.dart +++ b/lib/src/html/dom/node.dart @@ -386,7 +386,7 @@ abstract class Node extends EventTarget { return sb.toString(); } - void remove() { + void _removeFromTree(Node? replaceWith) { final parent = _parent; if (parent == null) { assert(_previousNode == null); @@ -394,75 +394,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 6c0dbc9..ecb578d 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) @@ -48,7 +52,7 @@ void _testNode() { expect( root.outerHtml, equals( - 'e0-texte1-texte2-text')); + 'e0-texte1-text')); // Replace child #1 of 'e1' { @@ -64,7 +68,7 @@ void _testNode() { expect( root.outerHtml, equals( - 'e0-texte1-text-replacede2-text')); + 'e0-texte1-text-replaced')); } // Replace child #2 of root ('e1') @@ -83,7 +87,23 @@ void _testNode() { expect( root.outerHtml, equals( - 'e0-texte1-replacede2-text')); + '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( + 'e1-replaced')); } }); test('replaceWith when the node has no parent', () {