Use DisposableStore for htmlContentRenderer

This commit is contained in:
Matt Bierner 2019-06-10 16:15:45 -07:00
parent 1f4e2a21fc
commit d32ba26ae2
6 changed files with 33 additions and 18 deletions

View file

@ -9,7 +9,7 @@ import { escape } from 'vs/base/common/strings';
import { removeMarkdownEscapes, IMarkdownString } from 'vs/base/common/htmlContent';
import * as marked from 'vs/base/common/marked/marked';
import { IMouseEvent } from 'vs/base/browser/mouseEvent';
import { IDisposable } from 'vs/base/common/lifecycle';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { onUnexpectedError } from 'vs/base/common/errors';
import { URI } from 'vs/base/common/uri';
import { parse } from 'vs/base/common/marshalling';
@ -17,7 +17,7 @@ import { cloneAndChange } from 'vs/base/common/objects';
export interface IContentActionHandler {
callback: (content: string, event?: IMouseEvent) => void;
readonly disposeables: IDisposable[];
readonly disposeables: DisposableStore;
}
export interface RenderOptions {
@ -189,7 +189,7 @@ export function renderMarkdown(markdown: IMarkdownString, options: RenderOptions
}
if (options.actionHandler) {
options.actionHandler.disposeables.push(DOM.addStandardDisposableListener(element, 'click', event => {
options.actionHandler.disposeables.add(DOM.addStandardDisposableListener(element, 'click', event => {
let target: HTMLElement | null = event.target;
if (target.tagName !== 'A') {
target = target.parentElement;
@ -284,7 +284,7 @@ function _renderFormattedText(element: Node, treeNode: IFormatParseTree, actionH
else if (treeNode.type === FormatType.Action && actionHandler) {
const a = document.createElement('a');
a.href = '#';
actionHandler.disposeables.push(DOM.addStandardDisposableListener(a, 'click', (event) => {
actionHandler.disposeables.add(DOM.addStandardDisposableListener(a, 'click', (event) => {
actionHandler.callback(String(treeNode.index), event);
}));

View file

@ -5,8 +5,19 @@
import * as assert from 'assert';
import * as marked from 'vs/base/common/marked/marked';
import { renderMarkdown, renderText, renderFormattedText } from 'vs/base/browser/htmlContentRenderer';
import { DisposableStore } from 'vs/base/common/lifecycle';
suite('HtmlContent', () => {
const store = new DisposableStore();
setup(() => {
store.clear();
});
teardown(() => {
store.clear();
});
test('render simple element', () => {
let result: HTMLElement = renderText('testing');
@ -55,7 +66,7 @@ suite('HtmlContent', () => {
assert.strictEqual(content, '0');
callbackCalled = true;
},
disposeables: []
disposeables: store
}
});
assert.strictEqual(result.innerHTML, '<a href="#">action</a>');
@ -74,7 +85,7 @@ suite('HtmlContent', () => {
assert.strictEqual(content, '0');
callbackCalled = true;
},
disposeables: []
disposeables: store
}
});
assert.strictEqual(result.innerHTML, '<i><b><a href="#">action</a></b></i>');

View file

@ -13,7 +13,7 @@ import { tokenizeToString } from 'vs/editor/common/modes/textToHtmlTokenizer';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { optional } from 'vs/platform/instantiation/common/instantiation';
import { Event, Emitter } from 'vs/base/common/event';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { TokenizationRegistry } from 'vs/editor/common/modes';
export interface IMarkdownRenderResult extends IDisposable {
@ -32,7 +32,7 @@ export class MarkdownRenderer {
) {
}
private getOptions(disposeables: IDisposable[]): RenderOptions {
private getOptions(disposeables: DisposableStore): RenderOptions {
return {
codeBlockRenderer: (languageAlias, value) => {
// In markdown,
@ -78,7 +78,7 @@ export class MarkdownRenderer {
}
render(markdown: IMarkdownString | undefined): IMarkdownRenderResult {
const disposeables: IDisposable[] = [];
const disposeables = new DisposableStore();
let element: HTMLElement;
if (!markdown) {
@ -89,7 +89,7 @@ export class MarkdownRenderer {
return {
element,
dispose: () => dispose(disposeables)
dispose: () => disposeables.dispose()
};
}
}

View file

@ -5,7 +5,7 @@
import 'vs/css!./media/views';
import { Event, Emitter } from 'vs/base/common/event';
import { IDisposable, dispose, Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { IDisposable, dispose, Disposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IAction, IActionViewItem, ActionRunner, Action } from 'vs/base/common/actions';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
@ -888,7 +888,7 @@ class MarkdownRenderer {
) {
}
private getOptions(disposeables: IDisposable[]): RenderOptions {
private getOptions(disposeables: DisposableStore): RenderOptions {
return {
actionHandler: {
callback: (content) => {
@ -908,11 +908,11 @@ class MarkdownRenderer {
}
render(markdown: IMarkdownString): IMarkdownRenderResult {
let disposeables: IDisposable[] = [];
const disposeables = new DisposableStore();
const element: HTMLElement = markdown ? renderMarkdown(markdown, this.getOptions(disposeables)) : document.createElement('span');
return {
element,
dispose: () => dispose(disposeables)
dispose: () => disposeables.dispose()
};
}
}

View file

@ -7,7 +7,7 @@ import * as dom from 'vs/base/browser/dom';
import * as nls from 'vs/nls';
import { renderMarkdown } from 'vs/base/browser/htmlContentRenderer';
import { onUnexpectedError } from 'vs/base/common/errors';
import { IDisposable } from 'vs/base/common/lifecycle';
import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { IDataSource, IFilter, IRenderer as ITreeRenderer, ITree } from 'vs/base/parts/tree/browser/tree';
import { IOpenerService } from 'vs/platform/opener/common/opener';
@ -144,6 +144,8 @@ export class CommentsModelRenderer implements ITreeRenderer {
private renderCommentElement(tree: ITree, element: CommentNode, templateData: ICommentThreadTemplateData) {
templateData.userName.textContent = element.comment.userName;
templateData.commentText.innerHTML = '';
const disposables = new DisposableStore();
templateData.disposables.push(disposables);
const renderedComment = renderMarkdown(element.comment.body, {
inline: true,
actionHandler: {
@ -155,7 +157,7 @@ export class CommentsModelRenderer implements ITreeRenderer {
// ignore
}
},
disposeables: templateData.disposables
disposeables: disposables
}
});

View file

@ -403,7 +403,9 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre
template.descriptionElement.innerHTML = '';
if (element.setting.descriptionIsMarkdown) {
const renderedDescription = this.renderDescriptionMarkdown(element, element.description, template.toDispose);
const disposables = new DisposableStore();
template.toDispose.push(disposables);
const renderedDescription = this.renderDescriptionMarkdown(element, element.description, disposables);
template.descriptionElement.appendChild(renderedDescription);
} else {
template.descriptionElement.innerText = element.description;
@ -447,7 +449,7 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre
}
private renderDescriptionMarkdown(element: SettingsTreeSettingElement, text: string, disposeables: IDisposable[]): HTMLElement {
private renderDescriptionMarkdown(element: SettingsTreeSettingElement, text: string, disposeables: DisposableStore): HTMLElement {
// Rewrite `#editor.fontSize#` to link format
text = fixSettingLinks(text);