diff --git a/documentation/docs/98-reference/.generated/compile-warnings.md b/documentation/docs/98-reference/.generated/compile-warnings.md index e232076765..b579d38602 100644 --- a/documentation/docs/98-reference/.generated/compile-warnings.md +++ b/documentation/docs/98-reference/.generated/compile-warnings.md @@ -635,9 +635,22 @@ In some situations a selector may target an element that is not 'visible' to the ### element_implicitly_closed ``` -The tag `<%name%>` was implicitly closed by the parent or a next element. This may cause DOM structure being other than expected one. +This element is implicitly closed by the following `%tag%`, which can cause an unexpected DOM structure. Add an explicit `%closing%` to avoid surprises. ``` +In HTML, some elements are implicitly closed by another element. For example, you cannot nest a `
` inside another `
`: + +```html + +
hello
+ + + +hello
+``` + +Similarly, a parent element's closing tag will implicitly close all child elements, even if the `` was a typo and you meant to create a _new_ element. To avoid ambiguity, it's always a good idea to have an explicit closing tag. + ### element_invalid_self_closing_tag ``` diff --git a/packages/svelte/messages/compile-warnings/template.md b/packages/svelte/messages/compile-warnings/template.md index 84b9c4a791..d61a61d950 100644 --- a/packages/svelte/messages/compile-warnings/template.md +++ b/packages/svelte/messages/compile-warnings/template.md @@ -32,7 +32,20 @@ ## element_implicitly_closed -> The tag `<%name%>` was implicitly closed by the parent or a next element. This may cause DOM structure being other than expected one. +> This element is implicitly closed by the following `%tag%`, which can cause an unexpected DOM structure. Add an explicit `%closing%` to avoid surprises. + +In HTML, some elements are implicitly closed by another element. For example, you cannot nest a `` inside another `
`: + +```html + +
hello
+ + + +hello
+``` + +Similarly, a parent element's closing tag will implicitly close all child elements, even if the `` was a typo and you meant to create a _new_ element. To avoid ambiguity, it's always a good idea to have an explicit closing tag. ## element_invalid_self_closing_tag 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 63b94193ba..6b6c9160d8 100644 --- a/packages/svelte/src/compiler/phases/1-parse/state/element.js +++ b/packages/svelte/src/compiler/phases/1-parse/state/element.js @@ -96,7 +96,11 @@ export default function element(parser) { if (parent.type === 'RegularElement') { if (!parser.last_auto_closed_tag || parser.last_auto_closed_tag.tag !== name) { const end = parent.fragment.nodes[0]?.start ?? start; - w.element_implicitly_closed({ start: parent.start, end }, parent.name); + w.element_implicitly_closed( + { start: parent.start, end }, + `${name}>`, + `${parent.name}>` + ); } } else if (!parser.loose) { if (parser.last_auto_closed_tag && parser.last_auto_closed_tag.tag === name) { @@ -192,7 +196,7 @@ export default function element(parser) { if (parent.type === 'RegularElement' && closing_tag_omitted(parent.name, name)) { const end = parent.fragment.nodes[0]?.start ?? start; - w.element_implicitly_closed({ start: parent.start, end }, parent.name); + w.element_implicitly_closed({ start: parent.start, end }, `<${name}>`, `${parent.name}>`); parent.end = start; parser.pop(); parser.last_auto_closed_tag = { diff --git a/packages/svelte/src/compiler/warnings.js b/packages/svelte/src/compiler/warnings.js index 661575eddf..2a8316308c 100644 --- a/packages/svelte/src/compiler/warnings.js +++ b/packages/svelte/src/compiler/warnings.js @@ -748,12 +748,13 @@ export function component_name_lowercase(node, name) { } /** - * The tag `<%name%>` was implicitly closed by the parent or a next element. This may cause DOM structure being other than expected one. + * This element is implicitly closed by the following `%tag%`, which can cause an unexpected DOM structure. Add an explicit `%closing%` to avoid surprises. * @param {null | NodeLike} node - * @param {string} name + * @param {string} tag + * @param {string} closing */ -export function element_implicitly_closed(node, name) { - w(node, 'element_implicitly_closed', `The tag \`<${name}>\` was implicitly closed by the parent or a next element. This may cause DOM structure being other than expected one.\nhttps://svelte.dev/e/element_implicitly_closed`); +export function element_implicitly_closed(node, tag, closing) { + w(node, 'element_implicitly_closed', `This element is implicitly closed by the following \`${tag}\`, which can cause an unexpected DOM structure. Add an explicit \`${closing}\` to avoid surprises.\nhttps://svelte.dev/e/element_implicitly_closed`); } /** diff --git a/packages/svelte/tests/validator/samples/implicitly-closed-by-parent/warnings.json b/packages/svelte/tests/validator/samples/implicitly-closed-by-parent/warnings.json index e495697d49..1316a2b65b 100644 --- a/packages/svelte/tests/validator/samples/implicitly-closed-by-parent/warnings.json +++ b/packages/svelte/tests/validator/samples/implicitly-closed-by-parent/warnings.json @@ -1,7 +1,7 @@ [ { "code": "element_implicitly_closed", - "message": "The tag `` was implicitly closed by the parent or a next element. This may cause DOM structure being other than expected one.", + "message": "This element is implicitly closed by the following `
`, which can cause an unexpected DOM structure. Add an explicit `
` to avoid surprises.", "start": { "line": 2, "column": 1 @@ -13,7 +13,7 @@ }, { "code": "element_implicitly_closed", - "message": "The tag `` was implicitly closed by the parent or a next element. This may cause DOM structure being other than expected one.", + "message": "This element is implicitly closed by the following `
`, which can cause an unexpected DOM structure. Add an explicit `
` to avoid surprises.", "start": { "line": 8, "column": 1