From 33c91a6b75e7e5050bdb47ee422f78f77a13c5fb Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 11 Aug 2024 07:57:14 -0400 Subject: [PATCH 1/5] feat: treat tag with `.` as a component, even if lowercase --- .../svelte/src/compiler/phases/1-parse/state/element.js | 4 ++-- .../samples/dot-notation-component/_config.js | 5 +++++ .../samples/dot-notation-component/child.svelte | 1 + .../samples/dot-notation-component/main.svelte | 7 +++++++ 4 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 packages/svelte/tests/runtime-runes/samples/dot-notation-component/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/dot-notation-component/child.svelte create mode 100644 packages/svelte/tests/runtime-runes/samples/dot-notation-component/main.svelte diff --git a/packages/svelte/src/compiler/phases/1-parse/state/element.js b/packages/svelte/src/compiler/phases/1-parse/state/element.js index bdadf41347fd..7e3b9d152385 100644 --- a/packages/svelte/src/compiler/phases/1-parse/state/element.js +++ b/packages/svelte/src/compiler/phases/1-parse/state/element.js @@ -74,7 +74,7 @@ function parent_is_shadowroot_template(stack) { const regex_closing_textarea_tag = /^<\/textarea(\s[^>]*)?>/i; const regex_closing_comment = /-->/; -const regex_capital_letter = /[A-Z]/; +const component_name = /^(?:[A-Z]|[A-Za-z][A-Za-z0-9_$]*\.)/; /** @param {Parser} parser */ export default function element(parser) { @@ -127,7 +127,7 @@ export default function element(parser) { const type = meta_tags.has(name) ? meta_tags.get(name) - : regex_capital_letter.test(name[0]) + : component_name.test(name) ? 'Component' : name === 'title' && parent_is_head(parser.stack) ? 'TitleElement' diff --git a/packages/svelte/tests/runtime-runes/samples/dot-notation-component/_config.js b/packages/svelte/tests/runtime-runes/samples/dot-notation-component/_config.js new file mode 100644 index 000000000000..3b44dd63caae --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/dot-notation-component/_config.js @@ -0,0 +1,5 @@ +import { test } from '../../test'; + +export default test({ + html: '

hello

' +}); diff --git a/packages/svelte/tests/runtime-runes/samples/dot-notation-component/child.svelte b/packages/svelte/tests/runtime-runes/samples/dot-notation-component/child.svelte new file mode 100644 index 000000000000..6e7c1e6ac83f --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/dot-notation-component/child.svelte @@ -0,0 +1 @@ +

hello

diff --git a/packages/svelte/tests/runtime-runes/samples/dot-notation-component/main.svelte b/packages/svelte/tests/runtime-runes/samples/dot-notation-component/main.svelte new file mode 100644 index 000000000000..12e9d22b369c --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/dot-notation-component/main.svelte @@ -0,0 +1,7 @@ + + + From e5f2ce389f4c4989d95fdd8545389a63a114b699 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 11 Aug 2024 07:57:52 -0400 Subject: [PATCH 2/5] changeset --- .changeset/gold-students-jump.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/gold-students-jump.md diff --git a/.changeset/gold-students-jump.md b/.changeset/gold-students-jump.md new file mode 100644 index 000000000000..d38393554aed --- /dev/null +++ b/.changeset/gold-students-jump.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +feat: treat tag with `.` as a component, even if lowercase From fe757e57097eb801ae89cfc3856b90aba36e5e47 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 11 Aug 2024 08:04:11 -0400 Subject: [PATCH 3/5] consistency --- packages/svelte/src/compiler/phases/1-parse/state/element.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/svelte/src/compiler/phases/1-parse/state/element.js b/packages/svelte/src/compiler/phases/1-parse/state/element.js index 7e3b9d152385..12e75400be3f 100644 --- a/packages/svelte/src/compiler/phases/1-parse/state/element.js +++ b/packages/svelte/src/compiler/phases/1-parse/state/element.js @@ -74,7 +74,7 @@ function parent_is_shadowroot_template(stack) { const regex_closing_textarea_tag = /^<\/textarea(\s[^>]*)?>/i; const regex_closing_comment = /-->/; -const component_name = /^(?:[A-Z]|[A-Za-z][A-Za-z0-9_$]*\.)/; +const regex_component_name = /^(?:[A-Z]|[A-Za-z][A-Za-z0-9_$]*\.)/; /** @param {Parser} parser */ export default function element(parser) { @@ -127,7 +127,7 @@ export default function element(parser) { const type = meta_tags.has(name) ? meta_tags.get(name) - : component_name.test(name) + : regex_component_name.test(name) ? 'Component' : name === 'title' && parent_is_head(parser.stack) ? 'TitleElement' From 594b3ecf378307aed63f552a47e16e44c78dc1a8 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 12 Aug 2024 06:34:38 -0400 Subject: [PATCH 4/5] note breaking change --- .../docs/content/03-appendix/02-breaking-changes.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sites/svelte-5-preview/src/routes/docs/content/03-appendix/02-breaking-changes.md b/sites/svelte-5-preview/src/routes/docs/content/03-appendix/02-breaking-changes.md index 95469ccbafa2..2653ab8cc80b 100644 --- a/sites/svelte-5-preview/src/routes/docs/content/03-appendix/02-breaking-changes.md +++ b/sites/svelte-5-preview/src/routes/docs/content/03-appendix/02-breaking-changes.md @@ -222,6 +222,16 @@ This is [no longer true in Svelte 5](/#H4sIAAAAAAAAE4WQwU7DMAyGX8VESANpXe8lq9Q8A ``` +### Dot notation indicates a component + +In Svelte 4, `` would create an element with a tag name of `"foo.bar"`. In Svelte 5, `foo.bar` is treated as a component instead. This is particularly useful inside `each` blocks: + +```svelte +{#each items as item} + +{/each} +``` + ## Other breaking changes ### Stricter `@const` assignment validation From 519957abb9192695e45756fa9748518d4d01966f Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 12 Aug 2024 06:35:22 -0400 Subject: [PATCH 5/5] oops, wrong place --- .../03-appendix/02-breaking-changes.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/sites/svelte-5-preview/src/routes/docs/content/03-appendix/02-breaking-changes.md b/sites/svelte-5-preview/src/routes/docs/content/03-appendix/02-breaking-changes.md index 2653ab8cc80b..7b589785d7ec 100644 --- a/sites/svelte-5-preview/src/routes/docs/content/03-appendix/02-breaking-changes.md +++ b/sites/svelte-5-preview/src/routes/docs/content/03-appendix/02-breaking-changes.md @@ -161,6 +161,16 @@ Svelte now use Mutation Observers instead of IFrames to measure dimensions for ` Content inside component tags becomes a [snippet prop](/docs/snippets) called `children`. You cannot have a separate prop by that name. +## Dot notation indicates a component + +In Svelte 4, `` would create an element with a tag name of `"foo.bar"`. In Svelte 5, `foo.bar` is treated as a component instead. This is particularly useful inside `each` blocks: + +```svelte +{#each items as item} + +{/each} +``` + ## Breaking changes in runes mode Some breaking changes only apply once your component is in runes mode. @@ -222,16 +232,6 @@ This is [no longer true in Svelte 5](/#H4sIAAAAAAAAE4WQwU7DMAyGX8VESANpXe8lq9Q8A ``` -### Dot notation indicates a component - -In Svelte 4, `` would create an element with a tag name of `"foo.bar"`. In Svelte 5, `foo.bar` is treated as a component instead. This is particularly useful inside `each` blocks: - -```svelte -{#each items as item} - -{/each} -``` - ## Other breaking changes ### Stricter `@const` assignment validation