diff --git a/CHANGELOG.md b/CHANGELOG.md index 665efd01..7967ee66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # prettier-plugin-svelte changelog +## 3.1.0 + +- (feat) add experimental support for Svelte 5 +- (feat) support `#snippet` and `@render` + ## 3.0.3 - (fix) handle static `tag` attributes on `` diff --git a/package-lock.json b/package-lock.json index 24007618..2a6a77b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "prettier-plugin-svelte", - "version": "3.0.3", + "version": "3.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "prettier-plugin-svelte", - "version": "3.0.3", + "version": "3.1.0", "license": "MIT", "devDependencies": { "@rollup/plugin-commonjs": "14.0.0", @@ -23,7 +23,7 @@ }, "peerDependencies": { "prettier": "^3.0.0", - "svelte": "^3.2.0 || ^4.0.0-next.0" + "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" } }, "node_modules/@babel/code-frame": { @@ -3256,9 +3256,9 @@ } }, "node_modules/svelte": { - "version": "3.59.1", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.59.1.tgz", - "integrity": "sha512-pKj8fEBmqf6mq3/NfrB9SLtcJcUvjYSWyePlfCqN9gujLB25RitWK8PvFzlwim6hD/We35KbPlRteuA6rnPGcQ==", + "version": "3.59.2", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.59.2.tgz", + "integrity": "sha512-vzSyuGr3eEoAtT/A6bmajosJZIUWySzY2CzB3w2pgPvnkUjGqlDnsNnA0PMO+mMAhuyMul6C2uuZzY6ELSkzyA==", "dev": true, "engines": { "node": ">= 8" diff --git a/package.json b/package.json index e7d05c8e..84ef685b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prettier-plugin-svelte", - "version": "3.0.3", + "version": "3.1.0", "description": "Svelte plugin for prettier", "main": "plugin.js", "files": [ @@ -51,6 +51,6 @@ }, "peerDependencies": { "prettier": "^3.0.0", - "svelte": "^3.2.0 || ^4.0.0-next.0" + "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" } } diff --git a/src/embed.ts b/src/embed.ts index 009472d2..4c433b5e 100644 --- a/src/embed.ts +++ b/src/embed.ts @@ -91,6 +91,18 @@ export function embed(path: FastPath, _options: Options) { printSvelteBlockJS('expression'); printSvelteBlockJS('key'); break; + case 'SnippetBlock': + // We merge the two parts into one expression, which future-proofs this for template TS support + if (node === parent.expression) { + parent.expression.end = + options.originalText.indexOf( + ')', + parent.context?.end ?? parent.expression.end, + ) + 1; + parent.context = null; + printSvelteBlockJS('expression'); + } + break; case 'Element': printJS(parent, options.svelteStrictMode ?? false, false, false, 'tag'); break; @@ -106,6 +118,18 @@ export function embed(path: FastPath, _options: Options) { case 'ConstTag': printJS(parent, false, false, true, 'expression'); break; + case 'RenderTag': + // We merge the two parts into one expression, which future-proofs this for template TS support + if (node === parent.expression) { + parent.expression.end = + options.originalText.indexOf( + ')', + parent.argument?.end ?? parent.expression.end, + ) + 1; + parent.argument = null; + printJS(parent, false, false, false, 'expression'); + } + break; case 'EventHandler': case 'Binding': case 'Class': diff --git a/src/print/index.ts b/src/print/index.ts index 9615de05..654a2d8c 100644 --- a/src/print/index.ts +++ b/src/print/index.ts @@ -607,6 +607,12 @@ export function print(path: FastPath, options: ParserOptions, print: PrintFn): D case 'PendingBlock': case 'CatchBlock': return printSvelteBlockChildren(path, print, options); + // Svelte 5 only + case 'SnippetBlock': { + const snippet = ['{#snippet ', printJS(path, print, 'expression')]; + snippet.push('}', printSvelteBlockChildren(path, print, options), '{/snippet}'); + return snippet; + } case 'EventHandler': return [ 'on:', @@ -718,6 +724,11 @@ export function print(path: FastPath, options: ParserOptions, print: PrintFn): D return ['animate:', node.name, node.expression ? ['=', ...printJsExpression()] : '']; case 'RawMustacheTag': return ['{@html ', printJS(path, print, 'expression'), '}']; + // Svelte 5 only + case 'RenderTag': { + const render = ['{@render ', printJS(path, print, 'expression'), '}']; + return render; + } case 'Spread': return ['{...', printJS(path, print, 'expression'), '}']; case 'ConstTag': diff --git a/src/print/node-helpers.ts b/src/print/node-helpers.ts index 1e388918..7ee1b632 100644 --- a/src/print/node-helpers.ts +++ b/src/print/node-helpers.ts @@ -60,6 +60,7 @@ export function isSvelteBlock( | ThenBlockNode { return [ 'IfBlock', + 'SnippetBlock', 'AwaitBlock', 'CatchBlock', 'EachBlock', diff --git a/src/print/nodes.ts b/src/print/nodes.ts index 48c247ac..b5e56b55 100644 --- a/src/print/nodes.ts +++ b/src/print/nodes.ts @@ -291,6 +291,19 @@ export interface CommentInfo { emptyLineAfter: boolean; } +export interface SnippetBlock extends BaseNode { + type: 'SnippetBlock'; + expression: IdentifierNode; + context: null | any; + children: Node[]; +} + +export interface RenderTag extends BaseNode { + type: 'RenderTag'; + expression: IdentifierNode; + argument: null | any; +} + export type Node = | FragmentNode | ElementNode @@ -335,7 +348,9 @@ export type Node = | DocumentNode | OptionsNode | SlotTemplateNode - | ConstTagNode; + | ConstTagNode + | RenderTag + | SnippetBlock; /** * The Svelte AST root node diff --git a/test/formatting/samples/move-options-to-top/input.html b/test/formatting/samples/move-options-to-top/input.html index 85f134dc..c76a3624 100644 --- a/test/formatting/samples/move-options-to-top/input.html +++ b/test/formatting/samples/move-options-to-top/input.html @@ -2,7 +2,7 @@

hi

- +

some stuff

diff --git a/test/formatting/samples/move-options-to-top/output.html b/test/formatting/samples/move-options-to-top/output.html index 41e5138c..34773b8d 100644 --- a/test/formatting/samples/move-options-to-top/output.html +++ b/test/formatting/samples/move-options-to-top/output.html @@ -1,4 +1,4 @@ - + diff --git a/test/printer/samples/snippet.html.skip b/test/printer/samples/snippet.html.skip new file mode 100644 index 00000000..f0f25473 --- /dev/null +++ b/test/printer/samples/snippet.html.skip @@ -0,0 +1,10 @@ +{#snippet foo()} +

foo

+{/snippet} + +{#snippet bar({ a, b })} +

bar

+{/snippet} + +{@render foo()} +{@render bar(x)} diff --git a/test/printer/samples/svelte-options-element.html b/test/printer/samples/svelte-options-element.html index d21bc7b0..61d87ebd 100644 --- a/test/printer/samples/svelte-options-element.html +++ b/test/printer/samples/svelte-options-element.html @@ -1 +1 @@ - +