mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-22 04:34:44 +00:00
Merge pull request #1503 from lightpanda-io/node_iterator
Fix 3 WPT cases for NodeIterator
This commit is contained in:
@@ -336,6 +336,7 @@ fn handleError(self: *Caller, comptime T: type, comptime F: type, err: anyerror,
|
||||
}
|
||||
|
||||
const js_err: *const v8.Value = switch (err) {
|
||||
error.TryCatchRethrow => return,
|
||||
error.InvalidArgument => isolate.createTypeError("invalid argument"),
|
||||
error.OutOfMemory => isolate.createError("out of memory"),
|
||||
error.IllegalConstructor => isolate.createError("Illegal Contructor"),
|
||||
|
||||
@@ -69,7 +69,15 @@ pub fn newInstance(self: *const Function, caught: *js.TryCatch.Caught) !js.Objec
|
||||
|
||||
pub fn call(self: *const Function, comptime T: type, args: anytype) !T {
|
||||
var caught: js.TryCatch.Caught = undefined;
|
||||
return self._tryCallWithThis(T, self.getThis(), args, &caught) catch |err| {
|
||||
return self._tryCallWithThis(T, self.getThis(), args, &caught, .{}) catch |err| {
|
||||
log.warn(.js, "call caught", .{ .err = err, .caught = caught });
|
||||
return err;
|
||||
};
|
||||
}
|
||||
|
||||
pub fn callRethrow(self: *const Function, comptime T: type, args: anytype) !T {
|
||||
var caught: js.TryCatch.Caught = undefined;
|
||||
return self._tryCallWithThis(T, self.getThis(), args, &caught, .{ .rethrow = true }) catch |err| {
|
||||
log.warn(.js, "call caught", .{ .err = err, .caught = caught });
|
||||
return err;
|
||||
};
|
||||
@@ -77,21 +85,24 @@ pub fn call(self: *const Function, comptime T: type, args: anytype) !T {
|
||||
|
||||
pub fn callWithThis(self: *const Function, comptime T: type, this: anytype, args: anytype) !T {
|
||||
var caught: js.TryCatch.Caught = undefined;
|
||||
return self._tryCallWithThis(T, this, args, &caught) catch |err| {
|
||||
return self._tryCallWithThis(T, this, args, &caught, .{}) catch |err| {
|
||||
log.warn(.js, "callWithThis caught", .{ .err = err, .caught = caught });
|
||||
return err;
|
||||
};
|
||||
}
|
||||
|
||||
pub fn tryCall(self: *const Function, comptime T: type, args: anytype, caught: *js.TryCatch.Caught) !T {
|
||||
return self._tryCallWithThis(T, self.getThis(), args, caught);
|
||||
return self._tryCallWithThis(T, self.getThis(), args, caught, .{});
|
||||
}
|
||||
|
||||
pub fn tryCallWithThis(self: *const Function, comptime T: type, this: anytype, args: anytype, caught: *js.TryCatch.Caught) !T {
|
||||
return self._tryCallWithThis(T, this, args, caught);
|
||||
return self._tryCallWithThis(T, this, args, caught, .{});
|
||||
}
|
||||
|
||||
pub fn _tryCallWithThis(self: *const Function, comptime T: type, this: anytype, args: anytype, caught: *js.TryCatch.Caught) !T {
|
||||
const CallOpts = struct {
|
||||
rethrow: bool = false,
|
||||
};
|
||||
fn _tryCallWithThis(self: *const Function, comptime T: type, this: anytype, args: anytype, caught: *js.TryCatch.Caught, comptime opts: CallOpts) !T {
|
||||
caught.* = .{};
|
||||
const local = self.local;
|
||||
|
||||
@@ -145,6 +156,10 @@ pub fn _tryCallWithThis(self: *const Function, comptime T: type, this: anytype,
|
||||
defer try_catch.deinit();
|
||||
|
||||
const handle = v8.v8__Function__Call(self.handle, local.handle, js_this.handle, @as(c_int, @intCast(js_args.len)), c_args) orelse {
|
||||
if ((comptime opts.rethrow) and try_catch.hasCaught()) {
|
||||
try_catch.rethrow();
|
||||
return error.TryCatchRethrow;
|
||||
}
|
||||
caught.* = try_catch.caughtOrError(local.call_arena, error.JSExecCallback);
|
||||
return error.JSExecCallback;
|
||||
};
|
||||
|
||||
@@ -20,6 +20,8 @@ const std = @import("std");
|
||||
const js = @import("js.zig");
|
||||
const v8 = js.v8;
|
||||
|
||||
const IS_DEBUG = @import("builtin").mode == .Debug;
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const TryCatch = @This();
|
||||
@@ -32,8 +34,19 @@ pub fn init(self: *TryCatch, l: *const js.Local) void {
|
||||
v8.v8__TryCatch__CONSTRUCT(&self.handle, l.isolate.handle);
|
||||
}
|
||||
|
||||
pub fn hasCaught(self: TryCatch) bool {
|
||||
return v8.v8__TryCatch__HasCaught(&self.handle);
|
||||
}
|
||||
|
||||
pub fn rethrow(self: *TryCatch) void {
|
||||
if (comptime IS_DEBUG) {
|
||||
std.debug.assert(self.hasCaught());
|
||||
}
|
||||
_ = v8.v8__TryCatch__ReThrow(&self.handle);
|
||||
}
|
||||
|
||||
pub fn caught(self: TryCatch, allocator: Allocator) ?Caught {
|
||||
if (!v8.v8__TryCatch__HasCaught(&self.handle)) {
|
||||
if (self.hasCaught() == false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ _what_to_show: u32,
|
||||
_filter: NodeFilter,
|
||||
_reference_node: *Node,
|
||||
_pointer_before_reference_node: bool,
|
||||
_active: bool = false,
|
||||
|
||||
pub fn init(root: *Node, what_to_show: u32, filter: ?FilterOpts, page: *Page) !*DOMNodeIterator {
|
||||
const node_filter = try NodeFilter.init(filter);
|
||||
@@ -64,6 +65,13 @@ pub fn getFilter(self: *const DOMNodeIterator) ?FilterOpts {
|
||||
}
|
||||
|
||||
pub fn nextNode(self: *DOMNodeIterator, page: *Page) !?*Node {
|
||||
if (self._active) {
|
||||
return error.InvalidStateError;
|
||||
}
|
||||
|
||||
self._active = true;
|
||||
defer self._active = false;
|
||||
|
||||
var node = self._reference_node;
|
||||
var before_node = self._pointer_before_reference_node;
|
||||
|
||||
@@ -95,6 +103,13 @@ pub fn nextNode(self: *DOMNodeIterator, page: *Page) !?*Node {
|
||||
}
|
||||
|
||||
pub fn previousNode(self: *DOMNodeIterator, page: *Page) !?*Node {
|
||||
if (self._active) {
|
||||
return error.InvalidStateError;
|
||||
}
|
||||
|
||||
self._active = true;
|
||||
defer self._active = false;
|
||||
|
||||
var node = self._reference_node;
|
||||
var before_node = self._pointer_before_reference_node;
|
||||
|
||||
@@ -119,6 +134,10 @@ pub fn previousNode(self: *DOMNodeIterator, page: *Page) !?*Node {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn detach(_: *const DOMNodeIterator) void {
|
||||
// no-op legacy
|
||||
}
|
||||
|
||||
fn filterNode(self: *const DOMNodeIterator, node: *Node, page: *Page) !i32 {
|
||||
// First check whatToShow
|
||||
if (!NodeFilter.shouldShow(node, self._what_to_show)) {
|
||||
@@ -181,6 +200,7 @@ pub const JsApi = struct {
|
||||
pub const whatToShow = bridge.accessor(DOMNodeIterator.getWhatToShow, null, .{});
|
||||
pub const filter = bridge.accessor(DOMNodeIterator.getFilter, null, .{});
|
||||
|
||||
pub const nextNode = bridge.function(DOMNodeIterator.nextNode, .{});
|
||||
pub const previousNode = bridge.function(DOMNodeIterator.previousNode, .{});
|
||||
pub const nextNode = bridge.function(DOMNodeIterator.nextNode, .{ .dom_exception = true });
|
||||
pub const previousNode = bridge.function(DOMNodeIterator.previousNode, .{ .dom_exception = true });
|
||||
pub const detach = bridge.function(DOMNodeIterator.detach, .{});
|
||||
};
|
||||
|
||||
@@ -67,7 +67,7 @@ pub const SHOW_NOTATION: u32 = 0x800;
|
||||
|
||||
pub fn acceptNode(self: *const NodeFilter, node: *Node, local: *const js.Local) !i32 {
|
||||
const func = self._func orelse return FILTER_ACCEPT;
|
||||
return local.toLocal(func).call(i32, .{node});
|
||||
return local.toLocal(func).callRethrow(i32, .{node});
|
||||
}
|
||||
|
||||
pub fn shouldShow(node: *const Node, what_to_show: u32) bool {
|
||||
|
||||
Reference in New Issue
Block a user