fix(compiler-sfc): transformAssetUrl should ignore inline data url (#1431)
This commit is contained in:
parent
37a5952c09
commit
90c285c5c8
@ -32,7 +32,8 @@ export function render(_ctx, _cache) {
|
|||||||
_createVNode(\\"img\\", { src: _imports_1 }),
|
_createVNode(\\"img\\", { src: _imports_1 }),
|
||||||
_createVNode(\\"img\\", { src: _imports_1 }),
|
_createVNode(\\"img\\", { src: _imports_1 }),
|
||||||
_createVNode(\\"img\\", { src: \\"http://example.com/fixtures/logo.png\\" }),
|
_createVNode(\\"img\\", { src: \\"http://example.com/fixtures/logo.png\\" }),
|
||||||
_createVNode(\\"img\\", { src: \\"/fixtures/logo.png\\" })
|
_createVNode(\\"img\\", { src: \\"/fixtures/logo.png\\" }),
|
||||||
|
_createVNode(\\"img\\", { src: \\"data:image/png;base64,i\\" })
|
||||||
], 64 /* STABLE_FRAGMENT */))
|
], 64 /* STABLE_FRAGMENT */))
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
@ -55,6 +55,10 @@ export function render(_ctx, _cache) {
|
|||||||
_createVNode(\\"img\\", {
|
_createVNode(\\"img\\", {
|
||||||
src: \\"/logo.png\\",
|
src: \\"/logo.png\\",
|
||||||
srcset: _hoisted_8
|
srcset: _hoisted_8
|
||||||
|
}),
|
||||||
|
_createVNode(\\"img\\", {
|
||||||
|
src: \\"data:image/png;base64,i\\",
|
||||||
|
srcset: \\"data:image/png;base64,i 1x, data:image/png;base64,i 2x\\"
|
||||||
})
|
})
|
||||||
], 64 /* STABLE_FRAGMENT */))
|
], 64 /* STABLE_FRAGMENT */))
|
||||||
}"
|
}"
|
||||||
@ -104,6 +108,10 @@ export function render(_ctx, _cache) {
|
|||||||
_createVNode(\\"img\\", {
|
_createVNode(\\"img\\", {
|
||||||
src: \\"/logo.png\\",
|
src: \\"/logo.png\\",
|
||||||
srcset: \\"/logo.png, /foo/logo.png 2x\\"
|
srcset: \\"/logo.png, /foo/logo.png 2x\\"
|
||||||
|
}),
|
||||||
|
_createVNode(\\"img\\", {
|
||||||
|
src: \\"data:image/png;base64,i\\",
|
||||||
|
srcset: \\"data:image/png;base64,i 1x, data:image/png;base64,i 2x\\"
|
||||||
})
|
})
|
||||||
], 64 /* STABLE_FRAGMENT */))
|
], 64 /* STABLE_FRAGMENT */))
|
||||||
}"
|
}"
|
||||||
@ -125,6 +133,7 @@ const _hoisted_7 = _imports_0 + ', ' + _imports_0 + '2x, ' + _imports_0 + '3x'
|
|||||||
const _hoisted_8 = _imports_1 + ', ' + _imports_1 + '2x'
|
const _hoisted_8 = _imports_1 + ', ' + _imports_1 + '2x'
|
||||||
const _hoisted_9 = \\"https://example.com/logo.png\\" + ', ' + \\"https://example.com/logo.png\\" + '2x'
|
const _hoisted_9 = \\"https://example.com/logo.png\\" + ', ' + \\"https://example.com/logo.png\\" + '2x'
|
||||||
const _hoisted_10 = _imports_1 + ', ' + _imports_0 + '2x'
|
const _hoisted_10 = _imports_1 + ', ' + _imports_0 + '2x'
|
||||||
|
const _hoisted_11 = \\"data:image/png;base64,i\\" + '1x, ' + \\"data:image/png;base64,i\\" + '2x'
|
||||||
|
|
||||||
export function render(_ctx, _cache) {
|
export function render(_ctx, _cache) {
|
||||||
return (_openBlock(), _createBlock(_Fragment, null, [
|
return (_openBlock(), _createBlock(_Fragment, null, [
|
||||||
@ -167,6 +176,10 @@ export function render(_ctx, _cache) {
|
|||||||
_createVNode(\\"img\\", {
|
_createVNode(\\"img\\", {
|
||||||
src: \\"/logo.png\\",
|
src: \\"/logo.png\\",
|
||||||
srcset: _hoisted_10
|
srcset: _hoisted_10
|
||||||
|
}),
|
||||||
|
_createVNode(\\"img\\", {
|
||||||
|
src: \\"data:image/png;base64,i\\",
|
||||||
|
srcset: _hoisted_11
|
||||||
})
|
})
|
||||||
], 64 /* STABLE_FRAGMENT */))
|
], 64 /* STABLE_FRAGMENT */))
|
||||||
}"
|
}"
|
||||||
|
@ -30,6 +30,7 @@ describe('compiler sfc: transform asset url', () => {
|
|||||||
<img src="~/fixtures/logo.png"/>
|
<img src="~/fixtures/logo.png"/>
|
||||||
<img src="http://example.com/fixtures/logo.png"/>
|
<img src="http://example.com/fixtures/logo.png"/>
|
||||||
<img src="/fixtures/logo.png"/>
|
<img src="/fixtures/logo.png"/>
|
||||||
|
<img src="data:image/png;base64,i"/>
|
||||||
`)
|
`)
|
||||||
|
|
||||||
expect(result.code).toMatchSnapshot()
|
expect(result.code).toMatchSnapshot()
|
||||||
|
@ -35,6 +35,7 @@ const src = `
|
|||||||
<img src="/logo.png" srcset="/logo.png, /logo.png 2x"/>
|
<img src="/logo.png" srcset="/logo.png, /logo.png 2x"/>
|
||||||
<img src="https://example.com/logo.png" srcset="https://example.com/logo.png, https://example.com/logo.png 2x"/>
|
<img src="https://example.com/logo.png" srcset="https://example.com/logo.png, https://example.com/logo.png 2x"/>
|
||||||
<img src="/logo.png" srcset="/logo.png, ./logo.png 2x"/>
|
<img src="/logo.png" srcset="/logo.png, ./logo.png 2x"/>
|
||||||
|
<img src="data:image/png;base64,i" srcset="data:image/png;base64,i 1x, data:image/png;base64,i 2x"/>
|
||||||
`
|
`
|
||||||
|
|
||||||
describe('compiler sfc: transform srcset', () => {
|
describe('compiler sfc: transform srcset', () => {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
isRelativeUrl,
|
isRelativeUrl,
|
||||||
isExternalUrl
|
isExternalUrl,
|
||||||
|
isDataUrl
|
||||||
} from '../../compiler-sfc/src/templateUtils'
|
} from '../../compiler-sfc/src/templateUtils'
|
||||||
|
|
||||||
describe('compiler sfc:templateUtils isRelativeUrl', () => {
|
describe('compiler sfc:templateUtils isRelativeUrl', () => {
|
||||||
@ -36,3 +37,17 @@ describe('compiler sfc:templateUtils isExternalUrl', () => {
|
|||||||
expect(result).toBe(true)
|
expect(result).toBe(true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('compiler sfc:templateUtils isDataUrl', () => {
|
||||||
|
test('should return true w/ hasn`t media type and encode', () => {
|
||||||
|
expect(isDataUrl('data:,i')).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should return true w/ media type + encode', () => {
|
||||||
|
expect(isDataUrl('data:image/png;base64,i')).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should return true w/ media type + hasn`t encode', () => {
|
||||||
|
expect(isDataUrl('data:image/png,i')).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
@ -7,7 +7,12 @@ import {
|
|||||||
SourceLocation,
|
SourceLocation,
|
||||||
TransformContext
|
TransformContext
|
||||||
} from '@vue/compiler-core'
|
} from '@vue/compiler-core'
|
||||||
import { isRelativeUrl, parseUrl, isExternalUrl } from './templateUtils'
|
import {
|
||||||
|
isRelativeUrl,
|
||||||
|
parseUrl,
|
||||||
|
isExternalUrl,
|
||||||
|
isDataUrl
|
||||||
|
} from './templateUtils'
|
||||||
import { isArray } from '@vue/shared'
|
import { isArray } from '@vue/shared'
|
||||||
|
|
||||||
export interface AssetURLTagConfig {
|
export interface AssetURLTagConfig {
|
||||||
@ -99,6 +104,7 @@ export const transformAssetUrl: NodeTransform = (
|
|||||||
!assetAttrs.includes(attr.name) ||
|
!assetAttrs.includes(attr.name) ||
|
||||||
!attr.value ||
|
!attr.value ||
|
||||||
isExternalUrl(attr.value.content) ||
|
isExternalUrl(attr.value.content) ||
|
||||||
|
isDataUrl(attr.value.content) ||
|
||||||
attr.value.content[0] === '#' ||
|
attr.value.content[0] === '#' ||
|
||||||
(!options.includeAbsolute && !isRelativeUrl(attr.value.content))
|
(!options.includeAbsolute && !isRelativeUrl(attr.value.content))
|
||||||
) {
|
) {
|
||||||
|
@ -6,7 +6,12 @@ import {
|
|||||||
NodeTypes,
|
NodeTypes,
|
||||||
SimpleExpressionNode
|
SimpleExpressionNode
|
||||||
} from '@vue/compiler-core'
|
} from '@vue/compiler-core'
|
||||||
import { isRelativeUrl, parseUrl, isExternalUrl } from './templateUtils'
|
import {
|
||||||
|
isRelativeUrl,
|
||||||
|
parseUrl,
|
||||||
|
isExternalUrl,
|
||||||
|
isDataUrl
|
||||||
|
} from './templateUtils'
|
||||||
import {
|
import {
|
||||||
AssetURLOptions,
|
AssetURLOptions,
|
||||||
defaultAssetUrlOptions
|
defaultAssetUrlOptions
|
||||||
@ -51,6 +56,15 @@ export const transformSrcset: NodeTransform = (
|
|||||||
return { url, descriptor }
|
return { url, descriptor }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// for data url need recheck url
|
||||||
|
for (let i = 0; i < imageCandidates.length; i++) {
|
||||||
|
if (imageCandidates[i].url.trim().startsWith('data:')) {
|
||||||
|
imageCandidates[i + 1].url =
|
||||||
|
imageCandidates[i].url + ',' + imageCandidates[i + 1].url
|
||||||
|
imageCandidates.splice(i, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// When srcset does not contain any relative URLs, skip transforming
|
// When srcset does not contain any relative URLs, skip transforming
|
||||||
if (
|
if (
|
||||||
!options.includeAbsolute &&
|
!options.includeAbsolute &&
|
||||||
@ -78,6 +92,7 @@ export const transformSrcset: NodeTransform = (
|
|||||||
imageCandidates.forEach(({ url, descriptor }, index) => {
|
imageCandidates.forEach(({ url, descriptor }, index) => {
|
||||||
if (
|
if (
|
||||||
!isExternalUrl(url) &&
|
!isExternalUrl(url) &&
|
||||||
|
!isDataUrl(url) &&
|
||||||
(options.includeAbsolute || isRelativeUrl(url))
|
(options.includeAbsolute || isRelativeUrl(url))
|
||||||
) {
|
) {
|
||||||
const { path } = parseUrl(url)
|
const { path } = parseUrl(url)
|
||||||
|
@ -11,6 +11,11 @@ export function isExternalUrl(url: string): boolean {
|
|||||||
return externalRE.test(url)
|
return externalRE.test(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const dataUrlRE = /^\s*data:/i
|
||||||
|
export function isDataUrl(url: string): boolean {
|
||||||
|
return dataUrlRE.test(url)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses string url into URL object.
|
* Parses string url into URL object.
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user