From f450bddcc398a466ece5f6e60e96ee4901127b4e Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Thu, 23 Apr 2026 20:16:28 +0800 Subject: [PATCH] Define v8 functions directly on console instance. functions should be defined directly on the window.console (and window.CSS) instances. This is necessary for being able to iterate their "own" properties. businessinsider.com has code that proxies console via such an iterator (through Object.entries(console)). This commit allows types to declare that they own their properties (as opposed to the prototype). Also fixed HTMLDocument.location. This was using Document._location, but that field wasn't always set. The new code removes the _location field and changes the getter to get window._location. (Also an issue on businessinsider.com) --- src/browser/Frame.zig | 1 - src/browser/js/Snapshot.zig | 8 +++++++- src/browser/tests/console/console.html | 10 ++++++++++ src/browser/tests/css.html | 5 +++++ src/browser/webapi/CSS.zig | 5 +++++ src/browser/webapi/Console.zig | 4 ++++ src/browser/webapi/HTMLDocument.zig | 3 ++- src/browser/webapi/Window.zig | 8 ++++---- 8 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/browser/Frame.zig b/src/browser/Frame.zig index 7994abb4..b6359aa9 100644 --- a/src/browser/Frame.zig +++ b/src/browser/Frame.zig @@ -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); } diff --git a/src/browser/js/Snapshot.zig b/src/browser/js/Snapshot.zig index 1fb61290..e0684969 100644 --- a/src/browser/js/Snapshot.zig +++ b/src/browser/js/Snapshot.zig @@ -588,6 +588,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; @@ -653,7 +659,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 => { diff --git a/src/browser/tests/console/console.html b/src/browser/tests/console/console.html index 33c2fa62..8f68ccd8 100644 --- a/src/browser/tests/console/console.html +++ b/src/browser/tests/console/console.html @@ -1,6 +1,16 @@ + + + +