Skip to content

Commit eae9f9c

Browse files
authored
Merge pull request #664 from lightpanda-io/treewalker
Add TreeWalker
2 parents d2c13ed + 97d414a commit eae9f9c

File tree

15 files changed

+436
-77
lines changed

15 files changed

+436
-77
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: ?TreeWalker.TreeWalkerOpts) !TreeWalker {
246+
return try TreeWalker.init(root, what_to_show, filter);
247+
}
241248
};
242249

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

src/browser/dom/dom.zig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ 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;
30+
const NodeFilter = @import("node_filter.zig").NodeFilter;
2931

3032
pub const Interfaces = .{
3133
DOMException,
@@ -39,4 +41,6 @@ pub const Interfaces = .{
3941
MutationObserver.Interfaces,
4042
IntersectionObserver.Interfaces,
4143
DOMParser,
44+
TreeWalker,
45+
NodeFilter,
4246
};

src/browser/dom/event_target.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ pub const EventTarget = struct {
5757
pub fn _addEventListener(
5858
self: *parser.EventTarget,
5959
typ: []const u8,
60-
cbk: Env.Callback,
60+
cbk: Env.Function,
6161
opts_: ?AddEventListenerOpts,
6262
state: *SessionState,
6363
) !void {
@@ -104,7 +104,7 @@ pub const EventTarget = struct {
104104
pub fn _removeEventListener(
105105
self: *parser.EventTarget,
106106
typ: []const u8,
107-
cbk: Env.Callback,
107+
cbk: Env.Function,
108108
capture: ?bool,
109109
// TODO: hanle EventListenerOptions
110110
// see #https://github.com/lightpanda-io/jsruntime-lib/issues/114

src/browser/dom/intersection_observer.zig

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,15 @@ const log = std.log.scoped(.events);
4040
// The returned Entries are phony, they always indicate full intersection.
4141
// https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver
4242
pub const IntersectionObserver = struct {
43-
callback: Env.Callback,
43+
callback: Env.Function,
4444
options: IntersectionObserverOptions,
4545
state: *SessionState,
4646

4747
observed_entries: std.ArrayListUnmanaged(IntersectionObserverEntry),
4848

4949
// new IntersectionObserver(callback)
5050
// new IntersectionObserver(callback, options) [not supported yet]
51-
pub fn constructor(callback: Env.Callback, options_: ?IntersectionObserverOptions, state: *SessionState) !IntersectionObserver {
51+
pub fn constructor(callback: Env.Function, options_: ?IntersectionObserverOptions, state: *SessionState) !IntersectionObserver {
5252
var options = IntersectionObserverOptions{
5353
.root = parser.documentToNode(parser.documentHTMLToDocument(state.window.document)),
5454
.rootMargin = "0px 0px 0px 0px",
@@ -85,8 +85,8 @@ pub const IntersectionObserver = struct {
8585
.options = &self.options,
8686
});
8787

88-
var result: Env.Callback.Result = undefined;
89-
self.callback.tryCall(.{self.observed_entries.items}, &result) catch {
88+
var result: Env.Function.Result = undefined;
89+
self.callback.tryCall(void, .{self.observed_entries.items}, &result) catch {
9090
log.err("intersection observer callback error: {s}", .{result.exception});
9191
log.debug("stack:\n{s}", .{result.stack orelse "???"});
9292
};

src/browser/dom/mutation_observer.zig

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@ const log = std.log.scoped(.events);
3636

3737
// WEB IDL https://dom.spec.whatwg.org/#interface-mutationobserver
3838
pub const MutationObserver = struct {
39-
cbk: Env.Callback,
39+
cbk: Env.Function,
4040
arena: Allocator,
4141

4242
// List of records which were observed. When the scopeEnds, we need to
4343
// execute our callback with it.
4444
observed: std.ArrayListUnmanaged(*MutationRecord),
4545

46-
pub fn constructor(cbk: Env.Callback, state: *SessionState) !MutationObserver {
46+
pub fn constructor(cbk: Env.Function, state: *SessionState) !MutationObserver {
4747
return .{
4848
.cbk = cbk,
4949
.observed = .{},
@@ -113,8 +113,8 @@ pub const MutationObserver = struct {
113113

114114
for (record) |r| {
115115
const records = [_]MutationRecord{r.*};
116-
var result: Env.Callback.Result = undefined;
117-
self.cbk.tryCall(.{records}, &result) catch {
116+
var result: Env.Function.Result = undefined;
117+
self.cbk.tryCall(void, .{records}, &result) catch {
118118
log.err("mutation observer callback error: {s}", .{result.exception});
119119
log.debug("stack:\n{s}", .{result.stack orelse "???"});
120120
};

src/browser/dom/node_filter.zig

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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+
21+
pub const NodeFilter = struct {
22+
pub const _FILTER_ACCEPT: u16 = 1;
23+
pub const _FILTER_REJECT: u16 = 2;
24+
pub const _FILTER_SKIP: u16 = 3;
25+
pub const _SHOW_ALL: u32 = std.math.maxInt(u32);
26+
pub const _SHOW_ELEMENT: u32 = 0b1;
27+
pub const _SHOW_ATTRIBUTE: u32 = 0b10;
28+
pub const _SHOW_TEXT: u32 = 0b100;
29+
pub const _SHOW_CDATA_SECTION: u32 = 0b1000;
30+
pub const _SHOW_ENTITY_REFERENCE: u32 = 0b10000;
31+
pub const _SHOW_ENTITY: u32 = 0b100000;
32+
pub const _SHOW_PROCESSING_INSTRUCTION: u32 = 0b1000000;
33+
pub const _SHOW_COMMENT: u32 = 0b10000000;
34+
pub const _SHOW_DOCUMENT: u32 = 0b100000000;
35+
pub const _SHOW_DOCUMENT_TYPE: u32 = 0b1000000000;
36+
pub const _SHOW_DOCUMENT_FRAGMENT: u32 = 0b10000000000;
37+
pub const _SHOW_NOTATION: u32 = 0b100000000000;
38+
};
39+
40+
const testing = @import("../../testing.zig");
41+
test "Browser.DOM.NodeFilter" {
42+
var runner = try testing.jsRunner(testing.tracking_allocator, .{});
43+
defer runner.deinit();
44+
45+
try runner.testCases(&.{
46+
.{ "NodeFilter.FILTER_ACCEPT", "1" },
47+
.{ "NodeFilter.FILTER_REJECT", "2" },
48+
.{ "NodeFilter.FILTER_SKIP", "3" },
49+
.{ "NodeFilter.SHOW_ALL", "4294967295" },
50+
.{ "NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT", "129" },
51+
}, .{});
52+
}

src/browser/dom/nodelist.zig

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const std = @import("std");
2121
const parser = @import("../netsurf.zig");
2222

2323
const JsThis = @import("../env.zig").JsThis;
24-
const Callback = @import("../env.zig").Callback;
24+
const Function = @import("../env.zig").Function;
2525

2626
const NodeUnion = @import("node.zig").Union;
2727
const Node = @import("node.zig").Node;
@@ -141,11 +141,11 @@ pub const NodeList = struct {
141141
// };
142142
// }
143143

144-
pub fn _forEach(self: *NodeList, cbk: Callback) !void { // TODO handle thisArg
144+
pub fn _forEach(self: *NodeList, cbk: Function) !void { // TODO handle thisArg
145145
for (self.nodes.items, 0..) |n, i| {
146146
const ii: u32 = @intCast(i);
147-
var result: Callback.Result = undefined;
148-
cbk.tryCall(.{ n, ii, self }, &result) catch {
147+
var result: Function.Result = undefined;
148+
cbk.tryCall(void, .{ n, ii, self }, &result) catch {
149149
log.err("callback error: {s}", .{result.exception});
150150
log.debug("stack:\n{s}", .{result.stack orelse "???"});
151151
};

src/browser/dom/token_list.zig

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const std = @import("std");
2121
const parser = @import("../netsurf.zig");
2222
const iterator = @import("../iterator/iterator.zig");
2323

24-
const Callback = @import("../env.zig").Callback;
24+
const Function = @import("../env.zig").Function;
2525
const JsObject = @import("../env.zig").JsObject;
2626
const DOMException = @import("exceptions.zig").DOMException;
2727

@@ -138,11 +138,11 @@ pub const DOMTokenList = struct {
138138
}
139139

140140
// TODO handle thisArg
141-
pub fn _forEach(self: *parser.TokenList, cbk: Callback, this_arg: JsObject) !void {
141+
pub fn _forEach(self: *parser.TokenList, cbk: Function, this_arg: JsObject) !void {
142142
var entries = _entries(self);
143143
while (try entries._next()) |entry| {
144-
var result: Callback.Result = undefined;
145-
cbk.tryCallWithThis(this_arg, .{ entry.@"1", entry.@"0", self }, &result) catch {
144+
var result: Function.Result = undefined;
145+
cbk.tryCallWithThis(void, this_arg, .{ entry.@"1", entry.@"0", self }, &result) catch {
146146
log.err("callback error: {s}", .{result.exception});
147147
log.debug("stack:\n{s}", .{result.stack orelse "???"});
148148
};

0 commit comments

Comments
 (0)