3 const _ = require("lodash");
4 const atRuleParamIndex = require("../../utils/atRuleParamIndex");
5 const report = require("../../utils/report");
6 const ruleMessages = require("../../utils/ruleMessages");
7 const styleSearch = require("style-search");
8 const validateOptions = require("../../utils/validateOptions");
10 const ruleName = "media-feature-parentheses-space-inside";
12 const messages = ruleMessages(ruleName, {
13 expectedOpening: 'Expected single space after "("',
14 rejectedOpening: 'Unexpected whitespace after "("',
15 expectedClosing: 'Expected single space before ")"',
16 rejectedClosing: 'Unexpected whitespace before ")"'
19 const rule = function(expectation) {
20 return (root, result) => {
21 const validOptions = validateOptions(result, ruleName, {
23 possible: ["always", "never"]
29 root.walkAtRules(/^media$/i, atRule => {
30 // If there are comments in the params, the complete string
31 // will be at atRule.raws.params.raw
32 const params = _.get(atRule, "raws.params.raw", atRule.params);
33 const indexBoost = atRuleParamIndex(atRule);
35 styleSearch({ source: params, target: "(" }, match => {
36 const nextCharIsSpace = params[match.startIndex + 1] === " ";
37 if (nextCharIsSpace && expectation === "never") {
39 message: messages.rejectedOpening,
41 index: match.startIndex + 1 + indexBoost,
46 if (!nextCharIsSpace && expectation === "always") {
48 message: messages.expectedOpening,
50 index: match.startIndex + 1 + indexBoost,
57 styleSearch({ source: params, target: ")" }, match => {
58 const prevCharIsSpace = params[match.startIndex - 1] === " ";
59 if (prevCharIsSpace && expectation === "never") {
61 message: messages.rejectedClosing,
63 index: match.startIndex - 1 + indexBoost,
68 if (!prevCharIsSpace && expectation === "always") {
70 message: messages.expectedClosing,
72 index: match.startIndex - 1 + indexBoost,
82 rule.ruleName = ruleName;
83 rule.messages = messages;
84 module.exports = rule;