Skip to content

Commit

Permalink
fix(build): use base64 for inline SVG if it contains both single and …
Browse files Browse the repository at this point in the history
…double quotes (#15271)
  • Loading branch information
chaejunlee committed Dec 15, 2023
1 parent d9ae1b2 commit 1bbff16
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 1 deletion.
5 changes: 4 additions & 1 deletion packages/vite/src/node/plugins/asset.ts
Expand Up @@ -415,14 +415,17 @@ export async function urlToBuiltUrl(
)
}

const nestedQuotesRE = /"[^"']*'[^"]*"|'[^'"]*"[^']*'/

// Inspired by https://github.com/iconify/iconify/blob/main/packages/utils/src/svg/url.ts
function svgToDataURL(content: Buffer): string {
const stringContent = content.toString()
// If the SVG contains some text or HTML, any transformation is unsafe, and given that double quotes would then
// need to be escaped, the gain to use a data URI would be ridiculous if not negative
if (
stringContent.includes('<text') ||
stringContent.includes('<foreignObject')
stringContent.includes('<foreignObject') ||
nestedQuotesRE.test(stringContent)
) {
return `data:image/svg+xml;base64,${content.toString('base64')}`
} else {
Expand Down
12 changes: 12 additions & 0 deletions playground/data-uri/__tests__/data-uri.spec.ts
Expand Up @@ -9,6 +9,18 @@ test('base64', async () => {
expect(await page.textContent('.base64')).toBe('hi')
})

test('svg data uri minify', async () => {
const sqdqs = await page.getByTestId('sqdqs').boundingBox()
const sqsdqs = await page.getByTestId('sqsdqs').boundingBox()
const dqsqs = await page.getByTestId('dqsqs').boundingBox()
const dqssqs = await page.getByTestId('dqssqs').boundingBox()

expect(sqdqs.height).toBe(100)
expect(sqsdqs.height).toBe(100)
expect(dqsqs.height).toBe(100)
expect(dqssqs.height).toBe(100)
})

test.runIf(isBuild)('should compile away the import for build', async () => {
const file = findAssetFile('index')
expect(file).not.toMatch('import')
Expand Down
1 change: 1 addition & 0 deletions playground/data-uri/double-quote-in-single-quotes.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions playground/data-uri/double-quotes-in-single-quotes.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions playground/data-uri/index.html
Expand Up @@ -12,3 +12,10 @@
document.querySelector(el).textContent = text
}
</script>

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

<div id="sqdqs"></div>
<div id="sqsdqs"></div>
<div id="dqsqs"></div>
<div id="dqssqs"></div>
18 changes: 18 additions & 0 deletions playground/data-uri/main.js
@@ -0,0 +1,18 @@
import sqdqs from './single-quote-in-double-quotes.svg'
import sqsdqs from './single-quotes-in-double-quotes.svg'
import dqsqs from './double-quote-in-single-quotes.svg'
import dqssqs from './double-quotes-in-single-quotes.svg'

document.querySelector('#sqdqs').innerHTML = `
<img data-testid="sqdqs" src="${sqdqs}" class="sqdqs" alt="load failed" />
`
document.querySelector('#sqsdqs').innerHTML = `
<img data-testid="sqsdqs" src="${sqsdqs}" class="sqsdqs" alt="load failed" />
`

document.querySelector('#dqsqs').innerHTML = `
<img data-testid="dqsqs" src="${dqsqs}" class="dqsqs" alt="load failed" />
`
document.querySelector('#dqssqs').innerHTML = `
<img data-testid="dqssqs" src="${dqssqs}" class="dqssqs" alt="load failed" />
`
1 change: 1 addition & 0 deletions playground/data-uri/single-quote-in-double-quotes.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions playground/data-uri/single-quotes-in-double-quotes.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 1bbff16

Please sign in to comment.