Skip to content

Commit

Permalink
feat: add Node.replaceWith
Browse files Browse the repository at this point in the history
  • Loading branch information
alextekartik committed Feb 24, 2025
1 parent b9a8006 commit aef1fe1
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 5 deletions.
29 changes: 27 additions & 2 deletions lib/src/html.dart
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ abstract class Node {

/// Replaces one child Node of the current one with the second one given in parameter.
Node replaceChild(Node newChild, Node oldChild);

/// Parent node (or null if not yet attached)
Node? get parentNode;
}

/// Text node
Expand Down Expand Up @@ -264,10 +267,10 @@ abstract class HtmlProvider {
Text createTextNode(String text);

// wrap a native document
Document wrapDocument(Object? documentImpl);
Document wrapDocument(Object documentImpl);

// get the native document
Object? unwrapDocument(Document? document);
Object unwrapDocument(Document document);

// wrap a native element
Element wrapElement(Object elementImpl);
Expand Down Expand Up @@ -329,4 +332,26 @@ extension TekartikHtmlNodeExt on Node {
var nodes = htmlProvider.createNodesHtml(html, noValidate: noValidate);
return appendChildren(nodes);
}

/// The Element.replaceWith() method replaces this Element in the children list
/// of its parent with a set of Node objects or strings.
void replaceWith(Node otherNode) {
parentNode!.replaceChild(otherNode, this);
}
}

extension TekartikHtmlNodeMixin on HtmlProvider {
Object? unwrapNodeOrNull(Node? node) {
if (node == null) {
return null;
}
return unwrapNode(node);
}

Node? wrapNodeOrNull(Object? nodeImpl) {
if (nodeImpl == null) {
return null;
}
return wrapNode(nodeImpl);
}
}
6 changes: 6 additions & 0 deletions lib/src/html5lib/html_html5lib.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ mixin _NodeHtml5libMixin implements Node {
HtmlProvider get htmlProvider => htmlProviderHtml5Lib;
late html5lib.Node _node;

@override
Node? get parentNode {
var html5LibParentNode = _node.parentNode;
return _html.wrapNodeOrNull(html5LibParentNode);
}

// ignore: unused_element
html5lib.Element get _element =>
_node as html5lib.Element; // only work if element
Expand Down
10 changes: 8 additions & 2 deletions lib/src/web/html_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,12 @@ class _ElementList extends ListBase<Element> implements ElementList {
}

mixin _NodeWebMixin implements NodeWeb {
@override
Node? get parentNode {
var webParentNode = webNode.parentNode;
return _html.wrapNodeOrNull(webParentNode);
}

@override
HtmlProvider get htmlProvider => htmlProviderWeb;

Expand Down Expand Up @@ -442,8 +448,8 @@ class _HtmlProviderWeb implements HtmlProviderWeb {
String get name => providerWebName;

@override
dynamic unwrapDocument(Document? document) {
return document?.webDoc;
Object unwrapDocument(Document document) {
return document.webDoc;
}

@override
Expand Down
2 changes: 1 addition & 1 deletion test/document_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ void testMain(HtmlProvider html) {
test('wrap', () {
var document = html.createDocument(title: 'test');

dynamic docImpl = html.unwrapDocument(document);
final docImpl = html.unwrapDocument(document);

document = html.wrapDocument(docImpl);
expect(document.title, 'test');
Expand Down
11 changes: 11 additions & 0 deletions test/node_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ void nodeTestGroup(final HtmlProvider html) {
test('child append/remove', () {
var element = html.createElementTag('div');
var textNode = html.createTextNode('hello');
expect(textNode.parentNode, isNull);
expect(element.appendChild(textNode), textNode);
expect(textNode.parentNode, element);
expect(element.childNodes.length, 1);
expect(element.removeChild(textNode), textNode);
expect(element.childNodes.length, 0);
Expand All @@ -43,6 +45,15 @@ void nodeTestGroup(final HtmlProvider html) {
expect(element.replaceChild(newTextNode, textNode), newTextNode);
expect(element.childNodes.first, newTextNode);
});
test('node replaceWith', () {
var element = html.createElementTag('div');
var textNode = html.createTextNode('hello');
var newTextNode = html.createTextNode('bye');
expect(element.appendChild(textNode), textNode);
textNode.replaceWith(newTextNode);

expect(element.childNodes.first, newTextNode);
});
test('child insert before', () {
var element = html.createElementTag('div');
var textNode = html.createTextNode('hello');
Expand Down

0 comments on commit aef1fe1

Please sign in to comment.