Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(305)

Side by Side Diff: docs/interface_share.md

Issue 1963823003: Rewrite Share interface docs and split into two APIs. (Closed) Base URL: git@github.com:chromium/ballista.git@master
Patch Set: Rebrand as Web Share (not Ballista). Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « docs/explainer.md ('k') | docs/interface_share_target.md » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Ballista Share Interface 1 # Web Share Interface
2 2
3 **Date**: 2016-04-29 3 **Date**: 2016-05-30
4 4
5 This document is a rough spec (i.e., *not* a formal web standard draft) of the 5 This document is a rough spec (i.e., *not* a formal web standard draft) of the
6 Ballista one-directional API. To avoid complexity, we avoid discussing the 6 Web Share API. The basic Share API just sends share requests (with no capability
7 bidirectional parts of the Ballista project here. 7 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.
8 receive). For a follow-up plan to have websites receive share requests from the
9 system, or other websites, see the [Share Target
10 API](interface_share_target.md).
8 11
9 Examples of using the one-directional API for sharing can be seen in the 12 Examples of using the Share API for sharing can be seen in the
10 [explainer document](explainer.md). 13 [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.
11 14
12 ## Requester API 15 **Note**: The Web Share API is the first concrete proposal of the [Ballista
16 project](../README.md), which aims to explore website-to-website and
17 website-to-native interoperability.
13 18
14 The `navigator.actions` interface (available from both foreground pages and 19 ## navigator.share
15 workers) is where our API surface lives. 20
21 The `navigator.share` function (available from both foreground pages and
22 workers) is the main method of the interface:
16 23
17 ```WebIDL 24 ```WebIDL
18 partial interface Navigator { 25 partial interface Navigator {
19 readonly attribute Actions actions; 26 Promise<void> share(ShareData data);
20 }; 27 };
21 28
22 partial interface WorkerNavigator { 29 partial interface WorkerNavigator {
23 readonly attribute Actions actions; 30 Promise<void> share(ShareData data);
31 };
32
33 dictionary ShareData {
34 DOMString? title;
35 DOMString? text;
36 DOMString? url;
24 }; 37 };
25 ``` 38 ```
26 39
27 ### performAction 40 The `share` method takes one argument: the object that will be delivered to the
41 handler. It contains the data being shared between applications.
28 42
29 The `navigator.actions` interface provides the `performAction` method which 43 The `data` object may have any of (and should have at least one of) the
30 initiates a request. 44 following optional fields:
45
46 * `title` (string): The title of the document being shared. May be ignored by
47 the handler.
48 * `text` (string): Arbitrary text that forms the body of the message being
49 shared.
50 * `url` (string): A URL or URI referring to a resource being shared.
51
52 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.
53
54 `share` always shows some form of UI, to give the user a choice of application
55 and get their approval to invoke and send data to a potentially native
56 application (which carries a security risk). UX mocks are shown
57 [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
58
59 `share`'s promise is resolved if the user chooses a target application,
60 and that application accepts the data without error. The promise may be rejected
61 in the following cases (it is possible to distinguish between these four failure
62 modes, but not learn the identity of the chosen application):
63
64 * The share was invalid (e.g., inappropriate fields in the `data` parameter).
65 * There were no apps available to handle sharing.
66 * The user cancelled the picker dialog instead of picking an app.
67 * The data could not be delivered to the target app (e.g., the chosen app could
68 not be launched), or the target app explicitly rejected the share event.
69
70 ## navigator.canShare
71
72 `navigator` also provides a method for determining whether there are any
73 applications that can handle sharing:
31 74
32 ```WebIDL 75 ```WebIDL
33 interface Actions { 76 partial interface Navigator {
34 Promise<Action> performAction((ActionOptions or DOMString) options, 77 boolean canShare();
35 object data);
36 };
37
38 dictionary ActionOptions {
39 DOMString verb;
40 };
41
42 dictionary Action {};
43 ```
44
45 The `performAction` method takes two arguments:
46 * `options` provides metadata about the action which is used by the user agent
47 to decide how to behave (what apps to show, how the UI is presented, whether
48 to expect a response, etc). Currently just has `verb` (the only non-optional
49 field) but we will expand this with more options in the future. If this is a
50 string `x`, that is short-hand for `{verb: x}`.
51 * `data` is the object that will be delivered to the handler. It contains the
52 data being shared between applications. Its fields depend on the verb (see
53 below for details on the `share` verb).
54
55 `performAction` always shows some form of UI, to give the user a choice of
56 application and get their approval to invoke and send data to a potentially
57 native application (which carries a security risk). UX mocks are shown
58 [here](user_flow.md).
59
60 `performAction` returns (asynchronously, via a promise) an `Action` object. This
61 object currently contains no fields, but we will extend it later. It is not
62 possible for the requester to learn the identity of the chosen application.
63
64 `performAction`'s promise may be rejected in the following cases (it is possible
65 to distinguish between these four failure modes, but again, not learn the
66 identity of the chosen application):
67
68 * The action was invalid (e.g., an unknown verb or inappropriate fields for the
69 given verb).
70 * There were no apps available to handle that specific action.
71 * The user cancelled the action instead of picking an app.
72 * The data could not be delivered to the target app (e.g., service worker could
73 not start, had no event handler, or the chosen native app could not be
74 launched), or the target app explicitly rejected the action.
75
76 ### canPerformAction
77
78 `navigator.actions` also provides a method for determining whether there are any
79 applications that can handle a particular action:
80
81 ```WebIDL
82 partial interface Actions {
83 boolean canPerformAction((ActionOptions or DOMString) options);
84 }; 78 };
85 ``` 79 ```
86 80
87 Returns `true` if there are one or more applications that could handle the 81 Returns `true` if there are one or more applications that could handle a share
88 action described by `options` (i.e., if `options` was passed to `performAction`, 82 event (i.e., if `share` was called, would any applications be presented to the
89 would any applications be presented to the user?). May give false positives, but 83 user?). May give false positives, but not false negatives (on some systems, it
90 not false negatives (on some systems, it may not be possible to determine in 84 may not be possible to determine in advance whether any native applications
91 advance whether any native applications support the action, in which case 85 support sharing, in which case `canShare` should return `true`; `false` means
92 `canPerformAction` should return `true`; `false` means that `performAction` will 86 that `share` will definitely fail). This can be used by websites to hide or
93 definitely fail). This can be used by websites to hide or disable the sharing 87 disable the sharing UI, to avoid presenting a button that just fails when users
94 UI, to avoid presenting a button that just fails when users press it. 88 press it.
95 89
96 **TODO(mgiuca)**: This may have to be asynchronous, so that the implementation 90 **TODO(mgiuca)**: This may have to be asynchronous, so that the implementation
97 can query the file system without blocking. 91 can query the file system without blocking.
98 92
99 **For consideration**: `canPerformAction` may present a fingerprinting issue, by 93 ## Share handlers
100 providing several bits of entropy about the identity of the device. (For
101 example, an attacker may passively run `canPerformAction` on all available verbs
102 with many different options sets, and the set of resulting bits will in some way
103 reflect the set of web and native applications registered/installed on the
104 device.) I suspect this entropy is minimal as most devices of a given operating
105 system would have a similar set of capabilities, but it may allow identification
106 of, e.g., users with native editors of obscure MIME types. Further analysis is
107 warranted.
108 94
109 ### Verbs 95 The list of share targets or handlers can be populated from a variety of
96 sources, depending on the user agent and underlying OS:
110 97
111 The *verb* is a string that determines what handlers are available (handlers 98 * Built-in service (e.g., "copy to clipboard").
112 explicitly register for certain verbs), as well as what fields are expected in 99 * Native applications.
113 the `options` and `data` objects, and how the interaction will take place (e.g., 100 * Web applications registered using the [Web Share Target
114 whether it will be one-way or bidirectional). Each verb is its own 101 API](interface_share_target.md).
115 mini-protocol.
116 102
117 To avoid a) proliferation of overly specialized verbs, and b) mismatched 103 The user agent can support any or all of the above (for example, on some
118 expectations about what a particular verb means, we will limit the set of verbs 104 platforms, there is no system for native apps to receive share data; some user
119 to those defined in the standard. We will leave the set of verbs open for new 105 agents may not support the Share Target API).
120 additions in the future, but not allow individual handlers or requesters to
121 invent their own verbs ad-hoc. User agents are expected to reject actions with
122 unexpected verbs, and enforce that the correct options and data are supplied for
123 the given verb.
124 106
125 In this document, we define only a single verb, `"share"`, but we expect several 107 The user agent may either present its own picker UI and then forward the share
126 other verbs to be defined in the initial standard. 108 data to the chosen app, or simply forward the share data to the system's native
109 app picking system (e.g., Android, iOS and Windows 10 all [support this concept
110 natively](native.md)) and let the OS do the work.
127 111
128 ### Built-in and native app handlers (web-to-native) 112 When forwarding to a website using the Share Target API, the `ShareData` object
129 113 is simply cloned. When forwarding to a native app, the user agent should do its
130 The user agent may choose to provide handlers that do not correspond to 114 best to map the fields onto the equivalent concepts. For example, on Android,
131 registered web applications. When the user selects these "fake" handlers, the 115 when a share is sent to a native application, the user agent may create an
132 user agent itself performs the duties of the handler. This can include:
133
134 * Providing a built-in service (such as "copy to clipboard").
135 * Forwarding the action to the native app picking system (e.g., [Android
136 intents](http://developer.android.com/training/sharing/send.html), [iOS share
137 sheets](https://developer.apple.com/library/ios/documentation/UIKit/Reference/ UIActivityViewController_Class/index.html),
138 [Windows Share contracts](https://msdn.microsoft.com/en-us/windows/uwp/app-to- app/share-data)).
139 * Forwarding the action directy on to a native system application.
140
141 In any case, the user agent is responsible for marshalling data to/from the
142 required formats and generally ensuring that the built-in or native handler
143 behaves like a web handler.
144
145 ## Handler API
146
147 Handlers **must** have a registered [service
148 worker](https://www.w3.org/TR/service-workers/) and a [web app
149 manifest](https://www.w3.org/TR/appmanifest/).
150
151 ### App manifest
152
153 The first thing a handler needs to do is declare its action handling
154 capabilities in the app manifest:
155
156 ```WebIDL
157 partial dictionary Manifest {
158 ManifestAction[]? actions;
159 };
160
161 dictionary ManifestAction {
162 DOMString verb;
163 };
164 ```
165
166 The `"actions"` member of the manifest contains a list of objects, one per verb
167 the application can handle. For the share verb, there is no additional metadata
168 required, so the following is sufficient:
169
170 ```JSON
171 "actions": [
172 {
173 "verb": "share"
174 }
175 ]
176 ```
177
178 For more complex verbs, other metadata may be provided, such as which MIME types
179 will be accepted.
180
181 The declarative nature of the manifest allows web applications to be indexed by
182 their action handling capabilities, allowing search services that, say, find all
183 web applications that handle "share" actions.
184
185 Handlers declaring actions in their manifest will **not** be automatically
186 registered; the user must explicitly authorize the registration. How this takes
187 place is still under consideration (see [User
188 Flow](user_flow.md#registering-a-website-as-a-handler-on-mobile), but will
189 ultimately be at the discretion of the user agent (the user may be automatically
190 prompted, or may have to explicitly request registration).
191
192 **For consideration**: We may wish to provide a method for websites to
193 explicitly request to prompt the user for handler registration. This would
194 *only* allow sites to register for verbs they have declared in the manifest. For
195 now, we have omitted such a method from the design to keep control in the hands
196 of user agents. It is easier to add such a method later than remove it.
197
198 ### Event handlers
199
200 When the user picks a registered web app as the target of an action, the
201 handler's service worker starts up (if it is not already running), and a
202 `"handle"` event is fired at the `navigator.actions` object.
203
204 ```WebIDL
205 partial interface Actions {
206 attribute EventHandler onhandle;
207 };
208 Actions implements EventTarget;
209
210 interface HandleEvent : ExtendableEvent {
211 readonly attribute ActionOptions options;
212 readonly attribute object data;
213
214 void reject(DOMException error);
215 };
216 ```
217
218 The `onhandle` handler (with corresponding event type `"handle"`) takes a
219 `HandleEvent`. The `options` and `data` fields are clones of the `options` and
220 `data` parameters passed to the `performAction` method by the requester.
221
222 If the `reject` method is called, the action fails and the requester's promise
223 is rejected. This must be called within the lifetime of the event (either in the
224 event handler, or in the promise passed to the event's
225 [`waitUntil`](https://www.w3.org/TR/service-workers/#wait-until-method) method).
226 The action also fails if the promise passed to `waitUntil` is rejected. Once the
227 event completes without failing, the action automatically succeeds, and the
228 requester's promise is resolved.
229
230 For one-way actions (like `"share"`), the end of the event's lifetime marks the
231 end of the action, and there is no further communication in either direction.
232
233 The handler-side API is defined entirely within the service worker. If the
234 handler needs to provide UI (which should be the common case), the service
235 worker must create a foreground page and send the appropriate data between the
236 worker and foreground page, out of band. The `handle` event handler is [allowed
237 to show a
238 popup](https://html.spec.whatwg.org/multipage/browsers.html#allowed-to-show-a-po pup),
239 which means it can call the
240 [`clients.openWindow`](https://www.w3.org/TR/service-workers/#clients-openwindow -method)
241 method.
242
243 ### System-generated actions (native-to-web)
244
245 Actions do not need to come from web requesters. The user agent may trigger an
246 action from some external stimulus, such as the user opening a file, or choosing
247 a web app as the target of a system intent. As in the web-to-native case, the
248 user agent is responsible for simulating the requester side of the connection
249 and marshalling data into the correct format.
250
251 For example, the user agent may register web handlers into the operating
252 system's native application pickers. When the user picks a web handler, the user
253 agent creates an `options` and `data` object and invokes the web handler, as if
254 it had been triggered by a web requester.
255
256 ## The "share" verb
257
258 When an action is sent using the `"share"` verb, the following extra rules
259 apply:
260
261 * It must be a one-way action (no response after the initial promise completes).
262 * No additional `options` are recognised.
263 * The `data` object may have any of (and should have at least one of) the
264 following optional fields:
265 * `title` (string): The title of the document being shared. May be ignored by
266 the handler.
267 * `text` (string): Arbitrary text that forms the body of the message being
268 shared.
269 * `url` (string): A URL or URI referring to a resource being shared.
270
271 We may later expand this to allow image data or file blobs.
272
273 How the handler deals with the data object is at the handler's discretion, and
274 will generally depend on the type of app. Here are some suggestions:
275
276 * An email client might draft a new email, using `title` as the subject of an
277 email, with `text` and `url` concatenated together as the body.
278 * A social networking app might draft a new post, ignoring `title`, using `text`
279 as the body of the message and adding `url` as a link. If `text` is missing,
280 it might use `url` in the body as well. If `url` is missing, it might scan
281 `text` looking for a URL and add that as a link.
282 * A text messaging app might draft a new message, ignoring `title` and using
283 `text` and `url` concatenated together. It might truncate the text or replace
284 `url` with a short link to fit into the message size.
285
286 When a user agent is acting as a requester or handler on behalf of a native
287 system application, it must understand the above requirements and convert
288 to/from the appropriate system data structures. For example, on Android, when a
289 web requester is used to send a system intent to a native application, the user
290 agent may create an
291 [Intent](http://developer.android.com/reference/android/content/Intent.html) 116 [Intent](http://developer.android.com/reference/android/content/Intent.html)
292 object with `ACTION_SEND`, setting the `EXTRA_SUBJECT` to `title`. Since Android 117 object with `ACTION_SEND`, setting the `EXTRA_SUBJECT` to `title`. Since Android
293 intents do not have a URL field, `EXTRA_TEXT` would be set to `text` and `url` 118 intents do not have a URL field, `EXTRA_TEXT` would be set to `text` and `url`
294 concatenated together. 119 concatenated together.
OLDNEW
« no previous file with comments | « docs/explainer.md ('k') | docs/interface_share_target.md » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698