Skip to content

feat: remove svelteStrictMode option #462

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 2 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,29 +94,6 @@ Format: join the keywords `options`, `scripts`, `markup`, `styles` with a `-` in

> 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`).

### Svelte Strict Mode

More strict HTML syntax: Quotes in attributes and no self-closing DOM elements (except void elements).

> In version 2 this overruled `svelteAllowShorthand`, which is no longer the case.

> In Svelte 5, attributes are never quoted, because this will mean "stringify this attribute value" in a future Svelte version

Example:

<!-- prettier-ignore -->
```html
<!-- svelteStrictMode: true -->
<div foo={bar}></div>

<!-- svelteStrictMode: false -->
<div foo={bar} />
```

| Default | CLI Override | API Override |
| ------- | ----------------------------- | -------------------------- |
| `false` | `--svelte-strict-mode <bool>` | `svelteStrictMode: <bool>` |

### Svelte Allow Shorthand

Option to enable/disable component attribute shorthand if attribute name and expression are same.
Expand Down Expand Up @@ -190,7 +167,6 @@ Whether or not to indent the code inside `<script>` and `<style>` tags in Svelte
```json
{
"svelteSortOrder": "options-styles-scripts-markup",
"svelteStrictMode": true,
"svelteBracketNewLine": false,
"svelteAllowShorthand": false,
"svelteIndentScriptAndStyle": false
Expand Down Expand Up @@ -233,6 +209,8 @@ Usage in the browser is semi-supported. You can import the plugin from `prettier

Upgrade to Svelte 5 before upgrading to `prettier-plugin-svelte@4`, as it doesn't support older Svelte versions.

`svelteStrictMode` option has been removed. Attributes are now never quoted, because this will mean "stringify this attribute value" in a future Svelte version.

## FAQ

### Why is the closing or opening tag (`>` or `<`) hugging the inner tag or text?
Expand Down
1 change: 0 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Config } from 'prettier';

export interface PluginConfig {
svelteSortOrder?: SortOrder;
svelteStrictMode?: boolean;
svelteBracketNewLine?: boolean;
svelteAllowShorthand?: boolean;
svelteIndentScriptAndStyle?: boolean;
Expand Down
18 changes: 2 additions & 16 deletions src/embed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,7 @@ export function embed(path: AstPath, _options: Options) {
// check the parent to see if we are inside an expression that should be embedded.
const parent: Node = path.getParentNode();
const printJsExpression = () =>
(parent as any).expression
? printJS(
parent,
(options.svelteStrictMode && !options._svelte_is5Plus) ?? false,
false,
false,
'expression',
)
: undefined;
(parent as any).expression ? printJS(parent, false, false, false, 'expression') : undefined;
const printSvelteBlockJS = (name: string) => printJS(parent, false, true, false, name);

switch (parent.type) {
Expand Down Expand Up @@ -116,13 +108,7 @@ export function embed(path: AstPath, _options: Options) {
}
break;
case 'Element':
printJS(
parent,
(options.svelteStrictMode && !options._svelte_is5Plus) ?? false,
false,
false,
'tag',
);
printJS(parent, false, false, false, 'tag');
break;
case 'MustacheTag':
printJS(parent, isInsideQuotedAttribute(path, options), false, false, 'expression');
Expand Down
5 changes: 1 addition & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { ParserOptions } from './options';

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

function locStart(node: any) {
return node.start;
Expand Down Expand Up @@ -56,9 +55,7 @@ export const parsers: Record<string, Parser> = {
// inside markdown), the originalText is not updated after preprocessing.
// Therefore we do it ourselves here.
options.originalText = text;
// Only Svelte 5 can have TS in the template
options._svelte_ts = isSvelte5Plus && result.isTypescript;
options._svelte_is5Plus = isSvelte5Plus;
options._svelte_ts = result.isTypescript;
return text;
},
locStart,
Expand Down
15 changes: 0 additions & 15 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@ import { SortOrder, PluginConfig } from '..';
export interface ParserOptions<T = any> extends PrettierParserOptions<T>, Partial<PluginConfig> {
_svelte_ts?: boolean;
_svelte_asFunction?: boolean;
/**
* Used for
* - deciding what quote behavior to use in the printer:
* A future version of Svelte treats quoted expressions as strings, so never use quotes in that case.
* Since Svelte 5 does still treat them equally, it's safer to remove quotes in all cases and in a future
* version of this plugin instead leave it up to the user to decide.
*/
_svelte_is5Plus?: boolean;
}

function makeChoice(choice: string) {
Expand Down Expand Up @@ -53,13 +45,6 @@ export const options: Record<keyof PluginConfig, SupportOption> = {
],
},
// todo: remove in v4
svelteStrictMode: {
category: 'Svelte',
type: 'boolean',
default: false,
description: 'More strict HTML syntax: Quotes in attributes, no self-closing DOM tags',
},
// todo: remove in v4
svelteBracketNewLine: {
category: 'Svelte',
type: 'boolean',
Expand Down
15 changes: 4 additions & 11 deletions src/print/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ export function print(path: AstPath, options: ParserOptions, print: PrintFn): Do
return printTopLevelParts(n, options, path, print);
}

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

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

const isSelfClosingTag =
isEmpty &&
((((node.type === 'Element' && !options.svelteStrictMode) ||
(((node.type === 'Element' ||
Comment on lines 212 to +214
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will follow up with a PR forcing correct closing type.

node.type === 'Head' ||
node.type === 'InlineComponent' ||
node.type === 'Slot' ||
Expand Down Expand Up @@ -446,9 +445,7 @@ export function print(path: AstPath, options: ParserOptions, print: PrintFn): Do
return [node.name];
}

const quotes =
!isLoneMustacheTag(node.value) ||
((options.svelteStrictMode && !options._svelte_is5Plus) ?? false);
const quotes = !isLoneMustacheTag(node.value);
const attrNodeValue = printAttributeNodeValue(path, print, quotes, node);
if (quotes) {
return [node.name, '=', '"', attrNodeValue, '"'];
Expand Down Expand Up @@ -605,7 +602,6 @@ export function print(path: AstPath, options: ParserOptions, print: PrintFn): Do
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}');
Expand Down Expand Up @@ -652,9 +648,7 @@ export function print(path: AstPath, options: ParserOptions, print: PrintFn): Do
return [...prefix, `=${open}`, node.name, close];
}
} else {
const quotes =
!isLoneMustacheTag(node.value) ||
((options.svelteStrictMode && !options._svelte_is5Plus) ?? false);
const quotes = !isLoneMustacheTag(node.value);
const attrNodeValue = printAttributeNodeValue(path, print, quotes, node);
if (quotes) {
return [...prefix, '=', '"', attrNodeValue, '"'];
Expand Down Expand Up @@ -721,7 +715,6 @@ export function print(path: AstPath, options: ParserOptions, print: PrintFn): Do
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;
Expand Down
3 changes: 1 addition & 2 deletions src/print/node-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -535,8 +535,7 @@ export function isInsideQuotedAttribute(path: AstPath, options: ParserOptions):
return stack.some(
(node) =>
(node.type === 'Attribute' || node.type === 'StyleDirective') &&
(!isLoneMustacheTag(node.value) ||
(options.svelteStrictMode && !options._svelte_is5Plus)),
!isLoneMustacheTag(node.value),
);
}

Expand Down
5 changes: 0 additions & 5 deletions test/formatting/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import { format } from 'prettier';
import { VERSION } from 'svelte/compiler';
import * as SveltePlugin from '../../src';

const isSvelte5Plus = Number(VERSION.split('.')[0]) >= 5;

let dirs = readdirSync('test/formatting/samples');
const printerFilesHaveOnly = readdirSync('test/printer/samples').some(
(f) => f.endsWith('.only.html') || f.endsWith('.only.md'),
Expand All @@ -29,9 +27,6 @@ for (const dir of dirs) {
).replace(/\r?\n/g, '\n');
const options = readOptions(`test/formatting/samples/${dir}/options.json`);

// Tests attribute quoting changes, which are different in Svelte 5
if (dir.endsWith('strict-mode-true') && isSvelte5Plus) continue;

test(`formatting: ${dir}`, async (t) => {
let onTestCompleted;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
<svelte:component this="{foo}" />
<input value="{foo}" />
<input value={foo} />
<input bind:value="{foo}" />
<input bind:value={foo} />
<input class:value="{foo}" />
<input class:value={foo} />
<input style:value="{foo}" />
<input style:value={foo} />

<svelte:component this="{foo}" />
<div style="width: {width}px"></div>

<div class:awesome="{isOk}"></div>

<div class="asd {otherclass + 'b'}"></div>

<input bind:value="{fooValue}" on:change="{onChange}" />

<a use:link="{linkValues + 'asd'}">Link</a>

<a href="{linkValues + 'asd'}">Link</a>

<button on:click="{() => console.log('hi')}">hi</button>

<div in:asd="{foo + 'bar'}" out:asd="{foo + 'bar'}"></div>

<div transistion:asd="{foo + 'bar'}"></div>

<div animate:asd="{foo + 'bar'}"></div>

<div />
<div></div>
<Component />
<Component></Component>
25 changes: 25 additions & 0 deletions test/formatting/samples/attribute-remove-quotes/output.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<input value={foo} />
<input value={foo} />
<input bind:value={foo} />
<input bind:value={foo} />
<input class:value={foo} />
<input class:value={foo} />
<input style:value={foo} />
<input style:value={foo} />

<svelte:component this={foo} />
<div style="width: {width}px"></div>
<div class:awesome={isOk}></div>
<div class="asd {otherclass + 'b'}"></div>
<input bind:value={fooValue} on:change={onChange} />
<a use:link={linkValues + "asd"}>Link</a>
<a href={linkValues + "asd"}>Link</a>
<button on:click={() => console.log("hi")}>hi</button>
<div in:asd={foo + "bar"} out:asd={foo + "bar"}></div>
<div transistion:asd={foo + "bar"}></div>
<div animate:asd={foo + "bar"}></div>

<div />
<div></div>
<Component />
<Component></Component>
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,3 @@
<input style:value />
<input style:value={value} />
<input style:value="{value}" />

<input value="{foo}" />
<input value={foo} />
<input bind:value="{foo}" />
<input bind:value={foo} />
<input class:value="{foo}" />
<input class:value={foo} />
<input style:value="{foo}" />
<input style:value={foo} />

<div />
<div></div>
<Component />
<Component></Component>
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,3 @@
<input style:value />
<input style:value />
<input style:value />

<input value={foo} />
<input value={foo} />
<input bind:value={foo} />
<input bind:value={foo} />
<input class:value={foo} />
<input class:value={foo} />
<input style:value={foo} />
<input style:value={foo} />

<div />
<div></div>
<Component />
<Component></Component>
28 changes: 0 additions & 28 deletions test/formatting/samples/strict-mode-true/input.html

This file was deleted.

3 changes: 0 additions & 3 deletions test/formatting/samples/strict-mode-true/options.json

This file was deleted.

28 changes: 0 additions & 28 deletions test/formatting/samples/strict-mode-true/output.html

This file was deleted.

5 changes: 0 additions & 5 deletions test/printer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import { format } from 'prettier';
import { VERSION } from 'svelte/compiler';
import * as SveltePlugin from '../../src';

const isSvelte5Plus = Number(VERSION.split('.')[0]) >= 5;

let files = readdirSync('test/printer/samples').filter(
(name) => name.endsWith('.html') || name.endsWith('.md'),
);
Expand All @@ -27,9 +25,6 @@ for (const file of files) {
`test/printer/samples/${file.replace('.only', '').replace(`.${ending}`, '.options.json')}`,
);

// Tests attribute quoting changes, which are different in Svelte 5
if (file.endsWith('attribute-quoted.html') && isSvelte5Plus) continue;

test(`printer: ${file.slice(0, file.length - `.${ending}`.length)}`, async (t) => {
const actualOutput = await format(input, {
parser: ending === 'html' ? 'svelte' : 'markdown',
Expand Down
Loading
Loading