1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { isObject, isString } from 'vs/base/common/types';
import { ILocalizedString } from 'vs/platform/action/common/action';
import { IExtensionManifest } from 'vs/platform/extensions/common/extensions';
import { localize } from 'vs/nls';
export interface ITranslations {
[key: string]: string | { message: string; comment: string[] };
}
export function localizeManifest(extensionManifest: IExtensionManifest, translations: ITranslations, fallbackTranslations?: ITranslations): IExtensionManifest {
try {
replaceNLStrings(extensionManifest, translations, fallbackTranslations);
} catch (error) {
/*Ignore Error*/
}
return extensionManifest;
}
/**
* This routine makes the following assumptions:
* The root element is an object literal
*/
function replaceNLStrings(extensionManifest: IExtensionManifest, messages: ITranslations, originalMessages?: ITranslations): void {
const processEntry = (obj: any, key: string | number, command?: boolean) => {
const value = obj[key];
if (isString(value)) {
const str = <string>value;
const length = str.length;
if (length > 1 && str[0] === '%' && str[length - 1] === '%') {
const messageKey = str.substr(1, length - 2);
let translated = messages[messageKey];
// If the messages come from a language pack they might miss some keys
// Fill them from the original messages.
if (translated === undefined && originalMessages) {
translated = originalMessages[messageKey];
}
const message: string | undefined = typeof translated === 'string' ? translated : translated.message;
if (message !== undefined) {
// This branch returns ILocalizedString's instead of Strings so that the Command Palette can contain both the localized and the original value.
const original = originalMessages?.[messageKey];
const originalMessage: string | undefined = typeof original === 'string' ? original : original?.message;
if (
// if we are translating the title or category of a command
command && (key === 'title' || key === 'category') &&
// and the original value is not the same as the translated value
originalMessage && originalMessage !== message
) {
const localizedString: ILocalizedString = {
value: message,
original: originalMessage
};
obj[key] = localizedString;
} else {
obj[key] = message;
}
} else {
console.warn(`[${extensionManifest.name}]: ${localize('missingNLSKey', "Couldn't find message for key {0}.", messageKey)}`);
}
}
} else if (isObject(value)) {
for (const k in value) {
if (value.hasOwnProperty(k)) {
k === 'commands' ? processEntry(value, k, true) : processEntry(value, k, command);
}
}
} else if (Array.isArray(value)) {
for (let i = 0; i < value.length; i++) {
processEntry(value, i, command);
}
}
};
for (const key in extensionManifest) {
if (extensionManifest.hasOwnProperty(key)) {
processEntry(extensionManifest, key);
}
}
}
|