Skip to content

Commit 9d878f1

Browse files
committed
run_scripts return the new node
1 parent 4791832 commit 9d878f1

File tree

1 file changed

+37
-27
lines changed

1 file changed

+37
-27
lines changed

packages/svelte/src/internal/client/dom/template.js

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export function template_with_script(content, flags) {
8282

8383
if (first) {
8484
first = false;
85-
run_scripts(node);
85+
node = run_scripts(node);
8686
}
8787

8888
return node;
@@ -161,7 +161,7 @@ export function svg_template_with_script(content, flags) {
161161

162162
if (first) {
163163
first = false;
164-
run_scripts(node);
164+
node = run_scripts(node);
165165
}
166166

167167
return node;
@@ -178,52 +178,62 @@ export function mathml_template(content, flags) {
178178
return ns_template(content, flags, 'math');
179179
}
180180

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+
181195
/**
182196
* Creating a document fragment from HTML that contains script tags will not execute
183197
* the scripts. We need to replace the script tags with new ones so that they are executed.
184198
* @param {Element | DocumentFragment} node
199+
* @returns {Element | DocumentFragment}
185200
*/
186201
function run_scripts(node) {
187202
// scripts were SSR'd, in which case they will run
188-
if (hydrating) return;
203+
if (hydrating) return node;
189204

190-
const is_fragment = node.nodeType === 11;
191-
const scripts =
192-
/** @type {HTMLElement} */ (node).tagName === 'SCRIPT'
193-
? [/** @type {HTMLScriptElement} */ (node)]
194-
: node.querySelectorAll('script');
195205
const effect = /** @type {Effect} */ (current_effect);
196206

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));
202209

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);
204224

205-
const replace = () => {
206225
// 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) {
208227
effect.nodes_start = clone;
209228
}
210-
if (is_fragment ? node.lastChild === script : node === script) {
229+
if (node.lastChild === script) {
211230
effect.nodes_end = clone;
212231
}
213232

214233
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();
225234
}
226235
}
236+
return node;
227237
}
228238

229239
/**

0 commit comments

Comments
 (0)