(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(require("xmldom"), (function webpackLoadOptionalExternalModule() { try { return require("jszip"); } catch(e) {} }())); else if(typeof define === 'function' && define.amd) define(["xmldom", "jszip"], factory); else if(typeof exports === 'object') exports["ePub"] = factory(require("xmldom"), (function webpackLoadOptionalExternalModule() { try { return require("jszip"); } catch(e) {} }())); else root["ePub"] = factory(root["xmldom"], root["jszip"]); })(this, function(__WEBPACK_EXTERNAL_MODULE_42__, __WEBPACK_EXTERNAL_MODULE_71__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = "/dist/"; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 25); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { "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; }; }(); exports.uuid = uuid; exports.documentHeight = documentHeight; exports.isElement = isElement; exports.isNumber = isNumber; exports.isFloat = isFloat; exports.prefixed = prefixed; exports.defaults = defaults; exports.extend = extend; exports.insert = insert; exports.locationOf = locationOf; exports.indexOfSorted = indexOfSorted; exports.bounds = bounds; exports.borders = borders; exports.nodeBounds = nodeBounds; exports.windowBounds = windowBounds; exports.indexOfNode = indexOfNode; exports.indexOfTextNode = indexOfTextNode; exports.indexOfElementNode = indexOfElementNode; exports.isXml = isXml; exports.createBlob = createBlob; exports.createBlobUrl = createBlobUrl; exports.revokeBlobUrl = revokeBlobUrl; exports.createBase64Url = createBase64Url; exports.type = type; exports.parse = parse; exports.qs = qs; exports.qsa = qsa; exports.qsp = qsp; exports.sprint = sprint; exports.treeWalker = treeWalker; exports.walk = walk; exports.blob2base64 = blob2base64; exports.defer = defer; exports.querySelectorByType = querySelectorByType; exports.findChildren = findChildren; exports.parents = parents; exports.filterChildren = filterChildren; exports.getParentByTagName = getParentByTagName; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** * Core Utilities and Helpers * @module Core */ /** * Vendor prefixed requestAnimationFrame * @returns {function} requestAnimationFrame * @memberof Core */ var requestAnimationFrame = exports.requestAnimationFrame = typeof window != "undefined" ? window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame : false; var ELEMENT_NODE = 1; var TEXT_NODE = 3; var COMMENT_NODE = 8; var DOCUMENT_NODE = 9; var _URL = typeof URL != "undefined" ? URL : typeof window != "undefined" ? window.URL || window.webkitURL || window.mozURL : undefined; /** * Generates a UUID * based on: http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript * @returns {string} uuid * @memberof Core */ function uuid() { var d = new Date().getTime(); var uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) { var r = (d + Math.random() * 16) % 16 | 0; d = Math.floor(d / 16); return (c == "x" ? r : r & 0x7 | 0x8).toString(16); }); return uuid; } /** * Gets the height of a document * @returns {number} height * @memberof Core */ function documentHeight() { return Math.max(document.documentElement.clientHeight, document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight); } /** * Checks if a node is an element * @param {object} obj * @returns {boolean} * @memberof Core */ function isElement(obj) { return !!(obj && obj.nodeType == 1); } /** * @param {any} n * @returns {boolean} * @memberof Core */ function isNumber(n) { return !isNaN(parseFloat(n)) && isFinite(n); } /** * @param {any} n * @returns {boolean} * @memberof Core */ function isFloat(n) { var f = parseFloat(n); if (isNumber(n) === false) { return false; } if (typeof n === "string" && n.indexOf(".") > -1) { return true; } return Math.floor(f) !== f; } /** * Get a prefixed css property * @param {string} unprefixed * @returns {string} * @memberof Core */ function prefixed(unprefixed) { var vendors = ["Webkit", "webkit", "Moz", "O", "ms"]; var prefixes = ["-webkit-", "-webkit-", "-moz-", "-o-", "-ms-"]; var upper = unprefixed[0].toUpperCase() + unprefixed.slice(1); var length = vendors.length; if (typeof document === "undefined" || typeof document.body.style[unprefixed] != "undefined") { return unprefixed; } for (var i = 0; i < length; i++) { if (typeof document.body.style[vendors[i] + upper] != "undefined") { return prefixes[i] + unprefixed; } } return unprefixed; } /** * Apply defaults to an object * @param {object} obj * @returns {object} * @memberof Core */ function defaults(obj) { for (var i = 1, length = arguments.length; i < length; i++) { var source = arguments[i]; for (var prop in source) { if (obj[prop] === void 0) obj[prop] = source[prop]; } } return obj; } /** * Extend properties of an object * @param {object} target * @returns {object} * @memberof Core */ function extend(target) { var sources = [].slice.call(arguments, 1); sources.forEach(function (source) { if (!source) return; Object.getOwnPropertyNames(source).forEach(function (propName) { Object.defineProperty(target, propName, Object.getOwnPropertyDescriptor(source, propName)); }); }); return target; } /** * Fast quicksort insert for sorted array -- based on: * http://stackoverflow.com/questions/1344500/efficient-way-to-insert-a-number-into-a-sorted-array-of-numbers * @param {any} item * @param {array} array * @param {function} [compareFunction] * @returns {number} location (in array) * @memberof Core */ function insert(item, array, compareFunction) { var location = locationOf(item, array, compareFunction); array.splice(location, 0, item); return location; } /** * Finds where something would fit into a sorted array * @param {any} item * @param {array} array * @param {function} [compareFunction] * @param {function} [_start] * @param {function} [_end] * @returns {number} location (in array) * @memberof Core */ function locationOf(item, array, compareFunction, _start, _end) { var start = _start || 0; var end = _end || array.length; var pivot = parseInt(start + (end - start) / 2); var compared; if (!compareFunction) { compareFunction = function compareFunction(a, b) { if (a > b) return 1; if (a < b) return -1; if (a == b) return 0; }; } if (end - start <= 0) { return pivot; } compared = compareFunction(array[pivot], item); if (end - start === 1) { return compared >= 0 ? pivot : pivot + 1; } if (compared === 0) { return pivot; } if (compared === -1) { return locationOf(item, array, compareFunction, pivot, end); } else { return locationOf(item, array, compareFunction, start, pivot); } } /** * Finds index of something in a sorted array * Returns -1 if not found * @param {any} item * @param {array} array * @param {function} [compareFunction] * @param {function} [_start] * @param {function} [_end] * @returns {number} index (in array) or -1 * @memberof Core */ function indexOfSorted(item, array, compareFunction, _start, _end) { var start = _start || 0; var end = _end || array.length; var pivot = parseInt(start + (end - start) / 2); var compared; if (!compareFunction) { compareFunction = function compareFunction(a, b) { if (a > b) return 1; if (a < b) return -1; if (a == b) return 0; }; } if (end - start <= 0) { return -1; // Not found } compared = compareFunction(array[pivot], item); if (end - start === 1) { return compared === 0 ? pivot : -1; } if (compared === 0) { return pivot; // Found } if (compared === -1) { return indexOfSorted(item, array, compareFunction, pivot, end); } else { return indexOfSorted(item, array, compareFunction, start, pivot); } } /** * Find the bounds of an element * taking padding and margin into account * @param {element} el * @returns {{ width: Number, height: Number}} * @memberof Core */ function bounds(el) { var style = window.getComputedStyle(el); var widthProps = ["width", "paddingRight", "paddingLeft", "marginRight", "marginLeft", "borderRightWidth", "borderLeftWidth"]; var heightProps = ["height", "paddingTop", "paddingBottom", "marginTop", "marginBottom", "borderTopWidth", "borderBottomWidth"]; var width = 0; var height = 0; widthProps.forEach(function (prop) { width += parseFloat(style[prop]) || 0; }); heightProps.forEach(function (prop) { height += parseFloat(style[prop]) || 0; }); return { height: height, width: width }; } /** * Find the bounds of an element * taking padding, margin and borders into account * @param {element} el * @returns {{ width: Number, height: Number}} * @memberof Core */ function borders(el) { var style = window.getComputedStyle(el); var widthProps = ["paddingRight", "paddingLeft", "marginRight", "marginLeft", "borderRightWidth", "borderLeftWidth"]; var heightProps = ["paddingTop", "paddingBottom", "marginTop", "marginBottom", "borderTopWidth", "borderBottomWidth"]; var width = 0; var height = 0; widthProps.forEach(function (prop) { width += parseFloat(style[prop]) || 0; }); heightProps.forEach(function (prop) { height += parseFloat(style[prop]) || 0; }); return { height: height, width: width }; } /** * Find the bounds of any node * allows for getting bounds of text nodes by wrapping them in a range * @param {node} node * @returns {BoundingClientRect} * @memberof Core */ function nodeBounds(node) { var elPos = void 0; var doc = node.ownerDocument; if (node.nodeType == Node.TEXT_NODE) { var elRange = doc.createRange(); elRange.selectNodeContents(node); elPos = elRange.getBoundingClientRect(); } else { elPos = node.getBoundingClientRect(); } return elPos; } /** * Find the equivelent of getBoundingClientRect of a browser window * @returns {{ width: Number, height: Number, top: Number, left: Number, right: Number, bottom: Number }} * @memberof Core */ function windowBounds() { var width = window.innerWidth; var height = window.innerHeight; return { top: 0, left: 0, right: width, bottom: height, width: width, height: height }; } /** * Gets the index of a node in its parent * @param {Node} node * @param {string} typeId * @return {number} index * @memberof Core */ function indexOfNode(node, typeId) { var parent = node.parentNode; var children = parent.childNodes; var sib; var index = -1; for (var i = 0; i < children.length; i++) { sib = children[i]; if (sib.nodeType === typeId) { index++; } if (sib == node) break; } return index; } /** * Gets the index of a text node in its parent * @param {node} textNode * @returns {number} index * @memberof Core */ function indexOfTextNode(textNode) { return indexOfNode(textNode, TEXT_NODE); } /** * Gets the index of an element node in its parent * @param {element} elementNode * @returns {number} index * @memberof Core */ function indexOfElementNode(elementNode) { return indexOfNode(elementNode, ELEMENT_NODE); } /** * Check if extension is xml * @param {string} ext * @returns {boolean} * @memberof Core */ function isXml(ext) { return ["xml", "opf", "ncx"].indexOf(ext) > -1; } /** * Create a new blob * @param {any} content * @param {string} mime * @returns {Blob} * @memberof Core */ function createBlob(content, mime) { return new Blob([content], { type: mime }); } /** * Create a new blob url * @param {any} content * @param {string} mime * @returns {string} url * @memberof Core */ function createBlobUrl(content, mime) { var tempUrl; var blob = createBlob(content, mime); tempUrl = _URL.createObjectURL(blob); return tempUrl; } /** * Remove a blob url * @param {string} url * @memberof Core */ function revokeBlobUrl(url) { return _URL.revokeObjectURL(url); } /** * Create a new base64 encoded url * @param {any} content * @param {string} mime * @returns {string} url * @memberof Core */ function createBase64Url(content, mime) { var data; var datauri; if (typeof content !== "string") { // Only handles strings return; } data = btoa(encodeURIComponent(content)); datauri = "data:" + mime + ";base64," + data; return datauri; } /** * Get type of an object * @param {object} obj * @returns {string} type * @memberof Core */ function type(obj) { return Object.prototype.toString.call(obj).slice(8, -1); } /** * Parse xml (or html) markup * @param {string} markup * @param {string} mime * @param {boolean} forceXMLDom force using xmlDom to parse instead of native parser * @returns {document} document * @memberof Core */ function parse(markup, mime, forceXMLDom) { var doc; var Parser; if (typeof DOMParser === "undefined" || forceXMLDom) { Parser = __webpack_require__(42).DOMParser; } else { Parser = DOMParser; } // Remove byte order mark before parsing // https://www.w3.org/International/questions/qa-byte-order-mark if (markup.charCodeAt(0) === 0xFEFF) { markup = markup.slice(1); } doc = new Parser().parseFromString(markup, mime); return doc; } /** * querySelector polyfill * @param {element} el * @param {string} sel selector string * @returns {element} element * @memberof Core */ function qs(el, sel) { var elements; if (!el) { throw new Error("No Element Provided"); } if (typeof el.querySelector != "undefined") { return el.querySelector(sel); } else { elements = el.getElementsByTagName(sel); if (elements.length) { return elements[0]; } } } /** * querySelectorAll polyfill * @param {element} el * @param {string} sel selector string * @returns {element[]} elements * @memberof Core */ function qsa(el, sel) { if (typeof el.querySelector != "undefined") { return el.querySelectorAll(sel); } else { return el.getElementsByTagName(sel); } } /** * querySelector by property * @param {element} el * @param {string} sel selector string * @param {object[]} props * @returns {element[]} elements * @memberof Core */ function qsp(el, sel, props) { var q, filtered; if (typeof el.querySelector != "undefined") { sel += "["; for (var prop in props) { sel += prop + "~='" + props[prop] + "'"; } sel += "]"; return el.querySelector(sel); } else { q = el.getElementsByTagName(sel); filtered = Array.prototype.slice.call(q, 0).filter(function (el) { for (var prop in props) { if (el.getAttribute(prop) === props[prop]) { return true; } } return false; }); if (filtered) { return filtered[0]; } } } /** * Sprint through all text nodes in a document * @memberof Core * @param {element} root element to start with * @param {function} func function to run on each element */ function sprint(root, func) { var doc = root.ownerDocument || root; if (typeof doc.createTreeWalker !== "undefined") { treeWalker(root, func, NodeFilter.SHOW_TEXT); } else { walk(root, function (node) { if (node && node.nodeType === 3) { // Node.TEXT_NODE func(node); } }, true); } } /** * Create a treeWalker * @memberof Core * @param {element} root element to start with * @param {function} func function to run on each element * @param {function | object} filter funtion or object to filter with */ function treeWalker(root, func, filter) { var treeWalker = document.createTreeWalker(root, filter, null, false); var node = void 0; while (node = treeWalker.nextNode()) { func(node); } } /** * @memberof Core * @param {node} node * @param {callback} return false for continue,true for break inside callback */ function walk(node, callback) { if (callback(node)) { return true; } node = node.firstChild; if (node) { do { var walked = walk(node, callback); if (walked) { return true; } node = node.nextSibling; } while (node); } } /** * Convert a blob to a base64 encoded string * @param {Blog} blob * @returns {string} * @memberof Core */ function blob2base64(blob) { return new Promise(function (resolve, reject) { var reader = new FileReader(); reader.readAsDataURL(blob); reader.onloadend = function () { resolve(reader.result); }; }); } /** * Creates a new pending promise and provides methods to resolve or reject it. * From: https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Deferred#backwards_forwards_compatible * @memberof Core */ function defer() { var _this = this; /* A method to resolve the associated Promise with the value passed. * If the promise is already settled it does nothing. * * @param {anything} value : This value is used to resolve the promise * If the value is a Promise then the associated promise assumes the state * of Promise passed as value. */ this.resolve = null; /* A method to reject the assocaited Promise with the value passed. * If the promise is already settled it does nothing. * * @param {anything} reason: The reason for the rejection of the Promise. * Generally its an Error object. If however a Promise is passed, then the Promise * itself will be the reason for rejection no matter the state of the Promise. */ this.reject = null; this.id = uuid(); /* A newly created Pomise object. * Initially in pending state. */ this.promise = new Promise(function (resolve, reject) { _this.resolve = resolve; _this.reject = reject; }); Object.freeze(this); } /** * querySelector with filter by epub type * @param {element} html * @param {string} element element type to find * @param {string} type epub type to find * @returns {element[]} elements * @memberof Core */ function querySelectorByType(html, element, type) { var query; if (typeof html.querySelector != "undefined") { query = html.querySelector(element + "[*|type=\"" + type + "\"]"); } // Handle IE not supporting namespaced epub:type in querySelector if (!query || query.length === 0) { query = qsa(html, element); for (var i = 0; i < query.length; i++) { if (query[i].getAttributeNS("http://www.idpf.org/2007/ops", "type") === type || query[i].getAttribute("epub:type") === type) { return query[i]; } } } else { return query; } } /** * Find direct decendents of an element * @param {element} el * @returns {element[]} children * @memberof Core */ function findChildren(el) { var result = []; var childNodes = el.childNodes; for (var i = 0; i < childNodes.length; i++) { var node = childNodes[i]; if (node.nodeType === 1) { result.push(node); } } return result; } /** * Find all parents (ancestors) of an element * @param {element} node * @returns {element[]} parents * @memberof Core */ function parents(node) { var nodes = [node]; for (; node; node = node.parentNode) { nodes.unshift(node); } return nodes; } /** * Find all direct decendents of a specific type * @param {element} el * @param {string} nodeName * @param {boolean} [single] * @returns {element[]} children * @memberof Core */ function filterChildren(el, nodeName, single) { var result = []; var childNodes = el.childNodes; for (var i = 0; i < childNodes.length; i++) { var node = childNodes[i]; if (node.nodeType === 1 && node.nodeName.toLowerCase() === nodeName) { if (single) { return node; } else { result.push(node); } } } if (!single) { return result; } } /** * Filter all parents (ancestors) with tag name * @param {element} node * @param {string} tagname * @returns {element[]} parents * @memberof Core */ function getParentByTagName(node, tagname) { var parent = void 0; if (node === null || tagname === '') return; parent = node.parentNode; while (parent.nodeType === 1) { if (parent.tagName.toLowerCase() === tagname) { return parent; } parent = parent.parentNode; } } /** * Lightweight Polyfill for DOM Range * @class * @memberof Core */ var RangeObject = exports.RangeObject = function () { function RangeObject() { _classCallCheck(this, RangeObject); this.collapsed = false; this.commonAncestorContainer = undefined; this.endContainer = undefined; this.endOffset = undefined; this.startContainer = undefined; this.startOffset = undefined; } _createClass(RangeObject, [{ key: "setStart", value: function setStart(startNode, startOffset) { this.startContainer = startNode; this.startOffset = startOffset; if (!this.endContainer) { this.collapse(true); } else { this.commonAncestorContainer = this._commonAncestorContainer(); } this._checkCollapsed(); } }, { key: "setEnd", value: function setEnd(endNode, endOffset) { this.endContainer = endNode; this.endOffset = endOffset; if (!this.startContainer) { this.collapse(false); } else { this.collapsed = false; this.commonAncestorContainer = this._commonAncestorContainer(); } this._checkCollapsed(); } }, { key: "collapse", value: function collapse(toStart) { this.collapsed = true; if (toStart) { this.endContainer = this.startContainer; this.endOffset = this.startOffset; this.commonAncestorContainer = this.startContainer.parentNode; } else { this.startContainer = this.endContainer; this.startOffset = this.endOffset; this.commonAncestorContainer = this.endOffset.parentNode; } } }, { key: "selectNode", value: function selectNode(referenceNode) { var parent = referenceNode.parentNode; var index = Array.prototype.indexOf.call(parent.childNodes, referenceNode); this.setStart(parent, index); this.setEnd(parent, index + 1); } }, { key: "selectNodeContents", value: function selectNodeContents(referenceNode) { var end = referenceNode.childNodes[referenceNode.childNodes - 1]; var endIndex = referenceNode.nodeType === 3 ? referenceNode.textContent.length : parent.childNodes.length; this.setStart(referenceNode, 0); this.setEnd(referenceNode, endIndex); } }, { key: "_commonAncestorContainer", value: function _commonAncestorContainer(startContainer, endContainer) { var startParents = parents(startContainer || this.startContainer); var endParents = parents(endContainer || this.endContainer); if (startParents[0] != endParents[0]) return undefined; for (var i = 0; i < startParents.length; i++) { if (startParents[i] != endParents[i]) { return startParents[i - 1]; } } } }, { key: "_checkCollapsed", value: function _checkCollapsed() { if (this.startContainer === this.endContainer && this.startOffset === this.endOffset) { this.collapsed = true; } else { this.collapsed = false; } } }, { key: "toString", value: function toString() { // TODO: implement walking between start and end to find text } }]); return RangeObject; }(); /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; 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 _core = __webpack_require__(0); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var ELEMENT_NODE = 1; var TEXT_NODE = 3; var COMMENT_NODE = 8; var DOCUMENT_NODE = 9; /** * Parsing and creation of EpubCFIs: http://www.idpf.org/epub/linking/cfi/epub-cfi.html * Implements: * - Character Offset: epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3) * - Simple Ranges : epubcfi(/6/4[chap01ref]!/4[body01]/10[para05],/2/1:1,/3:4) * Does Not Implement: * - Temporal Offset (~) * - Spatial Offset (@) * - Temporal-Spatial Offset (~ + @) * - Text Location Assertion ([) * @class @param {string | Range | Node } [cfiFrom] @param {string | object} [base] @param {string} [ignoreClass] class to ignore when parsing DOM */ var EpubCFI = function () { function EpubCFI(cfiFrom, base, ignoreClass) { _classCallCheck(this, EpubCFI); var type; this.str = ""; this.base = {}; this.spinePos = 0; // For compatibility this.range = false; // true || false; this.path = {}; this.start = null; this.end = null; // Allow instantiation without the "new" keyword if (!(this instanceof EpubCFI)) { return new EpubCFI(cfiFrom, base, ignoreClass); } if (typeof base === "string") { this.base = this.parseComponent(base); } else if ((typeof base === "undefined" ? "undefined" : _typeof(base)) === "object" && base.steps) { this.base = base; } type = this.checkType(cfiFrom); if (type === "string") { this.str = cfiFrom; return (0, _core.extend)(this, this.parse(cfiFrom)); } else if (type === "range") { return (0, _core.extend)(this, this.fromRange(cfiFrom, this.base, ignoreClass)); } else if (type === "node") { return (0, _core.extend)(this, this.fromNode(cfiFrom, this.base, ignoreClass)); } else if (type === "EpubCFI" && cfiFrom.path) { return cfiFrom; } else if (!cfiFrom) { return this; } else { throw new TypeError("not a valid argument for EpubCFI"); } } /** * Check the type of constructor input * @private */ _createClass(EpubCFI, [{ key: "checkType", value: function checkType(cfi) { if (this.isCfiString(cfi)) { return "string"; // Is a range object } else if (cfi && (typeof cfi === "undefined" ? "undefined" : _typeof(cfi)) === "object" && ((0, _core.type)(cfi) === "Range" || typeof cfi.startContainer != "undefined")) { return "range"; } else if (cfi && (typeof cfi === "undefined" ? "undefined" : _typeof(cfi)) === "object" && typeof cfi.nodeType != "undefined") { // || typeof cfi === "function" return "node"; } else if (cfi && (typeof cfi === "undefined" ? "undefined" : _typeof(cfi)) === "object" && cfi instanceof EpubCFI) { return "EpubCFI"; } else { return false; } } /** * Parse a cfi string to a CFI object representation * @param {string} cfiStr * @returns {object} cfi */ }, { key: "parse", value: function parse(cfiStr) { var cfi = { spinePos: -1, range: false, base: {}, path: {}, start: null, end: null }; var baseComponent, pathComponent, range; if (typeof cfiStr !== "string") { return { spinePos: -1 }; } if (cfiStr.indexOf("epubcfi(") === 0 && cfiStr[cfiStr.length - 1] === ")") { // Remove intial epubcfi( and ending ) cfiStr = cfiStr.slice(8, cfiStr.length - 1); } baseComponent = this.getChapterComponent(cfiStr); // Make sure this is a valid cfi or return if (!baseComponent) { return { spinePos: -1 }; } cfi.base = this.parseComponent(baseComponent); pathComponent = this.getPathComponent(cfiStr); cfi.path = this.parseComponent(pathComponent); range = this.getRange(cfiStr); if (range) { cfi.range = true; cfi.start = this.parseComponent(range[0]); cfi.end = this.parseComponent(range[1]); } // Get spine node position // cfi.spineSegment = cfi.base.steps[1]; // Chapter segment is always the second step cfi.spinePos = cfi.base.steps[1].index; return cfi; } }, { key: "parseComponent", value: function parseComponent(componentStr) { var component = { steps: [], terminal: { offset: null, assertion: null } }; var parts = componentStr.split(":"); var steps = parts[0].split("/"); var terminal; if (parts.length > 1) { terminal = parts[1]; component.terminal = this.parseTerminal(terminal); } if (steps[0] === "") { steps.shift(); // Ignore the first slash } component.steps = steps.map(function (step) { return this.parseStep(step); }.bind(this)); return component; } }, { key: "parseStep", value: function parseStep(stepStr) { var type, num, index, has_brackets, id; has_brackets = stepStr.match(/\[(.*)\]/); if (has_brackets && has_brackets[1]) { id = has_brackets[1]; } //-- Check if step is a text node or element num = parseInt(stepStr); if (isNaN(num)) { return; } if (num % 2 === 0) { // Even = is an element type = "element"; index = num / 2 - 1; } else { type = "text"; index = (num - 1) / 2; } return { "type": type, "index": index, "id": id || null }; } }, { key: "parseTerminal", value: function parseTerminal(termialStr) { var characterOffset, textLocationAssertion; var assertion = termialStr.match(/\[(.*)\]/); if (assertion && assertion[1]) { characterOffset = parseInt(termialStr.split("[")[0]); textLocationAssertion = assertion[1]; } else { characterOffset = parseInt(termialStr); } if (!(0, _core.isNumber)(characterOffset)) { characterOffset = null; } return { "offset": characterOffset, "assertion": textLocationAssertion }; } }, { key: "getChapterComponent", value: function getChapterComponent(cfiStr) { var indirection = cfiStr.split("!"); return indirection[0]; } }, { key: "getPathComponent", value: function getPathComponent(cfiStr) { var indirection = cfiStr.split("!"); if (indirection[1]) { var ranges = indirection[1].split(","); return ranges[0]; } } }, { key: "getRange", value: function getRange(cfiStr) { var ranges = cfiStr.split(","); if (ranges.length === 3) { return [ranges[1], ranges[2]]; } return false; } }, { key: "getCharecterOffsetComponent", value: function getCharecterOffsetComponent(cfiStr) { var splitStr = cfiStr.split(":"); return splitStr[1] || ""; } }, { key: "joinSteps", value: function joinSteps(steps) { if (!steps) { return ""; } return steps.map(function (part) { var segment = ""; if (part.type === "element") { segment += (part.index + 1) * 2; } if (part.type === "text") { segment += 1 + 2 * part.index; // TODO: double check that this is odd } if (part.id) { segment += "[" + part.id + "]"; } return segment; }).join("/"); } }, { key: "segmentString", value: function segmentString(segment) { var segmentString = "/"; segmentString += this.joinSteps(segment.steps); if (segment.terminal && segment.terminal.offset != null) { segmentString += ":" + segment.terminal.offset; } if (segment.terminal && segment.terminal.assertion != null) { segmentString += "[" + segment.terminal.assertion + "]"; } return segmentString; } /** * Convert CFI to a epubcfi(...) string * @returns {string} epubcfi */ }, { key: "toString", value: function toString() { var cfiString = "epubcfi("; cfiString += this.segmentString(this.base); cfiString += "!"; cfiString += this.segmentString(this.path); // Add Range, if present if (this.range && this.start) { cfiString += ","; cfiString += this.segmentString(this.start); } if (this.range && this.end) { cfiString += ","; cfiString += this.segmentString(this.end); } cfiString += ")"; return cfiString; } /** * Compare which of two CFIs is earlier in the text * @returns {number} First is earlier = -1, Second is earlier = 1, They are equal = 0 */ }, { key: "compare", value: function compare(cfiOne, cfiTwo) { var stepsA, stepsB; var terminalA, terminalB; var rangeAStartSteps, rangeAEndSteps; var rangeBEndSteps, rangeBEndSteps; var rangeAStartTerminal, rangeAEndTerminal; var rangeBStartTerminal, rangeBEndTerminal; if (typeof cfiOne === "string") { cfiOne = new EpubCFI(cfiOne); } if (typeof cfiTwo === "string") { cfiTwo = new EpubCFI(cfiTwo); } // Compare Spine Positions if (cfiOne.spinePos > cfiTwo.spinePos) { return 1; } if (cfiOne.spinePos < cfiTwo.spinePos) { 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 for (var i = 0; i < stepsA.length; i++) { if (!stepsA[i]) { return -1; } if (!stepsB[i]) { return 1; } if (stepsA[i].index > stepsB[i].index) { return 1; } if (stepsA[i].index < stepsB[i].index) { return -1; } // Otherwise continue checking } // All steps in First equal to Second and First is Less Specific if (stepsA.length < stepsB.length) { return 1; } // Compare the charecter offset of the text node if (terminalA.offset > terminalB.offset) { return 1; } if (terminalA.offset < terminalB.offset) { return -1; } // CFI's are equal return 0; } }, { key: "step", value: function step(node) { var nodeType = node.nodeType === TEXT_NODE ? "text" : "element"; return { "id": node.id, "tagName": node.tagName, "type": nodeType, "index": this.position(node) }; } }, { key: "filteredStep", value: function filteredStep(node, ignoreClass) { var filteredNode = this.filter(node, ignoreClass); var nodeType; // Node filtered, so ignore if (!filteredNode) { return; } // Otherwise add the filter node in nodeType = filteredNode.nodeType === TEXT_NODE ? "text" : "element"; return { "id": filteredNode.id, "tagName": filteredNode.tagName, "type": nodeType, "index": this.filteredPosition(filteredNode, ignoreClass) }; } }, { key: "pathTo", value: function pathTo(node, offset, ignoreClass) { var segment = { steps: [], terminal: { offset: null, assertion: null } }; var currentNode = node; var step; while (currentNode && currentNode.parentNode && currentNode.parentNode.nodeType != DOCUMENT_NODE) { if (ignoreClass) { step = this.filteredStep(currentNode, ignoreClass); } else { step = this.step(currentNode); } if (step) { segment.steps.unshift(step); } currentNode = currentNode.parentNode; } if (offset != null && offset >= 0) { segment.terminal.offset = offset; // Make sure we are getting to a textNode if there is an offset if (segment.steps[segment.steps.length - 1].type != "text") { segment.steps.push({ "type": "text", "index": 0 }); } } return segment; } }, { key: "equalStep", value: function equalStep(stepA, stepB) { if (!stepA || !stepB) { return false; } if (stepA.index === stepB.index && stepA.id === stepB.id && stepA.type === stepB.type) { return true; } return false; } /** * Create a CFI object from a Range * @param {Range} range * @param {string | object} base * @param {string} [ignoreClass] * @returns {object} cfi */ }, { key: "fromRange", value: function fromRange(range, base, ignoreClass) { var cfi = { range: false, base: {}, path: {}, start: null, end: null }; var start = range.startContainer; var end = range.endContainer; var startOffset = range.startOffset; var endOffset = range.endOffset; var needsIgnoring = false; if (ignoreClass) { // Tell pathTo if / what to ignore needsIgnoring = start.ownerDocument.querySelector("." + ignoreClass) != null; } if (typeof base === "string") { cfi.base = this.parseComponent(base); cfi.spinePos = cfi.base.steps[1].index; } else if ((typeof base === "undefined" ? "undefined" : _typeof(base)) === "object") { cfi.base = base; } if (range.collapsed) { if (needsIgnoring) { startOffset = this.patchOffset(start, startOffset, ignoreClass); } cfi.path = this.pathTo(start, startOffset, ignoreClass); } else { cfi.range = true; if (needsIgnoring) { startOffset = this.patchOffset(start, startOffset, ignoreClass); } cfi.start = this.pathTo(start, startOffset, ignoreClass); if (needsIgnoring) { endOffset = this.patchOffset(end, endOffset, ignoreClass); } cfi.end = this.pathTo(end, endOffset, ignoreClass); // Create a new empty path cfi.path = { steps: [], terminal: null }; // Push steps that are shared between start and end to the common path var len = cfi.start.steps.length; var i; for (i = 0; i < len; i++) { if (this.equalStep(cfi.start.steps[i], cfi.end.steps[i])) { if (i === len - 1) { // Last step is equal, check terminals if (cfi.start.terminal === cfi.end.terminal) { // CFI's are equal cfi.path.steps.push(cfi.start.steps[i]); // Not a range cfi.range = false; } } else { cfi.path.steps.push(cfi.start.steps[i]); } } else { break; } } cfi.start.steps = cfi.start.steps.slice(cfi.path.steps.length); cfi.end.steps = cfi.end.steps.slice(cfi.path.steps.length); // TODO: Add Sanity check to make sure that the end if greater than the start } return cfi; } /** * Create a CFI object from a Node * @param {Node} anchor * @param {string | object} base * @param {string} [ignoreClass] * @returns {object} cfi */ }, { key: "fromNode", value: function fromNode(anchor, base, ignoreClass) { var cfi = { range: false, base: {}, path: {}, start: null, end: null }; if (typeof base === "string") { cfi.base = this.parseComponent(base); cfi.spinePos = cfi.base.steps[1].index; } else if ((typeof base === "undefined" ? "undefined" : _typeof(base)) === "object") { cfi.base = base; } cfi.path = this.pathTo(anchor, null, ignoreClass); return cfi; } }, { key: "filter", value: function filter(anchor, ignoreClass) { var needsIgnoring; var sibling; // to join with var parent, previousSibling, nextSibling; var isText = false; if (anchor.nodeType === TEXT_NODE) { isText = true; parent = anchor.parentNode; needsIgnoring = anchor.parentNode.classList.contains(ignoreClass); } else { isText = false; needsIgnoring = anchor.classList.contains(ignoreClass); } if (needsIgnoring && isText) { previousSibling = parent.previousSibling; nextSibling = parent.nextSibling; // If the sibling is a text node, join the nodes if (previousSibling && previousSibling.nodeType === TEXT_NODE) { sibling = previousSibling; } else if (nextSibling && nextSibling.nodeType === TEXT_NODE) { sibling = nextSibling; } if (sibling) { return sibling; } else { // Parent will be ignored on next step return anchor; } } else if (needsIgnoring && !isText) { // Otherwise just skip the element node return false; } else { // No need to filter return anchor; } } }, { key: "patchOffset", value: function patchOffset(anchor, offset, ignoreClass) { if (anchor.nodeType != TEXT_NODE) { throw new Error("Anchor must be a text node"); } var curr = anchor; var totalOffset = offset; // If the parent is a ignored node, get offset from it's start if (anchor.parentNode.classList.contains(ignoreClass)) { curr = anchor.parentNode; } while (curr.previousSibling) { if (curr.previousSibling.nodeType === ELEMENT_NODE) { // Originally a text node, so join if (curr.previousSibling.classList.contains(ignoreClass)) { totalOffset += curr.previousSibling.textContent.length; } else { break; // Normal node, dont join } } else { // If the previous sibling is a text node, join the nodes totalOffset += curr.previousSibling.textContent.length; } curr = curr.previousSibling; } return totalOffset; } }, { key: "normalizedMap", value: function normalizedMap(children, nodeType, ignoreClass) { var output = {}; var prevIndex = -1; var i, len = children.length; var currNodeType; var prevNodeType; for (i = 0; i < len; i++) { currNodeType = children[i].nodeType; // Check if needs ignoring if (currNodeType === ELEMENT_NODE && children[i].classList.contains(ignoreClass)) { currNodeType = TEXT_NODE; } if (i > 0 && currNodeType === TEXT_NODE && prevNodeType === TEXT_NODE) { // join text nodes output[i] = prevIndex; } else if (nodeType === currNodeType) { prevIndex = prevIndex + 1; output[i] = prevIndex; } prevNodeType = currNodeType; } return output; } }, { key: "position", value: function position(anchor) { var children, index; if (anchor.nodeType === ELEMENT_NODE) { children = anchor.parentNode.children; if (!children) { children = (0, _core.findChildren)(anchor.parentNode); } index = Array.prototype.indexOf.call(children, anchor); } else { children = this.textNodes(anchor.parentNode); index = children.indexOf(anchor); } return index; } }, { key: "filteredPosition", value: function filteredPosition(anchor, ignoreClass) { var children, index, map; if (anchor.nodeType === ELEMENT_NODE) { children = anchor.parentNode.children; map = this.normalizedMap(children, ELEMENT_NODE, ignoreClass); } else { children = anchor.parentNode.childNodes; // Inside an ignored node if (anchor.parentNode.classList.contains(ignoreClass)) { anchor = anchor.parentNode; children = anchor.parentNode.childNodes; } map = this.normalizedMap(children, TEXT_NODE, ignoreClass); } index = Array.prototype.indexOf.call(children, anchor); return map[index]; } }, { key: "stepsToXpath", value: function stepsToXpath(steps) { var xpath = [".", "*"]; steps.forEach(function (step) { var position = step.index + 1; if (step.id) { xpath.push("*[position()=" + position + " and @id='" + step.id + "']"); } else if (step.type === "text") { xpath.push("text()[" + position + "]"); } else { xpath.push("*[" + position + "]"); } }); return xpath.join("/"); } /* To get the last step if needed: // Get the terminal step lastStep = steps[steps.length-1]; // Get the query string query = this.stepsToQuery(steps); // Find the containing element startContainerParent = doc.querySelector(query); // Find the text node within that element if(startContainerParent && lastStep.type == "text") { container = startContainerParent.childNodes[lastStep.index]; } */ }, { key: "stepsToQuerySelector", value: function stepsToQuerySelector(steps) { var query = ["html"]; steps.forEach(function (step) { var position = step.index + 1; if (step.id) { query.push("#" + step.id); } else if (step.type === "text") { // unsupported in querySelector // query.push("text()[" + position + "]"); } else { query.push("*:nth-child(" + position + ")"); } }); return query.join(">"); } }, { key: "textNodes", value: function textNodes(container, ignoreClass) { return Array.prototype.slice.call(container.childNodes).filter(function (node) { if (node.nodeType === TEXT_NODE) { return true; } else if (ignoreClass && node.classList.contains(ignoreClass)) { return true; } return false; }); } }, { key: "walkToNode", value: function walkToNode(steps, _doc, ignoreClass) { var doc = _doc || document; var container = doc.documentElement; var children; var step; var len = steps.length; var i; for (i = 0; i < len; i++) { step = steps[i]; if (step.type === "element") { //better to get a container using id as some times step.index may not be correct //For ex.https://github.com/futurepress/epub.js/issues/561 if (step.id) { container = doc.getElementById(step.id); } else { children = container.children || (0, _core.findChildren)(container); container = children[step.index]; } } else if (step.type === "text") { container = this.textNodes(container, ignoreClass)[step.index]; } if (!container) { //Break the for loop as due to incorrect index we can get error if //container is undefined so that other functionailties works fine //like navigation break; } } return container; } }, { key: "findNode", value: function findNode(steps, _doc, ignoreClass) { var doc = _doc || document; var container; var xpath; if (!ignoreClass && typeof doc.evaluate != "undefined") { xpath = this.stepsToXpath(steps); container = doc.evaluate(xpath, doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; } else if (ignoreClass) { container = this.walkToNode(steps, doc, ignoreClass); } else { container = this.walkToNode(steps, doc); } return container; } }, { key: "fixMiss", value: function fixMiss(steps, offset, _doc, ignoreClass) { var container = this.findNode(steps.slice(0, -1), _doc, ignoreClass); var children = container.childNodes; var map = this.normalizedMap(children, TEXT_NODE, ignoreClass); var child; var len; var lastStepIndex = steps[steps.length - 1].index; for (var childIndex in map) { if (!map.hasOwnProperty(childIndex)) return; if (map[childIndex] === lastStepIndex) { child = children[childIndex]; len = child.textContent.length; if (offset > len) { offset = offset - len; } else { if (child.nodeType === ELEMENT_NODE) { container = child.childNodes[0]; } else { container = child; } break; } } } return { container: container, offset: offset }; } /** * Creates a DOM range representing a CFI * @param {document} _doc document referenced in the base * @param {string} [ignoreClass] * @return {Range} */ }, { key: "toRange", value: function toRange(_doc, ignoreClass) { var doc = _doc || document; var range; var start, end, startContainer, endContainer; var cfi = this; var startSteps, endSteps; var needsIgnoring = ignoreClass ? doc.querySelector("." + ignoreClass) != null : false; var missed; if (typeof doc.createRange !== "undefined") { range = doc.createRange(); } else { range = new _core.RangeObject(); } if (cfi.range) { start = cfi.start; startSteps = cfi.path.steps.concat(start.steps); startContainer = this.findNode(startSteps, doc, needsIgnoring ? ignoreClass : null); end = cfi.end; endSteps = cfi.path.steps.concat(end.steps); endContainer = this.findNode(endSteps, doc, needsIgnoring ? ignoreClass : null); } else { start = cfi.path; startSteps = cfi.path.steps; startContainer = this.findNode(cfi.path.steps, doc, needsIgnoring ? ignoreClass : null); } if (startContainer) { try { if (start.terminal.offset != null) { range.setStart(startContainer, start.terminal.offset); } else { range.setStart(startContainer, 0); } } catch (e) { missed = this.fixMiss(startSteps, start.terminal.offset, doc, needsIgnoring ? ignoreClass : null); range.setStart(missed.container, missed.offset); } } else { console.log("No startContainer found for", this.toString()); // No start found return null; } if (endContainer) { try { if (end.terminal.offset != null) { range.setEnd(endContainer, end.terminal.offset); } else { range.setEnd(endContainer, 0); } } catch (e) { missed = this.fixMiss(endSteps, cfi.end.terminal.offset, doc, needsIgnoring ? ignoreClass : null); range.setEnd(missed.container, missed.offset); } } // doc.defaultView.getSelection().addRange(range); return range; } /** * Check if a string is wrapped with "epubcfi()" * @param {string} str * @returns {boolean} */ }, { key: "isCfiString", value: function isCfiString(str) { if (typeof str === "string" && str.indexOf("epubcfi(") === 0 && str[str.length - 1] === ")") { return true; } return false; } }, { key: "generateChapterComponent", value: function generateChapterComponent(_spineNodeIndex, _pos, id) { var pos = parseInt(_pos), spineNodeIndex = (_spineNodeIndex + 1) * 2, cfi = "/" + spineNodeIndex + "/"; cfi += (pos + 1) * 2; if (id) { cfi += "[" + id + "]"; } return cfi; } /** * Collapse a CFI Range to a single CFI Position * @param {boolean} [toStart=false] */ }, { key: "collapse", value: function collapse(toStart) { if (!this.range) { return; } this.range = false; if (toStart) { this.path.steps = this.path.steps.concat(this.start.steps); this.path.terminal = this.start.terminal; } else { this.path.steps = this.path.steps.concat(this.end.steps); this.path.terminal = this.end.terminal; } } }]); return EpubCFI; }(); exports.default = EpubCFI; module.exports = exports["default"]; /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var EPUBJS_VERSION = exports.EPUBJS_VERSION = "0.3"; // Dom events to listen for var DOM_EVENTS = exports.DOM_EVENTS = ["keydown", "keyup", "keypressed", "mouseup", "mousedown", "click", "touchend", "touchstart"]; var EVENTS = exports.EVENTS = { BOOK: { OPEN_FAILED: "openFailed" }, CONTENTS: { EXPAND: "expand", RESIZE: "resize", SELECTED: "selected", SELECTED_RANGE: "selectedRange", LINK_CLICKED: "linkClicked" }, LOCATIONS: { CHANGED: "changed" }, MANAGERS: { RESIZE: "resize", RESIZED: "resized", ORIENTATION_CHANGE: "orientationchange", ADDED: "added", SCROLL: "scroll", SCROLLED: "scrolled", REMOVED: "removed" }, VIEWS: { AXIS: "axis", LOAD_ERROR: "loaderror", RENDERED: "rendered", RESIZED: "resized", DISPLAYED: "displayed", SHOWN: "shown", HIDDEN: "hidden", MARK_CLICKED: "markClicked" }, RENDITION: { STARTED: "started", ATTACHED: "attached", DISPLAYED: "displayed", DISPLAY_ERROR: "displayerror", RENDERED: "rendered", REMOVED: "removed", RESIZED: "resized", ORIENTATION_CHANGE: "orientationchange", LOCATION_CHANGED: "locationChanged", RELOCATED: "relocated", MARK_CLICKED: "markClicked", SELECTED: "selected", LAYOUT: "layout" }, LAYOUT: { UPDATED: "updated" } }; /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var d = __webpack_require__(27) , callable = __webpack_require__(41) , apply = Function.prototype.apply, call = Function.prototype.call , create = Object.create, defineProperty = Object.defineProperty , defineProperties = Object.defineProperties , hasOwnProperty = Object.prototype.hasOwnProperty , descriptor = { configurable: true, enumerable: false, writable: true } , on, once, off, emit, methods, descriptors, base; on = function (type, listener) { var data; callable(listener); if (!hasOwnProperty.call(this, '__ee__')) { data = descriptor.value = create(null); defineProperty(this, '__ee__', descriptor); descriptor.value = null; } else { data = this.__ee__; } if (!data[type]) data[type] = listener; else if (typeof data[type] === 'object') data[type].push(listener); else data[type] = [data[type], listener]; return this; }; once = function (type, listener) { var once, self; callable(listener); self = this; on.call(this, type, once = function () { off.call(self, type, once); apply.call(listener, this, arguments); }); once.__eeOnceListener__ = listener; return this; }; off = function (type, listener) { var data, listeners, candidate, i; callable(listener); if (!hasOwnProperty.call(this, '__ee__')) return this; data = this.__ee__; if (!data[type]) return this; listeners = data[type]; if (typeof listeners === 'object') { for (i = 0; (candidate = listeners[i]); ++i) { if ((candidate === listener) || (candidate.__eeOnceListener__ === listener)) { if (listeners.length === 2) data[type] = listeners[i ? 0 : 1]; else listeners.splice(i, 1); } } } else { if ((listeners === listener) || (listeners.__eeOnceListener__ === listener)) { delete data[type]; } } return this; }; emit = function (type) { var i, l, listener, listeners, args; if (!hasOwnProperty.call(this, '__ee__')) return; listeners = this.__ee__[type]; if (!listeners) return; if (typeof listeners === 'object') { l = arguments.length; args = new Array(l - 1); for (i = 1; i < l; ++i) args[i - 1] = arguments[i]; listeners = listeners.slice(); for (i = 0; (listener = listeners[i]); ++i) { apply.call(listener, this, args); } } else { switch (arguments.length) { case 1: call.call(listeners, this); break; case 2: call.call(listeners, this, arguments[1]); break; case 3: call.call(listeners, this, arguments[1], arguments[2]); break; default: l = arguments.length; args = new Array(l - 1); for (i = 1; i < l; ++i) { args[i - 1] = arguments[i]; } apply.call(listeners, this, args); } } }; methods = { on: on, once: once, off: off, emit: emit }; descriptors = { on: d(on), once: d(once), off: d(off), emit: d(emit) }; base = defineProperties({}, descriptors); module.exports = exports = function (o) { return (o == null) ? create(base) : defineProperties(Object(o), descriptors); }; exports.methods = methods; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { "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 _pathWebpack = __webpack_require__(6); var _pathWebpack2 = _interopRequireDefault(_pathWebpack); 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"); } } /** * Creates a Path object for parsing and manipulation of a path strings * * Uses a polyfill for Nodejs path: https://nodejs.org/api/path.html * @param {string} pathString a url string (relative or absolute) * @class */ var Path = function () { function Path(pathString) { _classCallCheck(this, Path); var protocol; var parsed; protocol = pathString.indexOf("://"); if (protocol > -1) { pathString = new URL(pathString).pathname; } parsed = this.parse(pathString); this.path = pathString; if (this.isDirectory(pathString)) { this.directory = pathString; } else { this.directory = parsed.dir + "/"; } this.filename = parsed.base; this.extension = parsed.ext.slice(1); } /** * Parse the path: https://nodejs.org/api/path.html#path_path_parse_path * @param {string} what * @returns {object} */ _createClass(Path, [{ key: "parse", value: function parse(what) { return _pathWebpack2.default.parse(what); } /** * @param {string} what * @returns {boolean} */ }, { key: "isAbsolute", value: function isAbsolute(what) { return _pathWebpack2.default.isAbsolute(what || this.path); } /** * Check if path ends with a directory * @param {string} what * @returns {boolean} */ }, { key: "isDirectory", value: function isDirectory(what) { return what.charAt(what.length - 1) === "/"; } /** * Resolve a path against the directory of the Path * * https://nodejs.org/api/path.html#path_path_resolve_paths * @param {string} what * @returns {string} resolved */ }, { key: "resolve", value: function resolve(what) { return _pathWebpack2.default.resolve(this.directory, what); } /** * Resolve a path relative to the directory of the Path * * https://nodejs.org/api/path.html#path_path_relative_from_to * @param {string} what * @returns {string} relative */ }, { key: "relative", value: function relative(what) { return _pathWebpack2.default.relative(this.directory, what); } }, { key: "splitPath", value: function splitPath(filename) { return this.splitPathRe.exec(filename).slice(1); } /** * Return the path string * @returns {string} path */ }, { key: "toString", value: function toString() { return this.path; } }]); return Path; }(); exports.default = Path; module.exports = exports["default"]; /***/ }), /* 5 */ /***/ (function(module, exports, __webpack_require__) { "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 _path = __webpack_require__(4); var _path2 = _interopRequireDefault(_path); var _pathWebpack = __webpack_require__(6); var _pathWebpack2 = _interopRequireDefault(_pathWebpack); 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"); } } /** * creates a Url object for parsing and manipulation of a url string * @param {string} urlString a url string (relative or absolute) * @param {string} [baseString] optional base for the url, * default to window.location.href */ var Url = function () { function Url(urlString, baseString) { _classCallCheck(this, Url); var absolute = urlString.indexOf("://") > -1; var pathname = urlString; var basePath; this.Url = undefined; this.href = urlString; this.protocol = ""; this.origin = ""; this.hash = ""; this.hash = ""; this.search = ""; this.base = baseString; if (!absolute && baseString !== false && typeof baseString !== "string" && window && window.location) { this.base = window.location.href; } // URL Polyfill doesn't throw an error if base is empty if (absolute || this.base) { try { if (this.base) { // Safari doesn't like an undefined base this.Url = new URL(urlString, this.base); } else { this.Url = new URL(urlString); } this.href = this.Url.href; this.protocol = this.Url.protocol; this.origin = this.Url.origin; this.hash = this.Url.hash; this.search = this.Url.search; pathname = this.Url.pathname; } catch (e) { // Skip URL parsing this.Url = undefined; // resolve the pathname from the base if (this.base) { basePath = new _path2.default(this.base); pathname = basePath.resolve(pathname); } } } this.Path = new _path2.default(pathname); this.directory = this.Path.directory; this.filename = this.Path.filename; this.extension = this.Path.extension; } /** * @returns {Path} */ _createClass(Url, [{ key: "path", value: function path() { return this.Path; } /** * Resolves a relative path to a absolute url * @param {string} what * @returns {string} url */ }, { key: "resolve", value: function resolve(what) { var isAbsolute = what.indexOf("://") > -1; var fullpath; if (isAbsolute) { return what; } fullpath = _pathWebpack2.default.resolve(this.directory, what); return this.origin + fullpath; } /** * Resolve a path relative to the url * @param {string} what * @returns {string} path */ }, { key: "relative", value: function relative(what) { return _pathWebpack2.default.relative(what, this.directory); } /** * @returns {string} */ }, { key: "toString", value: function toString() { return this.href; } }]); return Url; }(); exports.default = Url; module.exports = exports["default"]; /***/ }), /* 6 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; if (!process) { var process = { "cwd" : function () { return '/' } }; } function assertPath(path) { if (typeof path !== 'string') { throw new TypeError('Path must be a string. Received ' + path); } } // Resolves . and .. elements in a path with directory names function normalizeStringPosix(path, allowAboveRoot) { var res = ''; var lastSlash = -1; var dots = 0; var code; for (var i = 0; i <= path.length; ++i) { if (i < path.length) code = path.charCodeAt(i); else if (code === 47/*/*/) break; else code = 47/*/*/; if (code === 47/*/*/) { if (lastSlash === i - 1 || dots === 1) { // NOOP } else if (lastSlash !== i - 1 && dots === 2) { if (res.length < 2 || res.charCodeAt(res.length - 1) !== 46/*.*/ || res.charCodeAt(res.length - 2) !== 46/*.*/) { if (res.length > 2) { var start = res.length - 1; var j = start; for (; j >= 0; --j) { if (res.charCodeAt(j) === 47/*/*/) break; } if (j !== start) { if (j === -1) res = ''; else res = res.slice(0, j); lastSlash = i; dots = 0; continue; } } else if (res.length === 2 || res.length === 1) { res = ''; lastSlash = i; dots = 0; continue; } } if (allowAboveRoot) { if (res.length > 0) res += '/..'; else res = '..'; } } else { if (res.length > 0) res += '/' + path.slice(lastSlash + 1, i); else res = path.slice(lastSlash + 1, i); } lastSlash = i; dots = 0; } else if (code === 46/*.*/ && dots !== -1) { ++dots; } else { dots = -1; } } return res; } function _format(sep, pathObject) { var dir = pathObject.dir || pathObject.root; var base = pathObject.base || ((pathObject.name || '') + (pathObject.ext || '')); if (!dir) { return base; } if (dir === pathObject.root) { return dir + base; } return dir + sep + base; } var posix = { // path.resolve([from ...], to) resolve: function resolve() { var resolvedPath = ''; var resolvedAbsolute = false; var cwd; for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { var path; if (i >= 0) path = arguments[i]; else { if (cwd === undefined) cwd = process.cwd(); path = cwd; } assertPath(path); // Skip empty entries if (path.length === 0) { continue; } resolvedPath = path + '/' + resolvedPath; resolvedAbsolute = path.charCodeAt(0) === 47/*/*/; } // At this point the path should be resolved to a full absolute path, but // handle relative paths to be safe (might happen when process.cwd() fails) // Normalize the path resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute); if (resolvedAbsolute) { if (resolvedPath.length > 0) return '/' + resolvedPath; else return '/'; } else if (resolvedPath.length > 0) { return resolvedPath; } else { return '.'; } }, normalize: function normalize(path) { assertPath(path); if (path.length === 0) return '.'; var isAbsolute = path.charCodeAt(0) === 47/*/*/; var trailingSeparator = path.charCodeAt(path.length - 1) === 47/*/*/; // Normalize the path path = normalizeStringPosix(path, !isAbsolute); if (path.length === 0 && !isAbsolute) path = '.'; if (path.length > 0 && trailingSeparator) path += '/'; if (isAbsolute) return '/' + path; return path; }, isAbsolute: function isAbsolute(path) { assertPath(path); return path.length > 0 && path.charCodeAt(0) === 47/*/*/; }, join: function join() { if (arguments.length === 0) return '.'; var joined; for (var i = 0; i < arguments.length; ++i) { var arg = arguments[i]; assertPath(arg); if (arg.length > 0) { if (joined === undefined) joined = arg; else joined += '/' + arg; } } if (joined === undefined) return '.'; return posix.normalize(joined); }, relative: function relative(from, to) { assertPath(from); assertPath(to); if (from === to) return ''; from = posix.resolve(from); to = posix.resolve(to); if (from === to) return ''; // Trim any leading backslashes var fromStart = 1; for (; fromStart < from.length; ++fromStart) { if (from.charCodeAt(fromStart) !== 47/*/*/) break; } var fromEnd = from.length; var fromLen = (fromEnd - fromStart); // Trim any leading backslashes var toStart = 1; for (; toStart < to.length; ++toStart) { if (to.charCodeAt(toStart) !== 47/*/*/) break; } var toEnd = to.length; var toLen = (toEnd - toStart); // Compare paths to find the longest common path from root var length = (fromLen < toLen ? fromLen : toLen); var lastCommonSep = -1; var i = 0; for (; i <= length; ++i) { if (i === length) { if (toLen > length) { if (to.charCodeAt(toStart + i) === 47/*/*/) { // We get here if `from` is the exact base path for `to`. // For example: from='/foo/bar'; to='/foo/bar/baz' return to.slice(toStart + i + 1); } else if (i === 0) { // We get here if `from` is the root // For example: from='/'; to='/foo' return to.slice(toStart + i); } } else if (fromLen > length) { if (from.charCodeAt(fromStart + i) === 47/*/*/) { // We get here if `to` is the exact base path for `from`. // For example: from='/foo/bar/baz'; to='/foo/bar' lastCommonSep = i; } else if (i === 0) { // We get here if `to` is the root. // For example: from='/foo'; to='/' lastCommonSep = 0; } } break; } var fromCode = from.charCodeAt(fromStart + i); var toCode = to.charCodeAt(toStart + i); if (fromCode !== toCode) break; else if (fromCode === 47/*/*/) lastCommonSep = i; } var out = ''; // Generate the relative path based on the path difference between `to` // and `from` for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) { if (i === fromEnd || from.charCodeAt(i) === 47/*/*/) { if (out.length === 0) out += '..'; else out += '/..'; } } // Lastly, append the rest of the destination (`to`) path that comes after // the common path parts if (out.length > 0) return out + to.slice(toStart + lastCommonSep); else { toStart += lastCommonSep; if (to.charCodeAt(toStart) === 47/*/*/) ++toStart; return to.slice(toStart); } }, _makeLong: function _makeLong(path) { return path; }, dirname: function dirname(path) { assertPath(path); if (path.length === 0) return '.'; var code = path.charCodeAt(0); var hasRoot = (code === 47/*/*/); var end = -1; var matchedSlash = true; for (var i = path.length - 1; i >= 1; --i) { code = path.charCodeAt(i); if (code === 47/*/*/) { if (!matchedSlash) { end = i; break; } } else { // We saw the first non-path separator matchedSlash = false; } } if (end === -1) return hasRoot ? '/' : '.'; if (hasRoot && end === 1) return '//'; return path.slice(0, end); }, basename: function basename(path, ext) { if (ext !== undefined && typeof ext !== 'string') throw new TypeError('"ext" argument must be a string'); assertPath(path); var start = 0; var end = -1; var matchedSlash = true; var i; if (ext !== undefined && ext.length > 0 && ext.length <= path.length) { if (ext.length === path.length && ext === path) return ''; var extIdx = ext.length - 1; var firstNonSlashEnd = -1; for (i = path.length - 1; i >= 0; --i) { var code = path.charCodeAt(i); if (code === 47/*/*/) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { start = i + 1; break; } } else { if (firstNonSlashEnd === -1) { // We saw the first non-path separator, remember this index in case // we need it if the extension ends up not matching matchedSlash = false; firstNonSlashEnd = i + 1; } if (extIdx >= 0) { // Try to match the explicit extension if (code === ext.charCodeAt(extIdx)) { if (--extIdx === -1) { // We matched the extension, so mark this as the end of our path // component end = i; } } else { // Extension does not match, so our result is the entire path // component extIdx = -1; end = firstNonSlashEnd; } } } } if (start === end) end = firstNonSlashEnd; else if (end === -1) end = path.length; return path.slice(start, end); } else { for (i = path.length - 1; i >= 0; --i) { if (path.charCodeAt(i) === 47/*/*/) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { start = i + 1; break; } } else if (end === -1) { // We saw the first non-path separator, mark this as the end of our // path component matchedSlash = false; end = i + 1; } } if (end === -1) return ''; return path.slice(start, end); } }, extname: function extname(path) { assertPath(path); var startDot = -1; var startPart = 0; var end = -1; var matchedSlash = true; // Track the state of characters (if any) we see before our first dot and // after any path separator we find var preDotState = 0; for (var i = path.length - 1; i >= 0; --i) { var code = path.charCodeAt(i); if (code === 47/*/*/) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { startPart = i + 1; break; } continue; } if (end === -1) { // We saw the first non-path separator, mark this as the end of our // extension matchedSlash = false; end = i + 1; } if (code === 46/*.*/) { // If this is our first dot, mark it as the start of our extension if (startDot === -1) startDot = i; else if (preDotState !== 1) preDotState = 1; } else if (startDot !== -1) { // We saw a non-dot and non-path separator before our dot, so we should // have a good chance at having a non-empty extension preDotState = -1; } } if (startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot preDotState === 0 || // The (right-most) trimmed path component is exactly '..' (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)) { return ''; } return path.slice(startDot, end); }, format: function format(pathObject) { if (pathObject === null || typeof pathObject !== 'object') { throw new TypeError( 'Parameter "pathObject" must be an object, not ' + typeof(pathObject) ); } return _format('/', pathObject); }, parse: function parse(path) { assertPath(path); var ret = { root: '', dir: '', base: '', ext: '', name: '' }; if (path.length === 0) return ret; var code = path.charCodeAt(0); var isAbsolute = (code === 47/*/*/); var start; if (isAbsolute) { ret.root = '/'; start = 1; } else { start = 0; } var startDot = -1; var startPart = 0; var end = -1; var matchedSlash = true; var i = path.length - 1; // Track the state of characters (if any) we see before our first dot and // after any path separator we find var preDotState = 0; // Get non-dir info for (; i >= start; --i) { code = path.charCodeAt(i); if (code === 47/*/*/) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { startPart = i + 1; break; } continue; } if (end === -1) { // We saw the first non-path separator, mark this as the end of our // extension matchedSlash = false; end = i + 1; } if (code === 46/*.*/) { // If this is our first dot, mark it as the start of our extension if (startDot === -1) startDot = i; else if (preDotState !== 1) preDotState = 1; } else if (startDot !== -1) { // We saw a non-dot and non-path separator before our dot, so we should // have a good chance at having a non-empty extension preDotState = -1; } } if (startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot preDotState === 0 || // The (right-most) trimmed path component is exactly '..' (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)) { if (end !== -1) { if (startPart === 0 && isAbsolute) ret.base = ret.name = path.slice(1, end); else ret.base = ret.name = path.slice(startPart, end); } } else { if (startPart === 0 && isAbsolute) { ret.name = path.slice(1, startDot); ret.base = path.slice(1, end); } else { ret.name = path.slice(startPart, startDot); ret.base = path.slice(startPart, end); } ret.ext = path.slice(startDot, end); } if (startPart > 0) ret.dir = path.slice(0, startPart - 1); else if (isAbsolute) ret.dir = '/'; return ret; }, sep: '/', delimiter: ':', posix: null }; module.exports = posix; /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.replaceBase = replaceBase; exports.replaceCanonical = replaceCanonical; exports.replaceMeta = replaceMeta; exports.replaceLinks = replaceLinks; exports.substitute = substitute; var _core = __webpack_require__(0); var _url = __webpack_require__(5); var _url2 = _interopRequireDefault(_url); var _path = __webpack_require__(4); var _path2 = _interopRequireDefault(_path); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function replaceBase(doc, section) { var base; var head; var url = section.url; var absolute = url.indexOf("://") > -1; if (!doc) { return; } head = (0, _core.qs)(doc, "head"); base = (0, _core.qs)(head, "base"); if (!base) { base = doc.createElement("base"); head.insertBefore(base, head.firstChild); } // Fix for Safari crashing if the url doesn't have an origin if (!absolute && window && window.location) { url = window.location.origin + url; } base.setAttribute("href", url); } function replaceCanonical(doc, section) { var head; var link; var url = section.canonical; if (!doc) { return; } head = (0, _core.qs)(doc, "head"); link = (0, _core.qs)(head, "link[rel='canonical']"); if (link) { link.setAttribute("href", url); } else { link = doc.createElement("link"); link.setAttribute("rel", "canonical"); link.setAttribute("href", url); head.appendChild(link); } } function replaceMeta(doc, section) { var head; var meta; var id = section.idref; if (!doc) { return; } head = (0, _core.qs)(doc, "head"); meta = (0, _core.qs)(head, "link[property='dc.identifier']"); if (meta) { meta.setAttribute("content", id); } else { meta = doc.createElement("meta"); meta.setAttribute("name", "dc.identifier"); meta.setAttribute("content", id); head.appendChild(meta); } } // TODO: move me to Contents function replaceLinks(contents, fn) { var links = contents.querySelectorAll("a[href]"); if (!links.length) { return; } var base = (0, _core.qs)(contents.ownerDocument, "base"); var location = base ? base.getAttribute("href") : undefined; var replaceLink = function (link) { var href = link.getAttribute("href"); if (href.indexOf("mailto:") === 0) { return; } var absolute = href.indexOf("://") > -1; var linkUrl = new _url2.default(href, location); if (absolute) { link.setAttribute("target", "_blank"); } else { link.onclick = function () { if (linkUrl && linkUrl.hash) { fn(linkUrl.Path.path + linkUrl.hash); } else if (linkUrl) { fn(linkUrl.Path.path); } else { fn(href); } return false; }; } }.bind(this); for (var i = 0; i < links.length; i++) { replaceLink(links[i]); } } function substitute(content, urls, replacements) { urls.forEach(function (url, i) { if (url && replacements[i]) { content = content.replace(new RegExp(url, "g"), replacements[i]); } }); return content; } /***/ }), /* 8 */ /***/ (function(module, exports) { var g; // This works in non-strict mode g = (function() { return this; })(); try { // This works if eval is allowed (see CSP) g = g || Function("return this")() || (1,eval)("this"); } catch(e) { // This works if the window reference is available if(typeof window === "object") g = window; } // g can still be undefined, but nothing to do about it... // We return undefined, instead of nothing here, so it's // easier to handle this case. if(!global) { ...} module.exports = g; /***/ }), /* 9 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var _undefined = __webpack_require__(34)(); // Support ES3 engines module.exports = function (val) { return (val !== _undefined) && (val !== null); }; /***/ }), /* 10 */ /***/ (function(module, exports, __webpack_require__) { "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; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** * Hooks allow for injecting functions that must all complete in order before finishing * They will execute in parallel but all must finish before continuing * Functions may return a promise if they are asycn. * @param {any} context scope of this * @example this.content = new EPUBJS.Hook(this); */ var Hook = function () { function Hook(context) { _classCallCheck(this, Hook); this.context = context || this; this.hooks = []; } /** * Adds a function to be run before a hook completes * @example this.content.register(function(){...}); */ _createClass(Hook, [{ key: "register", value: function register() { for (var i = 0; i < arguments.length; ++i) { if (typeof arguments[i] === "function") { this.hooks.push(arguments[i]); } else { // unpack array for (var j = 0; j < arguments[i].length; ++j) { this.hooks.push(arguments[i][j]); } } } } /** * Triggers a hook to run all functions * @example this.content.trigger(args).then(function(){...}); */ }, { key: "trigger", value: function trigger() { var args = arguments; var context = this.context; var promises = []; this.hooks.forEach(function (task) { var executing = task.apply(context, args); if (executing && typeof executing["then"] === "function") { // Task is a function that returns a promise promises.push(executing); } // Otherwise Task resolves immediately, continue }); return Promise.all(promises); } // Adds a function to be run before a hook completes }, { key: "list", value: function list() { return this.hooks; } }, { key: "clear", value: function clear() { return this.hooks = []; } }]); return Hook; }(); exports.default = Hook; module.exports = exports["default"]; /***/ }), /* 11 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _core = __webpack_require__(0); var _path = __webpack_require__(4); var _path2 = _interopRequireDefault(_path); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function request(url, type, withCredentials, headers) { var supportsURL = typeof window != "undefined" ? window.URL : false; // TODO: fallback for url if window isn't defined var BLOB_RESPONSE = supportsURL ? "blob" : "arraybuffer"; var deferred = new _core.defer(); var xhr = new XMLHttpRequest(); //-- Check from PDF.js: // https://github.com/mozilla/pdf.js/blob/master/web/compatibility.js var xhrPrototype = XMLHttpRequest.prototype; var header; if (!("overrideMimeType" in xhrPrototype)) { // IE10 might have response, but not overrideMimeType Object.defineProperty(xhrPrototype, "overrideMimeType", { value: function xmlHttpRequestOverrideMimeType() {} }); } if (withCredentials) { xhr.withCredentials = true; } xhr.onreadystatechange = handler; xhr.onerror = err; xhr.open("GET", url, true); for (header in headers) { xhr.setRequestHeader(header, headers[header]); } if (type == "json") { xhr.setRequestHeader("Accept", "application/json"); } // If type isn"t set, determine it from the file extension if (!type) { type = new _path2.default(url).extension; } if (type == "blob") { xhr.responseType = BLOB_RESPONSE; } if ((0, _core.isXml)(type)) { // xhr.responseType = "document"; xhr.overrideMimeType("text/xml"); // for OPF parsing } if (type == "xhtml") { // xhr.responseType = "document"; } if (type == "html" || type == "htm") { // xhr.responseType = "document"; } if (type == "binary") { xhr.responseType = "arraybuffer"; } xhr.send(); function err(e) { deferred.reject(e); } function handler() { if (this.readyState === XMLHttpRequest.DONE) { var responseXML = false; if (this.responseType === "" || this.responseType === "document") { responseXML = this.responseXML; } if (this.status === 200 || this.status === 0 || responseXML) { //-- Firefox is reporting 0 for blob urls var r; if (!this.response && !responseXML) { deferred.reject({ status: this.status, message: "Empty Response", stack: new Error().stack }); return deferred.promise; } if (this.status === 403) { deferred.reject({ status: this.status, response: this.response, message: "Forbidden", stack: new Error().stack }); return deferred.promise; } if (responseXML) { r = this.responseXML; } else if ((0, _core.isXml)(type)) { // xhr.overrideMimeType("text/xml"); // for OPF parsing // If this.responseXML wasn't set, try to parse using a DOMParser from text r = (0, _core.parse)(this.response, "text/xml"); } else if (type == "xhtml") { r = (0, _core.parse)(this.response, "application/xhtml+xml"); } else if (type == "html" || type == "htm") { r = (0, _core.parse)(this.response, "text/html"); } else if (type == "json") { r = JSON.parse(this.response); } else if (type == "blob") { if (supportsURL) { r = this.response; } else { //-- Safari doesn't support responseType blob, so create a blob from arraybuffer r = new Blob([this.response]); } } else { r = this.response; } deferred.resolve(r); } else { deferred.reject({ status: this.status, message: this.response, stack: new Error().stack }); } } } return deferred.promise; } exports.default = request; module.exports = exports["default"]; /***/ }), /* 12 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Task = undefined; 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 _core = __webpack_require__(0); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** * Queue for handling tasks one at a time * @class * @param {scope} context what this will resolve to in the tasks */ var Queue = function () { function Queue(context) { _classCallCheck(this, Queue); this._q = []; this.context = context; this.tick = _core.requestAnimationFrame; this.running = false; this.paused = false; } /** * Add an item to the queue * @return {Promise} */ _createClass(Queue, [{ key: "enqueue", value: function enqueue() { var deferred, promise; var queued; var task = [].shift.call(arguments); var args = arguments; // Handle single args without context // if(args && !Array.isArray(args)) { // args = [args]; // } if (!task) { throw new Error("No Task Provided"); } if (typeof task === "function") { deferred = new _core.defer(); promise = deferred.promise; queued = { "task": task, "args": args, //"context" : context, "deferred": deferred, "promise": promise }; } else { // Task is a promise queued = { "promise": task }; } this._q.push(queued); // Wait to start queue flush 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; } /** * Run one item * @return {Promise} */ }, { key: "dequeue", value: function dequeue() { var inwait, task, result; if (this._q.length && !this.paused) { inwait = this._q.shift(); task = inwait.task; if (task) { // console.log(task) result = task.apply(this.context, inwait.args); if (result && typeof result["then"] === "function") { // Task is a function that returns a promise return result.then(function () { inwait.deferred.resolve.apply(this.context, arguments); }.bind(this), function () { inwait.deferred.reject.apply(this.context, arguments); }.bind(this)); } else { // Task resolves immediately inwait.deferred.resolve.apply(this.context, result); return inwait.promise; } } else if (inwait.promise) { // Task is a promise return inwait.promise; } } else { inwait = new _core.defer(); inwait.deferred.resolve(); return inwait.promise; } } // Run All Immediately }, { key: "dump", value: function dump() { while (this._q.length) { this.dequeue(); } } /** * Run all tasks sequentially, at convince * @return {Promise} */ }, { key: "run", value: function run() { var _this = this; if (!this.running) { this.running = true; this.defered = new _core.defer(); } this.tick.call(window, function () { if (_this._q.length) { _this.dequeue().then(function () { this.run(); }.bind(_this)); } else { _this.defered.resolve(); _this.running = undefined; } }); // Unpause if (this.paused == true) { this.paused = false; } return this.defered.promise; } /** * Flush all, as quickly as possible * @return {Promise} */ }, { key: "flush", value: function flush() { if (this.running) { return this.running; } if (this._q.length) { this.running = this.dequeue().then(function () { this.running = undefined; return this.flush(); }.bind(this)); return this.running; } } /** * Clear all items in wait */ }, { key: "clear", value: function clear() { this._q = []; } /** * Get the number of tasks in the queue * @return {number} tasks */ }, { key: "length", value: function length() { return this._q.length; } /** * Pause a running queue */ }, { key: "pause", value: function pause() { this.paused = true; } /** * End the queue */ }, { key: "stop", value: function stop() { this._q = []; this.running = false; this.paused = true; } }]); return Queue; }(); /** * Create a new task from a callback * @class * @private * @param {function} task * @param {array} args * @param {scope} context * @return {function} task */ var Task = function Task(task, args, context) { _classCallCheck(this, Task); return function () { var _this2 = this; var toApply = arguments || []; return new Promise(function (resolve, reject) { var callback = function callback(value, err) { if (!value && err) { reject(err); } else { resolve(value); } }; // Add the callback to the arguments list toApply.push(callback); // Apply all arguments to the functions task.apply(context || _this2, toApply); }); }; }; exports.default = Queue; exports.Task = Task; /***/ }), /* 13 */ /***/ (function(module, exports, __webpack_require__) { "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 _eventEmitter = __webpack_require__(3); var _eventEmitter2 = _interopRequireDefault(_eventEmitter); var _core = __webpack_require__(0); var _epubcfi = __webpack_require__(1); var _epubcfi2 = _interopRequireDefault(_epubcfi); var _mapping = __webpack_require__(19); var _mapping2 = _interopRequireDefault(_mapping); var _replacements = __webpack_require__(7); var _constants = __webpack_require__(2); 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"); } } var hasNavigator = typeof navigator !== "undefined"; var isChrome = hasNavigator && /Chrome/.test(navigator.userAgent); var isWebkit = hasNavigator && !isChrome && /AppleWebKit/.test(navigator.userAgent); var ELEMENT_NODE = 1; var TEXT_NODE = 3; /** * Handles DOM manipulation, queries and events for View contents * @class * @param {document} doc Document * @param {element} content Parent Element (typically Body) * @param {string} cfiBase Section component of CFIs * @param {number} sectionIndex Index in Spine of Conntent's Section */ var Contents = function () { function Contents(doc, content, cfiBase, sectionIndex) { _classCallCheck(this, Contents); // Blank Cfi for Parsing this.epubcfi = new _epubcfi2.default(); this.document = doc; this.documentElement = this.document.documentElement; this.content = content || this.document.body; this.window = this.document.defaultView; this._size = { width: 0, height: 0 }; this.sectionIndex = sectionIndex || 0; this.cfiBase = cfiBase || ""; this.epubReadingSystem("epub.js", _constants.EPUBJS_VERSION); this.listeners(); } /** * Get DOM events that are listened for and passed along */ _createClass(Contents, [{ key: "width", /** * Get or Set width * @param {number} [w] * @returns {number} width */ value: function width(w) { // var frame = this.documentElement; var frame = this.content; if (w && (0, _core.isNumber)(w)) { w = w + "px"; } if (w) { frame.style.width = w; // this.content.style.width = w; } return this.window.getComputedStyle(frame)["width"]; } /** * Get or Set height * @param {number} [h] * @returns {number} height */ }, { key: "height", value: function height(h) { // var frame = this.documentElement; var frame = this.content; if (h && (0, _core.isNumber)(h)) { h = h + "px"; } if (h) { frame.style.height = h; // this.content.style.height = h; } return this.window.getComputedStyle(frame)["height"]; } /** * Get or Set width of the contents * @param {number} [w] * @returns {number} width */ }, { key: "contentWidth", value: function contentWidth(w) { var content = this.content || this.document.body; if (w && (0, _core.isNumber)(w)) { w = w + "px"; } if (w) { content.style.width = w; } return this.window.getComputedStyle(content)["width"]; } /** * Get or Set height of the contents * @param {number} [h] * @returns {number} height */ }, { key: "contentHeight", value: function contentHeight(h) { var content = this.content || this.document.body; if (h && (0, _core.isNumber)(h)) { h = h + "px"; } if (h) { content.style.height = h; } return this.window.getComputedStyle(content)["height"]; } /** * Get the width of the text using Range * @returns {number} width */ }, { key: "textWidth", value: function textWidth() { var rect = void 0; var width = void 0; var range = this.document.createRange(); var content = this.content || this.document.body; var border = (0, _core.borders)(content); // Select the contents of frame range.selectNodeContents(content); // get the width of the text content rect = range.getBoundingClientRect(); width = rect.width; if (border && border.width) { width += border.width; } return Math.round(width); } /** * Get the height of the text using Range * @returns {number} height */ }, { key: "textHeight", value: function textHeight() { var rect = void 0; var height = void 0; var range = this.document.createRange(); var content = this.content || this.document.body; var border = (0, _core.borders)(content); range.selectNodeContents(content); rect = range.getBoundingClientRect(); height = rect.height; if (height && border.height) { height += border.height; } return Math.round(height); } /** * Get documentElement scrollWidth * @returns {number} width */ }, { key: "scrollWidth", value: function scrollWidth() { var width = this.documentElement.scrollWidth; return width; } /** * Get documentElement scrollHeight * @returns {number} height */ }, { key: "scrollHeight", value: function scrollHeight() { var height = this.documentElement.scrollHeight; return height; } /** * Set overflow css style of the contents * @param {string} [overflow] */ }, { key: "overflow", value: function overflow(_overflow) { if (_overflow) { this.documentElement.style.overflow = _overflow; } return this.window.getComputedStyle(this.documentElement)["overflow"]; } /** * Set overflowX css style of the documentElement * @param {string} [overflow] */ }, { key: "overflowX", value: function overflowX(overflow) { if (overflow) { this.documentElement.style.overflowX = overflow; } return this.window.getComputedStyle(this.documentElement)["overflowX"]; } /** * Set overflowY css style of the documentElement * @param {string} [overflow] */ }, { key: "overflowY", value: function overflowY(overflow) { if (overflow) { this.documentElement.style.overflowY = overflow; } return this.window.getComputedStyle(this.documentElement)["overflowY"]; } /** * Set Css styles on the contents element (typically Body) * @param {string} property * @param {string} value * @param {boolean} [priority] set as "important" */ }, { key: "css", value: function css(property, value, priority) { var content = this.content || this.document.body; if (value) { content.style.setProperty(property, value, priority ? "important" : ""); } return this.window.getComputedStyle(content)[property]; } /** * Get or Set the viewport element * @param {object} [options] * @param {string} [options.width] * @param {string} [options.height] * @param {string} [options.scale] * @param {string} [options.minimum] * @param {string} [options.maximum] * @param {string} [options.scalable] */ }, { key: "viewport", value: function viewport(options) { var _width, _height, _scale, _minimum, _maximum, _scalable; // var width, height, scale, minimum, maximum, scalable; var $viewport = this.document.querySelector("meta[name='viewport']"); var parsed = { "width": undefined, "height": undefined, "scale": undefined, "minimum": undefined, "maximum": undefined, "scalable": undefined }; var newContent = []; var settings = {}; /* * check for the viewport size * */ if ($viewport && $viewport.hasAttribute("content")) { var content = $viewport.getAttribute("content"); var _width2 = content.match(/width\s*=\s*([^,]*)/); var _height2 = content.match(/height\s*=\s*([^,]*)/); var _scale2 = content.match(/initial-scale\s*=\s*([^,]*)/); var _minimum2 = content.match(/minimum-scale\s*=\s*([^,]*)/); var _maximum2 = content.match(/maximum-scale\s*=\s*([^,]*)/); var _scalable2 = content.match(/user-scalable\s*=\s*([^,]*)/); if (_width2 && _width2.length && typeof _width2[1] !== "undefined") { parsed.width = _width2[1]; } if (_height2 && _height2.length && typeof _height2[1] !== "undefined") { parsed.height = _height2[1]; } if (_scale2 && _scale2.length && typeof _scale2[1] !== "undefined") { parsed.scale = _scale2[1]; } if (_minimum2 && _minimum2.length && typeof _minimum2[1] !== "undefined") { parsed.minimum = _minimum2[1]; } if (_maximum2 && _maximum2.length && typeof _maximum2[1] !== "undefined") { parsed.maximum = _maximum2[1]; } if (_scalable2 && _scalable2.length && typeof _scalable2[1] !== "undefined") { parsed.scalable = _scalable2[1]; } } settings = (0, _core.defaults)(options || {}, parsed); if (options) { if (settings.width) { newContent.push("width=" + settings.width); } if (settings.height) { newContent.push("height=" + settings.height); } if (settings.scale) { newContent.push("initial-scale=" + settings.scale); } if (settings.scalable === "no") { newContent.push("minimum-scale=" + settings.scale); newContent.push("maximum-scale=" + settings.scale); newContent.push("user-scalable=" + settings.scalable); } else { if (settings.scalable) { newContent.push("user-scalable=" + settings.scalable); } if (settings.minimum) { newContent.push("minimum-scale=" + settings.minimum); } if (settings.maximum) { newContent.push("minimum-scale=" + settings.maximum); } } if (!$viewport) { $viewport = this.document.createElement("meta"); $viewport.setAttribute("name", "viewport"); this.document.querySelector("head").appendChild($viewport); } $viewport.setAttribute("content", newContent.join(", ")); this.window.scrollTo(0, 0); } return settings; } /** * Event emitter for when the contents has expanded * @private */ }, { key: "expand", value: function expand() { this.emit(_constants.EVENTS.CONTENTS.EXPAND); } /** * Add DOM listeners * @private */ }, { key: "listeners", value: function listeners() { this.imageLoadListeners(); this.mediaQueryListeners(); // this.fontLoadListeners(); this.addEventListeners(); this.addSelectionListeners(); // this.transitionListeners(); this.resizeListeners(); // this.resizeObservers(); this.linksHandler(); } /** * Remove DOM listeners * @private */ }, { key: "removeListeners", value: function removeListeners() { this.removeEventListeners(); this.removeSelectionListeners(); clearTimeout(this.expanding); } /** * Check if size of contents has changed and * emit 'resize' event if it has. * @private */ }, { key: "resizeCheck", value: function resizeCheck() { var width = this.textWidth(); var height = this.textHeight(); if (width != this._size.width || height != this._size.height) { this._size = { width: width, height: height }; this.onResize && this.onResize(this._size); this.emit(_constants.EVENTS.CONTENTS.RESIZE, this._size); } } /** * Poll for resize detection * @private */ }, { key: "resizeListeners", value: function resizeListeners() { var width, height; // Test size again clearTimeout(this.expanding); requestAnimationFrame(this.resizeCheck.bind(this)); this.expanding = setTimeout(this.resizeListeners.bind(this), 350); } /** * Use css transitions to detect resize * @private */ }, { key: "transitionListeners", value: function transitionListeners() { var body = this.content; body.style['transitionProperty'] = "font, font-size, font-size-adjust, font-stretch, font-variation-settings, font-weight, width, height"; body.style['transitionDuration'] = "0.001ms"; body.style['transitionTimingFunction'] = "linear"; body.style['transitionDelay'] = "0"; this.document.addEventListener('transitionend', this.resizeCheck.bind(this)); } /** * Listen for media query changes and emit 'expand' event * Adapted from: https://github.com/tylergaw/media-query-events/blob/master/js/mq-events.js * @private */ }, { key: "mediaQueryListeners", value: function mediaQueryListeners() { var sheets = this.document.styleSheets; var mediaChangeHandler = function (m) { if (m.matches && !this._expanding) { setTimeout(this.expand.bind(this), 1); } }.bind(this); for (var i = 0; i < sheets.length; i += 1) { var rules; // Firefox errors if we access cssRules cross-domain try { rules = sheets[i].cssRules; } catch (e) { return; } if (!rules) return; // Stylesheets changed for (var j = 0; j < rules.length; j += 1) { //if (rules[j].constructor === CSSMediaRule) { if (rules[j].media) { var mql = this.window.matchMedia(rules[j].media.mediaText); mql.addListener(mediaChangeHandler); //mql.onchange = mediaChangeHandler; } } } } /** * Use MutationObserver to listen for changes in the DOM and check for resize * @private */ }, { key: "resizeObservers", value: function resizeObservers() { var _this = this; // create an observer instance this.observer = new MutationObserver(function (mutations) { _this.resizeCheck(); }); // configuration of the observer: var config = { attributes: true, childList: true, characterData: true, subtree: true }; // pass in the target node, as well as the observer options this.observer.observe(this.document, config); } /** * Test if images are loaded or add listener for when they load * @private */ }, { key: "imageLoadListeners", value: function imageLoadListeners() { var images = this.document.querySelectorAll("img"); var img; for (var i = 0; i < images.length; i++) { img = images[i]; if (typeof img.naturalWidth !== "undefined" && img.naturalWidth === 0) { img.onload = this.expand.bind(this); } } } /** * Listen for font load and check for resize when loaded * @private */ }, { key: "fontLoadListeners", value: function fontLoadListeners() { if (!this.document || !this.document.fonts) { return; } this.document.fonts.ready.then(function () { this.resizeCheck(); }.bind(this)); } /** * Get the documentElement * @returns {element} documentElement */ }, { key: "root", value: function root() { if (!this.document) return null; return this.document.documentElement; } /** * Get the location offset of a EpubCFI or an #id * @param {string | EpubCFI} target * @param {string} [ignoreClass] for the cfi * @returns { {left: Number, top: Number } */ }, { key: "locationOf", value: function locationOf(target, ignoreClass) { var position; var targetPos = { "left": 0, "top": 0 }; if (!this.document) return targetPos; if (this.epubcfi.isCfiString(target)) { var range = new _epubcfi2.default(target).toRange(this.document, ignoreClass); if (range) { if (range.startContainer.nodeType === Node.ELEMENT_NODE) { position = range.startContainer.getBoundingClientRect(); targetPos.left = position.left; targetPos.top = position.top; } else { // Webkit does not handle collapsed range bounds correctly // https://bugs.webkit.org/show_bug.cgi?id=138949 // Construct a new non-collapsed range if (isWebkit) { var container = range.startContainer; var newRange = new Range(); try { if (container.nodeType === ELEMENT_NODE) { position = container.getBoundingClientRect(); } else if (range.startOffset + 2 < container.length) { newRange.setStart(container, range.startOffset); newRange.setEnd(container, range.startOffset + 2); position = newRange.getBoundingClientRect(); } else if (range.startOffset - 2 > 0) { newRange.setStart(container, range.startOffset - 2); newRange.setEnd(container, range.startOffset); position = newRange.getBoundingClientRect(); } else { // empty, return the parent element position = container.parentNode.getBoundingClientRect(); } } catch (e) { console.error(e, e.stack); } } else { position = range.getBoundingClientRect(); } } } } else if (typeof target === "string" && target.indexOf("#") > -1) { var id = target.substring(target.indexOf("#") + 1); var el = this.document.getElementById(id); if (el) { position = el.getBoundingClientRect(); } } if (position) { targetPos.left = position.left; targetPos.top = position.top; } return targetPos; } /** * Append a stylesheet link to the document head * @param {string} src url */ }, { key: "addStylesheet", value: function addStylesheet(src) { return new Promise(function (resolve, reject) { var $stylesheet; var ready = false; if (!this.document) { resolve(false); return; } // Check if link already exists $stylesheet = this.document.querySelector("link[href='" + src + "']"); if ($stylesheet) { resolve(true); return; // already present } $stylesheet = this.document.createElement("link"); $stylesheet.type = "text/css"; $stylesheet.rel = "stylesheet"; $stylesheet.href = src; $stylesheet.onload = $stylesheet.onreadystatechange = function () { if (!ready && (!this.readyState || this.readyState == "complete")) { ready = true; // Let apply setTimeout(function () { resolve(true); }, 1); } }; this.document.head.appendChild($stylesheet); }.bind(this)); } /** * Append stylesheet rules to a generate stylesheet * Array: https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/insertRule * Object: https://github.com/desirable-objects/json-to-css * @param {array | object} rules */ }, { key: "addStylesheetRules", value: function addStylesheetRules(rules) { var styleEl; var styleSheet; var key = "epubjs-inserted-css"; if (!this.document || !rules || rules.length === 0) return; // Check if link already exists styleEl = this.document.getElementById("#" + key); if (!styleEl) { styleEl = this.document.createElement("style"); styleEl.id = key; } // Append style element to head this.document.head.appendChild(styleEl); // Grab style sheet styleSheet = styleEl.sheet; if (Object.prototype.toString.call(rules) === "[object Array]") { for (var i = 0, rl = rules.length; i < rl; i++) { var j = 1, rule = rules[i], selector = rules[i][0], propStr = ""; // If the second argument of a rule is an array of arrays, correct our variables. if (Object.prototype.toString.call(rule[1][0]) === "[object Array]") { rule = rule[1]; j = 0; } for (var pl = rule.length; j < pl; j++) { var prop = rule[j]; propStr += prop[0] + ":" + prop[1] + (prop[2] ? " !important" : "") + ";\n"; } // Insert CSS Rule styleSheet.insertRule(selector + "{" + propStr + "}", styleSheet.cssRules.length); } } else { var selectors = Object.keys(rules); selectors.forEach(function (selector) { var definition = rules[selector]; if (Array.isArray(definition)) { definition.forEach(function (item) { var _rules = Object.keys(item); var result = _rules.map(function (rule) { return rule + ":" + item[rule]; }).join(';'); styleSheet.insertRule(selector + "{" + result + "}", styleSheet.cssRules.length); }); } else { var _rules = Object.keys(definition); var result = _rules.map(function (rule) { return rule + ":" + definition[rule]; }).join(';'); styleSheet.insertRule(selector + "{" + result + "}", styleSheet.cssRules.length); } }); } } /** * Append a script tag to the document head * @param {string} src url * @returns {Promise} loaded */ }, { key: "addScript", value: function addScript(src) { return new Promise(function (resolve, reject) { var $script; var ready = false; if (!this.document) { resolve(false); return; } $script = this.document.createElement("script"); $script.type = "text/javascript"; $script.async = true; $script.src = src; $script.onload = $script.onreadystatechange = function () { if (!ready && (!this.readyState || this.readyState == "complete")) { ready = true; setTimeout(function () { resolve(true); }, 1); } }; this.document.head.appendChild($script); }.bind(this)); } /** * Add a class to the contents container * @param {string} className */ }, { key: "addClass", value: function addClass(className) { var content; if (!this.document) return; content = this.content || this.document.body; if (content) { content.classList.add(className); } } /** * Remove a class from the contents container * @param {string} removeClass */ }, { key: "removeClass", value: function removeClass(className) { var content; if (!this.document) return; content = this.content || this.document.body; if (content) { content.classList.remove(className); } } /** * Add DOM event listeners * @private */ }, { key: "addEventListeners", value: function addEventListeners() { if (!this.document) { return; } _constants.DOM_EVENTS.forEach(function (eventName) { this.document.addEventListener(eventName, this.triggerEvent.bind(this), false); }, this); } /** * Remove DOM event listeners * @private */ }, { key: "removeEventListeners", value: function removeEventListeners() { if (!this.document) { return; } _constants.DOM_EVENTS.forEach(function (eventName) { this.document.removeEventListener(eventName, this.triggerEvent, false); }, this); } /** * Emit passed browser events * @private */ }, { key: "triggerEvent", value: function triggerEvent(e) { this.emit(e.type, e); } /** * Add listener for text selection * @private */ }, { key: "addSelectionListeners", value: function addSelectionListeners() { if (!this.document) { return; } this.document.addEventListener("selectionchange", this.onSelectionChange.bind(this), false); } /** * Remove listener for text selection * @private */ }, { key: "removeSelectionListeners", value: function removeSelectionListeners() { if (!this.document) { return; } this.document.removeEventListener("selectionchange", this.onSelectionChange, false); } /** * Handle getting text on selection * @private */ }, { key: "onSelectionChange", value: function onSelectionChange(e) { if (this.selectionEndTimeout) { clearTimeout(this.selectionEndTimeout); } this.selectionEndTimeout = setTimeout(function () { var selection = this.window.getSelection(); this.triggerSelectedEvent(selection); }.bind(this), 250); } /** * Emit event on text selection * @private */ }, { key: "triggerSelectedEvent", value: function triggerSelectedEvent(selection) { var range, cfirange; if (selection && selection.rangeCount > 0) { range = selection.getRangeAt(0); if (!range.collapsed) { // cfirange = this.section.cfiFromRange(range); cfirange = new _epubcfi2.default(range, this.cfiBase).toString(); this.emit(_constants.EVENTS.CONTENTS.SELECTED, cfirange); this.emit(_constants.EVENTS.CONTENTS.SELECTED_RANGE, range); } } } /** * Get a Dom Range from EpubCFI * @param {EpubCFI} _cfi * @param {string} [ignoreClass] * @returns {Range} range */ }, { key: "range", value: function range(_cfi, ignoreClass) { var cfi = new _epubcfi2.default(_cfi); return cfi.toRange(this.document, ignoreClass); } /** * Get an EpubCFI from a Dom Range * @param {Range} range * @param {string} [ignoreClass] * @returns {EpubCFI} cfi */ }, { key: "cfiFromRange", value: function cfiFromRange(range, ignoreClass) { return new _epubcfi2.default(range, this.cfiBase, ignoreClass).toString(); } /** * Get an EpubCFI from a Dom node * @param {node} node * @param {string} [ignoreClass] * @returns {EpubCFI} cfi */ }, { key: "cfiFromNode", value: function cfiFromNode(node, ignoreClass) { return new _epubcfi2.default(node, this.cfiBase, ignoreClass).toString(); } // TODO: find where this is used - remove? }, { key: "map", value: function map(layout) { var map = new _mapping2.default(layout); return map.section(); } /** * Size the contents to a given width and height * @param {number} [width] * @param {number} [height] */ }, { key: "size", value: function size(width, height) { var viewport = { scale: 1.0, scalable: "no" }; this.layoutStyle("scrolling"); if (width >= 0) { this.width(width); viewport.width = width; this.css("padding", "0 " + width / 12 + "px"); } if (height >= 0) { this.height(height); viewport.height = height; } this.css("margin", "0"); this.css("box-sizing", "border-box"); this.viewport(viewport); } /** * Apply columns to the contents for pagination * @param {number} width * @param {number} height * @param {number} columnWidth * @param {number} gap */ }, { key: "columns", value: function columns(width, height, columnWidth, gap) { var COLUMN_AXIS = (0, _core.prefixed)("column-axis"); var COLUMN_GAP = (0, _core.prefixed)("column-gap"); var COLUMN_WIDTH = (0, _core.prefixed)("column-width"); var COLUMN_FILL = (0, _core.prefixed)("column-fill"); var writingMode = this.writingMode(); var axis = writingMode.indexOf("vertical") === 0 ? "vertical" : "horizontal"; this.layoutStyle("paginated"); // Fix body width issues if rtl is only set on body element if (this.content.dir === "rtl") { this.direction("rtl"); } this.width(width); this.height(height); // Deal with Mobile trying to scale to viewport this.viewport({ width: width, height: height, scale: 1.0, scalable: "no" }); // TODO: inline-block needs more testing // Fixes Safari column cut offs, but causes RTL issues // this.css("display", "inline-block"); this.css("overflow-y", "hidden"); this.css("margin", "0", true); if (axis === "vertical") { this.css("padding-top", gap / 2 + "px", true); this.css("padding-bottom", gap / 2 + "px", true); this.css("padding-left", "20px"); this.css("padding-right", "20px"); } else { this.css("padding-top", "20px"); this.css("padding-bottom", "20px"); this.css("padding-left", gap / 2 + "px", true); this.css("padding-right", gap / 2 + "px", true); } this.css("box-sizing", "border-box"); this.css("max-width", "inherit"); this.css(COLUMN_AXIS, "horizontal"); this.css(COLUMN_FILL, "auto"); this.css(COLUMN_GAP, gap + "px"); this.css(COLUMN_WIDTH, columnWidth + "px"); } /** * Scale contents from center * @param {number} scale * @param {number} offsetX * @param {number} offsetY */ }, { key: "scaler", value: function scaler(scale, offsetX, offsetY) { var scaleStr = "scale(" + scale + ")"; var translateStr = ""; // this.css("position", "absolute")); this.css("transform-origin", "top left"); if (offsetX >= 0 || offsetY >= 0) { translateStr = " translate(" + (offsetX || 0) + "px, " + (offsetY || 0) + "px )"; } this.css("transform", scaleStr + translateStr); } /** * Fit contents into a fixed width and height * @param {number} width * @param {number} height */ }, { key: "fit", value: function fit(width, height) { var viewport = this.viewport(); var widthScale = width / parseInt(viewport.width); var heightScale = height / parseInt(viewport.height); var scale = widthScale < heightScale ? widthScale : heightScale; var offsetY = (height - viewport.height * scale) / 2; this.layoutStyle("paginated"); this.width(width); this.height(height); this.overflow("hidden"); // Scale to the correct size this.scaler(scale, 0, offsetY); this.css("background-color", "transparent"); } /** * Set the direction of the text * @param {string} [dir="ltr"] "rtl" | "ltr" */ }, { key: "direction", value: function direction(dir) { if (this.documentElement) { this.documentElement.style["direction"] = dir; } } }, { key: "mapPage", value: function mapPage(cfiBase, layout, start, end, dev) { var mapping = new _mapping2.default(layout, dev); return mapping.page(this, cfiBase, start, end); } /** * Emit event when link in content is clicked * @private */ }, { key: "linksHandler", value: function linksHandler() { var _this2 = this; (0, _replacements.replaceLinks)(this.content, function (href) { _this2.emit(_constants.EVENTS.CONTENTS.LINK_CLICKED, href); }); } /** * Set the writingMode of the text * @param {string} [mode="horizontal-tb"] "horizontal-tb" | "vertical-rl" | "vertical-lr" */ }, { key: "writingMode", value: function writingMode(mode) { var WRITING_MODE = (0, _core.prefixed)("writing-mode"); if (mode && this.documentElement) { this.documentElement.style[WRITING_MODE] = mode; } return this.window.getComputedStyle(this.documentElement)[WRITING_MODE] || ''; } /** * Set the layoutStyle of the content * @param {string} [style="paginated"] "scrolling" | "paginated" * @private */ }, { key: "layoutStyle", value: function layoutStyle(style) { if (style) { this._layoutStyle = style; navigator.epubReadingSystem.layoutStyle = this._layoutStyle; } return this._layoutStyle || "paginated"; } /** * Add the epubReadingSystem object to the navigator * @param {string} name * @param {string} version * @private */ }, { key: "epubReadingSystem", value: function epubReadingSystem(name, version) { navigator.epubReadingSystem = { name: name, version: version, layoutStyle: this.layoutStyle(), hasFeature: function hasFeature(feature) { switch (feature) { case "dom-manipulation": return true; case "layout-changes": return true; case "touch-events": return true; case "mouse-events": return true; case "keyboard-events": return true; case "spine-scripting": return false; default: return false; } } }; return navigator.epubReadingSystem; } }, { key: "destroy", value: function destroy() { // Stop observing if (this.observer) { this.observer.disconnect(); } this.document.removeEventListener('transitionend', this.resizeCheck); this.removeListeners(); } }], [{ key: "listenedEvents", get: function get() { return _constants.DOM_EVENTS; } }]); return Contents; }(); (0, _eventEmitter2.default)(Contents.prototype); exports.default = Contents; module.exports = exports["default"]; /***/ }), /* 14 */ /***/ (function(module, exports, __webpack_require__) { "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 _eventEmitter = __webpack_require__(3); var _eventEmitter2 = _interopRequireDefault(_eventEmitter); var _core = __webpack_require__(0); var _mapping = __webpack_require__(19); var _mapping2 = _interopRequireDefault(_mapping); var _queue = __webpack_require__(12); var _queue2 = _interopRequireDefault(_queue); var _stage = __webpack_require__(59); var _stage2 = _interopRequireDefault(_stage); var _views = __webpack_require__(69); var _views2 = _interopRequireDefault(_views); var _constants = __webpack_require__(2); 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"); } } var DefaultViewManager = function () { function DefaultViewManager(options) { _classCallCheck(this, DefaultViewManager); this.name = "default"; this.optsSettings = options.settings; this.View = options.view; this.request = options.request; this.renditionQueue = options.queue; this.q = new _queue2.default(this); this.settings = (0, _core.extend)(this.settings || {}, { infinite: true, hidden: false, width: undefined, height: undefined, axis: undefined, flow: "scrolled", ignoreClass: "", fullsize: undefined }); (0, _core.extend)(this.settings, options.settings || {}); this.viewSettings = { ignoreClass: this.settings.ignoreClass, axis: this.settings.axis, flow: this.settings.flow, layout: this.layout, method: this.settings.method, // srcdoc, blobUrl, write width: 0, height: 0, forceEvenPages: true }; this.rendered = false; } _createClass(DefaultViewManager, [{ key: "render", value: function render(element, size) { var tag = element.tagName; if (typeof this.settings.fullsize === "undefined" && tag && (tag.toLowerCase() == "body" || tag.toLowerCase() == "html")) { this.settings.fullsize = true; } if (this.settings.fullsize) { this.settings.overflow = "visible"; this.overflow = this.settings.overflow; } this.settings.size = size; // Save the stage this.stage = new _stage2.default({ width: size.width, height: size.height, overflow: this.overflow, hidden: this.settings.hidden, axis: this.settings.axis, fullsize: this.settings.fullsize, direction: this.settings.direction }); this.stage.attachTo(element); // Get this stage container div this.container = this.stage.getContainer(); // Views array methods this.views = new _views2.default(this.container); // Calculate Stage Size this._bounds = this.bounds(); this._stageSize = this.stage.size(); // Set the dimensions for views this.viewSettings.width = this._stageSize.width; this.viewSettings.height = this._stageSize.height; // Function to handle a resize event. // Will only attach if width and height are both fixed. this.stage.onResize(this.onResized.bind(this)); this.stage.onOrientationChange(this.onOrientationChange.bind(this)); // Add Event Listeners this.addEventListeners(); // Add Layout method // this.applyLayoutMethod(); if (this.layout) { this.updateLayout(); } this.rendered = true; } }, { key: "addEventListeners", value: function addEventListeners() { var scroller; window.addEventListener("unload", function (e) { this.destroy(); }.bind(this)); if (!this.settings.fullsize) { scroller = this.container; } else { scroller = window; } scroller.addEventListener("scroll", this.onScroll.bind(this)); } }, { key: "removeEventListeners", value: function removeEventListeners() { var scroller; if (!this.settings.fullsize) { scroller = this.container; } else { scroller = window; } scroller.removeEventListener("scroll", this.onScroll.bind(this)); } }, { key: "destroy", value: function destroy() { clearTimeout(this.orientationTimeout); clearTimeout(this.resizeTimeout); clearTimeout(this.afterScrolled); this.clear(); this.removeEventListeners(); this.stage.destroy(); this.rendered = false; /* clearTimeout(this.trimTimeout); if(this.settings.hidden) { this.element.removeChild(this.wrapper); } else { this.element.removeChild(this.container); } */ } }, { key: "onOrientationChange", value: function onOrientationChange(e) { var _window = window, orientation = _window.orientation; if (this.optsSettings.resizeOnOrientationChange) { this.resize(); } // Per ampproject: // In IOS 10.3, the measured size of an element is incorrect if the // element size depends on window size directly and the measurement // happens in window.resize event. Adding a timeout for correct // measurement. See https://github.com/ampproject/amphtml/issues/8479 clearTimeout(this.orientationTimeout); this.orientationTimeout = setTimeout(function () { this.orientationTimeout = undefined; if (this.optsSettings.resizeOnOrientationChange) { this.resize(); } this.emit(_constants.EVENTS.MANAGERS.ORIENTATION_CHANGE, orientation); }.bind(this), 500); } }, { key: "onResized", value: function onResized(e) { this.resize(); } }, { key: "resize", value: function resize(width, height) { var stageSize = this.stage.size(width, height); // For Safari, wait for orientation to catch up // if the window is a square this.winBounds = (0, _core.windowBounds)(); if (this.orientationTimeout && this.winBounds.width === this.winBounds.height) { // reset the stage size for next resize this._stageSize = undefined; return; } if (this._stageSize && this._stageSize.width === stageSize.width && this._stageSize.height === stageSize.height) { // Size is the same, no need to resize return; } this._stageSize = stageSize; this._bounds = this.bounds(); // Clear current views this.clear(); // Update for new views this.viewSettings.width = this._stageSize.width; this.viewSettings.height = this._stageSize.height; this.updateLayout(); this.emit(_constants.EVENTS.MANAGERS.RESIZED, { width: this._stageSize.width, height: this._stageSize.height }); } }, { key: "createView", value: function createView(section) { return new this.View(section, this.viewSettings); } }, { key: "display", value: function display(section, target) { var displaying = new _core.defer(); var displayed = displaying.promise; // Check if moving to target is needed if (target === section.href || (0, _core.isNumber)(target)) { target = undefined; } // Check to make sure the section we want isn't already shown var visible = this.views.find(section); // View is already shown, just move to correct location in view if (visible && section) { var offset = visible.offset(); if (this.settings.direction === "ltr") { this.scrollTo(offset.left, offset.top, true); } else { var width = visible.width(); this.scrollTo(offset.left + width, offset.top, true); } if (target) { var _offset = visible.locationOf(target); this.moveTo(_offset); } displaying.resolve(); return displayed; } // Hide all current views this.clear(); this.add(section).then(function (view) { // Move to correct place within the section, if needed if (target) { var _offset2 = view.locationOf(target); this.moveTo(_offset2); } }.bind(this), function (err) { displaying.reject(err); }).then(function () { var next; if (this.layout.name === "pre-paginated" && this.layout.divisor > 1) { next = section.next(); if (next) { return this.add(next); } } }.bind(this)).then(function () { this.views.show(); displaying.resolve(); }.bind(this)); // .then(function(){ // return this.hooks.display.trigger(view); // }.bind(this)) // .then(function(){ // this.views.show(); // }.bind(this)); return displayed; } }, { key: "afterDisplayed", value: function afterDisplayed(view) { this.emit(_constants.EVENTS.MANAGERS.ADDED, view); } }, { key: "afterResized", value: function afterResized(view) { this.emit(_constants.EVENTS.MANAGERS.RESIZE, view.section); } }, { key: "moveTo", value: function moveTo(offset) { var distX = 0, distY = 0; if (!this.isPaginated) { distY = offset.top; } else { distX = Math.floor(offset.left / this.layout.delta) * this.layout.delta; if (distX + this.layout.delta > this.container.scrollWidth) { distX = this.container.scrollWidth - this.layout.delta; } } this.scrollTo(distX, distY, true); } }, { key: "add", value: function add(section) { var _this = this; var view = this.createView(section); this.views.append(view); // view.on(EVENTS.VIEWS.SHOWN, this.afterDisplayed.bind(this)); view.onDisplayed = this.afterDisplayed.bind(this); view.onResize = this.afterResized.bind(this); view.on(_constants.EVENTS.VIEWS.AXIS, function (axis) { _this.updateAxis(axis); }); return view.display(this.request); } }, { key: "append", value: function append(section) { var _this2 = this; var view = this.createView(section); this.views.append(view); view.onDisplayed = this.afterDisplayed.bind(this); view.onResize = this.afterResized.bind(this); view.on(_constants.EVENTS.VIEWS.AXIS, function (axis) { _this2.updateAxis(axis); }); return view.display(this.request); } }, { key: "prepend", value: function prepend(section) { var _this3 = this; var view = this.createView(section); view.on(_constants.EVENTS.VIEWS.RESIZED, function (bounds) { _this3.counter(bounds); }); this.views.prepend(view); view.onDisplayed = this.afterDisplayed.bind(this); view.onResize = this.afterResized.bind(this); view.on(_constants.EVENTS.VIEWS.AXIS, function (axis) { _this3.updateAxis(axis); }); return view.display(this.request); } }, { key: "counter", value: function counter(bounds) { if (this.settings.axis === "vertical") { this.scrollBy(0, bounds.heightDelta, true); } else { this.scrollBy(bounds.widthDelta, 0, true); } } // resizeView(view) { // // if(this.settings.globalLayoutProperties.layout === "pre-paginated") { // view.lock("both", this.bounds.width, this.bounds.height); // } else { // view.lock("width", this.bounds.width, this.bounds.height); // } // // }; }, { key: "next", value: function next() { var next; var left; var dir = this.settings.direction; if (!this.views.length) return; if (this.isPaginated && this.settings.axis === "horizontal" && (!dir || dir === "ltr")) { this.scrollLeft = this.container.scrollLeft; left = this.container.scrollLeft + this.container.offsetWidth + this.layout.delta; if (left <= this.container.scrollWidth) { this.scrollBy(this.layout.delta, 0, true); } else { next = this.views.last().section.next(); } } else if (this.isPaginated && this.settings.axis === "horizontal" && dir === "rtl") { this.scrollLeft = this.container.scrollLeft; left = this.container.scrollLeft; if (left > 0) { this.scrollBy(this.layout.delta, 0, true); } else { next = this.views.last().section.next(); } } else if (this.isPaginated && this.settings.axis === "vertical") { this.scrollTop = this.container.scrollTop; var top = this.container.scrollTop + this.container.offsetHeight; if (top < this.container.scrollHeight) { this.scrollBy(0, this.layout.height, true); } else { next = this.views.last().section.next(); } } else { next = this.views.last().section.next(); } if (next) { this.clear(); return this.append(next).then(function () { var right; if (this.layout.name === "pre-paginated" && this.layout.divisor > 1) { right = next.next(); if (right) { return this.append(right); } } }.bind(this), function (err) { displaying.reject(err); }).then(function () { this.views.show(); }.bind(this)); } } }, { key: "prev", value: function prev() { var prev; var left; var dir = this.settings.direction; if (!this.views.length) return; if (this.isPaginated && this.settings.axis === "horizontal" && (!dir || dir === "ltr")) { this.scrollLeft = this.container.scrollLeft; left = this.container.scrollLeft; if (left > 0) { this.scrollBy(-this.layout.delta, 0, true); } else { prev = this.views.first().section.prev(); } } else if (this.isPaginated && this.settings.axis === "horizontal" && dir === "rtl") { this.scrollLeft = this.container.scrollLeft; left = this.container.scrollLeft + this.container.offsetWidth + this.layout.delta; if (left <= this.container.scrollWidth) { this.scrollBy(-this.layout.delta, 0, true); } else { prev = this.views.first().section.prev(); } } else if (this.isPaginated && this.settings.axis === "vertical") { this.scrollTop = this.container.scrollTop; var top = this.container.scrollTop; if (top > 0) { this.scrollBy(0, -this.layout.height, true); } else { prev = this.views.first().section.prev(); } } else { prev = this.views.first().section.prev(); } if (prev) { this.clear(); return this.prepend(prev).then(function () { var left; if (this.layout.name === "pre-paginated" && this.layout.divisor > 1) { left = prev.prev(); if (left) { return this.prepend(left); } } }.bind(this), function (err) { displaying.reject(err); }).then(function () { if (this.isPaginated && this.settings.axis === "horizontal") { if (this.settings.direction === "rtl") { this.scrollTo(0, 0, true); } else { this.scrollTo(this.container.scrollWidth - this.layout.delta, 0, true); } } this.views.show(); }.bind(this)); } } }, { key: "current", value: function current() { var visible = this.visible(); if (visible.length) { // Current is the last visible view return visible[visible.length - 1]; } return null; } }, { key: "clear", value: function clear() { // this.q.clear(); if (this.views) { this.views.hide(); this.scrollTo(0, 0, true); this.views.clear(); } } }, { key: "currentLocation", value: function currentLocation() { if (this.settings.axis === "vertical") { this.location = this.scrolledLocation(); } else { this.location = this.paginatedLocation(); } return this.location; } }, { key: "scrolledLocation", value: function scrolledLocation() { var _this4 = this; var visible = this.visible(); var container = this.container.getBoundingClientRect(); var pageHeight = container.height < window.innerHeight ? container.height : window.innerHeight; var offset = 0; var used = 0; if (this.settings.fullsize) { offset = window.scrollY; } var sections = visible.map(function (view) { var _view$section = view.section, index = _view$section.index, href = _view$section.href; var position = view.position(); var height = view.height(); var startPos = offset + container.top - position.top + used; var endPos = startPos + pageHeight - used; if (endPos > height) { endPos = height; used = endPos - startPos; } var totalPages = _this4.layout.count(height, pageHeight).pages; var currPage = Math.ceil(startPos / pageHeight); var pages = []; var endPage = Math.ceil(endPos / pageHeight); pages = []; for (var i = currPage; i <= endPage; i++) { var pg = i + 1; pages.push(pg); } var mapping = _this4.mapping.page(view.contents, view.section.cfiBase, startPos, endPos); return { index: index, href: href, pages: pages, totalPages: totalPages, mapping: mapping }; }); return sections; } }, { key: "paginatedLocation", value: function paginatedLocation() { var _this5 = this; var visible = this.visible(); var container = this.container.getBoundingClientRect(); var left = 0; var used = 0; if (this.settings.fullsize) { left = window.scrollX; } var sections = visible.map(function (view) { var _view$section2 = view.section, index = _view$section2.index, href = _view$section2.href; var offset = view.offset().left; var position = view.position().left; var width = view.width(); // Find mapping var start = left + container.left - position + used; var end = start + _this5.layout.width - used; var mapping = _this5.mapping.page(view.contents, view.section.cfiBase, start, end); // Find displayed pages //console.log("pre", end, offset + width); // if (end > offset + width) { // end = offset + width; // used = this.layout.pageWidth; // } // console.log("post", end); var totalPages = _this5.layout.count(width).pages; var startPage = Math.floor(start / _this5.layout.pageWidth); var pages = []; var endPage = Math.floor(end / _this5.layout.pageWidth); // start page should not be negative if (startPage < 0) { startPage = 0; endPage = endPage + 1; } // Reverse page counts for rtl if (_this5.settings.direction === "rtl") { var tempStartPage = startPage; startPage = totalPages - endPage; endPage = totalPages - tempStartPage; } for (var i = startPage + 1; i <= endPage; i++) { var pg = i; pages.push(pg); } return { index: index, href: href, pages: pages, totalPages: totalPages, mapping: mapping }; }); return sections; } }, { key: "isVisible", value: function isVisible(view, offsetPrev, offsetNext, _container) { var position = view.position(); var container = _container || this.bounds(); if (this.settings.axis === "horizontal" && position.right > container.left - offsetPrev && position.left < container.right + offsetNext) { return true; } else if (this.settings.axis === "vertical" && position.bottom > container.top - offsetPrev && position.top < container.bottom + offsetNext) { return true; } return false; } }, { key: "visible", value: function visible() { var container = this.bounds(); var views = this.views.displayed(); var viewsLength = views.length; var visible = []; var isVisible; var view; for (var i = 0; i < viewsLength; i++) { view = views[i]; isVisible = this.isVisible(view, 0, 0, container); if (isVisible === true) { visible.push(view); } } return visible; } }, { key: "scrollBy", value: function scrollBy(x, y, silent) { var dir = this.settings.direction === "rtl" ? -1 : 1; if (silent) { this.ignore = true; } if (!this.settings.fullsize) { if (x) this.container.scrollLeft += x * dir; if (y) this.container.scrollTop += y; } else { window.scrollBy(x * dir, y * dir); } this.scrolled = true; } }, { key: "scrollTo", value: function scrollTo(x, y, silent) { if (silent) { this.ignore = true; } if (!this.settings.fullsize) { this.container.scrollLeft = x; this.container.scrollTop = y; } else { window.scrollTo(x, y); } this.scrolled = true; } }, { key: "onScroll", value: function onScroll() { var scrollTop = void 0; var scrollLeft = void 0; if (!this.settings.fullsize) { scrollTop = this.container.scrollTop; scrollLeft = this.container.scrollLeft; } else { scrollTop = window.scrollY; scrollLeft = window.scrollX; } this.scrollTop = scrollTop; this.scrollLeft = scrollLeft; if (!this.ignore) { this.emit(_constants.EVENTS.MANAGERS.SCROLL, { top: scrollTop, left: scrollLeft }); clearTimeout(this.afterScrolled); this.afterScrolled = setTimeout(function () { this.emit(_constants.EVENTS.MANAGERS.SCROLLED, { top: this.scrollTop, left: this.scrollLeft }); }.bind(this), 20); } else { this.ignore = false; } } }, { key: "bounds", value: function bounds() { var bounds; bounds = this.stage.bounds(); return bounds; } }, { key: "applyLayout", value: function applyLayout(layout) { this.layout = layout; this.updateLayout(); // this.manager.layout(this.layout.format); } }, { key: "updateLayout", value: function updateLayout() { if (!this.stage) { return; } this._stageSize = this.stage.size(); if (!this.isPaginated) { this.layout.calculate(this._stageSize.width, this._stageSize.height); } else { this.layout.calculate(this._stageSize.width, this._stageSize.height, this.settings.gap); // Set the look ahead offset for what is visible this.settings.offset = this.layout.delta; // this.stage.addStyleRules("iframe", [{"margin-right" : this.layout.gap + "px"}]); } // Set the dimensions for views this.viewSettings.width = this.layout.width; this.viewSettings.height = this.layout.height; this.setLayout(this.layout); } }, { key: "setLayout", value: function setLayout(layout) { this.viewSettings.layout = layout; this.mapping = new _mapping2.default(layout.props, this.settings.direction, this.settings.axis); if (this.views) { this.views.forEach(function (view) { if (view) { view.setLayout(layout); } }); } } }, { key: "updateAxis", value: function updateAxis(axis, forceUpdate) { if (!this.isPaginated) { axis = "vertical"; } if (!forceUpdate && axis === this.settings.axis) { return; } this.settings.axis = axis; this.stage && this.stage.axis(axis); this.viewSettings.axis = axis; if (this.mapping) { this.mapping = new _mapping2.default(this.layout.props, this.settings.direction, this.settings.axis); } if (this.layout) { if (axis === "vertical") { this.layout.spread("none"); } else { this.layout.spread(this.layout.settings.spread); } } } }, { key: "updateFlow", value: function updateFlow(flow) { var isPaginated = flow === "paginated" || flow === "auto"; this.isPaginated = isPaginated; if (flow === "scrolled-doc" || flow === "scrolled-continuous" || flow === "scrolled") { this.updateAxis("vertical"); } this.viewSettings.flow = flow; if (!this.settings.overflow) { this.overflow = isPaginated ? "hidden" : "auto"; } else { this.overflow = this.settings.overflow; } // this.views.forEach(function(view){ // view.setAxis(axis); // }); this.updateLayout(); } }, { key: "getContents", value: function getContents() { var contents = []; if (!this.views) { return contents; } this.views.forEach(function (view) { var viewContents = view && view.contents; if (viewContents) { contents.push(viewContents); } }); return contents; } }, { key: "direction", value: function direction() { var dir = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "ltr"; this.settings.direction = dir; this.stage && this.stage.direction(dir); this.viewSettings.direction = dir; this.updateLayout(); } }, { key: "isRendered", value: function isRendered() { return this.rendered; } }]); return DefaultViewManager; }(); //-- Enable binding events to Manager (0, _eventEmitter2.default)(DefaultViewManager.prototype); exports.default = DefaultViewManager; module.exports = exports["default"]; /***/ }), /* 15 */ /***/ (function(module, exports) { /** * Checks if `value` is the * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * * _.isObject({}); * // => true * * _.isObject([1, 2, 3]); * // => true * * _.isObject(_.noop); * // => true * * _.isObject(null); * // => false */ function isObject(value) { var type = typeof value; return value != null && (type == 'object' || type == 'function'); } module.exports = isObject; /***/ }), /* 16 */ /***/ (function(module, exports) { /* * DOM Level 2 * Object DOMException * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html */ function copy(src,dest){ for(var p in src){ dest[p] = src[p]; } } /** ^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));? ^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));? */ function _extends(Class,Super){ var pt = Class.prototype; if(Object.create){ var ppt = Object.create(Super.prototype) pt.__proto__ = ppt; } if(!(pt instanceof Super)){ function t(){}; t.prototype = Super.prototype; t = new t(); copy(pt,t); Class.prototype = pt = t; } if(pt.constructor != Class){ if(typeof Class != 'function'){ console.error("unknow Class:"+Class) } pt.constructor = Class } } var htmlns = 'http://www.w3.org/1999/xhtml' ; // Node Types var NodeType = {} var ELEMENT_NODE = NodeType.ELEMENT_NODE = 1; var ATTRIBUTE_NODE = NodeType.ATTRIBUTE_NODE = 2; var TEXT_NODE = NodeType.TEXT_NODE = 3; var CDATA_SECTION_NODE = NodeType.CDATA_SECTION_NODE = 4; var ENTITY_REFERENCE_NODE = NodeType.ENTITY_REFERENCE_NODE = 5; var ENTITY_NODE = NodeType.ENTITY_NODE = 6; var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7; var COMMENT_NODE = NodeType.COMMENT_NODE = 8; var DOCUMENT_NODE = NodeType.DOCUMENT_NODE = 9; var DOCUMENT_TYPE_NODE = NodeType.DOCUMENT_TYPE_NODE = 10; var DOCUMENT_FRAGMENT_NODE = NodeType.DOCUMENT_FRAGMENT_NODE = 11; var NOTATION_NODE = NodeType.NOTATION_NODE = 12; // ExceptionCode var ExceptionCode = {} var ExceptionMessage = {}; var INDEX_SIZE_ERR = ExceptionCode.INDEX_SIZE_ERR = ((ExceptionMessage[1]="Index size error"),1); var DOMSTRING_SIZE_ERR = ExceptionCode.DOMSTRING_SIZE_ERR = ((ExceptionMessage[2]="DOMString size error"),2); var HIERARCHY_REQUEST_ERR = ExceptionCode.HIERARCHY_REQUEST_ERR = ((ExceptionMessage[3]="Hierarchy request error"),3); var WRONG_DOCUMENT_ERR = ExceptionCode.WRONG_DOCUMENT_ERR = ((ExceptionMessage[4]="Wrong document"),4); var INVALID_CHARACTER_ERR = ExceptionCode.INVALID_CHARACTER_ERR = ((ExceptionMessage[5]="Invalid character"),5); var NO_DATA_ALLOWED_ERR = ExceptionCode.NO_DATA_ALLOWED_ERR = ((ExceptionMessage[6]="No data allowed"),6); var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = ((ExceptionMessage[7]="No modification allowed"),7); var NOT_FOUND_ERR = ExceptionCode.NOT_FOUND_ERR = ((ExceptionMessage[8]="Not found"),8); var NOT_SUPPORTED_ERR = ExceptionCode.NOT_SUPPORTED_ERR = ((ExceptionMessage[9]="Not supported"),9); var INUSE_ATTRIBUTE_ERR = ExceptionCode.INUSE_ATTRIBUTE_ERR = ((ExceptionMessage[10]="Attribute in use"),10); //level2 var INVALID_STATE_ERR = ExceptionCode.INVALID_STATE_ERR = ((ExceptionMessage[11]="Invalid state"),11); var SYNTAX_ERR = ExceptionCode.SYNTAX_ERR = ((ExceptionMessage[12]="Syntax error"),12); var INVALID_MODIFICATION_ERR = ExceptionCode.INVALID_MODIFICATION_ERR = ((ExceptionMessage[13]="Invalid modification"),13); var NAMESPACE_ERR = ExceptionCode.NAMESPACE_ERR = ((ExceptionMessage[14]="Invalid namespace"),14); var INVALID_ACCESS_ERR = ExceptionCode.INVALID_ACCESS_ERR = ((ExceptionMessage[15]="Invalid access"),15); function DOMException(code, message) { if(message instanceof Error){ var error = message; }else{ error = this; Error.call(this, ExceptionMessage[code]); this.message = ExceptionMessage[code]; if(Error.captureStackTrace) Error.captureStackTrace(this, DOMException); } error.code = code; if(message) this.message = this.message + ": " + message; return error; }; DOMException.prototype = Error.prototype; copy(ExceptionCode,DOMException) /** * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177 * The NodeList interface provides the abstraction of an ordered collection of nodes, without defining or constraining how this collection is implemented. NodeList objects in the DOM are live. * The items in the NodeList are accessible via an integral index, starting from 0. */ function NodeList() { }; NodeList.prototype = { /** * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive. * @standard level1 */ length:0, /** * Returns the indexth item in the collection. If index is greater than or equal to the number of nodes in the list, this returns null. * @standard level1 * @param index unsigned long * Index into the collection. * @return Node * The node at the indexth position in the NodeList, or null if that is not a valid index. */ item: function(index) { return this[index] || null; }, toString:function(isHTML,nodeFilter){ for(var buf = [], i = 0;i=0){ var lastIndex = list.length-1 while(i0 || key == 'xmlns'){ // return null; // } //console.log() var i = this.length; while(i--){ var attr = this[i]; //console.log(attr.nodeName,key) if(attr.nodeName == key){ return attr; } } }, setNamedItem: function(attr) { var el = attr.ownerElement; if(el && el!=this._ownerElement){ throw new DOMException(INUSE_ATTRIBUTE_ERR); } var oldAttr = this.getNamedItem(attr.nodeName); _addNamedNode(this._ownerElement,this,attr,oldAttr); return oldAttr; }, /* returns Node */ setNamedItemNS: function(attr) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR var el = attr.ownerElement, oldAttr; if(el && el!=this._ownerElement){ throw new DOMException(INUSE_ATTRIBUTE_ERR); } oldAttr = this.getNamedItemNS(attr.namespaceURI,attr.localName); _addNamedNode(this._ownerElement,this,attr,oldAttr); return oldAttr; }, /* returns Node */ removeNamedItem: function(key) { var attr = this.getNamedItem(key); _removeNamedNode(this._ownerElement,this,attr); return attr; },// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR //for level2 removeNamedItemNS:function(namespaceURI,localName){ var attr = this.getNamedItemNS(namespaceURI,localName); _removeNamedNode(this._ownerElement,this,attr); return attr; }, getNamedItemNS: function(namespaceURI, localName) { var i = this.length; while(i--){ var node = this[i]; if(node.localName == localName && node.namespaceURI == namespaceURI){ return node; } } return null; } }; /** * @see http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490 */ function DOMImplementation(/* Object */ features) { this._features = {}; if (features) { for (var feature in features) { this._features = features[feature]; } } }; DOMImplementation.prototype = { hasFeature: function(/* string */ feature, /* string */ version) { var versions = this._features[feature.toLowerCase()]; if (versions && (!version || version in versions)) { return true; } else { return false; } }, // Introduced in DOM Level 2: createDocument:function(namespaceURI, qualifiedName, doctype){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR,WRONG_DOCUMENT_ERR var doc = new Document(); doc.implementation = this; doc.childNodes = new NodeList(); doc.doctype = doctype; if(doctype){ doc.appendChild(doctype); } if(qualifiedName){ var root = doc.createElementNS(namespaceURI,qualifiedName); doc.appendChild(root); } return doc; }, // Introduced in DOM Level 2: createDocumentType:function(qualifiedName, publicId, systemId){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR var node = new DocumentType(); node.name = qualifiedName; node.nodeName = qualifiedName; node.publicId = publicId; node.systemId = systemId; // Introduced in DOM Level 2: //readonly attribute DOMString internalSubset; //TODO:.. // readonly attribute NamedNodeMap entities; // readonly attribute NamedNodeMap notations; return node; } }; /** * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247 */ function Node() { }; Node.prototype = { firstChild : null, lastChild : null, previousSibling : null, nextSibling : null, attributes : null, parentNode : null, childNodes : null, ownerDocument : null, nodeValue : null, namespaceURI : null, prefix : null, localName : null, // Modified in DOM Level 2: insertBefore:function(newChild, refChild){//raises return _insertBefore(this,newChild,refChild); }, replaceChild:function(newChild, oldChild){//raises this.insertBefore(newChild,oldChild); if(oldChild){ this.removeChild(oldChild); } }, removeChild:function(oldChild){ return _removeChild(this,oldChild); }, appendChild:function(newChild){ return this.insertBefore(newChild,null); }, hasChildNodes:function(){ return this.firstChild != null; }, cloneNode:function(deep){ return cloneNode(this.ownerDocument||this,this,deep); }, // Modified in DOM Level 2: normalize:function(){ var child = this.firstChild; while(child){ var next = child.nextSibling; if(next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE){ this.removeChild(next); child.appendData(next.data); }else{ child.normalize(); child = next; } } }, // Introduced in DOM Level 2: isSupported:function(feature, version){ return this.ownerDocument.implementation.hasFeature(feature,version); }, // Introduced in DOM Level 2: hasAttributes:function(){ return this.attributes.length>0; }, lookupPrefix:function(namespaceURI){ var el = this; while(el){ var map = el._nsMap; //console.dir(map) if(map){ for(var n in map){ if(map[n] == namespaceURI){ return n; } } } el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode; } return null; }, // Introduced in DOM Level 3: lookupNamespaceURI:function(prefix){ var el = this; while(el){ var map = el._nsMap; //console.dir(map) if(map){ if(prefix in map){ return map[prefix] ; } } el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode; } return null; }, // Introduced in DOM Level 3: isDefaultNamespace:function(namespaceURI){ var prefix = this.lookupPrefix(namespaceURI); return prefix == null; } }; function _xmlEncoder(c){ return c == '<' && '<' || c == '>' && '>' || c == '&' && '&' || c == '"' && '"' || '&#'+c.charCodeAt()+';' } copy(NodeType,Node); copy(NodeType,Node.prototype); /** * @param callback return true for continue,false for break * @return boolean true: break visit; */ function _visitNode(node,callback){ if(callback(node)){ return true; } if(node = node.firstChild){ do{ if(_visitNode(node,callback)){return true} }while(node=node.nextSibling) } } function Document(){ } function _onAddAttribute(doc,el,newAttr){ doc && doc._inc++; var ns = newAttr.namespaceURI ; if(ns == 'http://www.w3.org/2000/xmlns/'){ //update namespace el._nsMap[newAttr.prefix?newAttr.localName:''] = newAttr.value } } function _onRemoveAttribute(doc,el,newAttr,remove){ doc && doc._inc++; var ns = newAttr.namespaceURI ; if(ns == 'http://www.w3.org/2000/xmlns/'){ //update namespace delete el._nsMap[newAttr.prefix?newAttr.localName:''] } } function _onUpdateChild(doc,el,newChild){ if(doc && doc._inc){ doc._inc++; //update childNodes var cs = el.childNodes; if(newChild){ cs[cs.length++] = newChild; }else{ //console.log(1) var child = el.firstChild; var i = 0; while(child){ cs[i++] = child; child =child.nextSibling; } cs.length = i; } } } /** * attributes; * children; * * writeable properties: * nodeValue,Attr:value,CharacterData:data * prefix */ function _removeChild(parentNode,child){ var previous = child.previousSibling; var next = child.nextSibling; if(previous){ previous.nextSibling = next; }else{ parentNode.firstChild = next } if(next){ next.previousSibling = previous; }else{ parentNode.lastChild = previous; } _onUpdateChild(parentNode.ownerDocument,parentNode); return child; } /** * preformance key(refChild == null) */ function _insertBefore(parentNode,newChild,nextChild){ var cp = newChild.parentNode; if(cp){ cp.removeChild(newChild);//remove and update } if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){ var newFirst = newChild.firstChild; if (newFirst == null) { return newChild; } var newLast = newChild.lastChild; }else{ newFirst = newLast = newChild; } var pre = nextChild ? nextChild.previousSibling : parentNode.lastChild; newFirst.previousSibling = pre; newLast.nextSibling = nextChild; if(pre){ pre.nextSibling = newFirst; }else{ parentNode.firstChild = newFirst; } if(nextChild == null){ parentNode.lastChild = newLast; }else{ nextChild.previousSibling = newLast; } do{ newFirst.parentNode = parentNode; }while(newFirst !== newLast && (newFirst= newFirst.nextSibling)) _onUpdateChild(parentNode.ownerDocument||parentNode,parentNode); //console.log(parentNode.lastChild.nextSibling == null) if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) { newChild.firstChild = newChild.lastChild = null; } return newChild; } function _appendSingleChild(parentNode,newChild){ var cp = newChild.parentNode; if(cp){ var pre = parentNode.lastChild; cp.removeChild(newChild);//remove and update var pre = parentNode.lastChild; } var pre = parentNode.lastChild; newChild.parentNode = parentNode; newChild.previousSibling = pre; newChild.nextSibling = null; if(pre){ pre.nextSibling = newChild; }else{ parentNode.firstChild = newChild; } parentNode.lastChild = newChild; _onUpdateChild(parentNode.ownerDocument,parentNode,newChild); return newChild; //console.log("__aa",parentNode.lastChild.nextSibling == null) } Document.prototype = { //implementation : null, nodeName : '#document', nodeType : DOCUMENT_NODE, doctype : null, documentElement : null, _inc : 1, insertBefore : function(newChild, refChild){//raises if(newChild.nodeType == DOCUMENT_FRAGMENT_NODE){ var child = newChild.firstChild; while(child){ var next = child.nextSibling; this.insertBefore(child,refChild); child = next; } return newChild; } if(this.documentElement == null && newChild.nodeType == ELEMENT_NODE){ this.documentElement = newChild; } return _insertBefore(this,newChild,refChild),(newChild.ownerDocument = this),newChild; }, removeChild : function(oldChild){ if(this.documentElement == oldChild){ this.documentElement = null; } return _removeChild(this,oldChild); }, // Introduced in DOM Level 2: importNode : function(importedNode,deep){ return importNode(this,importedNode,deep); }, // Introduced in DOM Level 2: getElementById : function(id){ var rtv = null; _visitNode(this.documentElement,function(node){ if(node.nodeType == ELEMENT_NODE){ if(node.getAttribute('id') == id){ rtv = node; return true; } } }) return rtv; }, //document factory method: createElement : function(tagName){ var node = new Element(); node.ownerDocument = this; node.nodeName = tagName; node.tagName = tagName; node.childNodes = new NodeList(); var attrs = node.attributes = new NamedNodeMap(); attrs._ownerElement = node; return node; }, createDocumentFragment : function(){ var node = new DocumentFragment(); node.ownerDocument = this; node.childNodes = new NodeList(); return node; }, createTextNode : function(data){ var node = new Text(); node.ownerDocument = this; node.appendData(data) return node; }, createComment : function(data){ var node = new Comment(); node.ownerDocument = this; node.appendData(data) return node; }, createCDATASection : function(data){ var node = new CDATASection(); node.ownerDocument = this; node.appendData(data) return node; }, createProcessingInstruction : function(target,data){ var node = new ProcessingInstruction(); node.ownerDocument = this; node.tagName = node.target = target; node.nodeValue= node.data = data; return node; }, createAttribute : function(name){ var node = new Attr(); node.ownerDocument = this; node.name = name; node.nodeName = name; node.localName = name; node.specified = true; return node; }, createEntityReference : function(name){ var node = new EntityReference(); node.ownerDocument = this; node.nodeName = name; return node; }, // Introduced in DOM Level 2: createElementNS : function(namespaceURI,qualifiedName){ var node = new Element(); var pl = qualifiedName.split(':'); var attrs = node.attributes = new NamedNodeMap(); node.childNodes = new NodeList(); node.ownerDocument = this; node.nodeName = qualifiedName; node.tagName = qualifiedName; node.namespaceURI = namespaceURI; if(pl.length == 2){ node.prefix = pl[0]; node.localName = pl[1]; }else{ //el.prefix = null; node.localName = qualifiedName; } attrs._ownerElement = node; return node; }, // Introduced in DOM Level 2: createAttributeNS : function(namespaceURI,qualifiedName){ var node = new Attr(); var pl = qualifiedName.split(':'); node.ownerDocument = this; node.nodeName = qualifiedName; node.name = qualifiedName; node.namespaceURI = namespaceURI; node.specified = true; if(pl.length == 2){ node.prefix = pl[0]; node.localName = pl[1]; }else{ //el.prefix = null; node.localName = qualifiedName; } return node; } }; _extends(Document,Node); function Element() { this._nsMap = {}; }; Element.prototype = { nodeType : ELEMENT_NODE, hasAttribute : function(name){ return this.getAttributeNode(name)!=null; }, getAttribute : function(name){ var attr = this.getAttributeNode(name); return attr && attr.value || ''; }, getAttributeNode : function(name){ return this.attributes.getNamedItem(name); }, setAttribute : function(name, value){ var attr = this.ownerDocument.createAttribute(name); attr.value = attr.nodeValue = "" + value; this.setAttributeNode(attr) }, removeAttribute : function(name){ var attr = this.getAttributeNode(name) attr && this.removeAttributeNode(attr); }, //four real opeartion method appendChild:function(newChild){ if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){ return this.insertBefore(newChild,null); }else{ return _appendSingleChild(this,newChild); } }, setAttributeNode : function(newAttr){ return this.attributes.setNamedItem(newAttr); }, setAttributeNodeNS : function(newAttr){ return this.attributes.setNamedItemNS(newAttr); }, removeAttributeNode : function(oldAttr){ //console.log(this == oldAttr.ownerElement) return this.attributes.removeNamedItem(oldAttr.nodeName); }, //get real attribute name,and remove it by removeAttributeNode removeAttributeNS : function(namespaceURI, localName){ var old = this.getAttributeNodeNS(namespaceURI, localName); old && this.removeAttributeNode(old); }, hasAttributeNS : function(namespaceURI, localName){ return this.getAttributeNodeNS(namespaceURI, localName)!=null; }, getAttributeNS : function(namespaceURI, localName){ var attr = this.getAttributeNodeNS(namespaceURI, localName); return attr && attr.value || ''; }, setAttributeNS : function(namespaceURI, qualifiedName, value){ var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName); attr.value = attr.nodeValue = "" + value; this.setAttributeNode(attr) }, getAttributeNodeNS : function(namespaceURI, localName){ return this.attributes.getNamedItemNS(namespaceURI, localName); }, getElementsByTagName : function(tagName){ return new LiveNodeList(this,function(base){ var ls = []; _visitNode(base,function(node){ if(node !== base && node.nodeType == ELEMENT_NODE && (tagName === '*' || node.tagName == tagName)){ ls.push(node); } }); return ls; }); }, getElementsByTagNameNS : function(namespaceURI, localName){ return new LiveNodeList(this,function(base){ var ls = []; _visitNode(base,function(node){ if(node !== base && node.nodeType === ELEMENT_NODE && (namespaceURI === '*' || node.namespaceURI === namespaceURI) && (localName === '*' || node.localName == localName)){ ls.push(node); } }); return ls; }); } }; Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName; Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS; _extends(Element,Node); function Attr() { }; Attr.prototype.nodeType = ATTRIBUTE_NODE; _extends(Attr,Node); function CharacterData() { }; CharacterData.prototype = { data : '', substringData : function(offset, count) { return this.data.substring(offset, offset+count); }, appendData: function(text) { text = this.data+text; this.nodeValue = this.data = text; this.length = text.length; }, insertData: function(offset,text) { this.replaceData(offset,0,text); }, appendChild:function(newChild){ throw new Error(ExceptionMessage[HIERARCHY_REQUEST_ERR]) }, deleteData: function(offset, count) { this.replaceData(offset,count,""); }, replaceData: function(offset, count, text) { var start = this.data.substring(0,offset); var end = this.data.substring(offset+count); text = start + text + end; this.nodeValue = this.data = text; this.length = text.length; } } _extends(CharacterData,Node); function Text() { }; Text.prototype = { nodeName : "#text", nodeType : TEXT_NODE, splitText : function(offset) { var text = this.data; var newText = text.substring(offset); text = text.substring(0, offset); this.data = this.nodeValue = text; this.length = text.length; var newNode = this.ownerDocument.createTextNode(newText); if(this.parentNode){ this.parentNode.insertBefore(newNode, this.nextSibling); } return newNode; } } _extends(Text,CharacterData); function Comment() { }; Comment.prototype = { nodeName : "#comment", nodeType : COMMENT_NODE } _extends(Comment,CharacterData); function CDATASection() { }; CDATASection.prototype = { nodeName : "#cdata-section", nodeType : CDATA_SECTION_NODE } _extends(CDATASection,CharacterData); function DocumentType() { }; DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE; _extends(DocumentType,Node); function Notation() { }; Notation.prototype.nodeType = NOTATION_NODE; _extends(Notation,Node); function Entity() { }; Entity.prototype.nodeType = ENTITY_NODE; _extends(Entity,Node); function EntityReference() { }; EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE; _extends(EntityReference,Node); function DocumentFragment() { }; DocumentFragment.prototype.nodeName = "#document-fragment"; DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE; _extends(DocumentFragment,Node); function ProcessingInstruction() { } ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE; _extends(ProcessingInstruction,Node); function XMLSerializer(){} XMLSerializer.prototype.serializeToString = function(node,isHtml,nodeFilter){ return nodeSerializeToString.call(node,isHtml,nodeFilter); } Node.prototype.toString = nodeSerializeToString; function nodeSerializeToString(isHtml,nodeFilter){ var buf = []; var refNode = this.nodeType == 9?this.documentElement:this; var prefix = refNode.prefix; var uri = refNode.namespaceURI; if(uri && prefix == null){ //console.log(prefix) var prefix = refNode.lookupPrefix(uri); if(prefix == null){ //isHTML = true; var visibleNamespaces=[ {namespace:uri,prefix:null} //{namespace:uri,prefix:''} ] } } serializeToString(this,buf,isHtml,nodeFilter,visibleNamespaces); //console.log('###',this.nodeType,uri,prefix,buf.join('')) return buf.join(''); } function needNamespaceDefine(node,isHTML, visibleNamespaces) { var prefix = node.prefix||''; var uri = node.namespaceURI; if (!prefix && !uri){ return false; } if (prefix === "xml" && uri === "http://www.w3.org/XML/1998/namespace" || uri == 'http://www.w3.org/2000/xmlns/'){ return false; } var i = visibleNamespaces.length //console.log('@@@@',node.tagName,prefix,uri,visibleNamespaces) while (i--) { var ns = visibleNamespaces[i]; // get namespace prefix //console.log(node.nodeType,node.tagName,ns.prefix,prefix) if (ns.prefix == prefix){ return ns.namespace != uri; } } //console.log(isHTML,uri,prefix=='') //if(isHTML && prefix ==null && uri == 'http://www.w3.org/1999/xhtml'){ // return false; //} //node.flag = '11111' //console.error(3,true,node.flag,node.prefix,node.namespaceURI) return true; } function serializeToString(node,buf,isHTML,nodeFilter,visibleNamespaces){ if(nodeFilter){ node = nodeFilter(node); if(node){ if(typeof node == 'string'){ buf.push(node); return; } }else{ return; } //buf.sort.apply(attrs, attributeSorter); } switch(node.nodeType){ case ELEMENT_NODE: if (!visibleNamespaces) visibleNamespaces = []; var startVisibleNamespaces = visibleNamespaces.length; var attrs = node.attributes; var len = attrs.length; var child = node.firstChild; var nodeName = node.tagName; isHTML = (htmlns === node.namespaceURI) ||isHTML buf.push('<',nodeName); for(var i=0;i'); //if is cdata child node if(isHTML && /^script$/i.test(nodeName)){ while(child){ if(child.data){ buf.push(child.data); }else{ serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces); } child = child.nextSibling; } }else { while(child){ serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces); child = child.nextSibling; } } buf.push(''); }else{ buf.push('/>'); } // remove added visible namespaces //visibleNamespaces.length = startVisibleNamespaces; return; case DOCUMENT_NODE: case DOCUMENT_FRAGMENT_NODE: var child = node.firstChild; while(child){ serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces); child = child.nextSibling; } return; case ATTRIBUTE_NODE: return buf.push(' ',node.name,'="',node.value.replace(/[<&"]/g,_xmlEncoder),'"'); case TEXT_NODE: return buf.push(node.data.replace(/[<&]/g,_xmlEncoder)); case CDATA_SECTION_NODE: return buf.push( ''); case COMMENT_NODE: return buf.push( ""); case DOCUMENT_TYPE_NODE: var pubid = node.publicId; var sysid = node.systemId; buf.push(''); }else if(sysid && sysid!='.'){ buf.push(' SYSTEM "',sysid,'">'); }else{ var sub = node.internalSubset; if(sub){ buf.push(" [",sub,"]"); } buf.push(">"); } return; case PROCESSING_INSTRUCTION_NODE: return buf.push( ""); case ENTITY_REFERENCE_NODE: return buf.push( '&',node.nodeName,';'); //case ENTITY_NODE: //case NOTATION_NODE: default: buf.push('??',node.nodeName); } } function importNode(doc,node,deep){ var node2; switch (node.nodeType) { case ELEMENT_NODE: node2 = node.cloneNode(false); node2.ownerDocument = doc; //var attrs = node2.attributes; //var len = attrs.length; //for(var i=0;i 0) && (this.settings.height === 0 || this.settings.height > 0)) { // viewport = "width="+this.settings.width+", height="+this.settings.height+""; } properties = { layout: layout, spread: spread, orientation: orientation, flow: flow, viewport: viewport, minSpreadWidth: minSpreadWidth, direction: direction }; return properties; } /** * Adjust the flow of the rendition to paginated or scrolled * (scrolled-continuous vs scrolled-doc are handled by different view managers) * @param {string} flow */ }, { key: "flow", value: function flow(_flow2) { var _flow = _flow2; if (_flow2 === "scrolled" || _flow2 === "scrolled-doc" || _flow2 === "scrolled-continuous") { _flow = "scrolled"; } if (_flow2 === "auto" || _flow2 === "paginated") { _flow = "paginated"; } this.settings.flow = _flow2; if (this._layout) { this._layout.flow(_flow); } if (this.manager && this._layout) { this.manager.applyLayout(this._layout); } if (this.manager) { this.manager.updateFlow(_flow); } if (this.manager && this.manager.isRendered() && this.location) { this.manager.clear(); this.display(this.location.start.cfi); } } /** * Adjust the layout of the rendition to reflowable or pre-paginated * @param {object} settings */ }, { key: "layout", value: function layout(settings) { var _this4 = this; if (settings) { this._layout = new _layout2.default(settings); this._layout.spread(settings.spread, this.settings.minSpreadWidth); // this.mapping = new Mapping(this._layout.props); this._layout.on(_constants.EVENTS.LAYOUT.UPDATED, function (props, changed) { _this4.emit(_constants.EVENTS.RENDITION.LAYOUT, props, changed); }); } if (this.manager && this._layout) { this.manager.applyLayout(this._layout); } return this._layout; } /** * Adjust if the rendition uses spreads * @param {string} spread none | auto (TODO: implement landscape, portrait, both) * @param {int} min min width to use spreads at */ }, { key: "spread", value: function spread(_spread, min) { this._layout.spread(_spread, min); if (this.manager.isRendered()) { this.manager.updateLayout(); } } /** * Adjust the direction of the rendition * @param {string} dir */ }, { key: "direction", value: function direction(dir) { this.settings.direction = dir || "ltr"; if (this.manager) { this.manager.direction(this.settings.direction); } if (this.manager && this.manager.isRendered() && this.location) { this.manager.clear(); this.display(this.location.start.cfi); } } /** * Report the current location * @fires relocated * @fires locationChanged */ }, { key: "reportLocation", value: function reportLocation() { return this.q.enqueue(function reportedLocation() { requestAnimationFrame(function reportedLocationAfterRAF() { var location = this.manager.currentLocation(); if (location && location.then && typeof location.then === "function") { location.then(function (result) { var located = this.located(result); if (!located || !located.start || !located.end) { return; } this.location = located; this.emit(_constants.EVENTS.RENDITION.LOCATION_CHANGED, { index: this.location.start.index, href: this.location.start.href, start: this.location.start.cfi, end: this.location.end.cfi, percentage: this.location.start.percentage }); this.emit(_constants.EVENTS.RENDITION.RELOCATED, this.location); }.bind(this)); } else if (location) { var located = this.located(location); if (!located || !located.start || !located.end) { return; } this.location = located; /** * @event locationChanged * @deprecated * @type {object} * @property {number} index * @property {string} href * @property {EpubCFI} start * @property {EpubCFI} end * @property {number} percentage * @memberof Rendition */ this.emit(_constants.EVENTS.RENDITION.LOCATION_CHANGED, { index: this.location.start.index, href: this.location.start.href, start: this.location.start.cfi, end: this.location.end.cfi, percentage: this.location.start.percentage }); /** * @event relocated * @type {displayedLocation} * @memberof Rendition */ this.emit(_constants.EVENTS.RENDITION.RELOCATED, this.location); } }.bind(this)); }.bind(this)); } /** * Get the Current Location object * @return {displayedLocation | promise} location (may be a promise) */ }, { key: "currentLocation", value: function currentLocation() { var location = this.manager.currentLocation(); if (location && location.then && typeof location.then === "function") { location.then(function (result) { var located = this.located(result); return located; }.bind(this)); } else if (location) { var located = this.located(location); return located; } } /** * Creates a Rendition#locationRange from location * passed by the Manager * @returns {displayedLocation} * @private */ }, { key: "located", value: function located(location) { if (!location.length) { return {}; } var start = location[0]; var end = location[location.length - 1]; var located = { start: { index: start.index, href: start.href, cfi: start.mapping.start, displayed: { page: start.pages[0] || 1, total: start.totalPages } }, end: { index: end.index, href: end.href, cfi: end.mapping.end, displayed: { page: end.pages[end.pages.length - 1] || 1, total: end.totalPages } } }; var locationStart = this.book.locations.locationFromCfi(start.mapping.start); var locationEnd = this.book.locations.locationFromCfi(end.mapping.end); if (locationStart != null) { located.start.location = locationStart; located.start.percentage = this.book.locations.percentageFromLocation(locationStart); } if (locationEnd != null) { located.end.location = locationEnd; located.end.percentage = this.book.locations.percentageFromLocation(locationEnd); } var pageStart = this.book.pageList.pageFromCfi(start.mapping.start); var pageEnd = this.book.pageList.pageFromCfi(end.mapping.end); if (pageStart != -1) { located.start.page = pageStart; } if (pageEnd != -1) { located.end.page = pageEnd; } if (end.index === this.book.spine.last().index && located.end.displayed.page >= located.end.displayed.total) { located.atEnd = true; } if (start.index === this.book.spine.first().index && located.start.displayed.page === 1) { located.atStart = true; } return located; } /** * Remove and Clean Up the Rendition */ }, { key: "destroy", value: function destroy() { // Clear the queue // this.q.clear(); // this.q = undefined; this.manager && this.manager.destroy(); this.book = undefined; // this.views = null; // this.hooks.display.clear(); // this.hooks.serialize.clear(); // this.hooks.content.clear(); // this.hooks.layout.clear(); // this.hooks.render.clear(); // this.hooks.show.clear(); // this.hooks = {}; // this.themes.destroy(); // this.themes = undefined; // this.epubcfi = undefined; // this.starting = undefined; // this.started = undefined; } /** * Pass the events from a view's Contents * @private * @param {Contents} view contents */ }, { key: "passEvents", value: function passEvents(contents) { var _this5 = this; var listenedEvents = _contents2.default.listenedEvents; listenedEvents.forEach(function (e) { contents.on(e, function (ev) { return _this5.triggerViewEvent(ev, contents); }); }); contents.on(_constants.EVENTS.CONTENTS.SELECTED, function (e) { return _this5.triggerSelectedEvent(e, contents); }); } /** * Emit events passed by a view * @private * @param {event} e */ }, { key: "triggerViewEvent", value: function triggerViewEvent(e, contents) { this.emit(e.type, e, contents); } /** * Emit a selection event's CFI Range passed from a a view * @private * @param {EpubCFI} cfirange */ }, { key: "triggerSelectedEvent", value: function triggerSelectedEvent(cfirange, contents) { /** * Emit that a text selection has occured * @event selected * @param {EpubCFI} cfirange * @param {Contents} contents * @memberof Rendition */ this.emit(_constants.EVENTS.RENDITION.SELECTED, cfirange, contents); } /** * Emit a markClicked event with the cfiRange and data from a mark * @private * @param {EpubCFI} cfirange */ }, { key: "triggerMarkEvent", value: function triggerMarkEvent(cfiRange, data, contents) { /** * Emit that a mark was clicked * @event markClicked * @param {EpubCFI} cfirange * @param {object} data * @param {Contents} contents * @memberof Rendition */ this.emit(_constants.EVENTS.RENDITION.MARK_CLICKED, cfiRange, data, contents); } /** * Get a Range from a Visible CFI * @param {string} cfi EpubCfi String * @param {string} ignoreClass * @return {range} */ }, { key: "getRange", value: function getRange(cfi, ignoreClass) { var _cfi = new _epubcfi2.default(cfi); var found = this.manager.visible().filter(function (view) { if (_cfi.spinePos === view.index) return true; }); // Should only every return 1 item if (found.length) { return found[0].contents.range(_cfi, ignoreClass); } } /** * Hook to adjust images to fit in columns * @param {Contents} contents * @private */ }, { key: "adjustImages", value: function adjustImages(contents) { if (this._layout.name === "pre-paginated") { return new Promise(function (resolve) { resolve(); }); } var computed = contents.window.getComputedStyle(contents.content, null); var height = contents.content.offsetHeight - (parseFloat(computed.paddingTop) + parseFloat(computed.paddingBottom)); contents.addStylesheetRules({ "img": { "max-width": (this._layout.columnWidth ? this._layout.columnWidth + "px" : "100%") + "!important", "max-height": height + "px" + "!important", "object-fit": "contain", "page-break-inside": "avoid", "break-inside": "avoid" }, "svg": { "max-width": (this._layout.columnWidth ? this._layout.columnWidth + "px" : "100%") + "!important", "max-height": height + "px" + "!important", "page-break-inside": "avoid", "break-inside": "avoid" } }); return new Promise(function (resolve, reject) { // Wait to apply setTimeout(function () { resolve(); }, 1); }); } /** * Get the Contents object of each rendered view * @returns {Contents[]} */ }, { key: "getContents", value: function getContents() { return this.manager ? this.manager.getContents() : []; } /** * Get the views member from the manager * @returns {Views} */ }, { key: "views", value: function views() { var views = this.manager ? this.manager.views : undefined; return views || []; } /** * Hook to handle link clicks in rendered content * @param {Contents} contents * @private */ }, { key: "handleLinks", value: function handleLinks(contents) { var _this6 = this; if (contents) { contents.on(_constants.EVENTS.CONTENTS.LINK_CLICKED, function (href) { var relative = _this6.book.path.relative(href); _this6.display(relative); }); } } /** * Hook to handle injecting stylesheet before * a Section is serialized * @param {document} doc * @param {Section} section * @private */ }, { key: "injectStylesheet", value: function injectStylesheet(doc, section) { var style = doc.createElement("link"); style.setAttribute("type", "text/css"); style.setAttribute("rel", "stylesheet"); style.setAttribute("href", this.settings.stylesheet); doc.getElementsByTagName("head")[0].appendChild(style); } /** * Hook to handle injecting scripts before * a Section is serialized * @param {document} doc * @param {Section} section * @private */ }, { key: "injectScript", value: function injectScript(doc, section) { var script = doc.createElement("script"); script.setAttribute("type", "text/javascript"); script.setAttribute("src", this.settings.script); script.textContent = " "; // Needed to prevent self closing tag doc.getElementsByTagName("head")[0].appendChild(script); } /** * Hook to handle the document identifier before * a Section is serialized * @param {document} doc * @param {Section} section * @private */ }, { key: "injectIdentifier", value: function injectIdentifier(doc, section) { var ident = this.book.package.metadata.identifier; var meta = doc.createElement("meta"); meta.setAttribute("name", "dc.relation.ispartof"); if (ident) { meta.setAttribute("content", ident); } doc.getElementsByTagName("head")[0].appendChild(meta); } }]); return Rendition; }(); //-- Enable binding events to Renderer (0, _eventEmitter2.default)(Rendition.prototype); exports.default = Rendition; module.exports = exports["default"]; /***/ }), /* 19 */ /***/ (function(module, exports, __webpack_require__) { "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 = __webpack_require__(1); var _epubcfi2 = _interopRequireDefault(_epubcfi); var _core = __webpack_require__(0); 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"); } } /** * Map text locations to CFI ranges * @class * @param {Layout} layout Layout to apply * @param {string} [direction="ltr"] Text direction * @param {string} [axis="horizontal"] vertical or horizontal axis * @param {boolean} [dev] toggle developer highlighting */ var Mapping = function () { function Mapping(layout, direction, axis, dev) { _classCallCheck(this, Mapping); this.layout = layout; this.horizontal = axis === "horizontal" ? true : false; this.direction = direction || "ltr"; this._dev = dev; } /** * Find CFI pairs for entire section at once */ _createClass(Mapping, [{ key: "section", value: function section(view) { var ranges = this.findRanges(view); var map = this.rangeListToCfiList(view.section.cfiBase, ranges); return map; } /** * Find CFI pairs for a page * @param {Contents} contents Contents from view * @param {string} cfiBase string of the base for a cfi * @param {number} start position to start at * @param {number} end position to end at */ }, { key: "page", value: function page(contents, cfiBase, start, end) { var root = contents && contents.document ? contents.document.body : false; var result; if (!root) { return; } result = this.rangePairToCfiPair(cfiBase, { start: this.findStart(root, start, end), end: this.findEnd(root, start, end) }); if (this._dev === true) { var doc = contents.document; var startRange = new _epubcfi2.default(result.start).toRange(doc); var endRange = new _epubcfi2.default(result.end).toRange(doc); var selection = doc.defaultView.getSelection(); var r = doc.createRange(); selection.removeAllRanges(); r.setStart(startRange.startContainer, startRange.startOffset); r.setEnd(endRange.endContainer, endRange.endOffset); selection.addRange(r); } return result; } /** * Walk a node, preforming a function on each node it finds * @private * @param {Node} root Node to walkToNode * @param {function} func walk function * @return {*} returns the result of the walk function */ }, { key: "walk", value: function walk(root, func) { // IE11 has strange issue, if root is text node IE throws exception on // calling treeWalker.nextNode(), saying // Unexpected call to method or property access instead of returing null value if (root && root.nodeType === Node.TEXT_NODE) { return; } // safeFilter is required so that it can work in IE as filter is a function for IE // and for other browser filter is an object. var filter = { acceptNode: function acceptNode(node) { if (node.data.trim().length > 0) { return NodeFilter.FILTER_ACCEPT; } else { return NodeFilter.FILTER_REJECT; } } }; var safeFilter = filter.acceptNode; safeFilter.acceptNode = filter.acceptNode; var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, safeFilter, false); var node; var result; while (node = treeWalker.nextNode()) { result = func(node); if (result) break; } return result; } }, { key: "findRanges", value: function findRanges(view) { var columns = []; var scrollWidth = view.contents.scrollWidth(); var spreads = Math.ceil(scrollWidth / this.layout.spreadWidth); var count = spreads * this.layout.divisor; var columnWidth = this.layout.columnWidth; var gap = this.layout.gap; var start, end; for (var i = 0; i < count.pages; i++) { start = (columnWidth + gap) * i; end = columnWidth * (i + 1) + gap * i; columns.push({ start: this.findStart(view.document.body, start, end), end: this.findEnd(view.document.body, start, end) }); } return columns; } /** * Find Start Range * @private * @param {Node} root root node * @param {number} start position to start at * @param {number} end position to end at * @return {Range} */ }, { key: "findStart", value: function findStart(root, start, end) { var _this = this; var stack = [root]; var $el; var found; var $prev = root; while (stack.length) { $el = stack.shift(); found = this.walk($el, function (node) { var left, right, top, bottom; var elPos; var elRange; elPos = (0, _core.nodeBounds)(node); if (_this.horizontal && _this.direction === "ltr") { left = _this.horizontal ? elPos.left : elPos.top; right = _this.horizontal ? elPos.right : elPos.bottom; if (left >= start && left <= end) { return node; } else if (right > start) { return node; } else { $prev = node; stack.push(node); } } else if (_this.horizontal && _this.direction === "rtl") { left = elPos.left; right = elPos.right; if (right <= end && right >= start) { return node; } else if (left < end) { return node; } else { $prev = node; stack.push(node); } } else { top = elPos.top; bottom = elPos.bottom; if (top >= start && top <= end) { return node; } else if (bottom > start) { return node; } else { $prev = node; stack.push(node); } } }); if (found) { return this.findTextStartRange(found, start, end); } } // Return last element return this.findTextStartRange($prev, start, end); } /** * Find End Range * @private * @param {Node} root root node * @param {number} start position to start at * @param {number} end position to end at * @return {Range} */ }, { key: "findEnd", value: function findEnd(root, start, end) { var _this2 = this; var stack = [root]; var $el; var $prev = root; var found; while (stack.length) { $el = stack.shift(); found = this.walk($el, function (node) { var left, right, top, bottom; var elPos; var elRange; elPos = (0, _core.nodeBounds)(node); if (_this2.horizontal && _this2.direction === "ltr") { left = Math.round(elPos.left); right = Math.round(elPos.right); if (left > end && $prev) { return $prev; } else if (right > end) { return node; } else { $prev = node; stack.push(node); } } else if (_this2.horizontal && _this2.direction === "rtl") { left = Math.round(_this2.horizontal ? elPos.left : elPos.top); right = Math.round(_this2.horizontal ? elPos.right : elPos.bottom); if (right < start && $prev) { return $prev; } else if (left < start) { return node; } else { $prev = node; stack.push(node); } } else { top = Math.round(elPos.top); bottom = Math.round(elPos.bottom); if (top > end && $prev) { return $prev; } else if (bottom > end) { return node; } else { $prev = node; stack.push(node); } } }); if (found) { return this.findTextEndRange(found, start, end); } } // end of chapter return this.findTextEndRange($prev, start, end); } /** * Find Text Start Range * @private * @param {Node} root root node * @param {number} start position to start at * @param {number} end position to end at * @return {Range} */ }, { key: "findTextStartRange", value: function findTextStartRange(node, start, end) { var ranges = this.splitTextNodeIntoRanges(node); var range; var pos; var left, top, right; for (var i = 0; i < ranges.length; i++) { range = ranges[i]; pos = range.getBoundingClientRect(); if (this.horizontal && this.direction === "ltr") { left = pos.left; if (left >= start) { return range; } } else if (this.horizontal && this.direction === "rtl") { right = pos.right; if (right <= end) { return range; } } else { top = pos.top; if (top >= start) { return range; } } // prev = range; } return ranges[0]; } /** * Find Text End Range * @private * @param {Node} root root node * @param {number} start position to start at * @param {number} end position to end at * @return {Range} */ }, { key: "findTextEndRange", value: function findTextEndRange(node, start, end) { var ranges = this.splitTextNodeIntoRanges(node); var prev; var range; var pos; var left, right, top, bottom; for (var i = 0; i < ranges.length; i++) { range = ranges[i]; pos = range.getBoundingClientRect(); if (this.horizontal && this.direction === "ltr") { left = pos.left; right = pos.right; if (left > end && prev) { return prev; } else if (right > end) { return range; } } else if (this.horizontal && this.direction === "rtl") { left = pos.left; right = pos.right; if (right < start && prev) { return prev; } else if (left < start) { return range; } } else { top = pos.top; bottom = pos.bottom; if (top > end && prev) { return prev; } else if (bottom > end) { return range; } } prev = range; } // Ends before limit return ranges[ranges.length - 1]; } /** * Split up a text node into ranges for each word * @private * @param {Node} root root node * @param {string} [_splitter] what to split on * @return {Range[]} */ }, { key: "splitTextNodeIntoRanges", value: function splitTextNodeIntoRanges(node, _splitter) { var ranges = []; var textContent = node.textContent || ""; var text = textContent.trim(); var range; var doc = node.ownerDocument; var splitter = _splitter || " "; var pos = text.indexOf(splitter); if (pos === -1 || node.nodeType != Node.TEXT_NODE) { range = doc.createRange(); range.selectNodeContents(node); return [range]; } range = doc.createRange(); range.setStart(node, 0); range.setEnd(node, pos); ranges.push(range); range = false; while (pos != -1) { pos = text.indexOf(splitter, pos + 1); if (pos > 0) { if (range) { range.setEnd(node, pos); ranges.push(range); } range = doc.createRange(); range.setStart(node, pos + 1); } } if (range) { range.setEnd(node, text.length); ranges.push(range); } return ranges; } /** * Turn a pair of ranges into a pair of CFIs * @private * @param {string} cfiBase base string for an EpubCFI * @param {object} rangePair { start: Range, end: Range } * @return {object} { start: "epubcfi(...)", end: "epubcfi(...)" } */ }, { key: "rangePairToCfiPair", value: function rangePairToCfiPair(cfiBase, rangePair) { var startRange = rangePair.start; var endRange = rangePair.end; startRange.collapse(true); endRange.collapse(false); var startCfi = new _epubcfi2.default(startRange, cfiBase).toString(); var endCfi = new _epubcfi2.default(endRange, cfiBase).toString(); return { start: startCfi, end: endCfi }; } }, { key: "rangeListToCfiList", value: function rangeListToCfiList(cfiBase, columns) { var map = []; var cifPair; for (var i = 0; i < columns.length; i++) { cifPair = this.rangePairToCfiPair(cfiBase, columns[i]); map.push(cifPair); } return map; } /** * Set the axis for mapping * @param {string} axis horizontal | vertical * @return {boolean} is it horizontal? */ }, { key: "axis", value: function axis(_axis) { if (_axis) { this.horizontal = _axis === "horizontal" ? true : false; } return this.horizontal; } }]); return Mapping; }(); exports.default = Mapping; module.exports = exports["default"]; /***/ }), /* 20 */ /***/ (function(module, exports, __webpack_require__) { "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 _eventEmitter = __webpack_require__(3); var _eventEmitter2 = _interopRequireDefault(_eventEmitter); var _core = __webpack_require__(0); var _epubcfi = __webpack_require__(1); var _epubcfi2 = _interopRequireDefault(_epubcfi); var _contents = __webpack_require__(13); var _contents2 = _interopRequireDefault(_contents); var _constants = __webpack_require__(2); var _marksPane = __webpack_require__(56); 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"); } } var IframeView = function () { function IframeView(section, options) { _classCallCheck(this, IframeView); this.settings = (0, _core.extend)({ ignoreClass: "", axis: options.layout && options.layout.props.flow === "scrolled" ? "vertical" : "horizontal", direction: undefined, width: 0, height: 0, layout: undefined, globalLayoutProperties: {}, method: undefined }, options || {}); this.id = "epubjs-view-" + (0, _core.uuid)(); this.section = section; this.index = section.index; this.element = this.container(this.settings.axis); this.added = false; this.displayed = false; this.rendered = false; // this.width = this.settings.width; // this.height = this.settings.height; this.fixedWidth = 0; this.fixedHeight = 0; // Blank Cfi for Parsing this.epubcfi = new _epubcfi2.default(); this.layout = this.settings.layout; // Dom events to listen for // this.listenedEvents = ["keydown", "keyup", "keypressed", "mouseup", "mousedown", "click", "touchend", "touchstart"]; this.pane = undefined; this.highlights = {}; this.underlines = {}; this.marks = {}; } _createClass(IframeView, [{ key: "container", value: function container(axis) { var element = document.createElement("div"); element.classList.add("epub-view"); // this.element.style.minHeight = "100px"; element.style.height = "0px"; element.style.width = "0px"; element.style.overflow = "hidden"; element.style.position = "relative"; element.style.display = "block"; if (axis && axis == "horizontal") { element.style.flex = "none"; } else { element.style.flex = "initial"; } return element; } }, { key: "create", value: function create() { if (this.iframe) { return this.iframe; } if (!this.element) { this.element = this.createContainer(); } this.iframe = document.createElement("iframe"); this.iframe.id = this.id; this.iframe.scrolling = "no"; // Might need to be removed: breaks ios width calculations this.iframe.style.overflow = "hidden"; this.iframe.seamless = "seamless"; // Back up if seamless isn't supported this.iframe.style.border = "none"; this.iframe.setAttribute("enable-annotation", "true"); this.resizing = true; // this.iframe.style.display = "none"; this.element.style.visibility = "hidden"; this.iframe.style.visibility = "hidden"; this.iframe.style.width = "0"; this.iframe.style.height = "0"; this._width = 0; this._height = 0; this.element.setAttribute("ref", this.index); this.element.appendChild(this.iframe); this.added = true; this.elementBounds = (0, _core.bounds)(this.element); // if(width || height){ // this.resize(width, height); // } else if(this.width && this.height){ // this.resize(this.width, this.height); // } else { // this.iframeBounds = bounds(this.iframe); // } // if ("srcdoc" in this.iframe) { // this.supportsSrcdoc = true; // } else { // this.supportsSrcdoc = false; // } this.supportsSrcdoc = false; if (!this.settings.method) { this.settings.method = this.supportsSrcdoc ? "srcdoc" : "write"; } return this.iframe; } }, { key: "render", value: function render(request, show) { // view.onLayout = this.layout.format.bind(this.layout); this.create(); // Fit to size of the container, apply padding this.size(); if (!this.sectionRender) { this.sectionRender = this.section.render(request); } // Render Chain return this.sectionRender.then(function (contents) { return this.load(contents); }.bind(this)).then(function () { var _this = this; // apply the layout function to the contents this.layout.format(this.contents); // find and report the writingMode axis var writingMode = this.contents.writingMode(); var axis = writingMode.indexOf("vertical") === 0 ? "vertical" : "horizontal"; this.setAxis(axis); this.emit(_constants.EVENTS.VIEWS.AXIS, axis); // Listen for events that require an expansion of the iframe this.addListeners(); return new Promise(function (resolve, reject) { // Expand the iframe to the full size of the content _this.expand(); resolve(); }); }.bind(this), function (e) { this.emit(_constants.EVENTS.VIEWS.LOAD_ERROR, e); return new Promise(function (resolve, reject) { reject(e); }); }.bind(this)).then(function () { this.emit(_constants.EVENTS.VIEWS.RENDERED, this.section); }.bind(this)); } }, { key: "reset", value: function reset() { if (this.iframe) { this.iframe.style.width = "0"; this.iframe.style.height = "0"; this._width = 0; this._height = 0; this._textWidth = undefined; this._contentWidth = undefined; this._textHeight = undefined; this._contentHeight = undefined; } this._needsReframe = true; } // Determine locks base on settings }, { key: "size", value: function size(_width, _height) { var width = _width || this.settings.width; var height = _height || this.settings.height; if (this.layout.name === "pre-paginated") { this.lock("both", width, height); } else if (this.settings.axis === "horizontal") { this.lock("height", width, height); } else { this.lock("width", width, height); } this.settings.width = width; this.settings.height = height; } // Lock an axis to element dimensions, taking borders into account }, { key: "lock", value: function lock(what, width, height) { var elBorders = (0, _core.borders)(this.element); var iframeBorders; if (this.iframe) { iframeBorders = (0, _core.borders)(this.iframe); } else { iframeBorders = { width: 0, height: 0 }; } if (what == "width" && (0, _core.isNumber)(width)) { this.lockedWidth = width - elBorders.width - iframeBorders.width; // this.resize(this.lockedWidth, width); // width keeps ratio correct } if (what == "height" && (0, _core.isNumber)(height)) { this.lockedHeight = height - elBorders.height - iframeBorders.height; // this.resize(width, this.lockedHeight); } if (what === "both" && (0, _core.isNumber)(width) && (0, _core.isNumber)(height)) { this.lockedWidth = width - elBorders.width - iframeBorders.width; this.lockedHeight = height - elBorders.height - iframeBorders.height; // this.resize(this.lockedWidth, this.lockedHeight); } if (this.displayed && this.iframe) { // this.contents.layout(); this.expand(); } } // Resize a single axis based on content dimensions }, { key: "expand", value: function expand(force) { var width = this.lockedWidth; var height = this.lockedHeight; var columns; var textWidth, textHeight; if (!this.iframe || this._expanding) return; this._expanding = true; if (this.layout.name === "pre-paginated") { width = this.layout.columnWidth; height = this.layout.height; } // Expand Horizontally else if (this.settings.axis === "horizontal") { // Get the width of the text width = this.contents.textWidth(); if (width % this.layout.pageWidth > 0) { width = Math.ceil(width / this.layout.pageWidth) * this.layout.pageWidth; } if (this.settings.forceEvenPages) { columns = width / this.layout.pageWidth; if (this.layout.divisor > 1 && this.layout.name === "reflowable" && columns % 2 > 0) { // add a blank page width += this.layout.pageWidth; } } } // Expand Vertically else if (this.settings.axis === "vertical") { height = this.contents.textHeight(); } // Only Resize if dimensions have changed or // if Frame is still hidden, so needs reframing if (this._needsReframe || width != this._width || height != this._height) { this.reframe(width, height); } this._expanding = false; } }, { key: "reframe", value: function reframe(width, height) { var _this2 = this; var size; if ((0, _core.isNumber)(width)) { this.element.style.width = width + "px"; this.iframe.style.width = width + "px"; this._width = width; } if ((0, _core.isNumber)(height)) { this.element.style.height = height + "px"; this.iframe.style.height = height + "px"; this._height = height; } var widthDelta = this.prevBounds ? width - this.prevBounds.width : width; var heightDelta = this.prevBounds ? height - this.prevBounds.height : height; size = { width: width, height: height, widthDelta: widthDelta, heightDelta: heightDelta }; this.pane && this.pane.render(); requestAnimationFrame(function () { var mark = void 0; for (var m in _this2.marks) { if (_this2.marks.hasOwnProperty(m)) { mark = _this2.marks[m]; _this2.placeMark(mark.element, mark.range); } } }); this.onResize(this, size); this.emit(_constants.EVENTS.VIEWS.RESIZED, size); this.prevBounds = size; this.elementBounds = (0, _core.bounds)(this.element); } }, { key: "load", value: function load(contents) { var loading = new _core.defer(); var loaded = loading.promise; if (!this.iframe) { loading.reject(new Error("No Iframe Available")); return loaded; } this.iframe.onload = function (event) { this.onLoad(event, loading); }.bind(this); if (this.settings.method === "blobUrl") { this.blobUrl = (0, _core.createBlobUrl)(contents, "application/xhtml+xml"); this.iframe.src = this.blobUrl; } else if (this.settings.method === "srcdoc") { this.iframe.srcdoc = contents; } else { this.document = this.iframe.contentDocument; if (!this.document) { loading.reject(new Error("No Document Available")); return loaded; } this.iframe.contentDocument.open(); this.iframe.contentDocument.write(contents); this.iframe.contentDocument.close(); } return loaded; } }, { key: "onLoad", value: function onLoad(event, promise) { var _this3 = this; this.window = this.iframe.contentWindow; this.document = this.iframe.contentDocument; this.contents = new _contents2.default(this.document, this.document.body, this.section.cfiBase, this.section.index); this.rendering = false; var link = this.document.querySelector("link[rel='canonical']"); if (link) { link.setAttribute("href", this.section.canonical); } else { link = this.document.createElement("link"); link.setAttribute("rel", "canonical"); link.setAttribute("href", this.section.canonical); this.document.querySelector("head").appendChild(link); } this.contents.on(_constants.EVENTS.CONTENTS.EXPAND, function () { if (_this3.displayed && _this3.iframe) { _this3.expand(); if (_this3.contents) { _this3.layout.format(_this3.contents); } } }); this.contents.on(_constants.EVENTS.CONTENTS.RESIZE, function (e) { if (_this3.displayed && _this3.iframe) { _this3.expand(); if (_this3.contents) { _this3.layout.format(_this3.contents); } } }); promise.resolve(this.contents); } }, { key: "setLayout", value: function setLayout(layout) { this.layout = layout; if (this.contents) { this.layout.format(this.contents); this.expand(); } } }, { key: "setAxis", value: function setAxis(axis) { // Force vertical for scrolled if (this.layout.props.flow === "scrolled") { axis = "vertical"; } this.settings.axis = axis; if (axis == "horizontal") { this.element.style.flex = "none"; } else { this.element.style.flex = "initial"; } this.size(); } }, { key: "addListeners", value: function addListeners() { //TODO: Add content listeners for expanding } }, { key: "removeListeners", value: function removeListeners(layoutFunc) { //TODO: remove content listeners for expanding } }, { key: "display", value: function display(request) { var displayed = new _core.defer(); if (!this.displayed) { this.render(request).then(function () { this.emit(_constants.EVENTS.VIEWS.DISPLAYED, this); this.onDisplayed(this); this.displayed = true; displayed.resolve(this); }.bind(this), function (err) { displayed.reject(err, this); }); } else { displayed.resolve(this); } return displayed.promise; } }, { key: "show", value: function show() { this.element.style.visibility = "visible"; if (this.iframe) { this.iframe.style.visibility = "visible"; // Remind Safari to redraw the iframe this.iframe.style.transform = "translateZ(0)"; this.iframe.offsetWidth; this.iframe.style.transform = null; } this.emit(_constants.EVENTS.VIEWS.SHOWN, this); } }, { key: "hide", value: function hide() { // this.iframe.style.display = "none"; this.element.style.visibility = "hidden"; this.iframe.style.visibility = "hidden"; this.stopExpanding = true; this.emit(_constants.EVENTS.VIEWS.HIDDEN, this); } }, { key: "offset", value: function offset() { return { top: this.element.offsetTop, left: this.element.offsetLeft }; } }, { key: "width", value: function width() { return this._width; } }, { key: "height", value: function height() { return this._height; } }, { key: "position", value: function position() { return this.element.getBoundingClientRect(); } }, { key: "locationOf", value: function locationOf(target) { var parentPos = this.iframe.getBoundingClientRect(); var targetPos = this.contents.locationOf(target, this.settings.ignoreClass); return { "left": targetPos.left, "top": targetPos.top }; } }, { key: "onDisplayed", value: function onDisplayed(view) { // Stub, override with a custom functions } }, { key: "onResize", value: function onResize(view, e) { // Stub, override with a custom functions } }, { key: "bounds", value: function bounds(force) { if (force || !this.elementBounds) { this.elementBounds = (0, _core.bounds)(this.element); } return this.elementBounds; } }, { key: "highlight", value: function highlight(cfiRange) { var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var cb = arguments[2]; var _this4 = this; var className = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : "epubjs-hl"; var styles = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; if (!this.contents) { return; } var attributes = Object.assign({ "fill": "yellow", "fill-opacity": "0.3", "mix-blend-mode": "multiply" }, styles); var range = this.contents.range(cfiRange); var emitter = function emitter() { _this4.emit(_constants.EVENTS.VIEWS.MARK_CLICKED, cfiRange, data); }; data["epubcfi"] = cfiRange; if (!this.pane) { this.pane = new _marksPane.Pane(this.iframe, this.element); } var m = new _marksPane.Highlight(range, className, data, attributes); var h = this.pane.addMark(m); this.highlights[cfiRange] = { "mark": h, "element": h.element, "listeners": [emitter, cb] }; h.element.setAttribute("ref", className); h.element.addEventListener("click", emitter); h.element.addEventListener("touchstart", emitter); if (cb) { h.element.addEventListener("click", cb); h.element.addEventListener("touchstart", cb); } return h; } }, { key: "underline", value: function underline(cfiRange) { var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var cb = arguments[2]; var _this5 = this; var className = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : "epubjs-ul"; var styles = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; if (!this.contents) { return; } var attributes = Object.assign({ "stroke": "black", "stroke-opacity": "0.3", "mix-blend-mode": "multiply" }, styles); var range = this.contents.range(cfiRange); var emitter = function emitter() { _this5.emit(_constants.EVENTS.VIEWS.MARK_CLICKED, cfiRange, data); }; data["epubcfi"] = cfiRange; if (!this.pane) { this.pane = new _marksPane.Pane(this.iframe, this.element); } var m = new _marksPane.Underline(range, className, data, attributes); var h = this.pane.addMark(m); this.underlines[cfiRange] = { "mark": h, "element": h.element, "listeners": [emitter, cb] }; h.element.setAttribute("ref", className); h.element.addEventListener("click", emitter); h.element.addEventListener("touchstart", emitter); if (cb) { h.element.addEventListener("click", cb); h.element.addEventListener("touchstart", cb); } return h; } }, { key: "mark", value: function mark(cfiRange) { var _this6 = this; var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var cb = arguments[2]; if (!this.contents) { return; } if (cfiRange in this.marks) { var item = this.marks[cfiRange]; return item; } var range = this.contents.range(cfiRange); if (!range) { return; } var container = range.commonAncestorContainer; var parent = container.nodeType === 1 ? container : container.parentNode; var emitter = function emitter(e) { _this6.emit(_constants.EVENTS.VIEWS.MARK_CLICKED, cfiRange, data); }; if (range.collapsed && container.nodeType === 1) { range = new Range(); range.selectNodeContents(container); } else if (range.collapsed) { // Webkit doesn't like collapsed ranges range = new Range(); range.selectNodeContents(parent); } var mark = this.document.createElement("a"); mark.setAttribute("ref", "epubjs-mk"); mark.style.position = "absolute"; mark.dataset["epubcfi"] = cfiRange; if (data) { Object.keys(data).forEach(function (key) { mark.dataset[key] = data[key]; }); } if (cb) { mark.addEventListener("click", cb); mark.addEventListener("touchstart", cb); } mark.addEventListener("click", emitter); mark.addEventListener("touchstart", emitter); this.placeMark(mark, range); this.element.appendChild(mark); this.marks[cfiRange] = { "element": mark, "range": range, "listeners": [emitter, cb] }; return parent; } }, { key: "placeMark", value: function placeMark(element, range) { var top = void 0, right = void 0, left = void 0; if (this.layout.name === "pre-paginated" || this.settings.axis !== "horizontal") { var pos = range.getBoundingClientRect(); top = pos.top; right = pos.right; } else { // Element might break columns, so find the left most element var rects = range.getClientRects(); var rect = void 0; for (var i = 0; i != rects.length; i++) { rect = rects[i]; if (!left || rect.left < left) { left = rect.left; right = left + this.layout.columnWidth - this.layout.gap; top = rect.top; } } } element.style.top = top + "px"; element.style.left = right + "px"; } }, { key: "unhighlight", value: function unhighlight(cfiRange) { var item = void 0; if (cfiRange in this.highlights) { item = this.highlights[cfiRange]; this.pane.removeMark(item.mark); item.listeners.forEach(function (l) { if (l) { item.element.removeEventListener("click", l); }; }); delete this.highlights[cfiRange]; } } }, { key: "ununderline", value: function ununderline(cfiRange) { var item = void 0; if (cfiRange in this.underlines) { item = this.underlines[cfiRange]; this.pane.removeMark(item.mark); item.listeners.forEach(function (l) { if (l) { item.element.removeEventListener("click", l); }; }); delete this.underlines[cfiRange]; } } }, { key: "unmark", value: function unmark(cfiRange) { var item = void 0; if (cfiRange in this.marks) { item = this.marks[cfiRange]; this.element.removeChild(item.element); item.listeners.forEach(function (l) { if (l) { item.element.removeEventListener("click", l); }; }); delete this.marks[cfiRange]; } } }, { key: "destroy", value: function destroy() { for (var cfiRange in this.highlights) { this.unhighlight(cfiRange); } for (var _cfiRange in this.underlines) { this.ununderline(_cfiRange); } for (var _cfiRange2 in this.marks) { this.unmark(_cfiRange2); } if (this.blobUrl) { (0, _core.revokeBlobUrl)(this.blobUrl); } if (this.displayed) { this.displayed = false; this.removeListeners(); this.stopExpanding = true; this.element.removeChild(this.iframe); this.iframe = undefined; this.contents = undefined; this._textWidth = null; this._textHeight = null; this._width = null; this._height = null; } // this.element.style.height = "0px"; // this.element.style.width = "0px"; } }]); return IframeView; }(); (0, _eventEmitter2.default)(IframeView.prototype); exports.default = IframeView; module.exports = exports["default"]; /***/ }), /* 21 */ /***/ (function(module, exports, __webpack_require__) { var isObject = __webpack_require__(15), now = __webpack_require__(61), toNumber = __webpack_require__(63); /** Error message constants. */ var FUNC_ERROR_TEXT = 'Expected a function'; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeMax = Math.max, nativeMin = Math.min; /** * Creates a debounced function that delays invoking `func` until after `wait` * milliseconds have elapsed since the last time the debounced function was * invoked. The debounced function comes with a `cancel` method to cancel * delayed `func` invocations and a `flush` method to immediately invoke them. * Provide `options` to indicate whether `func` should be invoked on the * leading and/or trailing edge of the `wait` timeout. The `func` is invoked * with the last arguments provided to the debounced function. Subsequent * calls to the debounced function return the result of the last `func` * invocation. * * **Note:** If `leading` and `trailing` options are `true`, `func` is * invoked on the trailing edge of the timeout only if the debounced function * is invoked more than once during the `wait` timeout. * * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred * until to the next tick, similar to `setTimeout` with a timeout of `0`. * * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) * for details over the differences between `_.debounce` and `_.throttle`. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to debounce. * @param {number} [wait=0] The number of milliseconds to delay. * @param {Object} [options={}] The options object. * @param {boolean} [options.leading=false] * Specify invoking on the leading edge of the timeout. * @param {number} [options.maxWait] * The maximum time `func` is allowed to be delayed before it's invoked. * @param {boolean} [options.trailing=true] * Specify invoking on the trailing edge of the timeout. * @returns {Function} Returns the new debounced function. * @example * * // Avoid costly calculations while the window size is in flux. * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); * * // Invoke `sendMail` when clicked, debouncing subsequent calls. * jQuery(element).on('click', _.debounce(sendMail, 300, { * 'leading': true, * 'trailing': false * })); * * // Ensure `batchLog` is invoked once after 1 second of debounced calls. * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); * var source = new EventSource('/stream'); * jQuery(source).on('message', debounced); * * // Cancel the trailing debounced invocation. * jQuery(window).on('popstate', debounced.cancel); */ function debounce(func, wait, options) { var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true; if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } wait = toNumber(wait) || 0; if (isObject(options)) { leading = !!options.leading; maxing = 'maxWait' in options; maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; trailing = 'trailing' in options ? !!options.trailing : trailing; } function invokeFunc(time) { var args = lastArgs, thisArg = lastThis; lastArgs = lastThis = undefined; lastInvokeTime = time; result = func.apply(thisArg, args); return result; } function leadingEdge(time) { // Reset any `maxWait` timer. lastInvokeTime = time; // Start the timer for the trailing edge. timerId = setTimeout(timerExpired, wait); // Invoke the leading edge. return leading ? invokeFunc(time) : result; } function remainingWait(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, result = wait - timeSinceLastCall; return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result; } function shouldInvoke(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime; // Either this is the first call, activity has stopped and we're at the // trailing edge, the system time has gone backwards and we're treating // it as the trailing edge, or we've hit the `maxWait` limit. return (lastCallTime === undefined || (timeSinceLastCall >= wait) || (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); } function timerExpired() { var time = now(); if (shouldInvoke(time)) { return trailingEdge(time); } // Restart the timer. timerId = setTimeout(timerExpired, remainingWait(time)); } function trailingEdge(time) { timerId = undefined; // Only invoke if we have `lastArgs` which means `func` has been // debounced at least once. if (trailing && lastArgs) { return invokeFunc(time); } lastArgs = lastThis = undefined; return result; } function cancel() { if (timerId !== undefined) { clearTimeout(timerId); } lastInvokeTime = 0; lastArgs = lastCallTime = lastThis = timerId = undefined; } function flush() { return timerId === undefined ? result : trailingEdge(now()); } function debounced() { var time = now(), isInvoking = shouldInvoke(time); lastArgs = arguments; lastThis = this; lastCallTime = time; if (isInvoking) { if (timerId === undefined) { return leadingEdge(lastCallTime); } if (maxing) { // Handle invocations in a tight loop. timerId = setTimeout(timerExpired, wait); return invokeFunc(lastCallTime); } } if (timerId === undefined) { timerId = setTimeout(timerExpired, wait); } return result; } debounced.cancel = cancel; debounced.flush = flush; return debounced; } module.exports = debounce; /***/ }), /* 22 */ /***/ (function(module, exports, __webpack_require__) { var freeGlobal = __webpack_require__(62); /** Detect free variable `self`. */ var freeSelf = typeof self == 'object' && self && self.Object === Object && self; /** Used as a reference to the global object. */ var root = freeGlobal || freeSelf || Function('return this')(); module.exports = root; /***/ }), /* 23 */ /***/ (function(module, exports, __webpack_require__) { var root = __webpack_require__(22); /** Built-in value references. */ var Symbol = root.Symbol; module.exports = Symbol; /***/ }), /* 24 */ /***/ (function(module, exports, __webpack_require__) { "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 _core = __webpack_require__(0); var _default = __webpack_require__(14); var _default2 = _interopRequireDefault(_default); var _constants = __webpack_require__(2); var _debounce = __webpack_require__(21); var _debounce2 = _interopRequireDefault(_debounce); 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"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var ContinuousViewManager = function (_DefaultViewManager) { _inherits(ContinuousViewManager, _DefaultViewManager); function ContinuousViewManager(options) { _classCallCheck(this, ContinuousViewManager); var _this = _possibleConstructorReturn(this, (ContinuousViewManager.__proto__ || Object.getPrototypeOf(ContinuousViewManager)).call(this, options)); _this.name = "continuous"; _this.settings = (0, _core.extend)(_this.settings || {}, { infinite: true, overflow: undefined, axis: undefined, flow: "scrolled", offset: 500, offsetDelta: 250, width: undefined, height: undefined }); (0, _core.extend)(_this.settings, options.settings || {}); // Gap can be 0, but defaults doesn't handle that if (options.settings.gap != "undefined" && options.settings.gap === 0) { _this.settings.gap = options.settings.gap; } _this.viewSettings = { ignoreClass: _this.settings.ignoreClass, axis: _this.settings.axis, flow: _this.settings.flow, layout: _this.layout, width: 0, height: 0, forceEvenPages: false }; _this.scrollTop = 0; _this.scrollLeft = 0; return _this; } _createClass(ContinuousViewManager, [{ key: "display", value: function display(section, target) { return _default2.default.prototype.display.call(this, section, target).then(function () { return this.fill(); }.bind(this)); } }, { key: "fill", value: function fill(_full) { var _this2 = this; var full = _full || new _core.defer(); this.q.enqueue(function () { return _this2.check(); }).then(function (result) { if (result) { _this2.fill(full); } else { full.resolve(); } }); return full.promise; } }, { key: "moveTo", value: function moveTo(offset) { // var bounds = this.stage.bounds(); // var dist = Math.floor(offset.top / bounds.height) * bounds.height; var distX = 0, distY = 0; var offsetX = 0, offsetY = 0; if (!this.isPaginated) { distY = offset.top; offsetY = offset.top + this.settings.offset; } else { distX = Math.floor(offset.left / this.layout.delta) * this.layout.delta; offsetX = distX + this.settings.offset; } if (distX > 0 || distY > 0) { this.scrollBy(distX, distY, true); } } }, { key: "afterResized", value: function afterResized(view) { this.emit(_constants.EVENTS.MANAGERS.RESIZE, view.section); } // Remove Previous Listeners if present }, { key: "removeShownListeners", value: function removeShownListeners(view) { // view.off("shown", this.afterDisplayed); // view.off("shown", this.afterDisplayedAbove); view.onDisplayed = function () {}; } }, { key: "add", value: function add(section) { var _this3 = this; var view = this.createView(section); this.views.append(view); view.on(_constants.EVENTS.VIEWS.RESIZED, function (bounds) { view.expanded = true; }); view.on(_constants.EVENTS.VIEWS.AXIS, function (axis) { _this3.updateAxis(axis); }); // view.on(EVENTS.VIEWS.SHOWN, this.afterDisplayed.bind(this)); view.onDisplayed = this.afterDisplayed.bind(this); view.onResize = this.afterResized.bind(this); return view.display(this.request); } }, { key: "append", value: function append(section) { var view = this.createView(section); view.on(_constants.EVENTS.VIEWS.RESIZED, function (bounds) { view.expanded = true; }); /* view.on(EVENTS.VIEWS.AXIS, (axis) => { this.updateAxis(axis); }); */ this.views.append(view); view.onDisplayed = this.afterDisplayed.bind(this); return view; } }, { key: "prepend", value: function prepend(section) { var _this4 = this; var view = this.createView(section); view.on(_constants.EVENTS.VIEWS.RESIZED, function (bounds) { _this4.counter(bounds); view.expanded = true; }); /* view.on(EVENTS.VIEWS.AXIS, (axis) => { this.updateAxis(axis); }); */ this.views.prepend(view); view.onDisplayed = this.afterDisplayed.bind(this); return view; } }, { key: "counter", value: function counter(bounds) { if (this.settings.axis === "vertical") { this.scrollBy(0, bounds.heightDelta, true); } else { this.scrollBy(bounds.widthDelta, 0, true); } } }, { key: "update", value: function update(_offset) { var container = this.bounds(); var views = this.views.all(); var viewsLength = views.length; var visible = []; var offset = typeof _offset != "undefined" ? _offset : this.settings.offset || 0; var isVisible; var view; var updating = new _core.defer(); var promises = []; for (var i = 0; i < viewsLength; i++) { view = views[i]; isVisible = this.isVisible(view, offset, offset, container); if (isVisible === true) { // console.log("visible " + view.index); if (!view.displayed) { var displayed = view.display(this.request).then(function (view) { view.show(); }, function (err) { view.hide(); }); promises.push(displayed); } else { view.show(); } visible.push(view); } else { this.q.enqueue(view.destroy.bind(view)); // console.log("hidden " + view.index); clearTimeout(this.trimTimeout); this.trimTimeout = setTimeout(function () { this.q.enqueue(this.trim.bind(this)); }.bind(this), 250); } } if (promises.length) { return Promise.all(promises).catch(function (err) { updating.reject(err); }); } else { updating.resolve(); return updating.promise; } } }, { key: "check", value: function check(_offsetLeft, _offsetTop) { var _this5 = this; var checking = new _core.defer(); var newViews = []; var horizontal = this.settings.axis === "horizontal"; var delta = this.settings.offset || 0; if (_offsetLeft && horizontal) { delta = _offsetLeft; } if (_offsetTop && !horizontal) { delta = _offsetTop; } var bounds = this._bounds; // bounds saved this until resize var rtl = this.settings.direction === "rtl"; var dir = horizontal && rtl ? -1 : 1; //RTL reverses scrollTop var offset = horizontal ? this.scrollLeft : this.scrollTop * dir; var visibleLength = horizontal ? Math.floor(bounds.width) : bounds.height; var contentLength = horizontal ? this.container.scrollWidth : this.container.scrollHeight; var prepend = function prepend() { var first = _this5.views.first(); var prev = first && first.section.prev(); if (prev) { newViews.push(_this5.prepend(prev)); } }; var append = function append() { var last = _this5.views.last(); var next = last && last.section.next(); if (next) { newViews.push(_this5.append(next)); } }; if (offset + visibleLength + delta >= contentLength) { if (horizontal && rtl) { prepend(); } else { append(); } } if (offset - delta < 0) { if (horizontal && rtl) { append(); } else { prepend(); } } var promises = newViews.map(function (view) { return view.displayed; }); if (newViews.length) { return Promise.all(promises).then(function () { if (_this5.layout.name === "pre-paginated" && _this5.layout.props.spread) { return _this5.check(); } }).then(function () { // Check to see if anything new is on screen after rendering return _this5.update(delta); }, function (err) { return err; }); } else { this.q.enqueue(function () { this.update(); }.bind(this)); checking.resolve(false); return checking.promise; } } }, { key: "trim", value: function trim() { var task = new _core.defer(); var displayed = this.views.displayed(); var first = displayed[0]; var last = displayed[displayed.length - 1]; var firstIndex = this.views.indexOf(first); var lastIndex = this.views.indexOf(last); var above = this.views.slice(0, firstIndex); var below = this.views.slice(lastIndex + 1); // Erase all but last above for (var i = 0; i < above.length - 1; i++) { this.erase(above[i], above); } // Erase all except first below for (var j = 1; j < below.length; j++) { this.erase(below[j]); } task.resolve(); return task.promise; } }, { key: "erase", value: function erase(view, above) { //Trim var prevTop; var prevLeft; if (!this.settings.fullsize) { prevTop = this.container.scrollTop; prevLeft = this.container.scrollLeft; } else { prevTop = window.scrollY; prevLeft = window.scrollX; } var bounds = view.bounds(); this.views.remove(view); if (above) { if (this.settings.axis === "vertical") { this.scrollTo(0, prevTop - bounds.height, true); } else { this.scrollTo(prevLeft - Math.floor(bounds.width), 0, true); } } } }, { key: "addEventListeners", value: function addEventListeners(stage) { window.addEventListener("unload", function (e) { this.ignore = true; // this.scrollTo(0,0); this.destroy(); }.bind(this)); this.addScrollListeners(); } }, { key: "addScrollListeners", value: function addScrollListeners() { var scroller; this.tick = _core.requestAnimationFrame; if (!this.settings.fullsize) { this.prevScrollTop = this.container.scrollTop; this.prevScrollLeft = this.container.scrollLeft; } else { this.prevScrollTop = window.scrollY; this.prevScrollLeft = window.scrollX; } this.scrollDeltaVert = 0; this.scrollDeltaHorz = 0; if (!this.settings.fullsize) { scroller = this.container; this.scrollTop = this.container.scrollTop; this.scrollLeft = this.container.scrollLeft; } else { scroller = window; this.scrollTop = window.scrollY; this.scrollLeft = window.scrollX; } scroller.addEventListener("scroll", this.onScroll.bind(this)); this._scrolled = (0, _debounce2.default)(this.scrolled.bind(this), 30); // this.tick.call(window, this.onScroll.bind(this)); this.didScroll = false; } }, { key: "removeEventListeners", value: function removeEventListeners() { var scroller; if (!this.settings.fullsize) { scroller = this.container; } else { scroller = window; } scroller.removeEventListener("scroll", this.onScroll.bind(this)); } }, { key: "onScroll", value: function onScroll() { var scrollTop = void 0; var scrollLeft = void 0; var dir = this.settings.direction === "rtl" ? -1 : 1; if (!this.settings.fullsize) { scrollTop = this.container.scrollTop; scrollLeft = this.container.scrollLeft; } else { scrollTop = window.scrollY * dir; scrollLeft = window.scrollX * dir; } this.scrollTop = scrollTop; this.scrollLeft = scrollLeft; if (!this.ignore) { this._scrolled(); } else { this.ignore = false; } this.scrollDeltaVert += Math.abs(scrollTop - this.prevScrollTop); this.scrollDeltaHorz += Math.abs(scrollLeft - this.prevScrollLeft); this.prevScrollTop = scrollTop; this.prevScrollLeft = scrollLeft; clearTimeout(this.scrollTimeout); this.scrollTimeout = setTimeout(function () { this.scrollDeltaVert = 0; this.scrollDeltaHorz = 0; }.bind(this), 150); this.didScroll = false; } }, { key: "scrolled", value: function scrolled() { this.q.enqueue(function () { this.check(); }.bind(this)); this.emit(_constants.EVENTS.MANAGERS.SCROLL, { top: this.scrollTop, left: this.scrollLeft }); clearTimeout(this.afterScrolled); this.afterScrolled = setTimeout(function () { this.emit(_constants.EVENTS.MANAGERS.SCROLLED, { top: this.scrollTop, left: this.scrollLeft }); }.bind(this)); } }, { key: "next", value: function next() { var dir = this.settings.direction; var delta = this.layout.props.name === "pre-paginated" && this.layout.props.spread ? this.layout.props.delta * 2 : this.layout.props.delta; if (!this.views.length) return; if (this.isPaginated && this.settings.axis === "horizontal") { this.scrollBy(delta, 0, true); } else { this.scrollBy(0, this.layout.height, true); } this.q.enqueue(function () { this.check(); }.bind(this)); } }, { key: "prev", value: function prev() { var dir = this.settings.direction; var delta = this.layout.props.name === "pre-paginated" && this.layout.props.spread ? this.layout.props.delta * 2 : this.layout.props.delta; if (!this.views.length) return; if (this.isPaginated && this.settings.axis === "horizontal") { this.scrollBy(-delta, 0, true); } else { this.scrollBy(0, -this.layout.height, true); } this.q.enqueue(function () { this.check(); }.bind(this)); } }, { key: "updateAxis", value: function updateAxis(axis, forceUpdate) { if (!this.isPaginated) { axis = "vertical"; } if (!forceUpdate && axis === this.settings.axis) { return; } this.settings.axis = axis; this.stage && this.stage.axis(axis); this.viewSettings.axis = axis; if (this.mapping) { this.mapping.axis(axis); } if (this.layout) { if (axis === "vertical") { this.layout.spread("none"); } else { this.layout.spread(this.layout.settings.spread); } } if (axis === "vertical") { this.settings.infinite = true; } else { this.settings.infinite = false; } } }]); return ContinuousViewManager; }(_default2.default); exports.default = ContinuousViewManager; module.exports = exports["default"]; /***/ }), /* 25 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* WEBPACK VAR INJECTION */(function(global) { Object.defineProperty(exports, "__esModule", { value: true }); var _book = __webpack_require__(26); var _book2 = _interopRequireDefault(_book); var _rendition = __webpack_require__(18); var _rendition2 = _interopRequireDefault(_rendition); var _epubcfi = __webpack_require__(1); var _epubcfi2 = _interopRequireDefault(_epubcfi); var _contents = __webpack_require__(13); var _contents2 = _interopRequireDefault(_contents); var _core = __webpack_require__(0); var utils = _interopRequireWildcard(_core); var _constants = __webpack_require__(2); __webpack_require__(72); var _iframe = __webpack_require__(20); var _iframe2 = _interopRequireDefault(_iframe); var _default = __webpack_require__(14); var _default2 = _interopRequireDefault(_default); var _continuous = __webpack_require__(24); var _continuous2 = _interopRequireDefault(_continuous); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Creates a new Book * @param {string|ArrayBuffer} url URL, Path or ArrayBuffer * @param {object} options to pass to the book * @returns {Book} a new Book object * @example ePub("/path/to/book.epub", {}) */ function ePub(url, options) { return new _book2.default(url, options); } ePub.VERSION = _constants.EPUBJS_VERSION; if (typeof global !== "undefined") { global.EPUBJS_VERSION = _constants.EPUBJS_VERSION; } ePub.Book = _book2.default; ePub.Rendition = _rendition2.default; ePub.Contents = _contents2.default; ePub.CFI = _epubcfi2.default; ePub.utils = utils; exports.default = ePub; module.exports = exports["default"]; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(8))) /***/ }), /* 26 */ /***/ (function(module, exports, __webpack_require__) { "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 _eventEmitter = __webpack_require__(3); var _eventEmitter2 = _interopRequireDefault(_eventEmitter); var _core = __webpack_require__(0); var _url = __webpack_require__(5); var _url2 = _interopRequireDefault(_url); var _path = __webpack_require__(4); var _path2 = _interopRequireDefault(_path); var _spine = __webpack_require__(43); var _spine2 = _interopRequireDefault(_spine); var _locations = __webpack_require__(47); var _locations2 = _interopRequireDefault(_locations); var _container = __webpack_require__(48); var _container2 = _interopRequireDefault(_container); var _packaging = __webpack_require__(49); var _packaging2 = _interopRequireDefault(_packaging); var _navigation = __webpack_require__(50); var _navigation2 = _interopRequireDefault(_navigation); var _resources = __webpack_require__(51); var _resources2 = _interopRequireDefault(_resources); var _pagelist = __webpack_require__(52); var _pagelist2 = _interopRequireDefault(_pagelist); var _rendition = __webpack_require__(18); var _rendition2 = _interopRequireDefault(_rendition); var _archive = __webpack_require__(70); var _archive2 = _interopRequireDefault(_archive); var _request2 = __webpack_require__(11); var _request3 = _interopRequireDefault(_request2); var _epubcfi = __webpack_require__(1); var _epubcfi2 = _interopRequireDefault(_epubcfi); var _constants = __webpack_require__(2); 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"); } } var CONTAINER_PATH = "META-INF/container.xml"; var INPUT_TYPE = { BINARY: "binary", BASE64: "base64", EPUB: "epub", OPF: "opf", MANIFEST: "json", DIRECTORY: "directory" }; /** * An Epub representation with methods for the loading, parsing and manipulation * of its contents. * @class * @param {string} [url] * @param {object} [options] * @param {method} [options.requestMethod] a request function to use instead of the default * @param {boolean} [options.requestCredentials=undefined] send the xhr request withCredentials * @param {object} [options.requestHeaders=undefined] send the xhr request headers * @param {string} [options.encoding=binary] optional to pass 'binary' or base64' for archived Epubs * @param {string} [options.replacements=none] use base64, blobUrl, or none for replacing assets in archived Epubs * @param {method} [options.canonical] optional function to determine canonical urls for a path * @param {string} [options.openAs] optional string to determine the input type * @returns {Book} * @example new Book("/path/to/book.epub", {}) * @example new Book({ replacements: "blobUrl" }) */ var Book = function () { function Book(url, options) { var _this = this; _classCallCheck(this, Book); // Allow passing just options to the Book if (typeof options === "undefined" && typeof url !== "string" && url instanceof Blob === false) { options = url; url = undefined; } this.settings = (0, _core.extend)(this.settings || {}, { requestMethod: undefined, requestCredentials: undefined, requestHeaders: undefined, encoding: undefined, replacements: undefined, canonical: undefined, openAs: undefined }); (0, _core.extend)(this.settings, options); // Promises this.opening = new _core.defer(); /** * @member {promise} opened returns after the book is loaded * @memberof Book */ this.opened = this.opening.promise; this.isOpen = false; this.loading = { manifest: new _core.defer(), spine: new _core.defer(), metadata: new _core.defer(), cover: new _core.defer(), navigation: new _core.defer(), pageList: new _core.defer(), resources: new _core.defer() }; this.loaded = { manifest: this.loading.manifest.promise, spine: this.loading.spine.promise, metadata: this.loading.metadata.promise, cover: this.loading.cover.promise, navigation: this.loading.navigation.promise, pageList: this.loading.pageList.promise, resources: this.loading.resources.promise }; /** * @member {promise} ready returns after the book is loaded and parsed * @memberof Book * @private */ this.ready = Promise.all([this.loaded.manifest, this.loaded.spine, this.loaded.metadata, this.loaded.cover, this.loaded.navigation, this.loaded.resources]); // Queue for methods used before opening this.isRendered = false; // this._q = queue(this); /** * @member {method} request * @memberof Book * @private */ this.request = this.settings.requestMethod || _request3.default; /** * @member {Spine} spine * @memberof Book */ this.spine = new _spine2.default(); /** * @member {Locations} locations * @memberof Book */ this.locations = new _locations2.default(this.spine, this.load.bind(this)); /** * @member {Navigation} navigation * @memberof Book */ this.navigation = undefined; /** * @member {PageList} pagelist * @memberof Book */ this.pageList = undefined; /** * @member {Url} url * @memberof Book * @private */ this.url = undefined; /** * @member {Path} path * @memberof Book * @private */ this.path = undefined; /** * @member {boolean} archived * @memberof Book * @private */ this.archived = false; /** * @member {Archive} archive * @memberof Book * @private */ this.archive = undefined; /** * @member {Resources} resources * @memberof Book * @private */ this.resources = undefined; /** * @member {Rendition} rendition * @memberof Book * @private */ this.rendition = undefined; /** * @member {Container} container * @memberof Book * @private */ this.container = undefined; /** * @member {Packaging} packaging * @memberof Book * @private */ this.packaging = undefined; // this.toc = undefined; if (url) { this.open(url, this.settings.openAs).catch(function (error) { var err = new Error("Cannot load book at " + url); _this.emit(_constants.EVENTS.BOOK.OPEN_FAILED, err); }); } } /** * Open a epub or url * @param {string | ArrayBuffer} input Url, Path or ArrayBuffer * @param {string} [what="binary", "base64", "epub", "opf", "json", "directory"] force opening as a certain type * @returns {Promise} of when the book has been loaded * @example book.open("/path/to/book.epub") */ _createClass(Book, [{ key: "open", value: function open(input, what) { var opening; var type = what || this.determineType(input); if (type === INPUT_TYPE.BINARY) { this.archived = true; this.url = new _url2.default("/", ""); opening = this.openEpub(input); } else if (type === INPUT_TYPE.BASE64) { this.archived = true; this.url = new _url2.default("/", ""); opening = this.openEpub(input, type); } else if (type === INPUT_TYPE.EPUB) { this.archived = true; this.url = new _url2.default("/", ""); opening = this.request(input, "binary", this.settings.requestCredentials).then(this.openEpub.bind(this)); } else if (type == INPUT_TYPE.OPF) { this.url = new _url2.default(input); opening = this.openPackaging(this.url.Path.toString()); } else if (type == INPUT_TYPE.MANIFEST) { this.url = new _url2.default(input); opening = this.openManifest(this.url.Path.toString()); } else { this.url = new _url2.default(input); opening = this.openContainer(CONTAINER_PATH).then(this.openPackaging.bind(this)); } return opening; } /** * Open an archived epub * @private * @param {binary} data * @param {string} [encoding] * @return {Promise} */ }, { key: "openEpub", value: function openEpub(data, encoding) { var _this2 = this; return this.unarchive(data, encoding || this.settings.encoding).then(function () { return _this2.openContainer(CONTAINER_PATH); }).then(function (packagePath) { return _this2.openPackaging(packagePath); }); } /** * Open the epub container * @private * @param {string} url * @return {string} packagePath */ }, { key: "openContainer", value: function openContainer(url) { var _this3 = this; return this.load(url).then(function (xml) { _this3.container = new _container2.default(xml); return _this3.resolve(_this3.container.packagePath); }); } /** * Open the Open Packaging Format Xml * @private * @param {string} url * @return {Promise} */ }, { key: "openPackaging", value: function openPackaging(url) { var _this4 = this; this.path = new _path2.default(url); return this.load(url).then(function (xml) { _this4.packaging = new _packaging2.default(xml); return _this4.unpack(_this4.packaging); }); } /** * Open the manifest JSON * @private * @param {string} url * @return {Promise} */ }, { key: "openManifest", value: function openManifest(url) { var _this5 = this; this.path = new _path2.default(url); return this.load(url).then(function (json) { _this5.packaging = new _packaging2.default(); _this5.packaging.load(json); return _this5.unpack(_this5.packaging); }); } /** * Load a resource from the Book * @param {string} path path to the resource to load * @return {Promise} returns a promise with the requested resource */ }, { key: "load", value: function load(path) { var resolved; if (this.archived) { resolved = this.resolve(path); return this.archive.request(resolved); } else { resolved = this.resolve(path); return this.request(resolved, null, this.settings.requestCredentials, this.settings.requestHeaders); } } /** * Resolve a path to it's absolute position in the Book * @param {string} path * @param {boolean} [absolute] force resolving the full URL * @return {string} the resolved path string */ }, { key: "resolve", value: function resolve(path, absolute) { if (!path) { return; } var resolved = path; var isAbsolute = path.indexOf("://") > -1; if (isAbsolute) { return path; } if (this.path) { resolved = this.path.resolve(path); } if (absolute != false && this.url) { resolved = this.url.resolve(resolved); } return resolved; } /** * Get a canonical link to a path * @param {string} path * @return {string} the canonical path string */ }, { key: "canonical", value: function canonical(path) { var url = path; if (!path) { return ""; } if (this.settings.canonical) { url = this.settings.canonical(path); } else { url = this.resolve(path, true); } return url; } /** * Determine the type of they input passed to open * @private * @param {string} input * @return {string} binary | directory | epub | opf */ }, { key: "determineType", value: function determineType(input) { var url; var path; var extension; if (this.settings.encoding === "base64") { return INPUT_TYPE.BASE64; } if (typeof input != "string") { return INPUT_TYPE.BINARY; } url = new _url2.default(input); path = url.path(); extension = path.extension; if (!extension) { return INPUT_TYPE.DIRECTORY; } if (extension === "epub") { return INPUT_TYPE.EPUB; } if (extension === "opf") { return INPUT_TYPE.OPF; } if (extension === "json") { return INPUT_TYPE.MANIFEST; } } /** * unpack the contents of the Books packageXml * @private * @param {document} packageXml XML Document */ }, { key: "unpack", value: function unpack(opf) { var _this6 = this; this.package = opf; this.spine.unpack(this.package, this.resolve.bind(this), this.canonical.bind(this)); this.resources = new _resources2.default(this.package.manifest, { archive: this.archive, resolver: this.resolve.bind(this), request: this.request.bind(this), replacements: this.settings.replacements || (this.archived ? "blobUrl" : "base64") }); this.loadNavigation(this.package).then(function () { // this.toc = this.navigation.toc; _this6.loading.navigation.resolve(_this6.navigation); }); if (this.package.coverPath) { this.cover = this.resolve(this.package.coverPath); } // Resolve promises this.loading.manifest.resolve(this.package.manifest); this.loading.metadata.resolve(this.package.metadata); this.loading.spine.resolve(this.spine); this.loading.cover.resolve(this.cover); this.loading.resources.resolve(this.resources); this.loading.pageList.resolve(this.pageList); this.isOpen = true; if (this.archived || this.settings.replacements && this.settings.replacements != "none") { this.replacements().then(function () { _this6.opening.resolve(_this6); }).catch(function (err) { console.error(err); }); } else { // Resolve book opened promise this.opening.resolve(this); } } /** * Load Navigation and PageList from package * @private * @param {document} opf XML Document */ }, { key: "loadNavigation", value: function loadNavigation(opf) { var _this7 = this; var navPath = opf.navPath || opf.ncxPath; var toc = opf.toc; // From json manifest if (toc) { return new Promise(function (resolve, reject) { _this7.navigation = new _navigation2.default(toc); if (opf.pageList) { _this7.pageList = new _pagelist2.default(opf.pageList); // TODO: handle page lists from Manifest } resolve(_this7.navigation); }); } if (!navPath) { return new Promise(function (resolve, reject) { _this7.navigation = new _navigation2.default(); _this7.pageList = new _pagelist2.default(); resolve(_this7.navigation); }); } return this.load(navPath, "xml").then(function (xml) { _this7.navigation = new _navigation2.default(xml); _this7.pageList = new _pagelist2.default(xml); return _this7.navigation; }); } /** * Gets a Section of the Book from the Spine * Alias for `book.spine.get` * @param {string} target * @return {Section} */ }, { key: "section", value: function section(target) { return this.spine.get(target); } /** * Sugar to render a book to an element * @param {element | string} element element or string to add a rendition to * @param {object} [options] * @return {Rendition} */ }, { key: "renderTo", value: function renderTo(element, options) { this.rendition = new _rendition2.default(this, options); this.rendition.attachTo(element); return this.rendition; } /** * Set if request should use withCredentials * @param {boolean} credentials */ }, { key: "setRequestCredentials", value: function setRequestCredentials(credentials) { this.settings.requestCredentials = credentials; } /** * Set headers request should use * @param {object} headers */ }, { key: "setRequestHeaders", value: function setRequestHeaders(headers) { this.settings.requestHeaders = headers; } /** * Unarchive a zipped epub * @private * @param {binary} input epub data * @param {string} [encoding] * @return {Archive} */ }, { key: "unarchive", value: function unarchive(input, encoding) { this.archive = new _archive2.default(); return this.archive.open(input, encoding); } /** * Get the cover url * @return {string} coverUrl */ }, { key: "coverUrl", value: function coverUrl() { var _this8 = this; var retrieved = this.loaded.cover.then(function (url) { if (_this8.archived) { // return this.archive.createUrl(this.cover); return _this8.resources.get(_this8.cover); } else { return _this8.cover; } }); return retrieved; } /** * Load replacement urls * @private * @return {Promise} completed loading urls */ }, { key: "replacements", value: function replacements() { var _this9 = this; this.spine.hooks.serialize.register(function (output, section) { section.output = _this9.resources.substitute(output, section.url); }); return this.resources.replacements().then(function () { return _this9.resources.replaceCss(); }); } /** * Find a DOM Range for a given CFI Range * @param {EpubCFI} cfiRange a epub cfi range * @return {Range} */ }, { key: "getRange", value: function getRange(cfiRange) { var cfi = new _epubcfi2.default(cfiRange); var item = this.spine.get(cfi.spinePos); var _request = this.load.bind(this); if (!item) { return new Promise(function (resolve, reject) { reject("CFI could not be found"); }); } return item.load(_request).then(function (contents) { var range = cfi.toRange(item.document); return range; }); } /** * 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 */ }, { key: "key", value: function key(identifier) { var ident = identifier || this.package.metadata.identifier || this.url.filename; return "epubjs:" + _constants.EPUBJS_VERSION + ":" + ident; } /** * Destroy the Book and all associated objects */ }, { key: "destroy", value: function destroy() { this.opened = undefined; this.loading = undefined; this.loaded = undefined; this.ready = undefined; this.isOpen = false; this.isRendered = false; this.spine && this.spine.destroy(); this.locations && this.locations.destroy(); this.pageList && this.pageList.destroy(); this.archive && this.archive.destroy(); this.resources && this.resources.destroy(); this.container && this.container.destroy(); this.packaging && this.packaging.destroy(); this.rendition && this.rendition.destroy(); this.spine = undefined; this.locations = undefined; this.pageList = undefined; this.archive = undefined; this.resources = undefined; this.container = undefined; this.packaging = undefined; this.rendition = undefined; this.navigation = undefined; this.url = undefined; this.path = undefined; this.archived = false; } }]); return Book; }(); //-- Enable binding events to book (0, _eventEmitter2.default)(Book.prototype); exports.default = Book; module.exports = exports["default"]; /***/ }), /* 27 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var assign = __webpack_require__(28) , normalizeOpts = __webpack_require__(36) , isCallable = __webpack_require__(37) , contains = __webpack_require__(38) , d; d = module.exports = function (dscr, value/*, options*/) { var c, e, w, options, desc; if ((arguments.length < 2) || (typeof dscr !== 'string')) { options = value; value = dscr; dscr = null; } else { options = arguments[2]; } if (dscr == null) { c = w = true; e = false; } else { c = contains.call(dscr, 'c'); e = contains.call(dscr, 'e'); w = contains.call(dscr, 'w'); } desc = { value: value, configurable: c, enumerable: e, writable: w }; return !options ? desc : assign(normalizeOpts(options), desc); }; d.gs = function (dscr, get, set/*, options*/) { var c, e, options, desc; if (typeof dscr !== 'string') { options = set; set = get; get = dscr; dscr = null; } else { options = arguments[3]; } if (get == null) { get = undefined; } else if (!isCallable(get)) { options = get; get = set = undefined; } else if (set == null) { set = undefined; } else if (!isCallable(set)) { options = set; set = undefined; } if (dscr == null) { c = true; e = false; } else { c = contains.call(dscr, 'c'); e = contains.call(dscr, 'e'); } desc = { get: get, set: set, configurable: c, enumerable: e }; return !options ? desc : assign(normalizeOpts(options), desc); }; /***/ }), /* 28 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = __webpack_require__(29)() ? Object.assign : __webpack_require__(30); /***/ }), /* 29 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function () { var assign = Object.assign, obj; if (typeof assign !== "function") return false; obj = { foo: "raz" }; assign(obj, { bar: "dwa" }, { trzy: "trzy" }); return (obj.foo + obj.bar + obj.trzy) === "razdwatrzy"; }; /***/ }), /* 30 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var keys = __webpack_require__(31) , value = __webpack_require__(35) , max = Math.max; module.exports = function (dest, src /*, …srcn*/) { var error, i, length = max(arguments.length, 2), assign; dest = Object(value(dest)); assign = function (key) { try { dest[key] = src[key]; } catch (e) { if (!error) error = e; } }; for (i = 1; i < length; ++i) { src = arguments[i]; keys(src).forEach(assign); } if (error !== undefined) throw error; return dest; }; /***/ }), /* 31 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = __webpack_require__(32)() ? Object.keys : __webpack_require__(33); /***/ }), /* 32 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function () { try { Object.keys("primitive"); return true; } catch (e) { return false; } }; /***/ }), /* 33 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var isValue = __webpack_require__(9); var keys = Object.keys; module.exports = function (object) { return keys(isValue(object) ? Object(object) : object); }; /***/ }), /* 34 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; // eslint-disable-next-line no-empty-function module.exports = function () {}; /***/ }), /* 35 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var isValue = __webpack_require__(9); module.exports = function (value) { if (!isValue(value)) throw new TypeError("Cannot use null or undefined"); return value; }; /***/ }), /* 36 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var isValue = __webpack_require__(9); var forEach = Array.prototype.forEach, create = Object.create; var process = function (src, obj) { var key; for (key in src) obj[key] = src[key]; }; // eslint-disable-next-line no-unused-vars module.exports = function (opts1 /*, …options*/) { var result = create(null); forEach.call(arguments, function (options) { if (!isValue(options)) return; process(Object(options), result); }); return result; }; /***/ }), /* 37 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; // Deprecated module.exports = function (obj) { return typeof obj === "function"; }; /***/ }), /* 38 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = __webpack_require__(39)() ? String.prototype.contains : __webpack_require__(40); /***/ }), /* 39 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var str = "razdwatrzy"; module.exports = function () { if (typeof str.contains !== "function") return false; return (str.contains("dwa") === true) && (str.contains("foo") === false); }; /***/ }), /* 40 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var indexOf = String.prototype.indexOf; module.exports = function (searchString/*, position*/) { return indexOf.call(this, searchString, arguments[1]) > -1; }; /***/ }), /* 41 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function (fn) { if (typeof fn !== "function") throw new TypeError(fn + " is not a function"); return fn; }; /***/ }), /* 42 */ /***/ (function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_42__; /***/ }), /* 43 */ /***/ (function(module, exports, __webpack_require__) { "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 = __webpack_require__(1); var _epubcfi2 = _interopRequireDefault(_epubcfi); var _hook = __webpack_require__(10); var _hook2 = _interopRequireDefault(_hook); var _section = __webpack_require__(44); var _section2 = _interopRequireDefault(_section); var _replacements = __webpack_require__(7); 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 {Packaging} _package * @param {method} resolver URL resolver * @param {method} canonical Resolve canonical url */ _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|number} [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); } /** * Find the first Section in the Spine * @return {Section} first section */ }, { 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); } /** * Find the last Section in the Spine * @return {Section} last section */ }, { 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"]; /***/ }), /* 44 */ /***/ (function(module, exports, __webpack_require__) { "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 _core = __webpack_require__(0); var _epubcfi = __webpack_require__(1); var _epubcfi2 = _interopRequireDefault(_epubcfi); var _hook = __webpack_require__(10); var _hook2 = _interopRequireDefault(_hook); var _replacements = __webpack_require__(7); 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"); } } /** * Represents a Section of the Book * * In most books this is equivelent to a Chapter * @param {object} item The spine item representing the section * @param {object} hooks hooks for serialize and content */ var Section = function () { function Section(item, hooks) { _classCallCheck(this, Section); this.idref = item.idref; this.linear = item.linear === "yes"; this.properties = item.properties; this.index = item.index; this.href = item.href; this.url = item.url; this.canonical = item.canonical; this.next = item.next; this.prev = item.prev; this.cfiBase = item.cfiBase; if (hooks) { this.hooks = hooks; } else { this.hooks = {}; this.hooks.serialize = new _hook2.default(this); this.hooks.content = new _hook2.default(this); } this.document = undefined; this.contents = undefined; this.output = undefined; } /** * Load the section from its url * @param {method} [_request] a request method to use for loading * @return {document} a promise with the xml document */ _createClass(Section, [{ key: "load", value: function load(_request) { var request = _request || this.request || __webpack_require__(11); var loading = new _core.defer(); var loaded = loading.promise; if (this.contents) { loading.resolve(this.contents); } else { request(this.url).then(function (xml) { // var directory = new Url(this.url).directory; this.document = xml; this.contents = xml.documentElement; return this.hooks.content.trigger(this.document, this); }.bind(this)).then(function () { loading.resolve(this.contents); }.bind(this)).catch(function (error) { loading.reject(error); }); } return loaded; } /** * Adds a base tag for resolving urls in the section * @private */ }, { key: "base", value: function base() { return (0, _replacements.replaceBase)(this.document, this); } /** * Render the contents of a section * @param {method} [_request] a request method to use for loading * @return {string} output a serialized XML Document */ }, { key: "render", value: function render(_request) { var rendering = new _core.defer(); var rendered = rendering.promise; this.output; // TODO: better way to return this from hooks? this.load(_request).then(function (contents) { var userAgent = typeof navigator !== 'undefined' && navigator.userAgent || ''; var isIE = userAgent.indexOf('Trident') >= 0; var Serializer; if (typeof XMLSerializer === "undefined" || isIE) { Serializer = __webpack_require__(45).XMLSerializer; } else { Serializer = XMLSerializer; } var serializer = new Serializer(); this.output = serializer.serializeToString(contents); return this.output; }.bind(this)).then(function () { return this.hooks.serialize.trigger(this.output, this); }.bind(this)).then(function () { rendering.resolve(this.output); }.bind(this)).catch(function (error) { rendering.reject(error); }); return rendered; } /** * Find a string in a section * @param {string} _query The query string to find * @return {object[]} A list of matches, with form {cfi, excerpt} */ }, { key: "find", value: function find(_query) { var section = this; var matches = []; var query = _query.toLowerCase(); var find = function find(node) { var text = node.textContent.toLowerCase(); var range = section.document.createRange(); var cfi; var pos; var last = -1; var excerpt; var limit = 150; while (pos != -1) { // Search for the query pos = text.indexOf(query, last + 1); if (pos != -1) { // We found it! Generate a CFI range = section.document.createRange(); range.setStart(node, pos); range.setEnd(node, pos + query.length); cfi = section.cfiFromRange(range); // Generate the excerpt if (node.textContent.length < limit) { excerpt = node.textContent; } else { excerpt = node.textContent.substring(pos - limit / 2, pos + limit / 2); excerpt = "..." + excerpt + "..."; } // Add the CFI to the matches list matches.push({ cfi: cfi, excerpt: excerpt }); } last = pos; } }; (0, _core.sprint)(section.document, function (node) { find(node); }); return matches; } }, { key: "reconcileLayoutSettings", /** * Reconciles the current chapters layout properies with * the global layout properities. * @param {object} globalLayout The global layout settings object, chapter properties string * @return {object} layoutProperties Object with layout properties */ value: function reconcileLayoutSettings(globalLayout) { //-- Get the global defaults var settings = { layout: globalLayout.layout, spread: globalLayout.spread, orientation: globalLayout.orientation }; //-- Get the chapter's display type this.properties.forEach(function (prop) { var rendition = prop.replace("rendition:", ""); var split = rendition.indexOf("-"); var property, value; if (split != -1) { property = rendition.slice(0, split); value = rendition.slice(split + 1); settings[property] = value; } }); return settings; } /** * Get a CFI from a Range in the Section * @param {range} _range * @return {string} cfi an EpubCFI string */ }, { key: "cfiFromRange", value: function cfiFromRange(_range) { return new _epubcfi2.default(_range, this.cfiBase).toString(); } /** * Get a CFI from an Element in the Section * @param {element} el * @return {string} cfi an EpubCFI string */ }, { key: "cfiFromElement", value: function cfiFromElement(el) { return new _epubcfi2.default(el, this.cfiBase).toString(); } /** * Unload the section document */ }, { key: "unload", value: function unload() { this.document = undefined; this.contents = undefined; this.output = undefined; } }, { key: "destroy", value: function destroy() { this.unload(); this.hooks.serialize.clear(); this.hooks.content.clear(); this.hooks = undefined; this.idref = undefined; this.linear = undefined; this.properties = undefined; this.index = undefined; this.href = undefined; this.url = undefined; this.next = undefined; this.prev = undefined; this.cfiBase = undefined; } }]); return Section; }(); exports.default = Section; module.exports = exports["default"]; /***/ }), /* 45 */ /***/ (function(module, exports, __webpack_require__) { function DOMParser(options){ this.options = options ||{locator:{}}; } DOMParser.prototype.parseFromString = function(source,mimeType){ var options = this.options; var sax = new XMLReader(); var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler var errorHandler = options.errorHandler; var locator = options.locator; var defaultNSMap = options.xmlns||{}; var entityMap = {'lt':'<','gt':'>','amp':'&','quot':'"','apos':"'"} if(locator){ domBuilder.setDocumentLocator(locator) } sax.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator); sax.domBuilder = options.domBuilder || domBuilder; if(/\/x?html?$/.test(mimeType)){ entityMap.nbsp = '\xa0'; entityMap.copy = '\xa9'; defaultNSMap['']= 'http://www.w3.org/1999/xhtml'; } defaultNSMap.xml = defaultNSMap.xml || 'http://www.w3.org/XML/1998/namespace'; if(source){ sax.parse(source,defaultNSMap,entityMap); }else{ sax.errorHandler.error("invalid doc source"); } return domBuilder.doc; } function buildErrorHandler(errorImpl,domBuilder,locator){ if(!errorImpl){ if(domBuilder instanceof DOMHandler){ return domBuilder; } errorImpl = domBuilder ; } var errorHandler = {} var isCallback = errorImpl instanceof Function; locator = locator||{} function build(key){ var fn = errorImpl[key]; if(!fn && isCallback){ fn = errorImpl.length == 2?function(msg){errorImpl(key,msg)}:errorImpl; } errorHandler[key] = fn && function(msg){ fn('[xmldom '+key+']\t'+msg+_locator(locator)); }||function(){}; } build('warning'); build('error'); build('fatalError'); return errorHandler; } //console.log('#\n\n\n\n\n\n\n####') /** * +ContentHandler+ErrorHandler * +LexicalHandler+EntityResolver2 * -DeclHandler-DTDHandler * * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2 * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html */ function DOMHandler() { this.cdata = false; } function position(locator,node){ node.lineNumber = locator.lineNumber; node.columnNumber = locator.columnNumber; } /** * @see org.xml.sax.ContentHandler#startDocument * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html */ DOMHandler.prototype = { startDocument : function() { this.doc = new DOMImplementation().createDocument(null, null, null); if (this.locator) { this.doc.documentURI = this.locator.systemId; } }, startElement:function(namespaceURI, localName, qName, attrs) { var doc = this.doc; var el = doc.createElementNS(namespaceURI, qName||localName); var len = attrs.length; appendElement(this, el); this.currentElement = el; this.locator && position(this.locator,el) for (var i = 0 ; i < len; i++) { var namespaceURI = attrs.getURI(i); var value = attrs.getValue(i); var qName = attrs.getQName(i); var attr = doc.createAttributeNS(namespaceURI, qName); this.locator &&position(attrs.getLocator(i),attr); attr.value = attr.nodeValue = value; el.setAttributeNode(attr) } }, endElement:function(namespaceURI, localName, qName) { var current = this.currentElement var tagName = current.tagName; this.currentElement = current.parentNode; }, startPrefixMapping:function(prefix, uri) { }, endPrefixMapping:function(prefix) { }, processingInstruction:function(target, data) { var ins = this.doc.createProcessingInstruction(target, data); this.locator && position(this.locator,ins) appendElement(this, ins); }, ignorableWhitespace:function(ch, start, length) { }, characters:function(chars, start, length) { chars = _toString.apply(this,arguments) //console.log(chars) if(chars){ if (this.cdata) { var charNode = this.doc.createCDATASection(chars); } else { var charNode = this.doc.createTextNode(chars); } if(this.currentElement){ this.currentElement.appendChild(charNode); }else if(/^\s*$/.test(chars)){ this.doc.appendChild(charNode); //process xml } this.locator && position(this.locator,charNode) } }, skippedEntity:function(name) { }, endDocument:function() { this.doc.normalize(); }, setDocumentLocator:function (locator) { if(this.locator = locator){// && !('lineNumber' in locator)){ locator.lineNumber = 0; } }, //LexicalHandler comment:function(chars, start, length) { chars = _toString.apply(this,arguments) var comm = this.doc.createComment(chars); this.locator && position(this.locator,comm) appendElement(this, comm); }, startCDATA:function() { //used in characters() methods this.cdata = true; }, endCDATA:function() { this.cdata = false; }, startDTD:function(name, publicId, systemId) { var impl = this.doc.implementation; if (impl && impl.createDocumentType) { var dt = impl.createDocumentType(name, publicId, systemId); this.locator && position(this.locator,dt) appendElement(this, dt); } }, /** * @see org.xml.sax.ErrorHandler * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html */ warning:function(error) { console.warn('[xmldom warning]\t'+error,_locator(this.locator)); }, error:function(error) { console.error('[xmldom error]\t'+error,_locator(this.locator)); }, fatalError:function(error) { console.error('[xmldom fatalError]\t'+error,_locator(this.locator)); throw error; } } function _locator(l){ if(l){ return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']' } } function _toString(chars,start,length){ if(typeof chars == 'string'){ return chars.substr(start,length) }else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)") if(chars.length >= start+length || start){ return new java.lang.String(chars,start,length)+''; } return chars; } } /* * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html * used method of org.xml.sax.ext.LexicalHandler: * #comment(chars, start, length) * #startCDATA() * #endCDATA() * #startDTD(name, publicId, systemId) * * * IGNORED method of org.xml.sax.ext.LexicalHandler: * #endDTD() * #startEntity(name) * #endEntity(name) * * * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html * IGNORED method of org.xml.sax.ext.DeclHandler * #attributeDecl(eName, aName, type, mode, value) * #elementDecl(name, model) * #externalEntityDecl(name, publicId, systemId) * #internalEntityDecl(name, value) * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html * IGNORED method of org.xml.sax.EntityResolver2 * #resolveEntity(String name,String publicId,String baseURI,String systemId) * #resolveEntity(publicId, systemId) * #getExternalSubset(name, baseURI) * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html * IGNORED method of org.xml.sax.DTDHandler * #notationDecl(name, publicId, systemId) {}; * #unparsedEntityDecl(name, publicId, systemId, notationName) {}; */ "endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){ DOMHandler.prototype[key] = function(){return null} }) /* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */ function appendElement (hander,node) { if (!hander.currentElement) { hander.doc.appendChild(node); } else { hander.currentElement.appendChild(node); } }//appendChild and setAttributeNS are preformance key //if(typeof require == 'function'){ var XMLReader = __webpack_require__(46).XMLReader; var DOMImplementation = exports.DOMImplementation = __webpack_require__(16).DOMImplementation; exports.XMLSerializer = __webpack_require__(16).XMLSerializer ; exports.DOMParser = DOMParser; //} /***/ }), /* 46 */ /***/ (function(module, exports) { //[4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF] //[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040] //[5] Name ::= NameStartChar (NameChar)* var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]///\u10000-\uEFFFF var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\\u00B7\\u0300-\\u036F\\u203F-\\u2040]"); var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$'); //var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/ //var handlers = 'resolveEntity,getExternalSubset,characters,endDocument,endElement,endPrefixMapping,ignorableWhitespace,processingInstruction,setDocumentLocator,skippedEntity,startDocument,startElement,startPrefixMapping,notationDecl,unparsedEntityDecl,error,fatalError,warning,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,comment,endCDATA,endDTD,endEntity,startCDATA,startDTD,startEntity'.split(',') //S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE //S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE var S_TAG = 0;//tag name offerring var S_ATTR = 1;//attr name offerring var S_ATTR_SPACE=2;//attr name end and space offer var S_EQ = 3;//=space? var S_ATTR_NOQUOT_VALUE = 4;//attr value(no quot value only) var S_ATTR_END = 5;//attr value end and no space(quot end) var S_TAG_SPACE = 6;//(attr value end || tag end ) && (space offer) var S_TAG_CLOSE = 7;//closed el function XMLReader(){ } XMLReader.prototype = { parse:function(source,defaultNSMap,entityMap){ var domBuilder = this.domBuilder; domBuilder.startDocument(); _copy(defaultNSMap ,defaultNSMap = {}) parse(source,defaultNSMap,entityMap, domBuilder,this.errorHandler); domBuilder.endDocument(); } } function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){ function fixedFromCharCode(code) { // String.prototype.fromCharCode does not supports // > 2 bytes unicode chars directly if (code > 0xffff) { code -= 0x10000; var surrogate1 = 0xd800 + (code >> 10) , surrogate2 = 0xdc00 + (code & 0x3ff); return String.fromCharCode(surrogate1, surrogate2); } else { return String.fromCharCode(code); } } function entityReplacer(a){ var k = a.slice(1,-1); if(k in entityMap){ return entityMap[k]; }else if(k.charAt(0) === '#'){ return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x'))) }else{ errorHandler.error('entity not found:'+a); return a; } } function appendText(end){//has some bugs if(end>start){ var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer); locator&&position(start); domBuilder.characters(xt,0,end-start); start = end } } function position(p,m){ while(p>=lineEnd && (m = linePattern.exec(source))){ lineStart = m.index; lineEnd = lineStart + m[0].length; locator.lineNumber++; //console.log('line++:',locator,startPos,endPos) } locator.columnNumber = p-lineStart+1; } var lineStart = 0; var lineEnd = 0; var linePattern = /.*(?:\r\n?|\n)|.*$/g var locator = domBuilder.locator; var parseStack = [{currentNSMap:defaultNSMapCopy}] var closeMap = {}; var start = 0; while(true){ try{ var tagStart = source.indexOf('<',start); if(tagStart<0){ if(!source.substr(start).match(/^\s*$/)){ var doc = domBuilder.doc; var text = doc.createTextNode(source.substr(start)); doc.appendChild(text); domBuilder.currentElement = text; } return; } if(tagStart>start){ appendText(tagStart); } switch(source.charAt(tagStart+1)){ case '/': var end = source.indexOf('>',tagStart+3); var tagName = source.substring(tagStart+2,end); var config = parseStack.pop(); if(end<0){ tagName = source.substring(tagStart+2).replace(/[\s<].*/,''); //console.error('#@@@@@@'+tagName) errorHandler.error("end tag name: "+tagName+' is not complete:'+config.tagName); end = tagStart+1+tagName.length; }else if(tagName.match(/\s locator&&position(tagStart); end = parseInstruction(source,tagStart,domBuilder); break; case '!':// start){ start = end; }else{ //TODO: 这里有可能sax回退,有位置错误风险 appendText(Math.max(tagStart,start)+1); } } } function copyLocator(f,t){ t.lineNumber = f.lineNumber; t.columnNumber = f.columnNumber; return t; } /** * @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack); * @return end of the elementStartPart(end of elementEndPart for selfClosed el) */ function parseElementStartPart(source,start,el,currentNSMap,entityReplacer,errorHandler){ var attrName; var value; var p = ++start; var s = S_TAG;//status while(true){ var c = source.charAt(p); switch(c){ case '=': if(s === S_ATTR){//attrName attrName = source.slice(start,p); s = S_EQ; }else if(s === S_ATTR_SPACE){ s = S_EQ; }else{ //fatalError: equal must after attrName or space after attrName throw new Error('attribute equal must after attrName'); } break; case '\'': case '"': if(s === S_EQ || s === S_ATTR //|| s == S_ATTR_SPACE ){//equal if(s === S_ATTR){ errorHandler.warning('attribute value must after "="') attrName = source.slice(start,p) } start = p+1; p = source.indexOf(c,start) if(p>0){ value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer); el.add(attrName,value,start-1); s = S_ATTR_END; }else{ //fatalError: no end quot match throw new Error('attribute value no end \''+c+'\' match'); } }else if(s == S_ATTR_NOQUOT_VALUE){ value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer); //console.log(attrName,value,start,p) el.add(attrName,value,start); //console.dir(el) errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!'); start = p+1; s = S_ATTR_END }else{ //fatalError: no equal before throw new Error('attribute value must after "="'); } break; case '/': switch(s){ case S_TAG: el.setTagName(source.slice(start,p)); case S_ATTR_END: case S_TAG_SPACE: case S_TAG_CLOSE: s =S_TAG_CLOSE; el.closed = true; case S_ATTR_NOQUOT_VALUE: case S_ATTR: case S_ATTR_SPACE: break; //case S_EQ: default: throw new Error("attribute invalid close char('/')") } break; case ''://end document //throw new Error('unexpected end of input') errorHandler.error('unexpected end of input'); if(s == S_TAG){ el.setTagName(source.slice(start,p)); } return p; case '>': switch(s){ case S_TAG: el.setTagName(source.slice(start,p)); case S_ATTR_END: case S_TAG_SPACE: case S_TAG_CLOSE: break;//normal case S_ATTR_NOQUOT_VALUE://Compatible state case S_ATTR: value = source.slice(start,p); if(value.slice(-1) === '/'){ el.closed = true; value = value.slice(0,-1) } case S_ATTR_SPACE: if(s === S_ATTR_SPACE){ value = attrName; } if(s == S_ATTR_NOQUOT_VALUE){ errorHandler.warning('attribute "'+value+'" missed quot(")!!'); el.add(attrName,value.replace(/&#?\w+;/g,entityReplacer),start) }else{ if(currentNSMap[''] !== 'http://www.w3.org/1999/xhtml' || !value.match(/^(?:disabled|checked|selected)$/i)){ errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!') } el.add(value,value,start) } break; case S_EQ: throw new Error('attribute value missed!!'); } // console.log(tagName,tagNamePattern,tagNamePattern.test(tagName)) return p; /*xml space '\x20' | #x9 | #xD | #xA; */ case '\u0080': c = ' '; default: if(c<= ' '){//space switch(s){ case S_TAG: el.setTagName(source.slice(start,p));//tagName s = S_TAG_SPACE; break; case S_ATTR: attrName = source.slice(start,p) s = S_ATTR_SPACE; break; case S_ATTR_NOQUOT_VALUE: var value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer); errorHandler.warning('attribute "'+value+'" missed quot(")!!'); el.add(attrName,value,start) case S_ATTR_END: s = S_TAG_SPACE; break; //case S_TAG_SPACE: //case S_EQ: //case S_ATTR_SPACE: // void();break; //case S_TAG_CLOSE: //ignore warning } }else{//not space //S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE //S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE switch(s){ //case S_TAG:void();break; //case S_ATTR:void();break; //case S_ATTR_NOQUOT_VALUE:void();break; case S_ATTR_SPACE: var tagName = el.tagName; if(currentNSMap[''] !== 'http://www.w3.org/1999/xhtml' || !attrName.match(/^(?:disabled|checked|selected)$/i)){ errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead2!!') } el.add(attrName,attrName,start); start = p; s = S_ATTR; break; case S_ATTR_END: errorHandler.warning('attribute space is required"'+attrName+'"!!') case S_TAG_SPACE: s = S_ATTR; start = p; break; case S_EQ: s = S_ATTR_NOQUOT_VALUE; start = p; break; case S_TAG_CLOSE: throw new Error("elements closed character '/' and '>' must be connected to"); } } }//end outer switch //console.log('p++',p) p++; } } /** * @return true if has new namespace define */ function appendElement(el,domBuilder,currentNSMap){ var tagName = el.tagName; var localNSMap = null; //var currentNSMap = parseStack[parseStack.length-1].currentNSMap; var i = el.length; while(i--){ var a = el[i]; var qName = a.qName; var value = a.value; var nsp = qName.indexOf(':'); if(nsp>0){ var prefix = a.prefix = qName.slice(0,nsp); var localName = qName.slice(nsp+1); var nsPrefix = prefix === 'xmlns' && localName }else{ localName = qName; prefix = null nsPrefix = qName === 'xmlns' && '' } //can not set prefix,because prefix !== '' a.localName = localName ; //prefix == null for no ns prefix attribute if(nsPrefix !== false){//hack!! if(localNSMap == null){ localNSMap = {} //console.log(currentNSMap,0) _copy(currentNSMap,currentNSMap={}) //console.log(currentNSMap,1) } currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value; a.uri = 'http://www.w3.org/2000/xmlns/' domBuilder.startPrefixMapping(nsPrefix, value) } } var i = el.length; while(i--){ a = el[i]; var prefix = a.prefix; if(prefix){//no prefix attribute has no namespace if(prefix === 'xml'){ a.uri = 'http://www.w3.org/XML/1998/namespace'; }if(prefix !== 'xmlns'){ a.uri = currentNSMap[prefix || ''] //{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)} } } } var nsp = tagName.indexOf(':'); if(nsp>0){ prefix = el.prefix = tagName.slice(0,nsp); localName = el.localName = tagName.slice(nsp+1); }else{ prefix = null;//important!! localName = el.localName = tagName; } //no prefix element has default namespace var ns = el.uri = currentNSMap[prefix || '']; domBuilder.startElement(ns,localName,tagName,el); //endPrefixMapping and startPrefixMapping have not any help for dom builder //localNSMap = null if(el.closed){ domBuilder.endElement(ns,localName,tagName); if(localNSMap){ for(prefix in localNSMap){ domBuilder.endPrefixMapping(prefix) } } }else{ el.currentNSMap = currentNSMap; el.localNSMap = localNSMap; //parseStack.push(el); return true; } } function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){ if(/^(?:script|textarea)$/i.test(tagName)){ var elEndStart = source.indexOf('',elStartEnd); var text = source.substring(elStartEnd+1,elEndStart); if(/[&<]/.test(text)){ if(/^script$/i.test(tagName)){ //if(!/\]\]>/.test(text)){ //lexHandler.startCDATA(); domBuilder.characters(text,0,text.length); //lexHandler.endCDATA(); return elEndStart; //} }//}else{//text area text = text.replace(/&#?\w+;/g,entityReplacer); domBuilder.characters(text,0,text.length); return elEndStart; //} } } return elStartEnd+1; } function fixSelfClosed(source,elStartEnd,tagName,closeMap){ //if(tagName in closeMap){ var pos = closeMap[tagName]; if(pos == null){ //console.log(tagName) pos = source.lastIndexOf('') if(pos',start+4); //append comment source.substring(4,end)// https://davidwalsh.name/add-rules-stylesheets style.appendChild(document.createTextNode("")); document.head.appendChild(style); return style.sheet; } }, { key: "addStyleRules", value: function addStyleRules(selector, rulesArray) { var scope = "#" + this.id + " "; var rules = ""; if (!this.sheet) { this.sheet = this.getSheet(); } rulesArray.forEach(function (set) { for (var prop in set) { if (set.hasOwnProperty(prop)) { rules += prop + ":" + set[prop] + ";"; } } }); this.sheet.insertRule(scope + selector + " {" + rules + "}", 0); } }, { key: "axis", value: function axis(_axis) { if (_axis === "horizontal") { this.container.style.display = "flex"; this.container.style.flexDirection = "row"; this.container.style.flexWrap = "nowrap"; } else { this.container.style.display = "block"; } } // orientation(orientation) { // if (orientation === "landscape") { // // } else { // // } // // this.orientation = orientation; // } }, { key: "direction", value: function direction(dir) { if (this.container) { this.container.dir = dir; this.container.style["direction"] = dir; } if (this.settings.fullsize) { document.body.style["direction"] = dir; } } }, { key: "destroy", value: function destroy() { var base; if (this.element) { if (this.settings.hidden) { base = this.wrapper; } else { base = this.container; } if (this.element.contains(this.container)) { this.element.removeChild(this.container); } window.removeEventListener("resize", this.resizeFunc); window.removeEventListener("orientationChange", this.orientationChangeFunc); } } }]); return Stage; }(); exports.default = Stage; module.exports = exports["default"]; /***/ }), /* 60 */ /***/ (function(module, exports, __webpack_require__) { var debounce = __webpack_require__(21), isObject = __webpack_require__(15); /** Error message constants. */ var FUNC_ERROR_TEXT = 'Expected a function'; /** * Creates a throttled function that only invokes `func` at most once per * every `wait` milliseconds. The throttled function comes with a `cancel` * method to cancel delayed `func` invocations and a `flush` method to * immediately invoke them. Provide `options` to indicate whether `func` * should be invoked on the leading and/or trailing edge of the `wait` * timeout. The `func` is invoked with the last arguments provided to the * throttled function. Subsequent calls to the throttled function return the * result of the last `func` invocation. * * **Note:** If `leading` and `trailing` options are `true`, `func` is * invoked on the trailing edge of the timeout only if the throttled function * is invoked more than once during the `wait` timeout. * * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred * until to the next tick, similar to `setTimeout` with a timeout of `0`. * * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) * for details over the differences between `_.throttle` and `_.debounce`. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to throttle. * @param {number} [wait=0] The number of milliseconds to throttle invocations to. * @param {Object} [options={}] The options object. * @param {boolean} [options.leading=true] * Specify invoking on the leading edge of the timeout. * @param {boolean} [options.trailing=true] * Specify invoking on the trailing edge of the timeout. * @returns {Function} Returns the new throttled function. * @example * * // Avoid excessively updating the position while scrolling. * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); * * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); * jQuery(element).on('click', throttled); * * // Cancel the trailing throttled invocation. * jQuery(window).on('popstate', throttled.cancel); */ function throttle(func, wait, options) { var leading = true, trailing = true; if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } if (isObject(options)) { leading = 'leading' in options ? !!options.leading : leading; trailing = 'trailing' in options ? !!options.trailing : trailing; } return debounce(func, wait, { 'leading': leading, 'maxWait': wait, 'trailing': trailing }); } module.exports = throttle; /***/ }), /* 61 */ /***/ (function(module, exports, __webpack_require__) { var root = __webpack_require__(22); /** * Gets the timestamp of the number of milliseconds that have elapsed since * the Unix epoch (1 January 1970 00:00:00 UTC). * * @static * @memberOf _ * @since 2.4.0 * @category Date * @returns {number} Returns the timestamp. * @example * * _.defer(function(stamp) { * console.log(_.now() - stamp); * }, _.now()); * // => Logs the number of milliseconds it took for the deferred invocation. */ var now = function() { return root.Date.now(); }; module.exports = now; /***/ }), /* 62 */ /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(global) {/** Detect free variable `global` from Node.js. */ var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; module.exports = freeGlobal; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(8))) /***/ }), /* 63 */ /***/ (function(module, exports, __webpack_require__) { var isObject = __webpack_require__(15), isSymbol = __webpack_require__(64); /** Used as references for various `Number` constants. */ var NAN = 0 / 0; /** Used to match leading and trailing whitespace. */ var reTrim = /^\s+|\s+$/g; /** Used to detect bad signed hexadecimal string values. */ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; /** Used to detect binary string values. */ var reIsBinary = /^0b[01]+$/i; /** Used to detect octal string values. */ var reIsOctal = /^0o[0-7]+$/i; /** Built-in method references without a dependency on `root`. */ var freeParseInt = parseInt; /** * Converts `value` to a number. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to process. * @returns {number} Returns the number. * @example * * _.toNumber(3.2); * // => 3.2 * * _.toNumber(Number.MIN_VALUE); * // => 5e-324 * * _.toNumber(Infinity); * // => Infinity * * _.toNumber('3.2'); * // => 3.2 */ function toNumber(value) { if (typeof value == 'number') { return value; } if (isSymbol(value)) { return NAN; } if (isObject(value)) { var other = typeof value.valueOf == 'function' ? value.valueOf() : value; value = isObject(other) ? (other + '') : other; } if (typeof value != 'string') { return value === 0 ? value : +value; } value = value.replace(reTrim, ''); var isBinary = reIsBinary.test(value); return (isBinary || reIsOctal.test(value)) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : (reIsBadHex.test(value) ? NAN : +value); } module.exports = toNumber; /***/ }), /* 64 */ /***/ (function(module, exports, __webpack_require__) { var baseGetTag = __webpack_require__(65), isObjectLike = __webpack_require__(68); /** `Object#toString` result references. */ var symbolTag = '[object Symbol]'; /** * Checks if `value` is classified as a `Symbol` primitive or object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. * @example * * _.isSymbol(Symbol.iterator); * // => true * * _.isSymbol('abc'); * // => false */ function isSymbol(value) { return typeof value == 'symbol' || (isObjectLike(value) && baseGetTag(value) == symbolTag); } module.exports = isSymbol; /***/ }), /* 65 */ /***/ (function(module, exports, __webpack_require__) { var Symbol = __webpack_require__(23), getRawTag = __webpack_require__(66), objectToString = __webpack_require__(67); /** `Object#toString` result references. */ var nullTag = '[object Null]', undefinedTag = '[object Undefined]'; /** Built-in value references. */ var symToStringTag = Symbol ? Symbol.toStringTag : undefined; /** * The base implementation of `getTag` without fallbacks for buggy environments. * * @private * @param {*} value The value to query. * @returns {string} Returns the `toStringTag`. */ function baseGetTag(value) { if (value == null) { return value === undefined ? undefinedTag : nullTag; } return (symToStringTag && symToStringTag in Object(value)) ? getRawTag(value) : objectToString(value); } module.exports = baseGetTag; /***/ }), /* 66 */ /***/ (function(module, exports, __webpack_require__) { var Symbol = __webpack_require__(23); /** Used for built-in method references. */ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var nativeObjectToString = objectProto.toString; /** Built-in value references. */ var symToStringTag = Symbol ? Symbol.toStringTag : undefined; /** * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. * * @private * @param {*} value The value to query. * @returns {string} Returns the raw `toStringTag`. */ function getRawTag(value) { var isOwn = hasOwnProperty.call(value, symToStringTag), tag = value[symToStringTag]; try { value[symToStringTag] = undefined; var unmasked = true; } catch (e) {} var result = nativeObjectToString.call(value); if (unmasked) { if (isOwn) { value[symToStringTag] = tag; } else { delete value[symToStringTag]; } } return result; } module.exports = getRawTag; /***/ }), /* 67 */ /***/ (function(module, exports) { /** Used for built-in method references. */ var objectProto = Object.prototype; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var nativeObjectToString = objectProto.toString; /** * Converts `value` to a string using `Object.prototype.toString`. * * @private * @param {*} value The value to convert. * @returns {string} Returns the converted string. */ function objectToString(value) { return nativeObjectToString.call(value); } module.exports = objectToString; /***/ }), /* 68 */ /***/ (function(module, exports) { /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike(value) { return value != null && typeof value == 'object'; } module.exports = isObjectLike; /***/ }), /* 69 */ /***/ (function(module, exports, __webpack_require__) { "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; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Views = function () { function Views(container) { _classCallCheck(this, Views); this.container = container; this._views = []; this.length = 0; this.hidden = false; } _createClass(Views, [{ key: "all", value: function all() { return this._views; } }, { key: "first", value: function first() { return this._views[0]; } }, { key: "last", value: function last() { return this._views[this._views.length - 1]; } }, { key: "indexOf", value: function indexOf(view) { return this._views.indexOf(view); } }, { key: "slice", value: function slice() { return this._views.slice.apply(this._views, arguments); } }, { key: "get", value: function get(i) { return this._views[i]; } }, { key: "append", value: function append(view) { this._views.push(view); if (this.container) { this.container.appendChild(view.element); } this.length++; return view; } }, { key: "prepend", value: function prepend(view) { this._views.unshift(view); if (this.container) { this.container.insertBefore(view.element, this.container.firstChild); } this.length++; return view; } }, { key: "insert", value: function insert(view, index) { this._views.splice(index, 0, view); if (this.container) { if (index < this.container.children.length) { this.container.insertBefore(view.element, this.container.children[index]); } else { this.container.appendChild(view.element); } } this.length++; return view; } }, { key: "remove", value: function remove(view) { var index = this._views.indexOf(view); if (index > -1) { this._views.splice(index, 1); } this.destroy(view); this.length--; } }, { key: "destroy", value: function destroy(view) { if (view.displayed) { view.destroy(); } if (this.container) { this.container.removeChild(view.element); } view = null; } // Iterators }, { key: "forEach", value: function forEach() { return this._views.forEach.apply(this._views, arguments); } }, { key: "clear", value: function clear() { // Remove all views var view; var len = this.length; if (!this.length) return; for (var i = 0; i < len; i++) { view = this._views[i]; this.destroy(view); } this._views = []; this.length = 0; } }, { key: "find", value: function find(section) { var view; var len = this.length; for (var i = 0; i < len; i++) { view = this._views[i]; if (view.displayed && view.section.index == section.index) { return view; } } } }, { key: "displayed", value: function displayed() { var displayed = []; var view; var len = this.length; for (var i = 0; i < len; i++) { view = this._views[i]; if (view.displayed) { displayed.push(view); } } return displayed; } }, { key: "show", value: function show() { var view; var len = this.length; for (var i = 0; i < len; i++) { view = this._views[i]; if (view.displayed) { view.show(); } } this.hidden = false; } }, { key: "hide", value: function hide() { var view; var len = this.length; for (var i = 0; i < len; i++) { view = this._views[i]; if (view.displayed) { view.hide(); } } this.hidden = true; } }]); return Views; }(); exports.default = Views; module.exports = exports["default"]; /***/ }), /* 70 */ /***/ (function(module, exports, __webpack_require__) { "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 _core = __webpack_require__(0); var _request = __webpack_require__(11); var _request2 = _interopRequireDefault(_request); var _mime = __webpack_require__(17); var _mime2 = _interopRequireDefault(_mime); var _path = __webpack_require__(4); var _path2 = _interopRequireDefault(_path); 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"); } } /** * Handles Unzipping a requesting files from an Epub Archive * @class */ var Archive = function () { function Archive() { _classCallCheck(this, Archive); this.zip = undefined; this.urlCache = {}; this.checkRequirements(); } /** * Checks to see if JSZip exists in global namspace, * Requires JSZip if it isn't there * @private */ _createClass(Archive, [{ key: "checkRequirements", value: function checkRequirements() { try { if (typeof JSZip === "undefined") { var _JSZip = __webpack_require__(71); this.zip = new _JSZip(); } else { this.zip = new JSZip(); } } catch (e) { throw new Error("JSZip lib not loaded"); } } /** * Open an archive * @param {binary} input * @param {boolean} [isBase64] tells JSZip if the input data is base64 encoded * @return {Promise} zipfile */ }, { key: "open", value: function open(input, isBase64) { return this.zip.loadAsync(input, { "base64": isBase64 }); } /** * Load and Open an archive * @param {string} zipUrl * @param {boolean} [isBase64] tells JSZip if the input data is base64 encoded * @return {Promise} zipfile */ }, { key: "openUrl", value: function openUrl(zipUrl, isBase64) { return (0, _request2.default)(zipUrl, "binary").then(function (data) { return this.zip.loadAsync(data, { "base64": isBase64 }); }.bind(this)); } /** * Request a url from the archive * @param {string} url a url to request from the archive * @param {string} [type] specify the type of the returned result * @return {Promise} */ }, { key: "request", value: function request(url, type) { var deferred = new _core.defer(); var response; var path = new _path2.default(url); // If type isn't set, determine it from the file extension if (!type) { type = path.extension; } if (type == "blob") { response = this.getBlob(url); } else { response = this.getText(url); } if (response) { response.then(function (r) { var result = this.handleResponse(r, type); deferred.resolve(result); }.bind(this)); } else { deferred.reject({ message: "File not found in the epub: " + url, stack: new Error().stack }); } return deferred.promise; } /** * Handle the response from request * @private * @param {any} response * @param {string} [type] * @return {any} the parsed result */ }, { key: "handleResponse", value: function handleResponse(response, type) { var r; if (type == "json") { r = JSON.parse(response); } else if ((0, _core.isXml)(type)) { r = (0, _core.parse)(response, "text/xml"); } else if (type == "xhtml") { r = (0, _core.parse)(response, "application/xhtml+xml"); } else if (type == "html" || type == "htm") { r = (0, _core.parse)(response, "text/html"); } else { r = response; } return r; } /** * Get a Blob from Archive by Url * @param {string} url * @param {string} [mimeType] * @return {Blob} */ }, { key: "getBlob", value: function getBlob(url, mimeType) { var decodededUrl = window.decodeURIComponent(url.substr(1)); // Remove first slash var entry = this.zip.file(decodededUrl); if (entry) { mimeType = mimeType || _mime2.default.lookup(entry.name); return entry.async("uint8array").then(function (uint8array) { return new Blob([uint8array], { type: mimeType }); }); } } /** * Get Text from Archive by Url * @param {string} url * @param {string} [encoding] * @return {string} */ }, { key: "getText", value: function getText(url, encoding) { var decodededUrl = window.decodeURIComponent(url.substr(1)); // Remove first slash var entry = this.zip.file(decodededUrl); if (entry) { return entry.async("string").then(function (text) { return text; }); } } /** * Get a base64 encoded result from Archive by Url * @param {string} url * @param {string} [mimeType] * @return {string} base64 encoded */ }, { key: "getBase64", value: function getBase64(url, mimeType) { var decodededUrl = window.decodeURIComponent(url.substr(1)); // Remove first slash var entry = this.zip.file(decodededUrl); if (entry) { mimeType = mimeType || _mime2.default.lookup(entry.name); return entry.async("base64").then(function (data) { return "data:" + mimeType + ";base64," + data; }); } } /** * Create a Url from an unarchived item * @param {string} url * @param {object} [options.base64] use base64 encoding or blob url * @return {Promise} url promise with Url string */ }, { key: "createUrl", value: function createUrl(url, options) { var deferred = new _core.defer(); var _URL = window.URL || window.webkitURL || window.mozURL; var tempUrl; var response; var useBase64 = options && options.base64; if (url in this.urlCache) { deferred.resolve(this.urlCache[url]); return deferred.promise; } if (useBase64) { response = this.getBase64(url); if (response) { response.then(function (tempUrl) { this.urlCache[url] = tempUrl; deferred.resolve(tempUrl); }.bind(this)); } } else { response = this.getBlob(url); if (response) { response.then(function (blob) { tempUrl = _URL.createObjectURL(blob); this.urlCache[url] = tempUrl; deferred.resolve(tempUrl); }.bind(this)); } } if (!response) { deferred.reject({ message: "File not found in the epub: " + url, stack: new Error().stack }); } return deferred.promise; } /** * Revoke Temp Url for a achive item * @param {string} url url of the item in the archive */ }, { key: "revokeUrl", value: function revokeUrl(url) { var _URL = window.URL || window.webkitURL || window.mozURL; var fromCache = this.urlCache[url]; if (fromCache) _URL.revokeObjectURL(fromCache); } }, { key: "destroy", value: function destroy() { var _URL = window.URL || window.webkitURL || window.mozURL; for (var fromCache in this.urlCache) { _URL.revokeObjectURL(fromCache); } this.zip = undefined; this.urlCache = {}; } }]); return Archive; }(); exports.default = Archive; module.exports = exports["default"]; /***/ }), /* 71 */ /***/ (function(module, exports) { if(typeof __WEBPACK_EXTERNAL_MODULE_71__ === 'undefined') {var e = new Error("Cannot find module \"jszip\""); e.code = 'MODULE_NOT_FOUND'; throw e;} module.exports = __WEBPACK_EXTERNAL_MODULE_71__; /***/ }), /* 72 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* WEBPACK VAR INJECTION */(function(global, module) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* From https://github.com/webcomponents/URL/blob/master/url.js * Added UMD, file link handling */ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; (function (root, factory) { // Fix for this being undefined in modules if (!root) { root = window || global; } if (( false ? 'undefined' : _typeof(module)) === 'object' && module.exports) { // Node module.exports = factory(root); } else if (true) { // AMD. Register as an anonymous module. !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); } else { // Browser globals (root is window) root.URL = factory(root); } })(undefined, function (scope) { // feature detect for URL constructor var hasWorkingUrl = false; if (!scope.forceJURL) { try { var u = new URL('b', 'http://a'); u.pathname = 'c%20d'; hasWorkingUrl = u.href === 'http://a/c%20d'; } catch (e) {} } if (hasWorkingUrl) return scope.URL; var relative = Object.create(null); relative['ftp'] = 21; relative['file'] = 0; relative['gopher'] = 70; relative['http'] = 80; relative['https'] = 443; relative['ws'] = 80; relative['wss'] = 443; var relativePathDotMapping = Object.create(null); relativePathDotMapping['%2e'] = '.'; relativePathDotMapping['.%2e'] = '..'; relativePathDotMapping['%2e.'] = '..'; relativePathDotMapping['%2e%2e'] = '..'; function isRelativeScheme(scheme) { return relative[scheme] !== undefined; } function invalid() { clear.call(this); this._isInvalid = true; } function IDNAToASCII(h) { if ('' == h) { invalid.call(this); } // XXX return h.toLowerCase(); } function percentEscape(c) { var unicode = c.charCodeAt(0); if (unicode > 0x20 && unicode < 0x7F && // " # < > ? ` [0x22, 0x23, 0x3C, 0x3E, 0x3F, 0x60].indexOf(unicode) == -1) { return c; } return encodeURIComponent(c); } function percentEscapeQuery(c) { // XXX This actually needs to encode c using encoding and then // convert the bytes one-by-one. var unicode = c.charCodeAt(0); if (unicode > 0x20 && unicode < 0x7F && // " # < > ` (do not escape '?') [0x22, 0x23, 0x3C, 0x3E, 0x60].indexOf(unicode) == -1) { return c; } return encodeURIComponent(c); } var EOF = undefined, ALPHA = /[a-zA-Z]/, ALPHANUMERIC = /[a-zA-Z0-9\+\-\.]/; function parse(input, stateOverride, base) { function err(message) { errors.push(message); } var state = stateOverride || 'scheme start', cursor = 0, buffer = '', seenAt = false, seenBracket = false, errors = []; loop: while ((input[cursor - 1] != EOF || cursor == 0) && !this._isInvalid) { var c = input[cursor]; switch (state) { case 'scheme start': if (c && ALPHA.test(c)) { buffer += c.toLowerCase(); // ASCII-safe state = 'scheme'; } else if (!stateOverride) { buffer = ''; state = 'no scheme'; continue; } else { err('Invalid scheme.'); break loop; } break; case 'scheme': if (c && ALPHANUMERIC.test(c)) { buffer += c.toLowerCase(); // ASCII-safe } else if (':' == c) { this._scheme = buffer; buffer = ''; if (stateOverride) { break loop; } if (isRelativeScheme(this._scheme)) { this._isRelative = true; } if ('file' == this._scheme) { state = 'relative'; } else if (this._isRelative && base && base._scheme == this._scheme) { state = 'relative or authority'; } else if (this._isRelative) { state = 'authority first slash'; } else { state = 'scheme data'; } } else if (!stateOverride) { buffer = ''; cursor = 0; state = 'no scheme'; continue; } else if (EOF == c) { break loop; } else { err('Code point not allowed in scheme: ' + c); break loop; } break; case 'scheme data': if ('?' == c) { this._query = '?'; state = 'query'; } else if ('#' == c) { this._fragment = '#'; state = 'fragment'; } else { // XXX error handling if (EOF != c && '\t' != c && '\n' != c && '\r' != c) { this._schemeData += percentEscape(c); } } break; case 'no scheme': if (!base || !isRelativeScheme(base._scheme)) { err('Missing scheme.'); invalid.call(this); } else { state = 'relative'; continue; } break; case 'relative or authority': if ('/' == c && '/' == input[cursor + 1]) { state = 'authority ignore slashes'; } else { err('Expected /, got: ' + c); state = 'relative'; continue; } break; case 'relative': this._isRelative = true; if ('file' != this._scheme) this._scheme = base._scheme; if (EOF == c) { this._host = base._host; this._port = base._port; this._path = base._path.slice(); this._query = base._query; this._username = base._username; this._password = base._password; break loop; } else if ('/' == c || '\\' == c) { if ('\\' == c) err('\\ is an invalid code point.'); state = 'relative slash'; } else if ('?' == c) { this._host = base._host; this._port = base._port; this._path = base._path.slice(); this._query = '?'; this._username = base._username; this._password = base._password; state = 'query'; } else if ('#' == c) { this._host = base._host; this._port = base._port; this._path = base._path.slice(); this._query = base._query; this._fragment = '#'; this._username = base._username; this._password = base._password; state = 'fragment'; } else { var nextC = input[cursor + 1]; var nextNextC = input[cursor + 2]; if ('file' != this._scheme || !ALPHA.test(c) || nextC != ':' && nextC != '|' || EOF != nextNextC && '/' != nextNextC && '\\' != nextNextC && '?' != nextNextC && '#' != nextNextC) { this._host = base._host; this._port = base._port; this._username = base._username; this._password = base._password; this._path = base._path.slice(); this._path.pop(); } state = 'relative path'; continue; } break; case 'relative slash': if ('/' == c || '\\' == c) { if ('\\' == c) { err('\\ is an invalid code point.'); } if ('file' == this._scheme) { state = 'file host'; } else { state = 'authority ignore slashes'; } } else { if ('file' != this._scheme) { this._host = base._host; this._port = base._port; this._username = base._username; this._password = base._password; } state = 'relative path'; continue; } break; case 'authority first slash': if ('/' == c) { state = 'authority second slash'; } else { err("Expected '/', got: " + c); state = 'authority ignore slashes'; continue; } break; case 'authority second slash': state = 'authority ignore slashes'; if ('/' != c) { err("Expected '/', got: " + c); continue; } break; case 'authority ignore slashes': if ('/' != c && '\\' != c) { state = 'authority'; continue; } else { err('Expected authority, got: ' + c); } break; case 'authority': if ('@' == c) { if (seenAt) { err('@ already seen.'); buffer += '%40'; } seenAt = true; for (var i = 0; i < buffer.length; i++) { var cp = buffer[i]; if ('\t' == cp || '\n' == cp || '\r' == cp) { err('Invalid whitespace in authority.'); continue; } // XXX check URL code points if (':' == cp && null === this._password) { this._password = ''; continue; } var tempC = percentEscape(cp); null !== this._password ? this._password += tempC : this._username += tempC; } buffer = ''; } else if (EOF == c || '/' == c || '\\' == c || '?' == c || '#' == c) { cursor -= buffer.length; buffer = ''; state = 'host'; continue; } else { buffer += c; } break; case 'file host': if (EOF == c || '/' == c || '\\' == c || '?' == c || '#' == c) { if (buffer.length == 2 && ALPHA.test(buffer[0]) && (buffer[1] == ':' || buffer[1] == '|')) { state = 'relative path'; } else if (buffer.length == 0) { state = 'relative path start'; } else { this._host = IDNAToASCII.call(this, buffer); buffer = ''; state = 'relative path start'; } continue; } else if ('\t' == c || '\n' == c || '\r' == c) { err('Invalid whitespace in file host.'); } else { buffer += c; } break; case 'host': case 'hostname': if (':' == c && !seenBracket) { // XXX host parsing this._host = IDNAToASCII.call(this, buffer); buffer = ''; state = 'port'; if ('hostname' == stateOverride) { break loop; } } else if (EOF == c || '/' == c || '\\' == c || '?' == c || '#' == c) { this._host = IDNAToASCII.call(this, buffer); buffer = ''; state = 'relative path start'; if (stateOverride) { break loop; } continue; } else if ('\t' != c && '\n' != c && '\r' != c) { if ('[' == c) { seenBracket = true; } else if (']' == c) { seenBracket = false; } buffer += c; } else { err('Invalid code point in host/hostname: ' + c); } break; case 'port': if (/[0-9]/.test(c)) { buffer += c; } else if (EOF == c || '/' == c || '\\' == c || '?' == c || '#' == c || stateOverride) { if ('' != buffer) { var temp = parseInt(buffer, 10); if (temp != relative[this._scheme]) { this._port = temp + ''; } buffer = ''; } if (stateOverride) { break loop; } state = 'relative path start'; continue; } else if ('\t' == c || '\n' == c || '\r' == c) { err('Invalid code point in port: ' + c); } else { invalid.call(this); } break; case 'relative path start': if ('\\' == c) err("'\\' not allowed in path."); state = 'relative path'; if ('/' != c && '\\' != c) { continue; } break; case 'relative path': if (EOF == c || '/' == c || '\\' == c || !stateOverride && ('?' == c || '#' == c)) { if ('\\' == c) { err('\\ not allowed in relative path.'); } var tmp; if (tmp = relativePathDotMapping[buffer.toLowerCase()]) { buffer = tmp; } if ('..' == buffer) { this._path.pop(); if ('/' != c && '\\' != c) { this._path.push(''); } } else if ('.' == buffer && '/' != c && '\\' != c) { this._path.push(''); } else if ('.' != buffer) { if ('file' == this._scheme && this._path.length == 0 && buffer.length == 2 && ALPHA.test(buffer[0]) && buffer[1] == '|') { buffer = buffer[0] + ':'; } this._path.push(buffer); } buffer = ''; if ('?' == c) { this._query = '?'; state = 'query'; } else if ('#' == c) { this._fragment = '#'; state = 'fragment'; } } else if ('\t' != c && '\n' != c && '\r' != c) { buffer += percentEscape(c); } break; case 'query': if (!stateOverride && '#' == c) { this._fragment = '#'; state = 'fragment'; } else if (EOF != c && '\t' != c && '\n' != c && '\r' != c) { this._query += percentEscapeQuery(c); } break; case 'fragment': if (EOF != c && '\t' != c && '\n' != c && '\r' != c) { this._fragment += c; } break; } cursor++; } } function clear() { this._scheme = ''; this._schemeData = ''; this._username = ''; this._password = null; this._host = ''; this._port = ''; this._path = []; this._query = ''; this._fragment = ''; this._isInvalid = false; this._isRelative = false; } // Does not process domain names or IP addresses. // Does not handle encoding for the query parameter. function jURL(url, base /* , encoding */) { if (base !== undefined && !(base instanceof jURL)) base = new jURL(String(base)); this._url = url; clear.call(this); var input = url.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g, ''); // encoding = encoding || 'utf-8' parse.call(this, input, null, base); } jURL.prototype = { toString: function toString() { return this.href; }, get href() { if (this._isInvalid) return this._url; var authority = ''; if ('' != this._username || null != this._password) { authority = this._username + (null != this._password ? ':' + this._password : '') + '@'; } return this.protocol + (this._isRelative ? '//' + authority + this.host : '') + this.pathname + this._query + this._fragment; }, set href(href) { clear.call(this); parse.call(this, href); }, get protocol() { return this._scheme + ':'; }, set protocol(protocol) { if (this._isInvalid) return; parse.call(this, protocol + ':', 'scheme start'); }, get host() { return this._isInvalid ? '' : this._port ? this._host + ':' + this._port : this._host; }, set host(host) { if (this._isInvalid || !this._isRelative) return; parse.call(this, host, 'host'); }, get hostname() { return this._host; }, set hostname(hostname) { if (this._isInvalid || !this._isRelative) return; parse.call(this, hostname, 'hostname'); }, get port() { return this._port; }, set port(port) { if (this._isInvalid || !this._isRelative) return; parse.call(this, port, 'port'); }, get pathname() { return this._isInvalid ? '' : this._isRelative ? '/' + this._path.join('/') : this._schemeData; }, set pathname(pathname) { if (this._isInvalid || !this._isRelative) return; this._path = []; parse.call(this, pathname, 'relative path start'); }, get search() { return this._isInvalid || !this._query || '?' == this._query ? '' : this._query; }, set search(search) { if (this._isInvalid || !this._isRelative) return; this._query = '?'; if ('?' == search[0]) search = search.slice(1); parse.call(this, search, 'query'); }, get hash() { return this._isInvalid || !this._fragment || '#' == this._fragment ? '' : this._fragment; }, set hash(hash) { if (this._isInvalid) return; this._fragment = '#'; if ('#' == hash[0]) hash = hash.slice(1); parse.call(this, hash, 'fragment'); }, get origin() { var host; if (this._isInvalid || !this._scheme) { return ''; } // javascript: Gecko returns String(""), WebKit/Blink String("null") // Gecko throws error for "data://" // data: Gecko returns "", Blink returns "data://", WebKit returns "null" // Gecko returns String("") for file: mailto: // WebKit/Blink returns String("SCHEME://") for file: mailto: switch (this._scheme) { case 'file': return 'file://'; // EPUBJS Added case 'data': case 'javascript': case 'mailto': return 'null'; } host = this.host; if (!host) { return ''; } return this._scheme + '://' + host; } }; // Copy over the static methods var OriginalURL = scope.URL; if (OriginalURL) { jURL.createObjectURL = function (blob) { // IE extension allows a second optional options argument. // http://msdn.microsoft.com/en-us/library/ie/hh772302(v=vs.85).aspx return OriginalURL.createObjectURL.apply(OriginalURL, arguments); }; jURL.revokeObjectURL = function (url) { OriginalURL.revokeObjectURL(url); }; } return jURL; }); /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(8), __webpack_require__(73)(module))) /***/ }), /* 73 */ /***/ (function(module, exports) { module.exports = function(module) { if(!module.webpackPolyfill) { module.deprecate = function() {}; module.paths = []; // module.parent = undefined by default if(!module.children) module.children = []; Object.defineProperty(module, "loaded", { enumerable: true, get: function() { return module.l; } }); Object.defineProperty(module, "id", { enumerable: true, get: function() { return module.i; } }); module.webpackPolyfill = 1; } return module; }; /***/ }) /******/ ]); }); //# sourceMappingURL=epub.js.map