1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | Object.defineProperty(exports, "__esModule", { value: true });
|
18 | exports.Iterators = exports.BottomUpTreeIterator = exports.TopDownTreeIterator = exports.BreadthFirstTreeIterator = exports.DepthFirstTreeIterator = exports.AbstractTreeIterator = exports.TreeIterator = void 0;
|
19 | const tree_1 = require("./tree");
|
20 | const tree_expansion_1 = require("./tree-expansion");
|
21 | var TreeIterator;
|
22 | (function (TreeIterator) {
|
23 | TreeIterator.DEFAULT_OPTIONS = {
|
24 | pruneCollapsed: false,
|
25 | pruneSiblings: false
|
26 | };
|
27 | })(TreeIterator = exports.TreeIterator || (exports.TreeIterator = {}));
|
28 | class AbstractTreeIterator {
|
29 | constructor(root, options) {
|
30 | this.root = root;
|
31 | this.options = {
|
32 | ...TreeIterator.DEFAULT_OPTIONS,
|
33 | ...options
|
34 | };
|
35 | this.delegate = this.iterator(this.root);
|
36 | }
|
37 |
|
38 | [Symbol.iterator]() {
|
39 | return this.delegate;
|
40 | }
|
41 | next() {
|
42 | return this.delegate.next();
|
43 | }
|
44 | children(node) {
|
45 | if (!tree_1.CompositeTreeNode.is(node)) {
|
46 | return undefined;
|
47 | }
|
48 | if (this.options.pruneCollapsed && this.isCollapsed(node)) {
|
49 | return undefined;
|
50 | }
|
51 | return node.children.slice();
|
52 | }
|
53 | isCollapsed(node) {
|
54 | return tree_expansion_1.ExpandableTreeNode.isCollapsed(node);
|
55 | }
|
56 | isEmpty(nodes) {
|
57 | return nodes === undefined || nodes.length === 0;
|
58 | }
|
59 | }
|
60 | exports.AbstractTreeIterator = AbstractTreeIterator;
|
61 | class DepthFirstTreeIterator extends AbstractTreeIterator {
|
62 | iterator(root) {
|
63 | return Iterators.depthFirst(root, this.children.bind(this));
|
64 | }
|
65 | }
|
66 | exports.DepthFirstTreeIterator = DepthFirstTreeIterator;
|
67 | class BreadthFirstTreeIterator extends AbstractTreeIterator {
|
68 | iterator(root) {
|
69 | return Iterators.breadthFirst(root, this.children.bind(this));
|
70 | }
|
71 | }
|
72 | exports.BreadthFirstTreeIterator = BreadthFirstTreeIterator;
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
82 |
|
83 |
|
84 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 | class TopDownTreeIterator extends AbstractTreeIterator {
|
103 | iterator(root) {
|
104 | const doNext = this.doNext.bind(this);
|
105 | return (function* () {
|
106 | let next = root;
|
107 | while (next) {
|
108 | yield next;
|
109 | next = doNext(next);
|
110 | }
|
111 | }).bind(this)();
|
112 | }
|
113 | doNext(node) {
|
114 | return this.findFirstChild(node) || this.findNextSibling(node);
|
115 | }
|
116 | findFirstChild(node) {
|
117 | return (this.children(node) || [])[0];
|
118 | }
|
119 | findNextSibling(node) {
|
120 | if (!node) {
|
121 | return undefined;
|
122 | }
|
123 | if (this.options.pruneSiblings && node === this.root) {
|
124 | return undefined;
|
125 | }
|
126 | if (node.nextSibling) {
|
127 | return node.nextSibling;
|
128 | }
|
129 | return this.findNextSibling(node.parent);
|
130 | }
|
131 | }
|
132 | exports.TopDownTreeIterator = TopDownTreeIterator;
|
133 |
|
134 |
|
135 |
|
136 |
|
137 | class BottomUpTreeIterator extends AbstractTreeIterator {
|
138 | iterator(root) {
|
139 | const doNext = this.doNext.bind(this);
|
140 | return (function* () {
|
141 | let next = root;
|
142 | while (next) {
|
143 | yield next;
|
144 | next = doNext(next);
|
145 | }
|
146 | }).bind(this)();
|
147 | }
|
148 | doNext(node) {
|
149 | const previousSibling = node.previousSibling;
|
150 | const lastChild = this.lastChild(previousSibling);
|
151 | return lastChild || node.parent;
|
152 | }
|
153 | lastChild(node) {
|
154 | const children = node ? this.children(node) : [];
|
155 | if (this.isEmpty(children)) {
|
156 | return node;
|
157 | }
|
158 | if (tree_1.CompositeTreeNode.is(node)) {
|
159 | const lastChild = tree_1.CompositeTreeNode.getLastChild(node);
|
160 | return this.lastChild(lastChild);
|
161 | }
|
162 | return undefined;
|
163 | }
|
164 | }
|
165 | exports.BottomUpTreeIterator = BottomUpTreeIterator;
|
166 | var Iterators;
|
167 | (function (Iterators) {
|
168 | |
169 |
|
170 |
|
171 | function* depthFirst(root, children, include = () => true) {
|
172 | let stack = [];
|
173 | stack.push(root);
|
174 | while (stack.length > 0) {
|
175 | const top = stack.pop();
|
176 | yield top;
|
177 | stack = stack.concat((children(top) || []).filter(include).reverse());
|
178 | }
|
179 | }
|
180 | Iterators.depthFirst = depthFirst;
|
181 | |
182 |
|
183 |
|
184 | function* breadthFirst(root, children, include = () => true) {
|
185 | let queue = [];
|
186 | queue.push(root);
|
187 | while (queue.length > 0) {
|
188 | const head = queue.shift();
|
189 | yield head;
|
190 | queue = queue.concat((children(head) || []).filter(include));
|
191 | }
|
192 | }
|
193 | Iterators.breadthFirst = breadthFirst;
|
194 | |
195 |
|
196 |
|
197 | function asIterator(elements) {
|
198 | return elements.slice()[Symbol.iterator]();
|
199 | }
|
200 | Iterators.asIterator = asIterator;
|
201 | |
202 |
|
203 |
|
204 |
|
205 |
|
206 |
|
207 |
|
208 | function* cycle(elements, start) {
|
209 | const copy = elements.slice();
|
210 | let index = !!start ? copy.indexOf(start) : 0;
|
211 | if (index === -1) {
|
212 | throw new Error(`${start} is not contained in ${copy}.`);
|
213 | }
|
214 | while (true) {
|
215 | yield copy[index];
|
216 | index++;
|
217 | if (index === copy.length) {
|
218 | index = 0;
|
219 | }
|
220 | }
|
221 | }
|
222 | Iterators.cycle = cycle;
|
223 | })(Iterators = exports.Iterators || (exports.Iterators = {}));
|
224 |
|
\ | No newline at end of file |