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 = Object.assign(Object.assign({}, TreeIterator.DEFAULT_OPTIONS), options);
|
32 | this.delegate = this.iterator(this.root);
|
33 | }
|
34 |
|
35 | [Symbol.iterator]() {
|
36 | return this.delegate;
|
37 | }
|
38 | next() {
|
39 | return this.delegate.next();
|
40 | }
|
41 | children(node) {
|
42 | if (!tree_1.CompositeTreeNode.is(node)) {
|
43 | return undefined;
|
44 | }
|
45 | if (this.options.pruneCollapsed && this.isCollapsed(node)) {
|
46 | return undefined;
|
47 | }
|
48 | return node.children.slice();
|
49 | }
|
50 | isCollapsed(node) {
|
51 | return tree_expansion_1.ExpandableTreeNode.isCollapsed(node);
|
52 | }
|
53 | isEmpty(nodes) {
|
54 | return nodes === undefined || nodes.length === 0;
|
55 | }
|
56 | }
|
57 | exports.AbstractTreeIterator = AbstractTreeIterator;
|
58 | class DepthFirstTreeIterator extends AbstractTreeIterator {
|
59 | iterator(root) {
|
60 | return Iterators.depthFirst(root, this.children.bind(this));
|
61 | }
|
62 | }
|
63 | exports.DepthFirstTreeIterator = DepthFirstTreeIterator;
|
64 | class BreadthFirstTreeIterator extends AbstractTreeIterator {
|
65 | iterator(root) {
|
66 | return Iterators.breadthFirst(root, this.children.bind(this));
|
67 | }
|
68 | }
|
69 | exports.BreadthFirstTreeIterator = BreadthFirstTreeIterator;
|
70 |
|
71 |
|
72 |
|
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 | class TopDownTreeIterator extends AbstractTreeIterator {
|
100 | iterator(root) {
|
101 | const doNext = this.doNext.bind(this);
|
102 | return (function* () {
|
103 | let next = root;
|
104 | while (next) {
|
105 | yield next;
|
106 | next = doNext(next);
|
107 | }
|
108 | }).bind(this)();
|
109 | }
|
110 | doNext(node) {
|
111 | return this.findFirstChild(node) || this.findNextSibling(node);
|
112 | }
|
113 | findFirstChild(node) {
|
114 | return (this.children(node) || [])[0];
|
115 | }
|
116 | findNextSibling(node) {
|
117 | if (!node) {
|
118 | return undefined;
|
119 | }
|
120 | if (this.options.pruneSiblings && node === this.root) {
|
121 | return undefined;
|
122 | }
|
123 | if (node.nextSibling) {
|
124 | return node.nextSibling;
|
125 | }
|
126 | return this.findNextSibling(node.parent);
|
127 | }
|
128 | }
|
129 | exports.TopDownTreeIterator = TopDownTreeIterator;
|
130 |
|
131 |
|
132 |
|
133 |
|
134 | class BottomUpTreeIterator extends AbstractTreeIterator {
|
135 | iterator(root) {
|
136 | const doNext = this.doNext.bind(this);
|
137 | return (function* () {
|
138 | let next = root;
|
139 | while (next) {
|
140 | yield next;
|
141 | next = doNext(next);
|
142 | }
|
143 | }).bind(this)();
|
144 | }
|
145 | doNext(node) {
|
146 | const previousSibling = node.previousSibling;
|
147 | const lastChild = this.lastChild(previousSibling);
|
148 | return lastChild || node.parent;
|
149 | }
|
150 | lastChild(node) {
|
151 | const children = node ? this.children(node) : [];
|
152 | if (this.isEmpty(children)) {
|
153 | return node;
|
154 | }
|
155 | if (tree_1.CompositeTreeNode.is(node)) {
|
156 | const lastChild = tree_1.CompositeTreeNode.getLastChild(node);
|
157 | return this.lastChild(lastChild);
|
158 | }
|
159 | return undefined;
|
160 | }
|
161 | }
|
162 | exports.BottomUpTreeIterator = BottomUpTreeIterator;
|
163 | var Iterators;
|
164 | (function (Iterators) {
|
165 | |
166 |
|
167 |
|
168 | function* depthFirst(root, children, include = () => true) {
|
169 | const stack = [];
|
170 | stack.push(root);
|
171 | while (stack.length > 0) {
|
172 | const top = stack.pop();
|
173 | yield top;
|
174 | stack.push(...(children(top) || []).filter(include).reverse());
|
175 | }
|
176 | }
|
177 | Iterators.depthFirst = depthFirst;
|
178 | |
179 |
|
180 |
|
181 | function* breadthFirst(root, children, include = () => true) {
|
182 | const queue = [];
|
183 | queue.push(root);
|
184 | while (queue.length > 0) {
|
185 | const head = queue.shift();
|
186 | yield head;
|
187 | queue.push(...(children(head) || []).filter(include));
|
188 | }
|
189 | }
|
190 | Iterators.breadthFirst = breadthFirst;
|
191 | |
192 |
|
193 |
|
194 | function asIterator(elements) {
|
195 | return elements.slice()[Symbol.iterator]();
|
196 | }
|
197 | Iterators.asIterator = asIterator;
|
198 | |
199 |
|
200 |
|
201 |
|
202 |
|
203 |
|
204 |
|
205 | function* cycle(elements, start) {
|
206 | const copy = elements.slice();
|
207 | let index = !!start ? copy.indexOf(start) : 0;
|
208 | if (index === -1) {
|
209 | throw new Error(`${start} is not contained in ${copy}.`);
|
210 | }
|
211 | while (true) {
|
212 | yield copy[index];
|
213 | index++;
|
214 | if (index === copy.length) {
|
215 | index = 0;
|
216 | }
|
217 | }
|
218 | }
|
219 | Iterators.cycle = cycle;
|
220 | })(Iterators = exports.Iterators || (exports.Iterators = {}));
|
221 |
|
\ | No newline at end of file |