From ee36f2f029a7cf77ed14fe2617058c96d97d8280 Mon Sep 17 00:00:00 2001 From: Aleksander Adamowski Date: Tue, 15 Oct 2013 21:02:47 +0200 Subject: [PATCH] Internal link handling: * Intercept internal link clicks. * Attach internal link clicks to proper reader navigation within the spine. * Open external links in a new browser window, separate from the reader. Change-Id: I14bb17a493e678e8a6331b99b7bb90c4aab4aa69 --- epub-modules/epub-renderer/end.frag | 65 ++++++++++++++++++++++----- epub-modules/epub-renderer/start.frag | 4 +- 2 files changed, 57 insertions(+), 12 deletions(-) diff --git a/epub-modules/epub-renderer/end.frag b/epub-modules/epub-renderer/end.frag index b83165ac8..d843938fa 100644 --- a/epub-modules/epub-renderer/end.frag +++ b/epub-modules/epub-renderer/end.frag @@ -9,12 +9,57 @@ return new SpineItem(); }; - var loadIframeFunctionGenerator = function(epubFetch) { - return function(iframe, src, callback, context) { + var loadIframeFunctionGenerator = function(epubFetch, reader) { + return function(iframe, src, origCallback, context) { + var callback = function(success) { + var epubContentDocument = this.$iframe[0].contentDocument; + $('a', epubContentDocument).click(function (clickEvent) { + // Check for both href and xlink:href attribute and get value + var href; + if (clickEvent.currentTarget.attributes["xlink:href"]) { + href = clickEvent.currentTarget.attributes["xlink:href"].value; + } + else { + href = clickEvent.currentTarget.attributes["href"].value; + } + var hrefUri = new URI(href); + var hrefIsRelative = hrefUri.is('relative'); + var hrefUriHasFilename = hrefUri.filename(); + var overrideClickEvent = false; + + if (hrefIsRelative) { + // TODO: + if (hrefUriHasFilename /* TODO: && check whether href actually resolves to a spine item */) { + + var currentSpineItemUri = new URI(context.currentSpineItem.href); + var openedSpineItemUri = hrefUri.absoluteTo(currentSpineItemUri); + var idref = openedSpineItemUri.pathname(); + var hashFrag = openedSpineItemUri.fragment(); + var spineItem = context.spine.getItemByHref(idref); + var pageData = new ReadiumSDK.Models.PageOpenRequest(spineItem); + if (hashFrag) { + pageData.setElementId(hashFrag); + } + reader.openPage(pageData); + overrideClickEvent = true; + } // otherwise it's probably just a hash frag that needs to be handled by browser's default handling + } else { + // It's an absolute URL to a remote site - open it in a separate window outside the reader + window.open(href, '_blank'); + overrideClickEvent = true; + } + + if (overrideClickEvent) { + clickEvent.preventDefault(); + clickEvent.stopPropagation(); + } + }); + origCallback.call(this, success); + } if (epubFetch.isPackageExploded()) { return origLoadIframeFunction(iframe, src, callback, context); } else { - var onLoadWrapperFunction = function(boolArg) { + var onLoadWrapperFunction = function(success) { var context = this; var itemHref = context.currentSpineItem.href; epubFetch.relativeToPackageFetchFileContents(itemHref, 'text', function(contentDocumentText) { @@ -25,14 +70,14 @@ var contentDocument = iframe.contentDocument; contentDocument.replaceChild(resolvedContentDocumentDom.documentElement, contentDocument.documentElement); - callback.call(context, boolArg); + callback.call(context, success); }); }, function(err) { if (err.message) { console.error(err.message); }; console.error(err); - callback.call(context, boolArg); + callback.call(context, success); }); }; // Feed an artificial empty HTML document to the IFRAME, then let the wrapper onload function @@ -46,15 +91,15 @@ }; var EpubRendererModule = function (epubFetch, elementToBindReaderTo, packageData) { - /* - * Patch the ReadiumSDK.Helpers.LoadIframe global function to support zipped EPUB packages: - */ - ReadiumSDK.Helpers.LoadIframe = loadIframeFunctionGenerator(epubFetch); - var reader = new ReadiumSDK.Views.ReaderView({ el: elementToBindReaderTo }); + /* + * Patch the ReadiumSDK.Helpers.LoadIframe global function to support zipped EPUB packages: + */ + ReadiumSDK.Helpers.LoadIframe = loadIframeFunctionGenerator(epubFetch, reader); + // Description: The public interface return { diff --git a/epub-modules/epub-renderer/start.frag b/epub-modules/epub-renderer/start.frag index 753b076f4..b1acf4d23 100644 --- a/epub-modules/epub-renderer/start.frag +++ b/epub-modules/epub-renderer/start.frag @@ -1,3 +1,3 @@ -define('epub_renderer_module', ['require', 'module', 'jquery', 'underscore', 'backbone'], +define('epub_renderer_module', ['require', 'module', 'jquery', 'underscore', 'backbone', 'URIjs/URI'], - function (require, module, $, _, Backbone) { + function (require, module, $, _, Backbone, URI) {