@@ -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