@@ -76,8 +76,7 @@ class WidgetManagerComponent {
76
76
}
77
77
78
78
const outputDisposables = new Map < string , { dispose ( ) : void } > ( ) ;
79
- const htmlDisposables = new WeakMap < HTMLElement , { dispose ( ) : void } > ( ) ;
80
- const renderedWidgets = new Map < string , { widget ?: { dispose : Function } } > ( ) ;
79
+ const renderedWidgets = new Map < string , { container : HTMLElement ; widget ?: { dispose : Function } } > ( ) ;
81
80
/**
82
81
* Called from renderer to render output.
83
82
* This will be exposed as a public method on window for renderer to render output.
@@ -105,8 +104,6 @@ export function renderOutput(outputItem: OutputItem, element: HTMLElement, logge
105
104
}
106
105
export function disposeOutput ( outputId ?: string ) {
107
106
if ( outputId ) {
108
- logMessage ( `Disposing widget ${ outputId } ` ) ;
109
- renderedWidgets . get ( outputId ) ?. widget ?. dispose ( ) ;
110
107
// We can't delete the widgets because they may be rerendered when we scroll them into view.
111
108
// See issue: https://github.com/microsoft/vscode-jupyter/issues/10485
112
109
// However we can mark them as not being currently rendered.
@@ -129,9 +126,13 @@ function renderIPyWidget(
129
126
logger : ( message : string ) => void
130
127
) {
131
128
logger ( `Rendering IPyWidget ${ outputId } with model ${ model . model_id } ` ) ;
132
- if ( renderedWidgets . has ( outputId ) ) {
129
+ if ( renderedWidgets . has ( outputId ) && renderedWidgets . get ( outputId ) ?. container === container ) {
133
130
return logger ( 'already rendering' ) ;
134
131
}
132
+ if ( renderedWidgets . has ( outputId ) ) {
133
+ logger ( 'Widget was already rendering for another container, dispose that widget so we can re-render it' ) ;
134
+ renderedWidgets . get ( outputId ) ?. widget ?. dispose ( ) ;
135
+ }
135
136
const output = document . createElement ( 'div' ) ;
136
137
output . className = 'cell-output cell-output' ;
137
138
if ( typeof model . _vsc_test_cellIndex === 'number' ) {
@@ -141,9 +142,14 @@ function renderIPyWidget(
141
142
ele . className = 'cell-output-ipywidget-background' ;
142
143
container . appendChild ( ele ) ;
143
144
ele . appendChild ( output ) ;
144
- renderedWidgets . set ( outputId , { } ) ;
145
+ renderedWidgets . set ( outputId , { container } ) ;
145
146
createWidgetView ( model , ele )
146
147
. then ( ( w ) => {
148
+ if ( renderedWidgets . get ( outputId ) ?. container !== container ) {
149
+ logger ( 'Widget container changed, hence disposing the widget' ) ;
150
+ w ?. dispose ( ) ;
151
+ return ;
152
+ }
147
153
if ( renderedWidgets . has ( outputId ) ) {
148
154
renderedWidgets . get ( outputId ) ! . widget = w ;
149
155
}
@@ -155,7 +161,6 @@ function renderIPyWidget(
155
161
}
156
162
} ;
157
163
outputDisposables . set ( outputId , disposable ) ;
158
- htmlDisposables . set ( ele , disposable ) ;
159
164
// Keep track of the fact that we have successfully rendered a widget for this outputId.
160
165
const statusInfo = stackOfWidgetsRenderStatusByOutputId . find ( ( item ) => item . outputId === outputId ) ;
161
166
if ( statusInfo ) {
0 commit comments