mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-21 20:24:42 +00:00
Add structuredClone() global function
Next.js hydration requires structuredClone(), which was not implemented. Uses a JSON stringify/parse round-trip via V8 to deep-clone values, covering all JSON-serializable types (objects, arrays, primitives).
This commit is contained in:
@@ -115,6 +115,30 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id=structuredClone>
|
||||
// Basic types
|
||||
testing.expectEqual(42, structuredClone(42));
|
||||
testing.expectEqual('hello', structuredClone('hello'));
|
||||
testing.expectEqual(true, structuredClone(true));
|
||||
testing.expectEqual(null, structuredClone(null));
|
||||
|
||||
// Object deep clone
|
||||
const obj = { a: 1, b: { c: 2 } };
|
||||
const cloned = structuredClone(obj);
|
||||
testing.expectEqual(1, cloned.a);
|
||||
testing.expectEqual(2, cloned.b.c);
|
||||
cloned.b.c = 99;
|
||||
testing.expectEqual(2, obj.b.c); // original unchanged
|
||||
|
||||
// Array deep clone
|
||||
const arr = [1, [2, 3]];
|
||||
const clonedArr = structuredClone(arr);
|
||||
testing.expectEqual(1, clonedArr[0]);
|
||||
testing.expectEqual(2, clonedArr[1][0]);
|
||||
clonedArr[1][0] = 99;
|
||||
testing.expectEqual(2, arr[1][0]); // original unchanged
|
||||
</script>
|
||||
|
||||
<script id=screen>
|
||||
testing.expectEqual(1920, screen.width);
|
||||
testing.expectEqual(1080, screen.height);
|
||||
|
||||
@@ -412,6 +412,18 @@ pub fn atob(_: *const Window, input: []const u8, page: *Page) ![]const u8 {
|
||||
return decoded;
|
||||
}
|
||||
|
||||
pub fn structuredClone(_: *const Window, value: js.Value) !js.Value {
|
||||
// Simplified structured clone using JSON round-trip.
|
||||
// Handles JSON-serializable types (objects, arrays, strings, numbers, booleans, null).
|
||||
const local = value.local;
|
||||
const str_handle = js.v8.v8__JSON__Stringify(local.handle, value.handle, null) orelse return error.DataCloneError;
|
||||
const cloned_handle = js.v8.v8__JSON__Parse(local.handle, str_handle) orelse return error.DataCloneError;
|
||||
return js.Value{
|
||||
.local = local,
|
||||
.handle = cloned_handle,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn getFrame(self: *Window, idx: usize) !?*Window {
|
||||
const page = self._page;
|
||||
const frames = page.frames.items;
|
||||
@@ -797,6 +809,7 @@ pub const JsApi = struct {
|
||||
pub const btoa = bridge.function(Window.btoa, .{});
|
||||
pub const atob = bridge.function(Window.atob, .{ .dom_exception = true });
|
||||
pub const reportError = bridge.function(Window.reportError, .{});
|
||||
pub const structuredClone = bridge.function(Window.structuredClone, .{});
|
||||
pub const getComputedStyle = bridge.function(Window.getComputedStyle, .{});
|
||||
pub const getSelection = bridge.function(Window.getSelection, .{});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user