1 | "use strict";
|
2 |
|
3 | const _ = require("lodash");
|
4 | const declarationValueIndex = require("../utils/declarationValueIndex");
|
5 | const isStandardSyntaxFunction = require("../utils/isStandardSyntaxFunction");
|
6 | const report = require("../utils/report");
|
7 | const valueParser = require("postcss-value-parser");
|
8 |
|
9 | module.exports = function(opts) {
|
10 | opts.root.walkDecls(decl => {
|
11 | const declValue = _.get(decl, "raws.value.raw", decl.value);
|
12 |
|
13 | let hasFixed;
|
14 | const parsedValue = valueParser(declValue);
|
15 |
|
16 | parsedValue.walk(valueNode => {
|
17 | if (valueNode.type !== "function") {
|
18 | return;
|
19 | }
|
20 |
|
21 | if (!isStandardSyntaxFunction(valueNode)) {
|
22 | return;
|
23 | }
|
24 |
|
25 |
|
26 | if (valueNode.value.toLowerCase() === "url") {
|
27 | return;
|
28 | }
|
29 |
|
30 | const argumentStrings = valueNode.nodes.map(node =>
|
31 | valueParser.stringify(node)
|
32 | );
|
33 |
|
34 | const functionArguments = (() => {
|
35 |
|
36 | let result =
|
37 | valueNode.before + argumentStrings.join("") + valueNode.after;
|
38 |
|
39 |
|
40 |
|
41 | result = result.replace(
|
42 | /( *\/(\*.*\*\/(?!\S)|\/.*)|(\/(\*.*\*\/|\/.*)))/,
|
43 | ""
|
44 | );
|
45 |
|
46 | return result;
|
47 | })();
|
48 |
|
49 | |
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 | function getCommaCheckIndex(commaNode, nodeIndex) {
|
56 | let commaBefore =
|
57 | valueNode.before +
|
58 | argumentStrings.slice(0, nodeIndex).join("") +
|
59 | commaNode.before;
|
60 |
|
61 |
|
62 |
|
63 | commaBefore = commaBefore.replace(
|
64 | /( *\/(\*.*\*\/(?!\S)|\/.*)|(\/(\*.*\*\/|\/.*)))/,
|
65 | ""
|
66 | );
|
67 |
|
68 | return commaBefore.length;
|
69 | }
|
70 |
|
71 | const commaDataList = [];
|
72 |
|
73 | valueNode.nodes.forEach((node, nodeIndex) => {
|
74 | if (node.type !== "div" || node.value !== ",") {
|
75 | return;
|
76 | }
|
77 |
|
78 | const checkIndex = getCommaCheckIndex(node, nodeIndex);
|
79 |
|
80 | commaDataList.push({
|
81 | commaNode: node,
|
82 | checkIndex,
|
83 | nodeIndex
|
84 | });
|
85 | });
|
86 |
|
87 | for (const { commaNode, checkIndex, nodeIndex } of commaDataList) {
|
88 | opts.locationChecker({
|
89 | source: functionArguments,
|
90 | index: checkIndex,
|
91 | err: message => {
|
92 | const index =
|
93 | declarationValueIndex(decl) +
|
94 | commaNode.sourceIndex +
|
95 | commaNode.before.length;
|
96 |
|
97 | if (opts.fix && opts.fix(commaNode, nodeIndex, valueNode.nodes)) {
|
98 | hasFixed = true;
|
99 |
|
100 | return;
|
101 | }
|
102 |
|
103 | report({
|
104 | index,
|
105 | message,
|
106 | node: decl,
|
107 | result: opts.result,
|
108 | ruleName: opts.checkedRuleName
|
109 | });
|
110 | }
|
111 | });
|
112 | }
|
113 | });
|
114 |
|
115 | if (hasFixed) {
|
116 | if (!decl.raws.value) {
|
117 | decl.value = parsedValue.toString();
|
118 | } else {
|
119 | decl.raws.value.raw = parsedValue.toString();
|
120 | }
|
121 | }
|
122 | });
|
123 | };
|