Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark and document use rules apply.
This specification defines a service discovery and light-weight RPC mechanism for web apps called Web Intents.
This document defines DOM interfaces and markup used by client and service pages to create, receive, and reply to Web Intents messages, and the procedures the User Agent carries out to facilitate that process.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This document was published by the Web Applications (WebApps) Working Group as an Editor's Draft. If you wish to make comments regarding this document, please send them to public-web-intents@w3.org (subscribe, archives). All feedback is welcome.
Publication as an Editor's Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
Web Intents enable rich integration between web applications. Increasingly, services available on the web have a need to pass rich data back and forth as they do their jobs. Web Intents facilitate this interchange while maintaining the kind of loose coupling and open architecture that has proven so advantageous for the web. They exist purely client-side, mediated through the User Agent, allowing the user a great degree of control over the security and privacy of the exchanged data.
An Intent is an action to be performed by a service. It consists of an "action" string which tells the service what kind of activity the user expects to be performed (i.e. "share" or "edit"), a "type" string which specifies the data payload the service should expect, and the data payload itself.
A client requests an Intent be handled, the User Agent allows the user to select which service to use, and the service performs the action of the Intent, possibly using data passed as input in the Intent. The service may return data as output to the client.
Web Intents provides a declarative syntax that allows services to list the Intents they handle. Using this method, pages mark up what actions they can handle what data types they expect.
Suppose there is a photo hosting application. This application allows a user to select images to be shared, edit those images, and then share them with friends. The application is built around making photos available to users, but has no built-in editor or sharing interface. But beside each photo, it can place an Edit button, with this kind of accompanying code:
document.getElementById('edit-photo').onclick = function() { var intent = new Intent("http://webintents.org/edit", "text/uri-list;type=image/jpeg", getImageDataURI(...)); navigator.startActivity(intent, imageEdited); }); function imageEdited(data) { document.getElementById('image').src = data; }
This assumes an image editor exists which can consume images specified as URIs (including data URIs), and produces a result in the same format. For instance, one such editor might be a meme-maker—an application allowing the user to place humorous messages on top of pictures they take.
Now that a picture has been selected and meme text added, the user undoubtedly wants to share the result with friends. Again, the photo hosting application may not have built-in sharing capabilities, but by adding a "share" button near images, and with this kind of accompany code, it can accomplish this integration:
document.getElementById('share-photo').onclick = function() { var intent = new Intent("http://webintents.org/share", "text/uri-list;type=image/jpeg", getPublicURIForImage(...)); navigator.startActivity(intent); });
Note that with this integration, other more high-minded services can be selected by the user as well. Instead of using the service to add funny captions, the user can utilize a sophisticated photo editing application to adjust exposure, remove red-eye, or do any number of other transformations on the image. The user can have many such tools registered, and choose any of that set to use at any given time. The photo hosting application isn't controlling which such application any given user uses, it is loosely coupled with such appliations by providing the data necessary for them to carry out their task and controls allowing the user to launch these activities on the data.
On the service page, it needs to register itself as a service, and handle the incoming intent data, possibly producing a response. That is done with this kind of code:
<html> <head> <title>Image Meme Editor</title> </head> <body> <intent action="http://webintents.org/edit" type="text/uri-list;type=image/*,image/*"></intent> <script> window.onload = function() { if (window.intent) { setImageContentURI(window.intent.data); } } document.getElementById('save-button').onclick = function() { window.intent.postReply(getImageDataURI(...)); } </script>
The assumed pieces here are functions which deal with the application's image display, for instance putting the image into a canvas and taking it back out again as a data URI.
An Intent is an action with accompanying data, which is to be performed by a Service of the user's choosing.
A Client is a web page which creates an intent and invokes it.
A Service is a web page which can handle a Web Intent, possibly returning a piece of data to the calling Client page.
Registration is how a Service page informs the User Agent that it is capable of handling Intents.
Invocation refers to the API by which a Client page dispatches an intent for handling.
Selection is the mechanism in which the User Agent decides which service will handle a particular intent.
Delivery is the means by which the User Agent hands intent data to a Service page for handling.
Response is the means in which the Service can respond to an Intent by passing data back through the User Agent to the Client page.
The client requests a specific intent handler and optionally sends in a callback to receive data from the service. The browser mediates the service selection by enumerating the list of registered services that match the requested intent action and type. The user is then able to select which service should handle the intent.
[Constructor(in string action, in string type, in any data)]
interface Intent {
readonly attribute DOMString action;
readonly attribute DOMString type;
readonly attribute any data;
void postResult (any data);
void postFailure (any data);
};
action
of type DOMString, readonlydata
of type any, readonlytype
of type DOMString, readonlypostFailure
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
data | any | ✘ | ✘ |
void
postResult
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
data | any | ✘ | ✘ |
void
The client invokes an intent by constructing an object as above and invoking
a navigator.startActivity
function on it. The callbacks are invoked when
the intent has been handled.
[NoInterfaceObject]
interface Intents {
void startActivity (Intent
intent, optional onSuccess, optional onFailure);
};
startActivity
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
intent |
| ✘ | ✘ | |
onSuccess |
| ✘ | ✔ | |
onFailure |
| ✘ | ✔ |
void
The invocation API is implemented by the window.navigator
object.
Navigator implements Intents
;
When the user agent loads a service page to handle an intent invocation, it
will place a window.intent
object in the scope of the page.
[NoInterfaceObject]
interface IntentProvider {
readonly attribute Intent
intent;
};
intent
of type Intent
, readonlyDOMWindow implements IntentProvider
;
All instances of the DOMWindow
type are defined to also implement the IntentProvider
interface.
This object will only be made available to service pages when they are
loaded in the context of an intent invocation. In other situations, the User
Agent must not make DOMWindow
implement
IntentProvider
.
The window.intent
object must be made available across
same-origin redirects of the service page. It must not be available if
redirects cross a same-origin boundary.
So the following redirect sequence
will work: http://example.com/service to http://example.com/login back to
http://example.com/service. In this case, the window.intent
data would be available to all three page loads.
This will also work: http://example.com/service to
http://example.com/newservice. In this sequence, the window.intent
data is available to both pages.
In this sequence, the window.intent
is only available to
example.com pages: http://example.com/service to http://login.example.com
and back to http://example.com/service. The intent data is not provided to
http://login.example.com
In other words, in the browsing context in which the intent is originally delivered, the intent data must be available to pages in a redirect sequence when they are in the same origin as that to which it was originally delivered, but must not be available to any other pages. If the user navigates to a different URL, even within the same origin, the intent data must not be made available.
Service pages declaratively mark themselves as providing handling functionality for particular intent actions and types. A User Agent must not deliver an intent to a page which is not described in its metadata describing what intents it can handle. The algorithm for matching intents is that the action string provided in invocation and registration must match exactly, and the type strings must match exactly except for possible [RFC2046] MIME subtype wildcards.
<!ENTITY % Disposition "{window|inline}"> <!ELEMENT INTENT - O EMPTY -- a Web Intents registration → <!ATTLIST INTENT action %URI; #required -- URI specifying action -- type %ContentTypes,%URI; #required -- advisory content type -- href %URI; #IMPLIED -- URI for linked resource -- title %i18n; #IMPLIED -- service title -- disposition %Disposition "window" -- where the service is created -- >
The dispositon
attribute allows a service to choose which
context to be opened in. The User Agent must not allow the client any
ability to change the disposition. The window
disposition means
that the service is opened in a new tab or window context. The
inline
disposition means that the User Agent should open the
service in a context directly related to the client page context in an
overlappable way. The User Agent must not allow this UI surface to be
under the control of the client page.
The User Agent should discard any registration markup which is not same-origin.
When the User Agent loads a page with registration markup, it should allow the user to configure that page as a web intents service. The details of this process is left up to the User Agent. The model is that the page advises of the ability to handle intents, and the User Agent may remember that, but
The User Agent must not allow web pages the ability to discover passively which services the user has configured to handler particular intents, or any intents, whether by enumeration or exact query. There may be mechanisms for the user to actively grant this information to web pages, but it must not be made available passively.
The User Agent may provide additional mechanisms for web intents service registration. For example, by external applications, through a separate API, as a result of a permissions bundle in a downloaded web application, or pre-bundled.
For intents invoked by client web applications, the User Agent must require that such invocations be directly caused by a user gesture. User Agents may also dispatch intents invoked through other mechanisms. For example, hardware events (i.e. plugging in a USB storage device) or software events (i.e. downloading a file).
When a client page invokes an intent, the User Agent dispatches it to a chosen service. The details of this process are left up to the User Agent. The User Agent may dispatch intents to web application service pages, helper applications, proxy them through connections to other hardware, etc. In general, though, the User Agent must provide a way for the user to configure which intents are delivered to which services. This process should be configurable on a per-invocation basis for most intents, although defaulting rules, as long as they are configurable by the user, are expected to mean that the User Agent need not present specific UI controls on every invocation.
When the User Agent delivers an intent payload to a web application, it
must make the window.intent
object available as the document
is loaded and parsed, so that scripts on the page may process the intent
data as they load. User agents must not place a window.intent
object in the scope of pages which do not have registration metadata
declaring themselves as intent handlers. This means that any use of
window.intent
in pages which do not explicitly declare
themselves as web intents handlers must not be overwritten by the User
Agent.
When a new context is opened for the service page, the User Agent must
connect the postResult
and postFailure
methods
of the window.intent
object so that they return their
serializable payloads to the registered handlers the User Agent received
in the invoking navigator.startActivity
call. If the user
closes the service page before it has responded, the User Agent should
invoke the onFailure
callback in the client page invocation,
if any. If the user cancels a service selection UI control the User Agent
displays in the course of dispatching an intent, the User Agent should
invoke the onFailure
callback in the client page invocation,
if any.
The User Agent should allow any serializable object to be passed between client to service and back from service to client. This includes Blobs [BLOB], MessagePorts, etc. The User Agent may inspect the payload of intents and present specialized UI corresponding to well-known intent types. The User Agent must not categorically prohibit dispatch of unknown intent types. This is not meant to prohibit the User Agent from performing filtering functions on intents, such as suppressing unwanted intent invocations, intents as used as an attack vector, and other mis-use.
In the same way User Agents may dispatch intents caused by non-web mechanisms to web applications, User Agents may dispatch intents invoked by web applications to handlers which are not web applications. In those cases, the User Agent should provide a public API mechanism for external connection to the intent dispatch mechanism selected. For example, the User Agent may be able to run an Operating System level command in response to an intent. The User Agent could provide a configuration interface such that the user can install handler applications, and a documented format in which intent payload data is translated to that application. In these cases, the requirement that User Agents should pass any serializable object may need to be relaxed for some kinds of handlers.
User Agents may also dispatch intents based on data-specific controls derived from microdata in pages. For instance, if the user has services registered which handle text/vcard, then the User Agent may provide the user with a way to invoke particular intents that consume such data as it detects it in web pages.
If the user has no services registered for a particular type of intent, the User Agent may display options from other sources of data about services it knows can handle that intent type so that the user can complete the activity.
Local web apps should be able to invoke and handle intents.
Web Intents invocations are modeled on RPC, but there are times when a persistent connection is desired. There are a few different methods that Web Intents should support for this. One is returning URIs which can be loaded by clients in an iframe and then messaged using other web platform features. Another is returning a defaulting token which the client can then use to target other intents directly at a known target. A third is returning a MessagePort to the client which can be used for subsequent communication.
In these cases, Web Intents is acting as a way for the user to attach a particular client page to a persistently-available service. It is up to the particular types of intents to describe exactly how this should work. i.e. whether the connection is permanent or temporary, whether tokens are user-consumable or opaque.
It should be possible for intents to be routed to external helper applications. For instance, a locally available photo editing tool could be configured to interact with the browser to handle an image edit intent. Or the browser could discover home networking equipment on the local network and make it available for particular types of intents.
It should be possible to translate a few existing features to use Web Intents, thus putting web applications on the same footing as local resources. For instance, it should be possible for the User Agent to translate file selection controls to intents such that the use can choose to upload a file from a cloud storage locker as well as from local disk. In these cases, the User Agent may supply built-in intent handlers corresponding to existing functionality.
Another use case is allowing web applications to function as plug-ins. For example, a link returning a resource of a type which the user agent doesn't know how to display can be translated into an intent which allows the user to configure a web application capable of reading that resource type and viewing it. This would let web apps function as plug-ins.
It is expected that many services for Web Intents will be ones the user has an account with. The service should be able to use standard login mechanisms in the context the User Agent places them within to perform authentication. That is, the service page handling an intent should be loaded with the same cookie jar and access to localStorage, etc. with which it runs in a normal browsing context. Intent data should be persisted by the User Agent across login redirects.
Many thanks to Robin Berjon for making our lives so much easier with his cool tool.
See also webintents.org for more examples and a sample Javascript implementation of Web Intents.
No informative references.