| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -104,6 +104,29 @@ describe('css url() references', () => { | |||
| 104 | 104 | }) | |
| 105 | 105 | }) | |
| 106 | 106 | ||
| 107 | + test('image-set with var', async () => { | ||
| 108 | + const imageSet = await getBg('.css-image-set-with-var') | ||
| 109 | + imageSet.split(', ').forEach((s) => { | ||
| 110 | + expect(s).toMatch(assetMatch) | ||
| 111 | + }) | ||
| 112 | + }) | ||
| 113 | + | ||
| 114 | + test('image-set with mix', async () => { | ||
| 115 | + const imageSet = await getBg('.css-image-set-mix-url-var') | ||
| 116 | + imageSet.split(', ').forEach((s) => { | ||
| 117 | + expect(s).toMatch(assetMatch) | ||
| 118 | + }) | ||
| 119 | + }) | ||
| 120 | + | ||
| 121 | + // not supported in browser now | ||
| 122 | + // https://drafts.csswg.org/css-images-4/#image-set-notation | ||
| 123 | + // test('image-set with multiple descriptor', async () => { | ||
| 124 | + // const imageSet = await getBg('.css-image-set-multiple-descriptor') | ||
| 125 | + // imageSet.split(', ').forEach((s) => { | ||
| 126 | + // expect(s).toMatch(assetMatch) | ||
| 127 | + // }) | ||
| 128 | + // }) | ||
| 129 | + | ||
| 107 | 130 | test('relative in @import', async () => { | |
| 108 | 131 | expect(await getBg('.css-url-relative-at-imported')).toMatch(assetMatch) | |
| 109 | 132 | }) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -26,6 +26,29 @@ | |||
| 26 | 26 | background-size: 10px; | |
| 27 | 27 | } | |
| 28 | 28 | ||
| 29 | + .css-image-set-with-var { | ||
| 30 | + --bg-img: url('../nested/asset.png'); | ||
| 31 | + background-image: -webkit-image-set(var(--bg-img) 1x, var(--bg-img) 2x); | ||
| 32 | + background-size: 10px; | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + .css-image-set-mix-url-var { | ||
| 36 | + --bg-img: url('../nested/asset.png'); | ||
| 37 | + background-image: -webkit-image-set( | ||
| 38 | + var(--bg-img) 1x, | ||
| 39 | + url('../nested/asset.png') 2x | ||
| 40 | + ); | ||
| 41 | + background-size: 10px; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + .css-image-set-multiple-descriptor { | ||
| 45 | + background-image: -webkit-image-set( | ||
| 46 | + '../nested/asset.png' type('image/png') 1x, | ||
| 47 | + '../nested/asset.png' type('image/png') 2x | ||
| 48 | + ); | ||
| 49 | + background-size: 10px; | ||
| 50 | + } | ||
| 51 | + | ||
| 29 | 52 | .css-url-public { | |
| 30 | 53 | background: url('/icon.png'); | |
| 31 | 54 | background-size: 10px; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -46,6 +46,34 @@ <h2>CSS url references</h2> | |||
| 46 | 46 | >CSS background with image-set() (relative)</span | |
| 47 | 47 | > | |
| 48 | 48 | </div> | |
| 49 | + <div class="css-image-set-with-var"> | ||
| 50 | + <span style="background: #fff"> | ||
| 51 | + CSS background image-set() (relative in var) | ||
| 52 | + </span> | ||
| 53 | + </div> | ||
| 54 | + <div class="css-image-set-mix-url-var"> | ||
| 55 | + <span style="background: #fff"> | ||
| 56 | + CSS background image-set() (mix var and url) | ||
| 57 | + </span> | ||
| 58 | + </div> | ||
| 59 | + <div class="css-image-set-multiple-descriptor"> | ||
| 60 | + <span style="background: #fff"> | ||
| 61 | + CSS background image-set() (with multiple descriptor) | ||
| 62 | + </span> | ||
| 63 | + </div> | ||
| 64 | + <div | ||
| 65 | + style=" | ||
| 66 | + background-image: -webkit-image-set( | ||
| 67 | + './nested/asset.png' type('image/png') 1x, | ||
| 68 | + './nested/asset.png' type('image/png') 2x | ||
| 69 | + ); | ||
| 70 | + background-size: 10px; | ||
| 71 | + " | ||
| 72 | + > | ||
| 73 | + <span style="background: #fff"> | ||
| 74 | + CSS background image-set() (with multiple descriptor) | ||
| 75 | + </span> | ||
| 76 | + </div> | ||
| 49 | 77 | <div class="css-url-relative-at-imported"> | |
| 50 | 78 | <span style="background: #fff" | |
| 51 | 79 | >CSS background (relative from @imported file in different dir)</span | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -104,6 +104,7 @@ const commonjsProxyRE = /\?commonjs-proxy/ | |||
| 104 | 104 | const inlineRE = /(\?|&)inline\b/ | |
| 105 | 105 | const inlineCSSRE = /(\?|&)inline-css\b/ | |
| 106 | 106 | const usedRE = /(\?|&)used\b/ | |
| 107 | + const varRE = /^var\(/i | ||
| 107 | 108 | ||
| 108 | 109 | const enum PreprocessLang { | |
| 109 | 110 | less = 'less', | |
@@ -980,7 +981,7 @@ export const cssUrlRE = | |||
| 980 | 981 | export const cssDataUriRE = | |
| 981 | 982 | /(?<=^|[^\w\-\u0080-\uffff])data-uri\(\s*('[^']+'|"[^"]+"|[^'")]+)\s*\)/ | |
| 982 | 983 | export const importCssRE = /@import ('[^']+\.css'|"[^"]+\.css"|[^'")]+\.css)/ | |
| 983 | - const cssImageSetRE = /image-set\(([^)]+)\)/ | ||
| 984 | + const cssImageSetRE = /(?<=image-set\()((?:[\w\-]+\([^\)]*\)|[^)])*)(?=\))/ | ||
| 984 | 985 | ||
| 985 | 986 | const UrlRewritePostcssPlugin: PostCSS.PluginCreator<{ | |
| 986 | 987 | replacer: CssUrlReplacer | |
@@ -1001,7 +1002,9 @@ const UrlRewritePostcssPlugin: PostCSS.PluginCreator<{ | |||
| 1001 | 1002 | const importer = declaration.source?.input.file | |
| 1002 | 1003 | return opts.replacer(rawUrl, importer) | |
| 1003 | 1004 | } | |
| 1004 | - const rewriterToUse = isCssUrl ? rewriteCssUrls : rewriteCssImageSet | ||
| 1005 | + const rewriterToUse = isCssImageSet | ||
| 1006 | + ? rewriteCssImageSet | ||
| 1007 | + : rewriteCssUrls | ||
| 1005 | 1008 | promises.push( | |
| 1006 | 1009 | rewriterToUse(declaration.value, replacerForDeclaration).then( | |
| 1007 | 1010 | (url) => { | |
@@ -1054,11 +1057,15 @@ function rewriteCssImageSet( | |||
| 1054 | 1057 | replacer: CssUrlReplacer | |
| 1055 | 1058 | ): Promise<string> { | |
| 1056 | 1059 | return asyncReplace(css, cssImageSetRE, async (match) => { | |
| 1057 | - const [matched, rawUrl] = match | ||
| 1058 | - const url = await processSrcSet(rawUrl, ({ url }) => | ||
| 1059 | - doUrlReplace(url, matched, replacer) | ||
| 1060 | - ) | ||
| 1061 | - return `image-set(${url})` | ||
| 1060 | + const [, rawUrl] = match | ||
| 1061 | + const url = await processSrcSet(rawUrl, async ({ url }) => { | ||
| 1062 | + // the url maybe url(...) | ||
| 1063 | + if (cssUrlRE.test(url)) { | ||
| 1064 | + return await rewriteCssUrls(url, replacer) | ||
| 1065 | + } | ||
| 1066 | + return await doUrlReplace(url, url, replacer) | ||
| 1067 | + }) | ||
| 1068 | + return url | ||
| 1062 | 1069 | }) | |
| 1063 | 1070 | } | |
| 1064 | 1071 | async function doUrlReplace( | |
@@ -1073,7 +1080,13 @@ async function doUrlReplace( | |||
| 1073 | 1080 | wrap = first | |
| 1074 | 1081 | rawUrl = rawUrl.slice(1, -1) | |
| 1075 | 1082 | } | |
| 1076 | - if (isExternalUrl(rawUrl) || isDataUrl(rawUrl) || rawUrl.startsWith('#')) { | ||
| 1083 | + | ||
| 1084 | + if ( | ||
| 1085 | + isExternalUrl(rawUrl) || | ||
| 1086 | + isDataUrl(rawUrl) || | ||
| 1087 | + rawUrl.startsWith('#') || | ||
| 1088 | + varRE.test(rawUrl) | ||
| 1089 | + ) { | ||
| 1077 | 1090 | return matched | |
| 1078 | 1091 | } | |
| 1079 | 1092 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -545,18 +545,21 @@ interface ImageCandidate { | |||
| 545 | 545 | descriptor: string | |
| 546 | 546 | } | |
| 547 | 547 | const escapedSpaceCharacters = /( |\\t|\\n|\\f|\\r)+/g | |
| 548 | + const imageSetUrlRE = /^(?:[\w\-]+\(.*?\)|'.*?'|".*?"|\S*)/ | ||
| 548 | 549 | export async function processSrcSet( | |
| 549 | 550 | srcs: string, | |
| 550 | 551 | replacer: (arg: ImageCandidate) => Promise<string> | |
| 551 | 552 | ): Promise<string> { | |
| 552 | 553 | const imageCandidates: ImageCandidate[] = srcs | |
| 553 | 554 | .split(',') | |
| 554 | 555 | .map((s) => { | |
| 555 | - const [url, descriptor] = s | ||
| 556 | - .replace(escapedSpaceCharacters, ' ') | ||
| 557 | - .trim() | ||
| 558 | - .split(' ', 2) | ||
| 559 | - return { url, descriptor } | ||
| 556 | + const src = s.replace(escapedSpaceCharacters, ' ').trim() | ||
| 557 | + const [url] = imageSetUrlRE.exec(src) || [] | ||
| 558 | + | ||
| 559 | + return { | ||
| 560 | + url, | ||
| 561 | + descriptor: src?.slice(url.length).trim() | ||
| 562 | + } | ||
| 560 | 563 | }) | |
| 561 | 564 | .filter(({ url }) => !!url) | |
| 562 | 565 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments