Reduce number of listeners we register for webviews

This commit is contained in:
Matt Bierner 2021-08-16 15:41:15 -07:00
parent 28a0006850
commit 2bd64d7164
No known key found for this signature in database
GPG key ID: 099C331567E11888

View file

@ -11,7 +11,7 @@ import { ThrottledDelayer } from 'vs/base/common/async';
import { streamToBuffer } from 'vs/base/common/buffer';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { Emitter } from 'vs/base/common/event';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { Schemas } from 'vs/base/common/network';
import { URI } from 'vs/base/common/uri';
import { localize } from 'vs/nls';
@ -117,6 +117,8 @@ export class IFrameWebview extends Disposable implements Webview {
private readonly _onDidHtmlChange: Emitter<string> = this._register(new Emitter<string>());
protected readonly onDidHtmlChange = this._onDidHtmlChange.event;
private readonly _messageHandlers = new Map<string, Set<(data: any) => void>>();
constructor(
public readonly id: string,
private readonly options: WebviewOptions,
@ -288,6 +290,13 @@ export class IFrameWebview extends Disposable implements Webview {
}
}));
this._register(addDisposableListener(window, 'message', e => {
if (e?.data?.target === this.id) {
const handlers = this._messageHandlers.get(e.data.channel);
handlers?.forEach(handler => handler(e.data.data));
}
}));
this.initElement(extension, options);
}
@ -413,13 +422,15 @@ export class IFrameWebview extends Disposable implements Webview {
}
protected on<T = unknown>(channel: WebviewMessageChannels, handler: (data: T) => void): IDisposable {
return addDisposableListener(window, 'message', e => {
if (!e || !e.data || e.data.target !== this.id) {
return;
}
if (e.data.channel === channel) {
handler(e.data.data);
}
let handlers = this._messageHandlers.get(channel);
if (!handlers) {
handlers = new Set();
this._messageHandlers.set(channel, handlers);
}
handlers.add(handler);
return toDisposable(() => {
this._messageHandlers.get(channel)?.delete(handler);
});
}