@@ -5,12 +5,13 @@ import { ISettingRegistry } from '@jupyterlab/settingregistry';
5
5
6
6
import * as nbformat from '@jupyterlab/nbformat' ;
7
7
8
- import { IConsoleTracker , CodeConsole } from '@jupyterlab/console' ;
9
-
10
- import { DocumentRegistry } from '@jupyterlab/docregistry' ;
8
+ import {
9
+ IConsoleTracker ,
10
+ CodeConsole ,
11
+ ConsolePanel ,
12
+ } from '@jupyterlab/console' ;
11
13
12
14
import {
13
- INotebookModel ,
14
15
INotebookTracker ,
15
16
Notebook ,
16
17
NotebookPanel ,
@@ -33,8 +34,6 @@ import { toArray, filter } from '@lumino/algorithm';
33
34
34
35
import { DisposableDelegate } from '@lumino/disposable' ;
35
36
36
- import { AttachedProperty } from '@lumino/properties' ;
37
-
38
37
import { WidgetRenderer } from './renderer' ;
39
38
40
39
import {
@@ -55,6 +54,7 @@ import '@jupyter-widgets/base/css/index.css';
55
54
import '@jupyter-widgets/controls/css/widgets-base.css' ;
56
55
import { KernelMessage } from '@jupyterlab/services' ;
57
56
import { ITranslator , nullTranslator } from '@jupyterlab/translation' ;
57
+ import { ISessionContext } from '@jupyterlab/apputils' ;
58
58
59
59
const WIDGET_REGISTRY : base . IWidgetRegistryData [ ] = [ ] ;
60
60
@@ -131,16 +131,69 @@ function* chain<T>(
131
131
}
132
132
}
133
133
134
- export function registerWidgetManager (
135
- context : DocumentRegistry . IContext < INotebookModel > ,
134
+ /**
135
+ * Get the kernel id of current notebook or console panel, this value
136
+ * is used as key for `Private.widgetManagerProperty` to store the widget
137
+ * manager of current notebook or console panel.
138
+ *
139
+ * @param {ISessionContext } sessionContext The session context of notebook or
140
+ * console panel.
141
+ */
142
+ async function getWidgetManagerOwner (
143
+ sessionContext : ISessionContext
144
+ ) : Promise < Private . IWidgetManagerOwner > {
145
+ await sessionContext . ready ;
146
+ return sessionContext . session ! . kernel ! . id ;
147
+ }
148
+
149
+ /**
150
+ * Common handler for registering both notebook and console
151
+ * `WidgetManager`
152
+ *
153
+ * @param {(Notebook | CodeConsole) } content Context of panel.
154
+ * @param {ISessionContext } sessionContext Session context of panel.
155
+ * @param {IRenderMimeRegistry } rendermime Rendermime of panel.
156
+ * @param {IterableIterator<WidgetRenderer> } renderers Iterator of
157
+ * `WidgetRenderer` inside panel
158
+ * @param {(() => WidgetManager | KernelWidgetManager) } widgetManagerFactory
159
+ * function to create widget manager.
160
+ */
161
+ async function registerWidgetHandler (
162
+ content : Notebook | CodeConsole ,
163
+ sessionContext : ISessionContext ,
136
164
rendermime : IRenderMimeRegistry ,
137
- renderers : IterableIterator < WidgetRenderer >
138
- ) : DisposableDelegate {
139
- let wManager = Private . widgetManagerProperty . get ( context ) ;
165
+ renderers : IterableIterator < WidgetRenderer > ,
166
+ widgetManagerFactory : ( ) => WidgetManager | KernelWidgetManager
167
+ ) : Promise < DisposableDelegate > {
168
+ const wManagerOwner = await getWidgetManagerOwner ( sessionContext ) ;
169
+ let wManager = Private . widgetManagerProperty . get ( wManagerOwner ) ;
170
+ let currentOwner : string ;
171
+
140
172
if ( ! wManager ) {
141
- wManager = new WidgetManager ( context , rendermime , SETTINGS ) ;
173
+ wManager = widgetManagerFactory ( ) ;
142
174
WIDGET_REGISTRY . forEach ( ( data ) => wManager ! . register ( data ) ) ;
143
- Private . widgetManagerProperty . set ( context , wManager ) ;
175
+ Private . widgetManagerProperty . set ( wManagerOwner , wManager ) ;
176
+ currentOwner = wManagerOwner ;
177
+ content . disposed . connect ( ( _ ) => {
178
+ const currentwManager = Private . widgetManagerProperty . get ( currentOwner ) ;
179
+ if ( currentwManager ) {
180
+ Private . widgetManagerProperty . delete ( currentOwner ) ;
181
+ }
182
+ } ) ;
183
+
184
+ sessionContext . kernelChanged . connect ( ( _ , args ) => {
185
+ const { newValue } = args ;
186
+ if ( newValue ) {
187
+ const newKernelId = newValue . id ;
188
+ const oldwManager = Private . widgetManagerProperty . get ( currentOwner ) ;
189
+
190
+ if ( oldwManager ) {
191
+ Private . widgetManagerProperty . delete ( currentOwner ) ;
192
+ Private . widgetManagerProperty . set ( newKernelId , oldwManager ) ;
193
+ }
194
+ currentOwner = newKernelId ;
195
+ }
196
+ } ) ;
144
197
}
145
198
146
199
for ( const r of renderers ) {
@@ -167,43 +220,43 @@ export function registerWidgetManager(
167
220
} ) ;
168
221
}
169
222
170
- export function registerConsoleWidgetManager (
171
- console : CodeConsole ,
172
- rendermime : IRenderMimeRegistry ,
223
+ export async function registerWidgetManager (
224
+ panel : NotebookPanel ,
173
225
renderers : IterableIterator < WidgetRenderer >
174
- ) : DisposableDelegate {
175
- let wManager = Private . widgetManagerProperty . get ( console ) ;
176
- if ( ! wManager ) {
177
- wManager = new KernelWidgetManager (
178
- console . sessionContext . session ?. kernel ! ,
179
- rendermime
180
- ) ;
181
- WIDGET_REGISTRY . forEach ( ( data ) => wManager ! . register ( data ) ) ;
182
- Private . widgetManagerProperty . set ( console , wManager ) ;
183
- }
184
-
185
- for ( const r of renderers ) {
186
- r . manager = wManager ;
187
- }
188
-
189
- // Replace the placeholder widget renderer with one bound to this widget
190
- // manager.
191
- rendermime . removeMimeType ( WIDGET_VIEW_MIMETYPE ) ;
192
- rendermime . addFactory (
193
- {
194
- safe : false ,
195
- mimeTypes : [ WIDGET_VIEW_MIMETYPE ] ,
196
- createRenderer : ( options ) => new WidgetRenderer ( options , wManager ) ,
197
- } ,
198
- 0
226
+ ) : Promise < DisposableDelegate > {
227
+ const content = panel . content ;
228
+ const context = panel . context ;
229
+ const sessionContext = context . sessionContext ;
230
+ const rendermime = content . rendermime ;
231
+ const widgetManagerFactory = ( ) =>
232
+ new WidgetManager ( context , rendermime , SETTINGS ) ;
233
+
234
+ return registerWidgetHandler (
235
+ content ,
236
+ sessionContext ,
237
+ rendermime ,
238
+ renderers ,
239
+ widgetManagerFactory
199
240
) ;
241
+ }
200
242
201
- return new DisposableDelegate ( ( ) => {
202
- if ( rendermime ) {
203
- rendermime . removeMimeType ( WIDGET_VIEW_MIMETYPE ) ;
204
- }
205
- wManager ! . dispose ( ) ;
206
- } ) ;
243
+ export async function registerConsoleWidgetManager (
244
+ panel : ConsolePanel ,
245
+ renderers : IterableIterator < WidgetRenderer >
246
+ ) : Promise < DisposableDelegate > {
247
+ const content = panel . console ;
248
+ const sessionContext = content . sessionContext ;
249
+ const rendermime = content . rendermime ;
250
+ const widgetManagerFactory = ( ) =>
251
+ new KernelWidgetManager ( sessionContext . session ! . kernel ! , rendermime ) ;
252
+
253
+ return registerWidgetHandler (
254
+ content ,
255
+ sessionContext ,
256
+ rendermime ,
257
+ renderers ,
258
+ widgetManagerFactory
259
+ ) ;
207
260
}
208
261
209
262
/**
@@ -247,12 +300,17 @@ function activateWidgetExtension(
247
300
const { commands } = app ;
248
301
const trans = ( translator ?? nullTranslator ) . load ( 'jupyterlab_widgets' ) ;
249
302
250
- const bindUnhandledIOPubMessageSignal = ( nb : NotebookPanel ) : void => {
303
+ const bindUnhandledIOPubMessageSignal = async (
304
+ nb : NotebookPanel
305
+ ) : Promise < void > => {
251
306
if ( ! loggerRegistry ) {
252
307
return ;
253
308
}
309
+ const wManagerOwner = await getWidgetManagerOwner (
310
+ nb . context . sessionContext
311
+ ) ;
312
+ const wManager = Private . widgetManagerProperty . get ( wManagerOwner ) ;
254
313
255
- const wManager = Private . widgetManagerProperty . get ( nb . context ) ;
256
314
if ( wManager ) {
257
315
wManager . onUnhandledIOPubMessage . connect (
258
316
(
@@ -300,48 +358,30 @@ function activateWidgetExtension(
300
358
) ;
301
359
302
360
if ( tracker !== null ) {
303
- tracker . forEach ( ( panel ) => {
304
- registerWidgetManager (
305
- panel . context ,
306
- panel . content . rendermime ,
307
- chain (
308
- notebookWidgetRenderers ( panel . content ) ,
309
- outputViews ( app , panel . context . path )
310
- )
361
+ const rendererIterator = ( panel : NotebookPanel ) =>
362
+ chain (
363
+ notebookWidgetRenderers ( panel . content ) ,
364
+ outputViews ( app , panel . context . path )
311
365
) ;
312
-
366
+ tracker . forEach ( async ( panel ) => {
367
+ await registerWidgetManager ( panel , rendererIterator ( panel ) ) ;
313
368
bindUnhandledIOPubMessageSignal ( panel ) ;
314
369
} ) ;
315
- tracker . widgetAdded . connect ( ( sender , panel ) => {
316
- registerWidgetManager (
317
- panel . context ,
318
- panel . content . rendermime ,
319
- chain (
320
- notebookWidgetRenderers ( panel . content ) ,
321
- outputViews ( app , panel . context . path )
322
- )
323
- ) ;
324
-
370
+ tracker . widgetAdded . connect ( async ( sender , panel ) => {
371
+ await registerWidgetManager ( panel , rendererIterator ( panel ) ) ;
325
372
bindUnhandledIOPubMessageSignal ( panel ) ;
326
373
} ) ;
327
374
}
328
375
329
376
if ( consoleTracker !== null ) {
377
+ const rendererIterator = ( panel : ConsolePanel ) =>
378
+ chain ( consoleWidgetRenderers ( panel . console ) ) ;
379
+
330
380
consoleTracker . forEach ( async ( panel ) => {
331
- await panel . sessionContext . ready ;
332
- registerConsoleWidgetManager (
333
- panel . console ,
334
- panel . console . rendermime ,
335
- chain ( consoleWidgetRenderers ( panel . console ) )
336
- ) ;
381
+ await registerConsoleWidgetManager ( panel , rendererIterator ( panel ) ) ;
337
382
} ) ;
338
383
consoleTracker . widgetAdded . connect ( async ( sender , panel ) => {
339
- await panel . sessionContext . ready ;
340
- registerConsoleWidgetManager (
341
- panel . console ,
342
- panel . console . rendermime ,
343
- chain ( consoleWidgetRenderers ( panel . console ) )
344
- ) ;
384
+ await registerConsoleWidgetManager ( panel , rendererIterator ( panel ) ) ;
345
385
} ) ;
346
386
}
347
387
if ( settingRegistry !== null ) {
@@ -415,14 +455,23 @@ function activateWidgetExtension(
415
455
416
456
namespace Private {
417
457
/**
418
- * A private attached property for a widget manager .
458
+ * A type alias for keys of `widgetManagerProperty` .
419
459
*/
420
- export const widgetManagerProperty = new AttachedProperty <
421
- DocumentRegistry . Context | CodeConsole ,
422
- WidgetManager | KernelWidgetManager | undefined
423
- > ( {
424
- name : 'widgetManager' ,
425
- create : ( owner : DocumentRegistry . Context | CodeConsole ) : undefined =>
426
- undefined ,
427
- } ) ;
460
+ export type IWidgetManagerOwner = string ;
461
+
462
+ /**
463
+ * A type alias for values of `widgetManagerProperty` .
464
+ */
465
+ export type IWidgetManagerValue =
466
+ | WidgetManager
467
+ | KernelWidgetManager
468
+ | undefined ;
469
+
470
+ /**
471
+ * A private map for a widget manager.
472
+ */
473
+ export const widgetManagerProperty = new Map <
474
+ IWidgetManagerOwner ,
475
+ IWidgetManagerValue
476
+ > ( ) ;
428
477
}
0 commit comments