EPUB Scriptable Components 1.0
Editor's Draft 6 July 2015
This version:
http://www.idpf.org/epub/sc/api/sc-api-20150706.html
Latest version:
http://www.idpf.org/epub/sc/api
Previous version:
http://www.idpf.org/epub/sc/api/sc-api-20150115.html
Copyright © 2014-2015 International Digital Publishing Forum™
All rights reserved. This work is protected under Title 17 of the United States Code. Reproduction and dissemination of this work with changes is prohibited except with the written permission of the International Digital Publishing Forum (IDPF).
EPUB is a registered trademark of the International Digital Publishing Forum.
Editors
Will Manis, Invited Expert
Brady Duga, Google
Darryl Lehmann, Imagineeringart.com Inc.
Mike Chen, Inkling
Status of this Document
This specification is a work in progress and subject to change.
All comments on this specification should be submitted via the EPUB 3 Working Group Issue Tracker, hosted on Google Code. NOTE: you must login via a Google Account in order to submit an issue. Please submit spec comments with the labels "Type-ReviewComment" and "Spec-EPUBSC". Members of the EPUB Working Group may submit questions via the mailing list.
Open issues in this draft
This section will be removed when this document leaves draft status.
Table of Contents
1.1.2 User Agent to Reading System Communication
2.2 Reading System Conformance
4. Inter-Component Communication
4.2.1 The PubSub Communication Bridge
4.3.2 Subscribe ("epubsc_subscribe")
4.3.3 Unsubscribe ("epubsc_unsubscribe")
4.3.4 Publish ("epubsc_publish")
4.4.2.1 Ready ("epubsc_ready")
4.4.2.2 Pause ("epubsc_pause")
4.4.2.3 Resume ("epubsc_resume")
4.4.2.5 Unload ("epubsc_unload")
4.4.2.6 Event ("epubsc_event")
5.Component-Parent Event Communication
5.2 Handling and Propagating Events
Appendix B. ComponentID sample code
Appendix D. Acknowledgements and Contributors
This section is informative
This specification, EPUB Scriptable Components, provides an interoperable publish and subscribe (pubsub) pattern by which interactive content can be created and incorporated into EPUB Publications. This interactive content can be rendered in any Reading System that conforms to the requirements in this specification.
This specification is not a replacement for the scripting architecture defined in [ContentDocs301], and implementing or using the APIs and processes does not replace the requirements, restrictions and best practices defined in that specification.
Scriptable Components can be used in Reading Systems that support only container-constrained scripts or that support full spine-level scripting.
The goal of this specification and [ESCPackage] is to allow third-party Scriptable Components (widgets) to be securely integrated into XHTML Content Documents. As such, this specification requires that Scriptable Components be embedded using the [HTML5] iframe element ‒ whether they are embedded into an XHTML Content Document in an EPUB Publication or into another Scriptable Component.
This specification assumes that domain isolation exists between the Scriptable Components, but the Reading System might or might not enforce domain isolation on the document referenced by the iframe element. If domain isolation is enforced a relatively high degree of isolation and security is achieved. If domain isolation is not enforced security could be an issue (e.g., the Scriptable Component might compromise the EPUB Publication and/or the Reading System).
Compliance with this specification does not guarantee any particular level of security, it is intended to provide a framework in which Reading System implementors can achieve security with third-party scripting.
Some Reading Systems on mobile devices are implemented using a system-provided web component (often referred to as a WebView) for the rendering of content. It is common for these components to provide some level of communication with the rest of the Reading System, for instance to report on progress and load content. Such calls can have both security and privacy implications. For example, it might be possible to determine the name of the user and the list of books in the users library. Such communications can also be used to exploit vulnerabilities, like buffer overflows, in the Reading System.
This specification does not directly resolve these issues. It is the responsibility of the Reading System implementor to account for the security and privacy implication of WebView-to-application communication.
As Scriptable Components evolve, they will invariably make use of communication resources to retrieve and store remote (cloud) data ‒ data that might contain sensitive personal information.
It is beyond the scope of this specification to ensure or enforce the privacy of this information. Reading Systems might employ measures to restrict or eliminate communication across a network, or limit or disallow cookies and local storage.
Refer to the EPUB Specifications for definitions of EPUB-specific terminology used in this document.
Component Parent
The parent that hosts the Scriptable Component, which could be either:
PubSub Communication Bridge
The publisher/subscriber relationship defined in 4.2.1 The PubSub Communication Bridge to facilitate message communication.
Scriptable Component
A scripted Distributable Object that is distributed for use in other EPUB Publications. A Scriptable Component conforms to all content requirements in this specification and in [ESCPackage].
The keywords must, must not, required, shall, shall not, should, should not, recommended, may, and optional in this document are to be interpreted as described in [RFC2119].
All sections of this specification are normative except where identified by the informative status label "This section is informative". The application of informative status to sections and appendices applies to all child content and subsections they may contain.
All examples in this specification are informative.
The following typographic conventions are used in this specification:
markup
All markup (elements, attributes, properties), code (JavaScript, pseudo-code), machine processable values (string, characters, media types) and file names are in red-orange monospace font.
markup
Links to markup and code definitions are underlined and in red-orange monospace font. Only the first instance in each section is linked.
http://www.idpf.org/
URIs are in navy blue monospace font.
hyperlink
Hyperlinks are underlined and in blue.
[reference]
Normative and informative references are enclosed in square brackets.
Term
Terms defined in the Terminology are in capital case.
Informative markup examples are in monospace font.
NOTE
Informative notes are preceded by a "Note" header.
An EPUB Content Document that supports Scriptable Components must meet the following criteria:
› It must conform to all content and security requirements in 3. Scriptable Components.
› It must contain EPUB Scriptable Component code that supports the pub/sub protocol defined in 4. Inter-Component Communication.
An EPUB Publication that contains EPUB Scriptable Components must be packaged in conformance with [ESCPackage].
EPUB Reading Systems that support Scriptable Components must meet the following criteria:
› All conformance requirements placed on Reading Systems by the EPUB specification, particularly the requirements for scripting [ContentDocs301], must be met.
› Container-constrained scripting [ContentDocs301] must be supported for the [HTML5] iframe element.
› If spine-level scripting [ContentDocs301] is not supported, the Reading System must still support the pubsub protocol defined 4.2.1 The PubSub Communication Bridge for Scriptable Components embedded directly in Top-level Content Documents (i.e., to ensure communication at the top-most level). Otherwise, if the Reading System supports spine-level scripting and it is enabled, it must not implement the pubsub protocol, as the spine-level Scriptable Components will already implement it.
All Scriptable Components must be hosted in an [HTML5] iframe element.
All resources used by a Scriptable Component must be included in the EPUB Container, unless allowed to be remotely hosted (e.g., audio/video).
Scriptable Components must assume that they exist in a separate domain from the EPUB Content Document that hosts them. Reading Systems may enforce domain isolation of Scriptable Components.
The only means of communication between an EPUB Content Document and the contained Scriptable Components must occur using the EPUB Scriptable Components protocol. No direct access across Scriptable Component boundaries is allowed; properties contained on window.parent [HTML5] must not be accessed.
This section is informative
A Scriptable Component communicates via a protocol layer driven internally by an implementation of the HTML5 postMessage API [HTML5WebMsg].
The Scriptable Component functions ubiquitously by being both subscriber and subscribed in this model. This distributed model means that each Scriptable Component is responsible for relaying the messaging protocol to its direct dependent children and its parent in turn.
This protocol defines the methods by which Scriptable Components communicate, and predefines a set of message topics for communication.
The window.postMessage() API [HTML5WebMsg] provides a safe communication bridge between two Scriptable Components in different domains, and is used by Scriptable Components to publish messages to target windows – their subscribers.
Scriptable Components must use the window.postMessage() method [HTML5WebMsg] to publish messages to, and through, target windows ‒ referred to hereafter as the PubSub Communication Bridge.
Subscribers, in turn, must register event listeners on the event handler event type "message" [HTML5WebMsg] to subscribe to messages.
Scriptable Components publish messages over the PubSub Communication Bridge to relay topics and events as they occur or are passed through.
Each message must be serialized as a JSON object [RFC4627] that conforms to the schema in Appendix A.
Messages are composed of the following properties:
Example of a message that passes temperature information on to another Scriptable Component.
{
"componentId": "b33ef720-556a-11e4-8ed6-0800200c9a66",
"messageId": "b33ef720-556a-11e4-8ed6-0800200c9a66+1",
"timestamp": 1413488477617,
"type": "epubsc_message",
"method": "epubsc_publish",
"topic": "current_temperature",
"topicData": {
"location": "Toronto, Ontario",
"currentTemp": 21,
"tempFormat": "Celsius"
}
};
Due to the distributed nature of the protocol defined in this section, the order in which messages are received by a subscriber cannot be guaranteed.
Scriptable Components consequently should not be designed to be dependent on an orderly arrival of messages from separate components. Scriptable Components should rely on the ordering of messages from a unique instance of a component. Message timing information should be extracted from the timestamp property.
Scriptable Components must implement the methods defined in this section to facilitate communication over the PubSub Communication Bridge.
The epubsc_subscribe method provides the mechanism for a Scriptable Component to subscribe to a topic.
This method needs to be aware of the topic to begin listening.
The epubsc_unsubscribe method provides the mechanism for a Scriptable Component to terminate listening to a particular topic.
This method needs to be aware of the topic string value to facilitate this lookup and removal.
The epubsc_publish method allows a ready Scriptable Component to publish a message on a previously subscribed topic.
This method needs to be aware of the topic name, and the message object to be passed.
All topic subscriptions and publications must be propagated up to the Component Parent, regardless of subscription
The component must send published topics to all subscribed children. If the sender is also subscribed, it must also receive the topic.
A component may subscribe to a topic multiple times.
A component may unsubscribe from a topic by removing a specific handler.
Topic names are used to identify what data is carried by a specific publish request.
Topic names must start with an alphanumeric character and must not contain whitespace characters, which are defined as the following:
Implementations can define their own topic names, but such names must not begin with the text “epubsc”, as this prefix is reserved for topics defined by this specification. The colon character (“:”, U+003A) is reserved by this specification for future use and must not be used in custom topic names. However, the inclusion of the character must not be considered an error by Reading Systems implementing this version of the specification.
Other than the reserved names, this specification does not define the meaning of any topic names.
The topic "epubsc_ready" is reserved to indicate that a component has entered its ready state and is able to receive messages.
At startup, a Scriptable Component must announce that it is ready to handle messages (topic subscriptions and publications) by publishing a message with the epubsc_ready topic.
The Scriptable Component also has to be able to store and maintain a list of participating Scriptable Components using their Component IDs.
The topic "epubsc_pause" is reserved to indicate that a component should enter its paused state (e.g., when it is no longer on a visible page or when the reading system is not the frontmost application).
The topic "epubsc_resume" is reserved to indicate that a component should resume its ready state.
The topic "epubsc_load" is reserved to indicate that a component has begun loading.
The topic "epubsc_unload" is reserved to indicate that a component has begun unloading.
The topic "epubsc_event" is reserved for JavaScript event communication.
To prepare to send and receive messages, a Scriptable Component must initiate the following steps during its load process:
This PubSub Communication Bridge is used to pass a message of a specific method type, as defined in 4.2.2 Message Structure.
The methods used to communicate are described in 4.3 Methods. These methods define a communication channel for specific handling.
At this stage, the Component can subscribe, unsubscribe, publish, and send topics through the PubSub Communication Bridge.
This section is informative
Scriptable Components can receive JavaScript events that are both meaningful and meaningless to their operation.
For example, a key press in an input field of the Scriptable Component would typically need to be handled by the Component, but a right arrow key press might not. Whether the Scriptable Component transmits information about the event to its Parent Component, giving the parent an opportunity to respond to it, depends on the nature of the event.
This section defines how Scriptable Components publish these events to their parent(s), including whether they were or were not handled.
Scriptable Components must relay [UIEvents] events to their Parent Component via the PubSub Communication Bridge.
Communication of these events is required whether the event has been handled by the Scriptable Component or not, and the message must use the epubsc_publish method with the reserved topic “epubsc_event”
To indicate if the event has been handled, the message's topicData must include the boolean property handled. The Component Parent should not respond to the event if this property is true.
The topicData also must be populated with copies of all applicable attributes [UIEvents] from the original event (e.g., altKey, button, ctrlKey, type).
The following example shows the epubsc_event message a Scriptable Component might send for a click event it did not handle.
{
"componentId": "1e5c4271-3ad2-43be-91d3-6df78a095047",
"messageId": "1e5c4271-3ad2-43be-91d3-6df78a095047+1",
"timestamp": 1431014848368,
"type": "epubsc_message",
"method": "epubsc_publish",
"topic": "epubsc_event",
"topicData": {
"handled": false,
"type": "click",
"screenY": 438,
"screenX": 1227,
"offsetY": 13,
"offsetX": 64,
"clientY": 13,
"clientX": 64,
"button": 0,
"buttons": 1,
"shiftKey": false,
"ctrlKey": false,
"cancelable": true,
"bubbles": true,
"altKey": false,
"timeStamp": 1432258647479,
"relatedTarget": null,
"metaKey": false,
"eventPhase": 3
}
}
All event messages must be propagated up to the Component Parent; the component must not send event messages to any of its children.
The JSON representation schema for messages:
{
"id": "http://www.idpf.org/epub/sc/1.0/schema.json",
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"title": "EPUB Scriptable Components Message Schema",
"description": "Schema validation for the message body",
"properties": {
"componentId": { "type": "string" },
"messageId": { "type": "string" },
"timestamp": { "type": "number" },
"type": {
"type": "string",
"enum": ["epubsc_message"]
},
"method": {
"type": "string",
"enum": ["epubsc_subscribe", "epubsc_unsubscribe", "epubsc_publish"]
},
"topic": { "type": "string" },
"topicData": { "type": "object" }
},
"required": ["componentId", "messageId", "timestamp", "method", "topic"],
"additionalProperties": false
}
Validation using this schema requires a processor that supports [JSONSchema].
This appendix is informative
The uniqueness of a component ID over a session is critically important to correct behavior of Scriptable Components. An implementation of [RFC4122] provides sufficient uniqueness.
Examples include:
function generateComponentID_() {
var d = new Date().getTime();
var template = "xxxxxxxx-xxxx-Zxxx-yxxx-xxxxxxxxxxxx";
return template.replace(/[xy]/g, function (c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d/16);
return (c == "x" ? r : (r & 0x7 | 0x8)).toString(16);
});
}
This appendix is informative
Allow two Scriptable Components to communicate. A UI control in one component may direct a visualization change in a second component.
An embedded Scriptable Component may contain a running video. When the EPUB document is paged or scrolled the Reading System will instruct the Scriptable Component to pause the video.
UI events occurring in IFrames are not bubbled to parent windows. Scriptable Components will enable event propagation and handling by parent windows and Reading Systems.
This appendix is informative
EPUB has been developed by the International Digital Publishing Forum in a cooperative effort, bringing together publishers, vendors, software developers, and experts in the relevant standards.
The EPUB Scriptable Components Packaging and Integration 1.0 specification was prepared by the International Digital Publishing Forum's EPUB Working Group, operating under under the leadership of:
Active members of the working group at the time of publication were:
IDPF Members
Invited Experts/Observers
[ContentDocs301] EPUB Content Documents 3.0.1.
[ESCPackage] EPUB Scriptable Components Packaging and Integration.
[HTML5] HTML5: A vocabulary and associated APIs for HTML and XHTML.
[HTML5WebMsg] HTML5 Web Messaging.
[JSONSchema] JSON Schema: core definitions and terminology.
[Publications301] EPUB Publications 3.0.1.
[RFC2119] Key words for use in RFCs to Indicate Requirement Levels (RFC 2119). March 1997.
[RFC4627] The application/json Media Type for JavaScript Object Notation (JSON) (RFC 4627). D. Crockford. July 2006.
[UIEvents] UI Events.
[RFC4122] A Universally Unique IDentifier (UUID) URN Namespace (RFC 4122). P. Leach, et al. July 2005.