This specification defines a mechanism for Web applications to register themselves as
being able to handle certain specific types of services ("grant wishes") with a user
agent. Once a service handler is registered, any Web application can then request its
functionality from the user agent in order to compose the service into itself.

This specification is a proposed extension specification to HTML and has no official
standing whatsoever.

Introduction

This specification defines a mechanism for Web applications to register themselves as
being able to handle certain specific types of services ("grant wishes") with a user
agent. Once a service handler is registered, any Web application can then request its
functionality from the user agent in order to compose the service into itself.

For instance, a Web application could register itself as an image editor. When another
application needs image editing functionality (e.g. a meme generator) then it can
instantiate the image editor as part of itself (typically in an iframe). The
editor is selected based on user preference rather than by hardcoding it. This provides a
simple yet powerful component model for Web applications.

This functionality is similar to that provided in Android Intents or in FirefoxOS
Activities. However, in order to ship more quickly and to explore the simpler options first
this specification is limited to a subset of the functionality afforded in existing systems.

Usage Scenarios

This section details a variety of usage scenarios for Wishes in order to help define how
exactly they should work.

Note that all code examples are provisional and use completely made up syntax. The scenarios
rely on the following loose terminology (to be tightened up when the view is clearer).

application

A regular Web application running in the user's browser, and typically calling upon wishes
in the following scenarios.

wish service

A Web page written in such a way that it knows how to grant a wish and that exposes
functionality to the application in that way.

Fire & Forget

This is the simplest case. Here the application formulates a wish but does not care
about any return value, or even about the success, of the wish.

A typical example is the wish to share. The user is visiting an application page,
finds it most cromulous, and wishes to share it with the world at large.

User clicks the “share” button in order to share this most cromulous piece of humour.

Creating a share button is a simple matter of attaching a handler to it and formulating
a wish.

The user is then presented with a list of wish services that she has installed in her user
agent (or, possibly, more generally on her operating system). Of these she selects the
“Unicorner” social sharing site where she can share with her fellow unicorns.

User selects “Unicorner” in the list of services that can grant the wish to share.

The wish service picker requires no work from the developer and is entirely
handled by the user agent. The list matches wish services that the user agent knows can
fulfil this wish (this can comprise those installed by the user, but can also come from
other sources such as system application, a specialised search engine, etc.). Installing
a wish into a user agent is covered in a later section.

The “Unicorner” web site, which is a social sharing web site that the user happens to like
(here showing how Wishes can help open up the Web to new contenders without having to
battle the inertia of millions of authors having to add new buttons to their pages), opens
up atop the application being shared (with some sort of signal that the wish
service is related to the application — all of this is naturally
implementation-dependent). The user can interact with it and hit “Share”.

Unicorner's next generation sharing UX.

There are two essential parts to the wish service's handling of the wish. The first
part is being notified of the wish, including of the wish's payload and acting
accordingly in order to grant it. The code for this is straightforward.

Note that the code above still needs to call grant() on the wish once the
action is completed, even though it is returning no data to the application. This
tells the user agent that the wish is granted and it can use that notification for
instance to close the tab containing the wish service.

Return Value

While “fire & forget” wishes definitely have their uses, it is common for
applications to expect data to be returned from the interaction with a
wish service.

In this scenario we consider the following workflow: a user wishes to create a hilarious
meme, and goes to a meme publishing web site for that purpose. The meme publishing
web site first asks the user to pick an image to serve as the starting point for the meme.
That operation relies on <input type=file> in order to show how wishes
can integrate with that part of the platform. Then it will offer to edit the image, using
a wish to edit.

In both cases, data is returned from the wish service, and in the second case data
is also received by it.

The application's UI is simple:

MemeCat — The World's Laziest Meme Maker

Clicking the first “Pick a picture” step hits an <input type=file>
control, which in fact just formulates the wish to pick a file. To give a better idea for
how this works, here is how you would get a list of files from a file input type.

These come out at the same amount of code. With the wish we need to handle clicking
ourselves which the file input type provides free, but if you ever wish to style your
file input control then that's a plus because you will need this sort of indirection
anyway. A positive side effect of the wish side is that you don't need no stinking
FileList.

It is important that the file input type and the wish to pick produce the same user
experience since to the user, who neither knows nor cares for the page source, they are
the same operation.

For the code examples we use the multiple attribute in order to
demonstrate its mapping, but the MemeCat application naturally only wants a single
image.

Irrespective of how MemeCat chose to implement its file picking, the user would be
presented with the familiar wish service picker:

The system file picker, as depicted if you let a standards geek create icons.

A wish service that knows how to grant a pick (of any kind) will return either
a File or an array thereof depending on the value of the
multiple field. Such a service could be implemented using code of the kind
that follows:

It is simply a wish to edit the given file MIME type, operating on the provided content.
Once done the edited content is sent back using the same mechanism as for the file picker.
It is worth noting here that it is entirely possible for this wish to be granted by a
native application (so long as the user agent knows how to interact with the platform's
conventions that support such communication).

Sharing can then be supported just as it is in the first section.

Explicit Wish

It is conceivable that there are cases in which an application may wish to operate
with just one explicitly well-defined wish service, making use of the wish
conventions for communication (likely because they are already supported by a given
service) but without giving the user the opportunity to choose the service (presumably
because it may result in a predictably poor decision).

To take the MemeCat example again, it is likely that the image source should be
open-ended, but the service might wish to enforce a given editor service that consistently
enforces Web meme conventions relying on the Impact font, specific stroke and fill, etc.
where a general-purpose image editor might let the user overlay her cat picture with, say,
Comic Sans text — clearly a bad thing.

It is unclear at this point whether explicit memes are required in an initial instalment
of this technology.

Installing a Wish

So far we have looked at scenarios involving formulating wishes from the
application's point of view, as well as how a given wish service might
reply. However in order for a service to grant a wish, the user agent needs to know about
it.

There are many ways in which a user agent can become aware of wishes that it can offer as
options to the user when needed. Here is a non-exhaustive list:

Explicit installation

The user may explicitly wish to “install” a given application as part of a list of
wishes. This may happen if the Web application itself is being installed (something
which can happen in some contexts), or as a form of bookmarking specific to wishes.
When visiting a site offering a wish service, the user agent may provide an
affordance for the user to specifically perform this action. Alternatively, it could be
made possible for Web applications to give users a way of installing them (instead of
relying on UA UI, which Web developers are often hesitant to.)

Remembered navigation

As the user navigates across the Web, her browser will come across pages that are
declaring wishes. While having wish picker dialogs immediately show all such wishes
would be a bad idea in that it would encourage spamming of that dialog (and even without
malicious intent would likely cause it to be overcrowded), it can nevertheless be a good
idea for browsers to remember that information so as to be able to offer those sites as
options, notably in case no other known service can grant a given wish.

Wish Search

The wish picker could expose a search affordance that would make it possible to find
wishes across the Web using a dedicated search engine.

Built-in or default wishes

User agents would likely ship with a number of wish services that they would
grant themselves (e.g. the wish to pick a file for instance). Likewise, they could
have a list of pre-configured services for various wishes.

Platform wishes

The browser can query the platform it is running on to find out if there are local
applications that could grant a given wish.

A wish is in effect nothing more than a Web application that can be interfaced with
programmatically following a specific interface. A wish service simply
needs to express a little bit of metadata so that it can be recognised by user agents,
crawlers, etc., but that metadata is very similar to that which can be used to describe
a Web application.

Because of that, wish services can declare themselves using additional information from
web apps manifest [[!appmanifest]]. Manifests can be linked in the usual manner:

<link rel="manifest" href="memecat.json">

This entails that any process exposed by the browser to install the wish would work
through installing the application. If there are cases in which one desires to solely
make the wish “installable” then a different syntax (but using the exact same JSON)
can be used:

<link rel="wish" href="memecat.json">

The JSON itself is an extension to the basic web apps manifest format.

Authors traditionally do not like to have to rely on UA affordances (because it means they
can't emphasise it if needed, also when explaining to users one needs to document for each
browser, stay up to date, etc.). If installing pages (in a sense specific to the Web)
becomes more mainstream, it would likely be welcome to support installation from actions
carried out inside of the viewport. Such a mechanism is not, however, catered to at this
point.

The Wish interface

Is it really useful to distinguish between fire&forget and return value wish modalities
through different methods? Maybe instead of once()/then() it
would be clearer to have it be send()/ask(). That depends on
whether it makes sense to enable Wishes to behave like Promises in some cases.

Future Scenarios

A number of different scenarios were considered for this functionality, but only a subset
thereof were kept in scope for this version. Those that were excluded, but that may return
in future, are captured below.

Full Duplex Communication

Once a wish service is instantiated, in theory there is no reason why it could not
remain permanently open and remain open to continuous, full-duplex communication with the
application. The use cases for this are however more tenuous than for the simpler
interactions, and more importantly the implementation is more difficult to convey in the
user interface. Because of this, at this point it is expected that this scenario will not
be covered by this version of the specification. A quick discussion of the scenario can
nevertheless prove useful.

One common application of full duplex wishes is patching together application components
that today are usually shipped as a single bundle. Imagine for instance that you two web
applications. One is a code management system which allows you to track progress, commits,
etc. on a project you are working on. Another is an IRC client which you use to
communicate with your team. Both already have your login information, settings, etc. that
should not need to be shared with anyone, even through tokens (with insufficient
granularity).

You can get wish services for these two talking together with the following
application.

The above is, clearly, a simplification, done in order to give the right idea. But as
such it could well enough operate.

It should be noted that because wishes match on both action (the verb) and on payload
type they likely encourage a relative proliferation of MIME type minting, as seen above.
That is not necessarily a bad thing. Whether a specific format should be encourage
(typically, MIME types) or whether we should just match any string (with prefix matching
when terminated with a *) is an open question.

Embedded Wish

While user agents are free to implement a user interface for wish services in any way they
see fit, some constraints (notably of relying on trusted chrome) are such that we can
expect typical implementations to render any wish service in a clearly separated
context.

This approach is clearly sufficient for many interactions, as can be readily seen in
mobile applications that make use of wish-like functionality.

It is, however, possible to conceive of cases involving more advanced applicative
composition for which it would be desirable to be able to embed multiple wish services
inside a given application, in order to produce a more useful whole.

An example of such a scenario could be for a mail user agent. It is a truth universally
acknowledged that MUAs are terrible to point of obeying principles of Churchillian
democracy: whichever one you choose is the worst form of MUA, except all the others that
you have tried. Part of the problem likely stems from the fact that a single MUA needs
to offer multiple different views on email (list of mailboxes, list of emails, emails,
etc.) all of which can be done in many different ways, and users do not fit into a simple
set of profiles that enjoy specific configurations: they will have preference combinations
all over the place. The combinatorics of the situation are such that the likelihood for
any given MUA vendor to produce a combination that matches your particular needs are
negligible enough that we can consider the task impossible.

This problem can be solved by making each component separate, and making it easy for
users to compose their own client from multiple sources, possibly replacing components
when they find better ones. We could therefore envision a world in which one's MUA is
a relatively dumb application that does nothing more than expose the data and
lay out replaceable embedded wishes for all the parts that make up a MUA's UI.

Such a universe of wonder is, however, far enough out of reach that wish embedding is not
at this point a driving consideration here.

Acknowledgements

The following people have contributed to the elaboration of this standard.

Of particular note, the original Web Intents people: Greg Billock, James Hawkins, and Paul
Kinlan. Many thanks for your patience, your dedication when surrounded by mockery, and
being fun to work with.