@@ -107,6 +107,13 @@ pub const Node = struct {
107
107
pub const _ENTITY_NODE = @intFromEnum (parser .NodeType .entity );
108
108
pub const _NOTATION_NODE = @intFromEnum (parser .NodeType .notation );
109
109
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
+
110
117
// JS funcs
111
118
// --------
112
119
@@ -260,14 +267,43 @@ pub const Node = struct {
260
267
}
261
268
262
269
pub fn _compareDocumentPosition (self : * parser.Node , other : * parser.Node ) ! u32 {
263
- if (self == other ) return 0 ;
270
+ if (self == other ) {
271
+ return 0 ;
272
+ }
264
273
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
+ };
267
286
268
287
// 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 );
271
307
}
272
308
273
309
// TODO Both are in a different trees in the same document.
0 commit comments