.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / stylelint / lib / rules / color-named / index.js
diff --git a/.config/coc/extensions/node_modules/coc-prettier/node_modules/stylelint/lib/rules/color-named/index.js b/.config/coc/extensions/node_modules/coc-prettier/node_modules/stylelint/lib/rules/color-named/index.js
new file mode 100644 (file)
index 0000000..583154a
--- /dev/null
@@ -0,0 +1,174 @@
+"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 insensivity
+const NODE_TYPES = ["word", "function"];
+
+const rule = function(expectation, options) {
+  return (root, result) => {
+    const validOptions = validateOptions(
+      result,
+      ruleName,
+      {
+        actual: expectation,
+        possible: ["never", "always-where-possible"]
+      },
+      {
+        actual: options,
+        possible: {
+          ignoreProperties: [_.isString],
+          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,
+          type = node.type,
+          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.indexOf(type) === -1) {
+          return;
+        }
+
+        // Check for named colors for "never" option
+        if (
+          expectation === "never" &&
+          type === "word" &&
+          namedColors.indexOf(value.toLowerCase()) !== -1
+        ) {
+          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.indexOf(
+                normalizedFunctionString.toLowerCase()
+              ) !== -1
+            ) {
+              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.indexOf(value.toLowerCase()) !== -1
+          ) {
+            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;