UNPKG

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