From 90c285c5c8ac13afb4932974c1f9aede15e81337 Mon Sep 17 00:00:00 2001
From: underfin <2218301630@qq.com>
Date: Wed, 24 Jun 2020 09:46:18 +0800
Subject: [PATCH] fix(compiler-sfc): transformAssetUrl should ignore inline
data url (#1431)
---
.../templateTransformAssetUrl.spec.ts.snap | 3 ++-
.../templateTransformSrcset.spec.ts.snap | 13 +++++++++++++
.../__tests__/templateTransformAssetUrl.spec.ts | 1 +
.../__tests__/templateTransformSrcset.spec.ts | 1 +
.../__tests__/templateUtils.spec.ts | 17 ++++++++++++++++-
.../src/templateTransformAssetUrl.ts | 8 +++++++-
.../compiler-sfc/src/templateTransformSrcset.ts | 17 ++++++++++++++++-
packages/compiler-sfc/src/templateUtils.ts | 5 +++++
8 files changed, 61 insertions(+), 4 deletions(-)
diff --git a/packages/compiler-sfc/__tests__/__snapshots__/templateTransformAssetUrl.spec.ts.snap b/packages/compiler-sfc/__tests__/__snapshots__/templateTransformAssetUrl.spec.ts.snap
index 998eeae5..e1c962a6 100644
--- a/packages/compiler-sfc/__tests__/__snapshots__/templateTransformAssetUrl.spec.ts.snap
+++ b/packages/compiler-sfc/__tests__/__snapshots__/templateTransformAssetUrl.spec.ts.snap
@@ -32,7 +32,8 @@ export function render(_ctx, _cache) {
_createVNode(\\"img\\", { src: _imports_1 }),
_createVNode(\\"img\\", { src: _imports_1 }),
_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 */))
}"
`;
diff --git a/packages/compiler-sfc/__tests__/__snapshots__/templateTransformSrcset.spec.ts.snap b/packages/compiler-sfc/__tests__/__snapshots__/templateTransformSrcset.spec.ts.snap
index 75c72ac1..2f057279 100644
--- a/packages/compiler-sfc/__tests__/__snapshots__/templateTransformSrcset.spec.ts.snap
+++ b/packages/compiler-sfc/__tests__/__snapshots__/templateTransformSrcset.spec.ts.snap
@@ -55,6 +55,10 @@ export function render(_ctx, _cache) {
_createVNode(\\"img\\", {
src: \\"/logo.png\\",
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 */))
}"
@@ -104,6 +108,10 @@ export function render(_ctx, _cache) {
_createVNode(\\"img\\", {
src: \\"/logo.png\\",
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 */))
}"
@@ -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_9 = \\"https://example.com/logo.png\\" + ', ' + \\"https://example.com/logo.png\\" + '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) {
return (_openBlock(), _createBlock(_Fragment, null, [
@@ -167,6 +176,10 @@ export function render(_ctx, _cache) {
_createVNode(\\"img\\", {
src: \\"/logo.png\\",
srcset: _hoisted_10
+ }),
+ _createVNode(\\"img\\", {
+ src: \\"data:image/png;base64,i\\",
+ srcset: _hoisted_11
})
], 64 /* STABLE_FRAGMENT */))
}"
diff --git a/packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts b/packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts
index 71be0e52..41eb6463 100644
--- a/packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts
+++ b/packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts
@@ -30,6 +30,7 @@ describe('compiler sfc: transform asset url', () => {
+
`)
expect(result.code).toMatchSnapshot()
diff --git a/packages/compiler-sfc/__tests__/templateTransformSrcset.spec.ts b/packages/compiler-sfc/__tests__/templateTransformSrcset.spec.ts
index 1bba0767..9d55dc87 100644
--- a/packages/compiler-sfc/__tests__/templateTransformSrcset.spec.ts
+++ b/packages/compiler-sfc/__tests__/templateTransformSrcset.spec.ts
@@ -35,6 +35,7 @@ const src = `
+
`
describe('compiler sfc: transform srcset', () => {
diff --git a/packages/compiler-sfc/__tests__/templateUtils.spec.ts b/packages/compiler-sfc/__tests__/templateUtils.spec.ts
index 7b4490fc..95bf619b 100644
--- a/packages/compiler-sfc/__tests__/templateUtils.spec.ts
+++ b/packages/compiler-sfc/__tests__/templateUtils.spec.ts
@@ -1,6 +1,7 @@
import {
isRelativeUrl,
- isExternalUrl
+ isExternalUrl,
+ isDataUrl
} from '../../compiler-sfc/src/templateUtils'
describe('compiler sfc:templateUtils isRelativeUrl', () => {
@@ -36,3 +37,17 @@ describe('compiler sfc:templateUtils isExternalUrl', () => {
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)
+ })
+})
diff --git a/packages/compiler-sfc/src/templateTransformAssetUrl.ts b/packages/compiler-sfc/src/templateTransformAssetUrl.ts
index a526d9a9..968b0606 100644
--- a/packages/compiler-sfc/src/templateTransformAssetUrl.ts
+++ b/packages/compiler-sfc/src/templateTransformAssetUrl.ts
@@ -7,7 +7,12 @@ import {
SourceLocation,
TransformContext
} from '@vue/compiler-core'
-import { isRelativeUrl, parseUrl, isExternalUrl } from './templateUtils'
+import {
+ isRelativeUrl,
+ parseUrl,
+ isExternalUrl,
+ isDataUrl
+} from './templateUtils'
import { isArray } from '@vue/shared'
export interface AssetURLTagConfig {
@@ -99,6 +104,7 @@ export const transformAssetUrl: NodeTransform = (
!assetAttrs.includes(attr.name) ||
!attr.value ||
isExternalUrl(attr.value.content) ||
+ isDataUrl(attr.value.content) ||
attr.value.content[0] === '#' ||
(!options.includeAbsolute && !isRelativeUrl(attr.value.content))
) {
diff --git a/packages/compiler-sfc/src/templateTransformSrcset.ts b/packages/compiler-sfc/src/templateTransformSrcset.ts
index 9790f896..7fcf6075 100644
--- a/packages/compiler-sfc/src/templateTransformSrcset.ts
+++ b/packages/compiler-sfc/src/templateTransformSrcset.ts
@@ -6,7 +6,12 @@ import {
NodeTypes,
SimpleExpressionNode
} from '@vue/compiler-core'
-import { isRelativeUrl, parseUrl, isExternalUrl } from './templateUtils'
+import {
+ isRelativeUrl,
+ parseUrl,
+ isExternalUrl,
+ isDataUrl
+} from './templateUtils'
import {
AssetURLOptions,
defaultAssetUrlOptions
@@ -51,6 +56,15 @@ export const transformSrcset: NodeTransform = (
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
if (
!options.includeAbsolute &&
@@ -78,6 +92,7 @@ export const transformSrcset: NodeTransform = (
imageCandidates.forEach(({ url, descriptor }, index) => {
if (
!isExternalUrl(url) &&
+ !isDataUrl(url) &&
(options.includeAbsolute || isRelativeUrl(url))
) {
const { path } = parseUrl(url)
diff --git a/packages/compiler-sfc/src/templateUtils.ts b/packages/compiler-sfc/src/templateUtils.ts
index 40b40199..6f93d612 100644
--- a/packages/compiler-sfc/src/templateUtils.ts
+++ b/packages/compiler-sfc/src/templateUtils.ts
@@ -11,6 +11,11 @@ export function isExternalUrl(url: string): boolean {
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.
*/