From a7c2331500c6cf70ec96d0f5406807afdef2a1f4 Mon Sep 17 00:00:00 2001 From: MellowCo <799478052@qq.com> Date: Sat, 19 Aug 2023 11:21:25 +0800 Subject: [PATCH] feat: simplify css props matcher --- src/rules/variables.ts | 44 +++++++++++++++++-- test/assets/output/preset-mini/targets.css | 1 - .../preset-weapp/targets-custom-rules.css | 1 - test/assets/output/preset-weapp/targets.css | 1 - test/assets/preset-mini-targets.ts | 2 +- test/preset-mini.test.ts | 2 +- 6 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/rules/variables.ts b/src/rules/variables.ts index a37cb39..35f4a57 100644 --- a/src/rules/variables.ts +++ b/src/rules/variables.ts @@ -26,12 +26,50 @@ export const cssVariables: Rule[] = [ ] export const cssProperty: Rule[] = [ - [/^\[(--(\w|\\\W)+|[\w-]+):(("[^\s"]+?"|'[^\s']+?'|`[^\s`]+?`|[^\s:'"`;{}]+?)+)\]$/, ([match, prop,, value]) => { - if (!isURI(match.slice(1, -1))) - return { [prop]: h.bracket(`[${value}]`) } + [/^\[(.*)\]$/, ([_, body]) => { + if (!body.includes(':')) + return + + const [prop, ...rest] = body.split(':') + const value = rest.join(':') + if (!isURI(body) && prop.match(/^[a-z-]+$/) && isValidCSSBody(value)) { + const parsed = h.bracket(`[${value}]`) + if (parsed) + return { [prop]: parsed } + } }], ] +function isValidCSSBody(body: string) { + let i = 0 + function findUntil(c: string) { + while (i < body.length) { + i += 1 + const char = body[i] + if (char === c) + return true + } + return false + } + + for (i = 0; i < body.length; i++) { + const c = body[i] + if ('"`\''.includes(c)) { + if (!findUntil(c)) + return false + } + else if (c === '(') { + if (!findUntil(')')) + return false + } + else if ('[]{}:'.includes(c)) { + return false + } + } + + return true +} + function isURI(declaration: string) { if (!declaration.includes('://')) return false diff --git a/test/assets/output/preset-mini/targets.css b/test/assets/output/preset-mini/targets.css index e64e755..1b78b8a 100644 --- a/test/assets/output/preset-mini/targets.css +++ b/test/assets/output/preset-mini/targets.css @@ -148,7 +148,6 @@ page,::before,::after{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate- .items-\$size{align-items:var(--size);} .ws-\$variable{white-space:var(--variable);} .\[--css-variable\:\"wght\"_400\,_\"opsz\"_14\]{--css-variable:"wght" 400, "opsz" 14;} -.\[--escaped\\\~variable\\\:\:100\%\]{--escaped\~variable\::100%;} .\[a\:b\]{a:b;} .\[background-image\:url\(star_transparent\.gif\)\,_url\(cat_front\.png\)\]{background-image:url(star_transparent.gif), url(cat_front.png);} .\[content\:attr\(attr_content\)\]{content:attr(attr content);} diff --git a/test/assets/output/preset-weapp/targets-custom-rules.css b/test/assets/output/preset-weapp/targets-custom-rules.css index c0e223e..88bb831 100644 --- a/test/assets/output/preset-weapp/targets-custom-rules.css +++ b/test/assets/output/preset-weapp/targets-custom-rules.css @@ -148,7 +148,6 @@ page,::before,::after{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate- .items-_do11_size{align-items:var(--size);} .ws-_do11_variable{white-space:var(--variable);} ._lfl11_--css-variable_cl11_\"wght\"_400_lco11__\"opsz\"_14_lfr11_{--css-variable:"wght" 400, "opsz" 14;} -._lfl11_--escaped\\\~variable\\_cl11__cl11_100_pes11__lfr11_{--escaped\~variable\::100%;} ._lfl11_a_cl11_b_lfr11_{a:b;} ._lfl11_background-image_cl11_url_lbl11_star_transparent_dl11_gif_lbr11__lco11__url_lbl11_cat_front_dl11_png_lbr11__lfr11_{background-image:url(star_transparent.gif), url(cat_front.png);} ._lfl11_content_cl11_attr_lbl11_attr_content_lbr11__lfr11_{content:attr(attr content);} diff --git a/test/assets/output/preset-weapp/targets.css b/test/assets/output/preset-weapp/targets.css index ac63707..2ff24fc 100644 --- a/test/assets/output/preset-weapp/targets.css +++ b/test/assets/output/preset-weapp/targets.css @@ -148,7 +148,6 @@ page,::before,::after{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate- .items-_do_size{align-items:var(--size);} .ws-_do_variable{white-space:var(--variable);} ._lfl_--css-variable_cl_\"wght\"_400_lco__\"opsz\"_14_lfr_{--css-variable:"wght" 400, "opsz" 14;} -._lfl_--escaped\\\~variable\\_cl__cl_100_pes__lfr_{--escaped\~variable\::100%;} ._lfl_a_cl_b_lfr_{a:b;} ._lfl_background-image_cl_url_lbl_star_transparent_dl_gif_lbr__lco__url_lbl_cat_front_dl_png_lbr__lfr_{background-image:url(star_transparent.gif), url(cat_front.png);} ._lfl_content_cl_attr_lbl_attr_content_lbr__lfr_{content:attr(attr content);} diff --git a/test/assets/preset-mini-targets.ts b/test/assets/preset-mini-targets.ts index df3236c..a8f385a 100644 --- a/test/assets/preset-mini-targets.ts +++ b/test/assets/preset-mini-targets.ts @@ -1079,7 +1079,6 @@ export const presetMiniTargets: string[] = [ '[font-feature-settings:\'cv02\',\'cv03\',\'cv04\',\'cv11\']', '[font-variation-settings:"wght"_400,_"opsz"_14]', '[--css-variable:"wght"_400,_"opsz"_14]', - '[--escaped\\~variable\\::100%]', // variants 'active:scale-4', @@ -1390,6 +1389,7 @@ export const presetMiniNonTargets = [ '[foo:\'bar\',"baz",`]', // escaped arbitrary css properties only allowed in css variables '[cant\~escape:me]', + '[https://example.com/documentation/](https://example.com/documentation/)', // not exists 'text-main/50', diff --git a/test/preset-mini.test.ts b/test/preset-mini.test.ts index 00dbefa..a6387d1 100644 --- a/test/preset-mini.test.ts +++ b/test/preset-mini.test.ts @@ -141,8 +141,8 @@ describe('preset-mini', () => { test('none targets', async () => { const { css, matched } = await uno.generate(new Set(presetMiniNonTargets), { minify: true, preflights: false }) - expect(css).toEqual('') expect([...matched]).toEqual([]) + expect(css).toEqual('') }) test('fontSize theme', async () => {