From ae3c6610e18c9b3d867fe7bbf074d1bae833ad2b Mon Sep 17 00:00:00 2001 From: Alan Cutter Date: Tue, 6 Jul 2021 17:04:25 +1000 Subject: [PATCH 01/19] Branch: launch-handler --- launch_handler-explainer.md | 108 ++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 launch_handler-explainer.md diff --git a/launch_handler-explainer.md b/launch_handler-explainer.md new file mode 100644 index 0000000..a922d76 --- /dev/null +++ b/launch_handler-explainer.md @@ -0,0 +1,108 @@ +# Web App Launch Handling + +## Overview + +This document describes a new `launch_handler` manifest member that enables +web apps to customise their launch behaviour across mulitple launch triggers. + + +## Use Cases + +- Web apps that are designed to be used in a single window e.g. a music app. + +- Web app that capture and handle share target events and user navigations + in existing windows without invoking a navigation and losing existing state.\ + E.g. sharing an image to a chat web app could open a picker overlayed on top + of an existing conversation to select which contact to send it to . + +- Opening a productivity web app via a + [file handler](https://github.com/WICG/file-handling/blob/main/explainer.md) + causes an existing window that already had the file open to come into focus + instead of launching a duplicate window. + + +## Background + +There are several ways for a web app window to be opened: +- Operating system app list +- [File handling](https://github.com/WICG/file-handling/blob/main/explainer.md) +- [Share target](https://w3c.github.io/web-share-target/) +- [In scope link capturing](https://github.com/WICG/sw-launch/blob/master/declarative_link_capturing.md) +- [Shortcuts](https://www.w3.org/TR/appmanifest/#dfn-shortcuts) +- [Note taking](https://wicg.github.io/manifest-incubations/index.html#note_taking-member) +- [Protocol handling](https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/URLProtocolHandler/explainer.md) + +Web apps launched via these triggers will open in a new or existing app window +depending on the user agent platform. There is currently no mechanism for the +web app to configure this behaviour. + + +## Proposal + +1. Add a `launch_handler` member to the web app manifest specifying . + + Example manifest located at `https://example.com/manifest.webmanifest`: + ```json + { + "id": "", + "name": "Example", + "display": "standalone", + "start_url": "/index.html", + "scope_extensions": [ + {"origin": "*.example.com"}, + {"origin": "example.co.uk"}, + {"origin": "*.example.co.uk"} + ] + } + ``` + In this example the "Example" app is extending its app scope to all its + subdomains along with its `.co.uk` site and its subdomains. + + + +## Security Considerations + +### Declarative link capturing events + +Capturing user navigations via `"capture_links": "existing-client-event"` has +the potential for the web app to spoof its associated origins. Event link +capturing must not be supported for associated origins unless they specify +`"authorize": ["intercept-links"]` in their entry for the associated web app. +This opt-in is used as a signal of trust between the associated origin and the +web app. + + +## Related Proposals + +### [URL Handlers](https://github.com/WICG/pwa-url-handler/blob/main/explainer.md) + +The Scope Extensions proposal is intended to be a replacement for the +[URL Handlers](https://github.com/WICG/pwa-url-handler/blob/main/explainer.md) +proposal with the following changes: + - Re-orient the goal to be focused just on expanding the set of origins/URLs in + the web app's scope. Remove the goal of registering web apps as URL handlers + in the user's operating system. That behaviour will be covered by the + [Declarative Link Capturing](https://github.com/WICG/sw-launch/blob/main/declarative_link_capturing.md) + proposal instead. + - Rename the new manifest field from `url_handlers` to `scope_extensions` to + reflect the change in goals. + - Move the association file from "/web-app-origin-association.json" to + "/.well-known/web-app-origin-association.json". This better conforms + with [RFC 8615](https://datatracker.ietf.org/doc/html/rfc8615). + - Change the association file entries to be keyed on the web app identifier + rather than the web app's manifest URL. This aligns with the recent + [PWA Unique ID](https://github.com/philloooo/pwa-unique-id/blob/main/explainer.md) + proposal. + - Rename `"paths"` to `"include_paths"` in the association file entries. + - Add an "authorize" field to the association file entries for the associated + origin to provide explicit opt-in signals for security sensitive + capabilities. + +### [Declarative Link Capturing](https://github.com/WICG/sw-launch/blob/main/declarative_link_capturing.md) + +Scope extensions can be considered the first stage in the link capturing +pipeline. This proposal allows developers to control the set of user navigation +URLs that the web app is intended to capture. The +[Declarative Link Capturing](https://github.com/WICG/sw-launch/blob/main/declarative_link_capturing.md) +proposal allows developers to control the action that is taken once a user +navigation is captured e.g. open a new app context or navigate an existing one. \ No newline at end of file From af2d564d350c617117d18e0f49a3cd98cb38675e Mon Sep 17 00:00:00 2001 From: Alan Cutter Date: Tue, 6 Jul 2021 17:58:12 +1000 Subject: [PATCH 02/19] More update --- launch_handler-explainer.md | 139 +++++++++++++++++------------------- 1 file changed, 67 insertions(+), 72 deletions(-) diff --git a/launch_handler-explainer.md b/launch_handler-explainer.md index a922d76..5ae393a 100644 --- a/launch_handler-explainer.md +++ b/launch_handler-explainer.md @@ -11,20 +11,15 @@ web apps to customise their launch behaviour across mulitple launch triggers. - Web apps that are designed to be used in a single window e.g. a music app. - Web app that capture and handle share target events and user navigations - in existing windows without invoking a navigation and losing existing state.\ + in existing windows without invoking a navigation and losing existing state. E.g. sharing an image to a chat web app could open a picker overlayed on top - of an existing conversation to select which contact to send it to . - -- Opening a productivity web app via a - [file handler](https://github.com/WICG/file-handling/blob/main/explainer.md) - causes an existing window that already had the file open to come into focus - instead of launching a duplicate window. + of an existing conversation to select which contact to send it to. ## Background There are several ways for a web app window to be opened: -- Operating system app list +- Platform specific app launch surface - [File handling](https://github.com/WICG/file-handling/blob/main/explainer.md) - [Share target](https://w3c.github.io/web-share-target/) - [In scope link capturing](https://github.com/WICG/sw-launch/blob/master/declarative_link_capturing.md) @@ -39,70 +34,70 @@ web app to configure this behaviour. ## Proposal -1. Add a `launch_handler` member to the web app manifest specifying . - - Example manifest located at `https://example.com/manifest.webmanifest`: - ```json - { - "id": "", - "name": "Example", - "display": "standalone", - "start_url": "/index.html", - "scope_extensions": [ - {"origin": "*.example.com"}, - {"origin": "example.co.uk"}, - {"origin": "*.example.co.uk"} - ] - } - ``` - In this example the "Example" app is extending its app scope to all its - subdomains along with its `.co.uk` site and its subdomains. - - - -## Security Considerations - -### Declarative link capturing events - -Capturing user navigations via `"capture_links": "existing-client-event"` has -the potential for the web app to spoof its associated origins. Event link -capturing must not be supported for associated origins unless they specify -`"authorize": ["intercept-links"]` in their entry for the associated web app. -This opt-in is used as a signal of trust between the associated origin and the -web app. - - -## Related Proposals - -### [URL Handlers](https://github.com/WICG/pwa-url-handler/blob/main/explainer.md) - -The Scope Extensions proposal is intended to be a replacement for the -[URL Handlers](https://github.com/WICG/pwa-url-handler/blob/main/explainer.md) -proposal with the following changes: - - Re-orient the goal to be focused just on expanding the set of origins/URLs in - the web app's scope. Remove the goal of registering web apps as URL handlers - in the user's operating system. That behaviour will be covered by the - [Declarative Link Capturing](https://github.com/WICG/sw-launch/blob/main/declarative_link_capturing.md) - proposal instead. - - Rename the new manifest field from `url_handlers` to `scope_extensions` to - reflect the change in goals. - - Move the association file from "/web-app-origin-association.json" to - "/.well-known/web-app-origin-association.json". This better conforms - with [RFC 8615](https://datatracker.ietf.org/doc/html/rfc8615). - - Change the association file entries to be keyed on the web app identifier - rather than the web app's manifest URL. This aligns with the recent - [PWA Unique ID](https://github.com/philloooo/pwa-unique-id/blob/main/explainer.md) - proposal. - - Rename `"paths"` to `"include_paths"` in the association file entries. - - Add an "authorize" field to the association file entries for the associated - origin to provide explicit opt-in signals for security sensitive - capabilities. +- Add a `launch_handler` member to the web app manifest specifying the default + client selection and navigation behaviour for web app launches. + The shape of this member is as follows: + ```json + "launch_handler": { + "route_to_client": "new" | "existing", + "navigate_client": true | false + } + ``` + + Example manifest: + ```json + { + "name": "Example app", + "start_url": "/index.html", + "launch_handler": { + "route_to_client": "existing", + "navigate_client": false + } + } + ``` + + If unspecified then `launch_handler` defaults to + `{"route_to_client": "new", "navigate_client": true}`. + + Both `route_to_client` and `navigate_client` also accept a list of values, the + first valid value will be used. + +- Enqueue a [`LaunchParams`]( + https://github.com/WICG/file-handling/blob/main/explainer.md#launch) + object in the DOM Window's `launchQueue` of the chosen client for every web + app launch. + +- Add a `url` field to `LaunchParams` and set it to the URL being launched if + the chosen launch client is not navigated as part of the launch. + + +## Future extensions to this proposal + +- Add a service worker `launch` event that intercepts every web app launch. + The service worker can choose to override the value of `route_to_client`, + `navigate_client` and `LaunchParams`. + + Use case:\ + Opening a productivity web app via a + [file handler](https://github.com/WICG/file-handling/blob/main/explainer.md) + causes an existing window that already had the file open to come into focus + instead of launching a duplicate window. + +- Add a `new_client_url` member to the web app manifest. All new clients that + don't navigate to the launch URL will open `new_client_url` instead. + + If `new_client_url` is the default value `null` then behave as if it is set to + the value of `start_url`. + + Use case:\ + Web apps that have heavy `start_url` pages and want to avoid loading + unnecessary resources. + + +## Related proposals ### [Declarative Link Capturing](https://github.com/WICG/sw-launch/blob/main/declarative_link_capturing.md) -Scope extensions can be considered the first stage in the link capturing -pipeline. This proposal allows developers to control the set of user navigation -URLs that the web app is intended to capture. The -[Declarative Link Capturing](https://github.com/WICG/sw-launch/blob/main/declarative_link_capturing.md) -proposal allows developers to control the action that is taken once a user -navigation is captured e.g. open a new app context or navigate an existing one. \ No newline at end of file +`launch_handler` generalises the concept of `capture_links` into two core +primitive actions (launch client selection and navigation) and more explicitly +decouples them from the specific "link capturing" launch trigger. From 5c482d73d04524d02e51e838538e9715a88aa4bd Mon Sep 17 00:00:00 2001 From: Alan Cutter Date: Tue, 6 Jul 2021 17:58:38 +1000 Subject: [PATCH 03/19] No json syntax --- launch_handler-explainer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launch_handler-explainer.md b/launch_handler-explainer.md index 5ae393a..af477fb 100644 --- a/launch_handler-explainer.md +++ b/launch_handler-explainer.md @@ -37,7 +37,7 @@ web app to configure this behaviour. - Add a `launch_handler` member to the web app manifest specifying the default client selection and navigation behaviour for web app launches. The shape of this member is as follows: - ```json + ``` "launch_handler": { "route_to_client": "new" | "existing", "navigate_client": true | false From 52652da7b9707be5dea0b3a2b0413a1f8d254a8e Mon Sep 17 00:00:00 2001 From: Alan Cutter Date: Tue, 6 Jul 2021 18:10:20 +1000 Subject: [PATCH 04/19] sub launch_handler --- launch_handler-explainer.md | 60 +++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/launch_handler-explainer.md b/launch_handler-explainer.md index af477fb..ee3c33b 100644 --- a/launch_handler-explainer.md +++ b/launch_handler-explainer.md @@ -3,7 +3,8 @@ ## Overview This document describes a new `launch_handler` manifest member that enables -web apps to customise their launch behaviour across mulitple launch triggers. +web apps to customise their launch behaviour across all types of app launch +triggers. ## Use Cases @@ -39,12 +40,20 @@ web app to configure this behaviour. The shape of this member is as follows: ``` "launch_handler": { - "route_to_client": "new" | "existing", - "navigate_client": true | false + "route_to_client": null | "new" | "existing", + "navigate_client": null | true | false } ``` - Example manifest: + If unspecified then `launch_handler` defaults to + `{"route_to_client": null, "navigate_client": null}` whereby the behaviour + is up to the user agent. + + Both `route_to_client` and `navigate_client` also accept a list of values, the + first valid value will be used. + + Example manifest that choses to receive all app launches as LaunchQueue events + in existing windows: ```json { "name": "Example app", @@ -56,12 +65,6 @@ web app to configure this behaviour. } ``` - If unspecified then `launch_handler` defaults to - `{"route_to_client": "new", "navigate_client": true}`. - - Both `route_to_client` and `navigate_client` also accept a list of values, the - first valid value will be used. - - Enqueue a [`LaunchParams`]( https://github.com/WICG/file-handling/blob/main/explainer.md#launch) object in the DOM Window's `launchQueue` of the chosen client for every web @@ -70,15 +73,18 @@ web app to configure this behaviour. - Add a `url` field to `LaunchParams` and set it to the URL being launched if the chosen launch client is not navigated as part of the launch. + Other web app APIs that involve launching may extend the `LaunchParams` with + more data specific to the method of launching e.g. a [share target]( + https://w3c.github.io/web-share-target/) payload. + ## Future extensions to this proposal -- Add a service worker `launch` event that intercepts every web app launch. +- Add a service worker `"launch"` event that intercepts every web app launch. The service worker can choose to override the value of `route_to_client`, `navigate_client` and `LaunchParams`. - Use case:\ - Opening a productivity web app via a + **Use case:** Opening a productivity web app via a [file handler](https://github.com/WICG/file-handling/blob/main/explainer.md) causes an existing window that already had the file open to come into focus instead of launching a duplicate window. @@ -89,9 +95,31 @@ web app to configure this behaviour. If `new_client_url` is the default value `null` then behave as if it is set to the value of `start_url`. - Use case:\ - Web apps that have heavy `start_url` pages and want to avoid loading - unnecessary resources. + **Use case:** Web apps that have heavy `start_url` pages and want to avoid + loading unnecessary resources. + +- Add the `launch_handler` field to other launch methods to allow sites to + customise the launch behaviour for specfic launch methods. E.g.: + ```json + { + "name": "Example app", + "description": "This app will navigate existing clients unless it was launched via the share target API.", + "launch_handler": { + "route_to_client": "existing", + "navigate_client": true + }, + "share_target": { + "action": "share.html", + "params": { + "title": "name", + "text": "description", + "url": "link" + }, + "launch_handler": { + "navigate_client": false + } + } + ``` ## Related proposals From 1dcd45cbc1472b6b31d8754709d824f6d13d44aa Mon Sep 17 00:00:00 2001 From: Alan Cutter Date: Tue, 6 Jul 2021 18:14:57 +1000 Subject: [PATCH 05/19] relevancy --- launch_handler-explainer.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/launch_handler-explainer.md b/launch_handler-explainer.md index ee3c33b..c206ca4 100644 --- a/launch_handler-explainer.md +++ b/launch_handler-explainer.md @@ -67,8 +67,8 @@ web app to configure this behaviour. - Enqueue a [`LaunchParams`]( https://github.com/WICG/file-handling/blob/main/explainer.md#launch) - object in the DOM Window's `launchQueue` of the chosen client for every web - app launch. + object in the DOM Window's `launchQueue` of the chosen client **for every web + app launch**. - Add a `url` field to `LaunchParams` and set it to the URL being launched if the chosen launch client is not navigated as part of the launch. @@ -124,8 +124,17 @@ web app to configure this behaviour. ## Related proposals + ### [Declarative Link Capturing](https://github.com/WICG/sw-launch/blob/main/declarative_link_capturing.md) `launch_handler` generalises the concept of `capture_links` into two core primitive actions (launch client selection and navigation) and more explicitly decouples them from the specific "link capturing" launch trigger. + + +### [File Handling](https://github.com/WICG/file-handling/blob/main/explainer.md) + +This proposal takes the `LaunchQueue` and `LaunchParams` ideas from the File +Handling proposal and extends them slightly. Instead of enqueuing `LaunchParams` +for specific types of launches they will be enqueued for every type of web app +launch. \ No newline at end of file From 86a2c34090588c422e5a69692bbafc8f8080a728 Mon Sep 17 00:00:00 2001 From: Alan Cutter Date: Tue, 6 Jul 2021 18:17:20 +1000 Subject: [PATCH 06/19] Fix json --- launch_handler-explainer.md | 1 + 1 file changed, 1 insertion(+) diff --git a/launch_handler-explainer.md b/launch_handler-explainer.md index c206ca4..0b6db5d 100644 --- a/launch_handler-explainer.md +++ b/launch_handler-explainer.md @@ -119,6 +119,7 @@ web app to configure this behaviour. "navigate_client": false } } + } ``` From c943305fb3ca554613a40cfad9368c1f98e3896f Mon Sep 17 00:00:00 2001 From: Alan Cutter Date: Tue, 6 Jul 2021 18:19:52 +1000 Subject: [PATCH 07/19] Cut down words --- launch_handler-explainer.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/launch_handler-explainer.md b/launch_handler-explainer.md index 0b6db5d..0f3d065 100644 --- a/launch_handler-explainer.md +++ b/launch_handler-explainer.md @@ -13,8 +13,8 @@ triggers. - Web app that capture and handle share target events and user navigations in existing windows without invoking a navigation and losing existing state. - E.g. sharing an image to a chat web app could open a picker overlayed on top - of an existing conversation to select which contact to send it to. + E.g. sharing an image to a chat web app could open a contact picker overlayed + on top existing chat content. ## Background From bc073ba03932bf2e115a3439a004639dd8ca85ca Mon Sep 17 00:00:00 2001 From: Alan Cutter Date: Tue, 6 Jul 2021 18:20:33 +1000 Subject: [PATCH 08/19] ontopof --- launch_handler-explainer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launch_handler-explainer.md b/launch_handler-explainer.md index 0f3d065..751c34d 100644 --- a/launch_handler-explainer.md +++ b/launch_handler-explainer.md @@ -14,7 +14,7 @@ triggers. - Web app that capture and handle share target events and user navigations in existing windows without invoking a navigation and losing existing state. E.g. sharing an image to a chat web app could open a contact picker overlayed - on top existing chat content. + on top of existing chat content. ## Background From 9dd9ab9f6cbeb68f71f77fdf65574979599b80fa Mon Sep 17 00:00:00 2001 From: Alan Cutter Date: Tue, 6 Jul 2021 18:22:10 +1000 Subject: [PATCH 09/19] Minor words --- launch_handler-explainer.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/launch_handler-explainer.md b/launch_handler-explainer.md index 751c34d..ae7ea3c 100644 --- a/launch_handler-explainer.md +++ b/launch_handler-explainer.md @@ -20,13 +20,13 @@ triggers. ## Background There are several ways for a web app window to be opened: -- Platform specific app launch surface - [File handling](https://github.com/WICG/file-handling/blob/main/explainer.md) -- [Share target](https://w3c.github.io/web-share-target/) - [In scope link capturing](https://github.com/WICG/sw-launch/blob/master/declarative_link_capturing.md) -- [Shortcuts](https://www.w3.org/TR/appmanifest/#dfn-shortcuts) - [Note taking](https://wicg.github.io/manifest-incubations/index.html#note_taking-member) +- Platform specific app launch surface - [Protocol handling](https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/URLProtocolHandler/explainer.md) +- [Share target](https://w3c.github.io/web-share-target/) +- [Shortcuts](https://www.w3.org/TR/appmanifest/#dfn-shortcuts) Web apps launched via these triggers will open in a new or existing app window depending on the user agent platform. There is currently no mechanism for the @@ -52,8 +52,8 @@ web app to configure this behaviour. Both `route_to_client` and `navigate_client` also accept a list of values, the first valid value will be used. - Example manifest that choses to receive all app launches as LaunchQueue events - in existing windows: + Example manifest that choses to receive all app launches as events in existing + web app windows: ```json { "name": "Example app", From 8591a72cf64d820eb9ef8cc601394fe3cce6ce2a Mon Sep 17 00:00:00 2001 From: Alan Cutter Date: Wed, 7 Jul 2021 14:05:16 +1000 Subject: [PATCH 10/19] "route_to": "auto" --- launch_handler-explainer.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/launch_handler-explainer.md b/launch_handler-explainer.md index ae7ea3c..b2b362c 100644 --- a/launch_handler-explainer.md +++ b/launch_handler-explainer.md @@ -40,16 +40,16 @@ web app to configure this behaviour. The shape of this member is as follows: ``` "launch_handler": { - "route_to_client": null | "new" | "existing", - "navigate_client": null | true | false + "route_to": "auto" | "new" | "existing", + "navigate_client": "auto" | true | false } ``` If unspecified then `launch_handler` defaults to - `{"route_to_client": null, "navigate_client": null}` whereby the behaviour + `{"route_to": "auto", "navigate_client": "auto"}` whereby the behaviour is up to the user agent. - Both `route_to_client` and `navigate_client` also accept a list of values, the + Both `route_to` and `navigate_client` also accept a list of values, the first valid value will be used. Example manifest that choses to receive all app launches as events in existing @@ -59,7 +59,7 @@ web app to configure this behaviour. "name": "Example app", "start_url": "/index.html", "launch_handler": { - "route_to_client": "existing", + "route_to": "existing", "navigate_client": false } } @@ -81,7 +81,7 @@ web app to configure this behaviour. ## Future extensions to this proposal - Add a service worker `"launch"` event that intercepts every web app launch. - The service worker can choose to override the value of `route_to_client`, + The service worker can choose to override the value of `route_to`, `navigate_client` and `LaunchParams`. **Use case:** Opening a productivity web app via a @@ -92,7 +92,7 @@ web app to configure this behaviour. - Add a `new_client_url` member to the web app manifest. All new clients that don't navigate to the launch URL will open `new_client_url` instead. - If `new_client_url` is the default value `null` then behave as if it is set to + If `new_client_url` is the default value `"auto"` then behave as if it is set to the value of `start_url`. **Use case:** Web apps that have heavy `start_url` pages and want to avoid @@ -105,7 +105,7 @@ web app to configure this behaviour. "name": "Example app", "description": "This app will navigate existing clients unless it was launched via the share target API.", "launch_handler": { - "route_to_client": "existing", + "route_to": "existing", "navigate_client": true }, "share_target": { From 9f2fac6ec1fb47f9ee6f2d25c89170d6f876a888 Mon Sep 17 00:00:00 2001 From: Alan Cutter Date: Wed, 7 Jul 2021 19:04:06 +1000 Subject: [PATCH 11/19] Missing -client --- launch_handler-explainer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launch_handler-explainer.md b/launch_handler-explainer.md index b2b362c..e51905d 100644 --- a/launch_handler-explainer.md +++ b/launch_handler-explainer.md @@ -40,7 +40,7 @@ web app to configure this behaviour. The shape of this member is as follows: ``` "launch_handler": { - "route_to": "auto" | "new" | "existing", + "route_to": "auto" | "new-client" | "existing-client", "navigate_client": "auto" | true | false } ``` From be471cccd0f174fa139ef30722f85c3ea729daef Mon Sep 17 00:00:00 2001 From: Alan Cutter Date: Fri, 9 Jul 2021 17:15:01 +1000 Subject: [PATCH 12/19] Review changes --- launch_handler-explainer.md | 109 +++++++++++++++++++++++++++++------- 1 file changed, 88 insertions(+), 21 deletions(-) diff --git a/launch_handler-explainer.md b/launch_handler-explainer.md index e51905d..7b72340 100644 --- a/launch_handler-explainer.md +++ b/launch_handler-explainer.md @@ -1,36 +1,69 @@ # Web App Launch Handling +Authors: alancutter@, mgiuca@, dominickn@ +Last updated: 2021-07-09 + + ## Overview This document describes a new `launch_handler` manifest member that enables web apps to customise their launch behaviour across all types of app launch triggers. +We found that almost all "launch" use cases could be covered by a select few +fixed rules (for example, "choose an existing window in the same app, focus it, +and navigate it to the launched URL"). This `launch_handler` proposal enables +sites to specify a set of fixed rules without having to implement custom +[service worker `launch`][sw-launch-explainer] event logic, which should satisfy +most use cases, and simplify the implementation in browsers and sites. + ## Use Cases -- Web apps that are designed to be used in a single window e.g. a music app. +- Single-window web apps: a web app that prefers to only have a single instance + of itself open at any time, with new navigations focusing the existing + instance.\ + Sub-use cases include: + - Apps that generally only make sense to have one instance running + (e.g., a music player, a game). + - Apps that include multi-document management within a single instance + (e.g., an HTML-implemented tab strip, floating sub-windows like Gmail). + + +## Non-goals + +- Forcing a web app to only ever appear in a single client (e.g. blocking being + opening in a browser tab when open in an app window). +- Configuring whether link navigations into the scope of a web app launch the + web app (this is out of scope and may be handled by a future version of the + [Declarative Link Capturing][dlc-explainer] spec). +- Multi-document-instance web apps: a web app that opens documents in their own + instances but wishes to refocus an already open document instead of opening + duplicate instances for it. This would instead by handled by the [service + worker `launch` event][sw-launch-explainer]. -- Web app that capture and handle share target events and user navigations - in existing windows without invoking a navigation and losing existing state. - E.g. sharing an image to a chat web app could open a contact picker overlayed - on top of existing chat content. ## Background -There are several ways for a web app window to be opened: -- [File handling](https://github.com/WICG/file-handling/blob/main/explainer.md) -- [In scope link capturing](https://github.com/WICG/sw-launch/blob/master/declarative_link_capturing.md) -- [Note taking](https://wicg.github.io/manifest-incubations/index.html#note_taking-member) -- Platform specific app launch surface -- [Protocol handling](https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/URLProtocolHandler/explainer.md) -- [Share target](https://w3c.github.io/web-share-target/) -- [Shortcuts](https://www.w3.org/TR/appmanifest/#dfn-shortcuts) +- There are several ways for a web app window to be opened: + - [File handling](https://github.com/WICG/file-handling/blob/main/explainer.md) + - [In scope link capturing](https://github.com/WICG/sw-launch/blob/master/declarative_link_capturing.md) + - [Note taking](https://wicg.github.io/manifest-incubations/index.html#note_taking-member) + - Platform specific app launch surface + - [Protocol handling](https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/URLProtocolHandler/explainer.md) + - [Share target](https://w3c.github.io/web-share-target/) + - [Shortcuts](https://www.w3.org/TR/appmanifest/#dfn-shortcuts) + + Web apps launched via these triggers will open in a new or existing app window + depending on the user agent platform. There is currently no mechanism for the + web app to configure this behaviour. -Web apps launched via these triggers will open in a new or existing app window -depending on the user agent platform. There is currently no mechanism for the -web app to configure this behaviour. +- This is a refactor of the [Declarative Link Capturing][dlc-explainer] + explainer with a reduced behaviour scope. This does not prescribe link + capturing as a means of launching a web app, instead it describes how the + launch of a web app (via link capturing or any other means) may be configured + by the manifest and service worker. ## Proposal @@ -126,11 +159,34 @@ web app to configure this behaviour. ## Related proposals -### [Declarative Link Capturing](https://github.com/WICG/sw-launch/blob/main/declarative_link_capturing.md) +### [Service Worker launch event][sw-launch-explainer] + +This proposal is declarative alternative to the [service worker `launch`]( +sw-launch-explainer) proposal in WICG. It covers many of the same +use cases, but omits the more advanced use cases (specifically, the option to +choose which client to focus). + +Use of `launch_handler` in the manifest would provide a "default" launch +behaviour that the service worker `launch` event handler can choose to override. + -`launch_handler` generalises the concept of `capture_links` into two core -primitive actions (launch client selection and navigation) and more explicitly -decouples them from the specific "link capturing" launch trigger. +### [Declarative Link Capturing][dlc-explainer] + +This `launch_handler` proposal is intended to be a successor to the "launch" +components of DLC and decouple launch configuration from "link capturing" +behaviour. + +`launch_handler` generalises the concept of a launch into two core primitive +actions; launch client selection and navigation, and explicitly decouples them +from the "link capturing" launch trigger. + + +### [WICG: URL Handlers](https://github.com/WICG/pwa-url-handler/blob/master/explainer.md) + +Similarly to Declarative Link Capturing this `launch_handler` proposal refactors +out the "launch" component from the URL Handler proposal. `launch_handler` +behaviour is intended for being "invoked" by URL Handlers at the point in which +a web app has been chosen to handle an out-of-browser link navigation. ### [File Handling](https://github.com/WICG/file-handling/blob/main/explainer.md) @@ -138,4 +194,15 @@ decouples them from the specific "link capturing" launch trigger. This proposal takes the `LaunchQueue` and `LaunchParams` ideas from the File Handling proposal and extends them slightly. Instead of enqueuing `LaunchParams` for specific types of launches they will be enqueued for every type of web app -launch. \ No newline at end of file +launch. + + +### [Tabbed Application Mode](https://github.com/w3c/manifest/issues/737) + +This proposal is intended to work in tandem with tabbed mode web app windows. +The behaviour of `"route_to": "new-client"` with an already open tabbed window +is to open a new tab in that window. + + +[sw-launch-explainer]: https://github.com/WICG/sw-launch/blob/main/explainer.md +[dlc-explainer]: https://github.com/WICG/sw-launch/blob/main/declarative_link_capturing.md \ No newline at end of file From 95a200104a6ef125ef20614d3e93b3d606dc5a94 Mon Sep 17 00:00:00 2001 From: Alan Cutter Date: Fri, 9 Jul 2021 17:20:51 +1000 Subject: [PATCH 13/19] Forwards compat description --- launch_handler-explainer.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/launch_handler-explainer.md b/launch_handler-explainer.md index 7b72340..57acca4 100644 --- a/launch_handler-explainer.md +++ b/launch_handler-explainer.md @@ -83,7 +83,13 @@ most use cases, and simplify the implementation in browsers and sites. is up to the user agent. Both `route_to` and `navigate_client` also accept a list of values, the - first valid value will be used. + first valid value will be used. This is to allow new values to be added to + the spec without breaking backwards compatibility with old implementations by + using them.\ + For example if `"matching-url-client"` were added sites would specify + `"route_to": ["matching-url-client", "existing-client"]` to continue + to control the behaviour of older browsers that didn't support + `"matching-url-client"`. Example manifest that choses to receive all app launches as events in existing web app windows: From 68d829c59bd4a70aa0e70d3b372a03d483fdebc9 Mon Sep 17 00:00:00 2001 From: Alan Cutter Date: Fri, 9 Jul 2021 17:55:04 +1000 Subject: [PATCH 14/19] Add interfaces --- launch_handler-explainer.md | 153 +++++++++++++++++++++++++----------- 1 file changed, 105 insertions(+), 48 deletions(-) diff --git a/launch_handler-explainer.md b/launch_handler-explainer.md index 57acca4..9abbec3 100644 --- a/launch_handler-explainer.md +++ b/launch_handler-explainer.md @@ -18,7 +18,7 @@ sites to specify a set of fixed rules without having to implement custom most use cases, and simplify the implementation in browsers and sites. -## Use Cases +## Use cases - Single-window web apps: a web app that prefers to only have a single instance of itself open at any time, with new navigations focusing the existing @@ -68,53 +68,107 @@ most use cases, and simplify the implementation in browsers and sites. ## Proposal -- Add a `launch_handler` member to the web app manifest specifying the default - client selection and navigation behaviour for web app launches. - The shape of this member is as follows: - ``` - "launch_handler": { - "route_to": "auto" | "new-client" | "existing-client", - "navigate_client": "auto" | true | false - } - ``` - If unspecified then `launch_handler` defaults to - `{"route_to": "auto", "navigate_client": "auto"}` whereby the behaviour - is up to the user agent. - - Both `route_to` and `navigate_client` also accept a list of values, the - first valid value will be used. This is to allow new values to be added to - the spec without breaking backwards compatibility with old implementations by - using them.\ - For example if `"matching-url-client"` were added sites would specify - `"route_to": ["matching-url-client", "existing-client"]` to continue - to control the behaviour of older browsers that didn't support - `"matching-url-client"`. - - Example manifest that choses to receive all app launches as events in existing - web app windows: - ```json - { - "name": "Example app", - "start_url": "/index.html", - "launch_handler": { - "route_to": "existing", - "navigate_client": false - } - } - ``` +### `LaunchQueue` and `LaunchParams` interfaces + +Add two new interfaces; `LaunchParams` and `LaunchQueue`. + +Whenever a web app is launched (via any user action) a `LaunchParams` object +will be enqueued in a global `LaunchQueue` instance of the browsing context that +handled the launch. + +This functions similarly to an event listener but avoids the problem where +scripts may "miss" events if they're too slow to register their event listeners, +this problem is particularly pronounced for launch events as they occur +during the page's initialization. -- Enqueue a [`LaunchParams`]( - https://github.com/WICG/file-handling/blob/main/explainer.md#launch) - object in the DOM Window's `launchQueue` of the chosen client **for every web - app launch**. +``` +[Exposed=Window] interface LaunchParams { + readonly attribute DOMString? targetURL; +}; -- Add a `url` field to `LaunchParams` and set it to the URL being launched if - the chosen launch client is not navigated as part of the launch. +callback LaunchConsumer = any (LaunchParams params); - Other web app APIs that involve launching may extend the `LaunchParams` with - more data specific to the method of launching e.g. a [share target]( - https://w3c.github.io/web-share-target/) payload. +[Exposed=Window] interface LaunchQueue { + void setConsumer(LaunchConsumer consumer); +}; + +partial interface Window { + readonly attribute LaunchQueue launchQueue; +}; +``` + +Example usage for a single-window music player app: +```javascript +launchQueue.setConsumer(launchParams => { + const songID = extractSongId(launchParams.targetURL); + if (songID) { + playSong(songID); + } +}); +``` + +The `targetURL` member in `LaunchParams` will only be set if the launch did not +create a new browsing context or navigate an existing one. + +Other web app APIs that involve launching may extend `LaunchParams` with +additional members containing data specific to the method of launching e.g. a +[share target](https://w3c.github.io/web-share-target/) payload. + + +### `launch_handler` manifest member + +Add a `launch_handler` member to the web app manifest specifying the default +client selection and navigation behaviour for web app launches. +The shape of this member is as follows: +``` +"launch_handler": { + "route_to": "new-client" | "existing-client" | "auto", + "navigate_existing_client": "always" | "never", +} +``` + +If unspecified then `launch_handler` defaults to +`{"route_to": "auto", "navigate_existing_client": "always"}`. + +`route_to`: +- `new-client`: A new browsing context is created in a web app window to load + the web app at the launch's target URL. +- `existing-client`: The most recently interacted with browsing context in a web + app window is chosen to handle the launch. How the launch is handled depends + on `navigate_existing_client`. +- `auto`: The behaviour is up to the user agent to decide what works best for + the platform. E.g. mobile devices only support single clients and would use + `existing-client` while desktop devices support multiple windows and would use + `new-client` to avoid data loss. + +`navigate_existing_client`: +- `always`: existing browsing contexts chosen for launch will navigate the + browsing context to the launch's target URL. +- `never`: existing browsing contexts chosen for launch will not be navigated + and instead have the targetURL set in the enqueued `LaunchParams`. + +Both `route_to` and `navigate_client` also accept a list of values, the +first valid value will be used. This is to allow new values to be added to +the spec without breaking backwards compatibility with old implementations by +using them.\ +For example if `"matching-url-client"` were added sites would specify +`"route_to": ["matching-url-client", "existing-client"]` to continue +to control the behaviour of older browsers that didn't support +`"matching-url-client"`. + +Example manifest that choses to receive all app launches as events in existing +web app windows: +```json +{ + "name": "Example app", + "start_url": "/index.html", + "launch_handler": { + "route_to": "existing", + "navigate_existing_client": "never" + } +} +``` ## Future extensions to this proposal @@ -197,10 +251,13 @@ a web app has been chosen to handle an out-of-browser link navigation. ### [File Handling](https://github.com/WICG/file-handling/blob/main/explainer.md) -This proposal takes the `LaunchQueue` and `LaunchParams` ideas from the File -Handling proposal and extends them slightly. Instead of enqueuing `LaunchParams` -for specific types of launches they will be enqueued for every type of web app -launch. +This proposal takes `LaunchQueue` and `LaunchParams` from the File Handling +proposal with a few changes: +- Instead of enqueuing `LaunchParams` for specific types of launches they will + be enqueued for every type of web app launch. +- An optional targetURL field is added. +- The interface is explicitly intended to be extended by other launch related + specs to contain launch specific data e.g. file handles or share data. ### [Tabbed Application Mode](https://github.com/w3c/manifest/issues/737) From 9dbb193d02060a8bd075466d3369098c049da28f Mon Sep 17 00:00:00 2001 From: Alan Cutter Date: Fri, 9 Jul 2021 18:00:13 +1000 Subject: [PATCH 15/19] Tweaks --- launch_handler-explainer.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/launch_handler-explainer.md b/launch_handler-explainer.md index 9abbec3..2ab81ae 100644 --- a/launch_handler-explainer.md +++ b/launch_handler-explainer.md @@ -71,16 +71,19 @@ most use cases, and simplify the implementation in browsers and sites. ### `LaunchQueue` and `LaunchParams` interfaces -Add two new interfaces; `LaunchParams` and `LaunchQueue`. +Add two new interfaces; `LaunchParams` and `LaunchQueue`. Add a global instance +of `LaunchQueue` to the `window` object named `launchQueue`. -Whenever a web app is launched (via any user action) a `LaunchParams` object -will be enqueued in a global `LaunchQueue` instance of the browsing context that -handled the launch. +Whenever a web app is launched (via any launch trigger) a `LaunchParams` object +will be enqueued in a global `LaunchQueue` instance for the browsing context +that handled the launch. Scripts can provide a single `LaunchConsumer` function +to receive enqueued `LaunchParams`. This functions similarly to an event listener but avoids the problem where scripts may "miss" events if they're too slow to register their event listeners, this problem is particularly pronounced for launch events as they occur -during the page's initialization. +during the page's initialization. LaunchParams are buffered indefinitely until +they are consumed. ``` [Exposed=Window] interface LaunchParams { From 96d661586d8aac7d3ee4aeee4b26d4ebb3aac0a1 Mon Sep 17 00:00:00 2001 From: Alan Cutter Date: Fri, 9 Jul 2021 18:07:20 +1000 Subject: [PATCH 16/19] Update new_client_url --- launch_handler-explainer.md | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/launch_handler-explainer.md b/launch_handler-explainer.md index 2ab81ae..a40a637 100644 --- a/launch_handler-explainer.md +++ b/launch_handler-explainer.md @@ -174,25 +174,18 @@ web app windows: ``` -## Future extensions to this proposal +## Possible extensions to this proposal -- Add a service worker `"launch"` event that intercepts every web app launch. - The service worker can choose to override the value of `route_to`, - `navigate_client` and `LaunchParams`. - - **Use case:** Opening a productivity web app via a - [file handler](https://github.com/WICG/file-handling/blob/main/explainer.md) - causes an existing window that already had the file open to come into focus - instead of launching a duplicate window. - -- Add a `new_client_url` member to the web app manifest. All new clients that - don't navigate to the launch URL will open `new_client_url` instead. - - If `new_client_url` is the default value `"auto"` then behave as if it is set to - the value of `start_url`. - - **Use case:** Web apps that have heavy `start_url` pages and want to avoid - loading unnecessary resources. +- Add two members: + ``` + "launch_handler": { + "navigate_new_clients": "always" | "never", + "new_client_url": , + } + ``` + This allows web apps to intercept new client navigations and provide a + constant alternative URL to handle the enqueued `LaunchParams` with + `targetURL` set. - Add the `launch_handler` field to other launch methods to allow sites to customise the launch behaviour for specfic launch methods. E.g.: From ad3d23091b3d5ce14618d1844f81ac5f2adf3666 Mon Sep 17 00:00:00 2001 From: Alan Cutter Date: Fri, 9 Jul 2021 18:09:49 +1000 Subject: [PATCH 17/19] typos --- launch_handler-explainer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launch_handler-explainer.md b/launch_handler-explainer.md index a40a637..71a84ad 100644 --- a/launch_handler-explainer.md +++ b/launch_handler-explainer.md @@ -33,7 +33,7 @@ most use cases, and simplify the implementation in browsers and sites. ## Non-goals - Forcing a web app to only ever appear in a single client (e.g. blocking being - opening in a browser tab when open in an app window). + opened in a browser tab while already opened in an app window). - Configuring whether link navigations into the scope of a web app launch the web app (this is out of scope and may be handled by a future version of the [Declarative Link Capturing][dlc-explainer] spec). From 857d65439ba13d60a34c848011e597b97e942ebd Mon Sep 17 00:00:00 2001 From: Alan Cutter Date: Fri, 9 Jul 2021 18:31:35 +1000 Subject: [PATCH 18/19] Tweaks --- launch_handler-explainer.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/launch_handler-explainer.md b/launch_handler-explainer.md index 71a84ad..28e610a 100644 --- a/launch_handler-explainer.md +++ b/launch_handler-explainer.md @@ -75,14 +75,14 @@ Add two new interfaces; `LaunchParams` and `LaunchQueue`. Add a global instance of `LaunchQueue` to the `window` object named `launchQueue`. Whenever a web app is launched (via any launch trigger) a `LaunchParams` object -will be enqueued in a global `LaunchQueue` instance for the browsing context -that handled the launch. Scripts can provide a single `LaunchConsumer` function -to receive enqueued `LaunchParams`. +will be enqueued in the `launchQueue` global `LaunchQueue` instance for the +browsing context that handled the launch. Scripts can provide a single +`LaunchConsumer` function to receive enqueued `LaunchParams`. This functions similarly to an event listener but avoids the problem where scripts may "miss" events if they're too slow to register their event listeners, this problem is particularly pronounced for launch events as they occur -during the page's initialization. LaunchParams are buffered indefinitely until +during the page's initialization. `LaunchParams` are buffered indefinitely until they are consumed. ``` @@ -136,10 +136,11 @@ If unspecified then `launch_handler` defaults to `route_to`: - `new-client`: A new browsing context is created in a web app window to load - the web app at the launch's target URL. + the launch's target URL. - `existing-client`: The most recently interacted with browsing context in a web - app window is chosen to handle the launch. How the launch is handled depends - on `navigate_existing_client`. + app window for the app being launched is chosen to handle the launch. How the + launch is handled within that browsing context depends on + `navigate_existing_client`. - `auto`: The behaviour is up to the user agent to decide what works best for the platform. E.g. mobile devices only support single clients and would use `existing-client` while desktop devices support multiple windows and would use @@ -149,7 +150,8 @@ If unspecified then `launch_handler` defaults to - `always`: existing browsing contexts chosen for launch will navigate the browsing context to the launch's target URL. - `never`: existing browsing contexts chosen for launch will not be navigated - and instead have the targetURL set in the enqueued `LaunchParams`. + and instead have `targetURL` in the enqueued `LaunchParams` set to the + launch's target URL. Both `route_to` and `navigate_client` also accept a list of values, the first valid value will be used. This is to allow new values to be added to From 1d58fd218d13819834fd96b81b2428e42d2db8c3 Mon Sep 17 00:00:00 2001 From: Alan Cutter Date: Fri, 9 Jul 2021 18:37:01 +1000 Subject: [PATCH 19/19] addLaunchConsumer --- launch_handler-explainer.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/launch_handler-explainer.md b/launch_handler-explainer.md index 28e610a..a799e69 100644 --- a/launch_handler-explainer.md +++ b/launch_handler-explainer.md @@ -213,6 +213,20 @@ web app windows: } ``` +- Add `attribute readonly LaunchConsumer? consumer` to `LaunchQueue`. This will + allow sites to chain `LaunchConsumers` together more independently. + ```js + function addLaunchConsumer(launchConsumer) { + const existingLaunchConsumer = launchQueue.consumer; + launchQueue.setConsumer(launchParams => { + existingLaunchConsumer?.(launchParams); + launchConsumer(launchParams); + }); + } + ``` + Or maybe the `LaunchQueue` interface should be `addConsumer`/`removeConsumer` + like `addEventListener`/`removeEventListener` but with buffering. + ## Related proposals