Merge branch 'main' into semantic-tree

This commit is contained in:
Adrià Arrufat
2026-03-09 20:13:47 +09:00
4 changed files with 80 additions and 3 deletions

View File

@@ -1022,3 +1022,50 @@
testing.expectEqual('Stnd', div.textContent);
}
</script>
<script id=getBoundingClientRect_collapsed>
{
const range = new Range();
const rect = range.getBoundingClientRect();
testing.expectTrue(rect instanceof DOMRect);
testing.expectEqual(0, rect.x);
testing.expectEqual(0, rect.y);
testing.expectEqual(0, rect.width);
testing.expectEqual(0, rect.height);
}
</script>
<script id=getBoundingClientRect_element>
{
const range = new Range();
const p = document.getElementById('p1');
range.selectNodeContents(p);
const rect = range.getBoundingClientRect();
testing.expectTrue(rect instanceof DOMRect);
// Non-collapsed range delegates to the container element
const elemRect = p.getBoundingClientRect();
testing.expectEqual(elemRect.x, rect.x);
testing.expectEqual(elemRect.y, rect.y);
testing.expectEqual(elemRect.width, rect.width);
testing.expectEqual(elemRect.height, rect.height);
}
</script>
<script id=getClientRects_collapsed>
{
const range = new Range();
const rects = range.getClientRects();
testing.expectEqual(0, rects.length);
}
</script>
<script id=getClientRects_element>
{
const range = new Range();
const p = document.getElementById('p1');
range.selectNodeContents(p);
const rects = range.getClientRects();
const elemRects = p.getClientRects();
testing.expectEqual(elemRects.length, rects.length);
}
</script>

View File

@@ -25,6 +25,7 @@ const Page = @import("../Page.zig");
const Node = @import("Node.zig");
const DocumentFragment = @import("DocumentFragment.zig");
const AbstractRange = @import("AbstractRange.zig");
const DOMRect = @import("DOMRect.zig");
const Range = @This();
@@ -643,6 +644,33 @@ fn nextAfterSubtree(node: *Node, root: *Node) ?*Node {
return null;
}
pub fn getBoundingClientRect(self: *const Range, page: *Page) DOMRect {
if (self._proto.getCollapsed()) {
return .{ ._x = 0, ._y = 0, ._width = 0, ._height = 0 };
}
const element = self.getContainerElement() orelse {
return .{ ._x = 0, ._y = 0, ._width = 0, ._height = 0 };
};
return element.getBoundingClientRect(page);
}
pub fn getClientRects(self: *const Range, page: *Page) ![]DOMRect {
if (self._proto.getCollapsed()) {
return &.{};
}
const element = self.getContainerElement() orelse {
return &.{};
};
return element.getClientRects(page);
}
fn getContainerElement(self: *const Range) ?*Node.Element {
const container = self._proto.getCommonAncestorContainer();
if (container.is(Node.Element)) |el| return el;
const parent = container.parentNode() orelse return null;
return parent.is(Node.Element);
}
pub const JsApi = struct {
pub const bridge = js.Bridge(Range);
@@ -681,6 +709,8 @@ pub const JsApi = struct {
pub const surroundContents = bridge.function(Range.surroundContents, .{ .dom_exception = true });
pub const createContextualFragment = bridge.function(Range.createContextualFragment, .{ .dom_exception = true });
pub const toString = bridge.function(Range.toString, .{ .dom_exception = true });
pub const getBoundingClientRect = bridge.function(Range.getBoundingClientRect, .{});
pub const getClientRects = bridge.function(Range.getClientRects, .{});
};
const testing = @import("../../testing.zig");

View File

@@ -30,7 +30,7 @@ _family: []const u8,
pub fn init(family: []const u8, source: []const u8, page: *Page) !*FontFace {
_ = source;
const arena = try page.getArena(.{.debug = "FontFace"});
const arena = try page.getArena(.{ .debug = "FontFace" });
errdefer page.releaseArena(arena);
const self = try arena.create(FontFace);

View File

@@ -28,7 +28,7 @@ const FontFaceSet = @This();
_arena: Allocator,
pub fn init(page: *Page) !*FontFaceSet {
const arena = try page.getArena(.{.debug = "FontFaceSet"});
const arena = try page.getArena(.{ .debug = "FontFaceSet" });
errdefer page.releaseArena(arena);
const self = try arena.create(FontFaceSet);
@@ -73,7 +73,7 @@ pub const JsApi = struct {
pub const prototype_chain = bridge.prototypeChain();
pub var class_id: bridge.ClassId = undefined;
pub const weak = true;
pub const finalizer = bridge.finalizer(FontFaceSet.deinit);
pub const finalizer = bridge.finalizer(FontFaceSet.deinit);
};
pub const size = bridge.property(0, .{ .template = false, .readonly = true });