diff --git a/.changeset/cold-teachers-turn.md b/.changeset/cold-teachers-turn.md new file mode 100644 index 0000000000..e86ffbcdfe --- /dev/null +++ b/.changeset/cold-teachers-turn.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix: correct start of `{:else if}` and `{:else}` diff --git a/packages/svelte/src/compiler/legacy.js b/packages/svelte/src/compiler/legacy.js index caa7f8238e..da0ba058d3 100644 --- a/packages/svelte/src/compiler/legacy.js +++ b/packages/svelte/src/compiler/legacy.js @@ -353,11 +353,12 @@ export function convert(source, ast) { }; } + const start = node.elseif ? node.consequent.nodes[0].start : node.start; remove_surrounding_whitespace_nodes(node.consequent.nodes); return { type: 'IfBlock', - start: node.start, + start, end: node.end, expression: node.test, children: node.consequent.nodes.map( diff --git a/packages/svelte/src/compiler/phases/1-parse/state/tag.js b/packages/svelte/src/compiler/phases/1-parse/state/tag.js index baa86783b0..14af03f6f6 100644 --- a/packages/svelte/src/compiler/phases/1-parse/state/tag.js +++ b/packages/svelte/src/compiler/phases/1-parse/state/tag.js @@ -345,7 +345,7 @@ function next(parser) { /** @type {ReturnType>} */ const child = parser.append({ - start: parser.index, + start: start - 1, end: -1, type: 'IfBlock', elseif: true, diff --git a/packages/svelte/tests/parser-modern/samples/if-block-else/input.svelte b/packages/svelte/tests/parser-modern/samples/if-block-else/input.svelte new file mode 100644 index 0000000000..28b41c046c --- /dev/null +++ b/packages/svelte/tests/parser-modern/samples/if-block-else/input.svelte @@ -0,0 +1,5 @@ +{#if foo} +

foo

+{:else} +

not foo

+{/if} diff --git a/packages/svelte/tests/parser-modern/samples/if-block-else/output.json b/packages/svelte/tests/parser-modern/samples/if-block-else/output.json new file mode 100644 index 0000000000..1193af156e --- /dev/null +++ b/packages/svelte/tests/parser-modern/samples/if-block-else/output.json @@ -0,0 +1,116 @@ +{ + "css": null, + "js": [], + "start": 0, + "end": 51, + "type": "Root", + "fragment": { + "type": "Fragment", + "nodes": [ + { + "type": "IfBlock", + "elseif": false, + "start": 0, + "end": 51, + "test": { + "type": "Identifier", + "start": 5, + "end": 8, + "loc": { + "start": { + "line": 1, + "column": 5 + }, + "end": { + "line": 1, + "column": 8 + } + }, + "name": "foo" + }, + "consequent": { + "type": "Fragment", + "nodes": [ + { + "type": "Text", + "start": 9, + "end": 11, + "raw": "\n\t", + "data": "\n\t" + }, + { + "type": "RegularElement", + "start": 11, + "end": 21, + "name": "p", + "attributes": [], + "fragment": { + "type": "Fragment", + "nodes": [ + { + "type": "Text", + "start": 14, + "end": 17, + "raw": "foo", + "data": "foo" + } + ], + "transparent": true + } + }, + { + "type": "Text", + "start": 21, + "end": 22, + "raw": "\n", + "data": "\n" + } + ], + "transparent": false + }, + "alternate": { + "type": "Fragment", + "nodes": [ + { + "type": "Text", + "start": 29, + "end": 31, + "raw": "\n\t", + "data": "\n\t" + }, + { + "type": "RegularElement", + "start": 31, + "end": 45, + "name": "p", + "attributes": [], + "fragment": { + "type": "Fragment", + "nodes": [ + { + "type": "Text", + "start": 34, + "end": 41, + "raw": "not foo", + "data": "not foo" + } + ], + "transparent": true + } + }, + { + "type": "Text", + "start": 45, + "end": 46, + "raw": "\n", + "data": "\n" + } + ], + "transparent": false + } + } + ], + "transparent": false + }, + "options": null +} diff --git a/packages/svelte/tests/parser-modern/samples/if-block-elseif/input.svelte b/packages/svelte/tests/parser-modern/samples/if-block-elseif/input.svelte new file mode 100644 index 0000000000..2566aef258 --- /dev/null +++ b/packages/svelte/tests/parser-modern/samples/if-block-elseif/input.svelte @@ -0,0 +1,5 @@ +{#if x > 10} +

x is greater than 10

+{:else if x < 5} +

x is less than 5

+{/if} diff --git a/packages/svelte/tests/parser-modern/samples/if-block-elseif/output.json b/packages/svelte/tests/parser-modern/samples/if-block-elseif/output.json new file mode 100644 index 0000000000..e68b154a55 --- /dev/null +++ b/packages/svelte/tests/parser-modern/samples/if-block-elseif/output.json @@ -0,0 +1,211 @@ +{ + "css": null, + "js": [], + "start": 0, + "end": 89, + "type": "Root", + "fragment": { + "type": "Fragment", + "nodes": [ + { + "type": "IfBlock", + "elseif": false, + "start": 0, + "end": 89, + "test": { + "type": "BinaryExpression", + "start": 5, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 5 + }, + "end": { + "line": 1, + "column": 11 + } + }, + "left": { + "type": "Identifier", + "start": 5, + "end": 6, + "loc": { + "start": { + "line": 1, + "column": 5 + }, + "end": { + "line": 1, + "column": 6 + } + }, + "name": "x" + }, + "operator": ">", + "right": { + "type": "Literal", + "start": 9, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 11 + } + }, + "value": 10, + "raw": "10" + } + }, + "consequent": { + "type": "Fragment", + "nodes": [ + { + "type": "Text", + "start": 12, + "end": 14, + "raw": "\n\t", + "data": "\n\t" + }, + { + "type": "RegularElement", + "start": 14, + "end": 41, + "name": "p", + "attributes": [], + "fragment": { + "type": "Fragment", + "nodes": [ + { + "type": "Text", + "start": 17, + "end": 37, + "raw": "x is greater than 10", + "data": "x is greater than 10" + } + ], + "transparent": true + } + }, + { + "type": "Text", + "start": 41, + "end": 42, + "raw": "\n", + "data": "\n" + } + ], + "transparent": false + }, + "alternate": { + "type": "Fragment", + "nodes": [ + { + "start": 42, + "end": 89, + "type": "IfBlock", + "elseif": true, + "test": { + "type": "BinaryExpression", + "start": 52, + "end": 57, + "loc": { + "start": { + "line": 3, + "column": 10 + }, + "end": { + "line": 3, + "column": 15 + } + }, + "left": { + "type": "Identifier", + "start": 52, + "end": 53, + "loc": { + "start": { + "line": 3, + "column": 10 + }, + "end": { + "line": 3, + "column": 11 + } + }, + "name": "x" + }, + "operator": "<", + "right": { + "type": "Literal", + "start": 56, + "end": 57, + "loc": { + "start": { + "line": 3, + "column": 14 + }, + "end": { + "line": 3, + "column": 15 + } + }, + "value": 5, + "raw": "5" + } + }, + "consequent": { + "type": "Fragment", + "nodes": [ + { + "type": "Text", + "start": 58, + "end": 60, + "raw": "\n\t", + "data": "\n\t" + }, + { + "type": "RegularElement", + "start": 60, + "end": 83, + "name": "p", + "attributes": [], + "fragment": { + "type": "Fragment", + "nodes": [ + { + "type": "Text", + "start": 63, + "end": 79, + "raw": "x is less than 5", + "data": "x is less than 5" + } + ], + "transparent": true + } + }, + { + "type": "Text", + "start": 83, + "end": 84, + "raw": "\n", + "data": "\n" + } + ], + "transparent": false + }, + "alternate": null + } + ], + "transparent": false + } + } + ], + "transparent": false + }, + "options": null +} diff --git a/packages/svelte/tests/parser-modern/samples/if-block/input.svelte b/packages/svelte/tests/parser-modern/samples/if-block/input.svelte new file mode 100644 index 0000000000..5851347a88 --- /dev/null +++ b/packages/svelte/tests/parser-modern/samples/if-block/input.svelte @@ -0,0 +1 @@ +{#if foo}bar{/if} diff --git a/packages/svelte/tests/parser-modern/samples/if-block/output.json b/packages/svelte/tests/parser-modern/samples/if-block/output.json new file mode 100644 index 0000000000..965f2b5614 --- /dev/null +++ b/packages/svelte/tests/parser-modern/samples/if-block/output.json @@ -0,0 +1,50 @@ +{ + "css": null, + "js": [], + "start": 0, + "end": 17, + "type": "Root", + "fragment": { + "type": "Fragment", + "nodes": [ + { + "type": "IfBlock", + "elseif": false, + "start": 0, + "end": 17, + "test": { + "type": "Identifier", + "start": 5, + "end": 8, + "loc": { + "start": { + "line": 1, + "column": 5 + }, + "end": { + "line": 1, + "column": 8 + } + }, + "name": "foo" + }, + "consequent": { + "type": "Fragment", + "nodes": [ + { + "type": "Text", + "start": 9, + "end": 12, + "raw": "bar", + "data": "bar" + } + ], + "transparent": false + }, + "alternate": null + } + ], + "transparent": false + }, + "options": null +}