UNPKG

2.44 kBJavaScriptView Raw
1'use strict';
2
3const _ = require('lodash');
4const postcss = require('postcss');
5const report = require('../../utils/report');
6const ruleMessages = require('../../utils/ruleMessages');
7const validateOptions = require('../../utils/validateOptions');
8
9const ruleName = 'linebreaks';
10
11const messages = ruleMessages(ruleName, {
12 expected: (linebreak) => `Expected linebreak to be ${linebreak}`,
13});
14
15function rule(actual, secondary, context) {
16 return (root, result) => {
17 const validOptions = validateOptions(result, ruleName, {
18 actual,
19 possible: ['unix', 'windows'],
20 });
21
22 if (!validOptions) {
23 return;
24 }
25
26 const shouldHaveCR = actual === 'windows';
27
28 if (context.fix) {
29 const propertiesToUpdate = ['selector', 'raws.before', 'raws.after', 'value', 'text'];
30
31 root.walk((node) => {
32 propertiesToUpdate.forEach((property) => {
33 const fixedData = fixData(_.get(node, property), shouldHaveCR);
34
35 _.set(node, property, fixedData);
36 });
37 });
38
39 root.raws.after = fixData(root.raws.after, shouldHaveCR);
40 } else {
41 const lines = root.source.input.css.split('\n');
42
43 for (let i = 0; i < lines.length; i++) {
44 let line = lines[i];
45
46 if (i < lines.length - 1 && !line.includes('\r')) {
47 line += '\n';
48 }
49
50 if (hasError(line, shouldHaveCR)) {
51 const lineNum = i + 1;
52 const colNum = line.length;
53
54 reportNewlineError(shouldHaveCR, lineNum, colNum, actual, result);
55 }
56 }
57 }
58
59 function hasError(dataToCheck, shouldHaveCR) {
60 const hasNewlineToVerify = /[\r\n]/.test(dataToCheck);
61 const hasCR = hasNewlineToVerify ? /\r/.test(dataToCheck) : false;
62
63 return hasNewlineToVerify && hasCR !== shouldHaveCR;
64 }
65
66 function fixData(data, shouldHaveCR) {
67 if (data) {
68 let result = data.replace(/\r/g, '');
69
70 if (shouldHaveCR) {
71 result = result.replace(/\n/g, '\r\n');
72 }
73
74 return result;
75 }
76
77 return data;
78 }
79
80 function createReportNode(line, column) {
81 // Creating a node manually helps us to point to empty lines.
82 return postcss.rule({
83 source: {
84 start: {
85 line,
86 column,
87 },
88 },
89 });
90 }
91
92 function reportNewlineError(shouldHaveCR, lineNum, colNum, actual, result) {
93 const reportNode = createReportNode(lineNum, colNum);
94
95 report({
96 message: messages.expected(actual),
97 node: reportNode,
98 result,
99 ruleName,
100 });
101 }
102 };
103}
104
105rule.ruleName = ruleName;
106rule.messages = messages;
107module.exports = rule;