Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ packages/web-features/index.d.ts
packages/**/LICENSE.txt
packages/web-features/data.json
packages/web-features/data.schema.json
packages/web-features/types.ts
packages/web-features/types*
packages/web-features/index.js
data.extended.json
index.js

# Ignore files created & used by pages & 11ty
/_site/**
3 changes: 0 additions & 3 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
/**/*.dist
/**/dist


# Exclude the website includes since these are typically fragments, or include
# things that makes Prettier unhappy.
/gh-pages/src/_includes/**
Expand All @@ -11,14 +10,12 @@
# TODO: Format all these files
README.md
index.ts
types.ts
2022-backgrounder.md
towards-features.md
/.github/**
/docs
!/docs/publishing.md
/features/draft
/schemas
/scripts/caniuse.ts
/scripts/schema.ts
/scripts/specs.ts
36 changes: 36 additions & 0 deletions assertions.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import assert from "node:assert/strict";
import { assertValidFeatureReference } from "./assertions";

describe("assertValidReference()", function () {
it("throws if target ID is a move", function () {
assert.throws(() => {
assertValidFeatureReference("a", "some-moving-feature", {
"some-moving-feature": { kind: "moved" },
});
});
});

it("throws if target ID is a split", function () {
assert.throws(() => {
assertValidFeatureReference("a", "some-split-feature", {
"some-split-feature": { kind: "split" },
});
});
});

it("throws if target ID is not defined", function () {
assert.throws(() => {
assertValidFeatureReference(
"a",
"this-is-a-completely-invalid-feature",
{},
);
});
});

it("does not throw if target ID is a feature", function () {
assert.doesNotThrow(() => {
assertValidFeatureReference("a", "dom", { dom: { kind: "feature" } });
});
});
});
29 changes: 29 additions & 0 deletions assertions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { isOrdinaryFeatureData } from "./type-guards";
import { WebFeaturesData } from "./types.quicktype";

/**
* Assert that a reference from one feature to another is an ordinary feature
* reference (i.e., it's defined and not some kind of redirect).
*
* @export
* @param {string} sourceId The feature that is referencing another feature
* @param {string} targetId The feature being referenced
* @param {WebFeaturesData["features"]} features Feature data
*/
export function assertValidFeatureReference(
sourceId: string,
targetId: string,
features: WebFeaturesData["features"],
) {
const target: unknown = features[targetId];
if (target === undefined) {
throw new Error(`${sourceId} references a non-existent feature`);
}
if (!isOrdinaryFeatureData(target)) {
throw new Error(
`${sourceId} references a redirect "${targetId} instead of an ordinary feature ID`,
);
}
}

// TODO: assertValidSnapshotReference
77 changes: 76 additions & 1 deletion docs/guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,81 @@ The identifier should match the name, with these additional guidelines:
- 👍 Recommended: `user-pseudos`
- 👎 Not recommended: `user-valid-and-user-invalid`

### Move a feature to a new ID

It’s possible to change or substitute a feature’s ID by creating a redirect from the original ID pointing to a new ID.
You can do this when:

* The original feature ID is misspelled.
For example, `numeric-seperators` (note spelling) data can be moved to `numeric-separators`.

* The original feature ID breaks the identifier guidelines.
For example, `drones-initial-support` data can be moved to `drones`.

* The original feature should not have existed as an independent feature.
For example, `single-color-gradients` was a poorly-conceived feature, where [a specification change](https://github.com/w3c/csswg-drafts/issues/10092) simplified the specification, implementation, and tools, but produced no novel browser behavior that developers could use in an application.
Instead, all the compatibility keys for the feature were reassigned to `gradients`.

* Data consumers report that the original feature ID is confusing or misleading.

You must not do this when the feature has been superseded, such that the feature's name has changed and the exposed behaviors or API surface have changed (in shipping browsers, up to and including unshipping).
Instead, use [`discouraged` data](#discouraged) with one or more `alternatives`.

To move the feature:

1. If applicable, move the existing YAML files for the feature to the target ID filename.
For example, rename `features/numeric-seperators.yml` to `features/numeric-separators.yml`.

If the original feature is being replaced by another feature, then move on to the next step.

2. Create a new YAML file for the original target ID filename.
For example, create an empty file `features/numeric-seperators.yml`.

3. Populate the following data in the new YAML file:

```yaml
kind: moved
redirect_target: TARGET-ID
```

where `TARGET-ID` is the target ID.

4. Regenerate the dist files.
Run `npm run dist`.

5. Commit your work and open a pull request.

### Split a feature into two or more other features

Some features may need to be split in two or more parts.
You can do this when the original feature should not have existed as an independent feature in the first place.
For example, similarly-named compat keys that ought to have been additions to existing features were erroneously combined and assigned to a new feature.

To split the feature:

1. If the feature to be split has any keys listed in `compat_features`, then reassign the keys to the target features.

To get the list of keys, you may need to first run `npm run undist -- $feature` where `$feature` is the path to the YAML file of the feature to be split.

2. Replace the contents of the original feature YAML file with the following data:

```yaml
kind: split
redirect_targets:
- target-id1
- target-id2
```

Replace the `target-id` values with two or more target ID strings.
Order `redirect_targets` by the most widely-relevant features first.
For example, if the feature is split to separate a Baseline subset of a feature from a non-Baseline subset, then put the Baseline feature first.
If you must break a tie, use alphabetical order.

3. Regenerate the dist files.
Run `npm run dist`.

4. Commit your work and open a pull request.

## Descriptions

The `description` field contains a short description of the feature in Markdown-formatted text, which is converted to HTML in the published package.
Expand Down Expand Up @@ -345,6 +420,6 @@ When you set a `discouraged` block in a feature file, do:
If possible, use the single most broadly applicable reference, such as specification text.
If a feature is removed from a specification, link to an issue, pull request, or commit showing the removal.

- Set one or more (optional) `alternative` feature IDs that are whole or partial substitutes for the discouraged feature.
- Set one or more (optional) `alternatives` feature IDs that are whole or partial substitutes for the discouraged feature.
An alternative doesn't have to be a narrow drop-in replacement for the discouraged feature but it must handle some use case of the discouraged feature.
Guide developers to the most relevant features that would help them stop using the discouraged feature.
1 change: 1 addition & 0 deletions features/conic-gradients.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ status:
compat_features:
- css.types.gradient.conic-gradient
- css.types.gradient.conic-gradient.doubleposition
- css.types.gradient.conic-gradient.single_color_stop
- css.types.gradient.repeating-conic-gradient
12 changes: 12 additions & 0 deletions features/conic-gradients.yml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,15 @@ compat_features:
# safari: "12.1"
# safari_ios: "12.2"
- css.types.gradient.conic-gradient.doubleposition

# baseline: low
# baseline_low_date: 2025-04-04
# support:
# chrome: "135"
# chrome_android: "135"
# edge: "135"
# firefox: "136"
# firefox_android: "136"
# safari: "18.4"
# safari_ios: "18.4"
- css.types.gradient.conic-gradient.single_color_stop
4 changes: 4 additions & 0 deletions features/gradients.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,22 @@ compat_features:
- css.types.gradient.linear-gradient.interpolation_hints
- css.types.gradient.linear-gradient.premultiplied_gradients
- css.types.gradient.linear-gradient.to
- css.types.gradient.linear-gradient.single_color_stop
- css.types.gradient.linear-gradient.unitless_0_angle
- css.types.gradient.repeating-linear-gradient
- css.types.gradient.repeating-linear-gradient.doubleposition
- css.types.gradient.repeating-linear-gradient.interpolation_hints
- css.types.gradient.repeating-linear-gradient.to
- css.types.gradient.repeating-linear-gradient.single_color_stop
- css.types.gradient.repeating-linear-gradient.unitless_0_angle
- css.types.gradient.radial-gradient
- css.types.gradient.radial-gradient.at
- css.types.gradient.radial-gradient.doubleposition
- css.types.gradient.radial-gradient.interpolation_hints
- css.types.gradient.radial-gradient.premultiplied_gradients
- css.types.gradient.radial-gradient.single_color_stop
- css.types.gradient.repeating-radial-gradient
- css.types.gradient.repeating-radial-gradient.at
- css.types.gradient.repeating-radial-gradient.doubleposition
- css.types.gradient.repeating-radial-gradient.interpolation_hints
- css.types.gradient.repeating-radial-gradient.single_color_stop
15 changes: 15 additions & 0 deletions features/gradients.yml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,18 @@ compat_features:
# safari_ios: "15"
- css.types.gradient.linear-gradient.premultiplied_gradients
- css.types.gradient.radial-gradient.premultiplied_gradients

# baseline: low
# baseline_low_date: 2025-04-04
# support:
# chrome: "135"
# chrome_android: "135"
# edge: "135"
# firefox: "136"
# firefox_android: "136"
# safari: "18.4"
# safari_ios: "18.4"
- css.types.gradient.linear-gradient.single_color_stop
- css.types.gradient.radial-gradient.single_color_stop
- css.types.gradient.repeating-linear-gradient.single_color_stop
- css.types.gradient.repeating-radial-gradient.single_color_stop
6 changes: 6 additions & 0 deletions features/numeric-separators.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: Numeric separators
description: To improve readability for numeric literals, underscores (`_`) can be used as separators. For example, `1_050.95` is equivalent to `1050.95`.
spec: https://tc39.es/ecma262/multipage/ecmascript-language-lexical-grammar.html#prod-NumericLiteralSeparator
group: javascript
compat_features:
- javascript.grammar.numeric_separators
17 changes: 17 additions & 0 deletions features/numeric-separators.yml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated from: numeric-separators.yml
# Do not edit this file by hand. Edit the source file instead!

status:
baseline: high
baseline_low_date: 2020-07-28
baseline_high_date: 2023-01-28
support:
chrome: "75"
chrome_android: "75"
edge: "79"
firefox: "70"
firefox_android: "79"
safari: "13"
safari_ios: "13"
compat_features:
- javascript.grammar.numeric_separators
8 changes: 2 additions & 6 deletions features/numeric-seperators.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
name: Numeric separators
description: To improve readability for numeric literals, underscores (`_`) can be used as separators. For example, `1_050.95` is equivalent to `1050.95`.
spec: https://tc39.es/ecma262/multipage/ecmascript-language-lexical-grammar.html#prod-NumericLiteralSeparator
group: javascript
compat_features:
- javascript.grammar.numeric_separators
kind: moved
redirect_target: numeric-separators
19 changes: 4 additions & 15 deletions features/numeric-seperators.yml.dist
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
# Generated from: numeric-seperators.yml
# Do not edit this file by hand. Edit the source file instead!
# This file intentionally left blank.
# Do not edit this file.
# The data for this feature has moved to numeric-separators.yml

status:
baseline: high
baseline_low_date: 2020-07-28
baseline_high_date: 2023-01-28
support:
chrome: "75"
chrome_android: "75"
edge: "79"
firefox: "70"
firefox_android: "79"
safari: "13"
safari_ios: "13"
compat_features:
- javascript.grammar.numeric_separators
{}
15 changes: 4 additions & 11 deletions features/single-color-gradients.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
name: Single color stop gradients
description: A single color stop can be provided to the `linear-gradient()`, `radial-gradient()`, and `conic-gradient()` CSS functions, and their repeating counterparts, to create a solid color background.
spec: https://drafts.csswg.org/css-images-4/#color-stop-syntax
group: gradients
compat_features:
- css.types.gradient.conic-gradient.single_color_stop
- css.types.gradient.linear-gradient.single_color_stop
- css.types.gradient.radial-gradient.single_color_stop
- css.types.gradient.repeating-conic-gradient.single_color_stop
- css.types.gradient.repeating-linear-gradient.single_color_stop
- css.types.gradient.repeating-radial-gradient.single_color_stop
kind: split
redirect_targets:
- gradients
- conic-gradients
25 changes: 6 additions & 19 deletions features/single-color-gradients.yml.dist
Original file line number Diff line number Diff line change
@@ -1,21 +1,8 @@
# Generated from: single-color-gradients.yml
# Do not edit this file by hand. Edit the source file instead!
# This file intentionally left blank.
# Do not edit this file.
# The data for this feature has moved to:
# - gradients.yml
# - conic-gradients.yml

status:
baseline: low
baseline_low_date: 2025-04-04
support:
chrome: "135"
chrome_android: "135"
edge: "135"
firefox: "136"
firefox_android: "136"
safari: "18.4"
safari_ios: "18.4"
compat_features:
- css.types.gradient.conic-gradient.single_color_stop
- css.types.gradient.linear-gradient.single_color_stop
- css.types.gradient.radial-gradient.single_color_stop
- css.types.gradient.repeating-conic-gradient.single_color_stop
- css.types.gradient.repeating-linear-gradient.single_color_stop
- css.types.gradient.repeating-radial-gradient.single_color_stop
{}
Loading