@@ -21,6 +21,7 @@ const parser = @import("../netsurf.zig");
2121
2222const NodeFilter = @import ("node_filter.zig" ).NodeFilter ;
2323const Env = @import ("../env.zig" ).Env ;
24+ const SessionState = @import ("../env.zig" ).SessionState ;
2425
2526// https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker
2627pub const TreeWalker = struct {
@@ -29,8 +30,6 @@ pub const TreeWalker = struct {
2930 what_to_show : u32 ,
3031 filter : ? Env.Function ,
3132
32- depth : usize ,
33-
3433 pub const TreeWalkerOpts = union (enum ) {
3534 function : Env.Function ,
3635 object : struct { acceptNode : Env .Function },
@@ -51,14 +50,17 @@ pub const TreeWalker = struct {
5150 .current_node = node ,
5251 .what_to_show = what_to_show orelse NodeFilter ._SHOW_ALL ,
5352 .filter = filter_func ,
54- .depth = 0 ,
5553 };
5654 }
5755
58- fn verify_what_to_show (self : * const TreeWalker , node : * parser.Node ) ! bool {
56+ const VerifyResult = enum { accept , skip , reject };
57+
58+ fn verify (self : * const TreeWalker , node : * parser.Node ) ! VerifyResult {
5959 const node_type = try parser .nodeType (node );
6060 const what_to_show = self .what_to_show ;
61- return switch (node_type ) {
61+
62+ // Verify that we can show this node type.
63+ if (! switch (node_type ) {
6264 .attribute = > what_to_show & NodeFilter ._SHOW_ATTRIBUTE != 0 ,
6365 .cdata_section = > what_to_show & NodeFilter ._SHOW_CDATA_SECTION != 0 ,
6466 .comment = > what_to_show & NodeFilter ._SHOW_COMMENT != 0 ,
@@ -71,17 +73,18 @@ pub const TreeWalker = struct {
7173 .notation = > what_to_show & NodeFilter ._SHOW_NOTATION != 0 ,
7274 .processing_instruction = > what_to_show & NodeFilter ._SHOW_PROCESSING_INSTRUCTION != 0 ,
7375 .text = > what_to_show & NodeFilter ._SHOW_TEXT != 0 ,
74- };
75- }
76+ }) return .reject ;
7677
77- fn verify_filter ( self : * const TreeWalker , node : * parser.Node ) ! bool {
78+ // Verify that we aren't filtering it out.
7879 if (self .filter ) | f | {
7980 const filter = try f .call (u32 , .{node });
8081 return switch (filter ) {
81- NodeFilter ._FILTER_ACCEPT = > true ,
82- else = > false ,
82+ NodeFilter ._FILTER_ACCEPT = > .accept ,
83+ NodeFilter ._FILTER_REJECT = > .reject ,
84+ NodeFilter ._FILTER_SKIP = > .skip ,
85+ else = > .reject ,
8386 };
84- } else return true ;
87+ } else return .accept ;
8588 }
8689
8790 pub fn get_root (self : * TreeWalker ) * parser.Node {
@@ -100,88 +103,191 @@ pub const TreeWalker = struct {
100103 return self .filter ;
101104 }
102105
103- pub fn _firstChild (self : * TreeWalker ) ! ? * parser.Node {
104- const children = try parser .nodeGetChildNodes (self .current_node );
106+ pub fn set_currentNode (self : * TreeWalker , node : * parser.Node ) ! void {
107+ self .current_node = node ;
108+ }
109+
110+ fn firstChild (self : * const TreeWalker , node : * parser.Node ) ! ? * parser.Node {
111+ const children = try parser .nodeGetChildNodes (node );
105112 const child_count = try parser .nodeListLength (children );
106113
107114 for (0.. child_count ) | i | {
108115 const index : u32 = @intCast (i );
109116 const child = (try parser .nodeListItem (children , index )) orelse return null ;
110117
111- if (! try self .verify_what_to_show (child )) continue ;
112- if (! try self .verify_filter (child )) continue ;
113-
114- self .depth += 1 ;
115- self .current_node = child ;
116- return child ;
118+ switch (try self .verify (child )) {
119+ .accept = > return child ,
120+ .reject = > continue ,
121+ .skip = > if (try self .firstChild (child )) | gchild | return gchild ,
122+ }
117123 }
118124
119125 return null ;
120126 }
121127
122- pub fn _lastChild (self : * TreeWalker ) ! ? * parser.Node {
123- const children = try parser .nodeGetChildNodes (self . current_node );
128+ fn lastChild (self : * const TreeWalker , node : * parser.Node ) ! ? * parser.Node {
129+ const children = try parser .nodeGetChildNodes (node );
124130 const child_count = try parser .nodeListLength (children );
125131
126- for (0.. child_count ) | i | {
127- const index : u32 = @intCast (child_count - 1 - i );
132+ var index : u32 = child_count ;
133+ while (index > 0 ) {
134+ index -= 1 ;
128135 const child = (try parser .nodeListItem (children , index )) orelse return null ;
129136
130- if (! try self .verify_what_to_show (child )) continue ;
131- if (! try self .verify_filter (child )) continue ;
137+ switch (try self .verify (child )) {
138+ .accept = > return child ,
139+ .reject = > continue ,
140+ .skip = > if (try self .lastChild (child )) | gchild | return gchild ,
141+ }
142+ }
143+
144+ return null ;
145+ }
146+
147+ fn nextSibling (self : * const TreeWalker , node : * parser.Node ) ! ? * parser.Node {
148+ var current = node ;
132149
133- self .depth += 1 ;
150+ while (true ) {
151+ current = (try parser .nodeNextSibling (current )) orelse return null ;
152+
153+ switch (try self .verify (current )) {
154+ .accept = > return current ,
155+ .skip , .reject = > continue ,
156+ }
157+ }
158+
159+ return null ;
160+ }
161+
162+ fn previousSibling (self : * const TreeWalker , node : * parser.Node ) ! ? * parser.Node {
163+ var current = node ;
164+
165+ while (true ) {
166+ current = (try parser .nodePreviousSibling (current )) orelse return null ;
167+
168+ switch (try self .verify (current )) {
169+ .accept = > return current ,
170+ .skip , .reject = > continue ,
171+ }
172+ }
173+
174+ return null ;
175+ }
176+
177+ fn parentNode (self : * const TreeWalker , node : * parser.Node ) ! ? * parser.Node {
178+ if (self .root == node ) return null ;
179+
180+ var current = node ;
181+ while (true ) {
182+ if (current == self .root ) return null ;
183+ current = (try parser .nodeParentNode (current )) orelse return null ;
184+
185+ switch (try self .verify (current )) {
186+ .accept = > return current ,
187+ .reject , .skip = > continue ,
188+ }
189+ }
190+ }
191+
192+ pub fn _firstChild (self : * TreeWalker ) ! ? * parser.Node {
193+ if (try self .firstChild (self .current_node )) | child | {
134194 self .current_node = child ;
135195 return child ;
136196 }
137197
138198 return null ;
139199 }
140200
141- pub fn _nextNode (self : * TreeWalker ) ! ? * parser.Node {
142- return self ._firstChild ();
201+ pub fn _lastChild (self : * TreeWalker ) ! ? * parser.Node {
202+ if (try self .lastChild (self .current_node )) | child | {
203+ self .current_node = child ;
204+ return child ;
205+ }
206+
207+ return null ;
143208 }
144209
145- pub fn _nextSibling (self : * TreeWalker ) ! ? * parser.Node {
210+ pub fn _nextNode (self : * TreeWalker ) ! ? * parser.Node {
211+ if (try self .firstChild (self .current_node )) | child | {
212+ self .current_node = child ;
213+ return child ;
214+ }
215+
146216 var current = self .current_node ;
217+ while (current != self .root ) {
218+ if (try self .nextSibling (current )) | sibling | {
219+ self .current_node = sibling ;
220+ return sibling ;
221+ }
147222
148- while (true ) {
149- current = (try parser .nodeNextSibling (current )) orelse return null ;
150- if (! try self .verify_what_to_show (current )) continue ;
151- if (! try self .verify_filter (current )) continue ;
152- break ;
223+ current = (try parser .nodeParentNode (current )) orelse break ;
153224 }
154225
155- return current ;
226+ return null ;
156227 }
157228
158- pub fn _parentNode (self : * TreeWalker ) ! ? * parser.Node {
159- if (self .depth == 0 ) return null ;
229+ pub fn _nextSibling (self : * TreeWalker ) ! ? * parser.Node {
230+ if (try self .nextSibling (self .current_node )) | sibling | {
231+ self .current_node = sibling ;
232+ return sibling ;
233+ }
160234
161- const parent = (try parser .nodeParentNode (self .current_node )) orelse return null ;
235+ return null ;
236+ }
162237
163- if (! try self .verify_what_to_show (parent )) return null ;
164- if (! try self .verify_filter (parent )) return null ;
238+ pub fn _parentNode (self : * TreeWalker ) ! ? * parser.Node {
239+ if (try self .parentNode (self .current_node )) | parent | {
240+ self .current_node = parent ;
241+ return parent ;
242+ }
165243
166- self .depth -= 1 ;
167- self .current_node = parent ;
168- return parent ;
244+ return null ;
169245 }
170246
171247 pub fn _previousNode (self : * TreeWalker ) ! ? * parser.Node {
172- return self ._parentNode ();
248+ var current = self .current_node ;
249+ while (try parser .nodePreviousSibling (current )) | previous | {
250+ current = previous ;
251+
252+ switch (try self .verify (current )) {
253+ .accept = > {
254+ // Get last child if it has one.
255+ if (try self .lastChild (current )) | child | {
256+ self .current_node = child ;
257+ return child ;
258+ }
259+
260+ // Otherwise, this node is our previous one.
261+ self .current_node = current ;
262+ return current ;
263+ },
264+ .reject = > continue ,
265+ .skip = > {
266+ // Get last child if it has one.
267+ if (try self .lastChild (current )) | child | {
268+ self .current_node = child ;
269+ return child ;
270+ }
271+ },
272+ }
273+ }
274+
275+ if (current != self .root ) {
276+ if (try self .parentNode (current )) | parent | {
277+ self .current_node = parent ;
278+ return parent ;
279+ }
280+ }
281+
282+ return null ;
173283 }
174284
175285 pub fn _previousSibling (self : * TreeWalker ) ! ? * parser.Node {
176- var current = self .current_node ;
177-
178- while (true ) {
179- current = (try parser .nodePreviousSibling (current )) orelse return null ;
180- if (! try self .verify_what_to_show (current )) continue ;
181- if (! try self .verify_filter (current )) continue ;
182- break ;
286+ if (try self .previousSibling (self .current_node )) | sibling | {
287+ self .current_node = sibling ;
288+ return sibling ;
183289 }
184290
185- return current ;
291+ return null ;
186292 }
187293};
0 commit comments