-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consider handling feature identifier changes or aliases #91
Comments
Thoughts on the different cases:
This case is different from the others, it's about the scope of the feature changing in addition to the name. This is a very long term problem, but I think we'll be better off trying to maintain a stable tree structure and only changing the properties of the nodes of the tree. Inverting parent-child relationships would be especially complex to understand and communicate I think.
For this I think we should have a concept of renaming using aliases, if we don't pick the best name first. Such aliases could remain long term if they don't get in the way. Technically, I think this requires that we have a
If we want to get rid of error, or if we've accidentally used up a good name, I think we need a concept of deprecation and removal. We'd mark features as deprecated and make that visible in the API and release notes, and then remove them in a future major release bump. |
My concrete proposal here is a new The API can wait until later, and might also including looking features up by BCD and caniuse identifiers. |
#202 stakes out the optional |
There's some additional discussion in #729. @romainmenke points out that |
The Maybe all features could have a stable machine readable id? Having such an id would make it easier for 3rd parties (like myself) to reference web-features without having to worry too much about churn. |
Would a "get feature" helper that follows aliases make this easier to deal with? That would also I'm a little bit hesitant on an ID which is guaranteed to never change, because it opens up new questions. If a feature needs to be split, which one gets to keep the ID? And with long term evolution you also have a problem akin to Ship of Theseus, does it ever become a new feature? |
This helps with discovery and it slightly reduces the amount of work to handle changes. |
This came up in the WebDX call today. There was a request for more examples (from me), especially actual historic ones. Some semantics we'll need to deal with:
There was also some discussion of features that evolved a lot, such as a CSS feature with changing name and syntax. I don't have a good example for this kind of thing and would welcome more thought on that. |
One (identified) example is the |
Reading through #91 (comment), I agree that those are the important cases. Simplified further, we can talk about features that are gone with no replacement, and features that are gone but there's one or more other features that took its place. Some mocked YAML to show what we might do in practice: #777 merely changed an identifier because we liked another better. Tools could follow the rename without looking closely. The # no name or description, it would just be duplicated
tombstone:
reason: 'Renamed to match the @font-face syntax and avoid the overly generic "fonts" identifier.'
redirect: font-face #1089 split a feature into several others. Some uses of it could be replaced with a more specific feature, others with multiple features, it can't be sorted out automatically. But sites like webstatus.dev could suggest which features to look at instead. The name: Custom elements
description: Custom elements are HTML elements with behavior that you define.
spec: https://html.spec.whatwg.org/multipage/custom-elements.html
caniuse: custom-elementsv1
tombstone:
reason: Split into more specific features and a group.
maybe_you_want: # needs better name
- autonomous-custom-elements
- customized-built-in-elements #1000 removed a feature where the replacement is quite different, it's not a simple rename. A name: Sanitizer API
description: The Sanitizer API sanitizes untrusted strings of HTML, Document and DocumentFragment objects. After sanitization, unwanted elements or attributes are removed, and the returned objects can safely be inserted into a document's DOM.
spec: https://wicg.github.io/sanitizer-api/ # not linted!
tombstone:
reason: Removed from Chrome, superseded by Unsanitized HTML parsing methods.
# nothing machine readable pointing to the Unsanitized HTML parsing methods feature I haven't given an example of a merge here, but I think that'll just be one of the first two forms. For cases that can be redirected automatically use the first form, and for other cases use the second. @ddbeck WDYT? @jcscottiii would something like this work for webstatus.dev if we published it in the package? |
The first two cases would be very helpful for webstatus.dev. The last case seems similar to the discouraged field. How do you imagine the third case would differ from the discouraged field? Another question I have: Would you continue to calculate baseline status for these features marked with tombstones? |
I think we would have to. At least for the |
@jcscottiii The main difference I'm thinking is that webstatus.dev wouldn't show the Sanitizer API since another feature has replaced it, but would show discouraged features, I assume.
Terrific question. I was imagining that we'd trim the YAML down to something minimal, but @captainbrosset makes a very good point that preserving everything allows consumers to migrate in their own time. So maybe we should consider the tombstone purely an extra field in terms of the schema, not a replacement for other information as I was thinking. |
Thanks to Philip for the concrete proposal and the discussion based on it. After reading through this and trying to apply the proposal to my examples #91 (comment), I think I’ve got a few questions/ideas for this, but I think we’re getting to close to what we need. Highlights for my long comment:
Types of tombstones and redirectsAfter trying to apply Philip’s idea to the situations I described in #91 (comment), I think there are three distinct types of tombstones/redirects. True tombstonesThis is when we don’t think developers should see/care about the feature at a given ID, at all. We’re holding it because we don’t want it to be used for something else. In HTTP terms, a 410 Gone or 403 Forbidden. A tombstoned feature has no (published) support information, name, or description. I'd expect consumers to basically ignore these entries. It’s a little bit of a misnomer, but a tombstone could be used to reserve an ID for future use too. If we wanted to clean up the terminology, we could call these “reserved” or something. Use cases: a feature that we added erroneously or prematurely; an ID reserved for future use. True redirectsThis is when we don’t think developers should see/care about the redirect itself, just the data at the other side of that redirect. In HTTP terms, a 301 Moved Permanently. For consumer convenience (per #91 (comment)), true redirects could have support information, names, and descriptions, pulled from its redirect target—though I expect consumers to do something about duplication in that case. If that data ever gets too cumbersome, we could periodically do breaking changes that force consumers to actually follow the redirects. Use cases: a feature was entered with a typo in the ID; an alias; developers started referring to a feature by a new name and we want the ID to match; a feature merged into another (provided we have an “inner feature” reference; see #2676). Informational redirectsThis is when the redirect itself has some informational value for developers. This would be any case where silently redirecting would be unhelpful or incomplete. In HTTP terms, a 300 Multiple Choices, I guess. For these cases, I'd expect the consumer make some kind of decision about how to show that redirect. Maybe they offer the user a choice, they pick one but offer a "did you mean…?" option, or they make an editorial decision. Interestingly, we already do this in a way, with a discouraged feature’s Use cases: one feature replaces another; we split a feature in two or more pieces; discouragement with one or more alternatives. Schema bikesheddingGiven the three types above, I think it would be nice if we had different ways of marking them for consumers, so our intent is clearer. I ended up coming up with these examples, to exercise the full range: # oops.yml
# accidentally committed a test file
reserved:
reason: deleted
# some-very-early-proposal.yml
reserved:
reason: future use
# numeric-seperators.yml
# our typo
redirect:
reason: typo
to: numeric-separators
# array-includes.yml
redirect:
reason: merged
to: array/array-includes
# referrer.yml
# the spec's typo
redirect:
reason: alias
to: referer
# custom-elements.yml
disambiguate:
reason: feature split
choices:
- autonomous-custom-elements
- customized-built-in-elements
# import-assertions.yml
# we already do this, minus the reason
discouraged:
according_to: …
reason: evolved into
alternatives:
- json-modules Things I’m still worried about
|
I really like this! Having multiple names/reasons for this mechanism, which in the end could just be very generic and use one field only, seems very useful for consumers. We give them a lot of subtle information about the state of a feature. I'm slightly worried about it making it harder to author/maintain features though. But I guess there's no real way around it anyway. Some thoughts below:
I disagree about the fact that developers should not see or care about future features. Raising awareness about newly proposed features and applying pressure to other actors is all part of getting a feature to eventually be part of the web platform. I don't think web-features should hide these.
I don't think this is necessary. If I'm understanding this correctly, this would make it possible for consumers to do something like: const theNewFeature = webFeatures[theOldId].redirect.to._someLinkToTheFeature; Which, I don't think is much easier than: const theNewId = webFeatures[theOldId].redirect.to;
const theNewFeature = webFeatures[theNewId];
Do you think we'd really want to clean up true redirects? I feel like we could live with them forever, just like tombstoned features. Especially if we just give consumers the redirected ID.
As said before, I like the different fields from a consumer's perspective, although I wonder if it would be nicer to be able to do something like
In many cases, discouraged and redirected are the same thing, but we still want to tell consumers about the difference. A field like
In my head, discouraged features are not true redirects, but informational redirects instead. It's, of course, up to consumers to decide if they just want to treat the discouraged feature is a redirect and just show the target feature, but some consumers like MDN will want to show the old discouraged feature in all its gory details, and provide a link to the new replacement feature.
Agreed
I like how we do things today: discouraged feature must have a Customizable select might be a good example:
At no point in this early development lifecycle of the feature was a "real" spec published, and there's no spec language anywhere that says that selectmenu or selectlist are obsolete/deprecated. |
Inspired by discussion on #89.
If the feature set is based on real-world usage by web developers, then some features may need to change identifiers from time to time or accommodate multiple known names. Some possible scenarios:
subgrid
is subsumed bygrid
. At least one feature is removed and the definition of another feature changes, triggering some sort of versioning event (either at the data or package level).es6
andes2015
).felxbox
) and we ship with the erroneous name.Some questions emerge:
The answers to some of these questions might influence how we handle versioning (if we understand versions to be a kind of identifier for a feature).
We ought to resolve this issue before a 1.0 release.
The text was updated successfully, but these errors were encountered: