UNPKG

2.7 kBJavaScriptView Raw
1// @ts-nocheck
2
3'use strict';
4
5const _ = require('lodash');
6const atRuleParamIndex = require('../../utils/atRuleParamIndex');
7const report = require('../../utils/report');
8const ruleMessages = require('../../utils/ruleMessages');
9const validateOptions = require('../../utils/validateOptions');
10const valueParser = require('postcss-value-parser');
11
12const ruleName = 'media-feature-parentheses-space-inside';
13
14const messages = ruleMessages(ruleName, {
15 expectedOpening: 'Expected single space after "("',
16 rejectedOpening: 'Unexpected whitespace after "("',
17 expectedClosing: 'Expected single space before ")"',
18 rejectedClosing: 'Unexpected whitespace before ")"',
19});
20
21function rule(expectation, options, context) {
22 return (root, result) => {
23 const validOptions = validateOptions(result, ruleName, {
24 actual: expectation,
25 possible: ['always', 'never'],
26 });
27
28 if (!validOptions) {
29 return;
30 }
31
32 root.walkAtRules(/^media$/i, (atRule) => {
33 // If there are comments in the params, the complete string
34 // will be at atRule.raws.params.raw
35 const params = _.get(atRule, 'raws.params.raw', atRule.params);
36 const indexBoost = atRuleParamIndex(atRule);
37 const violations = [];
38
39 const parsedParams = valueParser(params).walk((node) => {
40 if (node.type === 'function') {
41 const len = valueParser.stringify(node).length;
42
43 if (expectation === 'never') {
44 if (/[ \t]/.test(node.before)) {
45 if (context.fix) node.before = '';
46
47 violations.push({
48 message: messages.rejectedOpening,
49 index: node.sourceIndex + 1 + indexBoost,
50 });
51 }
52
53 if (/[ \t]/.test(node.after)) {
54 if (context.fix) node.after = '';
55
56 violations.push({
57 message: messages.rejectedClosing,
58 index: node.sourceIndex - 2 + len + indexBoost,
59 });
60 }
61 } else if (expectation === 'always') {
62 if (node.before === '') {
63 if (context.fix) node.before = ' ';
64
65 violations.push({
66 message: messages.expectedOpening,
67 index: node.sourceIndex + 1 + indexBoost,
68 });
69 }
70
71 if (node.after === '') {
72 if (context.fix) node.after = ' ';
73
74 violations.push({
75 message: messages.expectedClosing,
76 index: node.sourceIndex - 2 + len + indexBoost,
77 });
78 }
79 }
80 }
81 });
82
83 if (violations.length) {
84 if (context.fix) {
85 atRule.params = parsedParams.toString();
86
87 return;
88 }
89
90 violations.forEach((err) => {
91 report({
92 message: err.message,
93 node: atRule,
94 index: err.index,
95 result,
96 ruleName,
97 });
98 });
99 }
100 });
101 };
102}
103
104rule.ruleName = ruleName;
105rule.messages = messages;
106module.exports = rule;