.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / stylelint / lib / rules / function-linear-gradient-no-nonstandard-direction / index.js
1 "use strict";
2
3 const declarationValueIndex = require("../../utils/declarationValueIndex");
4 const functionArgumentsSearch = require("../../utils/functionArgumentsSearch");
5 const postcss = require("postcss");
6 const report = require("../../utils/report");
7 const ruleMessages = require("../../utils/ruleMessages");
8 const validateOptions = require("../../utils/validateOptions");
9 const valueParser = require("postcss-value-parser");
10
11 const ruleName = "function-linear-gradient-no-nonstandard-direction";
12
13 const messages = ruleMessages(ruleName, {
14   rejected: "Unexpected nonstandard direction"
15 });
16
17 function isStandardDirection(source, withToPrefix) {
18   const regexp = withToPrefix
19     ? /^to (top|left|bottom|right)(?: (top|left|bottom|right))?$/
20     : /^(top|left|bottom|right)(?: (top|left|bottom|right))?$/;
21
22   const matches = source.match(regexp);
23   if (!matches) {
24     return false;
25   }
26   if (matches.length === 2) {
27     return true;
28   }
29   // Cannot repeat side-or-corner, e.g. "to top top"
30   if (matches.length === 3 && matches[1] !== matches[2]) {
31     return true;
32   }
33   return false;
34 }
35
36 const rule = function(actual) {
37   return (root, result) => {
38     const validOptions = validateOptions(result, ruleName, { actual });
39     if (!validOptions) {
40       return;
41     }
42
43     root.walkDecls(decl => {
44       valueParser(decl.value).walk(valueNode => {
45         if (valueNode.type !== "function") {
46           return;
47         }
48         functionArgumentsSearch(
49           valueParser.stringify(valueNode).toLowerCase(),
50           "linear-gradient",
51           (expression, expressionIndex) => {
52             const firstArg = expression.split(",")[0].trim();
53
54             // If the first character is a number, we can assume the user intends an angle
55             if (/[\d.]/.test(firstArg[0])) {
56               if (/^[\d.]+(?:deg|grad|rad|turn)$/.test(firstArg)) {
57                 return;
58               }
59               complain();
60               return;
61             }
62
63             // The first argument may not be a direction: it may be an angle,
64             // or a color stop (in which case user gets default direction, "to bottom")
65             // cf. https://drafts.csswg.org/css-images-3/#linear-gradient-syntax
66             if (!/left|right|top|bottom/.test(firstArg)) {
67               return;
68             }
69
70             const withToPrefix = !postcss.vendor.prefix(valueNode.value);
71             if (!isStandardDirection(firstArg, withToPrefix)) {
72               complain();
73               return;
74             }
75
76             function complain() {
77               report({
78                 message: messages.rejected,
79                 node: decl,
80                 index:
81                   declarationValueIndex(decl) +
82                   valueNode.sourceIndex +
83                   expressionIndex,
84                 result,
85                 ruleName
86               });
87             }
88           }
89         );
90       });
91     });
92   };
93 };
94
95 rule.ruleName = ruleName;
96 rule.messages = messages;
97 module.exports = rule;