diff --git a/src/Config.zig b/src/Config.zig
index 15a64a6c..e11be2f9 100644
--- a/src/Config.zig
+++ b/src/Config.zig
@@ -389,7 +389,27 @@ pub const WaitUntil = enum {
/// Must be initialized with an allocator that outlives all HTTP connections.
pub const HttpHeaders = struct {
const user_agent_base: [:0]const u8 = "Lightpanda/1.0";
- pub const sec_ch_ua: [:0]const u8 = "Sec-Ch-Ua: \"Lightpanda\";v=\"1\"";
+
+ const Brand = struct {
+ brand: [:0]const u8,
+ version: [:0]const u8,
+ };
+
+ /// Source of truth for client-hints brand data. Both the Sec-Ch-Ua
+ /// HTTP header and navigator.userAgentData.brands derive from this
+ /// list, so the two sides cannot drift.
+ pub const brands = [_]Brand{
+ .{ .brand = "Lightpanda", .version = "1" },
+ };
+
+ pub const sec_ch_ua: [:0]const u8 = blk: {
+ var out: [:0]const u8 = "Sec-Ch-Ua:";
+ for (brands, 0..) |b, i| {
+ const sep = if (i == 0) " " else ", ";
+ out = out ++ sep ++ "\"" ++ b.brand ++ "\";v=\"" ++ b.version ++ "\"";
+ }
+ break :blk out;
+ };
user_agent: [:0]const u8, // User agent value (e.g. "Lightpanda/1.0")
user_agent_header: [:0]const u8,
diff --git a/src/browser/Frame.zig b/src/browser/Frame.zig
index 7994abb4..454ad784 100644
--- a/src/browser/Frame.zig
+++ b/src/browser/Frame.zig
@@ -809,8 +809,9 @@ pub fn documentIsLoaded(self: *Frame) void {
self._load_state = .load;
self.document._ready_state = .interactive;
- self._documentIsLoaded() catch |err| {
- log.err(.frame, "document is loaded", .{ .err = err, .type = self._type, .url = self.url });
+ self._documentIsLoaded() catch |err| switch (err) {
+ error.JsException => {}, // already logged
+ else => log.err(.frame, "document is loaded2", .{ .err = err, .type = self._type, .url = self.url }),
};
}
@@ -882,8 +883,9 @@ pub fn documentIsComplete(self: *Frame) void {
}
self._load_state = .complete;
- self._documentIsComplete() catch |err| {
- log.err(.frame, "document is complete", .{ .err = err, .type = self._type, .url = self.url });
+ self._documentIsComplete() catch |err| switch (err) {
+ error.JsException => {}, // already logged
+ else => log.err(.frame, "document is complete", .{ .err = err, .type = self._type, .url = self.url }),
};
}
diff --git a/src/browser/js/bridge.zig b/src/browser/js/bridge.zig
index e61818c7..ed903ea0 100644
--- a/src/browser/js/bridge.zig
+++ b/src/browser/js/bridge.zig
@@ -858,6 +858,7 @@ pub const PageJsApis = flattenTypes(&.{
@import("../webapi/EventTarget.zig"),
@import("../webapi/Location.zig"),
@import("../webapi/Navigator.zig"),
+ @import("../webapi/NavigatorUAData.zig"),
@import("../webapi/net/FormData.zig"),
@import("../webapi/net/Headers.zig"),
@import("../webapi/net/Request.zig"),
@@ -936,6 +937,7 @@ pub const WorkerJsApis = flattenTypes(&.{
@import("../webapi/AbortSignal.zig"),
@import("../webapi/AbortController.zig"),
@import("../webapi/URL.zig"),
+ @import("../webapi/canvas/OffscreenCanvas.zig"),
// @import("../webapi/Performance.zig"),
});
diff --git a/src/browser/tests/navigator/navigator.html b/src/browser/tests/navigator/navigator.html
index f6dafde8..92f33bab 100644
--- a/src/browser/tests/navigator/navigator.html
+++ b/src/browser/tests/navigator/navigator.html
@@ -65,6 +65,49 @@
testing.expectEqual(8, navigator.deviceMemory);
+
+
+
+