diff --git a/.changeset/wild-moose-destroy.md b/.changeset/wild-moose-destroy.md new file mode 100644 index 0000000000..9dfc8d2bc1 --- /dev/null +++ b/.changeset/wild-moose-destroy.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: don't skip custom elements with attributes diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/RegularElement.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/RegularElement.js index 16be82ed2c..dc283db7e2 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/visitors/RegularElement.js +++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/RegularElement.js @@ -7,10 +7,11 @@ import { } from '../../../../html-tree-validation.js'; import * as e from '../../../errors.js'; import * as w from '../../../warnings.js'; -import { create_attribute } from '../../nodes.js'; +import { create_attribute, is_custom_element_node } from '../../nodes.js'; import { regex_starts_with_newline } from '../../patterns.js'; import { check_element } from './shared/a11y.js'; import { validate_element } from './shared/element.js'; +import { mark_subtree_dynamic } from './shared/fragment.js'; /** * @param {RegularElement} node @@ -88,6 +89,11 @@ export function RegularElement(node, context) { node.metadata.svg = is_svg(node.name); node.metadata.mathml = is_mathml(node.name); + if (is_custom_element_node(node) && node.attributes.length > 0) { + // we're setting all attributes on custom elements through properties + mark_subtree_dynamic(context.path); + } + if (context.state.parent_element) { let past_parent = false; let only_warn = false; diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js index cbe0272827..6dcb794f2c 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js @@ -1,6 +1,6 @@ /** @import { Expression } from 'estree' */ /** @import { ExpressionTag, SvelteNode, Text } from '#compiler' */ -/** @import { ComponentClientTransformState, ComponentContext } from '../../types' */ +/** @import { ComponentContext } from '../../types' */ import { is_event_attribute, is_text_attribute } from '../../../../../utils/ast.js'; import * as b from '../../../../../utils/builders.js'; import { build_template_literal, build_update } from './utils.js'; diff --git a/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client/index.svelte.js index 5eacd941ea..4f59c4932e 100644 --- a/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client/index.svelte.js @@ -1,7 +1,7 @@ import "svelte/internal/disclose-version"; import * as $ from "svelte/internal/client"; -var root = $.template(`

we don't need to traverse these nodes

or

these

ones

`, 1); +var root = $.template(`

we don't need to traverse these nodes

or

these

ones

`, 3); export default function Skip_static_subtree($$anchor, $$props) { var fragment = root(); @@ -15,6 +15,12 @@ export default function Skip_static_subtree($$anchor, $$props) { $.html(node, () => $$props.content, false, false); $.reset(main); + + var cant_skip = $.sibling(main, 2); + var custom_elements = $.child(cant_skip); + + $.set_custom_element_data(custom_elements, "with", "attributes"); + $.reset(cant_skip); $.template_effect(() => $.set_text(text, $$props.title)); $.append($$anchor, fragment); } \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/server/index.svelte.js b/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/server/index.svelte.js index 8ea5fc9b13..1018b5425e 100644 --- a/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/server/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/server/index.svelte.js @@ -3,5 +3,5 @@ import * as $ from "svelte/internal/server"; export default function Skip_static_subtree($$payload, $$props) { let { title, content } = $$props; - $$payload.out += `

${$.escape(title)}

we don't need to traverse these nodes

or

these

ones

${$.html(content)}
`; + $$payload.out += `

${$.escape(title)}

we don't need to traverse these nodes

or

these

ones

${$.html(content)}
`; } \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/skip-static-subtree/index.svelte b/packages/svelte/tests/snapshot/samples/skip-static-subtree/index.svelte index 001196a879..cc9d8172e6 100644 --- a/packages/svelte/tests/snapshot/samples/skip-static-subtree/index.svelte +++ b/packages/svelte/tests/snapshot/samples/skip-static-subtree/index.svelte @@ -19,3 +19,7 @@

ones

{@html content} + + + +