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

Added locations

This commit is contained in:
fchasen 2015-07-08 21:54:00 -04:00
parent d7371a619d
commit 80787fc86b
10 changed files with 648 additions and 125 deletions

377
dist/epub.js vendored
View file

@ -2174,6 +2174,7 @@ EPUBJS.Queue = function(_context){
this.context = _context; this.context = _context;
this.tick = EPUBJS.core.requestAnimationFrame; this.tick = EPUBJS.core.requestAnimationFrame;
this.running = false; this.running = false;
this.paused = false;
}; };
// Add an item to the queue // Add an item to the queue
@ -2215,7 +2216,11 @@ EPUBJS.Queue.prototype.enqueue = function() {
this._q.push(queued); this._q.push(queued);
// Wait to start queue flush // Wait to start queue flush
setTimeout(this.flush.bind(this), 0); if (this.paused == false && !this.running) {
// setTimeout(this.flush.bind(this), 0);
// this.tick.call(window, this.run.bind(this));
this.run();
}
return queued.promise; return queued.promise;
}; };
@ -2268,25 +2273,46 @@ EPUBJS.Queue.prototype.dump = function(){
// Run all sequentially, at convince // Run all sequentially, at convince
EPUBJS.Queue.prototype.run = function(){ EPUBJS.Queue.prototype.run = function(){
if(!this.running && this._q.length) {
if(!this.running){
this.running = true; this.running = true;
this.dequeue().then(function(){ this.defered = new RSVP.defer();
this.running = false;
}.bind(this));
} }
this.tick.call(window, this.run.bind(this)); this.tick.call(window, function() {
if(this._q.length) {
this.dequeue()
.then(function(){
this.run();
}.bind(this));
} else {
this.defered.resolve();
this.running = undefined;
}
}.bind(this));
// Unpause
if(this.paused == true) {
this.paused = false;
}
return this.defered.promise;
}; };
// Flush all, as quickly as possible // Flush all, as quickly as possible
EPUBJS.Queue.prototype.flush = function(){ EPUBJS.Queue.prototype.flush = function(){
if(this.running){ if(this.running){
return this.running; return this.running;
} }
if(this._q.length) { if(this._q.length) {
this.running = this.dequeue(). this.running = this.dequeue()
then(function(){ .then(function(){
this.running = undefined; this.running = undefined;
return this.flush(); return this.flush();
}.bind(this)); }.bind(this));
@ -2306,6 +2332,10 @@ EPUBJS.Queue.prototype.length = function(){
return this._q.length; return this._q.length;
}; };
EPUBJS.Queue.prototype.pause = function(){
this.paused = true;
};
// Create a new task from a callback // Create a new task from a callback
EPUBJS.Task = function(task, args, context){ EPUBJS.Task = function(task, args, context){
@ -2793,10 +2823,10 @@ EPUBJS.EpubCFI.prototype.pathTo = function(node) {
'tagName' : node.tagName, 'tagName' : node.tagName,
'index' : children ? Array.prototype.indexOf.call(children, node) : 0 'index' : children ? Array.prototype.indexOf.call(children, node) : 0
}); });
node = node.parentNode; node = node.parentNode;
} }
return stack; return stack;
}; };
@ -2835,21 +2865,21 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
text, text,
parseStep = function(part){ parseStep = function(part){
var type, index, has_brackets, id; var type, index, has_brackets, id;
type = "element"; type = "element";
index = parseInt(part) / 2 - 1; index = parseInt(part) / 2 - 1;
has_brackets = part.match(/\[(.*)\]/); has_brackets = part.match(/\[(.*)\]/);
if(has_brackets && has_brackets[1]){ if(has_brackets && has_brackets[1]){
id = has_brackets[1]; id = has_brackets[1];
} }
return { return {
"type" : type, "type" : type,
'index' : index, 'index' : index,
'id' : id || false 'id' : id || false
}; };
}; };
if(typeof cfiStr !== "string") { if(typeof cfiStr !== "string") {
return {spinePos: -1}; return {spinePos: -1};
} }
@ -2868,7 +2898,7 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
if(!chapterComponent) { if(!chapterComponent) {
return {spinePos: -1}; return {spinePos: -1};
} }
// Chapter segment is always the second one // Chapter segment is always the second one
chapSegment = chapterComponent.split("/")[2] || ''; chapSegment = chapterComponent.split("/")[2] || '';
if(!chapSegment) return {spinePos:-1}; if(!chapSegment) return {spinePos:-1};
@ -2891,7 +2921,7 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
path.forEach(function(part){ path.forEach(function(part){
var step; var step;
if(part) { if(part) {
step = parseStep(part); step = parseStep(part);
cfi.steps.push(step); cfi.steps.push(step);
@ -2901,7 +2931,7 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
//-- Check if END is a text node or element //-- Check if END is a text node or element
endInt = parseInt(end); endInt = parseInt(end);
if(!isNaN(endInt)) { if(!isNaN(endInt)) {
if(endInt % 2 === 0) { // Even = is an element if(endInt % 2 === 0) { // Even = is an element
cfi.steps.push(parseStep(end)); cfi.steps.push(parseStep(end));
} else { } else {
@ -2921,7 +2951,7 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
} else { } else {
cfi.characterOffset = parseInt(charecterOffsetComponent); cfi.characterOffset = parseInt(charecterOffsetComponent);
} }
return cfi; return cfi;
}; };
@ -2932,7 +2962,7 @@ EPUBJS.EpubCFI.prototype.addMarker = function(cfi, _doc, _marker) {
var lastStep; var lastStep;
var text; var text;
var split; var split;
if(typeof cfi === 'string') { if(typeof cfi === 'string') {
cfi = this.parse(cfi); cfi = this.parse(cfi);
} }
@ -2947,13 +2977,13 @@ EPUBJS.EpubCFI.prototype.addMarker = function(cfi, _doc, _marker) {
// Find the CFI elements parent // Find the CFI elements parent
parent = this.findParent(cfi, doc); parent = this.findParent(cfi, doc);
if(!parent) { if(!parent) {
// CFI didn't return an element // CFI didn't return an element
// Maybe it isnt in the current chapter? // Maybe it isnt in the current chapter?
return false; return false;
} }
if(lastStep && lastStep.type === "text") { if(lastStep && lastStep.type === "text") {
text = parent.childNodes[lastStep.index]; text = parent.childNodes[lastStep.index];
if(cfi.characterOffset){ if(cfi.characterOffset){
@ -2966,7 +2996,7 @@ EPUBJS.EpubCFI.prototype.addMarker = function(cfi, _doc, _marker) {
} else { } else {
parent.insertBefore(marker, parent.firstChild); parent.insertBefore(marker, parent.firstChild);
} }
return marker; return marker;
}; };
@ -2975,7 +3005,7 @@ EPUBJS.EpubCFI.prototype.createMarker = function(_doc) {
var element = doc.createElement('span'); var element = doc.createElement('span');
element.id = "EPUBJS-CFI-MARKER:"+ EPUBJS.core.uuid(); element.id = "EPUBJS-CFI-MARKER:"+ EPUBJS.core.uuid();
element.classList.add("EPUBJS-CFI-MARKER"); element.classList.add("EPUBJS-CFI-MARKER");
return element; return element;
}; };
@ -3013,7 +3043,7 @@ EPUBJS.EpubCFI.prototype.findParent = function(cfi, _doc) {
if(typeof cfi === 'string') { if(typeof cfi === 'string') {
cfi = this.parse(cfi); cfi = this.parse(cfi);
} }
sections = cfi.steps.slice(0); // Clone steps array sections = cfi.steps.slice(0); // Clone steps array
if(!sections.length) { if(!sections.length) {
return doc.getElementsByTagName('body')[0]; return doc.getElementsByTagName('body')[0];
@ -3058,8 +3088,8 @@ EPUBJS.EpubCFI.prototype.compare = function(cfiOne, cfiTwo) {
if(cfiOne.spinePos < cfiTwo.spinePos) { if(cfiOne.spinePos < cfiTwo.spinePos) {
return -1; return -1;
} }
// Compare Each Step in the First item // Compare Each Step in the First item
for (var i = 0; i < cfiOne.steps.length; i++) { for (var i = 0; i < cfiOne.steps.length; i++) {
if(!cfiTwo.steps[i]) { if(!cfiTwo.steps[i]) {
@ -3073,7 +3103,7 @@ EPUBJS.EpubCFI.prototype.compare = function(cfiOne, cfiTwo) {
} }
// Otherwise continue checking // Otherwise continue checking
} }
// All steps in First present in Second // All steps in First present in Second
if(cfiOne.steps.length < cfiTwo.steps.length) { if(cfiOne.steps.length < cfiTwo.steps.length) {
return -1; return -1;
@ -3100,7 +3130,7 @@ EPUBJS.EpubCFI.prototype.generateCfiFromHref = function(href, book) {
var deferred = new RSVP.defer(); var deferred = new RSVP.defer();
var epubcfi = new EPUBJS.EpubCFI(); var epubcfi = new EPUBJS.EpubCFI();
var spineItem; var spineItem;
if(typeof spinePos !== "undefined"){ if(typeof spinePos !== "undefined"){
spineItem = book.spine[spinePos]; spineItem = book.spine[spinePos];
loaded = book.loadXml(spineItem.url); loaded = book.loadXml(spineItem.url);
@ -3111,7 +3141,7 @@ EPUBJS.EpubCFI.prototype.generateCfiFromHref = function(href, book) {
deferred.resolve(cfi); deferred.resolve(cfi);
}); });
} }
return deferred.promise; return deferred.promise;
}; };
@ -3134,7 +3164,7 @@ EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) {
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.parentNode; startElement = start.parentNode;
//startIndex = 1 + (2 * Array.prototype.indexOf.call(startElement.childNodes, start)); //startIndex = 1 + (2 * Array.prototype.indexOf.call(startElement.childNodes, start));
@ -3145,18 +3175,18 @@ EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) {
} else { } else {
startSteps = this.pathTo(start); startSteps = this.pathTo(start);
} }
startPath = this.generatePathComponent(startSteps); startPath = this.generatePathComponent(startSteps);
startOffset = range.startOffset; startOffset = range.startOffset;
if(!range.collapsed) { if(!range.collapsed) {
end = range.endContainer; end = range.endContainer;
if(end.nodeType === 3) { // text node if(end.nodeType === 3) { // text node
endElement = end.parentNode; endElement = end.parentNode;
// 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)); 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);
@ -3165,8 +3195,15 @@ EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) {
endPath = this.generatePathComponent(endSteps); endPath = this.generatePathComponent(endSteps);
endOffset = range.endOffset; endOffset = range.endOffset;
return "epubcfi(" + base + "!" + startPath + "/" + startIndex + ":" + startOffset + "," + endPath + "/" + endIndex + ":" + endOffset + ")"; // Remove steps present in startPath
endPath = endPath.replace(startPath, '');
if (endPath.length) {
endPath = endPath + "/";
}
return "epubcfi(" + base + "!" + startPath + "/" + startIndex + ":" + startOffset + "," + endPath + endIndex + ":" + endOffset + ")";
} else { } else {
return "epubcfi(" + base + "!" + startPath + "/"+ startIndex +":"+ startOffset +")"; return "epubcfi(" + base + "!" + startPath + "/"+ startIndex +":"+ startOffset +")";
} }
@ -3177,7 +3214,7 @@ EPUBJS.EpubCFI.prototype.generateXpathFromSteps = function(steps) {
steps.forEach(function(step){ steps.forEach(function(step){
var position = step.index + 1; var position = step.index + 1;
if(step.id){ if(step.id){
xpath.push("*[position()=" + position + " and @id='" + step.id + "']"); xpath.push("*[position()=" + position + " and @id='" + step.id + "']");
} else if(step.type === "text") { } else if(step.type === "text") {
@ -3198,19 +3235,19 @@ EPUBJS.EpubCFI.prototype.generateRangeFromCfi = function(cfi, _doc) {
var xpath; var xpath;
var startContainer; var startContainer;
var textLength; var textLength;
if(typeof cfi === 'string') { if(typeof cfi === 'string') {
cfi = this.parse(cfi); cfi = this.parse(cfi);
} }
// check spinePos // check spinePos
if(cfi.spinePos === -1) { if(cfi.spinePos === -1) {
// Not a valid CFI // Not a valid CFI
return false; return false;
} }
xpath = this.generateXpathFromSteps(cfi.steps); xpath = this.generateXpathFromSteps(cfi.steps);
// 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;
@ -3228,7 +3265,7 @@ EPUBJS.EpubCFI.prototype.generateRangeFromCfi = function(cfi, _doc) {
} else { } else {
console.debug("offset greater than length:", cfi.characterOffset, textLength); console.debug("offset greater than length:", cfi.characterOffset, textLength);
range.setStart(startContainer, textLength - 1 ); range.setStart(startContainer, textLength - 1 );
range.setEnd(startContainer, textLength ); range.setEnd(startContainer, textLength );
} }
} else if(startContainer) { } else if(startContainer) {
range.selectNode(startContainer); range.selectNode(startContainer);
@ -3245,6 +3282,7 @@ EPUBJS.EpubCFI.prototype.isCfiString = function(target) {
return false; return false;
}; };
EPUBJS.Navigation = function(_package, _request){ EPUBJS.Navigation = function(_package, _request){
var navigation = this; var navigation = this;
var parse = new EPUBJS.Parser(); var parse = new EPUBJS.Parser();
@ -3349,7 +3387,7 @@ EPUBJS.Section = function(item){
this.url = item.url; this.url = item.url;
this.next = item.next; this.next = item.next;
this.prev = item.prev; this.prev = item.prev;
this.epubcfi = new EPUBJS.EpubCFI(); this.epubcfi = new EPUBJS.EpubCFI();
this.cfiBase = item.cfiBase; this.cfiBase = item.cfiBase;
@ -3386,7 +3424,7 @@ EPUBJS.Section.prototype.load = function(_request){
loading.reject(error); loading.reject(error);
}); });
} }
return loaded; return loaded;
}; };
@ -3406,7 +3444,7 @@ EPUBJS.Section.prototype.replacements = function(_document){
} else { } else {
task.reject(new Error("No head to insert into")); task.reject(new Error("No head to insert into"));
} }
return task.promise; return task.promise;
}; };
@ -3418,7 +3456,7 @@ EPUBJS.Section.prototype.beforeSectionLoad = function(){
EPUBJS.Section.prototype.render = function(_request){ EPUBJS.Section.prototype.render = function(_request){
var rendering = new RSVP.defer(); var rendering = new RSVP.defer();
var rendered = rendering.promise; var rendered = rendering.promise;
this.load(_request).then(function(contents){ this.load(_request).then(function(contents){
var serializer = new XMLSerializer(); var serializer = new XMLSerializer();
var output = serializer.serializeToString(contents); var output = serializer.serializeToString(contents);
@ -3468,6 +3506,11 @@ EPUBJS.Section.prototype.reconcileLayoutSettings = function(global){
EPUBJS.Section.prototype.cfiFromRange = function(_range) { EPUBJS.Section.prototype.cfiFromRange = function(_range) {
return this.epubcfi.generateCfiFromRange(_range, this.cfiBase); return this.epubcfi.generateCfiFromRange(_range, this.cfiBase);
}; };
EPUBJS.Section.prototype.cfiFromElement = function(el) {
return this.epubcfi.generateCfiFromElement(el, this.cfiBase);
};
EPUBJS.Spine = function(_request){ EPUBJS.Spine = function(_request){
this.request = _request; this.request = _request;
this.spineItems = []; this.spineItems = [];
@ -3580,6 +3623,10 @@ EPUBJS.Spine.prototype.remove = function(section) {
} }
}; };
EPUBJS.Spine.prototype.each = function() {
return this.spineItems.forEach.apply(this.spineItems, arguments);
};
EPUBJS.replace = {}; EPUBJS.replace = {};
EPUBJS.replace.links = function(view, renderer) { EPUBJS.replace.links = function(view, renderer) {
@ -3623,7 +3670,7 @@ EPUBJS.replace.links = function(view, renderer) {
}; };
EPUBJS.Book = function(_url){ EPUBJS.Book = function(_url, options){
// Promises // Promises
this.opening = new RSVP.defer(); this.opening = new RSVP.defer();
this.opened = this.opening.promise; this.opened = this.opening.promise;
@ -3631,8 +3678,6 @@ EPUBJS.Book = function(_url){
this.url = undefined; this.url = undefined;
this.spine = new EPUBJS.Spine(this.request);
this.loading = { this.loading = {
manifest: new RSVP.defer(), manifest: new RSVP.defer(),
spine: new RSVP.defer(), spine: new RSVP.defer(),
@ -3659,6 +3704,9 @@ EPUBJS.Book = function(_url){
this.request = this.requestMethod.bind(this); this.request = this.requestMethod.bind(this);
this.spine = new EPUBJS.Spine(this.request);
this.locations = new EPUBJS.Locations(this.spine, this.request);
if(_url) { if(_url) {
this.open(_url); this.open(_url);
} }
@ -3689,7 +3737,7 @@ EPUBJS.Book.prototype.open = function(_url){
// Direct link to package, no container // Direct link to package, no container
this.packageUrl = uri.href; this.packageUrl = uri.href;
this.containerUrl = ''; this.containerUrl = '';
if(uri.origin) { if(uri.origin) {
this.url = uri.base; this.url = uri.base;
} else if(window){ } else if(window){
@ -3707,9 +3755,9 @@ EPUBJS.Book.prototype.open = function(_url){
this.url = ''; this.url = '';
} }
// Find the path to the Package from the container // Find the path to the Package from the container
else if (!uri.extension) { else if (!uri.extension) {
this.containerUrl = _url + containerPath; this.containerUrl = _url + containerPath;
epubPackage = this.request(this.containerUrl). epubPackage = this.request(this.containerUrl).
@ -3720,7 +3768,7 @@ EPUBJS.Book.prototype.open = function(_url){
var packageUri = EPUBJS.core.uri(paths.packagePath); var packageUri = EPUBJS.core.uri(paths.packagePath);
book.packageUrl = _url + paths.packagePath; book.packageUrl = _url + paths.packagePath;
book.encoding = paths.encoding; book.encoding = paths.encoding;
// Set Url relative to the content // Set Url relative to the content
if(packageUri.origin) { if(packageUri.origin) {
book.url = packageUri.base; book.url = packageUri.base;
@ -3731,7 +3779,7 @@ EPUBJS.Book.prototype.open = function(_url){
book.url = packageUri.directory; book.url = packageUri.directory;
} }
return book.request(book.packageUrl); return book.request(book.packageUrl);
}).catch(function(error) { }).catch(function(error) {
// handle errors in either of the two requests // handle errors in either of the two requests
console.error("Could not load book at: " + (this.packageUrl || this.containerPath)); console.error("Could not load book at: " + (this.packageUrl || this.containerPath));
@ -3781,7 +3829,7 @@ EPUBJS.Book.prototype.unpack = function(packageXml){
book.toc = toc; book.toc = toc;
book.loading.navigation.resolve(book.toc); book.loading.navigation.resolve(book.toc);
}); });
// //-- Set Global Layout setting based on metadata // //-- Set Global Layout setting based on metadata
// MOVE TO RENDER // MOVE TO RENDER
// book.globalLayoutProperties = book.parseLayoutProperties(book.package.metadata); // book.globalLayoutProperties = book.parseLayoutProperties(book.package.metadata);
@ -3796,7 +3844,7 @@ EPUBJS.Book.prototype.section = function(target) {
// Sugar to render a book // Sugar to render a book
EPUBJS.Book.prototype.renderTo = function(element, options) { EPUBJS.Book.prototype.renderTo = function(element, options) {
var renderer = (options && options.method) ? var renderer = (options && options.method) ?
options.method.charAt(0).toUpperCase() + options.method.substr(1) : options.method.charAt(0).toUpperCase() + options.method.substr(1) :
"Rendition"; "Rendition";
@ -3808,7 +3856,7 @@ EPUBJS.Book.prototype.renderTo = function(element, options) {
EPUBJS.Book.prototype.requestMethod = function(_url) { EPUBJS.Book.prototype.requestMethod = function(_url) {
// Switch request methods // Switch request methods
if(this.archived) { if(this.archived) {
// TODO: handle archived // TODO: handle archived
} else { } else {
return EPUBJS.core.request(_url, 'xml', this.requestCredentials, this.requestHeaders); return EPUBJS.core.request(_url, 'xml', this.requestCredentials, this.requestHeaders);
} }
@ -3822,6 +3870,7 @@ EPUBJS.Book.prototype.setRequestCredentials = function(_credentials) {
EPUBJS.Book.prototype.setRequestHeaders = function(_headers) { EPUBJS.Book.prototype.setRequestHeaders = function(_headers) {
this.requestHeaders = _headers; this.requestHeaders = _headers;
}; };
//-- Enable binding events to book //-- Enable binding events to book
RSVP.EventTarget.mixin(EPUBJS.Book.prototype); RSVP.EventTarget.mixin(EPUBJS.Book.prototype);
@ -3837,6 +3886,7 @@ RSVP.configure('instrument', true); //-- true | will logging out all RSVP reject
RSVP.on('rejected', function(event){ RSVP.on('rejected', function(event){
console.error(event.detail.message, event.detail.stack); console.error(event.detail.message, event.detail.stack);
}); });
EPUBJS.View = function(section, options) { EPUBJS.View = function(section, options) {
this.settings = options || {}; this.settings = options || {};
@ -6494,4 +6544,215 @@ EPUBJS.Map.prototype.rangeListToCfiList = function(view, columns){
} }
return map; return map;
}; };
EPUBJS.Locations = function(spine, request) {
this.spine = spine;
this.request = request;
this.q = new EPUBJS.Queue(this);
this.epubcfi = new EPUBJS.EpubCFI();
this._locations = [];
this.total = 0;
this.break = 150;
this._current = 0;
};
// Load all of sections in the book
EPUBJS.Locations.prototype.generate = function(chars) {
if (chars) {
this.break = chars;
}
this.q.pause();
this.spine.each(function(section) {
this.q.enqueue(this.process, section);
}.bind(this));
return this.q.run().then(function() {
this.total = this._locations.length-1;
if (this._currentCfi) {
this.currentLocation = this._currentCfi;
}
return this._locations;
// console.log(this.precentage(this.book.rendition.location.start), this.precentage(this.book.rendition.location.end));
}.bind(this));
};
EPUBJS.Locations.prototype.process = function(section) {
return section.load(this.request)
.then(function(contents) {
var range;
var doc = contents.ownerDocument;
var counter = 0;
this.sprint(contents, function(node) {
var len = node.length;
var dist;
var pos = 0;
// Start range
if (counter == 0) {
range = doc.createRange();
range.setStart(node, 0);
}
dist = this.break - counter;
// Node is smaller than a break
if(dist > len){
counter += len;
pos = len;
}
while (pos < len) {
counter = this.break;
pos += this.break;
// Gone over
if(pos >= len){
// Continue counter for next node
counter = len - (pos - this.break);
// At End
} else {
// End the previous range
range.setEnd(node, pos);
cfi = section.cfiFromRange(range);
this._locations.push(cfi);
counter = 0;
// Start new range
pos += 1;
range = doc.createRange();
range.setStart(node, pos);
}
}
}.bind(this));
// Close remaining
if (range) {
range.setEnd(prev, prev.length);
cfi = section.cfiFromRange(range);
this._locations.push(cfi)
counter = 0;
}
}.bind(this));
};
EPUBJS.Locations.prototype.sprint = function(root, func) {
var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null, false);
while ((node = treeWalker.nextNode())) {
func(node);
}
};
EPUBJS.Locations.prototype.locationFromCfi = function(cfi){
// Check if the location has not been set yet
if(this._locations.length === 0) {
return -1;
}
return EPUBJS.core.locationOf(cfi, this._locations, this.epubcfi.compare);
};
EPUBJS.Locations.prototype.precentageFromCfi = function(cfi) {
// Find closest cfi
var loc = this.locationFromCfi(cfi);
// Get percentage in total
return this.precentageFromLocation(loc);
};
EPUBJS.Locations.prototype.precentageFromLocation = function(loc) {
return Math.ceil((loc / this.total ) * 1000) / 1000;
};
EPUBJS.Locations.prototype.cfiFromLocation = function(loc){
var cfi = -1;
// check that pg is an int
if(typeof loc != "number"){
loc = parseInt(pg);
}
if(loc >= 0 && loc < this._locations.length) {
cfi = this._locations[loc];
}
return cfi;
};
EPUBJS.Locations.prototype.cfiFromPercentage = function(percent){
var loc = Math.round(this.total * percent);
return this.cfiFromLocation(loc);
};
EPUBJS.Locations.prototype.load = function(locations){
this._locations = JSON.parse(locations);
this.total = this._locations.length-1;
return this._locations;
};
EPUBJS.Locations.prototype.save = function(json){
return JSON.stringify(this._locations);
};
EPUBJS.Locations.prototype.getCurrent = function(json){
return this._current;
};
EPUBJS.Locations.prototype.setCurrent = function(curr){
var loc;
if(typeof curr == "string"){
this._currentCfi = curr;
} else if (typeof curr == "number") {
this._current = curr;
} else {
return;
}
if(this._locations.length === 0) {
return;
}
if(typeof curr == "string"){
loc = this.locationFromCfi(curr);
this._current = loc;
} else {
loc = curr;
}
console.log( this.precentageFromLocation(loc))
this.trigger("changed", {
percentage: this.precentageFromLocation(loc)
});
};
Object.defineProperty(EPUBJS.Locations.prototype, 'currentLocation', {
get: function () {
return this._current;
},
set: function (curr) {
this.setCurrent(curr);
}
});
RSVP.EventTarget.mixin(EPUBJS.Locations.prototype);

6
dist/epub.min.js vendored

File diff suppressed because one or more lines are too long

View file

@ -119,7 +119,7 @@
<script> <script>
// Load the opf // Load the opf
// var book = ePub("https://s3.amazonaws.com/moby-dick/OPS/package.opf"); // var book = ePub("https://s3.amazonaws.com/moby-dick/OPS/package.opf");
var book = ePub("books/alice/OPS/package.opf"); var book = ePub("../books/alice/OPS/package.opf");
var rendition = book.renderTo("viewer", { var rendition = book.renderTo("viewer", {
method: "paginate", method: "paginate",
width: "100%", width: "100%",
@ -148,7 +148,7 @@
rendition.prev(); rendition.prev();
}, false); }, false);
document.addEventListener("keyup", function(e){ var keyListener = function(e){
// Left Key // Left Key
if ((e.keyCode || e.which) == 37) { if ((e.keyCode || e.which) == 37) {
@ -160,7 +160,10 @@
rendition.next(); rendition.next();
} }
}, false); };
rendition.on("keyup", keyListener);
document.addEventListener("keyup", keyListener, false);
</script> </script>

View file

@ -29,7 +29,8 @@ var files = [
'src/rendition.js', 'src/rendition.js',
'src/continuous.js', 'src/continuous.js',
'src/paginate.js', 'src/paginate.js',
'src/map.js' 'src/map.js',
'src/locations.js'
]; ];
// Lint JS // Lint JS

View file

@ -1,4 +1,4 @@
EPUBJS.Book = function(_url){ EPUBJS.Book = function(_url, options){
// Promises // Promises
this.opening = new RSVP.defer(); this.opening = new RSVP.defer();
this.opened = this.opening.promise; this.opened = this.opening.promise;
@ -6,8 +6,6 @@ EPUBJS.Book = function(_url){
this.url = undefined; this.url = undefined;
this.spine = new EPUBJS.Spine(this.request);
this.loading = { this.loading = {
manifest: new RSVP.defer(), manifest: new RSVP.defer(),
spine: new RSVP.defer(), spine: new RSVP.defer(),
@ -34,6 +32,9 @@ EPUBJS.Book = function(_url){
this.request = this.requestMethod.bind(this); this.request = this.requestMethod.bind(this);
this.spine = new EPUBJS.Spine(this.request);
this.locations = new EPUBJS.Locations(this.spine, this.request);
if(_url) { if(_url) {
this.open(_url); this.open(_url);
} }
@ -64,7 +65,7 @@ EPUBJS.Book.prototype.open = function(_url){
// Direct link to package, no container // Direct link to package, no container
this.packageUrl = uri.href; this.packageUrl = uri.href;
this.containerUrl = ''; this.containerUrl = '';
if(uri.origin) { if(uri.origin) {
this.url = uri.base; this.url = uri.base;
} else if(window){ } else if(window){
@ -82,9 +83,9 @@ EPUBJS.Book.prototype.open = function(_url){
this.url = ''; this.url = '';
} }
// Find the path to the Package from the container // Find the path to the Package from the container
else if (!uri.extension) { else if (!uri.extension) {
this.containerUrl = _url + containerPath; this.containerUrl = _url + containerPath;
epubPackage = this.request(this.containerUrl). epubPackage = this.request(this.containerUrl).
@ -95,7 +96,7 @@ EPUBJS.Book.prototype.open = function(_url){
var packageUri = EPUBJS.core.uri(paths.packagePath); var packageUri = EPUBJS.core.uri(paths.packagePath);
book.packageUrl = _url + paths.packagePath; book.packageUrl = _url + paths.packagePath;
book.encoding = paths.encoding; book.encoding = paths.encoding;
// Set Url relative to the content // Set Url relative to the content
if(packageUri.origin) { if(packageUri.origin) {
book.url = packageUri.base; book.url = packageUri.base;
@ -106,7 +107,7 @@ EPUBJS.Book.prototype.open = function(_url){
book.url = packageUri.directory; book.url = packageUri.directory;
} }
return book.request(book.packageUrl); return book.request(book.packageUrl);
}).catch(function(error) { }).catch(function(error) {
// handle errors in either of the two requests // handle errors in either of the two requests
console.error("Could not load book at: " + (this.packageUrl || this.containerPath)); console.error("Could not load book at: " + (this.packageUrl || this.containerPath));
@ -156,7 +157,7 @@ EPUBJS.Book.prototype.unpack = function(packageXml){
book.toc = toc; book.toc = toc;
book.loading.navigation.resolve(book.toc); book.loading.navigation.resolve(book.toc);
}); });
// //-- Set Global Layout setting based on metadata // //-- Set Global Layout setting based on metadata
// MOVE TO RENDER // MOVE TO RENDER
// book.globalLayoutProperties = book.parseLayoutProperties(book.package.metadata); // book.globalLayoutProperties = book.parseLayoutProperties(book.package.metadata);
@ -171,7 +172,7 @@ EPUBJS.Book.prototype.section = function(target) {
// Sugar to render a book // Sugar to render a book
EPUBJS.Book.prototype.renderTo = function(element, options) { EPUBJS.Book.prototype.renderTo = function(element, options) {
var renderer = (options && options.method) ? var renderer = (options && options.method) ?
options.method.charAt(0).toUpperCase() + options.method.substr(1) : options.method.charAt(0).toUpperCase() + options.method.substr(1) :
"Rendition"; "Rendition";
@ -183,7 +184,7 @@ EPUBJS.Book.prototype.renderTo = function(element, options) {
EPUBJS.Book.prototype.requestMethod = function(_url) { EPUBJS.Book.prototype.requestMethod = function(_url) {
// Switch request methods // Switch request methods
if(this.archived) { if(this.archived) {
// TODO: handle archived // TODO: handle archived
} else { } else {
return EPUBJS.core.request(_url, 'xml', this.requestCredentials, this.requestHeaders); return EPUBJS.core.request(_url, 'xml', this.requestCredentials, this.requestHeaders);
} }
@ -197,6 +198,7 @@ EPUBJS.Book.prototype.setRequestCredentials = function(_credentials) {
EPUBJS.Book.prototype.setRequestHeaders = function(_headers) { EPUBJS.Book.prototype.setRequestHeaders = function(_headers) {
this.requestHeaders = _headers; this.requestHeaders = _headers;
}; };
//-- Enable binding events to book //-- Enable binding events to book
RSVP.EventTarget.mixin(EPUBJS.Book.prototype); RSVP.EventTarget.mixin(EPUBJS.Book.prototype);
@ -211,4 +213,4 @@ RSVP.configure('instrument', true); //-- true | will logging out all RSVP reject
// RSVP.on('fulfilled', listener); // RSVP.on('fulfilled', listener);
RSVP.on('rejected', function(event){ RSVP.on('rejected', function(event){
console.error(event.detail.message, event.detail.stack); console.error(event.detail.message, event.detail.stack);
}); });

View file

@ -58,10 +58,10 @@ EPUBJS.EpubCFI.prototype.pathTo = function(node) {
'tagName' : node.tagName, 'tagName' : node.tagName,
'index' : children ? Array.prototype.indexOf.call(children, node) : 0 'index' : children ? Array.prototype.indexOf.call(children, node) : 0
}); });
node = node.parentNode; node = node.parentNode;
} }
return stack; return stack;
}; };
@ -100,21 +100,21 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
text, text,
parseStep = function(part){ parseStep = function(part){
var type, index, has_brackets, id; var type, index, has_brackets, id;
type = "element"; type = "element";
index = parseInt(part) / 2 - 1; index = parseInt(part) / 2 - 1;
has_brackets = part.match(/\[(.*)\]/); has_brackets = part.match(/\[(.*)\]/);
if(has_brackets && has_brackets[1]){ if(has_brackets && has_brackets[1]){
id = has_brackets[1]; id = has_brackets[1];
} }
return { return {
"type" : type, "type" : type,
'index' : index, 'index' : index,
'id' : id || false 'id' : id || false
}; };
}; };
if(typeof cfiStr !== "string") { if(typeof cfiStr !== "string") {
return {spinePos: -1}; return {spinePos: -1};
} }
@ -133,7 +133,7 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
if(!chapterComponent) { if(!chapterComponent) {
return {spinePos: -1}; return {spinePos: -1};
} }
// Chapter segment is always the second one // Chapter segment is always the second one
chapSegment = chapterComponent.split("/")[2] || ''; chapSegment = chapterComponent.split("/")[2] || '';
if(!chapSegment) return {spinePos:-1}; if(!chapSegment) return {spinePos:-1};
@ -156,7 +156,7 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
path.forEach(function(part){ path.forEach(function(part){
var step; var step;
if(part) { if(part) {
step = parseStep(part); step = parseStep(part);
cfi.steps.push(step); cfi.steps.push(step);
@ -166,7 +166,7 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
//-- Check if END is a text node or element //-- Check if END is a text node or element
endInt = parseInt(end); endInt = parseInt(end);
if(!isNaN(endInt)) { if(!isNaN(endInt)) {
if(endInt % 2 === 0) { // Even = is an element if(endInt % 2 === 0) { // Even = is an element
cfi.steps.push(parseStep(end)); cfi.steps.push(parseStep(end));
} else { } else {
@ -186,7 +186,7 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
} else { } else {
cfi.characterOffset = parseInt(charecterOffsetComponent); cfi.characterOffset = parseInt(charecterOffsetComponent);
} }
return cfi; return cfi;
}; };
@ -197,7 +197,7 @@ EPUBJS.EpubCFI.prototype.addMarker = function(cfi, _doc, _marker) {
var lastStep; var lastStep;
var text; var text;
var split; var split;
if(typeof cfi === 'string') { if(typeof cfi === 'string') {
cfi = this.parse(cfi); cfi = this.parse(cfi);
} }
@ -212,13 +212,13 @@ EPUBJS.EpubCFI.prototype.addMarker = function(cfi, _doc, _marker) {
// Find the CFI elements parent // Find the CFI elements parent
parent = this.findParent(cfi, doc); parent = this.findParent(cfi, doc);
if(!parent) { if(!parent) {
// CFI didn't return an element // CFI didn't return an element
// Maybe it isnt in the current chapter? // Maybe it isnt in the current chapter?
return false; return false;
} }
if(lastStep && lastStep.type === "text") { if(lastStep && lastStep.type === "text") {
text = parent.childNodes[lastStep.index]; text = parent.childNodes[lastStep.index];
if(cfi.characterOffset){ if(cfi.characterOffset){
@ -231,7 +231,7 @@ EPUBJS.EpubCFI.prototype.addMarker = function(cfi, _doc, _marker) {
} else { } else {
parent.insertBefore(marker, parent.firstChild); parent.insertBefore(marker, parent.firstChild);
} }
return marker; return marker;
}; };
@ -240,7 +240,7 @@ EPUBJS.EpubCFI.prototype.createMarker = function(_doc) {
var element = doc.createElement('span'); var element = doc.createElement('span');
element.id = "EPUBJS-CFI-MARKER:"+ EPUBJS.core.uuid(); element.id = "EPUBJS-CFI-MARKER:"+ EPUBJS.core.uuid();
element.classList.add("EPUBJS-CFI-MARKER"); element.classList.add("EPUBJS-CFI-MARKER");
return element; return element;
}; };
@ -278,7 +278,7 @@ EPUBJS.EpubCFI.prototype.findParent = function(cfi, _doc) {
if(typeof cfi === 'string') { if(typeof cfi === 'string') {
cfi = this.parse(cfi); cfi = this.parse(cfi);
} }
sections = cfi.steps.slice(0); // Clone steps array sections = cfi.steps.slice(0); // Clone steps array
if(!sections.length) { if(!sections.length) {
return doc.getElementsByTagName('body')[0]; return doc.getElementsByTagName('body')[0];
@ -323,8 +323,8 @@ EPUBJS.EpubCFI.prototype.compare = function(cfiOne, cfiTwo) {
if(cfiOne.spinePos < cfiTwo.spinePos) { if(cfiOne.spinePos < cfiTwo.spinePos) {
return -1; return -1;
} }
// Compare Each Step in the First item // Compare Each Step in the First item
for (var i = 0; i < cfiOne.steps.length; i++) { for (var i = 0; i < cfiOne.steps.length; i++) {
if(!cfiTwo.steps[i]) { if(!cfiTwo.steps[i]) {
@ -338,7 +338,7 @@ EPUBJS.EpubCFI.prototype.compare = function(cfiOne, cfiTwo) {
} }
// Otherwise continue checking // Otherwise continue checking
} }
// All steps in First present in Second // All steps in First present in Second
if(cfiOne.steps.length < cfiTwo.steps.length) { if(cfiOne.steps.length < cfiTwo.steps.length) {
return -1; return -1;
@ -365,7 +365,7 @@ EPUBJS.EpubCFI.prototype.generateCfiFromHref = function(href, book) {
var deferred = new RSVP.defer(); var deferred = new RSVP.defer();
var epubcfi = new EPUBJS.EpubCFI(); var epubcfi = new EPUBJS.EpubCFI();
var spineItem; var spineItem;
if(typeof spinePos !== "undefined"){ if(typeof spinePos !== "undefined"){
spineItem = book.spine[spinePos]; spineItem = book.spine[spinePos];
loaded = book.loadXml(spineItem.url); loaded = book.loadXml(spineItem.url);
@ -376,7 +376,7 @@ EPUBJS.EpubCFI.prototype.generateCfiFromHref = function(href, book) {
deferred.resolve(cfi); deferred.resolve(cfi);
}); });
} }
return deferred.promise; return deferred.promise;
}; };
@ -399,7 +399,7 @@ EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) {
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.parentNode; startElement = start.parentNode;
//startIndex = 1 + (2 * Array.prototype.indexOf.call(startElement.childNodes, start)); //startIndex = 1 + (2 * Array.prototype.indexOf.call(startElement.childNodes, start));
@ -410,18 +410,18 @@ EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) {
} else { } else {
startSteps = this.pathTo(start); startSteps = this.pathTo(start);
} }
startPath = this.generatePathComponent(startSteps); startPath = this.generatePathComponent(startSteps);
startOffset = range.startOffset; startOffset = range.startOffset;
if(!range.collapsed) { if(!range.collapsed) {
end = range.endContainer; end = range.endContainer;
if(end.nodeType === 3) { // text node if(end.nodeType === 3) { // text node
endElement = end.parentNode; endElement = end.parentNode;
// 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)); 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);
@ -430,8 +430,15 @@ EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) {
endPath = this.generatePathComponent(endSteps); endPath = this.generatePathComponent(endSteps);
endOffset = range.endOffset; endOffset = range.endOffset;
return "epubcfi(" + base + "!" + startPath + "/" + startIndex + ":" + startOffset + "," + endPath + "/" + endIndex + ":" + endOffset + ")"; // Remove steps present in startPath
endPath = endPath.replace(startPath, '');
if (endPath.length) {
endPath = endPath + "/";
}
return "epubcfi(" + base + "!" + startPath + "/" + startIndex + ":" + startOffset + "," + endPath + endIndex + ":" + endOffset + ")";
} else { } else {
return "epubcfi(" + base + "!" + startPath + "/"+ startIndex +":"+ startOffset +")"; return "epubcfi(" + base + "!" + startPath + "/"+ startIndex +":"+ startOffset +")";
} }
@ -442,7 +449,7 @@ EPUBJS.EpubCFI.prototype.generateXpathFromSteps = function(steps) {
steps.forEach(function(step){ steps.forEach(function(step){
var position = step.index + 1; var position = step.index + 1;
if(step.id){ if(step.id){
xpath.push("*[position()=" + position + " and @id='" + step.id + "']"); xpath.push("*[position()=" + position + " and @id='" + step.id + "']");
} else if(step.type === "text") { } else if(step.type === "text") {
@ -463,19 +470,19 @@ EPUBJS.EpubCFI.prototype.generateRangeFromCfi = function(cfi, _doc) {
var xpath; var xpath;
var startContainer; var startContainer;
var textLength; var textLength;
if(typeof cfi === 'string') { if(typeof cfi === 'string') {
cfi = this.parse(cfi); cfi = this.parse(cfi);
} }
// check spinePos // check spinePos
if(cfi.spinePos === -1) { if(cfi.spinePos === -1) {
// Not a valid CFI // Not a valid CFI
return false; return false;
} }
xpath = this.generateXpathFromSteps(cfi.steps); xpath = this.generateXpathFromSteps(cfi.steps);
// 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;
@ -493,7 +500,7 @@ EPUBJS.EpubCFI.prototype.generateRangeFromCfi = function(cfi, _doc) {
} else { } else {
console.debug("offset greater than length:", cfi.characterOffset, textLength); console.debug("offset greater than length:", cfi.characterOffset, textLength);
range.setStart(startContainer, textLength - 1 ); range.setStart(startContainer, textLength - 1 );
range.setEnd(startContainer, textLength ); range.setEnd(startContainer, textLength );
} }
} else if(startContainer) { } else if(startContainer) {
range.selectNode(startContainer); range.selectNode(startContainer);
@ -509,4 +516,4 @@ EPUBJS.EpubCFI.prototype.isCfiString = function(target) {
} }
return false; return false;
}; };

211
src/locations.js Normal file
View file

@ -0,0 +1,211 @@
EPUBJS.Locations = function(spine, request) {
this.spine = spine;
this.request = request;
this.q = new EPUBJS.Queue(this);
this.epubcfi = new EPUBJS.EpubCFI();
this._locations = [];
this.total = 0;
this.break = 150;
this._current = 0;
};
// Load all of sections in the book
EPUBJS.Locations.prototype.generate = function(chars) {
if (chars) {
this.break = chars;
}
this.q.pause();
this.spine.each(function(section) {
this.q.enqueue(this.process, section);
}.bind(this));
return this.q.run().then(function() {
this.total = this._locations.length-1;
if (this._currentCfi) {
this.currentLocation = this._currentCfi;
}
return this._locations;
// console.log(this.precentage(this.book.rendition.location.start), this.precentage(this.book.rendition.location.end));
}.bind(this));
};
EPUBJS.Locations.prototype.process = function(section) {
return section.load(this.request)
.then(function(contents) {
var range;
var doc = contents.ownerDocument;
var counter = 0;
this.sprint(contents, function(node) {
var len = node.length;
var dist;
var pos = 0;
// Start range
if (counter == 0) {
range = doc.createRange();
range.setStart(node, 0);
}
dist = this.break - counter;
// Node is smaller than a break
if(dist > len){
counter += len;
pos = len;
}
while (pos < len) {
counter = this.break;
pos += this.break;
// Gone over
if(pos >= len){
// Continue counter for next node
counter = len - (pos - this.break);
// At End
} else {
// End the previous range
range.setEnd(node, pos);
cfi = section.cfiFromRange(range);
this._locations.push(cfi);
counter = 0;
// Start new range
pos += 1;
range = doc.createRange();
range.setStart(node, pos);
}
}
}.bind(this));
// Close remaining
if (range) {
range.setEnd(prev, prev.length);
cfi = section.cfiFromRange(range);
this._locations.push(cfi)
counter = 0;
}
}.bind(this));
};
EPUBJS.Locations.prototype.sprint = function(root, func) {
var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null, false);
while ((node = treeWalker.nextNode())) {
func(node);
}
};
EPUBJS.Locations.prototype.locationFromCfi = function(cfi){
// Check if the location has not been set yet
if(this._locations.length === 0) {
return -1;
}
return EPUBJS.core.locationOf(cfi, this._locations, this.epubcfi.compare);
};
EPUBJS.Locations.prototype.precentageFromCfi = function(cfi) {
// Find closest cfi
var loc = this.locationFromCfi(cfi);
// Get percentage in total
return this.precentageFromLocation(loc);
};
EPUBJS.Locations.prototype.precentageFromLocation = function(loc) {
return Math.ceil((loc / this.total ) * 1000) / 1000;
};
EPUBJS.Locations.prototype.cfiFromLocation = function(loc){
var cfi = -1;
// check that pg is an int
if(typeof loc != "number"){
loc = parseInt(pg);
}
if(loc >= 0 && loc < this._locations.length) {
cfi = this._locations[loc];
}
return cfi;
};
EPUBJS.Locations.prototype.cfiFromPercentage = function(percent){
var loc = Math.round(this.total * percent);
return this.cfiFromLocation(loc);
};
EPUBJS.Locations.prototype.load = function(locations){
this._locations = JSON.parse(locations);
this.total = this._locations.length-1;
return this._locations;
};
EPUBJS.Locations.prototype.save = function(json){
return JSON.stringify(this._locations);
};
EPUBJS.Locations.prototype.getCurrent = function(json){
return this._current;
};
EPUBJS.Locations.prototype.setCurrent = function(curr){
var loc;
if(typeof curr == "string"){
this._currentCfi = curr;
} else if (typeof curr == "number") {
this._current = curr;
} else {
return;
}
if(this._locations.length === 0) {
return;
}
if(typeof curr == "string"){
loc = this.locationFromCfi(curr);
this._current = loc;
} else {
loc = curr;
}
console.log( this.precentageFromLocation(loc))
this.trigger("changed", {
percentage: this.precentageFromLocation(loc)
});
};
Object.defineProperty(EPUBJS.Locations.prototype, 'currentLocation', {
get: function () {
return this._current;
},
set: function (curr) {
this.setCurrent(curr);
}
});
RSVP.EventTarget.mixin(EPUBJS.Locations.prototype);

View file

@ -3,6 +3,7 @@ EPUBJS.Queue = function(_context){
this.context = _context; this.context = _context;
this.tick = EPUBJS.core.requestAnimationFrame; this.tick = EPUBJS.core.requestAnimationFrame;
this.running = false; this.running = false;
this.paused = false;
}; };
// Add an item to the queue // Add an item to the queue
@ -44,7 +45,11 @@ EPUBJS.Queue.prototype.enqueue = function() {
this._q.push(queued); this._q.push(queued);
// Wait to start queue flush // Wait to start queue flush
setTimeout(this.flush.bind(this), 0); if (this.paused == false && !this.running) {
// setTimeout(this.flush.bind(this), 0);
// this.tick.call(window, this.run.bind(this));
this.run();
}
return queued.promise; return queued.promise;
}; };
@ -97,25 +102,46 @@ EPUBJS.Queue.prototype.dump = function(){
// Run all sequentially, at convince // Run all sequentially, at convince
EPUBJS.Queue.prototype.run = function(){ EPUBJS.Queue.prototype.run = function(){
if(!this.running && this._q.length) {
if(!this.running){
this.running = true; this.running = true;
this.dequeue().then(function(){ this.defered = new RSVP.defer();
this.running = false;
}.bind(this));
} }
this.tick.call(window, this.run.bind(this)); this.tick.call(window, function() {
if(this._q.length) {
this.dequeue()
.then(function(){
this.run();
}.bind(this));
} else {
this.defered.resolve();
this.running = undefined;
}
}.bind(this));
// Unpause
if(this.paused == true) {
this.paused = false;
}
return this.defered.promise;
}; };
// Flush all, as quickly as possible // Flush all, as quickly as possible
EPUBJS.Queue.prototype.flush = function(){ EPUBJS.Queue.prototype.flush = function(){
if(this.running){ if(this.running){
return this.running; return this.running;
} }
if(this._q.length) { if(this._q.length) {
this.running = this.dequeue(). this.running = this.dequeue()
then(function(){ .then(function(){
this.running = undefined; this.running = undefined;
return this.flush(); return this.flush();
}.bind(this)); }.bind(this));
@ -135,6 +161,10 @@ EPUBJS.Queue.prototype.length = function(){
return this._q.length; return this._q.length;
}; };
EPUBJS.Queue.prototype.pause = function(){
this.paused = true;
};
// Create a new task from a callback // Create a new task from a callback
EPUBJS.Task = function(task, args, context){ EPUBJS.Task = function(task, args, context){

View file

@ -7,7 +7,7 @@ EPUBJS.Section = function(item){
this.url = item.url; this.url = item.url;
this.next = item.next; this.next = item.next;
this.prev = item.prev; this.prev = item.prev;
this.epubcfi = new EPUBJS.EpubCFI(); this.epubcfi = new EPUBJS.EpubCFI();
this.cfiBase = item.cfiBase; this.cfiBase = item.cfiBase;
@ -44,7 +44,7 @@ EPUBJS.Section.prototype.load = function(_request){
loading.reject(error); loading.reject(error);
}); });
} }
return loaded; return loaded;
}; };
@ -64,7 +64,7 @@ EPUBJS.Section.prototype.replacements = function(_document){
} else { } else {
task.reject(new Error("No head to insert into")); task.reject(new Error("No head to insert into"));
} }
return task.promise; return task.promise;
}; };
@ -76,7 +76,7 @@ EPUBJS.Section.prototype.beforeSectionLoad = function(){
EPUBJS.Section.prototype.render = function(_request){ EPUBJS.Section.prototype.render = function(_request){
var rendering = new RSVP.defer(); var rendering = new RSVP.defer();
var rendered = rendering.promise; var rendered = rendering.promise;
this.load(_request).then(function(contents){ this.load(_request).then(function(contents){
var serializer = new XMLSerializer(); var serializer = new XMLSerializer();
var output = serializer.serializeToString(contents); var output = serializer.serializeToString(contents);
@ -125,4 +125,8 @@ EPUBJS.Section.prototype.reconcileLayoutSettings = function(global){
EPUBJS.Section.prototype.cfiFromRange = function(_range) { EPUBJS.Section.prototype.cfiFromRange = function(_range) {
return this.epubcfi.generateCfiFromRange(_range, this.cfiBase); return this.epubcfi.generateCfiFromRange(_range, this.cfiBase);
}; };
EPUBJS.Section.prototype.cfiFromElement = function(el) {
return this.epubcfi.generateCfiFromElement(el, this.cfiBase);
};

View file

@ -109,3 +109,7 @@ EPUBJS.Spine.prototype.remove = function(section) {
return this.spineItems.splice(index, 1); return this.spineItems.splice(index, 1);
} }
}; };
EPUBJS.Spine.prototype.each = function() {
return this.spineItems.forEach.apply(this.spineItems, arguments);
};