Skip to content

Commit 90c285c

Browse files
authored
fix(compiler-sfc): transformAssetUrl should ignore inline data url (#1431)
1 parent 37a5952 commit 90c285c

8 files changed

+61
-4
lines changed

packages/compiler-sfc/__tests__/__snapshots__/templateTransformAssetUrl.spec.ts.snap

+2-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ export function render(_ctx, _cache) {
3232
_createVNode(\\"img\\", { src: _imports_1 }),
3333
_createVNode(\\"img\\", { src: _imports_1 }),
3434
_createVNode(\\"img\\", { src: \\"http://example.com/fixtures/logo.png\\" }),
35-
_createVNode(\\"img\\", { src: \\"/fixtures/logo.png\\" })
35+
_createVNode(\\"img\\", { src: \\"/fixtures/logo.png\\" }),
36+
_createVNode(\\"img\\", { src: \\"data:image/png;base64,i\\" })
3637
], 64 /* STABLE_FRAGMENT */))
3738
}"
3839
`;

packages/compiler-sfc/__tests__/__snapshots__/templateTransformSrcset.spec.ts.snap

+13
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ export function render(_ctx, _cache) {
5555
_createVNode(\\"img\\", {
5656
src: \\"/logo.png\\",
5757
srcset: _hoisted_8
58+
}),
59+
_createVNode(\\"img\\", {
60+
src: \\"data:image/png;base64,i\\",
61+
srcset: \\"data:image/png;base64,i 1x, data:image/png;base64,i 2x\\"
5862
})
5963
], 64 /* STABLE_FRAGMENT */))
6064
}"
@@ -104,6 +108,10 @@ export function render(_ctx, _cache) {
104108
_createVNode(\\"img\\", {
105109
src: \\"/logo.png\\",
106110
srcset: \\"/logo.png, /foo/logo.png 2x\\"
111+
}),
112+
_createVNode(\\"img\\", {
113+
src: \\"data:image/png;base64,i\\",
114+
srcset: \\"data:image/png;base64,i 1x, data:image/png;base64,i 2x\\"
107115
})
108116
], 64 /* STABLE_FRAGMENT */))
109117
}"
@@ -125,6 +133,7 @@ const _hoisted_7 = _imports_0 + ', ' + _imports_0 + '2x, ' + _imports_0 + '3x'
125133
const _hoisted_8 = _imports_1 + ', ' + _imports_1 + '2x'
126134
const _hoisted_9 = \\"https://example.com/logo.png\\" + ', ' + \\"https://example.com/logo.png\\" + '2x'
127135
const _hoisted_10 = _imports_1 + ', ' + _imports_0 + '2x'
136+
const _hoisted_11 = \\"data:image/png;base64,i\\" + '1x, ' + \\"data:image/png;base64,i\\" + '2x'
128137
129138
export function render(_ctx, _cache) {
130139
return (_openBlock(), _createBlock(_Fragment, null, [
@@ -167,6 +176,10 @@ export function render(_ctx, _cache) {
167176
_createVNode(\\"img\\", {
168177
src: \\"/logo.png\\",
169178
srcset: _hoisted_10
179+
}),
180+
_createVNode(\\"img\\", {
181+
src: \\"data:image/png;base64,i\\",
182+
srcset: _hoisted_11
170183
})
171184
], 64 /* STABLE_FRAGMENT */))
172185
}"

packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ describe('compiler sfc: transform asset url', () => {
3030
<img src="~/fixtures/logo.png"/>
3131
<img src="http://example.com/fixtures/logo.png"/>
3232
<img src="/fixtures/logo.png"/>
33+
<img src="data:image/png;base64,i"/>
3334
`)
3435

3536
expect(result.code).toMatchSnapshot()

packages/compiler-sfc/__tests__/templateTransformSrcset.spec.ts

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ const src = `
3535
<img src="/logo.png" srcset="/logo.png, /logo.png 2x"/>
3636
<img src="https://example.com/logo.png" srcset="https://example.com/logo.png, https://example.com/logo.png 2x"/>
3737
<img src="/logo.png" srcset="/logo.png, ./logo.png 2x"/>
38+
<img src="data:image/png;base64,i" srcset="data:image/png;base64,i 1x, data:image/png;base64,i 2x"/>
3839
`
3940

4041
describe('compiler sfc: transform srcset', () => {

packages/compiler-sfc/__tests__/templateUtils.spec.ts

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
isRelativeUrl,
3-
isExternalUrl
3+
isExternalUrl,
4+
isDataUrl
45
} from '../../compiler-sfc/src/templateUtils'
56

67
describe('compiler sfc:templateUtils isRelativeUrl', () => {
@@ -36,3 +37,17 @@ describe('compiler sfc:templateUtils isExternalUrl', () => {
3637
expect(result).toBe(true)
3738
})
3839
})
40+
41+
describe('compiler sfc:templateUtils isDataUrl', () => {
42+
test('should return true w/ hasn`t media type and encode', () => {
43+
expect(isDataUrl('data:,i')).toBe(true)
44+
})
45+
46+
test('should return true w/ media type + encode', () => {
47+
expect(isDataUrl('data:image/png;base64,i')).toBe(true)
48+
})
49+
50+
test('should return true w/ media type + hasn`t encode', () => {
51+
expect(isDataUrl('data:image/png,i')).toBe(true)
52+
})
53+
})

packages/compiler-sfc/src/templateTransformAssetUrl.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@ import {
77
SourceLocation,
88
TransformContext
99
} from '@vue/compiler-core'
10-
import { isRelativeUrl, parseUrl, isExternalUrl } from './templateUtils'
10+
import {
11+
isRelativeUrl,
12+
parseUrl,
13+
isExternalUrl,
14+
isDataUrl
15+
} from './templateUtils'
1116
import { isArray } from '@vue/shared'
1217

1318
export interface AssetURLTagConfig {
@@ -99,6 +104,7 @@ export const transformAssetUrl: NodeTransform = (
99104
!assetAttrs.includes(attr.name) ||
100105
!attr.value ||
101106
isExternalUrl(attr.value.content) ||
107+
isDataUrl(attr.value.content) ||
102108
attr.value.content[0] === '#' ||
103109
(!options.includeAbsolute && !isRelativeUrl(attr.value.content))
104110
) {

packages/compiler-sfc/src/templateTransformSrcset.ts

+16-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@ import {
66
NodeTypes,
77
SimpleExpressionNode
88
} from '@vue/compiler-core'
9-
import { isRelativeUrl, parseUrl, isExternalUrl } from './templateUtils'
9+
import {
10+
isRelativeUrl,
11+
parseUrl,
12+
isExternalUrl,
13+
isDataUrl
14+
} from './templateUtils'
1015
import {
1116
AssetURLOptions,
1217
defaultAssetUrlOptions
@@ -51,6 +56,15 @@ export const transformSrcset: NodeTransform = (
5156
return { url, descriptor }
5257
})
5358

59+
// for data url need recheck url
60+
for (let i = 0; i < imageCandidates.length; i++) {
61+
if (imageCandidates[i].url.trim().startsWith('data:')) {
62+
imageCandidates[i + 1].url =
63+
imageCandidates[i].url + ',' + imageCandidates[i + 1].url
64+
imageCandidates.splice(i, 1)
65+
}
66+
}
67+
5468
// When srcset does not contain any relative URLs, skip transforming
5569
if (
5670
!options.includeAbsolute &&
@@ -78,6 +92,7 @@ export const transformSrcset: NodeTransform = (
7892
imageCandidates.forEach(({ url, descriptor }, index) => {
7993
if (
8094
!isExternalUrl(url) &&
95+
!isDataUrl(url) &&
8196
(options.includeAbsolute || isRelativeUrl(url))
8297
) {
8398
const { path } = parseUrl(url)

packages/compiler-sfc/src/templateUtils.ts

+5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ export function isExternalUrl(url: string): boolean {
1111
return externalRE.test(url)
1212
}
1313

14+
const dataUrlRE = /^\s*data:/i
15+
export function isDataUrl(url: string): boolean {
16+
return dataUrlRE.test(url)
17+
}
18+
1419
/**
1520
* Parses string url into URL object.
1621
*/

0 commit comments

Comments
 (0)