@projectwallace/css-analyzer 5.5.0 → 5.6.0
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/dist/index.d.ts +47 -12
- package/package.json +4 -4
- package/readme.md +4 -0
package/dist/analyzer.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e=require("css-tree/parser"),t=require("css-tree/walker");function r(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var n=/*#__PURE__*/r(e),i=/*#__PURE__*/r(t);function a(e,t){return t>=65&&t<=90&&(t|=32),e===t}function o(e,t){var r=t.length-e.length;if(r<0)return!1;for(var n=t.length-1;n>=r;n--)if(!1===a(e.charCodeAt(n-r),t.charCodeAt(n)))return!1;return!0}function s(e,t){if(t.length<e.length)return!1;for(var r=0;r<e.length;r++)if(!1===a(e.charCodeAt(r),t.charCodeAt(r)))return!1;return!0}function u(e,t){return e[0]===t[0]?e[1]===t[1]?t[2]-e[2]:t[1]-e[1]:t[0]-e[0]}var l=function(e){var t=0,r=0,n=0,a=0,o=!1;return i.default(e,function(e){switch(e.type){case"IdSelector":t++,a++;break;case"ClassSelector":r++,a++;break;case"AttributeSelector":r++,a++,Boolean(e.value)&&a++,o="role"===e.name.name||s("aria-",e.name.name);break;case"PseudoElementSelector":case"TypeSelector":if(a++,42===e.name.charCodeAt(0)&&1===e.name.length)break;n++;break;case"PseudoClassSelector":switch(e.name){case"before":case"after":case"first-letter":case"first-line":return n++,a++,this.skip;case"where":case"is":case"has":case"matches":case"-webkit-any":case"-moz-any":case"not":case"nth-child":case"nth-last-child":"nth-child"!==e.name&&"nth-last-child"!==e.name||r++;var c=(m=[],i.default(e,{visit:"Selector",enter:function(e){m.push(l(e))}}),m.sort(function(e,t){return u(e.specificity,t.specificity)}));if(0===c.length)return;if("where"!==e.name){var f=c[0].specificity;t+=f[0],r+=f[1],n+=f[2]}for(var d=0;d<c.length;d++){var h=c[d];h.isA11y&&(o=!0),a+=h.complexity}return a++,this.skip;default:return a++,r++,this.skip}case"Combinator":a++}var m}),{specificity:[t,r,n],complexity:a,isId:t>0,isA11y:o}},c={aliceblue:1,antiquewhite:1,aqua:1,aquamarine:1,azure:1,beige:1,bisque:1,black:1,blanchedalmond:1,blue:1,blueviolet:1,brown:1,burlywood:1,cadetblue:1,chartreuse:1,chocolate:1,coral:1,cornflowerblue:1,cornsilk:1,crimson:1,cyan:1,darkblue:1,darkcyan:1,darkgoldenrod:1,darkgray:1,darkgreen:1,darkgrey:1,darkkhaki:1,darkmagenta:1,darkolivegreen:1,darkorange:1,darkorchid:1,darkred:1,darksalmon:1,darkseagreen:1,darkslateblue:1,darkslategray:1,darkslategrey:1,darkturquoise:1,darkviolet:1,deeppink:1,deepskyblue:1,dimgray:1,dimgrey:1,dodgerblue:1,firebrick:1,floralwhite:1,forestgreen:1,fuchsia:1,gainsboro:1,ghostwhite:1,gold:1,goldenrod:1,gray:1,green:1,greenyellow:1,grey:1,honeydew:1,hotpink:1,indianred:1,indigo:1,ivory:1,khaki:1,lavender:1,lavenderblush:1,lawngreen:1,lemonchiffon:1,lightblue:1,lightcoral:1,lightcyan:1,lightgoldenrodyellow:1,lightgray:1,lightgreen:1,lightgrey:1,lightpink:1,lightsalmon:1,lightseagreen:1,lightskyblue:1,lightslategray:1,lightslategrey:1,lightsteelblue:1,lightyellow:1,lime:1,limegreen:1,linen:1,magenta:1,maroon:1,mediumaquamarine:1,mediumblue:1,mediumorchid:1,mediumpurple:1,mediumseagreen:1,mediumslateblue:1,mediumspringgreen:1,mediumturquoise:1,mediumvioletred:1,midnightblue:1,mintcream:1,mistyrose:1,moccasin:1,navajowhite:1,navy:1,oldlace:1,olive:1,olivedrab:1,orange:1,orangered:1,orchid:1,palegoldenrod:1,palegreen:1,paleturquoise:1,palevioletred:1,papayawhip:1,peachpuff:1,peru:1,pink:1,plum:1,powderblue:1,purple:1,rebeccapurple:1,red:1,rosybrown:1,royalblue:1,saddlebrown:1,salmon:1,sandybrown:1,seagreen:1,seashell:1,sienna:1,silver:1,skyblue:1,slateblue:1,slategray:1,slategrey:1,snow:1,springgreen:1,steelblue:1,tan:1,teal:1,thistle:1,tomato:1,turquoise:1,violet:1,wheat:1,white:1,whitesmoke:1,yellow:1,yellowgreen:1,canvas:1,canvastext:1,linktext:1,visitedtext:1,activetext:1,buttonface:1,buttontext:1,buttonborder:1,field:1,fieldtext:1,highlight:1,highlighttext:1,selecteditem:1,selecteditemtext:1,mark:1,marktext:1,graytext:1},f={rgb:1,rgba:1,hsl:1,hsla:1,hwb:1,lab:1,lch:1,oklab:1,oklch:1,color:1},d={inherit:1,initial:1,unset:1,revert:1,caption:1,icon:1,menu:1,"message-box":1,"small-caption":1,"status-bar":1},h={normal:1,"xx-small":1,"x-small":1,small:1,medium:1,large:1,"x-large":1,"xx-large":1,larger:1,smaller:1,bold:1,bolder:1,lighter:1,"ultra-condensed":1,"extra-condensed":1,condensed:1,"semi-condensed":1,"semi-expanded":1,expanded:1,"extra-expanded":1,"ultra-expanded":1,italic:1,oblique:1};function m(e){var t=e.children.first;return"Identifier"===t.type&&d[t.name]}var b={"xx-small":1,"x-small":1,small:1,medium:1,large:1,"x-large":1,"xx-large":1,larger:1,smaller:1},v={inherit:1,initial:1,unset:1,revert:1,caption:1,icon:1,menu:1,"message-box":1,"small-caption":1,"status-bar":1};function g(e){var t=e.children.first;return"Identifier"===t.type&&v[t.name]}var w={auto:1,inherit:1,initial:1,unset:1,revert:1,none:1};function k(e){if(!e.children)return!1;var t=e.children.first;return!!t&&!(e.children.size>1)&&"Identifier"===t.type&&w[t.name]}var p={linear:1,ease:1,"ease-in":1,"ease-out":1,"ease-in-out":1,"step-start":1,"step-end":1};function y(e){return 45===e.charCodeAt(0)&&45!==e.charCodeAt(1)&&-1!==e.indexOf("-",2)}function x(e){if(!e.children)return!1;for(var t=e.children.toArray(),r=0;r<t.length;r++){var n=t[r],i=n.type,a=n.name;if("Identifier"===i&&y(a))return!0;if("Function"===i){if(y(a))return!0;if(x(n))return!0}}return!1}var q=/*#__PURE__*/function(){function e(e){if(this.t={},this.i=0,this.o=0,e)for(var t=0;t<e.length;t++)this.push(e[t])}var t=e.prototype;return t.push=function(e){this.i++,this.t[e]?this.t[e]++:(this.t[e]=1,this.o++)},t.size=function(){return this.i},t.count=function(){return{total:this.i,totalUnique:this.o,unique:this.t,uniquenessRatio:0===this.i?0:this.o/this.i}},e}(),z=/*#__PURE__*/function(){function e(){this.u=new q,this.l={}}var t=e.prototype;return t.push=function(e,t){this.u.push(e),this.l[t]||(this.l[t]=new q),this.l[t].push(e)},t.count=function(){var e={};for(var t in this.l)e[t]=this.l[t].count();return Object.assign(this.u.count(),{itemsPerContext:e})},e}(),S=/*#__PURE__*/function(){function e(){this.t=[]}var t=e.prototype;return t.add=function(e){this.t.push(e)},t.size=function(){return this.t.length},t.aggregate=function(){if(0===this.t.length)return{min:0,max:0,mean:0,mode:0,median:0,range:0,sum:0};var e,t,r,n=this.t.slice().sort(function(e,t){return e-t}),i=n[0],a=n[n.length-1],o=this.t.reduce(function(e,t){return e+t}),s=function(e){for(var t=Object.create(null),r=-1,n=0,i=0,a=0;a<e.length;a++){var o=e[a],s=(t[o]||0)+1;t[o]=s,s>r&&(r=s,n=0,i=0),s>=r&&(n++,i+=o)}return i/n}(this.t),u=(t=(e=n).length/2)!==(r=Math.floor(t))?e[r]:(e[r]+e[r-1])/2;return{min:i,max:a,mean:o/this.t.length,mode:s,median:u,range:a-i,sum:o}},t.toArray=function(){return this.t},e}();function O(e){return!(e.length<3)&&45===e.charCodeAt(0)&&45===e.charCodeAt(1)}function I(e,t){return!O(t)&&o(e,t)}var C=/*#__PURE__*/function(){function e(){this.t=Object.create(null)}var t=e.prototype;return t.push=function(e){return this.t[e]?this.t[e]++:this.t[e]=1},t.count=function(){return Object.keys(this.t).length},e}();exports.analyze=function(e){var t=new Date,r=e.split(/\r?\n/);function d(e){var t=e.loc.start,n=e.loc.end;if(0==n.line-t.line)return r[t.line-1].substring(t.column-1,n.column-1);for(var i="",a=t.line;a<=n.line;a++){var o=r[a-1];i+=a!==t.line?a!==n.line?o+"\n":o.substring(0,n.column-1):o.substring(t.column-1)+"\n"}return i}var v,w,D=0,j=0,R=new q,U=new Date,F=n.default(e,{parseAtrulePrelude:!1,parseCustomProperty:!0,positions:!0,onComment:function(e){D++,j+=e.length}}),P=new Date,A=0,_=[],T=new q,B=new q,E=new q,H=new q,K=new q,L=new q,M=new q,N=new q,V=0,G=0,J=new S,Q=new S,W=new S,X=new q,Y=new C,Z=new S,$=new S,ee=new S,te=new q,re=new S,ne=[],ie=new q,ae=new q,oe=new C,se=0,ue=0,le=0,ce=new q,fe=new q,de=new q,he=new q,me=new q,be=new q,ve=new q,ge=new q,we=new q,ke=new q,pe=new q,ye=new q,xe=new z,qe=new z;i.default(F,function(e){switch(e.type){case"Atrule":A++;var t=e.name;if("font-face"===t){var r={};e.block.children.forEach(function(e){return r[e.property]=d(e.value)}),_.push(r);break}if("media"===t){E.push(e.prelude.value);break}if("supports"===t){K.push(e.prelude.value);break}if(o("keyframes",t)){var n="@"+t+" "+e.prelude.value;y(t)&&M.push(n),L.push(n);break}if("import"===t){B.push(e.prelude.value);break}if("charset"===t){H.push(e.prelude.value);break}if("container"===t){N.push(e.prelude.value);break}"layer"===t&&N.push(e.prelude.value.trim().split(",").map(function(e){return e.trim()}).forEach(function(e){return T.push(e)}));break;case"Rule":var q=e.prelude.children?e.prelude.children.size:0,z=e.block.children?e.block.children.size:0;J.add(q+z),Q.add(q),W.add(z),V++,0===z&&G++;break;case"Selector":var S=d(e);if(this.atrule&&o("keyframes",this.atrule.name))return X.push(S),this.skip;var C=l(e),D=C.specificity,j=C.complexity,U=C.isA11y;return C.isId&&ie.push(S),U&&ae.push(S),Y.push(S),re.add(j),te.push(D),void 0===v&&(v=D),void 0===w&&(w=D),Z.add(D[0]),$.add(D[1]),ee.add(D[2]),void 0!==w&&u(w,D)<0&&(w=D),void 0!==v&&u(v,D)>0&&(v=D),ne.push(D),this.skip;case"Dimension":if(!this.declaration)break;return qe.push(e.unit,this.declaration.property),this.skip;case"Url":s("data:",e.value)&&R.push(e.value);break;case"Value":if(k(e))break;var F=this.declaration.property;if(x(e)&&me.push(d(e)),I("z-index",F))return k(e)||be.push(d(e)),this.skip;if(I("font",F)){if(m(e)||we.push(function(e,t){var r="";return i.default(e,{reverse:!0,enter:function(e){if("String"===e.type){var n=e.loc.start,i=t({loc:{start:{line:n.line,column:n.column},end:{line:n.line,column:n.column+1}}});return r=i+e.value+i+r}return"Operator"===e.type&&44===e.value.charCodeAt(0)?r=e.value+r:"Identifier"===e.type?h[e.name]?this.skip:r=e.name+r:void 0}}),r}(e,d)),!g(e)){var P=function(e){var t,r=!1;return i.default(e,function(e){switch(e.type){case"Number":if(48===e.value.charCodeAt(0))return t="0",this.break;case"Operator":47===e.value.charCodeAt(0)&&(r=!0);break;case"Dimension":if(!r)return t=e.value+e.unit,this.break;case"Identifier":if(b[e.name])return t=e.name,this.break}}),t}(e);P&&ke.push(P)}break}if(I("font-size",F)){g(e)||ke.push(d(e));break}if(I("font-family",F)){m(e)||we.push(d(e));break}if(I("transition",F)||I("animation",F)){for(var ze=function(e,t){var r=!1,n=[],i=[];return e.forEach(function(e){return"Operator"===e.type?r=!1:"Dimension"===e.type&&!1===r?(r=!0,n.push(t(e))):"Identifier"===e.type&&p[e.name]?i.push(t(e)):"Function"!==e.type||"cubic-bezier"!==e.name&&"steps"!==e.name?void 0:i.push(t(e))}),[n,i]}(e.children,d),Se=ze[0],Oe=ze[1],Ie=0;Ie<Se.length;Ie++)ye.push(Se[Ie]);for(var Ce=0;Ce<Oe.length;Ce++)pe.push(Oe[Ce]);break}if(I("animation-duration",F)||I("transition-duration",F)){ye.push(d(e));break}if(I("transition-timing-function",F)||I("animation-timing-function",F)){pe.push(d(e));break}I("text-shadow",F)?k(e)||ve.push(d(e)):I("box-shadow",F)&&(k(e)||ge.push(d(e))),i.default(e,function(e){switch(e.type){case"Hash":return xe.push("#"+e.value,F),this.skip;case"Identifier":var t=e.name;return t.length>20||t.length<3||c[t.toLowerCase()]&&xe.push(d(e),F),this.skip;case"Function":if(function(e,t){if(e.length!==t.length)return!1;for(var r=0;r<e.length;r++)if(!1===a(e.charCodeAt(r),t.charCodeAt(r)))return!1;return!0}("var",e.name))return this.skip;f[e.name.toLowerCase()]&&xe.push(d(e),F)}});break;case"Declaration":se++;var De=d(e);oe.push(De),e.important&&(ue++,this.atrule&&o("keyframes",this.atrule.name)&&le++);var je=e.property;ce.push(je),y(je)?de.push(je):function(e){if(O(e)||y(e))return!1;var t=e.charCodeAt(0);return 47===t||95===t||43===t||42===t||38===t||36===t||35===t}(je)?fe.push(je):O(je)&&he.push(je)}});var ze=R.count(),Se=Object.keys(ze.unique).join("").length,Oe=oe.count(),Ie=re.size(),Ce=Z.aggregate(),De=$.aggregate(),je=ee.aggregate(),Re=te.count(),Ue=new q(re.toArray()).count(),Fe=Y.count(),Pe=new q(J.toArray()).count(),Ae=new q(Q.toArray()).count(),_e=new q(W.toArray()).count(),Te=Object.assign;return{stylesheet:{sourceLinesOfCode:A+Ie+se+X.size(),linesOfCode:r.length,size:e.length,comments:{total:D,size:j},embeddedContent:Te(ze,{size:{total:Se,ratio:0===e.length?0:Se/e.length}})},atrules:{fontface:{total:_.length,totalUnique:_.length,unique:_,uniquenessRatio:0===_.length?0:1},import:B.count(),media:E.count(),charset:H.count(),supports:K.count(),keyframes:Te(L.count(),{prefixed:Te(M.count(),{ratio:0===L.size()?0:M.size()/L.size()})}),container:N.count(),layer:T.count()},rules:{total:V,empty:{total:G,ratio:0===V?0:G/V},sizes:Te(J.aggregate(),{items:J.toArray(),unique:Pe.unique,totalUnique:Pe.totalUnique,uniquenessRatio:Pe.uniquenessRatio}),selectors:Te(Q.aggregate(),{items:Q.toArray(),unique:Ae.unique,totalUnique:Ae.totalUnique,uniquenessRatio:Ae.uniquenessRatio}),declarations:Te(W.aggregate(),{items:W.toArray(),unique:_e.unique,totalUnique:_e.totalUnique,uniquenessRatio:_e.uniquenessRatio})},selectors:{total:Ie,totalUnique:Fe,uniquenessRatio:0===Ie?0:Fe/Ie,specificity:{min:void 0===w?[0,0,0]:w,max:void 0===v?[0,0,0]:v,sum:[Ce.sum,De.sum,je.sum],mean:[Ce.mean,De.mean,je.mean],mode:[Ce.mode,De.mode,je.mode],median:[Ce.median,De.median,je.median],items:ne,unique:Re.unique,totalUnique:Re.totalUnique,uniquenessRatio:Re.uniquenessRatio},complexity:Te(re.aggregate(),Ue,{items:re.toArray()}),id:Te(ie.count(),{ratio:0===Ie?0:ie.size()/Ie}),accessibility:Te(ae.count(),{ratio:0===Ie?0:ae.size()/Ie}),keyframes:X.count()},declarations:{total:se,unique:{total:Oe,ratio:0===se?0:Oe/se},importants:{total:ue,ratio:0===se?0:ue/se,inKeyframes:{total:le,ratio:0===ue?0:le/ue}}},properties:Te(ce.count(),{prefixed:Te(de.count(),{ratio:0===ce.size()?0:de.size()/ce.size()}),custom:Te(he.count(),{ratio:0===ce.size()?0:he.size()/ce.size()}),browserhacks:Te(fe.count(),{ratio:0===ce.size()?0:fe.size()/ce.size()})}),values:{colors:xe.count(),fontFamilies:we.count(),fontSizes:ke.count(),zindexes:be.count(),textShadows:ve.count(),boxShadows:ge.count(),animations:{durations:ye.count(),timingFunctions:pe.count()},prefixes:me.count(),units:qe.count()},__meta__:{parseTime:P-U,analyzeTime:new Date-P,total:new Date-t}}},exports.compareSpecificity=u;
|
|
1
|
+
var e=require("css-tree/parser"),t=require("css-tree/walker");function r(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var n=/*#__PURE__*/r(e),i=/*#__PURE__*/r(t);function a(e,t){return t>=65&&t<=90&&(t|=32),e===t}function o(e,t){if(e.length!==t.length)return!1;for(var r=0;r<e.length;r++)if(!1===a(e.charCodeAt(r),t.charCodeAt(r)))return!1;return!0}function s(e,t){var r=t.length-e.length;if(r<0)return!1;for(var n=t.length-1;n>=r;n--)if(!1===a(e.charCodeAt(n-r),t.charCodeAt(n)))return!1;return!0}function u(e,t){if(t.length<e.length)return!1;for(var r=0;r<e.length;r++)if(!1===a(e.charCodeAt(r),t.charCodeAt(r)))return!1;return!0}function l(e,t,r){return o(t,e.property)&&"Identifier"===e.value.children.first.type&&o(r,e.value.children.first.name)}function c(e){return 45===e.charCodeAt(0)&&45!==e.charCodeAt(1)&&-1!==e.indexOf("-",2)}function f(e,t){return e[0]===t[0]?e[1]===t[1]?t[2]-e[2]:t[1]-e[1]:t[0]-e[0]}var d=function(e){var t=0,r=0,n=0,a=0,s=!1;return i.default(e,function(e){switch(e.type){case"IdSelector":t++,a++;break;case"ClassSelector":r++,a++;break;case"AttributeSelector":r++,a++,Boolean(e.value)&&a++,(o("role",e.name.name)||u("aria-",e.name.name))&&(s=!0);break;case"PseudoElementSelector":case"TypeSelector":if(a++,c(e.name)&&a++,42===e.name.charCodeAt(0)&&1===e.name.length)break;n++;break;case"PseudoClassSelector":switch(e.name){case"before":case"after":case"first-letter":case"first-line":return n++,a++,this.skip;case"where":case"is":case"has":case"matches":case"-webkit-any":case"-moz-any":case"not":case"nth-child":case"nth-last-child":c(e.name)&&a++,"nth-child"!==e.name&&"nth-last-child"!==e.name||r++;var l=(v=[],i.default(e,{visit:"Selector",enter:function(e){v.push(d(e))}}),v.sort(function(e,t){return f([e[0],e[1],e[2]],[t[0],t[1],t[2]])}));if(0===l.length)return;if("where"!==e.name){var h=l[0];t+=h[0],r+=h[1],n+=h[2]}for(var m=0;m<l.length;m++){var b=l[m];1===b[4]&&(s=!0),a+=b[3]}return a++,this.skip;default:return a++,r++,this.skip}case"Combinator":a++}var v}),[t,r,n,a,s?1:0]},h={aliceblue:1,antiquewhite:1,aqua:1,aquamarine:1,azure:1,beige:1,bisque:1,black:1,blanchedalmond:1,blue:1,blueviolet:1,brown:1,burlywood:1,cadetblue:1,chartreuse:1,chocolate:1,coral:1,cornflowerblue:1,cornsilk:1,crimson:1,cyan:1,darkblue:1,darkcyan:1,darkgoldenrod:1,darkgray:1,darkgreen:1,darkgrey:1,darkkhaki:1,darkmagenta:1,darkolivegreen:1,darkorange:1,darkorchid:1,darkred:1,darksalmon:1,darkseagreen:1,darkslateblue:1,darkslategray:1,darkslategrey:1,darkturquoise:1,darkviolet:1,deeppink:1,deepskyblue:1,dimgray:1,dimgrey:1,dodgerblue:1,firebrick:1,floralwhite:1,forestgreen:1,fuchsia:1,gainsboro:1,ghostwhite:1,gold:1,goldenrod:1,gray:1,green:1,greenyellow:1,grey:1,honeydew:1,hotpink:1,indianred:1,indigo:1,ivory:1,khaki:1,lavender:1,lavenderblush:1,lawngreen:1,lemonchiffon:1,lightblue:1,lightcoral:1,lightcyan:1,lightgoldenrodyellow:1,lightgray:1,lightgreen:1,lightgrey:1,lightpink:1,lightsalmon:1,lightseagreen:1,lightskyblue:1,lightslategray:1,lightslategrey:1,lightsteelblue:1,lightyellow:1,lime:1,limegreen:1,linen:1,magenta:1,maroon:1,mediumaquamarine:1,mediumblue:1,mediumorchid:1,mediumpurple:1,mediumseagreen:1,mediumslateblue:1,mediumspringgreen:1,mediumturquoise:1,mediumvioletred:1,midnightblue:1,mintcream:1,mistyrose:1,moccasin:1,navajowhite:1,navy:1,oldlace:1,olive:1,olivedrab:1,orange:1,orangered:1,orchid:1,palegoldenrod:1,palegreen:1,paleturquoise:1,palevioletred:1,papayawhip:1,peachpuff:1,peru:1,pink:1,plum:1,powderblue:1,purple:1,rebeccapurple:1,red:1,rosybrown:1,royalblue:1,saddlebrown:1,salmon:1,sandybrown:1,seagreen:1,seashell:1,sienna:1,silver:1,skyblue:1,slateblue:1,slategray:1,slategrey:1,snow:1,springgreen:1,steelblue:1,tan:1,teal:1,thistle:1,tomato:1,turquoise:1,violet:1,wheat:1,white:1,whitesmoke:1,yellow:1,yellowgreen:1,canvas:1,canvastext:1,linktext:1,visitedtext:1,activetext:1,buttonface:1,buttontext:1,buttonborder:1,field:1,fieldtext:1,highlight:1,highlighttext:1,selecteditem:1,selecteditemtext:1,mark:1,marktext:1,graytext:1},m={rgb:1,rgba:1,hsl:1,hsla:1,hwb:1,lab:1,lch:1,oklab:1,oklch:1,color:1},b={inherit:1,initial:1,unset:1,revert:1,caption:1,icon:1,menu:1,"message-box":1,"small-caption":1,"status-bar":1},v={normal:1,"xx-small":1,"x-small":1,small:1,medium:1,large:1,"x-large":1,"xx-large":1,larger:1,smaller:1,bold:1,bolder:1,lighter:1,"ultra-condensed":1,"extra-condensed":1,condensed:1,"semi-condensed":1,"semi-expanded":1,expanded:1,"extra-expanded":1,"ultra-expanded":1,italic:1,oblique:1};function g(e){var t=e.children.first;return"Identifier"===t.type&&b[t.name]}var w={"xx-small":1,"x-small":1,small:1,medium:1,large:1,"x-large":1,"xx-large":1,larger:1,smaller:1},k={inherit:1,initial:1,unset:1,revert:1,caption:1,icon:1,menu:1,"message-box":1,"small-caption":1,"status-bar":1};function p(e){var t=e.children.first;return"Identifier"===t.type&&k[t.name]}var y={auto:1,inherit:1,initial:1,unset:1,revert:1,none:1};function x(e){if(!e.children)return!1;var t=e.children.first;return!!t&&!(e.children.size>1)&&"Identifier"===t.type&&y[t.name]}var q={linear:1,ease:1,"ease-in":1,"ease-out":1,"ease-in-out":1,"step-start":1,"step-end":1};function z(e){if(!e.children)return!1;for(var t=e.children.toArray(),r=0;r<t.length;r++){var n=t[r],i=n.type,a=n.name;if("Identifier"===i&&c(a))return!0;if("Function"===i){if(c(a))return!0;if(z(n))return!0}}return!1}var I=/*#__PURE__*/function(){function e(e){if(this.t={},this.i=0,this.o=0,e)for(var t=0;t<e.length;t++)this.push(e[t])}var t=e.prototype;return t.push=function(e){this.i++,this.t[e]?this.t[e]++:(this.t[e]=1,this.o++)},t.size=function(){return this.i},t.count=function(){return{total:this.i,totalUnique:this.o,unique:this.t,uniquenessRatio:0===this.i?0:this.o/this.i}},e}(),S=/*#__PURE__*/function(){function e(){this.u=new I,this.l={}}var t=e.prototype;return t.push=function(e,t){this.u.push(e),this.l[t]||(this.l[t]=new I),this.l[t].push(e)},t.count=function(){var e={};for(var t in this.l)e[t]=this.l[t].count();return Object.assign(this.u.count(),{itemsPerContext:e})},e}(),O=/*#__PURE__*/function(){function e(){this.t=[]}var t=e.prototype;return t.push=function(e){this.t.push(e)},t.size=function(){return this.t.length},t.aggregate=function(){if(0===this.t.length)return{min:0,max:0,mean:0,mode:0,median:0,range:0,sum:0};var e,t,r,n=this.t.slice().sort(function(e,t){return e-t}),i=n[0],a=n[n.length-1],o=this.t.reduce(function(e,t){return e+t}),s=function(e){for(var t=Object.create(null),r=-1,n=0,i=0,a=0;a<e.length;a++){var o=e[a],s=(t[o]||0)+1;t[o]=s,s>r&&(r=s,n=0,i=0),s>=r&&(n++,i+=o)}return i/n}(this.t),u=(t=(e=n).length/2)!==(r=Math.floor(t))?e[r]:(e[r]+e[r-1])/2;return{min:i,max:a,mean:o/this.t.length,mode:s,median:u,range:a-i,sum:o}},t.toArray=function(){return this.t},e}();function D(e){return!(e.length<3)&&45===e.charCodeAt(0)&&45===e.charCodeAt(1)}function C(e,t){return!D(t)&&s(e,t)}var R=/*#__PURE__*/function(){function e(){this.t=Object.create(null)}var t=e.prototype;return t.push=function(e){var t=function(e){for(var t=167,r=0;r<e.length;r++)t^=e.charCodeAt(r),t*=403;return t}(e);this.t[t]||(this.t[t]=1)},t.count=function(){return Object.keys(this.t).length},e}();function U(e,t){return 0===t?0:e/t}exports.analyze=function(e){var t=Date.now(),r=e.split(/\r?\n/);function a(e){var t=e.loc.start,n=e.loc.end;if(0==n.line-t.line)return r[t.line-1].substring(t.column-1,n.column-1);for(var i="",a=t.line;a<=n.line;a++){var o=r[a-1];i+=a!==t.line?a!==n.line?o+"\n":o.substring(0,n.column-1):o.substring(t.column-1)+"\n"}return i}var b,k,y=0,j=0,F=new I,P=Date.now(),_=n.default(e,{parseCustomProperty:!0,positions:!0,onComment:function(e){y++,j+=e.length}}),M=Date.now(),T=0,A=[],B=new I,E=new I,H=new I,K=new I,L=new I,N=new I,Q=new I,V=new I,G=new I,J=new I,W=0,X=0,Y=new O,Z=new O,$=new O,ee=new I,te=new R,re=new O,ne=new O,ie=new O,ae=new I,oe=new O,se=[],ue=new I,le=new I,ce=new R,fe=0,de=0,he=0,me=new I,be=new I,ve=new I,ge=new I,we=new O,ke=new I,pe=new I,ye=new I,xe=new I,qe=new I,ze=new I,Ie=new I,Se=new I,Oe=new I,De=new S,Ce=new S;i.default(_,function(e){switch(e.type){case"Atrule":T++;var t=e.name;if("font-face"===t){var r={};e.block.children.forEach(function(e){return r[e.property]=a(e.value)}),A.push(r);break}if("media"===t){var n=a(e.prelude);H.push(n),function(e){var t=!1;return i.default(e,function(e){if("MediaQuery"===e.type&&1===e.children.size&&"Identifier"===e.children.first.type&&(u("\\0",(e=e.children.first).name)||s("\\9 ",e.name)))return t=!0,this.break;if("MediaFeature"===e.type){if(null!==e.value&&"\\0"===e.value.unit)return t=!0,this.break;if(o("-moz-images-in-menus",e.name)||o("min--moz-device-pixel-ratio",e.name)||o("-ms-high-contrast",e.name))return t=!0,this.break;if(o("min-resolution",e.name)&&o(".001",e.value.value)&&o("dpcm",e.value.unit))return t=!0,this.break;if(o("-webkit-min-device-pixel-ratio",e.name)&&(o("0",e.value.value)||o("10000",e.value.value)))return t=!0,this.break}}),t}(e.prelude)&&K.push(n);break}if("supports"===t){var y=a(e.prelude);N.push(y),function(e){var t=!1;return i.default(e,function(e){if("Declaration"===e.type&&(l(e,"-webkit-appearance","none")||l(e,"-moz-appearance","meterbar")))return t=!0,this.break}),t}(e.prelude)&&Q.push(y);break}if(s("keyframes",t)){var I="@"+t+" "+a(e.prelude);c(t)&&G.push(I),V.push(I);break}if("import"===t){E.push(a(e.prelude));break}if("charset"===t){L.push(a(e.prelude));break}if("container"===t){J.push(a(e.prelude));break}"layer"===t&&a(e.prelude).trim().split(",").forEach(function(e){return B.push(e.trim())});break;case"Rule":var S=e.prelude.children?e.prelude.children.size:0,O=e.block.children?e.block.children.size:0;Y.push(S+O),Z.push(S),$.push(O),W++,0===O&&X++;break;case"Selector":var R=a(e);if(this.atrule&&s("keyframes",this.atrule.name))return ee.push(R),this.skip;var U=d(e),j=U.splice(0,3),P=U[0],_=U[1];return j[0]>0&&ue.push(R),1===_&&le.push(R),te.push(R),oe.push(P),ae.push(j),void 0===b&&(b=j),void 0===k&&(k=j),re.push(j[0]),ne.push(j[1]),ie.push(j[2]),void 0!==k&&f(k,j)<0&&(k=j),void 0!==b&&f(b,j)>0&&(b=j),se.push(j),this.skip;case"Dimension":if(!this.declaration)break;return Ce.push(e.unit,this.declaration.property),this.skip;case"Url":u("data:",e.value)&&F.push(e.value);break;case"Value":if(x(e))break;var M=this.declaration,Re=M.property,Ue=M.important;if(z(e)&&ke.push(a(e)),"string"==typeof Ue&&pe.push(a(e)+"!"+Ue),e.children&&e.children.last&&"Identifier"===e.children.last.type&&s("\\9",e.children.last.name)&&pe.push(a(e)),C("z-index",Re))return x(e)||ye.push(a(e)),this.skip;if(C("font",Re)){if(g(e)||ze.push(function(e,t){var r="";return i.default(e,{reverse:!0,enter:function(e){if("String"===e.type){var n=e.loc.start,i=t({loc:{start:{line:n.line,column:n.column},end:{line:n.line,column:n.column+1}}});return r=i+e.value+i+r}return"Operator"===e.type&&44===e.value.charCodeAt(0)?r=e.value+r:"Identifier"===e.type?v[e.name]?this.skip:r=e.name+r:void 0}}),r}(e,a)),!p(e)){var je=function(e){var t,r=!1;return i.default(e,function(e){switch(e.type){case"Number":if(48===e.value.charCodeAt(0))return t="0",this.break;case"Operator":47===e.value.charCodeAt(0)&&(r=!0);break;case"Dimension":if(!r)return t=e.value+e.unit,this.break;case"Identifier":if(w[e.name])return t=e.name,this.break}}),t}(e);je&&Ie.push(je)}break}if(C("font-size",Re)){p(e)||Ie.push(a(e));break}if(C("font-family",Re)){g(e)||ze.push(a(e));break}if(C("transition",Re)||C("animation",Re)){for(var Fe=function(e,t){var r=!1,n=[],i=[];return e.forEach(function(e){return"Operator"===e.type?r=!1:"Dimension"===e.type&&!1===r?(r=!0,n.push(t(e))):"Identifier"===e.type&&q[e.name]?i.push(t(e)):"Function"!==e.type||"cubic-bezier"!==e.name&&"steps"!==e.name?void 0:i.push(t(e))}),[n,i]}(e.children,a),Pe=Fe[0],_e=Fe[1],Me=0;Me<Pe.length;Me++)Oe.push(Pe[Me]);for(var Te=0;Te<_e.length;Te++)Se.push(_e[Te]);break}if(C("animation-duration",Re)||C("transition-duration",Re)){Oe.push(a(e));break}if(C("transition-timing-function",Re)||C("animation-timing-function",Re)){Se.push(a(e));break}C("text-shadow",Re)?x(e)||xe.push(a(e)):C("box-shadow",Re)&&(x(e)||qe.push(a(e))),i.default(e,function(e){switch(e.type){case"Hash":return De.push("#"+e.value,Re),this.skip;case"Identifier":var t=e.name;return t.length>20||t.length<3||h[t.toLowerCase()]&&De.push(a(e),Re),this.skip;case"Function":if(o("var",e.name))return this.skip;m[e.name.toLowerCase()]&&De.push(a(e),Re)}});break;case"Declaration":if(null!==this.atrulePrelude)return this.skip;fe++;var Ae=a(e);ce.push(Ae),!0===e.important&&(de++,this.atrule&&s("keyframes",this.atrule.name)&&he++);var Be=e.property;me.push(Be),c(Be)?(ve.push(Be),we.push(2)):function(e){if(D(e)||c(e))return!1;var t=e.charCodeAt(0);return 47===t||95===t||43===t||42===t||38===t||36===t||35===t}(Be)?(be.push(Be),we.push(2)):D(Be)?(ge.push(Be),we.push(2)):we.push(1)}});var Re=F.count(),Ue=Object.keys(Re.unique).join("").length,je=ce.count(),Fe=oe.size(),Pe=re.aggregate(),_e=ne.aggregate(),Me=ie.aggregate(),Te=ae.count(),Ae=new I(oe.toArray()).count(),Be=te.count(),Ee=new I(Y.toArray()).count(),He=new I(Z.toArray()).count(),Ke=new I($.toArray()).count(),Le=Object.assign;return{stylesheet:{sourceLinesOfCode:T+Fe+fe+ee.size(),linesOfCode:r.length,size:e.length,comments:{total:y,size:j},embeddedContent:Le(Re,{size:{total:Ue,ratio:U(Ue,e.length)}})},atrules:{fontface:{total:A.length,totalUnique:A.length,unique:A,uniquenessRatio:0===A.length?0:1},import:E.count(),media:Le(H.count(),{browserhacks:K.count()}),charset:L.count(),supports:Le(N.count(),{browserhacks:Q.count()}),keyframes:Le(V.count(),{prefixed:Le(G.count(),{ratio:U(G.size(),V.size())})}),container:J.count(),layer:B.count()},rules:{total:W,empty:{total:X,ratio:U(X,W)},sizes:Le(Y.aggregate(),{items:Y.toArray(),unique:Ee.unique,totalUnique:Ee.totalUnique,uniquenessRatio:Ee.uniquenessRatio}),selectors:Le(Z.aggregate(),{items:Z.toArray(),unique:He.unique,totalUnique:He.totalUnique,uniquenessRatio:He.uniquenessRatio}),declarations:Le($.aggregate(),{items:$.toArray(),unique:Ke.unique,totalUnique:Ke.totalUnique,uniquenessRatio:Ke.uniquenessRatio})},selectors:{total:Fe,totalUnique:Be,uniquenessRatio:U(Be,Fe),specificity:{min:void 0===k?[0,0,0]:k,max:void 0===b?[0,0,0]:b,sum:[Pe.sum,_e.sum,Me.sum],mean:[Pe.mean,_e.mean,Me.mean],mode:[Pe.mode,_e.mode,Me.mode],median:[Pe.median,_e.median,Me.median],items:se,unique:Te.unique,totalUnique:Te.totalUnique,uniquenessRatio:Te.uniquenessRatio},complexity:Le(oe.aggregate(),Ae,{items:oe.toArray()}),id:Le(ue.count(),{ratio:U(ue.size(),Fe)}),accessibility:Le(le.count(),{ratio:U(le.size(),Fe)}),keyframes:ee.count()},declarations:{total:fe,totalUnique:je,uniquenessRatio:U(je,fe),unique:{total:je,ratio:U(je,fe)},importants:{total:de,ratio:U(de,fe),inKeyframes:{total:he,ratio:U(he,de)}}},properties:Le(me.count(),{prefixed:Le(ve.count(),{ratio:U(ve.size(),me.size())}),custom:Le(ge.count(),{ratio:U(ge.size(),me.size())}),browserhacks:Le(be.count(),{ratio:U(be.size(),me.size())}),complexity:we.aggregate()}),values:{colors:De.count(),fontFamilies:ze.count(),fontSizes:Ie.count(),zindexes:ye.count(),textShadows:xe.count(),boxShadows:qe.count(),animations:{durations:Oe.count(),timingFunctions:Se.count()},prefixes:ke.count(),browserhacks:pe.count(),units:Ce.count()},__meta__:{parseTime:M-P,analyzeTime:Date.now()-M,total:Date.now()-t}}},exports.compareSpecificity=f;
|
|
2
2
|
//# sourceMappingURL=analyzer.cjs.map
|
package/dist/analyzer.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyzer.cjs","sources":["../src/string-utils.js","../src/selectors/specificity.js","../src/values/colors.js","../src/values/font-families.js","../src/values/font-sizes.js","../src/values/values.js","../src/values/animations.js","../src/vendor-prefix.js","../src/values/vendor-prefix.js","../src/countable-collection.js","../src/context-collection.js","../src/aggregate-collection.js","../src/properties/property-utils.js","../src/occurrence-counter.js","../src/index.js"],"sourcesContent":["/**\n * Case-insensitive compare two character codes\n * @param {string} charA\n * @param {string} charB\n * @see https://github.com/csstree/csstree/blob/41f276e8862d8223eeaa01a3d113ab70bb13d2d9/lib/tokenizer/utils.js#L22\n */\nfunction compareChar(referenceCode, testCode) {\n // if uppercase\n if (testCode >= 0x0041 && testCode <= 0x005A) {\n // shifting the 6th bit makes a letter lowercase\n testCode = testCode | 32\n }\n return referenceCode === testCode\n}\n\n/**\n * Case-insensitive string-comparison\n * @param {string} base\n * @param {string} test\n * @returns {boolean} true if the two strings are the same, false otherwise\n */\nexport function strEquals(base, test) {\n if (base.length !== test.length) return false\n\n for (let i = 0; i < base.length; i++) {\n if (compareChar(base.charCodeAt(i), test.charCodeAt(i)) === false) {\n return false\n }\n }\n\n return true\n}\n\n/**\n * Case-insensitive testing whether a string ends with a given substring\n * @param {string} base e.g. '-webkit-transform'\n * @param {string} cmp e.g. 'transform'\n * @returns {boolean} true if `test` ends with `base`, false otherwise\n */\nexport function endsWith(base, test) {\n const offset = test.length - base.length\n\n if (offset < 0) {\n return false\n }\n\n for (let i = test.length - 1; i >= offset; i--) {\n if (compareChar(base.charCodeAt(i - offset), test.charCodeAt(i)) === false) {\n return false\n }\n }\n\n return true\n}\n\n/**\n * Case-insensitive testing whether a string starts with a given substring\n * @param {string} base\n * @param {test} test\n * @returns {boolean} true if `test` starts with `base`, false otherwise\n */\nexport function startsWith(base, test) {\n if (test.length < base.length) return false\n\n for (let i = 0; i < base.length; i++) {\n if (compareChar(base.charCodeAt(i), test.charCodeAt(i)) === false) {\n return false\n }\n }\n\n return true\n}\n","import walk from 'css-tree/walker'\nimport { startsWith } from '../string-utils.js'\n\n/**\n * Compare specificity A to Specificity B\n * @param {[number,number,number]} a - Specificity A\n * @param {[number,number,number]} 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 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').Selector} ast - AST Node for a Selector\n * @return {Object}\n * @property {[number,number,number]} specificity\n * @property {number} complexity\n * @property {Boolean} isId\n * @property {Boolean} isA11y\n */\nconst analyzeSpecificity = (node) => {\n let A = 0\n let B = 0\n let C = 0\n let complexity = 0\n let isA11y = false\n\n walk(node, 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 // Add 1 for [attr=value] (or any variation using *= $= ^= |= )\n if (Boolean(selector.value)) {\n complexity++\n }\n\n isA11y = selector.name.name === 'role' || startsWith('aria-', selector.name.name)\n break\n }\n case 'PseudoElementSelector':\n case 'TypeSelector': {\n complexity++\n\n // 42 === '*'.charCodeAt(0)\n if (selector.name.charCodeAt(0) === 42 && selector.name.length === 1) {\n break\n }\n\n C++\n break\n }\n case 'PseudoClassSelector': {\n switch (selector.name) {\n case 'before':\n case 'after':\n case 'first-letter':\n case 'first-line': {\n C++\n complexity++\n return this.skip\n }\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 case 'where':\n case 'is':\n case 'has':\n case 'matches':\n case '-webkit-any':\n case '-moz-any':\n case 'not':\n case 'nth-child':\n case 'nth-last-child': {\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 (selector.name === 'nth-child' || selector.name === 'nth-last-child') {\n // +1 for the pseudo class itself\n B++\n }\n\n const selectorList = selectorListSpecificities(selector)\n\n // Bail out for empty/non-existent :nth-child() params\n if (selectorList.length === 0) return\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 [topA, topB, topC] = selectorList[0].specificity\n A += topA\n B += topB\n C += topC\n }\n\n for (let i = 0; i < selectorList.length; i++) {\n const listItem = selectorList[i]\n if (listItem.isA11y) {\n isA11y = true\n }\n complexity += listItem.complexity\n }\n\n complexity++\n return this.skip\n }\n\n default: {\n // Regular pseudo classes have specificity [0,1,0]\n complexity++\n B++\n return this.skip\n }\n }\n }\n case 'Combinator': {\n complexity++\n break\n }\n }\n })\n\n return {\n /** @type {[number,number,number]} */\n specificity: [A, B, C],\n complexity,\n isId: A > 0,\n isA11y\n }\n}\n\nexport {\n analyzeSpecificity,\n compareSpecificity,\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","import walk from 'css-tree/walker'\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\nexport function isFontFamilyKeyword(node) {\n const firstChild = node.children.first\n return firstChild.type === 'Identifier' && systemKeywords[firstChild.name]\n}\n\nexport function getFamilyFromFont(node, stringifyNode) {\n let parts = ''\n\n walk(node, {\n reverse: true,\n enter: function (fontNode) {\n if (fontNode.type === 'String') {\n const loc = fontNode.loc.start\n // Stringify the first character to get the correct quote character\n const quote = stringifyNode({\n loc: {\n start: {\n line: loc.line,\n column: loc.column\n },\n end: {\n line: loc.line,\n column: loc.column + 1\n }\n }\n })\n return parts = quote + fontNode.value + quote + parts\n }\n if (fontNode.type === 'Operator' && fontNode.value.charCodeAt(0) === COMMA) {\n return parts = fontNode.value + parts\n }\n if (fontNode.type === 'Identifier') {\n if (keywordDisallowList[fontNode.name]) {\n return this.skip\n }\n return parts = fontNode.name + parts\n }\n }\n })\n\n return parts\n}\n","import walk from 'css-tree/walker'\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\nexport function isFontSizeKeyword(node) {\n const firstChild = node.children.first\n return firstChild.type === 'Identifier' && keywords[firstChild.name]\n}\n\nexport function getSizeFromFont(node) {\n let operator = false\n let size\n\n walk(node, 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 = fontNode.value + fontNode.unit\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 return size\n}\n","const keywords = {\n 'auto': 1,\n 'inherit': 1,\n 'initial': 1,\n 'unset': 1,\n 'revert': 1,\n 'none': 1, // for `text-shadow`, `box-shadow` and `background`\n}\n\nexport function isValueKeyword(node) {\n if (!node.children) return false\n const firstChild = node.children.first\n\n if (!firstChild) return false\n if (node.children.size > 1) return false\n return firstChild.type === 'Identifier' && keywords[firstChild.name]\n}\n","const 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\nexport function analyzeAnimation(children, stringifyNode) {\n let durationFound = false\n const durations = []\n const timingFunctions = []\n\n 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 durations.push(stringifyNode(child))\n }\n if (child.type === 'Identifier' && timingKeywords[child.name]) {\n return timingFunctions.push(stringifyNode(child))\n }\n if (child.type === 'Function'\n && (\n child.name === 'cubic-bezier' || child.name === 'steps'\n )\n ) {\n return timingFunctions.push(stringifyNode(child))\n }\n })\n\n return [durations, timingFunctions]\n}\n","const HYPHENMINUS = 45; // '-'.charCodeAt()\n\n/**\n * @param {string} keyword\n * @returns {boolean}\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 { hasVendorPrefix } from '../vendor-prefix.js'\n\nexport function isAstVendorPrefixed(node) {\n if (!node.children) {\n return false\n }\n\n const children = node.children.toArray()\n\n for (let index = 0; index < children.length; index++) {\n const node = children[index]\n const { type, name } = node;\n\n if (type === 'Identifier' && hasVendorPrefix(name)) {\n return true\n }\n\n if (type === 'Function') {\n if (hasVendorPrefix(name)) {\n return true\n }\n\n if (isAstVendorPrefixed(node)) {\n return true\n }\n }\n }\n\n return false\n}\n","class CountableCollection {\n /**\n * @param {string[]} initial\n */\n constructor(initial) {\n /** @type [index: string]: string */\n this._items = {}\n /** @type number */\n this._total = 0\n /** @type number */\n this._totalUnique = 0\n\n if (initial) {\n for (let i = 0; i < initial.length; i++) {\n this.push(initial[i])\n }\n }\n }\n\n /**\n * Push an item to the end of this collection\n * @param {string} item\n * @returns {void}\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 /**\n * Get the size of this collection\n * @returns {number} the size of this collection\n */\n size() {\n return this._total\n }\n\n /**\n * Get the counts of this collection, like total, uniques, etc.\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 { CountableCollection } from './countable-collection.js'\n\nclass ContextCollection {\n constructor() {\n this._list = new CountableCollection()\n /** @type {[index; string]: CountableCollection} */\n this._contexts = {}\n }\n\n /**\n * Add an item to this _list's context\n * @param {string} item Item to push\n * @param {string} context Context to push Item to\n */\n push(item, context) {\n this._list.push(item)\n\n if (!this._contexts[context]) {\n this._contexts[context] = new CountableCollection()\n }\n\n this._contexts[context].push(item)\n }\n\n count() {\n /** @type {[index: string]: string} */\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}","/**\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() {\n /** @type number[] */\n this._items = []\n }\n\n /**\n * Add a new Integer at the end of this AggregateCollection\n * @param {number} item - The item to add\n */\n add(item) {\n this._items.push(item)\n }\n\n size() {\n return this._items.length\n }\n\n aggregate() {\n if (this._items.length === 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 // TODO: can we avoid this sort()? It's slow\n /** @type Number[] */\n const sorted = this._items.slice().sort((a, b) => a - b)\n const min = sorted[0]\n const max = sorted[sorted.length - 1]\n\n const sum = this._items.reduce((total, num) => (total += num))\n const mode = Mode(this._items)\n const median = Median(sorted)\n\n return {\n min,\n max,\n mean: sum / this._items.length,\n mode,\n median,\n range: max - min,\n sum,\n }\n }\n\n /**\n * @returns {number[]} All _items in this collection\n */\n toArray() {\n return this._items\n }\n}\n\nexport {\n AggregateCollection\n}","import { hasVendorPrefix } from '../vendor-prefix.js'\nimport { endsWith } from '../string-utils.js'\n\n/**\n * @param {string} property\n * @see https://github.com/csstree/csstree/blob/master/lib/utils/names.js#L69\n */\nexport function isHack(property) {\n if (isCustom(property) || hasVendorPrefix(property)) return false\n\n let code = property.charCodeAt(0)\n\n return code === 47 // /\n || code === 95 // _\n || code === 43 // +\n || code === 42 // *\n || code === 38 // &\n || code === 36 // $\n || code === 35 // #\n}\n\nexport function isCustom(property) {\n if (property.length < 3) return false\n // 45 === '-'.charCodeAt(0)\n return property.charCodeAt(0) === 45 && property.charCodeAt(1) === 45\n}\n\nexport function isProperty(basename, property) {\n if (isCustom(property)) return false\n return endsWith(basename, property)\n}","export class OccurrenceCounter {\n constructor() {\n this._items = Object.create(null)\n }\n\n push(item) {\n if (this._items[item]) {\n return this._items[item]++\n }\n\n return this._items[item] = 1\n }\n\n count() {\n return Object.keys(this._items).length\n }\n}\n","import parse from 'css-tree/parser'\nimport walk from 'css-tree/walker'\nimport { analyzeSpecificity, compareSpecificity } from './selectors/specificity.js'\nimport { colorFunctions, colorNames } from './values/colors.js'\nimport { isFontFamilyKeyword, getFamilyFromFont } from './values/font-families.js'\nimport { isFontSizeKeyword, getSizeFromFont } from './values/font-sizes.js'\nimport { isValueKeyword } from './values/values.js'\nimport { analyzeAnimation } from './values/animations.js'\nimport { isAstVendorPrefixed } from './values/vendor-prefix.js'\nimport { ContextCollection } from './context-collection.js'\nimport { CountableCollection } from './countable-collection.js'\nimport { AggregateCollection } from './aggregate-collection.js'\nimport { strEquals, startsWith, endsWith } from './string-utils.js'\nimport { hasVendorPrefix } from './vendor-prefix.js'\nimport { isCustom, isHack, isProperty } from './properties/property-utils.js'\nimport { OccurrenceCounter } from './occurrence-counter.js'\n\n/**\n * Analyze CSS\n * @param {string} css\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').CssNode} 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 let 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 += line.substring(start.column - 1) + '\\n'\n continue\n }\n // Last line\n if (i === end.line) {\n value += line.substring(0, end.column - 1)\n continue\n }\n // All lines in between first and last\n value += line + '\\n'\n }\n\n return value\n }\n\n // Stylesheet\n let totalComments = 0\n let commentsSize = 0\n const embeds = new CountableCollection()\n\n const startParse = new Date()\n\n const ast = 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\n // Atrules\n let totalAtRules = 0\n /** @type {{[index: string]: string}[]} */\n const fontfaces = []\n const layers = new CountableCollection()\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 // Rules\n let totalRules = 0\n let emptyRules = 0\n const ruleSizes = new AggregateCollection()\n const selectorsPerRule = new AggregateCollection()\n const declarationsPerRule = new AggregateCollection()\n\n // Selectors\n const keyframeSelectors = new CountableCollection()\n /** @type number */\n const uniqueSelectors = new OccurrenceCounter()\n /** @type [number,number,number] */\n let maxSpecificity\n /** @type [number,number,number] */\n let minSpecificity\n const specificityA = new AggregateCollection()\n const specificityB = new AggregateCollection()\n const specificityC = new AggregateCollection()\n const uniqueSpecificities = new CountableCollection()\n const selectorComplexities = new AggregateCollection()\n /** @type [number,number,number][] */\n const specificities = []\n const ids = new CountableCollection()\n const a11y = new CountableCollection()\n\n // Declarations\n const uniqueDeclarations = new OccurrenceCounter()\n let totalDeclarations = 0\n let importantDeclarations = 0\n let importantsInKeyframes = 0\n\n // Properties\n const properties = new CountableCollection()\n const propertyHacks = new CountableCollection()\n const propertyVendorPrefixes = new CountableCollection()\n const customProperties = new CountableCollection()\n\n // Values\n const vendorPrefixedValues = new CountableCollection()\n const zindex = new CountableCollection()\n const textShadows = new CountableCollection()\n const boxShadows = new CountableCollection()\n const fontFamilies = new CountableCollection()\n const fontSizes = new CountableCollection()\n const timingFunctions = new CountableCollection()\n const durations = new CountableCollection()\n const colors = new ContextCollection()\n const units = new ContextCollection()\n\n walk(ast, function (node) {\n switch (node.type) {\n case 'Atrule': {\n totalAtRules++\n const atRuleName = node.name\n\n if (atRuleName === 'font-face') {\n /** @type {[index: string]: string} */\n const descriptors = {}\n\n node.block.children.forEach(\n /** @param {import('css-tree').Declaration} descriptor */\n descriptor => (descriptors[descriptor.property] = stringifyNode(descriptor.value))\n )\n\n fontfaces.push(descriptors)\n break\n }\n if (atRuleName === 'media') {\n medias.push(node.prelude.value)\n break\n }\n if (atRuleName === 'supports') {\n supports.push(node.prelude.value)\n break\n }\n if (endsWith('keyframes', atRuleName)) {\n const name = '@' + atRuleName + ' ' + node.prelude.value\n if (hasVendorPrefix(atRuleName)) {\n prefixedKeyframes.push(name)\n }\n keyframes.push(name)\n break\n }\n if (atRuleName === 'import') {\n imports.push(node.prelude.value)\n break\n }\n if (atRuleName === 'charset') {\n charsets.push(node.prelude.value)\n break\n }\n if (atRuleName === 'container') {\n containers.push(node.prelude.value)\n break\n }\n if (atRuleName === 'layer') {\n containers.push(\n node.prelude.value.trim()\n .split(',')\n .map(name => name.trim())\n .forEach(name => layers.push(name))\n )\n }\n break\n }\n case 'Rule': {\n const numSelectors = node.prelude.children ? node.prelude.children.size : 0\n const numDeclarations = node.block.children ? node.block.children.size : 0\n\n ruleSizes.add(numSelectors + numDeclarations)\n selectorsPerRule.add(numSelectors)\n declarationsPerRule.add(numDeclarations)\n\n totalRules++\n\n if (numDeclarations === 0) {\n emptyRules++\n }\n break\n }\n case 'Selector': {\n const selector = stringifyNode(node)\n\n if (this.atrule && endsWith('keyframes', this.atrule.name)) {\n keyframeSelectors.push(selector)\n return this.skip\n }\n\n const { specificity, complexity, isId, isA11y } = analyzeSpecificity(node)\n\n if (isId) {\n ids.push(selector)\n }\n\n if (isA11y) {\n a11y.push(selector)\n }\n\n uniqueSelectors.push(selector)\n selectorComplexities.add(complexity)\n uniqueSpecificities.push(specificity)\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\n // Avoid deeper 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 'Url': {\n if (startsWith('data:', node.value)) {\n embeds.push(node.value)\n }\n break\n }\n case 'Value': {\n if (isValueKeyword(node)) {\n break\n }\n\n const property = this.declaration.property\n\n if (isAstVendorPrefixed(node)) {\n vendorPrefixedValues.push(stringifyNode(node))\n }\n\n // Process properties first that don't have colors,\n // so we can avoid further walking them;\n if (isProperty('z-index', property)) {\n if (!isValueKeyword(node)) {\n zindex.push(stringifyNode(node))\n }\n return this.skip\n } else if (isProperty('font', property)) {\n if (!isFontFamilyKeyword(node)) {\n fontFamilies.push(getFamilyFromFont(node, stringifyNode))\n }\n if (!isFontSizeKeyword(node)) {\n const size = getSizeFromFont(node)\n if (size) {\n fontSizes.push(size)\n }\n }\n break\n } else if (isProperty('font-size', property)) {\n if (!isFontSizeKeyword(node)) {\n fontSizes.push(stringifyNode(node))\n }\n break\n } else if (isProperty('font-family', property)) {\n if (!isFontFamilyKeyword(node)) {\n fontFamilies.push(stringifyNode(node))\n }\n break\n } else if (isProperty('transition', property) || isProperty('animation', property)) {\n const [times, fns] = analyzeAnimation(node.children, stringifyNode)\n for (let i = 0; i < times.length; i++) {\n durations.push(times[i])\n }\n for (let i = 0; i < fns.length; i++) {\n timingFunctions.push(fns[i])\n }\n break\n } else if (isProperty('animation-duration', property) || isProperty('transition-duration', property)) {\n durations.push(stringifyNode(node))\n break\n } else if (isProperty('transition-timing-function', property) || isProperty('animation-timing-function', property)) {\n timingFunctions.push(stringifyNode(node))\n break\n } else if (isProperty('text-shadow', property)) {\n if (!isValueKeyword(node)) {\n textShadows.push(stringifyNode(node))\n }\n // no break here: potentially contains colors\n } else if (isProperty('box-shadow', property)) {\n if (!isValueKeyword(node)) {\n boxShadows.push(stringifyNode(node))\n }\n // no break here: potentially contains colors\n }\n\n walk(node, function (valueNode) {\n switch (valueNode.type) {\n case 'Hash': {\n colors.push('#' + valueNode.value, 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 // Don't walk var() multiple times\n if (strEquals('var', valueNode.name)) {\n return this.skip\n }\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 break\n }\n case 'Declaration': {\n totalDeclarations++\n\n const declaration = stringifyNode(node)\n uniqueDeclarations.push(declaration)\n\n if (node.important) {\n importantDeclarations++\n\n if (this.atrule && endsWith('keyframes', this.atrule.name)) {\n importantsInKeyframes++\n }\n }\n\n const { property } = node\n\n properties.push(property)\n\n if (hasVendorPrefix(property)) {\n propertyVendorPrefixes.push(property)\n } else if (isHack(property)) {\n propertyHacks.push(property)\n } else if (isCustom(property)) {\n customProperties.push(property)\n }\n break\n }\n }\n })\n\n const embeddedContent = embeds.count()\n const embedSize = Object.keys(embeddedContent.unique).join('').length\n\n const totalUniqueDeclarations = uniqueDeclarations.count()\n\n const totalSelectors = selectorComplexities.size()\n const specificitiesA = specificityA.aggregate()\n const specificitiesB = specificityB.aggregate()\n const specificitiesC = specificityC.aggregate()\n const uniqueSpecificitiesCount = uniqueSpecificities.count()\n const complexityCount = new CountableCollection(selectorComplexities.toArray()).count()\n const totalUniqueSelectors = uniqueSelectors.count()\n const uniqueRuleSize = new CountableCollection(ruleSizes.toArray()).count()\n const uniqueSelectorsPerRule = new CountableCollection(selectorsPerRule.toArray()).count()\n const uniqueDeclarationsPerRule = new CountableCollection(declarationsPerRule.toArray()).count()\n const assign = Object.assign\n\n return {\n stylesheet: {\n sourceLinesOfCode: totalAtRules + totalSelectors + totalDeclarations + keyframeSelectors.size(),\n linesOfCode: lines.length,\n size: css.length,\n comments: {\n total: totalComments,\n size: commentsSize,\n },\n embeddedContent: assign(embeddedContent, {\n size: {\n total: embedSize,\n ratio: css.length === 0 ? 0 : embedSize / css.length,\n },\n }),\n },\n atrules: {\n fontface: {\n total: fontfaces.length,\n totalUnique: fontfaces.length,\n unique: fontfaces,\n uniquenessRatio: fontfaces.length === 0 ? 0 : 1\n },\n import: imports.count(),\n media: medias.count(),\n charset: charsets.count(),\n supports: supports.count(),\n keyframes: assign(\n keyframes.count(), {\n prefixed: assign(\n prefixedKeyframes.count(), {\n ratio: keyframes.size() === 0 ? 0 : prefixedKeyframes.size() / keyframes.size()\n }),\n }),\n container: containers.count(),\n layer: layers.count(),\n },\n rules: {\n total: totalRules,\n empty: {\n total: emptyRules,\n ratio: totalRules === 0 ? 0 : emptyRules / totalRules\n },\n sizes: assign(\n ruleSizes.aggregate(),\n {\n items: ruleSizes.toArray(),\n unique: uniqueRuleSize.unique,\n totalUnique: uniqueRuleSize.totalUnique,\n uniquenessRatio: uniqueRuleSize.uniquenessRatio\n },\n ),\n selectors: assign(\n selectorsPerRule.aggregate(),\n {\n items: selectorsPerRule.toArray(),\n unique: uniqueSelectorsPerRule.unique,\n totalUnique: uniqueSelectorsPerRule.totalUnique,\n uniquenessRatio: uniqueSelectorsPerRule.uniquenessRatio\n },\n ),\n declarations: assign(\n declarationsPerRule.aggregate(),\n {\n items: declarationsPerRule.toArray(),\n unique: uniqueDeclarationsPerRule.unique,\n totalUnique: uniqueDeclarationsPerRule.totalUnique,\n uniquenessRatio: uniqueDeclarationsPerRule.uniquenessRatio,\n },\n ),\n },\n selectors: {\n total: totalSelectors,\n totalUnique: totalUniqueSelectors,\n uniquenessRatio: totalSelectors === 0 ? 0 : totalUniqueSelectors / totalSelectors,\n specificity: {\n min: minSpecificity === undefined ? [0, 0, 0] : minSpecificity,\n max: maxSpecificity === undefined ? [0, 0, 0] : maxSpecificity,\n sum: [specificitiesA.sum, specificitiesB.sum, specificitiesC.sum],\n mean: [specificitiesA.mean, specificitiesB.mean, specificitiesC.mean],\n mode: [specificitiesA.mode, specificitiesB.mode, specificitiesC.mode],\n median: [specificitiesA.median, specificitiesB.median, specificitiesC.median],\n items: specificities,\n unique: uniqueSpecificitiesCount.unique,\n totalUnique: uniqueSpecificitiesCount.totalUnique,\n uniquenessRatio: uniqueSpecificitiesCount.uniquenessRatio,\n },\n complexity: assign(\n selectorComplexities.aggregate(),\n complexityCount, {\n items: selectorComplexities.toArray(),\n }),\n id: assign(\n ids.count(), {\n ratio: totalSelectors === 0 ? 0 : ids.size() / totalSelectors,\n }),\n accessibility: assign(\n a11y.count(), {\n ratio: totalSelectors === 0 ? 0 : a11y.size() / totalSelectors,\n }),\n keyframes: keyframeSelectors.count(),\n },\n declarations: {\n total: totalDeclarations,\n unique: {\n total: totalUniqueDeclarations,\n ratio: totalDeclarations === 0 ? 0 : totalUniqueDeclarations / totalDeclarations,\n },\n importants: {\n total: importantDeclarations,\n ratio: totalDeclarations === 0 ? 0 : importantDeclarations / totalDeclarations,\n inKeyframes: {\n total: importantsInKeyframes,\n ratio: importantDeclarations === 0 ? 0 : importantsInKeyframes / importantDeclarations,\n },\n },\n },\n properties: assign(\n properties.count(), {\n prefixed: assign(\n propertyVendorPrefixes.count(), {\n ratio: properties.size() === 0 ? 0 : propertyVendorPrefixes.size() / properties.size(),\n }),\n custom: assign(\n customProperties.count(), {\n ratio: properties.size() === 0 ? 0 : customProperties.size() / properties.size(),\n }),\n browserhacks: assign(\n propertyHacks.count(), {\n ratio: properties.size() === 0 ? 0 : propertyHacks.size() / properties.size(),\n }),\n }),\n values: {\n colors: colors.count(),\n fontFamilies: fontFamilies.count(),\n fontSizes: fontSizes.count(),\n zindexes: zindex.count(),\n textShadows: textShadows.count(),\n boxShadows: boxShadows.count(),\n animations: {\n durations: durations.count(),\n timingFunctions: timingFunctions.count(),\n },\n prefixes: vendorPrefixedValues.count(),\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 {\n analyze,\n compareSpecificity,\n}\n"],"names":["compareChar","referenceCode","testCode","endsWith","base","test","offset","length","i","charCodeAt","startsWith","compareSpecificity","a","b","analyzeSpecificity","node","A","B","C","complexity","isA11y","walk","selector","type","Boolean","value","name","skip","selectorList","childSelectors","visit","enter","push","sort","specificity","listItem","isId","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","systemKeywords","inherit","initial","unset","revert","caption","icon","menu","keywordDisallowList","normal","small","medium","large","larger","smaller","bold","bolder","lighter","condensed","expanded","italic","oblique","isFontFamilyKeyword","firstChild","children","first","sizeKeywords","keywords","isFontSizeKeyword","auto","none","isValueKeyword","size","timingKeywords","linear","ease","hasVendorPrefix","keyword","indexOf","isAstVendorPrefixed","toArray","index","CountableCollection","this","_items","_total","_totalUnique","item","count","total","totalUnique","unique","uniquenessRatio","ContextCollection","_list","_contexts","context","itemsPerContext","Object","assign","AggregateCollection","add","aggregate","min","max","mean","mode","median","range","sum","arr","middle","lowerMiddleRank","sorted","slice","reduce","num","frequencies","create","maxOccurrences","maxOccurenceCount","element","updatedCount","Mode","Math","floor","isCustom","property","isProperty","basename","OccurrenceCounter","keys","css","start","Date","lines","split","stringifyNode","loc","end","line","substring","column","maxSpecificity","minSpecificity","totalComments","commentsSize","embeds","startParse","ast","parse","parseAtrulePrelude","parseCustomProperty","positions","onComment","comment","startAnalysis","totalAtRules","fontfaces","layers","imports","medias","charsets","supports","keyframes","prefixedKeyframes","containers","totalRules","emptyRules","ruleSizes","selectorsPerRule","declarationsPerRule","keyframeSelectors","uniqueSelectors","specificityA","specificityB","specificityC","uniqueSpecificities","selectorComplexities","specificities","ids","a11y","uniqueDeclarations","totalDeclarations","importantDeclarations","importantsInKeyframes","properties","propertyHacks","propertyVendorPrefixes","customProperties","vendorPrefixedValues","zindex","textShadows","boxShadows","fontFamilies","fontSizes","timingFunctions","durations","colors","units","atRuleName","descriptors","block","forEach","descriptor","prelude","trim","map","numSelectors","numDeclarations","atrule","undefined","declaration","unit","parts","reverse","fontNode","quote","getFamilyFromFont","operator","getSizeFromFont","durationFound","child","analyzeAnimation","times","fns","valueNode","toLowerCase","strEquals","important","code","isHack","embeddedContent","embedSize","join","totalUniqueDeclarations","totalSelectors","specificitiesA","specificitiesB","specificitiesC","uniqueSpecificitiesCount","complexityCount","totalUniqueSelectors","uniqueRuleSize","uniqueSelectorsPerRule","uniqueDeclarationsPerRule","stylesheet","sourceLinesOfCode","linesOfCode","comments","ratio","atrules","fontface","import","media","charset","prefixed","container","layer","rules","empty","sizes","items","selectors","declarations","id","accessibility","importants","inKeyframes","custom","browserhacks","values","zindexes","animations","prefixes","__meta__","parseTime","analyzeTime"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"analyzer.cjs","sources":["../src/string-utils.js","../src/atrules/atrules.js","../src/vendor-prefix.js","../src/selectors/specificity.js","../src/values/colors.js","../src/values/font-families.js","../src/values/font-sizes.js","../src/values/values.js","../src/values/animations.js","../src/values/vendor-prefix.js","../src/countable-collection.js","../src/context-collection.js","../src/aggregate-collection.js","../src/properties/property-utils.js","../src/occurrence-counter.js","../src/index.js"],"sourcesContent":["/**\n * Case-insensitive compare two character codes\n * @param {string} charA\n * @param {string} charB\n * @see https://github.com/csstree/csstree/blob/41f276e8862d8223eeaa01a3d113ab70bb13d2d9/lib/tokenizer/utils.js#L22\n */\nfunction compareChar(referenceCode, testCode) {\n // if uppercase\n if (testCode >= 0x0041 && testCode <= 0x005A) {\n // shifting the 6th bit makes a letter lowercase\n testCode = testCode | 32\n }\n return referenceCode === testCode\n}\n\n/**\n * Case-insensitive string-comparison\n * @param {string} base\n * @param {string} test\n * @returns {boolean} true if the two strings are the same, false otherwise\n */\nexport function strEquals(base, test) {\n if (base.length !== test.length) return false\n\n for (let i = 0; i < base.length; i++) {\n if (compareChar(base.charCodeAt(i), test.charCodeAt(i)) === false) {\n return false\n }\n }\n\n return true\n}\n\n/**\n * Case-insensitive testing whether a string ends with a given substring\n * @param {string} base e.g. '-webkit-transform'\n * @param {string} cmp e.g. 'transform'\n * @returns {boolean} true if `test` ends with `base`, false otherwise\n */\nexport function endsWith(base, test) {\n const offset = test.length - base.length\n\n if (offset < 0) {\n return false\n }\n\n for (let i = test.length - 1; i >= offset; i--) {\n if (compareChar(base.charCodeAt(i - offset), test.charCodeAt(i)) === false) {\n return false\n }\n }\n\n return true\n}\n\n/**\n * Case-insensitive testing whether a string starts with a given substring\n * @param {string} base\n * @param {test} test\n * @returns {boolean} true if `test` starts with `base`, false otherwise\n */\nexport function startsWith(base, test) {\n if (test.length < base.length) return false\n\n for (let i = 0; i < base.length; i++) {\n if (compareChar(base.charCodeAt(i), test.charCodeAt(i)) === false) {\n return false\n }\n }\n\n return true\n}\n","import { strEquals, startsWith, endsWith } from '../string-utils.js'\nimport walk from 'css-tree/walker'\n\n/**\n * Check whether node.property === property and node.value === value,\n * but case-insensitive and fast.\n * @param {import('css-tree').Declaration} node\n * @param {string} property - The CSS property to compare with (case-insensitive)\n * @param {string} value - The identifier/keyword value to compare with\n * @returns true if declaratioNode is the given property: value, false otherwise\n */\nfunction isPropertyValue(node, property, value) {\n return strEquals(property, node.property)\n && node.value.children.first.type === 'Identifier'\n && strEquals(value, node.value.children.first.name)\n}\n\n/**\n * Check if an @supports atRule is a browserhack\n * @param {import('css-tree').AtrulePrelude} prelude\n * @returns true if the atrule is a browserhack\n */\nexport function isSupportsBrowserhack(prelude) {\n let returnValue = false\n\n walk(prelude, function (node) {\n if (node.type === 'Declaration') {\n if (\n isPropertyValue(node, '-webkit-appearance', 'none')\n || isPropertyValue(node, '-moz-appearance', 'meterbar')\n ) {\n returnValue = true\n return this.break\n }\n }\n })\n\n return returnValue\n}\n\n/**\n * Check if a @media atRule is a browserhack\n * @param {import('css-tree').AtrulePrelude} prelude\n * @returns true if the atrule is a browserhack\n */\nexport function isMediaBrowserhack(prelude) {\n let returnValue = false\n\n walk(prelude, function (node) {\n if (node.type === 'MediaQuery'\n && node.children.size === 1\n && node.children.first.type === 'Identifier'\n ) {\n node = node.children.first\n // Note: CSSTree adds a trailing space to \\\\9\n if (startsWith('\\\\0', node.name) || endsWith('\\\\9 ', node.name)) {\n returnValue = true\n return this.break\n }\n }\n if (node.type === 'MediaFeature') {\n if (node.value !== null && node.value.unit === '\\\\0') {\n returnValue = true\n return this.break\n }\n if (strEquals('-moz-images-in-menus', node.name)\n || strEquals('min--moz-device-pixel-ratio', node.name)\n || strEquals('-ms-high-contrast', node.name)\n ) {\n returnValue = true\n return this.break\n }\n if (strEquals('min-resolution', node.name)\n && strEquals('.001', node.value.value)\n && strEquals('dpcm', node.value.unit)\n ) {\n returnValue = true\n return this.break\n }\n if (strEquals('-webkit-min-device-pixel-ratio', node.name)) {\n if ((strEquals('0', node.value.value) || strEquals('10000', node.value.value))) {\n returnValue = true\n return this.break\n }\n }\n }\n })\n\n return returnValue\n}","const HYPHENMINUS = 45; // '-'.charCodeAt()\n\n/**\n * @param {string} keyword\n * @returns {boolean}\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 walk from 'css-tree/walker'\nimport { startsWith, strEquals } from '../string-utils.js'\nimport { hasVendorPrefix } from '../vendor-prefix.js'\n\nconst COMPLEXITY = 3\nconst IS_A11Y = 4\n\n/**\n * Compare specificity A to Specificity B\n * @param {[number,number,number]} a - Specificity A\n * @param {[number,number,number]} 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 walk(selectorListAst, {\n visit: 'Selector',\n enter(node) {\n childSelectors.push(analyzeSelector(node))\n }\n })\n\n return childSelectors.sort((a, b) => compareSpecificity([a[0], a[1], a[2]], [b[0], b[1], b[2]]))\n}\n\n/**\n * Get the Specificity for the AST of a Selector Node\n * @param {import('css-tree').Selector} ast - AST Node for a Selector\n * @return {[number, number, number, number, number]} - Array with SpecificityA, SpecificityB, SpecificityC, complexity, isA11y\n */\nconst analyzeSelector = (node) => {\n let A = 0\n let B = 0\n let C = 0\n let complexity = 0\n let isA11y = false\n\n walk(node, 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 // Add 1 for [attr=value] (or any variation using *= $= ^= |= )\n if (Boolean(selector.value)) {\n complexity++\n }\n\n if (strEquals('role', selector.name.name) || startsWith('aria-', selector.name.name)) {\n isA11y = true\n }\n break\n }\n case 'PseudoElementSelector':\n case 'TypeSelector': {\n complexity++\n\n if (hasVendorPrefix(selector.name)) {\n complexity++\n }\n\n // 42 === '*'.charCodeAt(0)\n if (selector.name.charCodeAt(0) === 42 && selector.name.length === 1) {\n break\n }\n\n C++\n break\n }\n case 'PseudoClassSelector': {\n switch (selector.name) {\n case 'before':\n case 'after':\n case 'first-letter':\n case 'first-line': {\n C++\n complexity++\n return this.skip\n }\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 case 'where':\n case 'is':\n case 'has':\n case 'matches':\n case '-webkit-any':\n case '-moz-any':\n case 'not':\n case 'nth-child':\n case 'nth-last-child': {\n if (hasVendorPrefix(selector.name)) {\n complexity++\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 (selector.name === 'nth-child' || selector.name === 'nth-last-child') {\n // +1 for the pseudo class itself\n B++\n }\n\n const selectorList = selectorListSpecificities(selector)\n\n // Bail out for empty/non-existent :nth-child() params\n if (selectorList.length === 0) return\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 [topA, topB, topC] = selectorList[0]\n A += topA\n B += topB\n C += topC\n }\n\n for (let i = 0; i < selectorList.length; i++) {\n const listItem = selectorList[i]\n if (listItem[IS_A11Y] === 1) {\n isA11y = true\n }\n complexity += listItem[COMPLEXITY]\n }\n\n complexity++\n return this.skip\n }\n\n default: {\n // Regular pseudo classes have specificity [0,1,0]\n complexity++\n B++\n return this.skip\n }\n }\n }\n case 'Combinator': {\n complexity++\n break\n }\n }\n })\n\n return [\n A, B, C,\n complexity,\n isA11y ? 1 : 0,\n ]\n}\n\nexport {\n analyzeSelector,\n compareSpecificity,\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","import walk from 'css-tree/walker'\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\nexport function isFontFamilyKeyword(node) {\n const firstChild = node.children.first\n return firstChild.type === 'Identifier' && systemKeywords[firstChild.name]\n}\n\nexport function getFamilyFromFont(node, stringifyNode) {\n let parts = ''\n\n walk(node, {\n reverse: true,\n enter: function (fontNode) {\n if (fontNode.type === 'String') {\n const loc = fontNode.loc.start\n // Stringify the first character to get the correct quote character\n const quote = stringifyNode({\n loc: {\n start: {\n line: loc.line,\n column: loc.column\n },\n end: {\n line: loc.line,\n column: loc.column + 1\n }\n }\n })\n return parts = quote + fontNode.value + quote + parts\n }\n if (fontNode.type === 'Operator' && fontNode.value.charCodeAt(0) === COMMA) {\n return parts = fontNode.value + parts\n }\n if (fontNode.type === 'Identifier') {\n if (keywordDisallowList[fontNode.name]) {\n return this.skip\n }\n return parts = fontNode.name + parts\n }\n }\n })\n\n return parts\n}\n","import walk from 'css-tree/walker'\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\nexport function isFontSizeKeyword(node) {\n const firstChild = node.children.first\n return firstChild.type === 'Identifier' && keywords[firstChild.name]\n}\n\nexport function getSizeFromFont(node) {\n let operator = false\n let size\n\n walk(node, 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 = fontNode.value + fontNode.unit\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 return size\n}\n","const keywords = {\n 'auto': 1,\n 'inherit': 1,\n 'initial': 1,\n 'unset': 1,\n 'revert': 1,\n 'none': 1, // for `text-shadow`, `box-shadow` and `background`\n}\n\nexport function isValueKeyword(node) {\n if (!node.children) return false\n const firstChild = node.children.first\n if (!firstChild) return false\n\n if (node.children.size > 1) return false\n return firstChild.type === 'Identifier' && keywords[firstChild.name]\n}\n","const 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\nexport function analyzeAnimation(children, stringifyNode) {\n let durationFound = false\n const durations = []\n const timingFunctions = []\n\n 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 durations.push(stringifyNode(child))\n }\n if (child.type === 'Identifier' && timingKeywords[child.name]) {\n return timingFunctions.push(stringifyNode(child))\n }\n if (child.type === 'Function'\n && (\n child.name === 'cubic-bezier' || child.name === 'steps'\n )\n ) {\n return timingFunctions.push(stringifyNode(child))\n }\n })\n\n return [durations, timingFunctions]\n}\n","import { hasVendorPrefix } from '../vendor-prefix.js'\n\nexport function isAstVendorPrefixed(node) {\n if (!node.children) {\n return false\n }\n\n const children = node.children.toArray()\n\n for (let index = 0; index < children.length; index++) {\n const node = children[index]\n const { type, name } = node;\n\n if (type === 'Identifier' && hasVendorPrefix(name)) {\n return true\n }\n\n if (type === 'Function') {\n if (hasVendorPrefix(name)) {\n return true\n }\n\n if (isAstVendorPrefixed(node)) {\n return true\n }\n }\n }\n\n return false\n}\n","class CountableCollection {\n /**\n * @param {string[]} initial\n */\n constructor(initial) {\n /** @type [index: string]: string */\n this._items = {}\n /** @type number */\n this._total = 0\n /** @type number */\n this._totalUnique = 0\n\n if (initial) {\n for (let i = 0; i < initial.length; i++) {\n this.push(initial[i])\n }\n }\n }\n\n /**\n * Push an item to the end of this collection\n * @param {string} item\n * @returns {void}\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 /**\n * Get the size of this collection\n * @returns {number} the size of this collection\n */\n size() {\n return this._total\n }\n\n /**\n * Get the counts of this collection, like total, uniques, etc.\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 { CountableCollection } from './countable-collection.js'\n\nclass ContextCollection {\n constructor() {\n this._list = new CountableCollection()\n /** @type {[index; string]: CountableCollection} */\n this._contexts = {}\n }\n\n /**\n * Add an item to this _list's context\n * @param {string} item Item to push\n * @param {string} context Context to push Item to\n */\n push(item, context) {\n this._list.push(item)\n\n if (!this._contexts[context]) {\n this._contexts[context] = new CountableCollection()\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}","/**\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() {\n /** @type number[] */\n this._items = []\n }\n\n /**\n * Add a new Integer at the end of this AggregateCollection\n * @param {number} item - The item to add\n */\n push(item) {\n this._items.push(item)\n }\n\n size() {\n return this._items.length\n }\n\n aggregate() {\n if (this._items.length === 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 // TODO: can we avoid this sort()? It's slow\n /** @type Number[] */\n const sorted = this._items.slice().sort((a, b) => a - b)\n const min = sorted[0]\n const max = sorted[sorted.length - 1]\n\n const sum = this._items.reduce((total, num) => (total += num))\n const mode = Mode(this._items)\n const median = Median(sorted)\n\n return {\n min,\n max,\n mean: sum / this._items.length,\n mode,\n median,\n range: max - min,\n sum,\n }\n }\n\n /**\n * @returns {number[]} All _items in this collection\n */\n toArray() {\n return this._items\n }\n}\n\nexport {\n AggregateCollection\n}","import { hasVendorPrefix } from '../vendor-prefix.js'\nimport { endsWith } from '../string-utils.js'\n\n/**\n * @param {string} property\n * @see https://github.com/csstree/csstree/blob/master/lib/utils/names.js#L69\n */\nexport function isHack(property) {\n if (isCustom(property) || hasVendorPrefix(property)) return false\n\n let code = property.charCodeAt(0)\n\n return code === 47 // /\n || code === 95 // _\n || code === 43 // +\n || code === 42 // *\n || code === 38 // &\n || code === 36 // $\n || code === 35 // #\n}\n\nexport function isCustom(property) {\n if (property.length < 3) return false\n // 45 === '-'.charCodeAt(0)\n return property.charCodeAt(0) === 45 && property.charCodeAt(1) === 45\n}\n\nexport function isProperty(basename, property) {\n if (isCustom(property)) return false\n return endsWith(basename, property)\n}","/**\n * Convert a string to a number\n * @param {string} str\n * @returns {number} the hashed string\n * @see https://stackoverflow.com/a/51276700\n */\nfunction hash(str) {\n const prime = 403\n let hash = 167\n\n for (let i = 0; i < str.length; i++) {\n hash = hash ^ str.charCodeAt(i)\n hash *= prime\n }\n\n return hash\n}\n\nexport class OccurrenceCounter {\n constructor() {\n this._items = Object.create(null)\n }\n\n /**\n * Converting the CSS string to an integer because this collection potentially\n * becomes very large and storing the values as integers saves 10-70%\n *\n * @see https://github.com/projectwallace/css-analyzer/pull/242\n * @param {string} item\n * @returns {number} the count for this item\n */\n push(item) {\n const key = hash(item)\n\n if (this._items[key]) return\n this._items[key] = 1\n }\n\n count() {\n return Object.keys(this._items).length\n }\n}\n","import parse from 'css-tree/parser'\nimport walk from 'css-tree/walker'\nimport { isSupportsBrowserhack, isMediaBrowserhack } from './atrules/atrules.js'\nimport { analyzeSelector, compareSpecificity } from './selectors/specificity.js'\nimport { colorFunctions, colorNames } from './values/colors.js'\nimport { isFontFamilyKeyword, getFamilyFromFont } from './values/font-families.js'\nimport { isFontSizeKeyword, getSizeFromFont } from './values/font-sizes.js'\nimport { isValueKeyword } from './values/values.js'\nimport { analyzeAnimation } from './values/animations.js'\nimport { isAstVendorPrefixed } from './values/vendor-prefix.js'\nimport { ContextCollection } from './context-collection.js'\nimport { CountableCollection } from './countable-collection.js'\nimport { AggregateCollection } from './aggregate-collection.js'\nimport { strEquals, startsWith, endsWith } from './string-utils.js'\nimport { hasVendorPrefix } from './vendor-prefix.js'\nimport { isCustom, isHack, isProperty } from './properties/property-utils.js'\nimport { OccurrenceCounter } from './occurrence-counter.js'\n\nfunction ratio(part, total) {\n if (total === 0) return 0\n return part / total\n}\n\n/**\n * Analyze CSS\n * @param {string} css\n */\nconst analyze = (css) => {\n const start = Date.now()\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').CssNode} 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 let 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 += line.substring(start.column - 1) + '\\n'\n continue\n }\n // Last line\n if (i === end.line) {\n value += line.substring(0, end.column - 1)\n continue\n }\n // All lines in between first and last\n value += line + '\\n'\n }\n\n return value\n }\n\n // Stylesheet\n let totalComments = 0\n let commentsSize = 0\n const embeds = new CountableCollection()\n\n const startParse = Date.now()\n\n const ast = parse(css, {\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 = Date.now()\n\n // Atrules\n let totalAtRules = 0\n /** @type {string}[]} */\n const fontfaces = []\n const layers = new CountableCollection()\n const imports = new CountableCollection()\n const medias = new CountableCollection()\n const mediaBrowserhacks = new CountableCollection()\n const charsets = new CountableCollection()\n const supports = new CountableCollection()\n const supportsBrowserhacks = new CountableCollection()\n const keyframes = new CountableCollection()\n const prefixedKeyframes = new CountableCollection()\n const containers = new CountableCollection()\n\n // Rules\n let totalRules = 0\n let emptyRules = 0\n const ruleSizes = new AggregateCollection()\n const selectorsPerRule = new AggregateCollection()\n const declarationsPerRule = new AggregateCollection()\n\n // Selectors\n const keyframeSelectors = new CountableCollection()\n const uniqueSelectors = new OccurrenceCounter()\n /** @type [number,number,number] */\n let maxSpecificity\n /** @type [number,number,number] */\n let minSpecificity\n const specificityA = new AggregateCollection()\n const specificityB = new AggregateCollection()\n const specificityC = new AggregateCollection()\n const uniqueSpecificities = new CountableCollection()\n const selectorComplexities = new AggregateCollection()\n /** @type [number,number,number][] */\n const specificities = []\n const ids = new CountableCollection()\n const a11y = new CountableCollection()\n\n // Declarations\n const uniqueDeclarations = new OccurrenceCounter()\n let totalDeclarations = 0\n let importantDeclarations = 0\n let importantsInKeyframes = 0\n\n // Properties\n const properties = new CountableCollection()\n const propertyHacks = new CountableCollection()\n const propertyVendorPrefixes = new CountableCollection()\n const customProperties = new CountableCollection()\n const propertyComplexities = new AggregateCollection()\n\n // Values\n const vendorPrefixedValues = new CountableCollection()\n const valueBrowserhacks = new CountableCollection()\n const zindex = new CountableCollection()\n const textShadows = new CountableCollection()\n const boxShadows = new CountableCollection()\n const fontFamilies = new CountableCollection()\n const fontSizes = new CountableCollection()\n const timingFunctions = new CountableCollection()\n const durations = new CountableCollection()\n const colors = new ContextCollection()\n const units = new ContextCollection()\n\n walk(ast, function (node) {\n switch (node.type) {\n case 'Atrule': {\n totalAtRules++\n const atRuleName = node.name\n\n if (atRuleName === 'font-face') {\n /** @type {[index: string]: string} */\n const descriptors = {}\n\n node.block.children.forEach(\n /** @param {import('css-tree').Declaration} descriptor */\n descriptor => (descriptors[descriptor.property] = stringifyNode(descriptor.value))\n )\n\n fontfaces.push(descriptors)\n break\n }\n\n if (atRuleName === 'media') {\n const prelude = stringifyNode(node.prelude)\n medias.push(prelude)\n if (isMediaBrowserhack(node.prelude)) {\n mediaBrowserhacks.push(prelude)\n }\n break\n }\n if (atRuleName === 'supports') {\n const prelude = stringifyNode(node.prelude)\n supports.push(prelude)\n if (isSupportsBrowserhack(node.prelude)) {\n supportsBrowserhacks.push(prelude)\n }\n break\n }\n if (endsWith('keyframes', atRuleName)) {\n const name = '@' + atRuleName + ' ' + stringifyNode(node.prelude)\n if (hasVendorPrefix(atRuleName)) {\n prefixedKeyframes.push(name)\n }\n keyframes.push(name)\n break\n }\n if (atRuleName === 'import') {\n imports.push(stringifyNode(node.prelude))\n break\n }\n if (atRuleName === 'charset') {\n charsets.push(stringifyNode(node.prelude))\n break\n }\n if (atRuleName === 'container') {\n containers.push(stringifyNode(node.prelude))\n break\n }\n if (atRuleName === 'layer') {\n const prelude = stringifyNode(node.prelude)\n prelude.trim()\n .split(',')\n .forEach(name => layers.push(name.trim()))\n }\n break\n }\n case 'Rule': {\n const numSelectors = node.prelude.children ? node.prelude.children.size : 0\n const numDeclarations = node.block.children ? node.block.children.size : 0\n\n ruleSizes.push(numSelectors + numDeclarations)\n selectorsPerRule.push(numSelectors)\n declarationsPerRule.push(numDeclarations)\n\n totalRules++\n\n if (numDeclarations === 0) {\n emptyRules++\n }\n break\n }\n case 'Selector': {\n const selector = stringifyNode(node)\n\n if (this.atrule && endsWith('keyframes', this.atrule.name)) {\n keyframeSelectors.push(selector)\n return this.skip\n }\n\n const analysis = analyzeSelector(node)\n const specificity = analysis.splice(0, 3)\n const [complexity, isA11y] = analysis\n\n if (specificity[0] > 0) {\n ids.push(selector)\n }\n\n if (isA11y === 1) {\n a11y.push(selector)\n }\n\n uniqueSelectors.push(selector)\n selectorComplexities.push(complexity)\n uniqueSpecificities.push(specificity)\n\n if (maxSpecificity === undefined) {\n maxSpecificity = specificity\n }\n\n if (minSpecificity === undefined) {\n minSpecificity = specificity\n }\n\n specificityA.push(specificity[0])\n specificityB.push(specificity[1])\n specificityC.push(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\n // Avoid deeper 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 'Url': {\n if (startsWith('data:', node.value)) {\n embeds.push(node.value)\n }\n break\n }\n case 'Value': {\n if (isValueKeyword(node)) {\n break\n }\n\n const declaration = this.declaration\n const { property, important } = declaration\n\n if (isAstVendorPrefixed(node)) {\n vendorPrefixedValues.push(stringifyNode(node))\n }\n\n // i.e. `property: value !ie`\n if (typeof important === 'string') {\n valueBrowserhacks.push(stringifyNode(node) + '!' + important)\n }\n\n // i.e. `property: value\\9`\n if (node.children\n && node.children.last\n && node.children.last.type === 'Identifier'\n && endsWith('\\\\9', node.children.last.name)\n ) {\n valueBrowserhacks.push(stringifyNode(node))\n }\n\n // Process properties first that don't have colors,\n // so we can avoid further walking them;\n if (isProperty('z-index', property)) {\n if (!isValueKeyword(node)) {\n zindex.push(stringifyNode(node))\n }\n return this.skip\n } else if (isProperty('font', property)) {\n if (!isFontFamilyKeyword(node)) {\n fontFamilies.push(getFamilyFromFont(node, stringifyNode))\n }\n if (!isFontSizeKeyword(node)) {\n const size = getSizeFromFont(node)\n if (size) {\n fontSizes.push(size)\n }\n }\n break\n } else if (isProperty('font-size', property)) {\n if (!isFontSizeKeyword(node)) {\n fontSizes.push(stringifyNode(node))\n }\n break\n } else if (isProperty('font-family', property)) {\n if (!isFontFamilyKeyword(node)) {\n fontFamilies.push(stringifyNode(node))\n }\n break\n } else if (isProperty('transition', property) || isProperty('animation', property)) {\n const [times, fns] = analyzeAnimation(node.children, stringifyNode)\n for (let i = 0; i < times.length; i++) {\n durations.push(times[i])\n }\n for (let i = 0; i < fns.length; i++) {\n timingFunctions.push(fns[i])\n }\n break\n } else if (isProperty('animation-duration', property) || isProperty('transition-duration', property)) {\n durations.push(stringifyNode(node))\n break\n } else if (isProperty('transition-timing-function', property) || isProperty('animation-timing-function', property)) {\n timingFunctions.push(stringifyNode(node))\n break\n } else if (isProperty('text-shadow', property)) {\n if (!isValueKeyword(node)) {\n textShadows.push(stringifyNode(node))\n }\n // no break here: potentially contains colors\n } else if (isProperty('box-shadow', property)) {\n if (!isValueKeyword(node)) {\n boxShadows.push(stringifyNode(node))\n }\n // no break here: potentially contains colors\n }\n\n walk(node, function (valueNode) {\n switch (valueNode.type) {\n case 'Hash': {\n colors.push('#' + valueNode.value, 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 // Don't walk var() multiple times\n if (strEquals('var', valueNode.name)) {\n return this.skip\n }\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 break\n }\n case 'Declaration': {\n // Do not process Declarations in atRule preludes\n // because we will handle them manually\n if (this.atrulePrelude !== null) {\n return this.skip\n }\n\n totalDeclarations++\n\n const declaration = stringifyNode(node)\n uniqueDeclarations.push(declaration)\n\n if (node.important === true) {\n importantDeclarations++\n\n if (this.atrule && endsWith('keyframes', this.atrule.name)) {\n importantsInKeyframes++\n }\n }\n\n const { property } = node\n\n properties.push(property)\n\n if (hasVendorPrefix(property)) {\n propertyVendorPrefixes.push(property)\n propertyComplexities.push(2)\n } else if (isHack(property)) {\n propertyHacks.push(property)\n propertyComplexities.push(2)\n } else if (isCustom(property)) {\n customProperties.push(property)\n propertyComplexities.push(2)\n } else {\n propertyComplexities.push(1)\n }\n break\n }\n }\n })\n\n const embeddedContent = embeds.count()\n const embedSize = Object.keys(embeddedContent.unique).join('').length\n\n const totalUniqueDeclarations = uniqueDeclarations.count()\n\n const totalSelectors = selectorComplexities.size()\n const specificitiesA = specificityA.aggregate()\n const specificitiesB = specificityB.aggregate()\n const specificitiesC = specificityC.aggregate()\n const uniqueSpecificitiesCount = uniqueSpecificities.count()\n const complexityCount = new CountableCollection(selectorComplexities.toArray()).count()\n const totalUniqueSelectors = uniqueSelectors.count()\n const uniqueRuleSize = new CountableCollection(ruleSizes.toArray()).count()\n const uniqueSelectorsPerRule = new CountableCollection(selectorsPerRule.toArray()).count()\n const uniqueDeclarationsPerRule = new CountableCollection(declarationsPerRule.toArray()).count()\n const assign = Object.assign\n\n return {\n stylesheet: {\n sourceLinesOfCode: totalAtRules + totalSelectors + totalDeclarations + keyframeSelectors.size(),\n linesOfCode: lines.length,\n size: css.length,\n comments: {\n total: totalComments,\n size: commentsSize,\n },\n embeddedContent: assign(embeddedContent, {\n size: {\n total: embedSize,\n ratio: ratio(embedSize, css.length),\n },\n }),\n },\n atrules: {\n fontface: {\n total: fontfaces.length,\n totalUnique: fontfaces.length,\n unique: fontfaces,\n uniquenessRatio: fontfaces.length === 0 ? 0 : 1\n },\n import: imports.count(),\n media: assign(\n medias.count(),\n {\n browserhacks: mediaBrowserhacks.count(),\n }\n ),\n charset: charsets.count(),\n supports: assign(\n supports.count(),\n {\n browserhacks: supportsBrowserhacks.count(),\n },\n ),\n keyframes: assign(\n keyframes.count(), {\n prefixed: assign(\n prefixedKeyframes.count(), {\n ratio: ratio(prefixedKeyframes.size(), keyframes.size())\n }),\n }),\n container: containers.count(),\n layer: layers.count(),\n },\n rules: {\n total: totalRules,\n empty: {\n total: emptyRules,\n ratio: ratio(emptyRules, totalRules)\n },\n sizes: assign(\n ruleSizes.aggregate(),\n {\n items: ruleSizes.toArray(),\n unique: uniqueRuleSize.unique,\n totalUnique: uniqueRuleSize.totalUnique,\n uniquenessRatio: uniqueRuleSize.uniquenessRatio\n },\n ),\n selectors: assign(\n selectorsPerRule.aggregate(),\n {\n items: selectorsPerRule.toArray(),\n unique: uniqueSelectorsPerRule.unique,\n totalUnique: uniqueSelectorsPerRule.totalUnique,\n uniquenessRatio: uniqueSelectorsPerRule.uniquenessRatio\n },\n ),\n declarations: assign(\n declarationsPerRule.aggregate(),\n {\n items: declarationsPerRule.toArray(),\n unique: uniqueDeclarationsPerRule.unique,\n totalUnique: uniqueDeclarationsPerRule.totalUnique,\n uniquenessRatio: uniqueDeclarationsPerRule.uniquenessRatio,\n },\n ),\n },\n selectors: {\n total: totalSelectors,\n totalUnique: totalUniqueSelectors,\n uniquenessRatio: ratio(totalUniqueSelectors, totalSelectors),\n specificity: {\n /** @type [number, number, number] */\n min: minSpecificity === undefined ? [0, 0, 0] : minSpecificity,\n /** @type [number, number, number] */\n max: maxSpecificity === undefined ? [0, 0, 0] : maxSpecificity,\n /** @type [number, number, number] */\n sum: [specificitiesA.sum, specificitiesB.sum, specificitiesC.sum],\n /** @type [number, number, number] */\n mean: [specificitiesA.mean, specificitiesB.mean, specificitiesC.mean],\n /** @type [number, number, number] */\n mode: [specificitiesA.mode, specificitiesB.mode, specificitiesC.mode],\n /** @type [number, number, number] */\n median: [specificitiesA.median, specificitiesB.median, specificitiesC.median],\n items: specificities,\n unique: uniqueSpecificitiesCount.unique,\n totalUnique: uniqueSpecificitiesCount.totalUnique,\n uniquenessRatio: uniqueSpecificitiesCount.uniquenessRatio,\n },\n complexity: assign(\n selectorComplexities.aggregate(),\n complexityCount, {\n items: selectorComplexities.toArray(),\n }),\n id: assign(\n ids.count(), {\n ratio: ratio(ids.size(), totalSelectors),\n }),\n accessibility: assign(\n a11y.count(), {\n ratio: ratio(a11y.size(), totalSelectors),\n }),\n keyframes: keyframeSelectors.count(),\n },\n declarations: {\n total: totalDeclarations,\n totalUnique: totalUniqueDeclarations,\n uniquenessRatio: ratio(totalUniqueDeclarations, totalDeclarations),\n // @TODO: deprecated, remove in next major version\n unique: {\n total: totalUniqueDeclarations,\n ratio: ratio(totalUniqueDeclarations, totalDeclarations),\n },\n importants: {\n total: importantDeclarations,\n ratio: ratio(importantDeclarations, totalDeclarations),\n inKeyframes: {\n total: importantsInKeyframes,\n ratio: ratio(importantsInKeyframes, importantDeclarations),\n },\n },\n },\n properties: assign(\n properties.count(), {\n prefixed: assign(\n propertyVendorPrefixes.count(), {\n ratio: ratio(propertyVendorPrefixes.size(), properties.size()),\n }),\n custom: assign(\n customProperties.count(), {\n ratio: ratio(customProperties.size(), properties.size()),\n }),\n browserhacks: assign(\n propertyHacks.count(), {\n ratio: ratio(propertyHacks.size(), properties.size()),\n }),\n complexity: propertyComplexities.aggregate(),\n }),\n values: {\n colors: colors.count(),\n fontFamilies: fontFamilies.count(),\n fontSizes: fontSizes.count(),\n zindexes: zindex.count(),\n textShadows: textShadows.count(),\n boxShadows: boxShadows.count(),\n animations: {\n durations: durations.count(),\n timingFunctions: timingFunctions.count(),\n },\n prefixes: vendorPrefixedValues.count(),\n browserhacks: valueBrowserhacks.count(),\n units: units.count(),\n },\n __meta__: {\n parseTime: startAnalysis - startParse,\n analyzeTime: Date.now() - startAnalysis,\n total: Date.now() - start\n }\n }\n}\n\nexport {\n analyze,\n compareSpecificity,\n}\n"],"names":["compareChar","referenceCode","testCode","strEquals","base","test","length","i","charCodeAt","endsWith","offset","startsWith","isPropertyValue","node","property","value","children","first","type","name","hasVendorPrefix","keyword","indexOf","compareSpecificity","a","b","analyzeSelector","A","B","C","complexity","isA11y","walk","selector","Boolean","skip","selectorList","childSelectors","visit","enter","push","sort","listItem","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","systemKeywords","inherit","initial","unset","revert","caption","icon","menu","keywordDisallowList","normal","small","medium","large","larger","smaller","bold","bolder","lighter","condensed","expanded","italic","oblique","isFontFamilyKeyword","firstChild","sizeKeywords","keywords","isFontSizeKeyword","auto","none","isValueKeyword","size","timingKeywords","linear","ease","isAstVendorPrefixed","toArray","index","CountableCollection","this","_items","_total","_totalUnique","item","count","total","totalUnique","unique","uniquenessRatio","ContextCollection","_list","_contexts","context","itemsPerContext","Object","assign","AggregateCollection","aggregate","min","max","mean","mode","median","range","sum","arr","middle","lowerMiddleRank","sorted","slice","reduce","num","frequencies","create","maxOccurrences","maxOccurenceCount","element","updatedCount","Mode","Math","floor","isCustom","isProperty","basename","OccurrenceCounter","key","str","hash","keys","ratio","part","css","start","Date","now","lines","split","stringifyNode","loc","end","line","substring","column","maxSpecificity","minSpecificity","totalComments","commentsSize","embeds","startParse","ast","parse","parseCustomProperty","positions","onComment","comment","startAnalysis","totalAtRules","fontfaces","layers","imports","medias","mediaBrowserhacks","charsets","supports","supportsBrowserhacks","keyframes","prefixedKeyframes","containers","totalRules","emptyRules","ruleSizes","selectorsPerRule","declarationsPerRule","keyframeSelectors","uniqueSelectors","specificityA","specificityB","specificityC","uniqueSpecificities","selectorComplexities","specificities","ids","a11y","uniqueDeclarations","totalDeclarations","importantDeclarations","importantsInKeyframes","properties","propertyHacks","propertyVendorPrefixes","customProperties","propertyComplexities","vendorPrefixedValues","valueBrowserhacks","zindex","textShadows","boxShadows","fontFamilies","fontSizes","timingFunctions","durations","colors","units","atRuleName","descriptors","block","forEach","descriptor","prelude","returnValue","unit","isMediaBrowserhack","isSupportsBrowserhack","trim","numSelectors","numDeclarations","atrule","analysis","specificity","splice","undefined","declaration","important","last","parts","reverse","fontNode","quote","getFamilyFromFont","operator","getSizeFromFont","durationFound","child","analyzeAnimation","times","fns","valueNode","toLowerCase","atrulePrelude","code","isHack","embeddedContent","embedSize","join","totalUniqueDeclarations","totalSelectors","specificitiesA","specificitiesB","specificitiesC","uniqueSpecificitiesCount","complexityCount","totalUniqueSelectors","uniqueRuleSize","uniqueSelectorsPerRule","uniqueDeclarationsPerRule","stylesheet","sourceLinesOfCode","linesOfCode","comments","atrules","fontface","import","media","browserhacks","charset","prefixed","container","layer","rules","empty","sizes","items","selectors","declarations","id","accessibility","importants","inKeyframes","custom","values","zindexes","animations","prefixes","__meta__","parseTime","analyzeTime"],"mappings":"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"}
|
package/dist/analyzer.modern.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import e from"css-tree/parser";import t from"css-tree/walker";function n(e,t){return t>=65&&t<=90&&(t|=32),e===t}function i(e,t){const i=t.length-e.length;if(i<0)return!1;for(let r=t.length-1;r>=i;r--)if(!1===n(e.charCodeAt(r-i),t.charCodeAt(r)))return!1;return!0}function r(e,t){if(t.length<e.length)return!1;for(let i=0;i<e.length;i++)if(!1===n(e.charCodeAt(i),t.charCodeAt(i)))return!1;return!0}function a(e,t){return e[0]===t[0]?e[1]===t[1]?t[2]-e[2]:t[1]-e[1]:t[0]-e[0]}const s=e=>{let n=0,i=0,o=0,l=0,u=!1;return t(e,function(e){switch(e.type){case"IdSelector":n++,l++;break;case"ClassSelector":i++,l++;break;case"AttributeSelector":i++,l++,Boolean(e.value)&&l++,u="role"===e.name.name||r("aria-",e.name.name);break;case"PseudoElementSelector":case"TypeSelector":if(l++,42===e.name.charCodeAt(0)&&1===e.name.length)break;o++;break;case"PseudoClassSelector":switch(e.name){case"before":case"after":case"first-letter":case"first-line":return o++,l++,this.skip;case"where":case"is":case"has":case"matches":case"-webkit-any":case"-moz-any":case"not":case"nth-child":case"nth-last-child":{"nth-child"!==e.name&&"nth-last-child"!==e.name||i++;const r=function(e){const n=[];return t(e,{visit:"Selector",enter(e){n.push(s(e))}}),n.sort((e,t)=>a(e.specificity,t.specificity))}(e);if(0===r.length)return;if("where"!==e.name){const[e,t,a]=r[0].specificity;n+=e,i+=t,o+=a}for(let e=0;e<r.length;e++){const t=r[e];t.isA11y&&(u=!0),l+=t.complexity}return l++,this.skip}default:return l++,i++,this.skip}case"Combinator":l++}}),{specificity:[n,i,o],complexity:l,isId:n>0,isA11y:u}},o={aliceblue:1,antiquewhite:1,aqua:1,aquamarine:1,azure:1,beige:1,bisque:1,black:1,blanchedalmond:1,blue:1,blueviolet:1,brown:1,burlywood:1,cadetblue:1,chartreuse:1,chocolate:1,coral:1,cornflowerblue:1,cornsilk:1,crimson:1,cyan:1,darkblue:1,darkcyan:1,darkgoldenrod:1,darkgray:1,darkgreen:1,darkgrey:1,darkkhaki:1,darkmagenta:1,darkolivegreen:1,darkorange:1,darkorchid:1,darkred:1,darksalmon:1,darkseagreen:1,darkslateblue:1,darkslategray:1,darkslategrey:1,darkturquoise:1,darkviolet:1,deeppink:1,deepskyblue:1,dimgray:1,dimgrey:1,dodgerblue:1,firebrick:1,floralwhite:1,forestgreen:1,fuchsia:1,gainsboro:1,ghostwhite:1,gold:1,goldenrod:1,gray:1,green:1,greenyellow:1,grey:1,honeydew:1,hotpink:1,indianred:1,indigo:1,ivory:1,khaki:1,lavender:1,lavenderblush:1,lawngreen:1,lemonchiffon:1,lightblue:1,lightcoral:1,lightcyan:1,lightgoldenrodyellow:1,lightgray:1,lightgreen:1,lightgrey:1,lightpink:1,lightsalmon:1,lightseagreen:1,lightskyblue:1,lightslategray:1,lightslategrey:1,lightsteelblue:1,lightyellow:1,lime:1,limegreen:1,linen:1,magenta:1,maroon:1,mediumaquamarine:1,mediumblue:1,mediumorchid:1,mediumpurple:1,mediumseagreen:1,mediumslateblue:1,mediumspringgreen:1,mediumturquoise:1,mediumvioletred:1,midnightblue:1,mintcream:1,mistyrose:1,moccasin:1,navajowhite:1,navy:1,oldlace:1,olive:1,olivedrab:1,orange:1,orangered:1,orchid:1,palegoldenrod:1,palegreen:1,paleturquoise:1,palevioletred:1,papayawhip:1,peachpuff:1,peru:1,pink:1,plum:1,powderblue:1,purple:1,rebeccapurple:1,red:1,rosybrown:1,royalblue:1,saddlebrown:1,salmon:1,sandybrown:1,seagreen:1,seashell:1,sienna:1,silver:1,skyblue:1,slateblue:1,slategray:1,slategrey:1,snow:1,springgreen:1,steelblue:1,tan:1,teal:1,thistle:1,tomato:1,turquoise:1,violet:1,wheat:1,white:1,whitesmoke:1,yellow:1,yellowgreen:1,canvas:1,canvastext:1,linktext:1,visitedtext:1,activetext:1,buttonface:1,buttontext:1,buttonborder:1,field:1,fieldtext:1,highlight:1,highlighttext:1,selecteditem:1,selecteditemtext:1,mark:1,marktext:1,graytext:1},l={rgb:1,rgba:1,hsl:1,hsla:1,hwb:1,lab:1,lch:1,oklab:1,oklch:1,color:1},u={inherit:1,initial:1,unset:1,revert:1,caption:1,icon:1,menu:1,"message-box":1,"small-caption":1,"status-bar":1},c={normal:1,"xx-small":1,"x-small":1,small:1,medium:1,large:1,"x-large":1,"xx-large":1,larger:1,smaller:1,bold:1,bolder:1,lighter:1,"ultra-condensed":1,"extra-condensed":1,condensed:1,"semi-condensed":1,"semi-expanded":1,expanded:1,"extra-expanded":1,"ultra-expanded":1,italic:1,oblique:1};function d(e){const t=e.children.first;return"Identifier"===t.type&&u[t.name]}const h={"xx-small":1,"x-small":1,small:1,medium:1,large:1,"x-large":1,"xx-large":1,larger:1,smaller:1},m={inherit:1,initial:1,unset:1,revert:1,caption:1,icon:1,menu:1,"message-box":1,"small-caption":1,"status-bar":1};function f(e){const t=e.children.first;return"Identifier"===t.type&&m[t.name]}const b={auto:1,inherit:1,initial:1,unset:1,revert:1,none:1};function g(e){if(!e.children)return!1;const t=e.children.first;return!!t&&!(e.children.size>1)&&"Identifier"===t.type&&b[t.name]}const w={linear:1,ease:1,"ease-in":1,"ease-out":1,"ease-in-out":1,"step-start":1,"step-end":1};function p(e){return 45===e.charCodeAt(0)&&45!==e.charCodeAt(1)&&-1!==e.indexOf("-",2)}function k(e){if(!e.children)return!1;const t=e.children.toArray();for(let e=0;e<t.length;e++){const n=t[e],{type:i,name:r}=n;if("Identifier"===i&&p(r))return!0;if("Function"===i){if(p(r))return!0;if(k(n))return!0}}return!1}class y{constructor(e){if(this.t={},this.i=0,this.o=0,e)for(let t=0;t<e.length;t++)this.push(e[t])}push(e){this.i++,this.t[e]?this.t[e]++:(this.t[e]=1,this.o++)}size(){return this.i}count(){return{total:this.i,totalUnique:this.o,unique:this.t,uniquenessRatio:0===this.i?0:this.o/this.i}}}class x{constructor(){this.l=new y,this.u={}}push(e,t){this.l.push(e),this.u[t]||(this.u[t]=new y),this.u[t].push(e)}count(){const e={};for(let t in this.u)e[t]=this.u[t].count();return Object.assign(this.l.count(),{itemsPerContext:e})}}class v{constructor(){this.t=[]}add(e){this.t.push(e)}size(){return this.t.length}aggregate(){if(0===this.t.length)return{min:0,max:0,mean:0,mode:0,median:0,range:0,sum:0};const e=this.t.slice().sort((e,t)=>e-t),t=e[0],n=e[e.length-1],i=this.t.reduce((e,t)=>e+t),r=function(e){const t=Object.create(null);let n=-1,i=0,r=0;for(let a=0;a<e.length;a++){const s=e[a],o=(t[s]||0)+1;t[s]=o,o>n&&(n=o,i=0,r=0),o>=n&&(i++,r+=s)}return r/i}(this.t),a=function(e){const t=e.length/2,n=Math.floor(t);return t!==n?e[n]:(e[n]+e[n-1])/2}(e);return{min:t,max:n,mean:i/this.t.length,mode:r,median:a,range:n-t,sum:i}}toArray(){return this.t}}function q(e){return!(e.length<3)&&45===e.charCodeAt(0)&&45===e.charCodeAt(1)}function z(e,t){return!q(t)&&i(e,t)}class S{constructor(){this.t=Object.create(null)}push(e){return this.t[e]?this.t[e]++:this.t[e]=1}count(){return Object.keys(this.t).length}}const I=u=>{const m=new Date,b=u.split(/\r?\n/);function I(e){const t=e.loc.start,n=e.loc.end;if(0==n.line-t.line)return b[t.line-1].substring(t.column-1,n.column-1);let i="";for(let e=t.line;e<=n.line;e++){const r=b[e-1];i+=e!==t.line?e!==n.line?r+"\n":r.substring(0,n.column-1):r.substring(t.column-1)+"\n"}return i}let O=0,C=0;const D=new y,R=new Date,U=e(u,{parseAtrulePrelude:!1,parseCustomProperty:!0,positions:!0,onComment:function(e){O++,C+=e.length}}),j=new Date;let A=0;const F=[],P=new y,_=new y,T=new y,B=new y,E=new y,H=new y,K=new y,L=new y;let M=0,N=0;const V=new v,G=new v,J=new v,Q=new y,W=new S;let X,Y;const Z=new v,$=new v,ee=new v,te=new y,ne=new v,ie=[],re=new y,ae=new y,se=new S;let oe=0,le=0,ue=0;const ce=new y,de=new y,he=new y,me=new y,fe=new y,be=new y,ge=new y,we=new y,pe=new y,ke=new y,ye=new y,xe=new y,ve=new x,qe=new x;t(U,function(e){switch(e.type){case"Atrule":{A++;const t=e.name;if("font-face"===t){const t={};e.block.children.forEach(e=>t[e.property]=I(e.value)),F.push(t);break}if("media"===t){T.push(e.prelude.value);break}if("supports"===t){E.push(e.prelude.value);break}if(i("keyframes",t)){const n="@"+t+" "+e.prelude.value;p(t)&&K.push(n),H.push(n);break}if("import"===t){_.push(e.prelude.value);break}if("charset"===t){B.push(e.prelude.value);break}if("container"===t){L.push(e.prelude.value);break}"layer"===t&&L.push(e.prelude.value.trim().split(",").map(e=>e.trim()).forEach(e=>P.push(e)));break}case"Rule":{const t=e.prelude.children?e.prelude.children.size:0,n=e.block.children?e.block.children.size:0;V.add(t+n),G.add(t),J.add(n),M++,0===n&&N++;break}case"Selector":{const t=I(e);if(this.atrule&&i("keyframes",this.atrule.name))return Q.push(t),this.skip;const{specificity:n,complexity:r,isId:o,isA11y:l}=s(e);return o&&re.push(t),l&&ae.push(t),W.push(t),ne.add(r),te.push(n),void 0===X&&(X=n),void 0===Y&&(Y=n),Z.add(n[0]),$.add(n[1]),ee.add(n[2]),void 0!==Y&&a(Y,n)<0&&(Y=n),void 0!==X&&a(X,n)>0&&(X=n),ie.push(n),this.skip}case"Dimension":if(!this.declaration)break;return qe.push(e.unit,this.declaration.property),this.skip;case"Url":r("data:",e.value)&&D.push(e.value);break;case"Value":{if(g(e))break;const i=this.declaration.property;if(k(e)&&fe.push(I(e)),z("z-index",i))return g(e)||be.push(I(e)),this.skip;if(z("font",i)){if(d(e)||pe.push(function(e,n){let i="";return t(e,{reverse:!0,enter:function(e){if("String"===e.type){const t=e.loc.start,r=n({loc:{start:{line:t.line,column:t.column},end:{line:t.line,column:t.column+1}}});return i=r+e.value+r+i}return"Operator"===e.type&&44===e.value.charCodeAt(0)?i=e.value+i:"Identifier"===e.type?c[e.name]?this.skip:i=e.name+i:void 0}}),i}(e,I)),!f(e)){const n=function(e){let n,i=!1;return t(e,function(e){switch(e.type){case"Number":if(48===e.value.charCodeAt(0))return n="0",this.break;case"Operator":47===e.value.charCodeAt(0)&&(i=!0);break;case"Dimension":if(!i)return n=e.value+e.unit,this.break;case"Identifier":if(h[e.name])return n=e.name,this.break}}),n}(e);n&&ke.push(n)}break}if(z("font-size",i)){f(e)||ke.push(I(e));break}if(z("font-family",i)){d(e)||pe.push(I(e));break}if(z("transition",i)||z("animation",i)){const[t,n]=function(e,t){let n=!1;const i=[],r=[];return e.forEach(e=>"Operator"===e.type?n=!1:"Dimension"===e.type&&!1===n?(n=!0,i.push(t(e))):"Identifier"===e.type&&w[e.name]?r.push(t(e)):"Function"!==e.type||"cubic-bezier"!==e.name&&"steps"!==e.name?void 0:r.push(t(e))),[i,r]}(e.children,I);for(let e=0;e<t.length;e++)xe.push(t[e]);for(let e=0;e<n.length;e++)ye.push(n[e]);break}if(z("animation-duration",i)||z("transition-duration",i)){xe.push(I(e));break}if(z("transition-timing-function",i)||z("animation-timing-function",i)){ye.push(I(e));break}z("text-shadow",i)?g(e)||ge.push(I(e)):z("box-shadow",i)&&(g(e)||we.push(I(e))),t(e,function(e){switch(e.type){case"Hash":return ve.push("#"+e.value,i),this.skip;case"Identifier":{const{name:t}=e;return t.length>20||t.length<3||o[t.toLowerCase()]&&ve.push(I(e),i),this.skip}case"Function":if(function(e,t){if(e.length!==t.length)return!1;for(let i=0;i<e.length;i++)if(!1===n(e.charCodeAt(i),t.charCodeAt(i)))return!1;return!0}("var",e.name))return this.skip;l[e.name.toLowerCase()]&&ve.push(I(e),i)}});break}case"Declaration":{oe++;const t=I(e);se.push(t),e.important&&(le++,this.atrule&&i("keyframes",this.atrule.name)&&ue++);const{property:n}=e;ce.push(n),p(n)?he.push(n):function(e){if(q(e)||p(e))return!1;let t=e.charCodeAt(0);return 47===t||95===t||43===t||42===t||38===t||36===t||35===t}(n)?de.push(n):q(n)&&me.push(n);break}}});const ze=D.count(),Se=Object.keys(ze.unique).join("").length,Ie=se.count(),Oe=ne.size(),Ce=Z.aggregate(),De=$.aggregate(),Re=ee.aggregate(),Ue=te.count(),je=new y(ne.toArray()).count(),Ae=W.count(),Fe=new y(V.toArray()).count(),Pe=new y(G.toArray()).count(),_e=new y(J.toArray()).count(),Te=Object.assign;return{stylesheet:{sourceLinesOfCode:A+Oe+oe+Q.size(),linesOfCode:b.length,size:u.length,comments:{total:O,size:C},embeddedContent:Te(ze,{size:{total:Se,ratio:0===u.length?0:Se/u.length}})},atrules:{fontface:{total:F.length,totalUnique:F.length,unique:F,uniquenessRatio:0===F.length?0:1},import:_.count(),media:T.count(),charset:B.count(),supports:E.count(),keyframes:Te(H.count(),{prefixed:Te(K.count(),{ratio:0===H.size()?0:K.size()/H.size()})}),container:L.count(),layer:P.count()},rules:{total:M,empty:{total:N,ratio:0===M?0:N/M},sizes:Te(V.aggregate(),{items:V.toArray(),unique:Fe.unique,totalUnique:Fe.totalUnique,uniquenessRatio:Fe.uniquenessRatio}),selectors:Te(G.aggregate(),{items:G.toArray(),unique:Pe.unique,totalUnique:Pe.totalUnique,uniquenessRatio:Pe.uniquenessRatio}),declarations:Te(J.aggregate(),{items:J.toArray(),unique:_e.unique,totalUnique:_e.totalUnique,uniquenessRatio:_e.uniquenessRatio})},selectors:{total:Oe,totalUnique:Ae,uniquenessRatio:0===Oe?0:Ae/Oe,specificity:{min:void 0===Y?[0,0,0]:Y,max:void 0===X?[0,0,0]:X,sum:[Ce.sum,De.sum,Re.sum],mean:[Ce.mean,De.mean,Re.mean],mode:[Ce.mode,De.mode,Re.mode],median:[Ce.median,De.median,Re.median],items:ie,unique:Ue.unique,totalUnique:Ue.totalUnique,uniquenessRatio:Ue.uniquenessRatio},complexity:Te(ne.aggregate(),je,{items:ne.toArray()}),id:Te(re.count(),{ratio:0===Oe?0:re.size()/Oe}),accessibility:Te(ae.count(),{ratio:0===Oe?0:ae.size()/Oe}),keyframes:Q.count()},declarations:{total:oe,unique:{total:Ie,ratio:0===oe?0:Ie/oe},importants:{total:le,ratio:0===oe?0:le/oe,inKeyframes:{total:ue,ratio:0===le?0:ue/le}}},properties:Te(ce.count(),{prefixed:Te(he.count(),{ratio:0===ce.size()?0:he.size()/ce.size()}),custom:Te(me.count(),{ratio:0===ce.size()?0:me.size()/ce.size()}),browserhacks:Te(de.count(),{ratio:0===ce.size()?0:de.size()/ce.size()})}),values:{colors:ve.count(),fontFamilies:pe.count(),fontSizes:ke.count(),zindexes:be.count(),textShadows:ge.count(),boxShadows:we.count(),animations:{durations:xe.count(),timingFunctions:ye.count()},prefixes:fe.count(),units:qe.count()},__meta__:{parseTime:j-R,analyzeTime:new Date-j,total:new Date-m}}};export{I as analyze,a as compareSpecificity};
|
|
1
|
+
import e from"css-tree/parser";import t from"css-tree/walker";function n(e,t){return t>=65&&t<=90&&(t|=32),e===t}function i(e,t){if(e.length!==t.length)return!1;for(let i=0;i<e.length;i++)if(!1===n(e.charCodeAt(i),t.charCodeAt(i)))return!1;return!0}function r(e,t){const i=t.length-e.length;if(i<0)return!1;for(let r=t.length-1;r>=i;r--)if(!1===n(e.charCodeAt(r-i),t.charCodeAt(r)))return!1;return!0}function a(e,t){if(t.length<e.length)return!1;for(let i=0;i<e.length;i++)if(!1===n(e.charCodeAt(i),t.charCodeAt(i)))return!1;return!0}function s(e,t,n){return i(t,e.property)&&"Identifier"===e.value.children.first.type&&i(n,e.value.children.first.name)}function o(e){return 45===e.charCodeAt(0)&&45!==e.charCodeAt(1)&&-1!==e.indexOf("-",2)}function l(e,t){return e[0]===t[0]?e[1]===t[1]?t[2]-e[2]:t[1]-e[1]:t[0]-e[0]}const u=e=>{let n=0,r=0,s=0,c=0,h=!1;return t(e,function(e){switch(e.type){case"IdSelector":n++,c++;break;case"ClassSelector":r++,c++;break;case"AttributeSelector":r++,c++,Boolean(e.value)&&c++,(i("role",e.name.name)||a("aria-",e.name.name))&&(h=!0);break;case"PseudoElementSelector":case"TypeSelector":if(c++,o(e.name)&&c++,42===e.name.charCodeAt(0)&&1===e.name.length)break;s++;break;case"PseudoClassSelector":switch(e.name){case"before":case"after":case"first-letter":case"first-line":return s++,c++,this.skip;case"where":case"is":case"has":case"matches":case"-webkit-any":case"-moz-any":case"not":case"nth-child":case"nth-last-child":{o(e.name)&&c++,"nth-child"!==e.name&&"nth-last-child"!==e.name||r++;const i=function(e){const n=[];return t(e,{visit:"Selector",enter(e){n.push(u(e))}}),n.sort((e,t)=>l([e[0],e[1],e[2]],[t[0],t[1],t[2]]))}(e);if(0===i.length)return;if("where"!==e.name){const[e,t,a]=i[0];n+=e,r+=t,s+=a}for(let e=0;e<i.length;e++){const t=i[e];1===t[4]&&(h=!0),c+=t[3]}return c++,this.skip}default:return c++,r++,this.skip}case"Combinator":c++}}),[n,r,s,c,h?1:0]},c={aliceblue:1,antiquewhite:1,aqua:1,aquamarine:1,azure:1,beige:1,bisque:1,black:1,blanchedalmond:1,blue:1,blueviolet:1,brown:1,burlywood:1,cadetblue:1,chartreuse:1,chocolate:1,coral:1,cornflowerblue:1,cornsilk:1,crimson:1,cyan:1,darkblue:1,darkcyan:1,darkgoldenrod:1,darkgray:1,darkgreen:1,darkgrey:1,darkkhaki:1,darkmagenta:1,darkolivegreen:1,darkorange:1,darkorchid:1,darkred:1,darksalmon:1,darkseagreen:1,darkslateblue:1,darkslategray:1,darkslategrey:1,darkturquoise:1,darkviolet:1,deeppink:1,deepskyblue:1,dimgray:1,dimgrey:1,dodgerblue:1,firebrick:1,floralwhite:1,forestgreen:1,fuchsia:1,gainsboro:1,ghostwhite:1,gold:1,goldenrod:1,gray:1,green:1,greenyellow:1,grey:1,honeydew:1,hotpink:1,indianred:1,indigo:1,ivory:1,khaki:1,lavender:1,lavenderblush:1,lawngreen:1,lemonchiffon:1,lightblue:1,lightcoral:1,lightcyan:1,lightgoldenrodyellow:1,lightgray:1,lightgreen:1,lightgrey:1,lightpink:1,lightsalmon:1,lightseagreen:1,lightskyblue:1,lightslategray:1,lightslategrey:1,lightsteelblue:1,lightyellow:1,lime:1,limegreen:1,linen:1,magenta:1,maroon:1,mediumaquamarine:1,mediumblue:1,mediumorchid:1,mediumpurple:1,mediumseagreen:1,mediumslateblue:1,mediumspringgreen:1,mediumturquoise:1,mediumvioletred:1,midnightblue:1,mintcream:1,mistyrose:1,moccasin:1,navajowhite:1,navy:1,oldlace:1,olive:1,olivedrab:1,orange:1,orangered:1,orchid:1,palegoldenrod:1,palegreen:1,paleturquoise:1,palevioletred:1,papayawhip:1,peachpuff:1,peru:1,pink:1,plum:1,powderblue:1,purple:1,rebeccapurple:1,red:1,rosybrown:1,royalblue:1,saddlebrown:1,salmon:1,sandybrown:1,seagreen:1,seashell:1,sienna:1,silver:1,skyblue:1,slateblue:1,slategray:1,slategrey:1,snow:1,springgreen:1,steelblue:1,tan:1,teal:1,thistle:1,tomato:1,turquoise:1,violet:1,wheat:1,white:1,whitesmoke:1,yellow:1,yellowgreen:1,canvas:1,canvastext:1,linktext:1,visitedtext:1,activetext:1,buttonface:1,buttontext:1,buttonborder:1,field:1,fieldtext:1,highlight:1,highlighttext:1,selecteditem:1,selecteditemtext:1,mark:1,marktext:1,graytext:1},h={rgb:1,rgba:1,hsl:1,hsla:1,hwb:1,lab:1,lch:1,oklab:1,oklch:1,color:1},d={inherit:1,initial:1,unset:1,revert:1,caption:1,icon:1,menu:1,"message-box":1,"small-caption":1,"status-bar":1},m={normal:1,"xx-small":1,"x-small":1,small:1,medium:1,large:1,"x-large":1,"xx-large":1,larger:1,smaller:1,bold:1,bolder:1,lighter:1,"ultra-condensed":1,"extra-condensed":1,condensed:1,"semi-condensed":1,"semi-expanded":1,expanded:1,"extra-expanded":1,"ultra-expanded":1,italic:1,oblique:1};function f(e){const t=e.children.first;return"Identifier"===t.type&&d[t.name]}const b={"xx-small":1,"x-small":1,small:1,medium:1,large:1,"x-large":1,"xx-large":1,larger:1,smaller:1},g={inherit:1,initial:1,unset:1,revert:1,caption:1,icon:1,menu:1,"message-box":1,"small-caption":1,"status-bar":1};function w(e){const t=e.children.first;return"Identifier"===t.type&&g[t.name]}const p={auto:1,inherit:1,initial:1,unset:1,revert:1,none:1};function k(e){if(!e.children)return!1;const t=e.children.first;return!!t&&!(e.children.size>1)&&"Identifier"===t.type&&p[t.name]}const y={linear:1,ease:1,"ease-in":1,"ease-out":1,"ease-in-out":1,"step-start":1,"step-end":1};function x(e){if(!e.children)return!1;const t=e.children.toArray();for(let e=0;e<t.length;e++){const n=t[e],{type:i,name:r}=n;if("Identifier"===i&&o(r))return!0;if("Function"===i){if(o(r))return!0;if(x(n))return!0}}return!1}class v{constructor(e){if(this.t={},this.i=0,this.o=0,e)for(let t=0;t<e.length;t++)this.push(e[t])}push(e){this.i++,this.t[e]?this.t[e]++:(this.t[e]=1,this.o++)}size(){return this.i}count(){return{total:this.i,totalUnique:this.o,unique:this.t,uniquenessRatio:0===this.i?0:this.o/this.i}}}class q{constructor(){this.l=new v,this.u={}}push(e,t){this.l.push(e),this.u[t]||(this.u[t]=new v),this.u[t].push(e)}count(){const e={};for(let t in this.u)e[t]=this.u[t].count();return Object.assign(this.l.count(),{itemsPerContext:e})}}class z{constructor(){this.t=[]}push(e){this.t.push(e)}size(){return this.t.length}aggregate(){if(0===this.t.length)return{min:0,max:0,mean:0,mode:0,median:0,range:0,sum:0};const e=this.t.slice().sort((e,t)=>e-t),t=e[0],n=e[e.length-1],i=this.t.reduce((e,t)=>e+t),r=function(e){const t=Object.create(null);let n=-1,i=0,r=0;for(let a=0;a<e.length;a++){const s=e[a],o=(t[s]||0)+1;t[s]=o,o>n&&(n=o,i=0,r=0),o>=n&&(i++,r+=s)}return r/i}(this.t),a=function(e){const t=e.length/2,n=Math.floor(t);return t!==n?e[n]:(e[n]+e[n-1])/2}(e);return{min:t,max:n,mean:i/this.t.length,mode:r,median:a,range:n-t,sum:i}}toArray(){return this.t}}function I(e){return!(e.length<3)&&45===e.charCodeAt(0)&&45===e.charCodeAt(1)}function S(e,t){return!I(t)&&r(e,t)}class O{constructor(){this.t=Object.create(null)}push(e){const t=function(e){let t=167;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t*=403;return t}(e);this.t[t]||(this.t[t]=1)}count(){return Object.keys(this.t).length}}function D(e,t){return 0===t?0:e/t}const C=n=>{const d=Date.now(),g=n.split(/\r?\n/);function p(e){const t=e.loc.start,n=e.loc.end;if(0==n.line-t.line)return g[t.line-1].substring(t.column-1,n.column-1);let i="";for(let e=t.line;e<=n.line;e++){const r=g[e-1];i+=e!==t.line?e!==n.line?r+"\n":r.substring(0,n.column-1):r.substring(t.column-1)+"\n"}return i}let C=0,R=0;const U=new v,j=Date.now(),F=e(n,{parseCustomProperty:!0,positions:!0,onComment:function(e){C++,R+=e.length}}),P=Date.now();let _=0;const A=[],M=new v,T=new v,B=new v,E=new v,H=new v,K=new v,L=new v,N=new v,Q=new v,V=new v;let G=0,J=0;const W=new z,X=new z,Y=new z,Z=new v,$=new O;let ee,te;const ne=new z,ie=new z,re=new z,ae=new v,se=new z,oe=[],le=new v,ue=new v,ce=new O;let he=0,de=0,me=0;const fe=new v,be=new v,ge=new v,we=new v,pe=new z,ke=new v,ye=new v,xe=new v,ve=new v,qe=new v,ze=new v,Ie=new v,Se=new v,Oe=new v,De=new q,Ce=new q;t(F,function(e){switch(e.type){case"Atrule":{_++;const n=e.name;if("font-face"===n){const t={};e.block.children.forEach(e=>t[e.property]=p(e.value)),A.push(t);break}if("media"===n){const n=p(e.prelude);B.push(n),function(e){let n=!1;return t(e,function(e){if("MediaQuery"===e.type&&1===e.children.size&&"Identifier"===e.children.first.type&&(a("\\0",(e=e.children.first).name)||r("\\9 ",e.name)))return n=!0,this.break;if("MediaFeature"===e.type){if(null!==e.value&&"\\0"===e.value.unit)return n=!0,this.break;if(i("-moz-images-in-menus",e.name)||i("min--moz-device-pixel-ratio",e.name)||i("-ms-high-contrast",e.name))return n=!0,this.break;if(i("min-resolution",e.name)&&i(".001",e.value.value)&&i("dpcm",e.value.unit))return n=!0,this.break;if(i("-webkit-min-device-pixel-ratio",e.name)&&(i("0",e.value.value)||i("10000",e.value.value)))return n=!0,this.break}}),n}(e.prelude)&&E.push(n);break}if("supports"===n){const n=p(e.prelude);K.push(n),function(e){let n=!1;return t(e,function(e){if("Declaration"===e.type&&(s(e,"-webkit-appearance","none")||s(e,"-moz-appearance","meterbar")))return n=!0,this.break}),n}(e.prelude)&&L.push(n);break}if(r("keyframes",n)){const t="@"+n+" "+p(e.prelude);o(n)&&Q.push(t),N.push(t);break}if("import"===n){T.push(p(e.prelude));break}if("charset"===n){H.push(p(e.prelude));break}if("container"===n){V.push(p(e.prelude));break}"layer"===n&&p(e.prelude).trim().split(",").forEach(e=>M.push(e.trim()));break}case"Rule":{const t=e.prelude.children?e.prelude.children.size:0,n=e.block.children?e.block.children.size:0;W.push(t+n),X.push(t),Y.push(n),G++,0===n&&J++;break}case"Selector":{const t=p(e);if(this.atrule&&r("keyframes",this.atrule.name))return Z.push(t),this.skip;const n=u(e),i=n.splice(0,3),[a,s]=n;return i[0]>0&&le.push(t),1===s&&ue.push(t),$.push(t),se.push(a),ae.push(i),void 0===ee&&(ee=i),void 0===te&&(te=i),ne.push(i[0]),ie.push(i[1]),re.push(i[2]),void 0!==te&&l(te,i)<0&&(te=i),void 0!==ee&&l(ee,i)>0&&(ee=i),oe.push(i),this.skip}case"Dimension":if(!this.declaration)break;return Ce.push(e.unit,this.declaration.property),this.skip;case"Url":a("data:",e.value)&&U.push(e.value);break;case"Value":{if(k(e))break;const n=this.declaration,{property:a,important:s}=n;if(x(e)&&ke.push(p(e)),"string"==typeof s&&ye.push(p(e)+"!"+s),e.children&&e.children.last&&"Identifier"===e.children.last.type&&r("\\9",e.children.last.name)&&ye.push(p(e)),S("z-index",a))return k(e)||xe.push(p(e)),this.skip;if(S("font",a)){if(f(e)||ze.push(function(e,n){let i="";return t(e,{reverse:!0,enter:function(e){if("String"===e.type){const t=e.loc.start,r=n({loc:{start:{line:t.line,column:t.column},end:{line:t.line,column:t.column+1}}});return i=r+e.value+r+i}return"Operator"===e.type&&44===e.value.charCodeAt(0)?i=e.value+i:"Identifier"===e.type?m[e.name]?this.skip:i=e.name+i:void 0}}),i}(e,p)),!w(e)){const n=function(e){let n,i=!1;return t(e,function(e){switch(e.type){case"Number":if(48===e.value.charCodeAt(0))return n="0",this.break;case"Operator":47===e.value.charCodeAt(0)&&(i=!0);break;case"Dimension":if(!i)return n=e.value+e.unit,this.break;case"Identifier":if(b[e.name])return n=e.name,this.break}}),n}(e);n&&Ie.push(n)}break}if(S("font-size",a)){w(e)||Ie.push(p(e));break}if(S("font-family",a)){f(e)||ze.push(p(e));break}if(S("transition",a)||S("animation",a)){const[t,n]=function(e,t){let n=!1;const i=[],r=[];return e.forEach(e=>"Operator"===e.type?n=!1:"Dimension"===e.type&&!1===n?(n=!0,i.push(t(e))):"Identifier"===e.type&&y[e.name]?r.push(t(e)):"Function"!==e.type||"cubic-bezier"!==e.name&&"steps"!==e.name?void 0:r.push(t(e))),[i,r]}(e.children,p);for(let e=0;e<t.length;e++)Oe.push(t[e]);for(let e=0;e<n.length;e++)Se.push(n[e]);break}if(S("animation-duration",a)||S("transition-duration",a)){Oe.push(p(e));break}if(S("transition-timing-function",a)||S("animation-timing-function",a)){Se.push(p(e));break}S("text-shadow",a)?k(e)||ve.push(p(e)):S("box-shadow",a)&&(k(e)||qe.push(p(e))),t(e,function(e){switch(e.type){case"Hash":return De.push("#"+e.value,a),this.skip;case"Identifier":{const{name:t}=e;return t.length>20||t.length<3||c[t.toLowerCase()]&&De.push(p(e),a),this.skip}case"Function":if(i("var",e.name))return this.skip;h[e.name.toLowerCase()]&&De.push(p(e),a)}});break}case"Declaration":{if(null!==this.atrulePrelude)return this.skip;he++;const t=p(e);ce.push(t),!0===e.important&&(de++,this.atrule&&r("keyframes",this.atrule.name)&&me++);const{property:n}=e;fe.push(n),o(n)?(ge.push(n),pe.push(2)):function(e){if(I(e)||o(e))return!1;let t=e.charCodeAt(0);return 47===t||95===t||43===t||42===t||38===t||36===t||35===t}(n)?(be.push(n),pe.push(2)):I(n)?(we.push(n),pe.push(2)):pe.push(1);break}}});const Re=U.count(),Ue=Object.keys(Re.unique).join("").length,je=ce.count(),Fe=se.size(),Pe=ne.aggregate(),_e=ie.aggregate(),Ae=re.aggregate(),Me=ae.count(),Te=new v(se.toArray()).count(),Be=$.count(),Ee=new v(W.toArray()).count(),He=new v(X.toArray()).count(),Ke=new v(Y.toArray()).count(),Le=Object.assign;return{stylesheet:{sourceLinesOfCode:_+Fe+he+Z.size(),linesOfCode:g.length,size:n.length,comments:{total:C,size:R},embeddedContent:Le(Re,{size:{total:Ue,ratio:D(Ue,n.length)}})},atrules:{fontface:{total:A.length,totalUnique:A.length,unique:A,uniquenessRatio:0===A.length?0:1},import:T.count(),media:Le(B.count(),{browserhacks:E.count()}),charset:H.count(),supports:Le(K.count(),{browserhacks:L.count()}),keyframes:Le(N.count(),{prefixed:Le(Q.count(),{ratio:D(Q.size(),N.size())})}),container:V.count(),layer:M.count()},rules:{total:G,empty:{total:J,ratio:D(J,G)},sizes:Le(W.aggregate(),{items:W.toArray(),unique:Ee.unique,totalUnique:Ee.totalUnique,uniquenessRatio:Ee.uniquenessRatio}),selectors:Le(X.aggregate(),{items:X.toArray(),unique:He.unique,totalUnique:He.totalUnique,uniquenessRatio:He.uniquenessRatio}),declarations:Le(Y.aggregate(),{items:Y.toArray(),unique:Ke.unique,totalUnique:Ke.totalUnique,uniquenessRatio:Ke.uniquenessRatio})},selectors:{total:Fe,totalUnique:Be,uniquenessRatio:D(Be,Fe),specificity:{min:void 0===te?[0,0,0]:te,max:void 0===ee?[0,0,0]:ee,sum:[Pe.sum,_e.sum,Ae.sum],mean:[Pe.mean,_e.mean,Ae.mean],mode:[Pe.mode,_e.mode,Ae.mode],median:[Pe.median,_e.median,Ae.median],items:oe,unique:Me.unique,totalUnique:Me.totalUnique,uniquenessRatio:Me.uniquenessRatio},complexity:Le(se.aggregate(),Te,{items:se.toArray()}),id:Le(le.count(),{ratio:D(le.size(),Fe)}),accessibility:Le(ue.count(),{ratio:D(ue.size(),Fe)}),keyframes:Z.count()},declarations:{total:he,totalUnique:je,uniquenessRatio:D(je,he),unique:{total:je,ratio:D(je,he)},importants:{total:de,ratio:D(de,he),inKeyframes:{total:me,ratio:D(me,de)}}},properties:Le(fe.count(),{prefixed:Le(ge.count(),{ratio:D(ge.size(),fe.size())}),custom:Le(we.count(),{ratio:D(we.size(),fe.size())}),browserhacks:Le(be.count(),{ratio:D(be.size(),fe.size())}),complexity:pe.aggregate()}),values:{colors:De.count(),fontFamilies:ze.count(),fontSizes:Ie.count(),zindexes:xe.count(),textShadows:ve.count(),boxShadows:qe.count(),animations:{durations:Oe.count(),timingFunctions:Se.count()},prefixes:ke.count(),browserhacks:ye.count(),units:Ce.count()},__meta__:{parseTime:P-j,analyzeTime:Date.now()-P,total:Date.now()-d}}};export{C as analyze,l as compareSpecificity};
|
|
2
2
|
//# sourceMappingURL=analyzer.modern.js.map
|