@@ -447,6 +447,171 @@ <h2>
447
447
DOM events < a > fired</ a > by this specification use the < dfn > application
448
448
life-cycle task source</ dfn > .
449
449
</ p >
450
+ < section data-dfn-for ="BeforeInstallPromptEvent ">
451
+ < h3 >
452
+ < code > BeforeInstallPromptEvent</ code > Interface
453
+ </ h3 >
454
+ < pre class ="idl ">
455
+ [Constructor(DOMString typeArg, optional BeforeInstallPromptEventInit eventInit)]
456
+ interface BeforeInstallPromptEvent : Event {
457
+ readonly attribute Promise<AppBannerPromptOutcome> userChoice;
458
+ Promise<UserResponseObject> prompt();
459
+ };
460
+
461
+ dictionary BeforeInstallPromptEventInit : EventInit {
462
+ AppBannerPromptOutcome userChoice;
463
+ };
464
+
465
+ dictionary UserResponseObject {
466
+ AppBannerPromptOutcome userChoice;
467
+ };
468
+ </ pre >
469
+ < p >
470
+ The < dfn > BeforeInstallPromptEvent</ dfn > is dispatched prior to
471
+ activating an < a > automated install prompt</ a > , allowing a developer
472
+ to prevent the default action for an install prompt.
473
+ </ p >
474
+ < p >
475
+ Thus, the default action of the < a > BeforeInstallPromptEvent</ a > is to
476
+ < a data-lt ="presents an install prompt "> present an automated install
477
+ prompt</ a > to the end-user. Canceling the default action (via
478
+ < code > .preventDefault()</ code > ) prevents the user agent from
479
+ < a data-lt ="presents an install prompt "> presenting an automated
480
+ install prompt</ a > until a later time (see
481
+ < a > BeforeInstallPromptEvent.prompt</ a > () method).
482
+ </ p >
483
+ < p >
484
+ The < a > BeforeInstallPromptEvent</ a > has three internal slots, which
485
+ are set when the event is < a data-lt =
486
+ "construct a BeforeInstallPromptEvent "> constructed</ a > :
487
+ </ p >
488
+ < dl >
489
+ < dt >
490
+ < dfn > [[\didPrompt]]</ dfn >
491
+ </ dt >
492
+ < dd >
493
+ A boolean, initially < code > false</ code > . Represents if this event
494
+ was used to < a > present an install prompt</ a > to the end-user.
495
+ </ dd >
496
+ < dt >
497
+ < dfn > [[\promptOutcome]]</ dfn >
498
+ </ dt >
499
+ < dd >
500
+ A < a > AppBannerPromptOutcome</ a > enum value, initially set to
501
+ < code > null</ code > . Represents the outcome of < a > presenting an
502
+ install prompt</ a > .
503
+ </ dd >
504
+ < dt >
505
+ < dfn > [[\userResponsePromise]]</ dfn >
506
+ </ dt >
507
+ < dd >
508
+ A promise, which resolves with an < a > UserResponseObject</ a > , which
509
+ represent the outcome of < a > presenting an install prompt</ a > .
510
+ </ dd >
511
+ </ dl >
512
+ < section >
513
+ < h4 >
514
+ Constructor
515
+ </ h4 >
516
+ < p >
517
+ To construct an instance of the < a > BeforeInstallPromptEvent</ a >
518
+ interface, run the < dfn data-lt =
519
+ "construct a BeforeInstallPromptEvent "> steps to construct a
520
+ < code > BeforeInstallPromptEvent</ code > event</ dfn > :
521
+ </ p >
522
+ < ol >
523
+ < li > Let < a > [[\didPrompt]]</ a > be < code > false</ code > .
524
+ </ li >
525
+ < li > Let < a > [[\userResponsePromise]]</ a > be a newly created promise.
526
+ </ li >
527
+ < li > Let < a > [[\promptOutcome]]</ a > be < code > null</ code > .
528
+ </ li >
529
+ < li > If < code > eventInit.userChoice</ code > is valid, then:
530
+ < ol >
531
+ < li > Resolve < a > [[\userResponsePromise]]</ a > with
532
+ < code > eventInit.userChoice</ code > .
533
+ </ li >
534
+ < li > Set < a > [[\promptOutcome]]</ a > to the value of
535
+ < code > eventInit.userChoice</ code > .
536
+ </ li >
537
+ </ ol >
538
+ </ li >
539
+ </ ol >
540
+ </ section >
541
+ < section >
542
+ < h4 >
543
+ < code > prompt()</ code > method
544
+ </ h4 >
545
+ < p >
546
+ The < dfn > prompt</ dfn > method, when called, runs the following
547
+ steps:
548
+ </ p >
549
+ < ol >
550
+ < li > Let < var > p</ var > be a newly created promise.
551
+ </ li >
552
+ < li > Run the following steps < a > in parallel</ a > :
553
+ < ol >
554
+ < li > If < a > [[\promptOutcome]]</ a > is not < code > null</ code > ,
555
+ resolve < var > p</ var > with < a > [[\userResponsePromise]]</ a > and
556
+ terminate this algorithm.
557
+ </ li >
558
+ < li > If this event's < code > isTrusted</ code > attribute is < code >
559
+ false</ code > , reject < a > [[\userResponsePromise]]</ a > with
560
+ < a > NotAllowedError</ a > , optionally informing the developer
561
+ that untrusted events can't call < code > prompt()</ code > .
562
+ </ li >
563
+ < li > Else if < a > [[\didPrompt]]</ a > is < code > false</ code > , then
564
+ < a > request to present an install prompt</ a > and wait, possibly
565
+ indefinitely, for the end-user to make a choice.
566
+ </ li >
567
+ < li > Upon fulfillment of [[\userResponsePromise]], resolve < var >
568
+ p</ var > with < a > [[\userResponsePromise]]</ a > .
569
+ </ li >
570
+ </ ol >
571
+ </ li >
572
+ < li > Return < var > p</ var > .
573
+ </ li >
574
+ </ ol >
575
+ < p >
576
+ To < dfn > request to present an install prompt</ dfn > with
577
+ < a > BeforeInstallPromptEvent</ a > < var > event</ var > :
578
+ </ p >
579
+ < ol >
580
+ < li >
581
+ < a > Present an install prompt</ a > and let < var > event</ var > 's
582
+ < a > [[\promptOutcome]]</ a > be the result.
583
+ </ li >
584
+ < li > Let < var > userResponseObj</ var > be a newly created
585
+ < a > UserResponseObject</ a > whose < code > userChoice</ code > member is
586
+ set to event's < a > [[\promptOutcome]]</ a > .
587
+ </ li >
588
+ < li > Resolve < a > [[\userResponsePromise]]</ a > with
589
+ < var > userResponseObject</ var > .
590
+ </ li >
591
+ </ ol >
592
+ </ section >
593
+ < section class ="informative ">
594
+ < h4 >
595
+ Usage example
596
+ </ h4 >
597
+ < p >
598
+ This example shows how one might prevent an automated install
599
+ prompt from showing until the user has finished a set of tasks.
600
+ Those tasks are represented as an array of promises, which the
601
+ application "awaits" to finish before an install prompt is
602
+ presented to the end-user.
603
+ </ p >
604
+ < pre class ="example " title ="'beforeinstallprompt' in action ">
605
+ window.addEventListener("beforeinstallprompt", async function(event) {
606
+ event.preventDefault();
607
+ // await e.g., user composing an email...
608
+ await Promise.all(tasksThatPreventsInstallation);
609
+ const { userChoice } = await event.prompt();
610
+ console.info(`user selected: ${userChoice}`);
611
+ });
612
+ </ pre >
613
+ </ section >
614
+ </ section >
450
615
< section >
451
616
< h3 >
452
617
Extensions to the < code > Window</ code > object
0 commit comments