Skip to content

Commit 65a5d42

Browse files
committed
refactor: dispose after webview is closed
1 parent 4ed2ac8 commit 65a5d42

File tree

2 files changed

+39
-29
lines changed

2 files changed

+39
-29
lines changed

src/app.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ const vscode = acquireVsCodeApi();
1212
let firstTime = true;
1313
let root: INode | undefined;
1414
let style: HTMLStyleElement;
15-
let activeEl: Element | undefined;
15+
let active: {
16+
node: INode;
17+
el: Element;
18+
} | undefined;
1619

1720
const handlers = {
1821
async setData(data: { root?: INode; jsonOptions?: IMarkmapJSONOptions }) {
@@ -23,8 +26,8 @@ const handlers = {
2326
}
2427
},
2528
setCursor(line: number) {
26-
const active = root && findActiveNode(line);
27-
if (active) highlightNode(active);
29+
const node = root && findActiveNode(line);
30+
if (node) highlightNode(node);
2831
},
2932
setCSS(data: string) {
3033
if (!style) {
@@ -40,6 +43,10 @@ const handlers = {
4043
const content = new XMLSerializer().serializeToString(mm.svg.node());
4144
vscode.postMessage({ type: 'downloadSvg', data: { content, path } });
4245
},
46+
toggleNode(recursive: boolean) {
47+
if (!active) return;
48+
mm.toggleNode(active.node, recursive);
49+
},
4350
};
4451
window.addEventListener('message', (e) => {
4552
const { type, data } = e.data;
@@ -139,14 +146,15 @@ function highlightNode(node: INode) {
139146
bottom: 80,
140147
});
141148
const g = mm.findElement(node)?.g;
142-
activeEl = g?.querySelector('foreignObject');
149+
const el = g?.querySelector('foreignObject');
150+
active = el && { el, node };
143151
}
144152

145153
function checkHighlight() {
146-
if (!activeEl) {
154+
if (!active) {
147155
highlightEl.remove();
148156
} else {
149-
const rect = activeEl.getBoundingClientRect();
157+
const rect = active.el.getBoundingClientRect();
150158
highlightEl.setAttribute(
151159
'style',
152160
`--mm-highlight-x:${rect.x}px;--mm-highlight-y:${rect.y}px;--mm-highlight-width:${rect.width}px;--mm-highlight-height:${rect.height}px`,

src/extension.ts

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { JSItem, type CSSItem } from 'markmap-common';
33
import { fillTemplate } from 'markmap-render';
44
import { defaultOptions, type IMarkmapJSONOptions } from 'markmap-view';
55
import {
6-
CancellationToken,
76
ColorThemeKind,
87
CustomTextEditorProvider,
98
ExtensionContext,
@@ -61,11 +60,7 @@ class MarkmapEditor implements CustomTextEditorProvider {
6160
return data;
6261
}
6362

64-
public async resolveCustomTextEditor(
65-
document: TextDocument,
66-
webviewPanel: WebviewPanel,
67-
token: CancellationToken,
68-
): Promise<void> {
63+
resolveCustomTextEditor(document: TextDocument, webviewPanel: WebviewPanel) {
6964
webviewPanel.webview.options = {
7065
enableScripts: true,
7166
};
@@ -290,30 +285,38 @@ class MarkmapEditor implements CustomTextEditorProvider {
290285
logger.appendLine(data);
291286
},
292287
};
293-
webviewPanel.webview.onDidReceiveMessage((e) => {
294-
const handler = messageHandlers[e.type];
295-
handler?.(e.data);
296-
});
297-
workspace.onDidChangeTextDocument((e) => {
298-
if (e.document !== document) return;
299-
debouncedUpdate();
300-
});
301-
vscodeWindow.onDidChangeTextEditorSelection((e) => {
302-
if (e.textEditor.document !== document) return;
303-
debouncedUpdateCursor();
304-
});
305-
vscodeWindow.onDidChangeActiveColorTheme(updateTheme);
288+
306289
updateOptions();
307290
updateCSS();
308291
updateTheme();
309-
workspace.onDidChangeConfiguration((e) => {
310-
if (e.affectsConfiguration('markmap.defaultOptions')) updateOptions();
311-
if (e.affectsConfiguration('markmap.customCSS')) updateCSS();
292+
293+
const disposables = [
294+
webviewPanel.webview.onDidReceiveMessage((e) => {
295+
const handler = messageHandlers[e.type];
296+
handler?.(e.data);
297+
}),
298+
workspace.onDidChangeTextDocument((e) => {
299+
if (e.document !== document) return;
300+
debouncedUpdate();
301+
}),
302+
vscodeWindow.onDidChangeTextEditorSelection((e) => {
303+
if (e.textEditor.document !== document) return;
304+
debouncedUpdateCursor();
305+
}),
306+
vscodeWindow.onDidChangeActiveColorTheme(updateTheme),
307+
workspace.onDidChangeConfiguration((e) => {
308+
if (e.affectsConfiguration('markmap.defaultOptions')) updateOptions();
309+
if (e.affectsConfiguration('markmap.customCSS')) updateCSS();
310+
}),
311+
];
312+
webviewPanel.onDidDispose(() => {
313+
disposables.forEach((disposable) => disposable.dispose());
312314
});
313315
}
314316
}
315317

316318
export function activate(context: ExtensionContext) {
319+
const markmapEditor = new MarkmapEditor(context);
317320
context.subscriptions.push(
318321
commands.registerCommand(`${PREFIX}.open`, (uri?: Uri) => {
319322
uri ??= vscodeWindow.activeTextEditor?.document.uri;
@@ -325,7 +328,6 @@ export function activate(context: ExtensionContext) {
325328
);
326329
}),
327330
);
328-
const markmapEditor = new MarkmapEditor(context);
329331
context.subscriptions.push(
330332
vscodeWindow.registerCustomEditorProvider(VIEW_TYPE, markmapEditor, {
331333
webviewOptions: { retainContextWhenHidden: true },

0 commit comments

Comments
 (0)