From 174ea111b20c9c49cce4d1494b924abfcd1851e7 Mon Sep 17 00:00:00 2001 From: zhangyu96 Date: Wed, 27 Apr 2022 10:49:17 +0800 Subject: [PATCH 1/8] fix(css): var in image-set --- packages/playground/assets/__tests__/assets.spec.ts | 7 +++++++ packages/playground/assets/css/css-url.css | 6 ++++++ packages/playground/assets/index.html | 5 +++++ packages/vite/src/node/plugins/css.ts | 13 ++++++++++--- 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/packages/playground/assets/__tests__/assets.spec.ts b/packages/playground/assets/__tests__/assets.spec.ts index 75c0e57952db24..62fd5354d6df95 100644 --- a/packages/playground/assets/__tests__/assets.spec.ts +++ b/packages/playground/assets/__tests__/assets.spec.ts @@ -105,6 +105,13 @@ describe('css url() references', () => { }) }) + test('image-set with var', async () => { + const imageSet = await getBg('.css-image-set-with-var') + imageSet.split(', ').forEach((s) => { + expect(s).toMatch(assetMatch) + }) + }) + test('relative in @import', async () => { expect(await getBg('.css-url-relative-at-imported')).toMatch(assetMatch) }) diff --git a/packages/playground/assets/css/css-url.css b/packages/playground/assets/css/css-url.css index 8a3f00dee17bd9..35bed94c286e3b 100644 --- a/packages/playground/assets/css/css-url.css +++ b/packages/playground/assets/css/css-url.css @@ -26,6 +26,12 @@ background-size: 10px; } +.css-image-set-with-var { + --bg-img: url('../nested/asset.png'); + background-image: -webkit-image-set(var(--bg-img) 1x, var(--bg-img) 2x); + background-size: 10px; +} + .css-url-public { background: url('/icon.png'); background-size: 10px; diff --git a/packages/playground/assets/index.html b/packages/playground/assets/index.html index 6678a2da7c2106..1ee6411dee5305 100644 --- a/packages/playground/assets/index.html +++ b/packages/playground/assets/index.html @@ -46,6 +46,11 @@

CSS url references

>CSS background with image-set() (relative) +
+ + CSS background image-set() (relative in var) + +
CSS background (relative from @imported file in different dir) doUrlReplace(url, matched, replacer) ) - return `image-set(${url})` + return url }) } async function doUrlReplace( @@ -1061,7 +1062,13 @@ async function doUrlReplace( wrap = first rawUrl = rawUrl.slice(1, -1) } - if (isExternalUrl(rawUrl) || isDataUrl(rawUrl) || rawUrl.startsWith('#')) { + + if ( + isExternalUrl(rawUrl) || + isDataUrl(rawUrl) || + rawUrl.startsWith('#') || + varRE.test(rawUrl) + ) { return matched } From 86522c790c83b03bf784be74cb43cec0b1cbbc03 Mon Sep 17 00:00:00 2001 From: zhangyu96 Date: Thu, 28 Apr 2022 17:38:34 +0800 Subject: [PATCH 2/8] fix(css): var in image-set --- .../playground/assets/__tests__/assets.spec.ts | 14 ++++++++++++++ packages/playground/assets/css/css-url.css | 17 +++++++++++++++++ packages/playground/assets/index.html | 10 ++++++++++ packages/vite/src/node/plugins/css.ts | 18 ++++++++++++------ packages/vite/src/node/utils.ts | 7 ++++--- 5 files changed, 57 insertions(+), 9 deletions(-) diff --git a/packages/playground/assets/__tests__/assets.spec.ts b/packages/playground/assets/__tests__/assets.spec.ts index 62fd5354d6df95..c886c65a18d091 100644 --- a/packages/playground/assets/__tests__/assets.spec.ts +++ b/packages/playground/assets/__tests__/assets.spec.ts @@ -112,6 +112,20 @@ describe('css url() references', () => { }) }) + test('image-set with mix', async () => { + const imageSet = await getBg('.css-image-set-mix-url-var') + imageSet.split(', ').forEach((s) => { + expect(s).toMatch(assetMatch) + }) + }) + + // test('image-set with multiple descriptor', async () => { + // const imageSet = await getBg('.css-image-set-multiple-descriptor') + // imageSet.split(', ').forEach((s) => { + // expect(s).toMatch(assetMatch) + // }) + // }) + test('relative in @import', async () => { expect(await getBg('.css-url-relative-at-imported')).toMatch(assetMatch) }) diff --git a/packages/playground/assets/css/css-url.css b/packages/playground/assets/css/css-url.css index 35bed94c286e3b..9047cd384e7d38 100644 --- a/packages/playground/assets/css/css-url.css +++ b/packages/playground/assets/css/css-url.css @@ -32,6 +32,23 @@ background-size: 10px; } +.css-image-set-mix-url-var { + --bg-img: url('../nested/asset.png'); + background-image: -webkit-image-set( + var(--bg-img) 1x, + url('../nested/asset.png') 2x + ); + background-size: 10px; +} + +.css-image-set-multiple-descriptor { + background-image: -webkit-image-set( + '../nested/asset.png' type('image/png') 1x, + '../nested/asset.png' type('image/png') 2x + ); + background-size: 10px; +} + .css-url-public { background: url('/icon.png'); background-size: 10px; diff --git a/packages/playground/assets/index.html b/packages/playground/assets/index.html index 1ee6411dee5305..f5cfb2fcf0f16f 100644 --- a/packages/playground/assets/index.html +++ b/packages/playground/assets/index.html @@ -51,6 +51,16 @@

CSS url references

CSS background image-set() (relative in var)
+
+ + CSS background image-set() (mix var and url) + +
+
+ + CSS background image-set() (with multiple descriptor) + +
CSS background (relative from @imported file in different dir) { @@ -1043,10 +1045,14 @@ function rewriteCssImageSet( replacer: CssUrlReplacer ): Promise { return asyncReplace(css, cssImageSetRE, async (match) => { - const [matched, rawUrl] = match - const url = await processSrcSet(rawUrl, ({ url }) => - doUrlReplace(url, matched, replacer) - ) + const [, rawUrl] = match + const url = await processSrcSet(rawUrl, async ({ url }) => { + // the url maybe url(...) + if (cssUrlRE.test(url)) { + return await rewriteCssUrls(url, replacer) + } + return await doUrlReplace(url, url, replacer) + }) return url }) } diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index e7a20afbdd5ae7..a36689edc88ae7 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -552,11 +552,12 @@ export async function processSrcSet( const imageCandidates: ImageCandidate[] = srcs .split(',') .map((s) => { - const [url, descriptor] = s + const [url, ...descriptorArr] = s .replace(escapedSpaceCharacters, ' ') .trim() - .split(' ', 2) - return { url, descriptor } + .split(' ') + + return { url, descriptor: descriptorArr.join(' ') } }) .filter(({ url }) => !!url) From 20b81b00f201c451aa10ee0cd369e8ee3682bda6 Mon Sep 17 00:00:00 2001 From: zhangyu96 Date: Fri, 29 Apr 2022 11:33:55 +0800 Subject: [PATCH 3/8] fix(css): var in image-set --- packages/vite/src/node/utils.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index a36689edc88ae7..d98561329deed1 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -545,6 +545,7 @@ interface ImageCandidate { descriptor: string } const escapedSpaceCharacters = /( |\\t|\\n|\\f|\\r)+/g +const imageSetUrlRE = /^([\w\-]+\(.*?\)|'.*?'|".*?")/ export async function processSrcSet( srcs: string, replacer: (arg: ImageCandidate) => Promise @@ -552,12 +553,13 @@ export async function processSrcSet( const imageCandidates: ImageCandidate[] = srcs .split(',') .map((s) => { - const [url, ...descriptorArr] = s - .replace(escapedSpaceCharacters, ' ') - .trim() - .split(' ') + let src = s.replace(escapedSpaceCharacters, ' ').trim() + let [, url] = imageSetUrlRE.exec(src) || [] - return { url, descriptor: descriptorArr.join(' ') } + return { + url, + descriptor: src?.slice(url.length) + } }) .filter(({ url }) => !!url) From d8b4a7ae632d5292e5d3c9515763b939b46c4b7b Mon Sep 17 00:00:00 2001 From: zhangyu96 Date: Fri, 29 Apr 2022 14:46:52 +0800 Subject: [PATCH 4/8] fix(css): var in image-set --- packages/vite/src/node/utils.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index d98561329deed1..b323f6ab2a9e9f 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -545,7 +545,7 @@ interface ImageCandidate { descriptor: string } const escapedSpaceCharacters = /( |\\t|\\n|\\f|\\r)+/g -const imageSetUrlRE = /^([\w\-]+\(.*?\)|'.*?'|".*?")/ +const imageSetUrlRE = /^(?:[\w\-]+\(.*?\)|'.*?'|".*?"|\S*)/ export async function processSrcSet( srcs: string, replacer: (arg: ImageCandidate) => Promise @@ -554,11 +554,11 @@ export async function processSrcSet( .split(',') .map((s) => { let src = s.replace(escapedSpaceCharacters, ' ').trim() - let [, url] = imageSetUrlRE.exec(src) || [] + let [url] = imageSetUrlRE.exec(src) || [] return { url, - descriptor: src?.slice(url.length) + descriptor: src?.slice(url.length).trim() } }) .filter(({ url }) => !!url) From 4951e7dd5247ad2b707045640960f8176d5b0c22 Mon Sep 17 00:00:00 2001 From: zhangyu96 Date: Fri, 29 Apr 2022 16:58:19 +0800 Subject: [PATCH 5/8] update --- packages/vite/src/node/utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index b323f6ab2a9e9f..32b783974dacaf 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -553,8 +553,8 @@ export async function processSrcSet( const imageCandidates: ImageCandidate[] = srcs .split(',') .map((s) => { - let src = s.replace(escapedSpaceCharacters, ' ').trim() - let [url] = imageSetUrlRE.exec(src) || [] + const src = s.replace(escapedSpaceCharacters, ' ').trim() + const [url] = imageSetUrlRE.exec(src) || [] return { url, From 8e1d6ae0b00207ab8fd6e1f0e0c1ec73cab5c1f5 Mon Sep 17 00:00:00 2001 From: yoho Date: Mon, 2 May 2022 19:57:52 +0800 Subject: [PATCH 6/8] test: test for inline style in html --- packages/playground/assets/index.html | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/playground/assets/index.html b/packages/playground/assets/index.html index f5cfb2fcf0f16f..d56b88727e1051 100644 --- a/packages/playground/assets/index.html +++ b/packages/playground/assets/index.html @@ -61,6 +61,19 @@

CSS url references

CSS background image-set() (with multiple descriptor)
+
+ + CSS background image-set() (with multiple descriptor) + +
CSS background (relative from @imported file in different dir) Date: Mon, 2 May 2022 23:42:59 +0800 Subject: [PATCH 7/8] update --- packages/playground/assets/__tests__/assets.spec.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/playground/assets/__tests__/assets.spec.ts b/packages/playground/assets/__tests__/assets.spec.ts index c886c65a18d091..7956f5b2440e96 100644 --- a/packages/playground/assets/__tests__/assets.spec.ts +++ b/packages/playground/assets/__tests__/assets.spec.ts @@ -119,6 +119,8 @@ describe('css url() references', () => { }) }) + // not supported in browser now + // https://drafts.csswg.org/css-images-4/#image-set-notation // test('image-set with multiple descriptor', async () => { // const imageSet = await getBg('.css-image-set-multiple-descriptor') // imageSet.split(', ').forEach((s) => { From 6a4b9c47f239efb60d44fe7d7130b4df7d8a288d Mon Sep 17 00:00:00 2001 From: patak Date: Mon, 2 May 2022 20:33:59 +0200 Subject: [PATCH 8/8] chore: update var regex --- packages/vite/src/node/plugins/css.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index 1a2bed9b43754d..62b8b259147fe8 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -102,7 +102,7 @@ const commonjsProxyRE = /\?commonjs-proxy/ const inlineRE = /(\?|&)inline\b/ const inlineCSSRE = /(\?|&)inline-css\b/ const usedRE = /(\?|&)used\b/ -const varRE = /^var/i +const varRE = /^var\(/i const enum PreprocessLang { less = 'less',