UNPKG

@theia/filesystem

Version:
318 lines • 14 kB
"use strict"; // ***************************************************************************** // Copyright (C) 2017 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 // ***************************************************************************** Object.defineProperty(exports, "__esModule", { value: true }); exports.FileTreeWidget = exports.FILE_STAT_ICON_CLASS = exports.DIR_NODE_CLASS = exports.FILE_STAT_NODE_CLASS = exports.FILE_TREE_CLASS = void 0; const tslib_1 = require("tslib"); const React = require("@theia/core/shared/react"); const inversify_1 = require("@theia/core/shared/inversify"); const disposable_1 = require("@theia/core/lib/common/disposable"); const uri_1 = require("@theia/core/lib/common/uri"); const selection_1 = require("@theia/core/lib/common/selection"); const cancellation_1 = require("@theia/core/lib/common/cancellation"); const browser_1 = require("@theia/core/lib/browser"); const file_upload_service_1 = require("../file-upload-service"); const file_tree_1 = require("./file-tree"); const file_tree_model_1 = require("./file-tree-model"); const icon_theme_service_1 = require("@theia/core/lib/browser/icon-theme-service"); const shell_1 = require("@theia/core/lib/browser/shell"); const files_1 = require("../../common/files"); const core_1 = require("@theia/core"); exports.FILE_TREE_CLASS = 'theia-FileTree'; exports.FILE_STAT_NODE_CLASS = 'theia-FileStatNode'; exports.DIR_NODE_CLASS = 'theia-DirNode'; exports.FILE_STAT_ICON_CLASS = 'theia-FileStatIcon'; let FileTreeWidget = class FileTreeWidget extends browser_1.CompressedTreeWidget { constructor(props, model, contextMenuRenderer) { super(props, model, contextMenuRenderer); this.model = model; this.toCancelNodeExpansion = new disposable_1.DisposableCollection(); this.addClass(exports.FILE_TREE_CLASS); this.toDispose.push(this.toCancelNodeExpansion); } createNodeClassNames(node, props) { const classNames = super.createNodeClassNames(node, props); if (file_tree_1.FileStatNode.is(node)) { classNames.push(exports.FILE_STAT_NODE_CLASS); } if (file_tree_1.DirNode.is(node)) { classNames.push(exports.DIR_NODE_CLASS); } return classNames; } renderIcon(node, props) { const icon = this.toNodeIcon(node); if (icon) { return React.createElement("div", { className: icon + ' file-icon' }); } // eslint-disable-next-line no-null/no-null return null; } createContainerAttributes() { const attrs = super.createContainerAttributes(); return { ...attrs, onDragEnter: event => this.handleDragEnterEvent(this.model.root, event), onDragOver: event => this.handleDragOverEvent(this.model.root, event), onDragLeave: event => this.handleDragLeaveEvent(this.model.root, event), onDrop: event => this.handleDropEvent(this.model.root, event) }; } createNodeAttributes(node, props) { return { ...super.createNodeAttributes(node, props), ...this.getNodeDragHandlers(node, props), title: this.getNodeTooltip(node) }; } getNodeTooltip(node) { var _a, _b; const operativeNode = (_b = (_a = this.compressionService.getCompressionChain(node)) === null || _a === void 0 ? void 0 : _a.tail()) !== null && _b !== void 0 ? _b : node; const uri = selection_1.UriSelection.getUri(operativeNode); return uri ? uri.path.fsPath() : undefined; } getCaptionChildEventHandlers(node, props) { return { ...super.getCaptionChildEventHandlers(node, props), ...this.getNodeDragHandlers(node, props), }; } getNodeDragHandlers(node, props) { return { onDragStart: event => this.handleDragStartEvent(node, event), onDragEnter: event => this.handleDragEnterEvent(node, event), onDragOver: event => this.handleDragOverEvent(node, event), onDragLeave: event => this.handleDragLeaveEvent(node, event), onDrop: event => this.handleDropEvent(node, event), draggable: file_tree_1.FileStatNode.is(node), }; } handleDragStartEvent(node, event) { event.stopPropagation(); if (event.dataTransfer) { let selectedNodes; if (this.model.selectedNodes.find(selected => browser_1.TreeNode.equals(selected, node))) { selectedNodes = [...this.model.selectedNodes]; } else { selectedNodes = [node]; } this.setSelectedTreeNodesAsData(event.dataTransfer, node, selectedNodes); const uris = selectedNodes.filter(file_tree_1.FileStatNode.is).map(n => n.fileStat.resource); if (uris.length > 0) { shell_1.ApplicationShell.setDraggedEditorUris(event.dataTransfer, uris); } let label; if (selectedNodes.length === 1) { label = this.toNodeName(node); } else { label = String(selectedNodes.length); } const dragImage = document.createElement('div'); dragImage.className = 'theia-file-tree-drag-image'; dragImage.textContent = label; document.body.appendChild(dragImage); event.dataTransfer.setDragImage(dragImage, -10, -10); setTimeout(() => document.body.removeChild(dragImage), 0); } } handleDragEnterEvent(node, event) { event.preventDefault(); event.stopPropagation(); this.toCancelNodeExpansion.dispose(); const containing = file_tree_1.DirNode.getContainingDir(node); if (!!containing && !containing.selected) { this.model.selectNode(containing); } } handleDragOverEvent(node, event) { event.preventDefault(); event.stopPropagation(); event.dataTransfer.dropEffect = this.getDropEffect(event); if (!this.toCancelNodeExpansion.disposed) { return; } const timer = setTimeout(() => { const containing = file_tree_1.DirNode.getContainingDir(node); if (!!containing && !containing.expanded) { this.model.expandNode(containing); } }, 500); this.toCancelNodeExpansion.push(disposable_1.Disposable.create(() => clearTimeout(timer))); } handleDragLeaveEvent(node, event) { event.preventDefault(); event.stopPropagation(); this.toCancelNodeExpansion.dispose(); } async handleDropEvent(node, event) { try { event.preventDefault(); event.stopPropagation(); event.dataTransfer.dropEffect = this.getDropEffect(event); const containing = this.getDropTargetDirNode(node); if (containing) { const resources = this.getSelectedTreeNodesFromData(event.dataTransfer); if (resources.length > 0) { for (const treeNode of resources) { if (event.dataTransfer.dropEffect === 'copy' && file_tree_1.FileStatNode.is(treeNode)) { await this.model.copy(treeNode.uri, containing); } else { await this.model.move(treeNode, containing); } } } else { await this.uploadService.upload(containing.uri, { source: event.dataTransfer }); } } } catch (e) { if (!(0, cancellation_1.isCancelled)(e)) { console.error(e); } } } getDropTargetDirNode(node) { if (browser_1.CompositeTreeNode.is(node) && node.id === 'WorkspaceNodeId') { if (node.children.length === 1) { return file_tree_1.DirNode.getContainingDir(node.children[0]); } else if (node.children.length > 1) { // move file to the last root folder in multi-root scenario return file_tree_1.DirNode.getContainingDir(node.children[node.children.length - 1]); } } return file_tree_1.DirNode.getContainingDir(node); } getDropEffect(event) { const isCopy = core_1.isOSX ? event.altKey : event.ctrlKey; return isCopy ? 'copy' : 'move'; } setTreeNodeAsData(data, node) { data.setData('tree-node', node.id); } setSelectedTreeNodesAsData(data, sourceNode, relatedNodes) { this.setTreeNodeAsData(data, sourceNode); data.setData('selected-tree-nodes', JSON.stringify(relatedNodes.map(node => node.id))); } getTreeNodeFromData(data) { const id = data.getData('tree-node'); return this.model.getNode(id); } getSelectedTreeNodesFromData(data) { const resources = data.getData('selected-tree-nodes'); if (!resources) { return []; } const ids = JSON.parse(resources); return ids.map(id => this.model.getNode(id)).filter(node => node !== undefined); } get hidesExplorerArrows() { const theme = this.iconThemeService.getDefinition(this.iconThemeService.current); return !!theme && !!theme.hidesExplorerArrows; } renderExpansionToggle(node, props) { if (this.hidesExplorerArrows) { // eslint-disable-next-line no-null/no-null return null; } return super.renderExpansionToggle(node, props); } getPaddingLeft(node, props) { if (this.hidesExplorerArrows) { // additional left padding instead of top-level expansion toggle return super.getPaddingLeft(node, props) + this.props.leftPadding; } return super.getPaddingLeft(node, props); } needsExpansionTogglePadding(node) { const theme = this.iconThemeService.getDefinition(this.iconThemeService.current); if (theme && (theme.hidesExplorerArrows || (theme.hasFileIcons && !theme.hasFolderIcons))) { return false; } return super.needsExpansionTogglePadding(node); } deflateForStorage(node) { const deflated = super.deflateForStorage(node); if (file_tree_1.FileStatNode.is(node) && file_tree_1.FileStatNodeData.is(deflated)) { deflated.uri = node.uri.toString(); delete deflated['fileStat']; deflated.stat = files_1.FileStat.toStat(node.fileStat); } return deflated; } // eslint-disable-next-line @typescript-eslint/no-explicit-any inflateFromStorage(node, parent) { if (file_tree_1.FileStatNodeData.is(node)) { // eslint-disable-next-line @typescript-eslint/no-explicit-any const fileStatNode = node; const resource = new uri_1.default(node.uri); fileStatNode.uri = resource; let stat; // in order to support deprecated FileStat if (node.fileStat) { stat = { type: node.fileStat.isDirectory ? files_1.FileType.Directory : files_1.FileType.File, mtime: node.fileStat.mtime, size: node.fileStat.size }; delete node['fileStat']; } else if (node.stat) { stat = node.stat; delete node['stat']; } if (stat) { fileStatNode.fileStat = files_1.FileStat.fromStat(resource, stat); } } const inflated = super.inflateFromStorage(node, parent); if (file_tree_1.DirNode.is(inflated)) { inflated.fileStat.children = []; for (const child of inflated.children) { if (file_tree_1.FileStatNode.is(child)) { inflated.fileStat.children.push(child.fileStat); } } } return inflated; } getDepthPadding(depth) { // add additional depth so file nodes are rendered with padding in relation to the top level root node. return super.getDepthPadding(depth + 1); } }; exports.FileTreeWidget = FileTreeWidget; tslib_1.__decorate([ (0, inversify_1.inject)(file_upload_service_1.FileUploadService), tslib_1.__metadata("design:type", file_upload_service_1.FileUploadService) ], FileTreeWidget.prototype, "uploadService", void 0); tslib_1.__decorate([ (0, inversify_1.inject)(icon_theme_service_1.IconThemeService), tslib_1.__metadata("design:type", icon_theme_service_1.IconThemeService) ], FileTreeWidget.prototype, "iconThemeService", void 0); exports.FileTreeWidget = FileTreeWidget = tslib_1.__decorate([ (0, inversify_1.injectable)(), tslib_1.__param(0, (0, inversify_1.inject)(browser_1.TreeProps)), tslib_1.__param(1, (0, inversify_1.inject)(file_tree_model_1.FileTreeModel)), tslib_1.__param(2, (0, inversify_1.inject)(browser_1.ContextMenuRenderer)), tslib_1.__metadata("design:paramtypes", [Object, file_tree_model_1.FileTreeModel, browser_1.ContextMenuRenderer]) ], FileTreeWidget); //# sourceMappingURL=file-tree-widget.js.map