scancss
Version:
A robust CSS stylesheet statistics collector and analyzer
190 lines (137 loc) • 6.97 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.handleFunctions = handleFunctions;
var _postcssValuesParser = require('postcss-values-parser');
var _postcssValuesParser2 = _interopRequireDefault(_postcssValuesParser);
var _cssFilterFunctions = require('../../constants/cssFilterFunctions');
var _reCssGradientFunctionName = require('../../constants/reCssGradientFunctionName');
var _reImageDataUri = require('../../constants/reImageDataUri');
var _rePrefixedString = require('../../constants/rePrefixedString');
var _countUsage = require('../../calculators/countUsage');
var _transformString = require('../../converters/transformString');
var _trimExtraSpaces = require('../../converters/trimExtraSpaces');
var _trimSpacesNearCommas = require('../../converters/trimSpacesNearCommas');
var _trimSpacesNearParentheses = require('../../converters/trimSpacesNearParentheses');
var _trimLeadingZeros = require('../../converters/trimLeadingZeros');
var _trimTrailingZeros = require('../../converters/trimTrailingZeros');
var _isSafeAst = require('../../predicates/isSafeAst');
var _isValidCubicBezierArgs = require('../../predicates/isValidCubicBezierArgs');
var _isValidFramesFunctionArgs = require('../../predicates/isValidFramesFunctionArgs');
var _isValidStepsFunctionArgs = require('../../predicates/isValidStepsFunctionArgs');
var _handleVendorPrefix = require('../handleVendorPrefix');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function countFunction(func, report) {
report.functions.total++;
(0, _countUsage.countUsage)(func, report.functions.usage);
if (_rePrefixedString.rePrefixedString.test(func)) {
report.functions.prefixed++;
(0, _handleVendorPrefix.handleVendorPrefix)(func, report);
}
}
function countFilter(funcWithArgs, report) {
report.filters.total++;
(0, _countUsage.countUsage)(funcWithArgs, report.filters.usage);
}
function countDataUri(funcWithArgs, report) {
const processedFunc = (0, _transformString.transformString)(funcWithArgs, [_trimExtraSpaces.trimExtraSpaces, _trimSpacesNearCommas.trimSpacesNearCommas, _trimSpacesNearParentheses.trimSpacesNearParentheses]);
const urlArg = processedFunc.replace(/^url\(\s*['"]?\s*/g, '').replace(/\s*['"]?\s*\)/g, '').replace(/(\/?>)\s*(<\/?)/g, '$1$2');
/* istanbul ignore else */
if (urlArg.match(_reImageDataUri.reImageDataUri) !== null) {
report.dataUris.total++;
const dataUriByteLength = Buffer.byteLength(urlArg, 'utf8');
report.dataUris.length.total += dataUriByteLength;
/* istanbul ignore else */
if (report.dataUris.length.longest < dataUriByteLength) {
report.dataUris.length.longest = dataUriByteLength;
report.dataUris.length.longestDataUri = urlArg;
}
(0, _countUsage.countUsage)(urlArg, report.dataUris.usage);
}
}
function countGradient(funcWithArgs, report) {
report.gradients.total++;
(0, _countUsage.countUsage)(funcWithArgs, report.gradients.usage);
}
function countCubicBezier(funcWithArgs, prop, report) {
const reportSection = prop.includes('animation') ? report.animations : report.transitions;
(0, _countUsage.countUsage)(funcWithArgs, reportSection.timingFunctions);
const processedFunc = (0, _transformString.transformString)(funcWithArgs, [_trimExtraSpaces.trimExtraSpaces, _trimSpacesNearCommas.trimSpacesNearCommas, _trimSpacesNearParentheses.trimSpacesNearParentheses, _trimTrailingZeros.trimTrailingZeros, _trimLeadingZeros.trimLeadingZeros]);
/**
* Count invalid cubic beziers
* https://developer.mozilla.org/en-US/docs/Web/CSS/single-transition-timing-function#Examples
*/
if ((0, _isValidCubicBezierArgs.isValidCubicBezierArgs)(processedFunc) === false) {
(0, _countUsage.countUsage)(funcWithArgs, reportSection.invalidTimingFunctions);
}
}
function countStepsFunction(funcWithArgs, prop, report) {
const reportSection = prop.includes('animation') ? report.animations : report.transitions;
(0, _countUsage.countUsage)(funcWithArgs, reportSection.timingFunctions);
const processedFunc = (0, _transformString.transformString)(funcWithArgs, [_trimExtraSpaces.trimExtraSpaces, _trimSpacesNearCommas.trimSpacesNearCommas, _trimSpacesNearParentheses.trimSpacesNearParentheses]);
/**
* Count invalid cubic beziers
* https://developer.mozilla.org/en-US/docs/Web/CSS/single-transition-timing-function#Examples
*/
if ((0, _isValidStepsFunctionArgs.isValidStepsFunctionArgs)(processedFunc) === false) {
(0, _countUsage.countUsage)(funcWithArgs, reportSection.invalidTimingFunctions);
}
}
function countFramesFunction(funcWithArgs, prop, report) {
const reportSection = prop.includes('animation') ? report.animations : report.transitions;
(0, _countUsage.countUsage)(funcWithArgs, reportSection.timingFunctions);
const processedFunc = (0, _transformString.transformString)(funcWithArgs, [_trimExtraSpaces.trimExtraSpaces, _trimSpacesNearCommas.trimSpacesNearCommas, _trimSpacesNearParentheses.trimSpacesNearParentheses]);
/**
* Count invalid cubic beziers
* https://developer.mozilla.org/en-US/docs/Web/CSS/single-transition-timing-function#Examples
*/
if ((0, _isValidFramesFunctionArgs.isValidFramesFunctionArgs)(processedFunc) === false) {
(0, _countUsage.countUsage)(funcWithArgs, reportSection.invalidTimingFunctions);
}
}
function walkFunctionNodes(nodes, decl, report, options) {
/* eslint-disable-next-line complexity */
nodes.forEach(node => {
if (node.type === 'func') {
const funcName = node.value.toLowerCase();
const funcWithArgs = node.toString().trim();
countFunction(funcName, report);
if (_cssFilterFunctions.cssFilterFunctions.includes(funcName) && options.filters) {
countFilter(funcWithArgs, report);
}
if (funcName.match(_reCssGradientFunctionName.reCssGradientFunctionName) !== null && options.gradients) {
countGradient(funcWithArgs, report);
}
if (funcName === 'cubic-bezier' && options.transitionsAndAnimations) {
countCubicBezier(funcWithArgs, decl.prop, report);
}
if (funcName === 'steps' && options.transitionsAndAnimations) {
countStepsFunction(funcWithArgs, decl.prop, report);
}
if (funcName === 'frames' && options.transitionsAndAnimations) {
countFramesFunction(funcWithArgs, decl.prop, report);
}
if (funcName === 'url' && options.dataUris) {
countDataUri(funcWithArgs, report);
}
/* istanbul ignore else */
if (Array.isArray(node.nodes)) {
walkFunctionNodes(node.nodes, decl, report, options);
}
}
});
}
function handleFunctions(decl, report, options) {
try {
const ast = (0, _postcssValuesParser2.default)(decl.value).parse();
/* istanbul ignore else */
if ((0, _isSafeAst.isSafeAst)(ast)) {
walkFunctionNodes(ast.nodes[0].nodes, decl, report, options);
}
} catch (err) {
/* istanbul ignore next */
/* eslint-disable-next-line no-console */
console.log(`'postcss-values-parser' module error\n${err}`);
}
}