From 82980fffd50539b03fbc0385e0be3785fa0b2b6f Mon Sep 17 00:00:00 2001 From: Bart Veneman Date: Sun, 8 Feb 2026 23:17:44 +0100 Subject: [PATCH 1/2] feat: analyze `display` values --- src/index.test.ts | 6 ++ src/index.ts | 15 +++- src/values/display.test.ts | 169 +++++++++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 src/values/display.test.ts diff --git a/src/index.test.ts b/src/index.test.ts index 3421124..438c2a6 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -611,6 +611,12 @@ test('handles empty input gracefully', () => { unique: {}, uniquenessRatio: 0, }, + displays: { + total: 0, + totalUnique: 0, + unique: {}, + uniquenessRatio: 0, + }, }, } diff --git a/src/index.ts b/src/index.ts index 1e6f454..bdac419 100644 --- a/src/index.ts +++ b/src/index.ts @@ -170,6 +170,7 @@ function analyzeInternal(css: string, options: Options, useLo let valueComplexities = new AggregateCollection() let vendorPrefixedValues = new Collection(useLocations) let valueBrowserhacks = new Collection(useLocations) + let displays = new Collection(useLocations) let zindex = new Collection(useLocations) let textShadows = new Collection(useLocations) let boxShadows = new Collection(useLocations) @@ -501,10 +502,15 @@ function analyzeInternal(css: string, options: Options, useLo let valueLoc = toLoc(value) let complexity = 1 - // auto, inherit, initial, etc. + // auto, inherit, initial, none, etc. if (keywords.has(text)) { valueKeywords.p(text.toLowerCase(), valueLoc) valueComplexities.push(complexity) + + if (normalizedProperty === 'display') { + displays.p(text.toLowerCase(), valueLoc) + } + return } @@ -532,6 +538,12 @@ function analyzeInternal(css: string, options: Options, useLo if (isValueReset(value)) { resets.p(normalizedProperty, valueLoc) } + } else if (normalizedProperty === 'display') { + if (/var\(/.test(text)) { + displays.p(text, valueLoc) + } else { + displays.p(text.toLowerCase(), valueLoc) + } } else if (normalizedProperty === 'z-index') { zindex.p(text, valueLoc) return SKIP @@ -994,6 +1006,7 @@ function analyzeInternal(css: string, options: Options, useLo complexity: valueComplexity, keywords: valueKeywords.c(), resets: resets.c(), + displays: displays.c(), }, __meta__: { parseTime: startAnalysis - startParse, diff --git a/src/values/display.test.ts b/src/values/display.test.ts new file mode 100644 index 0000000..4669652 --- /dev/null +++ b/src/values/display.test.ts @@ -0,0 +1,169 @@ +import { describe, test, expect } from 'vitest' +import { analyze } from '../index' + +test('counts', () => { + // Test data from https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/display#syntax + const fixture = ` + test { + /* short display */ + display: none; + display: contents; + display: block; + display: flow-root; + display: inline; + display: inline-block; + display: list-item; + display: flex; + display: inline-flex; + display: grid; + display: inline-grid; + display: table; + display: inline-table; + } + ` + const actual = analyze(fixture).values.displays + expect(actual.total).toBe(13) + expect(actual.totalUnique).toBe(actual.total) + expect(actual.uniquenessRatio).toBe(1) + expect(actual.unique).toEqual({ + none: 1, + contents: 1, + block: 1, + 'flow-root': 1, + inline: 1, + 'inline-block': 1, + 'list-item': 1, + flex: 1, + 'inline-flex': 1, + grid: 1, + 'inline-grid': 1, + table: 1, + 'inline-table': 1, + }) +}) + +test('handles two-value', () => { + // Test data from https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/display#syntax + const fixture = ` + test { + /* full display */ + display: block flow; + display: block flow-root; + display: inline flow; + display: inline flow-root; + display: block flow list-item; + display: inline flow list-item; + display: block flex; + display: inline flex; + display: block grid; + display: inline grid; + display: block table; + display: inline table; + } + ` + const actual = analyze(fixture).values.displays + expect(actual.total).toBe(12) + expect(actual.totalUnique).toBe(actual.total) + expect(actual.uniquenessRatio).toBe(1) + expect(actual.unique).toEqual({ + 'block flow': 1, + 'block flow-root': 1, + 'inline flow': 1, + 'inline flow-root': 1, + 'block flow list-item': 1, + 'inline flow list-item': 1, + 'block flex': 1, + 'inline flex': 1, + 'block grid': 1, + 'inline grid': 1, + 'block table': 1, + 'inline table': 1, + }) +}) + +test('normalizes casing', () => { + const fixture = ` + test { + DISPLAY: BLOCK; + display: Block; + } + ` + const actual = analyze(fixture).values.displays + expect(actual.unique).toEqual({ + block: 2, + }) +}) + +test('handles value prefixes', () => { + const fixture = ` + test { + display: -webkit-box; + display: -Webkit-box; + display: -ms-flexbox; + display: -MS-flexbox; + } + ` + const actual = analyze(fixture).values.displays + expect(actual.unique).toEqual({ + '-webkit-box': 2, + '-ms-flexbox': 2, + }) +}) + +test('handles property prefixes', () => { + const fixture = ` + test { + -webkit-display: block; + -O-display: inline; + } + ` + const actual = analyze(fixture).values.displays + expect(actual.unique).toEqual({ + block: 1, + inline: 1, + }) +}) + +test('handles property browserhacks', () => { + const fixture = ` + test { + *display: block; + _display: inline; + } + ` + const actual = analyze(fixture).values.displays + expect(actual.unique).toEqual({ + block: 1, + inline: 1, + }) +}) + +test('handles value browserhacks', () => { + const fixture = ` + test { + display: inline\\9; + display: Inline\\9; + display: block!ie; + display: block !test; + } + ` + const actual = analyze(fixture).values.displays + expect(actual.unique).toEqual({ + inline: 2, + block: 2, + }) +}) + +test('handles var()', () => { + const fixture = ` + test { + display: var(--myDisplay); + display: var(--inline-dir) flow-root; + } + ` + const actual = analyze(fixture).values.displays + expect(actual.unique).toEqual({ + 'var(--myDisplay)': 1, + 'var(--inline-dir) flow-root': 1, + }) +}) From 5ab29ddf98593a7c678086e2728d577b217cf813 Mon Sep 17 00:00:00 2001 From: Bart Veneman Date: Sun, 8 Feb 2026 23:19:07 +0100 Subject: [PATCH 2/2] case sensitive var() --- src/index.ts | 2 +- src/values/display.test.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index bdac419..ea856f3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -539,7 +539,7 @@ function analyzeInternal(css: string, options: Options, useLo resets.p(normalizedProperty, valueLoc) } } else if (normalizedProperty === 'display') { - if (/var\(/.test(text)) { + if (/var\(/i.test(text)) { displays.p(text, valueLoc) } else { displays.p(text.toLowerCase(), valueLoc) diff --git a/src/values/display.test.ts b/src/values/display.test.ts index 4669652..b1d425e 100644 --- a/src/values/display.test.ts +++ b/src/values/display.test.ts @@ -159,11 +159,13 @@ test('handles var()', () => { test { display: var(--myDisplay); display: var(--inline-dir) flow-root; + display: Var(--inline-dir) flow-root; } ` const actual = analyze(fixture).values.displays expect(actual.unique).toEqual({ 'var(--myDisplay)': 1, 'var(--inline-dir) flow-root': 1, + 'Var(--inline-dir) flow-root': 1, }) })