Skip to content

Commit 4de4e75

Browse files
Merge pull request #951 from lightpanda-io/wpt_range
Improve correctness of Node.compareDocumentPosition and Range api.
2 parents 4fbedf5 + b46c181 commit 4de4e75

File tree

5 files changed

+296
-27
lines changed

5 files changed

+296
-27
lines changed

src/browser/dom/exceptions.zig

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,23 +68,24 @@ pub const DOMException = struct {
6868
}
6969

7070
// TODO: deinit
71-
pub fn init(alloc: std.mem.Allocator, err: anyerror, callerName: []const u8) !DOMException {
72-
const errCast = @as(parser.DOMError, @errorCast(err));
73-
const errName = DOMException.name(errCast);
74-
const str = switch (errCast) {
71+
pub fn init(alloc: std.mem.Allocator, err: anyerror, caller_name: []const u8) !DOMException {
72+
const dom_error = @as(parser.DOMError, @errorCast(err));
73+
const error_name = DOMException.name(dom_error);
74+
const str = switch (dom_error) {
7575
error.HierarchyRequest => try allocPrint(
7676
alloc,
7777
"{s}: Failed to execute '{s}' on 'Node': The new child element contains the parent.",
78-
.{ errName, callerName },
78+
.{ error_name, caller_name },
7979
),
80-
error.NoError => unreachable,
80+
// todo add more custom error messages
8181
else => try allocPrint(
8282
alloc,
83-
"{s}: TODO message", // TODO: implement other messages
84-
.{DOMException.name(errCast)},
83+
"{s}: Failed to execute '{s}' : {s}",
84+
.{ error_name, caller_name, error_name },
8585
),
86+
error.NoError => unreachable,
8687
};
87-
return .{ .err = errCast, .str = str };
88+
return .{ .err = dom_error, .str = str };
8889
}
8990

9091
fn error_from_str(name_: []const u8) ?parser.DOMError {

src/browser/dom/node.zig

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,13 @@ pub const Node = struct {
107107
pub const _ENTITY_NODE = @intFromEnum(parser.NodeType.entity);
108108
pub const _NOTATION_NODE = @intFromEnum(parser.NodeType.notation);
109109

110+
pub const _DOCUMENT_POSITION_DISCONNECTED = @intFromEnum(parser.DocumentPosition.disconnected);
111+
pub const _DOCUMENT_POSITION_PRECEDING = @intFromEnum(parser.DocumentPosition.preceding);
112+
pub const _DOCUMENT_POSITION_FOLLOWING = @intFromEnum(parser.DocumentPosition.following);
113+
pub const _DOCUMENT_POSITION_CONTAINS = @intFromEnum(parser.DocumentPosition.contains);
114+
pub const _DOCUMENT_POSITION_CONTAINED_BY = @intFromEnum(parser.DocumentPosition.contained_by);
115+
pub const _DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = @intFromEnum(parser.DocumentPosition.implementation_specific);
116+
110117
// JS funcs
111118
// --------
112119

@@ -260,14 +267,43 @@ pub const Node = struct {
260267
}
261268

262269
pub fn _compareDocumentPosition(self: *parser.Node, other: *parser.Node) !u32 {
263-
if (self == other) return 0;
270+
if (self == other) {
271+
return 0;
272+
}
264273

265-
const docself = try parser.nodeOwnerDocument(self);
266-
const docother = try parser.nodeOwnerDocument(other);
274+
const docself = try parser.nodeOwnerDocument(self) orelse blk: {
275+
if (try parser.nodeType(self) == .document) {
276+
break :blk @as(*parser.Document, @ptrCast(self));
277+
}
278+
break :blk null;
279+
};
280+
const docother = try parser.nodeOwnerDocument(other) orelse blk: {
281+
if (try parser.nodeType(other) == .document) {
282+
break :blk @as(*parser.Document, @ptrCast(other));
283+
}
284+
break :blk null;
285+
};
267286

268287
// Both are in different document.
269-
if (docself == null or docother == null or docother.? != docself.?) {
270-
return @intFromEnum(parser.DocumentPosition.disconnected);
288+
if (docself == null or docother == null or docself.? != docother.?) {
289+
return @intFromEnum(parser.DocumentPosition.disconnected) +
290+
@intFromEnum(parser.DocumentPosition.implementation_specific) +
291+
@intFromEnum(parser.DocumentPosition.preceding);
292+
}
293+
294+
if (@intFromPtr(self) == @intFromPtr(docself.?)) {
295+
// if self is the document, and we already know other is in the
296+
// document, then other is contained by and following self.
297+
return @intFromEnum(parser.DocumentPosition.following) +
298+
@intFromEnum(parser.DocumentPosition.contained_by);
299+
}
300+
301+
const rootself = try parser.nodeGetRootNode(self);
302+
const rootother = try parser.nodeGetRootNode(other);
303+
if (rootself != rootother) {
304+
return @intFromEnum(parser.DocumentPosition.disconnected) +
305+
@intFromEnum(parser.DocumentPosition.implementation_specific) +
306+
@intFromEnum(parser.DocumentPosition.preceding);
271307
}
272308

273309
// TODO Both are in a different trees in the same document.

0 commit comments

Comments
 (0)