.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / stylelint / lib / rules / declaration-block-no-redundant-longhand-properties / index.js
1 "use strict";
2
3 const _ = require("lodash");
4 const optionsMatches = require("../../utils/optionsMatches");
5 const postcss = require("postcss");
6 const report = require("../../utils/report");
7 const ruleMessages = require("../../utils/ruleMessages");
8 const shorthandData = require("../../reference/shorthandData");
9 const validateOptions = require("../../utils/validateOptions");
10
11 const ruleName = "declaration-block-no-redundant-longhand-properties";
12
13 const messages = ruleMessages(ruleName, {
14   expected: props => `Expected shorthand property "${props}"`
15 });
16
17 const rule = function(actual, options) {
18   return (root, result) => {
19     const validOptions = validateOptions(
20       result,
21       ruleName,
22       { actual },
23       {
24         actual: options,
25         possible: {
26           ignoreShorthands: [_.isString]
27         },
28         optional: true
29       }
30     );
31     if (!validOptions) {
32       return;
33     }
34
35     const longhandProperties = _.transform(
36       shorthandData,
37       (result, values, key) => {
38         if (optionsMatches(options, "ignoreShorthands", key)) {
39           return;
40         }
41
42         values.forEach(value => {
43           (result[value] || (result[value] = [])).push(key);
44         });
45       }
46     );
47
48     root.walkRules(check);
49     root.walkAtRules(check);
50
51     function check(statement) {
52       const longhandDeclarations = {};
53       // Shallow iteration so nesting doesn't produce
54       // false positives
55       statement.each(node => {
56         if (node.type !== "decl") {
57           return;
58         }
59
60         const prop = node.prop.toLowerCase();
61         const unprefixedProp = postcss.vendor.unprefixed(prop);
62         const prefix = postcss.vendor.prefix(prop);
63
64         const shorthandProperties = longhandProperties[unprefixedProp];
65
66         if (!shorthandProperties) {
67           return;
68         }
69
70         shorthandProperties.forEach(shorthandProperty => {
71           const prefixedShorthandProperty = prefix + shorthandProperty;
72
73           if (!longhandDeclarations[prefixedShorthandProperty]) {
74             longhandDeclarations[prefixedShorthandProperty] = [];
75           }
76
77           longhandDeclarations[prefixedShorthandProperty].push(prop);
78
79           const prefixedShorthandData = shorthandData[shorthandProperty].map(
80             item => {
81               return prefix + item;
82             }
83           );
84
85           if (
86             !_.isEqual(
87               prefixedShorthandData.sort(),
88               longhandDeclarations[prefixedShorthandProperty].sort()
89             )
90           ) {
91             return;
92           }
93
94           report({
95             ruleName,
96             result,
97             node,
98             message: messages.expected(prefixedShorthandProperty)
99           });
100         });
101       });
102     }
103   };
104 };
105
106 rule.ruleName = ruleName;
107 rule.messages = messages;
108 module.exports = rule;