From d2879a969f19605742cde880f55f6be55edde878 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Mon, 13 May 2024 17:30:25 +0100 Subject: [PATCH 1/2] fix: always use document.importNode for template cloning --- .changeset/shaggy-feet-kick.md | 5 +++++ .../3-transform/client/visitors/template.js | 9 --------- packages/svelte/src/constants.js | 1 - .../src/internal/client/dom/operations.js | 18 +++--------------- .../svelte/src/internal/client/dom/template.js | 11 +++++------ 5 files changed, 13 insertions(+), 31 deletions(-) create mode 100644 .changeset/shaggy-feet-kick.md diff --git a/.changeset/shaggy-feet-kick.md b/.changeset/shaggy-feet-kick.md new file mode 100644 index 000000000000..1e6d52a03142 --- /dev/null +++ b/.changeset/shaggy-feet-kick.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix: always use document.importNode for template cloning diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js index 082a6c4dee41..bb4989869a88 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js @@ -28,7 +28,6 @@ import { EACH_ITEM_REACTIVE, EACH_KEYED, TEMPLATE_FRAGMENT, - TEMPLATE_USE_IMPORT_NODE, TRANSITION_GLOBAL, TRANSITION_IN, TRANSITION_OUT @@ -1077,10 +1076,6 @@ function create_block(parent, name, nodes, context) { /** @type {import('estree').Expression[]} */ const args = [b.template([b.quasi(state.template.join(''), true)], [])]; - if (state.metadata.context.template_needs_import_node) { - args.push(b.literal(TEMPLATE_USE_IMPORT_NODE)); - } - add_template(template_name, args); body.push(b.var(id, b.call(template_name)), ...state.before_init, ...state.init); @@ -1121,10 +1116,6 @@ function create_block(parent, name, nodes, context) { } else { let flags = TEMPLATE_FRAGMENT; - if (state.metadata.context.template_needs_import_node) { - flags |= TEMPLATE_USE_IMPORT_NODE; - } - add_template(template_name, [ b.template([b.quasi(state.template.join(''), true)], []), b.literal(flags) diff --git a/packages/svelte/src/constants.js b/packages/svelte/src/constants.js index 0e3a1737abf3..521e89325c3b 100644 --- a/packages/svelte/src/constants.js +++ b/packages/svelte/src/constants.js @@ -17,7 +17,6 @@ export const TRANSITION_OUT = 1 << 1; export const TRANSITION_GLOBAL = 1 << 2; export const TEMPLATE_FRAGMENT = 1; -export const TEMPLATE_USE_IMPORT_NODE = 1 << 1; export const HYDRATION_START = '['; export const HYDRATION_END = ']'; diff --git a/packages/svelte/src/internal/client/dom/operations.js b/packages/svelte/src/internal/client/dom/operations.js index 3c3ca4f7fdcb..cd53f213c964 100644 --- a/packages/svelte/src/internal/client/dom/operations.js +++ b/packages/svelte/src/internal/client/dom/operations.js @@ -17,8 +17,8 @@ var text_prototype; /** @type {typeof Node.prototype.appendChild} */ var append_child_method; -/** @type {typeof Node.prototype.cloneNode} */ -var clone_node_method; +/** @type {typeof document.importNode} */ +export var import_node; /** @type {(this: Node) => ChildNode | null} */ var first_child_get; @@ -56,7 +56,7 @@ export function init_operations() { text_prototype = Text.prototype; append_child_method = node_prototype.appendChild; - clone_node_method = node_prototype.cloneNode; + import_node = document.importNode; $window = window; $document = document; @@ -106,18 +106,6 @@ export function init_operations() { export function append_child(element, child) { append_child_method.call(element, child); } - -/** - * @template {Node} N - * @param {N} node - * @param {boolean} deep - * @returns {N} - */ -/*#__NO_SIDE_EFFECTS__*/ -export function clone_node(node, deep) { - return /** @type {N} */ (clone_node_method.call(node, deep)); -} - /** @returns {Text} */ export function empty() { return document.createTextNode(''); diff --git a/packages/svelte/src/internal/client/dom/template.js b/packages/svelte/src/internal/client/dom/template.js index 8f754248e7eb..e92d9704e5da 100644 --- a/packages/svelte/src/internal/client/dom/template.js +++ b/packages/svelte/src/internal/client/dom/template.js @@ -1,8 +1,8 @@ import { hydrate_nodes, hydrating } from './hydration.js'; -import { clone_node, empty } from './operations.js'; +import { import_node, empty } from './operations.js'; import { create_fragment_from_html } from './reconciler.js'; import { current_effect } from '../runtime.js'; -import { TEMPLATE_FRAGMENT, TEMPLATE_USE_IMPORT_NODE } from '../../../constants.js'; +import { TEMPLATE_FRAGMENT } from '../../../constants.js'; import { effect } from '../reactivity/effects.js'; import { is_array } from '../utils.js'; @@ -41,7 +41,6 @@ export function push_template_node( /*#__NO_SIDE_EFFECTS__*/ export function template(content, flags) { var is_fragment = (flags & TEMPLATE_FRAGMENT) !== 0; - var use_import_node = (flags & TEMPLATE_USE_IMPORT_NODE) !== 0; /** @type {Node} */ var node; @@ -55,7 +54,7 @@ export function template(content, flags) { node = create_fragment_from_html(content); if (!is_fragment) node = /** @type {Node} */ (node.firstChild); } - var clone = use_import_node ? document.importNode(node, true) : clone_node(node, true); + var clone = import_node(node, true); push_template_node( is_fragment @@ -122,7 +121,7 @@ export function svg_template(content, flags) { } } - var clone = clone_node(node, true); + var clone = import_node(node, true); push_template_node( is_fragment @@ -189,7 +188,7 @@ export function mathml_template(content, flags) { } } - var clone = clone_node(node, true); + var clone = import_node(node, true); push_template_node( is_fragment From a659ef2335fd1d7464c081a60c24c5acbcdcdbdb Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Mon, 13 May 2024 17:37:19 +0100 Subject: [PATCH 2/2] fix tests --- packages/svelte/src/internal/client/dom/operations.js | 5 +---- packages/svelte/src/internal/client/dom/template.js | 8 ++++---- .../_expected/client/main.svelte.js | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/packages/svelte/src/internal/client/dom/operations.js b/packages/svelte/src/internal/client/dom/operations.js index cd53f213c964..ae71a1a44ac7 100644 --- a/packages/svelte/src/internal/client/dom/operations.js +++ b/packages/svelte/src/internal/client/dom/operations.js @@ -17,9 +17,6 @@ var text_prototype; /** @type {typeof Node.prototype.appendChild} */ var append_child_method; -/** @type {typeof document.importNode} */ -export var import_node; - /** @type {(this: Node) => ChildNode | null} */ var first_child_get; @@ -56,7 +53,6 @@ export function init_operations() { text_prototype = Text.prototype; append_child_method = node_prototype.appendChild; - import_node = document.importNode; $window = window; $document = document; @@ -106,6 +102,7 @@ export function init_operations() { export function append_child(element, child) { append_child_method.call(element, child); } + /** @returns {Text} */ export function empty() { return document.createTextNode(''); diff --git a/packages/svelte/src/internal/client/dom/template.js b/packages/svelte/src/internal/client/dom/template.js index e92d9704e5da..44063b3b3162 100644 --- a/packages/svelte/src/internal/client/dom/template.js +++ b/packages/svelte/src/internal/client/dom/template.js @@ -1,5 +1,5 @@ import { hydrate_nodes, hydrating } from './hydration.js'; -import { import_node, empty } from './operations.js'; +import { empty } from './operations.js'; import { create_fragment_from_html } from './reconciler.js'; import { current_effect } from '../runtime.js'; import { TEMPLATE_FRAGMENT } from '../../../constants.js'; @@ -54,7 +54,7 @@ export function template(content, flags) { node = create_fragment_from_html(content); if (!is_fragment) node = /** @type {Node} */ (node.firstChild); } - var clone = import_node(node, true); + var clone = document.importNode(node, true); push_template_node( is_fragment @@ -121,7 +121,7 @@ export function svg_template(content, flags) { } } - var clone = import_node(node, true); + var clone = document.importNode(node, true); push_template_node( is_fragment @@ -188,7 +188,7 @@ export function mathml_template(content, flags) { } } - var clone = import_node(node, true); + var clone = document.importNode(node, true); push_template_node( is_fragment diff --git a/packages/svelte/tests/snapshot/samples/dynamic-attributes-casing/_expected/client/main.svelte.js b/packages/svelte/tests/snapshot/samples/dynamic-attributes-casing/_expected/client/main.svelte.js index aa4d22d99a6d..92a492cdee3a 100644 --- a/packages/svelte/tests/snapshot/samples/dynamic-attributes-casing/_expected/client/main.svelte.js +++ b/packages/svelte/tests/snapshot/samples/dynamic-attributes-casing/_expected/client/main.svelte.js @@ -1,7 +1,7 @@ import "svelte/internal/disclose-version"; import * as $ from "svelte/internal/client"; -var root = $.template(`
`, 3); +var root = $.template(`
`, 1); export default function Main($$anchor) { // needs to be a snapshot test because jsdom does auto-correct the attribute casing