@@ -435,13 +435,14 @@ <h2>
435
435
< a > Queue a task</ a > on the < a > application life-cycle task
436
436
source</ a > to do the following:
437
437
< ol >
438
- < li > Let < var > target</ var > be at < a > Window</ a > object of the
439
- < a > top-level browsing context</ a > .
438
+ < li > Let < var > event</ var > be a newly constructed
439
+ < a > BeforeInstallPromptEvent</ a > named
440
+ < code > beforeinstallprompt</ code > , with its < code > cancelable</ code >
441
+ attribute initialized to true.
440
442
</ li >
441
- < li > Let < var > showPrompt</ var > be the result of < a > firing an
442
- event</ a > (< var > event</ var > ) named "beforeinstallprompt", using
443
- < a > BeforeInstallPromptEvent</ a > at < var > target</ var > with its
444
- < code > cancelable</ code > attribute initialized to true.
443
+ < li > Let < var > showPrompt</ var > be the result of < a > firing</ a >
444
+ < var > event</ var > at the < a > Window</ a > object of the < a > top-level
445
+ browsing context</ a > .
445
446
</ li >
446
447
< li > If < var > showPrompt</ var > is true, then, < a > in parallel</ a > ,
447
448
< a > request to present an install prompt</ a > with
@@ -450,6 +451,16 @@ <h2>
450
451
</ ol >
451
452
</ li >
452
453
</ ol >
454
+ < div class ="issue ">
455
+ Implementations may wish to show a prompt if, and only if, the site
456
+ explicitly requests it via
457
+ < a > < code > BeforeInstallPromptEvent.prompt()</ code > </ a > , but not
458
+ automatically without the site's approval. Is this something we want
459
+ to leave to the discretion of the user agent? (This would require
460
+ changing the language here, as "steps to notify before an automated
461
+ install prompt" would become "steps to notify that an install prompt
462
+ is available".)
463
+ </ div >
453
464
</ section >
454
465
< section >
455
466
< h3 id ="installation-sec ">
@@ -543,14 +554,22 @@ <h3>
543
554
activating an < a > automated install prompt</ a > , allowing a developer
544
555
to prevent the default action for an install prompt.
545
556
</ p >
546
- < p >
547
- Thus, the default action of the < a > BeforeInstallPromptEvent</ a > is to
557
+ < div class =" note " >
558
+ The default action of the < a > BeforeInstallPromptEvent</ a > is to
548
559
< a data-lt ="presents an install prompt "> present an automated install
549
560
prompt</ a > to the end-user. Canceling the default action (via
550
- < code > .preventDefault()</ code > ) prevents the user agent from
551
- < a data-lt ="presents an install prompt "> presenting an automated
552
- install prompt</ a > until a later time (see
553
- < a > BeforeInstallPromptEvent.prompt</ a > () method).
561
+ < a
562
+ data-cite ="DOM#dom-event-preventdefault "> < code > preventDefault</ code > </ a > )
563
+ prevents the user agent from < a data-lt ="presents an install
564
+ prompt "> presenting an automated install prompt</ a > . The user agent is
565
+ free to run < a > steps to notify before an automated install prompt</ a >
566
+ again at a later time.
567
+ </ div >
568
+ < p >
569
+ The < dfn > PromptResponseObject</ dfn > contains the result of calling < a
570
+ for ="BeforeInstallPromptEvent "> < code > prompt()</ code > </ a > . It contains
571
+ one member, < dfn for ="PromptResponseObject "> userChoice</ dfn > , which
572
+ states the user's chosen outcome.
554
573
</ p >
555
574
< p >
556
575
An instance of a < a > BeforeInstallPromptEvent</ a > has the following
561
580
< dfn > [[\didPrompt]]</ dfn >
562
581
</ dt >
563
582
< dd >
564
- A boolean, initially < code > false</ code > . Represents if this event
565
- was used to < a > present an install prompt</ a > to the end-user.
583
+ A boolean, initially < code > false</ code > . Represents whether this
584
+ event was used to < a > present an install prompt</ a > to the end-user.
566
585
</ dd >
567
586
< dt >
568
587
< dfn > [[\userResponsePromise]]</ dfn >
@@ -581,27 +600,24 @@ <h4>
581
600
steps:
582
601
</ p >
583
602
< ol >
584
- < li > Let < var > p</ var > be a newly created promise.
585
- </ li >
586
- < li > Resolve < var > p</ var > with
587
- < var > this</ var > .< a > [[\userResponsePromise]]</ a > .
588
- </ li >
589
603
< li > If < var > this</ var > .< a > [[\userResponsePromise]]</ a > is pending:
590
604
< ol >
591
- < li > If this event's < code > isTrusted</ code > attribute is < code >
592
- false</ code > , reject
605
+ < li > If this event's < a
606
+ data-cite ="!DOM#dom-event-istrusted "> < code > isTrusted</ code > </ a >
607
+ attribute is < code > false</ code > , reject
593
608
< var > this</ var > .< a > [[\userResponsePromise]]</ a > with
594
609
< a > NotAllowedError</ a > , optionally informing the developer
595
610
that untrusted events can't call < code > prompt()</ code > .
596
611
</ li >
597
612
< li > Else if < var > this</ var > .< a > [[\didPrompt]]</ a > is
598
- < code > false</ code > , then, < a > in parallel</ a > , < a > request to
599
- present an install prompt</ a > with this event. Wait, possibly
600
- indefinitely, for the end-user to make a choice.
613
+ < code > false</ code > , set < var > this</ var > .< a > [[\didPrompt]]</ a >
614
+ to < code > true</ code > , then < a > in parallel</ a > , < a > request to
615
+ present an install prompt</ a > with this event. Wait, possibly
616
+ indefinitely, for the end-user to make a choice.
601
617
</ li >
602
618
</ ol >
603
619
</ li >
604
- < li > Return < var > p </ var > .
620
+ < li > Return < var > this </ var > . < a > [[\userResponsePromise]] </ a > .
605
621
</ li >
606
622
</ ol >
607
623
< p >
@@ -613,12 +629,10 @@ <h4>
613
629
< a > Present an install prompt</ a > and let < var > outcome</ var > be
614
630
the result.
615
631
</ li >
616
- < li > Let < var > responseObj</ var > be a newly created
617
- < a > PromptResponseObject</ a > whose < code > userChoice</ code > member is
618
- the value of < var > outcome</ var > .
619
- </ li >
620
632
< li > Resolve < var > event</ var > .< a > [[\userResponsePromise]]</ a > with
621
- < var > responseObj</ var > .
633
+ a newly created < a > PromptResponseObject</ a > whose < a
634
+ for ="PromptResponseObject "> userChoice</ a > member is the value of
635
+ < var > outcome</ var > .
622
636
</ li >
623
637
</ ol >
624
638
</ section >
@@ -628,18 +642,30 @@ <h4>
628
642
</ h4 >
629
643
< p >
630
644
This example shows how one might prevent an automated install
631
- prompt from showing until the user has finished a set of tasks.
632
- Those tasks are represented as an array of promises, which the
633
- application "awaits" to finish before an install prompt is
634
- presented to the end-user .
645
+ prompt from showing until the user clicks a button to install the
646
+ app. In this way, the site can leave installation at the user's
647
+ discretion (rather than prompting at an arbitrary time), whilst
648
+ still providing a prominent UI to do so .
635
649
</ p >
636
- < pre class ="example " title ="'beforeinstallprompt' in action ">
637
- window.addEventListener("beforeinstallprompt", async (event) => {
650
+ < pre class ="example "
651
+ title ="Using beforeinstallprompt to present an install button ">
652
+ window.addEventListener("beforeinstallprompt", event => {
653
+ // Suppress automatic prompting.
638
654
event.preventDefault();
639
- // Wait for e.g., the user to request installation from inside the app.
640
- await Promise.all(tasksThatPreventsInstallation);
641
- const { userChoice } = await event.prompt();
642
- console.info(`user choice was: ${userChoice}`);
655
+
656
+ // Show the (disabled-by-default) install button. This button
657
+ // resolves the installButtonClicked promise when clicked.
658
+ installButton.disabled = false;
659
+
660
+ // Wait for the user to click the button.
661
+ installButton.addEventListener("click", async e => {
662
+ // The prompt() method can only be used once.
663
+ installButton.disabled = true;
664
+
665
+ // Show the prompt.
666
+ const { userChoice } = await event.prompt();
667
+ console.info(`user choice was: ${userChoice}`);
668
+ });
643
669
});
644
670
</ pre >
645
671
</ section >
@@ -649,9 +675,10 @@ <h3>
649
675
Extensions to the < code > Window</ code > object
650
676
</ h3 >
651
677
< p >
652
- The following extensions to the < dfn > < code > Window</ code > </ dfn > object
653
- specify the < a > event handler attributes</ a > on which events relating
654
- to the < a > installation</ a > of a web application are < a > fired</ a > .
678
+ The following extensions to the < dfn
679
+ data-cite ="!HTML#window "> < code > Window</ code > </ dfn > object specify the
680
+ < a > event handler attributes</ a > on which events relating to the
681
+ < a > installation</ a > of a web application are < a > fired</ a > .
655
682
</ p >
656
683
< pre class ="idl ">
657
684
partial interface Window {
@@ -691,16 +718,16 @@ <h4>
691
718
application</ a > ).
692
719
</ p >
693
720
</ section >
694
- < section >
721
+ < section data-dfn-for =" Window " >
695
722
< h4 >
696
723
< code > onbeforeinstallprompt</ code > attribute
697
724
</ h4 >
698
725
< p >
699
- The < dfn data-dfn-for =" Window " > onbeforeinstallprompt</ dfn > is an
700
- < a > event handler IDL attribute </ a > for the
701
- " < dfn > beforeinstallprompt </ dfn > " event type. The interface used for
702
- these events is the < a > BeforeInstallPromptEvent</ a > interface (see
703
- the < a > steps to notify before an automated install prompt</ a > ).
726
+ The < dfn > onbeforeinstallprompt</ dfn > is an < a > event handler IDL
727
+ attribute </ a > for the " < dfn > beforeinstallprompt </ dfn > " event type.
728
+ The interface used for these events is the
729
+ < a > BeforeInstallPromptEvent</ a > interface (see the < a > steps to
730
+ notify before an automated install prompt</ a > ).
704
731
</ p >
705
732
</ section >
706
733
</ section >
@@ -3625,7 +3652,7 @@ <h2>
3625
3652
< li >
3626
3653
< a href =
3627
3654
"https://dom.spec.whatwg.org/#concept-event-fire "> < dfn data-lt =
3628
- "fire|fired|firing an event "> Fire an event</ dfn > </ a >
3655
+ "fire|fired|firing "> Fire an event</ dfn > </ a >
3629
3656
</ li >
3630
3657
</ ul >
3631
3658
< p >
0 commit comments