mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-02-04 06:23:45 +00:00
add named access on the Window object
This commit is contained in:
@@ -74,26 +74,23 @@ pub fn createContext(self: *ExecutionWorld, page: *Page, enter: bool) !*Context
|
||||
|
||||
const env = self.env;
|
||||
const isolate = env.isolate;
|
||||
const arena = self.context_arena.allocator();
|
||||
|
||||
var v8_context: v8.Context = blk: {
|
||||
var temp_scope: v8.HandleScope = undefined;
|
||||
v8.HandleScope.init(&temp_scope, isolate);
|
||||
defer temp_scope.deinit();
|
||||
|
||||
if (comptime IS_DEBUG) {
|
||||
// Getting this into the snapshot is tricky (anything involving the
|
||||
// global is tricky). Easier to do here, and in debug mode, we're
|
||||
// fine with paying the small perf hit.
|
||||
const js_global = v8.FunctionTemplate.initDefault(isolate);
|
||||
const global_template = js_global.getInstanceTemplate();
|
||||
// Creates a global template that inherits from Window.
|
||||
const global_template = @import("Snapshot.zig").createGlobalTemplate(isolate, env.templates);
|
||||
|
||||
global_template.setNamedProperty(v8.NamedPropertyHandlerConfiguration{
|
||||
.getter = unknownPropertyCallback,
|
||||
.flags = v8.PropertyHandlerFlags.NonMasking | v8.PropertyHandlerFlags.OnlyInterceptStrings,
|
||||
}, null);
|
||||
}
|
||||
// Add the named property handler
|
||||
global_template.setNamedProperty(v8.NamedPropertyHandlerConfiguration{
|
||||
.getter = unknownPropertyCallback,
|
||||
.flags = v8.PropertyHandlerFlags.NonMasking | v8.PropertyHandlerFlags.OnlyInterceptStrings,
|
||||
}, v8.External.init(isolate, page));
|
||||
|
||||
const context_local = v8.Context.init(isolate, null, null);
|
||||
const context_local = v8.Context.init(isolate, global_template, null);
|
||||
const v8_context = v8.Persistent(v8.Context).init(isolate, context_local).castToContext();
|
||||
break :blk v8_context;
|
||||
};
|
||||
@@ -124,7 +121,7 @@ pub fn createContext(self: *ExecutionWorld, page: *Page, enter: bool) !*Context
|
||||
.handle_scope = handle_scope,
|
||||
.script_manager = &page._script_manager,
|
||||
.call_arena = page.call_arena,
|
||||
.arena = self.context_arena.allocator(),
|
||||
.arena = arena,
|
||||
};
|
||||
|
||||
var context = &self.context.?;
|
||||
@@ -159,9 +156,13 @@ pub fn resumeExecution(self: *const ExecutionWorld) void {
|
||||
|
||||
pub fn unknownPropertyCallback(c_name: ?*const v8.C_Name, raw_info: ?*const v8.C_PropertyCallbackInfo) callconv(.c) u8 {
|
||||
const info = v8.PropertyCallbackInfo.initFromV8(raw_info);
|
||||
const context = Context.fromIsolate(info.getIsolate());
|
||||
|
||||
const property = context.valueToString(.{ .handle = c_name.? }, .{}) catch "???";
|
||||
const data_value = info.getData();
|
||||
const external = data_value.castTo(v8.External);
|
||||
const page: *Page = @ptrCast(@alignCast(external.get()));
|
||||
|
||||
const context = Context.fromIsolate(info.getIsolate());
|
||||
const maybe_property: ?[]u8 = context.valueToString(.{ .handle = c_name.? }, .{}) catch null;
|
||||
|
||||
const ignored = std.StaticStringMap(void).initComptime(.{
|
||||
.{ "process", {} },
|
||||
@@ -185,12 +186,25 @@ pub fn unknownPropertyCallback(c_name: ?*const v8.C_Name, raw_info: ?*const v8.C
|
||||
.{ "CLOSURE_FLAGS", {} },
|
||||
});
|
||||
|
||||
if (!ignored.has(property)) {
|
||||
log.debug(.unknown_prop, "unkown global property", .{
|
||||
.info = "but the property can exist in pure JS",
|
||||
.stack = context.stackTrace() catch "???",
|
||||
.property = property,
|
||||
});
|
||||
if (maybe_property) |prop| {
|
||||
if (!ignored.has(prop)) {
|
||||
const document = page.document;
|
||||
|
||||
if (document.getElementById(prop)) |el| {
|
||||
const js_value = context.zigValueToJs(el, .{}) catch {
|
||||
return v8.Intercepted.No;
|
||||
};
|
||||
|
||||
info.getReturnValue().set(js_value);
|
||||
return v8.Intercepted.Yes;
|
||||
}
|
||||
|
||||
log.debug(.unknown_prop, "unknown global property", .{
|
||||
.info = "but the property can exist in pure JS",
|
||||
.stack = context.stackTrace() catch "???",
|
||||
.property = prop,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return v8.Intercepted.No;
|
||||
|
||||
@@ -54,7 +54,7 @@ pub fn set(self: Object, key: []const u8, value: anytype, opts: SetOpts) error{
|
||||
const context = self.context;
|
||||
|
||||
const js_key = v8.String.initUtf8(context.isolate, key);
|
||||
const js_value = try context.zigValueToJs(value);
|
||||
const js_value = try context.zigValueToJs(value, .{});
|
||||
|
||||
const res = self.js_obj.defineOwnProperty(context.v8_context, js_key.toName(), js_value, @bitCast(opts)) orelse false;
|
||||
if (!res) {
|
||||
|
||||
@@ -113,6 +113,17 @@ fn isValid(self: Snapshot) bool {
|
||||
return v8.SnapshotCreator.startupDataIsValid(self.startup_data);
|
||||
}
|
||||
|
||||
pub fn createGlobalTemplate(isolate: v8.Isolate, templates: []const v8.FunctionTemplate) v8.ObjectTemplate {
|
||||
// Set up the global template to inherit from Window's template
|
||||
// This way the global object gets all Window properties through inheritance
|
||||
const js_global = v8.FunctionTemplate.initDefault(isolate);
|
||||
js_global.setClassName(v8.String.initUtf8(isolate, "Window"));
|
||||
// Find Window in JsApis by name (avoids circular import)
|
||||
const window_index = comptime bridge.JsApiLookup.getId(Window.JsApi);
|
||||
js_global.inherit(templates[window_index]);
|
||||
return js_global.getInstanceTemplate();
|
||||
}
|
||||
|
||||
pub fn create(allocator: Allocator) !Snapshot {
|
||||
var external_references = collectExternalReferences();
|
||||
|
||||
@@ -154,14 +165,7 @@ pub fn create(allocator: Allocator) !Snapshot {
|
||||
|
||||
// Set up the global template to inherit from Window's template
|
||||
// This way the global object gets all Window properties through inheritance
|
||||
const js_global = v8.FunctionTemplate.initDefault(isolate);
|
||||
js_global.setClassName(v8.String.initUtf8(isolate, "Window"));
|
||||
|
||||
// Find Window in JsApis by name (avoids circular import)
|
||||
const window_index = comptime bridge.JsApiLookup.getId(Window.JsApi);
|
||||
js_global.inherit(templates[window_index]);
|
||||
|
||||
const global_template = js_global.getInstanceTemplate();
|
||||
const global_template = createGlobalTemplate(isolate, templates[0..]);
|
||||
|
||||
const context = v8.Context.init(isolate, global_template, null);
|
||||
context.enter();
|
||||
|
||||
21
src/browser/tests/window/named_access.html
Normal file
21
src/browser/tests/window/named_access.html
Normal file
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<script src="../testing.js"></script>
|
||||
|
||||
<div id=i></div>
|
||||
<div id=testDiv></div>
|
||||
<span id=mySpan></span>
|
||||
<p id=paragraph></p>
|
||||
|
||||
<script id=named_access_global>
|
||||
testing.expectEqual('i', i.id);
|
||||
testing.expectEqual('testDiv',testDiv.id);
|
||||
testing.expectEqual('mySpan', mySpan.id);
|
||||
testing.expectEqual('paragraph', paragraph.id);
|
||||
</script>
|
||||
|
||||
<script id=named_access_window>
|
||||
testing.expectEqual('i', window.i.id);
|
||||
testing.expectEqual('testDiv', window.testDiv.id);
|
||||
testing.expectEqual('mySpan', window.mySpan.id);
|
||||
testing.expectEqual('paragraph', window.paragraph.id);
|
||||
</script>
|
||||
Reference in New Issue
Block a user