Index: docs/interface_share.md |
diff --git a/docs/interface_share.md b/docs/interface_share.md |
index 619336ee34bab4b7e327ed454c4389cec8b6121e..b63203c3073fe988838cb600f183774934f9f003 100644 |
--- a/docs/interface_share.md |
+++ b/docs/interface_share.md |
@@ -1,293 +1,118 @@ |
-# Ballista Share Interface |
+# Web Share Interface |
-**Date**: 2016-04-29 |
+**Date**: 2016-05-30 |
This document is a rough spec (i.e., *not* a formal web standard draft) of the |
-Ballista one-directional API. To avoid complexity, we avoid discussing the |
-bidirectional parts of the Ballista project here. |
+Web Share API. The basic Share API just sends share requests (with no capability |
+for a website to receive share requests; only native system services can |
benwells
2016/06/01 00:48:33
I think the statement 'only native system services
Matt Giuca
2016/06/01 01:01:13
Done.
|
+receive). For a follow-up plan to have websites receive share requests from the |
+system, or other websites, see the [Share Target |
+API](interface_share_target.md). |
-Examples of using the one-directional API for sharing can be seen in the |
+Examples of using the Share API for sharing can be seen in the |
[explainer document](explainer.md). |
benwells
2016/06/01 00:48:33
Can we move these into this document? This API pro
Matt Giuca
2016/06/01 01:01:13
Are you saying the explainer and interface doc sho
benwells
2016/06/01 01:28:11
I mean that this needs to end up in a repository j
Matt Giuca
2016/06/01 01:31:57
Oh OK, gotcha. Yes, that refactoring is the subjec
benwells
2016/06/01 01:47:53
Acknowledged.
|
-## Requester API |
+**Note**: The Web Share API is the first concrete proposal of the [Ballista |
+project](../README.md), which aims to explore website-to-website and |
+website-to-native interoperability. |
-The `navigator.actions` interface (available from both foreground pages and |
-workers) is where our API surface lives. |
+## navigator.share |
+ |
+The `navigator.share` function (available from both foreground pages and |
+workers) is the main method of the interface: |
```WebIDL |
partial interface Navigator { |
- readonly attribute Actions actions; |
+ Promise<void> share(ShareData data); |
}; |
partial interface WorkerNavigator { |
- readonly attribute Actions actions; |
+ Promise<void> share(ShareData data); |
}; |
-``` |
- |
-### performAction |
- |
-The `navigator.actions` interface provides the `performAction` method which |
-initiates a request. |
-```WebIDL |
-interface Actions { |
- Promise<Action> performAction((ActionOptions or DOMString) options, |
- object data); |
+dictionary ShareData { |
+ DOMString? title; |
+ DOMString? text; |
+ DOMString? url; |
}; |
+``` |
-dictionary ActionOptions { |
- DOMString verb; |
-}; |
+The `share` method takes one argument: the object that will be delivered to the |
+handler. It contains the data being shared between applications. |
-dictionary Action {}; |
-``` |
+The `data` object may have any of (and should have at least one of) the |
+following optional fields: |
-The `performAction` method takes two arguments: |
-* `options` provides metadata about the action which is used by the user agent |
- to decide how to behave (what apps to show, how the UI is presented, whether |
- to expect a response, etc). Currently just has `verb` (the only non-optional |
- field) but we will expand this with more options in the future. If this is a |
- string `x`, that is short-hand for `{verb: x}`. |
-* `data` is the object that will be delivered to the handler. It contains the |
- data being shared between applications. Its fields depend on the verb (see |
- below for details on the `share` verb). |
+* `title` (string): The title of the document being shared. May be ignored by |
+ the handler. |
+* `text` (string): Arbitrary text that forms the body of the message being |
+ shared. |
+* `url` (string): A URL or URI referring to a resource being shared. |
-`performAction` always shows some form of UI, to give the user a choice of |
-application and get their approval to invoke and send data to a potentially |
-native application (which carries a security risk). UX mocks are shown |
-[here](user_flow.md). |
+We may later expand this to allow image data or file blobs. |
benwells
2016/06/01 00:48:33
Should this be a TODO, or at least more definite (
Matt Giuca
2016/06/01 01:01:12
Done.
|
-`performAction` returns (asynchronously, via a promise) an `Action` object. This |
-object currently contains no fields, but we will extend it later. It is not |
-possible for the requester to learn the identity of the chosen application. |
+`share` always shows some form of UI, to give the user a choice of application |
+and get their approval to invoke and send data to a potentially native |
+application (which carries a security risk). UX mocks are shown |
+[here](user_flow.md). |
benwells
2016/06/01 00:48:33
Again, these should be moved into this document to
Matt Giuca
2016/06/01 01:01:12
The user_flow mocks are being moved (in the follow
|
-`performAction`'s promise may be rejected in the following cases (it is possible |
-to distinguish between these four failure modes, but again, not learn the |
-identity of the chosen application): |
+`share`'s promise is resolved if the user chooses a target application, |
+and that application accepts the data without error. The promise may be rejected |
+in the following cases (it is possible to distinguish between these four failure |
+modes, but not learn the identity of the chosen application): |
-* The action was invalid (e.g., an unknown verb or inappropriate fields for the |
- given verb). |
-* There were no apps available to handle that specific action. |
-* The user cancelled the action instead of picking an app. |
-* The data could not be delivered to the target app (e.g., service worker could |
- not start, had no event handler, or the chosen native app could not be |
- launched), or the target app explicitly rejected the action. |
+* The share was invalid (e.g., inappropriate fields in the `data` parameter). |
+* There were no apps available to handle sharing. |
+* The user cancelled the picker dialog instead of picking an app. |
+* The data could not be delivered to the target app (e.g., the chosen app could |
+ not be launched), or the target app explicitly rejected the share event. |
-### canPerformAction |
+## navigator.canShare |
-`navigator.actions` also provides a method for determining whether there are any |
-applications that can handle a particular action: |
+`navigator` also provides a method for determining whether there are any |
+applications that can handle sharing: |
```WebIDL |
-partial interface Actions { |
- boolean canPerformAction((ActionOptions or DOMString) options); |
+partial interface Navigator { |
+ boolean canShare(); |
}; |
``` |
-Returns `true` if there are one or more applications that could handle the |
-action described by `options` (i.e., if `options` was passed to `performAction`, |
-would any applications be presented to the user?). May give false positives, but |
-not false negatives (on some systems, it may not be possible to determine in |
-advance whether any native applications support the action, in which case |
-`canPerformAction` should return `true`; `false` means that `performAction` will |
-definitely fail). This can be used by websites to hide or disable the sharing |
-UI, to avoid presenting a button that just fails when users press it. |
+Returns `true` if there are one or more applications that could handle a share |
+event (i.e., if `share` was called, would any applications be presented to the |
+user?). May give false positives, but not false negatives (on some systems, it |
+may not be possible to determine in advance whether any native applications |
+support sharing, in which case `canShare` should return `true`; `false` means |
+that `share` will definitely fail). This can be used by websites to hide or |
+disable the sharing UI, to avoid presenting a button that just fails when users |
+press it. |
**TODO(mgiuca)**: This may have to be asynchronous, so that the implementation |
can query the file system without blocking. |
-**For consideration**: `canPerformAction` may present a fingerprinting issue, by |
-providing several bits of entropy about the identity of the device. (For |
-example, an attacker may passively run `canPerformAction` on all available verbs |
-with many different options sets, and the set of resulting bits will in some way |
-reflect the set of web and native applications registered/installed on the |
-device.) I suspect this entropy is minimal as most devices of a given operating |
-system would have a similar set of capabilities, but it may allow identification |
-of, e.g., users with native editors of obscure MIME types. Further analysis is |
-warranted. |
- |
-### Verbs |
- |
-The *verb* is a string that determines what handlers are available (handlers |
-explicitly register for certain verbs), as well as what fields are expected in |
-the `options` and `data` objects, and how the interaction will take place (e.g., |
-whether it will be one-way or bidirectional). Each verb is its own |
-mini-protocol. |
- |
-To avoid a) proliferation of overly specialized verbs, and b) mismatched |
-expectations about what a particular verb means, we will limit the set of verbs |
-to those defined in the standard. We will leave the set of verbs open for new |
-additions in the future, but not allow individual handlers or requesters to |
-invent their own verbs ad-hoc. User agents are expected to reject actions with |
-unexpected verbs, and enforce that the correct options and data are supplied for |
-the given verb. |
- |
-In this document, we define only a single verb, `"share"`, but we expect several |
-other verbs to be defined in the initial standard. |
- |
-### Built-in and native app handlers (web-to-native) |
- |
-The user agent may choose to provide handlers that do not correspond to |
-registered web applications. When the user selects these "fake" handlers, the |
-user agent itself performs the duties of the handler. This can include: |
- |
-* Providing a built-in service (such as "copy to clipboard"). |
-* Forwarding the action to the native app picking system (e.g., [Android |
- intents](http://developer.android.com/training/sharing/send.html), [iOS share |
- sheets](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIActivityViewController_Class/index.html), |
- [Windows Share contracts](https://msdn.microsoft.com/en-us/windows/uwp/app-to-app/share-data)). |
-* Forwarding the action directy on to a native system application. |
- |
-In any case, the user agent is responsible for marshalling data to/from the |
-required formats and generally ensuring that the built-in or native handler |
-behaves like a web handler. |
- |
-## Handler API |
- |
-Handlers **must** have a registered [service |
-worker](https://www.w3.org/TR/service-workers/) and a [web app |
-manifest](https://www.w3.org/TR/appmanifest/). |
- |
-### App manifest |
- |
-The first thing a handler needs to do is declare its action handling |
-capabilities in the app manifest: |
- |
-```WebIDL |
-partial dictionary Manifest { |
- ManifestAction[]? actions; |
-}; |
- |
-dictionary ManifestAction { |
- DOMString verb; |
-}; |
-``` |
- |
-The `"actions"` member of the manifest contains a list of objects, one per verb |
-the application can handle. For the share verb, there is no additional metadata |
-required, so the following is sufficient: |
- |
-```JSON |
-"actions": [ |
- { |
- "verb": "share" |
- } |
-] |
-``` |
- |
-For more complex verbs, other metadata may be provided, such as which MIME types |
-will be accepted. |
- |
-The declarative nature of the manifest allows web applications to be indexed by |
-their action handling capabilities, allowing search services that, say, find all |
-web applications that handle "share" actions. |
- |
-Handlers declaring actions in their manifest will **not** be automatically |
-registered; the user must explicitly authorize the registration. How this takes |
-place is still under consideration (see [User |
-Flow](user_flow.md#registering-a-website-as-a-handler-on-mobile), but will |
-ultimately be at the discretion of the user agent (the user may be automatically |
-prompted, or may have to explicitly request registration). |
- |
-**For consideration**: We may wish to provide a method for websites to |
-explicitly request to prompt the user for handler registration. This would |
-*only* allow sites to register for verbs they have declared in the manifest. For |
-now, we have omitted such a method from the design to keep control in the hands |
-of user agents. It is easier to add such a method later than remove it. |
- |
-### Event handlers |
- |
-When the user picks a registered web app as the target of an action, the |
-handler's service worker starts up (if it is not already running), and a |
-`"handle"` event is fired at the `navigator.actions` object. |
- |
-```WebIDL |
-partial interface Actions { |
- attribute EventHandler onhandle; |
-}; |
-Actions implements EventTarget; |
+## Share handlers |
-interface HandleEvent : ExtendableEvent { |
- readonly attribute ActionOptions options; |
- readonly attribute object data; |
+The list of share targets or handlers can be populated from a variety of |
+sources, depending on the user agent and underlying OS: |
- void reject(DOMException error); |
-}; |
-``` |
- |
-The `onhandle` handler (with corresponding event type `"handle"`) takes a |
-`HandleEvent`. The `options` and `data` fields are clones of the `options` and |
-`data` parameters passed to the `performAction` method by the requester. |
- |
-If the `reject` method is called, the action fails and the requester's promise |
-is rejected. This must be called within the lifetime of the event (either in the |
-event handler, or in the promise passed to the event's |
-[`waitUntil`](https://www.w3.org/TR/service-workers/#wait-until-method) method). |
-The action also fails if the promise passed to `waitUntil` is rejected. Once the |
-event completes without failing, the action automatically succeeds, and the |
-requester's promise is resolved. |
- |
-For one-way actions (like `"share"`), the end of the event's lifetime marks the |
-end of the action, and there is no further communication in either direction. |
- |
-The handler-side API is defined entirely within the service worker. If the |
-handler needs to provide UI (which should be the common case), the service |
-worker must create a foreground page and send the appropriate data between the |
-worker and foreground page, out of band. The `handle` event handler is [allowed |
-to show a |
-popup](https://html.spec.whatwg.org/multipage/browsers.html#allowed-to-show-a-popup), |
-which means it can call the |
-[`clients.openWindow`](https://www.w3.org/TR/service-workers/#clients-openwindow-method) |
-method. |
- |
-### System-generated actions (native-to-web) |
- |
-Actions do not need to come from web requesters. The user agent may trigger an |
-action from some external stimulus, such as the user opening a file, or choosing |
-a web app as the target of a system intent. As in the web-to-native case, the |
-user agent is responsible for simulating the requester side of the connection |
-and marshalling data into the correct format. |
- |
-For example, the user agent may register web handlers into the operating |
-system's native application pickers. When the user picks a web handler, the user |
-agent creates an `options` and `data` object and invokes the web handler, as if |
-it had been triggered by a web requester. |
- |
-## The "share" verb |
- |
-When an action is sent using the `"share"` verb, the following extra rules |
-apply: |
- |
-* It must be a one-way action (no response after the initial promise completes). |
-* No additional `options` are recognised. |
-* The `data` object may have any of (and should have at least one of) the |
- following optional fields: |
- * `title` (string): The title of the document being shared. May be ignored by |
- the handler. |
- * `text` (string): Arbitrary text that forms the body of the message being |
- shared. |
- * `url` (string): A URL or URI referring to a resource being shared. |
- |
-We may later expand this to allow image data or file blobs. |
+* Built-in service (e.g., "copy to clipboard"). |
+* Native applications. |
+* Web applications registered using the [Web Share Target |
+ API](interface_share_target.md). |
-How the handler deals with the data object is at the handler's discretion, and |
-will generally depend on the type of app. Here are some suggestions: |
+The user agent can support any or all of the above (for example, on some |
+platforms, there is no system for native apps to receive share data; some user |
+agents may not support the Share Target API). |
-* An email client might draft a new email, using `title` as the subject of an |
- email, with `text` and `url` concatenated together as the body. |
-* A social networking app might draft a new post, ignoring `title`, using `text` |
- as the body of the message and adding `url` as a link. If `text` is missing, |
- it might use `url` in the body as well. If `url` is missing, it might scan |
- `text` looking for a URL and add that as a link. |
-* A text messaging app might draft a new message, ignoring `title` and using |
- `text` and `url` concatenated together. It might truncate the text or replace |
- `url` with a short link to fit into the message size. |
+The user agent may either present its own picker UI and then forward the share |
+data to the chosen app, or simply forward the share data to the system's native |
+app picking system (e.g., Android, iOS and Windows 10 all [support this concept |
+natively](native.md)) and let the OS do the work. |
-When a user agent is acting as a requester or handler on behalf of a native |
-system application, it must understand the above requirements and convert |
-to/from the appropriate system data structures. For example, on Android, when a |
-web requester is used to send a system intent to a native application, the user |
-agent may create an |
+When forwarding to a website using the Share Target API, the `ShareData` object |
+is simply cloned. When forwarding to a native app, the user agent should do its |
+best to map the fields onto the equivalent concepts. For example, on Android, |
+when a share is sent to a native application, the user agent may create an |
[Intent](http://developer.android.com/reference/android/content/Intent.html) |
object with `ACTION_SEND`, setting the `EXTRA_SUBJECT` to `title`. Since Android |
intents do not have a URL field, `EXTRA_TEXT` would be set to `text` and `url` |