UNPKG

2.24 kBJavaScriptView Raw
1'use strict';
2
3const _ = require('lodash');
4const declarationValueIndex = require('../../utils/declarationValueIndex');
5const findFontFamily = require('../../utils/findFontFamily');
6const keywordSets = require('../../reference/keywordSets');
7const optionsMatches = require('../../utils/optionsMatches');
8const report = require('../../utils/report');
9const ruleMessages = require('../../utils/ruleMessages');
10const validateOptions = require('../../utils/validateOptions');
11
12const ruleName = 'font-family-no-duplicate-names';
13
14const messages = ruleMessages(ruleName, {
15 rejected: (name) => `Unexpected duplicate name ${name}`,
16});
17
18const isFamilyNameKeyword = (node) =>
19 !node.quote && keywordSets.fontFamilyKeywords.has(node.value.toLowerCase());
20
21function rule(actual, options) {
22 return (root, result) => {
23 const validOptions = validateOptions(
24 result,
25 ruleName,
26 { actual },
27 {
28 actual: options,
29 possible: {
30 ignoreFontFamilyNames: [_.isString, _.isRegExp],
31 },
32 optional: true,
33 },
34 );
35
36 if (!validOptions) {
37 return;
38 }
39
40 root.walkDecls(/^font(-family)?$/i, (decl) => {
41 const keywords = new Set();
42 const familyNames = new Set();
43
44 const fontFamilies = findFontFamily(decl.value);
45
46 if (fontFamilies.length === 0) {
47 return;
48 }
49
50 fontFamilies.forEach((fontFamilyNode) => {
51 const family = fontFamilyNode.value.trim();
52
53 if (optionsMatches(options, 'ignoreFontFamilyNames', fontFamilyNode.value.trim())) {
54 return;
55 }
56
57 if (isFamilyNameKeyword(fontFamilyNode)) {
58 if (keywords.has(family.toLowerCase())) {
59 complain(
60 messages.rejected(family),
61 declarationValueIndex(decl) + fontFamilyNode.sourceIndex,
62 decl,
63 );
64
65 return;
66 }
67
68 keywords.add(family);
69
70 return;
71 }
72
73 if (familyNames.has(family)) {
74 complain(
75 messages.rejected(family),
76 declarationValueIndex(decl) + fontFamilyNode.sourceIndex,
77 decl,
78 );
79
80 return;
81 }
82
83 familyNames.add(family);
84 });
85 });
86
87 function complain(message, index, decl) {
88 report({
89 result,
90 ruleName,
91 message,
92 node: decl,
93 index,
94 });
95 }
96 };
97}
98
99rule.ruleName = ruleName;
100rule.messages = messages;
101module.exports = rule;