UNPKG

2.02 kBJavaScriptView Raw
1// @ts-nocheck
2
3'use strict';
4
5const isLogicalCombination = require('../../utils/isLogicalCombination');
6const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule');
7const parseSelector = require('../../utils/parseSelector');
8const report = require('../../utils/report');
9const resolvedNestedSelector = require('postcss-resolve-nested-selector');
10const ruleMessages = require('../../utils/ruleMessages');
11const validateOptions = require('../../utils/validateOptions');
12
13const ruleName = 'selector-max-id';
14
15const messages = ruleMessages(ruleName, {
16 expected: (selector, max) =>
17 `Expected "${selector}" to have no more than ${max} ID ${max === 1 ? 'selector' : 'selectors'}`,
18});
19
20function rule(max) {
21 return (root, result) => {
22 const validOptions = validateOptions(result, ruleName, {
23 actual: max,
24 possible: [
25 function (max) {
26 return typeof max === 'number' && max >= 0;
27 },
28 ],
29 });
30
31 if (!validOptions) {
32 return;
33 }
34
35 function checkSelector(selectorNode, ruleNode) {
36 const count = selectorNode.reduce((total, childNode) => {
37 // Only traverse inside actual selectors and logical combinations
38 if (childNode.type === 'selector' || isLogicalCombination(childNode)) {
39 checkSelector(childNode, ruleNode);
40 }
41
42 return (total += childNode.type === 'id' ? 1 : 0);
43 }, 0);
44
45 if (selectorNode.type !== 'root' && selectorNode.type !== 'pseudo' && count > max) {
46 report({
47 ruleName,
48 result,
49 node: ruleNode,
50 message: messages.expected(selectorNode, max),
51 word: selectorNode,
52 });
53 }
54 }
55
56 root.walkRules((ruleNode) => {
57 if (!isStandardSyntaxRule(ruleNode)) {
58 return;
59 }
60
61 ruleNode.selectors.forEach((selector) => {
62 resolvedNestedSelector(selector, ruleNode).forEach((resolvedSelector) => {
63 parseSelector(resolvedSelector, result, ruleNode, (container) =>
64 checkSelector(container, ruleNode),
65 );
66 });
67 });
68 });
69 };
70}
71
72rule.ruleName = ruleName;
73rule.messages = messages;
74module.exports = rule;