Skip to content

Commit

Permalink
Merge pull request #12 from Browsercore/node_followup
Browse files Browse the repository at this point in the history
Node followup
  • Loading branch information
francisbouvier authored Sep 29, 2023
2 parents 07c4779 + 4de6ad0 commit f1f787d
Show file tree
Hide file tree
Showing 2 changed files with 222 additions and 0 deletions.
145 changes: 145 additions & 0 deletions src/dom/node.zig
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,82 @@ pub const Node = struct {
const res = parser.nodeAppendChild(self, child);
return Node.toInterface(res);
}

pub fn _cloneNode(self: *parser.Node, deep: ?bool) Union {
const clone = parser.nodeCloneNode(self, deep orelse false);
return Node.toInterface(clone);
}

pub fn _compareDocumentPosition(self: *parser.Node, other: *parser.Node) void {
// TODO
_ = other;
_ = self;
std.log.err("Not implemented {s}", .{"node.compareDocumentPosition()"});
}

pub fn _contains(self: *parser.Node, other: *parser.Node) bool {
return parser.nodeContains(self, other);
}

pub fn _getRootNode(self: *parser.Node) void {
// TODO
_ = self;
std.log.err("Not implemented {s}", .{"node.getRootNode()"});
}

pub fn _hasChildNodes(self: *parser.Node) bool {
return parser.nodeHasChildNodes(self);
}

pub fn _insertBefore(self: *parser.Node, new_node: *parser.Node, ref_node: *parser.Node) *parser.Node {
return parser.nodeInsertBefore(self, new_node, ref_node);
}

pub fn _isDefaultNamespace(self: *parser.Node, namespace: []const u8) bool {
// TODO: namespace is not an optional parameter, but can be null.
return parser.nodeIsDefaultNamespace(self, namespace);
}

pub fn _isEqualNode(self: *parser.Node, other: *parser.Node) bool {
// TODO: other is not an optional parameter, but can be null.
return parser.nodeIsEqualNode(self, other);
}

pub fn _isSameNode(self: *parser.Node, other: *parser.Node) bool {
// TODO: other is not an optional parameter, but can be null.
// NOTE: there is no need to use isSameNode(); instead use the === strict equality operator
return parser.nodeIsSameNode(self, other);
}

pub fn _lookupPrefix(self: *parser.Node, namespace: ?[]const u8) ?[]const u8 {
// TODO: other is not an optional parameter, but can be null.
if (namespace == null) {
return null;
}
if (std.mem.eql(u8, namespace.?, "")) {
return null;
}
return parser.nodeLookupPrefix(self, namespace);
}

pub fn _lookupNamespaceURI(self: *parser.Node, prefix: ?[]const u8) ?[]const u8 {
// TODO: other is not an optional parameter, but can be null.
return parser.nodeLookupNamespaceURI(self, prefix);
}

pub fn _normalize(self: *parser.Node) void {
return parser.nodeNormalize(self);
}

pub fn _removeChild(self: *parser.Node, child: *parser.Node) Union {
const res = parser.nodeRemoveChild(self, child);
return Node.toInterface(res);
}

pub fn _replaceChild(self: *parser.Node, new_child: *parser.Node, old_child: *parser.Node) Union {
const res = parser.nodeReplaceChild(self, new_child, old_child);
return Node.toInterface(res);
}
};

pub const Types = generate.Tuple(.{
Expand Down Expand Up @@ -253,4 +329,73 @@ pub fn testExecFn(
.{ .src = "content.appendChild(link).toString()", .ex = "[object HTMLAnchorElement]" },
};
try checkCases(js_env, &node_append_child);

var node_clone = [_]Case{
.{ .src = "let clone = link.cloneNode()", .ex = "undefined" },
.{ .src = "clone.toString()", .ex = "[object HTMLAnchorElement]" },
.{ .src = "clone.parentNode === null", .ex = "true" },
.{ .src = "clone.firstChild === null", .ex = "true" },
.{ .src = "let clone_deep = link.cloneNode(true)", .ex = "undefined" },
.{ .src = "clone_deep.firstChild.nodeName === '#text'", .ex = "true" },
};
try checkCases(js_env, &node_clone);

var node_contains = [_]Case{
.{ .src = "link.contains(text)", .ex = "true" },
.{ .src = "text.contains(link)", .ex = "false" },
};
try checkCases(js_env, &node_contains);

var node_has_child_nodes = [_]Case{
.{ .src = "link.hasChildNodes()", .ex = "true" },
.{ .src = "text.hasChildNodes()", .ex = "false" },
};
try checkCases(js_env, &node_has_child_nodes);

var node_insert_before = [_]Case{
.{ .src = "let insertBefore = document.createElement('a')", .ex = "undefined" },
.{ .src = "link.insertBefore(insertBefore, text) !== undefined", .ex = "true" },
.{ .src = "link.firstChild.localName === 'a'", .ex = "true" },
};
try checkCases(js_env, &node_insert_before);

var node_is_default_namespace = [_]Case{
// TODO: does not seems to work
// .{ .src = "link.isDefaultNamespace('')", .ex = "true" },
.{ .src = "link.isDefaultNamespace('false')", .ex = "false" },
};
try checkCases(js_env, &node_is_default_namespace);

var node_is_equal_node = [_]Case{
.{ .src = "let equal1 = document.createElement('a')", .ex = "undefined" },
.{ .src = "let equal2 = document.createElement('a')", .ex = "undefined" },
.{ .src = "equal1.textContent = 'is equal'", .ex = "is equal" },
.{ .src = "equal2.textContent = 'is equal'", .ex = "is equal" },
// TODO: does not seems to work
// .{ .src = "equal1.isEqualNode(equal2)", .ex = "true" },
};
try checkCases(js_env, &node_is_equal_node);

var node_is_same_node = [_]Case{
.{ .src = "document.body.isSameNode(document.body)", .ex = "true" },
};
try checkCases(js_env, &node_is_same_node);

var node_normalize = [_]Case{
// TODO: no test
.{ .src = "link.normalize()", .ex = "undefined" },
};
try checkCases(js_env, &node_normalize);

var node_remove_child = [_]Case{
.{ .src = "content.removeChild(append) !== undefined", .ex = "true" },
.{ .src = "content.lastChild.__proto__.constructor.name !== 'HTMLHeadingElement'", .ex = "true" },
};
try checkCases(js_env, &node_remove_child);

var node_replace_child = [_]Case{
.{ .src = "let replace = document.createElement('div')", .ex = "undefined" },
.{ .src = "link.replaceChild(replace, insertBefore) !== undefined", .ex = "true" },
};
try checkCases(js_env, &node_replace_child);
}
77 changes: 77 additions & 0 deletions src/netsurf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,83 @@ pub fn nodeAppendChild(node: *Node, child: *Node) *Node {
return res.?;
}

pub fn nodeCloneNode(node: *Node, is_deep: bool) *Node {
var res: ?*Node = undefined;
_ = nodeVtable(node).dom_node_clone_node.?(node, is_deep, &res);
return res.?;
}

pub fn nodeContains(node: *Node, other: *Node) bool {
var res: bool = undefined;
_ = c._dom_node_contains(node, other, &res);
return res;
}

pub fn nodeHasChildNodes(node: *Node) bool {
var res: bool = undefined;
_ = nodeVtable(node).dom_node_has_child_nodes.?(node, &res);
return res;
}

pub fn nodeInsertBefore(node: *Node, new_node: *Node, ref_node: *Node) *Node {
var res: ?*Node = undefined;
_ = nodeVtable(node).dom_node_insert_before.?(node, new_node, ref_node, &res);
return res.?;
}

pub fn nodeIsDefaultNamespace(node: *Node, namespace: []const u8) bool {
const s = stringFromData(namespace);
var res: bool = undefined;
_ = nodeVtable(node).dom_node_is_default_namespace.?(node, s, &res);
return res;
}

pub fn nodeIsEqualNode(node: *Node, other: *Node) bool {
var res: bool = undefined;
_ = nodeVtable(node).dom_node_is_equal.?(node, other, &res);
return res;
}

pub fn nodeIsSameNode(node: *Node, other: *Node) bool {
var res: bool = undefined;
_ = nodeVtable(node).dom_node_is_same.?(node, other, &res);
return res;
}

pub fn nodeLookupPrefix(node: *Node, namespace: []const u8) ?[]const u8 {
var s: ?*String = undefined;
_ = nodeVtable(node).dom_node_lookup_prefix.?(node, stringFromData(namespace), &s);
if (s == null) {
return null;
}
return stringToData(s.?);
}

pub fn nodeLookupNamespaceURI(node: *Node, prefix: ?[]const u8) ?[]const u8 {
var s: ?*String = undefined;
_ = nodeVtable(node).dom_node_lookup_namespace.?(node, stringFromData(prefix.?), &s);
if (s == null) {
return null;
}
return stringToData(s.?);
}

pub fn nodeNormalize(node: *Node) void {
_ = nodeVtable(node).dom_node_normalize.?(node);
}

pub fn nodeRemoveChild(node: *Node, child: *Node) *Node {
var res: ?*Node = undefined;
_ = nodeVtable(node).dom_node_remove_child.?(node, child, &res);
return res.?;
}

pub fn nodeReplaceChild(node: *Node, new_child: *Node, old_child: *Node) *Node {
var res: ?*Node = undefined;
_ = nodeVtable(node).dom_node_replace_child.?(node, new_child, old_child, &res);
return res.?;
}

// CharacterData
pub const CharacterData = c.dom_characterdata;

Expand Down

0 comments on commit f1f787d

Please sign in to comment.