Skip to content

Commit 3734f80

Browse files
authored
fix(css): escape double quotes in url() when lightningcss is used (#18997)
1 parent 3e4caab commit 3734f80

File tree

7 files changed

+43
-11
lines changed

7 files changed

+43
-11
lines changed

packages/vite/src/node/plugins/css.ts

+15-11
Original file line numberDiff line numberDiff line change
@@ -3237,21 +3237,25 @@ async function compileLightningCSS(
32373237
let css = decoder.decode(res.code)
32383238
for (const dep of res.dependencies!) {
32393239
switch (dep.type) {
3240-
case 'url':
3240+
case 'url': {
3241+
let replaceUrl: string
32413242
if (skipUrlReplacer(dep.url)) {
3242-
css = css.replace(dep.placeholder, () => dep.url)
3243-
break
3244-
}
3245-
if (urlReplacer) {
3246-
const replaceUrl = await urlReplacer(
3247-
dep.url,
3248-
toAbsolute(dep.loc.filePath),
3249-
)
3250-
css = css.replace(dep.placeholder, () => replaceUrl)
3243+
replaceUrl = dep.url
3244+
} else if (urlReplacer) {
3245+
replaceUrl = await urlReplacer(dep.url, toAbsolute(dep.loc.filePath))
32513246
} else {
3252-
css = css.replace(dep.placeholder, () => dep.url)
3247+
replaceUrl = dep.url
32533248
}
3249+
3250+
css = css.replace(
3251+
dep.placeholder,
3252+
// lightningcss always generates `url("placeholder")`
3253+
// (`url('placeholder')`, `url(placeholder)` is not generated)
3254+
// so escape double quotes
3255+
() => replaceUrl.replaceAll('"', '\\"'),
3256+
)
32543257
break
3258+
}
32553259
default:
32563260
throw new Error(`Unsupported dependency type: ${dep.type}`)
32573261
}

playground/assets/__tests__/assets.spec.ts

+6
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,12 @@ describe('css url() references', () => {
276276
expect(bg).toMatch(assetMatch)
277277
})
278278

279+
test('preinlined SVG', async () => {
280+
expect(await getBg('.css-url-preinlined-svg')).toMatch(
281+
/data:image\/svg\+xml,.+/,
282+
)
283+
})
284+
279285
test.runIf(isBuild)('generated paths in CSS', () => {
280286
const css = findAssetFile(/index-[-\w]{8}\.css$/, 'foo')
281287

playground/assets/css/css-url.css

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

playground/assets/index.html

+3
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ <h2>CSS url references</h2>
139139
<div class="css-url-aliased">
140140
<span style="background: #fff">CSS background (aliased)</span>
141141
</div>
142+
<div class="css-url-preinlined-svg">
143+
<span style="background: #fff">CSS background (pre inlined SVG)</span>
144+
</div>
142145
<div class="css-manual-chunks-relative">
143146
<span style="background: #fff"
144147
>CSS nested manual chunks relative base background</span

playground/css-lightningcss/__tests__/css-lightningcss.spec.ts

+6
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,9 @@ test('aliased asset', async () => {
8787
const bg = await getBg('.css-url-aliased')
8888
expect(bg).toMatch('data:image/svg+xml,')
8989
})
90+
91+
test('preinlined SVG', async () => {
92+
expect(await getBg('.css-url-preinlined-svg')).toMatch(
93+
/data:image\/svg\+xml,.+/,
94+
)
95+
})

playground/css-lightningcss/css-url.css

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

playground/css-lightningcss/index.html

+3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ <h1>Lightning CSS</h1>
3333
<div class="css-url-aliased">
3434
<span style="background: #fff">CSS background (aliased)</span>
3535
</div>
36+
<div class="css-url-preinlined-svg">
37+
<span style="background: #fff">CSS background (pre inlined SVG)</span>
38+
</div>
3639
</div>
3740

3841
<script type="module" src="./main.js"></script>

0 commit comments

Comments
 (0)