From 6b5bc49b75a541c037684a61f69455aad146371c Mon Sep 17 00:00:00 2001 From: Bart Veneman Date: Thu, 15 Oct 2026 13:59:06 +0200 Subject: [PATCH] fix: make sure to check for case sensitivity in more places --- src/defined-used.test.ts | 12 ++++++++++++ src/index.ts | 21 ++++++++++----------- src/string-utils.ts | 2 -- src/values/browserhacks.ts | 6 +++--- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/defined-used.test.ts b/src/defined-used.test.ts index 51fa88d9..a53cc927 100644 --- a/src/defined-used.test.ts +++ b/src/defined-used.test.ts @@ -91,6 +91,12 @@ describe('Custom properties', () => { expect(result.used).toEqual(['--color']) }) + test('tracks VAR() references as used regardless of case', () => { + let css = `.foo { color: VAR(--color); }` + let result = analyze(css).properties.custom + expect(result.used).toEqual(['--color']) + }) + test('identifies unused custom properties', () => { let css = `:root { --color: red; --size: 16px; } .foo { color: var(--color); }` let result = analyze(css).properties.custom @@ -384,6 +390,12 @@ describe('Anchor names', () => { expect(result.used).toContain('--my-anchor') }) + test('tracks ANCHOR() and ANCHOR-SIZE() functions as used regardless of case', () => { + let css = `.positioned { position: absolute; top: ANCHOR(--my-anchor bottom); width: ANCHOR-SIZE(--my-anchor width); }` + let result = analyze(css).properties.anchorNames + expect(result.used).toContain('--my-anchor') + }) + test('identifies unused anchor names', () => { let css = ` .anchor { anchor-name: --tooltip; } diff --git a/src/index.ts b/src/index.ts index 800c5e9c..aea77b03 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,6 +3,7 @@ import { type CSSNode, is_custom, SKIP, + str_equals, str_starts_with, walk, parse, @@ -730,7 +731,7 @@ function analyzeInternal(css: string, options: Options, useLo } } else if (normalizedProperty === 'anchor-name') { for (let child of value.children) { - if (is_identifier(child) && str_starts_with(child.text, '--')) { + if (is_identifier(child) && is_custom(child.text)) { anchorNamesTracking.define(child.text) } } @@ -738,7 +739,7 @@ function analyzeInternal(css: string, options: Options, useLo if ( value.first_child && is_identifier(value.first_child) && - str_starts_with(value.first_child.text, '--') + is_custom(value.first_child.text) ) { anchorNamesTracking.use(value.first_child.text) } @@ -832,21 +833,19 @@ function analyzeInternal(css: string, options: Options, useLo let firstFuncChild = valueNode.first_child // Track var(--custom-property) usage - if ( - funcName === 'var' && - firstFuncChild && - is_identifier(firstFuncChild) && - str_starts_with(firstFuncChild.text, '--') - ) { - customPropsTracking.use(firstFuncChild.text) + if (str_equals('var', funcName) && firstFuncChild && is_identifier(firstFuncChild)) { + let name = firstFuncChild.text + if (is_custom(name)) { + customPropsTracking.use(name) + } } // Track anchor(--name) and anchor-size(--name) usage if ( - (funcName === 'anchor' || funcName === 'anchor-size') && + (str_equals('anchor', funcName) || str_equals('anchor-size', funcName)) && firstFuncChild && is_identifier(firstFuncChild) && - str_starts_with(firstFuncChild.text, '--') + is_custom(firstFuncChild.text) ) { anchorNamesTracking.use(firstFuncChild.text) } diff --git a/src/string-utils.ts b/src/string-utils.ts index ff94399a..a0e77360 100644 --- a/src/string-utils.ts +++ b/src/string-utils.ts @@ -1,5 +1,3 @@ -import { str_equals, str_starts_with } from '@projectwallace/css-parser' - export function unquote(str: string): string { return str.replaceAll(/(?:^['"])|(?:['"]$)/g, '') } diff --git a/src/values/browserhacks.ts b/src/values/browserhacks.ts index 56a4063b..1ce1c691 100644 --- a/src/values/browserhacks.ts +++ b/src/values/browserhacks.ts @@ -4,6 +4,7 @@ import { is_identifier, is_function, is_url, + str_equals, walk, } from '@projectwallace/css-parser' import { endsWith, unquote } from '../string-utils.js' @@ -48,10 +49,9 @@ export function isValueBrowserhack(node: Value, on_hack: (hack: string) => void) // alpha(), expression(), and behavior .htc hacks walk(node, function (child) { if (is_function(child)) { - const name = child.name.toLowerCase() - if (name === 'alpha') { + if (str_equals('alpha', child.name)) { on_hack('alpha()') - } else if (name === 'expression') { + } else if (str_equals('expression', child.name)) { on_hack('expression()') } }