diff --git a/packages/preferences/src/browser/views/components/preference-markdown-renderer.ts b/packages/preferences/src/browser/views/components/preference-markdown-renderer.ts
new file mode 100644
index 0000000000000..231524e99a504
--- /dev/null
+++ b/packages/preferences/src/browser/views/components/preference-markdown-renderer.ts
@@ -0,0 +1,68 @@
+// *****************************************************************************
+// Copyright (C) 2023 TypeFox and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// http://www.eclipse.org/legal/epl-2.0.
+//
+// This Source Code may also be made available under the following Secondary
+// Licenses when the conditions for such availability set forth in the Eclipse
+// Public License v. 2.0 are satisfied: GNU General Public License, version 2
+// with the GNU Classpath Exception which is available at
+// https://www.gnu.org/software/classpath/license.html.
+//
+// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
+// *****************************************************************************
+
+import { inject, injectable } from '@theia/core/shared/inversify';
+import { PreferenceTreeModel } from '../../preference-tree-model';
+import { PreferenceTreeLabelProvider } from '../../util/preference-tree-label-provider';
+import * as markdownit from '@theia/core/shared/markdown-it';
+
+@injectable()
+export class PreferenceMarkdownRenderer {
+
+ @inject(PreferenceTreeModel) protected readonly model: PreferenceTreeModel;
+ @inject(PreferenceTreeLabelProvider) protected readonly labelProvider: PreferenceTreeLabelProvider;
+
+ protected _renderer?: markdownit;
+
+ render(text: string): string {
+ return this.getRenderer().render(text);
+ }
+
+ renderInline(text: string): string {
+ return this.getRenderer().renderInline(text);
+ }
+
+ protected getRenderer(): markdownit {
+ this._renderer ??= this.buildMarkdownRenderer();
+ return this._renderer;
+ }
+
+ protected buildMarkdownRenderer(): markdownit {
+ const engine = markdownit();
+ const inlineCode = engine.renderer.rules.code_inline;
+
+ engine.renderer.rules.code_inline = (tokens, idx, options, env, self) => {
+ const token = tokens[idx];
+ const content = token.content;
+ if (content.startsWith('#') && content.endsWith('#')) {
+ const preferenceId = content.substring(1, content.length - 1);
+ const preferenceNode = this.model.getNodeFromPreferenceId(preferenceId);
+ if (preferenceNode) {
+ let name = this.labelProvider.getName(preferenceNode);
+ const prefix = this.labelProvider.getPrefix(preferenceNode, true);
+ if (prefix) {
+ name = prefix + name;
+ }
+ return `${name}`;
+ } else {
+ console.warn(`Linked preference "${preferenceId}" not found.`);
+ }
+ }
+ return inlineCode ? inlineCode(tokens, idx, options, env, self) : '';
+ };
+ return engine;
+ }
+}
diff --git a/packages/preferences/src/browser/views/components/preference-node-renderer.ts b/packages/preferences/src/browser/views/components/preference-node-renderer.ts
index b034b8a477955..35fff31db55ef 100644
--- a/packages/preferences/src/browser/views/components/preference-node-renderer.ts
+++ b/packages/preferences/src/browser/views/components/preference-node-renderer.ts
@@ -27,9 +27,9 @@ import { JSONValue } from '@theia/core/shared/@phosphor/coreutils';
import debounce = require('@theia/core/shared/lodash.debounce');
import { PreferenceTreeModel } from '../../preference-tree-model';
import { PreferencesSearchbarWidget } from '../preference-searchbar-widget';
-import * as markdownit from '@theia/core/shared/markdown-it';
import * as DOMPurify from '@theia/core/shared/dompurify';
import URI from '@theia/core/lib/common/uri';
+import { PreferenceMarkdownRenderer } from './preference-markdown-renderer';
export const PreferenceNodeRendererFactory = Symbol('PreferenceNodeRendererFactory');
export type PreferenceNodeRendererFactory = (node: Preference.TreeNode) => PreferenceNodeRenderer;
@@ -163,13 +163,13 @@ export abstract class PreferenceLeafNodeRenderer | undefined;
protected isModifiedFromDefault = false;
- protected markdownRenderer: markdownit;
get schema(): PreferenceDataProperty {
return this.preferenceNode.preference.data;
@@ -179,7 +179,6 @@ export abstract class PreferenceLeafNodeRenderer(this.id, this.scopeTracker.currentScope.uri);
}
- protected buildMarkdownRenderer(): markdownit {
- const engine = markdownit();
- const inlineCode = engine.renderer.rules.code_inline;
-
- engine.renderer.rules.code_inline = (tokens, idx, options, env, self) => {
- const token = tokens[idx];
- const content = token.content;
- if (content.startsWith('#') && content.endsWith('#')) {
- const preferenceId = content.substring(1, content.length - 1);
- const preferenceNode = this.model.getNodeFromPreferenceId(preferenceId);
- if (preferenceNode) {
- let name = this.labelProvider.getName(preferenceNode);
- const prefix = this.labelProvider.getPrefix(preferenceNode, true);
- if (prefix) {
- name = prefix + name;
- }
- return `${name}`;
- } else {
- console.warn(`Linked preference "${preferenceId}" not found. Source: "${this.preferenceNode.preferenceId}"`);
- }
- }
- return inlineCode ? inlineCode(tokens, idx, options, env, self) : '';
- };
- return engine;
- }
-
protected openLink(event: MouseEvent): void {
if (event.target instanceof HTMLAnchorElement) {
event.preventDefault();
diff --git a/packages/preferences/src/browser/views/preference-widget-bindings.ts b/packages/preferences/src/browser/views/preference-widget-bindings.ts
index a2369163124e4..926893f74ad96 100644
--- a/packages/preferences/src/browser/views/preference-widget-bindings.ts
+++ b/packages/preferences/src/browser/views/preference-widget-bindings.ts
@@ -30,6 +30,7 @@ import {
import { PreferenceNumberInputRenderer, PreferenceNumberInputRendererContribution } from './components/preference-number-input';
import { PreferenceSelectInputRenderer, PreferenceSelectInputRendererContribution } from './components/preference-select-input';
import { PreferenceStringInputRenderer, PreferenceStringInputRendererContribution } from './components/preference-string-input';
+import { PreferenceMarkdownRenderer } from './components/preference-markdown-renderer';
import { PreferencesEditorWidget } from './preference-editor-widget';
import { PreferencesScopeTabBar } from './preference-scope-tabbar-widget';
import { PreferencesSearchbarWidget } from './preference-searchbar-widget';
@@ -95,5 +96,7 @@ export function createPreferencesWidgetContainer(parent: interfaces.Container):
return creator.createRenderer(node, container);
});
+ child.bind(PreferenceMarkdownRenderer).toSelf().inSingletonScope();
+
return child;
}