Skip to content

Commit 94b5a07

Browse files
authored
breaking: remove svelteStrictMode option (#462)
Svelte 5 no longer needs this option: - quoting is decided by prettier completely as there's no two ways of doing the same anymore - more strict closing tag behavior will mean we also have no two way of doing the same here, too, soon
1 parent 81f8f0d commit 94b5a07

21 files changed

+49
-193
lines changed

README.md

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -94,29 +94,6 @@ Format: join the keywords `options`, `scripts`, `markup`, `styles` with a `-` in
9494

9595
> The `options` order option only exists since version 2. If you use version 1 of `prettier-plugin-svelte`, omit that option (so for example only write `scripts-markup-styles`).
9696
97-
### Svelte Strict Mode
98-
99-
More strict HTML syntax: Quotes in attributes and no self-closing DOM elements (except void elements).
100-
101-
> In version 2 this overruled `svelteAllowShorthand`, which is no longer the case.
102-
103-
> In Svelte 5, attributes are never quoted, because this will mean "stringify this attribute value" in a future Svelte version
104-
105-
Example:
106-
107-
<!-- prettier-ignore -->
108-
```html
109-
<!-- svelteStrictMode: true -->
110-
<div foo={bar}></div>
111-
112-
<!-- svelteStrictMode: false -->
113-
<div foo={bar} />
114-
```
115-
116-
| Default | CLI Override | API Override |
117-
| ------- | ----------------------------- | -------------------------- |
118-
| `false` | `--svelte-strict-mode <bool>` | `svelteStrictMode: <bool>` |
119-
12097
### Svelte Allow Shorthand
12198

12299
Option to enable/disable component attribute shorthand if attribute name and expression are same.
@@ -190,7 +167,6 @@ Whether or not to indent the code inside `<script>` and `<style>` tags in Svelte
190167
```json
191168
{
192169
"svelteSortOrder": "options-styles-scripts-markup",
193-
"svelteStrictMode": true,
194170
"svelteBracketNewLine": false,
195171
"svelteAllowShorthand": false,
196172
"svelteIndentScriptAndStyle": false
@@ -233,6 +209,8 @@ Usage in the browser is semi-supported. You can import the plugin from `prettier
233209
234210
Upgrade to Svelte 5 before upgrading to `prettier-plugin-svelte@4`, as it doesn't support older Svelte versions.
235211

212+
`svelteStrictMode` option has been removed. Attributes are now never quoted, because this will mean "stringify this attribute value" in a future Svelte version.
213+
236214
## FAQ
237215

238216
### Why is the closing or opening tag (`>` or `<`) hugging the inner tag or text?

index.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { Config } from 'prettier';
22

33
export interface PluginConfig {
44
svelteSortOrder?: SortOrder;
5-
svelteStrictMode?: boolean;
65
svelteBracketNewLine?: boolean;
76
svelteAllowShorthand?: boolean;
87
svelteIndentScriptAndStyle?: boolean;

src/embed.ts

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,7 @@ export function embed(path: AstPath, _options: Options) {
7777
// check the parent to see if we are inside an expression that should be embedded.
7878
const parent: Node = path.getParentNode();
7979
const printJsExpression = () =>
80-
(parent as any).expression
81-
? printJS(
82-
parent,
83-
(options.svelteStrictMode && !options._svelte_is5Plus) ?? false,
84-
false,
85-
false,
86-
'expression',
87-
)
88-
: undefined;
80+
(parent as any).expression ? printJS(parent, false, false, false, 'expression') : undefined;
8981
const printSvelteBlockJS = (name: string) => printJS(parent, false, true, false, name);
9082

9183
switch (parent.type) {
@@ -116,13 +108,7 @@ export function embed(path: AstPath, _options: Options) {
116108
}
117109
break;
118110
case 'Element':
119-
printJS(
120-
parent,
121-
(options.svelteStrictMode && !options._svelte_is5Plus) ?? false,
122-
false,
123-
false,
124-
'tag',
125-
);
111+
printJS(parent, false, false, false, 'tag');
126112
break;
127113
case 'MustacheTag':
128114
printJS(parent, isInsideQuotedAttribute(path, options), false, false, 'expression');

src/index.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { ParserOptions } from './options';
99

1010
const babelParser = prettierPluginBabel.parsers.babel;
1111
const typescriptParser = prettierPluginBabel.parsers['babel-ts']; // TODO use TypeScript parser in next major?
12-
const isSvelte5Plus = Number(VERSION.split('.')[0]) >= 5;
1312

1413
function locStart(node: any) {
1514
return node.start;
@@ -56,9 +55,7 @@ export const parsers: Record<string, Parser> = {
5655
// inside markdown), the originalText is not updated after preprocessing.
5756
// Therefore we do it ourselves here.
5857
options.originalText = text;
59-
// Only Svelte 5 can have TS in the template
60-
options._svelte_ts = isSvelte5Plus && result.isTypescript;
61-
options._svelte_is5Plus = isSvelte5Plus;
58+
options._svelte_ts = result.isTypescript;
6259
return text;
6360
},
6461
locStart,

src/options.ts

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,6 @@ import { SortOrder, PluginConfig } from '..';
44
export interface ParserOptions<T = any> extends PrettierParserOptions<T>, Partial<PluginConfig> {
55
_svelte_ts?: boolean;
66
_svelte_asFunction?: boolean;
7-
/**
8-
* Used for
9-
* - deciding what quote behavior to use in the printer:
10-
* A future version of Svelte treats quoted expressions as strings, so never use quotes in that case.
11-
* Since Svelte 5 does still treat them equally, it's safer to remove quotes in all cases and in a future
12-
* version of this plugin instead leave it up to the user to decide.
13-
*/
14-
_svelte_is5Plus?: boolean;
157
}
168

179
function makeChoice(choice: string) {
@@ -53,13 +45,6 @@ export const options: Record<keyof PluginConfig, SupportOption> = {
5345
],
5446
},
5547
// todo: remove in v4
56-
svelteStrictMode: {
57-
category: 'Svelte',
58-
type: 'boolean',
59-
default: false,
60-
description: 'More strict HTML syntax: Quotes in attributes, no self-closing DOM tags',
61-
},
62-
// todo: remove in v4
6348
svelteBracketNewLine: {
6449
category: 'Svelte',
6550
type: 'boolean',

src/print/index.ts

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,7 @@ export function print(path: AstPath, options: ParserOptions, print: PrintFn): Do
8888
return printTopLevelParts(n, options, path, print);
8989
}
9090

91-
const [open, close] =
92-
options.svelteStrictMode && !options._svelte_is5Plus ? ['"{', '}"'] : ['{', '}'];
91+
const [open, close] = ['{', '}'];
9392
const printJsExpression = () => [open, printJS(path, print, 'expression'), close];
9493
const node = n as Node;
9594

@@ -212,7 +211,7 @@ export function print(path: AstPath, options: ParserOptions, print: PrintFn): Do
212211

213212
const isSelfClosingTag =
214213
isEmpty &&
215-
((((node.type === 'Element' && !options.svelteStrictMode) ||
214+
(((node.type === 'Element' ||
216215
node.type === 'Head' ||
217216
node.type === 'InlineComponent' ||
218217
node.type === 'Slot' ||
@@ -446,9 +445,7 @@ export function print(path: AstPath, options: ParserOptions, print: PrintFn): Do
446445
return [node.name];
447446
}
448447

449-
const quotes =
450-
!isLoneMustacheTag(node.value) ||
451-
((options.svelteStrictMode && !options._svelte_is5Plus) ?? false);
448+
const quotes = !isLoneMustacheTag(node.value);
452449
const attrNodeValue = printAttributeNodeValue(path, print, quotes, node);
453450
if (quotes) {
454451
return [node.name, '=', '"', attrNodeValue, '"'];
@@ -605,7 +602,6 @@ export function print(path: AstPath, options: ParserOptions, print: PrintFn): Do
605602
case 'PendingBlock':
606603
case 'CatchBlock':
607604
return printSvelteBlockChildren(path, print, options);
608-
// Svelte 5 only
609605
case 'SnippetBlock': {
610606
const snippet = ['{#snippet ', printJS(path, print, 'expression')];
611607
snippet.push('}', printSvelteBlockChildren(path, print, options), '{/snippet}');
@@ -652,9 +648,7 @@ export function print(path: AstPath, options: ParserOptions, print: PrintFn): Do
652648
return [...prefix, `=${open}`, node.name, close];
653649
}
654650
} else {
655-
const quotes =
656-
!isLoneMustacheTag(node.value) ||
657-
((options.svelteStrictMode && !options._svelte_is5Plus) ?? false);
651+
const quotes = !isLoneMustacheTag(node.value);
658652
const attrNodeValue = printAttributeNodeValue(path, print, quotes, node);
659653
if (quotes) {
660654
return [...prefix, '=', '"', attrNodeValue, '"'];
@@ -721,7 +715,6 @@ export function print(path: AstPath, options: ParserOptions, print: PrintFn): Do
721715
return ['animate:', node.name, node.expression ? ['=', ...printJsExpression()] : ''];
722716
case 'RawMustacheTag':
723717
return ['{@html ', printJS(path, print, 'expression'), '}'];
724-
// Svelte 5 only
725718
case 'RenderTag': {
726719
const render = ['{@render ', printJS(path, print, 'expression'), '}'];
727720
return render;

src/print/node-helpers.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -535,8 +535,7 @@ export function isInsideQuotedAttribute(path: AstPath, options: ParserOptions):
535535
return stack.some(
536536
(node) =>
537537
(node.type === 'Attribute' || node.type === 'StyleDirective') &&
538-
(!isLoneMustacheTag(node.value) ||
539-
(options.svelteStrictMode && !options._svelte_is5Plus)),
538+
!isLoneMustacheTag(node.value),
540539
);
541540
}
542541

test/formatting/index.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import { format } from 'prettier';
44
import { VERSION } from 'svelte/compiler';
55
import * as SveltePlugin from '../../src';
66

7-
const isSvelte5Plus = Number(VERSION.split('.')[0]) >= 5;
8-
97
let dirs = readdirSync('test/formatting/samples');
108
const printerFilesHaveOnly = readdirSync('test/printer/samples').some(
119
(f) => f.endsWith('.only.html') || f.endsWith('.only.md'),
@@ -29,9 +27,6 @@ for (const dir of dirs) {
2927
).replace(/\r?\n/g, '\n');
3028
const options = readOptions(`test/formatting/samples/${dir}/options.json`);
3129

32-
// Tests attribute quoting changes, which are different in Svelte 5
33-
if (dir.endsWith('strict-mode-true') && isSvelte5Plus) continue;
34-
3530
test(`formatting: ${dir}`, async (t) => {
3631
let onTestCompleted;
3732

Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
1-
<svelte:component this="{foo}" />
1+
<input value="{foo}" />
2+
<input value={foo} />
3+
<input bind:value="{foo}" />
4+
<input bind:value={foo} />
5+
<input class:value="{foo}" />
6+
<input class:value={foo} />
7+
<input style:value="{foo}" />
8+
<input style:value={foo} />
29

10+
<svelte:component this="{foo}" />
311
<div style="width: {width}px"></div>
4-
512
<div class:awesome="{isOk}"></div>
6-
713
<div class="asd {otherclass + 'b'}"></div>
8-
914
<input bind:value="{fooValue}" on:change="{onChange}" />
10-
1115
<a use:link="{linkValues + 'asd'}">Link</a>
12-
1316
<a href="{linkValues + 'asd'}">Link</a>
14-
1517
<button on:click="{() => console.log('hi')}">hi</button>
16-
1718
<div in:asd="{foo + 'bar'}" out:asd="{foo + 'bar'}"></div>
18-
1919
<div transistion:asd="{foo + 'bar'}"></div>
20-
2120
<div animate:asd="{foo + 'bar'}"></div>
21+
22+
<div />
23+
<div></div>
24+
<Component />
25+
<Component></Component>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<input value={foo} />
2+
<input value={foo} />
3+
<input bind:value={foo} />
4+
<input bind:value={foo} />
5+
<input class:value={foo} />
6+
<input class:value={foo} />
7+
<input style:value={foo} />
8+
<input style:value={foo} />
9+
10+
<svelte:component this={foo} />
11+
<div style="width: {width}px"></div>
12+
<div class:awesome={isOk}></div>
13+
<div class="asd {otherclass + 'b'}"></div>
14+
<input bind:value={fooValue} on:change={onChange} />
15+
<a use:link={linkValues + "asd"}>Link</a>
16+
<a href={linkValues + "asd"}>Link</a>
17+
<button on:click={() => console.log("hi")}>hi</button>
18+
<div in:asd={foo + "bar"} out:asd={foo + "bar"}></div>
19+
<div transistion:asd={foo + "bar"}></div>
20+
<div animate:asd={foo + "bar"}></div>
21+
22+
<div />
23+
<div></div>
24+
<Component />
25+
<Component></Component>

test/formatting/samples/strict-mode-false/input.html renamed to test/formatting/samples/attribute-shorthand/input.html

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,3 @@
1212
<input style:value />
1313
<input style:value={value} />
1414
<input style:value="{value}" />
15-
16-
<input value="{foo}" />
17-
<input value={foo} />
18-
<input bind:value="{foo}" />
19-
<input bind:value={foo} />
20-
<input class:value="{foo}" />
21-
<input class:value={foo} />
22-
<input style:value="{foo}" />
23-
<input style:value={foo} />
24-
25-
<div />
26-
<div></div>
27-
<Component />
28-
<Component></Component>

test/formatting/samples/strict-mode-false/output.html renamed to test/formatting/samples/attribute-shorthand/output.html

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,3 @@
1212
<input style:value />
1313
<input style:value />
1414
<input style:value />
15-
16-
<input value={foo} />
17-
<input value={foo} />
18-
<input bind:value={foo} />
19-
<input bind:value={foo} />
20-
<input class:value={foo} />
21-
<input class:value={foo} />
22-
<input style:value={foo} />
23-
<input style:value={foo} />
24-
25-
<div />
26-
<div></div>
27-
<Component />
28-
<Component></Component>

test/formatting/samples/strict-mode-true/input.html

Lines changed: 0 additions & 28 deletions
This file was deleted.

test/formatting/samples/strict-mode-true/options.json

Lines changed: 0 additions & 3 deletions
This file was deleted.

test/formatting/samples/strict-mode-true/output.html

Lines changed: 0 additions & 28 deletions
This file was deleted.

test/printer/index.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import { format } from 'prettier';
44
import { VERSION } from 'svelte/compiler';
55
import * as SveltePlugin from '../../src';
66

7-
const isSvelte5Plus = Number(VERSION.split('.')[0]) >= 5;
8-
97
let files = readdirSync('test/printer/samples').filter(
108
(name) => name.endsWith('.html') || name.endsWith('.md'),
119
);
@@ -27,9 +25,6 @@ for (const file of files) {
2725
`test/printer/samples/${file.replace('.only', '').replace(`.${ending}`, '.options.json')}`,
2826
);
2927

30-
// Tests attribute quoting changes, which are different in Svelte 5
31-
if (file.endsWith('attribute-quoted.html') && isSvelte5Plus) continue;
32-
3328
test(`printer: ${file.slice(0, file.length - `.${ending}`.length)}`, async (t) => {
3429
const actualOutput = await format(input, {
3530
parser: ending === 'html' ? 'svelte' : 'markdown',

0 commit comments

Comments
 (0)