introducerbookmark
features

Bookmark Introducer

Overview

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.

Client Cheatsheet

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.

Markup

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>

Style

Clients are encouraged to visually annotate a bookmark with the Open Share 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:

example bookmark

Implementation

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.

Bookmark Event

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.

Service Cheatsheet

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.

Installation

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.

Presentation

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.

Receiving a URL

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();
  };
});

Declaration

A Client declares compatibility with the Bookmark Introducer by making a connect call that specifies the intent:

bookmark-intent = "http://web-send.org/bookmark/"

MIME Extension

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');

Service Frame Allowance

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.

Message Data

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.

For example, the Service response data might be:

{
  "attribution" : "service.example.com"
}

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.

References

Normative References

[HTML]
HTML5, I. Hickson. W3C, 24 June 2010.
[HTTP]
Hypertext Transfer Protocol -- HTTP/1.1, R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter, P. Leach, T. Berners-Lee. IETF RFC 2616, June 1999.
[JSONML]
JsonML (JSON Markup Language), jsonml.org.
[origin]
The HTTP Origin Header (work in progress), A. Barth, C. Jackson, I. Hickson. IETF.
[Web Introducer]
Web Introducer, web-send.org.

Acknowledgments

The editors thank Will Meyer.


by