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");
11 const ruleName = "function-parentheses-space-inside";
13 const messages = ruleMessages(ruleName, {
14 expectedOpening: 'Expected single space after "("',
15 rejectedOpening: 'Unexpected whitespace after "("',
16 expectedClosing: 'Expected single space before ")"',
17 rejectedClosing: 'Unexpected whitespace before ")"',
18 expectedOpeningSingleLine:
19 'Expected single space after "(" in a single-line function',
20 rejectedOpeningSingleLine:
21 'Unexpected whitespace after "(" in a single-line function',
22 expectedClosingSingleLine:
23 'Expected single space before ")" in a single-line function',
24 rejectedClosingSingleLine:
25 'Unexpected whitespace before ")" in a single-line function'
28 const rule = function(expectation) {
29 return (root, result) => {
30 const validOptions = validateOptions(result, ruleName, {
32 possible: ["always", "never", "always-single-line", "never-single-line"]
38 root.walkDecls(decl => {
39 if (decl.value.indexOf("(") === -1) {
43 valueParser(decl.value).walk(valueNode => {
44 if (valueNode.type !== "function") {
48 if (!isStandardSyntaxFunction(valueNode)) {
52 // Ignore function without parameters
53 if (!valueNode.nodes.length) {
57 const functionString = valueParser.stringify(valueNode);
58 const isSingleLine = isSingleLineString(functionString);
62 const openingIndex = valueNode.sourceIndex + valueNode.value.length + 1;
64 if (expectation === "always" && valueNode.before !== " ") {
65 complain(messages.expectedOpening, openingIndex);
68 if (expectation === "never" && valueNode.before !== "") {
69 complain(messages.rejectedOpening, openingIndex);
74 expectation === "always-single-line" &&
75 valueNode.before !== " "
77 complain(messages.expectedOpeningSingleLine, openingIndex);
82 expectation === "never-single-line" &&
83 valueNode.before !== ""
85 complain(messages.rejectedOpeningSingleLine, openingIndex);
90 const closingIndex = valueNode.sourceIndex + functionString.length - 2;
92 if (expectation === "always" && valueNode.after !== " ") {
93 complain(messages.expectedClosing, closingIndex);
96 if (expectation === "never" && valueNode.after !== "") {
97 complain(messages.rejectedClosing, closingIndex);
102 expectation === "always-single-line" &&
103 valueNode.after !== " "
105 complain(messages.expectedClosingSingleLine, closingIndex);
110 expectation === "never-single-line" &&
111 valueNode.after !== ""
113 complain(messages.rejectedClosingSingleLine, closingIndex);
117 function complain(message, offset) {
123 index: declarationValueIndex(decl) + offset
130 rule.ruleName = ruleName;
131 rule.messages = messages;
132 module.exports = rule;