Re: [w3c/manifest] Add beforeinstallprompt event (#417)

> I think it's the opposite:
>
> window.addEventListener('beforeinstallprompt', e => e.prompt());
> window.addEventListener('beforeinstallprompt', e => e.preventDefault());

That's the same as my example with the two registrations swapped around, right? My assumption was that the [registration order doesn't matter](https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-basic) (so this is the same as my example)... either way, the point is that as it stands now (in Chrome), it will either prompt or not prompt depending on the order the events get delivered (which may or may not be the same as the declaration order).

The question is whether it's acceptable to have a web API that behaves differently depending on event order. It doesn't seem too horrible given that I can easily write some code like this:

```js
var pressed = False;
window.addEventListener('keydown', e => { pressed = true; });
window.addEventListener('keydown', e => {
  if (pressed)
    alert('You pressed the key');
});
```

Whether the alert is shown depends on the execution order of the listeners, which is unspecified. Any stateful API can be made to behave differently depending on event listener evaluation order. So I'm not really seeing the big deal of adding a new API whose behaviour can be made to depend on event listener evaluation order (really, it just means the API is stateful).

Anyway, assuming we don't want the API to be abuseable in this way...

> Ok, but this might be where you end up getting into funky race conditions depending on ordering of in which scripts are executed (using script@async): event order registration is not deterministic.

My suggestion was to make `prompt` show the prompt regardless of whether `preventDefault` had been called, and conversely, make `preventDefault` *not* prevent the prompt if `prompt` has been explicitly called. This should mean in the above example (regardless of which order the listeners are registered or which order the UA decides to execute the listeners in) it behaves the same way.

- If `prompt` goes before `preventDefault`, it shows the prompt and `preventDefault` has no effect.
- If `preventDefault` goes before `prompt`, the automatic prompt is cancelled, but then `prompt` causes the manual prompt to be displayed.

So either way, the user will see the prompt.

> Are we sure we can't do a flipkart here?

Your example captures the way I imagined a hypothetical `navigator.showInstallPrompt` to work. However, note that this API by itself doesn't solve the unspecified order problem:

```js
window.addEventListener('beforeinstallprompt', e => e.preventDefault());
window.addEventListener('beforeinstallprompt', e => navigator.showInstallPrompt());
```

You have the same problem. So the question of whether to make `BeforeInstallPromptEvent.prompt()` (or `navigator.showInstallPrompt`) not require `preventDefault` is orthogonal to the question of whether it should be a method on `BeforeInstallPromptEvent` or `navigator`.

> A little out of left field, but we might even consider if there is overlap with the permissions API?

I'm not really a fan of this approach because it implies the user would be prompted right away and/or that the page has to continuously poll to see whether the permission is available. I'd rather it be delivered as an event.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/manifest/issues/417#issuecomment-229279128

Received on Wednesday, 29 June 2016 07:34:41 UTC