From 965f6bb992db153febb5d36c50b90532870f6dc4 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Thu, 10 Dec 2020 14:53:17 -0800 Subject: [PATCH 1/3] Fix support for IPyWidgets in Interactive Window --- news/2 Fixes/4203.md | 1 + .../ipywidgets/commonMessageCoordinator.ts | 42 ++++++++++--------- .../notebookIPyWidgetCoordinator.ts | 3 +- .../ipywidgets/webviewIPyWidgetCoordinator.ts | 3 +- 4 files changed, 27 insertions(+), 22 deletions(-) create mode 100644 news/2 Fixes/4203.md diff --git a/news/2 Fixes/4203.md b/news/2 Fixes/4203.md new file mode 100644 index 00000000000..e26fb070ef7 --- /dev/null +++ b/news/2 Fixes/4203.md @@ -0,0 +1 @@ +Fix support for IPyWidgets in Interactive Window. diff --git a/src/client/datascience/ipywidgets/commonMessageCoordinator.ts b/src/client/datascience/ipywidgets/commonMessageCoordinator.ts index be219677bfe..72e1f216dce 100644 --- a/src/client/datascience/ipywidgets/commonMessageCoordinator.ts +++ b/src/client/datascience/ipywidgets/commonMessageCoordinator.ts @@ -62,10 +62,8 @@ export class CommonMessageCoordinator { this.jupyterOutput = this.serviceContainer.get(IOutputChannel, JUPYTER_OUTPUT_CHANNEL); } - public static async create(identity: Uri, serviceContainer: IServiceContainer): Promise { - const result = new CommonMessageCoordinator(identity, serviceContainer); - await result.initialize(); - return result; + public static create(identity: Uri, serviceContainer: IServiceContainer): CommonMessageCoordinator { + return new CommonMessageCoordinator(identity, serviceContainer); } public dispose() { @@ -94,6 +92,19 @@ export class CommonMessageCoordinator { this.getIPyWidgetScriptSource()?.onMessage(message, payload); } + public async initialize() { + const dispatcher = this.getIPyWidgetMessageDispatcher(); + const promises = []; + if (dispatcher) { + promises.push(dispatcher.initialize()); + } + const scriptSource = this.getIPyWidgetScriptSource(); + if (scriptSource) { + promises.push(scriptSource.initialize()); + } + return Promise.all(promises); + } + private hash(s: string): string { return this.hashFn().update(s).digest('hex'); } @@ -164,6 +175,9 @@ export class CommonMessageCoordinator { this.ipyWidgetMessageDispatcher = this.serviceContainer .get(IPyWidgetMessageDispatcherFactory) .create(this.identity); + this.disposables.push( + this.ipyWidgetMessageDispatcher.postMessage(this.postEmitter.fire.bind(this.postEmitter)) + ); } return this.ipyWidgetMessageDispatcher; } @@ -183,23 +197,11 @@ export class CommonMessageCoordinator { this.serviceContainer.get(IPersistentStateFactory), this.serviceContainer.get(IExtensionContext) ); + this.disposables.push(this.ipyWidgetScriptSource.postMessage(this.postEmitter.fire.bind(this.postEmitter))); + this.disposables.push( + this.ipyWidgetScriptSource.postInternalMessage(this.postEmitter.fire.bind(this.postEmitter)) + ); } return this.ipyWidgetScriptSource; } - - private async initialize() { - const dispatcher = this.getIPyWidgetMessageDispatcher(); - const promises = []; - if (dispatcher) { - this.disposables.push(dispatcher.postMessage(this.postEmitter.fire.bind(this.postEmitter))); - promises.push(dispatcher.initialize()); - } - const scriptSource = this.getIPyWidgetScriptSource(); - if (scriptSource) { - this.disposables.push(scriptSource.postMessage(this.postEmitter.fire.bind(this.postEmitter))); - this.disposables.push(scriptSource.postInternalMessage(this.postEmitter.fire.bind(this.postEmitter))); - promises.push(scriptSource.initialize()); - } - return Promise.all(promises); - } } diff --git a/src/client/datascience/ipywidgets/notebookIPyWidgetCoordinator.ts b/src/client/datascience/ipywidgets/notebookIPyWidgetCoordinator.ts index 0ca348e0f49..1f2f4685349 100644 --- a/src/client/datascience/ipywidgets/notebookIPyWidgetCoordinator.ts +++ b/src/client/datascience/ipywidgets/notebookIPyWidgetCoordinator.ts @@ -38,7 +38,8 @@ export class NotebookIPyWidgetCoordinator implements INotebookKernelResolver { // entire VS code session, we have a map of notebook document to message coordinator let promise = this.messageCoordinators.get(document.uri.toString()); if (!promise) { - promise = CommonMessageCoordinator.create(document.uri, this.serviceContainer); + const coordinator = CommonMessageCoordinator.create(document.uri, this.serviceContainer); + const promise = coordinator.initialize().then(() => coordinator); this.messageCoordinators.set(document.uri.toString(), promise); } return Cancellation.race(() => promise!.then(this.attachCoordinator.bind(this, document, webview)), token); diff --git a/src/client/datascience/ipywidgets/webviewIPyWidgetCoordinator.ts b/src/client/datascience/ipywidgets/webviewIPyWidgetCoordinator.ts index 5889cf6af0b..9d0c6d8eb80 100644 --- a/src/client/datascience/ipywidgets/webviewIPyWidgetCoordinator.ts +++ b/src/client/datascience/ipywidgets/webviewIPyWidgetCoordinator.ts @@ -62,7 +62,7 @@ export class WebviewIPyWidgetCoordinator implements IInteractiveWindowListener { // There should be an instance of the WebviewMessageCoordinator per notebook webview or interactive window. Create // the message coordinator as soon as we're sure what notebook we're in. this.notebookIdentity = args.resource; - this.messageCoordinator = await CommonMessageCoordinator.create(this.notebookIdentity, this.serviceContainer); + this.messageCoordinator = CommonMessageCoordinator.create(this.notebookIdentity, this.serviceContainer); this.messageCoordinatorEvent = this.messageCoordinator.postMessage((e) => { // Special case a specific message. It must be posted to the internal class, not the webview if (e.message === InteractiveWindowMessages.ConvertUriForUseInWebViewRequest) { @@ -71,5 +71,6 @@ export class WebviewIPyWidgetCoordinator implements IInteractiveWindowListener { this.postEmitter.fire(e); } }); + this.messageCoordinator.initialize(); } } From ad96777a48b7b8761aae8d698456edde3f841882 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Thu, 10 Dec 2020 14:59:41 -0800 Subject: [PATCH 2/3] Fixes --- .../datascience/ipywidgets/notebookIPyWidgetCoordinator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/datascience/ipywidgets/notebookIPyWidgetCoordinator.ts b/src/client/datascience/ipywidgets/notebookIPyWidgetCoordinator.ts index 1f2f4685349..06068354500 100644 --- a/src/client/datascience/ipywidgets/notebookIPyWidgetCoordinator.ts +++ b/src/client/datascience/ipywidgets/notebookIPyWidgetCoordinator.ts @@ -39,7 +39,7 @@ export class NotebookIPyWidgetCoordinator implements INotebookKernelResolver { let promise = this.messageCoordinators.get(document.uri.toString()); if (!promise) { const coordinator = CommonMessageCoordinator.create(document.uri, this.serviceContainer); - const promise = coordinator.initialize().then(() => coordinator); + promise = coordinator.initialize().then(() => coordinator); this.messageCoordinators.set(document.uri.toString(), promise); } return Cancellation.race(() => promise!.then(this.attachCoordinator.bind(this, document, webview)), token); From 3edf91e77017a96b7a64257c65f5811abfe11eb1 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Thu, 10 Dec 2020 15:05:15 -0800 Subject: [PATCH 3/3] Fixes --- .../datascience/ipywidgets/webviewIPyWidgetCoordinator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/datascience/ipywidgets/webviewIPyWidgetCoordinator.ts b/src/client/datascience/ipywidgets/webviewIPyWidgetCoordinator.ts index 9d0c6d8eb80..3a6ad2d8505 100644 --- a/src/client/datascience/ipywidgets/webviewIPyWidgetCoordinator.ts +++ b/src/client/datascience/ipywidgets/webviewIPyWidgetCoordinator.ts @@ -71,6 +71,6 @@ export class WebviewIPyWidgetCoordinator implements IInteractiveWindowListener { this.postEmitter.fire(e); } }); - this.messageCoordinator.initialize(); + return this.messageCoordinator.initialize(); } }