diff --git a/.changeset/plenty-moments-grab.md b/.changeset/plenty-moments-grab.md new file mode 100644 index 000000000..91cfd4c42 --- /dev/null +++ b/.changeset/plenty-moments-grab.md @@ -0,0 +1,5 @@ +--- +'svelte-language-server': patch +--- + +fix: always treat a script tag as top-level if it's the first tag in the file diff --git a/packages/language-server/src/lib/documents/utils.ts b/packages/language-server/src/lib/documents/utils.ts index 374fdb07a..d37987244 100644 --- a/packages/language-server/src/lib/documents/utils.ts +++ b/packages/language-server/src/lib/documents/utils.ts @@ -72,6 +72,15 @@ function extractTags( * If that is BEFORE `{#X`, we are inside a moustache tag. */ function isNotInsideControlFlowTag(tag: Node) { + const tagIndex = rootNodes.indexOf(tag); + // Quick check: if the tag has nothing before it, it can't be inside a control flow tag + // This also works around a case where the tag is treated as under a control flow tag when vscode-html-languageservice parses something wrong + if (tagIndex === 0) { + const startContent = text.substring(0, tag.start); + if (startContent.trim() === '') { + return true; + } + } const nodes = rootNodes.slice(rootNodes.indexOf(tag)); const rootContentAfterTag = nodes .map((node, idx) => { diff --git a/packages/language-server/test/lib/documents/utils.test.ts b/packages/language-server/test/lib/documents/utils.test.ts index a54b8b53e..509212020 100644 --- a/packages/language-server/test/lib/documents/utils.test.ts +++ b/packages/language-server/test/lib/documents/utils.test.ts @@ -50,7 +50,7 @@ describe('document/utils', () => { assert.deepStrictEqual(extractStyleTag(text), null); }); - it('is canse sensitive to style/script', () => { + it('is case sensitive to style/script', () => { const text = ` @@ -344,6 +344,20 @@ describe('document/utils', () => { container: { start: 151, end: 181 } }); }); + + it('extract tag correctly if nothing is before the tag', () => { + const text = ` + {/if}`; + assert.deepStrictEqual(extractScriptTags(text)?.script, { + content: 'let value = 2', + attributes: {}, + start: 8, + end: 21, + startPos: Position.create(0, 8), + endPos: Position.create(0, 21), + container: { start: 0, end: 30 } + }); + }); }); describe('#getLineAtPosition', () => {