1 | const {SHOW_ALL, SHOW_COMMENT, SHOW_ELEMENT} = require('./NodeFilter.js');
|
2 |
|
3 | const 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 |
|
19 | const 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 |
|
32 | module.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 | };
|