From 2722d25edb03f8f53d8b944c256f01a811c2f748 Mon Sep 17 00:00:00 2001 From: Amanda Baker Date: Tue, 15 Oct 2024 17:49:39 -0700 Subject: [PATCH 1/5] Require id in manifest and support 0 param installation --- WebInstall/explainer_same_domain.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/WebInstall/explainer_same_domain.md b/WebInstall/explainer_same_domain.md index 1bd10af7..707cf0e5 100644 --- a/WebInstall/explainer_same_domain.md +++ b/WebInstall/explainer_same_domain.md @@ -42,11 +42,11 @@ The current way of supporting installation is vai the `onbeforeinstallprompt` ev The `navigator.install` method allows a imperative way to install web content, and works for UAs that prompt and don't prompt: ```javascript -/* tries to install the current domain */ +/* tries to install the current document */ const installApp = async () => { if (!navigator.install) return; // api not supported try { - await navigator.install('content_id_123'); + await navigator.install(); } catch(err) { switch(err.name){ case 'AbortError': @@ -61,7 +61,7 @@ const installApp = async () => { The **`navigator.install` method can overlap with some functionality of `beforeinstallprompt` for same-origin installation**. When the method is called it will trigger the UA to prompt for the installation of an application. This is analogous to when the end user clicks on an affordance that the UA might have to inform the user of installing. On Edge, Chrome (desktop) and Samsung Internet (mobile), this would be when the user clicks on the 'app available' banner or related UX that appears on the omnibox of the browser. For browsers that do not implement prompting, the expected behaviour is analogous to their installation paradigm. For example, in Safari (desktop) the behaviour might be that it shows a dialog to add the content to the dock as an app. -On UAs that support prompting, the threshold for `navigator.install` to resolve on same-origin installations uses the same checks that `onbeforeinstallprompt` currently has for prompting (if required by the UA). The promise doesn't resolve unless the *installability criteria* is met. *Note that the criteria defined by UAs varies and can be that there is NO criteria*. +On UAs that support prompting, the threshold for `navigator.install` to resolve on same-origin installations uses the same checks that `onbeforeinstallprompt` currently has for prompting (if required by the UA). The promise doesn't resolve unless the *installability criteria* is met. *Note that the criteria defined by UAs varies and can be that there is NO criteria aside from requiring an id in the site's manifest*. When called on the same domain, the **`install` method will trigger/open the prompt for installation the same way that using `onbeforeinstallprompt` does right now for browser that prompts.** If there is an error with the installation, then the promise returns a `DOMException` of type 'AbortError'. @@ -72,7 +72,7 @@ When called on the same domain, the **`install` method will trigger/open the pro ### The `navigator.install` method -To install a web site/app, the site/app would use the promise-based method`navigator.install([[, install_url], ])`. This method will: +To install a web site/app, the site/app would use the promise-based method `navigator.install(id, install_url, [])`. This method will: * Resolve when an installation was completed. * The success value will be an object that contains: @@ -85,7 +85,7 @@ To install a web site/app, the site/app would use the promise-based method`navig const installApp = async () => { try{ - const value = await navigator.install('content_id_123'); + const value = await navigator.install(); } catch(err){console.error(err.message)} }; @@ -96,8 +96,10 @@ const installApp = async () => { #### **Signatures of the `install` method (same-origin)** The same-origin part of the Web Install API consists of the extension to the navigator interface with the install method. The install method can be used in several different ways. There is no difference in behaviour when this is called from a standalone window or a tab. -1. `navigator.install(id[[, install_url], ])`: The method takes an id (and optional install url) and tries to install the current origin. If the content being installed has a manifest file, this `id` must match the value in the manifest file. If there is no manifest file present, this `id` will act as the app id for the installed content. This is relevant since if the installed content were to be given a manifest file and made into an application, there is a way to automatically update the app going forward. -The call can also receive an object with parameters that it can use to customize a same domain installation. These parameters alter how the app is installed and are defined in an object. More information about the parameters is found in the [Parameters](#parameters) subsection of this specification. +1. `navigator.install()`: The method takes no parameters and tries to install the current document. If the content to be installed does not link to a manifest with a valid id, then installation will fail. +2. `navigator.install(id, install_url, [])`: The method takes an id and install url and tries to install the web content at `install_url`. If the content to be installed does not have a linked manifest that specifies an id, and the provided `id` parameter does not match the computed id, then installation will fail. + +Both calls can also receive an object with parameters that they can use to customize a same domain installation. These parameters alter how the app is installed and are defined in an object. More information about the parameters is found in the [Parameters](#parameters) subsection of this specification. #### **Parameters** From 80148b1a25d2cfffc4a2f4aa5f6518ab0017106d Mon Sep 17 00:00:00 2001 From: Amanda Baker Date: Mon, 21 Oct 2024 15:39:57 -0700 Subject: [PATCH 2/5] Address misc feedback --- WebInstall/explainer_same_domain.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/WebInstall/explainer_same_domain.md b/WebInstall/explainer_same_domain.md index 707cf0e5..dd2b8a0a 100644 --- a/WebInstall/explainer_same_domain.md +++ b/WebInstall/explainer_same_domain.md @@ -37,7 +37,7 @@ Modern browsers have UX that enable users to *install* web content on their devi ### **Installing a web app from the current origin** The site can trigger its own installation. -The current way of supporting installation is vai the `onbeforeinstallprompt` event, which only works in browsers that have a prompting UI affordace. +The current way of supporting installation is via the `onbeforeinstallprompt` event, which only works in browsers that have a prompting UI affordance. The `navigator.install` method allows a imperative way to install web content, and works for UAs that prompt and don't prompt: @@ -65,8 +65,6 @@ On UAs that support prompting, the threshold for `navigator.install` to resolve When called on the same domain, the **`install` method will trigger/open the prompt for installation the same way that using `onbeforeinstallprompt` does right now for browser that prompts.** If there is an error with the installation, then the promise returns a `DOMException` of type 'AbortError'. -*Any same-origin content can be installed even if it is **NOT** an application.* - ## Proposed Solution @@ -97,7 +95,7 @@ const installApp = async () => { The same-origin part of the Web Install API consists of the extension to the navigator interface with the install method. The install method can be used in several different ways. There is no difference in behaviour when this is called from a standalone window or a tab. 1. `navigator.install()`: The method takes no parameters and tries to install the current document. If the content to be installed does not link to a manifest with a valid id, then installation will fail. -2. `navigator.install(id, install_url, [])`: The method takes an id and install url and tries to install the web content at `install_url`. If the content to be installed does not have a linked manifest that specifies an id, and the provided `id` parameter does not match the computed id, then installation will fail. +2. `navigator.install(id, install_url, [])`: The method takes an id and install url and tries to install the web content at `install_url`. If the content to be installed does not link to a manifest OR if the manifest does not include a valid id OR if the id parameter does not match either the declared or resolved manifest id, then installation will fail. Both calls can also receive an object with parameters that they can use to customize a same domain installation. These parameters alter how the app is installed and are defined in an object. More information about the parameters is found in the [Parameters](#parameters) subsection of this specification. @@ -117,7 +115,7 @@ To install a same domain web site/app, the process is as follows: ## Relation with other web APIs -* **`navigator.install` and manifest file's `prefer_related_applications`:** When the `related_applications` and `prefer_related_applications` key/values are present in the manifest, the UA should try to handoff the install to the prefered catalog. If this is not possible then it fallback to a default UA install. +* **`navigator.install` and manifest file's `prefer_related_applications`:** When the `related_applications` and `prefer_related_applications` key/values are present in the manifest, the UA should try to handoff the install to the preferred catalog. If this is not possible then it fallback to a default UA install. * **`navigator.install` and getInstalledRelatedApps():** If a web app tries to install itself (same domain install) it can first use the `getInstalledRelatedApps()` to check if it is already installed and hide the installation UI. @@ -160,8 +158,10 @@ A user agent might decide to have only the requirement of HTTPS to allow install * Should we allow an [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) to enable cancelling the installation if the process takes too long? ## Glossary -* **installation origin**: the origin that initiates the call to the `install` method. -* **installed origin**: the origin that is installed with the `install` method. +* **Installation origin**: The origin that initiates the call to the `install` method. +* **Installed origin**: The origin that is installed with the `install` method. +* **Declared manifest id**: The id as it is declared in the manifest. See [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/Manifest/id) for more info. +* **Resolved manifest id**: The processed id after it is resolved against the `start_url`'s origin. Since the declared id is resolved against an origin, this will take the form of a url (e.g. "https://example.com/my_app"), although it may not point to a valid resource. See [W3 manifest spec](https://www.w3.org/TR/appmanifest/#id-member) for detailed parsing info. ## Acknowledgements From ad09dfe117348afd038d45c7cb817d841e46f9ed Mon Sep 17 00:00:00 2001 From: Amanda Baker Date: Mon, 21 Oct 2024 15:43:48 -0700 Subject: [PATCH 3/5] Add missing and update wording of no params install --- WebInstall/explainer_same_domain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebInstall/explainer_same_domain.md b/WebInstall/explainer_same_domain.md index dd2b8a0a..3b3526c7 100644 --- a/WebInstall/explainer_same_domain.md +++ b/WebInstall/explainer_same_domain.md @@ -94,7 +94,7 @@ const installApp = async () => { #### **Signatures of the `install` method (same-origin)** The same-origin part of the Web Install API consists of the extension to the navigator interface with the install method. The install method can be used in several different ways. There is no difference in behaviour when this is called from a standalone window or a tab. -1. `navigator.install()`: The method takes no parameters and tries to install the current document. If the content to be installed does not link to a manifest with a valid id, then installation will fail. +1. `navigator.install()`: The method takes no parameters and tries to install the current document. If the content to be installed does not link to a manifest with an explicitly defined `id` value, then installation will fail. 2. `navigator.install(id, install_url, [])`: The method takes an id and install url and tries to install the web content at `install_url`. If the content to be installed does not link to a manifest OR if the manifest does not include a valid id OR if the id parameter does not match either the declared or resolved manifest id, then installation will fail. Both calls can also receive an object with parameters that they can use to customize a same domain installation. These parameters alter how the app is installed and are defined in an object. More information about the parameters is found in the [Parameters](#parameters) subsection of this specification. From 61b18aa69d60156190eb1fc29452ef68bc072896 Mon Sep 17 00:00:00 2001 From: Amanda Baker Date: Mon, 18 Nov 2024 14:44:01 -0800 Subject: [PATCH 4/5] Update install signature descriptions --- WebInstall/explainer_same_domain.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WebInstall/explainer_same_domain.md b/WebInstall/explainer_same_domain.md index 3b3526c7..a22cf576 100644 --- a/WebInstall/explainer_same_domain.md +++ b/WebInstall/explainer_same_domain.md @@ -94,8 +94,8 @@ const installApp = async () => { #### **Signatures of the `install` method (same-origin)** The same-origin part of the Web Install API consists of the extension to the navigator interface with the install method. The install method can be used in several different ways. There is no difference in behaviour when this is called from a standalone window or a tab. -1. `navigator.install()`: The method takes no parameters and tries to install the current document. If the content to be installed does not link to a manifest with an explicitly defined `id` value, then installation will fail. -2. `navigator.install(id, install_url, [])`: The method takes an id and install url and tries to install the web content at `install_url`. If the content to be installed does not link to a manifest OR if the manifest does not include a valid id OR if the id parameter does not match either the declared or resolved manifest id, then installation will fail. +1. `navigator.install()`: The method takes no parameters and tries to install the current document. Installation will proceed as long as the current document links to a manifest that includes a declared id. +2. `navigator.install(id, install_url, [])`: The method takes an id and install url and tries to install the web content at `install_url`. Installation will proceed as long as the target web app has a declared id in its manifest and the `id` parameter either matches the declared or resolved manifest id. Both calls can also receive an object with parameters that they can use to customize a same domain installation. These parameters alter how the app is installed and are defined in an object. More information about the parameters is found in the [Parameters](#parameters) subsection of this specification. From 8ec723d50dce73b9fb0a7037e102ac52fc520a36 Mon Sep 17 00:00:00 2001 From: Amanda Baker Date: Mon, 18 Nov 2024 16:53:17 -0800 Subject: [PATCH 5/5] Update 2 params description (again) --- WebInstall/explainer_same_domain.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/WebInstall/explainer_same_domain.md b/WebInstall/explainer_same_domain.md index a22cf576..a9aebeeb 100644 --- a/WebInstall/explainer_same_domain.md +++ b/WebInstall/explainer_same_domain.md @@ -95,7 +95,10 @@ const installApp = async () => { The same-origin part of the Web Install API consists of the extension to the navigator interface with the install method. The install method can be used in several different ways. There is no difference in behaviour when this is called from a standalone window or a tab. 1. `navigator.install()`: The method takes no parameters and tries to install the current document. Installation will proceed as long as the current document links to a manifest that includes a declared id. -2. `navigator.install(id, install_url, [])`: The method takes an id and install url and tries to install the web content at `install_url`. Installation will proceed as long as the target web app has a declared id in its manifest and the `id` parameter either matches the declared or resolved manifest id. +2. `navigator.install(id, install_url, [])`: The method takes an id and install url and tries to install the web content at `install_url`. Installation will proceed if the following are true: + a. The target web app links to a manifest. + b. The target web app's manifest includes either an `id` or `start_url`. + c. The `id` parameter matches the declared or resolved id of the target web app. Both calls can also receive an object with parameters that they can use to customize a same domain installation. These parameters alter how the app is installed and are defined in an object. More information about the parameters is found in the [Parameters](#parameters) subsection of this specification.