From b25c1947c6bcb43298914ee32d11e82e178978d5 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 22 Jan 2018 17:58:51 +0100 Subject: [PATCH] #41752 Update extension point --- .../configuration-editing/src/extension.ts | 10 +-- .../contrib/languagePackExtensions.ts | 16 +++-- .../common/extensionEnablementService.ts | 2 +- .../common/extensionManagement.ts | 9 +-- .../common/extensionEnablementService.test.ts | 2 +- .../browser/localizationsExtensionPoint.ts | 69 +++++++++++++++++++ src/vs/workbench/workbench.main.ts | 3 + 7 files changed, 93 insertions(+), 18 deletions(-) create mode 100644 src/vs/workbench/api/browser/localizationsExtensionPoint.ts diff --git a/extensions/configuration-editing/src/extension.ts b/extensions/configuration-editing/src/extension.ts index aacb21ff777..a081f0ad448 100644 --- a/extensions/configuration-editing/src/extension.ts +++ b/extensions/configuration-editing/src/extension.ts @@ -87,11 +87,11 @@ function registerLocaleCompletionsInLanguageDocument(): vscode.Disposable { function provideContributedLocalesProposals(range: vscode.Range): vscode.ProviderResult { const contributedLocales: string[] = []; for (const extension of vscode.extensions.all) { - if (extension.packageJSON && extension.packageJSON['contributes'] && extension.packageJSON['contributes']['locales'] && extension.packageJSON['contributes']['locales'].length) { - const locales: { locale: string }[] = extension.packageJSON['contributes']['locales']; - for (const locale of locales) { - if (contributedLocales.indexOf(locale.locale) === -1) { - contributedLocales.push(locale.locale); + if (extension.packageJSON && extension.packageJSON['contributes'] && extension.packageJSON['contributes']['localizations'] && extension.packageJSON['contributes']['localizations'].length) { + const localizations: { languageId: string }[] = extension.packageJSON['contributes']['localizations']; + for (const localization of localizations) { + if (contributedLocales.indexOf(localization.languageId) === -1) { + contributedLocales.push(localization.languageId); } } } diff --git a/src/vs/code/electron-browser/sharedProcess/contrib/languagePackExtensions.ts b/src/vs/code/electron-browser/sharedProcess/contrib/languagePackExtensions.ts index 1add53f4777..64fd8395763 100644 --- a/src/vs/code/electron-browser/sharedProcess/contrib/languagePackExtensions.ts +++ b/src/vs/code/electron-browser/sharedProcess/contrib/languagePackExtensions.ts @@ -16,7 +16,7 @@ import { ILogService } from 'vs/platform/log/common/log'; interface ILanguageSource { extensionIdentifier: IExtensionIdentifier; version: string; - path: string; + translations: string; } export class LanguagePackExtensions extends Disposable { @@ -52,7 +52,7 @@ export class LanguagePackExtensions extends Disposable { } private onDidInstallExtension(extension: ILocalExtension): void { - if (extension && extension.manifest && extension.manifest.contributes && extension.manifest.contributes.locales && extension.manifest.contributes.locales.length) { + if (extension && extension.manifest && extension.manifest.contributes && extension.manifest.contributes.localizations && extension.manifest.contributes.localizations.length) { this.logService.debug('Adding language packs from the extension', extension.identifier.id); this.withLanguagePacks(languagePacks => { this.removeLanguagePacksFromExtensions(languagePacks, { id: getGalleryExtensionIdFromLocal(extension), uuid: extension.identifier.uuid }); @@ -68,12 +68,14 @@ export class LanguagePackExtensions extends Disposable { private addLanguagePacksFromExtensions(languagePacks: { [language: string]: ILanguageSource[] }, ...extensions: ILocalExtension[]): void { for (const extension of extensions) { - if (extension && extension.manifest && extension.manifest.contributes && extension.manifest.contributes.locales && extension.manifest.contributes.locales.length) { + if (extension && extension.manifest && extension.manifest.contributes && extension.manifest.contributes.localizations && extension.manifest.contributes.localizations.length) { const extensionIdentifier = { id: getGalleryExtensionIdFromLocal(extension), uuid: extension.identifier.uuid }; - for (const localeContribution of extension.manifest.contributes.locales) { - const languageSources = languagePacks[localeContribution.locale] || []; - languageSources.splice(0, 0, { extensionIdentifier, path: join(extension.path, localeContribution.path), version: extension.manifest.version }); - languagePacks[localeContribution.locale] = languageSources; + for (const localizationContribution of extension.manifest.contributes.localizations) { + if (localizationContribution.languagId && localizationContribution.translations) { + const languageSources = languagePacks[localizationContribution.languagId] || []; + languageSources.splice(0, 0, { extensionIdentifier, translations: join(extension.path, localizationContribution.translations), version: extension.manifest.version }); + languagePacks[localizationContribution.languagId] = languageSources; + } } } } diff --git a/src/vs/platform/extensionManagement/common/extensionEnablementService.ts b/src/vs/platform/extensionManagement/common/extensionEnablementService.ts index 990894ef862..8e4c9917668 100644 --- a/src/vs/platform/extensionManagement/common/extensionEnablementService.ts +++ b/src/vs/platform/extensionManagement/common/extensionEnablementService.ts @@ -78,7 +78,7 @@ export class ExtensionEnablementService implements IExtensionEnablementService { } canChangeEnablement(extension: ILocalExtension): boolean { - return !this.environmentService.disableExtensions && !(extension.manifest && extension.manifest.contributes && extension.manifest.contributes.locales && extension.manifest.contributes.locales.length); + return !this.environmentService.disableExtensions && !(extension.manifest && extension.manifest.contributes && extension.manifest.contributes.localizations && extension.manifest.contributes.localizations.length); } setEnablement(arg: ILocalExtension | IExtensionIdentifier, newState: EnablementState): TPromise { diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index 28f19aa05df..9789db5e966 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -85,9 +85,10 @@ export interface IColor { defaults: { light: string, dark: string, highContrast: string }; } -export interface ILocale { - locale: string; - path: string; +export interface ILocalization { + languagId: string; + languageName?: string; + translations: string; } export interface IExtensionContributions { @@ -104,7 +105,7 @@ export interface IExtensionContributions { iconThemes?: ITheme[]; views?: { [location: string]: IView[] }; colors?: IColor[]; - locales?: ILocale[]; + localizations?: ILocalization[]; } export interface IExtensionManifest { diff --git a/src/vs/platform/extensionManagement/test/common/extensionEnablementService.test.ts b/src/vs/platform/extensionManagement/test/common/extensionEnablementService.test.ts index 4ccb6691229..efdb210e498 100644 --- a/src/vs/platform/extensionManagement/test/common/extensionEnablementService.test.ts +++ b/src/vs/platform/extensionManagement/test/common/extensionEnablementService.test.ts @@ -326,7 +326,7 @@ suite('ExtensionEnablementService Test', () => { }); test('test canChangeEnablement return false for language packs', () => { - assert.equal(testObject.canChangeEnablement(aLocalExtension('pub.a', { locales: [{ locale: 'gr', path: 'somepath' }] })), false); + assert.equal(testObject.canChangeEnablement(aLocalExtension('pub.a', { localizations: [{ languagId: 'gr', translations: 'somepath' }] })), false); }); }); diff --git a/src/vs/workbench/api/browser/localizationsExtensionPoint.ts b/src/vs/workbench/api/browser/localizationsExtensionPoint.ts new file mode 100644 index 00000000000..dcead032694 --- /dev/null +++ b/src/vs/workbench/api/browser/localizationsExtensionPoint.ts @@ -0,0 +1,69 @@ +/*--------------------------------------------------------------------------------------------- + * 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 { IJSONSchema } from 'vs/base/common/jsonSchema'; +import { ExtensionMessageCollector, ExtensionsRegistry } from 'vs/platform/extensions/common/extensionsRegistry'; + +namespace schema { + + // --localizations contribution point + + export interface ILocalizationDescriptor { + languageId: string; + languageName: string; + translations: string; + } + + export function validateLocalizationDescriptors(localizationDescriptors: ILocalizationDescriptor[], collector: ExtensionMessageCollector): boolean { + if (!Array.isArray(localizationDescriptors)) { + collector.error(localize('requirearray', "localizations must be an array")); + return false; + } + + for (let descriptor of localizationDescriptors) { + if (typeof descriptor.languageId !== 'string') { + collector.error(localize('requirestring', "property `{0}` is mandatory and must be of type `string`", 'languageId')); + return false; + } + if (typeof descriptor.languageName !== 'string') { + collector.error(localize('optstring', "property `{0}` can be omitted or must be of type `string`", 'languageName')); + return false; + } + if (descriptor.translations && typeof descriptor.translations !== 'string') { + collector.error(localize('requirestring', "property `{0}` is mandatory and must be of type `string`", 'translations')); + return false; + } + } + + return true; + } + + export const localizationsContribution: IJSONSchema = { + description: localize('vscode.extension.contributes.localizations', "Contributes localizations to the editor"), + type: 'array', + items: { + type: 'object', + properties: { + id: { + description: localize('vscode.extension.contributes.localizations.languageId', 'Id of the language into which the display strings are translated.'), + type: 'string' + }, + name: { + description: localize('vscode.extension.contributes.localizations.languageName', 'Name of the language into which the display strings are translated.'), + type: 'string' + }, + translations: { + description: localize('vscode.extension.contributes.localizations.translations', 'A relative path to the folder containing all translation files for the contributed language.'), + type: 'string' + } + } + } + }; +} + +ExtensionsRegistry.registerExtensionPoint('localizations', [], schema.localizationsContribution) + .setHandler((extensions) => extensions.forEach(extension => schema.validateLocalizationDescriptors(extension.value, extension.collector))); \ No newline at end of file diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index cc5fa97e31a..2966cea4559 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -21,6 +21,9 @@ import 'vs/platform/actions/electron-browser/menusExtensionPoint'; // Views import 'vs/workbench/api/browser/viewsExtensionPoint'; +// Localizations +import 'vs/workbench/api/browser/localizationsExtensionPoint'; + // Workbench import 'vs/workbench/browser/actions/toggleActivityBarVisibility'; import 'vs/workbench/browser/actions/toggleStatusbarVisibility';