From 09b4ad41a7e3aeccb14723e377f680a1a4c43164 Mon Sep 17 00:00:00 2001 From: Bart Veneman Date: Tue, 27 Oct 2026 14:13:15 +0100 Subject: [PATCH 1/3] chore(deps): upgrade css-parser to 0.19.0 --- package.json | 2 +- pnpm-lock.yaml | 22 ++++++++++---- src/index.ts | 67 ++++++++++++------------------------------ src/selectors/utils.ts | 2 +- 4 files changed, 37 insertions(+), 56 deletions(-) diff --git a/package.json b/package.json index 4de7fb9..c9603c0 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "knip": "knip" }, "dependencies": { - "@projectwallace/css-parser": "~0.18.9" + "@projectwallace/css-parser": "~0.19.0" }, "devDependencies": { "@projectwallace/preset-oxlint": "^0.0.11", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f3bc0d4..548ed99 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: '@projectwallace/css-parser': - specifier: ~0.18.9 - version: 0.18.9 + specifier: ~0.19.0 + version: 0.19.0 devDependencies: '@projectwallace/preset-oxlint': specifier: ^0.0.11 @@ -564,8 +564,8 @@ packages: cpu: [x64] os: [win32] - '@projectwallace/css-parser@0.18.9': - resolution: {integrity: sha512-euAUMV2madmhqCeTVNGbeewj8x0VhUIxVik/aGpyIrVBbKfzDV3IxEu/YDTYdUTkwrf+RZPyDkiYQhDuZMW/cg==} + '@projectwallace/css-parser@0.19.0': + resolution: {integrity: sha512-Sgb2uCRJbVfsEHbGaypNd8XnBcwtofc8vwDuxLrXXMQ1BeYT0X7Jr/DuFgbDX4cvQT9HusLXcNWT8JdjFzV/cw==} engines: {pnpm: '>=11.0.0'} '@projectwallace/preset-oxlint@0.0.11': @@ -846,67 +846,79 @@ packages: resolution: {integrity: sha512-wdL2XmTiZixAOaHk9Z0JJZ8u9Qm8d333Zjpc6gaxXFX+UR5BlsfxZ7a2+2Rm71pamppsPYGUGFq2oVLbh6DISw==} cpu: [arm64] os: [android] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-core/binding-darwin-arm64@0.19.0': resolution: {integrity: sha512-7sNJa6XJhyetnTy64jw3NEi4YgUcezHk1G5GH9FSvXAuC8wIlbaOwT9lgq5qo5sspjrZJQlBR1TWflP49uRpMw==} cpu: [arm64] os: [darwin] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-core/binding-darwin-x64@0.19.0': resolution: {integrity: sha512-pTC7dYEc59isdyizc3nsuyFNBu2LU5wMYZ1be6UMr59PY/AJNtO1aBLWV0MgL/z7C1nv/2sX4TNjGgKLoeevJw==} cpu: [x64] os: [darwin] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-core/binding-freebsd-x64@0.19.0': resolution: {integrity: sha512-xrZjF6XOEwyLOiDIfrwDdRCS6ghxcJeirNC1KivQhVcUwlRonaU79S3/Uiyx3lBylPnT8qKJ3/aMT+H52nGTJQ==} cpu: [x64] os: [freebsd] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-core/binding-linux-arm-gnu@0.19.0': resolution: {integrity: sha512-0OyIH53C0I1CbADHn9FSdCfX5qbpeLwJhmOVhonFJNYheybOnkSJ50qGMfTJIb8y5zrwqvLs7FVBvz6Fk8maZg==} cpu: [arm] os: [linux] libc: [glibc] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-core/binding-linux-arm-musl@0.19.0': resolution: {integrity: sha512-z/iPfkCOCSXE34VXNt0uP1ORSW+4mEa9b5CiJcWZeqZH08g49bFU/jRM2T04f+Wpw5mJ6HIzNBiojxeAbrHjeg==} cpu: [arm] os: [linux] libc: [musl] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-core/binding-linux-arm64-gnu@0.19.0': resolution: {integrity: sha512-jLNTi+gzaRwBJ+gwhCJ+rDb5dmx/8hEBx93UWd7hjMSqPTL1D1wvVSvXVAldV5kALvju7b0/m51EHEhs4+I1fA==} cpu: [arm64] os: [linux] libc: [glibc] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-core/binding-linux-arm64-musl@0.19.0': resolution: {integrity: sha512-YwyPIdW/rN2Fmv0MTFWi47FaB3F9g+2b+sJISyAw83Yd60RWH4T3Nx6XkAHHVN+uKJNBAd6So7/BVihSiFYvuQ==} cpu: [arm64] os: [linux] libc: [musl] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-core/binding-linux-x64-gnu@0.19.0': resolution: {integrity: sha512-/vskaAXVX3ESR43FiTdfiYS7z1b9uoQJwVQ/0RgUHgN2sWoAyCZs+aX4CgU7eKGIHTVfp9VFwv+c+2XchYiEtQ==} cpu: [x64] os: [linux] libc: [glibc] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-core/binding-linux-x64-musl@0.19.0': resolution: {integrity: sha512-FuXL5igeSKib9Rye02TdH+D6SQezTyGxIATMu1Qsn/QywrzwpGl35OLpS2C1x5vpGLeVE2XgiLd5mVPFHmIglQ==} cpu: [x64] os: [linux] libc: [musl] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-core/binding-win32-arm64@0.19.0': resolution: {integrity: sha512-YuJAe7zEKT1Xa7LuHlhGJpPnYQeVtvo0rZvNjJRqkH0hQGOw4C8QeP30Tg5VKGzZfo2x8CjhjEhKt4TmLwfmdg==} cpu: [arm64] os: [win32] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-core/binding-win32-x64@0.19.0': resolution: {integrity: sha512-o8iY/mXwlRkedp0LNTr4+TEfXTPQwoNZmv6k+1WIAd1ZXEn8xJJTBCtB0osaVvdZo/x/cNmV16UrWrrGpM5Mvw==} cpu: [x64] os: [win32] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-toolchain/types@0.19.0': resolution: {integrity: sha512-tFkNbsP4WXX9UMUC5syJGdK9dPMLK0PPaIuXCcCYH75sZ8MrebfBZ2XvCILRTw8AgLivSSCfDa4R67iYBDa4Kg==} @@ -1681,7 +1693,7 @@ snapshots: '@oxlint/binding-win32-x64-msvc@1.89.0': optional: true - '@projectwallace/css-parser@0.18.9': {} + '@projectwallace/css-parser@0.19.0': {} '@projectwallace/preset-oxlint@0.0.11(oxlint@1.89.0)': dependencies: diff --git a/src/index.ts b/src/index.ts index aea77b0..6a87c5d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,9 +14,7 @@ import { is_atrule, is_selector, is_declaration, - is_supports_query, is_supports_declaration, - is_layer_name, is_identifier, is_attribute_selector, is_type_selector, @@ -46,12 +44,7 @@ import { AggregateCollection } from './aggregate-collection.js' import { DefinedUsed } from './defined-used.js' import { endsWith, unquote } from './string-utils.js' import { getEmbedType } from './stylesheet/stylesheet.js' -import { - basename, - SPACING_RESET_PROPERTIES, - border_radius_properties, - shorthand_properties, -} from './properties/property-utils.js' +import { basename, SPACING_RESET_PROPERTIES, border_radius_properties, shorthand_properties } from './properties/property-utils.js' export type Specificity = [number, number, number] @@ -65,14 +58,8 @@ export type Options = { useLocations?: boolean } -export function analyze( - css: string, - options?: Options & { useLocations?: false | undefined }, -): ReturnType> -export function analyze( - css: string, - options: Options & { useLocations: true }, -): ReturnType> +export function analyze(css: string, options?: Options & { useLocations?: false | undefined }): ReturnType> +export function analyze(css: string, options: Options & { useLocations: true }): ReturnType> export function analyze(css: string, options: Options = {}): any { const useLocations = options.useLocations === true if (useLocations) { @@ -315,10 +302,14 @@ function analyzeInternal(css: string, options: Options, useLo if (is_atrule_prelude(node.prelude) && node.prelude.has_children) { for (let child of node.prelude) { - if (is_supports_query(child)) { + if (!is_function(child)) { + continue + } + + if (str_equals('supports', child.name) && child.value) { supports.p(child.value, toLoc(child)) - } else if (is_layer_name(child) && child.value) { - // can be empty string + } else if (str_equals('layer', child.name) && child.value) { + // layer() can be empty layers.p(child.value, toLoc(child)) layerNamesTracking.use(child.value) } @@ -340,9 +331,7 @@ function analyzeInternal(css: string, options: Options, useLo customPropsTracking.define(node.prelude.text) } else if (normalized_name === 'function') { let prelude = node.prelude.text - let name = prelude.includes('(') - ? prelude.slice(0, prelude.indexOf('(')).trim() - : prelude.trim() + let name = prelude.includes('(') ? prelude.slice(0, prelude.indexOf('(')).trim() : prelude.trim() functions.p(name, toLoc(node)) } else if (normalized_name === 'charset') { charsets.p(node.prelude.text.toLowerCase(), toLoc(node)) @@ -436,11 +425,7 @@ function analyzeInternal(css: string, options: Options, useLo walk(node, (child) => { if (is_attribute_selector(child)) { attributeSelectors.p(child.name.toLowerCase(), loc) - } else if ( - is_type_selector(child) && - !child.name.startsWith('--') && - child.name.includes('-') - ) { + } else if (is_type_selector(child) && !child.name.startsWith('--') && child.name.includes('-')) { customElementSelectors.p(child.name.toLowerCase(), loc) } else if (is_pseudo_class_selector(child)) { pseudoClasses.p(child.name.toLowerCase(), loc) @@ -679,10 +664,7 @@ function analyzeInternal(css: string, options: Options, useLo } }) return SKIP - } else if ( - normalizedProperty === 'animation-duration' || - normalizedProperty === 'transition-duration' - ) { + } else if (normalizedProperty === 'animation-duration' || normalizedProperty === 'transition-duration') { for (let child of value.children) { if (!is_operator(child)) { let text = child.text @@ -693,10 +675,7 @@ function analyzeInternal(css: string, options: Options, useLo } } } - } else if ( - normalizedProperty === 'transition-timing-function' || - normalizedProperty === 'animation-timing-function' - ) { + } else if (normalizedProperty === 'transition-timing-function' || normalizedProperty === 'animation-timing-function') { for (let child of value.children) { if (!is_operator(child)) { timingFunctions.p(child.text, valueLoc) @@ -736,11 +715,7 @@ function analyzeInternal(css: string, options: Options, useLo } } } else if (normalizedProperty === 'position-anchor') { - if ( - value.first_child && - is_identifier(value.first_child) && - is_custom(value.first_child.text) - ) { + if (value.first_child && is_identifier(value.first_child) && is_custom(value.first_child.text)) { anchorNamesTracking.use(value.first_child.text) } } else if (border_radius_properties.has(normalizedProperty)) { @@ -869,7 +844,7 @@ function analyzeInternal(css: string, options: Options, useLo } else if (is_url(node)) { let { value } = node let embed = unquote(value ?? '') - if (str_starts_with(embed, 'data:')) { + if (str_starts_with('data:', embed)) { let size = embed.length let type = getEmbedType(embed) @@ -925,16 +900,10 @@ function analyzeInternal(css: string, options: Options, useLo return { stylesheet: { - sourceLinesOfCode: - atruleCount.total + totalSelectors + totalDeclarations + keyframeSelectors.size(), + sourceLinesOfCode: atruleCount.total + totalSelectors + totalDeclarations + keyframeSelectors.size(), linesOfCode, size: cssLen, - complexity: - atRuleComplexity.sum + - selectorComplexity.sum + - declarationComplexity.sum + - propertyComplexity.sum + - valueComplexity.sum, + complexity: atRuleComplexity.sum + selectorComplexity.sum + declarationComplexity.sum + propertyComplexity.sum + valueComplexity.sum, comments: { total: totalComments, size: commentsSize, diff --git a/src/selectors/utils.ts b/src/selectors/utils.ts index 7f55458..8f1d204 100644 --- a/src/selectors/utils.ts +++ b/src/selectors/utils.ts @@ -76,7 +76,7 @@ export function isAccessibility( walk(selector, function (node) { if (is_attribute_selector(node)) { const name = node.name || '' - if (str_equals('role', name) || str_starts_with(name, 'aria-')) { + if (str_equals('role', name) || str_starts_with('aria-', name)) { on_selector(normalize(node)) } } From 4e1da1b6e077dd468d94b6720ae65238da58044e Mon Sep 17 00:00:00 2001 From: Bart Veneman Date: Tue, 27 Oct 2026 14:14:16 +0100 Subject: [PATCH 2/3] dedupe --- pnpm-lock.yaml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 548ed99..26430e1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -846,79 +846,67 @@ packages: resolution: {integrity: sha512-wdL2XmTiZixAOaHk9Z0JJZ8u9Qm8d333Zjpc6gaxXFX+UR5BlsfxZ7a2+2Rm71pamppsPYGUGFq2oVLbh6DISw==} cpu: [arm64] os: [android] - deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-core/binding-darwin-arm64@0.19.0': resolution: {integrity: sha512-7sNJa6XJhyetnTy64jw3NEi4YgUcezHk1G5GH9FSvXAuC8wIlbaOwT9lgq5qo5sspjrZJQlBR1TWflP49uRpMw==} cpu: [arm64] os: [darwin] - deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-core/binding-darwin-x64@0.19.0': resolution: {integrity: sha512-pTC7dYEc59isdyizc3nsuyFNBu2LU5wMYZ1be6UMr59PY/AJNtO1aBLWV0MgL/z7C1nv/2sX4TNjGgKLoeevJw==} cpu: [x64] os: [darwin] - deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-core/binding-freebsd-x64@0.19.0': resolution: {integrity: sha512-xrZjF6XOEwyLOiDIfrwDdRCS6ghxcJeirNC1KivQhVcUwlRonaU79S3/Uiyx3lBylPnT8qKJ3/aMT+H52nGTJQ==} cpu: [x64] os: [freebsd] - deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-core/binding-linux-arm-gnu@0.19.0': resolution: {integrity: sha512-0OyIH53C0I1CbADHn9FSdCfX5qbpeLwJhmOVhonFJNYheybOnkSJ50qGMfTJIb8y5zrwqvLs7FVBvz6Fk8maZg==} cpu: [arm] os: [linux] libc: [glibc] - deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-core/binding-linux-arm-musl@0.19.0': resolution: {integrity: sha512-z/iPfkCOCSXE34VXNt0uP1ORSW+4mEa9b5CiJcWZeqZH08g49bFU/jRM2T04f+Wpw5mJ6HIzNBiojxeAbrHjeg==} cpu: [arm] os: [linux] libc: [musl] - deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-core/binding-linux-arm64-gnu@0.19.0': resolution: {integrity: sha512-jLNTi+gzaRwBJ+gwhCJ+rDb5dmx/8hEBx93UWd7hjMSqPTL1D1wvVSvXVAldV5kALvju7b0/m51EHEhs4+I1fA==} cpu: [arm64] os: [linux] libc: [glibc] - deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-core/binding-linux-arm64-musl@0.19.0': resolution: {integrity: sha512-YwyPIdW/rN2Fmv0MTFWi47FaB3F9g+2b+sJISyAw83Yd60RWH4T3Nx6XkAHHVN+uKJNBAd6So7/BVihSiFYvuQ==} cpu: [arm64] os: [linux] libc: [musl] - deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-core/binding-linux-x64-gnu@0.19.0': resolution: {integrity: sha512-/vskaAXVX3ESR43FiTdfiYS7z1b9uoQJwVQ/0RgUHgN2sWoAyCZs+aX4CgU7eKGIHTVfp9VFwv+c+2XchYiEtQ==} cpu: [x64] os: [linux] libc: [glibc] - deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-core/binding-linux-x64-musl@0.19.0': resolution: {integrity: sha512-FuXL5igeSKib9Rye02TdH+D6SQezTyGxIATMu1Qsn/QywrzwpGl35OLpS2C1x5vpGLeVE2XgiLd5mVPFHmIglQ==} cpu: [x64] os: [linux] libc: [musl] - deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-core/binding-win32-arm64@0.19.0': resolution: {integrity: sha512-YuJAe7zEKT1Xa7LuHlhGJpPnYQeVtvo0rZvNjJRqkH0hQGOw4C8QeP30Tg5VKGzZfo2x8CjhjEhKt4TmLwfmdg==} cpu: [arm64] os: [win32] - deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-core/binding-win32-x64@0.19.0': resolution: {integrity: sha512-o8iY/mXwlRkedp0LNTr4+TEfXTPQwoNZmv6k+1WIAd1ZXEn8xJJTBCtB0osaVvdZo/x/cNmV16UrWrrGpM5Mvw==} cpu: [x64] os: [win32] - deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-toolchain/types@0.19.0': resolution: {integrity: sha512-tFkNbsP4WXX9UMUC5syJGdK9dPMLK0PPaIuXCcCYH75sZ8MrebfBZ2XvCILRTw8AgLivSSCfDa4R67iYBDa4Kg==} From 281c82c287c951888981c70e6d9e5112a2beb458 Mon Sep 17 00:00:00 2001 From: Bart Veneman Date: Tue, 27 Oct 2026 14:15:06 +0100 Subject: [PATCH 3/3] fmt --- src/index.ts | 53 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/src/index.ts b/src/index.ts index 6a87c5d..7689832 100644 --- a/src/index.ts +++ b/src/index.ts @@ -44,7 +44,12 @@ import { AggregateCollection } from './aggregate-collection.js' import { DefinedUsed } from './defined-used.js' import { endsWith, unquote } from './string-utils.js' import { getEmbedType } from './stylesheet/stylesheet.js' -import { basename, SPACING_RESET_PROPERTIES, border_radius_properties, shorthand_properties } from './properties/property-utils.js' +import { + basename, + SPACING_RESET_PROPERTIES, + border_radius_properties, + shorthand_properties, +} from './properties/property-utils.js' export type Specificity = [number, number, number] @@ -58,8 +63,14 @@ export type Options = { useLocations?: boolean } -export function analyze(css: string, options?: Options & { useLocations?: false | undefined }): ReturnType> -export function analyze(css: string, options: Options & { useLocations: true }): ReturnType> +export function analyze( + css: string, + options?: Options & { useLocations?: false | undefined }, +): ReturnType> +export function analyze( + css: string, + options: Options & { useLocations: true }, +): ReturnType> export function analyze(css: string, options: Options = {}): any { const useLocations = options.useLocations === true if (useLocations) { @@ -331,7 +342,9 @@ function analyzeInternal(css: string, options: Options, useLo customPropsTracking.define(node.prelude.text) } else if (normalized_name === 'function') { let prelude = node.prelude.text - let name = prelude.includes('(') ? prelude.slice(0, prelude.indexOf('(')).trim() : prelude.trim() + let name = prelude.includes('(') + ? prelude.slice(0, prelude.indexOf('(')).trim() + : prelude.trim() functions.p(name, toLoc(node)) } else if (normalized_name === 'charset') { charsets.p(node.prelude.text.toLowerCase(), toLoc(node)) @@ -425,7 +438,11 @@ function analyzeInternal(css: string, options: Options, useLo walk(node, (child) => { if (is_attribute_selector(child)) { attributeSelectors.p(child.name.toLowerCase(), loc) - } else if (is_type_selector(child) && !child.name.startsWith('--') && child.name.includes('-')) { + } else if ( + is_type_selector(child) && + !child.name.startsWith('--') && + child.name.includes('-') + ) { customElementSelectors.p(child.name.toLowerCase(), loc) } else if (is_pseudo_class_selector(child)) { pseudoClasses.p(child.name.toLowerCase(), loc) @@ -664,7 +681,10 @@ function analyzeInternal(css: string, options: Options, useLo } }) return SKIP - } else if (normalizedProperty === 'animation-duration' || normalizedProperty === 'transition-duration') { + } else if ( + normalizedProperty === 'animation-duration' || + normalizedProperty === 'transition-duration' + ) { for (let child of value.children) { if (!is_operator(child)) { let text = child.text @@ -675,7 +695,10 @@ function analyzeInternal(css: string, options: Options, useLo } } } - } else if (normalizedProperty === 'transition-timing-function' || normalizedProperty === 'animation-timing-function') { + } else if ( + normalizedProperty === 'transition-timing-function' || + normalizedProperty === 'animation-timing-function' + ) { for (let child of value.children) { if (!is_operator(child)) { timingFunctions.p(child.text, valueLoc) @@ -715,7 +738,11 @@ function analyzeInternal(css: string, options: Options, useLo } } } else if (normalizedProperty === 'position-anchor') { - if (value.first_child && is_identifier(value.first_child) && is_custom(value.first_child.text)) { + if ( + value.first_child && + is_identifier(value.first_child) && + is_custom(value.first_child.text) + ) { anchorNamesTracking.use(value.first_child.text) } } else if (border_radius_properties.has(normalizedProperty)) { @@ -900,10 +927,16 @@ function analyzeInternal(css: string, options: Options, useLo return { stylesheet: { - sourceLinesOfCode: atruleCount.total + totalSelectors + totalDeclarations + keyframeSelectors.size(), + sourceLinesOfCode: + atruleCount.total + totalSelectors + totalDeclarations + keyframeSelectors.size(), linesOfCode, size: cssLen, - complexity: atRuleComplexity.sum + selectorComplexity.sum + declarationComplexity.sum + propertyComplexity.sum + valueComplexity.sum, + complexity: + atRuleComplexity.sum + + selectorComplexity.sum + + declarationComplexity.sum + + propertyComplexity.sum + + valueComplexity.sum, comments: { total: totalComments, size: commentsSize,