1
0
Fork 0
mirror of https://github.com/futurepress/epub.js.git synced 2025-10-03 14:59:18 +02:00

update cfi handling

This commit is contained in:
fchasen 2014-05-18 23:56:15 -07:00
parent 48612637d4
commit b6c8d3ea7d
16 changed files with 727 additions and 291 deletions

2
books

@ -1 +1 @@
Subproject commit ab9755a74714b647290c861f666515de220935d8 Subproject commit 950c742b3d66cc7ac53bd0663a41315f001da1c4

View file

@ -2759,8 +2759,14 @@ EPUBJS.Book.prototype.listenToRenderer = function(renderer){
// Prevents the Render from loading a different chapter when back button is pressed // Prevents the Render from loading a different chapter when back button is pressed
EPUBJS.Book.prototype.loadChange = function(url){ EPUBJS.Book.prototype.loadChange = function(url){
var uri = EPUBJS.core.uri(url); var uri = EPUBJS.core.uri(url);
if(!this._rendering && this.currentChapter && uri.path != this.currentChapter.absolute){ var chapter;
// console.warn("Miss Match", uri.path, this.currentChapter.absolute);
if(this.currentChapter) {
chapter = EPUBJS.core.uri(this.currentChapter.absolute);
}
if(!this._rendering && this.currentChapter && uri.path != chapter.path){
console.warn("Miss Match", uri.path, this.currentChapter.absolute);
this.goto(uri.filename); this.goto(uri.filename);
} }
}; };
@ -2985,7 +2991,7 @@ EPUBJS.Book.prototype.displayChapter = function(chap, end, deferred){
} }
if(this._rendering) { if(this._rendering || this._rendering) {
// Pass along the current defer // Pass along the current defer
this._displayQ.enqueue("displayChapter", [chap, end, defer]); this._displayQ.enqueue("displayChapter", [chap, end, defer]);
return defer.promise; return defer.promise;
@ -3011,23 +3017,18 @@ EPUBJS.Book.prototype.displayChapter = function(chap, end, deferred){
this._rendering = true; this._rendering = true;
render = book.renderer.displayChapter(chapter, this.globalLayoutProperties); render = book.renderer.displayChapter(chapter, this.globalLayoutProperties);
if(cfi) {
book.renderer.gotoCfi(cfi);
} else if(end) {
book.renderer.lastPage();
}
//-- Success, Clear render queue //-- Success, Clear render queue
render.then(function(rendered){ render.then(function(rendered){
// var inwait; // var inwait;
//-- Set the book's spine position //-- Set the book's spine position
book.spinePos = pos; book.spinePos = pos;
if(cfi) { defer.resolve(book.renderer);
rendered.gotoCfi(cfi);
defer.resolve(book.renderer);
} else if(end) {
rendered.lastPage();
defer.resolve(book.renderer);
} else {
defer.resolve(book.renderer);
}
if(!book.settings.fromStorage && if(!book.settings.fromStorage &&
!book.settings.contained) { !book.settings.contained) {
@ -3037,6 +3038,9 @@ EPUBJS.Book.prototype.displayChapter = function(chap, end, deferred){
book.currentChapter = chapter; book.currentChapter = chapter;
book._rendering = false; book._rendering = false;
book._displayQ.dequeue(); book._displayQ.dequeue();
if(book._displayQ.length() === 0) {
book._gotoQ.dequeue();
}
}, function(error) { }, function(error) {
// handle errors in either of the two requests // handle errors in either of the two requests
@ -3136,12 +3140,14 @@ EPUBJS.Book.prototype.gotoCfi = function(cfiString, defer){
deferred = defer || new RSVP.defer(); deferred = defer || new RSVP.defer();
if(!this.isRendered) { if(!this.isRendered) {
console.warn("Not yet Rendered");
this.settings.previousLocationCfi = cfiString; this.settings.previousLocationCfi = cfiString;
return false; return false;
} }
// Currently going to a chapter // Currently going to a chapter
if(this._moving) { if(this._moving || this._rendering) {
console.warn("Renderer is moving");
this._gotoQ.enqueue("gotoCfi", [cfiString, deferred]); this._gotoQ.enqueue("gotoCfi", [cfiString, deferred]);
return false; return false;
} }
@ -3174,8 +3180,8 @@ EPUBJS.Book.prototype.gotoCfi = function(cfiString, defer){
this.spinePos = spinePos; this.spinePos = spinePos;
render = this.renderer.displayChapter(this.currentChapter, this.globalLayoutProperties); render = this.renderer.displayChapter(this.currentChapter, this.globalLayoutProperties);
this.renderer.gotoCfi(cfi);
render.then(function(rendered){ render.then(function(rendered){
rendered.gotoCfi(cfi);
this._moving = false; this._moving = false;
deferred.resolve(rendered.currentLocationCfi); deferred.resolve(rendered.currentLocationCfi);
}.bind(this)); }.bind(this));
@ -3199,7 +3205,7 @@ EPUBJS.Book.prototype.gotoHref = function(url, defer){
} }
// Currently going to a chapter // Currently going to a chapter
if(this._moving) { if(this._moving || this._rendering) {
this._gotoQ.enqueue("gotoHref", [url, deferred]); this._gotoQ.enqueue("gotoHref", [url, deferred]);
return false; return false;
} }
@ -3311,12 +3317,20 @@ EPUBJS.Book.prototype.fromStorage = function(stored) {
*/ */
EPUBJS.Book.prototype.setStyle = function(style, val, prefixed) { EPUBJS.Book.prototype.setStyle = function(style, val, prefixed) {
var noreflow = ["color", "background", "background-color"];
if(!this.isRendered) return this._q.enqueue("setStyle", arguments); if(!this.isRendered) return this._q.enqueue("setStyle", arguments);
this.settings.styles[style] = val; this.settings.styles[style] = val;
this.renderer.setStyle(style, val, prefixed); this.renderer.setStyle(style, val, prefixed);
this.renderer.reformat();
if(noreflow.indexOf(style) === -1) {
clearTimeout(this.reformatTimeout);
this.reformatTimeout = setTimeout(function(){
this.renderer.reformat();
}.bind(this), 10);
}
}; };
EPUBJS.Book.prototype.removeStyle = function(style) { EPUBJS.Book.prototype.removeStyle = function(style) {
@ -3570,8 +3584,8 @@ EPUBJS.Chapter.prototype.cfiFromRange = function(_range) {
// Check for Contents // Check for Contents
if(!this.contents) return; if(!this.contents) return;
startXpath = EPUBJS.core.getElementXPath(_range.startContainer); startXpath = EPUBJS.core.getElementXPath(_range.startContainer);
// console.log(startContainer)
endXpath = EPUBJS.core.getElementXPath(_range.endContainer); endXpath = EPUBJS.core.getElementXPath(_range.endContainer);
startContainer = this.contents.evaluate(startXpath, this.contents, EPUBJS.core.nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; startContainer = this.contents.evaluate(startXpath, this.contents, EPUBJS.core.nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
@ -3580,7 +3594,6 @@ EPUBJS.Chapter.prototype.cfiFromRange = function(_range) {
} }
range = this.contents.createRange(); range = this.contents.createRange();
// Find Exact Range in original document // Find Exact Range in original document
if(startContainer) { if(startContainer) {
try { try {
@ -3589,7 +3602,7 @@ EPUBJS.Chapter.prototype.cfiFromRange = function(_range) {
range.setEnd(endContainer, _range.endOffset); range.setEnd(endContainer, _range.endOffset);
} }
} catch (e) { } catch (e) {
// console.log("missed"); console.log("missed");
startContainer = false; startContainer = false;
} }
@ -3597,7 +3610,7 @@ EPUBJS.Chapter.prototype.cfiFromRange = function(_range) {
// Fuzzy Match // Fuzzy Match
if(!startContainer) { if(!startContainer) {
// console.log("not found, try fuzzy match"); console.log("not found, try fuzzy match");
cleanStartTextContent = EPUBJS.core.cleanStringForXpath(_range.startContainer.textContent); cleanStartTextContent = EPUBJS.core.cleanStringForXpath(_range.startContainer.textContent);
startXpath = "//text()[contains(.," + cleanStartTextContent + ")]"; startXpath = "//text()[contains(.," + cleanStartTextContent + ")]";
@ -3755,6 +3768,7 @@ EPUBJS.core.uri = function(url){
if(search != -1) { if(search != -1) {
uri.search = url.slice(search + 1); uri.search = url.slice(search + 1);
url = url.slice(0, search); url = url.slice(0, search);
href = url;
} }
if(doubleSlash != -1) { if(doubleSlash != -1) {
@ -4029,11 +4043,12 @@ EPUBJS.core.queue = function(_scope){
if(_q.length) { if(_q.length) {
inwait = _q.shift(); inwait = _q.shift();
// Defer to any current tasks // Defer to any current tasks
setTimeout(function(){ // setTimeout(function(){
scope[inwait.funcName].apply(inwait.context || scope, inwait.args); scope[inwait.funcName].apply(inwait.context || scope, inwait.args);
}, 0); // }, 0);
} }
}; };
// Run All // Run All
var flush = function(){ var flush = function(){
while(_q.length) { while(_q.length) {
@ -4044,11 +4059,17 @@ EPUBJS.core.queue = function(_scope){
var clear = function(){ var clear = function(){
_q = []; _q = [];
}; };
var length = function(){
return _q.length;
};
return { return {
"enqueue" : enqueue, "enqueue" : enqueue,
"dequeue" : dequeue, "dequeue" : dequeue,
"flush" : flush, "flush" : flush,
"clear" : clear "clear" : clear,
"length" : length
}; };
}; };
@ -4067,16 +4088,20 @@ EPUBJS.core.getElementXPath = function(element) {
EPUBJS.core.getElementTreeXPath = function(element) { EPUBJS.core.getElementTreeXPath = function(element) {
var paths = []; var paths = [];
var isXhtml = (element.ownerDocument.documentElement.getAttribute('xmlns') === "http://www.w3.org/1999/xhtml"); var isXhtml = (element.ownerDocument.documentElement.getAttribute('xmlns') === "http://www.w3.org/1999/xhtml");
var index, nodeName, tagName, pathIndex;
if(element.nodeType === 3){ if(element.nodeType === Node.TEXT_NODE){
paths.push("text()"); // index = Array.prototype.indexOf.call(element.parentNode.childNodes, element) + 1;
element = element.parentElement; index = EPUBJS.core.indexOfTextNode(element) + 1;
paths.push("text()["+index+"]");
element = element.parentNode;
} }
// Use nodeName (instead of localName) so namespace prefix is included (if any). // Use nodeName (instead of localName) so namespace prefix is included (if any).
for (; element && element.nodeType == 1; element = element.parentNode) for (; element && element.nodeType == 1; element = element.parentNode)
{ {
var index = 0; index = 0;
for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling) for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling)
{ {
// Ignore document type declaration. // Ignore document type declaration.
@ -4087,9 +4112,9 @@ EPUBJS.core.getElementTreeXPath = function(element) {
++index; ++index;
} }
} }
var nodeName = element.nodeName.toLowerCase(); nodeName = element.nodeName.toLowerCase();
var tagName = (isXhtml ? "xhtml:" + nodeName : nodeName); tagName = (isXhtml ? "xhtml:" + nodeName : nodeName);
var pathIndex = (index ? "[" + (index+1) + "]" : ""); pathIndex = (index ? "[" + (index+1) + "]" : "");
paths.splice(0, 0, tagName + pathIndex); paths.splice(0, 0, tagName + pathIndex);
} }
@ -4119,6 +4144,22 @@ EPUBJS.core.cleanStringForXpath = function(str) {
}); });
return "concat(\'\'," + parts.join(",") + ")"; return "concat(\'\'," + parts.join(",") + ")";
}; };
EPUBJS.core.indexOfTextNode = function(textNode){
var parent = textNode.parentElement;
var children = parent.childNodes;
var sib;
var index = -1;
for (var i = 0; i < children.length; i++) {
sib = children[i];
if(sib.nodeType === Node.TEXT_NODE){
index++;
}
if(sib == textNode) break;
}
return index;
};
EPUBJS.EpubCFI = function(cfiStr){ EPUBJS.EpubCFI = function(cfiStr){
if(cfiStr) return this.parse(cfiStr); if(cfiStr) return this.parse(cfiStr);
}; };
@ -4518,12 +4559,13 @@ EPUBJS.EpubCFI.prototype.generateCfiFromRangeAnchor = function(range, base) {
EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) { EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) {
var start, startElement, startSteps, startPath, startOffset, startIndex; var start, startElement, startSteps, startPath, startOffset, startIndex;
var end, endElement, endSteps, endPath, endOffset, endIndex; var end, endElement, endSteps, endPath, endOffset, endIndex;
start = range.startContainer; start = range.startContainer;
if(start.nodeType === 3) { // text node if(start.nodeType === 3) { // text node
startElement = start.parentElement; startElement = start.parentElement;
startIndex = 1 + (2 * Array.prototype.indexOf.call(startElement.childNodes, start)); //startIndex = 1 + (2 * Array.prototype.indexOf.call(startElement.childNodes, start));
startIndex = 1 + (2 * EPUBJS.core.indexOfTextNode(start));
startSteps = this.pathTo(startElement); startSteps = this.pathTo(startElement);
} else if(range.collapsed) { } else if(range.collapsed) {
return this.generateCfiFromElement(start, base); // single element return this.generateCfiFromElement(start, base); // single element
@ -4539,7 +4581,9 @@ EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) {
if(end.nodeType === 3) { // text node if(end.nodeType === 3) { // text node
endElement = end.parentElement; endElement = end.parentElement;
endIndex = 1 + (2 * Array.prototype.indexOf.call(endElement.childNodes, end)); // endIndex = 1 + (2 * Array.prototype.indexOf.call(endElement.childNodes, end));
endIndex = 1 + (2 * EPUBJS.core.indexOfTextNode(end));
endSteps = this.pathTo(endElement); endSteps = this.pathTo(endElement);
} else { } else {
endSteps = this.pathTo(end); endSteps = this.pathTo(end);
@ -4597,18 +4641,21 @@ EPUBJS.EpubCFI.prototype.generateRangeFromCfi = function(cfi, _doc) {
// Get the terminal step // Get the terminal step
lastStep = cfi.steps[cfi.steps.length-1]; lastStep = cfi.steps[cfi.steps.length-1];
startContainer = doc.evaluate(xpath, doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; startContainer = doc.evaluate(xpath, doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if(!startContainer) { if(!startContainer) {
return null; return null;
} }
if(startContainer && cfi.characterOffset >= 0) { if(startContainer && cfi.characterOffset >= 0) {
textLength = startContainer.length; textLength = startContainer.length;
if(cfi.characterOffset < textLength) { if(cfi.characterOffset < textLength) {
range.setStart(startContainer, cfi.characterOffset); range.setStart(startContainer, cfi.characterOffset);
range.setEnd(startContainer, textLength ); range.setEnd(startContainer, textLength );
} else { } else {
range.setStart(startContainer, cfi.characterOffset - 1 ); console.debug("offset greater than length:", cfi.characterOffset, textLength);
range.setEnd(startContainer, cfi.characterOffset ); range.setStart(startContainer, textLength - 1 );
range.setEnd(startContainer, textLength );
} }
} else if(startContainer) { } else if(startContainer) {
range.selectNode(startContainer); range.selectNode(startContainer);
@ -4783,6 +4830,7 @@ EPUBJS.Layout.Reflowable.prototype.format = function(documentElement, _width, _h
var columnAxis = EPUBJS.core.prefixed('columnAxis'); var columnAxis = EPUBJS.core.prefixed('columnAxis');
var columnGap = EPUBJS.core.prefixed('columnGap'); var columnGap = EPUBJS.core.prefixed('columnGap');
var columnWidth = EPUBJS.core.prefixed('columnWidth'); var columnWidth = EPUBJS.core.prefixed('columnWidth');
var columnFill = EPUBJS.core.prefixed('columnFill');
//-- Check the width and create even width columns //-- Check the width and create even width columns
var width = Math.floor(_width); var width = Math.floor(_width);
@ -4804,6 +4852,7 @@ EPUBJS.Layout.Reflowable.prototype.format = function(documentElement, _width, _h
//-- Add columns //-- Add columns
documentElement.style[columnAxis] = "horizontal"; documentElement.style[columnAxis] = "horizontal";
documentElement.style[columnFill] = "auto";
documentElement.style[columnWidth] = width+"px"; documentElement.style[columnWidth] = width+"px";
documentElement.style[columnGap] = gap+"px"; documentElement.style[columnGap] = gap+"px";
this.colWidth = width; this.colWidth = width;
@ -4836,6 +4885,7 @@ EPUBJS.Layout.ReflowableSpreads.prototype.format = function(documentElement, _wi
var columnAxis = EPUBJS.core.prefixed('columnAxis'); var columnAxis = EPUBJS.core.prefixed('columnAxis');
var columnGap = EPUBJS.core.prefixed('columnGap'); var columnGap = EPUBJS.core.prefixed('columnGap');
var columnWidth = EPUBJS.core.prefixed('columnWidth'); var columnWidth = EPUBJS.core.prefixed('columnWidth');
var columnFill = EPUBJS.core.prefixed('columnFill');
var divisor = 2, var divisor = 2,
cutoff = 800; cutoff = 800;
@ -4864,8 +4914,10 @@ EPUBJS.Layout.ReflowableSpreads.prototype.format = function(documentElement, _wi
//-- Add columns //-- Add columns
documentElement.style[columnAxis] = "horizontal"; documentElement.style[columnAxis] = "horizontal";
documentElement.style[columnFill] = "auto";
documentElement.style[columnGap] = gap+"px"; documentElement.style[columnGap] = gap+"px";
documentElement.style[columnWidth] = colWidth+"px"; documentElement.style[columnWidth] = colWidth+"px";
this.colWidth = colWidth; this.colWidth = colWidth;
this.gap = gap; this.gap = gap;
return { return {
@ -5566,7 +5618,9 @@ EPUBJS.Render.Iframe.prototype.load = function(url){
EPUBJS.Render.Iframe.prototype.loaded = function(v){ EPUBJS.Render.Iframe.prototype.loaded = function(v){
var url = this.iframe.contentWindow.location.href; var url = this.iframe.contentWindow.location.href;
this.trigger("render:loaded", url); if(url != "about:blank"){
this.trigger("render:loaded", url);
}
}; };
// Resize the iframe to the given width and height // Resize the iframe to the given width and height
@ -5739,7 +5793,7 @@ EPUBJS.Renderer = function(renderMethod, hidden) {
this.spreads = true; this.spreads = true;
this.isForcedSingle = false; this.isForcedSingle = false;
this.resized = _.throttle(this.onResized.bind(this), 10); this.resized = _.debounce(this.onResized.bind(this), 100);
this.layoutSettings = {}; this.layoutSettings = {};
@ -5752,6 +5806,8 @@ EPUBJS.Renderer = function(renderMethod, hidden) {
//-- Queue up page changes if page map isn't ready //-- Queue up page changes if page map isn't ready
this._q = EPUBJS.core.queue(this); this._q = EPUBJS.core.queue(this);
this._moving = false;
}; };
@ -5805,14 +5861,23 @@ EPUBJS.Renderer.prototype.initialize = function(element, width, height){
*/ */
EPUBJS.Renderer.prototype.displayChapter = function(chapter, globalLayout){ EPUBJS.Renderer.prototype.displayChapter = function(chapter, globalLayout){
var store = false; var store = false;
if(this._moving) {
console.error("Rendering In Progress");
return;
}
this._moving = true;
// Get the url string from the chapter (may be from storage) // Get the url string from the chapter (may be from storage)
return chapter.url(). return chapter.url().
then(function(url) { then(function(url) {
// Unload the previous chapter listener // Unload the previous chapter listener
if(this.currentChapter) { if(this.currentChapter) {
this.currentChapter.unload(); // Remove stored blobs this.currentChapter.unload(); // Remove stored blobs
this.render.window.removeEventListener("resize", this.resized);
if(this.render.window){
this.render.window.removeEventListener("resize", this.resized);
}
this.removeEventListeners(); this.removeEventListeners();
this.removeSelectionListeners(); this.removeSelectionListeners();
this.trigger("renderer:chapterUnloaded"); this.trigger("renderer:chapterUnloaded");
@ -5820,10 +5885,9 @@ EPUBJS.Renderer.prototype.displayChapter = function(chapter, globalLayout){
this.doc = null; this.doc = null;
this.pageMap = null; this.pageMap = null;
} }
this.currentChapter = chapter; this.currentChapter = chapter;
this.chapterPos = 1; this.chapterPos = 1;
this.pageMap = null;
this.currentChapterCfiBase = chapter.cfiBase; this.currentChapterCfiBase = chapter.cfiBase;
this.layoutSettings = this.reconcileLayoutSettings(globalLayout, chapter.properties); this.layoutSettings = this.reconcileLayoutSettings(globalLayout, chapter.properties);
@ -5861,11 +5925,11 @@ EPUBJS.Renderer.prototype.load = function(url){
this.formated = this.layout.format(contents, this.render.width, this.render.height, this.gap); this.formated = this.layout.format(contents, this.render.width, this.render.height, this.gap);
this.render.setPageDimensions(this.formated.pageWidth, this.formated.pageHeight); this.render.setPageDimensions(this.formated.pageWidth, this.formated.pageHeight);
// window.addEventListener("orientationchange", this.onResized.bind(this), false);
if(!this.initWidth && !this.initHeight){ if(!this.initWidth && !this.initHeight){
this.render.window.addEventListener("resize", this.resized, false); this.render.window.addEventListener("resize", this.resized, false);
} }
this.addEventListeners(); this.addEventListeners();
this.addSelectionListeners(); this.addSelectionListeners();
@ -5873,18 +5937,24 @@ EPUBJS.Renderer.prototype.load = function(url){
this.beforeDisplay(function(){ this.beforeDisplay(function(){
var pages = this.layout.calculatePages(); var pages = this.layout.calculatePages();
var msg = this.currentChapter; var msg = this.currentChapter;
this.updatePages(pages); var queued = this._q.length();
this._moving = false;
this.updatePages(pages);
this.visibleRangeCfi = this.getVisibleRangeCfi(); this.visibleRangeCfi = this.getVisibleRangeCfi();
this.currentLocationCfi = this.visibleRangeCfi.start; this.currentLocationCfi = this.visibleRangeCfi.start;
this.trigger("renderer:locationChanged", this.currentLocationCfi);
this.trigger("renderer:visibleRangeChanged", this.visibleRangeCfi);
msg.cfi = this.currentLocationCfi; if(queued === 0) {
this.trigger("renderer:locationChanged", this.currentLocationCfi);
this.trigger("renderer:visibleRangeChanged", this.visibleRangeCfi);
}
msg.cfi = this.currentLocationCfi; //TODO: why is this cfi passed to chapterDisplayed
this.trigger("renderer:chapterDisplayed", msg); this.trigger("renderer:chapterDisplayed", msg);
this.visible(true); this.visible(true);
deferred.resolve(this); //-- why does this return the renderer? deferred.resolve(this); //-- why does this return the renderer?
}.bind(this)); }.bind(this));
@ -5975,9 +6045,17 @@ EPUBJS.Renderer.prototype.beforeDisplay = function(callback, renderer){
// Update the renderer with the information passed by the layout // Update the renderer with the information passed by the layout
EPUBJS.Renderer.prototype.updatePages = function(layout){ EPUBJS.Renderer.prototype.updatePages = function(layout){
this.pageMap = this.mapPage(); this.pageMap = this.mapPage();
this.displayedPages = layout.displayedPages; // this.displayedPages = layout.displayedPages;
this.currentChapter.pages = layout.pageCount;
if (this.spreads) {
this.displayedPages = Math.ceil(this.pageMap.length / 2);
} else {
this.displayedPages = this.pageMap.length;
}
// this.currentChapter.pages = layout.pageCount;
this.currentChapter.pages = this.pageMap.length;
this._q.flush(); this._q.flush();
}; };
@ -5987,8 +6065,13 @@ EPUBJS.Renderer.prototype.reformat = function(){
var formated, pages; var formated, pages;
if(!this.contents) return; if(!this.contents) return;
this.layoutMethod = this.determineLayout(this.layoutSettings); spreads = this.determineSpreads(this.minSpreadWidth);
this.layout = new EPUBJS.Layout[this.layoutMethod](); // Only re-layout if the spreads have switched
if(spreads != this.spreads){
this.spreads = spreads;
this.layoutMethod = this.determineLayout(this.layoutSettings);
this.layout = new EPUBJS.Layout[this.layoutMethod]();
}
this.formated = this.layout.format(this.contents, this.render.width, this.render.height, this.gap); this.formated = this.layout.format(this.contents, this.render.width, this.render.height, this.gap);
this.render.setPageDimensions(this.formated.pageWidth, this.formated.pageHeight); this.render.setPageDimensions(this.formated.pageWidth, this.formated.pageHeight);
@ -6059,8 +6142,8 @@ EPUBJS.Renderer.prototype.applyHeadTags = function(headTags) {
//-- NAVIGATION //-- NAVIGATION
EPUBJS.Renderer.prototype.page = function(pg){ EPUBJS.Renderer.prototype.page = function(pg){
if(!this.pageMap) { if(!this.pageMap) {
console.warn("pageMap not set, queuing");
this._q.enqueue("page", arguments); this._q.enqueue("page", arguments);
return true; return true;
} }
@ -6117,6 +6200,10 @@ EPUBJS.Renderer.prototype.pageByElement = function(el){
// Jump to the last page of the chapter // Jump to the last page of the chapter
EPUBJS.Renderer.prototype.lastPage = function(){ EPUBJS.Renderer.prototype.lastPage = function(){
if(this._moving) {
return this._q.enqueue("lastPage", arguments);
}
this.page(this.displayedPages); this.page(this.displayedPages);
}; };
@ -6231,7 +6318,7 @@ EPUBJS.Renderer.prototype.textSprint = function(root, func) {
}; };
EPUBJS.Renderer.prototype.sprint = function(root, func) { EPUBJS.Renderer.prototype.sprint = function(root, func) {
var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, false, false); var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, null, false);
var node; var node;
while ((node = treeWalker.nextNode())) { while ((node = treeWalker.nextNode())) {
func(node); func(node);
@ -6252,15 +6339,30 @@ EPUBJS.Renderer.prototype.mapPage = function(){
var cfi; var cfi;
var check = function(node) { var check = function(node) {
var elPos; var elPos;
var elRange;
var children = Array.prototype.slice.call(node.childNodes); var children = Array.prototype.slice.call(node.childNodes);
if (node.nodeType == Node.ELEMENT_NODE) { if (node.nodeType == Node.ELEMENT_NODE) {
elPos = node.getBoundingClientRect(); // elPos = node.getBoundingClientRect();
elRange = document.createRange();
elRange.selectNodeContents(node);
elPos = elRange.getBoundingClientRect();
if(!elPos || (elPos.width === 0 && elPos.height === 0)) { if(!elPos || (elPos.width === 0 && elPos.height === 0)) {
return; return;
} }
if(elPos.left + elPos.width > elLimit) { //-- Element starts new Col
if(elPos.left > elLimit) {
children.forEach(function(node){
if(node.nodeType == Node.TEXT_NODE &&
node.textContent.trim().length) {
checkText(node);
}
});
}
//-- Element Spans new Col
if(elPos.right > elLimit) {
children.forEach(function(node){ children.forEach(function(node){
if(node.nodeType == Node.TEXT_NODE && if(node.nodeType == Node.TEXT_NODE &&
node.textContent.trim().length) { node.textContent.trim().length) {
@ -6299,6 +6401,7 @@ EPUBJS.Renderer.prototype.mapPage = function(){
start: cfi, start: cfi,
end: null end: null
}); });
page += 1; page += 1;
limit = (width * page) - offset; limit = (width * page) - offset;
elLimit = limit; elLimit = limit;
@ -6336,6 +6439,7 @@ EPUBJS.Renderer.prototype.mapPage = function(){
ranges = null; ranges = null;
range = null; range = null;
root = null; root = null;
return map; return map;
}; };
@ -6560,7 +6664,7 @@ EPUBJS.Renderer.prototype.getVisibleRangeCfi = function(){
} }
if(!startRange) { if(!startRange) {
console.warn("page range miss:", pg); console.warn("page range miss:", pg, this.pageMap);
startRange = this.pageMap[this.pageMap.length-1]; startRange = this.pageMap[this.pageMap.length-1];
endRange = startRange; endRange = startRange;
} }
@ -6576,7 +6680,11 @@ EPUBJS.Renderer.prototype.gotoCfi = function(cfi){
var pg; var pg;
var marker; var marker;
var range; var range;
if(this._moving){
return this._q.enqueue("gotoCfi", arguments);
}
if(_.isString(cfi)){ if(_.isString(cfi)){
cfi = this.epubcfi.parse(cfi); cfi = this.epubcfi.parse(cfi);
} }
@ -6651,13 +6759,7 @@ EPUBJS.Renderer.prototype.resize = function(width, height, setSize){
this.render.resize(this.width, this.height); this.render.resize(this.width, this.height);
} }
spreads = this.determineSpreads(this.minSpreadWidth);
// Only re-layout if the spreads have switched
if(spreads != this.spreads){
this.spreads = spreads;
this.layoutMethod = this.determineLayout(this.layoutSettings);
this.layout = new EPUBJS.Layout[this.layoutMethod]();
}
if(this.contents){ if(this.contents){
this.reformat(); this.reformat();
@ -6679,7 +6781,9 @@ EPUBJS.Renderer.prototype.onResized = function(e) {
}; };
EPUBJS.Renderer.prototype.addEventListeners = function(){ EPUBJS.Renderer.prototype.addEventListeners = function(){
if(!this.render.document) {
return;
}
this.listenedEvents.forEach(function(eventName){ this.listenedEvents.forEach(function(eventName){
this.render.document.addEventListener(eventName, this.triggerEvent.bind(this), false); this.render.document.addEventListener(eventName, this.triggerEvent.bind(this), false);
}, this); }, this);
@ -6687,7 +6791,9 @@ EPUBJS.Renderer.prototype.addEventListeners = function(){
}; };
EPUBJS.Renderer.prototype.removeEventListeners = function(){ EPUBJS.Renderer.prototype.removeEventListeners = function(){
if(!this.render.document) {
return;
}
this.listenedEvents.forEach(function(eventName){ this.listenedEvents.forEach(function(eventName){
this.render.document.removeEventListener(eventName, this.triggerEvent, false); this.render.document.removeEventListener(eventName, this.triggerEvent, false);
}, this); }, this);
@ -6704,6 +6810,9 @@ EPUBJS.Renderer.prototype.addSelectionListeners = function(){
}; };
EPUBJS.Renderer.prototype.removeSelectionListeners = function(){ EPUBJS.Renderer.prototype.removeSelectionListeners = function(){
if(!this.render.document) {
return;
}
this.doc.removeEventListener("selectionchange", this.onSelectionChange, false); this.doc.removeEventListener("selectionchange", this.onSelectionChange, false);
}; };

File diff suppressed because one or more lines are too long

4
build/epub.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -2758,8 +2758,14 @@ EPUBJS.Book.prototype.listenToRenderer = function(renderer){
// Prevents the Render from loading a different chapter when back button is pressed // Prevents the Render from loading a different chapter when back button is pressed
EPUBJS.Book.prototype.loadChange = function(url){ EPUBJS.Book.prototype.loadChange = function(url){
var uri = EPUBJS.core.uri(url); var uri = EPUBJS.core.uri(url);
if(!this._rendering && this.currentChapter && uri.path != this.currentChapter.absolute){ var chapter;
// console.warn("Miss Match", uri.path, this.currentChapter.absolute);
if(this.currentChapter) {
chapter = EPUBJS.core.uri(this.currentChapter.absolute);
}
if(!this._rendering && this.currentChapter && uri.path != chapter.path){
console.warn("Miss Match", uri.path, this.currentChapter.absolute);
this.goto(uri.filename); this.goto(uri.filename);
} }
}; };
@ -2984,7 +2990,7 @@ EPUBJS.Book.prototype.displayChapter = function(chap, end, deferred){
} }
if(this._rendering) { if(this._rendering || this._rendering) {
// Pass along the current defer // Pass along the current defer
this._displayQ.enqueue("displayChapter", [chap, end, defer]); this._displayQ.enqueue("displayChapter", [chap, end, defer]);
return defer.promise; return defer.promise;
@ -3010,23 +3016,18 @@ EPUBJS.Book.prototype.displayChapter = function(chap, end, deferred){
this._rendering = true; this._rendering = true;
render = book.renderer.displayChapter(chapter, this.globalLayoutProperties); render = book.renderer.displayChapter(chapter, this.globalLayoutProperties);
if(cfi) {
book.renderer.gotoCfi(cfi);
} else if(end) {
book.renderer.lastPage();
}
//-- Success, Clear render queue //-- Success, Clear render queue
render.then(function(rendered){ render.then(function(rendered){
// var inwait; // var inwait;
//-- Set the book's spine position //-- Set the book's spine position
book.spinePos = pos; book.spinePos = pos;
if(cfi) { defer.resolve(book.renderer);
rendered.gotoCfi(cfi);
defer.resolve(book.renderer);
} else if(end) {
rendered.lastPage();
defer.resolve(book.renderer);
} else {
defer.resolve(book.renderer);
}
if(!book.settings.fromStorage && if(!book.settings.fromStorage &&
!book.settings.contained) { !book.settings.contained) {
@ -3036,6 +3037,9 @@ EPUBJS.Book.prototype.displayChapter = function(chap, end, deferred){
book.currentChapter = chapter; book.currentChapter = chapter;
book._rendering = false; book._rendering = false;
book._displayQ.dequeue(); book._displayQ.dequeue();
if(book._displayQ.length() === 0) {
book._gotoQ.dequeue();
}
}, function(error) { }, function(error) {
// handle errors in either of the two requests // handle errors in either of the two requests
@ -3135,12 +3139,14 @@ EPUBJS.Book.prototype.gotoCfi = function(cfiString, defer){
deferred = defer || new RSVP.defer(); deferred = defer || new RSVP.defer();
if(!this.isRendered) { if(!this.isRendered) {
console.warn("Not yet Rendered");
this.settings.previousLocationCfi = cfiString; this.settings.previousLocationCfi = cfiString;
return false; return false;
} }
// Currently going to a chapter // Currently going to a chapter
if(this._moving) { if(this._moving || this._rendering) {
console.warn("Renderer is moving");
this._gotoQ.enqueue("gotoCfi", [cfiString, deferred]); this._gotoQ.enqueue("gotoCfi", [cfiString, deferred]);
return false; return false;
} }
@ -3173,8 +3179,8 @@ EPUBJS.Book.prototype.gotoCfi = function(cfiString, defer){
this.spinePos = spinePos; this.spinePos = spinePos;
render = this.renderer.displayChapter(this.currentChapter, this.globalLayoutProperties); render = this.renderer.displayChapter(this.currentChapter, this.globalLayoutProperties);
this.renderer.gotoCfi(cfi);
render.then(function(rendered){ render.then(function(rendered){
rendered.gotoCfi(cfi);
this._moving = false; this._moving = false;
deferred.resolve(rendered.currentLocationCfi); deferred.resolve(rendered.currentLocationCfi);
}.bind(this)); }.bind(this));
@ -3198,7 +3204,7 @@ EPUBJS.Book.prototype.gotoHref = function(url, defer){
} }
// Currently going to a chapter // Currently going to a chapter
if(this._moving) { if(this._moving || this._rendering) {
this._gotoQ.enqueue("gotoHref", [url, deferred]); this._gotoQ.enqueue("gotoHref", [url, deferred]);
return false; return false;
} }
@ -3310,12 +3316,20 @@ EPUBJS.Book.prototype.fromStorage = function(stored) {
*/ */
EPUBJS.Book.prototype.setStyle = function(style, val, prefixed) { EPUBJS.Book.prototype.setStyle = function(style, val, prefixed) {
var noreflow = ["color", "background", "background-color"];
if(!this.isRendered) return this._q.enqueue("setStyle", arguments); if(!this.isRendered) return this._q.enqueue("setStyle", arguments);
this.settings.styles[style] = val; this.settings.styles[style] = val;
this.renderer.setStyle(style, val, prefixed); this.renderer.setStyle(style, val, prefixed);
this.renderer.reformat();
if(noreflow.indexOf(style) === -1) {
clearTimeout(this.reformatTimeout);
this.reformatTimeout = setTimeout(function(){
this.renderer.reformat();
}.bind(this), 10);
}
}; };
EPUBJS.Book.prototype.removeStyle = function(style) { EPUBJS.Book.prototype.removeStyle = function(style) {
@ -3569,8 +3583,8 @@ EPUBJS.Chapter.prototype.cfiFromRange = function(_range) {
// Check for Contents // Check for Contents
if(!this.contents) return; if(!this.contents) return;
startXpath = EPUBJS.core.getElementXPath(_range.startContainer); startXpath = EPUBJS.core.getElementXPath(_range.startContainer);
// console.log(startContainer)
endXpath = EPUBJS.core.getElementXPath(_range.endContainer); endXpath = EPUBJS.core.getElementXPath(_range.endContainer);
startContainer = this.contents.evaluate(startXpath, this.contents, EPUBJS.core.nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; startContainer = this.contents.evaluate(startXpath, this.contents, EPUBJS.core.nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
@ -3579,7 +3593,6 @@ EPUBJS.Chapter.prototype.cfiFromRange = function(_range) {
} }
range = this.contents.createRange(); range = this.contents.createRange();
// Find Exact Range in original document // Find Exact Range in original document
if(startContainer) { if(startContainer) {
try { try {
@ -3588,7 +3601,7 @@ EPUBJS.Chapter.prototype.cfiFromRange = function(_range) {
range.setEnd(endContainer, _range.endOffset); range.setEnd(endContainer, _range.endOffset);
} }
} catch (e) { } catch (e) {
// console.log("missed"); console.log("missed");
startContainer = false; startContainer = false;
} }
@ -3596,7 +3609,7 @@ EPUBJS.Chapter.prototype.cfiFromRange = function(_range) {
// Fuzzy Match // Fuzzy Match
if(!startContainer) { if(!startContainer) {
// console.log("not found, try fuzzy match"); console.log("not found, try fuzzy match");
cleanStartTextContent = EPUBJS.core.cleanStringForXpath(_range.startContainer.textContent); cleanStartTextContent = EPUBJS.core.cleanStringForXpath(_range.startContainer.textContent);
startXpath = "//text()[contains(.," + cleanStartTextContent + ")]"; startXpath = "//text()[contains(.," + cleanStartTextContent + ")]";
@ -3754,6 +3767,7 @@ EPUBJS.core.uri = function(url){
if(search != -1) { if(search != -1) {
uri.search = url.slice(search + 1); uri.search = url.slice(search + 1);
url = url.slice(0, search); url = url.slice(0, search);
href = url;
} }
if(doubleSlash != -1) { if(doubleSlash != -1) {
@ -4028,11 +4042,12 @@ EPUBJS.core.queue = function(_scope){
if(_q.length) { if(_q.length) {
inwait = _q.shift(); inwait = _q.shift();
// Defer to any current tasks // Defer to any current tasks
setTimeout(function(){ // setTimeout(function(){
scope[inwait.funcName].apply(inwait.context || scope, inwait.args); scope[inwait.funcName].apply(inwait.context || scope, inwait.args);
}, 0); // }, 0);
} }
}; };
// Run All // Run All
var flush = function(){ var flush = function(){
while(_q.length) { while(_q.length) {
@ -4043,11 +4058,17 @@ EPUBJS.core.queue = function(_scope){
var clear = function(){ var clear = function(){
_q = []; _q = [];
}; };
var length = function(){
return _q.length;
};
return { return {
"enqueue" : enqueue, "enqueue" : enqueue,
"dequeue" : dequeue, "dequeue" : dequeue,
"flush" : flush, "flush" : flush,
"clear" : clear "clear" : clear,
"length" : length
}; };
}; };
@ -4066,16 +4087,20 @@ EPUBJS.core.getElementXPath = function(element) {
EPUBJS.core.getElementTreeXPath = function(element) { EPUBJS.core.getElementTreeXPath = function(element) {
var paths = []; var paths = [];
var isXhtml = (element.ownerDocument.documentElement.getAttribute('xmlns') === "http://www.w3.org/1999/xhtml"); var isXhtml = (element.ownerDocument.documentElement.getAttribute('xmlns') === "http://www.w3.org/1999/xhtml");
var index, nodeName, tagName, pathIndex;
if(element.nodeType === 3){ if(element.nodeType === Node.TEXT_NODE){
paths.push("text()"); // index = Array.prototype.indexOf.call(element.parentNode.childNodes, element) + 1;
element = element.parentElement; index = EPUBJS.core.indexOfTextNode(element) + 1;
paths.push("text()["+index+"]");
element = element.parentNode;
} }
// Use nodeName (instead of localName) so namespace prefix is included (if any). // Use nodeName (instead of localName) so namespace prefix is included (if any).
for (; element && element.nodeType == 1; element = element.parentNode) for (; element && element.nodeType == 1; element = element.parentNode)
{ {
var index = 0; index = 0;
for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling) for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling)
{ {
// Ignore document type declaration. // Ignore document type declaration.
@ -4086,9 +4111,9 @@ EPUBJS.core.getElementTreeXPath = function(element) {
++index; ++index;
} }
} }
var nodeName = element.nodeName.toLowerCase(); nodeName = element.nodeName.toLowerCase();
var tagName = (isXhtml ? "xhtml:" + nodeName : nodeName); tagName = (isXhtml ? "xhtml:" + nodeName : nodeName);
var pathIndex = (index ? "[" + (index+1) + "]" : ""); pathIndex = (index ? "[" + (index+1) + "]" : "");
paths.splice(0, 0, tagName + pathIndex); paths.splice(0, 0, tagName + pathIndex);
} }
@ -4118,6 +4143,22 @@ EPUBJS.core.cleanStringForXpath = function(str) {
}); });
return "concat(\'\'," + parts.join(",") + ")"; return "concat(\'\'," + parts.join(",") + ")";
}; };
EPUBJS.core.indexOfTextNode = function(textNode){
var parent = textNode.parentElement;
var children = parent.childNodes;
var sib;
var index = -1;
for (var i = 0; i < children.length; i++) {
sib = children[i];
if(sib.nodeType === Node.TEXT_NODE){
index++;
}
if(sib == textNode) break;
}
return index;
};
EPUBJS.EpubCFI = function(cfiStr){ EPUBJS.EpubCFI = function(cfiStr){
if(cfiStr) return this.parse(cfiStr); if(cfiStr) return this.parse(cfiStr);
}; };
@ -4517,12 +4558,13 @@ EPUBJS.EpubCFI.prototype.generateCfiFromRangeAnchor = function(range, base) {
EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) { EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) {
var start, startElement, startSteps, startPath, startOffset, startIndex; var start, startElement, startSteps, startPath, startOffset, startIndex;
var end, endElement, endSteps, endPath, endOffset, endIndex; var end, endElement, endSteps, endPath, endOffset, endIndex;
start = range.startContainer; start = range.startContainer;
if(start.nodeType === 3) { // text node if(start.nodeType === 3) { // text node
startElement = start.parentElement; startElement = start.parentElement;
startIndex = 1 + (2 * Array.prototype.indexOf.call(startElement.childNodes, start)); //startIndex = 1 + (2 * Array.prototype.indexOf.call(startElement.childNodes, start));
startIndex = 1 + (2 * EPUBJS.core.indexOfTextNode(start));
startSteps = this.pathTo(startElement); startSteps = this.pathTo(startElement);
} else if(range.collapsed) { } else if(range.collapsed) {
return this.generateCfiFromElement(start, base); // single element return this.generateCfiFromElement(start, base); // single element
@ -4538,7 +4580,9 @@ EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) {
if(end.nodeType === 3) { // text node if(end.nodeType === 3) { // text node
endElement = end.parentElement; endElement = end.parentElement;
endIndex = 1 + (2 * Array.prototype.indexOf.call(endElement.childNodes, end)); // endIndex = 1 + (2 * Array.prototype.indexOf.call(endElement.childNodes, end));
endIndex = 1 + (2 * EPUBJS.core.indexOfTextNode(end));
endSteps = this.pathTo(endElement); endSteps = this.pathTo(endElement);
} else { } else {
endSteps = this.pathTo(end); endSteps = this.pathTo(end);
@ -4596,18 +4640,21 @@ EPUBJS.EpubCFI.prototype.generateRangeFromCfi = function(cfi, _doc) {
// Get the terminal step // Get the terminal step
lastStep = cfi.steps[cfi.steps.length-1]; lastStep = cfi.steps[cfi.steps.length-1];
startContainer = doc.evaluate(xpath, doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; startContainer = doc.evaluate(xpath, doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if(!startContainer) { if(!startContainer) {
return null; return null;
} }
if(startContainer && cfi.characterOffset >= 0) { if(startContainer && cfi.characterOffset >= 0) {
textLength = startContainer.length; textLength = startContainer.length;
if(cfi.characterOffset < textLength) { if(cfi.characterOffset < textLength) {
range.setStart(startContainer, cfi.characterOffset); range.setStart(startContainer, cfi.characterOffset);
range.setEnd(startContainer, textLength ); range.setEnd(startContainer, textLength );
} else { } else {
range.setStart(startContainer, cfi.characterOffset - 1 ); console.debug("offset greater than length:", cfi.characterOffset, textLength);
range.setEnd(startContainer, cfi.characterOffset ); range.setStart(startContainer, textLength - 1 );
range.setEnd(startContainer, textLength );
} }
} else if(startContainer) { } else if(startContainer) {
range.selectNode(startContainer); range.selectNode(startContainer);
@ -4782,6 +4829,7 @@ EPUBJS.Layout.Reflowable.prototype.format = function(documentElement, _width, _h
var columnAxis = EPUBJS.core.prefixed('columnAxis'); var columnAxis = EPUBJS.core.prefixed('columnAxis');
var columnGap = EPUBJS.core.prefixed('columnGap'); var columnGap = EPUBJS.core.prefixed('columnGap');
var columnWidth = EPUBJS.core.prefixed('columnWidth'); var columnWidth = EPUBJS.core.prefixed('columnWidth');
var columnFill = EPUBJS.core.prefixed('columnFill');
//-- Check the width and create even width columns //-- Check the width and create even width columns
var width = Math.floor(_width); var width = Math.floor(_width);
@ -4803,6 +4851,7 @@ EPUBJS.Layout.Reflowable.prototype.format = function(documentElement, _width, _h
//-- Add columns //-- Add columns
documentElement.style[columnAxis] = "horizontal"; documentElement.style[columnAxis] = "horizontal";
documentElement.style[columnFill] = "auto";
documentElement.style[columnWidth] = width+"px"; documentElement.style[columnWidth] = width+"px";
documentElement.style[columnGap] = gap+"px"; documentElement.style[columnGap] = gap+"px";
this.colWidth = width; this.colWidth = width;
@ -4835,6 +4884,7 @@ EPUBJS.Layout.ReflowableSpreads.prototype.format = function(documentElement, _wi
var columnAxis = EPUBJS.core.prefixed('columnAxis'); var columnAxis = EPUBJS.core.prefixed('columnAxis');
var columnGap = EPUBJS.core.prefixed('columnGap'); var columnGap = EPUBJS.core.prefixed('columnGap');
var columnWidth = EPUBJS.core.prefixed('columnWidth'); var columnWidth = EPUBJS.core.prefixed('columnWidth');
var columnFill = EPUBJS.core.prefixed('columnFill');
var divisor = 2, var divisor = 2,
cutoff = 800; cutoff = 800;
@ -4863,8 +4913,10 @@ EPUBJS.Layout.ReflowableSpreads.prototype.format = function(documentElement, _wi
//-- Add columns //-- Add columns
documentElement.style[columnAxis] = "horizontal"; documentElement.style[columnAxis] = "horizontal";
documentElement.style[columnFill] = "auto";
documentElement.style[columnGap] = gap+"px"; documentElement.style[columnGap] = gap+"px";
documentElement.style[columnWidth] = colWidth+"px"; documentElement.style[columnWidth] = colWidth+"px";
this.colWidth = colWidth; this.colWidth = colWidth;
this.gap = gap; this.gap = gap;
return { return {
@ -5565,7 +5617,9 @@ EPUBJS.Render.Iframe.prototype.load = function(url){
EPUBJS.Render.Iframe.prototype.loaded = function(v){ EPUBJS.Render.Iframe.prototype.loaded = function(v){
var url = this.iframe.contentWindow.location.href; var url = this.iframe.contentWindow.location.href;
this.trigger("render:loaded", url); if(url != "about:blank"){
this.trigger("render:loaded", url);
}
}; };
// Resize the iframe to the given width and height // Resize the iframe to the given width and height
@ -5738,7 +5792,7 @@ EPUBJS.Renderer = function(renderMethod, hidden) {
this.spreads = true; this.spreads = true;
this.isForcedSingle = false; this.isForcedSingle = false;
this.resized = _.throttle(this.onResized.bind(this), 10); this.resized = _.debounce(this.onResized.bind(this), 100);
this.layoutSettings = {}; this.layoutSettings = {};
@ -5751,6 +5805,8 @@ EPUBJS.Renderer = function(renderMethod, hidden) {
//-- Queue up page changes if page map isn't ready //-- Queue up page changes if page map isn't ready
this._q = EPUBJS.core.queue(this); this._q = EPUBJS.core.queue(this);
this._moving = false;
}; };
@ -5804,14 +5860,23 @@ EPUBJS.Renderer.prototype.initialize = function(element, width, height){
*/ */
EPUBJS.Renderer.prototype.displayChapter = function(chapter, globalLayout){ EPUBJS.Renderer.prototype.displayChapter = function(chapter, globalLayout){
var store = false; var store = false;
if(this._moving) {
console.error("Rendering In Progress");
return;
}
this._moving = true;
// Get the url string from the chapter (may be from storage) // Get the url string from the chapter (may be from storage)
return chapter.url(). return chapter.url().
then(function(url) { then(function(url) {
// Unload the previous chapter listener // Unload the previous chapter listener
if(this.currentChapter) { if(this.currentChapter) {
this.currentChapter.unload(); // Remove stored blobs this.currentChapter.unload(); // Remove stored blobs
this.render.window.removeEventListener("resize", this.resized);
if(this.render.window){
this.render.window.removeEventListener("resize", this.resized);
}
this.removeEventListeners(); this.removeEventListeners();
this.removeSelectionListeners(); this.removeSelectionListeners();
this.trigger("renderer:chapterUnloaded"); this.trigger("renderer:chapterUnloaded");
@ -5819,10 +5884,9 @@ EPUBJS.Renderer.prototype.displayChapter = function(chapter, globalLayout){
this.doc = null; this.doc = null;
this.pageMap = null; this.pageMap = null;
} }
this.currentChapter = chapter; this.currentChapter = chapter;
this.chapterPos = 1; this.chapterPos = 1;
this.pageMap = null;
this.currentChapterCfiBase = chapter.cfiBase; this.currentChapterCfiBase = chapter.cfiBase;
this.layoutSettings = this.reconcileLayoutSettings(globalLayout, chapter.properties); this.layoutSettings = this.reconcileLayoutSettings(globalLayout, chapter.properties);
@ -5860,11 +5924,11 @@ EPUBJS.Renderer.prototype.load = function(url){
this.formated = this.layout.format(contents, this.render.width, this.render.height, this.gap); this.formated = this.layout.format(contents, this.render.width, this.render.height, this.gap);
this.render.setPageDimensions(this.formated.pageWidth, this.formated.pageHeight); this.render.setPageDimensions(this.formated.pageWidth, this.formated.pageHeight);
// window.addEventListener("orientationchange", this.onResized.bind(this), false);
if(!this.initWidth && !this.initHeight){ if(!this.initWidth && !this.initHeight){
this.render.window.addEventListener("resize", this.resized, false); this.render.window.addEventListener("resize", this.resized, false);
} }
this.addEventListeners(); this.addEventListeners();
this.addSelectionListeners(); this.addSelectionListeners();
@ -5872,18 +5936,24 @@ EPUBJS.Renderer.prototype.load = function(url){
this.beforeDisplay(function(){ this.beforeDisplay(function(){
var pages = this.layout.calculatePages(); var pages = this.layout.calculatePages();
var msg = this.currentChapter; var msg = this.currentChapter;
this.updatePages(pages); var queued = this._q.length();
this._moving = false;
this.updatePages(pages);
this.visibleRangeCfi = this.getVisibleRangeCfi(); this.visibleRangeCfi = this.getVisibleRangeCfi();
this.currentLocationCfi = this.visibleRangeCfi.start; this.currentLocationCfi = this.visibleRangeCfi.start;
this.trigger("renderer:locationChanged", this.currentLocationCfi);
this.trigger("renderer:visibleRangeChanged", this.visibleRangeCfi);
msg.cfi = this.currentLocationCfi; if(queued === 0) {
this.trigger("renderer:locationChanged", this.currentLocationCfi);
this.trigger("renderer:visibleRangeChanged", this.visibleRangeCfi);
}
msg.cfi = this.currentLocationCfi; //TODO: why is this cfi passed to chapterDisplayed
this.trigger("renderer:chapterDisplayed", msg); this.trigger("renderer:chapterDisplayed", msg);
this.visible(true); this.visible(true);
deferred.resolve(this); //-- why does this return the renderer? deferred.resolve(this); //-- why does this return the renderer?
}.bind(this)); }.bind(this));
@ -5974,9 +6044,17 @@ EPUBJS.Renderer.prototype.beforeDisplay = function(callback, renderer){
// Update the renderer with the information passed by the layout // Update the renderer with the information passed by the layout
EPUBJS.Renderer.prototype.updatePages = function(layout){ EPUBJS.Renderer.prototype.updatePages = function(layout){
this.pageMap = this.mapPage(); this.pageMap = this.mapPage();
this.displayedPages = layout.displayedPages; // this.displayedPages = layout.displayedPages;
this.currentChapter.pages = layout.pageCount;
if (this.spreads) {
this.displayedPages = Math.ceil(this.pageMap.length / 2);
} else {
this.displayedPages = this.pageMap.length;
}
// this.currentChapter.pages = layout.pageCount;
this.currentChapter.pages = this.pageMap.length;
this._q.flush(); this._q.flush();
}; };
@ -5986,8 +6064,13 @@ EPUBJS.Renderer.prototype.reformat = function(){
var formated, pages; var formated, pages;
if(!this.contents) return; if(!this.contents) return;
this.layoutMethod = this.determineLayout(this.layoutSettings); spreads = this.determineSpreads(this.minSpreadWidth);
this.layout = new EPUBJS.Layout[this.layoutMethod](); // Only re-layout if the spreads have switched
if(spreads != this.spreads){
this.spreads = spreads;
this.layoutMethod = this.determineLayout(this.layoutSettings);
this.layout = new EPUBJS.Layout[this.layoutMethod]();
}
this.formated = this.layout.format(this.contents, this.render.width, this.render.height, this.gap); this.formated = this.layout.format(this.contents, this.render.width, this.render.height, this.gap);
this.render.setPageDimensions(this.formated.pageWidth, this.formated.pageHeight); this.render.setPageDimensions(this.formated.pageWidth, this.formated.pageHeight);
@ -6058,8 +6141,8 @@ EPUBJS.Renderer.prototype.applyHeadTags = function(headTags) {
//-- NAVIGATION //-- NAVIGATION
EPUBJS.Renderer.prototype.page = function(pg){ EPUBJS.Renderer.prototype.page = function(pg){
if(!this.pageMap) { if(!this.pageMap) {
console.warn("pageMap not set, queuing");
this._q.enqueue("page", arguments); this._q.enqueue("page", arguments);
return true; return true;
} }
@ -6116,6 +6199,10 @@ EPUBJS.Renderer.prototype.pageByElement = function(el){
// Jump to the last page of the chapter // Jump to the last page of the chapter
EPUBJS.Renderer.prototype.lastPage = function(){ EPUBJS.Renderer.prototype.lastPage = function(){
if(this._moving) {
return this._q.enqueue("lastPage", arguments);
}
this.page(this.displayedPages); this.page(this.displayedPages);
}; };
@ -6230,7 +6317,7 @@ EPUBJS.Renderer.prototype.textSprint = function(root, func) {
}; };
EPUBJS.Renderer.prototype.sprint = function(root, func) { EPUBJS.Renderer.prototype.sprint = function(root, func) {
var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, false, false); var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, null, false);
var node; var node;
while ((node = treeWalker.nextNode())) { while ((node = treeWalker.nextNode())) {
func(node); func(node);
@ -6251,15 +6338,30 @@ EPUBJS.Renderer.prototype.mapPage = function(){
var cfi; var cfi;
var check = function(node) { var check = function(node) {
var elPos; var elPos;
var elRange;
var children = Array.prototype.slice.call(node.childNodes); var children = Array.prototype.slice.call(node.childNodes);
if (node.nodeType == Node.ELEMENT_NODE) { if (node.nodeType == Node.ELEMENT_NODE) {
elPos = node.getBoundingClientRect(); // elPos = node.getBoundingClientRect();
elRange = document.createRange();
elRange.selectNodeContents(node);
elPos = elRange.getBoundingClientRect();
if(!elPos || (elPos.width === 0 && elPos.height === 0)) { if(!elPos || (elPos.width === 0 && elPos.height === 0)) {
return; return;
} }
if(elPos.left + elPos.width > elLimit) { //-- Element starts new Col
if(elPos.left > elLimit) {
children.forEach(function(node){
if(node.nodeType == Node.TEXT_NODE &&
node.textContent.trim().length) {
checkText(node);
}
});
}
//-- Element Spans new Col
if(elPos.right > elLimit) {
children.forEach(function(node){ children.forEach(function(node){
if(node.nodeType == Node.TEXT_NODE && if(node.nodeType == Node.TEXT_NODE &&
node.textContent.trim().length) { node.textContent.trim().length) {
@ -6298,6 +6400,7 @@ EPUBJS.Renderer.prototype.mapPage = function(){
start: cfi, start: cfi,
end: null end: null
}); });
page += 1; page += 1;
limit = (width * page) - offset; limit = (width * page) - offset;
elLimit = limit; elLimit = limit;
@ -6335,6 +6438,7 @@ EPUBJS.Renderer.prototype.mapPage = function(){
ranges = null; ranges = null;
range = null; range = null;
root = null; root = null;
return map; return map;
}; };
@ -6559,7 +6663,7 @@ EPUBJS.Renderer.prototype.getVisibleRangeCfi = function(){
} }
if(!startRange) { if(!startRange) {
console.warn("page range miss:", pg); console.warn("page range miss:", pg, this.pageMap);
startRange = this.pageMap[this.pageMap.length-1]; startRange = this.pageMap[this.pageMap.length-1];
endRange = startRange; endRange = startRange;
} }
@ -6575,7 +6679,11 @@ EPUBJS.Renderer.prototype.gotoCfi = function(cfi){
var pg; var pg;
var marker; var marker;
var range; var range;
if(this._moving){
return this._q.enqueue("gotoCfi", arguments);
}
if(_.isString(cfi)){ if(_.isString(cfi)){
cfi = this.epubcfi.parse(cfi); cfi = this.epubcfi.parse(cfi);
} }
@ -6650,13 +6758,7 @@ EPUBJS.Renderer.prototype.resize = function(width, height, setSize){
this.render.resize(this.width, this.height); this.render.resize(this.width, this.height);
} }
spreads = this.determineSpreads(this.minSpreadWidth);
// Only re-layout if the spreads have switched
if(spreads != this.spreads){
this.spreads = spreads;
this.layoutMethod = this.determineLayout(this.layoutSettings);
this.layout = new EPUBJS.Layout[this.layoutMethod]();
}
if(this.contents){ if(this.contents){
this.reformat(); this.reformat();
@ -6678,7 +6780,9 @@ EPUBJS.Renderer.prototype.onResized = function(e) {
}; };
EPUBJS.Renderer.prototype.addEventListeners = function(){ EPUBJS.Renderer.prototype.addEventListeners = function(){
if(!this.render.document) {
return;
}
this.listenedEvents.forEach(function(eventName){ this.listenedEvents.forEach(function(eventName){
this.render.document.addEventListener(eventName, this.triggerEvent.bind(this), false); this.render.document.addEventListener(eventName, this.triggerEvent.bind(this), false);
}, this); }, this);
@ -6686,7 +6790,9 @@ EPUBJS.Renderer.prototype.addEventListeners = function(){
}; };
EPUBJS.Renderer.prototype.removeEventListeners = function(){ EPUBJS.Renderer.prototype.removeEventListeners = function(){
if(!this.render.document) {
return;
}
this.listenedEvents.forEach(function(eventName){ this.listenedEvents.forEach(function(eventName){
this.render.document.removeEventListener(eventName, this.triggerEvent, false); this.render.document.removeEventListener(eventName, this.triggerEvent, false);
}, this); }, this);
@ -6703,6 +6809,9 @@ EPUBJS.Renderer.prototype.addSelectionListeners = function(){
}; };
EPUBJS.Renderer.prototype.removeSelectionListeners = function(){ EPUBJS.Renderer.prototype.removeSelectionListeners = function(){
if(!this.render.document) {
return;
}
this.doc.removeEventListener("selectionchange", this.onSelectionChange, false); this.doc.removeEventListener("selectionchange", this.onSelectionChange, false);
}; };

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

251
reader/js/epub.min.js vendored
View file

@ -2759,8 +2759,14 @@ EPUBJS.Book.prototype.listenToRenderer = function(renderer){
// Prevents the Render from loading a different chapter when back button is pressed // Prevents the Render from loading a different chapter when back button is pressed
EPUBJS.Book.prototype.loadChange = function(url){ EPUBJS.Book.prototype.loadChange = function(url){
var uri = EPUBJS.core.uri(url); var uri = EPUBJS.core.uri(url);
if(!this._rendering && this.currentChapter && uri.path != this.currentChapter.absolute){ var chapter;
// console.warn("Miss Match", uri.path, this.currentChapter.absolute);
if(this.currentChapter) {
chapter = EPUBJS.core.uri(this.currentChapter.absolute);
}
if(!this._rendering && this.currentChapter && uri.path != chapter.path){
console.warn("Miss Match", uri.path, this.currentChapter.absolute);
this.goto(uri.filename); this.goto(uri.filename);
} }
}; };
@ -2985,7 +2991,7 @@ EPUBJS.Book.prototype.displayChapter = function(chap, end, deferred){
} }
if(this._rendering) { if(this._rendering || this._rendering) {
// Pass along the current defer // Pass along the current defer
this._displayQ.enqueue("displayChapter", [chap, end, defer]); this._displayQ.enqueue("displayChapter", [chap, end, defer]);
return defer.promise; return defer.promise;
@ -3011,23 +3017,18 @@ EPUBJS.Book.prototype.displayChapter = function(chap, end, deferred){
this._rendering = true; this._rendering = true;
render = book.renderer.displayChapter(chapter, this.globalLayoutProperties); render = book.renderer.displayChapter(chapter, this.globalLayoutProperties);
if(cfi) {
book.renderer.gotoCfi(cfi);
} else if(end) {
book.renderer.lastPage();
}
//-- Success, Clear render queue //-- Success, Clear render queue
render.then(function(rendered){ render.then(function(rendered){
// var inwait; // var inwait;
//-- Set the book's spine position //-- Set the book's spine position
book.spinePos = pos; book.spinePos = pos;
if(cfi) { defer.resolve(book.renderer);
rendered.gotoCfi(cfi);
defer.resolve(book.renderer);
} else if(end) {
rendered.lastPage();
defer.resolve(book.renderer);
} else {
defer.resolve(book.renderer);
}
if(!book.settings.fromStorage && if(!book.settings.fromStorage &&
!book.settings.contained) { !book.settings.contained) {
@ -3037,6 +3038,9 @@ EPUBJS.Book.prototype.displayChapter = function(chap, end, deferred){
book.currentChapter = chapter; book.currentChapter = chapter;
book._rendering = false; book._rendering = false;
book._displayQ.dequeue(); book._displayQ.dequeue();
if(book._displayQ.length() === 0) {
book._gotoQ.dequeue();
}
}, function(error) { }, function(error) {
// handle errors in either of the two requests // handle errors in either of the two requests
@ -3136,12 +3140,14 @@ EPUBJS.Book.prototype.gotoCfi = function(cfiString, defer){
deferred = defer || new RSVP.defer(); deferred = defer || new RSVP.defer();
if(!this.isRendered) { if(!this.isRendered) {
console.warn("Not yet Rendered");
this.settings.previousLocationCfi = cfiString; this.settings.previousLocationCfi = cfiString;
return false; return false;
} }
// Currently going to a chapter // Currently going to a chapter
if(this._moving) { if(this._moving || this._rendering) {
console.warn("Renderer is moving");
this._gotoQ.enqueue("gotoCfi", [cfiString, deferred]); this._gotoQ.enqueue("gotoCfi", [cfiString, deferred]);
return false; return false;
} }
@ -3174,8 +3180,8 @@ EPUBJS.Book.prototype.gotoCfi = function(cfiString, defer){
this.spinePos = spinePos; this.spinePos = spinePos;
render = this.renderer.displayChapter(this.currentChapter, this.globalLayoutProperties); render = this.renderer.displayChapter(this.currentChapter, this.globalLayoutProperties);
this.renderer.gotoCfi(cfi);
render.then(function(rendered){ render.then(function(rendered){
rendered.gotoCfi(cfi);
this._moving = false; this._moving = false;
deferred.resolve(rendered.currentLocationCfi); deferred.resolve(rendered.currentLocationCfi);
}.bind(this)); }.bind(this));
@ -3199,7 +3205,7 @@ EPUBJS.Book.prototype.gotoHref = function(url, defer){
} }
// Currently going to a chapter // Currently going to a chapter
if(this._moving) { if(this._moving || this._rendering) {
this._gotoQ.enqueue("gotoHref", [url, deferred]); this._gotoQ.enqueue("gotoHref", [url, deferred]);
return false; return false;
} }
@ -3311,12 +3317,20 @@ EPUBJS.Book.prototype.fromStorage = function(stored) {
*/ */
EPUBJS.Book.prototype.setStyle = function(style, val, prefixed) { EPUBJS.Book.prototype.setStyle = function(style, val, prefixed) {
var noreflow = ["color", "background", "background-color"];
if(!this.isRendered) return this._q.enqueue("setStyle", arguments); if(!this.isRendered) return this._q.enqueue("setStyle", arguments);
this.settings.styles[style] = val; this.settings.styles[style] = val;
this.renderer.setStyle(style, val, prefixed); this.renderer.setStyle(style, val, prefixed);
this.renderer.reformat();
if(noreflow.indexOf(style) === -1) {
clearTimeout(this.reformatTimeout);
this.reformatTimeout = setTimeout(function(){
this.renderer.reformat();
}.bind(this), 10);
}
}; };
EPUBJS.Book.prototype.removeStyle = function(style) { EPUBJS.Book.prototype.removeStyle = function(style) {
@ -3570,8 +3584,8 @@ EPUBJS.Chapter.prototype.cfiFromRange = function(_range) {
// Check for Contents // Check for Contents
if(!this.contents) return; if(!this.contents) return;
startXpath = EPUBJS.core.getElementXPath(_range.startContainer); startXpath = EPUBJS.core.getElementXPath(_range.startContainer);
// console.log(startContainer)
endXpath = EPUBJS.core.getElementXPath(_range.endContainer); endXpath = EPUBJS.core.getElementXPath(_range.endContainer);
startContainer = this.contents.evaluate(startXpath, this.contents, EPUBJS.core.nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; startContainer = this.contents.evaluate(startXpath, this.contents, EPUBJS.core.nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
@ -3580,7 +3594,6 @@ EPUBJS.Chapter.prototype.cfiFromRange = function(_range) {
} }
range = this.contents.createRange(); range = this.contents.createRange();
// Find Exact Range in original document // Find Exact Range in original document
if(startContainer) { if(startContainer) {
try { try {
@ -3589,7 +3602,7 @@ EPUBJS.Chapter.prototype.cfiFromRange = function(_range) {
range.setEnd(endContainer, _range.endOffset); range.setEnd(endContainer, _range.endOffset);
} }
} catch (e) { } catch (e) {
// console.log("missed"); console.log("missed");
startContainer = false; startContainer = false;
} }
@ -3597,7 +3610,7 @@ EPUBJS.Chapter.prototype.cfiFromRange = function(_range) {
// Fuzzy Match // Fuzzy Match
if(!startContainer) { if(!startContainer) {
// console.log("not found, try fuzzy match"); console.log("not found, try fuzzy match");
cleanStartTextContent = EPUBJS.core.cleanStringForXpath(_range.startContainer.textContent); cleanStartTextContent = EPUBJS.core.cleanStringForXpath(_range.startContainer.textContent);
startXpath = "//text()[contains(.," + cleanStartTextContent + ")]"; startXpath = "//text()[contains(.," + cleanStartTextContent + ")]";
@ -3755,6 +3768,7 @@ EPUBJS.core.uri = function(url){
if(search != -1) { if(search != -1) {
uri.search = url.slice(search + 1); uri.search = url.slice(search + 1);
url = url.slice(0, search); url = url.slice(0, search);
href = url;
} }
if(doubleSlash != -1) { if(doubleSlash != -1) {
@ -4029,11 +4043,12 @@ EPUBJS.core.queue = function(_scope){
if(_q.length) { if(_q.length) {
inwait = _q.shift(); inwait = _q.shift();
// Defer to any current tasks // Defer to any current tasks
setTimeout(function(){ // setTimeout(function(){
scope[inwait.funcName].apply(inwait.context || scope, inwait.args); scope[inwait.funcName].apply(inwait.context || scope, inwait.args);
}, 0); // }, 0);
} }
}; };
// Run All // Run All
var flush = function(){ var flush = function(){
while(_q.length) { while(_q.length) {
@ -4044,11 +4059,17 @@ EPUBJS.core.queue = function(_scope){
var clear = function(){ var clear = function(){
_q = []; _q = [];
}; };
var length = function(){
return _q.length;
};
return { return {
"enqueue" : enqueue, "enqueue" : enqueue,
"dequeue" : dequeue, "dequeue" : dequeue,
"flush" : flush, "flush" : flush,
"clear" : clear "clear" : clear,
"length" : length
}; };
}; };
@ -4067,16 +4088,20 @@ EPUBJS.core.getElementXPath = function(element) {
EPUBJS.core.getElementTreeXPath = function(element) { EPUBJS.core.getElementTreeXPath = function(element) {
var paths = []; var paths = [];
var isXhtml = (element.ownerDocument.documentElement.getAttribute('xmlns') === "http://www.w3.org/1999/xhtml"); var isXhtml = (element.ownerDocument.documentElement.getAttribute('xmlns') === "http://www.w3.org/1999/xhtml");
var index, nodeName, tagName, pathIndex;
if(element.nodeType === 3){ if(element.nodeType === Node.TEXT_NODE){
paths.push("text()"); // index = Array.prototype.indexOf.call(element.parentNode.childNodes, element) + 1;
element = element.parentElement; index = EPUBJS.core.indexOfTextNode(element) + 1;
paths.push("text()["+index+"]");
element = element.parentNode;
} }
// Use nodeName (instead of localName) so namespace prefix is included (if any). // Use nodeName (instead of localName) so namespace prefix is included (if any).
for (; element && element.nodeType == 1; element = element.parentNode) for (; element && element.nodeType == 1; element = element.parentNode)
{ {
var index = 0; index = 0;
for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling) for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling)
{ {
// Ignore document type declaration. // Ignore document type declaration.
@ -4087,9 +4112,9 @@ EPUBJS.core.getElementTreeXPath = function(element) {
++index; ++index;
} }
} }
var nodeName = element.nodeName.toLowerCase(); nodeName = element.nodeName.toLowerCase();
var tagName = (isXhtml ? "xhtml:" + nodeName : nodeName); tagName = (isXhtml ? "xhtml:" + nodeName : nodeName);
var pathIndex = (index ? "[" + (index+1) + "]" : ""); pathIndex = (index ? "[" + (index+1) + "]" : "");
paths.splice(0, 0, tagName + pathIndex); paths.splice(0, 0, tagName + pathIndex);
} }
@ -4119,6 +4144,22 @@ EPUBJS.core.cleanStringForXpath = function(str) {
}); });
return "concat(\'\'," + parts.join(",") + ")"; return "concat(\'\'," + parts.join(",") + ")";
}; };
EPUBJS.core.indexOfTextNode = function(textNode){
var parent = textNode.parentElement;
var children = parent.childNodes;
var sib;
var index = -1;
for (var i = 0; i < children.length; i++) {
sib = children[i];
if(sib.nodeType === Node.TEXT_NODE){
index++;
}
if(sib == textNode) break;
}
return index;
};
EPUBJS.EpubCFI = function(cfiStr){ EPUBJS.EpubCFI = function(cfiStr){
if(cfiStr) return this.parse(cfiStr); if(cfiStr) return this.parse(cfiStr);
}; };
@ -4518,12 +4559,13 @@ EPUBJS.EpubCFI.prototype.generateCfiFromRangeAnchor = function(range, base) {
EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) { EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) {
var start, startElement, startSteps, startPath, startOffset, startIndex; var start, startElement, startSteps, startPath, startOffset, startIndex;
var end, endElement, endSteps, endPath, endOffset, endIndex; var end, endElement, endSteps, endPath, endOffset, endIndex;
start = range.startContainer; start = range.startContainer;
if(start.nodeType === 3) { // text node if(start.nodeType === 3) { // text node
startElement = start.parentElement; startElement = start.parentElement;
startIndex = 1 + (2 * Array.prototype.indexOf.call(startElement.childNodes, start)); //startIndex = 1 + (2 * Array.prototype.indexOf.call(startElement.childNodes, start));
startIndex = 1 + (2 * EPUBJS.core.indexOfTextNode(start));
startSteps = this.pathTo(startElement); startSteps = this.pathTo(startElement);
} else if(range.collapsed) { } else if(range.collapsed) {
return this.generateCfiFromElement(start, base); // single element return this.generateCfiFromElement(start, base); // single element
@ -4539,7 +4581,9 @@ EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) {
if(end.nodeType === 3) { // text node if(end.nodeType === 3) { // text node
endElement = end.parentElement; endElement = end.parentElement;
endIndex = 1 + (2 * Array.prototype.indexOf.call(endElement.childNodes, end)); // endIndex = 1 + (2 * Array.prototype.indexOf.call(endElement.childNodes, end));
endIndex = 1 + (2 * EPUBJS.core.indexOfTextNode(end));
endSteps = this.pathTo(endElement); endSteps = this.pathTo(endElement);
} else { } else {
endSteps = this.pathTo(end); endSteps = this.pathTo(end);
@ -4597,18 +4641,21 @@ EPUBJS.EpubCFI.prototype.generateRangeFromCfi = function(cfi, _doc) {
// Get the terminal step // Get the terminal step
lastStep = cfi.steps[cfi.steps.length-1]; lastStep = cfi.steps[cfi.steps.length-1];
startContainer = doc.evaluate(xpath, doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; startContainer = doc.evaluate(xpath, doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if(!startContainer) { if(!startContainer) {
return null; return null;
} }
if(startContainer && cfi.characterOffset >= 0) { if(startContainer && cfi.characterOffset >= 0) {
textLength = startContainer.length; textLength = startContainer.length;
if(cfi.characterOffset < textLength) { if(cfi.characterOffset < textLength) {
range.setStart(startContainer, cfi.characterOffset); range.setStart(startContainer, cfi.characterOffset);
range.setEnd(startContainer, textLength ); range.setEnd(startContainer, textLength );
} else { } else {
range.setStart(startContainer, cfi.characterOffset - 1 ); console.debug("offset greater than length:", cfi.characterOffset, textLength);
range.setEnd(startContainer, cfi.characterOffset ); range.setStart(startContainer, textLength - 1 );
range.setEnd(startContainer, textLength );
} }
} else if(startContainer) { } else if(startContainer) {
range.selectNode(startContainer); range.selectNode(startContainer);
@ -4783,6 +4830,7 @@ EPUBJS.Layout.Reflowable.prototype.format = function(documentElement, _width, _h
var columnAxis = EPUBJS.core.prefixed('columnAxis'); var columnAxis = EPUBJS.core.prefixed('columnAxis');
var columnGap = EPUBJS.core.prefixed('columnGap'); var columnGap = EPUBJS.core.prefixed('columnGap');
var columnWidth = EPUBJS.core.prefixed('columnWidth'); var columnWidth = EPUBJS.core.prefixed('columnWidth');
var columnFill = EPUBJS.core.prefixed('columnFill');
//-- Check the width and create even width columns //-- Check the width and create even width columns
var width = Math.floor(_width); var width = Math.floor(_width);
@ -4804,6 +4852,7 @@ EPUBJS.Layout.Reflowable.prototype.format = function(documentElement, _width, _h
//-- Add columns //-- Add columns
documentElement.style[columnAxis] = "horizontal"; documentElement.style[columnAxis] = "horizontal";
documentElement.style[columnFill] = "auto";
documentElement.style[columnWidth] = width+"px"; documentElement.style[columnWidth] = width+"px";
documentElement.style[columnGap] = gap+"px"; documentElement.style[columnGap] = gap+"px";
this.colWidth = width; this.colWidth = width;
@ -4836,6 +4885,7 @@ EPUBJS.Layout.ReflowableSpreads.prototype.format = function(documentElement, _wi
var columnAxis = EPUBJS.core.prefixed('columnAxis'); var columnAxis = EPUBJS.core.prefixed('columnAxis');
var columnGap = EPUBJS.core.prefixed('columnGap'); var columnGap = EPUBJS.core.prefixed('columnGap');
var columnWidth = EPUBJS.core.prefixed('columnWidth'); var columnWidth = EPUBJS.core.prefixed('columnWidth');
var columnFill = EPUBJS.core.prefixed('columnFill');
var divisor = 2, var divisor = 2,
cutoff = 800; cutoff = 800;
@ -4864,8 +4914,10 @@ EPUBJS.Layout.ReflowableSpreads.prototype.format = function(documentElement, _wi
//-- Add columns //-- Add columns
documentElement.style[columnAxis] = "horizontal"; documentElement.style[columnAxis] = "horizontal";
documentElement.style[columnFill] = "auto";
documentElement.style[columnGap] = gap+"px"; documentElement.style[columnGap] = gap+"px";
documentElement.style[columnWidth] = colWidth+"px"; documentElement.style[columnWidth] = colWidth+"px";
this.colWidth = colWidth; this.colWidth = colWidth;
this.gap = gap; this.gap = gap;
return { return {
@ -5566,7 +5618,9 @@ EPUBJS.Render.Iframe.prototype.load = function(url){
EPUBJS.Render.Iframe.prototype.loaded = function(v){ EPUBJS.Render.Iframe.prototype.loaded = function(v){
var url = this.iframe.contentWindow.location.href; var url = this.iframe.contentWindow.location.href;
this.trigger("render:loaded", url); if(url != "about:blank"){
this.trigger("render:loaded", url);
}
}; };
// Resize the iframe to the given width and height // Resize the iframe to the given width and height
@ -5739,7 +5793,7 @@ EPUBJS.Renderer = function(renderMethod, hidden) {
this.spreads = true; this.spreads = true;
this.isForcedSingle = false; this.isForcedSingle = false;
this.resized = _.throttle(this.onResized.bind(this), 10); this.resized = _.debounce(this.onResized.bind(this), 100);
this.layoutSettings = {}; this.layoutSettings = {};
@ -5752,6 +5806,8 @@ EPUBJS.Renderer = function(renderMethod, hidden) {
//-- Queue up page changes if page map isn't ready //-- Queue up page changes if page map isn't ready
this._q = EPUBJS.core.queue(this); this._q = EPUBJS.core.queue(this);
this._moving = false;
}; };
@ -5805,14 +5861,23 @@ EPUBJS.Renderer.prototype.initialize = function(element, width, height){
*/ */
EPUBJS.Renderer.prototype.displayChapter = function(chapter, globalLayout){ EPUBJS.Renderer.prototype.displayChapter = function(chapter, globalLayout){
var store = false; var store = false;
if(this._moving) {
console.error("Rendering In Progress");
return;
}
this._moving = true;
// Get the url string from the chapter (may be from storage) // Get the url string from the chapter (may be from storage)
return chapter.url(). return chapter.url().
then(function(url) { then(function(url) {
// Unload the previous chapter listener // Unload the previous chapter listener
if(this.currentChapter) { if(this.currentChapter) {
this.currentChapter.unload(); // Remove stored blobs this.currentChapter.unload(); // Remove stored blobs
this.render.window.removeEventListener("resize", this.resized);
if(this.render.window){
this.render.window.removeEventListener("resize", this.resized);
}
this.removeEventListeners(); this.removeEventListeners();
this.removeSelectionListeners(); this.removeSelectionListeners();
this.trigger("renderer:chapterUnloaded"); this.trigger("renderer:chapterUnloaded");
@ -5820,10 +5885,9 @@ EPUBJS.Renderer.prototype.displayChapter = function(chapter, globalLayout){
this.doc = null; this.doc = null;
this.pageMap = null; this.pageMap = null;
} }
this.currentChapter = chapter; this.currentChapter = chapter;
this.chapterPos = 1; this.chapterPos = 1;
this.pageMap = null;
this.currentChapterCfiBase = chapter.cfiBase; this.currentChapterCfiBase = chapter.cfiBase;
this.layoutSettings = this.reconcileLayoutSettings(globalLayout, chapter.properties); this.layoutSettings = this.reconcileLayoutSettings(globalLayout, chapter.properties);
@ -5861,11 +5925,11 @@ EPUBJS.Renderer.prototype.load = function(url){
this.formated = this.layout.format(contents, this.render.width, this.render.height, this.gap); this.formated = this.layout.format(contents, this.render.width, this.render.height, this.gap);
this.render.setPageDimensions(this.formated.pageWidth, this.formated.pageHeight); this.render.setPageDimensions(this.formated.pageWidth, this.formated.pageHeight);
// window.addEventListener("orientationchange", this.onResized.bind(this), false);
if(!this.initWidth && !this.initHeight){ if(!this.initWidth && !this.initHeight){
this.render.window.addEventListener("resize", this.resized, false); this.render.window.addEventListener("resize", this.resized, false);
} }
this.addEventListeners(); this.addEventListeners();
this.addSelectionListeners(); this.addSelectionListeners();
@ -5873,18 +5937,24 @@ EPUBJS.Renderer.prototype.load = function(url){
this.beforeDisplay(function(){ this.beforeDisplay(function(){
var pages = this.layout.calculatePages(); var pages = this.layout.calculatePages();
var msg = this.currentChapter; var msg = this.currentChapter;
this.updatePages(pages); var queued = this._q.length();
this._moving = false;
this.updatePages(pages);
this.visibleRangeCfi = this.getVisibleRangeCfi(); this.visibleRangeCfi = this.getVisibleRangeCfi();
this.currentLocationCfi = this.visibleRangeCfi.start; this.currentLocationCfi = this.visibleRangeCfi.start;
this.trigger("renderer:locationChanged", this.currentLocationCfi);
this.trigger("renderer:visibleRangeChanged", this.visibleRangeCfi);
msg.cfi = this.currentLocationCfi; if(queued === 0) {
this.trigger("renderer:locationChanged", this.currentLocationCfi);
this.trigger("renderer:visibleRangeChanged", this.visibleRangeCfi);
}
msg.cfi = this.currentLocationCfi; //TODO: why is this cfi passed to chapterDisplayed
this.trigger("renderer:chapterDisplayed", msg); this.trigger("renderer:chapterDisplayed", msg);
this.visible(true); this.visible(true);
deferred.resolve(this); //-- why does this return the renderer? deferred.resolve(this); //-- why does this return the renderer?
}.bind(this)); }.bind(this));
@ -5975,9 +6045,17 @@ EPUBJS.Renderer.prototype.beforeDisplay = function(callback, renderer){
// Update the renderer with the information passed by the layout // Update the renderer with the information passed by the layout
EPUBJS.Renderer.prototype.updatePages = function(layout){ EPUBJS.Renderer.prototype.updatePages = function(layout){
this.pageMap = this.mapPage(); this.pageMap = this.mapPage();
this.displayedPages = layout.displayedPages; // this.displayedPages = layout.displayedPages;
this.currentChapter.pages = layout.pageCount;
if (this.spreads) {
this.displayedPages = Math.ceil(this.pageMap.length / 2);
} else {
this.displayedPages = this.pageMap.length;
}
// this.currentChapter.pages = layout.pageCount;
this.currentChapter.pages = this.pageMap.length;
this._q.flush(); this._q.flush();
}; };
@ -5987,8 +6065,13 @@ EPUBJS.Renderer.prototype.reformat = function(){
var formated, pages; var formated, pages;
if(!this.contents) return; if(!this.contents) return;
this.layoutMethod = this.determineLayout(this.layoutSettings); spreads = this.determineSpreads(this.minSpreadWidth);
this.layout = new EPUBJS.Layout[this.layoutMethod](); // Only re-layout if the spreads have switched
if(spreads != this.spreads){
this.spreads = spreads;
this.layoutMethod = this.determineLayout(this.layoutSettings);
this.layout = new EPUBJS.Layout[this.layoutMethod]();
}
this.formated = this.layout.format(this.contents, this.render.width, this.render.height, this.gap); this.formated = this.layout.format(this.contents, this.render.width, this.render.height, this.gap);
this.render.setPageDimensions(this.formated.pageWidth, this.formated.pageHeight); this.render.setPageDimensions(this.formated.pageWidth, this.formated.pageHeight);
@ -6059,8 +6142,8 @@ EPUBJS.Renderer.prototype.applyHeadTags = function(headTags) {
//-- NAVIGATION //-- NAVIGATION
EPUBJS.Renderer.prototype.page = function(pg){ EPUBJS.Renderer.prototype.page = function(pg){
if(!this.pageMap) { if(!this.pageMap) {
console.warn("pageMap not set, queuing");
this._q.enqueue("page", arguments); this._q.enqueue("page", arguments);
return true; return true;
} }
@ -6117,6 +6200,10 @@ EPUBJS.Renderer.prototype.pageByElement = function(el){
// Jump to the last page of the chapter // Jump to the last page of the chapter
EPUBJS.Renderer.prototype.lastPage = function(){ EPUBJS.Renderer.prototype.lastPage = function(){
if(this._moving) {
return this._q.enqueue("lastPage", arguments);
}
this.page(this.displayedPages); this.page(this.displayedPages);
}; };
@ -6231,7 +6318,7 @@ EPUBJS.Renderer.prototype.textSprint = function(root, func) {
}; };
EPUBJS.Renderer.prototype.sprint = function(root, func) { EPUBJS.Renderer.prototype.sprint = function(root, func) {
var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, false, false); var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, null, false);
var node; var node;
while ((node = treeWalker.nextNode())) { while ((node = treeWalker.nextNode())) {
func(node); func(node);
@ -6252,15 +6339,30 @@ EPUBJS.Renderer.prototype.mapPage = function(){
var cfi; var cfi;
var check = function(node) { var check = function(node) {
var elPos; var elPos;
var elRange;
var children = Array.prototype.slice.call(node.childNodes); var children = Array.prototype.slice.call(node.childNodes);
if (node.nodeType == Node.ELEMENT_NODE) { if (node.nodeType == Node.ELEMENT_NODE) {
elPos = node.getBoundingClientRect(); // elPos = node.getBoundingClientRect();
elRange = document.createRange();
elRange.selectNodeContents(node);
elPos = elRange.getBoundingClientRect();
if(!elPos || (elPos.width === 0 && elPos.height === 0)) { if(!elPos || (elPos.width === 0 && elPos.height === 0)) {
return; return;
} }
if(elPos.left + elPos.width > elLimit) { //-- Element starts new Col
if(elPos.left > elLimit) {
children.forEach(function(node){
if(node.nodeType == Node.TEXT_NODE &&
node.textContent.trim().length) {
checkText(node);
}
});
}
//-- Element Spans new Col
if(elPos.right > elLimit) {
children.forEach(function(node){ children.forEach(function(node){
if(node.nodeType == Node.TEXT_NODE && if(node.nodeType == Node.TEXT_NODE &&
node.textContent.trim().length) { node.textContent.trim().length) {
@ -6299,6 +6401,7 @@ EPUBJS.Renderer.prototype.mapPage = function(){
start: cfi, start: cfi,
end: null end: null
}); });
page += 1; page += 1;
limit = (width * page) - offset; limit = (width * page) - offset;
elLimit = limit; elLimit = limit;
@ -6336,6 +6439,7 @@ EPUBJS.Renderer.prototype.mapPage = function(){
ranges = null; ranges = null;
range = null; range = null;
root = null; root = null;
return map; return map;
}; };
@ -6560,7 +6664,7 @@ EPUBJS.Renderer.prototype.getVisibleRangeCfi = function(){
} }
if(!startRange) { if(!startRange) {
console.warn("page range miss:", pg); console.warn("page range miss:", pg, this.pageMap);
startRange = this.pageMap[this.pageMap.length-1]; startRange = this.pageMap[this.pageMap.length-1];
endRange = startRange; endRange = startRange;
} }
@ -6576,7 +6680,11 @@ EPUBJS.Renderer.prototype.gotoCfi = function(cfi){
var pg; var pg;
var marker; var marker;
var range; var range;
if(this._moving){
return this._q.enqueue("gotoCfi", arguments);
}
if(_.isString(cfi)){ if(_.isString(cfi)){
cfi = this.epubcfi.parse(cfi); cfi = this.epubcfi.parse(cfi);
} }
@ -6651,13 +6759,7 @@ EPUBJS.Renderer.prototype.resize = function(width, height, setSize){
this.render.resize(this.width, this.height); this.render.resize(this.width, this.height);
} }
spreads = this.determineSpreads(this.minSpreadWidth);
// Only re-layout if the spreads have switched
if(spreads != this.spreads){
this.spreads = spreads;
this.layoutMethod = this.determineLayout(this.layoutSettings);
this.layout = new EPUBJS.Layout[this.layoutMethod]();
}
if(this.contents){ if(this.contents){
this.reformat(); this.reformat();
@ -6679,7 +6781,9 @@ EPUBJS.Renderer.prototype.onResized = function(e) {
}; };
EPUBJS.Renderer.prototype.addEventListeners = function(){ EPUBJS.Renderer.prototype.addEventListeners = function(){
if(!this.render.document) {
return;
}
this.listenedEvents.forEach(function(eventName){ this.listenedEvents.forEach(function(eventName){
this.render.document.addEventListener(eventName, this.triggerEvent.bind(this), false); this.render.document.addEventListener(eventName, this.triggerEvent.bind(this), false);
}, this); }, this);
@ -6687,7 +6791,9 @@ EPUBJS.Renderer.prototype.addEventListeners = function(){
}; };
EPUBJS.Renderer.prototype.removeEventListeners = function(){ EPUBJS.Renderer.prototype.removeEventListeners = function(){
if(!this.render.document) {
return;
}
this.listenedEvents.forEach(function(eventName){ this.listenedEvents.forEach(function(eventName){
this.render.document.removeEventListener(eventName, this.triggerEvent, false); this.render.document.removeEventListener(eventName, this.triggerEvent, false);
}, this); }, this);
@ -6704,6 +6810,9 @@ EPUBJS.Renderer.prototype.addSelectionListeners = function(){
}; };
EPUBJS.Renderer.prototype.removeSelectionListeners = function(){ EPUBJS.Renderer.prototype.removeSelectionListeners = function(){
if(!this.render.document) {
return;
}
this.doc.removeEventListener("selectionchange", this.onSelectionChange, false); this.doc.removeEventListener("selectionchange", this.onSelectionChange, false);
}; };

View file

@ -509,8 +509,14 @@ EPUBJS.Book.prototype.listenToRenderer = function(renderer){
// Prevents the Render from loading a different chapter when back button is pressed // Prevents the Render from loading a different chapter when back button is pressed
EPUBJS.Book.prototype.loadChange = function(url){ EPUBJS.Book.prototype.loadChange = function(url){
var uri = EPUBJS.core.uri(url); var uri = EPUBJS.core.uri(url);
if(!this._rendering && this.currentChapter && uri.path != this.currentChapter.absolute){ var chapter;
// console.warn("Miss Match", uri.path, this.currentChapter.absolute);
if(this.currentChapter) {
chapter = EPUBJS.core.uri(this.currentChapter.absolute);
}
if(!this._rendering && this.currentChapter && uri.path != chapter.path){
console.warn("Miss Match", uri.path, this.currentChapter.absolute);
this.goto(uri.filename); this.goto(uri.filename);
} }
}; };
@ -735,7 +741,7 @@ EPUBJS.Book.prototype.displayChapter = function(chap, end, deferred){
} }
if(this._rendering) { if(this._rendering || this._rendering) {
// Pass along the current defer // Pass along the current defer
this._displayQ.enqueue("displayChapter", [chap, end, defer]); this._displayQ.enqueue("displayChapter", [chap, end, defer]);
return defer.promise; return defer.promise;
@ -761,23 +767,18 @@ EPUBJS.Book.prototype.displayChapter = function(chap, end, deferred){
this._rendering = true; this._rendering = true;
render = book.renderer.displayChapter(chapter, this.globalLayoutProperties); render = book.renderer.displayChapter(chapter, this.globalLayoutProperties);
if(cfi) {
book.renderer.gotoCfi(cfi);
} else if(end) {
book.renderer.lastPage();
}
//-- Success, Clear render queue //-- Success, Clear render queue
render.then(function(rendered){ render.then(function(rendered){
// var inwait; // var inwait;
//-- Set the book's spine position //-- Set the book's spine position
book.spinePos = pos; book.spinePos = pos;
if(cfi) { defer.resolve(book.renderer);
rendered.gotoCfi(cfi);
defer.resolve(book.renderer);
} else if(end) {
rendered.lastPage();
defer.resolve(book.renderer);
} else {
defer.resolve(book.renderer);
}
if(!book.settings.fromStorage && if(!book.settings.fromStorage &&
!book.settings.contained) { !book.settings.contained) {
@ -787,6 +788,9 @@ EPUBJS.Book.prototype.displayChapter = function(chap, end, deferred){
book.currentChapter = chapter; book.currentChapter = chapter;
book._rendering = false; book._rendering = false;
book._displayQ.dequeue(); book._displayQ.dequeue();
if(book._displayQ.length() === 0) {
book._gotoQ.dequeue();
}
}, function(error) { }, function(error) {
// handle errors in either of the two requests // handle errors in either of the two requests
@ -886,12 +890,14 @@ EPUBJS.Book.prototype.gotoCfi = function(cfiString, defer){
deferred = defer || new RSVP.defer(); deferred = defer || new RSVP.defer();
if(!this.isRendered) { if(!this.isRendered) {
console.warn("Not yet Rendered");
this.settings.previousLocationCfi = cfiString; this.settings.previousLocationCfi = cfiString;
return false; return false;
} }
// Currently going to a chapter // Currently going to a chapter
if(this._moving) { if(this._moving || this._rendering) {
console.warn("Renderer is moving");
this._gotoQ.enqueue("gotoCfi", [cfiString, deferred]); this._gotoQ.enqueue("gotoCfi", [cfiString, deferred]);
return false; return false;
} }
@ -924,8 +930,8 @@ EPUBJS.Book.prototype.gotoCfi = function(cfiString, defer){
this.spinePos = spinePos; this.spinePos = spinePos;
render = this.renderer.displayChapter(this.currentChapter, this.globalLayoutProperties); render = this.renderer.displayChapter(this.currentChapter, this.globalLayoutProperties);
this.renderer.gotoCfi(cfi);
render.then(function(rendered){ render.then(function(rendered){
rendered.gotoCfi(cfi);
this._moving = false; this._moving = false;
deferred.resolve(rendered.currentLocationCfi); deferred.resolve(rendered.currentLocationCfi);
}.bind(this)); }.bind(this));
@ -949,7 +955,7 @@ EPUBJS.Book.prototype.gotoHref = function(url, defer){
} }
// Currently going to a chapter // Currently going to a chapter
if(this._moving) { if(this._moving || this._rendering) {
this._gotoQ.enqueue("gotoHref", [url, deferred]); this._gotoQ.enqueue("gotoHref", [url, deferred]);
return false; return false;
} }
@ -1061,12 +1067,20 @@ EPUBJS.Book.prototype.fromStorage = function(stored) {
*/ */
EPUBJS.Book.prototype.setStyle = function(style, val, prefixed) { EPUBJS.Book.prototype.setStyle = function(style, val, prefixed) {
var noreflow = ["color", "background", "background-color"];
if(!this.isRendered) return this._q.enqueue("setStyle", arguments); if(!this.isRendered) return this._q.enqueue("setStyle", arguments);
this.settings.styles[style] = val; this.settings.styles[style] = val;
this.renderer.setStyle(style, val, prefixed); this.renderer.setStyle(style, val, prefixed);
this.renderer.reformat();
if(noreflow.indexOf(style) === -1) {
clearTimeout(this.reformatTimeout);
this.reformatTimeout = setTimeout(function(){
this.renderer.reformat();
}.bind(this), 10);
}
}; };
EPUBJS.Book.prototype.removeStyle = function(style) { EPUBJS.Book.prototype.removeStyle = function(style) {

View file

@ -86,8 +86,8 @@ EPUBJS.Chapter.prototype.cfiFromRange = function(_range) {
// Check for Contents // Check for Contents
if(!this.contents) return; if(!this.contents) return;
startXpath = EPUBJS.core.getElementXPath(_range.startContainer); startXpath = EPUBJS.core.getElementXPath(_range.startContainer);
// console.log(startContainer)
endXpath = EPUBJS.core.getElementXPath(_range.endContainer); endXpath = EPUBJS.core.getElementXPath(_range.endContainer);
startContainer = this.contents.evaluate(startXpath, this.contents, EPUBJS.core.nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; startContainer = this.contents.evaluate(startXpath, this.contents, EPUBJS.core.nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
@ -96,7 +96,6 @@ EPUBJS.Chapter.prototype.cfiFromRange = function(_range) {
} }
range = this.contents.createRange(); range = this.contents.createRange();
// Find Exact Range in original document // Find Exact Range in original document
if(startContainer) { if(startContainer) {
try { try {
@ -105,7 +104,7 @@ EPUBJS.Chapter.prototype.cfiFromRange = function(_range) {
range.setEnd(endContainer, _range.endOffset); range.setEnd(endContainer, _range.endOffset);
} }
} catch (e) { } catch (e) {
// console.log("missed"); console.log("missed");
startContainer = false; startContainer = false;
} }
@ -113,7 +112,7 @@ EPUBJS.Chapter.prototype.cfiFromRange = function(_range) {
// Fuzzy Match // Fuzzy Match
if(!startContainer) { if(!startContainer) {
// console.log("not found, try fuzzy match"); console.log("not found, try fuzzy match");
cleanStartTextContent = EPUBJS.core.cleanStringForXpath(_range.startContainer.textContent); cleanStartTextContent = EPUBJS.core.cleanStringForXpath(_range.startContainer.textContent);
startXpath = "//text()[contains(.," + cleanStartTextContent + ")]"; startXpath = "//text()[contains(.," + cleanStartTextContent + ")]";

View file

@ -130,6 +130,7 @@ EPUBJS.core.uri = function(url){
if(search != -1) { if(search != -1) {
uri.search = url.slice(search + 1); uri.search = url.slice(search + 1);
url = url.slice(0, search); url = url.slice(0, search);
href = url;
} }
if(doubleSlash != -1) { if(doubleSlash != -1) {
@ -404,11 +405,12 @@ EPUBJS.core.queue = function(_scope){
if(_q.length) { if(_q.length) {
inwait = _q.shift(); inwait = _q.shift();
// Defer to any current tasks // Defer to any current tasks
setTimeout(function(){ // setTimeout(function(){
scope[inwait.funcName].apply(inwait.context || scope, inwait.args); scope[inwait.funcName].apply(inwait.context || scope, inwait.args);
}, 0); // }, 0);
} }
}; };
// Run All // Run All
var flush = function(){ var flush = function(){
while(_q.length) { while(_q.length) {
@ -419,11 +421,17 @@ EPUBJS.core.queue = function(_scope){
var clear = function(){ var clear = function(){
_q = []; _q = [];
}; };
var length = function(){
return _q.length;
};
return { return {
"enqueue" : enqueue, "enqueue" : enqueue,
"dequeue" : dequeue, "dequeue" : dequeue,
"flush" : flush, "flush" : flush,
"clear" : clear "clear" : clear,
"length" : length
}; };
}; };
@ -442,16 +450,20 @@ EPUBJS.core.getElementXPath = function(element) {
EPUBJS.core.getElementTreeXPath = function(element) { EPUBJS.core.getElementTreeXPath = function(element) {
var paths = []; var paths = [];
var isXhtml = (element.ownerDocument.documentElement.getAttribute('xmlns') === "http://www.w3.org/1999/xhtml"); var isXhtml = (element.ownerDocument.documentElement.getAttribute('xmlns') === "http://www.w3.org/1999/xhtml");
var index, nodeName, tagName, pathIndex;
if(element.nodeType === 3){ if(element.nodeType === Node.TEXT_NODE){
paths.push("text()"); // index = Array.prototype.indexOf.call(element.parentNode.childNodes, element) + 1;
element = element.parentElement; index = EPUBJS.core.indexOfTextNode(element) + 1;
paths.push("text()["+index+"]");
element = element.parentNode;
} }
// Use nodeName (instead of localName) so namespace prefix is included (if any). // Use nodeName (instead of localName) so namespace prefix is included (if any).
for (; element && element.nodeType == 1; element = element.parentNode) for (; element && element.nodeType == 1; element = element.parentNode)
{ {
var index = 0; index = 0;
for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling) for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling)
{ {
// Ignore document type declaration. // Ignore document type declaration.
@ -462,9 +474,9 @@ EPUBJS.core.getElementTreeXPath = function(element) {
++index; ++index;
} }
} }
var nodeName = element.nodeName.toLowerCase(); nodeName = element.nodeName.toLowerCase();
var tagName = (isXhtml ? "xhtml:" + nodeName : nodeName); tagName = (isXhtml ? "xhtml:" + nodeName : nodeName);
var pathIndex = (index ? "[" + (index+1) + "]" : ""); pathIndex = (index ? "[" + (index+1) + "]" : "");
paths.splice(0, 0, tagName + pathIndex); paths.splice(0, 0, tagName + pathIndex);
} }
@ -493,4 +505,20 @@ EPUBJS.core.cleanStringForXpath = function(str) {
return "\'" + part + "\'"; return "\'" + part + "\'";
}); });
return "concat(\'\'," + parts.join(",") + ")"; return "concat(\'\'," + parts.join(",") + ")";
};
EPUBJS.core.indexOfTextNode = function(textNode){
var parent = textNode.parentElement;
var children = parent.childNodes;
var sib;
var index = -1;
for (var i = 0; i < children.length; i++) {
sib = children[i];
if(sib.nodeType === Node.TEXT_NODE){
index++;
}
if(sib == textNode) break;
}
return index;
}; };

View file

@ -397,12 +397,13 @@ EPUBJS.EpubCFI.prototype.generateCfiFromRangeAnchor = function(range, base) {
EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) { EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) {
var start, startElement, startSteps, startPath, startOffset, startIndex; var start, startElement, startSteps, startPath, startOffset, startIndex;
var end, endElement, endSteps, endPath, endOffset, endIndex; var end, endElement, endSteps, endPath, endOffset, endIndex;
start = range.startContainer; start = range.startContainer;
if(start.nodeType === 3) { // text node if(start.nodeType === 3) { // text node
startElement = start.parentElement; startElement = start.parentElement;
startIndex = 1 + (2 * Array.prototype.indexOf.call(startElement.childNodes, start)); //startIndex = 1 + (2 * Array.prototype.indexOf.call(startElement.childNodes, start));
startIndex = 1 + (2 * EPUBJS.core.indexOfTextNode(start));
startSteps = this.pathTo(startElement); startSteps = this.pathTo(startElement);
} else if(range.collapsed) { } else if(range.collapsed) {
return this.generateCfiFromElement(start, base); // single element return this.generateCfiFromElement(start, base); // single element
@ -418,7 +419,9 @@ EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) {
if(end.nodeType === 3) { // text node if(end.nodeType === 3) { // text node
endElement = end.parentElement; endElement = end.parentElement;
endIndex = 1 + (2 * Array.prototype.indexOf.call(endElement.childNodes, end)); // endIndex = 1 + (2 * Array.prototype.indexOf.call(endElement.childNodes, end));
endIndex = 1 + (2 * EPUBJS.core.indexOfTextNode(end));
endSteps = this.pathTo(endElement); endSteps = this.pathTo(endElement);
} else { } else {
endSteps = this.pathTo(end); endSteps = this.pathTo(end);
@ -476,18 +479,21 @@ EPUBJS.EpubCFI.prototype.generateRangeFromCfi = function(cfi, _doc) {
// Get the terminal step // Get the terminal step
lastStep = cfi.steps[cfi.steps.length-1]; lastStep = cfi.steps[cfi.steps.length-1];
startContainer = doc.evaluate(xpath, doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; startContainer = doc.evaluate(xpath, doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if(!startContainer) { if(!startContainer) {
return null; return null;
} }
if(startContainer && cfi.characterOffset >= 0) { if(startContainer && cfi.characterOffset >= 0) {
textLength = startContainer.length; textLength = startContainer.length;
if(cfi.characterOffset < textLength) { if(cfi.characterOffset < textLength) {
range.setStart(startContainer, cfi.characterOffset); range.setStart(startContainer, cfi.characterOffset);
range.setEnd(startContainer, textLength ); range.setEnd(startContainer, textLength );
} else { } else {
range.setStart(startContainer, cfi.characterOffset - 1 ); console.debug("offset greater than length:", cfi.characterOffset, textLength);
range.setEnd(startContainer, cfi.characterOffset ); range.setStart(startContainer, textLength - 1 );
range.setEnd(startContainer, textLength );
} }
} else if(startContainer) { } else if(startContainer) {
range.selectNode(startContainer); range.selectNode(startContainer);

View file

@ -10,6 +10,7 @@ EPUBJS.Layout.Reflowable.prototype.format = function(documentElement, _width, _h
var columnAxis = EPUBJS.core.prefixed('columnAxis'); var columnAxis = EPUBJS.core.prefixed('columnAxis');
var columnGap = EPUBJS.core.prefixed('columnGap'); var columnGap = EPUBJS.core.prefixed('columnGap');
var columnWidth = EPUBJS.core.prefixed('columnWidth'); var columnWidth = EPUBJS.core.prefixed('columnWidth');
var columnFill = EPUBJS.core.prefixed('columnFill');
//-- Check the width and create even width columns //-- Check the width and create even width columns
var width = Math.floor(_width); var width = Math.floor(_width);
@ -31,6 +32,7 @@ EPUBJS.Layout.Reflowable.prototype.format = function(documentElement, _width, _h
//-- Add columns //-- Add columns
documentElement.style[columnAxis] = "horizontal"; documentElement.style[columnAxis] = "horizontal";
documentElement.style[columnFill] = "auto";
documentElement.style[columnWidth] = width+"px"; documentElement.style[columnWidth] = width+"px";
documentElement.style[columnGap] = gap+"px"; documentElement.style[columnGap] = gap+"px";
this.colWidth = width; this.colWidth = width;
@ -63,6 +65,7 @@ EPUBJS.Layout.ReflowableSpreads.prototype.format = function(documentElement, _wi
var columnAxis = EPUBJS.core.prefixed('columnAxis'); var columnAxis = EPUBJS.core.prefixed('columnAxis');
var columnGap = EPUBJS.core.prefixed('columnGap'); var columnGap = EPUBJS.core.prefixed('columnGap');
var columnWidth = EPUBJS.core.prefixed('columnWidth'); var columnWidth = EPUBJS.core.prefixed('columnWidth');
var columnFill = EPUBJS.core.prefixed('columnFill');
var divisor = 2, var divisor = 2,
cutoff = 800; cutoff = 800;
@ -91,8 +94,10 @@ EPUBJS.Layout.ReflowableSpreads.prototype.format = function(documentElement, _wi
//-- Add columns //-- Add columns
documentElement.style[columnAxis] = "horizontal"; documentElement.style[columnAxis] = "horizontal";
documentElement.style[columnFill] = "auto";
documentElement.style[columnGap] = gap+"px"; documentElement.style[columnGap] = gap+"px";
documentElement.style[columnWidth] = colWidth+"px"; documentElement.style[columnWidth] = colWidth+"px";
this.colWidth = colWidth; this.colWidth = colWidth;
this.gap = gap; this.gap = gap;
return { return {

View file

@ -69,7 +69,9 @@ EPUBJS.Render.Iframe.prototype.load = function(url){
EPUBJS.Render.Iframe.prototype.loaded = function(v){ EPUBJS.Render.Iframe.prototype.loaded = function(v){
var url = this.iframe.contentWindow.location.href; var url = this.iframe.contentWindow.location.href;
this.trigger("render:loaded", url); if(url != "about:blank"){
this.trigger("render:loaded", url);
}
}; };
// Resize the iframe to the given width and height // Resize the iframe to the given width and height

View file

@ -29,7 +29,7 @@ EPUBJS.Renderer = function(renderMethod, hidden) {
this.spreads = true; this.spreads = true;
this.isForcedSingle = false; this.isForcedSingle = false;
this.resized = _.throttle(this.onResized.bind(this), 10); this.resized = _.debounce(this.onResized.bind(this), 100);
this.layoutSettings = {}; this.layoutSettings = {};
@ -42,6 +42,8 @@ EPUBJS.Renderer = function(renderMethod, hidden) {
//-- Queue up page changes if page map isn't ready //-- Queue up page changes if page map isn't ready
this._q = EPUBJS.core.queue(this); this._q = EPUBJS.core.queue(this);
this._moving = false;
}; };
@ -95,14 +97,23 @@ EPUBJS.Renderer.prototype.initialize = function(element, width, height){
*/ */
EPUBJS.Renderer.prototype.displayChapter = function(chapter, globalLayout){ EPUBJS.Renderer.prototype.displayChapter = function(chapter, globalLayout){
var store = false; var store = false;
if(this._moving) {
console.error("Rendering In Progress");
return;
}
this._moving = true;
// Get the url string from the chapter (may be from storage) // Get the url string from the chapter (may be from storage)
return chapter.url(). return chapter.url().
then(function(url) { then(function(url) {
// Unload the previous chapter listener // Unload the previous chapter listener
if(this.currentChapter) { if(this.currentChapter) {
this.currentChapter.unload(); // Remove stored blobs this.currentChapter.unload(); // Remove stored blobs
this.render.window.removeEventListener("resize", this.resized);
if(this.render.window){
this.render.window.removeEventListener("resize", this.resized);
}
this.removeEventListeners(); this.removeEventListeners();
this.removeSelectionListeners(); this.removeSelectionListeners();
this.trigger("renderer:chapterUnloaded"); this.trigger("renderer:chapterUnloaded");
@ -110,10 +121,9 @@ EPUBJS.Renderer.prototype.displayChapter = function(chapter, globalLayout){
this.doc = null; this.doc = null;
this.pageMap = null; this.pageMap = null;
} }
this.currentChapter = chapter; this.currentChapter = chapter;
this.chapterPos = 1; this.chapterPos = 1;
this.pageMap = null;
this.currentChapterCfiBase = chapter.cfiBase; this.currentChapterCfiBase = chapter.cfiBase;
this.layoutSettings = this.reconcileLayoutSettings(globalLayout, chapter.properties); this.layoutSettings = this.reconcileLayoutSettings(globalLayout, chapter.properties);
@ -151,11 +161,11 @@ EPUBJS.Renderer.prototype.load = function(url){
this.formated = this.layout.format(contents, this.render.width, this.render.height, this.gap); this.formated = this.layout.format(contents, this.render.width, this.render.height, this.gap);
this.render.setPageDimensions(this.formated.pageWidth, this.formated.pageHeight); this.render.setPageDimensions(this.formated.pageWidth, this.formated.pageHeight);
// window.addEventListener("orientationchange", this.onResized.bind(this), false);
if(!this.initWidth && !this.initHeight){ if(!this.initWidth && !this.initHeight){
this.render.window.addEventListener("resize", this.resized, false); this.render.window.addEventListener("resize", this.resized, false);
} }
this.addEventListeners(); this.addEventListeners();
this.addSelectionListeners(); this.addSelectionListeners();
@ -163,18 +173,24 @@ EPUBJS.Renderer.prototype.load = function(url){
this.beforeDisplay(function(){ this.beforeDisplay(function(){
var pages = this.layout.calculatePages(); var pages = this.layout.calculatePages();
var msg = this.currentChapter; var msg = this.currentChapter;
this.updatePages(pages); var queued = this._q.length();
this._moving = false;
this.updatePages(pages);
this.visibleRangeCfi = this.getVisibleRangeCfi(); this.visibleRangeCfi = this.getVisibleRangeCfi();
this.currentLocationCfi = this.visibleRangeCfi.start; this.currentLocationCfi = this.visibleRangeCfi.start;
this.trigger("renderer:locationChanged", this.currentLocationCfi);
this.trigger("renderer:visibleRangeChanged", this.visibleRangeCfi);
msg.cfi = this.currentLocationCfi; if(queued === 0) {
this.trigger("renderer:locationChanged", this.currentLocationCfi);
this.trigger("renderer:visibleRangeChanged", this.visibleRangeCfi);
}
msg.cfi = this.currentLocationCfi; //TODO: why is this cfi passed to chapterDisplayed
this.trigger("renderer:chapterDisplayed", msg); this.trigger("renderer:chapterDisplayed", msg);
this.visible(true); this.visible(true);
deferred.resolve(this); //-- why does this return the renderer? deferred.resolve(this); //-- why does this return the renderer?
}.bind(this)); }.bind(this));
@ -265,9 +281,17 @@ EPUBJS.Renderer.prototype.beforeDisplay = function(callback, renderer){
// Update the renderer with the information passed by the layout // Update the renderer with the information passed by the layout
EPUBJS.Renderer.prototype.updatePages = function(layout){ EPUBJS.Renderer.prototype.updatePages = function(layout){
this.pageMap = this.mapPage(); this.pageMap = this.mapPage();
this.displayedPages = layout.displayedPages; // this.displayedPages = layout.displayedPages;
this.currentChapter.pages = layout.pageCount;
if (this.spreads) {
this.displayedPages = Math.ceil(this.pageMap.length / 2);
} else {
this.displayedPages = this.pageMap.length;
}
// this.currentChapter.pages = layout.pageCount;
this.currentChapter.pages = this.pageMap.length;
this._q.flush(); this._q.flush();
}; };
@ -277,8 +301,13 @@ EPUBJS.Renderer.prototype.reformat = function(){
var formated, pages; var formated, pages;
if(!this.contents) return; if(!this.contents) return;
this.layoutMethod = this.determineLayout(this.layoutSettings); spreads = this.determineSpreads(this.minSpreadWidth);
this.layout = new EPUBJS.Layout[this.layoutMethod](); // Only re-layout if the spreads have switched
if(spreads != this.spreads){
this.spreads = spreads;
this.layoutMethod = this.determineLayout(this.layoutSettings);
this.layout = new EPUBJS.Layout[this.layoutMethod]();
}
this.formated = this.layout.format(this.contents, this.render.width, this.render.height, this.gap); this.formated = this.layout.format(this.contents, this.render.width, this.render.height, this.gap);
this.render.setPageDimensions(this.formated.pageWidth, this.formated.pageHeight); this.render.setPageDimensions(this.formated.pageWidth, this.formated.pageHeight);
@ -349,8 +378,8 @@ EPUBJS.Renderer.prototype.applyHeadTags = function(headTags) {
//-- NAVIGATION //-- NAVIGATION
EPUBJS.Renderer.prototype.page = function(pg){ EPUBJS.Renderer.prototype.page = function(pg){
if(!this.pageMap) { if(!this.pageMap) {
console.warn("pageMap not set, queuing");
this._q.enqueue("page", arguments); this._q.enqueue("page", arguments);
return true; return true;
} }
@ -407,6 +436,10 @@ EPUBJS.Renderer.prototype.pageByElement = function(el){
// Jump to the last page of the chapter // Jump to the last page of the chapter
EPUBJS.Renderer.prototype.lastPage = function(){ EPUBJS.Renderer.prototype.lastPage = function(){
if(this._moving) {
return this._q.enqueue("lastPage", arguments);
}
this.page(this.displayedPages); this.page(this.displayedPages);
}; };
@ -521,7 +554,7 @@ EPUBJS.Renderer.prototype.textSprint = function(root, func) {
}; };
EPUBJS.Renderer.prototype.sprint = function(root, func) { EPUBJS.Renderer.prototype.sprint = function(root, func) {
var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, false, false); var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, null, false);
var node; var node;
while ((node = treeWalker.nextNode())) { while ((node = treeWalker.nextNode())) {
func(node); func(node);
@ -542,15 +575,30 @@ EPUBJS.Renderer.prototype.mapPage = function(){
var cfi; var cfi;
var check = function(node) { var check = function(node) {
var elPos; var elPos;
var elRange;
var children = Array.prototype.slice.call(node.childNodes); var children = Array.prototype.slice.call(node.childNodes);
if (node.nodeType == Node.ELEMENT_NODE) { if (node.nodeType == Node.ELEMENT_NODE) {
elPos = node.getBoundingClientRect(); // elPos = node.getBoundingClientRect();
elRange = document.createRange();
elRange.selectNodeContents(node);
elPos = elRange.getBoundingClientRect();
if(!elPos || (elPos.width === 0 && elPos.height === 0)) { if(!elPos || (elPos.width === 0 && elPos.height === 0)) {
return; return;
} }
if(elPos.left + elPos.width > elLimit) { //-- Element starts new Col
if(elPos.left > elLimit) {
children.forEach(function(node){
if(node.nodeType == Node.TEXT_NODE &&
node.textContent.trim().length) {
checkText(node);
}
});
}
//-- Element Spans new Col
if(elPos.right > elLimit) {
children.forEach(function(node){ children.forEach(function(node){
if(node.nodeType == Node.TEXT_NODE && if(node.nodeType == Node.TEXT_NODE &&
node.textContent.trim().length) { node.textContent.trim().length) {
@ -589,6 +637,7 @@ EPUBJS.Renderer.prototype.mapPage = function(){
start: cfi, start: cfi,
end: null end: null
}); });
page += 1; page += 1;
limit = (width * page) - offset; limit = (width * page) - offset;
elLimit = limit; elLimit = limit;
@ -626,6 +675,7 @@ EPUBJS.Renderer.prototype.mapPage = function(){
ranges = null; ranges = null;
range = null; range = null;
root = null; root = null;
return map; return map;
}; };
@ -850,7 +900,7 @@ EPUBJS.Renderer.prototype.getVisibleRangeCfi = function(){
} }
if(!startRange) { if(!startRange) {
console.warn("page range miss:", pg); console.warn("page range miss:", pg, this.pageMap);
startRange = this.pageMap[this.pageMap.length-1]; startRange = this.pageMap[this.pageMap.length-1];
endRange = startRange; endRange = startRange;
} }
@ -866,7 +916,11 @@ EPUBJS.Renderer.prototype.gotoCfi = function(cfi){
var pg; var pg;
var marker; var marker;
var range; var range;
if(this._moving){
return this._q.enqueue("gotoCfi", arguments);
}
if(_.isString(cfi)){ if(_.isString(cfi)){
cfi = this.epubcfi.parse(cfi); cfi = this.epubcfi.parse(cfi);
} }
@ -941,13 +995,7 @@ EPUBJS.Renderer.prototype.resize = function(width, height, setSize){
this.render.resize(this.width, this.height); this.render.resize(this.width, this.height);
} }
spreads = this.determineSpreads(this.minSpreadWidth);
// Only re-layout if the spreads have switched
if(spreads != this.spreads){
this.spreads = spreads;
this.layoutMethod = this.determineLayout(this.layoutSettings);
this.layout = new EPUBJS.Layout[this.layoutMethod]();
}
if(this.contents){ if(this.contents){
this.reformat(); this.reformat();
@ -969,7 +1017,9 @@ EPUBJS.Renderer.prototype.onResized = function(e) {
}; };
EPUBJS.Renderer.prototype.addEventListeners = function(){ EPUBJS.Renderer.prototype.addEventListeners = function(){
if(!this.render.document) {
return;
}
this.listenedEvents.forEach(function(eventName){ this.listenedEvents.forEach(function(eventName){
this.render.document.addEventListener(eventName, this.triggerEvent.bind(this), false); this.render.document.addEventListener(eventName, this.triggerEvent.bind(this), false);
}, this); }, this);
@ -977,7 +1027,9 @@ EPUBJS.Renderer.prototype.addEventListeners = function(){
}; };
EPUBJS.Renderer.prototype.removeEventListeners = function(){ EPUBJS.Renderer.prototype.removeEventListeners = function(){
if(!this.render.document) {
return;
}
this.listenedEvents.forEach(function(eventName){ this.listenedEvents.forEach(function(eventName){
this.render.document.removeEventListener(eventName, this.triggerEvent, false); this.render.document.removeEventListener(eventName, this.triggerEvent, false);
}, this); }, this);
@ -994,6 +1046,9 @@ EPUBJS.Renderer.prototype.addSelectionListeners = function(){
}; };
EPUBJS.Renderer.prototype.removeSelectionListeners = function(){ EPUBJS.Renderer.prototype.removeSelectionListeners = function(){
if(!this.render.document) {
return;
}
this.doc.removeEventListener("selectionchange", this.onSelectionChange, false); this.doc.removeEventListener("selectionchange", this.onSelectionChange, false);
}; };