From 202ee1646d7f0e60bc80f006f9ae02cc7b090d55 Mon Sep 17 00:00:00 2001 From: Francis Bouvier Date: Mon, 2 Oct 2023 17:25:32 +0200 Subject: [PATCH] characterdata: add nextElementSibling getter Signed-off-by: Francis Bouvier --- src/dom/character_data.zig | 31 +++++++++++++++++++++++++------ src/netsurf.zig | 19 +++++++++++++++++++ 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/dom/character_data.zig b/src/dom/character_data.zig index fefd77f7..81797c07 100644 --- a/src/dom/character_data.zig +++ b/src/dom/character_data.zig @@ -10,6 +10,7 @@ const parser = @import("../netsurf.zig"); const Node = @import("node.zig").Node; const Comment = @import("comment.zig").Comment; const Text = @import("text.zig").Text; +const HTMLElem = @import("../html/elements.zig"); pub const CharacterData = struct { pub const Self = parser.CharacterData; @@ -25,6 +26,14 @@ pub const CharacterData = struct { return parser.characterDataLength(self); } + pub fn get_nextElementSibling(self: *parser.CharacterData) ?HTMLElem.Union { + const res = parser.nodeNextElementSibling(parser.characterDataToNode(self)); + if (res == null) { + return null; + } + return HTMLElem.toInterface(HTMLElem.Union, res.?); + } + // Read/Write attributes pub fn get_data(self: *parser.CharacterData) []const u8 { @@ -53,20 +62,30 @@ pub fn testExecFn( comptime _: []jsruntime.API, ) !void { var get_data = [_]Case{ - .{ .src = "let cdata_t = document.getElementById('link').firstChild", .ex = "undefined" }, - .{ .src = "cdata_t.data", .ex = "OK" }, + .{ .src = "let link = document.getElementById('link')", .ex = "undefined" }, + .{ .src = "let cdata = link.firstChild", .ex = "undefined" }, + .{ .src = "cdata.data", .ex = "OK" }, }; try checkCases(js_env, &get_data); var set_data = [_]Case{ - .{ .src = "cdata_t.data = 'OK modified'", .ex = "OK modified" }, - .{ .src = "cdata_t.data === 'OK modified'", .ex = "true" }, - .{ .src = "cdata_t.data = 'OK'", .ex = "OK" }, + .{ .src = "cdata.data = 'OK modified'", .ex = "OK modified" }, + .{ .src = "cdata.data === 'OK modified'", .ex = "true" }, + .{ .src = "cdata.data = 'OK'", .ex = "OK" }, }; try checkCases(js_env, &set_data); var get_length = [_]Case{ - .{ .src = "cdata_t.length === 2", .ex = "true" }, + .{ .src = "cdata.length === 2", .ex = "true" }, }; try checkCases(js_env, &get_length); + + var get_next_elem_sibling = [_]Case{ + .{ .src = "cdata.nextElementSibling === null", .ex = "true" }, + // create a next element + .{ .src = "let next = document.createElement('a')", .ex = "undefined" }, + .{ .src = "link.appendChild(next, cdata) !== undefined", .ex = "true" }, + .{ .src = "cdata.nextElementSibling.localName === 'a' ", .ex = "true" }, + }; + try checkCases(js_env, &get_next_elem_sibling); } diff --git a/src/netsurf.zig b/src/netsurf.zig index 26eac06e..f6a7285a 100644 --- a/src/netsurf.zig +++ b/src/netsurf.zig @@ -267,6 +267,21 @@ pub fn nodeNextSibling(node: *Node) ?*Node { return res; } +pub fn nodeNextElementSibling(node: *Node) ?*Element { + var n = node; + while (true) { + const next = nodeNextSibling(n); + if (next == null) { + return null; + } + if (nodeType(next.?) == .element) { + return @as(*Element, @ptrCast(next.?)); + } + n = next.?; + } + return null; +} + pub fn nodePreviousSibling(node: *Node) ?*Node { var res: ?*Node = undefined; _ = nodeVtable(node).dom_node_get_previous_sibling.?(node, &res); @@ -424,6 +439,10 @@ fn characterDataVtable(data: *CharacterData) c.dom_characterdata_vtable { return getVtable(c.dom_characterdata_vtable, CharacterData, data); } +pub inline fn characterDataToNode(cdata: *CharacterData) *Node { + return @as(*Node, @ptrCast(cdata)); +} + pub fn characterDataData(cdata: *CharacterData) []const u8 { var s: ?*String = undefined; _ = characterDataVtable(cdata).dom_characterdata_get_data.?(cdata, &s);