Merge pull request #2224 from lightpanda-io/console_own_properties

Define v8 functions directly on console instance.
This commit is contained in:
Karl Seguin
2026-04-24 16:34:46 +08:00
committed by GitHub
8 changed files with 37 additions and 7 deletions

View File

@@ -721,7 +721,6 @@ fn scheduleNavigationWithArena(originator: *Frame, arena: Allocator, request_url
if (!opts.force and URL.eqlDocument(target.url, resolved_url)) {
target.url = try target.arena.dupeZ(u8, resolved_url);
target.window._location = try Location.init(target.url, target);
target.document._location = target.window._location;
if (target.parent == null) {
try session.navigation.updateEntries(target.url, opts.kind, target, true);
}

View File

@@ -587,6 +587,12 @@ fn attachClass(comptime JsApi: type, isolate: *v8.Isolate, template: *const v8.F
const prototype = v8.v8__FunctionTemplate__PrototypeTemplate(template);
const signature = v8.v8__Signature__New(isolate, template);
// Namespace objects (e.g. console) expose their members as own properties
// of each instance rather than via the prototype, so Object.entries(...)
// returns them. See https://console.spec.whatwg.org/#console-namespace.
const own_properties = @hasDecl(JsApi.Meta, "own_properties") and JsApi.Meta.own_properties;
const member_template = if (own_properties) instance else prototype;
const declarations = @typeInfo(JsApi).@"struct".decls;
var has_named_index_getter = false;
@@ -652,7 +658,7 @@ fn attachClass(comptime JsApi: type, isolate: *v8.Isolate, template: *const v8.F
if (value.static) {
v8.v8__Template__Set(@ptrCast(template), js_name, @ptrCast(function_template), v8.None);
} else {
v8.v8__Template__Set(@ptrCast(prototype), js_name, @ptrCast(function_template), v8.None);
v8.v8__Template__Set(@ptrCast(member_template), js_name, @ptrCast(function_template), v8.None);
}
},
bridge.Indexed => {

View File

@@ -1,6 +1,16 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=entries>
{
const entries = Object.entries(console);
testing.expectEqual(true, entries.length > 10);
const log_entry = entries.find((e) => e[0] == 'log');
testing.expectEqual(true, log_entry[1] === console.log);
}
</script>
<script id="time">
// should not crash
console.time();

View File

@@ -7,6 +7,11 @@
testing.expectEqual('function', typeof CSS.supports);
</script>
<script id="entries">
const entries = Object.entries(CSS);
testing.expectEqual(true, entries.length >= 2);
</script>
<script id="escape_basic">
{
testing.expectEqual('hello', CSS.escape('hello'));

View File

@@ -165,6 +165,11 @@ pub const JsApi = struct {
pub const Meta = struct {
pub const name = "Css";
// Per the CSSOM spec, CSS is a namespace object — members are own
// properties so Object.entries(CSS) returns them.
pub const own_properties = true;
pub const prototype_chain = bridge.prototypeChain();
pub var class_id: bridge.ClassId = undefined;
pub const empty_with_no_proto = true;

View File

@@ -178,6 +178,10 @@ pub const JsApi = struct {
pub const Meta = struct {
pub const name = "Console";
// Per the console spec, members are own properties of the namespace
// object, so Object.entries(console) returns them.
pub const own_properties = true;
pub const prototype_chain = bridge.prototypeChain();
pub var class_id: bridge.ClassId = undefined;
};

View File

@@ -197,7 +197,8 @@ pub fn getCurrentScript(self: *const HTMLDocument) ?*Element.Html.Script {
}
pub fn getLocation(self: *const HTMLDocument) ?*@import("Location.zig") {
return self._proto._location;
const frame = self._proto._frame orelse return null;
return frame.window._location;
}
pub fn setLocation(self: *HTMLDocument, url: [:0]const u8, frame: *Frame) !void {

View File

@@ -170,14 +170,14 @@ pub fn getOrigin(self: *const Window) []const u8 {
return self._frame.origin orelse "null";
}
pub fn getLocation(self: *const Window) *Location {
return self._location;
}
pub fn getSelection(self: *const Window) *Selection {
return &self._document._selection;
}
pub fn getLocation(self: *const Window) *Location {
return self._location;
}
pub fn setLocation(self: *Window, url: [:0]const u8, frame: *Frame) !void {
return frame.scheduleNavigation(url, .{ .reason = .script, .kind = .{ .push = null } }, .{ .script = self._frame });
}