UNPKG

@codingame/monaco-vscode-extensions-service-override

Version:

VSCode public API plugged on the monaco editor - extensions service-override

313 lines (310 loc) 14.5 kB
import { __decorate, __param } from 'vscode/external/tslib/tslib.es6.js'; import { Disposable, DisposableMap, DisposableStore } from 'vscode/vscode/vs/base/common/lifecycle'; import { ExtHostContext, MainContext } from 'vscode/vscode/vs/workbench/api/common/extHost.protocol'; import { Extensions, NoTreeViewError, ResolvableTreeItem } from 'vscode/vscode/vs/workbench/common/views'; import { extHostNamedCustomer } from '../../services/extensions/common/extHostCustomers.js'; import { distinct } from 'vscode/vscode/vs/base/common/arrays'; import { INotificationService } from 'vscode/vscode/vs/platform/notification/common/notification.service'; import { isUndefinedOrNull, isNumber } from 'vscode/vscode/vs/base/common/types'; import { Registry } from 'vscode/vscode/vs/platform/registry/common/platform'; import { IExtensionService } from 'vscode/vscode/vs/workbench/services/extensions/common/extensions.service'; import { ILogService } from 'vscode/vscode/vs/platform/log/common/log.service'; import { VSDataTransfer, createStringDataTransferItem } from 'vscode/vscode/vs/base/common/dataTransfer'; import { DataTransferFileCache } from '../common/shared/dataTransferCache.js'; import { DataTransfer } from 'vscode/vscode/vs/workbench/api/common/extHostTypeConverters'; import { IViewsService } from 'vscode/vscode/vs/workbench/services/views/common/viewsService.service'; let MainThreadTreeViews = class MainThreadTreeViews extends Disposable { constructor(extHostContext, viewsService, notificationService, extensionService, logService) { super(); this.viewsService = viewsService; this.notificationService = notificationService; this.extensionService = extensionService; this.logService = logService; this._dataProviders = this._register(( new DisposableMap())); this._dndControllers = ( new Map()); this._proxy = ( extHostContext.getProxy(ExtHostContext.ExtHostTreeViews)); } async $registerTreeViewDataProvider(treeViewId, options) { this.logService.trace('MainThreadTreeViews#$registerTreeViewDataProvider', treeViewId, options); this.extensionService.whenInstalledExtensionsRegistered().then(() => { const dataProvider = ( new TreeViewDataProvider(treeViewId, this._proxy, this.notificationService)); const disposables = ( new DisposableStore()); this._dataProviders.set(treeViewId, { dataProvider, dispose: () => disposables.dispose() }); const dndController = (options.hasHandleDrag || options.hasHandleDrop) ? ( new TreeViewDragAndDropController( treeViewId, options.dropMimeTypes, options.dragMimeTypes, options.hasHandleDrag, this._proxy )) : undefined; const viewer = this.getTreeView(treeViewId); if (viewer) { viewer.showCollapseAllAction = options.showCollapseAll; viewer.canSelectMany = options.canSelectMany; viewer.manuallyManageCheckboxes = options.manuallyManageCheckboxes; viewer.dragAndDropController = dndController; if (dndController) { this._dndControllers.set(treeViewId, dndController); } viewer.dataProvider = dataProvider; this.registerListeners(treeViewId, viewer, disposables); this._proxy.$setVisible(treeViewId, viewer.visible); } else { this.notificationService.error('No view is registered with id: ' + treeViewId); } }); } $reveal(treeViewId, itemInfo, options) { this.logService.trace('MainThreadTreeViews#$reveal', treeViewId, itemInfo?.item, itemInfo?.parentChain, options); return this.viewsService.openView(treeViewId, options.focus) .then(() => { const viewer = this.getTreeView(treeViewId); if (viewer && itemInfo) { return this.reveal(viewer, this._dataProviders.get(treeViewId).dataProvider, itemInfo.item, itemInfo.parentChain, options); } return undefined; }); } $refresh(treeViewId, itemsToRefreshByHandle) { this.logService.trace('MainThreadTreeViews#$refresh', treeViewId, itemsToRefreshByHandle); const viewer = this.getTreeView(treeViewId); const dataProvider = this._dataProviders.get(treeViewId); if (viewer && dataProvider) { const itemsToRefresh = dataProvider.dataProvider.getItemsToRefresh(itemsToRefreshByHandle); return viewer.refresh(itemsToRefresh.length ? itemsToRefresh : undefined); } return Promise.resolve(); } $setMessage(treeViewId, message) { this.logService.trace('MainThreadTreeViews#$setMessage', treeViewId, ( message.toString())); const viewer = this.getTreeView(treeViewId); if (viewer) { viewer.message = message; } } $setTitle(treeViewId, title, description) { this.logService.trace('MainThreadTreeViews#$setTitle', treeViewId, title, description); const viewer = this.getTreeView(treeViewId); if (viewer) { viewer.title = title; viewer.description = description; } } $setBadge(treeViewId, badge) { this.logService.trace('MainThreadTreeViews#$setBadge', treeViewId, badge?.value, badge?.tooltip); const viewer = this.getTreeView(treeViewId); if (viewer) { viewer.badge = badge; } } $resolveDropFileData(destinationViewId, requestId, dataItemId) { const controller = this._dndControllers.get(destinationViewId); if (!controller) { throw ( new Error('Unknown tree')); } return controller.resolveDropFileData(requestId, dataItemId); } async $disposeTree(treeViewId) { const viewer = this.getTreeView(treeViewId); if (viewer) { viewer.dataProvider = undefined; } this._dataProviders.deleteAndDispose(treeViewId); } async reveal(treeView, dataProvider, itemIn, parentChain, options) { options = options ? options : { select: false, focus: false }; const select = isUndefinedOrNull(options.select) ? false : options.select; const focus = isUndefinedOrNull(options.focus) ? false : options.focus; let expand = Math.min(isNumber(options.expand) ? options.expand : options.expand === true ? 1 : 0, 3); if (dataProvider.isEmpty()) { await treeView.refresh(); } for (const parent of parentChain) { const parentItem = dataProvider.getItem(parent.handle); if (parentItem) { await treeView.expand(parentItem); } } const item = dataProvider.getItem(itemIn.handle); if (item) { await treeView.reveal(item); if (select) { treeView.setSelection([item]); } if (focus === false) { treeView.setFocus(); } else if (focus) { treeView.setFocus(item); } let itemsToExpand = [item]; for (; itemsToExpand.length > 0 && expand > 0; expand--) { await treeView.expand(itemsToExpand); itemsToExpand = itemsToExpand.reduce((result, itemValue) => { const item = dataProvider.getItem(itemValue.handle); if (item && item.children && item.children.length) { result.push(...item.children); } return result; }, []); } } } registerListeners(treeViewId, treeView, disposables) { disposables.add(treeView.onDidExpandItem(item => this._proxy.$setExpanded(treeViewId, item.handle, true))); disposables.add(treeView.onDidCollapseItem(item => this._proxy.$setExpanded(treeViewId, item.handle, false))); disposables.add(treeView.onDidChangeSelectionAndFocus(items => this._proxy.$setSelectionAndFocus(treeViewId, ( items.selection.map(({ handle }) => handle)), items.focus.handle))); disposables.add(treeView.onDidChangeVisibility(isVisible => this._proxy.$setVisible(treeViewId, isVisible))); disposables.add(treeView.onDidChangeCheckboxState(items => { this._proxy.$changeCheckboxState(treeViewId, ( items.map(item => { return { treeItemHandle: item.handle, newState: item.checkbox?.isChecked ?? false }; }))); })); } getTreeView(treeViewId) { const viewDescriptor = ( Registry.as(Extensions.ViewsRegistry)).getView(treeViewId); return viewDescriptor ? viewDescriptor.treeView : null; } dispose() { for (const dataprovider of this._dataProviders) { const treeView = this.getTreeView(dataprovider[0]); if (treeView) { treeView.dataProvider = undefined; } } this._dataProviders.dispose(); this._dndControllers.clear(); super.dispose(); } }; MainThreadTreeViews = __decorate([ extHostNamedCustomer(MainContext.MainThreadTreeViews), ( __param(1, IViewsService)), ( __param(2, INotificationService)), ( __param(3, IExtensionService)), ( __param(4, ILogService)) ], MainThreadTreeViews); class TreeViewDragAndDropController { constructor(treeViewId, dropMimeTypes, dragMimeTypes, hasWillDrop, _proxy) { this.treeViewId = treeViewId; this.dropMimeTypes = dropMimeTypes; this.dragMimeTypes = dragMimeTypes; this.hasWillDrop = hasWillDrop; this._proxy = _proxy; this.dataTransfersCache = ( new DataTransferFileCache()); } async handleDrop(dataTransfer, targetTreeItem, token, operationUuid, sourceTreeId, sourceTreeItemHandles) { const request = this.dataTransfersCache.add(dataTransfer); try { const dataTransferDto = await DataTransfer.from(dataTransfer); if (token.isCancellationRequested) { return; } return await this._proxy.$handleDrop(this.treeViewId, request.id, dataTransferDto, targetTreeItem?.handle, token, operationUuid, sourceTreeId, sourceTreeItemHandles); } finally { request.dispose(); } } async handleDrag(sourceTreeItemHandles, operationUuid, token) { if (!this.hasWillDrop) { return; } const additionalDataTransferDTO = await this._proxy.$handleDrag(this.treeViewId, sourceTreeItemHandles, operationUuid, token); if (!additionalDataTransferDTO) { return; } const additionalDataTransfer = ( new VSDataTransfer()); additionalDataTransferDTO.items.forEach(([type, item]) => { additionalDataTransfer.replace(type, createStringDataTransferItem(item.asString)); }); return additionalDataTransfer; } resolveDropFileData(requestId, dataItemId) { return this.dataTransfersCache.resolveFileData(requestId, dataItemId); } } class TreeViewDataProvider { constructor(treeViewId, _proxy, notificationService) { this.treeViewId = treeViewId; this._proxy = _proxy; this.notificationService = notificationService; this.itemsMap = ( new Map()); this.hasResolve = this._proxy.$hasResolve(this.treeViewId); } getChildren(treeItem) { if (!treeItem) { this.itemsMap.clear(); } return this._proxy.$getChildren(this.treeViewId, treeItem ? treeItem.handle : undefined) .then(children => this.postGetChildren(children), err => { if (!NoTreeViewError.is(err)) { this.notificationService.error(err); } return []; }); } getItemsToRefresh(itemsToRefreshByHandle) { const itemsToRefresh = []; if (itemsToRefreshByHandle) { for (const treeItemHandle of ( Object.keys(itemsToRefreshByHandle))) { const currentTreeItem = this.getItem(treeItemHandle); if (currentTreeItem) { const treeItem = itemsToRefreshByHandle[treeItemHandle]; this.updateTreeItem(currentTreeItem, treeItem); if (treeItemHandle === treeItem.handle) { itemsToRefresh.push(currentTreeItem); } else { this.itemsMap.delete(treeItemHandle); this.itemsMap.set(currentTreeItem.handle, currentTreeItem); const parent = treeItem.parentHandle ? this.itemsMap.get(treeItem.parentHandle) : null; if (parent) { itemsToRefresh.push(parent); } } } } } return itemsToRefresh; } getItem(treeItemHandle) { return this.itemsMap.get(treeItemHandle); } isEmpty() { return this.itemsMap.size === 0; } async postGetChildren(elements) { if (elements === undefined) { return undefined; } const result = []; const hasResolve = await this.hasResolve; if (elements) { for (const element of elements) { const resolvable = ( new ResolvableTreeItem(element, hasResolve ? (token) => { return this._proxy.$resolve(this.treeViewId, element.handle, token); } : undefined)); this.itemsMap.set(element.handle, resolvable); result.push(resolvable); } } return result; } updateTreeItem(current, treeItem) { treeItem.children = treeItem.children ? treeItem.children : undefined; if (current) { const properties = distinct([...( Object.keys(current instanceof ResolvableTreeItem ? current.asTreeItem() : current)), ...( Object.keys(treeItem))]); for (const property of properties) { current[property] = treeItem[property]; } if (current instanceof ResolvableTreeItem) { current.resetResolve(); } } } } export { MainThreadTreeViews };