The Bookmark Introducer is a [Web Introducer] based API for sharing bookmarks. A bookmark is a permalink and associated metadata. A bookmark is offered for sharing by a Client and received by a user-selected service Service. The provided service might be social bookmarking, email authoring, link shortening, or any other service whose input might be a bookmark.
The first two sections (Client Cheatsheet, Service Cheatsheet) offer suggestions for creating content that conforms to this specification. These details can be altered and customized to support a site's preferred user experience. The following sections (Declaration, Service Frame Allowance, Message Data) define the parts of the protocol that are required for interoperation.
This section is non-normative.
This section summarizes the implementation of a simple Client page. Following the advice in this section is not required for interoperation. This advice just explains an easy way to create a page that conforms to the normative parts of this specification. More customized interactions can be implemented by making direct use of the Bookmark Introducer API.
Clients are encouraged to represent a bookmark using an [HTML] <a> element having a rel attribute with value "bookmark".
For example, a Client might represent a bookmark with markup like:
<a rel="bookmark" type="application/atom+xml" href="http://example.org/#foo">example bookmark</a>
Clients are encouraged
to visually annotate a bookmark with the
icon.
For example, a bookmark might be styled using CSS like:
a[rel~=bookmark] {
padding-left: 20px;
background: url("openshareicon-16x16.png") no-repeat;
}
And so appear like:
To enable the Bookmark Introducer for content that uses the suggested markup, include:
<script src="introducer.js"></script>
This script will make an introduction request in response to a click event on a bookmark element.
After a bookmark is shared, a custom
[HTML] event of type
'bookmark' is dispatched on the bookmark element. The event's detail
property is the message data
returned by the Service.
By listening for this event, a Client can maintain a counter of
the number of times a bookmark has been
shared.
This section is non-normative.
This section summarizes the implementation of a simple Service that operates on a URL. This section assumes that all Service pages include:
<script src="introducer.js"></script>
This script implements the Introducer API.
Before receiving a bookmark from a Client page, a Service site first installs itself with the user-agent by making an invocation like:
introducer.install(
'data:image/png;base64,iVBORw0KGgoAAAANSUhEU…',
"Example.com",
'https://service.example.com/home/#s=qwerqwer',
function () {
introducer.offer(
'bookmark',
"Like",
[ 'http://web-send.org/bookmark/' ],
'https://service.example.com/bookmark/in-window',
'https://service.example.com/bookmark/in-frame');
});
The above invocation can be made from any page in the Service's [origin]. There is only one installation per origin. The installation can be updated by repeating the same invocation with the updated information.
The Service label is the action verb that will be presented to the user during a sharing interaction. Using the above code, the specified icon followed by the text "Like" will be presented as an option during a sharing interaction.
The frame declared in a Service offer will be loaded in a Client page during bookmark sharing. The frame dimensions will be 500 pixels wide and 100 pixels tall. The frame will be removed from the Client page after the sharing interaction is complete.
To receive a bookmark, the Service frame includes code like:
introducer.accept(location.protocol + '//' + location.host,
function (client, origin, wanted) {
client.onmessage = function (event) {
// Extract the URL from the received <a> element.
var url = event.data[0][1].href;
// Do something with the received URL.
…
// Send confirmation message to the Client.
client.postMessage({
attribution: location.host
});
client.close();
};
});
A Client declares compatibility with the Bookmark Introducer by making a connect call that specifies the intent:
bookmark-intent = "http://web-send.org/bookmark/"
A Client can enable Service filtering based on the MIME media-type of the bookmarked resource by including additional intents.
To enable filtering on a particular MIME type, specify an intent:
bookmark-intent-MIME-type = bookmark-intent "#" MIME-type "/" MIME-type = token ; in lowercase
To enable filtering on a particular MIME subtype, specify an intent:
bookmark-intent-MIME-subtype = bookmark-intent-MIME-type MIME-subtype MIME-subtype = token ; in lowercase
Where token is as defined by [HTTP].
For example, when sharing a blog, a Client might make a connect call like:
introducer.connect(anchor, frame, [ 'http://web-send.org/bookmark/', 'http://web-send.org/bookmark/#application/', 'http://web-send.org/bookmark/#application/atom+xml' ], function (service, agreed, framed) { … });
If a Service is only interested in receiving a bookmark for a blog, and not to another kind of resource, it should only register for blog bookmark intents. For example, such a Service offer looks like:
introducer.offer( 'reader', "follow", [ 'http://web-send.org/bookmark/#application/atom+xml', 'http://web-send.org/bookmark/#application/rss+xml' ], 'https://service.example.com/reader/');
In contrast, a Service interested in receiving a bookmark for any kind of resource, has a installation that looks like:
introducer.offer( 'generic', "bookmark", [ 'http://web-send.org/bookmark/' ], 'https://service.example.com/bookmark/in-window', 'https://service.example.com/bookmark/in-frame');
A Client MUST allow a Service frame with dimensions in pixels of at least:
frame-width = 500 frame-height = 100
A Service can therefore expect to present a user interface of this size in the Client page. If more space is needed, the Service declaration should specify a window instead of a frame.
If the Service loses input focus, the Client can terminate the interaction and so remove any loaded frame.
After a successful introduction, the Client sends the selected Service a single bookmark. The sent message data is an array of [JSONML] representations of [HTML] elements. The first value in the array is always an <a> element with an href attribute specifying a URL suitable for navigation in a user-agent. Each subsequent value in the array is an alternative representation of the bookmark as one of the following [HTML] elements: <a>, <audio>, <blockquote>, <embed>, <iframe>, <img>, <object>, <q>, or <video>.
For example, the data sent by the Client might look like:
[ [ "A", {
"rel" : "bookmark",
"type" : "image/application/atom+xml",
"href" : "http://example.org/#foo"
}, "example bookmark" ] ]
When sharing a bookmark to a secondary resource, such as a video, the sent data might look like:
[ [ "A", {
"rel" : "bookmark",
"href" : "http://example.org/#foo"
}, "example video bookmark" ],
[ "VIDEO", {
"src" : "http://example.org/video.mp4"
} ]
]
Not all of the listed [HTML] elements
are necessarily a suitable alternative representation for a bookmark to a resource of a particular MIME type.
For example, a Client
should not send an <img>
element as an alternative representation of a bookmark to an audio/* resource. A
Service should ignore
alternative bookmark representations that
it does not understand.
To confirm receipt of the bookmark, the Service sends a response message. The sent message data is an object with one optional property named attribution whose value is a globally unique identifier for a group of sharing interactions. A Client might use this response property for page analytics.
After the Client receives any message from the Service, the interaction is complete. The Client then removes any Service frame and closes the message channel.
The editors thank Will Meyer.