Skip to content

Commit 152d0fd

Browse files
committed
add TreeWalker
1 parent 6506fa7 commit 152d0fd

File tree

3 files changed

+103
-0
lines changed

3 files changed

+103
-0
lines changed

src/browser/dom/document.zig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ const css = @import("css.zig");
3030

3131
const Element = @import("element.zig").Element;
3232
const ElementUnion = @import("element.zig").Union;
33+
const TreeWalker = @import("tree_walker.zig").TreeWalker;
34+
35+
const Env = @import("../env.zig").Env;
3336

3437
const DOMImplementation = @import("implementation.zig").DOMImplementation;
3538

@@ -238,6 +241,10 @@ pub const Document = struct {
238241
pub fn _replaceChildren(self: *parser.Document, nodes: []const Node.NodeOrText) !void {
239242
return Node.replaceChildren(parser.documentToNode(self), nodes);
240243
}
244+
245+
pub fn _createTreeWalker(_: *parser.Document, root: *parser.Node, what_to_show: ?u32, filter: ?Env.Callback) TreeWalker {
246+
return TreeWalker.init(root, what_to_show, filter);
247+
}
241248
};
242249

243250
const testing = @import("../../testing.zig");

src/browser/dom/dom.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const Node = @import("node.zig");
2626
const MutationObserver = @import("mutation_observer.zig");
2727
const IntersectionObserver = @import("intersection_observer.zig");
2828
const DOMParser = @import("dom_parser.zig").DOMParser;
29+
const TreeWalker = @import("tree_walker.zig").TreeWalker;
2930

3031
pub const Interfaces = .{
3132
DOMException,
@@ -39,4 +40,5 @@ pub const Interfaces = .{
3940
MutationObserver.Interfaces,
4041
IntersectionObserver.Interfaces,
4142
DOMParser,
43+
TreeWalker,
4244
};

src/browser/dom/tree_walker.zig

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Copyright (C) 2023-2024 Lightpanda (Selecy SAS)
2+
//
3+
// Francis Bouvier <[email protected]>
4+
// Pierre Tachoire <[email protected]>
5+
//
6+
// This program is free software: you can redistribute it and/or modify
7+
// it under the terms of the GNU Affero General Public License as
8+
// published by the Free Software Foundation, either version 3 of the
9+
// License, or (at your option) any later version.
10+
//
11+
// This program is distributed in the hope that it will be useful,
12+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
// GNU Affero General Public License for more details.
15+
//
16+
// You should have received a copy of the GNU Affero General Public License
17+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
18+
19+
const std = @import("std");
20+
const parser = @import("../netsurf.zig");
21+
22+
const NodeFilter = @import("node_filter.zig").NodeFilter;
23+
const Env = @import("../env.zig").Env;
24+
25+
// https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker
26+
pub const TreeWalker = struct {
27+
root: *parser.Node,
28+
current_node: *parser.Node,
29+
what_to_show: u32,
30+
filter: ?Env.Callback,
31+
32+
pub fn init(node: *parser.Node, what_to_show: ?u32, filter: ?Env.Callback) TreeWalker {
33+
return .{
34+
.root = node,
35+
.current_node = node,
36+
.what_to_show = what_to_show orelse NodeFilter._SHOW_ALL,
37+
.filter = filter,
38+
};
39+
}
40+
41+
pub fn get_root(self: *TreeWalker) *parser.Node {
42+
return self.root;
43+
}
44+
45+
pub fn get_currentNode(self: *TreeWalker) *parser.Node {
46+
return self.current_node;
47+
}
48+
49+
pub fn get_whatToShow(self: *TreeWalker) u32 {
50+
return self.what_to_show;
51+
}
52+
53+
pub fn get_filter(self: *TreeWalker) ?Env.Callback {
54+
return self.filter;
55+
}
56+
57+
pub fn _firstChild(self: *TreeWalker) ?*parser.Node {
58+
const first_child = parser.nodeFirstChild(self.current_node) catch return null;
59+
self.current_node = first_child orelse return null;
60+
return first_child;
61+
}
62+
63+
pub fn _lastChild(self: *TreeWalker) ?*parser.Node {
64+
const last_child = parser.nodeLastChild(self.current_node) catch return null;
65+
self.current_node = last_child orelse return null;
66+
return last_child;
67+
}
68+
69+
pub fn _nextNode(self: *TreeWalker) ?*parser.Node {
70+
return self._firstChild();
71+
}
72+
73+
pub fn _nextSibling(self: *TreeWalker) ?*parser.Node {
74+
const next_sibling = parser.nodeNextSibling(self.current_node) catch return null;
75+
self.current_node = next_sibling orelse return null;
76+
return next_sibling;
77+
}
78+
79+
pub fn _parentNode(self: *TreeWalker) ?*parser.Node {
80+
const parent = parser.nodeParentNode(self.current_node) catch return null;
81+
self.current_node = parent orelse return null;
82+
return parent;
83+
}
84+
85+
pub fn _previousNode(self: *TreeWalker) ?*parser.Node {
86+
return self._parentNode();
87+
}
88+
89+
pub fn _previousSibling(self: *TreeWalker) ?*parser.Node {
90+
const previous_sibling = parser.nodePreviousSibling(self.current_node) catch return null;
91+
self.current_node = previous_sibling orelse return null;
92+
return previous_sibling;
93+
}
94+
};

0 commit comments

Comments
 (0)