diff --git a/.eslintplugin/code-no-unexternalized-strings.ts b/.eslintplugin/code-no-unexternalized-strings.ts index d0c30527f7cdf..0dc36ff800dbd 100644 --- a/.eslintplugin/code-no-unexternalized-strings.ts +++ b/.eslintplugin/code-no-unexternalized-strings.ts @@ -85,6 +85,27 @@ export = new class NoUnexternalizedStrings implements eslint.Rule.RuleModule { } } + function visitL10NCall(node: TSESTree.CallExpression) { + + // localize(key, message) + const [messageNode] = (node).arguments; + + // remove message-argument from doubleQuoted list and make + // sure it is a string-literal + if (isStringLiteral(messageNode)) { + doubleQuotedStringLiterals.delete(messageNode); + } else if (messageNode.type === AST_NODE_TYPES.ObjectExpression) { + for (const prop of messageNode.properties) { + if (prop.type === AST_NODE_TYPES.Property) { + if (prop.key.type === AST_NODE_TYPES.Identifier && prop.key.name === 'message') { + doubleQuotedStringLiterals.delete(prop.value); + break; + } + } + } + } + } + function reportBadStringsAndBadKeys() { // (1) // report all strings that are in double quotes @@ -118,6 +139,7 @@ export = new class NoUnexternalizedStrings implements eslint.Rule.RuleModule { ['Literal']: (node: any) => collectDoubleQuotedStrings(node), ['ExpressionStatement[directive] Literal:exit']: (node: any) => doubleQuotedStringLiterals.delete(node), ['CallExpression[callee.type="MemberExpression"][callee.object.name="nls"][callee.property.name="localize"]:exit']: (node: any) => visitLocalizeCall(node), + ['CallExpression[callee.type="MemberExpression"][callee.object.property.name="l10n"][callee.property.name="t"]:exit']: (node: any) => visitL10NCall(node), ['CallExpression[callee.name="localize"][arguments.length>=2]:exit']: (node: any) => visitLocalizeCall(node), ['Program:exit']: reportBadStringsAndBadKeys, }; diff --git a/extensions/markdown-language-features/package.json b/extensions/markdown-language-features/package.json index 960939ed7b9d4..a2d6c46a4c888 100644 --- a/extensions/markdown-language-features/package.json +++ b/extensions/markdown-language-features/package.json @@ -628,7 +628,6 @@ "morphdom": "^2.6.1", "picomatch": "^2.3.1", "vscode-languageclient": "^8.0.2", - "vscode-nls": "^5.2.0", "vscode-uri": "^3.0.3" }, "devDependencies": { diff --git a/extensions/markdown-language-features/src/client/client.ts b/extensions/markdown-language-features/src/client/client.ts index 118a71dd473e9..82fbc7edaed2c 100644 --- a/extensions/markdown-language-features/src/client/client.ts +++ b/extensions/markdown-language-features/src/client/client.ts @@ -5,7 +5,6 @@ import * as vscode from 'vscode'; import { BaseLanguageClient, LanguageClientOptions, NotebookDocumentSyncRegistrationType } from 'vscode-languageclient'; -import * as nls from 'vscode-nls'; import { IMdParser } from '../markdownEngine'; import * as proto from './protocol'; import { looksLikeMarkdownPath, markdownFileExtensions } from '../util/file'; @@ -13,7 +12,6 @@ import { VsCodeMdWorkspace } from './workspace'; import { FileWatcherManager } from './fileWatchingManager'; import { IDisposable } from '../util/dispose'; -const localize = nls.loadMessageBundle(); export type LanguageClientConstructor = (name: string, description: string, clientOptions: LanguageClientOptions) => BaseLanguageClient; @@ -64,7 +62,7 @@ export async function startClient(factory: LanguageClientConstructor, parser: IM }, }; - const client = factory('markdown', localize('markdownServer.name', 'Markdown Language Server'), clientOptions); + const client = factory('markdown', vscode.l10n.t("Markdown Language Server"), clientOptions); client.registerProposedFeatures(); diff --git a/extensions/markdown-language-features/src/commands/insertResource.ts b/extensions/markdown-language-features/src/commands/insertResource.ts index aef9bf648b8cb..66041df75d30b 100644 --- a/extensions/markdown-language-features/src/commands/insertResource.ts +++ b/extensions/markdown-language-features/src/commands/insertResource.ts @@ -4,14 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import * as nls from 'vscode-nls'; import { Utils } from 'vscode-uri'; import { Command } from '../commandManager'; import { createUriListSnippet, getParentDocumentUri, imageFileExtensions } from '../languageFeatures/dropIntoEditor'; import { coalesce } from '../util/arrays'; import { Schemes } from '../util/schemes'; -const localize = nls.loadMessageBundle(); export class InsertLinkFromWorkspace implements Command { @@ -27,8 +25,8 @@ export class InsertLinkFromWorkspace implements Command { canSelectFiles: true, canSelectFolders: false, canSelectMany: true, - openLabel: localize('insertLink.openLabel', "Insert link"), - title: localize('insertLink.title', "Insert link"), + openLabel: vscode.l10n.t("Insert link"), + title: vscode.l10n.t("Insert link"), defaultUri: getDefaultUri(activeEditor.document), }); @@ -50,10 +48,10 @@ export class InsertImageFromWorkspace implements Command { canSelectFolders: false, canSelectMany: true, filters: { - [localize('insertImage.imagesLabel', "Images")]: Array.from(imageFileExtensions) + [vscode.l10n.t("Images")]: Array.from(imageFileExtensions) }, - openLabel: localize('insertImage.openLabel', "Insert image"), - title: localize('insertImage.title', "Insert image"), + openLabel: vscode.l10n.t("Insert image"), + title: vscode.l10n.t("Insert image"), defaultUri: getDefaultUri(activeEditor.document), }); diff --git a/extensions/markdown-language-features/src/languageFeatures/diagnostics.ts b/extensions/markdown-language-features/src/languageFeatures/diagnostics.ts index b43a11f97841b..f54c136ad1a44 100644 --- a/extensions/markdown-language-features/src/languageFeatures/diagnostics.ts +++ b/extensions/markdown-language-features/src/languageFeatures/diagnostics.ts @@ -4,10 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import * as nls from 'vscode-nls'; import { CommandManager } from '../commandManager'; -const localize = nls.loadMessageBundle(); // Copied from markdown language service export enum DiagnosticCode { @@ -55,7 +53,7 @@ class AddToIgnoreLinksQuickFixProvider implements vscode.CodeActionProvider { const hrefText = (diagnostic as any).data?.hrefText; if (hrefText) { const fix = new vscode.CodeAction( - localize('ignoreLinksQuickFix.title', "Exclude '{0}' from link validation.", hrefText), + vscode.l10n.t("Exclude '{0}' from link validation.", hrefText), vscode.CodeActionKind.QuickFix); fix.command = { diff --git a/extensions/markdown-language-features/src/languageFeatures/fileReferences.ts b/extensions/markdown-language-features/src/languageFeatures/fileReferences.ts index 83f44c8837f0f..2f2af15df0871 100644 --- a/extensions/markdown-language-features/src/languageFeatures/fileReferences.ts +++ b/extensions/markdown-language-features/src/languageFeatures/fileReferences.ts @@ -5,12 +5,9 @@ import * as vscode from 'vscode'; import type * as lsp from 'vscode-languageserver-types'; -import * as nls from 'vscode-nls'; import { MdLanguageClient } from '../client/client'; import { Command, CommandManager } from '../commandManager'; -const localize = nls.loadMessageBundle(); - export class FindFileReferencesCommand implements Command { @@ -23,13 +20,13 @@ export class FindFileReferencesCommand implements Command { public async execute(resource?: vscode.Uri) { resource ??= vscode.window.activeTextEditor?.document.uri; if (!resource) { - vscode.window.showErrorMessage(localize('error.noResource', "Find file references failed. No resource provided.")); + vscode.window.showErrorMessage(vscode.l10n.t("Find file references failed. No resource provided.")); return; } await vscode.window.withProgress({ location: vscode.ProgressLocation.Window, - title: localize('progress.title', "Finding file references") + title: vscode.l10n.t("Finding file references") }, async (_progress, token) => { const locations = (await this._client.getReferencesToFileInWorkspace(resource!, token)).map(loc => { return new vscode.Location(vscode.Uri.parse(loc.uri), convertRange(loc.range)); diff --git a/extensions/markdown-language-features/src/languageFeatures/linkUpdater.ts b/extensions/markdown-language-features/src/languageFeatures/linkUpdater.ts index ae59e77af3327..5d2cf053eb4c7 100644 --- a/extensions/markdown-language-features/src/languageFeatures/linkUpdater.ts +++ b/extensions/markdown-language-features/src/languageFeatures/linkUpdater.ts @@ -7,14 +7,12 @@ import * as path from 'path'; import * as picomatch from 'picomatch'; import * as vscode from 'vscode'; import { TextDocumentEdit } from 'vscode-languageclient'; -import * as nls from 'vscode-nls'; import { MdLanguageClient } from '../client/client'; import { Delayer } from '../util/async'; import { noopToken } from '../util/cancellation'; import { Disposable } from '../util/dispose'; import { convertRange } from './fileReferences'; -const localize = nls.loadMessageBundle(); const settingNames = Object.freeze({ enabled: 'updateLinksOnFileMove.enabled', @@ -54,7 +52,7 @@ class UpdateLinksOnFileRenameHandler extends Disposable { this._delayer.trigger(() => { vscode.window.withProgress({ location: vscode.ProgressLocation.Window, - title: localize('renameProgress.title', "Checking for Markdown links to update") + title: vscode.l10n.t("Checking for Markdown links to update") }, () => this._flushRenames()); }); } @@ -121,26 +119,26 @@ class UpdateLinksOnFileRenameHandler extends Disposable { } const rejectItem: vscode.MessageItem = { - title: localize('reject.title', "No"), + title: vscode.l10n.t("No"), isCloseAffordance: true, }; const acceptItem: vscode.MessageItem = { - title: localize('accept.title', "Yes"), + title: vscode.l10n.t("Yes"), }; const alwaysItem: vscode.MessageItem = { - title: localize('always.title', "Always"), + title: vscode.l10n.t("Always"), }; const neverItem: vscode.MessageItem = { - title: localize('never.title', "Never"), + title: vscode.l10n.t("Never"), }; const choice = await vscode.window.showInformationMessage( newResources.length === 1 - ? localize('prompt', "Update Markdown links for '{0}'?", path.basename(newResources[0].fsPath)) - : this._getConfirmMessage(localize('promptMoreThanOne', "Update Markdown links for the following {0} files?", newResources.length), newResources), { + ? vscode.l10n.t("Update Markdown links for '{0}'?", path.basename(newResources[0].fsPath)) + : this._getConfirmMessage(vscode.l10n.t("Update Markdown links for the following {0} files?", newResources.length), newResources), { modal: true, }, rejectItem, acceptItem, alwaysItem, neverItem); @@ -203,9 +201,9 @@ class UpdateLinksOnFileRenameHandler extends Disposable { if (resourcesToConfirm.length > MAX_CONFIRM_FILES) { if (resourcesToConfirm.length - MAX_CONFIRM_FILES === 1) { - paths.push(localize('moreFile', "...1 additional file not shown")); + paths.push(vscode.l10n.t("...1 additional file not shown")); } else { - paths.push(localize('moreFiles', "...{0} additional files not shown", resourcesToConfirm.length - MAX_CONFIRM_FILES)); + paths.push(vscode.l10n.t("...{0} additional files not shown", resourcesToConfirm.length - MAX_CONFIRM_FILES)); } } diff --git a/extensions/markdown-language-features/src/preview/documentRenderer.ts b/extensions/markdown-language-features/src/preview/documentRenderer.ts index d20dbeb203c31..e7b965aa8e451 100644 --- a/extensions/markdown-language-features/src/preview/documentRenderer.ts +++ b/extensions/markdown-language-features/src/preview/documentRenderer.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import * as nls from 'vscode-nls'; import * as uri from 'vscode-uri'; import { ILogger } from '../logging'; import { MarkdownItEngine } from '../markdownEngine'; @@ -14,7 +13,6 @@ import { WebviewResourceProvider } from '../util/resources'; import { MarkdownPreviewConfiguration, MarkdownPreviewConfigurationManager } from './previewConfig'; import { ContentSecurityPolicyArbiter, MarkdownPreviewSecurityLevel } from './security'; -const localize = nls.loadMessageBundle(); /** * Strings used inside the markdown preview. @@ -23,17 +21,11 @@ const localize = nls.loadMessageBundle(); * can be localized using our normal localization process. */ const previewStrings = { - cspAlertMessageText: localize( - 'preview.securityMessage.text', - 'Some content has been disabled in this document'), + cspAlertMessageText: vscode.l10n.t("Some content has been disabled in this document"), - cspAlertMessageTitle: localize( - 'preview.securityMessage.title', - 'Potentially unsafe or insecure content has been disabled in the Markdown preview. Change the Markdown preview security setting to allow insecure content or enable scripts'), + cspAlertMessageTitle: vscode.l10n.t("Potentially unsafe or insecure content has been disabled in the Markdown preview. Change the Markdown preview security setting to allow insecure content or enable scripts"), - cspAlertMessageLabel: localize( - 'preview.securityMessage.label', - 'Content Disabled Security Warning') + cspAlertMessageLabel: vscode.l10n.t("Content Disabled Security Warning") }; export interface MarkdownContentProviderOutput { @@ -130,7 +122,7 @@ export class MdDocumentRenderer { public renderFileNotFoundDocument(resource: vscode.Uri): string { const resourcePath = uri.Utils.basename(resource); - const body = localize('preview.notFound', '{0} cannot be found', resourcePath); + const body = vscode.l10n.t('{0} cannot be found', resourcePath); return ` diff --git a/extensions/markdown-language-features/src/preview/preview.ts b/extensions/markdown-language-features/src/preview/preview.ts index 24cdc05943fa9..3d04c6db3095f 100644 --- a/extensions/markdown-language-features/src/preview/preview.ts +++ b/extensions/markdown-language-features/src/preview/preview.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import * as nls from 'vscode-nls'; import * as uri from 'vscode-uri'; import { ILogger } from '../logging'; import { MarkdownContributionProvider } from '../markdownExtensions'; @@ -18,7 +17,6 @@ import { MarkdownPreviewConfigurationManager } from './previewConfig'; import { scrollEditorToLine, StartingScrollFragment, StartingScrollLine, StartingScrollLocation } from './scrolling'; import { getVisibleLine, LastScrollLocation, TopmostLineMonitor } from './topmostLineMonitor'; -const localize = nls.loadMessageBundle(); interface WebviewMessage { readonly source: string; @@ -192,9 +190,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider { case 'previewStyleLoadError': vscode.window.showWarningMessage( - localize('onPreviewStyleLoadError', - "Could not load 'markdown.styles': {0}", - e.body.unloadedStyles.join(', '))); + vscode.l10n.t("Could not load 'markdown.styles': {0}", e.body.unloadedStyles.join(', '))); break; } })); @@ -372,7 +368,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider { .then((editor) => { revealLineInEditor(editor); }, () => { - vscode.window.showErrorMessage(localize('preview.clickOpenFailed', 'Could not open {0}', this._resource.toString())); + vscode.window.showErrorMessage(vscode.l10n.t('Could not open {0}', this._resource.toString())); }); } @@ -773,8 +769,8 @@ export class DynamicMarkdownPreview extends Disposable implements IManagedMarkdo private static _getPreviewTitle(resource: vscode.Uri, locked: boolean): string { const resourceLabel = uri.Utils.basename(resource); return locked - ? localize('lockedPreviewTitle', '[Preview] {0}', resourceLabel) - : localize('previewTitle', 'Preview {0}', resourceLabel); + ? vscode.l10n.t('[Preview] {0}', resourceLabel) + : vscode.l10n.t('Preview {0}', resourceLabel); } public get position(): vscode.ViewColumn | undefined { diff --git a/extensions/markdown-language-features/src/preview/previewManager.ts b/extensions/markdown-language-features/src/preview/previewManager.ts index 89873110eb10d..dc4d311a96d26 100644 --- a/extensions/markdown-language-features/src/preview/previewManager.ts +++ b/extensions/markdown-language-features/src/preview/previewManager.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import * as nls from 'vscode-nls'; import { ILogger } from '../logging'; import { MarkdownContributionProvider } from '../markdownExtensions'; import { Disposable, disposeAll } from '../util/dispose'; @@ -16,8 +15,6 @@ import { MarkdownPreviewConfigurationManager } from './previewConfig'; import { scrollEditorToLine, StartingScrollFragment } from './scrolling'; import { TopmostLineMonitor } from './topmostLineMonitor'; -const localize = nls.loadMessageBundle(); - export interface DynamicPreviewSettings { readonly resourceColumn: vscode.ViewColumn; @@ -216,7 +213,7 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview -

${localize('preview.restoreError', "An unexpected error occurred while restoring the Markdown preview.")}

+

${vscode.l10n.t("An unexpected error occurred while restoring the Markdown preview.")}

`; } diff --git a/extensions/markdown-language-features/src/preview/security.ts b/extensions/markdown-language-features/src/preview/security.ts index 539ec55bc4091..0ba1a9f61f087 100644 --- a/extensions/markdown-language-features/src/preview/security.ts +++ b/extensions/markdown-language-features/src/preview/security.ts @@ -4,13 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import * as nls from 'vscode-nls'; import { MarkdownPreviewManager } from './previewManager'; - -const localize = nls.loadMessageBundle(); - export const enum MarkdownPreviewSecurityLevel { Strict = 0, AllowInsecureContent = 1, @@ -108,35 +104,33 @@ export class PreviewSecuritySelector { [ { type: MarkdownPreviewSecurityLevel.Strict, - label: markActiveWhen(currentSecurityLevel === MarkdownPreviewSecurityLevel.Strict) + localize('strict.title', 'Strict'), - description: localize('strict.description', 'Only load secure content'), + label: markActiveWhen(currentSecurityLevel === MarkdownPreviewSecurityLevel.Strict) + vscode.l10n.t("Strict"), + description: vscode.l10n.t("Only load secure content"), }, { type: MarkdownPreviewSecurityLevel.AllowInsecureLocalContent, - label: markActiveWhen(currentSecurityLevel === MarkdownPreviewSecurityLevel.AllowInsecureLocalContent) + localize('insecureLocalContent.title', 'Allow insecure local content'), - description: localize('insecureLocalContent.description', 'Enable loading content over http served from localhost'), + label: markActiveWhen(currentSecurityLevel === MarkdownPreviewSecurityLevel.AllowInsecureLocalContent) + vscode.l10n.t("Allow insecure local content"), + description: vscode.l10n.t("Enable loading content over http served from localhost"), }, { type: MarkdownPreviewSecurityLevel.AllowInsecureContent, - label: markActiveWhen(currentSecurityLevel === MarkdownPreviewSecurityLevel.AllowInsecureContent) + localize('insecureContent.title', 'Allow insecure content'), - description: localize('insecureContent.description', 'Enable loading content over http'), + label: markActiveWhen(currentSecurityLevel === MarkdownPreviewSecurityLevel.AllowInsecureContent) + vscode.l10n.t("Allow insecure content"), + description: vscode.l10n.t("Enable loading content over http"), }, { type: MarkdownPreviewSecurityLevel.AllowScriptsAndAllContent, - label: markActiveWhen(currentSecurityLevel === MarkdownPreviewSecurityLevel.AllowScriptsAndAllContent) + localize('disable.title', 'Disable'), - description: localize('disable.description', 'Allow all content and script execution. Not recommended'), + label: markActiveWhen(currentSecurityLevel === MarkdownPreviewSecurityLevel.AllowScriptsAndAllContent) + vscode.l10n.t("Disable"), + description: vscode.l10n.t("Allow all content and script execution. Not recommended"), }, { type: 'moreinfo', - label: localize('moreInfo.title', 'More Information'), + label: vscode.l10n.t("More Information"), description: '' }, { type: 'toggle', label: this._cspArbiter.shouldDisableSecurityWarnings() - ? localize('enableSecurityWarning.title', "Enable preview security warnings in this workspace") - : localize('disableSecurityWarning.title', "Disable preview security warning in this workspace"), - description: localize('toggleSecurityWarning.description', 'Does not affect the content security level') + ? vscode.l10n.t("Enable preview security warnings in this workspace") + : vscode.l10n.t("Disable preview security warning in this workspace"), + description: vscode.l10n.t("Does not affect the content security level") }, ], { - placeHolder: localize( - 'preview.showPreviewSecuritySelector.title', - 'Select security settings for Markdown previews in this workspace'), + placeHolder: vscode.l10n.t("Select security settings for Markdown previews in this workspace"), }); if (!selection) { return; diff --git a/extensions/markdown-language-features/yarn.lock b/extensions/markdown-language-features/yarn.lock index 6bd778ed89968..33734b3ac3eb2 100644 --- a/extensions/markdown-language-features/yarn.lock +++ b/extensions/markdown-language-features/yarn.lock @@ -258,11 +258,6 @@ vscode-nls@^5.0.1: resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.0.1.tgz#ba23fc4d4420d25e7f886c8e83cbdcec47aa48b2" integrity sha512-hHQV6iig+M21lTdItKPkJAaWrxALQb/nqpVffakO4knJOh3DrU2SXOMzUzNgo1eADPzu3qSsJY1weCzvR52q9A== -vscode-nls@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.2.0.tgz#3cb6893dd9bd695244d8a024bdf746eea665cc3f" - integrity sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng== - vscode-uri@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.3.tgz#a95c1ce2e6f41b7549f86279d19f47951e4f4d84"