@projectwallace/css-analyzer 5.0.1 → 5.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analyzer.cjs +1 -1
- package/dist/analyzer.cjs.map +1 -1
- package/dist/analyzer.modern.js +1 -1
- package/dist/analyzer.modern.js.map +1 -1
- package/dist/analyzer.module.js +1 -1
- package/dist/analyzer.module.js.map +1 -1
- package/dist/analyzer.umd.js +1 -1
- package/dist/analyzer.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/analyzer.umd.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyzer.umd.js","sources":["../src/selectors/specificity.js","../src/aggregate-collection.js","../src/rules/rules.js","../src/values/colors.js","../src/countable-collection.js","../src/values/font-families.js","../src/values/font-sizes.js","../src/declarations/declarations.js","../src/selectors/selectors.js","../src/properties/properties.js","../src/values/values.js","../src/values/animations.js","../src/vendor-prefix.js","../src/values/vendor-prefix.js","../src/atrules/atrules.js","../src/context-collection.js","../src/index.js"],"sourcesContent":["import * as csstree from 'css-tree'\n\n/**\n * @typedef {[number, number, number]} Specificity\n *\n * @typedef {import('css-tree').Selector} Selector\n */\n\n/**\n * Compare specificity A to Specificity B\n * @param {Specificity} a - Specificity A\n * @param {Specificity} b - Specificity B\n * @returns {number} sortIndex - 0 when a==b, 1 when a<b, -1 when a>b\n */\nfunction compareSpecificity(a, b) {\n if (a[0] === b[0]) {\n if (a[1] === b[1]) {\n return b[2] - a[2]\n }\n\n return b[1] - a[1]\n }\n\n return b[0] - a[0]\n}\n\n/**\n *\n * @param {import('css-tree').SelectorList} selectorListAst\n * @returns {Selector} topSpecificitySelector\n */\nfunction selectorListSpecificities(selectorListAst) {\n const childSelectors = []\n csstree.walk(selectorListAst, {\n visit: 'Selector',\n enter(node) {\n childSelectors.push(analyzeSpecificity(node))\n }\n })\n\n return childSelectors.sort((a, b) => compareSpecificity(a.specificity, b.specificity))\n}\n\n/**\n * Get the Specificity for the AST of a Selector Node\n * @param {import('css-tree').Node} ast - AST Node for a Selector\n * @return {Object}\n * @property {Specificity} specificity\n * @property {number} complexity\n */\nconst analyzeSpecificity = (ast) => {\n let A = 0\n let B = 0\n let C = 0\n let complexity = 0\n let isA11y = false\n\n csstree.walk(ast, {\n enter: function (selector) {\n switch (selector.type) {\n case 'IdSelector': {\n A++\n complexity++\n break\n }\n case 'ClassSelector': {\n B++\n complexity++\n break\n }\n case 'AttributeSelector': {\n B++\n complexity++\n\n if (Boolean(selector.value)) {\n complexity++\n }\n isA11y = selector.name.name === 'role' || selector.name.name.startsWith('aria-')\n break\n }\n case 'PseudoElementSelector':\n case 'TypeSelector': {\n if (selector.name !== '*') {\n C++\n }\n complexity++\n break\n }\n case 'PseudoClassSelector': {\n if (['before', 'after', 'first-letter', 'first-line'].includes(selector.name)) {\n C++\n complexity++\n return this.skip\n }\n // The specificity of an :is(), :not(), or :has() pseudo-class is\n // replaced by the specificity of the most specific complex\n // selector in its selector list argument.\n\n // CSSTree doesn't parse the arguments of :is, :has and :matches,\n // so we need to create an AST out of them ourselves\n if (['is', 'has', 'matches'].includes(selector.name)) {\n const rawSelectorList = csstree.find(selector, ({ type }) => type === 'Raw')\n const childAst = csstree.parse(rawSelectorList.value, { context: 'selectorList' })\n const selectorList = selectorListSpecificities(childAst)\n const [topA, topB, topC] = selectorList[0].specificity\n A += topA\n B += topB\n C += topC\n\n for (let i = 0; i < selectorList.length; i++) {\n complexity += selectorList[i].complexity\n }\n complexity++\n return\n }\n\n // CSSTree *does* parse the arguments of the :not() pseudo-class,\n // so we have direct access to the AST, instead of having to parse\n // the arguments ourselves.\n if (selector.name === 'not') {\n const selectorList = selectorListSpecificities(selector)\n const [topA, topB, topC] = selectorList[0].specificity\n A += topA\n B += topB\n C += topC\n\n for (let i = 0; i < selectorList.length; i++) {\n complexity += selectorList[i].complexity\n }\n complexity++\n return this.skip\n }\n\n // The specificity of an :nth-child() or :nth-last-child() selector\n // is the specificity of the pseudo class itself (counting as one\n // pseudo-class selector) plus the specificity of the most\n // specific complex selector in its selector list argument (if any).\n if (['nth-child', 'nth-last-child'].includes(selector.name)) {\n // +1 for the pseudo class itself\n B++\n\n const childSelectors = selectorListSpecificities(selector)\n\n if (childSelectors.length === 0) {\n return\n }\n\n const [topA, topB, topC] = childSelectors[0].specificity\n A += topA\n B += topB\n C += topC\n\n for (let i = 0; i < childSelectors.length; i++) {\n complexity += childSelectors[i].complexity;\n }\n\n complexity++\n return\n }\n\n // The specificity of a :where() pseudo-class is replaced by zero,\n // but it does count towards complexity.\n if (selector.name === 'where') {\n const rawSelectorList = csstree.find(selector, ({ type }) => type === 'Raw')\n const childAst = csstree.parse(rawSelectorList.value, { context: 'selectorList' })\n const childSelectors = selectorListSpecificities(childAst)\n\n for (let i = 0; i < childSelectors.length; i++) {\n complexity += childSelectors[i].complexity;\n }\n\n complexity++\n return\n }\n\n // Regular pseudo classes have specificity [0,1,0]\n complexity++\n B++\n break\n }\n case 'Combinator': {\n complexity++\n break\n }\n }\n }\n })\n\n return {\n /** @type Specificity */\n specificity: [A, B, C],\n complexity,\n isId: A > 0,\n isA11y\n }\n}\n\nexport {\n analyzeSpecificity,\n compareSpecificity,\n}","/**\n * Find the mode (most occurring value) in an array of Numbers\n * Takes the mean/average of multiple values if multiple values occur the same amount of times.\n *\n * @see https://github.com/angus-c/just/blob/684af9ca0c7808bc78543ec89379b1fdfce502b1/packages/array-mode/index.js\n * @param {Array} arr - Array to find the mode value for\n * @returns {Number} mode - The `mode` value of `arr`\n */\nfunction Mode(arr) {\n const frequencies = Object.create(null)\n let maxOccurrences = -1\n let maxOccurenceCount = 0\n let sum = 0\n\n for (let i = 0; i < arr.length; i++) {\n const element = arr[i]\n const updatedCount = (frequencies[element] || 0) + 1\n frequencies[element] = updatedCount\n\n if (updatedCount > maxOccurrences) {\n maxOccurrences = updatedCount\n maxOccurenceCount = 0\n sum = 0\n }\n\n if (updatedCount >= maxOccurrences) {\n maxOccurenceCount++\n sum += element\n }\n }\n\n return sum / maxOccurenceCount\n}\n\n/**\n * Find the middle number in an Array of Numbers\n * Returns the average of 2 numbers if the Array length is an even number\n * @see https://github.com/angus-c/just/blob/684af9ca0c7808bc78543ec89379b1fdfce502b1/packages/array-median/index.js\n * @param {Array} arr - A sorted Array\n * @returns {Number} - The array's Median\n */\nfunction Median(arr) {\n const middle = arr.length / 2\n const lowerMiddleRank = Math.floor(middle)\n\n if (middle !== lowerMiddleRank) {\n return arr[lowerMiddleRank]\n }\n return (arr[lowerMiddleRank] + arr[lowerMiddleRank - 1]) / 2\n}\n\nclass AggregateCollection {\n constructor(size) {\n /** @type Number[] */\n this.items = new Uint8Array(size)\n this.sum = 0\n this.cursor = 0\n }\n\n /**\n * Add a new Integer to the AggregateCollection\n * @param {number} item - The item to add to the AggregateCollection\n */\n add(item) {\n this.items[this.cursor] = (item)\n this.sum += item\n this.cursor++\n }\n\n aggregate() {\n if (this.cursor === 0) {\n return {\n min: 0,\n max: 0,\n mean: 0,\n mode: 0,\n median: 0,\n range: 0,\n sum: 0,\n }\n }\n\n /** @type Number[] */\n const sorted = new Uint8Array(\n this.items.slice(0, this.cursor)\n ).sort((a, b) => a - b)\n const min = sorted[0]\n const max = sorted[sorted.length - 1]\n\n const mode = Mode(sorted)\n const median = Median(sorted)\n\n return {\n min,\n max,\n mean: this.sum / this.cursor,\n mode,\n median,\n range: max - min,\n sum: this.sum,\n }\n }\n\n toArray() {\n return Array.from(\n this.items.subarray(0, this.cursor)\n )\n }\n}\n\nexport {\n AggregateCollection\n}","import * as csstree from 'css-tree'\nimport { AggregateCollection } from '../aggregate-collection.js'\n\nconst analyzeRules = ({ rules }) => {\n const totalRules = rules.length\n const selectorsPerRule = new AggregateCollection(totalRules)\n const declarationsPerRule = new AggregateCollection(totalRules)\n\n let emptyRules = 0\n\n for (let i = 0; i < totalRules; i++) {\n let selectors = 0\n let declarations = 0\n\n csstree.walk(rules[i], {\n enter: function (childNode) {\n if (childNode.type === 'Selector') {\n selectors++\n return this.skip\n }\n\n if (childNode.type === 'Declaration') {\n declarations++\n return this.skip\n }\n }\n })\n\n if (declarations === 0) {\n emptyRules++\n }\n\n // For later aggregations\n selectorsPerRule.add(selectors)\n declarationsPerRule.add(declarations)\n }\n\n return {\n total: totalRules,\n empty: {\n total: emptyRules,\n ratio: emptyRules / totalRules\n },\n selectors: {\n ...selectorsPerRule.aggregate(),\n items: selectorsPerRule.toArray(),\n },\n declarations: {\n ...declarationsPerRule.aggregate(),\n items: declarationsPerRule.toArray()\n },\n }\n}\n\nexport {\n analyzeRules\n}","export const colorNames = {\n // CSS Named Colors\n // Spec: https://drafts.csswg.org/css-color/#named-colors\n aliceblue: 1,\n antiquewhite: 1,\n aqua: 1,\n aquamarine: 1,\n azure: 1,\n beige: 1,\n bisque: 1,\n black: 1,\n blanchedalmond: 1,\n blue: 1,\n blueviolet: 1,\n brown: 1,\n burlywood: 1,\n cadetblue: 1,\n chartreuse: 1,\n chocolate: 1,\n coral: 1,\n cornflowerblue: 1,\n cornsilk: 1,\n crimson: 1,\n cyan: 1,\n darkblue: 1,\n darkcyan: 1,\n darkgoldenrod: 1,\n darkgray: 1,\n darkgreen: 1,\n darkgrey: 1,\n darkkhaki: 1,\n darkmagenta: 1,\n darkolivegreen: 1,\n darkorange: 1,\n darkorchid: 1,\n darkred: 1,\n darksalmon: 1,\n darkseagreen: 1,\n darkslateblue: 1,\n darkslategray: 1,\n darkslategrey: 1,\n darkturquoise: 1,\n darkviolet: 1,\n deeppink: 1,\n deepskyblue: 1,\n dimgray: 1,\n dimgrey: 1,\n dodgerblue: 1,\n firebrick: 1,\n floralwhite: 1,\n forestgreen: 1,\n fuchsia: 1,\n gainsboro: 1,\n ghostwhite: 1,\n gold: 1,\n goldenrod: 1,\n gray: 1,\n green: 1,\n greenyellow: 1,\n grey: 1,\n honeydew: 1,\n hotpink: 1,\n indianred: 1,\n indigo: 1,\n ivory: 1,\n khaki: 1,\n lavender: 1,\n lavenderblush: 1,\n lawngreen: 1,\n lemonchiffon: 1,\n lightblue: 1,\n lightcoral: 1,\n lightcyan: 1,\n lightgoldenrodyellow: 1,\n lightgray: 1,\n lightgreen: 1,\n lightgrey: 1,\n lightpink: 1,\n lightsalmon: 1,\n lightseagreen: 1,\n lightskyblue: 1,\n lightslategray: 1,\n lightslategrey: 1,\n lightsteelblue: 1,\n lightyellow: 1,\n lime: 1,\n limegreen: 1,\n linen: 1,\n magenta: 1,\n maroon: 1,\n mediumaquamarine: 1,\n mediumblue: 1,\n mediumorchid: 1,\n mediumpurple: 1,\n mediumseagreen: 1,\n mediumslateblue: 1,\n mediumspringgreen: 1,\n mediumturquoise: 1,\n mediumvioletred: 1,\n midnightblue: 1,\n mintcream: 1,\n mistyrose: 1,\n moccasin: 1,\n navajowhite: 1,\n navy: 1,\n oldlace: 1,\n olive: 1,\n olivedrab: 1,\n orange: 1,\n orangered: 1,\n orchid: 1,\n palegoldenrod: 1,\n palegreen: 1,\n paleturquoise: 1,\n palevioletred: 1,\n papayawhip: 1,\n peachpuff: 1,\n peru: 1,\n pink: 1,\n plum: 1,\n powderblue: 1,\n purple: 1,\n rebeccapurple: 1,\n red: 1,\n rosybrown: 1,\n royalblue: 1,\n saddlebrown: 1,\n salmon: 1,\n sandybrown: 1,\n seagreen: 1,\n seashell: 1,\n sienna: 1,\n silver: 1,\n skyblue: 1,\n slateblue: 1,\n slategray: 1,\n slategrey: 1,\n snow: 1,\n springgreen: 1,\n steelblue: 1,\n tan: 1,\n teal: 1,\n thistle: 1,\n tomato: 1,\n turquoise: 1,\n violet: 1,\n wheat: 1,\n white: 1,\n whitesmoke: 1,\n yellow: 1,\n yellowgreen: 1,\n\n // CSS System Colors\n // Spec: https://drafts.csswg.org/css-color/#css-system-colors\n canvas: 1,\n canvastext: 1,\n linktext: 1,\n visitedtext: 1,\n activetext: 1,\n buttonface: 1,\n buttontext: 1,\n buttonborder: 1,\n field: 1,\n fieldtext: 1,\n highlight: 1,\n highlighttext: 1,\n selecteditem: 1,\n selecteditemtext: 1,\n mark: 1,\n marktext: 1,\n graytext: 1,\n\n // TODO: Deprecated CSS System colors\n // Spec: https://drafts.csswg.org/css-color/#deprecated-system-colors\n}\n\nexport const colorFunctions = {\n rgb: 1,\n rgba: 1,\n hsl: 1,\n hsla: 1,\n hwb: 1,\n lab: 1,\n lch: 1,\n oklab: 1,\n oklch: 1,\n color: 1,\n}\n\nexport const analyzeColors = ({ colors }) => {\n return colors.count()\n}\n","class CountableCollection {\n constructor(initial) {\n this.items = {}\n this.total = 0\n this.totalUnique = 0\n\n if (initial) {\n for (let index = 0; index < initial.length; index++) {\n this.push(initial[index])\n }\n }\n }\n\n /**\n *\n * @param {string} item\n */\n push(item) {\n this.total++\n\n if (this.items[item]) {\n this.items[item]++\n return\n }\n\n this.items[item] = 1\n this.totalUnique++\n }\n\n size() {\n return this.total\n }\n\n count() {\n return {\n total: this.total,\n totalUnique: this.totalUnique,\n unique: this.items,\n uniquenessRatio: this.total === 0 ? 0 : this.totalUnique / this.total,\n }\n }\n}\n\nexport {\n CountableCollection\n}","import * as csstree from 'css-tree'\nimport { CountableCollection } from '../countable-collection.js'\n\nconst systemKeywords = {\n // Global CSS keywords\n 'inherit': 1,\n 'initial': 1,\n 'unset': 1,\n 'revert': 1,\n\n // System font keywords\n 'caption': 1,\n 'icon': 1,\n 'menu': 1,\n 'message-box': 1,\n 'small-caption': 1,\n 'status-bar': 1,\n}\n\nconst keywordDisallowList = {\n // font-weight, font-stretch, font-style\n 'normal': 1,\n\n // font-size keywords\n 'xx-small': 1,\n 'x-small': 1,\n 'small': 1,\n 'medium': 1,\n 'large': 1,\n 'x-large': 1,\n 'xx-large': 1,\n 'larger': 1,\n 'smaller': 1,\n\n // font-weight keywords\n 'bold': 1,\n 'bolder': 1,\n 'lighter': 1,\n\n // font-stretch keywords\n 'ultra-condensed': 1,\n 'extra-condensed': 1,\n 'condensed': 1,\n 'semi-condensed': 1,\n 'semi-expanded': 1,\n 'expanded': 1,\n 'extra-expanded': 1,\n 'ultra-expanded': 1,\n\n // font-style keywords\n 'italic': 1,\n 'oblique': 1,\n}\n\nconst COMMA = 44 // ','.charCodeAt(0) === 44\n\nconst analyzeFontFamilies = ({ fontValues, fontFamilyValues }) => {\n const all = new CountableCollection(fontFamilyValues)\n\n for (let index = 0; index < fontValues.length; index++) {\n const value = fontValues[index]\n\n // Avoid tree traversal as soon as possible\n const firstChild = value.children.first\n\n if (firstChild.type === 'Identifier' && systemKeywords[firstChild.name]) {\n continue\n }\n\n const parts = []\n\n csstree.walk(value, {\n reverse: true,\n enter: function (fontNode) {\n if (fontNode.type === 'String') {\n return parts.unshift(fontNode)\n }\n if (fontNode.type === 'Operator' && fontNode.value.charCodeAt(0) === COMMA) {\n return parts.unshift(fontNode)\n }\n if (fontNode.type === 'Identifier') {\n if (keywordDisallowList[fontNode.name]) {\n return this.skip\n }\n return parts.unshift(fontNode)\n }\n }\n })\n\n all.push(parts.map(csstree.generate).join(''))\n }\n\n return all.count()\n}\n\nexport {\n analyzeFontFamilies\n}","import * as csstree from 'css-tree'\nimport { CountableCollection } from '../countable-collection.js'\n\nconst sizeKeywords = {\n 'xx-small': 1,\n 'x-small': 1,\n 'small': 1,\n 'medium': 1,\n 'large': 1,\n 'x-large': 1,\n 'xx-large': 1,\n 'larger': 1,\n 'smaller': 1,\n}\n\nconst keywords = {\n // Global CSS keywords\n 'inherit': 1,\n 'initial': 1,\n 'unset': 1,\n 'revert': 1,\n\n // System font keywords\n 'caption': 1,\n 'icon': 1,\n 'menu': 1,\n 'message-box': 1,\n 'small-caption': 1,\n 'status-bar': 1,\n}\n\nconst ZERO = 48 // '0'.charCodeAt(0) === 48\nconst SLASH = 47 // '/'.charCodeAt(0) === 47\n\nconst analyzeFontSizes = ({ stringifyNode, fontSizeValues, fontValues }) => {\n const all = new CountableCollection(fontSizeValues)\n\n for (let index = 0; index < fontValues.length; index++) {\n const fontNode = fontValues[index];\n // Try to eliminate a keyword before we continue\n const firstChild = fontNode.children.first\n\n if (firstChild.type === 'Identifier' && keywords[firstChild.name]) {\n continue\n }\n\n let operator = false\n let size\n\n csstree.walk(fontNode, {\n enter: function (fontNode) {\n switch (fontNode.type) {\n case 'Number': {\n // Special case for `font: 0/0 a`\n if (fontNode.value.charCodeAt(0) === ZERO) {\n size = '0'\n return this.break\n }\n }\n case 'Operator': {\n if (fontNode.value.charCodeAt(0) === SLASH) {\n operator = true\n }\n break\n }\n case 'Dimension': {\n if (!operator) {\n size = stringifyNode(fontNode)\n return this.break\n }\n }\n case 'Identifier': {\n if (sizeKeywords[fontNode.name]) {\n size = fontNode.name\n return this.break\n }\n }\n }\n }\n })\n\n if (size) {\n all.push(size)\n }\n }\n\n return all.count()\n}\n\nexport {\n analyzeFontSizes\n}","const analyzeDeclarations = ({ stringifyNode, declarations }) => {\n const total = declarations.length\n const cache = Object.create(null)\n let importants = 0\n let totalUnique = 0\n let totalInKeyframes = 0\n\n for (let i = 0; i < total; i++) {\n const declaration = declarations[i]\n\n if (declaration.important === true) {\n importants++\n\n if (declaration.inKeyframe) {\n totalInKeyframes++\n }\n }\n\n const stringified = stringifyNode(declaration)\n\n if (!cache[stringified]) {\n cache[stringified] = 1\n totalUnique++\n }\n }\n\n return {\n total,\n unique: {\n total: totalUnique,\n ratio: total === 0 ? 0 : totalUnique / total,\n },\n importants: {\n total: importants,\n ratio: total === 0 ? 0 : importants / total,\n inKeyframes: {\n total: totalInKeyframes,\n ratio: importants === 0 ? 0 : totalInKeyframes / importants,\n },\n },\n }\n}\n\nexport {\n analyzeDeclarations\n}","import { analyzeSpecificity, compareSpecificity } from './specificity.js'\nimport { AggregateCollection } from '../aggregate-collection.js'\nimport { CountableCollection } from '../countable-collection.js'\n\n/** @typedef {[number, number, number]} Specificity */\n\nconst analyzeSelectors = ({ stringifyNode, selectors }) => {\n const counts = Object.create(null)\n const cache = Object.create(null)\n const totalSelectors = selectors.length\n\n /** @type Specificity|undefined */\n let maxSpecificity\n /** @type Specificity|undefined */\n let minSpecificity\n let specificityA = new AggregateCollection(totalSelectors)\n let specificityB = new AggregateCollection(totalSelectors)\n let specificityC = new AggregateCollection(totalSelectors)\n let totalUnique = 0\n const complexityAggregator = new AggregateCollection(totalSelectors);\n\n const specificities = []\n const complexities = []\n const ids = new CountableCollection()\n const a11y = new CountableCollection()\n const keyframes = new CountableCollection()\n\n for (let i = 0; i < totalSelectors; i++) {\n const node = selectors[i];\n const value = stringifyNode(node)\n\n if (node.isKeyframeSelector) {\n keyframes.push(value)\n // Do not attempt to further analyze <keyframe-selectors>\n continue\n }\n\n const { specificity, complexity, isId, isA11y } = cache[value] || analyzeSpecificity(node)\n\n if (isId) {\n ids.push(value)\n }\n\n if (isA11y) {\n a11y.push(value)\n }\n\n if (!cache[value]) {\n cache[value] = { complexity, specificity, isId, isA11y }\n totalUnique++\n counts[value] = 1\n } else {\n counts[value]++\n }\n\n complexityAggregator.add(complexity)\n\n if (maxSpecificity === undefined) {\n maxSpecificity = specificity\n }\n\n if (minSpecificity === undefined) {\n minSpecificity = specificity\n }\n\n specificityA.add(specificity[0])\n specificityB.add(specificity[1])\n specificityC.add(specificity[2])\n\n if (minSpecificity !== undefined && compareSpecificity(minSpecificity, specificity) < 0) {\n minSpecificity = specificity\n }\n\n if (maxSpecificity !== undefined && compareSpecificity(maxSpecificity, specificity) > 0) {\n maxSpecificity = specificity\n }\n\n specificities.push(specificity)\n complexities.push(complexity)\n }\n\n const aggregatesA = specificityA.aggregate()\n const aggregatesB = specificityB.aggregate()\n const aggregatesC = specificityC.aggregate()\n const complexityCount = new CountableCollection(complexities).count()\n\n return {\n total: totalSelectors,\n totalUnique,\n uniquenessRatio: totalUnique / totalSelectors,\n specificity: {\n sum: [aggregatesA.sum, aggregatesB.sum, aggregatesC.sum],\n min: minSpecificity,\n max: maxSpecificity,\n mean: [aggregatesA.mean, aggregatesB.mean, aggregatesC.mean],\n mode: [aggregatesA.mode, aggregatesB.mode, aggregatesC.mode],\n median: [aggregatesA.median, aggregatesB.median, aggregatesC.median],\n items: specificities\n },\n complexity: {\n ...complexityAggregator.aggregate(),\n ...complexityCount,\n items: complexities,\n },\n id: {\n ...ids.count(),\n ratio: ids.size() / totalSelectors,\n },\n accessibility: {\n ...a11y.count(),\n ratio: a11y.size() / totalSelectors,\n },\n keyframes: {\n ...keyframes.count(),\n ratio: keyframes.size() / totalSelectors,\n }\n }\n}\n\nexport {\n analyzeSelectors\n}","import { CountableCollection } from '../countable-collection.js'\n\nconst analyzeProperties = ({ properties }) => {\n const all = new CountableCollection(properties.map(p => p.authored))\n const prefixed = new CountableCollection()\n const hacks = new CountableCollection()\n const customs = new CountableCollection()\n const totalProperties = properties.length\n\n for (let i = 0; i < totalProperties; i++) {\n const property = properties[i]\n\n if (property.vendor) {\n prefixed.push(property.authored)\n continue\n }\n\n if (property.hack) {\n hacks.push(property.authored)\n continue\n }\n\n if (property.custom) {\n customs.push(property.authored)\n continue\n }\n }\n\n return {\n ...all.count(),\n prefixed: {\n ...prefixed.count(),\n ratio: prefixed.size() / totalProperties,\n },\n custom: {\n ...customs.count(),\n ratio: customs.size() / totalProperties,\n },\n browserhacks: {\n ...hacks.count(),\n ratio: hacks.size() / totalProperties,\n }\n }\n}\n\nexport {\n analyzeProperties\n}","import { CountableCollection } from '../countable-collection.js'\n\nconst keywords = {\n 'auto': 1,\n 'inherit': 1,\n 'initial': 1,\n 'unset': 1,\n 'revert': 1,\n 'none': 1, // for `text-shadow`\n}\n\nconst analyzeValues = ({ values, stringifyNode }) => {\n const all = new CountableCollection()\n\n for (let i = 0; i < values.length; i++) {\n const node = values[i]\n const firstChild = node.children.first\n\n if (!firstChild) continue\n if (firstChild.type === 'Identifier' && keywords[firstChild.name]) continue\n\n all.push(stringifyNode(node))\n }\n\n return all.count()\n}\n\nexport {\n analyzeValues\n}","import { CountableCollection } from '../countable-collection.js'\n\nconst timingKeywords = {\n 'linear': 1,\n 'ease': 1,\n 'ease-in': 1,\n 'ease-out': 1,\n 'ease-in-out': 1,\n 'step-start': 1,\n 'step-end': 1,\n}\n\nconst analyzeAnimations = ({ animations, durations, timingFunctions, stringifyNode }) => {\n const allDurations = new CountableCollection(durations.map(stringifyNode))\n const allTimingFunctions = new CountableCollection(timingFunctions.map(stringifyNode))\n\n for (let index = 0; index < animations.length; index++) {\n const node = animations[index]\n // Flag to know if we've grabbed the first Duration\n // yet (the first Dimension in a shorthand)\n let durationFound = false\n\n node.value.children.forEach(child => {\n // Right after a ',' we start over again\n if (child.type === 'Operator') {\n return durationFound = false\n }\n if (child.type === 'Dimension' && durationFound === false) {\n durationFound = true\n return allDurations.push(stringifyNode(child))\n }\n if (child.type === 'Identifier' && timingKeywords[child.name]) {\n return allTimingFunctions.push(stringifyNode(child))\n }\n if (child.type === 'Function'\n && (\n child.name === 'cubic-bezier' || child.name === 'steps'\n )\n ) {\n return allTimingFunctions.push(stringifyNode(child))\n }\n })\n }\n\n return {\n durations: allDurations.count(),\n timingFunctions: allTimingFunctions.count(),\n }\n}\n\nexport {\n analyzeAnimations\n}","const HYPHENMINUS = 45; // '-'.charCodeAt()\n\nfunction hasVendorPrefix(keyword) {\n if (keyword.charCodeAt(0) === HYPHENMINUS && keyword.charCodeAt(1) !== HYPHENMINUS) {\n // String must have a 2nd occurrence of '-', at least at position 3 (offset=2)\n if (keyword.indexOf('-', 2) !== -1) {\n return true\n }\n }\n\n return false\n}\n\nexport {\n hasVendorPrefix\n}","import { CountableCollection } from '../countable-collection.js'\nimport { hasVendorPrefix } from '../vendor-prefix.js'\n\nfunction isAstVendorPrefixed(children) {\n children = children.toArray()\n\n for (let index = 0; index < children.length; index++) {\n const child = children[index];\n\n if (child.type === 'Identifier' && child.name.length >= 3) {\n if (hasVendorPrefix(child.name)) {\n return true\n }\n }\n\n if (child.type === 'Function') {\n if (hasVendorPrefix(child.name)) {\n return true\n }\n\n if (child.children && isAstVendorPrefixed(child.children)) {\n return true\n }\n }\n }\n return false\n}\n\nconst analyzeVendorPrefixes = ({ values, stringifyNode }) => {\n const all = new CountableCollection()\n\n for (let i = 0; i < values.length; i++) {\n const value = values[i]\n\n if (value.children && isAstVendorPrefixed(value.children)) {\n all.push(stringifyNode(value))\n }\n }\n\n return all.count()\n}\n\nexport {\n analyzeVendorPrefixes\n}","import { CountableCollection } from '../countable-collection.js'\nimport { hasVendorPrefix } from '../vendor-prefix.js'\n\nconst analyzeAtRules = ({ atrules, stringifyNode }) => {\n const fontfaces = []\n const imports = new CountableCollection()\n const medias = new CountableCollection()\n const charsets = new CountableCollection()\n const supports = new CountableCollection()\n const keyframes = new CountableCollection()\n const prefixedKeyframes = new CountableCollection()\n const containers = new CountableCollection()\n\n const machine = {\n 'font-face': (node) => {\n const descriptors = {}\n\n node.block.children.forEach(descriptor => {\n descriptors[descriptor.property] = stringifyNode(descriptor.value)\n })\n\n fontfaces.push(descriptors)\n },\n 'media': node => medias.push(node.prelude.value),\n 'supports': node => supports.push(node.prelude.value),\n 'keyframes': node => keyframes.push(`@${node.name} ${node.prelude.value}`),\n 'import': node => imports.push(node.prelude.value),\n 'charset': node => charsets.push(node.prelude.value),\n 'container': node => containers.push(node.prelude.value),\n }\n\n for (let i = 0; i < atrules.length; i++) {\n const node = atrules[i]\n const nodeName = node.name\n const action = machine[nodeName]\n if (action) {\n action(node)\n continue\n }\n\n if (nodeName.endsWith('keyframes')) {\n const name = `@${nodeName} ${node.prelude.value}`\n keyframes.push(name)\n\n if (hasVendorPrefix(nodeName)) {\n prefixedKeyframes.push(name)\n }\n continue\n }\n }\n\n return {\n fontface: {\n total: fontfaces.length,\n totalUnique: fontfaces.length,\n unique: fontfaces,\n uniquenessRatio: 1\n },\n import: imports.count(),\n media: medias.count(),\n charset: charsets.count(),\n supports: supports.count(),\n keyframes: {\n ...keyframes.count(),\n prefixed: {\n ...prefixedKeyframes.count(),\n ratio: prefixedKeyframes.size() / keyframes.size()\n }\n },\n container: containers.count(),\n }\n}\n\nexport {\n analyzeAtRules\n}","import { CountableCollection } from './countable-collection.js'\n\nclass ContextCollection {\n constructor() {\n this.list = new CountableCollection()\n this.contexts = {}\n this.contextCount = 0\n }\n\n push(item, context) {\n this.list.push(item)\n\n if (!this.contexts[context]) {\n this.contexts[context] = new CountableCollection()\n this.contextCount++\n }\n\n this.contexts[context].push(item)\n }\n\n count() {\n const itemsPerContext = {}\n\n for (let context in this.contexts) {\n itemsPerContext[context] = this.contexts[context].count()\n }\n\n return Object.assign(this.list.count(), {\n itemsPerContext\n })\n }\n}\n\nexport {\n ContextCollection\n}","import * as csstree from 'css-tree'\nimport { compareSpecificity } from './selectors/specificity.js'\nimport { analyzeRules } from './rules/rules.js'\nimport { analyzeColors, colorFunctions, colorNames } from './values/colors.js'\nimport { analyzeFontFamilies } from './values/font-families.js'\nimport { analyzeFontSizes } from './values/font-sizes.js'\nimport { analyzeDeclarations } from './declarations/declarations.js'\nimport { analyzeSelectors } from './selectors/selectors.js'\nimport { analyzeProperties } from './properties/properties.js'\nimport { analyzeValues } from './values/values.js'\nimport { analyzeAnimations } from './values/animations.js'\nimport { analyzeVendorPrefixes } from './values/vendor-prefix.js'\nimport { analyzeAtRules } from './atrules/atrules.js'\nimport { CountableCollection } from './countable-collection.js'\nimport { ContextCollection } from './context-collection.js'\n\n/**\n *\n * @param {string} css\n * @returns\n */\nconst analyze = (css) => {\n const start = new Date()\n\n // We need all lines later on when we need to stringify the AST again\n // e.g. for Selectors\n const lines = css.split(/\\r?\\n/)\n\n /**\n * Recreate the authored CSS from a CSSTree node\n * @param {import('css-tree').Node} node - Node from CSSTree AST to stringify\n * @returns {string} str - The stringified node\n */\n function stringifyNode(node) {\n const start = node.loc.start\n const end = node.loc.end\n const lineCount = end.line - start.line\n\n // Single-line nodes\n if (lineCount === 0) {\n return lines[start.line - 1].substring(start.column - 1, end.column - 1)\n }\n\n // Multi-line nodes\n const value = []\n\n for (let i = start.line; i <= end.line; i++) {\n const line = lines[i - 1]\n // First line\n if (i === start.line) {\n value.push(line.substring(start.column - 1))\n continue\n }\n // Last line\n if (i === end.line) {\n value.push(line.substring(0, end.column - 1))\n continue\n }\n // All lines in between first and last\n value.push(line)\n }\n\n return value.join('\\n')\n }\n\n const startParse = new Date()\n let totalComments = 0\n let commentsSize = 0\n\n const ast = csstree.parse(css, {\n parseAtrulePrelude: false,\n parseCustomProperty: true, // To find font-families, colors, etc.\n positions: true, // So we can use stringifyNode()\n onComment: function (comment) {\n totalComments++\n commentsSize += comment.length\n },\n })\n\n const startAnalysis = new Date()\n const atrules = []\n const rules = []\n const selectors = []\n const declarations = []\n const properties = []\n const values = []\n const zindex = []\n const textShadows = []\n const boxShadows = []\n const fontValues = []\n const fontFamilyValues = []\n const fontSizeValues = []\n const animations = []\n const timingFunctions = []\n const durations = []\n const colors = new ContextCollection()\n const units = new ContextCollection()\n\n csstree.walk(ast, {\n enter: function (node) {\n switch (node.type) {\n case 'Atrule': {\n atrules.push(node)\n break\n }\n case 'Rule': {\n rules.push(node)\n break\n }\n case 'Selector': {\n selectors.push({\n ...node,\n isKeyframeSelector: this.atrule && this.atrule.name.endsWith('keyframes')\n })\n\n // Avoid further walking of selectors to not mess with\n // our specificity calculations in case of a selector\n // with :where() or :is() that contain SelectorLists\n // as children\n return this.skip\n }\n case 'Dimension': {\n if (!this.declaration) {\n break\n }\n\n units.push(node.unit, this.declaration.property)\n\n return this.skip\n }\n case 'Declaration': {\n declarations.push({\n ...node,\n inKeyframe: this.atrule && this.atrule.name.endsWith('keyframes')\n })\n\n const { value, property } = node\n const fullProperty = {\n authored: property,\n ...csstree.property(property)\n }\n\n properties.push(fullProperty)\n values.push(value)\n\n switch (fullProperty.basename) {\n case 'z-index': {\n zindex.push(value)\n break\n }\n case 'text-shadow': {\n textShadows.push(value)\n break\n }\n case 'box-shadow': {\n boxShadows.push(value)\n break\n }\n case 'font': {\n fontValues.push(value)\n break\n }\n case 'font-family': {\n fontFamilyValues.push(stringifyNode(value))\n // Prevent analyzer to find color names in this property\n return this.skip\n }\n case 'font-size': {\n fontSizeValues.push(stringifyNode(value))\n break\n }\n case 'transition':\n case 'animation': {\n animations.push(node)\n break\n }\n case 'animation-duration':\n case 'transition-duration': {\n durations.push(value)\n break\n }\n case 'transition-timing-function':\n case 'animation-timing-function': {\n timingFunctions.push(value)\n break\n }\n }\n\n csstree.walk(node.value, {\n enter: function (valueNode) {\n switch (valueNode.type) {\n case 'Hash': {\n colors.push(stringifyNode(valueNode), property)\n\n return this.skip\n }\n case 'Identifier': {\n const { name } = valueNode\n // Bail out if it can't be a color name\n // 20 === 'lightgoldenrodyellow'.length\n // 3 === 'red'.length\n if (name.length > 20 || name.length < 3) {\n return this.skip\n }\n if (colorNames[name.toLowerCase()]) {\n colors.push(stringifyNode(valueNode), property)\n }\n return this.skip\n }\n case 'Function': {\n if (colorFunctions[valueNode.name.toLowerCase()]) {\n colors.push(stringifyNode(valueNode), property)\n }\n // No this.skip here intentionally,\n // otherwise we'll miss colors in linear-gradient() etc.\n }\n }\n }\n })\n }\n }\n }\n })\n\n return {\n stylesheet: {\n sourceLinesOfCode: atrules.length + selectors.length + declarations.length,\n linesOfCode: lines.length,\n size: css.length,\n comments: {\n total: totalComments,\n size: commentsSize,\n },\n },\n atrules: analyzeAtRules({ atrules, stringifyNode }),\n rules: analyzeRules({ rules }),\n selectors: analyzeSelectors({ stringifyNode, selectors }),\n declarations: analyzeDeclarations({ stringifyNode, declarations }),\n properties: analyzeProperties({ properties }),\n values: {\n colors: analyzeColors({ colors }),\n fontFamilies: analyzeFontFamilies({ stringifyNode, fontValues, fontFamilyValues }),\n fontSizes: analyzeFontSizes({ stringifyNode, fontValues, fontSizeValues }),\n zindexes: analyzeValues({ values: zindex, stringifyNode }),\n textShadows: analyzeValues({ values: textShadows, stringifyNode }),\n boxShadows: analyzeValues({ values: boxShadows, stringifyNode }),\n animations: analyzeAnimations({ animations, timingFunctions, durations, stringifyNode }),\n prefixes: analyzeVendorPrefixes({ values, stringifyNode }),\n units: units.count(),\n },\n __meta__: {\n parseTime: startAnalysis - startParse,\n analyzeTime: new Date() - startAnalysis,\n total: new Date() - start\n }\n }\n}\n\nexport { analyze, compareSpecificity }"],"names":["compareSpecificity","a","b","selectorListSpecificities","selectorListAst","childSelectors","csstree","walk","visit","enter","node","push","analyzeSpecificity","sort","specificity","ast","A","B","C","complexity","isA11y","selector","type","Boolean","value","name","startsWith","includes","skip","rawSelectorList","find","selectorList","parse","context","i","length","isId","AggregateCollection","size","this","items","Uint8Array","sum","cursor","add","item","aggregate","min","max","mean","mode","median","range","arr","middle","lowerMiddleRank","sorted","slice","frequencies","Object","create","maxOccurrences","maxOccurenceCount","element","updatedCount","Mode","Math","floor","toArray","Array","from","subarray","analyzeRules","rules","totalRules","selectorsPerRule","declarationsPerRule","emptyRules","selectors","declarations","childNode","total","empty","ratio","colorNames","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkgrey","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","green","greenyellow","grey","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightgrey","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen","canvas","canvastext","linktext","visitedtext","activetext","buttonface","buttontext","buttonborder","field","fieldtext","highlight","highlighttext","selecteditem","selecteditemtext","mark","marktext","graytext","colorFunctions","rgb","rgba","hsl","hsla","hwb","lab","lch","oklab","oklch","color","CountableCollection","initial","totalUnique","index","count","unique","uniquenessRatio","systemKeywords","inherit","unset","revert","caption","icon","menu","keywordDisallowList","normal","small","medium","large","larger","smaller","bold","bolder","lighter","condensed","expanded","italic","oblique","analyzeFontFamilies","fontValues","all","fontFamilyValues","firstChild","children","first","parts","reverse","fontNode","charCodeAt","unshift","map","generate","join","sizeKeywords","keywords","analyzeFontSizes","stringifyNode","fontSizeValues","operator","analyzeDeclarations","cache","importants","totalInKeyframes","declaration","important","inKeyframe","stringified","inKeyframes","analyzeSelectors","maxSpecificity","minSpecificity","counts","totalSelectors","specificityA","specificityB","specificityC","complexityAggregator","specificities","complexities","ids","a11y","keyframes","isKeyframeSelector","undefined","aggregatesA","aggregatesB","aggregatesC","complexityCount","id","accessibility","analyzeProperties","properties","p","authored","prefixed","hacks","customs","totalProperties","property","vendor","hack","custom","browserhacks","auto","none","analyzeValues","values","timingKeywords","linear","ease","analyzeAnimations","animations","timingFunctions","allDurations","durations","allTimingFunctions","durationFound","forEach","child","hasVendorPrefix","keyword","indexOf","isAstVendorPrefixed","analyzeVendorPrefixes","analyzeAtRules","atrules","fontfaces","imports","medias","charsets","supports","prefixedKeyframes","containers","machine","descriptors","block","descriptor","media","prelude","import","charset","container","nodeName","action","endsWith","fontface","ContextCollection","list","contexts","contextCount","itemsPerContext","assign","css","start","Date","lines","split","loc","end","line","substring","column","startParse","totalComments","commentsSize","parseAtrulePrelude","parseCustomProperty","positions","onComment","comment","startAnalysis","zindex","textShadows","boxShadows","colors","units","atrule","unit","fullProperty","basename","valueNode","toLowerCase","stylesheet","sourceLinesOfCode","linesOfCode","comments","fontFamilies","fontSizes","zindexes","prefixes","__meta__","parseTime","analyzeTime"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"analyzer.umd.js","sources":["../src/selectors/specificity.js","../src/aggregate-collection.js","../src/rules/rules.js","../src/values/colors.js","../src/countable-collection.js","../src/values/font-families.js","../src/values/font-sizes.js","../src/declarations/declarations.js","../src/selectors/selectors.js","../src/properties/properties.js","../src/values/values.js","../src/values/animations.js","../src/vendor-prefix.js","../src/values/vendor-prefix.js","../src/atrules/atrules.js","../src/context-collection.js","../src/index.js"],"sourcesContent":["import * as csstree from 'css-tree'\n\n/**\n * @typedef {[number, number, number]} Specificity\n *\n * @typedef {import('css-tree').Selector} Selector\n */\n\n/**\n * Compare specificity A to Specificity B\n * @param {Specificity} a - Specificity A\n * @param {Specificity} b - Specificity B\n * @returns {number} sortIndex - 0 when a==b, 1 when a<b, -1 when a>b\n */\nfunction compareSpecificity(a, b) {\n if (a[0] === b[0]) {\n if (a[1] === b[1]) {\n return b[2] - a[2]\n }\n\n return b[1] - a[1]\n }\n\n return b[0] - a[0]\n}\n\n/**\n *\n * @param {import('css-tree').SelectorList} selectorListAst\n * @returns {Selector} topSpecificitySelector\n */\nfunction selectorListSpecificities(selectorListAst) {\n const childSelectors = []\n csstree.walk(selectorListAst, {\n visit: 'Selector',\n enter(node) {\n childSelectors.push(analyzeSpecificity(node))\n }\n })\n\n return childSelectors.sort((a, b) => compareSpecificity(a.specificity, b.specificity))\n}\n\n/**\n * Get the Specificity for the AST of a Selector Node\n * @param {import('css-tree').Node} ast - AST Node for a Selector\n * @return {Object}\n * @property {Specificity} specificity\n * @property {number} complexity\n */\nconst analyzeSpecificity = (ast) => {\n let A = 0\n let B = 0\n let C = 0\n let complexity = 0\n let isA11y = false\n\n csstree.walk(ast, {\n enter: function (selector) {\n switch (selector.type) {\n case 'IdSelector': {\n A++\n complexity++\n break\n }\n case 'ClassSelector': {\n B++\n complexity++\n break\n }\n case 'AttributeSelector': {\n B++\n complexity++\n\n if (Boolean(selector.value)) {\n complexity++\n }\n isA11y = selector.name.name === 'role' || selector.name.name.startsWith('aria-')\n break\n }\n case 'PseudoElementSelector':\n case 'TypeSelector': {\n if (selector.name !== '*') {\n C++\n }\n complexity++\n break\n }\n case 'PseudoClassSelector': {\n if (['before', 'after', 'first-letter', 'first-line'].includes(selector.name)) {\n C++\n complexity++\n return this.skip\n }\n // The specificity of an :is(), :not(), or :has() pseudo-class is\n // replaced by the specificity of the most specific complex\n // selector in its selector list argument.\n\n // CSSTree doesn't parse the arguments of :is, :has and :matches,\n // so we need to create an AST out of them ourselves\n if (['is', 'has', 'matches'].includes(selector.name)) {\n const rawSelectorList = csstree.find(selector, ({ type }) => type === 'Raw')\n const childAst = csstree.parse(rawSelectorList.value, { context: 'selectorList' })\n const selectorList = selectorListSpecificities(childAst)\n const [topA, topB, topC] = selectorList[0].specificity\n A += topA\n B += topB\n C += topC\n\n for (let i = 0; i < selectorList.length; i++) {\n complexity += selectorList[i].complexity\n }\n complexity++\n return\n }\n\n // CSSTree *does* parse the arguments of the :not() pseudo-class,\n // so we have direct access to the AST, instead of having to parse\n // the arguments ourselves.\n if (selector.name === 'not') {\n const selectorList = selectorListSpecificities(selector)\n const [topA, topB, topC] = selectorList[0].specificity\n A += topA\n B += topB\n C += topC\n\n for (let i = 0; i < selectorList.length; i++) {\n complexity += selectorList[i].complexity\n }\n complexity++\n return this.skip\n }\n\n // The specificity of an :nth-child() or :nth-last-child() selector\n // is the specificity of the pseudo class itself (counting as one\n // pseudo-class selector) plus the specificity of the most\n // specific complex selector in its selector list argument (if any).\n if (['nth-child', 'nth-last-child'].includes(selector.name)) {\n // +1 for the pseudo class itself\n B++\n\n const childSelectors = selectorListSpecificities(selector)\n\n if (childSelectors.length === 0) {\n return\n }\n\n const [topA, topB, topC] = childSelectors[0].specificity\n A += topA\n B += topB\n C += topC\n\n for (let i = 0; i < childSelectors.length; i++) {\n complexity += childSelectors[i].complexity;\n }\n\n complexity++\n return\n }\n\n // The specificity of a :where() pseudo-class is replaced by zero,\n // but it does count towards complexity.\n if (selector.name === 'where') {\n const rawSelectorList = csstree.find(selector, ({ type }) => type === 'Raw')\n const childAst = csstree.parse(rawSelectorList.value, { context: 'selectorList' })\n const childSelectors = selectorListSpecificities(childAst)\n\n for (let i = 0; i < childSelectors.length; i++) {\n complexity += childSelectors[i].complexity;\n }\n\n complexity++\n return\n }\n\n // Regular pseudo classes have specificity [0,1,0]\n complexity++\n B++\n break\n }\n case 'Combinator': {\n complexity++\n break\n }\n }\n }\n })\n\n return {\n /** @type Specificity */\n specificity: [A, B, C],\n complexity,\n isId: A > 0,\n isA11y\n }\n}\n\nexport {\n analyzeSpecificity,\n compareSpecificity,\n}","/**\n * Find the mode (most occurring value) in an array of Numbers\n * Takes the mean/average of multiple values if multiple values occur the same amount of times.\n *\n * @see https://github.com/angus-c/just/blob/684af9ca0c7808bc78543ec89379b1fdfce502b1/packages/array-mode/index.js\n * @param {Array} arr - Array to find the mode value for\n * @returns {Number} mode - The `mode` value of `arr`\n */\nfunction Mode(arr) {\n const frequencies = Object.create(null)\n let maxOccurrences = -1\n let maxOccurenceCount = 0\n let sum = 0\n\n for (let i = 0; i < arr.length; i++) {\n const element = arr[i]\n const updatedCount = (frequencies[element] || 0) + 1\n frequencies[element] = updatedCount\n\n if (updatedCount > maxOccurrences) {\n maxOccurrences = updatedCount\n maxOccurenceCount = 0\n sum = 0\n }\n\n if (updatedCount >= maxOccurrences) {\n maxOccurenceCount++\n sum += element\n }\n }\n\n return sum / maxOccurenceCount\n}\n\n/**\n * Find the middle number in an Array of Numbers\n * Returns the average of 2 numbers if the Array length is an even number\n * @see https://github.com/angus-c/just/blob/684af9ca0c7808bc78543ec89379b1fdfce502b1/packages/array-median/index.js\n * @param {Array} arr - A sorted Array\n * @returns {Number} - The array's Median\n */\nfunction Median(arr) {\n const middle = arr.length / 2\n const lowerMiddleRank = Math.floor(middle)\n\n if (middle !== lowerMiddleRank) {\n return arr[lowerMiddleRank]\n }\n return (arr[lowerMiddleRank] + arr[lowerMiddleRank - 1]) / 2\n}\n\nclass AggregateCollection {\n constructor(size) {\n /** @type Number[] */\n this.items = new Uint8Array(size)\n this.sum = 0\n this.cursor = 0\n }\n\n /**\n * Add a new Integer to the AggregateCollection\n * @param {number} item - The item to add to the AggregateCollection\n */\n add(item) {\n this.items[this.cursor] = (item)\n this.sum += item\n this.cursor++\n }\n\n aggregate() {\n if (this.cursor === 0) {\n return {\n min: 0,\n max: 0,\n mean: 0,\n mode: 0,\n median: 0,\n range: 0,\n sum: 0,\n }\n }\n\n /** @type Number[] */\n const sorted = new Uint8Array(\n this.items.slice(0, this.cursor)\n ).sort((a, b) => a - b)\n const min = sorted[0]\n const max = sorted[sorted.length - 1]\n\n const mode = Mode(sorted)\n const median = Median(sorted)\n\n return {\n min,\n max,\n mean: this.sum / this.cursor,\n mode,\n median,\n range: max - min,\n sum: this.sum,\n }\n }\n\n toArray() {\n return Array.from(\n this.items.subarray(0, this.cursor)\n )\n }\n}\n\nexport {\n AggregateCollection\n}","import * as csstree from 'css-tree'\nimport { AggregateCollection } from '../aggregate-collection.js'\n\nconst analyzeRules = ({ rules }) => {\n const totalRules = rules.length\n const selectorsPerRule = new AggregateCollection(totalRules)\n const declarationsPerRule = new AggregateCollection(totalRules)\n\n let emptyRules = 0\n\n for (let i = 0; i < totalRules; i++) {\n let selectors = 0\n let declarations = 0\n\n csstree.walk(rules[i], {\n enter: function (childNode) {\n if (childNode.type === 'Selector') {\n selectors++\n return this.skip\n }\n\n if (childNode.type === 'Declaration') {\n declarations++\n return this.skip\n }\n }\n })\n\n if (declarations === 0) {\n emptyRules++\n }\n\n // For later aggregations\n selectorsPerRule.add(selectors)\n declarationsPerRule.add(declarations)\n }\n\n return {\n total: totalRules,\n empty: {\n total: emptyRules,\n ratio: totalRules === 0 ? 0 : emptyRules / totalRules\n },\n selectors: {\n ...selectorsPerRule.aggregate(),\n items: selectorsPerRule.toArray(),\n },\n declarations: {\n ...declarationsPerRule.aggregate(),\n items: declarationsPerRule.toArray()\n },\n }\n}\n\nexport {\n analyzeRules\n}","export const colorNames = {\n // CSS Named Colors\n // Spec: https://drafts.csswg.org/css-color/#named-colors\n aliceblue: 1,\n antiquewhite: 1,\n aqua: 1,\n aquamarine: 1,\n azure: 1,\n beige: 1,\n bisque: 1,\n black: 1,\n blanchedalmond: 1,\n blue: 1,\n blueviolet: 1,\n brown: 1,\n burlywood: 1,\n cadetblue: 1,\n chartreuse: 1,\n chocolate: 1,\n coral: 1,\n cornflowerblue: 1,\n cornsilk: 1,\n crimson: 1,\n cyan: 1,\n darkblue: 1,\n darkcyan: 1,\n darkgoldenrod: 1,\n darkgray: 1,\n darkgreen: 1,\n darkgrey: 1,\n darkkhaki: 1,\n darkmagenta: 1,\n darkolivegreen: 1,\n darkorange: 1,\n darkorchid: 1,\n darkred: 1,\n darksalmon: 1,\n darkseagreen: 1,\n darkslateblue: 1,\n darkslategray: 1,\n darkslategrey: 1,\n darkturquoise: 1,\n darkviolet: 1,\n deeppink: 1,\n deepskyblue: 1,\n dimgray: 1,\n dimgrey: 1,\n dodgerblue: 1,\n firebrick: 1,\n floralwhite: 1,\n forestgreen: 1,\n fuchsia: 1,\n gainsboro: 1,\n ghostwhite: 1,\n gold: 1,\n goldenrod: 1,\n gray: 1,\n green: 1,\n greenyellow: 1,\n grey: 1,\n honeydew: 1,\n hotpink: 1,\n indianred: 1,\n indigo: 1,\n ivory: 1,\n khaki: 1,\n lavender: 1,\n lavenderblush: 1,\n lawngreen: 1,\n lemonchiffon: 1,\n lightblue: 1,\n lightcoral: 1,\n lightcyan: 1,\n lightgoldenrodyellow: 1,\n lightgray: 1,\n lightgreen: 1,\n lightgrey: 1,\n lightpink: 1,\n lightsalmon: 1,\n lightseagreen: 1,\n lightskyblue: 1,\n lightslategray: 1,\n lightslategrey: 1,\n lightsteelblue: 1,\n lightyellow: 1,\n lime: 1,\n limegreen: 1,\n linen: 1,\n magenta: 1,\n maroon: 1,\n mediumaquamarine: 1,\n mediumblue: 1,\n mediumorchid: 1,\n mediumpurple: 1,\n mediumseagreen: 1,\n mediumslateblue: 1,\n mediumspringgreen: 1,\n mediumturquoise: 1,\n mediumvioletred: 1,\n midnightblue: 1,\n mintcream: 1,\n mistyrose: 1,\n moccasin: 1,\n navajowhite: 1,\n navy: 1,\n oldlace: 1,\n olive: 1,\n olivedrab: 1,\n orange: 1,\n orangered: 1,\n orchid: 1,\n palegoldenrod: 1,\n palegreen: 1,\n paleturquoise: 1,\n palevioletred: 1,\n papayawhip: 1,\n peachpuff: 1,\n peru: 1,\n pink: 1,\n plum: 1,\n powderblue: 1,\n purple: 1,\n rebeccapurple: 1,\n red: 1,\n rosybrown: 1,\n royalblue: 1,\n saddlebrown: 1,\n salmon: 1,\n sandybrown: 1,\n seagreen: 1,\n seashell: 1,\n sienna: 1,\n silver: 1,\n skyblue: 1,\n slateblue: 1,\n slategray: 1,\n slategrey: 1,\n snow: 1,\n springgreen: 1,\n steelblue: 1,\n tan: 1,\n teal: 1,\n thistle: 1,\n tomato: 1,\n turquoise: 1,\n violet: 1,\n wheat: 1,\n white: 1,\n whitesmoke: 1,\n yellow: 1,\n yellowgreen: 1,\n\n // CSS System Colors\n // Spec: https://drafts.csswg.org/css-color/#css-system-colors\n canvas: 1,\n canvastext: 1,\n linktext: 1,\n visitedtext: 1,\n activetext: 1,\n buttonface: 1,\n buttontext: 1,\n buttonborder: 1,\n field: 1,\n fieldtext: 1,\n highlight: 1,\n highlighttext: 1,\n selecteditem: 1,\n selecteditemtext: 1,\n mark: 1,\n marktext: 1,\n graytext: 1,\n\n // TODO: Deprecated CSS System colors\n // Spec: https://drafts.csswg.org/css-color/#deprecated-system-colors\n}\n\nexport const colorFunctions = {\n rgb: 1,\n rgba: 1,\n hsl: 1,\n hsla: 1,\n hwb: 1,\n lab: 1,\n lch: 1,\n oklab: 1,\n oklch: 1,\n color: 1,\n}\n\nexport const analyzeColors = ({ colors }) => {\n return colors.count()\n}\n","class CountableCollection {\n /**\n * @param {string[]} initial\n */\n constructor(initial) {\n this.items = {}\n this.total = 0\n this.totalUnique = 0\n\n if (initial) {\n for (let index = 0; index < initial.length; index++) {\n this.push(initial[index])\n }\n }\n }\n\n /**\n *\n * @param {string} item\n */\n push(item) {\n this.total++\n\n if (this.items[item]) {\n this.items[item]++\n return\n }\n\n this.items[item] = 1\n this.totalUnique++\n }\n\n size() {\n return this.total\n }\n\n count() {\n return {\n total: this.total,\n totalUnique: this.totalUnique,\n unique: this.items,\n uniquenessRatio: this.total === 0 ? 0 : this.totalUnique / this.total,\n }\n }\n}\n\nexport {\n CountableCollection\n}","import * as csstree from 'css-tree'\nimport { CountableCollection } from '../countable-collection.js'\n\nconst systemKeywords = {\n // Global CSS keywords\n 'inherit': 1,\n 'initial': 1,\n 'unset': 1,\n 'revert': 1,\n\n // System font keywords\n 'caption': 1,\n 'icon': 1,\n 'menu': 1,\n 'message-box': 1,\n 'small-caption': 1,\n 'status-bar': 1,\n}\n\nconst keywordDisallowList = {\n // font-weight, font-stretch, font-style\n 'normal': 1,\n\n // font-size keywords\n 'xx-small': 1,\n 'x-small': 1,\n 'small': 1,\n 'medium': 1,\n 'large': 1,\n 'x-large': 1,\n 'xx-large': 1,\n 'larger': 1,\n 'smaller': 1,\n\n // font-weight keywords\n 'bold': 1,\n 'bolder': 1,\n 'lighter': 1,\n\n // font-stretch keywords\n 'ultra-condensed': 1,\n 'extra-condensed': 1,\n 'condensed': 1,\n 'semi-condensed': 1,\n 'semi-expanded': 1,\n 'expanded': 1,\n 'extra-expanded': 1,\n 'ultra-expanded': 1,\n\n // font-style keywords\n 'italic': 1,\n 'oblique': 1,\n}\n\nconst COMMA = 44 // ','.charCodeAt(0) === 44\n\nconst analyzeFontFamilies = ({ fontValues, fontFamilyValues }) => {\n const all = new CountableCollection(fontFamilyValues)\n\n for (let index = 0; index < fontValues.length; index++) {\n const value = fontValues[index]\n\n // Avoid tree traversal as soon as possible\n const firstChild = value.children.first\n\n if (firstChild.type === 'Identifier' && systemKeywords[firstChild.name]) {\n continue\n }\n\n const parts = []\n\n csstree.walk(value, {\n reverse: true,\n enter: function (fontNode) {\n if (fontNode.type === 'String') {\n return parts.unshift(fontNode)\n }\n if (fontNode.type === 'Operator' && fontNode.value.charCodeAt(0) === COMMA) {\n return parts.unshift(fontNode)\n }\n if (fontNode.type === 'Identifier') {\n if (keywordDisallowList[fontNode.name]) {\n return this.skip\n }\n return parts.unshift(fontNode)\n }\n }\n })\n\n all.push(parts.map(csstree.generate).join(''))\n }\n\n return all.count()\n}\n\nexport {\n analyzeFontFamilies\n}","import * as csstree from 'css-tree'\nimport { CountableCollection } from '../countable-collection.js'\n\nconst sizeKeywords = {\n 'xx-small': 1,\n 'x-small': 1,\n 'small': 1,\n 'medium': 1,\n 'large': 1,\n 'x-large': 1,\n 'xx-large': 1,\n 'larger': 1,\n 'smaller': 1,\n}\n\nconst keywords = {\n // Global CSS keywords\n 'inherit': 1,\n 'initial': 1,\n 'unset': 1,\n 'revert': 1,\n\n // System font keywords\n 'caption': 1,\n 'icon': 1,\n 'menu': 1,\n 'message-box': 1,\n 'small-caption': 1,\n 'status-bar': 1,\n}\n\nconst ZERO = 48 // '0'.charCodeAt(0) === 48\nconst SLASH = 47 // '/'.charCodeAt(0) === 47\n\nconst analyzeFontSizes = ({ stringifyNode, fontSizeValues, fontValues }) => {\n const all = new CountableCollection(fontSizeValues)\n\n for (let index = 0; index < fontValues.length; index++) {\n const fontNode = fontValues[index];\n // Try to eliminate a keyword before we continue\n const firstChild = fontNode.children.first\n\n if (firstChild.type === 'Identifier' && keywords[firstChild.name]) {\n continue\n }\n\n let operator = false\n let size\n\n csstree.walk(fontNode, {\n enter: function (fontNode) {\n switch (fontNode.type) {\n case 'Number': {\n // Special case for `font: 0/0 a`\n if (fontNode.value.charCodeAt(0) === ZERO) {\n size = '0'\n return this.break\n }\n }\n case 'Operator': {\n if (fontNode.value.charCodeAt(0) === SLASH) {\n operator = true\n }\n break\n }\n case 'Dimension': {\n if (!operator) {\n size = stringifyNode(fontNode)\n return this.break\n }\n }\n case 'Identifier': {\n if (sizeKeywords[fontNode.name]) {\n size = fontNode.name\n return this.break\n }\n }\n }\n }\n })\n\n if (size) {\n all.push(size)\n }\n }\n\n return all.count()\n}\n\nexport {\n analyzeFontSizes\n}","const analyzeDeclarations = ({ stringifyNode, declarations }) => {\n const total = declarations.length\n const cache = Object.create(null)\n let importants = 0\n let totalUnique = 0\n let totalInKeyframes = 0\n\n for (let i = 0; i < total; i++) {\n const declaration = declarations[i]\n\n if (declaration.important === true) {\n importants++\n\n if (declaration.inKeyframe) {\n totalInKeyframes++\n }\n }\n\n const stringified = stringifyNode(declaration)\n\n if (!cache[stringified]) {\n cache[stringified] = 1\n totalUnique++\n }\n }\n\n return {\n total,\n unique: {\n total: totalUnique,\n ratio: total === 0 ? 0 : totalUnique / total,\n },\n importants: {\n total: importants,\n ratio: total === 0 ? 0 : importants / total,\n inKeyframes: {\n total: totalInKeyframes,\n ratio: importants === 0 ? 0 : totalInKeyframes / importants,\n },\n },\n }\n}\n\nexport {\n analyzeDeclarations\n}","import { analyzeSpecificity, compareSpecificity } from './specificity.js'\nimport { AggregateCollection } from '../aggregate-collection.js'\nimport { CountableCollection } from '../countable-collection.js'\n\n/** @typedef {[number, number, number]} Specificity */\n\nconst analyzeSelectors = ({ stringifyNode, selectors }) => {\n const counts = Object.create(null)\n const cache = Object.create(null)\n const totalSelectors = selectors.length\n\n /** @type Specificity|undefined */\n let maxSpecificity\n /** @type Specificity|undefined */\n let minSpecificity\n let specificityA = new AggregateCollection(totalSelectors)\n let specificityB = new AggregateCollection(totalSelectors)\n let specificityC = new AggregateCollection(totalSelectors)\n let totalUnique = 0\n const complexityAggregator = new AggregateCollection(totalSelectors);\n\n const specificities = []\n const complexities = []\n const ids = new CountableCollection()\n const a11y = new CountableCollection()\n const keyframes = new CountableCollection()\n\n for (let i = 0; i < totalSelectors; i++) {\n const node = selectors[i];\n const value = stringifyNode(node)\n\n if (node.isKeyframeSelector) {\n keyframes.push(value)\n // Do not attempt to further analyze <keyframe-selectors>\n continue\n }\n\n const { specificity, complexity, isId, isA11y } = cache[value] || analyzeSpecificity(node)\n\n if (isId) {\n ids.push(value)\n }\n\n if (isA11y) {\n a11y.push(value)\n }\n\n if (!cache[value]) {\n cache[value] = { complexity, specificity, isId, isA11y }\n totalUnique++\n counts[value] = 1\n } else {\n counts[value]++\n }\n\n complexityAggregator.add(complexity)\n\n if (maxSpecificity === undefined) {\n maxSpecificity = specificity\n }\n\n if (minSpecificity === undefined) {\n minSpecificity = specificity\n }\n\n specificityA.add(specificity[0])\n specificityB.add(specificity[1])\n specificityC.add(specificity[2])\n\n if (minSpecificity !== undefined && compareSpecificity(minSpecificity, specificity) < 0) {\n minSpecificity = specificity\n }\n\n if (maxSpecificity !== undefined && compareSpecificity(maxSpecificity, specificity) > 0) {\n maxSpecificity = specificity\n }\n\n specificities.push(specificity)\n complexities.push(complexity)\n }\n\n const aggregatesA = specificityA.aggregate()\n const aggregatesB = specificityB.aggregate()\n const aggregatesC = specificityC.aggregate()\n const complexityCount = new CountableCollection(complexities).count()\n\n return {\n total: totalSelectors,\n totalUnique,\n uniquenessRatio: totalSelectors === 0 ? 0 : totalUnique / totalSelectors,\n specificity: {\n sum: [aggregatesA.sum, aggregatesB.sum, aggregatesC.sum],\n min: minSpecificity,\n max: maxSpecificity,\n mean: [aggregatesA.mean, aggregatesB.mean, aggregatesC.mean],\n mode: [aggregatesA.mode, aggregatesB.mode, aggregatesC.mode],\n median: [aggregatesA.median, aggregatesB.median, aggregatesC.median],\n items: specificities\n },\n complexity: {\n ...complexityAggregator.aggregate(),\n ...complexityCount,\n items: complexities,\n },\n id: {\n ...ids.count(),\n ratio: totalSelectors === 0 ? 0 : ids.size() / totalSelectors,\n },\n accessibility: {\n ...a11y.count(),\n ratio: totalSelectors === 0 ? 0 : a11y.size() / totalSelectors,\n },\n keyframes: {\n ...keyframes.count(),\n ratio: totalSelectors === 0 ? 0 : keyframes.size() / totalSelectors,\n }\n }\n}\n\nexport {\n analyzeSelectors\n}","import { CountableCollection } from '../countable-collection.js'\n\nconst analyzeProperties = ({ properties }) => {\n const all = new CountableCollection(properties.map(p => p.authored))\n const prefixed = new CountableCollection()\n const hacks = new CountableCollection()\n const customs = new CountableCollection()\n const totalProperties = properties.length\n\n for (let i = 0; i < totalProperties; i++) {\n const property = properties[i]\n\n if (property.vendor) {\n prefixed.push(property.authored)\n continue\n }\n\n if (property.hack) {\n hacks.push(property.authored)\n continue\n }\n\n if (property.custom) {\n customs.push(property.authored)\n continue\n }\n }\n\n return {\n ...all.count(),\n prefixed: {\n ...prefixed.count(),\n ratio: prefixed.size() / totalProperties,\n },\n custom: {\n ...customs.count(),\n ratio: customs.size() / totalProperties,\n },\n browserhacks: {\n ...hacks.count(),\n ratio: hacks.size() / totalProperties,\n }\n }\n}\n\nexport {\n analyzeProperties\n}","import { CountableCollection } from '../countable-collection.js'\n\nconst keywords = {\n 'auto': 1,\n 'inherit': 1,\n 'initial': 1,\n 'unset': 1,\n 'revert': 1,\n 'none': 1, // for `text-shadow`\n}\n\nconst analyzeValues = ({ values, stringifyNode }) => {\n const all = new CountableCollection()\n\n for (let i = 0; i < values.length; i++) {\n const node = values[i]\n const firstChild = node.children.first\n\n if (!firstChild) continue\n if (firstChild.type === 'Identifier' && keywords[firstChild.name]) continue\n\n all.push(stringifyNode(node))\n }\n\n return all.count()\n}\n\nexport {\n analyzeValues\n}","import { CountableCollection } from '../countable-collection.js'\n\nconst timingKeywords = {\n 'linear': 1,\n 'ease': 1,\n 'ease-in': 1,\n 'ease-out': 1,\n 'ease-in-out': 1,\n 'step-start': 1,\n 'step-end': 1,\n}\n\nconst analyzeAnimations = ({ animations, durations, timingFunctions, stringifyNode }) => {\n const allDurations = new CountableCollection(durations.map(stringifyNode))\n const allTimingFunctions = new CountableCollection(timingFunctions.map(stringifyNode))\n\n for (let index = 0; index < animations.length; index++) {\n const node = animations[index]\n // Flag to know if we've grabbed the first Duration\n // yet (the first Dimension in a shorthand)\n let durationFound = false\n\n node.value.children.forEach(child => {\n // Right after a ',' we start over again\n if (child.type === 'Operator') {\n return durationFound = false\n }\n if (child.type === 'Dimension' && durationFound === false) {\n durationFound = true\n return allDurations.push(stringifyNode(child))\n }\n if (child.type === 'Identifier' && timingKeywords[child.name]) {\n return allTimingFunctions.push(stringifyNode(child))\n }\n if (child.type === 'Function'\n && (\n child.name === 'cubic-bezier' || child.name === 'steps'\n )\n ) {\n return allTimingFunctions.push(stringifyNode(child))\n }\n })\n }\n\n return {\n durations: allDurations.count(),\n timingFunctions: allTimingFunctions.count(),\n }\n}\n\nexport {\n analyzeAnimations\n}","const HYPHENMINUS = 45; // '-'.charCodeAt()\n\nfunction hasVendorPrefix(keyword) {\n if (keyword.charCodeAt(0) === HYPHENMINUS && keyword.charCodeAt(1) !== HYPHENMINUS) {\n // String must have a 2nd occurrence of '-', at least at position 3 (offset=2)\n if (keyword.indexOf('-', 2) !== -1) {\n return true\n }\n }\n\n return false\n}\n\nexport {\n hasVendorPrefix\n}","import { CountableCollection } from '../countable-collection.js'\nimport { hasVendorPrefix } from '../vendor-prefix.js'\n\nfunction isAstVendorPrefixed(children) {\n children = children.toArray()\n\n for (let index = 0; index < children.length; index++) {\n const child = children[index];\n\n if (child.type === 'Identifier' && child.name.length >= 3) {\n if (hasVendorPrefix(child.name)) {\n return true\n }\n }\n\n if (child.type === 'Function') {\n if (hasVendorPrefix(child.name)) {\n return true\n }\n\n if (child.children && isAstVendorPrefixed(child.children)) {\n return true\n }\n }\n }\n return false\n}\n\nconst analyzeVendorPrefixes = ({ values, stringifyNode }) => {\n const all = new CountableCollection()\n\n for (let i = 0; i < values.length; i++) {\n const value = values[i]\n\n if (value.children && isAstVendorPrefixed(value.children)) {\n all.push(stringifyNode(value))\n }\n }\n\n return all.count()\n}\n\nexport {\n analyzeVendorPrefixes\n}","import { CountableCollection } from '../countable-collection.js'\nimport { hasVendorPrefix } from '../vendor-prefix.js'\n\nconst analyzeAtRules = ({ atrules, stringifyNode }) => {\n const fontfaces = []\n const imports = new CountableCollection()\n const medias = new CountableCollection()\n const charsets = new CountableCollection()\n const supports = new CountableCollection()\n const keyframes = new CountableCollection()\n const prefixedKeyframes = new CountableCollection()\n const containers = new CountableCollection()\n\n const machine = {\n 'font-face': (node) => {\n const descriptors = {}\n\n node.block.children.forEach(descriptor => {\n descriptors[descriptor.property] = stringifyNode(descriptor.value)\n })\n\n fontfaces.push(descriptors)\n },\n 'media': node => medias.push(node.prelude.value),\n 'supports': node => supports.push(node.prelude.value),\n 'keyframes': node => keyframes.push(`@${node.name} ${node.prelude.value}`),\n 'import': node => imports.push(node.prelude.value),\n 'charset': node => charsets.push(node.prelude.value),\n 'container': node => containers.push(node.prelude.value),\n }\n\n for (let i = 0; i < atrules.length; i++) {\n const node = atrules[i]\n const nodeName = node.name\n const action = machine[nodeName]\n if (action) {\n action(node)\n continue\n }\n\n if (nodeName.endsWith('keyframes')) {\n const name = `@${nodeName} ${node.prelude.value}`\n keyframes.push(name)\n\n if (hasVendorPrefix(nodeName)) {\n prefixedKeyframes.push(name)\n }\n continue\n }\n }\n\n return {\n fontface: {\n total: fontfaces.length,\n totalUnique: fontfaces.length,\n unique: fontfaces,\n uniquenessRatio: 1\n },\n import: imports.count(),\n media: medias.count(),\n charset: charsets.count(),\n supports: supports.count(),\n keyframes: {\n ...keyframes.count(),\n prefixed: {\n ...prefixedKeyframes.count(),\n ratio: keyframes.size() === 0 ? 0 : prefixedKeyframes.size() / keyframes.size()\n }\n },\n container: containers.count(),\n }\n}\n\nexport {\n analyzeAtRules\n}","import { CountableCollection } from './countable-collection.js'\n\nclass ContextCollection {\n constructor() {\n this.list = new CountableCollection()\n this.contexts = {}\n this.contextCount = 0\n }\n\n push(item, context) {\n this.list.push(item)\n\n if (!this.contexts[context]) {\n this.contexts[context] = new CountableCollection()\n this.contextCount++\n }\n\n this.contexts[context].push(item)\n }\n\n count() {\n const itemsPerContext = {}\n\n for (let context in this.contexts) {\n itemsPerContext[context] = this.contexts[context].count()\n }\n\n return Object.assign(this.list.count(), {\n itemsPerContext\n })\n }\n}\n\nexport {\n ContextCollection\n}","import * as csstree from 'css-tree'\nimport { compareSpecificity } from './selectors/specificity.js'\nimport { analyzeRules } from './rules/rules.js'\nimport { analyzeColors, colorFunctions, colorNames } from './values/colors.js'\nimport { analyzeFontFamilies } from './values/font-families.js'\nimport { analyzeFontSizes } from './values/font-sizes.js'\nimport { analyzeDeclarations } from './declarations/declarations.js'\nimport { analyzeSelectors } from './selectors/selectors.js'\nimport { analyzeProperties } from './properties/properties.js'\nimport { analyzeValues } from './values/values.js'\nimport { analyzeAnimations } from './values/animations.js'\nimport { analyzeVendorPrefixes } from './values/vendor-prefix.js'\nimport { analyzeAtRules } from './atrules/atrules.js'\nimport { CountableCollection } from './countable-collection.js'\nimport { ContextCollection } from './context-collection.js'\n\n/**\n *\n * @param {string} css\n * @returns\n */\nconst analyze = (css) => {\n const start = new Date()\n\n // We need all lines later on when we need to stringify the AST again\n // e.g. for Selectors\n const lines = css.split(/\\r?\\n/)\n\n /**\n * Recreate the authored CSS from a CSSTree node\n * @param {import('css-tree').Node} node - Node from CSSTree AST to stringify\n * @returns {string} str - The stringified node\n */\n function stringifyNode(node) {\n const start = node.loc.start\n const end = node.loc.end\n const lineCount = end.line - start.line\n\n // Single-line nodes\n if (lineCount === 0) {\n return lines[start.line - 1].substring(start.column - 1, end.column - 1)\n }\n\n // Multi-line nodes\n const value = []\n\n for (let i = start.line; i <= end.line; i++) {\n const line = lines[i - 1]\n // First line\n if (i === start.line) {\n value.push(line.substring(start.column - 1))\n continue\n }\n // Last line\n if (i === end.line) {\n value.push(line.substring(0, end.column - 1))\n continue\n }\n // All lines in between first and last\n value.push(line)\n }\n\n return value.join('\\n')\n }\n\n const startParse = new Date()\n let totalComments = 0\n let commentsSize = 0\n\n const ast = csstree.parse(css, {\n parseAtrulePrelude: false,\n parseCustomProperty: true, // To find font-families, colors, etc.\n positions: true, // So we can use stringifyNode()\n onComment: function (comment) {\n totalComments++\n commentsSize += comment.length\n },\n })\n\n const startAnalysis = new Date()\n const atrules = []\n const rules = []\n const selectors = []\n const declarations = []\n const properties = []\n const values = []\n const zindex = []\n const textShadows = []\n const boxShadows = []\n const fontValues = []\n const fontFamilyValues = []\n const fontSizeValues = []\n const animations = []\n const timingFunctions = []\n const durations = []\n const colors = new ContextCollection()\n const units = new ContextCollection()\n\n csstree.walk(ast, {\n enter: function (node) {\n switch (node.type) {\n case 'Atrule': {\n atrules.push(node)\n break\n }\n case 'Rule': {\n rules.push(node)\n break\n }\n case 'Selector': {\n selectors.push({\n ...node,\n isKeyframeSelector: this.atrule && this.atrule.name.endsWith('keyframes')\n })\n\n // Avoid further walking of selectors to not mess with\n // our specificity calculations in case of a selector\n // with :where() or :is() that contain SelectorLists\n // as children\n return this.skip\n }\n case 'Dimension': {\n if (!this.declaration) {\n break\n }\n\n units.push(node.unit, this.declaration.property)\n\n return this.skip\n }\n case 'Declaration': {\n declarations.push({\n ...node,\n inKeyframe: this.atrule && this.atrule.name.endsWith('keyframes')\n })\n\n const { value, property } = node\n const fullProperty = {\n authored: property,\n ...csstree.property(property)\n }\n\n properties.push(fullProperty)\n values.push(value)\n\n switch (fullProperty.basename) {\n case 'z-index': {\n zindex.push(value)\n break\n }\n case 'text-shadow': {\n textShadows.push(value)\n break\n }\n case 'box-shadow': {\n boxShadows.push(value)\n break\n }\n case 'font': {\n fontValues.push(value)\n break\n }\n case 'font-family': {\n fontFamilyValues.push(stringifyNode(value))\n // Prevent analyzer to find color names in this property\n return this.skip\n }\n case 'font-size': {\n fontSizeValues.push(stringifyNode(value))\n break\n }\n case 'transition':\n case 'animation': {\n animations.push(node)\n break\n }\n case 'animation-duration':\n case 'transition-duration': {\n durations.push(value)\n break\n }\n case 'transition-timing-function':\n case 'animation-timing-function': {\n timingFunctions.push(value)\n break\n }\n }\n\n csstree.walk(node.value, {\n enter: function (valueNode) {\n switch (valueNode.type) {\n case 'Hash': {\n colors.push(stringifyNode(valueNode), property)\n\n return this.skip\n }\n case 'Identifier': {\n const { name } = valueNode\n // Bail out if it can't be a color name\n // 20 === 'lightgoldenrodyellow'.length\n // 3 === 'red'.length\n if (name.length > 20 || name.length < 3) {\n return this.skip\n }\n if (colorNames[name.toLowerCase()]) {\n colors.push(stringifyNode(valueNode), property)\n }\n return this.skip\n }\n case 'Function': {\n if (colorFunctions[valueNode.name.toLowerCase()]) {\n colors.push(stringifyNode(valueNode), property)\n }\n // No this.skip here intentionally,\n // otherwise we'll miss colors in linear-gradient() etc.\n }\n }\n }\n })\n }\n }\n }\n })\n\n return {\n stylesheet: {\n sourceLinesOfCode: atrules.length + selectors.length + declarations.length,\n linesOfCode: lines.length,\n size: css.length,\n comments: {\n total: totalComments,\n size: commentsSize,\n },\n },\n atrules: analyzeAtRules({ atrules, stringifyNode }),\n rules: analyzeRules({ rules }),\n selectors: analyzeSelectors({ stringifyNode, selectors }),\n declarations: analyzeDeclarations({ stringifyNode, declarations }),\n properties: analyzeProperties({ properties }),\n values: {\n colors: analyzeColors({ colors }),\n fontFamilies: analyzeFontFamilies({ stringifyNode, fontValues, fontFamilyValues }),\n fontSizes: analyzeFontSizes({ stringifyNode, fontValues, fontSizeValues }),\n zindexes: analyzeValues({ values: zindex, stringifyNode }),\n textShadows: analyzeValues({ values: textShadows, stringifyNode }),\n boxShadows: analyzeValues({ values: boxShadows, stringifyNode }),\n animations: analyzeAnimations({ animations, timingFunctions, durations, stringifyNode }),\n prefixes: analyzeVendorPrefixes({ values, stringifyNode }),\n units: units.count(),\n },\n __meta__: {\n parseTime: startAnalysis - startParse,\n analyzeTime: new Date() - startAnalysis,\n total: new Date() - start\n }\n }\n}\n\nexport { analyze, compareSpecificity }"],"names":["compareSpecificity","a","b","selectorListSpecificities","selectorListAst","childSelectors","csstree","walk","visit","enter","node","push","analyzeSpecificity","sort","specificity","ast","A","B","C","complexity","isA11y","selector","type","Boolean","value","name","startsWith","includes","skip","rawSelectorList","find","selectorList","parse","context","i","length","isId","AggregateCollection","size","this","items","Uint8Array","sum","cursor","add","item","aggregate","min","max","mean","mode","median","range","arr","middle","lowerMiddleRank","sorted","slice","frequencies","Object","create","maxOccurrences","maxOccurenceCount","element","updatedCount","Mode","Math","floor","toArray","Array","from","subarray","analyzeRules","rules","totalRules","selectorsPerRule","declarationsPerRule","emptyRules","selectors","declarations","childNode","total","empty","ratio","colorNames","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkgrey","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","green","greenyellow","grey","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightgrey","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen","canvas","canvastext","linktext","visitedtext","activetext","buttonface","buttontext","buttonborder","field","fieldtext","highlight","highlighttext","selecteditem","selecteditemtext","mark","marktext","graytext","colorFunctions","rgb","rgba","hsl","hsla","hwb","lab","lch","oklab","oklch","color","CountableCollection","initial","totalUnique","index","count","unique","uniquenessRatio","systemKeywords","inherit","unset","revert","caption","icon","menu","keywordDisallowList","normal","small","medium","large","larger","smaller","bold","bolder","lighter","condensed","expanded","italic","oblique","analyzeFontFamilies","fontValues","all","fontFamilyValues","firstChild","children","first","parts","reverse","fontNode","charCodeAt","unshift","map","generate","join","sizeKeywords","keywords","analyzeFontSizes","stringifyNode","fontSizeValues","operator","analyzeDeclarations","cache","importants","totalInKeyframes","declaration","important","inKeyframe","stringified","inKeyframes","analyzeSelectors","maxSpecificity","minSpecificity","counts","totalSelectors","specificityA","specificityB","specificityC","complexityAggregator","specificities","complexities","ids","a11y","keyframes","isKeyframeSelector","undefined","aggregatesA","aggregatesB","aggregatesC","complexityCount","id","accessibility","analyzeProperties","properties","p","authored","prefixed","hacks","customs","totalProperties","property","vendor","hack","custom","browserhacks","auto","none","analyzeValues","values","timingKeywords","linear","ease","analyzeAnimations","animations","timingFunctions","allDurations","durations","allTimingFunctions","durationFound","forEach","child","hasVendorPrefix","keyword","indexOf","isAstVendorPrefixed","analyzeVendorPrefixes","analyzeAtRules","atrules","fontfaces","imports","medias","charsets","supports","prefixedKeyframes","containers","machine","descriptors","block","descriptor","media","prelude","import","charset","container","nodeName","action","endsWith","fontface","ContextCollection","list","contexts","contextCount","itemsPerContext","assign","css","start","Date","lines","split","loc","end","line","substring","column","startParse","totalComments","commentsSize","parseAtrulePrelude","parseCustomProperty","positions","onComment","comment","startAnalysis","zindex","textShadows","boxShadows","colors","units","atrule","unit","fullProperty","basename","valueNode","toLowerCase","stylesheet","sourceLinesOfCode","linesOfCode","comments","fontFamilies","fontSizes","zindexes","prefixes","__meta__","parseTime","analyzeTime"],"mappings":"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"}
|