diff --git a/src/countable-collection.js b/src/countable-collection.js deleted file mode 100644 index 67864c5..0000000 --- a/src/countable-collection.js +++ /dev/null @@ -1,48 +0,0 @@ -class CountableCollection { - - /** @param {string[]?} initial */ - constructor(initial) { - /** @type {Map} */ - this._items = new Map() - this._total = 0 - - if (initial) { - for (let i = 0; i < initial.length; i++) { - this.push(initial[i]) - } - } - } - - /** @param {string} item */ - push(item) { - this._total++ - - if (this._items.has(item)) { - this._items.set(item, this._items.get(item) + 1) - return - } - - this._items.set(item, 1) - } - - size() { - return this._total - } - - count() { - let items = this._items - let size = items.size - let total = this._total - - return { - total: total, - totalUnique: size, - unique: Object.fromEntries(items), - uniquenessRatio: total === 0 ? 0 : size / total, - } - } -} - -export { - CountableCollection -} \ No newline at end of file diff --git a/src/countable-collection.test.js b/src/countable-collection.test.js deleted file mode 100644 index d9cc3cd..0000000 --- a/src/countable-collection.test.js +++ /dev/null @@ -1,67 +0,0 @@ -import { suite } from 'uvu'; -import * as assert from 'uvu/assert'; -import { CountableCollection } from './countable-collection.js' - -const CollectionSuite = suite('CountableCollection') - -CollectionSuite('counts correctly', () => { - const fixture = new CountableCollection() - fixture.push('a') - fixture.push('a') - fixture.push('b') - fixture.push('b') - fixture.push('c') - fixture.push('d') - const actual = fixture.count() - const expected = { - total: 6, - totalUnique: 4, - unique: { - a: 2, - b: 2, - c: 1, - d: 1, - }, - uniquenessRatio: 4 / 6, - } - - assert.equal(actual, expected) -}) - -CollectionSuite('handles empty collections correctly', () => { - const fixture = new CountableCollection() - const actual = fixture.count() - const expected = { - total: 0, - totalUnique: 0, - unique: {}, - uniquenessRatio: 0, - } - assert.equal(actual, expected) -}) - -CollectionSuite('accepts an initial collection', () => { - const fixture = new CountableCollection(['a', 'b']) - fixture.push('a') - fixture.push('a') - fixture.push('b') - fixture.push('b') - fixture.push('c') - fixture.push('d') - const actual = fixture.count() - const expected = { - total: 8, - totalUnique: 4, - unique: { - a: 3, - b: 3, - c: 1, - d: 1, - }, - uniquenessRatio: 4 / 8, - } - - assert.equal(actual, expected) -}) - -CollectionSuite.run() \ No newline at end of file diff --git a/src/index.js b/src/index.js index 4958e05..725b626 100644 --- a/src/index.js +++ b/src/index.js @@ -476,13 +476,13 @@ export function analyze(css, options = {}) { } else if (isProperty('line-height', property)) { lineHeights.p(stringifyNode(node), loc) } else if (isProperty('transition', property) || isProperty('animation', property)) { - let [times, fns] = analyzeAnimation(children, stringifyNode) - for (let i = 0; i < times.length; i++) { - durations.p(times[i], loc) - } - for (let i = 0; i < fns.length; i++) { - timingFunctions.p(fns[i], loc) - } + analyzeAnimation(children, function (item) { + if (item.type === 'fn') { + timingFunctions.p(stringifyNode(item.value), loc) + } else if (item.type === 'duration') { + durations.p(stringifyNode(item.value), loc) + } + }) break } else if (isProperty('animation-duration', property) || isProperty('transition-duration', property)) { if (children && children.size > 1) { diff --git a/src/selectors/utils.js b/src/selectors/utils.js index 78d0c24..1c1c5d3 100644 --- a/src/selectors/utils.js +++ b/src/selectors/utils.js @@ -1,3 +1,4 @@ +// @ts-expect-error CSS Tree types are incomplete import walk from 'css-tree/walker' import { startsWith, strEquals } from '../string-utils.js' import { hasVendorPrefix } from '../vendor-prefix.js' @@ -28,6 +29,7 @@ function analyzeList(selectorListAst, cb) { return childSelectors } +/** @param {string} name */ function isPseudoFunction(name) { return ( strEquals(name, 'not') @@ -102,7 +104,7 @@ export function isPrefixed(selector) { /** * Get the Complexity for the AST of a Selector Node * @param {import('css-tree').Selector} selector - AST Node for a Selector - * @return {[number, boolean]} - The numeric complexity of the Selector and whether it's prefixed or not + * @return {number} - The numeric complexity of the Selector and whether it's prefixed or not */ export function getComplexity(selector) { let complexity = 0 diff --git a/src/values/animations.js b/src/values/animations.js index d1e3b8e..5fb6c57 100644 --- a/src/values/animations.js +++ b/src/values/animations.js @@ -21,10 +21,8 @@ const TIMING_FUNCTION_VALUES = new KeywordSet([ 'steps' ]) -export function analyzeAnimation(children, stringifyNode) { +export function analyzeAnimation(children, cb) { let durationFound = false - let durations = [] - let timingFunctions = [] children.forEach(child => { let type = child.type @@ -36,15 +34,22 @@ export function analyzeAnimation(children, stringifyNode) { } if (type === Dimension && durationFound === false) { durationFound = true - return durations.push(stringifyNode(child)) + return cb({ + type: 'duration', + value: child, + }) } if (type === Identifier && TIMING_KEYWORDS.has(name)) { - return timingFunctions.push(stringifyNode(child)) + return cb({ + type: 'fn', + value: child, + }) } if (type === Func && TIMING_FUNCTION_VALUES.has(name)) { - return timingFunctions.push(stringifyNode(child)) + return cb({ + type: 'fn', + value: child, + }) } }) - - return [durations, timingFunctions] } diff --git a/src/values/vendor-prefix.js b/src/values/vendor-prefix.js index 6f9bcd3..0a127c4 100644 --- a/src/values/vendor-prefix.js +++ b/src/values/vendor-prefix.js @@ -11,10 +11,7 @@ export function isValuePrefixed(node) { return false } - let list = children.toArray() - - for (let index = 0; index < list.length; index++) { - let node = list[index] + for (let node of children) { let { type, name } = node; if (type === Identifier && hasVendorPrefix(name)) { @@ -22,11 +19,7 @@ export function isValuePrefixed(node) { } if (type === Func) { - if (hasVendorPrefix(name)) { - return true - } - - if (isValuePrefixed(node)) { + if (hasVendorPrefix(name) || isValuePrefixed(node)) { return true } }