|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- // @ts-nocheck
-
- 'use strict';
-
- const _ = require('lodash');
- const declarationValueIndex = require('../../utils/declarationValueIndex');
- const isStandardSyntaxFunction = require('../../utils/isStandardSyntaxFunction');
- const isStandardSyntaxValue = require('../../utils/isStandardSyntaxValue');
- const keywordSets = require('../../reference/keywordSets');
- const namedColorDataHex = require('../../reference/namedColorData');
- const optionsMatches = require('../../utils/optionsMatches');
- const propertySets = require('../../reference/propertySets');
- const report = require('../../utils/report');
- const ruleMessages = require('../../utils/ruleMessages');
- const validateOptions = require('../../utils/validateOptions');
- const valueParser = require('postcss-value-parser');
-
- const generateColorFuncs = require('./generateColorFuncs');
-
- const ruleName = 'color-named';
-
- const messages = ruleMessages(ruleName, {
- expected: (named, original) => `Expected "${original}" to be "${named}"`,
- rejected: (named) => `Unexpected named color "${named}"`,
- });
-
- // Todo tested on case insensitivity
- const NODE_TYPES = new Set(['word', 'function']);
-
- function rule(expectation, options) {
- return (root, result) => {
- const validOptions = validateOptions(
- result,
- ruleName,
- {
- actual: expectation,
- possible: ['never', 'always-where-possible'],
- },
- {
- actual: options,
- possible: {
- ignoreProperties: [_.isString, _.isRegExp],
- ignore: ['inside-function'],
- },
- optional: true,
- },
- );
-
- if (!validOptions) {
- return;
- }
-
- const namedColors = Object.keys(namedColorDataHex);
- const namedColorData = {};
-
- namedColors.forEach((name) => {
- const hex = namedColorDataHex[name];
-
- namedColorData[name] = {
- hex,
- func: generateColorFuncs(hex[0]),
- };
- });
-
- root.walkDecls((decl) => {
- if (propertySets.acceptCustomIdents.has(decl.prop)) {
- return;
- }
-
- // Return early if the property is to be ignored
- if (optionsMatches(options, 'ignoreProperties', decl.prop)) {
- return;
- }
-
- valueParser(decl.value).walk((node) => {
- const value = node.value;
- const type = node.type;
- const sourceIndex = node.sourceIndex;
-
- if (optionsMatches(options, 'ignore', 'inside-function') && type === 'function') {
- return false;
- }
-
- if (!isStandardSyntaxFunction(node)) {
- return false;
- }
-
- if (!isStandardSyntaxValue(value)) {
- return;
- }
-
- // Return early if neither a word nor a function
- if (!NODE_TYPES.has(type)) {
- return;
- }
-
- // Check for named colors for "never" option
- if (
- expectation === 'never' &&
- type === 'word' &&
- namedColors.includes(value.toLowerCase())
- ) {
- complain(messages.rejected(value), decl, declarationValueIndex(decl) + sourceIndex);
-
- return;
- }
-
- // Check "always-where-possible" option ...
- if (expectation !== 'always-where-possible') {
- return;
- }
-
- // First by checking for alternative color function representations ...
- if (type === 'function' && keywordSets.colorFunctionNames.has(value.toLowerCase())) {
- // Remove all spaces to match what's in `representations`
- const normalizedFunctionString = valueParser.stringify(node).replace(/\s+/g, '');
- let namedColor;
-
- for (let i = 0, l = namedColors.length; i < l; i++) {
- namedColor = namedColors[i];
-
- if (namedColorData[namedColor].func.includes(normalizedFunctionString.toLowerCase())) {
- complain(
- messages.expected(namedColor, normalizedFunctionString),
- decl,
- declarationValueIndex(decl) + sourceIndex,
- );
-
- return; // Exit as soon as a problem is found
- }
- }
-
- return;
- }
-
- // Then by checking for alternative hex representations
- let namedColor;
-
- for (let i = 0, l = namedColors.length; i < l; i++) {
- namedColor = namedColors[i];
-
- if (namedColorData[namedColor].hex.includes(value.toLowerCase())) {
- complain(
- messages.expected(namedColor, value),
- decl,
- declarationValueIndex(decl) + sourceIndex,
- );
-
- return; // Exit as soon as a problem is found
- }
- }
- });
- });
-
- function complain(message, node, index) {
- report({
- result,
- ruleName,
- message,
- node,
- index,
- });
- }
- };
- }
-
- rule.ruleName = ruleName;
- rule.messages = messages;
- module.exports = rule;
|