Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/services/localization/browser/localeService.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { localize } from '../../../../nls.js';
7
import { Language, LANGUAGE_DEFAULT } from '../../../../base/common/platform.js';
8
import { IDialogService } from '../../../../platform/dialogs/common/dialogs.js';
9
import { ILanguagePackItem } from '../../../../platform/languagePacks/common/languagePacks.js';
10
import { IActiveLanguagePackService, ILocaleService } from '../common/locale.js';
11
import { IHostService } from '../../host/browser/host.js';
12
import { IProductService } from '../../../../platform/product/common/productService.js';
13
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
14
import { CancellationToken } from '../../../../base/common/cancellation.js';
15
import { IExtensionGalleryService } from '../../../../platform/extensionManagement/common/extensionManagement.js';
16
import { ILogService } from '../../../../platform/log/common/log.js';
17
18
const localeStorage = new class LocaleStorage {
19
20
private static readonly LOCAL_STORAGE_LOCALE_KEY = 'vscode.nls.locale';
21
private static readonly LOCAL_STORAGE_EXTENSION_ID_KEY = 'vscode.nls.languagePackExtensionId';
22
23
setLocale(locale: string): void {
24
localStorage.setItem(LocaleStorage.LOCAL_STORAGE_LOCALE_KEY, locale);
25
this.doSetLocaleToCookie(locale);
26
}
27
28
private doSetLocaleToCookie(locale: string): void {
29
document.cookie = `${LocaleStorage.LOCAL_STORAGE_LOCALE_KEY}=${locale};path=/;max-age=3153600000`;
30
}
31
32
clearLocale(): void {
33
localStorage.removeItem(LocaleStorage.LOCAL_STORAGE_LOCALE_KEY);
34
this.doClearLocaleToCookie();
35
}
36
37
private doClearLocaleToCookie(): void {
38
document.cookie = `${LocaleStorage.LOCAL_STORAGE_LOCALE_KEY}=;path=/;max-age=0`;
39
}
40
41
setExtensionId(extensionId: string): void {
42
localStorage.setItem(LocaleStorage.LOCAL_STORAGE_EXTENSION_ID_KEY, extensionId);
43
}
44
45
getExtensionId(): string | null {
46
return localStorage.getItem(LocaleStorage.LOCAL_STORAGE_EXTENSION_ID_KEY);
47
}
48
49
clearExtensionId(): void {
50
localStorage.removeItem(LocaleStorage.LOCAL_STORAGE_EXTENSION_ID_KEY);
51
}
52
};
53
54
export class WebLocaleService implements ILocaleService {
55
56
declare readonly _serviceBrand: undefined;
57
58
constructor(
59
@IDialogService private readonly dialogService: IDialogService,
60
@IHostService private readonly hostService: IHostService,
61
@IProductService private readonly productService: IProductService
62
) { }
63
64
async setLocale(languagePackItem: ILanguagePackItem, _skipDialog = false): Promise<void> {
65
const locale = languagePackItem.id;
66
if (locale === Language.value() || (!locale && Language.value() === navigator.language.toLowerCase())) {
67
return;
68
}
69
if (locale) {
70
localeStorage.setLocale(locale);
71
if (languagePackItem.extensionId) {
72
localeStorage.setExtensionId(languagePackItem.extensionId);
73
}
74
} else {
75
localeStorage.clearLocale();
76
localeStorage.clearExtensionId();
77
}
78
79
const restartDialog = await this.dialogService.confirm({
80
type: 'info',
81
message: localize('relaunchDisplayLanguageMessage', "To change the display language, {0} needs to reload", this.productService.nameLong),
82
detail: localize('relaunchDisplayLanguageDetail', "Press the reload button to refresh the page and set the display language to {0}.", languagePackItem.label),
83
primaryButton: localize({ key: 'reload', comment: ['&& denotes a mnemonic character'] }, "&&Reload"),
84
});
85
86
if (restartDialog.confirmed) {
87
this.hostService.restart();
88
}
89
}
90
91
async clearLocalePreference(): Promise<void> {
92
localeStorage.clearLocale();
93
localeStorage.clearExtensionId();
94
95
if (Language.value() === navigator.language.toLowerCase()) {
96
return;
97
}
98
99
const restartDialog = await this.dialogService.confirm({
100
type: 'info',
101
message: localize('clearDisplayLanguageMessage', "To change the display language, {0} needs to reload", this.productService.nameLong),
102
detail: localize('clearDisplayLanguageDetail', "Press the reload button to refresh the page and use your browser's language."),
103
primaryButton: localize({ key: 'reload', comment: ['&& denotes a mnemonic character'] }, "&&Reload"),
104
});
105
106
if (restartDialog.confirmed) {
107
this.hostService.restart();
108
}
109
}
110
}
111
112
class WebActiveLanguagePackService implements IActiveLanguagePackService {
113
_serviceBrand: undefined;
114
115
constructor(
116
@IExtensionGalleryService private readonly galleryService: IExtensionGalleryService,
117
@ILogService private readonly logService: ILogService
118
) { }
119
120
async getExtensionIdProvidingCurrentLocale(): Promise<string | undefined> {
121
const language = Language.value();
122
if (language === LANGUAGE_DEFAULT) {
123
return undefined;
124
}
125
const extensionId = localeStorage.getExtensionId();
126
if (extensionId) {
127
return extensionId;
128
}
129
130
if (!this.galleryService.isEnabled()) {
131
return undefined;
132
}
133
134
try {
135
const tagResult = await this.galleryService.query({ text: `tag:lp-${language}` }, CancellationToken.None);
136
137
// Only install extensions that are published by Microsoft and start with vscode-language-pack for extra certainty
138
const extensionToInstall = tagResult.firstPage.find(e => e.publisher === 'MS-CEINTL' && e.name.startsWith('vscode-language-pack'));
139
if (extensionToInstall) {
140
localeStorage.setExtensionId(extensionToInstall.identifier.id);
141
return extensionToInstall.identifier.id;
142
}
143
144
// TODO: If a non-Microsoft language pack is installed, we should prompt the user asking if they want to install that.
145
// Since no such language packs exist yet, we can wait until that happens to implement this.
146
} catch (e) {
147
// Best effort
148
this.logService.error(e);
149
}
150
151
return undefined;
152
}
153
}
154
155
registerSingleton(ILocaleService, WebLocaleService, InstantiationType.Delayed);
156
registerSingleton(IActiveLanguagePackService, WebActiveLanguagePackService, InstantiationType.Delayed);
157
158