]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-sfc): transformAssetUrl should ignore inline data url (#1431)
authorunderfin <2218301630@qq.com>
Wed, 24 Jun 2020 01:46:18 +0000 (09:46 +0800)
committerGitHub <noreply@github.com>
Wed, 24 Jun 2020 01:46:18 +0000 (21:46 -0400)
packages/compiler-sfc/__tests__/__snapshots__/templateTransformAssetUrl.spec.ts.snap
packages/compiler-sfc/__tests__/__snapshots__/templateTransformSrcset.spec.ts.snap
packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts
packages/compiler-sfc/__tests__/templateTransformSrcset.spec.ts
packages/compiler-sfc/__tests__/templateUtils.spec.ts
packages/compiler-sfc/src/templateTransformAssetUrl.ts
packages/compiler-sfc/src/templateTransformSrcset.ts
packages/compiler-sfc/src/templateUtils.ts

index 998eeae568d39afc326912b40862e6d5f820b4f1..e1c962a6ff5650fad0d6727d014d3e7f0b909d69 100644 (file)
@@ -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 */))
 }"
 `;
index 75c72ac1947dd0dcab7881b005c9e454bd78668b..2f0572799085ccb5f3743247783b6239dae7f72e 100644 (file)
@@ -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 */))
 }"
index 71be0e5275564403603a6bf334b961c6e3374b70..41eb6463cc30147726e40e3b6978eef59b35aa56 100644 (file)
@@ -30,6 +30,7 @@ describe('compiler sfc: transform asset url', () => {
                        <img src="~/fixtures/logo.png"/>
                        <img src="http://example.com/fixtures/logo.png"/>
                        <img src="/fixtures/logo.png"/>
+                       <img src="data:image/png;base64,i"/>
                `)
 
     expect(result.code).toMatchSnapshot()
index 1bba07672b1deef2fd9654e693b40efdb0d1ecdb..9d55dc870ee42217f6206b4985b54661d0ed86cd 100644 (file)
@@ -35,6 +35,7 @@ const src = `
 <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="/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', () => {
index 7b4490fc76fc67df01bace2ccdda14c006a38dda..95bf619be5f389cb265776e860c7f73866a78ac3 100644 (file)
@@ -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)
+  })
+})
index a526d9a9c4291a5e97fad69c569c07e9b9b94ffa..968b0606b8cb072abf9421a2b723d739dd67780a 100644 (file)
@@ -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))
       ) {
index 9790f896cb17e7331448ca469154d7a3c08832f8..7fcf60754b728086d9ffe7e650ba5606c0ca4352 100644 (file)
@@ -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)
index 40b40199089b71b6b5010d4da42bd73f3daa9c52..6f93d612abfb45d2dccb6f144ee32b7bdd587bdf 100644 (file)
@@ -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.
  */