Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save robertknight/b539e55795ac089d0b69 to your computer and use it in GitHub Desktop.
Save robertknight/b539e55795ac089d0b69 to your computer and use it in GitHub Desktop.
ePubJS customized embedding notes

epub.js is working on integrating Hypothesis into their reader. Although ePub content is HTML and therefore they can use Hypothesis' existing code for annotating web content, their reader is somewhat different than a typical web page and consequently the built-in method of scrolling to an annotation when the user selects it in the sidebar does not work.

epub.js' reader consists of viewer controls, with an <iframe> in the middle of the page, which displays the HTML for the current chapter. The <iframe> can be set to be the full height of the document.

The current integration works by embedding Hypothesis in the outer document, and also loading Hypothesis into the <iframe> but only loading Annotator.Guest in the <iframe> instead of the sidebar. The guest then connects to the sidebar in the host document.

When a user selects an annotation in the sidebar, H attempts to scroll the element into view in the <iframe>, but since the <iframe> extends to the full height of the <iframe>'s document, it does nothing. H doesn't know that it needs to scroll the parent window instead and in some embedding scenarios, that might not even be possible for the <iframe>'s content to do directly.

 --------------------- Outer document
 |--------| |--------|
 | epub   | |    H   |
 | iframe | | Sidebar|
 |        | |--------|
 ---------------------
 |        |
 |  ...   |

Goal

Enable viewer applications (such as ePub JS) with web-like content to listen for the user selecting and focusing annotations in the sidebar so they can any necessary custom behavior.

Plan

  1. Add events for when annotations are highlighted and selected by broadcasting events using the existing Annotator Plugin infrastructure. These events should include the annotation that was selected and the DOM argument as parameters. Customized embedders can hook into these events and implement any additional logic they need.
  2. Document in the API in http://h.readthedocs.org/en/latest/hacking/customized-embedding.html

From the embedders point of view, the API could look something like this, using the notation from the Plugin development docs:

// the user hovered over the annotation in the sidebar
annotationFocused(highlightElements, annotation)

// the user selected an annotation in the sidebar
annotationSelected(highlightElements, annotation)

Usage would be as follows:

window.hypothesisConfig = function () {
	var Annotator = this.Annotator;
	function Guest() {
		Annotator.Guest.apply(this, arguments);
		this.subscribe('annotationSelected', function (elements) {
			// custom scroll logic here
		});
	}
	Guest.prototype = Object.create(Annotator.Guest.prototype);
		
	return {
     constructor: Guest,
     ...
    };
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment