Skip to content

Commit 4eb902c

Browse files
ddbeckjamesnw
andauthored
Add discouraged to schema (and with statement demo feature) (#2388)
Co-authored-by: James Stuckey Weber <[email protected]>
1 parent caf4dcd commit 4eb902c

File tree

10 files changed

+161
-20
lines changed

10 files changed

+161
-20
lines changed

docs/guidelines.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,3 +309,42 @@ For example, don't assign a feature to both `css` and `fonts`, since `css` is th
309309

310310
Do assign features to groups when there's an opportunity for future feature composition (see [#971](https://github.com/web-platform-dx/web-features/issues/971)).
311311
For example, several features for the JavaScript `Array` interface are members of the `array` group.
312+
313+
## Discouraged
314+
315+
Rarely, the developers should not use a platform feature because it's the consensus of relevant stakeholders (i.e., a standards body and implementers), even if that feature is still implemented in browsers.
316+
Mark a feature as discouraged when:
317+
318+
- The specification adopts clear language directing developers to stop using that feature or to prefer to an alternative.
319+
This is often through terms like "deprecated", "obsolete", or "legacy."
320+
They can also be in the form of one-off recommendations to use alternatives (such as "[…ought to be used instead](https://dom.spec.whatwg.org/#ref-for-concept-event%E2%91%A4%E2%91%A3)").
321+
322+
- The specification removes that feature from the specification without a succession plan (such as moving it to another specification).
323+
324+
- The specification editors intend to discourage or remove the feature from the specification.
325+
For example, meeting minutes show that a committee achieved consensus to remove a feature from a specification, even if the removal is not complete.
326+
327+
- All of the (present) implementers issue warnings when using that feature or have published something expressing an intention to unship that feature.
328+
329+
330+
Do not mark a feature as discouraged when:
331+
332+
- The feature is merely old or unpopular, no matter how many [_considered harmful_](https://en.wikipedia.org/wiki/Considered_harmful) blog posts it may have garnered.
333+
For example, despite the existence of `fetch`, `XMLHttpRequest` is not a discouraged feature.
334+
335+
- The feature is controversial.
336+
Opposition to a feature (without consensus) is not sufficient to mark a feature as discouraged.
337+
For example, do not mark a feature as discouraged because a vendor has given it a negative standards position.
338+
339+
- The feature is buggy or not implemented in one or more browsers.
340+
Contribute to accurate support data instead.
341+
342+
When you set a `discouraged` block in a feature file, do:
343+
344+
- Set a (required) `according_to` URL, linking to evidence that the feature is discouraged.
345+
If possible, use the single most broadly applicable reference, such as specification text.
346+
If a feature is removed from a specification, link to an issue, pull request, or commit showing the removal.
347+
348+
- Set one or more (optional) `alternative` feature IDs that are whole or partial substitutes for the discouraged feature.
349+
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.
350+
Guide developers to the most relevant features that would help them stop using the discouraged feature.

features/symbol.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,5 @@ compat_features:
2323
- javascript.builtins.Symbol.toString
2424
- javascript.builtins.Symbol.toStringTag
2525
- javascript.builtins.Symbol.toStringTag.dom_objects
26-
- javascript.builtins.Symbol.unscopables
2726
- javascript.builtins.Symbol.valueOf
2827
- javascript.builtins.Symbol.@@toPrimitive

features/symbol.yml.dist

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,6 @@ compat_features:
4545
- javascript.builtins.Symbol.for
4646
- javascript.builtins.Symbol.keyFor
4747

48-
# baseline: high
49-
# baseline_low_date: 2016-08-02
50-
# baseline_high_date: 2019-02-02
51-
# support:
52-
# chrome: "38"
53-
# chrome_android: "38"
54-
# edge: "12"
55-
# firefox: "48"
56-
# firefox_android: "48"
57-
# safari: "9"
58-
# safari_ios: "9"
59-
- javascript.builtins.Symbol.unscopables
60-
6148
# baseline: high
6249
# baseline_low_date: 2016-09-20
6350
# baseline_high_date: 2019-03-20

features/with.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: with
2+
description: The `with` JavaScript statement adds a given object to the chain of scopes used to evaluate names.
3+
spec: https://tc39.es/ecma262/multipage/ecmascript-language-statements-and-declarations.html#sec-with-statement
4+
group: javascript
5+
discouraged:
6+
# One thing that is potentially missing here is a "reason" like this:
7+
8+
# reason: browser-warning
9+
# reason: spec-caution
10+
# reason: pending-removal
11+
12+
# This would allow us to signal to tools how "fatal" the discouragement is
13+
# (e.g., pending-removal should trigger noisy errors for developers but spec
14+
# caution would not). I'm not sure the full range of these yet; I think it
15+
# might be easier to choose the set of reasons after we've enumerated a bunch
16+
# of discouraged features.
17+
according_to:
18+
- https://tc39.es/ecma262/multipage/ecmascript-language-statements-and-declarations.html#sec-with-statement
19+
alternatives:
20+
- destructuring
21+
compat_features:
22+
- javascript.statements.with
23+
- javascript.builtins.Symbol.unscopables
24+
- javascript.builtins.Array.@@unscopables

features/with.yml.dist

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Generated from: with.yml
2+
# Do not edit this file by hand. Edit the source file instead!
3+
4+
status:
5+
baseline: false
6+
support:
7+
chrome: "38"
8+
chrome_android: "38"
9+
edge: "12"
10+
firefox: "48"
11+
firefox_android: "48"
12+
safari: "10"
13+
safari_ios: "10"
14+
compat_features:
15+
# baseline: high
16+
# baseline_low_date: 2016-08-02
17+
# baseline_high_date: 2019-02-02
18+
# support:
19+
# chrome: "38"
20+
# chrome_android: "38"
21+
# edge: "12"
22+
# firefox: "48"
23+
# firefox_android: "48"
24+
# safari: "9"
25+
# safari_ios: "9"
26+
- javascript.builtins.Symbol.unscopables
27+
28+
# baseline: high
29+
# baseline_low_date: 2016-09-20
30+
# baseline_high_date: 2019-03-20
31+
# support:
32+
# chrome: "38"
33+
# chrome_android: "38"
34+
# edge: "12"
35+
# firefox: "48"
36+
# firefox_android: "48"
37+
# safari: "10"
38+
# safari_ios: "10"
39+
- javascript.builtins.Array.@@unscopables
40+
41+
# baseline: false
42+
# support:
43+
# chrome: "1"
44+
# chrome_android: "18"
45+
# edge: "12"
46+
# firefox: "1"
47+
# firefox_android: "4"
48+
# safari: "1"
49+
# safari_ios: "1"
50+
- javascript.statements.with

index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,16 @@ for (const [key, data] of yamlEntries('features')) {
182182
features[key] = data;
183183
}
184184

185+
// Assert that discouraged feature's alternatives are valid
186+
for (const [id, feature] of Object.entries(features)) {
187+
for (const alternative of feature.discouraged?.alternatives ?? []) {
188+
console.log(`Confirming ${alternative} in feature set`);
189+
if (!(alternative in features)) {
190+
throw new Error(`${id}'s alternative "${alternative}" is not a valid feature ID`);
191+
}
192+
}
193+
}
194+
185195
const compat = new Compat();
186196
const browsers: Partial<WebFeaturesData["browsers"]> = {};
187197
for (const browser of coreBrowserSet.map(identifier => compat.browser(identifier))) {

packages/web-features/README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# Curated list of Web platform features
22

3-
This package is experimental, expect frequent breaking changes!
4-
53
## Usage
64

75
```sh
@@ -27,13 +25,18 @@ import schema from "web-features/data.schema.json" with { type: "json" };
2725

2826
## Rendering Baseline statuses with `web-features`
2927

30-
If you're using `web-features` to render Baseline iconography or browser logos with support markers, then you must follow these procedures to ensure consistent usage.
28+
If you're using `web-features` to render Baseline iconography or browser logos with support markers, then you must follow the [name and logo usage guidelines](https://web-platform-dx.github.io/web-features/name-and-logo-usage-guidelines/).
3129

3230
For Baseline iconography, follow this procedure for each feature:
3331

3432
1. If `status.baseline` is `"high"`, then show an affirmative "widely available" icon.
3533
1. If `status.baseline` is `"low"`, then show an affirmative "newly available" icon.
3634
1. If `status.baseline` is `false`, then show a "limited availability" non-Baseline icon.
35+
36+
**Note**: All features that have the `discouraged` property are, by definition, non-Baseline, and `status.baseline` will be `false`.
37+
If a feature has the `discouraged` property, consider showing a message describing the feature's discouraged status instead of Baseline iconography.
38+
Showing Baseline iconography for discouraged features may confuse readers.
39+
3740
1. If `status.baseline` is `undefined`, then **do not** show any Baseline or non-Baseline badge.
3841

3942
For browser support iconography (that is, browser logos and checkmarks and Xs), follow this procedure for each browser:

schemas/data.schema.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,28 @@
5757
"description": "Short description of the feature, as an HTML string",
5858
"type": "string"
5959
},
60+
"discouraged": {
61+
"additionalProperties": false,
62+
"description": "Whether developers are formally discouraged from using this feature",
63+
"properties": {
64+
"according_to": {
65+
"description": "Links to a formal discouragement notice, such as specification text, intent-to-unship, etc.",
66+
"items": {
67+
"type": "string"
68+
},
69+
"type": "array"
70+
},
71+
"alternatives": {
72+
"description": "IDs for features that substitute some or all of this feature's utility",
73+
"items": {},
74+
"type": "array"
75+
}
76+
},
77+
"required": [
78+
"according_to"
79+
],
80+
"type": "object"
81+
},
6082
"group": {
6183
"anyOf": [
6284
{

scripts/dist.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -233,9 +233,7 @@ function toDist(sourcePath: string): YAML.Document {
233233
checkAncestors: true,
234234
});
235235

236-
if (computedStatus.discouraged) {
237-
const isDraft: boolean = source.draft_date ?? false;
238-
236+
if (computedStatus.discouraged && !source.discouraged) {
239237
if (!source.draft_date) {
240238
logger.error(
241239
`${id}: contains at least one deprecated compat feature. This is forbidden for published features.`,

types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ export interface FeatureData {
4545
status: SupportStatus;
4646
/** Sources of support data for this feature */
4747
compat_features?: string[];
48+
/** Whether developers are formally discouraged from using this feature */
49+
discouraged?: Discouraged;
4850
}
4951

5052
type BrowserIdentifier = "chrome" | "chrome_android" | "edge" | "firefox" | "firefox_android" | "safari" | "safari_ios";
@@ -69,6 +71,13 @@ interface SupportStatus extends Status {
6971
by_compat_key?: Record<string, Status>
7072
}
7173

74+
interface Discouraged {
75+
/** Links to a formal discouragement notice, such as specification text, intent-to-unship, etc. */
76+
according_to: string[];
77+
/** IDs for features that substitute some or all of this feature's utility */
78+
alternatives?: (keyof WebFeaturesData["features"])[];
79+
}
80+
7281
export interface GroupData {
7382
/** Short name */
7483
name: string;

0 commit comments

Comments
 (0)