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

Hi, I'd like to pick up where this discussion left off in April (since it seems we dropped the ball on the Chrome side). I've chatted with Dom, Mounir, Ben, Alex and Owen (all from Chrome) to get up to speed.

Here's the state of play wrt `beforeinstallprompt` (BIP) and `install` events:

* BIP is implemented and available by default on Chrome (and has been since Chrome 44, in 2015).
* BIP was briefly played with in the spec by Marcos (c9d2df5a) but taken out in favour of install.
* install has been implemented in Firefox 49 (not yet stable).

It looks like install is going ahead and it's relatively simple and non-controversial, so I've started implementation in Chrome (I just sent an [Intent to Implement email](https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/hWT6i_qXcjo) today; [Chrome tracking bug](https://crbug.com/623821)).

However, we still think there's value in BIP. Last signal from Marcos on this was:

> we might need to come up with some other way to deal with `beforeinstallprompt`.

I don't think `install` satisfies this requiement. We want a way to report to the website *before* showing the install prompt, to give the site an opportunity to suppress the banner and expose it to the user at a more convenient time (e.g., instead of it popping up in the user's face, it can provide a banner/button to install).

Now I'm trying to understand what Boris's objections are to the current implementation of BIP in Chrome. I don't really understand this:

> So the idea is that you can only prompt if no one else has prevented
you from doing so? And hence the behavior is event listener ordering
dependent? :(

My understanding is that you can only prompt iff you've previously called `preventDefault` on the event. So it seems more like the "event listener ordering dependent" problem is if you have two listeners, one calls `preventDefault` and the other calls prompt:

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

Now in this particular case, it's unspecified whether the prompt is shown, depending on whether the first or second event fires first. Is *that* Boris's problem? Please explain if I'm mistaken.

I'm trying to figure out how serious a problem this is. On the one hand, it's trivial for a web developer to write code that depends on the delivery order of events (and we can't do anything about that). But if we really want to solve this, we could make it so that `prompt()` is always successful: the very existence of the `BeforeInstallPromptEvent` means that the UA has permitted an install prompt, so you should always be able to show the prompt if you have such an object. Calling `preventDefault()` on the event *after* calling `prompt()` would have no effect. Therefore, as `prompt()` always trumps `preventDefault()`, if you call both you will see the prompt regardless of the order. Does that satisfy your concerns?

On the other hand, I do find there something a bit weird about using the event object itself to do this (potentially having to store the event object around for a long time until you are ready to prompt it). Some more approaches (backwards-incompatible with the current Chrome implementation):
* A global method like `navigator.showInstallPrompt()` that lets you explicitly ask to show an install prompt, which will succeed if you've been given a BIP event and haven't yet prompted, but fails otherwise.
* An object on the event has the `prompt` method (rather than the event object itself). That way you can store that object without having to store the whole event object.

I hope we can get beforeinstallprompt into the spec as it provides real value and we don't want it to just sit around as a Chrome-only thing.

---
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-228991332

Received on Tuesday, 28 June 2016 08:56:42 UTC