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', () => {