scancss
Version:
A robust CSS stylesheet statistics collector and analyzer
275 lines (205 loc) • 10.1 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = scancss;
var _gzipSize = require('gzip-size');
var _gzipSize2 = _interopRequireDefault(_gzipSize);
var _lodash = require('lodash.isplainobject');
var _lodash2 = _interopRequireDefault(_lodash);
var _isAtRuleDeclaration = require('./predicates/isAtRuleDeclaration');
var _handleComment = require('./handlers/handleComment');
var _handleAtRule = require('./handlers/atrules/handleAtRule');
var _handleRule = require('./handlers/handleRule');
var _handleDeclaration = require('./handlers/handleDeclaration');
var _roundDivision = require('./calculators/roundDivision');
var _percentDifference = require('./calculators/percentDifference');
var _difference = require('./converters/difference');
var _getEmptyReport = require('./common/getEmptyReport');
var _parseCss = require('./common/parseCss');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* eslint-disable-next-line complexity */
function scancss(src, options) {
if (typeof src !== 'string') {
throw new TypeError('`scancss` expects a string');
} else {
const cssRoot = (0, _parseCss.parseCss)(src);
const scancssOptions = Object.assign({}, {
size: true,
comments: true,
atRules: true,
rules: true,
selectors: true,
selectorsUsage: true,
attributesUsage: true,
selectorComplexityThreshold: 4,
specificityGraph: false,
declarations: true,
properties: true,
engineTriggerProperties: true,
uniqueDeclarationsList: false,
displays: true,
positions: true,
zIndices: true,
floats: true,
borderRadiuses: true,
widths: true,
heights: true,
letterSpacings: true,
fonts: true,
colors: true,
backgroundColors: true,
allColors: true,
transitionsAndAnimations: true,
functions: true,
filters: true,
gradients: true,
units: true,
variables: true,
dataUris: true,
browserHacks: true,
performanceHacks: true
}, (0, _lodash2.default)(options) && Object.keys(options).length > 0 ? options : {});
const report = (0, _getEmptyReport.getEmptyReport)();
if (scancssOptions.size) {
report.size.source = Buffer.byteLength(src, 'utf8');
report.size.gzipSource = _gzipSize2.default.sync(src);
}
cssRoot.walk(node => {
if (node.type === 'comment' && scancssOptions.comments) {
(0, _handleComment.handleComment)(node, report);
}
if (node.type === 'atrule' && scancssOptions.atRules) {
(0, _handleAtRule.handleAtRule)(node, report, scancssOptions);
}
if (node.type === 'rule' && scancssOptions.rules) {
(0, _handleRule.handleRule)(node, report, scancssOptions);
}
/**
* Some at-rules have special `descriptors` which are not declarations
*/
if (node.type === 'decl' && scancssOptions.declarations) {
if (node.parent.type === 'atrule' && (0, _isAtRuleDeclaration.isAtRuleDeclaration)(node.parent.name, node) === false) {
return;
}
(0, _handleDeclaration.handleDeclaration)(node, report, scancssOptions);
}
});
if (scancssOptions.comments) {
report.comments.sizeRatio = (0, _roundDivision.roundDivision)(report.comments.length.total, report.size.source);
report.comments.sizeRatioPercent = (0, _percentDifference.percentDifference)(report.size.source, report.comments.length.total);
report.comments.length.average = (0, _roundDivision.roundDivision)(report.comments.length.total, report.comments.total, 2);
}
if (scancssOptions.atRules) {
report.atRules.unknown.unique = Object.keys(report.atRules.unknown.usage).length;
report.atRules.descriptors.unique = Object.keys(report.atRules.descriptors.usage).length;
report.imports.unique = Object.keys(report.imports.usage).length;
report.mediaQueries.unique = Object.keys(report.mediaQueries.usage).length;
report.mediaQueries.types.unique = Object.keys(report.mediaQueries.types.usage).length;
report.mediaQueries.types.deprecated.unique = Object.keys(report.mediaQueries.types.deprecated.usage).length;
report.mediaQueries.features.unique = Object.keys(report.mediaQueries.features.usage).length;
report.mediaQueries.features.deprecated.unique = Object.keys(report.mediaQueries.features.deprecated.usage).length;
}
if (scancssOptions.selectors) {
report.selectors.sizeRatio = (0, _roundDivision.roundDivision)(report.selectors.length.total, report.size.source);
report.selectors.sizeRatioPercent = (0, _percentDifference.percentDifference)(report.size.source, report.selectors.length.total);
report.selectors.length.average = (0, _roundDivision.roundDivision)(report.selectors.length.total, report.selectors.total, 2);
report.selectors.averagePerRule = (0, _roundDivision.roundDivision)(report.selectors.total, report.rules.total, 2);
const highestSpecificitySelector = report.selectors.specificity.highest10[0];
if ((0, _lodash2.default)(highestSpecificitySelector)) {
report.selectors.specificity.highest = highestSpecificitySelector.specificity;
report.selectors.specificity.highestSelector = highestSpecificitySelector.selector;
}
report.selectors.specificity.average = [(0, _roundDivision.roundDivision)(report.selectors.specificity.total[0], report.selectors.total || 0, 2), (0, _roundDivision.roundDivision)(report.selectors.specificity.total[1], report.selectors.total || 0, 2), (0, _roundDivision.roundDivision)(report.selectors.specificity.total[2], report.selectors.total || 0, 2)];
report.selectors.unique = Object.keys(report.selectors.usage).length;
if (scancssOptions.selectorsUsage === false) {
report.selectors.usage = {};
}
}
if (scancssOptions.declarations) {
report.declarations.averagePerRule = (0, _roundDivision.roundDivision)(report.declarations.total, report.rules.total, 2);
report.declarations.unique = report.declarations.list.length;
if (scancssOptions.uniqueDeclarationsList === false) {
report.declarations.list.length = 0;
}
report.declarations.uniqueRatio = (0, _roundDivision.roundDivision)(report.declarations.unique, report.declarations.total);
report.declarations.length.average = (0, _roundDivision.roundDivision)(report.declarations.length.total, report.declarations.total, 2);
report.declarations.sizeRatio = (0, _roundDivision.roundDivision)(report.declarations.length.total, report.size.source);
report.declarations.sizeRatioPercent = (0, _percentDifference.percentDifference)(report.size.source, report.declarations.length.total);
}
if (scancssOptions.properties) {
report.properties.unique = Object.keys(report.properties.usage).length;
report.properties.uniqueRatio = (0, _roundDivision.roundDivision)(report.properties.unique, report.properties.total);
report.properties.shorthandsRatio = (0, _roundDivision.roundDivision)(report.properties.shorthands, report.properties.total);
}
if (scancssOptions.displays) {
report.displays.unique = Object.keys(report.displays.usage).length;
}
if (scancssOptions.positions) {
report.positions.unique = Object.keys(report.positions.usage).length;
}
if (scancssOptions.zIndices) {
report.zIndices.unique = Object.keys(report.zIndices.usage).length;
}
if (scancssOptions.floats) {
report.floats.unique = Object.keys(report.floats.usage).length;
}
if (scancssOptions.borderRadiuses) {
report.borderRadiuses.unique = Object.keys(report.borderRadiuses.usage).length;
}
if (scancssOptions.widths) {
report.widths.unique = Object.keys(report.widths.usage).length;
}
if (scancssOptions.heights) {
report.heights.unique = Object.keys(report.heights.usage).length;
}
if (scancssOptions.letterSpacings) {
report.letterSpacings.unique = Object.keys(report.letterSpacings.usage).length;
}
if (scancssOptions.fonts) {
report.fontSizes.unique = Object.keys(report.fontSizes.usage).length;
report.lineHeights.unique = Object.keys(report.lineHeights.usage).length;
report.fontFamilies.unique = Object.keys(report.fontFamilies.usage).length;
}
if (scancssOptions.functions) {
report.functions.unique = Object.keys(report.functions.usage).length;
}
if (scancssOptions.filters) {
report.filters.unique = Object.keys(report.filters.usage).length;
}
if (scancssOptions.gradients) {
report.gradients.unique = Object.keys(report.gradients.usage).length;
}
if (scancssOptions.units) {
report.units.unique = Object.keys(report.units.usage).length;
report.units.excessive.unique = Object.keys(report.units.excessive.usage).length;
report.units.unknown.unique = Object.keys(report.units.unknown.usage).length;
}
if (scancssOptions.variables) {
report.variables.unique = Object.keys(report.variables.usage).length;
}
if (scancssOptions.dataUris) {
report.dataUris.unique = Object.keys(report.dataUris.usage).length;
report.dataUris.length.average = (0, _roundDivision.roundDivision)(report.dataUris.length.total, report.dataUris.total, 2);
report.dataUris.sizeRatio = (0, _roundDivision.roundDivision)(report.dataUris.length.total, report.size.source);
report.dataUris.sizeRatioPercent = (0, _percentDifference.percentDifference)(report.size.source, report.dataUris.length.total);
}
if (scancssOptions.colors) {
report.colors.unique = Object.keys(report.colors.usage).length;
}
if (scancssOptions.backgroundColors) {
report.backgroundColors.unique = Object.keys(report.backgroundColors.usage).length;
}
if (scancssOptions.allColors) {
report.allColors.unique = Object.keys(report.allColors.usage).length;
}
if (scancssOptions.transitionsAndAnimations) {
report.animations.unique = Object.keys(report.animations.usage).length;
report.animations.withoutDefinitions = (0, _difference.difference)(Object.keys(report.animations.usage), report.keyframes.definedAnimations);
}
report.vendorPrefixes.unique = Object.keys(report.vendorPrefixes.usage).length;
report.vendorPrefixes.unknown.unique = Object.keys(report.vendorPrefixes.unknown.usage).length;
return report;
}
}
module.exports = exports['default'];