Skip to content

Commit

Permalink
Add discouraged to schema (and with statement demo feature) (#2388)
Browse files Browse the repository at this point in the history
Co-authored-by: James Stuckey Weber <jamesnw@gmail.com>
  • Loading branch information
ddbeck and jamesnw authored Dec 20, 2024
1 parent caf4dcd commit 4eb902c
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 20 deletions.
39 changes: 39 additions & 0 deletions docs/guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,3 +309,42 @@ For example, don't assign a feature to both `css` and `fonts`, since `css` is th

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)).
For example, several features for the JavaScript `Array` interface are members of the `array` group.

## Discouraged

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.
Mark a feature as discouraged when:

- The specification adopts clear language directing developers to stop using that feature or to prefer to an alternative.
This is often through terms like "deprecated", "obsolete", or "legacy."
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)").

- The specification removes that feature from the specification without a succession plan (such as moving it to another specification).

- The specification editors intend to discourage or remove the feature from the specification.
For example, meeting minutes show that a committee achieved consensus to remove a feature from a specification, even if the removal is not complete.

- All of the (present) implementers issue warnings when using that feature or have published something expressing an intention to unship that feature.


Do not mark a feature as discouraged when:

- 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.
For example, despite the existence of `fetch`, `XMLHttpRequest` is not a discouraged feature.

- The feature is controversial.
Opposition to a feature (without consensus) is not sufficient to mark a feature as discouraged.
For example, do not mark a feature as discouraged because a vendor has given it a negative standards position.

- The feature is buggy or not implemented in one or more browsers.
Contribute to accurate support data instead.

When you set a `discouraged` block in a feature file, do:

- Set a (required) `according_to` URL, linking to evidence that the feature is discouraged.
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.
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: 0 additions & 1 deletion features/symbol.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,5 @@ compat_features:
- javascript.builtins.Symbol.toString
- javascript.builtins.Symbol.toStringTag
- javascript.builtins.Symbol.toStringTag.dom_objects
- javascript.builtins.Symbol.unscopables
- javascript.builtins.Symbol.valueOf
- javascript.builtins.Symbol.@@toPrimitive
13 changes: 0 additions & 13 deletions features/symbol.yml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,6 @@ compat_features:
- javascript.builtins.Symbol.for
- javascript.builtins.Symbol.keyFor

# baseline: high
# baseline_low_date: 2016-08-02
# baseline_high_date: 2019-02-02
# support:
# chrome: "38"
# chrome_android: "38"
# edge: "12"
# firefox: "48"
# firefox_android: "48"
# safari: "9"
# safari_ios: "9"
- javascript.builtins.Symbol.unscopables

# baseline: high
# baseline_low_date: 2016-09-20
# baseline_high_date: 2019-03-20
Expand Down
24 changes: 24 additions & 0 deletions features/with.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: with
description: The `with` JavaScript statement adds a given object to the chain of scopes used to evaluate names.
spec: https://tc39.es/ecma262/multipage/ecmascript-language-statements-and-declarations.html#sec-with-statement
group: javascript
discouraged:
# One thing that is potentially missing here is a "reason" like this:

# reason: browser-warning
# reason: spec-caution
# reason: pending-removal

# This would allow us to signal to tools how "fatal" the discouragement is
# (e.g., pending-removal should trigger noisy errors for developers but spec
# caution would not). I'm not sure the full range of these yet; I think it
# might be easier to choose the set of reasons after we've enumerated a bunch
# of discouraged features.
according_to:
- https://tc39.es/ecma262/multipage/ecmascript-language-statements-and-declarations.html#sec-with-statement
alternatives:
- destructuring
compat_features:
- javascript.statements.with
- javascript.builtins.Symbol.unscopables
- javascript.builtins.Array.@@unscopables
50 changes: 50 additions & 0 deletions features/with.yml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Generated from: with.yml
# Do not edit this file by hand. Edit the source file instead!

status:
baseline: false
support:
chrome: "38"
chrome_android: "38"
edge: "12"
firefox: "48"
firefox_android: "48"
safari: "10"
safari_ios: "10"
compat_features:
# baseline: high
# baseline_low_date: 2016-08-02
# baseline_high_date: 2019-02-02
# support:
# chrome: "38"
# chrome_android: "38"
# edge: "12"
# firefox: "48"
# firefox_android: "48"
# safari: "9"
# safari_ios: "9"
- javascript.builtins.Symbol.unscopables

# baseline: high
# baseline_low_date: 2016-09-20
# baseline_high_date: 2019-03-20
# support:
# chrome: "38"
# chrome_android: "38"
# edge: "12"
# firefox: "48"
# firefox_android: "48"
# safari: "10"
# safari_ios: "10"
- javascript.builtins.Array.@@unscopables

# baseline: false
# support:
# chrome: "1"
# chrome_android: "18"
# edge: "12"
# firefox: "1"
# firefox_android: "4"
# safari: "1"
# safari_ios: "1"
- javascript.statements.with
10 changes: 10 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,16 @@ for (const [key, data] of yamlEntries('features')) {
features[key] = data;
}

// Assert that discouraged feature's alternatives are valid
for (const [id, feature] of Object.entries(features)) {
for (const alternative of feature.discouraged?.alternatives ?? []) {
console.log(`Confirming ${alternative} in feature set`);
if (!(alternative in features)) {
throw new Error(`${id}'s alternative "${alternative}" is not a valid feature ID`);
}
}
}

const compat = new Compat();
const browsers: Partial<WebFeaturesData["browsers"]> = {};
for (const browser of coreBrowserSet.map(identifier => compat.browser(identifier))) {
Expand Down
9 changes: 6 additions & 3 deletions packages/web-features/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Curated list of Web platform features

This package is experimental, expect frequent breaking changes!

## Usage

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

## Rendering Baseline statuses with `web-features`

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.
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/).

For Baseline iconography, follow this procedure for each feature:

1. If `status.baseline` is `"high"`, then show an affirmative "widely available" icon.
1. If `status.baseline` is `"low"`, then show an affirmative "newly available" icon.
1. If `status.baseline` is `false`, then show a "limited availability" non-Baseline icon.

**Note**: All features that have the `discouraged` property are, by definition, non-Baseline, and `status.baseline` will be `false`.
If a feature has the `discouraged` property, consider showing a message describing the feature's discouraged status instead of Baseline iconography.
Showing Baseline iconography for discouraged features may confuse readers.

1. If `status.baseline` is `undefined`, then **do not** show any Baseline or non-Baseline badge.

For browser support iconography (that is, browser logos and checkmarks and Xs), follow this procedure for each browser:
Expand Down
22 changes: 22 additions & 0 deletions schemas/data.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,28 @@
"description": "Short description of the feature, as an HTML string",
"type": "string"
},
"discouraged": {
"additionalProperties": false,
"description": "Whether developers are formally discouraged from using this feature",
"properties": {
"according_to": {
"description": "Links to a formal discouragement notice, such as specification text, intent-to-unship, etc.",
"items": {
"type": "string"
},
"type": "array"
},
"alternatives": {
"description": "IDs for features that substitute some or all of this feature's utility",
"items": {},
"type": "array"
}
},
"required": [
"according_to"
],
"type": "object"
},
"group": {
"anyOf": [
{
Expand Down
4 changes: 1 addition & 3 deletions scripts/dist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,7 @@ function toDist(sourcePath: string): YAML.Document {
checkAncestors: true,
});

if (computedStatus.discouraged) {
const isDraft: boolean = source.draft_date ?? false;

if (computedStatus.discouraged && !source.discouraged) {
if (!source.draft_date) {
logger.error(
`${id}: contains at least one deprecated compat feature. This is forbidden for published features.`,
Expand Down
9 changes: 9 additions & 0 deletions types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export interface FeatureData {
status: SupportStatus;
/** Sources of support data for this feature */
compat_features?: string[];
/** Whether developers are formally discouraged from using this feature */
discouraged?: Discouraged;
}

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

interface Discouraged {
/** Links to a formal discouragement notice, such as specification text, intent-to-unship, etc. */
according_to: string[];
/** IDs for features that substitute some or all of this feature's utility */
alternatives?: (keyof WebFeaturesData["features"])[];
}

export interface GroupData {
/** Short name */
name: string;
Expand Down

0 comments on commit 4eb902c

Please sign in to comment.