Skip to content

Commit

Permalink
fix(svelte-scoped): escape template literal characters in placeholder…
Browse files Browse the repository at this point in the history
… replacement (#3253)
  • Loading branch information
chu121su12 committed Oct 23, 2023
1 parent 901f10c commit c15a29d
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 1 deletion.
5 changes: 4 additions & 1 deletion packages/svelte-scoped/src/_vite/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ export function replaceGlobalStylesPlaceholder(code: string, stylesTag: string)
const matchCapturedQuoteMark = '\\1'
const QUOTES_WITH_PLACEHOLDER_RE = new RegExp(captureQuoteMark + GLOBAL_STYLES_PLACEHOLDER + matchCapturedQuoteMark)

const escapedStylesTag = stylesTag.replaceAll(/`/g, '\\`')
const escapedStylesTag = stylesTag
.replaceAll(/\\(?![`$])/g, '\\\\')
.replaceAll(/(?<!\\)([`$])/g, '\\$1')

return code.replace(QUOTES_WITH_PLACEHOLDER_RE, `\`${escapedStylesTag}\``)
// preset-web-fonts doesn't heed the minify option and sends through newlines (\n) that break if we use regular quotes here. Always using a backtick here is easier than removing newlines, which are actually kind of useful in dev mode. I might consider turning minify off altogether in dev mode.
}
Expand Down
3 changes: 3 additions & 0 deletions packages/svelte-scoped/test/fixtures/escaped-unicode.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
li::before {
content: "\200B";
}
16 changes: 16 additions & 0 deletions packages/svelte-scoped/test/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { describe, expect, it } from 'vitest'
import { preprocess } from 'svelte/compiler'
import { format as prettier } from 'prettier'
import fs from 'fs-extra'

// @ts-expect-error missing types
import prettierSvelte from 'prettier-plugin-svelte'
Expand All @@ -9,6 +10,8 @@ import presetIcons from '@unocss/preset-icons'
import presetTypography from '@unocss/preset-typography'
import UnocssSveltePreprocess from '../src/preprocess'
import type { UnocssSveltePreprocessOptions } from '../src/preprocess'
import { replaceGlobalStylesPlaceholder } from '../src/_vite/global'
import { GLOBAL_STYLES_PLACEHOLDER } from '../src/_vite/constants'

const defaultOptions: UnocssSveltePreprocessOptions = {
configOrPath: {
Expand Down Expand Up @@ -49,3 +52,16 @@ describe('svelte-preprocessor', () => {
})
}
})

describe('svelte-scoped helpers', () => {
it('escape template literal characters in placeholder replacement', async () => {
const css = await fs.readFile('packages/svelte-scoped/test/fixtures/escaped-unicode.css', 'utf8')

const escaped = replaceGlobalStylesPlaceholder(
`'${GLOBAL_STYLES_PLACEHOLDER}'`
, `<style type="text/css">${css}</style>`,
)

expect(escaped).toContain('"\\\\200B"')
})
})

0 comments on commit c15a29d

Please sign in to comment.