Closed fallaciousreasoning closed 4 years ago
@mgiuca let's discuss this when I get back. I know there's no scope setting the app badge from the ServiceWorker, but it is kind of gross :P
calling setAppBadge from the ServiceWorker will result in the app whose scope exactly matches the service worker (<-- to be discussed, could be above scope, could be within scope) being badged.
We discussed this a bit in the meeting and I believe it would set the badge for any app that is within the scope of the SW.
OK, I had a chat with Raymes. I'm on board with this mostly.
A summary of the (rather extensive) changes (just based on Jay's post) from what I had proposed in #51:
Badge
namespace; methods appear on Navigator
and WorkerNavigator
.setForScope
to setAppBadge
, with a focus explicitly on badging apps (no more "handle" contexts, it's explicit to apps).setForDocument
to setClientBadge
.setClientBadge
from a SW, and being able to specify a client to go along with it.Some thoughts:
Navigator
namespace a fair amount).Client
to be supplied when this is called from a document, and it doesn't make sense to not supply a Client
when called from a worker. I think this needs some thought.void
and add a promise if there are some defined failure conditions that the caller needs to know about.The big one: removing scope.
The main technical drawback of this is that if you have multiple apps governed by a single SW, you can't badge them individually. Apparently, y'all discussed this and decided that was a use case we want to discourage. I'm hesitant about this, since I don't think the Badge API is the right place to make a stand on this: if we really think that sites should not have multiple apps per SW (i.e., each app should have a SW at the same scope as the app scope), then we should officially (in the Manifest spec) state that this is expected, and not having a SW at the same scope as the manifest is deprecated, and future APIs may not support multiple apps per SW. However, I'm happy for the Badge API to have this deficiency which we can later rectify by either a) adding scope
as an option, or b) making the above deprecation announcement in the Manifest spec.
Aside from this, there is a big conceptual problem with the proposal: it has basically the exact opposite behaviour when called from a document vs called from a SW. When called from a document, the user agent searches up the URL hierarchy looking for an app scope to badge. When called from a SW, the user agent searches down the URL hierarchy, looking for any nested app scopes to badge. That's potentially quite confusing.
The way I found to rationalize this, though, is as follows: when called from a document, it searches up the URL hierarchy looking for an app scope to badge. When called from a SW, it applies that algorithm to each URL governed by the SW scope, which causes it to search up the hierarchy looking for an app scope. I still feel uneasy about it.
It has an advantage over the current scope proposal of having a better default in the case where you have multiple apps in different paths, each with their own SW, on the same origin. The default now isolates the badge to the "current app" without having to specify a scope. That's pretty nice.
Follow-up discussion with @raymeskhoury and @fallaciousreasoning :
setAppBadge
is called from a document, we badge the app whose manifest is <link>
ed from that page, if-and-only-if the page is also within scope of the manifest. (As opposed to searching upwards for any manifest in scope.) Rationale: That way, if https://example.com
has a manifest that is installed and https://example.com/foo
has one that is not installed, calling setAppBadge
from https://example.com/foo
will not (inappropriately) set a badge on the top-level app, because its pages won't be linking to that manifest. We can reconsider this; the downside is that the badge API won't work if you aren't linking to your manifest on every page. Edit: Actually we're leaning towards not doing this, and just relying on a future "carve-out" mechanism for scopes.setAppBadge
is called from a SW, badge all apps whose scope is "within scope" (even though I don't think SW spec uses that language) of the SW. We specifically will use the definition of scope matching for this, so that if scope matching becomes more finessed in the future (e.g., allowing carve-out sub-URLs that are out of scope) we would respect that.See also https://github.com/w3c/manifest/issues/782 for results of TPAC discussion.
- I agree with Raymes; I don't see the point of returning a promise unless we have some failure cases defined (currently it's designed as "fire and forget"). (In fact I'm kind of regretting adding a promise to Web Share since you don't really need to know if it succeeded and it caused a lot of troubles.) I think we should start with just
void
and add a promise if there are some defined failure conditions that the caller needs to know about.
OK OK we just discussed this and now I understand the reason why we need to make a promise from the get-go.
Say we made it void
return, then any errors (e.g., TypeErrors caused by bad inputs) will throw an exception synchronously. If we later change it to return a Promise<void>
, then these errors (even those detected synchronously) will now reject the promise rather than throwing. So that will break the existing API. So if we want to leave aside the possibility of returning a Promise in the future, we need to start out returning a Promise<void>
.
- ~Resolved~ that when
setAppBadge
is called from a document, we badge the app whose manifest is<link>
ed from that page, if-and-only-if the page is also within scope of the manifest. (As opposed to searching upwards for any manifest in scope.) Rationale: That way, ifhttps://example.com
has a manifest that is installed andhttps://example.com/foo
has one that is not installed, callingsetAppBadge
fromhttps://example.com/foo
will not (inappropriately) set a badge on the top-level app, because its pages won't be linking to that manifest. We can reconsider this; the downside is that the badge API won't work if you aren't linking to your manifest on every page. Edit: Actually we're leaning towards not doing this, and just relying on a future "carve-out" mechanism for scopes.
Long discussion about this with @fallaciousreasoning . We had tentatively decided this as shown in the quoted paragraph, but now we're committing to that decision. Summary:
Choice of two options:
setAppBadge
from a document searches upwards for the nearest containing installed app.setAppBadge
from a document gets the <link rel=manifest>
in the current document, and badges the associated app.Decision: Option 1.
Rationale: Option 1 has the downside discussed above when you have apps with nested scopes. If you have an app scope https://example.com/
and an app scope https://example.com/foo/
, if you call setAppBadge
from https://example.com/foo/
, it will badge the /foo/
app if it is installed, but if /foo/
is not installed but /
is, it will badge /
. It's impossible to control which app gets badged because you don't know which apps the user has installed.
However, it was discussed at TPAC that we do not want to explicitly cater for the nested app use case. On the horizon, we may define a way for scopes to exclude sub-paths which would give you more control (then /foo/
might not match the scope /
).
On the other hand, Option 2 has an even more difficult problem: it requires us to finally solve the long-standing issue of specifying the identity of an app (#586). Because we would have to say "follow the <link rel=manifest>
for the current document, and get the associated app and badge it. We would need to explicitly define a way to find an associated installed app, given a manifest. We have never explicitly defined this: is it the manifest URL? The start URL? The scope URL? We've always wanted to answer this but it's hard (even within Chrome, our desktop/Android implementations disagree about what the app key is), and whatever we pick makes it impossible to migrate some aspect of your app. Ideally, we would define an explicit app_id
field so you can migrate the app without changing its identity.
So we don't want to block on #586. Therefore, we're going with Option 1. However, if we do add app_id
to manifest in the future, then we could add an optional parameter to the Badge API to specify an app_id
to badge, which means you can avoid accidentally badging an outer-scope app.
When an app is installed, its identity should be clear in that it's isolated from the web browser (it has its own cache, permissions, cookie jar, URL scope, etc)... i.e., it becomes an OS level concern, no? setAppBadge()
applies to "that installed thing" 📲 - being option 2.
I guess the point being that it's unlikely we will ever agree what the identity of an installed app is (or how that's actually implemented).... just that we know what the qualities are, and that there is a "app installed on the OS, as far as the user is concerned" - but the rest is details.
I guess the point being that it's unlikely we will ever agree what the identity of an installed app is (or how that's actually implemented)....
I hope eventually we will agree (but I don't want to block on this).
Yes. Right now, "identity" is a user-agent-specific concept. It doesn't really come up at all unless you consider cross-device syncing and/or automatic updating, which aren't part of a spec.
What I mean by identity is: what aspect of the website would have to change in order for the user agent to consider this "a different app". If it's the manifest URL, that means if you move the manifest URL, now the user agent may offer to install a new app because you don't already have that one installed. But it could also be the scope URL, which means you can change your manifest URL as long as you keep the scope the same, and the user agent will continue to view it as the same app.
If we specced the Badge API as "badge the app associated with the currently linked manifest", then that question of "how does a manifest URL / contents relate to an actual app object installed in the UA's app database" becomes part of the spec for the first time.
If we specced the Badge API as "badge the app associated with the currently linked manifest", then that question of "how does a manifest URL / contents relate to an actual app object installed in the UA's app database" becomes part of the spec for the first time.
Manifests and installed apps are conceptually separate things: a web app could be installed without any manifest at all (i.e., they are somewhat orthogonal things, though manifests help - but it's UA dependent).
We've landed the changes proposed at the top of this issue (to the explainer at least). Spec changes coming in #45.
The Badging API was discussed at TPAC 2019-09.
After some discussion a new shape for the API was decided on:
navigator.setAppBadge(number); navigator.setClientBadge(number, { client });
setXXXBadge
methods are exposed on the navigator on the ServiceWorker and Window. CallingsetClientBadge
from the window without specifying a client or client id will result in the current client being badged.calling
setAppBadge
from the window will result in the app with the most specific scope containing the current document being badged.calling
setAppBadge
from the ServiceWorker will result in the app whose scope exactly matches the service worker (<-- to be discussed, could be above scope, could be within scope) being badged.