Skip to content
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

Issue with "Navigator.platform": Cross-browser API marked deprecated and Chromium-only alternative suggested #14429

Closed
hsivonen opened this issue Mar 29, 2022 · 11 comments · Fixed by #14452
Assignees
Labels
Content:WebAPI Web API docs

Comments

@hsivonen
Copy link
Contributor

MDN URL: https://developer.mozilla.org/en-US/docs/Web/API/Navigator/platform

What information was incorrect, unhelpful, or incomplete?

The page claims that navigator.platform is deprecated even though it's not marked deprecated in the spec.

The page suggests using a Chromium-only alternative even though the page notes that it's neither supported by all major browsers nor accepted by a standards group.

Specific section or headline?

The very top of the document.

What did you expect to see?

Expected the page not to claim deprecation and expected not to suggest using a Chromium-only API instead.

Did you test this? If so, how?

Not applicable.

MDN Content page report details
@github-actions github-actions bot added the needs triage Triage needed by staff and/or partners. Automatically applied when an issue is opened. label Mar 29, 2022
@eemeli
Copy link
Contributor

eemeli commented Mar 29, 2022

Went down the rabbit hole a bit chasing the origin of this, just out of interest. The origin of the change is in browser-compat-data, where the marking-as-deprecated appears to originate in mdn/browser-compat-data#6567 (comment) by @sideshowbarker, for which the subsequent change was confirmed by @foolip in mdn/browser-compat-data#6612 (comment).

@sideshowbarker sideshowbarker self-assigned this Mar 29, 2022
@sideshowbarker sideshowbarker added Content:WebAPI Web API docs and removed needs triage Triage needed by staff and/or partners. Automatically applied when an issue is opened. labels Mar 29, 2022
sideshowbarker added a commit that referenced this issue Mar 30, 2022
- Don’t say that navigator.userAgentData.platform is “recommended”; it’s
  sufficient to just point out that it exists as an alternative.
- Since it’s so far only in Blink, say “not yet supported by **most**
  browsers” rather than “not yet supported by some major browsers.

See #14429
sideshowbarker added a commit that referenced this issue Mar 30, 2022
For the navigator.platform article, this change replaces the
Deprecated_Header macro and its boilerplate text with some
more-appropriate alternative pseudo-boilerplate text.

See #14429
@sideshowbarker
Copy link
Collaborator

Thanks much @eemeli for investigating this and pinging me, and thanks @hsivonen for raising this.

I have a few questions and comments about this that’ll take me some time to write up, but for now I’ve opened #14452 with changes that I hope might have a chance of resolving it to everybody’s satisfaction. So please take a look at that PR and comment there — either if you have suggestions for specific refinements to it, or if you think it’s not actually at all the right solution to the issue.

@sideshowbarker
Copy link
Collaborator

@hsivonen, in case you don’t find #14452 to be a satisfactory resolution to this issue, then some questions:

  • Do you think MDN should be encouraging web developers to rely on navigator.platform in the code they write?
  • Do you think, despite the spec allowing the empty string for navigator.platform, UAs in practice — for compat reasons — will continue to return an accurate indication of the platform for it, in whatever way they already do now?
    In other words, do you think it’s reliable/future-proof as far as code using it being unlikely not to break in the future?
  • If in fact you agree MDN should not really be encouraging developers to rely on navigator.platform, do you anyway still think labeling it as “Discouraged” rather than “Deprecated” — the way I did in Un-deprecate navigator.platform (was: Replace Deprecated_Header in navigator.platform doc and adjust navigator.userAgentData.platform note wording) #14452 — is not the right fix?

See #12017 (comment) for some related comments, but to summarize those at point-of-use here, the context of my questions above relates to the following points:

  1. For all of the NavigatorID mixin which navigator.platform is included in, at https://html.spec.whatwg.org/multipage/system-state.html#client-identification:tracking-vector, the spec includes a big red warning with the following text:

    Any information in this API that varies from user to user can be used to profile the user. In fact, if enough such information is available, a user can actually be uniquely identified. For this reason, user agent implementers are strongly urged to include as little information in this API as possible.

  2. The spec allows conforming UAs to do the following:

  • any UA can return the empty string for navigator.platform rather than an accurate indication of the platform
  • any UA that currently does actually return an accurate indication of the platform for navigator.platform is free to change its behavior at any time, and to instead start returning the empty string

Given all that, it seems like:

  • If any web developers have existing code they’ve written that relies on navigator.platform accurately indicating the actual platform in any UA (even just one UA), that code’s at risk of breaking at any point — because any UA is free to change its behavior at any time and start returning the empty string, and still be conforming to the spec requirements
  • If any web developers are writing new code under the assumption that navigator.platform will always continue to return an accurate indication of the actual platform in any particular UA, they’re creating code that’s at risk of breaking. Even if the developers are writing their code based on testing what strings current UAs actually return, the developers can’t safely rely on that code continuing to work the same way it does now — again, because any UA is free to change its behavior at any time and start returning the empty string, and still be conforming to the spec requirements.

That’s why I believe MDN should discourage web developers from writing code that uses navigator.platform.

@sideshowbarker
Copy link
Collaborator

I guess it’s also worth pointing out here that maybe another thing to consider for this specific case is a spec change.

What I mean is, it seems possible, for backward-compat reasons, any UAs currently returning an accurate indication of the platform from navigator.platform might be unlikely to ever change behavior and start returning the empty string instead.

That said, if any UA currently returning an accurate indication of the platform from navigator.platform were to change its behavior and instead start returning the empty string, that change would put that UA more in line with what they are “strongly urged” to do by the current spec.

So, if we think that UAs are unlikely to ever actually change their current behavior — that is, if we don’t think that UAs are every going to move to returning the empty string — then perhaps we need to consider changing the spec so that UAs are not allowed to return the empty string for it, and are not “strongly urged to include as little information as possible” from it.

But unless/until the spec for this change, then the reasons I’ve outlined here in my other comments are why I believe it’s appropriate and helpful for MDN to discourage web developers from writing code that uses navigator.platform.

@sideshowbarker
Copy link
Collaborator

Sorry for the verbosity of my comments but I have one last verbose (meta)comment here for now and then I’ll be quiet.

To be clear: I actually fully agree that for the specific case of navigator.platform, labeling is as “Deprecated” isn’t accurate. But it’s not the only such case we have; instead, it’s just one instance of a general problem we’re not really addressing if we just keep fixing these case-by-case the way I’ve tried to do in #14452.

So, somewhat implicit in my #14452 change and my other comments here is a point of view that we could deal with this case and all other cases too by making a global change to using “Discouraged” everywhere we now use “Deprecated”.

It’s been understood for quite a while now that the “Deprecated” term has problems in the context of MDN — and at https://github.com/mdn/content/discussions/5549 we have an open/unresolved discussion about the problems, and in https://github.com/mdn/content/discussions/5549#discussioncomment-814689 I’ve proposed we replace it in MDN with “Discouraged”. Anybody reading this might want to also consider weighing in on that discussion.

The core problem is, for cases where we want to flag something as being relatively less-reliable for developers to use, the current MDN/BCD flag taxonomy only allows a flag named “Deprecated”. (And all text in the red Deprecated box at the top of the https://developer.mozilla.org/en-US/docs/Web/API/Navigator/platform is boilerplate from adding a {{Deprecated_Header}} macro call to the source of the page; see https://github.com/mdn/content/blob/main/files/en-us/web/api/navigator/platform/index.md?plain=1#L14.)

So, short of making the global shift to “Discouraged” and away from “Deprecated”, we could keep dealing with specific cases like this one by doing what I did in #14452 (replacing the Deprecated_Header and its boilerplate macro text with some alternative wording). But that actually only solves part of the problem. Another part of the problem is that for the related BCD data, we currently don’t really have any similar case-by-case alternative option at all at hand — because there’s a discrete set of relevant flag names in BCD, which includes deprecated but not anything like ”discouraged”.

One effect of that is, at https://developer.mozilla.org/en-US/docs/Web/API/Navigator/platform#browser_compatibility, even with the #14452 change merged, we’ll still have an indicator and generated boilerplate text that says, “Deprecated. Not for use in new websites”. Thus, this issue can’t really be fully resolved without some change to BCD.

So a possible additional change we could make is, flip the navigator.platform BCD data back to "deprecated": false.

But I think that’d be the wrong change. I think instead the right BCD change would be to use this issue as an opportunity to go ahead and globally convert the name of the current deprecated BCD flag to discouraged, and to also update the generated boilerplate to something like “Discouraged. Avoid using, and update existing code if possible”.

@hsivonen
Copy link
Contributor Author

Do you think MDN should be encouraging web developers to rely on navigator.platform in the code they write?

In general, this shouldn't be encouraged, but I can think of an exception:

Personally, I can think of one use case where relying on this is probably the least bad option (though I'd be happy to learn about a better option): Checking navigator.platform.indexOf("Mac") === 0 (or, more properly, navigator.platform.indexOf("Mac") === 0 || navigator.platform == "iPhone") to decide whether command or control is the modifier key for keyboard shortcuts.

Do you think, despite the spec allowing the empty string for navigator.platform, UAs in practice — for compat reasons — will continue to return an accurate indication of the platform for it, in whatever way they already do now?

My personal educated guess, which shouldn't be taken as a commitment by Mozilla, is that this property is going to continue to distinguish between Apple platforms vs. non-Apple platforms in order to avoid breaking code that decides whether command or control is the keyboard shortcut modifier key.

However, personally, I think it's reasonable to expect browsers to consolidate the return values for non-Apple platforms over time. (Within Apple platforms, the return value is already not "accurate" in the sense of iPadOS and macOS on Apple Silicon claiming "MacIntel".)

If in fact you agree MDN should not really be encouraging developers to rely on navigator.platform

I think in general, developers shouldn't try to find out the OS, either via navigator.platform or via a Blink-specific API, but if they need to figure out Apple vs. non-Apple for modifier key purposes, navigator.platform is the API that works cross-browser.

I'm a bit shy to suggest that your PR should suggest this use case before seeing comments by others in case I'm just unaware of a better way to decide between command and control.

@hsivonen
Copy link
Contributor Author

However, personally, I think it's reasonable to expect browsers to consolidate the return values for non-Apple platforms over time.

Specifically, my educated guess of an end state is that navigator.platform will end up having 5 distinct values:

  • "iPhone" for Apple phone-sized and smaller devices.
  • "MacIntel" for Apple larger-than-phone devices.
  • "Win32" for desktop Windows.
  • "Linux armv81" for non-Apple phone-and-smaller devices.
  • "Linux x86_64" for everything else.

Source: https://www.chromium.org/updates/ua-reduction/ plus WebKit on iOS and (not tested personally) watchOS returning "iPhone", but there's no spec text to support this guess of an end state. A possible further reduction would be collapsing "Win32" and "Linux x86_64" into "Win32", but I think that's less likely than the end state being 5 values.

I haven't done the research of how the empty string ended up in the spec, but it's hard for me to see any vendor having the appetite to pursue that one.

@hsivonen
Copy link
Contributor Author

I haven't done the research of how the empty string ended up in the spec, but it's hard for me to see any vendor having the appetite to pursue that one.

I did the research and, as a result, made a spec PR to get rid of the empty string.

@sideshowbarker
Copy link
Collaborator

Personally, I can think of one use case where relying on this is probably the least bad option (though I'd be happy to learn about a better option): Checking navigator.platform.indexOf("Mac") === 0 (or, more properly, navigator.platform.indexOf("Mac") === 0 || navigator.platform == "iPhone") to decide whether command or control is the modifier key for keyboard shortcuts.

Thanks — it’s great to have a specific concrete use case to focus on, and that one’s also the case behind https://css-tricks.com/snippets/javascript/test-mac-pc-javascript/ and some other places where navigator.platform is suggested.

But when you say that for the deciding-on-a-modifier-key case, navigator.platform seems like the least bad option, are you considering the option of — rather than the trying to detect the platform and (I assume) then taking one code path for the command-key-modifier case if it’s Apple and different code path for the control-key-modifier case it’s non-Apple — instead just having one code path that checks for keydown, then bothif (event.ctrlKey || event.metaKey) together, and then for whatever actual that modifier key is pressed along with?

What is mean is, something like what’s in some of the answers at https://stackoverflow.com/questions/3902635/how-does-one-capture-a-macs-command-key-via-javascript

But if that’s not actually a good option for the scenario you in mind — which I can imagine might be if say, the scenario is to give the user guidance up front about exactly which modifier key to press (command or control), based on knowing what platform they’re on — then yeah I can see how there’s a need for navigator.platform for that kind of scenario, and so we should not have MDN discouraging it.

On the other hands, if you think doing the if (event.ctrlKey || event.metaKey) thing might be a better option, then maybe it makes sense to have MDN discourage the use of navigator.platform, and we can add an example in MDN of doing the if (event.ctrlKey || event.metaKey) thing as an alternative for the deciding-on-a-modifier-key case.

@sideshowbarker
Copy link
Collaborator

I think in general, developers shouldn't try to find out the OS, either via navigator.platform or via a Blink-specific API

I agree and I think among the set of people working on developing and maintaining the APIs, there’s agreement about that. However, for the record here, I guess we still need to recognize that web developers are continuing to use navigator.platform — even in spite of some of them knowing that MDN has it marked as deprecated — and for a lot of cases other than just the deciding-on-a-modifier-key case. See, for example, https://stackoverflow.com/questions/10527983/best-way-to-detect-mac-os-x-or-windows-computers-with-javascript-or-jquery and https://stackoverflow.com/questions/9514179/how-to-find-the-operating-system-details-using-javascript and https://stackoverflow.com/questions/38241480/detect-macos-ios-windows-android-and-linux-os-with-js.

So maybe having MDN try to discourage developers from using it is already kind of a lost cause.

My personal educated guess, which shouldn't be taken as a commitment by Mozilla, is that this property is going to continue to distinguish between Apple platforms vs. non-Apple platforms in order to avoid breaking code that decides whether command or control is the keyboard shortcut modifier key.

I haven't done the research of how the empty string ended up in the spec, but it's hard for me to see any vendor having the appetite to pursue that one.

OK, then those are further data points to suggest that having MDN try to discourage developers from using navigator.platform is maybe kind of a lost cause.

@hsivonen
Copy link
Contributor Author

Personally, I can think of one use case where relying on this is probably the least bad option (though I'd be happy to learn about a better option): Checking navigator.platform.indexOf("Mac") === 0 (or, more properly, navigator.platform.indexOf("Mac") === 0 || navigator.platform == "iPhone") to decide whether command or control is the modifier key for keyboard shortcuts.

Thanks — it’s great to have a specific concrete use case to focus on, and that one’s also the case behind https://css-tricks.com/snippets/javascript/test-mac-pc-javascript/ and some other places where navigator.platform is suggested.

Notably, this covers the side of showing advice—apparently in a way where writing "control key (or command on Mac)" is considered bad enough that the author wants to show only "control key" or "command key".

But when you say that for the deciding-on-a-modifier-key case, navigator.platform seems like the least bad option, are you considering the option of — rather than the trying to detect the platform and (I assume) then taking one code path for the command-key-modifier case if it’s Apple and different code path for the control-key-modifier case it’s non-Apple — instead just having one code path that checks for keydown, then bothif (event.ctrlKey || event.metaKey) together, and then for whatever actual that modifier key is pressed along with?

This occurred to me. I haven't thought through if this has downsides that would not make this viable advice.

and for a lot of cases other than just the deciding-on-a-modifier-key case. See, for example

Unfortunately, many of these don't say why they want to know.

sideshowbarker added a commit that referenced this issue Mar 31, 2022
Fixes #14429.

For the navigator.platform article, this change does the following:

- Drop the Deprecated_Header macro.
- Add admonishments that navigator.platform should be avoided in favor
  of feature detection.
- Relegate mention of (equally-bad) navigator.userAgentData.platform to
  just being a "See also".
- Add an example of the single known good case where using
  navigator.platform isn’t completely bad.

Related BCD change: mdn/browser-compat-data#15599
sideshowbarker added a commit that referenced this issue Mar 31, 2022
Fixes #14429.

For the navigator.platform article, this change does the following:

- Drop the Deprecated_Header macro.
- Add admonishments that navigator.platform should be avoided in favor
  of feature detection.
- Relegate mention of (equally-bad) navigator.userAgentData.platform to
  just being a "See also".
- Add an example of the single known good case where using
  navigator.platform isn’t completely bad.

Related BCD change: mdn/browser-compat-data#15599

Related spec change: whatwg/html#7762
sideshowbarker added a commit that referenced this issue Mar 31, 2022
Fixes #14429.

For the navigator.platform article, this change does the following:

- Drop the Deprecated_Header macro.
- Add admonishments that navigator.platform should be avoided in favor
  of feature detection.
- Relegate mention of (equally-bad) navigator.userAgentData.platform to
  just being a "See also".
- Add an example of the single known good case where using
  navigator.platform isn’t completely bad.

Related BCD change: mdn/browser-compat-data#15599

Related spec change: whatwg/html#7762
teoli2003 added a commit that referenced this issue Mar 31, 2022
…vigator.platform doc and adjust navigator.userAgentData.platform note wording) (#14452)

* Adjust wording of note about navigator.userAgentData.platform

- Don’t say that navigator.userAgentData.platform is “recommended”; it’s
  sufficient to just point out that it exists as an alternative.
- Since it’s so far only in Blink, say “not yet supported by **most**
  browsers” rather than “not yet supported by some major browsers.

See #14429

* Replace Deprecated_Header in navigator.platform doc

For the navigator.platform article, this change replaces the
Deprecated_Header macro and its boilerplate text with some
more-appropriate alternative pseudo-boilerplate text.

See #14429

* Update files/en-us/web/api/navigator/platform/index.md

Co-authored-by: wbamberg <will@bootbonnet.ca>

* Drop “yet” in text about navigator.userAgentData.platform not being supported/adopted

* Un-deprecate navigator.platform; improve advice and example

Fixes #14429.

For the navigator.platform article, this change does the following:

- Drop the Deprecated_Header macro.
- Add admonishments that navigator.platform should be avoided in favor
  of feature detection.
- Relegate mention of (equally-bad) navigator.userAgentData.platform to
  just being a "See also".
- Add an example of the single known good case where using
  navigator.platform isn’t completely bad.

Related BCD change: mdn/browser-compat-data#15599

Related spec change: whatwg/html#7762

* Refine explanation of matching on navigator.platform value

* Fix markdown formatting of example navigator.platform values

* Grammar fix

* Update files/en-us/web/api/navigator/platform/index.md

Co-authored-by: Jean-Yves Perrier <jypenator@gmail.com>

Co-authored-by: wbamberg <will@bootbonnet.ca>
Co-authored-by: Jean-Yves Perrier <jypenator@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Content:WebAPI Web API docs
Projects
None yet
3 participants