Skip to content

Commit

Permalink
Add ignoreLonghands: [] to `declaration-block-no-redundant-longhand…
Browse files Browse the repository at this point in the history
…-properties` (#7611)
  • Loading branch information
Mouvedia committed Apr 18, 2024
1 parent fd1e50f commit 9959110
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/selfish-plums-dream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"stylelint": minor
---

Fixed: `declaration-block-no-redundant-longhand-properties` autofix for `text-decoration`
5 changes: 5 additions & 0 deletions .changeset/sharp-buses-drop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"stylelint": minor
---

Added: `ignoreLonghands: []` to `declaration-block-no-redundant-longhand-properties`
1 change: 1 addition & 0 deletions lib/reference/properties.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,7 @@ const longhandSubPropertiesOfShorthandProperties = new Map([
'text-decoration-line',
'text-decoration-style',
'text-decoration-color',
'text-decoration-thickness',
]),
],
[
Expand Down
1 change: 1 addition & 0 deletions lib/reference/properties.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ export const longhandSubPropertiesOfShorthandProperties = new Map([
'text-decoration-line',
'text-decoration-style',
'text-decoration-color',
'text-decoration-thickness',
]),
],
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,60 @@ a {

## Optional secondary options

### `ignoreLonghands: ["string"]`

Given:

<!-- prettier-ignore -->
```json
["text-decoration-thickness", "background-size", "background-origin", "background-clip"]
```

The following patterns are considered problems:

<!-- prettier-ignore -->
```css
a {
text-decoration-line: underline;
text-decoration-style: solid;
text-decoration-color: purple;
}
```

<!-- prettier-ignore -->
```css
a {
background-repeat: repeat;
background-attachment: scroll;
background-position: 0% 0%;
background-color: transparent;
background-image: none;
background-size: contain;
background-origin: border-box;
background-clip: text;
}
```

The following patterns are _not_ considered problems:

<!-- prettier-ignore -->
```css
a {
text-decoration: underline solid purple;
text-decoration-thickness: 1px;
}
```

<!-- prettier-ignore -->
```css
a {
background: none 0% 0% repeat scroll transparent;
background-size: contain;
background-origin: border-box;
background-clip: text;
}
```

### `ignoreShorthands: ["/regex/", /regex/, "string"]`

Given:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ testRule({
code: 'a { transition-delay: 500ms, 1s; transition-duration: 250ms,2s; transition-timing-function: ease-in-out; transition-property: inherit; }',
description: 'transition property contains basic keyword (inherit)',
},
{
code: 'a { text-decoration-line: underline; text-decoration-style: solid; text-decoration-color: purple; }',
description: 'missing text-decoration-thickness',
},
{
code: 'a { background-repeat: repeat; background-attachment: scroll; background-position: 0% 0%; background-color: transparent; background-image: none; background-origin: border-box; background-clip: text; }',
description: 'missing background-size',
},
],

reject: [
Expand Down Expand Up @@ -387,6 +395,50 @@ testRule({
'the repeat() notation has non-trivial semantics and is currently not fixable (rows)',
message: messages.expected('grid-template'),
},
{
code: 'a { text-decoration-color: purple; text-decoration-thickness: 1px; text-decoration-style: solid; text-decoration-line: underline; }',
fixed: 'a { text-decoration: underline solid purple 1px; }',
message: messages.expected('text-decoration'),
description: 'CSS Text Decoration Module Level 4',
},
],
});

testRule({
ruleName,
config: [
true,
{
ignoreLonghands: [
'background-size',
'background-origin',
'background-clip',
'text-decoration-thickness',
],
},
],
fix: true,

reject: [
{
code: 'a { text-decoration-line: underline; text-decoration-style: solid; text-decoration-color: purple; }',
fixed: 'a { text-decoration: underline solid purple; }',
description: 'CSS Text Decoration Module Level 3',
message: messages.expected('text-decoration'),
},
{
code: 'a { text-decoration-color: purple; text-decoration-thickness: 1px; text-decoration-style: solid; text-decoration-line: underline; text-decoration-width: 1px; }',
fixed:
'a { text-decoration: underline solid purple; text-decoration-thickness: 1px; text-decoration-width: 1px; }',
description: 'ignore text-decoration-width by default',
message: messages.expected('text-decoration'),
},
{
code: 'a { background-repeat: repeat; background-attachment: scroll; background-position: 0% 0%; background-color: transparent; background-image: none; background-size: contain; background-origin: border-box; background-clip: text; }',
fixed:
'a { background: none 0% 0% repeat scroll transparent; background-size: contain; background-origin: border-box; background-clip: text; }',
message: messages.expected('background'),
},
],
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ const rule = (primary, secondaryOptions, context) => {
actual: secondaryOptions,
possible: {
ignoreShorthands: [validateTypes.isString, validateTypes.isRegExp],
ignoreLonghands: [validateTypes.isString],
},
optional: true,
},
Expand All @@ -230,13 +231,17 @@ const rule = (primary, secondaryOptions, context) => {

/** @type {Map<string, import('stylelint').ShorthandProperties[]>} */
const longhandToShorthands = new Map();
/** @type {string[]} */
const ignoreLonghands = secondaryOptions?.ignoreLonghands ?? [];

for (const [shorthand, longhandProps] of properties.longhandSubPropertiesOfShorthandProperties.entries()) {
if (optionsMatches(secondaryOptions, 'ignoreShorthands', shorthand)) {
continue;
}

for (const longhand of longhandProps) {
if (ignoreLonghands.includes(longhand)) continue;

const shorthands = longhandToShorthands.get(longhand) || [];

shorthands.push(shorthand);
Expand Down Expand Up @@ -278,11 +283,15 @@ const rule = (primary, secondaryOptions, context) => {
longhandDeclarationNode.push(decl);
longhandDeclarationNodes.set(prefixedShorthandProperty, longhandDeclarationNode);

const shorthandProps = properties.longhandSubPropertiesOfShorthandProperties.get(shorthandProperty);
const prefixedShorthandData = Array.from(shorthandProps || [], (item) => prefix + item);
const shorthandProps = new Set(
properties.longhandSubPropertiesOfShorthandProperties.get(shorthandProperty),
);

ignoreLonghands.forEach((value) => shorthandProps.delete(value));
const prefixedShorthandData = Array.from(shorthandProps, (item) => prefix + item);
const copiedPrefixedShorthandData = [...prefixedShorthandData];

// TODO use toSorted in the next major that supports it
if (!arrayEqual(copiedPrefixedShorthandData.sort(), longhandDeclaration.sort())) {
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ const rule = (primary, secondaryOptions, context) => {
actual: secondaryOptions,
possible: {
ignoreShorthands: [isString, isRegExp],
ignoreLonghands: [isString],
},
optional: true,
},
Expand All @@ -227,13 +228,17 @@ const rule = (primary, secondaryOptions, context) => {

/** @type {Map<string, import('stylelint').ShorthandProperties[]>} */
const longhandToShorthands = new Map();
/** @type {string[]} */
const ignoreLonghands = secondaryOptions?.ignoreLonghands ?? [];

for (const [shorthand, longhandProps] of longhandSubPropertiesOfShorthandProperties.entries()) {
if (optionsMatches(secondaryOptions, 'ignoreShorthands', shorthand)) {
continue;
}

for (const longhand of longhandProps) {
if (ignoreLonghands.includes(longhand)) continue;

const shorthands = longhandToShorthands.get(longhand) || [];

shorthands.push(shorthand);
Expand Down Expand Up @@ -275,11 +280,15 @@ const rule = (primary, secondaryOptions, context) => {
longhandDeclarationNode.push(decl);
longhandDeclarationNodes.set(prefixedShorthandProperty, longhandDeclarationNode);

const shorthandProps = longhandSubPropertiesOfShorthandProperties.get(shorthandProperty);
const prefixedShorthandData = Array.from(shorthandProps || [], (item) => prefix + item);
const shorthandProps = new Set(
longhandSubPropertiesOfShorthandProperties.get(shorthandProperty),
);

ignoreLonghands.forEach((value) => shorthandProps.delete(value));
const prefixedShorthandData = Array.from(shorthandProps, (item) => prefix + item);
const copiedPrefixedShorthandData = [...prefixedShorthandData];

// TODO use toSorted in the next major that supports it
if (!arrayEqual(copiedPrefixedShorthandData.sort(), longhandDeclaration.sort())) {
continue;
}
Expand Down

0 comments on commit 9959110

Please sign in to comment.