Skip to content

Commit 11099b6

Browse files
committed
Match predefined function names case-insensitively
This commit fixes some case-sensitives operations on predefined function names, which are no longer normalized to lowercase during tokenization since 62c87e1. For performance reasons, substitutions are not parsed like other functions so there are now tests in uppercase for all of them. Some checks are not implemented ideally and will be revisited later.
1 parent 8304dbc commit 11099b6

File tree

4 files changed

+45
-41
lines changed

4 files changed

+45
-41
lines changed

__tests__/style.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -408,11 +408,11 @@ describe('arbitrary substitution', () => {
408408
const style = createStyleBlock()
409409
const valid = [
410410
// Valid at parse time
411-
['unknown(attr(name))'],
412-
['unknown(env(name))'],
413-
['unknown(inherit(--custom))'],
414-
['unknown(random-item(--key, 1))'],
415-
['unknown(var(--custom))'],
411+
['unknown(ATTR(name))'],
412+
['unknown(ENV(name))'],
413+
['unknown(INHERIT(--custom))'],
414+
['unknown(RANDOM-ITEM(--key, 1))'],
415+
['unknown(VAR(--custom))'],
416416
['unknown(--custom())'],
417417
// Nested inside itself
418418
['attr(name, attr(name))'],
@@ -470,10 +470,10 @@ describe('<whole-value>', () => {
470470
const style = createStyleBlock()
471471
const valid = [
472472
// Resolved at parse time
473-
['first-valid(1)', '1', 'opacity'],
473+
['FIRST-VALID(1)', '1', 'opacity'],
474474
// Serialize the list of tokens
475-
[' /**/ mix( 0, 1, /**/ 1e0 /**/ ', 'mix(0, 1, 1)', 'opacity'],
476-
[' /**/ toggle( /**/ 1e0 /**/ ', 'toggle(1)', 'opacity'],
475+
[' /**/ MIX( 0, 1, /**/ 1e0 /**/ ', 'mix(0, 1, 1)', 'opacity'],
476+
[' /**/ TOGGLE( /**/ 1e0 /**/ ', 'toggle(1)', 'opacity'],
477477
// Nested inside itself
478478
['first-valid(toggle(first-valid(1)))', 'toggle(1)', 'opacity'],
479479
['mix(0, 1, toggle(mix(0, 1, 1)))', 'mix(0, 1, toggle(mix(0, 1, 1)))', 'opacity'],

__tests__/value.js

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,6 +1061,10 @@ describe('<url>', () => {
10611061
})
10621062
test('valid', () => {
10631063
const valid = [
1064+
// Case-insensitive name
1065+
['URL(file.jpg)', 'url("file.jpg")'],
1066+
['URL("file.jpg")', 'url("file.jpg")'],
1067+
['SRC("file.jpg")', 'src("file.jpg")'],
10641068
// Unclosed (parse error)
10651069
['url(', 'url("")'],
10661070
['url( ', 'url("")'],
@@ -1638,7 +1642,7 @@ describe('<calc()>', () => {
16381642
test('valid single operand', () => {
16391643
const valid = [
16401644
// <number>, <dimension>, <percentage>
1641-
['<number>', 'calc(1)'],
1645+
['<number>', 'CALC(1)', 'calc(1)'],
16421646
['<length>', 'calc(1px)'],
16431647
['<percentage>', 'calc(1%)'],
16441648
// <calc-keyword>
@@ -1819,7 +1823,7 @@ describe('<min()>, <max()>', () => {
18191823
['<length-percentage>', 'min(1%)', 'calc(1%)'],
18201824
// Identical units
18211825
['<number>', 'min(0, 1)', 'calc(0)'],
1822-
['<length>', 'min(0em, 1em)'],
1826+
['<length>', 'MIN(0em, 1em)', 'min(0em, 1em)'],
18231827
['<length-percentage>', 'min(0%, 1%)'],
18241828
['<percentage>', 'min(0%, 1%)', 'calc(0%)'],
18251829
// Different units
@@ -1854,7 +1858,7 @@ describe('<clamp()>', () => {
18541858
['<number>', 'clamp(0, 2, 1)', 'calc(1)'],
18551859
['<number>', 'clamp(1, 0, 2)', 'calc(1)'],
18561860
['<number>', 'clamp(1, 2, 0)', 'calc(1)'],
1857-
['<length>', 'clamp(0em, 1em, 2em)'],
1861+
['<length>', 'CLAMP(0em, 1em, 2em)', 'clamp(0em, 1em, 2em)'],
18581862
['<length-percentage>', 'clamp(0%, 1%, 2%)'],
18591863
['<percentage>', 'clamp(0%, 1%, 2%)', 'calc(1%)'],
18601864
// Different units
@@ -1891,7 +1895,7 @@ describe('<round()>', () => {
18911895
['<number>', 'round(down, 1.9)', 'calc(1)'],
18921896
['<number>', 'round(to-zero, 1, 2)', 'calc(0)'],
18931897
['<number>', 'round(to-zero, -1, 2)', 'calc(0)'],
1894-
['<length>', 'round(1em, 1em)'],
1898+
['<length>', 'ROUND(1em, 1em)', 'round(1em, 1em)'],
18951899
['<length-percentage>', 'round(1%, 1%)'],
18961900
['<percentage>', 'round(1%, 1%)', 'calc(1%)'],
18971901
// Different units
@@ -1974,7 +1978,7 @@ describe('<mod()>', () => {
19741978
['<number>', 'mod(3, 2)', 'calc(1)'],
19751979
['<number>', 'mod(3, -2)', 'calc(-1)'],
19761980
['<number>', 'mod(-3, 2)', 'calc(1)'],
1977-
['<length>', 'mod(3em, 2em)'],
1981+
['<length>', 'MOD(3em, 2em)', 'mod(3em, 2em)'],
19781982
['<length-percentage>', 'mod(3%, 2%)'],
19791983
['<percentage>', 'mod(3%, 2%)', 'calc(1%)'],
19801984
// Different units
@@ -2018,7 +2022,7 @@ describe('<rem()>', () => {
20182022
['<number>', 'rem(3, 2)', 'calc(1)'],
20192023
['<number>', 'rem(3, -2)', 'calc(1)'],
20202024
['<number>', 'rem(-3, 2)', 'calc(-1)'],
2021-
['<length>', 'rem(3em, 2em)'],
2025+
['<length>', 'REM(3em, 2em)', 'rem(3em, 2em)'],
20222026
['<length-percentage>', 'rem(3%, 2%)'],
20232027
['<percentage>', 'rem(3%, 2%)', 'calc(1%)'],
20242028
// Different units
@@ -2059,7 +2063,7 @@ describe('<sin()>', () => {
20592063
const valid = [
20602064
['<number>', 'sin(45)', `calc(${+Math.sin(45).toFixed(6)})`],
20612065
['<number>', 'sin(45deg)', `calc(${+Math.sin(toRadians(45)).toFixed(6)})`],
2062-
['<angle-percentage>', 'calc(1deg * sin(1%))'],
2066+
['<angle-percentage>', 'calc(1deg * SIN(1%))', 'calc(1deg * sin(1%))'],
20632067
]
20642068
valid.forEach(([definition, input, expected = input]) => expect(parse(definition, input)).toBe(expected))
20652069
})
@@ -2085,7 +2089,7 @@ describe('<cos()>', () => {
20852089
const valid = [
20862090
['<number>', 'cos(45)', `calc(${+Math.cos(45).toFixed(6)})`],
20872091
['<number>', 'cos(45deg)', `calc(${+Math.cos(toRadians(45)).toFixed(6)})`],
2088-
['<angle-percentage>', 'calc(1deg * cos(1%))'],
2092+
['<angle-percentage>', 'calc(1deg * COS(1%))', 'calc(1deg * cos(1%))'],
20892093
]
20902094
valid.forEach(([definition, input, expected = input]) => expect(parse(definition, input)).toBe(expected))
20912095
})
@@ -2106,7 +2110,7 @@ describe('<tan()>', () => {
21062110
const valid = [
21072111
['<number>', 'tan(45)', `calc(${+Math.tan(45).toFixed(6)})`],
21082112
['<number>', 'tan(45deg)', `calc(${+Math.tan(toRadians(45)).toFixed(6)})`],
2109-
['<angle-percentage>', 'calc(1deg * tan(1%))'],
2113+
['<angle-percentage>', 'calc(1deg * TAN(1%))', 'calc(1deg * tan(1%))'],
21102114
]
21112115
valid.forEach(([definition, input, expected = input]) => expect(parse(definition, input)).toBe(expected))
21122116
})
@@ -2141,7 +2145,7 @@ describe('<asin()>', () => {
21412145
})
21422146
test('valid', () => {
21432147
expect(parse('<angle>', 'asin(0.5)')).toBe('calc(30deg)')
2144-
expect(parse('<angle-percentage>', 'asin(1% / 1deg)')).toBe('asin(1% / 1deg)')
2148+
expect(parse('<angle-percentage>', 'ASIN(1% / 1deg)')).toBe('asin(1% / 1deg)')
21452149
})
21462150
})
21472151
describe('<acos()>', () => {
@@ -2159,7 +2163,7 @@ describe('<acos()>', () => {
21592163
})
21602164
test('valid', () => {
21612165
expect(parse('<angle>', 'acos(0.5)')).toBe('calc(60deg)')
2162-
expect(parse('<angle-percentage>', 'acos(1% / 1deg)')).toBe('acos(1% / 1deg)')
2166+
expect(parse('<angle-percentage>', 'ACOS(1% / 1deg)')).toBe('acos(1% / 1deg)')
21632167
})
21642168
})
21652169
describe('<atan()>', () => {
@@ -2177,7 +2181,7 @@ describe('<atan()>', () => {
21772181
})
21782182
test('valid', () => {
21792183
expect(parse('<angle>', 'atan(0.5)')).toBe(`calc(${+toDegrees(Math.atan(0.5)).toFixed(6)}deg)`)
2180-
expect(parse('<angle-percentage>', 'atan(1% / 1deg)')).toBe('atan(1% / 1deg)')
2184+
expect(parse('<angle-percentage>', 'ATAN(1% / 1deg)')).toBe('atan(1% / 1deg)')
21812185
})
21822186
})
21832187
describe('<atan2()>', () => {
@@ -2196,7 +2200,7 @@ describe('<atan2()>', () => {
21962200
const valid = [
21972201
['<angle>', 'atan2(1, 1)', `calc(${+toDegrees(Math.atan2(1, 1)).toFixed(6)}deg)`],
21982202
['<angle>', 'atan2(1px, 1px)', `calc(${+toDegrees(Math.atan2(1, 1)).toFixed(6)}deg)`],
2199-
['<length-percentage>', 'calc(atan2(1%, 1%) / 1deg * 1px)', 'calc(1px * atan2(1%, 1%) / 1deg)'],
2203+
['<length-percentage>', 'calc(ATAN2(1%, 1%) / 1deg * 1px)', 'calc(1px * atan2(1%, 1%) / 1deg)'],
22002204
['<angle>', 'atan2(1in, 100px)', `calc(${+toDegrees(Math.atan2(96, 100)).toFixed(6)}deg)`],
22012205
['<angle>', 'atan2(1em, 1px)', 'atan2(1em, 1px)'],
22022206
['<angle-percentage>', 'atan2(1deg, atan2(1%, 1%))', 'atan2(1deg, atan2(1%, 1%))'],
@@ -2218,7 +2222,7 @@ describe('<pow()>', () => {
22182222
})
22192223
test('valid', () => {
22202224
expect(parse('<number>', 'pow(4, 2)')).toBe('calc(16)')
2221-
expect(parse('<length-percentage>', 'calc(1px * pow(1, 1% / 1px))')).toBe('calc(1px * pow(1, 1% / 1px))')
2225+
expect(parse('<length-percentage>', 'calc(1px * POW(1, 1% / 1px))')).toBe('calc(1px * pow(1, 1% / 1px))')
22222226
})
22232227
})
22242228
describe('<sqrt()>', () => {
@@ -2235,7 +2239,7 @@ describe('<sqrt()>', () => {
22352239
})
22362240
test('valid', () => {
22372241
expect(parse('<number>', 'sqrt(4)')).toBe('calc(2)')
2238-
expect(parse('<length-percentage>', 'calc(1px * sqrt(1% / 1px))')).toBe('calc(1px * sqrt(1% / 1px))')
2242+
expect(parse('<length-percentage>', 'calc(1px * SQRT(1% / 1px))')).toBe('calc(1px * sqrt(1% / 1px))')
22392243
})
22402244
})
22412245
describe('<hypot()>', () => {
@@ -2254,7 +2258,7 @@ describe('<hypot()>', () => {
22542258
const valid = [
22552259
// Identical units
22562260
['<number>', 'hypot(3, 4)', 'calc(5)'],
2257-
['<length>', 'hypot(1em, 2em)'],
2261+
['<length>', 'HYPOT(1em, 2em)', 'hypot(1em, 2em)'],
22582262
['<length-percentage>', 'hypot(1%)'],
22592263
['<percentage>', 'hypot(3%, 4%)', 'calc(5%)'],
22602264
// Different units
@@ -2281,7 +2285,7 @@ describe('<log()>', () => {
22812285
const valid = [
22822286
['<number>', 'log(e)', 'calc(1)'],
22832287
['<number>', 'log(8, 2)', 'calc(3)'],
2284-
['<length-percentage>', 'calc(1px * log(1, 1% / 1px))'],
2288+
['<length-percentage>', 'calc(1px * LOG(1, 1% / 1px))', 'calc(1px * log(1, 1% / 1px))'],
22852289
]
22862290
valid.forEach(([definition, input, expected = input]) => expect(parse(definition, input)).toBe(expected))
22872291
})
@@ -2300,7 +2304,7 @@ describe('<exp()>', () => {
23002304
})
23012305
test('valid', () => {
23022306
expect(parse('<number>', 'exp(1)')).toBe(`calc(${Math.E.toFixed(6)})`)
2303-
expect(parse('<length-percentage>', 'calc(1px * exp(1% / 1px))')).toBe('calc(1px * exp(1% / 1px))')
2307+
expect(parse('<length-percentage>', 'calc(1px * EXP(1% / 1px))')).toBe('calc(1px * exp(1% / 1px))')
23042308
})
23052309
})
23062310
describe('<abs()>', () => {
@@ -2312,7 +2316,7 @@ describe('<abs()>', () => {
23122316
const valid = [
23132317
['<number>', 'abs(-1)', 'calc(1)'],
23142318
['<number>', 'abs(-infinity)', 'calc(infinity)'],
2315-
['<length>', 'abs(-1em)'],
2319+
['<length>', 'ABS(-1em)', 'abs(-1em)'],
23162320
['<length-percentage>', 'abs(abs(-1%))'],
23172321
['<percentage>', 'abs(-1%)', 'calc(1%)'],
23182322
]
@@ -2328,7 +2332,7 @@ describe('<sign()>', () => {
23282332
const valid = [
23292333
['<number>', 'sign(-2)', 'calc(-1)'],
23302334
['<number>', 'sign(-infinity)', 'calc(-1)'],
2331-
['<number>', 'sign(-1em)', 'sign(-1em)'],
2335+
['<number>', 'SIGN(-1em)', 'sign(-1em)'],
23322336
['<length-percentage>', 'calc(sign(-1%) * 1%)', 'calc(1% * sign(-1%))'],
23332337
]
23342338
valid.forEach(([definition, input, expected]) => expect(parse(definition, input)).toBe(expected))
@@ -2353,7 +2357,7 @@ describe('<calc-mix()>', () => {
23532357
})
23542358
test('valid', () => {
23552359
const valid = [
2356-
['<length>', 'calc-mix(--timeline, 1px * 1, 1px)', 'calc-mix(--timeline, 1px, 1px)'],
2360+
['<length>', 'CALC-MIX(--timeline, 1px * 1, 1px)', 'calc-mix(--timeline, 1px, 1px)'],
23572361
['<length>', 'calc-mix(0 * 1, 1px, 1px)', 'calc-mix(0, 1px, 1px)'],
23582362
['<length>', 'calc-mix(0%, 1px, 1px)'],
23592363
['<length>', 'calc-mix(progress(1%, 1% + 1%, 1%), 1px, 1px)', 'calc-mix(1, 1px, 1px)'],
@@ -2379,7 +2383,7 @@ describe('<random()>', () => {
23792383
})
23802384
test('valid', () => {
23812385
const valid = [
2382-
['<number>', 'random(auto, 1 / 1, 1em / 1px)', 'random(1, 1em / 1px)'],
2386+
['<number>', 'RANDOM(auto, 1 / 1, 1em / 1px)', 'random(1, 1em / 1px)'],
23832387
['<length-percentage>', 'random(--key, 1px, 1%)'],
23842388
['<length-percentage>', 'calc(1px * random(1% / 1px, 1))'],
23852389
]
@@ -2405,7 +2409,7 @@ describe('<progress()>', () => {
24052409
['<number>', 'progress(1, 0, 2)', 'calc(0.5)'],
24062410
['<number>', 'progress(1, 2, 0)', 'calc(0.5)'],
24072411
['<number>', 'progress(-1, 0, 2)', 'calc(-0.5)'],
2408-
['<number>', 'progress(1em, 0em, 2em)'],
2412+
['<number>', 'PROGRESS(1em, 0em, 2em)', 'progress(1em, 0em, 2em)'],
24092413
['<length-percentage>', 'calc(1px * progress(1%, 0%, 2%))'],
24102414
// Different units
24112415
['<number>', 'progress(48px, 0px, 1in)', 'calc(0.5)'],
@@ -2436,7 +2440,7 @@ describe('<container-progress()>', () => {
24362440
invalid.forEach(([definition, input]) => expect(parse(definition, input, false)).toBeNull())
24372441
})
24382442
test('valid', () => {
2439-
expect(parse('<number>', 'container-progress(width, 0px + 1px, 1px * 1)'))
2443+
expect(parse('<number>', 'CONTAINER-PROGRESS(width, 0px + 1px, 1px * 1)'))
24402444
.toBe('container-progress(width, 1px, 1px)')
24412445
expect(parse('<number>', 'container-progress(aspect-ratio, -1, 1)'))
24422446
.toBe('container-progress(aspect-ratio, -1, 1)')
@@ -2459,13 +2463,13 @@ describe('<media-progress()>', () => {
24592463
invalid.forEach(([definition, input]) => expect(parse(definition, input, false)).toBeNull())
24602464
})
24612465
test('valid', () => {
2462-
expect(parse('<number>', 'media-progress(width, 0px + 1px, 1px * 1)')).toBe('media-progress(width, 1px, 1px)')
2466+
expect(parse('<number>', 'MEDIA-PROGRESS(width, 0px + 1px, 1px * 1)')).toBe('media-progress(width, 1px, 1px)')
24632467
expect(parse('<number>', 'media-progress(aspect-ratio, -1, 1)')).toBe('media-progress(aspect-ratio, -1, 1)')
24642468
})
24652469
})
24662470
describe('<sibling-count()>, <sibling-index()>', () => {
24672471
test('valid', () => {
2468-
expect(parse('<integer>', 'sibling-index()')).toBe('sibling-index()')
2472+
expect(parse('<integer>', 'SIBLING-INDEX()')).toBe('sibling-index()')
24692473
expect(parse('<length>', 'calc(sibling-index() * 1px)')).toBe('calc(1px * sibling-index())')
24702474
})
24712475
})

lib/parse/preprocess.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,9 @@ function preParseCompoundSelector(node) {
189189
next
190190
&& !isColon(next)
191191
&& findContext('function', node, node =>
192-
pseudos.logical[node.input.current?.name]
192+
pseudos.logical[node.input.current?.name.toLowerCase()]
193193
// ::part(name):not(type) must be valid (but match nothing)
194-
&& node.input.prev(1, 1)?.name !== 'part'
194+
&& node.input.prev(1, 1)?.name?.toLowerCase() !== 'part'
195195
&& findParent(
196196
node,
197197
node => node.definition.name === '<pseudo-compound-selector>',
@@ -210,7 +210,7 @@ function preParseCompoundSelector(node) {
210210
*/
211211
function preParseImageSet(node) {
212212
if (
213-
node.input.next()?.name === 'image-set'
213+
node.input.next()?.name?.toLowerCase() === 'image-set'
214214
&& findContext('function', node, node => node.definition.name === 'image-set')
215215
) {
216216
return error(node)
@@ -229,12 +229,12 @@ function preParseImageSetOption(node) {
229229
const { context, input } = node
230230
const next = input.next()
231231
if (next) {
232-
const { name, types } = next
232+
const name = next.name?.toLowerCase()
233233
if (
234234
context.function.parent.parent?.definition.name === '<url-set>'
235235
&& name !== 'src'
236236
&& name !== 'url'
237-
&& types[0] !== '<string-token>'
237+
&& next.types[0] !== '<string-token>'
238238
) {
239239
return error(node)
240240
}
@@ -280,7 +280,7 @@ function preParseLength(node) {
280280
*/
281281
function preParseMix(node) {
282282
if (properties[node.context.declaration?.definition.name]?.animate === false) {
283-
return node.input.next()?.name === 'mix' ? error(node) : null
283+
return node.input.next()?.name?.toLowerCase() === 'mix' ? error(node) : null
284284
}
285285
}
286286

lib/parse/replace.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ function replaceForgivingSelector({ context: { forgiving, strict }, input }) {
4646
function replaceNumeric(node, parser) {
4747

4848
const { context, definition, input, parent } = node
49-
const { name } = input.next()
49+
const name = input.next().name?.toLowerCase()
5050
const topLevel = !context.replaced
5151

5252
const fn = name && substitutions.numeric.find(definition => definition.name === name)

0 commit comments

Comments
 (0)