From a873709f0ee31f7bbb90404f98893927161801ee Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Wed, 13 Jul 2022 08:22:14 -0700 Subject: [PATCH 1/8] initial attempt --- src/browser/main.ts | 56 +++++++++++++++++++++++++++++++++---- src/browser/nlsWebData.d.ts | 4 +++ src/common/common.ts | 10 +++++++ src/node/main.ts | 12 +------- 4 files changed, 66 insertions(+), 16 deletions(-) create mode 100644 src/browser/nlsWebData.d.ts diff --git a/src/browser/main.ts b/src/browser/main.ts index 647a2d2..b77f1bf 100644 --- a/src/browser/main.ts +++ b/src/browser/main.ts @@ -5,25 +5,71 @@ import RAL from '../common/ral'; -import { setPseudo, localize, Options, LocalizeInfo } from '../common/common'; - +import { setPseudo, localize, Options, LocalizeInfo, isString, BundleFormat, MessageFormat, isNumber, format, LocalizeFunc } from '../common/common'; +import * as nlsData from 'vscode-nls-web-data'; export { MessageFormat, BundleFormat, Options, LocalizeInfo, LocalizeFunc, LoadFunc, KeyInfo } from '../common/common'; +interface InternalOptions { + locale: string | undefined; + language: string | undefined; + languagePackSupport: boolean; + cacheLanguageResolution: boolean; + messageFormat: MessageFormat; + languagePackId?: string; + cacheRoot?: string; +} + +let options: InternalOptions; + export function loadMessageBundle(_file?: string) { + if (nlsData?.length) { + return createScopedLocalizeFunction(nlsData); + } return function (key: string | number | LocalizeInfo, message: string, ...args: any[]): string { if (typeof key === 'number') { - throw new Error(`Browser implementation does currently not support externalized strings.`); + throw new Error('Externalized strings were not present in the environment.'); } else { return localize(key, message, ...args); } }; } -export function config(options?: Options) { - setPseudo(options?.locale?.toLowerCase() === 'pseudo'); +export function config(opts?: Options) { + if (opts) { + if (isString(opts.locale)) { + options.locale = opts.locale.toLowerCase(); + options.language = options.locale; + } + if (opts.messageFormat !== undefined) { + options.messageFormat = opts.messageFormat; + } + if (opts.bundleFormat === BundleFormat.standalone && options.languagePackSupport === true) { + options.languagePackSupport = false; + } + } + setPseudo(options.locale === 'pseudo'); return loadMessageBundle; } +function createScopedLocalizeFunction(messages: string[]): LocalizeFunc { + return function (key: any, message: string, ...args: any[]): string { + if (isNumber(key)) { + if (key >= messages.length) { + console.error(`Broken localize call found. Index out of bounds. Stacktrace is\n: ${(new Error('')).stack}`); + return; + } + return format(messages[key], args); + } else { + if (isString(message)) { + console.warn(`Message ${message} didn't get externalized correctly.`); + return format(message, args); + } else { + console.error(`Broken localize call found. Stacktrace is\n: ${(new Error('')).stack}`); + } + } + }; +} + RAL.install(Object.freeze({ loadMessageBundle: loadMessageBundle, config: config diff --git a/src/browser/nlsWebData.d.ts b/src/browser/nlsWebData.d.ts new file mode 100644 index 0000000..bfceb1e --- /dev/null +++ b/src/browser/nlsWebData.d.ts @@ -0,0 +1,4 @@ +declare module 'vscode-nls-web-data' { + const LocalizedStrings: string[]; + export = LocalizedStrings; +} diff --git a/src/common/common.ts b/src/common/common.ts index 111df72..912338a 100644 --- a/src/common/common.ts +++ b/src/common/common.ts @@ -91,6 +91,16 @@ export function isDefined(value: any): boolean { return typeof value !== 'undefined'; } +const toString = Object.prototype.toString; + +export function isNumber(value: any): value is number { + return toString.call(value) === '[object Number]'; +} + +export function isString(value: any): value is string { + return toString.call(value) === '[object String]'; +} + export let isPseudo = false; export function setPseudo(pseudo: boolean) { diff --git a/src/node/main.ts b/src/node/main.ts index 484409e..8ae0f85 100644 --- a/src/node/main.ts +++ b/src/node/main.ts @@ -10,21 +10,11 @@ import RAL from '../common/ral'; import { format, localize, isDefined, setPseudo, isPseudo, MessageFormat, BundleFormat, Options, TranslationConfig, LanguageBundle, LocalizeFunc, - NlsBundle, MetaDataFile, MetadataHeader, I18nBundle, SingleFileJsonFormat, LoadFunc + NlsBundle, MetaDataFile, MetadataHeader, I18nBundle, SingleFileJsonFormat, LoadFunc, isString, isNumber } from '../common/common'; export { MessageFormat, BundleFormat, Options, LocalizeInfo, LocalizeFunc, LoadFunc, KeyInfo } from '../common/common'; -const toString = Object.prototype.toString; - -function isNumber(value: any): value is number { - return toString.call(value) === '[object Number]'; -} - -function isString(value: any): value is string { - return toString.call(value) === '[object String]'; -} - function isBoolean(value: any): value is boolean { return value === true || value === false; } From 6c250423670c9bd35fb82f31fd392f38ef7c62ad Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Wed, 13 Jul 2022 12:30:04 -0700 Subject: [PATCH 2/8] use file --- src/browser/main.ts | 15 ++++++++++++--- src/browser/tsconfig.json | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/browser/main.ts b/src/browser/main.ts index b77f1bf..cd86a80 100644 --- a/src/browser/main.ts +++ b/src/browser/main.ts @@ -21,9 +21,18 @@ interface InternalOptions { let options: InternalOptions; -export function loadMessageBundle(_file?: string) { - if (nlsData?.length) { - return createScopedLocalizeFunction(nlsData); +export function loadMessageBundle(file?: string) { + if (!file) { + // No file. We are in dev mode. Return the default + // localize function. + return localize; + } + // Remove extension since we load json files. + if (file.endsWith('.js')) { + file = file.substring(0, file.length - 3); + } + if (nlsData && nlsData[file]) { + return createScopedLocalizeFunction(nlsData[file]); } return function (key: string | number | LocalizeInfo, message: string, ...args: any[]): string { if (typeof key === 'number') { diff --git a/src/browser/tsconfig.json b/src/browser/tsconfig.json index ce58932..e1cc8de 100644 --- a/src/browser/tsconfig.json +++ b/src/browser/tsconfig.json @@ -2,7 +2,7 @@ "extends": "../../tsconfig.base.json", "compilerOptions": { "lib": [ - "es5", + "es2015", "dom" ], "outDir": "../../lib/browser" From a65c256823e87c8dae3e2b5cbd6cf815aea1a42f Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Thu, 14 Jul 2022 14:42:39 -0700 Subject: [PATCH 3/8] add ts --- src/browser/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/main.ts b/src/browser/main.ts index cd86a80..029bf66 100644 --- a/src/browser/main.ts +++ b/src/browser/main.ts @@ -28,7 +28,7 @@ export function loadMessageBundle(file?: string) { return localize; } // Remove extension since we load json files. - if (file.endsWith('.js')) { + if (file.endsWith('.js') || file.endsWith('.ts')) { file = file.substring(0, file.length - 3); } if (nlsData && nlsData[file]) { From 3d7b8a625e43421185e60e7f96f14a6cae9a7774 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Thu, 14 Jul 2022 15:06:07 -0700 Subject: [PATCH 4/8] also remove leading slash --- src/browser/main.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/browser/main.ts b/src/browser/main.ts index 029bf66..f53790f 100644 --- a/src/browser/main.ts +++ b/src/browser/main.ts @@ -31,6 +31,9 @@ export function loadMessageBundle(file?: string) { if (file.endsWith('.js') || file.endsWith('.ts')) { file = file.substring(0, file.length - 3); } + if (file.startsWith('/')) { + file = file.substring(1); + } if (nlsData && nlsData[file]) { return createScopedLocalizeFunction(nlsData[file]); } From 68db23e7221da390d0c815427b969113a0583b3a Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Thu, 14 Jul 2022 16:31:57 -0700 Subject: [PATCH 5/8] try a different way to import a module --- src/browser/main.ts | 18 ++++-------------- src/browser/nlsWebData.d.ts | 4 ---- src/browser/vscode-nls-web-data.ts | 5 +++++ 3 files changed, 9 insertions(+), 18 deletions(-) delete mode 100644 src/browser/nlsWebData.d.ts create mode 100644 src/browser/vscode-nls-web-data.ts diff --git a/src/browser/main.ts b/src/browser/main.ts index f53790f..6b09ad3 100644 --- a/src/browser/main.ts +++ b/src/browser/main.ts @@ -6,7 +6,7 @@ import RAL from '../common/ral'; import { setPseudo, localize, Options, LocalizeInfo, isString, BundleFormat, MessageFormat, isNumber, format, LocalizeFunc } from '../common/common'; -import * as nlsData from 'vscode-nls-web-data'; +import * as nlsData from './vscode-nls-web-data'; export { MessageFormat, BundleFormat, Options, LocalizeInfo, LocalizeFunc, LoadFunc, KeyInfo } from '../common/common'; interface InternalOptions { @@ -46,20 +46,10 @@ export function loadMessageBundle(file?: string) { }; } +// This API doesn't really do anything in practice because the message bundle _has_ to be loaded +// ahead of time via 'vscode-nls-web-data'. export function config(opts?: Options) { - if (opts) { - if (isString(opts.locale)) { - options.locale = opts.locale.toLowerCase(); - options.language = options.locale; - } - if (opts.messageFormat !== undefined) { - options.messageFormat = opts.messageFormat; - } - if (opts.bundleFormat === BundleFormat.standalone && options.languagePackSupport === true) { - options.languagePackSupport = false; - } - } - setPseudo(options.locale === 'pseudo'); + setPseudo(options?.locale?.toLowerCase() === 'pseudo'); return loadMessageBundle; } diff --git a/src/browser/nlsWebData.d.ts b/src/browser/nlsWebData.d.ts deleted file mode 100644 index bfceb1e..0000000 --- a/src/browser/nlsWebData.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare module 'vscode-nls-web-data' { - const LocalizedStrings: string[]; - export = LocalizedStrings; -} diff --git a/src/browser/vscode-nls-web-data.ts b/src/browser/vscode-nls-web-data.ts new file mode 100644 index 0000000..ddeda8d --- /dev/null +++ b/src/browser/vscode-nls-web-data.ts @@ -0,0 +1,5 @@ +/* +* REQUIRING THIS FILE WILL BE INTERCEPTED BY VSCODE AND WILL +* CONTAIN ACTUAL NLS DATA. +*/ +export {}; From c40a143f160755be030e8a4f48cecc24cd348ed1 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Thu, 14 Jul 2022 16:35:14 -0700 Subject: [PATCH 6/8] clean up imports --- src/browser/main.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/browser/main.ts b/src/browser/main.ts index 6b09ad3..c692045 100644 --- a/src/browser/main.ts +++ b/src/browser/main.ts @@ -5,8 +5,10 @@ import RAL from '../common/ral'; -import { setPseudo, localize, Options, LocalizeInfo, isString, BundleFormat, MessageFormat, isNumber, format, LocalizeFunc } from '../common/common'; +// Requiring this file will be intercepted by VS Code and will contain actual NLS data. import * as nlsData from './vscode-nls-web-data'; + +import { setPseudo, localize, Options, LocalizeInfo, isString, MessageFormat, isNumber, format, LocalizeFunc } from '../common/common'; export { MessageFormat, BundleFormat, Options, LocalizeInfo, LocalizeFunc, LoadFunc, KeyInfo } from '../common/common'; interface InternalOptions { From 44d6a933a92b420a076dd5ed63c494a9a0b061b8 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Fri, 15 Jul 2022 10:16:27 -0700 Subject: [PATCH 7/8] use a sync require instead --- src/browser/main.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/browser/main.ts b/src/browser/main.ts index c692045..aacc832 100644 --- a/src/browser/main.ts +++ b/src/browser/main.ts @@ -5,12 +5,19 @@ import RAL from '../common/ral'; -// Requiring this file will be intercepted by VS Code and will contain actual NLS data. -import * as nlsData from './vscode-nls-web-data'; - import { setPseudo, localize, Options, LocalizeInfo, isString, MessageFormat, isNumber, format, LocalizeFunc } from '../common/common'; export { MessageFormat, BundleFormat, Options, LocalizeInfo, LocalizeFunc, LoadFunc, KeyInfo } from '../common/common'; +let nlsData: { [key: string]: string[] }; +try { + // Requiring this file will be intercepted by VS Code and will contain actual NLS data. + // @ts-ignore + nlsData = require('vscode-nls-web-data'); +} catch(e) { + console.error('Loading vscode-nls-web-data failed. Are you running this outside of VS Code? If so, you may need to intercept the import call with your bundled NLS data.'); + nlsData = {}; +} + interface InternalOptions { locale: string | undefined; language: string | undefined; From 1cd95c3418ecf2b8d9977d80009d992f849b0cab Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Thu, 28 Jul 2022 11:13:07 -0700 Subject: [PATCH 8/8] don't need this file anymore --- src/browser/vscode-nls-web-data.ts | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 src/browser/vscode-nls-web-data.ts diff --git a/src/browser/vscode-nls-web-data.ts b/src/browser/vscode-nls-web-data.ts deleted file mode 100644 index ddeda8d..0000000 --- a/src/browser/vscode-nls-web-data.ts +++ /dev/null @@ -1,5 +0,0 @@ -/* -* REQUIRING THIS FILE WILL BE INTERCEPTED BY VSCODE AND WILL -* CONTAIN ACTUAL NLS DATA. -*/ -export {};