Initial commit

This commit is contained in:
Patrick Marsceill
2017-03-09 13:16:08 -05:00
commit b7b0d0d7bf
4147 changed files with 401224 additions and 0 deletions

View File

@@ -0,0 +1,158 @@
# declaration-block-no-redundant-longhand-properties
Disallow longhand properties that can be combined into one shorthand property.
```css
a {
padding-top: 1px;
padding-right: 2px;
padding-bottom: 3px;
padding-left: 4px; }
/** ↑
* These longhand properties */
```
The longhand properties in the example above can be more concisely written as:
```css
a {
padding: 1px 2px 3px 4px;
}
```
This rule will only warn if you've used the longhand equivalent of *all* the properties that the shorthand will set.
This rule warns when the following shorthand properties can be used:
- `padding`
- `margin`
- `background`
- `font`
- `border`
- `border-top`
- `border-bottom`
- `border-left`
- `border-right`
- `border-width`
- `border-style`
- `border-color`
- `border-radius`
- `transition`
## Options
### `true`
The following patterns are considered warnings:
```css
a {
margin-top: 1px;
margin-right: 2px;
margin-bottom: 3px;
margin-left: 4px;
}
```
```css
a {
font-style: italic;
font-variant: normal;
font-weight: bold;
font-stretch: normal;
font-size: 14px;
line-height: 1.2;
font-family: serif;
}
```
```css
a {
-webkit-transition-property: top;
-webkit-transition-duration: 2s;
-webkit-transition-timing-function: ease;
-webkit-transition-delay: 0.5s;
}
```
The following patterns are *not* considered warnings:
```css
a {
margin: 1px 2px 3px 4px;
}
```
```css
a {
font: italic normal bold normal 14px/1.2 serif;
}
```
```css
a {
-webkit-transition: top 2s ease 0.5s;
}
```
```css
a {
margin-top: 1px;
margin-right: 2px;
}
```
```css
a {
margin-top: 1px;
margin-right: 2px;
margin-bottom: 3px;
}
```
## Optional secondary options
### `ignoreShorthands: ["/regex/", "string"]`
Given:
```js
["padding", "/border/"]
```
The following patterns are *not* considered warnings:
```css
a {
padding-top: 20px;
padding-right: 10px;
padding-bottom: 30px;
padding-left: 10px;
}
```
```css
a {
border-top-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
border-right-width: 1px;
}
```
```css
a {
border-top-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
border-right-width: 1px;
}
```
```css
a {
border-top-color: green;
border-top-style: double;
border-top-width: 7px;
}
```

View File

@@ -0,0 +1,80 @@
"use strict"
const _ = require("lodash")
const optionsMatches = require("../../utils/optionsMatches")
const report = require("../../utils/report")
const ruleMessages = require("../../utils/ruleMessages")
const shorthandData = require("../../reference/shorthandData")
const validateOptions = require("../../utils/validateOptions")
const ruleName = "declaration-block-no-redundant-longhand-properties"
const messages = ruleMessages(ruleName, {
expected: props => `Expected shorthand property "${props}"`,
})
const rule = function (actual, options) {
return (root, result) => {
const validOptions = validateOptions(result, ruleName, { actual }, {
actual: options,
possible: {
ignoreShorthands: [_.isString],
},
optional: true,
})
if (!validOptions) {
return
}
const longhandProperties = _.transform(shorthandData, (result, values, key) => {
if (optionsMatches(options, "ignoreShorthands", key)) {
return
}
values.forEach(value => {
(result[value] || (result[value] = [])).push(key)
})
})
root.walkRules(check)
root.walkAtRules(check)
function check(statement) {
const longhandDeclarations = {}
// Shallow iteration so nesting doesn't produce
// false positives
statement.each(node => {
if (node.type !== "decl") {
return
}
const prop = node.prop.toLowerCase()
const shorthandProperties = longhandProperties[prop]
if (!shorthandProperties) {
return
}
shorthandProperties.forEach(shorthandProperty => {
(longhandDeclarations[shorthandProperty] || (longhandDeclarations[shorthandProperty] = [])).push(prop)
if (!_.isEqual(shorthandData[shorthandProperty].sort(), longhandDeclarations[shorthandProperty].sort())) {
return
}
report({
ruleName,
result,
node,
message: messages.expected(shorthandProperty),
})
})
})
}
}
}
rule.ruleName = ruleName
rule.messages = messages
module.exports = rule