epubjs
Version:
Parse and Render Epubs
314 lines (252 loc) • 7.65 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _epubcfi = require("./epubcfi");
var _epubcfi2 = _interopRequireDefault(_epubcfi);
var _hook = require("./utils/hook");
var _hook2 = _interopRequireDefault(_hook);
var _section = require("./section");
var _section2 = _interopRequireDefault(_section);
var _replacements = require("./utils/replacements");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/**
* A collection of Spine Items
*/
var Spine = function () {
function Spine() {
_classCallCheck(this, Spine);
this.spineItems = [];
this.spineByHref = {};
this.spineById = {};
this.hooks = {};
this.hooks.serialize = new _hook2.default();
this.hooks.content = new _hook2.default();
// Register replacements
this.hooks.content.register(_replacements.replaceBase);
this.hooks.content.register(_replacements.replaceCanonical);
this.hooks.content.register(_replacements.replaceMeta);
this.epubcfi = new _epubcfi2.default();
this.loaded = false;
this.items = undefined;
this.manifest = undefined;
this.spineNodeIndex = undefined;
this.baseUrl = undefined;
this.length = undefined;
}
/**
* Unpack items from a opf into spine items
* @param {Package} _package
* @param {method} resolver URL resolver
*/
_createClass(Spine, [{
key: "unpack",
value: function unpack(_package, resolver, canonical) {
var _this = this;
this.items = _package.spine;
this.manifest = _package.manifest;
this.spineNodeIndex = _package.spineNodeIndex;
this.baseUrl = _package.baseUrl || _package.basePath || "";
this.length = this.items.length;
this.items.forEach(function (item, index) {
var manifestItem = _this.manifest[item.idref];
var spineItem;
item.index = index;
item.cfiBase = _this.epubcfi.generateChapterComponent(_this.spineNodeIndex, item.index, item.idref);
if (item.href) {
item.url = resolver(item.href, true);
item.canonical = canonical(item.href);
}
if (manifestItem) {
item.href = manifestItem.href;
item.url = resolver(item.href, true);
item.canonical = canonical(item.href);
if (manifestItem.properties.length) {
item.properties.push.apply(item.properties, manifestItem.properties);
}
}
if (item.linear === "yes") {
item.prev = function () {
var prevIndex = item.index;
while (prevIndex > 0) {
var prev = this.get(prevIndex - 1);
if (prev && prev.linear) {
return prev;
}
prevIndex -= 1;
}
return;
}.bind(_this);
item.next = function () {
var nextIndex = item.index;
while (nextIndex < this.spineItems.length - 1) {
var next = this.get(nextIndex + 1);
if (next && next.linear) {
return next;
}
nextIndex += 1;
}
return;
}.bind(_this);
} else {
item.prev = function () {
return;
};
item.next = function () {
return;
};
}
spineItem = new _section2.default(item, _this.hooks);
_this.append(spineItem);
});
this.loaded = true;
}
/**
* Get an item from the spine
* @param {string|int} [target]
* @return {Section} section
* @example spine.get();
* @example spine.get(1);
* @example spine.get("chap1.html");
* @example spine.get("#id1234");
*/
}, {
key: "get",
value: function get(target) {
var index = 0;
if (typeof target === "undefined") {
while (index < this.spineItems.length) {
var next = this.spineItems[index];
if (next && next.linear) {
break;
}
index += 1;
}
} else if (this.epubcfi.isCfiString(target)) {
var cfi = new _epubcfi2.default(target);
index = cfi.spinePos;
} else if (typeof target === "number" || isNaN(target) === false) {
index = target;
} else if (typeof target === "string" && target.indexOf("#") === 0) {
index = this.spineById[target.substring(1)];
} else if (typeof target === "string") {
// Remove fragments
target = target.split("#")[0];
index = this.spineByHref[target] || this.spineByHref[encodeURI(target)];
}
return this.spineItems[index] || null;
}
/**
* Append a Section to the Spine
* @private
* @param {Section} section
*/
}, {
key: "append",
value: function append(section) {
var index = this.spineItems.length;
section.index = index;
this.spineItems.push(section);
// Encode and Decode href lookups
// see pr for details: https://github.com/futurepress/epub.js/pull/358
this.spineByHref[decodeURI(section.href)] = index;
this.spineByHref[encodeURI(section.href)] = index;
this.spineByHref[section.href] = index;
this.spineById[section.idref] = index;
return index;
}
/**
* Prepend a Section to the Spine
* @private
* @param {Section} section
*/
}, {
key: "prepend",
value: function prepend(section) {
// var index = this.spineItems.unshift(section);
this.spineByHref[section.href] = 0;
this.spineById[section.idref] = 0;
// Re-index
this.spineItems.forEach(function (item, index) {
item.index = index;
});
return 0;
}
// insert(section, index) {
//
// };
/**
* Remove a Section from the Spine
* @private
* @param {Section} section
*/
}, {
key: "remove",
value: function remove(section) {
var index = this.spineItems.indexOf(section);
if (index > -1) {
delete this.spineByHref[section.href];
delete this.spineById[section.idref];
return this.spineItems.splice(index, 1);
}
}
/**
* Loop over the Sections in the Spine
* @return {method} forEach
*/
}, {
key: "each",
value: function each() {
return this.spineItems.forEach.apply(this.spineItems, arguments);
}
}, {
key: "first",
value: function first() {
var index = 0;
do {
var next = this.get(index);
if (next && next.linear) {
return next;
}
index += 1;
} while (index < this.spineItems.length);
}
}, {
key: "last",
value: function last() {
var index = this.spineItems.length - 1;
do {
var prev = this.get(index);
if (prev && prev.linear) {
return prev;
}
index -= 1;
} while (index >= 0);
}
}, {
key: "destroy",
value: function destroy() {
this.each(function (section) {
return section.destroy();
});
this.spineItems = undefined;
this.spineByHref = undefined;
this.spineById = undefined;
this.hooks.serialize.clear();
this.hooks.content.clear();
this.hooks = undefined;
this.epubcfi = undefined;
this.loaded = false;
this.items = undefined;
this.manifest = undefined;
this.spineNodeIndex = undefined;
this.baseUrl = undefined;
this.length = undefined;
}
}]);
return Spine;
}();
exports.default = Spine;
module.exports = exports["default"];