.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / stylelint / lib / rules / number-max-precision / index.js
1 "use strict";
2
3 const atRuleParamIndex = require("../../utils/atRuleParamIndex");
4 const declarationValueIndex = require("../../utils/declarationValueIndex");
5 const getUnitFromValueNode = require("../../utils/getUnitFromValueNode");
6 const optionsMatches = require("../../utils/optionsMatches");
7 const report = require("../../utils/report");
8 const ruleMessages = require("../../utils/ruleMessages");
9 const validateOptions = require("../../utils/validateOptions");
10
11 const _ = require("lodash");
12 const valueParser = require("postcss-value-parser");
13
14 const ruleName = "number-max-precision";
15
16 const messages = ruleMessages(ruleName, {
17   expected: (number, precision) =>
18     `Expected "${number}" to be "${number.toFixed(precision)}"`
19 });
20
21 const rule = function(precision, options) {
22   return (root, result) => {
23     const validOptions = validateOptions(
24       result,
25       ruleName,
26       {
27         actual: precision,
28         possible: [_.isNumber]
29       },
30       {
31         optional: true,
32         actual: options,
33         possible: {
34           ignoreUnits: [_.isString]
35         }
36       }
37     );
38     if (!validOptions) {
39       return;
40     }
41
42     root.walkAtRules(atRule => {
43       if (atRule.name.toLowerCase() === "import") {
44         return;
45       }
46
47       check(atRule, atRule.params, atRuleParamIndex);
48     });
49
50     root.walkDecls(decl => check(decl, decl.value, declarationValueIndex));
51
52     function check(node, value, getIndex) {
53       // Get out quickly if there are no periods
54       if (value.indexOf(".") === -1) {
55         return;
56       }
57
58       valueParser(value).walk(valueNode => {
59         const unit = getUnitFromValueNode(valueNode);
60
61         if (optionsMatches(options, "ignoreUnits", unit)) {
62           return;
63         }
64
65         // Ignore `url` function
66         if (
67           valueNode.type === "function" &&
68           valueNode.value.toLowerCase() === "url"
69         ) {
70           return false;
71         }
72
73         // Ignore strings, comments, etc
74         if (valueNode.type !== "word") {
75           return;
76         }
77
78         const match = /\d*\.(\d+)/.exec(valueNode.value);
79
80         if (match === null) {
81           return;
82         }
83
84         if (match[1].length <= precision) {
85           return;
86         }
87
88         report({
89           result,
90           ruleName,
91           node,
92           index: getIndex(node) + valueNode.sourceIndex + match.index,
93           message: messages.expected(parseFloat(match[0]), precision)
94         });
95       });
96     }
97   };
98 };
99
100 rule.ruleName = ruleName;
101 rule.messages = messages;
102 module.exports = rule;