.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / stylelint / lib / rules / function-parentheses-newline-inside / index.js
1 "use strict";
2
3 const declarationValueIndex = require("../../utils/declarationValueIndex");
4 const isSingleLineString = require("../../utils/isSingleLineString");
5 const isStandardSyntaxFunction = require("../../utils/isStandardSyntaxFunction");
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-parentheses-newline-inside";
12
13 const messages = ruleMessages(ruleName, {
14   expectedOpening: 'Expected newline after "("',
15   expectedClosing: 'Expected newline before ")"',
16   expectedOpeningMultiLine:
17     'Expected newline after "(" in a multi-line function',
18   rejectedOpeningMultiLine:
19     'Unexpected whitespace after "(" in a multi-line function',
20   expectedClosingMultiLine:
21     'Expected newline before ")" in a multi-line function',
22   rejectedClosingMultiLine:
23     'Unexpected whitespace before ")" in a multi-line function'
24 });
25
26 const rule = function(expectation) {
27   return (root, result) => {
28     const validOptions = validateOptions(result, ruleName, {
29       actual: expectation,
30       possible: ["always", "always-multi-line", "never-multi-line"]
31     });
32     if (!validOptions) {
33       return;
34     }
35
36     root.walkDecls(decl => {
37       if (decl.value.indexOf("(") === -1) {
38         return;
39       }
40
41       valueParser(decl.value).walk(valueNode => {
42         if (valueNode.type !== "function") {
43           return;
44         }
45
46         if (!isStandardSyntaxFunction(valueNode)) {
47           return;
48         }
49
50         const functionString = valueParser.stringify(valueNode);
51         const isMultiLine = !isSingleLineString(functionString);
52         function containsNewline(str) {
53           return str.indexOf("\n") !== -1;
54         }
55
56         // Check opening ...
57
58         const openingIndex = valueNode.sourceIndex + valueNode.value.length + 1;
59
60         if (expectation === "always" && !containsNewline(valueNode.before)) {
61           complain(messages.expectedOpening, openingIndex);
62         }
63
64         if (
65           isMultiLine &&
66           expectation === "always-multi-line" &&
67           !containsNewline(valueNode.before)
68         ) {
69           complain(messages.expectedOpeningMultiLine, openingIndex);
70         }
71
72         if (
73           isMultiLine &&
74           expectation === "never-multi-line" &&
75           valueNode.before !== ""
76         ) {
77           complain(messages.rejectedOpeningMultiLine, openingIndex);
78         }
79
80         // Check closing ...
81
82         const closingIndex = valueNode.sourceIndex + functionString.length - 2;
83
84         if (expectation === "always" && !containsNewline(valueNode.after)) {
85           complain(messages.expectedClosing, closingIndex);
86         }
87
88         if (
89           isMultiLine &&
90           expectation === "always-multi-line" &&
91           !containsNewline(valueNode.after)
92         ) {
93           complain(messages.expectedClosingMultiLine, closingIndex);
94         }
95
96         if (
97           isMultiLine &&
98           expectation === "never-multi-line" &&
99           valueNode.after !== ""
100         ) {
101           complain(messages.rejectedClosingMultiLine, closingIndex);
102         }
103       });
104
105       function complain(message, offset) {
106         report({
107           ruleName,
108           result,
109           message,
110           node: decl,
111           index: declarationValueIndex(decl) + offset
112         });
113       }
114     });
115   };
116 };
117
118 rule.ruleName = ruleName;
119 rule.messages = messages;
120 module.exports = rule;