Skip to content

Commit a94563c

Browse files
authored
(feat) trim whitespace in class attributes (#356)
fixes #339
1 parent 7abac5f commit a94563c

File tree

5 files changed

+84
-3
lines changed

5 files changed

+84
-3
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- (feat) support `requirePragma` and `insertPragma` options ([#350](https://github.com/sveltejs/prettier-plugin-svelte/issues/350))
66
- (feat) support `<svelte:document>`
7+
- (feat) trim whitespace in `class` attributes ([#339](https://github.com/sveltejs/prettier-plugin-svelte/issues/339))
78

89
## 2.9.0
910

src/print/index.ts

+30-2
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,38 @@ export function print(path: FastPath, options: ParserOptions, print: PrintFn): D
180180
*/
181181
return fill(splitTextToDocs(node));
182182
} else {
183-
const rawText = getUnencodedText(node);
184-
if (path.getParentNode().type === 'Attribute') {
183+
let rawText = getUnencodedText(node);
184+
const parent = path.getParentNode();
185+
if (parent.type === 'Attribute') {
185186
// Direct child of attribute value -> add literallines at end of lines
186187
// so that other things don't break in unexpected places
188+
if (parent.name === 'class' && path.getParentNode(1).type === 'Element') {
189+
// Special treatment for class attribute on html elements. Prettier
190+
// will force everything into one line, we deviate from that and preserve lines.
191+
rawText = rawText.replace(
192+
/([^ \t\n])(([ \t]+$)|([ \t]+(\r?\n))|[ \t]+)/g,
193+
// Remove trailing whitespace in lines with non-whitespace characters
194+
// except at the end of the string
195+
(
196+
match,
197+
characterBeforeWhitespace,
198+
_,
199+
isEndOfString,
200+
isEndOfLine,
201+
endOfLine,
202+
) =>
203+
isEndOfString
204+
? match
205+
: characterBeforeWhitespace + (isEndOfLine ? endOfLine : ' '),
206+
);
207+
// Shrink trailing whitespace in case it's followed by a mustache tag
208+
// and remove it completely if it's at the end of the string, but not
209+
// if it's on its own line
210+
rawText = rawText.replace(
211+
/([^ \t\n])[ \t]+$/,
212+
parent.value.indexOf(node) === parent.value.length - 1 ? '$1' : '$1 ',
213+
);
214+
}
187215
return concat(replaceEndOfLineWith(rawText, literalline));
188216
}
189217
return rawText;

test/formatting/samples/attribute-with-linebreaks/output.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<div
2-
class=" {longExpressionThatForcesLinebreaks} longExpressionThatForcesLinebreaks longExpressionThatForcesLinebreaks "
2+
class=" {longExpressionThatForcesLinebreaks} longExpressionThatForcesLinebreaks longExpressionThatForcesLinebreaks"
33
alt="When reformatting class attributes it is fine to trim and add new line breaks.
44
That's not the case with other attributes. "
55
data-value={array.map((item) => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<button
2+
class="bg-green-500 text-gray-100 hover:bg-green-400 flex items-center px-4 py-2 border border-l-0 rounded-r "
3+
>
4+
Copy
5+
</button>
6+
<div
7+
class="bg-green-500 text-gray-100 hover:bg-green-400 flex items-center px-4 py-2 border border-l-0 rounded-r"
8+
>
9+
Copy
10+
</div>
11+
<span
12+
class="bg-green-500 text-gray-100 hover:bg-green-400 flex
13+
14+
items-center px-4 py-2 border border-l-0 rounded-r "
15+
>
16+
Copy
17+
</span>
18+
<p
19+
class="bg-green-500
20+
text-gray-100 hover:bg-green-400 flex items-center px-4 py-2 border border-l-0 rounded-r
21+
"
22+
>
23+
Copy
24+
</p>
25+
26+
<P class="leave me alone because I'm a prop " />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<button
2+
class="bg-green-500 text-gray-100 hover:bg-green-400 flex items-center px-4 py-2 border border-l-0 rounded-r"
3+
>
4+
Copy
5+
</button>
6+
<div
7+
class="bg-green-500 text-gray-100 hover:bg-green-400 flex items-center px-4 py-2 border border-l-0 rounded-r"
8+
>
9+
Copy
10+
</div>
11+
<span
12+
class="bg-green-500 text-gray-100 hover:bg-green-400 flex
13+
14+
items-center px-4 py-2 border border-l-0 rounded-r"
15+
>
16+
Copy
17+
</span>
18+
<p
19+
class="bg-green-500
20+
text-gray-100 hover:bg-green-400 flex items-center px-4 py-2 border border-l-0 rounded-r
21+
"
22+
>
23+
Copy
24+
</p>
25+
26+
<P class="leave me alone because I'm a prop " />

0 commit comments

Comments
 (0)