1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
18 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
19 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
20 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
21 | return c > 3 && r && Object.defineProperty(target, key, r), r;
|
22 | };
|
23 | var __metadata = (this && this.__metadata) || function (k, v) {
|
24 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
25 | };
|
26 | Object.defineProperty(exports, "__esModule", { value: true });
|
27 | exports.TreeImpl = exports.CompositeTreeNode = exports.TreeNode = exports.Tree = void 0;
|
28 | const inversify_1 = require("inversify");
|
29 | const event_1 = require("../../common/event");
|
30 | const disposable_1 = require("../../common/disposable");
|
31 | const cancellation_1 = require("../../common/cancellation");
|
32 | const promise_util_1 = require("../../common/promise-util");
|
33 | const common_1 = require("../../common");
|
34 | exports.Tree = Symbol('Tree');
|
35 | var TreeNode;
|
36 | (function (TreeNode) {
|
37 | function is(node) {
|
38 | return (0, common_1.isObject)(node) && 'id' in node && 'parent' in node;
|
39 | }
|
40 | TreeNode.is = is;
|
41 | function equals(left, right) {
|
42 | return left === right || (!!left && !!right && left.id === right.id);
|
43 | }
|
44 | TreeNode.equals = equals;
|
45 | function isVisible(node) {
|
46 | return !!node && (node.visible === undefined || node.visible);
|
47 | }
|
48 | TreeNode.isVisible = isVisible;
|
49 | })(TreeNode = exports.TreeNode || (exports.TreeNode = {}));
|
50 | var CompositeTreeNode;
|
51 | (function (CompositeTreeNode) {
|
52 | function is(node) {
|
53 | return (0, common_1.isObject)(node) && 'children' in node;
|
54 | }
|
55 | CompositeTreeNode.is = is;
|
56 | function getFirstChild(parent) {
|
57 | return parent.children[0];
|
58 | }
|
59 | CompositeTreeNode.getFirstChild = getFirstChild;
|
60 | function getLastChild(parent) {
|
61 | return parent.children[parent.children.length - 1];
|
62 | }
|
63 | CompositeTreeNode.getLastChild = getLastChild;
|
64 | function isAncestor(parent, child) {
|
65 | if (!child) {
|
66 | return false;
|
67 | }
|
68 | if (TreeNode.equals(parent, child.parent)) {
|
69 | return true;
|
70 | }
|
71 | return isAncestor(parent, child.parent);
|
72 | }
|
73 | CompositeTreeNode.isAncestor = isAncestor;
|
74 | function indexOf(parent, node) {
|
75 | if (!node) {
|
76 | return -1;
|
77 | }
|
78 | return parent.children.findIndex(child => TreeNode.equals(node, child));
|
79 | }
|
80 | CompositeTreeNode.indexOf = indexOf;
|
81 | function addChildren(parent, children) {
|
82 | for (const child of children) {
|
83 | addChild(parent, child);
|
84 | }
|
85 | return parent;
|
86 | }
|
87 | CompositeTreeNode.addChildren = addChildren;
|
88 | function addChild(parent, child) {
|
89 | const children = parent.children;
|
90 | const index = children.findIndex(value => value.id === child.id);
|
91 | if (index !== -1) {
|
92 | children.splice(index, 1, child);
|
93 | setParent(child, index, parent);
|
94 | }
|
95 | else {
|
96 | children.push(child);
|
97 | setParent(child, parent.children.length - 1, parent);
|
98 | }
|
99 | return parent;
|
100 | }
|
101 | CompositeTreeNode.addChild = addChild;
|
102 | function removeChild(parent, child) {
|
103 | const children = parent.children;
|
104 | const index = children.findIndex(value => value.id === child.id);
|
105 | if (index === -1) {
|
106 | return;
|
107 | }
|
108 | children.splice(index, 1);
|
109 | const { previousSibling, nextSibling } = child;
|
110 | if (previousSibling) {
|
111 | Object.assign(previousSibling, { nextSibling });
|
112 | }
|
113 | if (nextSibling) {
|
114 | Object.assign(nextSibling, { previousSibling });
|
115 | }
|
116 | }
|
117 | CompositeTreeNode.removeChild = removeChild;
|
118 | function setParent(child, index, parent) {
|
119 | const previousSibling = parent.children[index - 1];
|
120 | const nextSibling = parent.children[index + 1];
|
121 | Object.assign(child, { parent, previousSibling, nextSibling });
|
122 | if (previousSibling) {
|
123 | Object.assign(previousSibling, { nextSibling: child });
|
124 | }
|
125 | if (nextSibling) {
|
126 | Object.assign(nextSibling, { previousSibling: child });
|
127 | }
|
128 | }
|
129 | CompositeTreeNode.setParent = setParent;
|
130 | })(CompositeTreeNode = exports.CompositeTreeNode || (exports.CompositeTreeNode = {}));
|
131 |
|
132 |
|
133 |
|
134 | let TreeImpl = class TreeImpl {
|
135 | constructor() {
|
136 | this.onChangedEmitter = new event_1.Emitter();
|
137 | this.onNodeRefreshedEmitter = new event_1.Emitter();
|
138 | this.toDispose = new disposable_1.DisposableCollection();
|
139 | this.onDidChangeBusyEmitter = new event_1.Emitter();
|
140 | this.onDidChangeBusy = this.onDidChangeBusyEmitter.event;
|
141 | this.onDidUpdateEmitter = new event_1.Emitter();
|
142 | this.onDidUpdate = this.onDidUpdateEmitter.event;
|
143 | this.nodes = {};
|
144 | this.toDisposeOnSetRoot = new disposable_1.DisposableCollection();
|
145 | this.toDispose.push(this.onChangedEmitter);
|
146 | this.toDispose.push(this.onNodeRefreshedEmitter);
|
147 | this.toDispose.push(this.onDidChangeBusyEmitter);
|
148 | }
|
149 | dispose() {
|
150 | this.nodes = {};
|
151 | this.toDispose.dispose();
|
152 | }
|
153 | get root() {
|
154 | return this._root;
|
155 | }
|
156 | set root(root) {
|
157 | this.toDisposeOnSetRoot.dispose();
|
158 | const cancelRefresh = new cancellation_1.CancellationTokenSource();
|
159 | this.toDisposeOnSetRoot.push(cancelRefresh);
|
160 | this.nodes = {};
|
161 | this._root = root;
|
162 | this.addNode(root);
|
163 | this.refresh(undefined, cancelRefresh.token);
|
164 | }
|
165 | get onChanged() {
|
166 | return this.onChangedEmitter.event;
|
167 | }
|
168 | fireChanged() {
|
169 | this.onChangedEmitter.fire(undefined);
|
170 | }
|
171 | get onNodeRefreshed() {
|
172 | return this.onNodeRefreshedEmitter.event;
|
173 | }
|
174 | async fireNodeRefreshed(parent) {
|
175 | await event_1.WaitUntilEvent.fire(this.onNodeRefreshedEmitter, parent);
|
176 | this.fireChanged();
|
177 | }
|
178 | getNode(id) {
|
179 | return id !== undefined ? this.nodes[id] : undefined;
|
180 | }
|
181 | validateNode(node) {
|
182 | const id = !!node ? node.id : undefined;
|
183 | return this.getNode(id);
|
184 | }
|
185 | async refresh(raw, cancellationToken) {
|
186 | const parent = !raw ? this._root : this.validateNode(raw);
|
187 | let result;
|
188 | if (CompositeTreeNode.is(parent)) {
|
189 | const busySource = new cancellation_1.CancellationTokenSource();
|
190 | this.doMarkAsBusy(parent, 800, busySource.token);
|
191 | try {
|
192 | result = parent;
|
193 | const children = await this.resolveChildren(parent);
|
194 | if (cancellationToken === null || cancellationToken === void 0 ? void 0 : cancellationToken.isCancellationRequested) {
|
195 | return;
|
196 | }
|
197 | result = await this.setChildren(parent, children);
|
198 | if (cancellationToken === null || cancellationToken === void 0 ? void 0 : cancellationToken.isCancellationRequested) {
|
199 | return;
|
200 | }
|
201 | }
|
202 | finally {
|
203 | busySource.cancel();
|
204 | }
|
205 | }
|
206 | this.fireChanged();
|
207 | return result;
|
208 | }
|
209 | resolveChildren(parent) {
|
210 | return Promise.resolve(Array.from(parent.children));
|
211 | }
|
212 | async setChildren(parent, children) {
|
213 | const root = this.getRootNode(parent);
|
214 | if (this.nodes[root.id] && this.nodes[root.id] !== root) {
|
215 | console.error(`Child node '${parent.id}' does not belong to this '${root.id}' tree.`);
|
216 | return undefined;
|
217 | }
|
218 | this.removeNode(parent);
|
219 | parent.children = children;
|
220 | this.addNode(parent);
|
221 | await this.fireNodeRefreshed(parent);
|
222 | return parent;
|
223 | }
|
224 | removeNode(node) {
|
225 | if (CompositeTreeNode.is(node)) {
|
226 | node.children.forEach(child => this.removeNode(child));
|
227 | }
|
228 | if (node) {
|
229 | delete this.nodes[node.id];
|
230 | }
|
231 | }
|
232 | getRootNode(node) {
|
233 | if (node.parent === undefined) {
|
234 | return node;
|
235 | }
|
236 | else {
|
237 | return this.getRootNode(node.parent);
|
238 | }
|
239 | }
|
240 | addNode(node) {
|
241 | if (node) {
|
242 | this.nodes[node.id] = node;
|
243 | }
|
244 | if (CompositeTreeNode.is(node)) {
|
245 | const { children } = node;
|
246 | children.forEach((child, index) => {
|
247 | CompositeTreeNode.setParent(child, index, node);
|
248 | this.addNode(child);
|
249 | });
|
250 | }
|
251 | }
|
252 | async markAsBusy(raw, ms, token) {
|
253 | const node = this.validateNode(raw);
|
254 | if (node) {
|
255 | await this.doMarkAsBusy(node, ms, token);
|
256 | }
|
257 | }
|
258 | markAsChecked(node, checked) {
|
259 | node.checkboxInfo.checked = checked;
|
260 | this.onDidUpdateEmitter.fire([node]);
|
261 | }
|
262 | async doMarkAsBusy(node, ms, token) {
|
263 | try {
|
264 | await (0, promise_util_1.timeout)(ms, token);
|
265 | this.doSetBusy(node);
|
266 | token.onCancellationRequested(() => this.doResetBusy(node));
|
267 | }
|
268 | catch {
|
269 |
|
270 | }
|
271 | }
|
272 | doSetBusy(node) {
|
273 | const oldBusy = node.busy || 0;
|
274 | node.busy = oldBusy + 1;
|
275 | if (oldBusy === 0) {
|
276 | this.onDidChangeBusyEmitter.fire(node);
|
277 | }
|
278 | }
|
279 | doResetBusy(node) {
|
280 | const oldBusy = node.busy || 0;
|
281 | if (oldBusy > 0) {
|
282 | node.busy = oldBusy - 1;
|
283 | if (node.busy === 0) {
|
284 | this.onDidChangeBusyEmitter.fire(node);
|
285 | }
|
286 | }
|
287 | }
|
288 | };
|
289 | TreeImpl = __decorate([
|
290 | (0, inversify_1.injectable)(),
|
291 | __metadata("design:paramtypes", [])
|
292 | ], TreeImpl);
|
293 | exports.TreeImpl = TreeImpl;
|
294 |
|
\ | No newline at end of file |