Skip to content

Commit f1f787d

Browse files
Merge pull request #12 from Browsercore/node_followup
Node followup
2 parents 07c4779 + 4de6ad0 commit f1f787d

File tree

2 files changed

+222
-0
lines changed

2 files changed

+222
-0
lines changed

src/dom/node.zig

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,82 @@ pub const Node = struct {
129129
const res = parser.nodeAppendChild(self, child);
130130
return Node.toInterface(res);
131131
}
132+
133+
pub fn _cloneNode(self: *parser.Node, deep: ?bool) Union {
134+
const clone = parser.nodeCloneNode(self, deep orelse false);
135+
return Node.toInterface(clone);
136+
}
137+
138+
pub fn _compareDocumentPosition(self: *parser.Node, other: *parser.Node) void {
139+
// TODO
140+
_ = other;
141+
_ = self;
142+
std.log.err("Not implemented {s}", .{"node.compareDocumentPosition()"});
143+
}
144+
145+
pub fn _contains(self: *parser.Node, other: *parser.Node) bool {
146+
return parser.nodeContains(self, other);
147+
}
148+
149+
pub fn _getRootNode(self: *parser.Node) void {
150+
// TODO
151+
_ = self;
152+
std.log.err("Not implemented {s}", .{"node.getRootNode()"});
153+
}
154+
155+
pub fn _hasChildNodes(self: *parser.Node) bool {
156+
return parser.nodeHasChildNodes(self);
157+
}
158+
159+
pub fn _insertBefore(self: *parser.Node, new_node: *parser.Node, ref_node: *parser.Node) *parser.Node {
160+
return parser.nodeInsertBefore(self, new_node, ref_node);
161+
}
162+
163+
pub fn _isDefaultNamespace(self: *parser.Node, namespace: []const u8) bool {
164+
// TODO: namespace is not an optional parameter, but can be null.
165+
return parser.nodeIsDefaultNamespace(self, namespace);
166+
}
167+
168+
pub fn _isEqualNode(self: *parser.Node, other: *parser.Node) bool {
169+
// TODO: other is not an optional parameter, but can be null.
170+
return parser.nodeIsEqualNode(self, other);
171+
}
172+
173+
pub fn _isSameNode(self: *parser.Node, other: *parser.Node) bool {
174+
// TODO: other is not an optional parameter, but can be null.
175+
// NOTE: there is no need to use isSameNode(); instead use the === strict equality operator
176+
return parser.nodeIsSameNode(self, other);
177+
}
178+
179+
pub fn _lookupPrefix(self: *parser.Node, namespace: ?[]const u8) ?[]const u8 {
180+
// TODO: other is not an optional parameter, but can be null.
181+
if (namespace == null) {
182+
return null;
183+
}
184+
if (std.mem.eql(u8, namespace.?, "")) {
185+
return null;
186+
}
187+
return parser.nodeLookupPrefix(self, namespace);
188+
}
189+
190+
pub fn _lookupNamespaceURI(self: *parser.Node, prefix: ?[]const u8) ?[]const u8 {
191+
// TODO: other is not an optional parameter, but can be null.
192+
return parser.nodeLookupNamespaceURI(self, prefix);
193+
}
194+
195+
pub fn _normalize(self: *parser.Node) void {
196+
return parser.nodeNormalize(self);
197+
}
198+
199+
pub fn _removeChild(self: *parser.Node, child: *parser.Node) Union {
200+
const res = parser.nodeRemoveChild(self, child);
201+
return Node.toInterface(res);
202+
}
203+
204+
pub fn _replaceChild(self: *parser.Node, new_child: *parser.Node, old_child: *parser.Node) Union {
205+
const res = parser.nodeReplaceChild(self, new_child, old_child);
206+
return Node.toInterface(res);
207+
}
132208
};
133209

134210
pub const Types = generate.Tuple(.{
@@ -253,4 +329,73 @@ pub fn testExecFn(
253329
.{ .src = "content.appendChild(link).toString()", .ex = "[object HTMLAnchorElement]" },
254330
};
255331
try checkCases(js_env, &node_append_child);
332+
333+
var node_clone = [_]Case{
334+
.{ .src = "let clone = link.cloneNode()", .ex = "undefined" },
335+
.{ .src = "clone.toString()", .ex = "[object HTMLAnchorElement]" },
336+
.{ .src = "clone.parentNode === null", .ex = "true" },
337+
.{ .src = "clone.firstChild === null", .ex = "true" },
338+
.{ .src = "let clone_deep = link.cloneNode(true)", .ex = "undefined" },
339+
.{ .src = "clone_deep.firstChild.nodeName === '#text'", .ex = "true" },
340+
};
341+
try checkCases(js_env, &node_clone);
342+
343+
var node_contains = [_]Case{
344+
.{ .src = "link.contains(text)", .ex = "true" },
345+
.{ .src = "text.contains(link)", .ex = "false" },
346+
};
347+
try checkCases(js_env, &node_contains);
348+
349+
var node_has_child_nodes = [_]Case{
350+
.{ .src = "link.hasChildNodes()", .ex = "true" },
351+
.{ .src = "text.hasChildNodes()", .ex = "false" },
352+
};
353+
try checkCases(js_env, &node_has_child_nodes);
354+
355+
var node_insert_before = [_]Case{
356+
.{ .src = "let insertBefore = document.createElement('a')", .ex = "undefined" },
357+
.{ .src = "link.insertBefore(insertBefore, text) !== undefined", .ex = "true" },
358+
.{ .src = "link.firstChild.localName === 'a'", .ex = "true" },
359+
};
360+
try checkCases(js_env, &node_insert_before);
361+
362+
var node_is_default_namespace = [_]Case{
363+
// TODO: does not seems to work
364+
// .{ .src = "link.isDefaultNamespace('')", .ex = "true" },
365+
.{ .src = "link.isDefaultNamespace('false')", .ex = "false" },
366+
};
367+
try checkCases(js_env, &node_is_default_namespace);
368+
369+
var node_is_equal_node = [_]Case{
370+
.{ .src = "let equal1 = document.createElement('a')", .ex = "undefined" },
371+
.{ .src = "let equal2 = document.createElement('a')", .ex = "undefined" },
372+
.{ .src = "equal1.textContent = 'is equal'", .ex = "is equal" },
373+
.{ .src = "equal2.textContent = 'is equal'", .ex = "is equal" },
374+
// TODO: does not seems to work
375+
// .{ .src = "equal1.isEqualNode(equal2)", .ex = "true" },
376+
};
377+
try checkCases(js_env, &node_is_equal_node);
378+
379+
var node_is_same_node = [_]Case{
380+
.{ .src = "document.body.isSameNode(document.body)", .ex = "true" },
381+
};
382+
try checkCases(js_env, &node_is_same_node);
383+
384+
var node_normalize = [_]Case{
385+
// TODO: no test
386+
.{ .src = "link.normalize()", .ex = "undefined" },
387+
};
388+
try checkCases(js_env, &node_normalize);
389+
390+
var node_remove_child = [_]Case{
391+
.{ .src = "content.removeChild(append) !== undefined", .ex = "true" },
392+
.{ .src = "content.lastChild.__proto__.constructor.name !== 'HTMLHeadingElement'", .ex = "true" },
393+
};
394+
try checkCases(js_env, &node_remove_child);
395+
396+
var node_replace_child = [_]Case{
397+
.{ .src = "let replace = document.createElement('div')", .ex = "undefined" },
398+
.{ .src = "link.replaceChild(replace, insertBefore) !== undefined", .ex = "true" },
399+
};
400+
try checkCases(js_env, &node_replace_child);
256401
}

src/netsurf.zig

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,83 @@ pub fn nodeAppendChild(node: *Node, child: *Node) *Node {
340340
return res.?;
341341
}
342342

343+
pub fn nodeCloneNode(node: *Node, is_deep: bool) *Node {
344+
var res: ?*Node = undefined;
345+
_ = nodeVtable(node).dom_node_clone_node.?(node, is_deep, &res);
346+
return res.?;
347+
}
348+
349+
pub fn nodeContains(node: *Node, other: *Node) bool {
350+
var res: bool = undefined;
351+
_ = c._dom_node_contains(node, other, &res);
352+
return res;
353+
}
354+
355+
pub fn nodeHasChildNodes(node: *Node) bool {
356+
var res: bool = undefined;
357+
_ = nodeVtable(node).dom_node_has_child_nodes.?(node, &res);
358+
return res;
359+
}
360+
361+
pub fn nodeInsertBefore(node: *Node, new_node: *Node, ref_node: *Node) *Node {
362+
var res: ?*Node = undefined;
363+
_ = nodeVtable(node).dom_node_insert_before.?(node, new_node, ref_node, &res);
364+
return res.?;
365+
}
366+
367+
pub fn nodeIsDefaultNamespace(node: *Node, namespace: []const u8) bool {
368+
const s = stringFromData(namespace);
369+
var res: bool = undefined;
370+
_ = nodeVtable(node).dom_node_is_default_namespace.?(node, s, &res);
371+
return res;
372+
}
373+
374+
pub fn nodeIsEqualNode(node: *Node, other: *Node) bool {
375+
var res: bool = undefined;
376+
_ = nodeVtable(node).dom_node_is_equal.?(node, other, &res);
377+
return res;
378+
}
379+
380+
pub fn nodeIsSameNode(node: *Node, other: *Node) bool {
381+
var res: bool = undefined;
382+
_ = nodeVtable(node).dom_node_is_same.?(node, other, &res);
383+
return res;
384+
}
385+
386+
pub fn nodeLookupPrefix(node: *Node, namespace: []const u8) ?[]const u8 {
387+
var s: ?*String = undefined;
388+
_ = nodeVtable(node).dom_node_lookup_prefix.?(node, stringFromData(namespace), &s);
389+
if (s == null) {
390+
return null;
391+
}
392+
return stringToData(s.?);
393+
}
394+
395+
pub fn nodeLookupNamespaceURI(node: *Node, prefix: ?[]const u8) ?[]const u8 {
396+
var s: ?*String = undefined;
397+
_ = nodeVtable(node).dom_node_lookup_namespace.?(node, stringFromData(prefix.?), &s);
398+
if (s == null) {
399+
return null;
400+
}
401+
return stringToData(s.?);
402+
}
403+
404+
pub fn nodeNormalize(node: *Node) void {
405+
_ = nodeVtable(node).dom_node_normalize.?(node);
406+
}
407+
408+
pub fn nodeRemoveChild(node: *Node, child: *Node) *Node {
409+
var res: ?*Node = undefined;
410+
_ = nodeVtable(node).dom_node_remove_child.?(node, child, &res);
411+
return res.?;
412+
}
413+
414+
pub fn nodeReplaceChild(node: *Node, new_child: *Node, old_child: *Node) *Node {
415+
var res: ?*Node = undefined;
416+
_ = nodeVtable(node).dom_node_replace_child.?(node, new_child, old_child, &res);
417+
return res.?;
418+
}
419+
343420
// CharacterData
344421
pub const CharacterData = c.dom_characterdata;
345422

0 commit comments

Comments
 (0)