@theia/core
Version:
Theia is a cloud & desktop IDE framework implemented in TypeScript.
147 lines (135 loc) • 5.33 kB
text/typescript
// *****************************************************************************
// Copyright (C) 2018 TypeFox and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************
/* eslint-disable @typescript-eslint/no-explicit-any */
import { injectable } from 'inversify';
import { MaybePromise } from '../../common/types';
import { TreeImpl, CompositeTreeNode, TreeNode, SelectableTreeNode, ExpandableTreeNode } from '../tree';
import { TreeElement, CompositeTreeElement, TreeSource } from './tree-source';
()
export class SourceTree extends TreeImpl {
override async resolveChildren(parent: TreeElementNodeParent): Promise<TreeNode[]> {
const elements = await this.resolveElements(parent);
const nodes: TreeNode[] = [];
let index = 0;
for (const element of elements) {
if (element.visible !== false) {
nodes.push(this.toNode(element, index++, parent));
}
}
return nodes;
}
protected resolveElements(parent: TreeElementNodeParent): MaybePromise<IterableIterator<TreeElement>> {
if (TreeSourceNode.is(parent)) {
return parent.source.getElements();
}
return parent.element.getElements();
}
protected toNode(element: TreeElement, index: number, parent: TreeElementNodeParent): TreeElementNode {
const id = element.id ? String(element.id) : (parent.id + ':' + index);
const name = id;
const existing = this.getNode(id);
const updated = existing && <TreeElementNode>Object.assign(existing, { element, parent });
if (CompositeTreeElement.hasElements(element)) {
if (updated) {
if (!ExpandableTreeNode.is(updated)) {
Object.assign(updated, { expanded: false });
}
if (!CompositeTreeNode.is(updated)) {
Object.assign(updated, { children: [] });
}
return updated;
}
return {
element,
parent,
id,
name,
selected: false,
expanded: false,
children: []
} as TreeElementNode;
}
if (CompositeTreeElementNode.is(updated)) {
delete (updated as any).expanded;
delete (updated as any).children;
}
if (updated) {
if (ExpandableTreeNode.is(updated)) {
delete (updated as any).expanded;
}
if (CompositeTreeNode.is(updated)) {
delete (updated as any).children;
}
return updated;
}
return {
element,
parent,
id,
name,
selected: false
};
}
}
export type TreeElementNodeParent = CompositeTreeElementNode | TreeSourceNode;
export interface TreeElementNode extends TreeNode, SelectableTreeNode {
element: TreeElement
parent: TreeElementNodeParent
}
export namespace TreeElementNode {
export function is(node: TreeNode | undefined): node is TreeElementNode {
return SelectableTreeNode.is(node) && 'element' in node;
}
}
export interface CompositeTreeElementNode extends TreeElementNode, CompositeTreeNode, ExpandableTreeNode {
element: CompositeTreeElement
children: TreeElementNode[]
parent: TreeElementNodeParent
}
export namespace CompositeTreeElementNode {
export function is(node: TreeNode | undefined): node is CompositeTreeElementNode {
return TreeElementNode.is(node) && CompositeTreeNode.is(node) && ExpandableTreeNode.is(node) && !!node.visible;
}
}
export interface TreeSourceNode extends CompositeTreeNode, SelectableTreeNode {
visible: false
children: TreeElementNode[]
parent: undefined
source: TreeSource
}
export namespace TreeSourceNode {
export function is(node: TreeNode | undefined): node is TreeSourceNode {
return CompositeTreeNode.is(node) && !node.visible && 'source' in node;
}
export function to(source: undefined): undefined;
export function to(source: TreeSource): TreeSourceNode;
export function to(source: TreeSource | undefined): TreeSourceNode | undefined;
export function to(source: TreeSource | undefined): TreeSourceNode | undefined {
if (!source) {
return source;
}
const id = source.id || '__source__';
return {
id,
name: id,
visible: false,
children: [],
source,
parent: undefined,
selected: false
};
}
}