@@ -82,7 +82,7 @@ export function template_with_script(content, flags) {
82
82
83
83
if ( first ) {
84
84
first = false ;
85
- run_scripts ( node ) ;
85
+ node = run_scripts ( node ) ;
86
86
}
87
87
88
88
return node ;
@@ -161,7 +161,7 @@ export function svg_template_with_script(content, flags) {
161
161
162
162
if ( first ) {
163
163
first = false ;
164
- run_scripts ( node ) ;
164
+ node = run_scripts ( node ) ;
165
165
}
166
166
167
167
return node ;
@@ -178,52 +178,62 @@ export function mathml_template(content, flags) {
178
178
return ns_template ( content , flags , 'math' ) ;
179
179
}
180
180
181
+ /**
182
+ * Clone a SCRIPT
183
+ * @param {HTMLScriptElement } script
184
+ * @returns {HTMLScriptElement }
185
+ */
186
+ function clone_script ( script ) {
187
+ const clone = document . createElement ( 'script' ) ;
188
+ for ( var attribute of script . attributes ) {
189
+ clone . setAttribute ( attribute . name , attribute . value ) ;
190
+ }
191
+ clone . textContent = script . textContent ;
192
+ return clone ;
193
+ }
194
+
181
195
/**
182
196
* Creating a document fragment from HTML that contains script tags will not execute
183
197
* the scripts. We need to replace the script tags with new ones so that they are executed.
184
198
* @param {Element | DocumentFragment } node
199
+ * @returns {Element | DocumentFragment }
185
200
*/
186
201
function run_scripts ( node ) {
187
202
// scripts were SSR'd, in which case they will run
188
- if ( hydrating ) return ;
203
+ if ( hydrating ) return node ;
189
204
190
- const is_fragment = node . nodeType === 11 ;
191
- const scripts =
192
- /** @type {HTMLElement } */ ( node ) . tagName === 'SCRIPT'
193
- ? [ /** @type {HTMLScriptElement } */ ( node ) ]
194
- : node . querySelectorAll ( 'script' ) ;
195
205
const effect = /** @type {Effect } */ ( current_effect ) ;
196
206
197
- for ( const script of scripts ) {
198
- const clone = document . createElement ( 'script' ) ;
199
- for ( var attribute of script . attributes ) {
200
- clone . setAttribute ( attribute . name , attribute . value ) ;
201
- }
207
+ if ( /** @type {HTMLElement } */ ( node ) . tagName === 'SCRIPT' ) {
208
+ const clone = clone_script ( /** @type {HTMLScriptElement } */ ( node ) ) ;
202
209
203
- clone . textContent = script . textContent ;
210
+ // The script has changed - if it's at the edges, the effect now points at dead nodes
211
+ effect . nodes_start = clone ;
212
+ effect . nodes_end = clone ;
213
+
214
+ // return the cloned script
215
+ return clone ;
216
+ }
217
+
218
+ if ( node . nodeType === 11 ) {
219
+ // fragment
220
+ const scripts = node . querySelectorAll ( 'script' ) ;
221
+
222
+ for ( const script of scripts ) {
223
+ const clone = clone_script ( script ) ;
204
224
205
- const replace = ( ) => {
206
225
// The script has changed - if it's at the edges, the effect now points at dead nodes
207
- if ( is_fragment ? node . firstChild === script : node === script ) {
226
+ if ( node . firstChild === script ) {
208
227
effect . nodes_start = clone ;
209
228
}
210
- if ( is_fragment ? node . lastChild === script : node === script ) {
229
+ if ( node . lastChild === script ) {
211
230
effect . nodes_end = clone ;
212
231
}
213
232
214
233
script . replaceWith ( clone ) ;
215
- } ;
216
-
217
- // If node === script tag, replaceWith will do nothing because there's no parent yet,
218
- // waiting until that's the case using an effect solves this.
219
- // Don't do it in other circumstances or we could accidentally execute scripts
220
- // in an adjacent @html tag that was instantiated in the meantime.
221
- if ( script === node ) {
222
- queue_micro_task ( replace ) ;
223
- } else {
224
- replace ( ) ;
225
234
}
226
235
}
236
+ return node ;
227
237
}
228
238
229
239
/**
0 commit comments