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>
|
||||||
|
|
||||||
|
<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>
|
<script id=screen>
|
||||||
testing.expectEqual(1920, screen.width);
|
testing.expectEqual(1920, screen.width);
|
||||||
testing.expectEqual(1080, screen.height);
|
testing.expectEqual(1080, screen.height);
|
||||||
|
|||||||
@@ -412,6 +412,18 @@ pub fn atob(_: *const Window, input: []const u8, page: *Page) ![]const u8 {
|
|||||||
return decoded;
|
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 {
|
pub fn getFrame(self: *Window, idx: usize) !?*Window {
|
||||||
const page = self._page;
|
const page = self._page;
|
||||||
const frames = page.frames.items;
|
const frames = page.frames.items;
|
||||||
@@ -797,6 +809,7 @@ pub const JsApi = struct {
|
|||||||
pub const btoa = bridge.function(Window.btoa, .{});
|
pub const btoa = bridge.function(Window.btoa, .{});
|
||||||
pub const atob = bridge.function(Window.atob, .{ .dom_exception = true });
|
pub const atob = bridge.function(Window.atob, .{ .dom_exception = true });
|
||||||
pub const reportError = bridge.function(Window.reportError, .{});
|
pub const reportError = bridge.function(Window.reportError, .{});
|
||||||
|
pub const structuredClone = bridge.function(Window.structuredClone, .{});
|
||||||
pub const getComputedStyle = bridge.function(Window.getComputedStyle, .{});
|
pub const getComputedStyle = bridge.function(Window.getComputedStyle, .{});
|
||||||
pub const getSelection = bridge.function(Window.getSelection, .{});
|
pub const getSelection = bridge.function(Window.getSelection, .{});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user