Skip to content

Commit f56c9ee

Browse files
committed
Bail out of whitespace removal inside template literals based on position
1 parent 4b553d7 commit f56c9ee

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

src/index.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,31 @@ function transformJavaScript(ast: import('@babel/types').Node, { env }: Transfor
633633
start &&= entry.key !== 'right'
634634
end &&= entry.key !== 'left'
635635
}
636+
637+
// This is probably expression *inside* of a template literal. To collapse whitespace
638+
// `Expression`s adjacent-before a quasi must start with whitespace
639+
// `Expression`s adjacent-after a quasi must end with whitespace
640+
//
641+
// Note this check will bail out on more than it really should as it
642+
// could be reset somewhere along the way by having whitespace around a
643+
// string further up but not at the "root" but that complicates things
644+
if (entry.parent.type === 'TemplateLiteral') {
645+
let nodeStart = entry.node.start ?? null
646+
let nodeEnd = entry.node.end ?? null
647+
648+
for (let quasi of entry.parent.quasis) {
649+
let quasiStart = quasi.end ?? null
650+
let quasiEnd = quasi.end ?? null
651+
652+
if (nodeStart !== null && quasiEnd !== null && nodeStart - quasiEnd <= 2) {
653+
start &&= /^\s/.test(quasi.value.raw)
654+
}
655+
656+
if (nodeEnd !== null && quasiStart !== null && nodeEnd - quasiStart <= 2) {
657+
end &&= /\s$/.test(quasi.value.raw)
658+
}
659+
}
660+
}
636661
}
637662

638663
if (isStringLiteral(node)) {

tests/format.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ describe('whitespace', () => {
6666
expect(result).toEqual(";<div className={a + ' p-4 ' + b}></div>")
6767
})
6868

69+
test('whitespace is not trimmed inside adjacent-before/after template expressions', async ({ expect }) => {
70+
let result = await format(";<div className={`header${isExtendable ? ' header-extendable' : ''}`} />", {
71+
parser: 'babel',
72+
})
73+
74+
expect(result).toEqual(";<div className={`header${isExtendable ? ' header-extendable' : ''}`} />")
75+
})
76+
6977
test('duplicate classes are dropped', async ({ expect }) => {
7078
let result = await format('<div class="underline line-through underline flex"></div>')
7179

0 commit comments

Comments
 (0)