UNPKG

2.34 kBJavaScriptView Raw
1'use strict';
2
3const ruleMessages = require('../../utils/ruleMessages');
4const selectorAttributeOperatorSpaceChecker = require('../selectorAttributeOperatorSpaceChecker');
5const validateOptions = require('../../utils/validateOptions');
6const whitespaceChecker = require('../../utils/whitespaceChecker');
7
8const ruleName = 'selector-attribute-operator-space-before';
9
10const messages = ruleMessages(ruleName, {
11 expectedBefore: (operator) => `Expected single space before "${operator}"`,
12 rejectedBefore: (operator) => `Unexpected whitespace before "${operator}"`,
13});
14
15const meta = {
16 url: 'https://stylelint.io/user-guide/rules/list/selector-attribute-operator-space-before',
17};
18
19/** @type {import('stylelint').Rule} */
20const rule = (primary, _secondaryOptions, context) => {
21 const checker = whitespaceChecker('space', primary, messages);
22
23 return (root, result) => {
24 const validOptions = validateOptions(result, ruleName, {
25 actual: primary,
26 possible: ['always', 'never'],
27 });
28
29 if (!validOptions) {
30 return;
31 }
32
33 selectorAttributeOperatorSpaceChecker({
34 root,
35 result,
36 locationChecker: checker.before,
37 checkedRuleName: ruleName,
38 checkBeforeOperator: true,
39 fix: context.fix
40 ? (attributeNode) => {
41 const rawAttr = attributeNode.raws.spaces && attributeNode.raws.spaces.attribute;
42 const rawAttrAfter = rawAttr && rawAttr.after;
43
44 /** @type {{ attrAfter: string, setAttrAfter: (fixed: string) => void }} */
45 const { attrAfter, setAttrAfter } = rawAttrAfter
46 ? {
47 attrAfter: rawAttrAfter,
48 setAttrAfter(fixed) {
49 rawAttr.after = fixed;
50 },
51 }
52 : {
53 attrAfter:
54 (attributeNode.spaces.attribute && attributeNode.spaces.attribute.after) || '',
55 setAttrAfter(fixed) {
56 if (!attributeNode.spaces.attribute) attributeNode.spaces.attribute = {};
57
58 attributeNode.spaces.attribute.after = fixed;
59 },
60 };
61
62 if (primary === 'always') {
63 setAttrAfter(attrAfter.replace(/\s*$/, ' '));
64
65 return true;
66 }
67
68 if (primary === 'never') {
69 setAttrAfter(attrAfter.replace(/\s*$/, ''));
70
71 return true;
72 }
73
74 return false;
75 }
76 : null,
77 });
78 };
79};
80
81rule.ruleName = ruleName;
82rule.messages = messages;
83rule.meta = meta;
84module.exports = rule;