UNPKG

2.38 kBJavaScriptView Raw
1'use strict';
2
3const declarationValueIndex = require('../../utils/declarationValueIndex');
4const findNotContiguousOrRectangular = require('./utils/findNotContiguousOrRectangular');
5const isRectangular = require('./utils/isRectangular');
6const report = require('../../utils/report');
7const ruleMessages = require('../../utils/ruleMessages');
8const validateOptions = require('../../utils/validateOptions');
9const valueParser = require('postcss-value-parser');
10
11const ruleName = 'named-grid-areas-no-invalid';
12
13const messages = ruleMessages(ruleName, {
14 expectedToken: () => 'Expected cell token within string',
15 expectedSameNumber: () => 'Expected same number of cell tokens in each string',
16 expectedRectangle: (name) => `Expected single filled-in rectangle for "${name}"`,
17});
18
19const meta = {
20 url: 'https://stylelint.io/user-guide/rules/list/named-grid-areas-no-invalid',
21};
22
23/** @type {import('stylelint').Rule} */
24const rule = (primary) => {
25 return (root, result) => {
26 const validOptions = validateOptions(result, ruleName, { actual: primary });
27
28 if (!validOptions) {
29 return;
30 }
31
32 root.walkDecls(/^(?:grid|grid-template|grid-template-areas)$/i, (decl) => {
33 const { value } = decl;
34
35 if (value.toLowerCase().trim() === 'none') return;
36
37 /** @type {string[][]} */
38 const areas = [];
39 let reportSent = false;
40
41 valueParser(value).walk(({ sourceIndex, type, value: tokenValue }) => {
42 if (type !== 'string') return;
43
44 if (tokenValue === '') {
45 complain(messages.expectedToken(), sourceIndex);
46 reportSent = true;
47
48 return;
49 }
50
51 areas.push(
52 tokenValue
53 .trim()
54 .split(' ')
55 .filter((s) => s.length > 0),
56 );
57 });
58
59 if (reportSent) return;
60
61 if (!isRectangular(areas)) {
62 complain(messages.expectedSameNumber());
63
64 return;
65 }
66
67 const notContiguousOrRectangular = findNotContiguousOrRectangular(areas);
68
69 for (const name of notContiguousOrRectangular.sort()) {
70 complain(messages.expectedRectangle(name));
71 }
72
73 /**
74 * @param {string} message
75 * @param {number} [sourceIndex=0]
76 */
77 function complain(message, sourceIndex = 0) {
78 report({
79 message,
80 node: decl,
81 index: declarationValueIndex(decl) + sourceIndex,
82 result,
83 ruleName,
84 });
85 }
86 });
87 };
88};
89
90rule.ruleName = ruleName;
91rule.messages = messages;
92rule.meta = meta;
93module.exports = rule;