scancss
Version:
A robust CSS stylesheet statistics collector and analyzer
187 lines (140 loc) • 6.14 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.handleColorable = handleColorable;
var _postcssValuesParser = require('postcss-values-parser');
var _postcssValuesParser2 = _interopRequireDefault(_postcssValuesParser);
var _cssColorNamesMap = require('../../../constants/cssColorNamesMap');
var _cssSystemColors = require('../../../constants/cssSystemColors');
var _cssColorFunctions = require('../../../constants/cssColorFunctions');
var _countUsage = require('../../../calculators/countUsage');
var _restoreFullHex = require('../../../converters/restoreFullHex');
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');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const cssColorNames = Object.keys(_cssColorNamesMap.cssColorNamesMap);
const lowercasedCssSystemColors = _cssSystemColors.cssSystemColors.map(color => color.toLowerCase());
function countColorInSection(color, reportSection) {
reportSection.total++;
(0, _countUsage.countUsage)(color, reportSection.usage);
}
function countKeywordColor(prop, color, report, options) {
const reportSectionName = color + 'Keyword';
if (prop.startsWith('background') && options.backgroundColors) {
countColorInSection(color, report.backgroundColors);
report.backgroundColors[reportSectionName]++;
} else if (prop.startsWith('background') === false && options.colors) {
countColorInSection(color, report.colors);
report.colors[reportSectionName]++;
}
/* istanbul ignore else */
if (options.allColors) {
countColorInSection(color, report.allColors);
report.allColors[reportSectionName]++;
}
}
/**
* https://www.w3.org/TR/CSS22/ui.html#system-colors
*/
function countNamedColor(prop, color, report, options) {
if (prop.startsWith('background') && options.backgroundColors) {
countColorInSection(color, report.backgroundColors);
(0, _countUsage.countUsage)(color, report.backgroundColors.named);
} else if (prop.startsWith('background') === false && options.colors) {
countColorInSection(color, report.colors);
(0, _countUsage.countUsage)(color, report.colors.named);
}
if (options.allColors) {
countColorInSection(color, report.allColors);
(0, _countUsage.countUsage)(color, report.allColors.named);
}
}
function normalizeModelColor(color) {
if (color.startsWith('#')) {
return color.length === 4 || color.length === 5 ? (0, _restoreFullHex.restoreFullHex)(color) : color;
}
return (0, _transformString.transformString)(color, [_trimExtraSpaces.trimExtraSpaces, _trimSpacesNearCommas.trimSpacesNearCommas, _trimSpacesNearParentheses.trimSpacesNearParentheses, _trimTrailingZeros.trimTrailingZeros, _trimLeadingZeros.trimLeadingZeros]);
}
function countColorModel(prop, color, report, model, options) {
const normalizedColor = normalizeModelColor(color);
if (prop.startsWith('background') && options.backgroundColors) {
countColorInSection(normalizedColor, report.backgroundColors);
(0, _countUsage.countUsage)(model, report.backgroundColors.models);
} else if (prop.startsWith('background') === false && options.colors) {
countColorInSection(normalizedColor, report.colors);
(0, _countUsage.countUsage)(model, report.colors.models);
}
if (options.allColors) {
countColorInSection(normalizedColor, report.allColors);
(0, _countUsage.countUsage)(model, report.allColors.models);
}
}
function countSystemColor(prop, color, report, options) {
if (prop.startsWith('background') && options.backgroundColors) {
countColorInSection(color, report.backgroundColors);
(0, _countUsage.countUsage)(color, report.backgroundColors.system);
} else if (prop.startsWith('background') === false && options.colors) {
countColorInSection(color, report.colors);
(0, _countUsage.countUsage)(color, report.colors.system);
}
if (options.allColors) {
countColorInSection(color, report.allColors);
(0, _countUsage.countUsage)(color, report.allColors.system);
}
}
function walkNodes(nodes, decl, report, options) {
nodes.forEach(node => {
const lowerCasedValue = node.value.toLowerCase();
if (node.type === 'word') {
if (cssColorNames.includes(lowerCasedValue)) {
countNamedColor(decl.prop, lowerCasedValue, report, options);
return;
}
if (lowerCasedValue === 'transparent') {
countKeywordColor(decl.prop, 'transparent', report, options);
return;
}
if (lowerCasedValue === 'currentcolor') {
countKeywordColor(decl.prop, 'currentColor', report, options);
return;
}
if (lowerCasedValue.startsWith('#')) {
if (lowerCasedValue.length === 4 || lowerCasedValue.length === 7) {
countColorModel(decl.prop, lowerCasedValue, report, 'hex', options);
return;
}
/* istanbul ignore else */
if (lowerCasedValue.length === 5 || lowerCasedValue.length === 9) {
countColorModel(decl.prop, lowerCasedValue, report, 'hexa', options);
return;
}
}
if (lowercasedCssSystemColors.includes(lowerCasedValue)) {
countSystemColor(decl.prop, lowerCasedValue, report, options);
return;
}
}
if (node.type === 'func') {
if (_cssColorFunctions.cssColorFunctions.includes(lowerCasedValue)) {
countColorModel(decl.prop, node.toString(), report, lowerCasedValue, options);
}
/* istanbul ignore else */
if (Array.isArray(node.nodes)) {
walkNodes(node.nodes, decl, report, options);
}
}
});
}
function handleColorable(decl, report, options) {
const ast = (0, _postcssValuesParser2.default)(decl.value).parse();
/* istanbul ignore else */
if ((0, _isSafeAst.isSafeAst)(ast)) {
walkNodes(ast.nodes[0].nodes, decl, report, options);
}
}