- From: Marcos Cáceres <notifications@github.com>
- Date: Thu, 20 Oct 2016 23:14:50 -0700
- To: w3c/manifest <manifest@noreply.github.com>
- Message-ID: <w3c/manifest/pull/506/review/4999048@github.com>
marcoscaceres commented on this pull request.
@mgiuca, again many thanks for all the feedback. I'm going to close this PR and send a fresh, hopefully final version.
> +};
+
+dictionary BeforeInstallPromptEventInit : EventInit {
+ AppBannerPromptOutcome userChoice;
+};
+ </pre>
+ <p>
+ The <dfn><code>BeforeInstallPromptEvent</code></dfn> is dispatched
+ prior to activating an <a>automated install prompt</a>, allowing a
+ developer to prevent the default action for an install prompt.
+ </p>
+ <p>
+ Thus, the default action of the <a>BeforeInstallPromptEvent</a> is to
+ present an automated install prompt to the end user. Cancelling the
+ default action (via <code>.preventDefault()</code>) prevents the user
+ agent from presenting the automated install prompt.
Added example
> @@ -0,0 +1,143 @@
+/*globals BeforeInstallPromptEvent, DOMException*/
Yeah, I left it open so could call the methods from the console.
> @@ -0,0 +1,143 @@
+/*globals BeforeInstallPromptEvent, DOMException*/
+"use strict";
+const internalSlots = new WeakMap();
heh, I'm not a fan of the reverse :) However, once we put this into it's own scope, as suggested in your first comment, it won't matter. Hopefully JS will get real private members in the future.
> @@ -0,0 +1,143 @@
+/*globals BeforeInstallPromptEvent, DOMException*/
+"use strict";
+const internalSlots = new WeakMap();
+const installProcesses = [];
+const AppBannerPromptOutcome = new Set([
+ "accepted",
+ "dismissed",
+]);
+
+class BeforeInstallPromptEvent extends Event {
+ constructor(typeArg, eventInit) {
+ // WebIDL Guard. Wont be in spec in spec as it's all handled by WebIDL.
fixed
> + }
+ super(typeArg, Object.assign({ cancelable: true }, eventInit));
+
+ if (eventInit && typeof eventInit.userChoice !== "undefined" && !AppBannerPromptOutcome.has(String(eventInit.userChoice))) {
+ const msg = `The provided value '${eventInit.userChoice}' is not a valid` +
+ "enum value of type AppBannerPromptOutcome.";
+ throw new TypeError(msg);
+ }
+ // End WebIDL guard.
+ const internal = {
+ didPrompt: false,
+ };
+
+ internal.userChoice = new Promise((resolve) => {
+ internal.userChoiceHandlers = {
+ resolve,
So, before it held .resolve and .reject. But will change to your suggestion:
```
internal.userChoiceResolver = resolve;
```
> + const promptOutcome = await showInstallPrompt();
+ internalSlots.get(this).userChoiceHandlers.resolve(promptOutcome);
+ }.bind(this)())
+ }
+
+ get userChoice() {
+ return internalSlots.get(this).userChoice;
+ }
+}
+
+async function notifyBeforeInstallPrompt(element) {
+ await trackReadyState();
+ if (installProcesses.length) {
+ return;
+ }
+ const event = new BeforeInstallPromptEvent("beforeinstallprompt");
Yeah, I was thinking of doing that (I've just been commenting out the checks while I play with this). Obviously, trusted gets set automatically when the real even is created by the browser through the binding layer.
Within a few weeks, we will have both Chrome and Firefox implementing this for real in C++, so let's keep the current sample implementation as is.
> + }
+}
+
+async function notifyBeforeInstallPrompt(element) {
+ await trackReadyState();
+ if (installProcesses.length) {
+ return;
+ }
+ const event = new BeforeInstallPromptEvent("beforeinstallprompt");
+ window.dispatchEvent(event);
+ if (!event.defaultPrevented) {
+ await showInstallPrompt(element);
+ }
+}
+
+function trackReadyState() {
Technically you are correct, but as this doesn't use a "await" keyword anywhere, it's fine to leave looking like a sync function.
> + .then(value => console.assert(value === "dismissed"))
+ .catch(err => console.assert(false, assertion, err));
+} {
+ const assertion = "BeforeInstallPromptEvent has a prompt() method";
+ const e = new BeforeInstallPromptEvent("");
+ console.assert("prompt" in e, assertion);
+} {
+ const assertion = "prompt() is a function";
+ const e = new BeforeInstallPromptEvent("");
+ console.assert(e.prompt instanceof Function, assertion);
+} {
+ const assertion = "prompt() takes no arguments";
+ const e = new BeforeInstallPromptEvent("");
+ console.assert(e.prompt.length === 0, assertion);
+} {
+ const assertion = "calling prompt with unstrusted event results in NotAllowedError error";
fixed
> + console.assert(false, assertion);
+ } catch (err) {
+ console.assert(err instanceof DOMException, assertion);
+ console.assert(err.type = "NotAllowedError", assertion);
+ }
+ try {
+ e.prompt();
+ console.assert(false, assertion);
+ } catch (err) {
+ console.assert(err instanceof DOMException, assertion);
+ console.assert(err.type = "InvalidStateError", assertion);
+ }
+}
+
+// install events
+window.addEventListener("install", (ev) => {
Heh. Got used to the old way 👍 fixed!
--
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/pull/506#pullrequestreview-4999048
Received on Friday, 21 October 2016 06:15:20 UTC