@@ -38,7 +38,7 @@ const getRelatedScript = (target, type) => {
38
38
return editor ?. parentNode ?. previousElementSibling ;
39
39
} ;
40
40
41
- async function execute ( { currentTarget} ) {
41
+ async function execute ( { currentTarget, script } ) {
42
42
const { env, pySrc, outDiv} = this ;
43
43
const hasRunButton = ! ! currentTarget ;
44
44
@@ -91,14 +91,13 @@ async function execute({ currentTarget }) {
91
91
// creation and destruction of editors on the fly
92
92
if ( hasRunButton ) {
93
93
for ( const type of TYPES . keys ( ) ) {
94
- const script = getRelatedScript ( currentTarget , type ) ;
95
- if ( script ) {
96
- defineProperties ( script , { xworker :{ value :xworker } } ) ;
97
- break ;
98
- }
94
+ script = getRelatedScript ( currentTarget , type ) ;
95
+ if ( script ) break ;
99
96
}
100
97
}
101
98
99
+ defineProperties ( script , { xworker :{ value :xworker } } ) ;
100
+
102
101
const { sync} = xworker ;
103
102
const { promise, resolve} = withResolvers ( ) ;
104
103
envs . set ( env , promise ) ;
@@ -157,6 +156,20 @@ async function execute({ currentTarget }) {
157
156
} ) ;
158
157
}
159
158
159
+ const replaceScript = ( script , type ) => {
160
+ script . xworker ?. terminate ( ) ;
161
+ const clone = script . cloneNode ( true ) ;
162
+ clone . type = `${ type } -editor` ;
163
+ const editor = editors . get ( script ) ;
164
+ if ( editor ) {
165
+ const content = editor . state . doc . toString ( ) ;
166
+ clone . textContent = content ;
167
+ editors . delete ( script ) ;
168
+ script . nextElementSibling . remove ( ) ;
169
+ }
170
+ script . replaceWith ( clone ) ;
171
+ } ;
172
+
160
173
const makeRunButton = ( handler , type ) => {
161
174
const runButton = document . createElement ( "button" ) ;
162
175
runButton . className = `absolute${ type } -editor-run-button` ;
@@ -169,15 +182,25 @@ const makeRunButton = (handler, type) => {
169
182
) {
170
183
const script = getRelatedScript ( runButton , type ) ;
171
184
if ( script ) {
172
- const editor = editors . get ( script ) ;
173
- const content = editor . state . doc . toString ( ) ;
174
- const clone = script . cloneNode ( true ) ;
175
- clone . type = `${ type } -editor` ;
176
- clone . textContent = content ;
177
- script . xworker . terminate ( ) ;
178
- script . nextElementSibling . remove ( ) ;
179
- script . replaceWith ( clone ) ;
180
- editors . delete ( script ) ;
185
+ const env = script . getAttribute ( "env" ) ;
186
+ // remove the bootstrapped env which could be one or shared
187
+ if ( env ) {
188
+ for ( const [ key , value ] of TYPES ) {
189
+ if ( key === type ) {
190
+ configs . delete ( `${ value } -${ env } ` ) ;
191
+ envs . delete ( `${ value } -${ env } ` ) ;
192
+ break ;
193
+ }
194
+ }
195
+ }
196
+ // lonley script without setup node should be replaced
197
+ if ( script . xworker ) replaceScript ( script , type ) ;
198
+ // all scripts sharing the same env should be replaced
199
+ else {
200
+ const sel = `script[type^="${ type } -editor"][env="${ env } "]` ;
201
+ for ( const script of document . querySelectorAll ( sel ) )
202
+ replaceScript ( script , type ) ;
203
+ }
181
204
}
182
205
return ;
183
206
}
@@ -365,7 +388,7 @@ const init = async (script, type, interpreter) => {
365
388
} ;
366
389
367
390
if ( isSetup ) {
368
- await context . handleEvent ( { currentTarget :null } ) ;
391
+ await context . handleEvent ( { currentTarget :null , script } ) ;
369
392
notifyEditor ( ) ;
370
393
return ;
371
394
}