UNPKG

epubjs

Version:
284 lines (241 loc) 6.1 kB
import _JSON$stringify from "babel-runtime/core-js/json/stringify"; import _classCallCheck from "babel-runtime/helpers/classCallCheck"; import _createClass from "babel-runtime/helpers/createClass"; import EpubCFI from "../utils/epubcfi"; import { qs, qsa, querySelectorByType, indexOfSorted, locationOf } from "../utils/core"; /** * Page List Parser * @param {document} [xml] */ var PageList = function () { function PageList(xml) { _classCallCheck(this, PageList); this.pages = []; this.locations = []; this.epubcfi = new EpubCFI(); this.firstPage = 0; this.lastPage = 0; this.totalPages = 0; this.toc = undefined; this.ncx = undefined; if (xml) { this.pageList = this.parse(xml); } if (this.pageList && this.pageList.length) { this.process(this.pageList); } } /** * Parse PageList Xml * @param {document} xml */ _createClass(PageList, [{ key: "parse", value: function parse(xml) { var html = qs(xml, "html"); var ncx = qs(xml, "ncx"); if (html) { return this.parseNav(xml); } else if (ncx) { // Not supported // return this.parseNcx(xml); return; } } /** * Parse a Nav PageList * @private * @param {document} navHtml * @return {PageList.item[]} list */ }, { key: "parseNav", value: function parseNav(navHtml) { var navElement = querySelectorByType(navHtml, "nav", "page-list"); var navItems = navElement ? qsa(navElement, "li") : []; var length = navItems.length; var i; 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 */ }, { key: "item", value: function item(_item) { var 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 */ }, { key: "process", value: function 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; } /** * Get a PageList result from a EpubCFI * @param {string} cfi EpubCFI String * @return {string} page */ }, { key: "pageFromCfi", value: function 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 */ }, { key: "cfiFromPage", value: function 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 */ }, { key: "pageFromPercentage", value: function 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 */ }, { key: "percentageFromPage", value: function 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 */ }, { key: "percentageFromCfi", value: function percentageFromCfi(cfi) { var pg = this.pageFromCfi(cfi); var percentage = this.percentageFromPage(pg); return percentage; } /** * Export pages as an Array * @return {array} */ }, { key: "toArray", value: function toArray() { return this.locations; } /** * Export pages as JSON * @return {json} */ }, { key: "toJSON", value: function toJSON() { return _JSON$stringify(this.locations); } }, { key: "destroy", value: function destroy() { this.pages = undefined; this.locations = undefined; this.epubcfi = undefined; this.pageList = undefined; this.toc = undefined; this.ncx = undefined; } }]); return PageList; }(); export default PageList;