Skip to content

Commit acd4cf1

Browse files
ddbeckjcscottiiifoolipcaptainbrossetszepeviktor
authored
Prepare v3.0.0 (#3333)
* Demonstrate JSON Schema as source of truth for web-features data (#2990) * Add move and split redirects to the schema (#3000) * Add guidelines for moving and splitting features (#3180) * Add consumer docs for moved and split features (#3181) * Change schema `string | string[]` properties to `string[]` (#3184) * Fix missing `group` and `snapshot` keys from convenience types Co-authored-by: James C Scott III <7788930+jcscottiii@users.noreply.github.com> Co-authored-by: Philip Jägenstedt <philip@foolip.org> Co-authored-by: Patrick Brosset <patrickbrosset@gmail.com> Co-authored-by: szepeviktor <952007+szepeviktor@users.noreply.github.com> Co-authored-by: LeoMcA <755354+LeoMcA@users.noreply.github.com> Co-authored-by: foolip <498917+foolip@users.noreply.github.com>
1 parent aeaa595 commit acd4cf1

34 files changed

+2074
-880
lines changed

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ packages/web-features/index.d.ts
55
packages/**/LICENSE.txt
66
packages/web-features/data.json
77
packages/web-features/data.schema.json
8-
packages/web-features/types.ts
8+
packages/web-features/types*
9+
packages/web-features/index.js
910
data.extended.json
10-
index.js
1111

1212
# Ignore files created & used by pages & 11ty
1313
/_site/**

.prettierignore

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
/**/*.dist
33
/**/dist
44

5-
65
# Exclude the website includes since these are typically fragments, or include
76
# things that makes Prettier unhappy.
87
/gh-pages/src/_includes/**
@@ -11,14 +10,12 @@
1110
# TODO: Format all these files
1211
README.md
1312
index.ts
14-
types.ts
1513
2022-backgrounder.md
1614
towards-features.md
1715
/.github/**
1816
/docs
1917
!/docs/publishing.md
2018
/features/draft
21-
/schemas
2219
/scripts/caniuse.ts
2320
/scripts/schema.ts
2421
/scripts/specs.ts

assertions.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import assert from "node:assert/strict";
2+
import { assertValidFeatureReference } from "./assertions";
3+
4+
describe("assertValidReference()", function () {
5+
it("throws if target ID is a move", function () {
6+
assert.throws(() => {
7+
assertValidFeatureReference("a", "some-moving-feature", {
8+
"some-moving-feature": { kind: "moved" },
9+
});
10+
});
11+
});
12+
13+
it("throws if target ID is a split", function () {
14+
assert.throws(() => {
15+
assertValidFeatureReference("a", "some-split-feature", {
16+
"some-split-feature": { kind: "split" },
17+
});
18+
});
19+
});
20+
21+
it("throws if target ID is not defined", function () {
22+
assert.throws(() => {
23+
assertValidFeatureReference(
24+
"a",
25+
"this-is-a-completely-invalid-feature",
26+
{},
27+
);
28+
});
29+
});
30+
31+
it("does not throw if target ID is a feature", function () {
32+
assert.doesNotThrow(() => {
33+
assertValidFeatureReference("a", "dom", { dom: { kind: "feature" } });
34+
});
35+
});
36+
});

assertions.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { isOrdinaryFeatureData } from "./type-guards";
2+
import { WebFeaturesData } from "./types.quicktype";
3+
4+
/**
5+
* Assert that a reference from one feature to another is an ordinary feature
6+
* reference (i.e., it's defined and not some kind of redirect).
7+
*
8+
* @export
9+
* @param {string} sourceId The feature that is referencing another feature
10+
* @param {string} targetId The feature being referenced
11+
* @param {WebFeaturesData["features"]} features Feature data
12+
*/
13+
export function assertValidFeatureReference(
14+
sourceId: string,
15+
targetId: string,
16+
features: WebFeaturesData["features"],
17+
) {
18+
const target: unknown = features[targetId];
19+
if (target === undefined) {
20+
throw new Error(`${sourceId} references a non-existent feature`);
21+
}
22+
if (!isOrdinaryFeatureData(target)) {
23+
throw new Error(
24+
`${sourceId} references a redirect "${targetId} instead of an ordinary feature ID`,
25+
);
26+
}
27+
}
28+
29+
// TODO: assertValidSnapshotReference

docs/guidelines.md

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,81 @@ The identifier should match the name, with these additional guidelines:
7777
- 👍 Recommended: `user-pseudos`
7878
- 👎 Not recommended: `user-valid-and-user-invalid`
7979

80+
### Move a feature to a new ID
81+
82+
It’s possible to change or substitute a feature’s ID by creating a redirect from the original ID pointing to a new ID.
83+
You can do this when:
84+
85+
* The original feature ID is misspelled.
86+
For example, `numeric-seperators` (note spelling) data can be moved to `numeric-separators`.
87+
88+
* The original feature ID breaks the identifier guidelines.
89+
For example, `drones-initial-support` data can be moved to `drones`.
90+
91+
* The original feature should not have existed as an independent feature.
92+
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.
93+
Instead, all the compatibility keys for the feature were reassigned to `gradients`.
94+
95+
* Data consumers report that the original feature ID is confusing or misleading.
96+
97+
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).
98+
Instead, use [`discouraged` data](#discouraged) with one or more `alternatives`.
99+
100+
To move the feature:
101+
102+
1. If applicable, move the existing YAML files for the feature to the target ID filename.
103+
For example, rename `features/numeric-seperators.yml` to `features/numeric-separators.yml`.
104+
105+
If the original feature is being replaced by another feature, then move on to the next step.
106+
107+
2. Create a new YAML file for the original target ID filename.
108+
For example, create an empty file `features/numeric-seperators.yml`.
109+
110+
3. Populate the following data in the new YAML file:
111+
112+
```yaml
113+
kind: moved
114+
redirect_target: TARGET-ID
115+
```
116+
117+
where `TARGET-ID` is the target ID.
118+
119+
4. Regenerate the dist files.
120+
Run `npm run dist`.
121+
122+
5. Commit your work and open a pull request.
123+
124+
### Split a feature into two or more other features
125+
126+
Some features may need to be split in two or more parts.
127+
You can do this when the original feature should not have existed as an independent feature in the first place.
128+
For example, similarly-named compat keys that ought to have been additions to existing features were erroneously combined and assigned to a new feature.
129+
130+
To split the feature:
131+
132+
1. If the feature to be split has any keys listed in `compat_features`, then reassign the keys to the target features.
133+
134+
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.
135+
136+
2. Replace the contents of the original feature YAML file with the following data:
137+
138+
```yaml
139+
kind: split
140+
redirect_targets:
141+
- target-id1
142+
- target-id2
143+
```
144+
145+
Replace the `target-id` values with two or more target ID strings.
146+
Order `redirect_targets` by the most widely-relevant features first.
147+
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.
148+
If you must break a tie, use alphabetical order.
149+
150+
3. Regenerate the dist files.
151+
Run `npm run dist`.
152+
153+
4. Commit your work and open a pull request.
154+
80155
## Descriptions
81156

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

348-
- Set one or more (optional) `alternative` feature IDs that are whole or partial substitutes for the discouraged feature.
423+
- Set one or more (optional) `alternatives` feature IDs that are whole or partial substitutes for the discouraged feature.
349424
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.
350425
Guide developers to the most relevant features that would help them stop using the discouraged feature.

features/conic-gradients.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ status:
88
compat_features:
99
- css.types.gradient.conic-gradient
1010
- css.types.gradient.conic-gradient.doubleposition
11+
- css.types.gradient.conic-gradient.single_color_stop
1112
- css.types.gradient.repeating-conic-gradient

features/conic-gradients.yml.dist

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,15 @@ compat_features:
4141
# safari: "12.1"
4242
# safari_ios: "12.2"
4343
- css.types.gradient.conic-gradient.doubleposition
44+
45+
# baseline: low
46+
# baseline_low_date: 2025-04-04
47+
# support:
48+
# chrome: "135"
49+
# chrome_android: "135"
50+
# edge: "135"
51+
# firefox: "136"
52+
# firefox_android: "136"
53+
# safari: "18.4"
54+
# safari_ios: "18.4"
55+
- css.types.gradient.conic-gradient.single_color_stop

features/gradients.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,22 @@ compat_features:
1616
- css.types.gradient.linear-gradient.interpolation_hints
1717
- css.types.gradient.linear-gradient.premultiplied_gradients
1818
- css.types.gradient.linear-gradient.to
19+
- css.types.gradient.linear-gradient.single_color_stop
1920
- css.types.gradient.linear-gradient.unitless_0_angle
2021
- css.types.gradient.repeating-linear-gradient
2122
- css.types.gradient.repeating-linear-gradient.doubleposition
2223
- css.types.gradient.repeating-linear-gradient.interpolation_hints
2324
- css.types.gradient.repeating-linear-gradient.to
25+
- css.types.gradient.repeating-linear-gradient.single_color_stop
2426
- css.types.gradient.repeating-linear-gradient.unitless_0_angle
2527
- css.types.gradient.radial-gradient
2628
- css.types.gradient.radial-gradient.at
2729
- css.types.gradient.radial-gradient.doubleposition
2830
- css.types.gradient.radial-gradient.interpolation_hints
2931
- css.types.gradient.radial-gradient.premultiplied_gradients
32+
- css.types.gradient.radial-gradient.single_color_stop
3033
- css.types.gradient.repeating-radial-gradient
3134
- css.types.gradient.repeating-radial-gradient.at
3235
- css.types.gradient.repeating-radial-gradient.doubleposition
3336
- css.types.gradient.repeating-radial-gradient.interpolation_hints
37+
- css.types.gradient.repeating-radial-gradient.single_color_stop

features/gradients.yml.dist

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,18 @@ compat_features:
145145
# safari_ios: "15"
146146
- css.types.gradient.linear-gradient.premultiplied_gradients
147147
- css.types.gradient.radial-gradient.premultiplied_gradients
148+
149+
# baseline: low
150+
# baseline_low_date: 2025-04-04
151+
# support:
152+
# chrome: "135"
153+
# chrome_android: "135"
154+
# edge: "135"
155+
# firefox: "136"
156+
# firefox_android: "136"
157+
# safari: "18.4"
158+
# safari_ios: "18.4"
159+
- css.types.gradient.linear-gradient.single_color_stop
160+
- css.types.gradient.radial-gradient.single_color_stop
161+
- css.types.gradient.repeating-linear-gradient.single_color_stop
162+
- css.types.gradient.repeating-radial-gradient.single_color_stop

features/numeric-separators.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
name: Numeric separators
2+
description: To improve readability for numeric literals, underscores (`_`) can be used as separators. For example, `1_050.95` is equivalent to `1050.95`.
3+
spec: https://tc39.es/ecma262/multipage/ecmascript-language-lexical-grammar.html#prod-NumericLiteralSeparator
4+
group: javascript
5+
compat_features:
6+
- javascript.grammar.numeric_separators

0 commit comments

Comments
 (0)