Skip to content

Commit

Permalink
Add media-feature-name-value-no-unknown (#6906)
Browse files Browse the repository at this point in the history
* wip

* first working draft

* Create real-dingos-boil.md

* note 1

* increase test coverage

* increase coverage

* increase test coverage

* cleanup

* improve code comments

* cleanup and a few more tests

* increase test coverage

* Apply suggestions from code review

Co-authored-by: Masafumi Koba <473530+ybiquitous@users.noreply.github.com>

* Update lib/rules/media-feature-name-value-no-unknown/index.js

Co-authored-by: Masafumi Koba <473530+ybiquitous@users.noreply.github.com>

* Update lib/rules/media-feature-name-value-no-unknown/index.js

Co-authored-by: Masafumi Koba <473530+ybiquitous@users.noreply.github.com>

* apply suggestions from code review

* refactor : add resolutionUnits to reference/units

* Update lib/reference/units.js

Co-authored-by: Masafumi Koba <473530+ybiquitous@users.noreply.github.com>

* fix endIndex offset

---------

Co-authored-by: Masafumi Koba <473530+ybiquitous@users.noreply.github.com>
  • Loading branch information
romainmenke and ybiquitous committed Jun 13, 2023
1 parent 7f51872 commit cbc0b6e
Show file tree
Hide file tree
Showing 10 changed files with 760 additions and 32 deletions.
5 changes: 5 additions & 0 deletions .changeset/real-dingos-boil.md
@@ -0,0 +1,5 @@
---
"stylelint": minor
---

Added: `media-feature-name-value-no-unknown`
1 change: 1 addition & 0 deletions docs/user-guide/rules.md
Expand Up @@ -88,6 +88,7 @@ Disallow unknown things with these `no-unknown` rules.
- [`declaration-property-value-no-unknown`](../../lib/rules/declaration-property-value-no-unknown/README.md): Disallow unknown values for properties within declarations.
- [`function-no-unknown`](../../lib/rules/function-no-unknown/README.md): Disallow unknown functions (Ⓡ & Ⓢ).
- [`media-feature-name-no-unknown`](../../lib/rules/media-feature-name-no-unknown/README.md): Disallow unknown media feature names (Ⓡ & Ⓢ).
- [`media-feature-name-value-no-unknown`](../../lib/rules/media-feature-name-value-no-unknown/README.md): Disallow unknown values for media features.
- [`no-unknown-animations`](../../lib/rules/no-unknown-animations/README.md): Disallow unknown animations.
- [`no-unknown-custom-properties`](../../lib/rules/no-unknown-custom-properties/README.md): Disallow unknown custom properties.
- [`property-no-unknown`](../../lib/rules/property-no-unknown/README.md): Disallow unknown properties (Ⓡ & Ⓢ).
Expand Down
90 changes: 66 additions & 24 deletions lib/reference/mediaFeatures.js
Expand Up @@ -6,25 +6,27 @@ const deprecatedMediaFeatureNames = new Set([
'device-aspect-ratio',
'device-height',
'device-width',
'max-device-aspect-ratio',
'max-device-height',
'max-device-width',
'min-device-aspect-ratio',
'min-device-height',
'min-device-width',
]);

const rangeTypeMediaFeatureNames = new Set([
const rangeTypeMediaFeatureNames = uniteSets(deprecatedMediaFeatureNames, [
'aspect-ratio',
'color-index',
'color',
'color-index',
'height',
'horizontal-viewport-segments',
'monochrome',
'resolution',
'vertical-viewport-segments',
'width',
]);

const mediaFeatureNames = uniteSets(deprecatedMediaFeatureNames, rangeTypeMediaFeatureNames, [
const rangeTypeMediaFeatureNamesWithMinMaxPrefix = new Set(
[...rangeTypeMediaFeatureNames].flatMap((name) => {
return [`min-${name}`, `max-${name}`];
}),
);

const discreteTypeMediaFeatureNames = new Set([
'any-hover',
'any-pointer',
'color-gamut',
Expand All @@ -35,20 +37,6 @@ const mediaFeatureNames = uniteSets(deprecatedMediaFeatureNames, rangeTypeMediaF
'hover',
'inverted-colors',
'light-level',
'max-aspect-ratio',
'max-color',
'max-color-index',
'max-height',
'max-monochrome',
'max-resolution',
'max-width',
'min-aspect-ratio',
'min-color',
'min-color-index',
'min-height',
'min-monochrome',
'min-resolution',
'min-width',
'orientation',
'overflow-block',
'overflow-inline',
Expand All @@ -63,7 +51,61 @@ const mediaFeatureNames = uniteSets(deprecatedMediaFeatureNames, rangeTypeMediaF
'video-dynamic-range',
]);

module.exports = {
const mediaFeatureNames = uniteSets(
deprecatedMediaFeatureNames,
rangeTypeMediaFeatureNames,
rangeTypeMediaFeatureNamesWithMinMaxPrefix,
discreteTypeMediaFeatureNames,
);

const mediaFeatureNameAllowedValueKeywords = new Map([
['any-hover', new Set(['none', 'hover'])],
['any-pointer', new Set(['none', 'coarse', 'fine'])],
['color-gamut', new Set(['srgb', 'p3', 'rec2020'])],
['display-mode', new Set(['fullscreen', 'standalone', 'minimal-ui', 'browser'])],
['dynamic-range', new Set(['standard', 'high'])],
['environment-blending', new Set(['opaque', 'additive', 'subtractive'])],
['forced-colors', new Set(['none', 'active'])],
['hover', new Set(['none', 'hover'])],
['inverted-colors', new Set(['none', 'inverted'])],
['nav-controls', new Set(['none', 'back'])],
['orientation', new Set(['portrait', 'landscape'])],
['overflow-block', new Set(['none', 'scroll', 'paged'])],
['overflow-inline', new Set(['none', 'scroll'])],
['pointer', new Set(['none', 'coarse', 'fine'])],
['prefers-color-scheme', new Set(['light', 'dark'])],
['prefers-contrast', new Set(['no-preference', 'less', 'more', 'custom'])],
['prefers-reduced-data', new Set(['no-preference', 'reduce'])],
['prefers-reduced-motion', new Set(['no-preference', 'reduce'])],
['prefers-reduced-transparency', new Set(['no-preference', 'reduce'])],
['resolution', new Set(['infinite'])],
['scan', new Set(['interlace', 'progressive'])],
['scripting', new Set(['none', 'initial-only', 'enabled'])],
['update', new Set(['none', 'slow', 'fast'])],
['video-color-gamut', new Set(['srgb', 'p3', 'rec2020'])],
['video-dynamic-range', new Set(['standard', 'high'])],
]);

const mediaFeatureNameAllowedValueTypes = new Map([
['aspect-ratio', new Set(['ratio'])],
['color', new Set(['integer'])],
['color-index', new Set(['integer'])],
['device-aspect-ratio', new Set(['ratio'])],
['device-height', new Set(['length'])],
['device-width', new Set(['length'])],
['grid', new Set(['mq-boolean'])],
['height', new Set(['length'])],
['horizontal-viewport-segments', new Set(['integer'])],
['monochrome', new Set(['integer'])],
['resolution', new Set(['resolution'])],
['vertical-viewport-segments', new Set(['integer'])],
['width', new Set(['length'])],
]);

module.exports = {
mediaFeatureNameAllowedValueKeywords,
mediaFeatureNameAllowedValueTypes,
mediaFeatureNames,
rangeTypeMediaFeatureNames,
rangeTypeMediaFeatureNamesWithMinMaxPrefix,
};
9 changes: 4 additions & 5 deletions lib/reference/units.js
Expand Up @@ -62,7 +62,9 @@ const lengthUnits = new Set([
'cqmax',
]);

const units = uniteSets(lengthUnits, [
const resolutionUnits = new Set(['dpi', 'dpcm', 'dppx', 'x']);

const units = uniteSets(lengthUnits, resolutionUnits, [
// Relative length units
'%',
// Time length units
Expand All @@ -76,13 +78,10 @@ const units = uniteSets(lengthUnits, [
// Frequency
'Hz',
'kHz',
// Resolution
'dpi',
'dpcm',
'dppx',
]);

module.exports = {
lengthUnits,
resolutionUnits,
units,
};
3 changes: 3 additions & 0 deletions lib/rules/index.js
Expand Up @@ -200,6 +200,9 @@ const rules = {
'media-feature-name-value-allowed-list': importLazy(() =>
require('./media-feature-name-value-allowed-list'),
)(),
'media-feature-name-value-no-unknown': importLazy(() =>
require('./media-feature-name-value-no-unknown'),
)(),
'media-feature-parentheses-space-inside': importLazy(() =>
require('./media-feature-parentheses-space-inside'),
)(),
Expand Down
57 changes: 57 additions & 0 deletions lib/rules/media-feature-name-value-no-unknown/README.md
@@ -0,0 +1,57 @@
# media-feature-name-value-no-unknown

Disallow unknown values for media features.

<!-- prettier-ignore -->
```css
@media (color: red) {}
/** ↑ ↑
* feature and value pairs like these */
```

This rule considers values for media features defined within the CSS specifications to be known.

This rule is only appropriate for CSS. You should not turn it on for CSS-like languages, such as Sass or Less, as they have their own syntaxes.

This rule is experimental with some false negatives that we'll patch in minor releases.

It sometimes overlaps with:

- [`unit-no-unknown`](../unit-no-unknown/README.md)

If duplicate problems are flagged, you can turn off the corresponding rule.

The [`message` secondary option](../../../docs/user-guide/configure.md#message) can accept the arguments of this rule.

## Options

### `true`

The following patterns are considered problems:

<!-- prettier-ignore -->
```css
@media (color: red) { top: 1px; }
```

<!-- prettier-ignore -->
```css
@media (width: 10) { top: 1px; }
```

<!-- prettier-ignore -->
```css
@media (width: auto) { top: 1px; }
```

The following patterns are _not_ considered problems:

<!-- prettier-ignore -->
```css
@media (color: 8) { top: 1px; }
```

<!-- prettier-ignore -->
```css
@media (width: 10px) { top: 1px; }
```

0 comments on commit cbc0b6e

Please sign in to comment.