Skip to content

Commit

Permalink
fix(preset-mini): simplify css props matcher, fix #2951
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Aug 7, 2023
1 parent 93a0812 commit b01eca9
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 11 deletions.
44 changes: 41 additions & 3 deletions packages/preset-mini/src/_rules/variables.ts
Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion test/assets/output/preset-mini-targets.css
Expand Up @@ -7,7 +7,6 @@
.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);}
Expand Down
3 changes: 2 additions & 1 deletion test/assets/preset-mini-targets.ts
Expand Up @@ -926,7 +926,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',
Expand Down Expand Up @@ -1145,6 +1144,8 @@ export const presetMiniNonTargets = [
'[foo:\'bar\',"baz",`]',
// escaped arbitrary css properties only allowed in css variables
'[cant\~escape:me]',
// https://github.com/unocss/unocss/issues/2951
'[https://example.com/documentation/](https://example.com/documentation/)',

// not exists
'text-main/50',
Expand Down
5 changes: 0 additions & 5 deletions test/pos.test.ts
Expand Up @@ -176,11 +176,6 @@ describe('matched-positions', async () => {
37,
"[color:'red']",
],
[
52,
71,
"[content:'bar:baz']",
],
]
`)
})
Expand Down
2 changes: 1 addition & 1 deletion test/preset-mini.test.ts
Expand Up @@ -144,8 +144,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 () => {
Expand Down

0 comments on commit b01eca9

Please sign in to comment.