Skip to content

Commit ed74195

Browse files
authored
Add Node.compareDocumentPosition implementation (#16)
1 parent 22b2ed3 commit ed74195

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

src/entries/dom-api.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,93 @@
11
import {document as lightJsDocument} from '@litejs/dom';
22
import {CSSStyleDeclaration} from '@litejs/dom/css';
3+
import {Node} from '@litejs/dom/dom';
34

45
CSSStyleDeclaration.prototype.setProperty = function(key, value) {
56
this[key] = value;
67
};
78

9+
Node.DOCUMENT_POSITION_DISCONNECTED = 1;
10+
Node.DOCUMENT_POSITION_PRECEDING = 2;
11+
Node.DOCUMENT_POSITION_FOLLOWING = 4;
12+
Node.DOCUMENT_POSITION_CONTAINS = 8;
13+
Node.DOCUMENT_POSITION_CONTAINED_BY = 16;
14+
Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 32;
15+
16+
Node.compareDocumentPosition = compareDocumentPosition;
17+
18+
function recursivelyWalk(nodes, cb) {
19+
for (let i = 0, len = nodes.length; i < len; i++) {
20+
const node = nodes[i];
21+
22+
if (cb(node)) {
23+
return cb(node);
24+
}
25+
26+
if (node.childNodes?.length) {
27+
const ret = recursivelyWalk(node.childNodes, cb);
28+
if (ret) {
29+
return ret;
30+
}
31+
}
32+
}
33+
}
34+
35+
function compareDocumentPosition(other) {
36+
if (this === other) {
37+
return 0;
38+
}
39+
40+
let reference = this,
41+
referenceTop = this,
42+
otherTop = other;
43+
44+
while (referenceTop.parentNode) {
45+
referenceTop = referenceTop.parentNode;
46+
}
47+
while (otherTop.parentNode) {
48+
otherTop = otherTop.parentNode;
49+
}
50+
51+
if (referenceTop !== otherTop) {
52+
return Node.DOCUMENT_POSITION_DISCONNECTED;
53+
}
54+
55+
let children = reference.childNodes;
56+
let ret = recursivelyWalk(
57+
children,
58+
(node) => node === other,
59+
);
60+
if (ret) {
61+
return Node.DOCUMENT_POSITION_CONTAINED_BY;
62+
}
63+
64+
children = other.childNodes;
65+
ret = recursivelyWalk(
66+
children,
67+
(node) => node === reference,
68+
);
69+
if (ret) {
70+
return Node.DOCUMENT_POSITION_CONTAINS;
71+
}
72+
73+
ret = recursivelyWalk(
74+
[referenceTop],
75+
(node) => {
76+
if (node === other) {
77+
return 'other';
78+
}
79+
80+
if (node === reference) {
81+
return 'reference';
82+
}
83+
}
84+
);
85+
86+
if (ret === 'other') {
87+
return Node.DOCUMENT_POSITION_PRECEDING;
88+
}
89+
90+
return Node.DOCUMENT_POSITION_FOLLOWING;
91+
}
92+
893
export const document = lightJsDocument;

0 commit comments

Comments
 (0)