UNPKG

2.65 kBJavaScriptView Raw
1// @ts-nocheck
2
3'use strict';
4
5const declarationValueIndex = require('../../utils/declarationValueIndex');
6const isStandardSyntaxDeclaration = require('../../utils/isStandardSyntaxDeclaration');
7const report = require('../../utils/report');
8const ruleMessages = require('../../utils/ruleMessages');
9const validateOptions = require('../../utils/validateOptions');
10const whitespaceChecker = require('../../utils/whitespaceChecker');
11
12const ruleName = 'declaration-colon-newline-after';
13
14const messages = ruleMessages(ruleName, {
15 expectedAfter: () => 'Expected newline after ":"',
16 expectedAfterMultiLine: () => 'Expected newline after ":" with a multi-line declaration',
17});
18
19function rule(expectation, options, context) {
20 const checker = whitespaceChecker('newline', expectation, messages);
21
22 return (root, result) => {
23 const validOptions = validateOptions(result, ruleName, {
24 actual: expectation,
25 possible: ['always', 'always-multi-line'],
26 });
27
28 if (!validOptions) {
29 return;
30 }
31
32 root.walkDecls((decl) => {
33 if (!isStandardSyntaxDeclaration(decl)) {
34 return;
35 }
36
37 // Get the raw prop, and only the prop
38 const endOfPropIndex = declarationValueIndex(decl) + (decl.raws.between || '').length - 1;
39
40 // The extra characters tacked onto the end ensure that there is a character to check
41 // after the colon. Otherwise, with `background:pink` the character after the
42 const propPlusColon = `${decl.toString().slice(0, endOfPropIndex)}xxx`;
43
44 for (let i = 0, l = propPlusColon.length; i < l; i++) {
45 if (propPlusColon[i] !== ':') {
46 continue;
47 }
48
49 const indexToCheck = /^[^\S\r\n]*\/\*/.test(propPlusColon.slice(i + 1))
50 ? propPlusColon.indexOf('*/', i) + 1
51 : i;
52
53 checker.afterOneOnly({
54 source: propPlusColon,
55 index: indexToCheck,
56 lineCheckStr: decl.value,
57 err: (m) => {
58 if (context.fix) {
59 const between = decl.raws.between;
60 const betweenStart = declarationValueIndex(decl) - between.length;
61 const sliceIndex = indexToCheck - betweenStart + 1;
62 const betweenBefore = between.slice(0, sliceIndex);
63 const betweenAfter = between.slice(sliceIndex);
64
65 if (/^\s*\r?\n/.test(betweenAfter)) {
66 decl.raws.between = betweenBefore + betweenAfter.replace(/^[^\S\r\n]*/, '');
67 } else {
68 decl.raws.between = betweenBefore + context.newline + betweenAfter;
69 }
70
71 return;
72 }
73
74 report({
75 message: m,
76 node: decl,
77 index: indexToCheck,
78 result,
79 ruleName,
80 });
81 },
82 });
83 }
84 });
85 };
86}
87
88rule.ruleName = ruleName;
89rule.messages = messages;
90module.exports = rule;