Skip to content

Commit

Permalink
fix(css): escape double quotes in url() when lightningcss is used (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
sapphi-red authored Dec 18, 2024
1 parent 3e4caab commit 3734f80
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 11 deletions.
26 changes: 15 additions & 11 deletions packages/vite/src/node/plugins/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3237,21 +3237,25 @@ async function compileLightningCSS(
let css = decoder.decode(res.code)
for (const dep of res.dependencies!) {
switch (dep.type) {
case 'url':
case 'url': {
let replaceUrl: string
if (skipUrlReplacer(dep.url)) {
css = css.replace(dep.placeholder, () => dep.url)
break
}
if (urlReplacer) {
const replaceUrl = await urlReplacer(
dep.url,
toAbsolute(dep.loc.filePath),
)
css = css.replace(dep.placeholder, () => replaceUrl)
replaceUrl = dep.url
} else if (urlReplacer) {
replaceUrl = await urlReplacer(dep.url, toAbsolute(dep.loc.filePath))
} else {
css = css.replace(dep.placeholder, () => dep.url)
replaceUrl = dep.url
}

css = css.replace(
dep.placeholder,
// lightningcss always generates `url("placeholder")`
// (`url('placeholder')`, `url(placeholder)` is not generated)
// so escape double quotes
() => replaceUrl.replaceAll('"', '\\"'),
)
break
}
default:
throw new Error(`Unsupported dependency type: ${dep.type}`)
}
Expand Down
6 changes: 6 additions & 0 deletions playground/assets/__tests__/assets.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,12 @@ describe('css url() references', () => {
expect(bg).toMatch(assetMatch)
})

test('preinlined SVG', async () => {
expect(await getBg('.css-url-preinlined-svg')).toMatch(
/data:image\/svg\+xml,.+/,
)
})

test.runIf(isBuild)('generated paths in CSS', () => {
const css = findAssetFile(/index-[-\w]{8}\.css$/, 'foo')

Expand Down
5 changes: 5 additions & 0 deletions playground/assets/css/css-url.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions playground/assets/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ <h2>CSS url references</h2>
<div class="css-url-aliased">
<span style="background: #fff">CSS background (aliased)</span>
</div>
<div class="css-url-preinlined-svg">
<span style="background: #fff">CSS background (pre inlined SVG)</span>
</div>
<div class="css-manual-chunks-relative">
<span style="background: #fff"
>CSS nested manual chunks relative base background</span
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,9 @@ test('aliased asset', async () => {
const bg = await getBg('.css-url-aliased')
expect(bg).toMatch('data:image/svg+xml,')
})

test('preinlined SVG', async () => {
expect(await getBg('.css-url-preinlined-svg')).toMatch(
/data:image\/svg\+xml,.+/,
)
})
5 changes: 5 additions & 0 deletions playground/css-lightningcss/css-url.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions playground/css-lightningcss/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ <h1>Lightning CSS</h1>
<div class="css-url-aliased">
<span style="background: #fff">CSS background (aliased)</span>
</div>
<div class="css-url-preinlined-svg">
<span style="background: #fff">CSS background (pre inlined SVG)</span>
</div>
</div>

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

0 comments on commit 3734f80

Please sign in to comment.