mirror of
https://github.com/futurepress/epub.js.git
synced 2025-10-05 15:32:55 +02:00
Added locations, updated cfi to handle ranges
This commit is contained in:
parent
dd14b692dc
commit
165d8a4875
8 changed files with 278 additions and 34 deletions
|
@ -139,3 +139,17 @@ body {
|
||||||
#book-viewer iframe {
|
#book-viewer iframe {
|
||||||
padding: 40px 40px;
|
padding: 40px 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#controls {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 16px;
|
||||||
|
left: 50%;
|
||||||
|
width: 400px;
|
||||||
|
margin-left: -200px;
|
||||||
|
text-align: center;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#controls > input[type=range] {
|
||||||
|
width: 400px;
|
||||||
|
}
|
||||||
|
|
143
examples/locations.html
Normal file
143
examples/locations.html
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>EPUB.js Spreads Example</title>
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.1/jszip.min.js"></script>
|
||||||
|
<script src="../dist/epub.js"></script>
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css" href="examples.css">
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="title"></div>
|
||||||
|
<div id="viewer" class="spreads"></div>
|
||||||
|
<a id="prev" href="#prev" class="arrow">‹</a>
|
||||||
|
<a id="next" href="#next" class="arrow">›</a>
|
||||||
|
<div id="controls">
|
||||||
|
<input id="current-percent" size="3" value="0" /> %
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
var controls = document.getElementById("controls");
|
||||||
|
var currentPage = document.getElementById("current-percent");
|
||||||
|
var slider = document.createElement("input");
|
||||||
|
var slide = function(){
|
||||||
|
var cfi = book.locations.cfiFromPercentage(slider.value);
|
||||||
|
rendition.display(cfi);
|
||||||
|
};
|
||||||
|
var mouseDown = false;
|
||||||
|
|
||||||
|
// Load the opf
|
||||||
|
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||||
|
var rendition = book.renderTo("viewer", {
|
||||||
|
width: "100%",
|
||||||
|
height: 500
|
||||||
|
});
|
||||||
|
|
||||||
|
var displayed = rendition.display();
|
||||||
|
|
||||||
|
var title = document.getElementById("title");
|
||||||
|
|
||||||
|
var next = document.getElementById("next");
|
||||||
|
next.addEventListener("click", function(e){
|
||||||
|
rendition.next();
|
||||||
|
e.preventDefault();
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
var prev = document.getElementById("prev");
|
||||||
|
prev.addEventListener("click", function(e){
|
||||||
|
rendition.prev();
|
||||||
|
e.preventDefault();
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
var keyListener = function(e){
|
||||||
|
|
||||||
|
// Left Key
|
||||||
|
if ((e.keyCode || e.which) == 37) {
|
||||||
|
rendition.prev();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Right Key
|
||||||
|
if ((e.keyCode || e.which) == 39) {
|
||||||
|
rendition.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
rendition.on("keyup", keyListener);
|
||||||
|
document.addEventListener("keyup", keyListener, false);
|
||||||
|
|
||||||
|
rendition.on("locationChanged", function(location){
|
||||||
|
console.log(location);
|
||||||
|
});
|
||||||
|
|
||||||
|
book.ready.then(function(){
|
||||||
|
// Load in stored locations from json or local storage
|
||||||
|
var key = book.key()+'-locations';
|
||||||
|
var stored = localStorage.getItem(key);
|
||||||
|
if (stored) {
|
||||||
|
return book.locations.load(stored);
|
||||||
|
} else {
|
||||||
|
// Or generate the locations on the fly
|
||||||
|
// Can pass an option number of chars to break sections by
|
||||||
|
// default is 150 chars
|
||||||
|
return book.locations.generate(600);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(function(locations){
|
||||||
|
|
||||||
|
controls.style.display = "block";
|
||||||
|
slider.setAttribute("type", "range");
|
||||||
|
slider.setAttribute("min", 0);
|
||||||
|
slider.setAttribute("max", 100);
|
||||||
|
// slider.setAttribute("max", book.locations.total+1);
|
||||||
|
slider.setAttribute("step", 1);
|
||||||
|
slider.setAttribute("value", 0);
|
||||||
|
|
||||||
|
slider.addEventListener("change", slide, false);
|
||||||
|
slider.addEventListener("mousedown", function(){
|
||||||
|
mouseDown = true;
|
||||||
|
}, false);
|
||||||
|
slider.addEventListener("mouseup", function(){
|
||||||
|
mouseDown = false;
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
// Wait for book to be rendered to get current page
|
||||||
|
displayed.then(function(){
|
||||||
|
// Get the current CFI
|
||||||
|
var currentLocation = rendition.currentLocation();
|
||||||
|
// Get the Percentage (or location) from that CFI
|
||||||
|
var currentPage = book.locations.percentageFromCfi(currentLocation);
|
||||||
|
slider.value = currentPage;
|
||||||
|
currentPage.value = currentPage;
|
||||||
|
});
|
||||||
|
|
||||||
|
controls.appendChild(slider);
|
||||||
|
|
||||||
|
currentPage.addEventListener("change", function(){
|
||||||
|
var cfi = book.locations.cfiFromPercentage(currentPage.value/100);
|
||||||
|
rendition.display(cfi);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
// Listen for location changed event, get percentage from CFI
|
||||||
|
rendition.on('locationChanged', function(location){
|
||||||
|
var percent = book.locations.percentageFromCfi(location);
|
||||||
|
var percentage = Math.floor(percent * 100);
|
||||||
|
if(!mouseDown) {
|
||||||
|
slider.value = percentage;
|
||||||
|
}
|
||||||
|
currentPage.value = percentage;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Save out the generated locations to JSON
|
||||||
|
localStorage.setItem(book.key()+'-locations', book.locations.save());
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -9,7 +9,7 @@
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "./node_modules/.bin/karma start --single-run --browsers PhantomJS",
|
"test": "./node_modules/.bin/karma start --single-run --browsers PhantomJS",
|
||||||
"start": "webpack-dev-server --inline --hot",
|
"start": "webpack-dev-server --inline",
|
||||||
"build": "./node_modules/.bin/gulp minify"
|
"build": "./node_modules/.bin/gulp minify"
|
||||||
},
|
},
|
||||||
"author": "fchasen@gmail.com",
|
"author": "fchasen@gmail.com",
|
||||||
|
|
15
src/book.js
15
src/book.js
|
@ -111,7 +111,7 @@ function Book(url, options){
|
||||||
/**
|
/**
|
||||||
* @property {Locations} locations
|
* @property {Locations} locations
|
||||||
*/
|
*/
|
||||||
this.locations = new Locations(this.spine, this.load);
|
this.locations = new Locations(this.spine, this.load.bind(this));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {Navigation} navigation
|
* @property {Navigation} navigation
|
||||||
|
@ -173,7 +173,7 @@ Book.prototype.open = function(input, what){
|
||||||
.then(this.openEpub.bind(this));
|
.then(this.openEpub.bind(this));
|
||||||
} else if(type == "opf") {
|
} else if(type == "opf") {
|
||||||
this.url = new Url(input);
|
this.url = new Url(input);
|
||||||
opening = this.openPackaging(input);
|
opening = this.openPackaging(this.url.Path.toString());
|
||||||
} else {
|
} else {
|
||||||
this.url = new Url(input);
|
this.url = new Url(input);
|
||||||
opening = this.openContainer(CONTAINER_PATH)
|
opening = this.openContainer(CONTAINER_PATH)
|
||||||
|
@ -223,7 +223,6 @@ Book.prototype.openContainer = function(url){
|
||||||
Book.prototype.openPackaging = function(url){
|
Book.prototype.openPackaging = function(url){
|
||||||
var packageUrl;
|
var packageUrl;
|
||||||
this.path = new Path(url);
|
this.path = new Path(url);
|
||||||
|
|
||||||
return this.load(url)
|
return this.load(url)
|
||||||
.then(function(xml) {
|
.then(function(xml) {
|
||||||
this.packaging = new Packaging(xml);
|
this.packaging = new Packaging(xml);
|
||||||
|
@ -474,6 +473,16 @@ Book.prototype.range = function(cfiRange) {
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the Book Key using the identifer in the manifest or other string provided
|
||||||
|
* @param {[string]} identifier to use instead of metadata identifier
|
||||||
|
* @return {string} key
|
||||||
|
*/
|
||||||
|
Book.prototype.key = function(identifier){
|
||||||
|
var ident = identifier || this.package.metadata.identifier || this.url.filename;
|
||||||
|
return "epubjs:" + ePub.VERSION + ":" + ident;
|
||||||
|
};
|
||||||
|
|
||||||
//-- Enable binding events to book
|
//-- Enable binding events to book
|
||||||
EventEmitter(Book.prototype);
|
EventEmitter(Book.prototype);
|
||||||
|
|
||||||
|
|
|
@ -304,6 +304,9 @@ EpubCFI.prototype.toString = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
EpubCFI.prototype.compare = function(cfiOne, cfiTwo) {
|
EpubCFI.prototype.compare = function(cfiOne, cfiTwo) {
|
||||||
|
var stepsA, stepsB;
|
||||||
|
var terminalA, terminalB;
|
||||||
|
|
||||||
if(typeof cfiOne === 'string') {
|
if(typeof cfiOne === 'string') {
|
||||||
cfiOne = new EpubCFI(cfiOne);
|
cfiOne = new EpubCFI(cfiOne);
|
||||||
}
|
}
|
||||||
|
@ -318,36 +321,52 @@ EpubCFI.prototype.compare = function(cfiOne, cfiTwo) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cfiOne.range) {
|
||||||
|
stepsA = cfiOne.path.steps.concat(cfiOne.start.steps);
|
||||||
|
terminalA = cfiOne.start.terminal;
|
||||||
|
} else {
|
||||||
|
stepsA = cfiOne.path.steps;
|
||||||
|
terminalA = cfiOne.path.terminal;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfiTwo.range) {
|
||||||
|
stepsB = cfiTwo.path.steps.concat(cfiTwo.start.steps);
|
||||||
|
terminalB = cfiTwo.start.terminal;
|
||||||
|
} else {
|
||||||
|
stepsB = cfiTwo.path.steps;
|
||||||
|
terminalB = cfiTwo.path.terminal;
|
||||||
|
}
|
||||||
|
|
||||||
// Compare Each Step in the First item
|
// Compare Each Step in the First item
|
||||||
for (var i = 0; i < cfiOne.path.steps.length; i++) {
|
for (var i = 0; i < stepsA.length; i++) {
|
||||||
if(!cfiTwo.path.steps[i]) {
|
if(!stepsA[i]) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(!stepsB[i]) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(cfiOne.path.steps[i].index > cfiTwo.path.steps[i].index) {
|
if(stepsA[i].index > stepsB[i].index) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(cfiOne.path.steps[i].index < cfiTwo.path.steps[i].index) {
|
if(stepsA[i].index < stepsB[i].index) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// Otherwise continue checking
|
// Otherwise continue checking
|
||||||
}
|
}
|
||||||
|
|
||||||
// All steps in First equal to Second and First is Less Specific
|
// All steps in First equal to Second and First is Less Specific
|
||||||
if(cfiOne.path.steps.length < cfiTwo.path.steps.length) {
|
if(stepsA.length < stepsB.length) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare the charecter offset of the text node
|
// Compare the charecter offset of the text node
|
||||||
if(cfiOne.path.terminal.offset > cfiTwo.path.terminal.offset) {
|
if(terminalA.offset > terminalB.offset) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(cfiOne.path.terminal.offset < cfiTwo.path.terminal.offset) {
|
if(terminalA.offset < terminalB.offset) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: compare ranges
|
|
||||||
|
|
||||||
// CFI's are equal
|
// CFI's are equal
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
@ -485,7 +504,6 @@ EpubCFI.prototype.fromRange = function(range, base, ignoreClass) {
|
||||||
}
|
}
|
||||||
|
|
||||||
cfi.start = this.pathTo(start, startOffset, ignoreClass);
|
cfi.start = this.pathTo(start, startOffset, ignoreClass);
|
||||||
|
|
||||||
if (needsIgnoring) {
|
if (needsIgnoring) {
|
||||||
endOffset = this.patchOffset(end, endOffset, ignoreClass);
|
endOffset = this.patchOffset(end, endOffset, ignoreClass);
|
||||||
}
|
}
|
||||||
|
@ -504,7 +522,7 @@ EpubCFI.prototype.fromRange = function(range, base, ignoreClass) {
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
if (this.equalStep(cfi.start.steps[i], cfi.end.steps[i])) {
|
if (this.equalStep(cfi.start.steps[i], cfi.end.steps[i])) {
|
||||||
if(i == len-1) {
|
if(i === len-1) {
|
||||||
// Last step is equal, check terminals
|
// Last step is equal, check terminals
|
||||||
if(cfi.start.terminal === cfi.end.terminal) {
|
if(cfi.start.terminal === cfi.end.terminal) {
|
||||||
// CFI's are equal
|
// CFI's are equal
|
||||||
|
|
|
@ -51,7 +51,7 @@ Locations.prototype.generate = function(chars) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._locations;
|
return this._locations;
|
||||||
// console.log(this.precentage(this.book.rendition.location.start), this.precentage(this.book.rendition.location.end));
|
// console.log(this.percentage(this.book.rendition.location.start), this.percentage(this.book.rendition.location.end));
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -63,9 +63,10 @@ Locations.prototype.process = function(section) {
|
||||||
|
|
||||||
var range;
|
var range;
|
||||||
var doc = contents.ownerDocument;
|
var doc = contents.ownerDocument;
|
||||||
|
var body = core.qs(doc, 'body');
|
||||||
var counter = 0;
|
var counter = 0;
|
||||||
|
|
||||||
this.sprint(contents, function(node) {
|
this.sprint(body, function(node) {
|
||||||
var len = node.length;
|
var len = node.length;
|
||||||
var dist;
|
var dist;
|
||||||
var pos = 0;
|
var pos = 0;
|
||||||
|
@ -138,15 +139,17 @@ Locations.prototype.locationFromCfi = function(cfi){
|
||||||
if(this._locations.length === 0) {
|
if(this._locations.length === 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
return core.locationOf(cfi.start, this._locations, this.epubcfi.compare);
|
||||||
return core.locationOf(cfi, this._locations, this.epubcfi.compare);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Locations.prototype.precentageFromCfi = function(cfi) {
|
Locations.prototype.percentageFromCfi = function(cfi) {
|
||||||
|
if(this._locations.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
// Find closest cfi
|
// Find closest cfi
|
||||||
var loc = this.locationFromCfi(cfi);
|
var loc = this.locationFromCfi(cfi);
|
||||||
// Get percentage in total
|
// Get percentage in total
|
||||||
return this.precentageFromLocation(loc);
|
return this.percentageFromLocation(loc);
|
||||||
};
|
};
|
||||||
|
|
||||||
Locations.prototype.percentageFromLocation = function(loc) {
|
Locations.prototype.percentageFromLocation = function(loc) {
|
||||||
|
@ -214,7 +217,7 @@ Locations.prototype.setCurrent = function(curr){
|
||||||
}
|
}
|
||||||
|
|
||||||
this.emit("changed", {
|
this.emit("changed", {
|
||||||
percentage: this.precentageFromLocation(loc)
|
percentage: this.percentageFromLocation(loc)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -159,6 +159,15 @@ DefaultViewManager.prototype.display = function(section, target){
|
||||||
this.views.clear();
|
this.views.clear();
|
||||||
|
|
||||||
this.add(section)
|
this.add(section)
|
||||||
|
.then(function(view){
|
||||||
|
|
||||||
|
// Move to correct place within the section, if needed
|
||||||
|
if(target) {
|
||||||
|
offset = view.locationOf(target);
|
||||||
|
this.moveTo(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
}.bind(this))
|
||||||
.then(function(){
|
.then(function(){
|
||||||
var next;
|
var next;
|
||||||
if (this.layout.name === "pre-paginated" &&
|
if (this.layout.name === "pre-paginated" &&
|
||||||
|
@ -169,13 +178,7 @@ DefaultViewManager.prototype.display = function(section, target){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.bind(this))
|
}.bind(this))
|
||||||
.then(function(view){
|
.then(function(){
|
||||||
|
|
||||||
// Move to correct place within the section, if needed
|
|
||||||
if(target) {
|
|
||||||
offset = view.locationOf(target);
|
|
||||||
this.moveTo(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.views.show();
|
this.views.show();
|
||||||
|
|
||||||
|
@ -362,15 +365,34 @@ DefaultViewManager.prototype.current = function(){
|
||||||
};
|
};
|
||||||
|
|
||||||
DefaultViewManager.prototype.currentLocation = function(){
|
DefaultViewManager.prototype.currentLocation = function(){
|
||||||
|
|
||||||
|
if (this.settings.axis === "vertical") {
|
||||||
|
this.location = this.scrolledLocation();
|
||||||
|
} else {
|
||||||
|
this.location = this.paginatedLocation();
|
||||||
|
}
|
||||||
|
return this.location;
|
||||||
|
};
|
||||||
|
|
||||||
|
DefaultViewManager.prototype.scrolledLocation = function(){
|
||||||
|
var view;
|
||||||
|
|
||||||
|
if(this.views.length) {
|
||||||
|
view = this.views.first();
|
||||||
|
return this.mapping.page(view, view.section.cfiBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
DefaultViewManager.prototype.paginatedLocation = function(){
|
||||||
var view;
|
var view;
|
||||||
var start, end;
|
var start, end;
|
||||||
|
|
||||||
if(this.views.length) {
|
if(this.views.length) {
|
||||||
view = this.views.first();
|
view = this.views.first();
|
||||||
start = container.left - view.position().left;
|
start = this._bounds.left - view.position().left;
|
||||||
end = start + this.layout.spread;
|
end = start + this.layout.spreadWidth;
|
||||||
|
return this.mapping.page(view, view.section.cfiBase, start, end);
|
||||||
return this.mapping.page(view, view.section.cfiBase);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -315,7 +315,7 @@ Rendition.prototype.afterDisplayed = function(view){
|
||||||
* Report resize events and display the last seen location
|
* Report resize events and display the last seen location
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
Rendition.prototype.onResized = function(){
|
Rendition.prototype.onResized = function(size){
|
||||||
|
|
||||||
if(this.location) {
|
if(this.location) {
|
||||||
this.display(this.location.start);
|
this.display(this.location.start);
|
||||||
|
@ -454,6 +454,7 @@ Rendition.prototype.spread = function(spread, min){
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Report the current location
|
* Report the current location
|
||||||
|
* @private
|
||||||
*/
|
*/
|
||||||
Rendition.prototype.reportLocation = function(){
|
Rendition.prototype.reportLocation = function(){
|
||||||
return this.q.enqueue(function(){
|
return this.q.enqueue(function(){
|
||||||
|
@ -461,16 +462,50 @@ Rendition.prototype.reportLocation = function(){
|
||||||
if (location && location.then && typeof location.then === 'function') {
|
if (location && location.then && typeof location.then === 'function') {
|
||||||
location.then(function(result) {
|
location.then(function(result) {
|
||||||
this.location = result;
|
this.location = result;
|
||||||
|
|
||||||
|
this.percentage = this.book.locations.percentageFromCfi(result);
|
||||||
|
if (this.percentage != null) {
|
||||||
|
this.location.percentage = this.percentage;
|
||||||
|
}
|
||||||
|
|
||||||
this.emit("locationChanged", this.location);
|
this.emit("locationChanged", this.location);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
} else if (location) {
|
} else if (location) {
|
||||||
this.location = location;
|
this.location = location;
|
||||||
|
this.percentage = this.book.locations.percentageFromCfi(location);
|
||||||
|
if (this.percentage != null) {
|
||||||
|
this.location.percentage = this.percentage;
|
||||||
|
}
|
||||||
|
|
||||||
this.emit("locationChanged", this.location);
|
this.emit("locationChanged", this.location);
|
||||||
}
|
}
|
||||||
|
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Current Location CFI
|
||||||
|
* @return {EpubCFI} location (may be a promise)
|
||||||
|
*/
|
||||||
|
Rendition.prototype.currentLocation = function(){
|
||||||
|
var location = this.manager.currentLocation();
|
||||||
|
if (location && location.then && typeof location.then === 'function') {
|
||||||
|
location.then(function(result) {
|
||||||
|
var percentage = this.book.locations.percentageFromCfi(result);
|
||||||
|
if (percentage != null) {
|
||||||
|
result.percentage = percentage;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}.bind(this));
|
||||||
|
} else if (location) {
|
||||||
|
var percentage = this.book.locations.percentageFromCfi(location);
|
||||||
|
if (percentage != null) {
|
||||||
|
location.percentage = percentage;
|
||||||
|
}
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove and Clean Up the Rendition
|
* Remove and Clean Up the Rendition
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue