mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-25 02:58:56 +01:00
132 lines
4.7 KiB
TypeScript
132 lines
4.7 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
'use strict';
|
|
|
|
import { localize } from 'vs/nls';
|
|
import { forEach } from 'vs/base/common/collections';
|
|
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
|
import { ExtensionMessageCollector, ExtensionsRegistry } from 'vs/platform/extensions/common/extensionsRegistry';
|
|
import { ViewLocation, ViewsRegistry, IViewDescriptor } from 'vs/workbench/common/views';
|
|
import { TreeView } from 'vs/workbench/browser/parts/views/treeView';
|
|
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
|
import { coalesce, } from 'vs/base/common/arrays';
|
|
|
|
namespace schema {
|
|
|
|
// --views contribution point
|
|
|
|
export interface IUserFriendlyViewDescriptor {
|
|
id: string;
|
|
name: string;
|
|
when?: string;
|
|
}
|
|
|
|
export function isValidViewDescriptors(viewDescriptors: IUserFriendlyViewDescriptor[], collector: ExtensionMessageCollector): boolean {
|
|
if (!Array.isArray(viewDescriptors)) {
|
|
collector.error(localize('requirearray', "views must be an array"));
|
|
return false;
|
|
}
|
|
|
|
for (let descriptor of viewDescriptors) {
|
|
if (typeof descriptor.id !== 'string') {
|
|
collector.error(localize('requirestring', "property `{0}` is mandatory and must be of type `string`", 'id'));
|
|
return false;
|
|
}
|
|
if (typeof descriptor.name !== 'string') {
|
|
collector.error(localize('requirestring', "property `{0}` is mandatory and must be of type `string`", 'name'));
|
|
return false;
|
|
}
|
|
if (descriptor.when && typeof descriptor.when !== 'string') {
|
|
collector.error(localize('optstring', "property `{0}` can be omitted or must be of type `string`", 'when'));
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
const viewDescriptor: IJSONSchema = {
|
|
type: 'object',
|
|
properties: {
|
|
id: {
|
|
description: localize('vscode.extension.contributes.view.id', 'Identifier of the view. Use this to register a data provider through `vscode.window.registerTreeDataProviderForView` API. Also to trigger activating your extension by registering `onView:${id}` event to `activationEvents`.'),
|
|
type: 'string'
|
|
},
|
|
name: {
|
|
description: localize('vscode.extension.contributes.view.name', 'The human-readable name of the view. Will be shown'),
|
|
type: 'string'
|
|
},
|
|
when: {
|
|
description: localize('vscode.extension.contributes.view.when', 'Condition which must be true to show this view'),
|
|
type: 'string'
|
|
},
|
|
}
|
|
};
|
|
|
|
export const viewsContribution: IJSONSchema = {
|
|
description: localize('vscode.extension.contributes.views', "Contributes views to the editor"),
|
|
type: 'object',
|
|
properties: {
|
|
'explorer': {
|
|
description: localize('views.explorer', "Explorer View"),
|
|
type: 'array',
|
|
items: viewDescriptor
|
|
},
|
|
'debug': {
|
|
description: localize('views.debug', "Debug View"),
|
|
type: 'array',
|
|
items: viewDescriptor
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
ExtensionsRegistry.registerExtensionPoint<{ [loc: string]: schema.IUserFriendlyViewDescriptor[] }>('views', [], schema.viewsContribution)
|
|
.setHandler((extensions) => {
|
|
for (let extension of extensions) {
|
|
const { value, collector } = extension;
|
|
|
|
forEach(value, entry => {
|
|
if (!schema.isValidViewDescriptors(entry.value, collector)) {
|
|
return;
|
|
}
|
|
|
|
const location = ViewLocation.getContributedViewLocation(entry.key);
|
|
if (!location) {
|
|
collector.warn(localize('locationId.invalid', "`{0}` is not a valid view location", entry.key));
|
|
return;
|
|
}
|
|
|
|
const registeredViews = ViewsRegistry.getViews(location);
|
|
const viewIds = [];
|
|
const viewDescriptors = coalesce(entry.value.map(item => {
|
|
const viewDescriptor = <IViewDescriptor>{
|
|
id: item.id,
|
|
name: item.name,
|
|
ctor: TreeView,
|
|
location,
|
|
when: ContextKeyExpr.deserialize(item.when),
|
|
canToggleVisibility: true,
|
|
collapsed: true
|
|
};
|
|
|
|
// validate
|
|
if (viewIds.indexOf(viewDescriptor.id) !== -1) {
|
|
collector.error(localize('duplicateView1', "Cannot register multiple views with same id `{0}` in the location `{1}`", viewDescriptor.id, viewDescriptor.location.id));
|
|
return null;
|
|
}
|
|
if (registeredViews.some(v => v.id === viewDescriptor.id)) {
|
|
collector.error(localize('duplicateView2', "A view with id `{0}` is already registered in the location `{1}`", viewDescriptor.id, viewDescriptor.location.id));
|
|
return null;
|
|
}
|
|
|
|
viewIds.push(viewDescriptor.id);
|
|
return viewDescriptor;
|
|
}));
|
|
ViewsRegistry.registerViews(viewDescriptors);
|
|
});
|
|
}
|
|
});
|