UNPKG

2.1 kBJavaScriptView Raw
1// @ts-nocheck
2
3'use strict';
4
5const isStandardSyntaxCombinator = require('../utils/isStandardSyntaxCombinator');
6const isStandardSyntaxRule = require('../utils/isStandardSyntaxRule');
7const parseSelector = require('../utils/parseSelector');
8const report = require('../utils/report');
9
10module.exports = function (opts) {
11 let hasFixed;
12
13 opts.root.walkRules((rule) => {
14 if (!isStandardSyntaxRule(rule)) {
15 return;
16 }
17
18 hasFixed = false;
19 const selector = rule.raws.selector ? rule.raws.selector.raw : rule.selector;
20
21 const fixedSelector = parseSelector(selector, opts.result, rule, (selectorTree) => {
22 selectorTree.walkCombinators((node) => {
23 // Ignore non-standard combinators
24 if (!isStandardSyntaxCombinator(node)) {
25 return;
26 }
27
28 // Ignore spaced descendant combinator
29 if (/\s/.test(node.value)) {
30 return;
31 }
32
33 // Check the exist of node in prev of the combinator.
34 // in case some that aren't the first begin with combinators (nesting syntax)
35 if (opts.locationType === 'before' && !node.prev()) {
36 return;
37 }
38
39 const parentParentNode = node.parent && node.parent.parent;
40
41 // Ignore pseudo-classes selector like `.foo:nth-child(2n + 1) {}`
42 if (parentParentNode && parentParentNode.type === 'pseudo') {
43 return;
44 }
45
46 const sourceIndex = node.sourceIndex;
47 const index =
48 node.value.length > 1 && opts.locationType === 'before'
49 ? sourceIndex
50 : sourceIndex + node.value.length - 1;
51
52 check(selector, node, index, rule, sourceIndex);
53 });
54 });
55
56 if (hasFixed) {
57 if (!rule.raws.selector) {
58 rule.selector = fixedSelector;
59 } else {
60 rule.raws.selector.raw = fixedSelector;
61 }
62 }
63 });
64
65 function check(source, combinator, index, node, sourceIndex) {
66 opts.locationChecker({
67 source,
68 index,
69 errTarget: combinator.value,
70 err: (m) => {
71 if (opts.fix && opts.fix(combinator)) {
72 hasFixed = true;
73
74 return;
75 }
76
77 report({
78 message: m,
79 node,
80 index: sourceIndex,
81 result: opts.result,
82 ruleName: opts.checkedRuleName,
83 });
84 },
85 });
86 }
87};