summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2017-06-09 15:13:51 +0300
committerAndrew Dolgov <[email protected]>2017-06-09 15:13:51 +0300
commitbbd8f03dfb41595e9b6513a656ca14b68695632f (patch)
treed88191b9aece7b05d0bd21a91b2193f53b3e4458 /lib
parent4fe174cd142731f3131a05b1753cf3a0fcae0340 (diff)
update epub.js
Diffstat (limited to 'lib')
-rw-r--r--lib/epub.js417
1 files changed, 266 insertions, 151 deletions
diff --git a/lib/epub.js b/lib/epub.js
index c00249d..a45e06d 100644
--- a/lib/epub.js
+++ b/lib/epub.js
@@ -3,13 +3,13 @@
* @copyright Copyright (c) 2016 Yehuda Katz, Tom Dale, Stefan Penner and contributors
* @license Licensed under MIT license
* See https://raw.githubusercontent.com/tildeio/rsvp.js/master/LICENSE
- * @version 3.3.3
+ * @version 3.5.0
*/
(function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
- typeof define === 'function' && define.amd ? define(['exports'], factory) :
- (factory((global.RSVP = global.RSVP || {})));
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+ typeof define === 'function' && define.amd ? define(['exports'], factory) :
+ (factory((global.RSVP = global.RSVP || {})));
}(this, (function (exports) { 'use strict';
function indexOf(callbacks, callback) {
@@ -283,7 +283,7 @@ function scheduleFlush() {
queue.length = 0;
}, 50);
}
-function instrument(eventName, promise, child) {
+function instrument$1(eventName, promise, child) {
if (1 === queue.push({
name: eventName,
payload: {
@@ -366,18 +366,18 @@ function getThen(promise) {
}
}
-function tryThen(then, value, fulfillmentHandler, rejectionHandler) {
+function tryThen(then$$1, value, fulfillmentHandler, rejectionHandler) {
try {
- then.call(value, fulfillmentHandler, rejectionHandler);
+ then$$1.call(value, fulfillmentHandler, rejectionHandler);
} catch (e) {
return e;
}
}
-function handleForeignThenable(promise, thenable, then) {
+function handleForeignThenable(promise, thenable, then$$1) {
config.async(function (promise) {
var sealed = false;
- var error = tryThen(then, thenable, function (value) {
+ var error = tryThen(then$$1, thenable, function (value) {
if (sealed) {
return;
}
@@ -422,16 +422,17 @@ function handleOwnThenable(promise, thenable) {
}
}
-function handleMaybeThenable(promise, maybeThenable, then$$) {
- if (maybeThenable.constructor === promise.constructor && then$$ === then && promise.constructor.resolve === resolve$1) {
+function handleMaybeThenable(promise, maybeThenable, then$$1) {
+ if (maybeThenable.constructor === promise.constructor && then$$1 === then && promise.constructor.resolve === resolve$1) {
handleOwnThenable(promise, maybeThenable);
} else {
- if (then$$ === GET_THEN_ERROR) {
+ if (then$$1 === GET_THEN_ERROR) {
reject(promise, GET_THEN_ERROR.error);
- } else if (then$$ === undefined) {
+ GET_THEN_ERROR.error = null;
+ } else if (then$$1 === undefined) {
fulfill(promise, maybeThenable);
- } else if (isFunction(then$$)) {
- handleForeignThenable(promise, maybeThenable, then$$);
+ } else if (isFunction(then$$1)) {
+ handleForeignThenable(promise, maybeThenable, then$$1);
} else {
fulfill(promise, maybeThenable);
}
@@ -466,7 +467,7 @@ function fulfill(promise, value) {
if (promise._subscribers.length === 0) {
if (config.instrument) {
- instrument('fulfilled', promise);
+ instrument$1('fulfilled', promise);
}
} else {
config.async(publish, promise);
@@ -502,7 +503,7 @@ function publish(promise) {
var settled = promise._state;
if (config.instrument) {
- instrument(settled === FULFILLED ? 'fulfilled' : 'rejected', promise);
+ instrument$1(settled === FULFILLED ? 'fulfilled' : 'rejected', promise);
}
if (subscribers.length === 0) {
@@ -555,10 +556,10 @@ function invokeCallback(settled, promise, callback, detail) {
if (value === TRY_CATCH_ERROR) {
failed = true;
error = value.error;
- value = null;
+ value.error = null; // release
} else {
- succeeded = true;
- }
+ succeeded = true;
+ }
if (promise === value) {
reject(promise, withOwnPromise());
@@ -610,7 +611,7 @@ function then(onFulfillment, onRejection, label) {
var state = parent._state;
if (state === FULFILLED && !onFulfillment || state === REJECTED && !onRejection) {
- config.instrument && instrument('chained', parent, parent);
+ config.instrument && instrument$1('chained', parent, parent);
return parent;
}
@@ -619,7 +620,7 @@ function then(onFulfillment, onRejection, label) {
var child = new parent.constructor(noop, label);
var result = parent._result;
- config.instrument && instrument('chained', parent, child);
+ config.instrument && instrument$1('chained', parent, child);
if (state) {
(function () {
@@ -699,28 +700,28 @@ Enumerator.prototype._enumerate = function () {
Enumerator.prototype._settleMaybeThenable = function (entry, i) {
var c = this._instanceConstructor;
- var resolve = c.resolve;
+ var resolve$$1 = c.resolve;
- if (resolve === resolve$1) {
- var then$$ = getThen(entry);
+ if (resolve$$1 === resolve$1) {
+ var then$$1 = getThen(entry);
- if (then$$ === then && entry._state !== PENDING) {
+ if (then$$1 === then && entry._state !== PENDING) {
entry._onError = null;
this._settledAt(entry._state, i, entry._result);
- } else if (typeof then$$ !== 'function') {
+ } else if (typeof then$$1 !== 'function') {
this._remaining--;
this._result[i] = this._makeResult(FULFILLED, i, entry);
- } else if (c === Promise) {
+ } else if (c === Promise$1) {
var promise = new c(noop);
- handleMaybeThenable(promise, entry, then$$);
+ handleMaybeThenable(promise, entry, then$$1);
this._willSettleAt(promise, i);
} else {
- this._willSettleAt(new c(function (resolve) {
- return resolve(entry);
+ this._willSettleAt(new c(function (resolve$$1) {
+ return resolve$$1(entry);
}), i);
}
} else {
- this._willSettleAt(resolve(entry), i);
+ this._willSettleAt(resolve$$1(entry), i);
}
};
@@ -812,7 +813,7 @@ Enumerator.prototype._willSettleAt = function (promise, i) {
fulfilled, or rejected if any of them become rejected.
@static
*/
-function all(entries, label) {
+function all$1(entries, label) {
return new Enumerator(this, entries, true, /* abort on reject */label).promise;
}
@@ -882,7 +883,7 @@ function all(entries, label) {
@return {Promise} a promise which settles in the same way as the first passed
promise to settle.
*/
-function race(entries, label) {
+function race$1(entries, label) {
/*jshint validthis:true */
var Constructor = this;
@@ -1062,29 +1063,29 @@ function needsNew() {
Useful for tooling.
@constructor
*/
-function Promise(resolver, label) {
+function Promise$1(resolver, label) {
this._id = counter++;
this._label = label;
this._state = undefined;
this._result = undefined;
this._subscribers = [];
- config.instrument && instrument('created', this);
+ config.instrument && instrument$1('created', this);
if (noop !== resolver) {
typeof resolver !== 'function' && needsResolver();
- this instanceof Promise ? initializePromise(this, resolver) : needsNew();
+ this instanceof Promise$1 ? initializePromise(this, resolver) : needsNew();
}
}
-Promise.cast = resolve$1; // deprecated
-Promise.all = all;
-Promise.race = race;
-Promise.resolve = resolve$1;
-Promise.reject = reject$1;
+Promise$1.cast = resolve$1; // deprecated
+Promise$1.all = all$1;
+Promise$1.race = race$1;
+Promise$1.resolve = resolve$1;
+Promise$1.reject = reject$1;
-Promise.prototype = {
- constructor: Promise,
+Promise$1.prototype = {
+ constructor: Promise$1,
_guidKey: guidKey,
@@ -1342,7 +1343,7 @@ Promise.prototype = {
try {
return findAuthor(); // succeed or fail
} catch(error) {
- return findOtherAuther();
+ return findOtherAuthor();
} finally {
// always runs
// doesn't affect the return value
@@ -1353,7 +1354,7 @@ Promise.prototype = {
```js
findAuthor().catch(function(reason){
- return findOtherAuther();
+ return findOtherAuthor();
}).finally(function(){
// author was either found, or not
});
@@ -1570,7 +1571,7 @@ function wrapThenable(_then, promise) {
`RSVP.Promise`
@static
*/
-function denodeify(nodeFunc, options) {
+function denodeify$1(nodeFunc, options) {
var fn = function fn() {
var self = this;
var l = arguments.length;
@@ -1584,7 +1585,7 @@ function denodeify(nodeFunc, options) {
// TODO: clean this up
promiseInput = needsPromiseInput(arg);
if (promiseInput === GET_THEN_ERROR$1) {
- var p = new Promise(noop);
+ var p = new Promise$1(noop);
reject(p, GET_THEN_ERROR$1.value);
return p;
} else if (promiseInput && promiseInput !== true) {
@@ -1594,7 +1595,7 @@ function denodeify(nodeFunc, options) {
args[i] = arg;
}
- var promise = new Promise(noop);
+ var promise = new Promise$1(noop);
args[l] = function (err, val) {
if (err) reject(promise, err);else if (options === undefined) resolve(promise, val);else if (options === true) resolve(promise, arrayResult(arguments));else if (isArray(options)) resolve(promise, makeObject(arguments, options));else resolve(promise, val);
@@ -1621,7 +1622,7 @@ function handleValueInput(promise, args, nodeFunc, self) {
}
function handlePromiseInput(promise, args, nodeFunc, self) {
- return Promise.all(args).then(function (args) {
+ return Promise$1.all(args).then(function (args) {
var result = tryApply(nodeFunc, self, args);
if (result === ERROR) {
reject(promise, result.value);
@@ -1632,7 +1633,7 @@ function handlePromiseInput(promise, args, nodeFunc, self) {
function needsPromiseInput(arg) {
if (arg && typeof arg === 'object') {
- if (arg.constructor === Promise) {
+ if (arg.constructor === Promise$1) {
return true;
} else {
return getThen$1(arg);
@@ -1652,8 +1653,8 @@ function needsPromiseInput(arg) {
@param {String} label An optional label. This is useful
for tooling.
*/
-function all$1(array, label) {
- return Promise.all(array, label);
+function all$3(array, label) {
+ return Promise$1.all(array, label);
}
function AllSettled(Constructor, entries, label) {
@@ -1718,8 +1719,8 @@ AllSettled.prototype._validationError = function () {
@return {Promise} promise that is fulfilled with an array of the settled
states of the constituent promises.
*/
-function allSettled(entries, label) {
- return new AllSettled(Promise, entries, label).promise;
+function allSettled$1(entries, label) {
+ return new AllSettled(Promise$1, entries, label).promise;
}
/**
@@ -1732,8 +1733,8 @@ function allSettled(entries, label) {
@param {String} label An optional label. This is useful
for tooling.
*/
-function race$1(array, label) {
- return Promise.race(array, label);
+function race$3(array, label) {
+ return Promise$1.race(array, label);
}
function PromiseHash(Constructor, object, label) {
@@ -1867,8 +1868,8 @@ PromiseHash.prototype._enumerate = function () {
@return {Promise} promise that is fulfilled when all properties of `promises`
have been fulfilled, or rejected if any of them become rejected.
*/
-function hash(object, label) {
- return new PromiseHash(Promise, object, label).promise;
+function hash$1(object, label) {
+ return new PromiseHash(Promise$1, object, label).promise;
}
function HashSettled(Constructor, object, label) {
@@ -1984,11 +1985,51 @@ HashSettled.prototype._validationError = function () {
have been settled.
@static
*/
-function hashSettled(object, label) {
- return new HashSettled(Promise, object, label).promise;
+function hashSettled$1(object, label) {
+ return new HashSettled(Promise$1, object, label).promise;
}
-function rethrow(reason) {
+/**
+ `RSVP.rethrow` will rethrow an error on the next turn of the JavaScript event
+ loop in order to aid debugging.
+
+ Promises A+ specifies that any exceptions that occur with a promise must be
+ caught by the promises implementation and bubbled to the last handler. For
+ this reason, it is recommended that you always specify a second rejection
+ handler function to `then`. However, `RSVP.rethrow` will throw the exception
+ outside of the promise, so it bubbles up to your console if in the browser,
+ or domain/cause uncaught exception in Node. `rethrow` will also throw the
+ error again so the error can be handled by the promise per the spec.
+
+ ```javascript
+ function throws(){
+ throw new Error('Whoops!');
+ }
+
+ let promise = new RSVP.Promise(function(resolve, reject){
+ throws();
+ });
+
+ promise.catch(RSVP.rethrow).then(function(){
+ // Code here doesn't run because the promise became rejected due to an
+ // error!
+ }, function (err){
+ // handle the error here
+ });
+ ```
+
+ The 'Whoops' error will be thrown on the next turn of the event loop
+ and you can watch for it in your console. You can also handle it using a
+ rejection handler given to `.then` or `.catch` on the returned promise.
+
+ @method rethrow
+ @static
+ @for RSVP
+ @param {Error} reason reason the promise became rejected.
+ @throws Error
+ @static
+*/
+function rethrow$1(reason) {
setTimeout(function () {
throw reason;
});
@@ -2027,10 +2068,10 @@ function rethrow(reason) {
Useful for tooling.
@return {Object}
*/
-function defer(label) {
+function defer$1(label) {
var deferred = { resolve: undefined, reject: undefined };
- deferred.promise = new Promise(function (resolve, reject) {
+ deferred.promise = new Promise$1(function (resolve, reject) {
deferred.resolve = resolve;
deferred.reject = reject;
}, label);
@@ -2116,8 +2157,8 @@ function defer(label) {
The promise will be rejected if any of the given `promises` become rejected.
@static
*/
-function map(promises, mapFn, label) {
- return Promise.all(promises, label).then(function (values) {
+function map$1(promises, mapFn, label) {
+ return Promise$1.all(promises, label).then(function (values) {
if (!isFunction(mapFn)) {
throw new TypeError("You must pass a function as map's second argument.");
}
@@ -2129,7 +2170,7 @@ function map(promises, mapFn, label) {
results[i] = mapFn(values[i]);
}
- return Promise.all(results, label);
+ return Promise$1.all(results, label);
});
}
@@ -2145,8 +2186,8 @@ function map(promises, mapFn, label) {
@return {Promise} a promise that will become fulfilled with the given
`value`
*/
-function resolve$2(value, label) {
- return Promise.resolve(value, label);
+function resolve$3(value, label) {
+ return Promise$1.resolve(value, label);
}
/**
@@ -2160,8 +2201,8 @@ function resolve$2(value, label) {
Useful for tooling.
@return {Promise} a promise rejected with the given `reason`.
*/
-function reject$2(reason, label) {
- return Promise.reject(reason, label);
+function reject$3(reason, label) {
+ return Promise$1.reject(reason, label);
}
/**
@@ -2251,15 +2292,15 @@ function reject$2(reason, label) {
*/
function resolveAll(promises, label) {
- return Promise.all(promises, label);
+ return Promise$1.all(promises, label);
}
function resolveSingle(promise, label) {
- return Promise.resolve(promise, label).then(function (promises) {
+ return Promise$1.resolve(promise, label).then(function (promises) {
return resolveAll(promises, label);
});
}
-function filter(promises, filterFn, label) {
+function filter$1(promises, filterFn, label) {
var promise = isArray(promises) ? resolveAll(promises, label) : resolveSingle(promises, label);
return promise.then(function (values) {
if (!isFunction(filterFn)) {
@@ -2293,7 +2334,7 @@ function filter(promises, filterFn, label) {
var len = 0;
var vertxNext = undefined;
-function asap(callback, arg) {
+function asap$1(callback, arg) {
queue$1[len] = callback;
queue$1[len + 1] = arg;
len += 2;
@@ -2425,11 +2466,11 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
// the default export here is for backwards compat:
// https://github.com/tildeio/rsvp.js/issues/434
-config.async = asap;
+config.async = asap$1;
config.after = function (cb) {
return setTimeout(cb, 0);
};
-var cast = resolve$2;
+var cast = resolve$3;
var async = function async(callback, arg) {
return config.async(callback, arg);
@@ -2453,55 +2494,59 @@ if (typeof window !== 'undefined' && typeof window['__PROMISE_INSTRUMENTATION__'
}
}
}var rsvp = (_async$filter = {
+ asap: asap$1,
cast: cast,
- Promise: Promise,
+ Promise: Promise$1,
EventTarget: EventTarget,
- all: all$1,
- allSettled: allSettled,
- race: race$1,
- hash: hash,
- hashSettled: hashSettled,
- rethrow: rethrow,
- defer: defer,
- denodeify: denodeify,
+ all: all$3,
+ allSettled: allSettled$1,
+ race: race$3,
+ hash: hash$1,
+ hashSettled: hashSettled$1,
+ rethrow: rethrow$1,
+ defer: defer$1,
+ denodeify: denodeify$1,
configure: configure,
on: on,
off: off,
- resolve: resolve$2,
- reject: reject$2,
- map: map
+ resolve: resolve$3,
+ reject: reject$3,
+ map: map$1
}, _defineProperty(_async$filter, 'async', async), _defineProperty(_async$filter, 'filter', // babel seems to error if async isn't a computed prop here...
-filter), _async$filter);
+filter$1), _async$filter);
exports['default'] = rsvp;
+exports.asap = asap$1;
exports.cast = cast;
-exports.Promise = Promise;
+exports.Promise = Promise$1;
exports.EventTarget = EventTarget;
-exports.all = all$1;
-exports.allSettled = allSettled;
-exports.race = race$1;
-exports.hash = hash;
-exports.hashSettled = hashSettled;
-exports.rethrow = rethrow;
-exports.defer = defer;
-exports.denodeify = denodeify;
+exports.all = all$3;
+exports.allSettled = allSettled$1;
+exports.race = race$3;
+exports.hash = hash$1;
+exports.hashSettled = hashSettled$1;
+exports.rethrow = rethrow$1;
+exports.defer = defer$1;
+exports.denodeify = denodeify$1;
exports.configure = configure;
exports.on = on;
exports.off = off;
-exports.resolve = resolve$2;
-exports.reject = reject$2;
-exports.map = map;
+exports.resolve = resolve$3;
+exports.reject = reject$3;
+exports.map = map$1;
exports.async = async;
-exports.filter = filter;
+exports.filter = filter$1;
Object.defineProperty(exports, '__esModule', { value: true });
})));
+
//
+
'use strict';
var EPUBJS = EPUBJS || {};
-EPUBJS.VERSION = "0.2.15";
+EPUBJS.VERSION = "0.2.19";
EPUBJS.plugins = EPUBJS.plugins || {};
@@ -2586,6 +2631,7 @@ EPUBJS.Book = function(options){
reload : false,
goto : false,
styles : {},
+ classes : [],
headTags : {},
withCredentials: false,
render_method: "Iframe",
@@ -3776,6 +3822,47 @@ EPUBJS.Book.prototype.removeStyle = function(style) {
delete this.settings.styles[style];
};
+EPUBJS.Book.prototype.resetClasses = function(classes) {
+
+ if(!this.isRendered) return this._q.enqueue("setClasses", arguments);
+
+ if(classes.constructor === String) classes = [ classes ];
+
+ this.settings.classes = classes;
+
+ this.renderer.setClasses(this.settings.classes);
+ this.renderer.reformat();
+};
+
+EPUBJS.Book.prototype.addClass = function(aClass) {
+
+ if(!this.isRendered) return this._q.enqueue("addClass", arguments);
+
+ if(this.settings.classes.indexOf(aClass) == -1) {
+ this.settings.classes.push(aClass);
+ }
+
+ this.renderer.setClasses(this.settings.classes);
+ this.renderer.reformat();
+};
+
+EPUBJS.Book.prototype.removeClass = function(aClass) {
+
+ if(!this.isRendered) return this._q.enqueue("removeClass", arguments);
+
+ var idx = this.settings.classes.indexOf(aClass);
+
+ if(idx != -1) {
+
+ delete this.settings.classes[idx];
+
+ this.renderer.setClasses(this.settings.classes);
+ this.renderer.reformat();
+
+ }
+
+};
+
EPUBJS.Book.prototype.addHeadTag = function(tag, attrs) {
if(!this.isRendered) return this._q.enqueue("addHeadTag", arguments);
this.settings.headTags[tag] = attrs;
@@ -3874,6 +3961,12 @@ EPUBJS.Book.prototype.applyStyles = function(renderer, callback){
callback();
};
+EPUBJS.Book.prototype.applyClasses = function(renderer, callback){
+ // if(!this.isRendered) return this._q.enqueue("applyClasses", arguments);
+ renderer.setClasses(this.settings.classes);
+ callback();
+};
+
EPUBJS.Book.prototype.applyHeadTags = function(renderer, callback){
// if(!this.isRendered) return this._q.enqueue("applyHeadTags", arguments);
renderer.applyHeadTags(this.settings.headTags);
@@ -3883,6 +3976,7 @@ EPUBJS.Book.prototype.applyHeadTags = function(renderer, callback){
EPUBJS.Book.prototype._registerReplacements = function(renderer){
renderer.registerHook("beforeChapterDisplay", this.applyStyles.bind(this, renderer), true);
renderer.registerHook("beforeChapterDisplay", this.applyHeadTags.bind(this, renderer), true);
+ renderer.registerHook("beforeChapterDisplay", this.applyClasses.bind(this, renderer), true);
renderer.registerHook("beforeChapterDisplay", EPUBJS.replace.hrefs.bind(this), true);
};
@@ -4089,7 +4183,7 @@ EPUBJS.Chapter.prototype.cfiFromRange = function(_range) {
var range;
var startXpath, endXpath;
var startContainer, endContainer;
- var cleanTextContent, cleanEndTextContent;
+ var cleanTextContent, cleanStartTextContent, cleanEndTextContent;
// Check for Contents
if(!this.document) return;
@@ -4340,6 +4434,11 @@ EPUBJS.Chapter.prototype.replaceWithStored = function(query, attr, func, callbac
var EPUBJS = EPUBJS || {};
EPUBJS.core = {};
+var ELEMENT_NODE = 1;
+var TEXT_NODE = 3;
+var COMMENT_NODE = 8;
+var DOCUMENT_NODE = 9;
+
//-- Get a element for an id
EPUBJS.core.getEl = function(elem) {
return document.getElementById(elem);
@@ -4512,7 +4611,7 @@ EPUBJS.core.uri = function(url){
if(search != -1) {
uri.search = url.slice(search + 1);
url = url.slice(0, search);
- href = url;
+ href = uri.href;
}
if(doubleSlash != -1) {
@@ -4964,13 +5063,37 @@ EPUBJS.core.values = function(object) {
return result;
};
+EPUBJS.core.indexOfNode = function(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;
+}
+
+EPUBJS.core.indexOfTextNode = function(textNode) {
+ return EPUBJS.core.indexOfNode(textNode, TEXT_NODE);
+}
+
+EPUBJS.core.indexOfElementNode = function(elementNode) {
+ return EPUBJS.core.indexOfNode(elementNode, ELEMENT_NODE);
+}
+
EPUBJS.EpubCFI = function(cfiStr){
if(cfiStr) return this.parse(cfiStr);
};
EPUBJS.EpubCFI.prototype.generateChapterComponent = function(_spineNodeIndex, _pos, id) {
var pos = parseInt(_pos),
- spineNodeIndex = _spineNodeIndex + 1,
+ spineNodeIndex = (_spineNodeIndex + 1) * 2,
cfi = '/'+spineNodeIndex+'/';
cfi += (pos + 1) * 2;
@@ -4983,20 +5106,9 @@ EPUBJS.EpubCFI.prototype.generateChapterComponent = function(_spineNodeIndex, _p
};
EPUBJS.EpubCFI.prototype.generatePathComponent = function(steps) {
- var parts = [];
-
- steps.forEach(function(part){
- var segment = '';
- segment += (part.index + 1) * 2;
-
- if(part.id) {
- segment += "[" + part.id + "]";
- }
-
- parts.push(segment);
- });
-
- return parts.join('/');
+ return steps.map(function(part) {
+ return (part.index + 1) * 2 + (part.id ? '[' + part.id + ']' : '');
+ }).join('/');
};
EPUBJS.EpubCFI.prototype.generateCfiFromElement = function(element, chapter) {
@@ -5007,7 +5119,7 @@ EPUBJS.EpubCFI.prototype.generateCfiFromElement = function(element, chapter) {
return "epubcfi(" + chapter + "!/4/)";
} else {
// First Text Node
- return "epubcfi(" + chapter + "!" + path + "/1:0)";
+ return "epubcfi(" + chapter + "!/" + path + "/1:0)";
}
};
@@ -5352,7 +5464,7 @@ EPUBJS.EpubCFI.prototype.generateCfiFromTextNode = function(anchor, offset, base
var steps = this.pathTo(parent);
var path = this.generatePathComponent(steps);
var index = 1 + (2 * Array.prototype.indexOf.call(parent.childNodes, anchor));
- return "epubcfi(" + base + "!" + path + "/"+index+":"+(offset || 0)+")";
+ return "epubcfi(" + base + "!/" + path + "/"+index+":"+(offset || 0)+")";
};
EPUBJS.EpubCFI.prototype.generateCfiFromRangeAnchor = function(range, base) {
@@ -5404,10 +5516,10 @@ EPUBJS.EpubCFI.prototype.generateCfiFromRange = function(range, base) {
endPath = endPath + "/";
}
- return "epubcfi(" + base + "!" + startPath + "/" + startIndex + ":" + startOffset + "," + endPath + endIndex + ":" + endOffset + ")";
+ return "epubcfi(" + base + "!/" + startPath + "/" + startIndex + ":" + startOffset + "," + endPath + endIndex + ":" + endOffset + ")";
} else {
- return "epubcfi(" + base + "!" + startPath + "/"+ startIndex +":"+ startOffset +")";
+ return "epubcfi(" + base + "!/" + startPath + "/"+ startIndex +":"+ startOffset +")";
}
};
@@ -5509,12 +5621,7 @@ EPUBJS.EpubCFI.prototype.generateRangeFromCfi = function(cfi, _doc) {
};
EPUBJS.EpubCFI.prototype.isCfiString = function(target) {
- if(typeof target === "string" &&
- target.indexOf("epubcfi(") === 0) {
- return true;
- }
-
- return false;
+ return typeof target === 'string' && target.indexOf('epubcfi(') === 0;
};
EPUBJS.Events = function(obj, el){
@@ -5711,7 +5818,7 @@ EPUBJS.Layout.isFixedLayout = function (documentElement) {
return false;
}
var content = viewport.getAttribute("content");
- return /,/.test(content);
+ return (/width=(\d+)/.test(content) && /height=(\d+)/.test(content));
};
EPUBJS.Layout.Reflowable = function(){
@@ -6465,24 +6572,23 @@ EPUBJS.Parser.prototype.manifest = function(manifestXml){
};
EPUBJS.Parser.prototype.spine = function(spineXml, manifest){
- var spine = [];
-
var selected = spineXml.getElementsByTagName("itemref"),
items = Array.prototype.slice.call(selected);
- var spineNodeIndex = Array.prototype.indexOf.call(spineXml.parentNode.childNodes, spineXml);
+ // var spineNodeIndex = Array.prototype.indexOf.call(spineXml.parentNode.childNodes, spineXml);
+ var spineNodeIndex = EPUBJS.core.indexOfElementNode(spineXml);
var epubcfi = new EPUBJS.EpubCFI();
//-- Add to array to mantain ordering and cross reference with manifest
- items.forEach(function(item, index){
+ return items.map(function(item, index) {
var Id = item.getAttribute('idref');
var cfiBase = epubcfi.generateChapterComponent(spineNodeIndex, index, Id);
var props = item.getAttribute('properties') || '';
var propArray = props.length ? props.split(' ') : [];
var manifestProps = manifest[Id].properties;
var manifestPropArray = manifestProps.length ? manifestProps.split(' ') : [];
- var vert = {
+ return {
'id' : Id,
'linear' : item.getAttribute('linear') || '',
'properties' : propArray,
@@ -6493,10 +6599,7 @@ EPUBJS.Parser.prototype.spine = function(spineXml, manifest){
'cfiBase' : cfiBase,
'cfi' : "epubcfi(" + cfiBase + ")"
};
- spine.push(vert);
});
-
- return spine;
};
EPUBJS.Parser.prototype.querySelectorByType = function(html, element, type){
@@ -6682,7 +6785,7 @@ EPUBJS.Render.Iframe = function() {
//-- Build up any html needed
EPUBJS.Render.Iframe.prototype.create = function(){
this.element = document.createElement('div');
- this.element.id = "epubjs-view:" + this.id
+ this.element.id = "epubjs-view:" + this.id;
this.isMobile = navigator.userAgent.match(/(iPad|iPhone|iPod|Mobile|Android)/g);
this.transform = EPUBJS.core.prefixed('transform');
@@ -6893,6 +6996,10 @@ EPUBJS.Render.Iframe.prototype.removeStyle = function(style){
};
+EPUBJS.Render.Iframe.prototype.setClasses = function(classes){
+ if(this.bodyEl) this.bodyEl.className = classes.join(" ");
+};
+
EPUBJS.Render.Iframe.prototype.addHeadTag = function(tag, attrs, _doc) {
var doc = _doc || this.document;
var tagEl = doc.createElement(tag);
@@ -7389,10 +7496,10 @@ EPUBJS.Renderer.prototype.remove = function() {
this.removeEventListeners();
this.removeSelectionListeners();
}
-
- // clean container content
- this.container.innerHtml = "";
-// this.container.removeChild(this.element);
+
+ // clean container content
+ //this.container.innerHtml = ""; // not safe
+ this.container.removeChild(this.element);
};
//-- STYLES
@@ -7411,6 +7518,10 @@ EPUBJS.Renderer.prototype.removeStyle = function(style){
this.render.removeStyle(style);
};
+EPUBJS.Renderer.prototype.setClasses = function(classes){
+ this.render.setClasses(classes);
+};
+
//-- HEAD TAGS
EPUBJS.Renderer.prototype.applyHeadTags = function(headTags) {
for ( var headTag in headTags ) {
@@ -8163,7 +8274,7 @@ EPUBJS.Renderer.prototype.resize = function(width, height, setSize){
EPUBJS.Renderer.prototype.onResized = function(e) {
this.trigger('renderer:beforeResize');
-
+
var width = this.container.clientWidth;
var height = this.container.clientHeight;
@@ -8456,7 +8567,6 @@ EPUBJS.replace.cssImports = function (_store, base, text) {
EPUBJS.replace.cssUrls = function(_store, base, text){
var deferred = new RSVP.defer(),
- promises = [],
matches = text.match(/url\(\'?\"?((?!data:)[^\'|^\"^\)]*)\'?\"?\)/g);
if(!_store) return;
@@ -8466,15 +8576,13 @@ EPUBJS.replace.cssUrls = function(_store, base, text){
return deferred.promise;
}
- matches.forEach(function(str){
+ var promises = matches.map(function(str) {
var full = EPUBJS.core.resolveUrl(base, str.replace(/url\(|[|\)|\'|\"]|\?.*$/g, ''));
- var replaced = _store.getUrl(full).then(function(url){
+ return _store.getUrl(full).then(function(url) {
text = text.replace(str, 'url("'+url+'")');
}, function(reason) {
deferred.reject(reason);
});
-
- promises.push(replaced);
});
RSVP.all(promises).then(function(){
@@ -8772,6 +8880,13 @@ EPUBJS.Unarchiver.prototype.getXml = function(url, encoding){
then(function(text){
var parser = new DOMParser();
var mimeType = EPUBJS.core.getMimeType(url);
+
+ // Remove byte order mark before parsing
+ // https://www.w3.org/International/questions/qa-byte-order-mark
+ if(text.charCodeAt(0) === 0xFEFF) {
+ text = text.slice(1);
+ }
+
return parser.parseFromString(text, mimeType);
});