UNPKG

2.28 kBJavaScriptView Raw
1'use strict';
2
3const blockString = require('../../utils/blockString');
4const rawNodeString = require('../../utils/rawNodeString');
5const report = require('../../utils/report');
6const ruleMessages = require('../../utils/ruleMessages');
7const validateOptions = require('../../utils/validateOptions');
8const whitespaceChecker = require('../../utils/whitespaceChecker');
9const { isAtRule, isRule } = require('../../utils/typeGuards');
10
11const ruleName = 'declaration-block-semicolon-space-after';
12
13const messages = ruleMessages(ruleName, {
14 expectedAfter: () => 'Expected single space after ";"',
15 rejectedAfter: () => 'Unexpected whitespace after ";"',
16 expectedAfterSingleLine: () =>
17 'Expected single space after ";" in a single-line declaration block',
18 rejectedAfterSingleLine: () =>
19 'Unexpected whitespace after ";" in a single-line declaration block',
20});
21
22/** @type {import('stylelint').Rule} */
23const rule = (primary, _secondaryOptions, context) => {
24 const checker = whitespaceChecker('space', primary, messages);
25
26 return function (root, result) {
27 const validOptions = validateOptions(result, ruleName, {
28 actual: primary,
29 possible: ['always', 'never', 'always-single-line', 'never-single-line'],
30 });
31
32 if (!validOptions) {
33 return;
34 }
35
36 root.walkDecls((decl) => {
37 // Ignore last declaration if there's no trailing semicolon
38 const parentRule = decl.parent;
39
40 if (!parentRule) throw new Error('A parent node must be present');
41
42 if (!isAtRule(parentRule) && !isRule(parentRule)) {
43 return;
44 }
45
46 if (!parentRule.raws.semicolon && parentRule.last === decl) {
47 return;
48 }
49
50 const nextDecl = decl.next();
51
52 if (!nextDecl) {
53 return;
54 }
55
56 checker.after({
57 source: rawNodeString(nextDecl),
58 index: -1,
59 lineCheckStr: blockString(parentRule),
60 err: (m) => {
61 if (context.fix) {
62 if (primary.startsWith('always')) {
63 nextDecl.raws.before = ' ';
64
65 return;
66 }
67
68 if (primary.startsWith('never')) {
69 nextDecl.raws.before = '';
70
71 return;
72 }
73 }
74
75 report({
76 message: m,
77 node: decl,
78 index: decl.toString().length + 1,
79 result,
80 ruleName,
81 });
82 },
83 });
84 });
85 };
86};
87
88rule.ruleName = ruleName;
89rule.messages = messages;
90module.exports = rule;