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-newline-inside";
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'
26 const rule = function(expectation) {
27 return (root, result) => {
28 const validOptions = validateOptions(result, ruleName, {
30 possible: ["always", "always-multi-line", "never-multi-line"]
36 root.walkDecls(decl => {
37 if (decl.value.indexOf("(") === -1) {
41 valueParser(decl.value).walk(valueNode => {
42 if (valueNode.type !== "function") {
46 if (!isStandardSyntaxFunction(valueNode)) {
50 const functionString = valueParser.stringify(valueNode);
51 const isMultiLine = !isSingleLineString(functionString);
52 function containsNewline(str) {
53 return str.indexOf("\n") !== -1;
58 const openingIndex = valueNode.sourceIndex + valueNode.value.length + 1;
60 if (expectation === "always" && !containsNewline(valueNode.before)) {
61 complain(messages.expectedOpening, openingIndex);
66 expectation === "always-multi-line" &&
67 !containsNewline(valueNode.before)
69 complain(messages.expectedOpeningMultiLine, openingIndex);
74 expectation === "never-multi-line" &&
75 valueNode.before !== ""
77 complain(messages.rejectedOpeningMultiLine, openingIndex);
82 const closingIndex = valueNode.sourceIndex + functionString.length - 2;
84 if (expectation === "always" && !containsNewline(valueNode.after)) {
85 complain(messages.expectedClosing, closingIndex);
90 expectation === "always-multi-line" &&
91 !containsNewline(valueNode.after)
93 complain(messages.expectedClosingMultiLine, closingIndex);
98 expectation === "never-multi-line" &&
99 valueNode.after !== ""
101 complain(messages.rejectedClosingMultiLine, closingIndex);
105 function complain(message, offset) {
111 index: declarationValueIndex(decl) + offset
118 rule.ruleName = ruleName;
119 rule.messages = messages;
120 module.exports = rule;