.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / stylelint / lib / rules / function-url-quotes / index.js
1 "use strict";
2
3 const _ = require("lodash");
4 const atRuleParamIndex = require("../../utils/atRuleParamIndex");
5 const functionArgumentsSearch = require("../../utils/functionArgumentsSearch");
6 const isStandardSyntaxUrl = require("../../utils/isStandardSyntaxUrl");
7 const optionsMatches = require("../../utils/optionsMatches");
8 const report = require("../../utils/report");
9 const ruleMessages = require("../../utils/ruleMessages");
10 const validateOptions = require("../../utils/validateOptions");
11
12 const ruleName = "function-url-quotes";
13
14 const messages = ruleMessages(ruleName, {
15   expected: () => "Expected quotes",
16   rejected: () => "Unexpected quotes"
17 });
18
19 const rule = function(expectation, options) {
20   return (root, result) => {
21     const validOptions = validateOptions(
22       result,
23       ruleName,
24       {
25         actual: expectation,
26         possible: ["always", "never"]
27       },
28       {
29         actual: options,
30         possible: {
31           except: ["empty"]
32         },
33         optional: true
34       }
35     );
36     if (!validOptions) {
37       return;
38     }
39
40     root.walkAtRules(checkStatement);
41     root.walkRules(checkStatement);
42
43     function checkStatement(statement) {
44       if (statement.type === "atrule") {
45         checkAtRuleParams(statement);
46       }
47
48       statement.walkDecls(function(decl) {
49         functionArgumentsSearch(
50           decl.toString().toLowerCase(),
51           "url",
52           (args, index) => {
53             checkArgs(args, decl, index, "url");
54           }
55         );
56       });
57     }
58
59     function checkAtRuleParams(atRule) {
60       const atRuleParamsLowerCase = atRule.params.toLowerCase();
61       functionArgumentsSearch(atRuleParamsLowerCase, "url", (args, index) => {
62         checkArgs(args, atRule, index + atRuleParamIndex(atRule), "url");
63       });
64       functionArgumentsSearch(
65         atRuleParamsLowerCase,
66         "url-prefix",
67         (args, index) => {
68           checkArgs(
69             args,
70             atRule,
71             index + atRuleParamIndex(atRule),
72             "url-prefix"
73           );
74         }
75       );
76       functionArgumentsSearch(
77         atRuleParamsLowerCase,
78         "domain",
79         (args, index) => {
80           checkArgs(args, atRule, index + atRuleParamIndex(atRule), "domain");
81         }
82       );
83     }
84
85     function checkArgs(args, node, index, functionName) {
86       let shouldHasQuotes = expectation === "always";
87
88       const leftTrimmedArgs = args.trimLeft();
89       if (!isStandardSyntaxUrl(leftTrimmedArgs)) {
90         return;
91       }
92       const complaintIndex = index + args.length - leftTrimmedArgs.length;
93       const hasQuotes =
94         leftTrimmedArgs[0] === "'" || leftTrimmedArgs[0] === '"';
95
96       const trimmedArg = args.trim();
97       const isEmptyArgument = _.includes(["", "''", '""'], trimmedArg);
98       if (optionsMatches(options, "except", "empty") && isEmptyArgument) {
99         shouldHasQuotes = !shouldHasQuotes;
100       }
101
102       if (shouldHasQuotes) {
103         if (hasQuotes) {
104           return;
105         }
106         complain(messages.expected(functionName), node, complaintIndex);
107       } else {
108         if (!hasQuotes) {
109           return;
110         }
111         complain(messages.rejected(functionName), node, complaintIndex);
112       }
113     }
114
115     function complain(message, node, index) {
116       report({
117         message,
118         node,
119         index,
120         result,
121         ruleName
122       });
123     }
124   };
125 };
126
127 rule.ruleName = ruleName;
128 rule.messages = messages;
129 module.exports = rule;