.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / stylelint / lib / rules / number-leading-zero / index.js
diff --git a/.config/coc/extensions/node_modules/coc-prettier/node_modules/stylelint/lib/rules/number-leading-zero/index.js b/.config/coc/extensions/node_modules/coc-prettier/node_modules/stylelint/lib/rules/number-leading-zero/index.js
new file mode 100644 (file)
index 0000000..daf4195
--- /dev/null
@@ -0,0 +1,160 @@
+"use strict";
+
+const atRuleParamIndex = require("../../utils/atRuleParamIndex");
+const declarationValueIndex = require("../../utils/declarationValueIndex");
+const report = require("../../utils/report");
+const ruleMessages = require("../../utils/ruleMessages");
+const validateOptions = require("../../utils/validateOptions");
+const valueParser = require("postcss-value-parser");
+
+const ruleName = "number-leading-zero";
+
+const messages = ruleMessages(ruleName, {
+  expected: "Expected a leading zero",
+  rejected: "Unexpected leading zero"
+});
+
+const rule = function(expectation, secondary, context) {
+  return (root, result) => {
+    const validOptions = validateOptions(result, ruleName, {
+      actual: expectation,
+      possible: ["always", "never"]
+    });
+    if (!validOptions) {
+      return;
+    }
+
+    root.walkAtRules(atRule => {
+      if (atRule.name.toLowerCase() === "import") {
+        return;
+      }
+
+      check(atRule, atRule.params, atRuleParamIndex);
+    });
+
+    root.walkDecls(decl => check(decl, decl.value, declarationValueIndex));
+
+    function check(node, value, getIndex) {
+      const neverFixPositions = [];
+      const alwaysFixPositions = [];
+
+      // Get out quickly if there are no periods
+      if (value.indexOf(".") === -1) {
+        return;
+      }
+
+      valueParser(value).walk(valueNode => {
+        // Ignore `url` function
+        if (
+          valueNode.type === "function" &&
+          valueNode.value.toLowerCase() === "url"
+        ) {
+          return false;
+        }
+
+        // Ignore strings, comments, etc
+        if (valueNode.type !== "word") {
+          return;
+        }
+
+        // Check leading zero
+        if (expectation === "always") {
+          const match = /(?:\D|^)(\.\d+)/.exec(valueNode.value);
+
+          if (match === null) {
+            return;
+          }
+          // The regexp above consists of 2 capturing groups (or capturing parentheses).
+          // We need the index of the second group. This makes sanse when we have "-.5" as an input
+          // for regex. And we need the index of ".5".
+          const capturingGroupIndex = match[0].length - match[1].length;
+
+          const index =
+            valueNode.sourceIndex + match.index + capturingGroupIndex;
+
+          if (context.fix) {
+            alwaysFixPositions.unshift({
+              index
+            });
+            return;
+          } else {
+            complain(messages.expected, node, getIndex(node) + index);
+          }
+        }
+
+        if (expectation === "never") {
+          const match = /(?:\D|^)(0+)(\.\d+)/.exec(valueNode.value);
+
+          if (match === null) {
+            return;
+          }
+
+          // The regexp above consists of 3 capturing groups (or capturing parentheses).
+          // We need the index of the second group. This makes sanse when we have "-00.5"
+          // as an input for regex. And we need the index of "00".
+          const capturingGroupIndex =
+            match[0].length - (match[1].length + match[2].length);
+
+          const index =
+            valueNode.sourceIndex + match.index + capturingGroupIndex;
+
+          if (context.fix) {
+            neverFixPositions.unshift({
+              startIndex: index,
+              // match[1].length is the length of our matched zero(s)
+              endIndex: index + match[1].length
+            });
+            return;
+          } else {
+            complain(messages.rejected, node, getIndex(node) + index);
+          }
+        }
+      });
+
+      if (alwaysFixPositions.length) {
+        alwaysFixPositions.forEach(function(fixPosition) {
+          const index = fixPosition.index;
+          if (node.type === "atrule") {
+            node.params = addLeadingZero(node.params, index);
+          } else {
+            node.value = addLeadingZero(node.value, index);
+          }
+        });
+      }
+
+      if (neverFixPositions.length) {
+        neverFixPositions.forEach(function(fixPosition) {
+          const startIndex = fixPosition.startIndex;
+          const endIndex = fixPosition.endIndex;
+          if (node.type === "atrule") {
+            node.params = removeLeadingZeros(node.params, startIndex, endIndex);
+          } else {
+            node.value = removeLeadingZeros(node.value, startIndex, endIndex);
+          }
+        });
+      }
+    }
+
+    function complain(message, node, index) {
+      report({
+        result,
+        ruleName,
+        message,
+        node,
+        index
+      });
+    }
+  };
+};
+
+function addLeadingZero(input, index) {
+  return input.slice(0, index) + "0" + input.slice(index);
+}
+
+function removeLeadingZeros(input, startIndex, endIndex) {
+  return input.slice(0, startIndex) + input.slice(endIndex);
+}
+
+rule.ruleName = ruleName;
+rule.messages = messages;
+module.exports = rule;