diff --git a/packages/svelte/src/internal/client/dom/template.js b/packages/svelte/src/internal/client/dom/template.js index d6e6dedbfd..c2d40c3058 100644 --- a/packages/svelte/src/internal/client/dom/template.js +++ b/packages/svelte/src/internal/client/dom/template.js @@ -72,25 +72,8 @@ export function template(content, flags) { */ /*#__NO_SIDE_EFFECTS__*/ export function template_with_script(content, flags) { - var first = true; - var fn = template(content, flags | TEMPLATE_FRAGMENT); - - return () => { - if (hydrating) return fn(); - - var fragment = /** @type {DocumentFragment} */ (fn()); - - if (first) { - first = false; - run_scripts(fragment); - } - - if ((flags & TEMPLATE_FRAGMENT) !== 0) { - return fragment; - } - - return /** @type {Node} */ (fragment.firstChild); - }; + var fn = template(content, flags); + return () => run_scripts(/** @type {Element | DocumentFragment} */ (fn())); } /** @@ -155,25 +138,8 @@ export function ns_template(content, flags, ns = 'svg') { */ /*#__NO_SIDE_EFFECTS__*/ export function svg_template_with_script(content, flags) { - var first = true; - var fn = ns_template(content, flags | TEMPLATE_FRAGMENT); - - return () => { - if (hydrating) return fn(); - - var fragment = /** @type {DocumentFragment} */ (fn()); - - if (first) { - first = false; - run_scripts(fragment); - } - - if ((flags & TEMPLATE_FRAGMENT) !== 0) { - return fragment; - } - - return /** @type {Node} */ (fragment.firstChild); - }; + var fn = ns_template(content, flags); + return () => run_scripts(/** @type {Element | DocumentFragment} */ (fn())); } /** @@ -189,15 +155,21 @@ export function mathml_template(content, flags) { /** * Creating a document fragment from HTML that contains script tags will not execute * the scripts. We need to replace the script tags with new ones so that they are executed. - * @param {DocumentFragment} fragment + * @param {Element | DocumentFragment} node + * @returns {Node | Node[]} */ -function run_scripts(fragment) { +function run_scripts(node) { // scripts were SSR'd, in which case they will run - if (hydrating) return; + if (hydrating) return node; + const is_fragment = node.nodeType === 11; + const scripts = + /** @type {HTMLElement} */ (node).tagName === 'SCRIPT' + ? [/** @type {HTMLScriptElement} */ (node)] + : node.querySelectorAll('script'); const effect = /** @type {Effect} */ (active_effect); - for (const script of fragment.querySelectorAll('script')) { + for (const script of scripts) { const clone = document.createElement('script'); for (var attribute of script.attributes) { clone.setAttribute(attribute.name, attribute.value); @@ -206,15 +178,22 @@ function run_scripts(fragment) { clone.textContent = script.textContent; // The script has changed - if it's at the edges, the effect now points at dead nodes - if (fragment.firstChild === script) { + if (is_fragment ? node.firstChild === script : node === script) { effect.nodes_start = clone; } - if (fragment.lastChild === script) { + if (is_fragment ? node.lastChild === script : node === script) { effect.nodes_end = clone; } - script.replaceWith(clone); + // If node === script tag, replaceWith will do nothing because there's no parent yet + if (script === node) { + // but we can returns the cloned