Skip to content

Commit 62c87e1

Browse files
committed
Do not normalize all function names to lowercase
This is a prerequisite to add support for mixins, whose name is case-sensitive. The name of a function in its grammar definition is now processed as an actual grammar definition rather than just a string directly matched against the input function name.
1 parent e0efe23 commit 62c87e1

File tree

4 files changed

+31
-23
lines changed

4 files changed

+31
-23
lines changed

lib/parse/grammar.js

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -252,30 +252,28 @@ function matchSimpleBlock(block, node, parser) {
252252
* @returns {object|null}
253253
*/
254254
function matchFunction(fn, node, parser) {
255-
if (fn.types[0] === '<function>') {
256-
const { context, definition: { name, value }, input } = node
257-
const { functions: { aliases, mappings } } = compatibility
258-
if (name && aliases?.get(fn.name) === name) {
259-
fn = { ...fn, name }
255+
let { name, types, value } = fn
256+
if (types[0] !== '<function>') {
257+
return null
258+
}
259+
const { context, definition, input } = node
260+
const ctx = { ...context, function: node }
261+
if (definition.name) {
262+
name = parser.parseCSSValue(name, definition.name, ctx)
263+
if (name === null || name instanceof SyntaxError) {
264+
return name
260265
}
261-
if (!name || name === fn.name || mappings?.get(fn.name) === name) {
262-
if (value) {
263-
const match = parser.parseCSSValue(
264-
new Stream(fn.value, input.source),
265-
value,
266-
{ ...context, function: node })
267-
if (match instanceof SyntaxError) {
268-
return match
269-
}
270-
if (match) {
271-
return { ...fn, value: match }
272-
}
273-
} else {
274-
return fn
275-
}
266+
fn = { ...fn, name: name.value }
267+
}
268+
if (definition.value) {
269+
value = new Stream(value, input.source)
270+
value = parser.parseCSSValue(value, definition.value, ctx)
271+
if (value === null || value instanceof SyntaxError) {
272+
return value
276273
}
274+
fn = { ...fn, value }
277275
}
278-
return null
276+
return fn
279277
}
280278

281279
/**

lib/parse/postprocess.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,16 @@ function postParseKeyword(keyword, { context, definition: { range } }) {
787787
if (lowercase === range.toLowerCase()) {
788788
return { ...keyword, value: lowercase }
789789
}
790+
if (context.function?.definition.name === range) {
791+
const { values: { functions: { aliases, mappings } } } = compatibility
792+
if (aliases?.get(lowercase) === range) {
793+
return { ...keyword, value: range }
794+
}
795+
if (mappings?.has(lowercase) === range) {
796+
return { ...keyword, value: lowercase }
797+
}
798+
return null
799+
}
790800
const { aliases, mappings } = compatibility.values.keywords[context.declaration?.definition.name] ?? {}
791801
if (aliases?.get(lowercase) === range) {
792802
return { ...keyword, value: range }

lib/parse/tokenize.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ function consumeIdentifierLike(chars) {
284284
}
285285
return consumeUrl(chars, identifier)
286286
}
287-
return { end: chars.index + 1, start, types: ['<function-token>'], value: lowercase }
287+
return { end: chars.index + 1, start, types: ['<function-token>'], value }
288288
}
289289
return identifier
290290
}

lib/serialize.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ function serializeFilter({ name, value }) {
843843
* @returns {string}
844844
*/
845845
function serializeFunction({ name, value }) {
846-
return `${name}(${serializeCSSComponentValue(value, name)})`
846+
return `${serializeIdentifier({ value: name })}(${serializeCSSComponentValue(value, name)})`
847847
}
848848

849849
/**

0 commit comments

Comments
 (0)