Skip to content

Commit

Permalink
Add ignore: ["consecutive-duplicates-with-same-prefixless-values"] to…
Browse files Browse the repository at this point in the history
… declaration-block-no-duplicate-properties (#5609)

Fixes #5607
  • Loading branch information
MightyCreak committed Oct 29, 2021
1 parent c844c4b commit d722e07
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 17 deletions.
37 changes: 37 additions & 0 deletions lib/rules/declaration-block-no-duplicate-properties/README.md
Expand Up @@ -108,6 +108,43 @@ p {
}
```

### `ignore: ["consecutive-duplicates-with-same-prefixless-values"]`

Ignore consecutive duplicated properties with identical values, when ignoring their prefix.

This option is useful to deal with draft CSS values while still being future proof. E.g. using `fit-content` and `-moz-fit-content`.

The following patterns are considered violations:

<!-- prettier-ignore -->
```css
/* nonconsecutive duplicates */
p {
width: fit-content;
height: 32px;
width: -moz-fit-content;
}
```

<!-- prettier-ignore -->
```css
/* properties with different prefixless values */
p {
width: -moz-fit-content;
width: 100%;
}
```

The following patterns are _not_ considered violations:

<!-- prettier-ignore -->
```css
p {
width: -moz-fit-content;
width: fit-content;
}
```

### `ignoreProperties: ["/regex/", "non-regex"]`

Ignore duplicates of specific properties.
Expand Down
Expand Up @@ -168,7 +168,43 @@ testRule({
},
{
code: 'p { font-size: 16px; font-size: 16px; font-weight: 400; }',
message: messages.rejected('16px'),
message: messages.rejected('font-size'),
},
],
});

testRule({
ruleName,
config: [true, { ignore: ['consecutive-duplicates-with-same-prefixless-values'] }],
skipBasicChecks: true,

accept: [
{
code: 'p { width: -moz-fit-content; width: fit-content; }',
},
{
code: 'p { width: fit-content; width: -moz-fit-content; }',
},
{
code: 'p { width: -MOZ-fit-content; width: fit-content; }',
},
{
code: 'p { width: -webkit-fit-content; width: -moz-fit-content; width: fit-content; }',
},
],

reject: [
{
code: 'p { width: fit-content; height: 32px; width: -moz-fit-content; }',
message: messages.rejected('width'),
},
{
code: 'p { width: 100%; width: -moz-fit-content; height: 32px; }',
message: messages.rejected('width'),
},
{
code: 'p { width: -moz-fit-content; width: -moz-fit-content; }',
message: messages.rejected('width'),
},
],
});
Expand Down
56 changes: 40 additions & 16 deletions lib/rules/declaration-block-no-duplicate-properties/index.js
Expand Up @@ -8,6 +8,7 @@ const report = require('../../utils/report');
const ruleMessages = require('../../utils/ruleMessages');
const validateOptions = require('../../utils/validateOptions');
const { isString } = require('../../utils/validateTypes');
const vendor = require('../../utils/vendor');

const ruleName = 'declaration-block-no-duplicate-properties';

Expand All @@ -25,7 +26,11 @@ const rule = (primary, secondaryOptions) => {
{
actual: secondaryOptions,
possible: {
ignore: ['consecutive-duplicates', 'consecutive-duplicates-with-different-values'],
ignore: [
'consecutive-duplicates',
'consecutive-duplicates-with-different-values',
'consecutive-duplicates-with-same-prefixless-values',
],
ignoreProperties: [isString],
},
optional: true,
Expand All @@ -36,6 +41,18 @@ const rule = (primary, secondaryOptions) => {
return;
}

const ignoreDuplicates = optionsMatches(secondaryOptions, 'ignore', 'consecutive-duplicates');
const ignoreDiffValues = optionsMatches(
secondaryOptions,
'ignore',
'consecutive-duplicates-with-different-values',
);
const ignorePrefixlessSameValues = optionsMatches(
secondaryOptions,
'ignore',
'consecutive-duplicates-with-same-prefixless-values',
);

eachDeclarationBlock(root, (eachDecl) => {
/** @type {string[]} */
const decls = [];
Expand Down Expand Up @@ -67,14 +84,8 @@ const rule = (primary, secondaryOptions) => {
const indexDuplicate = decls.indexOf(prop.toLowerCase());

if (indexDuplicate !== -1) {
if (
optionsMatches(
secondaryOptions,
'ignore',
'consecutive-duplicates-with-different-values',
)
) {
// if duplicates are not consecutive
if (ignoreDiffValues || ignorePrefixlessSameValues) {
// fails if duplicates are not consecutive
if (indexDuplicate !== decls.length - 1) {
report({
message: messages.rejected(prop),
Expand All @@ -86,10 +97,26 @@ const rule = (primary, secondaryOptions) => {
return;
}

// if values of consecutive duplicates are equal
if (value === values[indexDuplicate]) {
const duplicateValue = values[indexDuplicate];

if (ignorePrefixlessSameValues) {
// fails if values of consecutive, unprefixed duplicates are equal
if (vendor.unprefixed(value) !== vendor.unprefixed(duplicateValue)) {
report({
message: messages.rejected(prop),
node: decl,
result,
ruleName,
});

return;
}
}

// fails if values of consecutive duplicates are equal
if (value === duplicateValue) {
report({
message: messages.rejected(value),
message: messages.rejected(prop),
node: decl,
result,
ruleName,
Expand All @@ -101,10 +128,7 @@ const rule = (primary, secondaryOptions) => {
return;
}

if (
optionsMatches(secondaryOptions, 'ignore', 'consecutive-duplicates') &&
indexDuplicate === decls.length - 1
) {
if (ignoreDuplicates && indexDuplicate === decls.length - 1) {
return;
}

Expand Down

0 comments on commit d722e07

Please sign in to comment.