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 | var __param = (this && this.__param) || function (paramIndex, decorator) {
|
27 | return function (target, key) { decorator(target, key, paramIndex); }
|
28 | };
|
29 | var TreeWidget_1;
|
30 | Object.defineProperty(exports, "__esModule", { value: true });
|
31 | exports.TreeWidget = exports.defaultTreeProps = exports.TreeProps = exports.TREE_NODE_INDENT_GUIDE_CLASS = exports.TREE_NODE_CAPTION_CLASS = exports.COMPOSITE_TREE_NODE_CLASS = exports.EXPANDABLE_TREE_NODE_CLASS = exports.TREE_NODE_SEGMENT_GROW_CLASS = exports.TREE_NODE_SEGMENT_CLASS = exports.TREE_NODE_TAIL_CLASS = exports.TREE_NODE_INFO_CLASS = exports.TREE_NODE_CONTENT_CLASS = exports.TREE_NODE_CLASS = exports.TREE_CONTAINER_CLASS = exports.TREE_CLASS = void 0;
|
32 | const inversify_1 = require("inversify");
|
33 | const common_1 = require("../../common");
|
34 | const keys_1 = require("../keyboard/keys");
|
35 | const context_menu_renderer_1 = require("../context-menu-renderer");
|
36 | const widgets_1 = require("../widgets");
|
37 | const tree_1 = require("./tree");
|
38 | const tree_model_1 = require("./tree-model");
|
39 | const tree_expansion_1 = require("./tree-expansion");
|
40 | const tree_selection_1 = require("./tree-selection");
|
41 | const tree_decorator_1 = require("./tree-decorator");
|
42 | const objects_1 = require("../../common/objects");
|
43 | const os_1 = require("../../common/os");
|
44 | const react_widget_1 = require("../widgets/react-widget");
|
45 | const React = require("react");
|
46 | const react_virtuoso_1 = require("react-virtuoso");
|
47 | const tree_iterator_1 = require("./tree-iterator");
|
48 | const search_box_1 = require("./search-box");
|
49 | const tree_search_1 = require("./tree-search");
|
50 | const domutils_1 = require("@phosphor/domutils");
|
51 | const tree_widget_selection_1 = require("./tree-widget-selection");
|
52 | const label_provider_1 = require("../label-provider");
|
53 | const core_preferences_1 = require("../core-preferences");
|
54 | const tree_focus_service_1 = require("./tree-focus-service");
|
55 | const react_1 = require("react");
|
56 | const debounce = require('lodash.debounce');
|
57 | exports.TREE_CLASS = 'theia-Tree';
|
58 | exports.TREE_CONTAINER_CLASS = 'theia-TreeContainer';
|
59 | exports.TREE_NODE_CLASS = 'theia-TreeNode';
|
60 | exports.TREE_NODE_CONTENT_CLASS = 'theia-TreeNodeContent';
|
61 | exports.TREE_NODE_INFO_CLASS = 'theia-TreeNodeInfo';
|
62 | exports.TREE_NODE_TAIL_CLASS = 'theia-TreeNodeTail';
|
63 | exports.TREE_NODE_SEGMENT_CLASS = 'theia-TreeNodeSegment';
|
64 | exports.TREE_NODE_SEGMENT_GROW_CLASS = 'theia-TreeNodeSegmentGrow';
|
65 | exports.EXPANDABLE_TREE_NODE_CLASS = 'theia-ExpandableTreeNode';
|
66 | exports.COMPOSITE_TREE_NODE_CLASS = 'theia-CompositeTreeNode';
|
67 | exports.TREE_NODE_CAPTION_CLASS = 'theia-TreeNodeCaption';
|
68 | exports.TREE_NODE_INDENT_GUIDE_CLASS = 'theia-tree-node-indent';
|
69 | exports.TreeProps = Symbol('TreeProps');
|
70 |
|
71 |
|
72 |
|
73 | exports.defaultTreeProps = {
|
74 | leftPadding: 8,
|
75 | expansionTogglePadding: 22
|
76 | };
|
77 | let TreeWidget = TreeWidget_1 = class TreeWidget extends react_widget_1.ReactWidget {
|
78 | constructor(props, model, contextMenuRenderer) {
|
79 | super();
|
80 | this.props = props;
|
81 | this.model = model;
|
82 | this.contextMenuRenderer = contextMenuRenderer;
|
83 | this.decorations = new Map();
|
84 | this.shouldScrollToRow = true;
|
85 | this.rows = new Map();
|
86 | this.updateRows = debounce(() => this.doUpdateRows(), 10);
|
87 | this.scheduleUpdateScrollToRow = debounce(this.updateScrollToRow);
|
88 | |
89 |
|
90 |
|
91 |
|
92 | this.updateDecorations = debounce(() => this.doUpdateDecorations(), 150);
|
93 | this.ScrollingRowRenderer = ({ rows }) => {
|
94 | (0, react_1.useEffect)(() => this.scrollToSelected());
|
95 | return React.createElement(React.Fragment, null, rows.map(row => React.createElement("div", { key: row.index }, this.renderNodeRow(row))));
|
96 | };
|
97 | this.scrollArea = this.node;
|
98 | |
99 |
|
100 |
|
101 | this.renderNodeRow = (row) => this.doRenderNodeRow(row);
|
102 | |
103 |
|
104 |
|
105 | this.toggle = (event) => this.doToggle(event);
|
106 | |
107 |
|
108 |
|
109 | this.handleExpansionToggleDblClickEvent = (event) => this.doHandleExpansionToggleDblClickEvent(event);
|
110 | this.scrollOptions = {
|
111 | suppressScrollX: true,
|
112 | minScrollbarLength: 35
|
113 | };
|
114 | this.addClass(exports.TREE_CLASS);
|
115 | this.node.tabIndex = 0;
|
116 | }
|
117 | init() {
|
118 | if (this.props.search) {
|
119 | this.searchBox = this.searchBoxFactory({ ...search_box_1.SearchBoxProps.DEFAULT, showButtons: true, showFilter: true });
|
120 | this.searchBox.node.addEventListener('focus', () => {
|
121 | this.node.focus();
|
122 | });
|
123 | this.toDispose.pushAll([
|
124 | this.searchBox,
|
125 | this.searchBox.onTextChange(async (data) => {
|
126 | await this.treeSearch.filter(data);
|
127 | this.searchHighlights = this.treeSearch.getHighlights();
|
128 | this.searchBox.updateHighlightInfo({
|
129 | filterText: data,
|
130 | total: this.rows.size,
|
131 | matched: this.searchHighlights.size
|
132 | });
|
133 | this.update();
|
134 | }),
|
135 | this.searchBox.onClose(data => this.treeSearch.filter(undefined)),
|
136 | this.searchBox.onNext(() => {
|
137 |
|
138 | if (this.searchHighlights.size > 1) {
|
139 | this.model.selectNextNode();
|
140 | }
|
141 | }),
|
142 | this.searchBox.onPrevious(() => {
|
143 |
|
144 | if (this.searchHighlights.size > 1) {
|
145 | this.model.selectPrevNode();
|
146 | }
|
147 | }),
|
148 | this.searchBox.onFilterToggled(e => {
|
149 | this.updateRows();
|
150 | }),
|
151 | this.treeSearch,
|
152 | this.treeSearch.onFilteredNodesChanged(nodes => {
|
153 | if (this.searchBox.isFiltering) {
|
154 | this.updateRows();
|
155 | }
|
156 | const node = nodes.find(tree_selection_1.SelectableTreeNode.is);
|
157 | if (node) {
|
158 | this.model.selectNode(node);
|
159 | }
|
160 | }),
|
161 | ]);
|
162 | }
|
163 | this.node.addEventListener('mousedown', this.handleMiddleClickEvent.bind(this));
|
164 | this.node.addEventListener('mouseup', this.handleMiddleClickEvent.bind(this));
|
165 | this.node.addEventListener('auxclick', this.handleMiddleClickEvent.bind(this));
|
166 | this.toDispose.pushAll([
|
167 | this.model,
|
168 | this.model.onChanged(() => this.updateRows()),
|
169 | this.model.onSelectionChanged(() => this.scheduleUpdateScrollToRow({ resize: false })),
|
170 | this.focusService.onDidChangeFocus(() => this.scheduleUpdateScrollToRow({ resize: false })),
|
171 | this.model.onDidChangeBusy(() => this.update()),
|
172 | this.model.onDidUpdate(() => this.update()),
|
173 | this.model.onNodeRefreshed(() => this.updateDecorations()),
|
174 | this.model.onExpansionChanged(() => this.updateDecorations()),
|
175 | this.decoratorService,
|
176 | this.decoratorService.onDidChangeDecorations(() => this.updateDecorations()),
|
177 | this.labelProvider.onDidChange(e => {
|
178 | for (const row of this.rows.values()) {
|
179 | if (e.affects(row)) {
|
180 | this.update();
|
181 | return;
|
182 | }
|
183 | }
|
184 | })
|
185 | ]);
|
186 | setTimeout(() => {
|
187 | this.updateRows();
|
188 | this.updateDecorations();
|
189 | });
|
190 | if (this.props.globalSelection) {
|
191 | this.toDispose.pushAll([
|
192 | this.model.onSelectionChanged(() => {
|
193 | if (this.node.contains(document.activeElement)) {
|
194 | this.updateGlobalSelection();
|
195 | }
|
196 | }),
|
197 | this.focusService.onDidChangeFocus(focus => {
|
198 | if (focus && this.node.contains(document.activeElement) && this.model.selectedNodes[0] !== focus && this.model.selectedNodes.includes(focus)) {
|
199 | this.updateGlobalSelection();
|
200 | }
|
201 | }),
|
202 | common_1.Disposable.create(() => {
|
203 | const selection = this.selectionService.selection;
|
204 | if (tree_widget_selection_1.TreeWidgetSelection.isSource(selection, this)) {
|
205 | this.selectionService.selection = undefined;
|
206 | }
|
207 | })
|
208 | ]);
|
209 | }
|
210 | this.toDispose.push(this.corePreferences.onPreferenceChanged(preference => {
|
211 | if (preference.preferenceName === 'workbench.tree.renderIndentGuides') {
|
212 | this.update();
|
213 | }
|
214 | }));
|
215 | }
|
216 | |
217 |
|
218 |
|
219 | updateGlobalSelection() {
|
220 | this.selectionService.selection = tree_widget_selection_1.TreeWidgetSelection.create(this);
|
221 | }
|
222 | doUpdateRows() {
|
223 | const root = this.model.root;
|
224 | const rowsToUpdate = [];
|
225 | if (root) {
|
226 | const depths = new Map();
|
227 | let index = 0;
|
228 | for (const node of new tree_iterator_1.TopDownTreeIterator(root, {
|
229 | pruneCollapsed: true,
|
230 | pruneSiblings: true
|
231 | })) {
|
232 | if (this.shouldDisplayNode(node)) {
|
233 | const depth = this.getDepthForNode(node, depths);
|
234 | if (tree_1.CompositeTreeNode.is(node)) {
|
235 | depths.set(node, depth);
|
236 | }
|
237 | rowsToUpdate.push([node.id, this.toNodeRow(node, index++, depth)]);
|
238 | }
|
239 | }
|
240 | }
|
241 | this.rows = new Map(rowsToUpdate);
|
242 | this.updateScrollToRow();
|
243 | }
|
244 | getDepthForNode(node, depths) {
|
245 | const parentDepth = depths.get(node.parent);
|
246 | return parentDepth === undefined ? 0 : tree_1.TreeNode.isVisible(node.parent) ? parentDepth + 1 : parentDepth;
|
247 | }
|
248 | toNodeRow(node, index, depth) {
|
249 | return { node, index, depth };
|
250 | }
|
251 | shouldDisplayNode(node) {
|
252 | var _a;
|
253 | return tree_1.TreeNode.isVisible(node) && (!((_a = this.searchBox) === null || _a === void 0 ? void 0 : _a.isFiltering) || this.treeSearch.passesFilters(node));
|
254 | }
|
255 | |
256 |
|
257 |
|
258 |
|
259 | updateScrollToRow() {
|
260 | this.scrollToRow = this.getScrollToRow();
|
261 | this.update();
|
262 | }
|
263 | |
264 |
|
265 |
|
266 |
|
267 |
|
268 | getScrollToRow() {
|
269 | var _a;
|
270 | if (!this.shouldScrollToRow) {
|
271 | return undefined;
|
272 | }
|
273 | const { focusedNode } = this.focusService;
|
274 | return focusedNode && ((_a = this.rows.get(focusedNode.id)) === null || _a === void 0 ? void 0 : _a.index);
|
275 | }
|
276 | async doUpdateDecorations() {
|
277 | this.decorations = await this.decoratorService.getDecorations(this.model);
|
278 | this.update();
|
279 | }
|
280 | onActivateRequest(msg) {
|
281 | super.onActivateRequest(msg);
|
282 | this.node.focus({ preventScroll: true });
|
283 | }
|
284 | |
285 |
|
286 |
|
287 | doFocus() {
|
288 | if (!this.model.selectedNodes.length) {
|
289 | const node = this.getNodeToFocus();
|
290 | if (tree_selection_1.SelectableTreeNode.is(node)) {
|
291 | this.model.selectNode(node);
|
292 | }
|
293 | }
|
294 | }
|
295 | |
296 |
|
297 |
|
298 |
|
299 |
|
300 | getNodeToFocus() {
|
301 | const { focusedNode } = this.focusService;
|
302 | if (focusedNode) {
|
303 | return focusedNode;
|
304 | }
|
305 | const { root } = this.model;
|
306 | if (tree_selection_1.SelectableTreeNode.isVisible(root)) {
|
307 | return root;
|
308 | }
|
309 | return this.model.getNextSelectableNode(root);
|
310 | }
|
311 | onUpdateRequest(msg) {
|
312 | if (!this.isAttached || !this.isVisible) {
|
313 | return;
|
314 | }
|
315 | super.onUpdateRequest(msg);
|
316 | }
|
317 | onResize(msg) {
|
318 | super.onResize(msg);
|
319 | this.update();
|
320 | }
|
321 | render() {
|
322 | return React.createElement('div', this.createContainerAttributes(), this.renderTree(this.model));
|
323 | }
|
324 | |
325 |
|
326 |
|
327 | createContainerAttributes() {
|
328 | const classNames = [exports.TREE_CONTAINER_CLASS];
|
329 | if (!this.rows.size) {
|
330 | classNames.push('empty');
|
331 | }
|
332 | if (this.model.selectedNodes.length === 0 && !this.focusService.focusedNode) {
|
333 | classNames.push('focused');
|
334 | }
|
335 | return {
|
336 | className: classNames.join(' '),
|
337 | onContextMenu: event => this.handleContextMenuEvent(this.getContainerTreeNode(), event)
|
338 | };
|
339 | }
|
340 | |
341 |
|
342 |
|
343 |
|
344 |
|
345 | getContainerTreeNode() {
|
346 | return this.model.root;
|
347 | }
|
348 | |
349 |
|
350 |
|
351 |
|
352 | renderTree(model) {
|
353 | if (model.root) {
|
354 | const rows = Array.from(this.rows.values());
|
355 | if (this.props.virtualized === false) {
|
356 | return React.createElement(this.ScrollingRowRenderer, { rows: rows });
|
357 | }
|
358 | return React.createElement(TreeWidget_1.View, { ref: view => this.view = (view || undefined), width: this.node.offsetWidth, height: this.node.offsetHeight, rows: rows, renderNodeRow: this.renderNodeRow, scrollToRow: this.scrollToRow });
|
359 | }
|
360 |
|
361 | return null;
|
362 | }
|
363 | |
364 |
|
365 |
|
366 | scrollToSelected() {
|
367 | if (this.props.scrollIfActive === true && !this.node.contains(document.activeElement)) {
|
368 | return;
|
369 | }
|
370 | const focus = this.node.getElementsByClassName(widgets_1.FOCUS_CLASS)[0];
|
371 | if (focus) {
|
372 | domutils_1.ElementExt.scrollIntoViewIfNeeded(this.scrollArea, focus);
|
373 | }
|
374 | else {
|
375 | const selected = this.node.getElementsByClassName(widgets_1.SELECTED_CLASS)[0];
|
376 | if (selected) {
|
377 | domutils_1.ElementExt.scrollIntoViewIfNeeded(this.scrollArea, selected);
|
378 | }
|
379 | }
|
380 | }
|
381 | |
382 |
|
383 |
|
384 | doRenderNodeRow({ node, depth }) {
|
385 | return React.createElement(React.Fragment, null,
|
386 | this.renderIndent(node, { depth }),
|
387 | this.renderNode(node, { depth }));
|
388 | }
|
389 | |
390 |
|
391 |
|
392 |
|
393 |
|
394 | renderIcon(node, props) {
|
395 |
|
396 | return null;
|
397 | }
|
398 | |
399 |
|
400 |
|
401 |
|
402 | doToggle(event) {
|
403 | const nodeId = event.currentTarget.getAttribute('data-node-id');
|
404 | if (nodeId) {
|
405 | const node = this.model.getNode(nodeId);
|
406 | if (node && this.props.expandOnlyOnExpansionToggleClick) {
|
407 | if (this.isExpandable(node) && !this.hasShiftMask(event) && !this.hasCtrlCmdMask(event)) {
|
408 | this.model.toggleNodeExpansion(node);
|
409 | }
|
410 | }
|
411 | else {
|
412 | this.handleClickEvent(node, event);
|
413 | }
|
414 | }
|
415 | event.stopPropagation();
|
416 | }
|
417 | |
418 |
|
419 |
|
420 |
|
421 |
|
422 | renderExpansionToggle(node, props) {
|
423 | if (!this.isExpandable(node)) {
|
424 |
|
425 | return null;
|
426 | }
|
427 | const classes = [exports.TREE_NODE_SEGMENT_CLASS, widgets_1.EXPANSION_TOGGLE_CLASS];
|
428 | if (!node.expanded) {
|
429 | classes.push(widgets_1.COLLAPSED_CLASS);
|
430 | }
|
431 | if (node.busy) {
|
432 | classes.push(widgets_1.BUSY_CLASS, ...widgets_1.CODICON_LOADING_CLASSES);
|
433 | }
|
434 | else {
|
435 | classes.push(...widgets_1.CODICON_TREE_ITEM_CLASSES);
|
436 | }
|
437 | const className = classes.join(' ');
|
438 | return React.createElement("div", { "data-node-id": node.id, className: className, onClick: this.toggle, onDoubleClick: this.handleExpansionToggleDblClickEvent });
|
439 | }
|
440 | |
441 |
|
442 |
|
443 |
|
444 |
|
445 | renderCheckbox(node, props) {
|
446 | var _a, _b;
|
447 | if (node.checkboxInfo === undefined) {
|
448 |
|
449 | return null;
|
450 | }
|
451 | return React.createElement("input", { "data-node-id": node.id, readOnly: true, type: 'checkbox', checked: !!node.checkboxInfo.checked, title: node.checkboxInfo.tooltip, "aria-label": (_a = node.checkboxInfo.accessibilityInformation) === null || _a === void 0 ? void 0 : _a.label, role: (_b = node.checkboxInfo.accessibilityInformation) === null || _b === void 0 ? void 0 : _b.role, className: 'theia-input', onClick: event => this.toggleChecked(event) });
|
452 | }
|
453 | toggleChecked(event) {
|
454 | const nodeId = event.currentTarget.getAttribute('data-node-id');
|
455 | if (nodeId) {
|
456 | const node = this.model.getNode(nodeId);
|
457 | if (node) {
|
458 | this.model.markAsChecked(node, !node.checkboxInfo.checked);
|
459 | }
|
460 | else {
|
461 | this.handleClickEvent(node, event);
|
462 | }
|
463 | }
|
464 | event.preventDefault();
|
465 | event.stopPropagation();
|
466 | }
|
467 | |
468 |
|
469 |
|
470 |
|
471 |
|
472 | renderCaption(node, props) {
|
473 | const attrs = this.getCaptionAttributes(node, props);
|
474 | const children = this.getCaptionChildren(node, props);
|
475 | return React.createElement('div', attrs, children);
|
476 | }
|
477 | getCaptionAttributes(node, props) {
|
478 | const tooltip = this.getDecorationData(node, 'tooltip').filter(objects_1.notEmpty).join(' • ');
|
479 | const classes = [exports.TREE_NODE_SEGMENT_CLASS];
|
480 | if (!this.hasTrailingSuffixes(node)) {
|
481 | classes.push(exports.TREE_NODE_SEGMENT_GROW_CLASS);
|
482 | }
|
483 | const className = classes.join(' ');
|
484 | let attrs = this.decorateCaption(node, {
|
485 | className, id: node.id
|
486 | });
|
487 | if (tooltip.length > 0) {
|
488 | attrs = {
|
489 | ...attrs,
|
490 | title: tooltip
|
491 | };
|
492 | }
|
493 | return attrs;
|
494 | }
|
495 | getCaptionChildren(node, props) {
|
496 | const children = [];
|
497 | const caption = this.toNodeName(node);
|
498 | const highlight = this.getDecorationData(node, 'highlight')[0];
|
499 | if (highlight) {
|
500 | children.push(this.toReactNode(caption, highlight));
|
501 | }
|
502 | const searchHighlight = this.searchHighlights ? this.searchHighlights.get(node.id) : undefined;
|
503 | if (searchHighlight) {
|
504 | children.push(...this.toReactNode(caption, searchHighlight));
|
505 | }
|
506 | else if (!highlight) {
|
507 | children.push(caption);
|
508 | }
|
509 | return children;
|
510 | }
|
511 | |
512 |
|
513 |
|
514 |
|
515 |
|
516 | toReactNode(caption, highlight) {
|
517 | let style = {};
|
518 | if (highlight.color) {
|
519 | style = {
|
520 | ...style,
|
521 | color: highlight.color
|
522 | };
|
523 | }
|
524 | if (highlight.backgroundColor) {
|
525 | style = {
|
526 | ...style,
|
527 | backgroundColor: highlight.backgroundColor
|
528 | };
|
529 | }
|
530 | const createChildren = (fragment, index) => {
|
531 | const { data } = fragment;
|
532 | if (fragment.highlight) {
|
533 | return React.createElement("mark", { className: tree_decorator_1.TreeDecoration.Styles.CAPTION_HIGHLIGHT_CLASS, style: style, key: index }, data);
|
534 | }
|
535 | else {
|
536 | return data;
|
537 | }
|
538 | };
|
539 | return tree_decorator_1.TreeDecoration.CaptionHighlight.split(caption, highlight).map(createChildren);
|
540 | }
|
541 | |
542 |
|
543 |
|
544 |
|
545 |
|
546 | decorateCaption(node, attrs) {
|
547 | const style = this.getDecorationData(node, 'fontData')
|
548 | .filter(objects_1.notEmpty)
|
549 | .reverse()
|
550 | .map(fontData => this.applyFontStyles({}, fontData))
|
551 | .reduce((acc, current) => ({
|
552 | ...acc,
|
553 | ...current
|
554 | }), {});
|
555 | return {
|
556 | ...attrs,
|
557 | style
|
558 | };
|
559 | }
|
560 | |
561 |
|
562 |
|
563 |
|
564 |
|
565 |
|
566 | hasTrailingSuffixes(node) {
|
567 | return this.getDecorationData(node, 'captionSuffixes').filter(objects_1.notEmpty).reduce((acc, current) => acc.concat(current), []).length > 0;
|
568 | }
|
569 | |
570 |
|
571 |
|
572 |
|
573 |
|
574 | applyFontStyles(original, fontData) {
|
575 | if (fontData === undefined) {
|
576 | return original;
|
577 | }
|
578 | const modified = { ...original };
|
579 | const { color, style } = fontData;
|
580 | if (color) {
|
581 | modified.color = color;
|
582 | }
|
583 | if (style) {
|
584 | (Array.isArray(style) ? style : [style]).forEach(s => {
|
585 | switch (s) {
|
586 | case 'bold':
|
587 | modified.fontWeight = s;
|
588 | break;
|
589 | case 'normal':
|
590 | case 'oblique':
|
591 | case 'italic':
|
592 | modified.fontStyle = s;
|
593 | break;
|
594 | case 'underline':
|
595 | case 'line-through':
|
596 | modified.textDecoration = s;
|
597 | break;
|
598 | default:
|
599 | throw new Error(`Unexpected font style: "${s}".`);
|
600 | }
|
601 | });
|
602 | }
|
603 | return modified;
|
604 | }
|
605 | |
606 |
|
607 |
|
608 |
|
609 |
|
610 |
|
611 | renderCaptionAffixes(node, props, affixKey) {
|
612 | const suffix = affixKey === 'captionSuffixes';
|
613 | const affixClass = suffix ? tree_decorator_1.TreeDecoration.Styles.CAPTION_SUFFIX_CLASS : tree_decorator_1.TreeDecoration.Styles.CAPTION_PREFIX_CLASS;
|
614 | const classes = [exports.TREE_NODE_SEGMENT_CLASS, affixClass];
|
615 | const affixes = this.getDecorationData(node, affixKey).filter(objects_1.notEmpty).reduce((acc, current) => acc.concat(current), []);
|
616 | const children = [];
|
617 | for (let i = 0; i < affixes.length; i++) {
|
618 | const affix = affixes[i];
|
619 | if (suffix && i === affixes.length - 1) {
|
620 | classes.push(exports.TREE_NODE_SEGMENT_GROW_CLASS);
|
621 | }
|
622 | const style = this.applyFontStyles({}, affix.fontData);
|
623 | const className = classes.join(' ');
|
624 | const key = node.id + '_' + i;
|
625 | const attrs = {
|
626 | className,
|
627 | style,
|
628 | key
|
629 | };
|
630 | children.push(React.createElement('div', attrs, affix.data));
|
631 | }
|
632 | return React.createElement(React.Fragment, null, children);
|
633 | }
|
634 | |
635 |
|
636 |
|
637 |
|
638 |
|
639 | decorateIcon(node, icon) {
|
640 | if (!icon) {
|
641 | return;
|
642 | }
|
643 | const overlayIcons = [];
|
644 |
|
645 | const seenPositions = new Set();
|
646 | const overlays = this.getDecorationData(node, 'iconOverlay').filter(objects_1.notEmpty);
|
647 | for (const overlay of overlays) {
|
648 | if (!seenPositions.has(overlay.position)) {
|
649 | seenPositions.add(overlay.position);
|
650 | const iconClasses = [tree_decorator_1.TreeDecoration.Styles.DECORATOR_SIZE_CLASS, tree_decorator_1.TreeDecoration.IconOverlayPosition.getStyle(overlay.position)];
|
651 | const style = (color) => color === undefined ? {} : { color };
|
652 | if (overlay.background) {
|
653 | overlayIcons.push(React.createElement("span", { key: node.id + 'bg', className: this.getIconClass(overlay.background.shape, iconClasses), style: style(overlay.background.color) }));
|
654 | }
|
655 | const overlayIcon = 'icon' in overlay ? overlay.icon : overlay.iconClass;
|
656 | overlayIcons.push(React.createElement("span", { key: node.id, className: this.getIconClass(overlayIcon, iconClasses), style: style(overlay.color) }));
|
657 | }
|
658 | }
|
659 | if (overlayIcons.length > 0) {
|
660 | return React.createElement("div", { className: tree_decorator_1.TreeDecoration.Styles.ICON_WRAPPER_CLASS },
|
661 | icon,
|
662 | overlayIcons);
|
663 | }
|
664 | return icon;
|
665 | }
|
666 | |
667 |
|
668 |
|
669 |
|
670 |
|
671 | renderTailDecorations(node, props) {
|
672 | const tailDecorations = this.getDecorationData(node, 'tailDecorations').reduce((acc, current) => acc.concat(current), []);
|
673 | if (tailDecorations.length === 0) {
|
674 | return;
|
675 | }
|
676 | return this.renderTailDecorationsForNode(node, props, tailDecorations);
|
677 | }
|
678 | renderTailDecorationsForNode(node, props, tailDecorations) {
|
679 | let dotDecoration;
|
680 | const otherDecorations = [];
|
681 | tailDecorations.reverse().forEach(decoration => {
|
682 | if (tree_decorator_1.TreeDecoration.TailDecoration.isDotDecoration(decoration)) {
|
683 | dotDecoration || (dotDecoration = decoration);
|
684 | }
|
685 | else if (decoration.data || decoration.icon || decoration.iconClass) {
|
686 | otherDecorations.push(decoration);
|
687 | }
|
688 | });
|
689 | const decorationsToRender = dotDecoration ? [dotDecoration, ...otherDecorations] : otherDecorations;
|
690 | return React.createElement(React.Fragment, null, decorationsToRender.map((decoration, index) => {
|
691 | const { tooltip, data, fontData, color, icon, iconClass } = decoration;
|
692 | const iconToRender = icon !== null && icon !== void 0 ? icon : iconClass;
|
693 | const className = [exports.TREE_NODE_SEGMENT_CLASS, exports.TREE_NODE_TAIL_CLASS, 'flex'].join(' ');
|
694 | const style = fontData ? this.applyFontStyles({}, fontData) : color ? { color } : undefined;
|
695 | const content = data ? data : iconToRender
|
696 | ? React.createElement("span", { key: node.id + 'icon' + index, className: this.getIconClass(iconToRender, iconToRender === 'circle' ? [tree_decorator_1.TreeDecoration.Styles.DECORATOR_SIZE_CLASS] : []) })
|
697 | : '';
|
698 | return React.createElement("div", { key: node.id + className + index, className: className, style: style, title: tooltip },
|
699 | content,
|
700 | index !== decorationsToRender.length - 1 ? ',' : '');
|
701 | }));
|
702 | }
|
703 | |
704 |
|
705 |
|
706 |
|
707 |
|
708 |
|
709 |
|
710 |
|
711 | getIconClass(iconName, additionalClasses = []) {
|
712 | const iconClass = (typeof iconName === 'string') ? ['a', 'fa', `fa-${iconName}`] : ['a'].concat(iconName);
|
713 | return iconClass.concat(additionalClasses).join(' ');
|
714 | }
|
715 | |
716 |
|
717 |
|
718 |
|
719 |
|
720 | renderIndent(node, props) {
|
721 | const renderIndentGuides = this.corePreferences['workbench.tree.renderIndentGuides'];
|
722 | if (renderIndentGuides === 'none') {
|
723 | return undefined;
|
724 | }
|
725 | const indentDivs = [];
|
726 | let current = node;
|
727 | let depth = props.depth;
|
728 | while (current && depth) {
|
729 | const classNames = [exports.TREE_NODE_INDENT_GUIDE_CLASS];
|
730 | if (this.needsActiveIndentGuideline(current)) {
|
731 | classNames.push('active');
|
732 | }
|
733 | else {
|
734 | classNames.push(renderIndentGuides === 'onHover' ? 'hover' : 'always');
|
735 | }
|
736 | const paddingLeft = this.getDepthPadding(depth);
|
737 | indentDivs.unshift(React.createElement("div", { key: depth, className: classNames.join(' '), style: {
|
738 | paddingLeft: `${paddingLeft}px`
|
739 | } }));
|
740 | current = current.parent;
|
741 | depth--;
|
742 | }
|
743 | return indentDivs;
|
744 | }
|
745 | needsActiveIndentGuideline(node) {
|
746 | const parent = node.parent;
|
747 | if (!parent || !this.isExpandable(parent)) {
|
748 | return false;
|
749 | }
|
750 | if (tree_selection_1.SelectableTreeNode.isSelected(parent)) {
|
751 | return true;
|
752 | }
|
753 | if (parent.expanded) {
|
754 | for (const sibling of parent.children) {
|
755 | if (tree_selection_1.SelectableTreeNode.isSelected(sibling) && !(this.isExpandable(sibling) && sibling.expanded)) {
|
756 | return true;
|
757 | }
|
758 | }
|
759 | }
|
760 | return false;
|
761 | }
|
762 | |
763 |
|
764 |
|
765 |
|
766 |
|
767 | renderNode(node, props) {
|
768 | if (!tree_1.TreeNode.isVisible(node)) {
|
769 | return undefined;
|
770 | }
|
771 | const attributes = this.createNodeAttributes(node, props);
|
772 | const content = React.createElement("div", { className: exports.TREE_NODE_CONTENT_CLASS },
|
773 | this.renderExpansionToggle(node, props),
|
774 | this.renderCheckbox(node, props),
|
775 | this.decorateIcon(node, this.renderIcon(node, props)),
|
776 | this.renderCaptionAffixes(node, props, 'captionPrefixes'),
|
777 | this.renderCaption(node, props),
|
778 | this.renderCaptionAffixes(node, props, 'captionSuffixes'),
|
779 | this.renderTailDecorations(node, props));
|
780 | return React.createElement('div', attributes, content);
|
781 | }
|
782 | |
783 |
|
784 |
|
785 |
|
786 |
|
787 | createNodeAttributes(node, props) {
|
788 | const className = this.createNodeClassNames(node, props).join(' ');
|
789 | const style = this.createNodeStyle(node, props);
|
790 | return {
|
791 | className,
|
792 | style,
|
793 | onClick: event => this.handleClickEvent(node, event),
|
794 | onDoubleClick: event => this.handleDblClickEvent(node, event),
|
795 | onAuxClick: event => this.handleAuxClickEvent(node, event),
|
796 | onContextMenu: event => this.handleContextMenuEvent(node, event),
|
797 | };
|
798 | }
|
799 | |
800 |
|
801 |
|
802 |
|
803 |
|
804 |
|
805 |
|
806 | createNodeClassNames(node, props) {
|
807 | const classNames = [exports.TREE_NODE_CLASS];
|
808 | if (tree_1.CompositeTreeNode.is(node)) {
|
809 | classNames.push(exports.COMPOSITE_TREE_NODE_CLASS);
|
810 | }
|
811 | if (this.isExpandable(node)) {
|
812 | classNames.push(exports.EXPANDABLE_TREE_NODE_CLASS);
|
813 | }
|
814 | if (this.rowIsSelected(node, props)) {
|
815 | classNames.push(widgets_1.SELECTED_CLASS);
|
816 | }
|
817 | if (this.focusService.hasFocus(node)) {
|
818 | classNames.push(widgets_1.FOCUS_CLASS);
|
819 | }
|
820 | return classNames;
|
821 | }
|
822 | rowIsSelected(node, props) {
|
823 | return tree_selection_1.SelectableTreeNode.isSelected(node);
|
824 | }
|
825 | |
826 |
|
827 |
|
828 |
|
829 |
|
830 |
|
831 |
|
832 | getDefaultNodeStyle(node, props) {
|
833 | const paddingLeft = this.getPaddingLeft(node, props) + 'px';
|
834 | return { paddingLeft };
|
835 | }
|
836 | getPaddingLeft(node, props) {
|
837 | return this.getDepthPadding(props.depth) + (this.needsExpansionTogglePadding(node) ? this.props.expansionTogglePadding : 0);
|
838 | }
|
839 | |
840 |
|
841 |
|
842 |
|
843 | needsExpansionTogglePadding(node) {
|
844 | return !this.isExpandable(node);
|
845 | }
|
846 | |
847 |
|
848 |
|
849 |
|
850 |
|
851 | createNodeStyle(node, props) {
|
852 | return this.decorateNodeStyle(node, this.getDefaultNodeStyle(node, props));
|
853 | }
|
854 | |
855 |
|
856 |
|
857 |
|
858 |
|
859 |
|
860 |
|
861 | decorateNodeStyle(node, style) {
|
862 | const backgroundColor = this.getDecorationData(node, 'backgroundColor').filter(objects_1.notEmpty).shift();
|
863 | if (backgroundColor) {
|
864 | style = {
|
865 | ...(style || {}),
|
866 | backgroundColor
|
867 | };
|
868 | }
|
869 | return style;
|
870 | }
|
871 | |
872 |
|
873 |
|
874 |
|
875 |
|
876 |
|
877 | isExpandable(node) {
|
878 | return tree_expansion_1.ExpandableTreeNode.is(node);
|
879 | }
|
880 | |
881 |
|
882 |
|
883 |
|
884 |
|
885 |
|
886 | getDecorations(node) {
|
887 | const decorations = [];
|
888 | if (tree_decorator_1.DecoratedTreeNode.is(node)) {
|
889 | decorations.push(node.decorationData);
|
890 | }
|
891 | if (this.decorations.has(node.id)) {
|
892 | decorations.push(...this.decorations.get(node.id));
|
893 | }
|
894 | return decorations.sort(tree_decorator_1.TreeDecoration.Data.comparePriority);
|
895 | }
|
896 | |
897 |
|
898 |
|
899 |
|
900 |
|
901 |
|
902 |
|
903 | getDecorationData(node, key) {
|
904 | return this.getDecorations(node).filter(data => data[key] !== undefined).map(data => data[key]);
|
905 | }
|
906 | |
907 |
|
908 |
|
909 | getScrollContainer() {
|
910 | this.toDisposeOnDetach.push(common_1.Disposable.create(() => {
|
911 | const { scrollTop, scrollLeft } = this.node;
|
912 | this.lastScrollState = { scrollTop, scrollLeft };
|
913 | }));
|
914 | if (this.lastScrollState) {
|
915 | const { scrollTop, scrollLeft } = this.lastScrollState;
|
916 | this.node.scrollTop = scrollTop;
|
917 | this.node.scrollLeft = scrollLeft;
|
918 | }
|
919 | return this.node;
|
920 | }
|
921 | onAfterAttach(msg) {
|
922 | const up = [
|
923 | keys_1.Key.ARROW_UP,
|
924 | keys_1.KeyCode.createKeyCode({ first: keys_1.Key.ARROW_UP, modifiers: [keys_1.KeyModifier.Shift] })
|
925 | ];
|
926 | const down = [
|
927 | keys_1.Key.ARROW_DOWN,
|
928 | keys_1.KeyCode.createKeyCode({ first: keys_1.Key.ARROW_DOWN, modifiers: [keys_1.KeyModifier.Shift] })
|
929 | ];
|
930 | if (this.props.search) {
|
931 | if (this.searchBox.isAttached) {
|
932 | widgets_1.Widget.detach(this.searchBox);
|
933 | }
|
934 | widgets_1.UnsafeWidgetUtilities.attach(this.searchBox, this.node.parentElement);
|
935 | this.addKeyListener(this.node, this.searchBox.keyCodePredicate.bind(this.searchBox), this.searchBox.handle.bind(this.searchBox));
|
936 | this.toDisposeOnDetach.push(common_1.Disposable.create(() => {
|
937 | widgets_1.Widget.detach(this.searchBox);
|
938 | }));
|
939 | }
|
940 | super.onAfterAttach(msg);
|
941 | this.addKeyListener(this.node, keys_1.Key.ARROW_LEFT, event => this.handleLeft(event));
|
942 | this.addKeyListener(this.node, keys_1.Key.ARROW_RIGHT, event => this.handleRight(event));
|
943 | this.addKeyListener(this.node, up, event => this.handleUp(event));
|
944 | this.addKeyListener(this.node, down, event => this.handleDown(event));
|
945 | this.addKeyListener(this.node, keys_1.Key.ENTER, event => this.handleEnter(event));
|
946 | this.addKeyListener(this.node, keys_1.Key.SPACE, event => this.handleSpace(event));
|
947 | this.addKeyListener(this.node, keys_1.Key.ESCAPE, event => this.handleEscape(event));
|
948 |
|
949 | this.addEventListener(this.node, 'ps-scroll-y', (e) => {
|
950 | if (this.view && this.view.list) {
|
951 | const { scrollTop } = e.target;
|
952 | this.view.list.scrollTo({
|
953 | top: scrollTop
|
954 | });
|
955 | }
|
956 | });
|
957 | }
|
958 | |
959 |
|
960 |
|
961 |
|
962 | async handleLeft(event) {
|
963 | if (!!this.props.multiSelect && (this.hasCtrlCmdMask(event) || this.hasShiftMask(event))) {
|
964 | return;
|
965 | }
|
966 | if (!await this.model.collapseNode()) {
|
967 | this.model.selectParent();
|
968 | }
|
969 | }
|
970 | |
971 |
|
972 |
|
973 |
|
974 | async handleRight(event) {
|
975 | if (!!this.props.multiSelect && (this.hasCtrlCmdMask(event) || this.hasShiftMask(event))) {
|
976 | return;
|
977 | }
|
978 | if (!await this.model.expandNode()) {
|
979 | this.model.selectNextNode();
|
980 | }
|
981 | }
|
982 | |
983 |
|
984 |
|
985 |
|
986 | handleUp(event) {
|
987 | if (!!this.props.multiSelect && this.hasShiftMask(event)) {
|
988 | this.model.selectPrevNode(tree_selection_1.TreeSelection.SelectionType.RANGE);
|
989 | }
|
990 | else {
|
991 | this.model.selectPrevNode();
|
992 | }
|
993 | this.node.focus();
|
994 | }
|
995 | |
996 |
|
997 |
|
998 |
|
999 | handleDown(event) {
|
1000 | if (!!this.props.multiSelect && this.hasShiftMask(event)) {
|
1001 | this.model.selectNextNode(tree_selection_1.TreeSelection.SelectionType.RANGE);
|
1002 | }
|
1003 | else {
|
1004 | this.model.selectNextNode();
|
1005 | }
|
1006 | this.node.focus();
|
1007 | }
|
1008 | |
1009 |
|
1010 |
|
1011 |
|
1012 |
|
1013 | handleEnter(event) {
|
1014 | this.model.openNode();
|
1015 | }
|
1016 | |
1017 |
|
1018 |
|
1019 |
|
1020 |
|
1021 | handleSpace(event) {
|
1022 | const { focusedNode } = this.focusService;
|
1023 | if (!this.props.multiSelect || (!event.ctrlKey && !event.metaKey && !event.shiftKey)) {
|
1024 | this.tapNode(focusedNode);
|
1025 | }
|
1026 | }
|
1027 | handleEscape(event) {
|
1028 | if (this.model.selectedNodes.length <= 1) {
|
1029 | this.focusService.setFocus(undefined);
|
1030 | this.node.focus();
|
1031 | }
|
1032 | this.model.clearSelection();
|
1033 | }
|
1034 | |
1035 |
|
1036 |
|
1037 |
|
1038 |
|
1039 | handleClickEvent(node, event) {
|
1040 | if (node) {
|
1041 | event.stopPropagation();
|
1042 | const shiftMask = this.hasShiftMask(event);
|
1043 | const ctrlCmdMask = this.hasCtrlCmdMask(event);
|
1044 | if (this.props.multiSelect && (shiftMask || ctrlCmdMask) && tree_selection_1.SelectableTreeNode.is(node)) {
|
1045 | if (shiftMask) {
|
1046 | this.model.selectRange(node);
|
1047 | }
|
1048 | else if (ctrlCmdMask) {
|
1049 | this.model.toggleNode(node);
|
1050 | }
|
1051 | }
|
1052 | else {
|
1053 | this.tapNode(node);
|
1054 | }
|
1055 | }
|
1056 | }
|
1057 | |
1058 |
|
1059 |
|
1060 | tapNode(node) {
|
1061 | if (tree_selection_1.SelectableTreeNode.is(node)) {
|
1062 | this.model.selectNode(node);
|
1063 | }
|
1064 | if (node && !this.props.expandOnlyOnExpansionToggleClick && this.isExpandable(node)) {
|
1065 | this.model.toggleNodeExpansion(node);
|
1066 | }
|
1067 | }
|
1068 | |
1069 |
|
1070 |
|
1071 |
|
1072 |
|
1073 | handleDblClickEvent(node, event) {
|
1074 | this.model.openNode(node);
|
1075 | event.stopPropagation();
|
1076 | }
|
1077 | |
1078 |
|
1079 |
|
1080 |
|
1081 |
|
1082 | handleAuxClickEvent(node, event) {
|
1083 | if (event.button === 1) {
|
1084 | this.model.openNode(node);
|
1085 | if (tree_selection_1.SelectableTreeNode.is(node)) {
|
1086 | this.model.selectNode(node);
|
1087 | }
|
1088 | }
|
1089 | event.stopPropagation();
|
1090 | }
|
1091 | |
1092 |
|
1093 |
|
1094 |
|
1095 | handleMiddleClickEvent(event) {
|
1096 |
|
1097 | if (event.button === 1) {
|
1098 | event.preventDefault();
|
1099 | }
|
1100 | }
|
1101 | |
1102 |
|
1103 |
|
1104 |
|
1105 |
|
1106 |
|
1107 | handleContextMenuEvent(node, event) {
|
1108 | if (tree_selection_1.SelectableTreeNode.is(node)) {
|
1109 |
|
1110 | if (!this.props.multiSelect || !node.selected) {
|
1111 | const type = !!this.props.multiSelect && this.hasCtrlCmdMask(event) ? tree_selection_1.TreeSelection.SelectionType.TOGGLE : tree_selection_1.TreeSelection.SelectionType.DEFAULT;
|
1112 | this.model.addSelection({ node, type });
|
1113 | }
|
1114 | this.focusService.setFocus(node);
|
1115 | const contextMenuPath = this.props.contextMenuPath;
|
1116 | if (contextMenuPath) {
|
1117 | const { x, y } = event.nativeEvent;
|
1118 | const args = this.toContextMenuArgs(node);
|
1119 | setTimeout(() => this.contextMenuRenderer.render({
|
1120 | menuPath: contextMenuPath,
|
1121 | anchor: { x, y },
|
1122 | args
|
1123 | }), 10);
|
1124 | }
|
1125 | }
|
1126 | event.stopPropagation();
|
1127 | event.preventDefault();
|
1128 | }
|
1129 | |
1130 |
|
1131 |
|
1132 |
|
1133 | doHandleExpansionToggleDblClickEvent(event) {
|
1134 | if (this.props.expandOnlyOnExpansionToggleClick) {
|
1135 |
|
1136 | event.stopPropagation();
|
1137 | }
|
1138 | }
|
1139 | |
1140 |
|
1141 |
|
1142 |
|
1143 |
|
1144 | toContextMenuArgs(node) {
|
1145 | return undefined;
|
1146 | }
|
1147 | |
1148 |
|
1149 |
|
1150 |
|
1151 |
|
1152 |
|
1153 | hasCtrlCmdMask(event) {
|
1154 | return os_1.isOSX ? event.metaKey : event.ctrlKey;
|
1155 | }
|
1156 | |
1157 |
|
1158 |
|
1159 |
|
1160 |
|
1161 |
|
1162 | hasShiftMask(event) {
|
1163 |
|
1164 | if (this.hasCtrlCmdMask(event)) {
|
1165 | return false;
|
1166 | }
|
1167 | return event.shiftKey;
|
1168 | }
|
1169 | |
1170 |
|
1171 |
|
1172 |
|
1173 | deflateForStorage(node) {
|
1174 |
|
1175 | const copy = Object.assign({}, node);
|
1176 | if (copy.parent) {
|
1177 | delete copy.parent;
|
1178 | }
|
1179 | if ('previousSibling' in copy) {
|
1180 | delete copy.previousSibling;
|
1181 | }
|
1182 | if ('nextSibling' in copy) {
|
1183 | delete copy.nextSibling;
|
1184 | }
|
1185 | if ('busy' in copy) {
|
1186 | delete copy.busy;
|
1187 | }
|
1188 | if (tree_1.CompositeTreeNode.is(node)) {
|
1189 | copy.children = [];
|
1190 | for (const child of node.children) {
|
1191 | copy.children.push(this.deflateForStorage(child));
|
1192 | }
|
1193 | }
|
1194 | return copy;
|
1195 | }
|
1196 | |
1197 |
|
1198 |
|
1199 |
|
1200 |
|
1201 |
|
1202 | inflateFromStorage(node, parent) {
|
1203 | if (node.selected) {
|
1204 | node.selected = false;
|
1205 | }
|
1206 | if (parent) {
|
1207 | node.parent = parent;
|
1208 | }
|
1209 | if (Array.isArray(node.children)) {
|
1210 | for (const child of node.children) {
|
1211 | this.inflateFromStorage(child, node);
|
1212 | }
|
1213 | }
|
1214 | return node;
|
1215 | }
|
1216 | |
1217 |
|
1218 |
|
1219 | storeState() {
|
1220 | var _a;
|
1221 | const decorations = this.decoratorService.deflateDecorators(this.decorations);
|
1222 | let state = {
|
1223 | decorations
|
1224 | };
|
1225 | if (this.model.root) {
|
1226 | state = {
|
1227 | ...state,
|
1228 | root: this.deflateForStorage(this.model.root),
|
1229 | model: this.model.storeState(),
|
1230 | focusedNodeId: (_a = this.focusService.focusedNode) === null || _a === void 0 ? void 0 : _a.id
|
1231 | };
|
1232 | }
|
1233 | return state;
|
1234 | }
|
1235 | |
1236 |
|
1237 |
|
1238 |
|
1239 | restoreState(oldState) {
|
1240 |
|
1241 | const { root, decorations, model, focusedNodeId } = oldState;
|
1242 | if (root) {
|
1243 | this.model.root = this.inflateFromStorage(root);
|
1244 | }
|
1245 | if (decorations) {
|
1246 | this.decorations = this.decoratorService.inflateDecorators(decorations);
|
1247 | }
|
1248 | if (model) {
|
1249 | this.model.restoreState(model);
|
1250 | }
|
1251 | if (focusedNodeId) {
|
1252 | const candidate = this.model.getNode(focusedNodeId);
|
1253 | if (tree_selection_1.SelectableTreeNode.is(candidate)) {
|
1254 | this.focusService.setFocus(candidate);
|
1255 | }
|
1256 | }
|
1257 | }
|
1258 | toNodeIcon(node) {
|
1259 | return this.labelProvider.getIcon(node);
|
1260 | }
|
1261 | toNodeName(node) {
|
1262 | return this.labelProvider.getName(node);
|
1263 | }
|
1264 | toNodeDescription(node) {
|
1265 | return this.labelProvider.getLongName(node);
|
1266 | }
|
1267 | getDepthPadding(depth) {
|
1268 | return depth * this.props.leftPadding;
|
1269 | }
|
1270 | };
|
1271 | __decorate([
|
1272 | (0, inversify_1.inject)(tree_decorator_1.TreeDecoratorService),
|
1273 | __metadata("design:type", Object)
|
1274 | ], TreeWidget.prototype, "decoratorService", void 0);
|
1275 | __decorate([
|
1276 | (0, inversify_1.inject)(tree_search_1.TreeSearch),
|
1277 | __metadata("design:type", tree_search_1.TreeSearch)
|
1278 | ], TreeWidget.prototype, "treeSearch", void 0);
|
1279 | __decorate([
|
1280 | (0, inversify_1.inject)(search_box_1.SearchBoxFactory),
|
1281 | __metadata("design:type", Function)
|
1282 | ], TreeWidget.prototype, "searchBoxFactory", void 0);
|
1283 | __decorate([
|
1284 | (0, inversify_1.inject)(tree_focus_service_1.TreeFocusService),
|
1285 | __metadata("design:type", Object)
|
1286 | ], TreeWidget.prototype, "focusService", void 0);
|
1287 | __decorate([
|
1288 | (0, inversify_1.inject)(common_1.SelectionService),
|
1289 | __metadata("design:type", common_1.SelectionService)
|
1290 | ], TreeWidget.prototype, "selectionService", void 0);
|
1291 | __decorate([
|
1292 | (0, inversify_1.inject)(label_provider_1.LabelProvider),
|
1293 | __metadata("design:type", label_provider_1.LabelProvider)
|
1294 | ], TreeWidget.prototype, "labelProvider", void 0);
|
1295 | __decorate([
|
1296 | (0, inversify_1.inject)(core_preferences_1.CorePreferences),
|
1297 | __metadata("design:type", Object)
|
1298 | ], TreeWidget.prototype, "corePreferences", void 0);
|
1299 | __decorate([
|
1300 | (0, inversify_1.postConstruct)(),
|
1301 | __metadata("design:type", Function),
|
1302 | __metadata("design:paramtypes", []),
|
1303 | __metadata("design:returntype", void 0)
|
1304 | ], TreeWidget.prototype, "init", null);
|
1305 | TreeWidget = TreeWidget_1 = __decorate([
|
1306 | (0, inversify_1.injectable)(),
|
1307 | __param(0, (0, inversify_1.inject)(exports.TreeProps)),
|
1308 | __param(1, (0, inversify_1.inject)(tree_model_1.TreeModel)),
|
1309 | __param(2, (0, inversify_1.inject)(context_menu_renderer_1.ContextMenuRenderer)),
|
1310 | __metadata("design:paramtypes", [Object, Object, context_menu_renderer_1.ContextMenuRenderer])
|
1311 | ], TreeWidget);
|
1312 | exports.TreeWidget = TreeWidget;
|
1313 | (function (TreeWidget) {
|
1314 | class View extends React.Component {
|
1315 | render() {
|
1316 | const { rows, width, height, scrollToRow } = this.props;
|
1317 | return React.createElement(react_virtuoso_1.Virtuoso, { ref: list => {
|
1318 | this.list = (list || undefined);
|
1319 | if (this.list && scrollToRow !== undefined) {
|
1320 | this.list.scrollIntoView({
|
1321 | index: scrollToRow,
|
1322 | align: 'center'
|
1323 | });
|
1324 | }
|
1325 | }, totalCount: rows.length, itemContent: index => this.props.renderNodeRow(rows[index]), width: width, height: height,
|
1326 |
|
1327 | overscan: 500 });
|
1328 | }
|
1329 | }
|
1330 | TreeWidget.View = View;
|
1331 | })(TreeWidget = exports.TreeWidget || (exports.TreeWidget = {}));
|
1332 | exports.TreeWidget = TreeWidget;
|
1333 |
|
\ | No newline at end of file |