UNPKG

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