mirror of
https://github.com/futurepress/epub.js.git
synced 2025-10-05 15:32:55 +02:00
Intial move to ES2015
This commit is contained in:
parent
b0944bdff8
commit
353dfa62fd
46 changed files with 16839 additions and 18742 deletions
484
src/pagelist.js
484
src/pagelist.js
|
@ -1,249 +1,257 @@
|
|||
var EpubCFI = require('./epubcfi');
|
||||
var core = require('./core');
|
||||
import EpubCFI from './epubcfi';
|
||||
import {
|
||||
qs,
|
||||
qsa,
|
||||
querySelectorByType,
|
||||
indexOfSorted,
|
||||
locationOf
|
||||
} from './utils/core';
|
||||
|
||||
/**
|
||||
* Page List Parser
|
||||
* @param {[document]} xml
|
||||
*/
|
||||
function PageList(xml) {
|
||||
this.pages = [];
|
||||
this.locations = [];
|
||||
this.epubcfi = new EpubCFI();
|
||||
class PageList {
|
||||
constructor(xml) {
|
||||
this.pages = [];
|
||||
this.locations = [];
|
||||
this.epubcfi = new EpubCFI();
|
||||
|
||||
if (xml) {
|
||||
this.pageList = this.parse(xml);
|
||||
}
|
||||
|
||||
if(this.pageList && this.pageList.length) {
|
||||
this.process(this.pageList);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse PageList Xml
|
||||
* @param {document} xml
|
||||
*/
|
||||
PageList.prototype.parse = function(xml) {
|
||||
var html = core.qs(xml, "html");
|
||||
// var ncx = core.qs(xml, "ncx");
|
||||
|
||||
if(html) {
|
||||
this.toc = this.parseNav(xml);
|
||||
} else if(ncx){ // Not supported
|
||||
// this.toc = this.parseNcx(xml);
|
||||
return;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse a Nav PageList
|
||||
* @private
|
||||
* @param {document} navHtml
|
||||
* @return {PageList.item[]} list
|
||||
*/
|
||||
PageList.prototype.parseNav = function(navHtml){
|
||||
var navElement = core.querySelectorByType(navHtml, "nav", "page-list");
|
||||
var navItems = navElement ? core.qsa(navElement, "li") : [];
|
||||
var length = navItems.length;
|
||||
var i;
|
||||
var toc = {};
|
||||
var list = [];
|
||||
var item;
|
||||
|
||||
if(!navItems || length === 0) return list;
|
||||
|
||||
for (i = 0; i < length; ++i) {
|
||||
item = this.item(navItems[i]);
|
||||
list.push(item);
|
||||
}
|
||||
|
||||
return list;
|
||||
};
|
||||
|
||||
/**
|
||||
* Page List Item
|
||||
* @private
|
||||
* @param {object} item
|
||||
* @return {object} pageListItem
|
||||
*/
|
||||
PageList.prototype.item = function(item){
|
||||
var id = item.getAttribute('id') || false,
|
||||
content = core.qs(item, "a"),
|
||||
href = content.getAttribute('href') || '',
|
||||
text = content.textContent || "",
|
||||
page = parseInt(text),
|
||||
isCfi = href.indexOf("epubcfi"),
|
||||
split,
|
||||
packageUrl,
|
||||
cfi;
|
||||
|
||||
if(isCfi != -1) {
|
||||
split = href.split("#");
|
||||
packageUrl = split[0];
|
||||
cfi = split.length > 1 ? split[1] : false;
|
||||
return {
|
||||
"cfi" : cfi,
|
||||
"href" : href,
|
||||
"packageUrl" : packageUrl,
|
||||
"page" : page
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
"href" : href,
|
||||
"page" : page
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Process pageList items
|
||||
* @private
|
||||
* @param {array} pageList
|
||||
*/
|
||||
PageList.prototype.process = function(pageList){
|
||||
pageList.forEach(function(item){
|
||||
this.pages.push(item.page);
|
||||
if (item.cfi) {
|
||||
this.locations.push(item.cfi);
|
||||
if (xml) {
|
||||
this.pageList = this.parse(xml);
|
||||
}
|
||||
}, this);
|
||||
this.firstPage = parseInt(this.pages[0]);
|
||||
this.lastPage = parseInt(this.pages[this.pages.length-1]);
|
||||
this.totalPages = this.lastPage - this.firstPage;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Replace HREFs with CFI
|
||||
* TODO: implement getting CFI from Href
|
||||
*/
|
||||
PageList.prototype.addCFIs = function() {
|
||||
this.pageList.forEach(function(pg){
|
||||
if(!pg.cfi) {
|
||||
// epubcfi.generateCfiFromHref(pg.href, book).then(function(cfi){
|
||||
// pg.cfi = cfi;
|
||||
// pg.packageUrl = book.settings.packageUrl;
|
||||
// });
|
||||
if(this.pageList && this.pageList.length) {
|
||||
this.process(this.pageList);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse PageList Xml
|
||||
* @param {document} xml
|
||||
*/
|
||||
parse(xml) {
|
||||
var html = qs(xml, "html");
|
||||
// var ncx = qs(xml, "ncx");
|
||||
|
||||
if(html) {
|
||||
this.toc = this.parseNav(xml);
|
||||
} else if(ncx){ // Not supported
|
||||
// this.toc = this.parseNcx(xml);
|
||||
return;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse a Nav PageList
|
||||
* @private
|
||||
* @param {document} navHtml
|
||||
* @return {PageList.item[]} list
|
||||
*/
|
||||
parseNav(navHtml){
|
||||
var navElement = querySelectorByType(navHtml, "nav", "page-list");
|
||||
var navItems = navElement ? qsa(navElement, "li") : [];
|
||||
var length = navItems.length;
|
||||
var i;
|
||||
var toc = {};
|
||||
var list = [];
|
||||
var item;
|
||||
|
||||
if(!navItems || length === 0) return list;
|
||||
|
||||
for (i = 0; i < length; ++i) {
|
||||
item = this.item(navItems[i]);
|
||||
list.push(item);
|
||||
}
|
||||
|
||||
return list;
|
||||
};
|
||||
|
||||
/**
|
||||
* Page List Item
|
||||
* @private
|
||||
* @param {object} item
|
||||
* @return {object} pageListItem
|
||||
*/
|
||||
item(item){
|
||||
var id = item.getAttribute('id') || false,
|
||||
content = qs(item, "a"),
|
||||
href = content.getAttribute('href') || '',
|
||||
text = content.textContent || "",
|
||||
page = parseInt(text),
|
||||
isCfi = href.indexOf("epubcfi"),
|
||||
split,
|
||||
packageUrl,
|
||||
cfi;
|
||||
|
||||
if(isCfi != -1) {
|
||||
split = href.split("#");
|
||||
packageUrl = split[0];
|
||||
cfi = split.length > 1 ? split[1] : false;
|
||||
return {
|
||||
"cfi" : cfi,
|
||||
"href" : href,
|
||||
"packageUrl" : packageUrl,
|
||||
"page" : page
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
"href" : href,
|
||||
"page" : page
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Process pageList items
|
||||
* @private
|
||||
* @param {array} pageList
|
||||
*/
|
||||
process(pageList){
|
||||
pageList.forEach(function(item){
|
||||
this.pages.push(item.page);
|
||||
if (item.cfi) {
|
||||
this.locations.push(item.cfi);
|
||||
}
|
||||
}, this);
|
||||
this.firstPage = parseInt(this.pages[0]);
|
||||
this.lastPage = parseInt(this.pages[this.pages.length-1]);
|
||||
this.totalPages = this.lastPage - this.firstPage;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Replace HREFs with CFI
|
||||
* TODO: implement getting CFI from Href
|
||||
*/
|
||||
addCFIs() {
|
||||
this.pageList.forEach(function(pg){
|
||||
if(!pg.cfi) {
|
||||
// epubcfi.generateCfiFromHref(pg.href, book).then(function(cfi){
|
||||
// pg.cfi = cfi;
|
||||
// pg.packageUrl = book.settings.packageUrl;
|
||||
// });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
EPUBJS.generateCfiFromHref(href, book) {
|
||||
var uri = EPUBJS.core.uri(href);
|
||||
var path = uri.path;
|
||||
var fragment = uri.fragment;
|
||||
var spinePos = book.spineIndexByURL[path];
|
||||
var loaded;
|
||||
var deferred = new RSVP.defer();
|
||||
var epubcfi = new EPUBJS.EpubCFI();
|
||||
var spineItem;
|
||||
|
||||
if(typeof spinePos !== "undefined"){
|
||||
spineItem = book.spine[spinePos];
|
||||
loaded = book.loadXml(spineItem.url);
|
||||
loaded.then(function(doc){
|
||||
var element = doc.getElementById(fragment);
|
||||
var cfi;
|
||||
cfi = epubcfi.generateCfiFromElement(element, spineItem.cfiBase);
|
||||
deferred.resolve(cfi);
|
||||
});
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get a PageList result from a EpubCFI
|
||||
* @param {string} cfi EpubCFI String
|
||||
* @return {string} page
|
||||
*/
|
||||
pageFromCfi(cfi){
|
||||
var pg = -1;
|
||||
|
||||
// Check if the pageList has not been set yet
|
||||
if(this.locations.length === 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// TODO: check if CFI is valid?
|
||||
|
||||
// check if the cfi is in the location list
|
||||
// var index = this.locations.indexOf(cfi);
|
||||
var index = indexOfSorted(cfi, this.locations, this.epubcfi.compare);
|
||||
if(index != -1) {
|
||||
pg = this.pages[index];
|
||||
} else {
|
||||
// Otherwise add it to the list of locations
|
||||
// Insert it in the correct position in the locations page
|
||||
//index = EPUBJS.core.insert(cfi, this.locations, this.epubcfi.compare);
|
||||
index = locationOf(cfi, this.locations, this.epubcfi.compare);
|
||||
// Get the page at the location just before the new one, or return the first
|
||||
pg = index-1 >= 0 ? this.pages[index-1] : this.pages[0];
|
||||
if(pg !== undefined) {
|
||||
// Add the new page in so that the locations and page array match up
|
||||
//this.pages.splice(index, 0, pg);
|
||||
} else {
|
||||
pg = -1;
|
||||
}
|
||||
|
||||
}
|
||||
return pg;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an EpubCFI from a Page List Item
|
||||
* @param {string} pg
|
||||
* @return {string} cfi
|
||||
*/
|
||||
cfiFromPage(pg){
|
||||
var cfi = -1;
|
||||
// check that pg is an int
|
||||
if(typeof pg != "number"){
|
||||
pg = parseInt(pg);
|
||||
}
|
||||
|
||||
// check if the cfi is in the page list
|
||||
// Pages could be unsorted.
|
||||
var index = this.pages.indexOf(pg);
|
||||
if(index != -1) {
|
||||
cfi = this.locations[index];
|
||||
}
|
||||
// TODO: handle pages not in the list
|
||||
return cfi;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a Page from Book percentage
|
||||
* @param {number} percent
|
||||
* @return {string} page
|
||||
*/
|
||||
pageFromPercentage(percent){
|
||||
var pg = Math.round(this.totalPages * percent);
|
||||
return pg;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a value between 0 - 1 corresponding to the location of a page
|
||||
* @param {int} pg the page
|
||||
* @return {number} percentage
|
||||
*/
|
||||
percentageFromPage(pg){
|
||||
var percentage = (pg - this.firstPage) / this.totalPages;
|
||||
return Math.round(percentage * 1000) / 1000;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a value between 0 - 1 corresponding to the location of a cfi
|
||||
* @param {string} cfi EpubCFI String
|
||||
* @return {number} percentage
|
||||
*/
|
||||
percentageFromCfi(cfi){
|
||||
var pg = this.pageFromCfi(cfi);
|
||||
var percentage = this.percentageFromPage(pg);
|
||||
return percentage;
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
EPUBJS.EpubCFI.prototype.generateCfiFromHref = function(href, book) {
|
||||
var uri = EPUBJS.core.uri(href);
|
||||
var path = uri.path;
|
||||
var fragment = uri.fragment;
|
||||
var spinePos = book.spineIndexByURL[path];
|
||||
var loaded;
|
||||
var deferred = new RSVP.defer();
|
||||
var epubcfi = new EPUBJS.EpubCFI();
|
||||
var spineItem;
|
||||
|
||||
if(typeof spinePos !== "undefined"){
|
||||
spineItem = book.spine[spinePos];
|
||||
loaded = book.loadXml(spineItem.url);
|
||||
loaded.then(function(doc){
|
||||
var element = doc.getElementById(fragment);
|
||||
var cfi;
|
||||
cfi = epubcfi.generateCfiFromElement(element, spineItem.cfiBase);
|
||||
deferred.resolve(cfi);
|
||||
});
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get a PageList result from a EpubCFI
|
||||
* @param {string} cfi EpubCFI String
|
||||
* @return {string} page
|
||||
*/
|
||||
PageList.prototype.pageFromCfi = function(cfi){
|
||||
var pg = -1;
|
||||
|
||||
// Check if the pageList has not been set yet
|
||||
if(this.locations.length === 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// TODO: check if CFI is valid?
|
||||
|
||||
// check if the cfi is in the location list
|
||||
// var index = this.locations.indexOf(cfi);
|
||||
var index = core.indexOfSorted(cfi, this.locations, this.epubcfi.compare);
|
||||
if(index != -1) {
|
||||
pg = this.pages[index];
|
||||
} else {
|
||||
// Otherwise add it to the list of locations
|
||||
// Insert it in the correct position in the locations page
|
||||
//index = EPUBJS.core.insert(cfi, this.locations, this.epubcfi.compare);
|
||||
index = EPUBJS.core.locationOf(cfi, this.locations, this.epubcfi.compare);
|
||||
// Get the page at the location just before the new one, or return the first
|
||||
pg = index-1 >= 0 ? this.pages[index-1] : this.pages[0];
|
||||
if(pg !== undefined) {
|
||||
// Add the new page in so that the locations and page array match up
|
||||
//this.pages.splice(index, 0, pg);
|
||||
} else {
|
||||
pg = -1;
|
||||
}
|
||||
|
||||
}
|
||||
return pg;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an EpubCFI from a Page List Item
|
||||
* @param {string} pg
|
||||
* @return {string} cfi
|
||||
*/
|
||||
PageList.prototype.cfiFromPage = function(pg){
|
||||
var cfi = -1;
|
||||
// check that pg is an int
|
||||
if(typeof pg != "number"){
|
||||
pg = parseInt(pg);
|
||||
}
|
||||
|
||||
// check if the cfi is in the page list
|
||||
// Pages could be unsorted.
|
||||
var index = this.pages.indexOf(pg);
|
||||
if(index != -1) {
|
||||
cfi = this.locations[index];
|
||||
}
|
||||
// TODO: handle pages not in the list
|
||||
return cfi;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a Page from Book percentage
|
||||
* @param {number} percent
|
||||
* @return {string} page
|
||||
*/
|
||||
PageList.prototype.pageFromPercentage = function(percent){
|
||||
var pg = Math.round(this.totalPages * percent);
|
||||
return pg;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a value between 0 - 1 corresponding to the location of a page
|
||||
* @param {int} pg the page
|
||||
* @return {number} percentage
|
||||
*/
|
||||
PageList.prototype.percentageFromPage = function(pg){
|
||||
var percentage = (pg - this.firstPage) / this.totalPages;
|
||||
return Math.round(percentage * 1000) / 1000;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a value between 0 - 1 corresponding to the location of a cfi
|
||||
* @param {string} cfi EpubCFI String
|
||||
* @return {number} percentage
|
||||
*/
|
||||
PageList.prototype.percentageFromCfi = function(cfi){
|
||||
var pg = this.pageFromCfi(cfi);
|
||||
var percentage = this.percentageFromPage(pg);
|
||||
return percentage;
|
||||
};
|
||||
|
||||
module.exports = PageList;
|
||||
export default PageList;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue