-
Notifications
You must be signed in to change notification settings - Fork 168
Add navigator.install()
#1175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add navigator.install()
#1175
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -2433,6 +2433,15 @@ <h2> | |||||||||||||||||||||
a new [=top-level browsing context=] with the manifest's members | ||||||||||||||||||||||
[=applied=]. | ||||||||||||||||||||||
</p> | ||||||||||||||||||||||
<p> | ||||||||||||||||||||||
At the discretion of the operating system or user agent, web | ||||||||||||||||||||||
applications may be [=installed=] once or multiple times. | ||||||||||||||||||||||
</p> | ||||||||||||||||||||||
<aside class="note" title="Multiple installations"> | ||||||||||||||||||||||
User agents may allow multiple installations of the same web | ||||||||||||||||||||||
application, for example, so they can be used with different profiles, | ||||||||||||||||||||||
such as "work" or "private" profiles. | ||||||||||||||||||||||
</aside> | ||||||||||||||||||||||
<p> | ||||||||||||||||||||||
Once a web application is [=installed=] it is known as a <dfn class= | ||||||||||||||||||||||
"export">installed web application</dfn>: That is, the manifest's | ||||||||||||||||||||||
|
@@ -2599,6 +2608,124 @@ <h3> | |||||||||||||||||||||
</p> | ||||||||||||||||||||||
</section> | ||||||||||||||||||||||
</section> | ||||||||||||||||||||||
<section> | ||||||||||||||||||||||
<h2> | ||||||||||||||||||||||
API Definition | ||||||||||||||||||||||
</h2> | ||||||||||||||||||||||
<section data-dfn-for="Navigator"> | ||||||||||||||||||||||
<h3> | ||||||||||||||||||||||
Extensions to the `Navigator` interface | ||||||||||||||||||||||
</h3><!-- todo: parameters --> | ||||||||||||||||||||||
<!-- todo: options bag --> | ||||||||||||||||||||||
<!-- todo: return value --> | ||||||||||||||||||||||
<pre class="idl"> | ||||||||||||||||||||||
partial interface Navigator { | ||||||||||||||||||||||
[SecureContext, NewObject] Promise<undefined> install(); | ||||||||||||||||||||||
}; | ||||||||||||||||||||||
</pre> | ||||||||||||||||||||||
<h3> | ||||||||||||||||||||||
Internal Slots | ||||||||||||||||||||||
</h3> | ||||||||||||||||||||||
<p> | ||||||||||||||||||||||
This API adds the following internal slot to the {{Navigator}} | ||||||||||||||||||||||
interface. | ||||||||||||||||||||||
</p> | ||||||||||||||||||||||
<dl> | ||||||||||||||||||||||
<dt> | ||||||||||||||||||||||
{{Promise}}? <dfn>[[\installPromise]]</dfn> | ||||||||||||||||||||||
</dt> | ||||||||||||||||||||||
<dd> | ||||||||||||||||||||||
The [=this=].{{Navigator/[[installPromise]]}} is a promise that | ||||||||||||||||||||||
represents a user's current intent to install an application. It is | ||||||||||||||||||||||
initialized to `null`. | ||||||||||||||||||||||
</dd> | ||||||||||||||||||||||
</dl> | ||||||||||||||||||||||
<h3> | ||||||||||||||||||||||
<dfn>install()</dfn> method | ||||||||||||||||||||||
</h3> | ||||||||||||||||||||||
<p> | ||||||||||||||||||||||
When the {{Navigator/install()}} method is called, run the following | ||||||||||||||||||||||
steps to [=install=] the website. | ||||||||||||||||||||||
</p> | ||||||||||||||||||||||
<ol class="algorithm"> | ||||||||||||||||||||||
<li>Let |global:Window| be [=this=]'s [=relevant global object=]. | ||||||||||||||||||||||
</li> | ||||||||||||||||||||||
<li>Let |document:Document| be |global|'s [=associated Document=]. | ||||||||||||||||||||||
</li> | ||||||||||||||||||||||
<li>If |document| is not [=Document/fully active=], return [=a | ||||||||||||||||||||||
promise rejected with=] an {{"InvalidStateError"}} {{DOMException}}. | ||||||||||||||||||||||
</li><!-- todo: permission policy? --> | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of a permission policy, this should throw with a NotAllowedError if the browsing context is not the top-level traversable. |
||||||||||||||||||||||
<li>If [=this=].{{Navigator/[[installPromise]]}} is not `null`, | ||||||||||||||||||||||
return [=a promise rejected with=] an {{"InvalidStateError"}} | ||||||||||||||||||||||
{{DOMException}}. | ||||||||||||||||||||||
</li> | ||||||||||||||||||||||
<li>If |global| does not have [=transient activation=], return [=a | ||||||||||||||||||||||
promise rejected with=] a {{"NotAllowedError"}} {{DOMException}}. | ||||||||||||||||||||||
</li> | ||||||||||||||||||||||
<li>[=Consume user activation=] of |global|. | ||||||||||||||||||||||
</li> | ||||||||||||||||||||||
<li>Set [=this=].{{Navigator/[[installPromise]]}} to be <a>a new | ||||||||||||||||||||||
promise</a>. | ||||||||||||||||||||||
</li> | ||||||||||||||||||||||
<li>Return [=this=].{{Navigator/[[installPromise]]}} and <a>in | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we have a race condition here. The manifest may already be getting processed for other reasons. I think the only thing this can really do is present the install prompt. That install prompt gets asynchronously populated by the manifest (in parallel). |
||||||||||||||||||||||
parallel</a>: | ||||||||||||||||||||||
<ol> | ||||||||||||||||||||||
<li>[=Processing|Process=] the |document|'s [=manifest=]. | ||||||||||||||||||||||
</li> | ||||||||||||||||||||||
<li>If the |document|'s [=Document/processed manifest=] is null, | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think the processed manifest can ever be null. It will have the defaults. |
||||||||||||||||||||||
[=queue a global task=] on the [=user interaction task source=] | ||||||||||||||||||||||
using |global| to: | ||||||||||||||||||||||
<ol> | ||||||||||||||||||||||
<li>[=Reject=] [=this=].{{Navigator/[[installPromise]]}} with | ||||||||||||||||||||||
an {{"DataError"}} {{DOMException}}. | ||||||||||||||||||||||
</li> | ||||||||||||||||||||||
<li>Set [=this=].{{Navigator/[[installPromise]]}} to `null`. | ||||||||||||||||||||||
</li> | ||||||||||||||||||||||
<li>Terminate this algorithm. | ||||||||||||||||||||||
</li> | ||||||||||||||||||||||
</ol> | ||||||||||||||||||||||
</li> | ||||||||||||||||||||||
<li>Present an installation UI for the |document|'s | ||||||||||||||||||||||
[=Document/processed manifest=]. | ||||||||||||||||||||||
<aside class="note"> | ||||||||||||||||||||||
If a user agent only allows one instance of the application | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's a lot of RFC2119 language here, which is not appropriate for a note. |
||||||||||||||||||||||
to be [=installed=], it may show a launch UI instead. In this | ||||||||||||||||||||||
case, the user agent should return the result of the launch | ||||||||||||||||||||||
prompt. For privacy reasons, this API should not reveal | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It can't do this (reveal anything) anyway, so the should not doesn't make sense here. |
||||||||||||||||||||||
signals indicating that an application was already | ||||||||||||||||||||||
[=installed=]. | ||||||||||||||||||||||
</aside> | ||||||||||||||||||||||
</li> | ||||||||||||||||||||||
<li>Wait for the user's choice. | ||||||||||||||||||||||
</li> | ||||||||||||||||||||||
<li>If the user chose to abort the install operation, or if | ||||||||||||||||||||||
installing the application has failed, [=queue a global task=] on | ||||||||||||||||||||||
the [=user interaction task source=] using |global| to: | ||||||||||||||||||||||
<ol> | ||||||||||||||||||||||
<li>[=Reject=] [=this=].{{Navigator/[[installPromise]]}} with | ||||||||||||||||||||||
an {{"AbortError"}} {{DOMException}}. | ||||||||||||||||||||||
</li> | ||||||||||||||||||||||
<li>Set [=this=].{{Navigator/[[installPromise]]}} to `null`. | ||||||||||||||||||||||
</li> | ||||||||||||||||||||||
<li>Terminate this algorithm. | ||||||||||||||||||||||
</li> | ||||||||||||||||||||||
</ol> | ||||||||||||||||||||||
</li> | ||||||||||||||||||||||
<li>Otherwise, [=queue a global task=] on the [=user interaction | ||||||||||||||||||||||
task source=] using |global| to: | ||||||||||||||||||||||
<ol> | ||||||||||||||||||||||
<li>[=Resolve=] [=this=].{{Navigator/[[installPromise]]}} | ||||||||||||||||||||||
with `undefined`. | ||||||||||||||||||||||
</li> | ||||||||||||||||||||||
<li>Set [=this=].{{Navigator/[[installPromise]]}} to `null`. | ||||||||||||||||||||||
</li> | ||||||||||||||||||||||
Comment on lines
+2717
to
+2721
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we want this the other way around... otherwise, resolving the promise would immediately call the resolver function, which might put things in a weird state.
Suggested change
|
||||||||||||||||||||||
</ol> | ||||||||||||||||||||||
</li> | ||||||||||||||||||||||
</ol> | ||||||||||||||||||||||
</li> | ||||||||||||||||||||||
</ol> | ||||||||||||||||||||||
</section> | ||||||||||||||||||||||
</section> | ||||||||||||||||||||||
<section id="nav-scope"> | ||||||||||||||||||||||
<h2> | ||||||||||||||||||||||
Navigation scope | ||||||||||||||||||||||
|
@@ -3519,6 +3646,7 @@ <h2> | |||||||||||||||||||||
navigation. | ||||||||||||||||||||||
</p> | ||||||||||||||||||||||
</section> | ||||||||||||||||||||||
<section id="idl-index" class="appendix"></section> | ||||||||||||||||||||||
<section id="index"></section> | ||||||||||||||||||||||
</body> | ||||||||||||||||||||||
</html> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.