diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 0fcaa4e05f2..f6c9685fcb5 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -2107,6 +2107,18 @@ declare module 'vscode' { //#region @connor4312 - notebook messaging: https://github.com/microsoft/vscode/issues/123601 + export interface NotebookRendererMessage { + /** + * Editor that sent the message. + */ + editor: NotebookEditor; + + /** + * Message sent from the webview. + */ + message: T; + } + /** * Renderer messaging is used to communicate with a single renderer. It's * returned from {@link notebook.createRendererMessaging}. @@ -2115,18 +2127,14 @@ declare module 'vscode' { /** * Events that fires when a message is received from a renderer. */ - messageHandler?: (editor: NotebookEditor, message: TReceive) => void; + onDidReceiveMessage: Event>; /** * Sends a message to the renderer. + * @param editor Editor to target with the message * @param message Message to send */ - postMessage(message: TSend): void; - - /** - * Disposes of the messaging instance and unsubscribes from messages. - */ - dispose(): void; + postMessage(editor: NotebookEditor, message: TSend): void; } export namespace notebook { diff --git a/src/vs/workbench/api/browser/mainThreadNotebookRenderers.ts b/src/vs/workbench/api/browser/mainThreadNotebookRenderers.ts index 0883f85bc29..5adf89ce7a7 100644 --- a/src/vs/workbench/api/browser/mainThreadNotebookRenderers.ts +++ b/src/vs/workbench/api/browser/mainThreadNotebookRenderers.ts @@ -23,7 +23,7 @@ export class MainThreadNotebookRenderers extends Disposable implements MainThrea })); } - $postMessage(rendererId: string, message: unknown): void { - this.messaging.fireDidReceiveMessage(rendererId, message); + $postMessage(editorId: string, rendererId: string, message: unknown): void { + this.messaging.fireDidReceiveMessage(editorId, rendererId, message); } } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index e9473957ba6..56ab5feffc4 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -915,7 +915,7 @@ export interface MainThreadNotebookKernelsShape extends IDisposable { } export interface MainThreadNotebookRenderersShape extends IDisposable { - $postMessage(rendererId: string, message: unknown): void; + $postMessage(editorId: string, rendererId: string, message: unknown): void; } export interface MainThreadUrlsShape extends IDisposable { diff --git a/src/vs/workbench/api/common/extHostNotebookEditor.ts b/src/vs/workbench/api/common/extHostNotebookEditor.ts index 30f8c6d52e4..9804ba2be5b 100644 --- a/src/vs/workbench/api/common/extHostNotebookEditor.ts +++ b/src/vs/workbench/api/common/extHostNotebookEditor.ts @@ -73,6 +73,8 @@ class NotebookEditorCellEditBuilder implements vscode.NotebookEditorEdit { export class ExtHostNotebookEditor { + public static readonly apiEditorsToExtHost = new WeakMap(); + private _selections: vscode.NotebookRange[] = []; private _visibleRanges: vscode.NotebookRange[] = []; private _viewColumn?: vscode.ViewColumn; @@ -127,6 +129,8 @@ export class ExtHostNotebookEditor { return that.setDecorations(decorationType, range); } }; + + ExtHostNotebookEditor.apiEditorsToExtHost.set(this._editor, this); } return this._editor; } diff --git a/src/vs/workbench/api/common/extHostNotebookRenderers.ts b/src/vs/workbench/api/common/extHostNotebookRenderers.ts index 0d175f5c561..fcf5eb9cfd5 100644 --- a/src/vs/workbench/api/common/extHostNotebookRenderers.ts +++ b/src/vs/workbench/api/common/extHostNotebookRenderers.ts @@ -6,10 +6,11 @@ import { Emitter } from 'vs/base/common/event'; import { ExtHostNotebookRenderersShape, IMainContext, MainContext, MainThreadNotebookRenderersShape } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostNotebookController } from 'vs/workbench/api/common/extHostNotebook'; +import { ExtHostNotebookEditor } from 'vs/workbench/api/common/extHostNotebookEditor'; import * as vscode from 'vscode'; export class ExtHostNotebookRenderers implements ExtHostNotebookRenderersShape { - private readonly _rendererMessageEmitters = new Map>(); + private readonly _rendererMessageEmitters = new Map>>(); private readonly proxy: MainThreadNotebookRenderersShape; constructor(mainContext: IMainContext, private readonly _extHostNotebook: ExtHostNotebookController) { @@ -22,15 +23,21 @@ export class ExtHostNotebookRenderers implements ExtHostNotebookRenderersShape { return; } - this._rendererMessageEmitters.get(rendererId)?.fire({ document: editor.apiEditor, data: message }); + this._rendererMessageEmitters.get(rendererId)?.fire({ editor: editor.apiEditor, message }); } public createRendererMessaging(rendererId: string): vscode.NotebookRendererMessaging { - const emitter = this.getOrCreateEmitterFor(rendererId); - const listener = emitter.event(e => messaging.messageHandler?.(e.document, e.data)); const messaging: vscode.NotebookRendererMessaging = { - dispose: () => listener.dispose(), - postMessage: message => this.proxy.$postMessage(rendererId, message), + onDidReceiveMessage: (...args) => + this.getOrCreateEmitterFor(rendererId).event(...args), + postMessage: (editor, message) => { + const extHostEditor = ExtHostNotebookEditor.apiEditorsToExtHost.get(editor); + if (!extHostEditor) { + throw new Error(`The first argument to postMessage() must be a NotebookEditor`); + } + + this.proxy.$postMessage(extHostEditor.id, rendererId, message); + }, }; return messaging; diff --git a/src/vs/workbench/contrib/notebook/browser/notebookRendererMessagingServiceImpl.ts b/src/vs/workbench/contrib/notebook/browser/notebookRendererMessagingServiceImpl.ts index 6524ebb4224..0d816f42fb5 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookRendererMessagingServiceImpl.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookRendererMessagingServiceImpl.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Emitter } from 'vs/base/common/event'; +import { Emitter, Event } from 'vs/base/common/event'; import { INotebookRendererMessagingService, IScopedRendererMessaging } from 'vs/workbench/contrib/notebook/common/notebookRendererMessagingService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; @@ -16,7 +16,7 @@ export class NotebookRendererMessagingService implements INotebookRendererMessag * be sent once activation finishes, or undefined if activation is complete. */ private readonly activations = new Map(); - private readonly receiveMessageEmitter = new Emitter<{ rendererId: string, message: unknown }>(); + private readonly receiveMessageEmitter = new Emitter<{ editorId: string; rendererId: string, message: unknown }>(); public readonly onDidReceiveMessage = this.receiveMessageEmitter.event; private readonly postMessageEmitter = new Emitter(); public readonly onShouldPostMessage = this.postMessageEmitter.event; @@ -24,8 +24,8 @@ export class NotebookRendererMessagingService implements INotebookRendererMessag constructor(@IExtensionService private readonly extensionService: IExtensionService) { } /** @inheritdoc */ - public fireDidReceiveMessage(rendererId: string, message: unknown): void { - this.receiveMessageEmitter.fire({ rendererId, message }); + public fireDidReceiveMessage(editorId: string, rendererId: string, message: unknown): void { + this.receiveMessageEmitter.fire({ editorId, rendererId, message }); } /** @inheritdoc */ @@ -49,7 +49,7 @@ export class NotebookRendererMessagingService implements INotebookRendererMessag /** @inheritdoc */ public getScoped(editorId: string): IScopedRendererMessaging { return { - onDidReceiveMessage: this.onDidReceiveMessage, + onDidReceiveMessage: Event.filter(this.onDidReceiveMessage, e => e.editorId === editorId), postMessage: (rendererId, message) => this.postMessage(editorId, rendererId, message), }; } diff --git a/src/vs/workbench/contrib/notebook/common/notebookRendererMessagingService.ts b/src/vs/workbench/contrib/notebook/common/notebookRendererMessagingService.ts index 0f00b8f6af3..2264baa168f 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookRendererMessagingService.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookRendererMessagingService.ts @@ -28,7 +28,7 @@ export interface INotebookRendererMessagingService { /** * Called when the main thread gets a message for a renderer. */ - fireDidReceiveMessage(rendererId: string, message: unknown): void; + fireDidReceiveMessage(editorId: string, rendererId: string, message: unknown): void; } export interface IScopedRendererMessaging {