From fe41b1ca23afc3ff12a730f245c0190910fc251f Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Mon, 10 Oct 2022 12:46:58 +0200 Subject: [PATCH] (feat) add `svelteSortOrder: none` Closes #314 --- CHANGELOG.md | 1 + src/embed.ts | 2 +- src/options.ts | 6 ++ src/print/index.ts | 56 +++++++++++++++---- test/printer/samples/sort-order-none.html | 23 ++++++++ .../samples/sort-order-none.options.json | 3 + test/printer/samples/sort-order-none2.html | 23 ++++++++ .../samples/sort-order-none2.options.json | 3 + 8 files changed, 106 insertions(+), 11 deletions(-) create mode 100644 test/printer/samples/sort-order-none.html create mode 100644 test/printer/samples/sort-order-none.options.json create mode 100644 test/printer/samples/sort-order-none2.html create mode 100644 test/printer/samples/sort-order-none2.options.json diff --git a/CHANGELOG.md b/CHANGELOG.md index a7da8022..cdf0aef8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 2.8.0 (unreleased) * (feat) support `singleAttributePerLine` Prettier option ([#305](https://github.com/sveltejs/prettier-plugin-svelte/issues/305)) +* (feat) add `svelteSortOrder: none` Prettier option which skips reordering scripts/styles/html ([#305](https://github.com/sveltejs/prettier-plugin-svelte/issues/314)) ## 2.7.1 diff --git a/src/embed.ts b/src/embed.ts index cdf78b3a..a03f60d3 100644 --- a/src/embed.ts +++ b/src/embed.ts @@ -223,7 +223,7 @@ function embedTag( ]); let result = groupConcat([openingTag, body, '']); - if (isTopLevel) { + if (isTopLevel && options.svelteSortOrder !== 'none') { // top level embedded nodes have been moved from their normal position in the // node tree. if there is a comment referring to it, it must be recreated at // the new position. diff --git a/src/options.ts b/src/options.ts index eb3cef1e..b22877a1 100644 --- a/src/options.ts +++ b/src/options.ts @@ -48,6 +48,7 @@ export const options: Record = { makeChoice('markup-scripts-styles-options'), makeChoice('styles-markup-scripts-options'), makeChoice('styles-scripts-markup-options'), + makeChoice('none'), // Deprecated, keep in 2.x for backwards-compatibility. svelte:options will be moved to the top makeChoice('scripts-markup-styles'), makeChoice('scripts-styles-markup'), @@ -114,6 +115,7 @@ export type SortOrder = | 'markup-scripts-styles-options' | 'styles-markup-scripts-options' | 'styles-scripts-markup-options' + | 'none' | DeprecatedSortOrder; export type DeprecatedSortOrder = @@ -129,6 +131,10 @@ export type SortOrderPart = 'scripts' | 'markup' | 'styles' | 'options'; const sortOrderSeparator = '-'; export function parseSortOrder(sortOrder: SortOrder): SortOrderPart[] { + if (sortOrder === 'none') { + return []; + } + const order = sortOrder.split(sortOrderSeparator) as SortOrderPart[]; // For backwards compatibility: Add options to beginning if not present if (!order.includes('options')) { diff --git a/src/print/index.ts b/src/print/index.ts index 0b8af275..c783c0e0 100644 --- a/src/print/index.ts +++ b/src/print/index.ts @@ -44,6 +44,7 @@ import { isIgnoreStartDirective, isIgnoreEndDirective, isNodeTopLevelHTML, + getChildren, } from './node-helpers'; import { ASTNode, @@ -388,7 +389,10 @@ export function print(path: FastPath, options: ParserOptions, print: PrintFn): D ]); } case 'Options': - throw new Error('Options tags should have been handled by prepareChildren'); + if (options.svelteSortOrder !== 'none') { + throw new Error('Options tags should have been handled by prepareChildren'); + } + // else fall through to Body case 'Body': return groupConcat([ '<', @@ -720,6 +724,36 @@ function printTopLevelParts( path: FastPath, print: PrintFn, ): Doc { + if (options.svelteSortOrder === 'none') { + const topLevelPartsByEnd: Record = {}; + + if (n.module) { + n.module.type = 'Script'; + n.module.attributes = extractAttributes(getText(n.module, options)); + topLevelPartsByEnd[n.module.end] = n.module; + } + if (n.instance) { + n.instance.type = 'Script'; + n.instance.attributes = extractAttributes(getText(n.instance, options)); + topLevelPartsByEnd[n.instance.end] = n.instance; + } + if (n.css) { + n.css.type = 'Style'; + n.css.content.type = 'StyleProgram'; + topLevelPartsByEnd[n.css.end] = n.css; + } + + const children = getChildren(n.html); + for (let i = 0; i < children.length; i++) { + const node = children[i]; + if (topLevelPartsByEnd[node.start]) { + children.splice(i, 0, topLevelPartsByEnd[node.start]); + delete topLevelPartsByEnd[node.start]; + } + } + return path.call(print, 'html'); + } + const parts: Record = { options: [], scripts: [], @@ -1022,16 +1056,18 @@ function prepareChildren( continue; } - if (isCommentFollowedByOptions(currentChild, idx)) { - svelteOptionsComment = printComment(currentChild); - const nextChild = children[idx + 1]; - idx += nextChild && isEmptyTextNode(nextChild) ? 1 : 0; - continue; - } + if (options.svelteSortOrder !== 'none') { + if (isCommentFollowedByOptions(currentChild, idx)) { + svelteOptionsComment = printComment(currentChild); + const nextChild = children[idx + 1]; + idx += nextChild && isEmptyTextNode(nextChild) ? 1 : 0; + continue; + } - if (currentChild.type === 'Options') { - printSvelteOptions(currentChild, idx, path, print); - continue; + if (currentChild.type === 'Options') { + printSvelteOptions(currentChild, idx, path, print); + continue; + } } childrenWithoutOptions.push(currentChild); diff --git a/test/printer/samples/sort-order-none.html b/test/printer/samples/sort-order-none.html new file mode 100644 index 00000000..ada7724e --- /dev/null +++ b/test/printer/samples/sort-order-none.html @@ -0,0 +1,23 @@ +

Hello {name}!

+ + + +

yeah why not

+ + + + + +

I hope noone orders them like this

+ + + +

I really do

diff --git a/test/printer/samples/sort-order-none.options.json b/test/printer/samples/sort-order-none.options.json new file mode 100644 index 00000000..fd6e47a8 --- /dev/null +++ b/test/printer/samples/sort-order-none.options.json @@ -0,0 +1,3 @@ +{ + "svelteSortOrder": "none" +} diff --git a/test/printer/samples/sort-order-none2.html b/test/printer/samples/sort-order-none2.html new file mode 100644 index 00000000..df863350 --- /dev/null +++ b/test/printer/samples/sort-order-none2.html @@ -0,0 +1,23 @@ + + +

Hello {name}!

+ + + +

yeah why not

+ + + +

I hope noone orders them like this

+ + + +

I really do

diff --git a/test/printer/samples/sort-order-none2.options.json b/test/printer/samples/sort-order-none2.options.json new file mode 100644 index 00000000..fd6e47a8 --- /dev/null +++ b/test/printer/samples/sort-order-none2.options.json @@ -0,0 +1,3 @@ +{ + "svelteSortOrder": "none" +}