This specification defines an API that allows websites to declare
themselves as web share targets, which can receive shared
content from either the Web Share API, or
system events (e.g., shares from native apps).
This is a similar mechanism to navigator.registerProtocolHandler,
in that it works by registering the website with the user agent, to
later be invoked from another site or native application via the
user agent (possibly at the discretion of the user). The difference is
that registerProtocolHandler
registers the handler via a programmatic API, whereas a Web Share
Target is is declared in the Web App
Manifest, to be registered at a time of the user agent or user's
choosing.
Status of This Document
This is a preview
Do not attempt to implement this version of the specification. Do not reference this
version as authoritative in any way.
Instead, see https://wicg.github.io/web-share-target/ for the Editor's draft.
This is an early draft of the Web Share Target spec.
1.
Prerequisites
In order to implement this API, it is REQUIRED that the user agent
implements Web App Manifest. This spec
also re-uses some definitions from the Web
Share API spec. Implementation of that spec is NOT REQUIRED to
implement this one (but it is RECOMMENDED).
The url_template contains a number
of placeholder fields that will be replaced with the shared data when
the target is invoked. Once the fields are replaced, it should
be a URL that is relative to the directory containing the manifest URL.
For the purpose of this example, we assume the manifest is located at
https://example.org/includinator/manifest.webmanifest.
When a share takes place, if the user selects this app as the share
target, the user agent populates the fields of the URL template, then
opens a new browsing context at that URL. Any missing fields are left
empty (but note that the query parameters are not removed). For
example, if an incoming share contains the title "My News" and the URL
http://example.com/news, the user agent will open a new
window or tab and navigate to:
How the handler deals with the shared data is at the handler's
discretion, and will generally depend on the type of app. Here are some
suggestions:
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.
3.
Extension to the Web App Manifest
The following IDL extends the WebAppManifest dictionary.
The extension point actually needs to come after the other fields are
post-processed. Otherwise, we will be using a potentially invalid or
relative scope URL.
3.1 share_target member
The share_target member of the manifest is a
ShareTarget dictionary that declares this application to be a
web share target, and describes how the application receives
share data.
A web share target is a web
site in a secure
context with a valid manifest containing a share_target
member. A web share target is a type of share target.
Issue 27: Properly define the secure context requirement
A web share target is defined as "a web site in a secure context".
We need to more precisely define this requirement. Note that the secure context algorithm is defined over an environment settings object, not a URL. We need to block share targets that are specified from a non-secure manifest OR those final URL is non-secure.
The steps for post-processing the share_target
member is given by the following algorithm. The algorithm takes
a ShareTargetshare target, a URLscope URL, and a URLmanifest URL. This algorithm
returns a ShareTarget or undefined.
If share target is undefined, then return
undefined.
If URL template is undefined, then return
undefined.
Let test relative URL be the result of running the
replace placeholders algorithm on URL template with
{} (the empty ShareData). If the
result is failure, issue a developer
warning that the URL template is invalid, and return
undefined.
Let test absolute URL be the result of running the
URL parser on test
relative URL, with manifest URL as the
base, and no encoding override. If test
absolute URL is failure, issue a developer
warning that the URL template is invalid, and return
undefined.
If test absolute URL is not within scope of scope
URL,
issue a developer warning that the URL template is outside of
the manifest scope, and return undefined.
Return share target.
Note
Unlike the other post-processing steps for URL members of the
manifest, this algorithm does not update the manifest object with
the absolute URL for url_template. This is because the URL parser won't work on the URL
template; it can only be run after the placeholders are replaced at
launch time.
Therefore, the above steps just validate the URL template, and if
it is invalid, ignore the share target. The launch algorithm below
repeats these same steps using the actual share data.
3.2 ShareTarget and its members
The ShareTarget dictionary contains the following members.
The url_template member describes which share data fields
are passed to the web share target, and in what format. It contains
zero or more placeholders of the form
"{field}". Each fieldMUST be a valid
WebIDL identifier, and
SHOULD be a key of the ShareData dictionary.
After these placeholders are removed, it MUST form a valid URL string.
Note
The { and } characters are illegal in a
valid URL string, so they
always represent a placeholder in the url_template string, and
do not need to be escaped.
Any fields that are not present in the url_template will be
silently dropped from the share payload when sharing to this app. The
url_templateMAY contain fields that are not ShareData keys, for
forwards compatibility.
4.
Registration of web share targets
How and when web share targets are "registered" is at the
discretion of the user agent and/or the end user. In fact,
"registration" is a user-agent-specific concept that is not formally
defined here; user agents are NOT REQUIRED to "register" web share
targets at all; they are only REQUIRED to provide some mechanism to
convey shared data to a web share target of the end user's choosing.
User agents MAY consider a web share target "registered" even if it is
not installed.
The user agent MAY automatically register all web share targets
as the user visits the site, but it is RECOMMENDED that more discretion
is applied, to avoid overwhelming the user with the choice of a large
number of targets.
Note
Examples of registration strategies that user agents can employ are:
Only register a web share target once it is installed.
Only register a web share target once the end user has used the
site for some period of time.
When presenting the end user with a list of web share targets,
the user agent MAY use an online service which has pre-indexed
manifests, and therefore show the user targets that they have never
visited or explicitly registered.
Issue 26: Way to explicitly register share targets
We may wish to provide a method for websites to explicitly request to prompt the user for handler registration. This would be limited to prompting to register the share_target already declared in the manifest (not dynamically creating share targets). 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.
5.
Handling incoming shares
A web share target is invoked when the end user is sharing some
data intended for a generic application, and indicates that specific
web share target as the receiver of the data.
It is not specified where the data comes from, or how the end user
indicates the web share target as the receiver. However, one possible
source is a call to navigator.share in the
same user agent.
Note
Examples of other possible sources of a web share target
invocation are:
From the built-in UI of the user agent (e.g., the end user
picks "Share" from a browser's menu, to share the current page title
as "title" and the current page URL as
"url").
A share action triggered from a native application (via a
proprietary share system), followed by the end user choosing a web
share target as the receiver.
5.1
Obtaining a ShareData
When a web share target is invoked, the data MAY be in
an unspecified format. The user agent MUST first convert the data
into a ShareData dictionary, if
it is not already, by mapping to the fields of ShareData
from equivalent concepts in the host system. If the source was a call
to navigator.share, the
user agent SHOULD use the ShareData argument
unmodified (but this is not always possible, as it might have to
round-trip through some other format in a lossy manner). The user
agent MAY employ heuristics to map the data onto the
ShareData fields as well as possible.
Note
For example, the host share system may not have a dedicated URL
field, but a convention that both plain text and URLs are sometimes
transmitted in a "text" field. This is the case on Android. The user
agent can check whether all or part of the "text" field is a
valid URL string, and if so,
move that part of the "text" field to the ShareData's url field.
Let relative URL be the result of running the
replace placeholders algorithm on
manifest["share_target"]["url_template"] with data. If the
result is failure, abort these steps.
Let final URL be the result of running the
URL parser on
relative URL, with manifest URL as the
base, and no encoding override.
If final URL is failure, abort these steps.
If final URL is not within scope of
manifest's scope URL, abort these steps.
Run the window open
steps on final URL, with empty target and
empty features.
Replace the characters in template from indices
start to end, inclusive, with
value.
If template contains U+007D (}), return
failure (unmatched closing brace).
Return template.
Note
The above algorithm assumes that all values of ShareData are of type
USVString, which is
currently the case. If new members are added in the future that are
not strings, the above algorithm will need to specify
conversion to a string.
For example, if an image member is
added, this would likely be an ImageBitmapSource, which
would be converted into a Blob URL before being inserted
into the URL template.
6.
Security and privacy considerations
This section is non-normative.
Invoking a web share target means potentially sending
private user data to a third-party website. Implementors are to take
every precaution that the user understands which party the data is
being sent to (e.g., communicating the web share target's
origin), before running the invocation algorithm.
Of particular concern is spoofing: a web share target presenting
itself as a different party (by setting its name and icon accordingly).
The spoofing risk is heightened if web share targets are chosen
from an online index, rather than a set of targets that the end user
has explicitly installed or registered.
The requirement that the web share target be a secure context is to prevent
private user data from being transmitted to a party that does not
control the origin in question, or in clear text over the network.
A.
Acknowledgments
This section is non-normative.
Thanks to the Web Intents team, who laid
the groundwork for the web app interoperability use cases. In
particular, Paul Kinlan, who did
a lot of early advocacy for Web Share and Web Share Target.
Thanks to Connie Pyromallis, who wrote an early draft of this spec, and
helped design and prototype the API.