Skip to content

Commit a15295a

Browse files
Add range context support for media-feature-name-* rules (#4581)
* feat: add ranged context support for media-feature-name-* rules * test: update snapshot * docs: update docs * chore: add comments to the code Co-authored-by: jeddy3 <[email protected]>
1 parent 9bac82a commit a15295a

File tree

18 files changed

+455
-108
lines changed

18 files changed

+455
-108
lines changed

lib/rules/media-feature-name-blacklist/README.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ Specify a blacklist of disallowed media feature names.
88
* This media feature name */
99
```
1010

11-
**Caveat:** Media feature names within a range context are currently ignored.
12-
1311
## Options
1412

1513
`array|string|regex`: `["array", "of", "unprefixed", /media-features/ or "regex"]|"media-feature"|/regex/`
@@ -30,6 +28,14 @@ The following patterns are considered violations:
3028
@media (my-width: 50em) {}
3129
```
3230

31+
```css
32+
@media (max-width < 50em) {}
33+
```
34+
35+
```css
36+
@media (10em < my-height < 50em) {}
37+
```
38+
3339
The following patterns are *not* considered violations:
3440

3541
```css
@@ -39,3 +45,11 @@ The following patterns are *not* considered violations:
3945
```css
4046
@media print and (min-resolution: 300dpi) {}
4147
```
48+
49+
```css
50+
@media (min-width >= 50em) {}
51+
```
52+
53+
```css
54+
@media (10em < width < 50em) {}
55+
```

lib/rules/media-feature-name-blacklist/__tests__/index.js

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,18 @@ testRule(rule, {
1818
code: '@media (MiN-wIdTh: 50em) { }',
1919
},
2020
{
21-
code: '@media (--wide-viewport) { }',
22-
description: 'ignore custom media query',
21+
code: '@media (height <= 50em) { }',
2322
},
2423
{
25-
code: '@media (/* max-width: 50em */ min-width: 50em) { }',
26-
description: 'ignore comments',
24+
code: '@media (400px < height < 1000px) { }',
2725
},
2826
{
29-
code: '@media (width <= 50em) { }',
30-
description: 'ignore media features in a range context',
27+
code: '@media (--wide-viewport) { }',
28+
description: 'ignore custom media query',
3129
},
3230
{
33-
code: '@media (400px < width < 1000px) { }',
34-
description: 'ignore media features in a range context',
31+
code: '@media (/* max-width: 50em */ min-width: 50em) { }',
32+
description: 'ignore comments',
3533
},
3634
{
3735
code: '@media (monochrome) { }',
@@ -70,6 +68,33 @@ testRule(rule, {
7068
line: 1,
7169
column: 9,
7270
},
71+
{
72+
code: '@media (width: 50em) { }',
73+
message: messages.rejected('width'),
74+
line: 1,
75+
column: 9,
76+
},
77+
{
78+
code: '@media (20em < width <= 50em) { }',
79+
message: messages.rejected('width'),
80+
line: 1,
81+
column: 16,
82+
},
83+
{
84+
code: '@media (10em < max-width <= 50em) and (width > 50em) { }',
85+
warnings: [
86+
{
87+
message: messages.rejected('max-width'),
88+
line: 1,
89+
column: 16,
90+
},
91+
{
92+
message: messages.rejected('width'),
93+
line: 1,
94+
column: 40,
95+
},
96+
],
97+
},
7398
],
7499
});
75100

@@ -90,6 +115,24 @@ testRule(rule, {
90115
line: 1,
91116
column: 9,
92117
},
118+
{
119+
code: '@media (my-width >= 50em) { }',
120+
message: messages.rejected('my-width'),
121+
line: 1,
122+
column: 9,
123+
},
124+
{
125+
code: '@media (10em < my-width <= 50em) { }',
126+
message: messages.rejected('my-width'),
127+
line: 1,
128+
column: 16,
129+
},
130+
{
131+
code: '@media (50em < my-width) { }',
132+
message: messages.rejected('my-width'),
133+
line: 1,
134+
column: 16,
135+
},
93136
],
94137
});
95138

lib/rules/media-feature-name-blacklist/index.js

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const isRangeContextMediaFeature = require('../../utils/isRangeContextMediaFeatu
77
const isStandardSyntaxMediaFeatureName = require('../../utils/isStandardSyntaxMediaFeatureName');
88
const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp');
99
const mediaParser = require('postcss-media-query-parser').default;
10+
const rangeContextNodeParser = require('../rangeContextNodeParser');
1011
const report = require('../../utils/report');
1112
const ruleMessages = require('../../utils/ruleMessages');
1213
const validateOptions = require('../../utils/validateOptions');
@@ -31,14 +32,22 @@ function rule(blacklist) {
3132
root.walkAtRules(/^media$/i, (atRule) => {
3233
mediaParser(atRule.params).walk(/^media-feature$/i, (mediaFeatureNode) => {
3334
const parent = mediaFeatureNode.parent;
34-
const sourceIndex = mediaFeatureNode.sourceIndex;
35-
const value = mediaFeatureNode.value;
35+
const mediaFeatureRangeContext = isRangeContextMediaFeature(parent.value);
3636

37-
if (
38-
isRangeContextMediaFeature(parent.value) ||
39-
!isStandardSyntaxMediaFeatureName(value) ||
40-
isCustomMediaQuery(value)
41-
) {
37+
let value;
38+
let sourceIndex;
39+
40+
if (mediaFeatureRangeContext) {
41+
const parsedRangeContext = rangeContextNodeParser(mediaFeatureNode);
42+
43+
value = parsedRangeContext.name.value;
44+
sourceIndex = parsedRangeContext.name.sourceIndex;
45+
} else {
46+
value = mediaFeatureNode.value;
47+
sourceIndex = mediaFeatureNode.sourceIndex;
48+
}
49+
50+
if (!isStandardSyntaxMediaFeatureName(value) || isCustomMediaQuery(value)) {
4251
return;
4352
}
4453

lib/rules/media-feature-name-case/README.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ Specify lowercase or uppercase for media feature names.
88
* This media feature name */
99
```
1010

11-
This rule ignores media feature names within a range context.
12-
1311
The [`fix` option](../../../docs/user-guide/usage/options.md#fix) can automatically fix all of the problems reported by this rule.
1412

1513
## Options
@@ -32,6 +30,10 @@ The following patterns are considered violations:
3230
@media (min-width: 700px) and (ORIENTATION: landscape) {}
3331
```
3432

33+
```css
34+
@media (WIDTH > 10em) {}
35+
```
36+
3537
The following patterns are *not* considered violations:
3638

3739
```css
@@ -46,6 +48,10 @@ The following patterns are *not* considered violations:
4648
@media (min-width: 700px) and (orientation: landscape) {}
4749
```
4850

51+
```css
52+
@media (width > 10em) {}
53+
```
54+
4955
### `"upper"`
5056

5157
The following patterns are considered violations:
@@ -62,6 +68,10 @@ The following patterns are considered violations:
6268
@media (MIN-WIDTH: 700px) and (orientation: landscape) {}
6369
```
6470

71+
```css
72+
@media (10em < width <= 50em) {}
73+
```
74+
6575
The following patterns are *not* considered violations:
6676

6777
```css
@@ -75,3 +85,7 @@ The following patterns are *not* considered violations:
7585
```css
7686
@media (MIN-WIDTH: 700px) and (ORIENTATION: landscape) {}
7787
```
88+
89+
```css
90+
@media (10em < WIDTH <= 50em) {}
91+
```

lib/rules/media-feature-name-case/__tests__/index.js

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@ testRule(rule, {
1818
{
1919
code: '@media (min-width: 700PX) { }',
2020
},
21+
{
22+
code: '@media (width < 100px) { }',
23+
},
24+
{
25+
code: '@media (width = 100px) { }',
26+
},
27+
{
28+
code: '@media (width <= 100px) { }',
29+
},
30+
{
31+
code: '@media (10px <= width <= 100px) { }',
32+
},
2133
{
2234
code: '@media (min-width: 700px) and (orientation: landscape) { }',
2335
},
@@ -48,22 +60,6 @@ testRule(rule, {
4860
code: '@media (--VIEWPORT-MEDIUM) { }',
4961
description: 'ignore css variables',
5062
},
51-
{
52-
code: '@media (WIDTH < 100px) { }',
53-
description: 'ignore range context',
54-
},
55-
{
56-
code: '@media (WIDTH = 100px) { }',
57-
description: 'ignore range context',
58-
},
59-
{
60-
code: '@media (WIDTH <= 100px) { }',
61-
description: 'ignore range context',
62-
},
63-
{
64-
code: '@media (10px >= WIDTH <= 100px) { }',
65-
description: 'ignore complex range context',
66-
},
6763
],
6864

6965
reject: [
@@ -133,6 +129,41 @@ testRule(rule, {
133129
line: 1,
134130
column: 9,
135131
},
132+
{
133+
code: '@media (height: 50em) and (orientation: landscape) and (WIDTH: 25em) {}',
134+
fixed: '@media (height: 50em) and (orientation: landscape) and (width: 25em) {}',
135+
message: messages.expected('WIDTH', 'width'),
136+
line: 1,
137+
column: 57,
138+
},
139+
{
140+
code: '@media (WIDTH > 50em) {}',
141+
fixed: '@media (width > 50em) {}',
142+
message: messages.expected('WIDTH', 'width'),
143+
line: 1,
144+
column: 9,
145+
},
146+
{
147+
code: '@media (10em < WIDTH <= 50em) {}',
148+
fixed: '@media (10em < width <= 50em) {}',
149+
message: messages.expected('WIDTH', 'width'),
150+
line: 1,
151+
column: 16,
152+
},
153+
{
154+
code: '@media (width > 10em) and (WIDTH < 50em) {}',
155+
fixed: '@media (width > 10em) and (width < 50em) {}',
156+
message: messages.expected('WIDTH', 'width'),
157+
line: 1,
158+
column: 28,
159+
},
160+
{
161+
code: '@media (10em < WIDTH) {}',
162+
fixed: '@media (10em < width) {}',
163+
message: messages.expected('WIDTH', 'width'),
164+
line: 1,
165+
column: 16,
166+
},
136167
],
137168
});
138169

lib/rules/media-feature-name-case/index.js

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const isCustomMediaQuery = require('../../utils/isCustomMediaQuery');
66
const isRangeContextMediaFeature = require('../../utils/isRangeContextMediaFeature');
77
const isStandardSyntaxMediaFeatureName = require('../../utils/isStandardSyntaxMediaFeatureName');
88
const mediaParser = require('postcss-media-query-parser').default;
9+
const rangeContextNodeParser = require('../rangeContextNodeParser');
910
const report = require('../../utils/report');
1011
const ruleMessages = require('../../utils/ruleMessages');
1112
const validateOptions = require('../../utils/validateOptions');
@@ -33,14 +34,22 @@ function rule(expectation, options, context) {
3334

3435
mediaParser(mediaRule).walk(/^media-feature$/i, (mediaFeatureNode) => {
3536
const parent = mediaFeatureNode.parent;
36-
const sourceIndex = mediaFeatureNode.sourceIndex;
37-
const value = mediaFeatureNode.value;
38-
39-
if (
40-
isRangeContextMediaFeature(parent.value) ||
41-
!isStandardSyntaxMediaFeatureName(value) ||
42-
isCustomMediaQuery(value)
43-
) {
37+
const mediaFeatureRangeContext = isRangeContextMediaFeature(parent.value);
38+
39+
let value;
40+
let sourceIndex;
41+
42+
if (mediaFeatureRangeContext) {
43+
const parsedRangeContext = rangeContextNodeParser(mediaFeatureNode);
44+
45+
value = parsedRangeContext.name.value;
46+
sourceIndex = parsedRangeContext.name.sourceIndex;
47+
} else {
48+
value = mediaFeatureNode.value;
49+
sourceIndex = mediaFeatureNode.sourceIndex;
50+
}
51+
52+
if (!isStandardSyntaxMediaFeatureName(value) || isCustomMediaQuery(value)) {
4453
return;
4554
}
4655

lib/rules/media-feature-name-no-unknown/README.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@ Disallow unknown media feature names.
1010

1111
This rule considers media feature names defined in the CSS Specifications, up to and including Editor's Drafts, to be known.
1212

13-
This rule ignores:
14-
15-
- media feature names within a range context
16-
- vendor-prefixed media feature names
13+
This rule ignores vendor-prefixed media feature names.
1714

1815
## Options
1916

@@ -29,6 +26,10 @@ The following patterns are considered violations:
2926
@media screen and (unknown: 10px) {}
3027
```
3128

29+
```css
30+
@media screen and (unknown > 10px) {}
31+
```
32+
3233
The following patterns are *not* considered violations:
3334

3435
```css
@@ -71,6 +72,10 @@ The following patterns are *not* considered violations:
7172
@media screen and (custom: 10px) {}
7273
```
7374

75+
```css
76+
@media screen and (100px < custom < 700px) {}
77+
```
78+
7479
```css
7580
@media (min-width: 700px) and (custom: 10px) {}
7681
```

0 commit comments

Comments
 (0)