UNPKG

1.29 kBJavaScriptView Raw
1const {SHOW_ALL, SHOW_COMMENT, SHOW_ELEMENT} = require('./NodeFilter.js');
2
3const flat = (parentNode, list) => {
4 const root = !list;
5 if (root)
6 list = new Set;
7 else
8 list.add(parentNode);
9 const {childNodes, nextSibling} = parentNode;
10 for (let i = 0, {length} = childNodes; i < length; i++)
11 flat(childNodes[i], list);
12 if (!root && nextSibling)
13 flat(nextSibling, list);
14 if (root)
15 return [...list];
16};
17
18// this is dumb, but it works for uhtml 😎
19const isOK = ({nodeType}, mask) => {
20 if (mask === SHOW_ALL)
21 return true;
22 const OTHERS = SHOW_ELEMENT | SHOW_COMMENT;
23 switch (nodeType) {
24 case 1:
25 return mask === SHOW_ELEMENT || mask === OTHERS;
26 case 8:
27 return mask === SHOW_COMMENT || mask === OTHERS;
28 }
29 return false;
30};
31
32module.exports = class TreeWalker {
33 constructor(root, whatToShow = SHOW_ALL) {
34 this.root = root;
35 this.currentNode = null;
36 this.whatToShow = whatToShow;
37 this._list = flat(root);
38 this._index = 0;
39 this._length = this._list.length;
40 }
41 nextNode() {
42 while (this._index < this._length) {
43 const currentNode = this._list[this._index++];
44 if (isOK(currentNode, this.whatToShow))
45 return (this.currentNode = currentNode);
46 }
47 return (this.currentNode = null);
48 }
49};