mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-22 04:34:44 +00:00
Fix 3 WPT cases for NodeIterator
- Prevent recursive filters - Rethrow on filter exception - Add no-op (as per spec) `detach`
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) {
|
const js_err: *const v8.Value = switch (err) {
|
||||||
|
error.TryCatchRethrow => return,
|
||||||
error.InvalidArgument => isolate.createTypeError("invalid argument"),
|
error.InvalidArgument => isolate.createTypeError("invalid argument"),
|
||||||
error.OutOfMemory => isolate.createError("out of memory"),
|
error.OutOfMemory => isolate.createError("out of memory"),
|
||||||
error.IllegalConstructor => isolate.createError("Illegal Contructor"),
|
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 {
|
pub fn call(self: *const Function, comptime T: type, args: anytype) !T {
|
||||||
var caught: js.TryCatch.Caught = undefined;
|
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 });
|
log.warn(.js, "call caught", .{ .err = err, .caught = caught });
|
||||||
return err;
|
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 {
|
pub fn callWithThis(self: *const Function, comptime T: type, this: anytype, args: anytype) !T {
|
||||||
var caught: js.TryCatch.Caught = undefined;
|
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 });
|
log.warn(.js, "callWithThis caught", .{ .err = err, .caught = caught });
|
||||||
return err;
|
return err;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tryCall(self: *const Function, comptime T: type, args: anytype, caught: *js.TryCatch.Caught) !T {
|
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 {
|
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.* = .{};
|
caught.* = .{};
|
||||||
const local = self.local;
|
const local = self.local;
|
||||||
|
|
||||||
@@ -145,6 +156,10 @@ pub fn _tryCallWithThis(self: *const Function, comptime T: type, this: anytype,
|
|||||||
defer try_catch.deinit();
|
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 {
|
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);
|
caught.* = try_catch.caughtOrError(local.call_arena, error.JSExecCallback);
|
||||||
return error.JSExecCallback;
|
return error.JSExecCallback;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ const std = @import("std");
|
|||||||
const js = @import("js.zig");
|
const js = @import("js.zig");
|
||||||
const v8 = js.v8;
|
const v8 = js.v8;
|
||||||
|
|
||||||
|
const IS_DEBUG = @import("builtin").mode == .Debug;
|
||||||
|
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
const TryCatch = @This();
|
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);
|
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 {
|
pub fn caught(self: TryCatch, allocator: Allocator) ?Caught {
|
||||||
if (!v8.v8__TryCatch__HasCaught(&self.handle)) {
|
if (self.hasCaught() == false) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ _what_to_show: u32,
|
|||||||
_filter: NodeFilter,
|
_filter: NodeFilter,
|
||||||
_reference_node: *Node,
|
_reference_node: *Node,
|
||||||
_pointer_before_reference_node: bool,
|
_pointer_before_reference_node: bool,
|
||||||
|
_active: bool = false,
|
||||||
|
|
||||||
pub fn init(root: *Node, what_to_show: u32, filter: ?FilterOpts, page: *Page) !*DOMNodeIterator {
|
pub fn init(root: *Node, what_to_show: u32, filter: ?FilterOpts, page: *Page) !*DOMNodeIterator {
|
||||||
const node_filter = try NodeFilter.init(filter);
|
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 {
|
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 node = self._reference_node;
|
||||||
var before_node = self._pointer_before_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 {
|
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 node = self._reference_node;
|
||||||
var before_node = self._pointer_before_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 {
|
fn filterNode(self: *const DOMNodeIterator, node: *Node, page: *Page) !i32 {
|
||||||
// First check whatToShow
|
// First check whatToShow
|
||||||
if (!NodeFilter.shouldShow(node, self._what_to_show)) {
|
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 whatToShow = bridge.accessor(DOMNodeIterator.getWhatToShow, null, .{});
|
||||||
pub const filter = bridge.accessor(DOMNodeIterator.getFilter, null, .{});
|
pub const filter = bridge.accessor(DOMNodeIterator.getFilter, null, .{});
|
||||||
|
|
||||||
pub const nextNode = bridge.function(DOMNodeIterator.nextNode, .{});
|
pub const nextNode = bridge.function(DOMNodeIterator.nextNode, .{ .dom_exception = true });
|
||||||
pub const previousNode = bridge.function(DOMNodeIterator.previousNode, .{});
|
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 {
|
pub fn acceptNode(self: *const NodeFilter, node: *Node, local: *const js.Local) !i32 {
|
||||||
const func = self._func orelse return FILTER_ACCEPT;
|
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 {
|
pub fn shouldShow(node: *const Node, what_to_show: u32) bool {
|
||||||
|
|||||||
Reference in New Issue
Block a user