diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/languages.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/languages.test.ts index dd30fce0aa4..d0594904374 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/languages.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/languages.test.ts @@ -96,6 +96,8 @@ suite('vscode API - languages', () => { assert.ok(found); }); + // HINT: If this test fails, and you have been modifying code used in workers, you might have + // accidentally broken the workers. Check the logs for errors. test('link detector', async function () { const uri = await createRandomFile('class A { // http://a.com }', undefined, '.java'); const doc = await vscode.workspace.openTextDocument(uri); diff --git a/src/vs/base/common/platform.ts b/src/vs/base/common/platform.ts index 948b62e0a93..78704d04368 100644 --- a/src/vs/base/common/platform.ts +++ b/src/vs/base/common/platform.ts @@ -80,7 +80,19 @@ if (typeof navigator === 'object' && !isElectronRenderer) { _isIOS = (_userAgent.indexOf('Macintosh') >= 0 || _userAgent.indexOf('iPad') >= 0 || _userAgent.indexOf('iPhone') >= 0) && !!navigator.maxTouchPoints && navigator.maxTouchPoints > 0; _isLinux = _userAgent.indexOf('Linux') >= 0; _isWeb = true; - _locale = navigator.language; + + // Gather loader configuration since that contains the locale + let loaderConfiguration: any = null; + if (typeof globals.require !== 'undefined' && typeof globals.require.getConfig === 'function') { + // Get the configuration from the Monaco AMD Loader + loaderConfiguration = globals.require.getConfig(); + } else if (typeof globals.requirejs !== 'undefined') { + // Get the configuration from requirejs + loaderConfiguration = globals.requirejs.s.contexts._.config; + } + const configuredLocale = loaderConfiguration?.['vs/nls']?.['availableLanguages']?.['*'] as string | undefined; + _locale = configuredLocale || navigator.language; + _language = _locale; } diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index d8914408e4a..4c5c3eb50b3 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -43,7 +43,7 @@ // Set up nls if the user is not using the default language (English) const nlsConfig = {}; - const locale = navigator.language; + const locale = window.localStorage.getItem('vscode.nls.locale') || navigator.language; if (!locale.startsWith('en')) { nlsConfig['vs/nls'] = { availableLanguages: { diff --git a/src/vs/platform/languagePacks/browser/languagePacks.ts b/src/vs/platform/languagePacks/browser/languagePacks.ts new file mode 100644 index 00000000000..83b4c051e0f --- /dev/null +++ b/src/vs/platform/languagePacks/browser/languagePacks.ts @@ -0,0 +1,13 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ILanguagePackItem, LanguagePackBaseService } from 'vs/platform/languagePacks/common/languagePacks'; + +export class WebLanguagePacksService extends LanguagePackBaseService { + // Web doesn't have a concept of language packs, so we just return an empty array + getInstalledLanguages(): Promise { + return Promise.resolve([]); + } +} diff --git a/src/vs/platform/languagePacks/common/languagePacks.ts b/src/vs/platform/languagePacks/common/languagePacks.ts index 61c6c04553a..146cbce7401 100644 --- a/src/vs/platform/languagePacks/common/languagePacks.ts +++ b/src/vs/platform/languagePacks/common/languagePacks.ts @@ -25,7 +25,7 @@ export interface ILanguagePackService { } export abstract class LanguagePackBaseService extends Disposable implements ILanguagePackService { - _serviceBrand: undefined; + declare readonly _serviceBrand: undefined; constructor(@IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService) { super(); diff --git a/src/vs/platform/languagePacks/node/languagePacks.ts b/src/vs/platform/languagePacks/node/languagePacks.ts index 369f4bb32f6..3d40555a04f 100644 --- a/src/vs/platform/languagePacks/node/languagePacks.ts +++ b/src/vs/platform/languagePacks/node/languagePacks.ts @@ -28,9 +28,6 @@ interface ILanguagePack { } export class NativeLanguagePackService extends LanguagePackBaseService { - - declare readonly _serviceBrand: undefined; - private readonly cache: LanguagePacksCache; constructor( diff --git a/src/vs/workbench/contrib/localization/browser/localization.contribution.ts b/src/vs/workbench/contrib/localization/browser/localization.contribution.ts new file mode 100644 index 00000000000..79f2f0a777b --- /dev/null +++ b/src/vs/workbench/contrib/localization/browser/localization.contribution.ts @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { registerAction2 } from 'vs/platform/actions/common/actions'; +import { ClearDisplayLanguageAction, ConfigureDisplayLanguageAction } from 'vs/workbench/contrib/localization/browser/localizationsActions'; + +// Register action to configure locale and related settings +registerAction2(ConfigureDisplayLanguageAction); +registerAction2(ClearDisplayLanguageAction); diff --git a/src/vs/workbench/services/localization/browser/localeService.ts b/src/vs/workbench/services/localization/browser/localeService.ts new file mode 100644 index 00000000000..802d9bdd46f --- /dev/null +++ b/src/vs/workbench/services/localization/browser/localeService.ts @@ -0,0 +1,26 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { language } from 'vs/base/common/platform'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { ILocaleService } from 'vs/workbench/services/localization/common/locale'; + +export class WebLocaleService implements ILocaleService { + declare readonly _serviceBrand: undefined; + + async setLocale(locale: string | undefined): Promise { + if (locale === language || (!locale && language === navigator.language)) { + return false; + } + if (locale) { + window.localStorage.setItem('vscode.nls.locale', locale); + } else { + window.localStorage.removeItem('vscode.nls.locale'); + } + return true; + } +} + +registerSingleton(ILocaleService, WebLocaleService, true); diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index 7cc89fe419b..3f84c0d4b7c 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -62,6 +62,7 @@ import 'vs/workbench/services/files/browser/elevatedFileService'; import 'vs/workbench/services/workingCopy/browser/workingCopyHistoryService'; import 'vs/workbench/services/userDataSync/browser/webUserDataSyncEnablementService'; import 'vs/workbench/services/configurationResolver/browser/configurationResolverService'; +import 'vs/workbench/services/localization/browser/localeService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; @@ -87,6 +88,8 @@ import { ITitleService } from 'vs/workbench/services/title/common/titleService'; import { TitlebarPart } from 'vs/workbench/browser/parts/titlebar/titlebarPart'; import { ITimerService, TimerService } from 'vs/workbench/services/timer/browser/timerService'; import { IDiagnosticsService, NullDiagnosticsService } from 'vs/platform/diagnostics/common/diagnostics'; +import { ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks'; +import { WebLanguagePacksService } from 'vs/platform/languagePacks/browser/languagePacks'; registerSingleton(IWorkbenchExtensionManagementService, ExtensionManagementService); registerSingleton(IAccessibilityService, AccessibilityService, true); @@ -103,6 +106,7 @@ registerSingleton(IExtensionTipsService, ExtensionTipsService); registerSingleton(ITimerService, TimerService); registerSingleton(ICustomEndpointTelemetryService, NullEndpointTelemetryService, true); registerSingleton(IDiagnosticsService, NullDiagnosticsService, true); +registerSingleton(ILanguagePackService, WebLanguagePacksService, true); //#endregion @@ -118,6 +122,9 @@ import 'vs/workbench/contrib/logs/browser/logs.contribution'; // Explorer import 'vs/workbench/contrib/files/browser/files.web.contribution'; +// Localization +import 'vs/workbench/contrib/localization/browser/localization.contribution'; + // Performance import 'vs/workbench/contrib/performance/browser/performance.web.contribution';