mirror of
https://github.com/futurepress/epub.js.git
synced 2025-10-04 15:09:16 +02:00
672 lines
No EOL
17 KiB
JavaScript
672 lines
No EOL
17 KiB
JavaScript
(function(globals) {
|
|
var define, requireModule;
|
|
|
|
(function() {
|
|
var registry = {}, seen = {};
|
|
|
|
define = function(name, deps, callback) {
|
|
registry[name] = { deps: deps, callback: callback };
|
|
};
|
|
|
|
requireModule = function(name) {
|
|
if (seen[name]) { return seen[name]; }
|
|
seen[name] = {};
|
|
|
|
var mod = registry[name];
|
|
if (!mod) {
|
|
throw new Error("Module '" + name + "' not found.");
|
|
}
|
|
|
|
var deps = mod.deps,
|
|
callback = mod.callback,
|
|
reified = [],
|
|
exports;
|
|
|
|
for (var i=0, l=deps.length; i<l; i++) {
|
|
if (deps[i] === 'exports') {
|
|
reified.push(exports = {});
|
|
} else {
|
|
reified.push(requireModule(deps[i]));
|
|
}
|
|
}
|
|
|
|
var value = callback.apply(this, reified);
|
|
return seen[name] = exports || value;
|
|
};
|
|
})();
|
|
|
|
define("rsvp/all",
|
|
["rsvp/promise","exports"],
|
|
function(__dependency1__, __exports__) {
|
|
"use strict";
|
|
var Promise = __dependency1__.Promise;
|
|
/* global toString */
|
|
|
|
|
|
function all(promises) {
|
|
if (Object.prototype.toString.call(promises) !== "[object Array]") {
|
|
throw new TypeError('You must pass an array to all.');
|
|
}
|
|
|
|
return new Promise(function(resolve, reject) {
|
|
var results = [], remaining = promises.length,
|
|
promise;
|
|
|
|
if (remaining === 0) {
|
|
resolve([]);
|
|
}
|
|
|
|
function resolver(index) {
|
|
return function(value) {
|
|
resolveAll(index, value);
|
|
};
|
|
}
|
|
|
|
function resolveAll(index, value) {
|
|
results[index] = value;
|
|
if (--remaining === 0) {
|
|
resolve(results);
|
|
}
|
|
}
|
|
|
|
for (var i = 0; i < promises.length; i++) {
|
|
promise = promises[i];
|
|
|
|
if (promise && typeof promise.then === 'function') {
|
|
promise.then(resolver(i), reject);
|
|
} else {
|
|
resolveAll(i, promise);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
__exports__.all = all;
|
|
});
|
|
define("rsvp/async",
|
|
["exports"],
|
|
function(__exports__) {
|
|
"use strict";
|
|
var browserGlobal = (typeof window !== 'undefined') ? window : {};
|
|
var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
|
|
var local = (typeof global !== 'undefined') ? global : this;
|
|
|
|
// node
|
|
function useNextTick() {
|
|
return function() {
|
|
process.nextTick(flush);
|
|
};
|
|
}
|
|
|
|
function useMutationObserver() {
|
|
var observer = new BrowserMutationObserver(flush);
|
|
var element = document.createElement('div');
|
|
observer.observe(element, { attributes: true });
|
|
|
|
// Chrome Memory Leak: https://bugs.webkit.org/show_bug.cgi?id=93661
|
|
window.addEventListener('unload', function(){
|
|
observer.disconnect();
|
|
observer = null;
|
|
}, false);
|
|
|
|
return function() {
|
|
element.setAttribute('drainQueue', 'drainQueue');
|
|
};
|
|
}
|
|
|
|
function useSetTimeout() {
|
|
return function() {
|
|
local.setTimeout(flush, 1);
|
|
};
|
|
}
|
|
|
|
var queue = [];
|
|
function flush() {
|
|
for (var i = 0; i < queue.length; i++) {
|
|
var tuple = queue[i];
|
|
var callback = tuple[0], arg = tuple[1];
|
|
callback(arg);
|
|
}
|
|
queue = [];
|
|
}
|
|
|
|
var scheduleFlush;
|
|
|
|
// Decide what async method to use to triggering processing of queued callbacks:
|
|
if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
|
|
scheduleFlush = useNextTick();
|
|
} else if (BrowserMutationObserver) {
|
|
scheduleFlush = useMutationObserver();
|
|
} else {
|
|
scheduleFlush = useSetTimeout();
|
|
}
|
|
|
|
function async(callback, arg) {
|
|
var length = queue.push([callback, arg]);
|
|
if (length === 1) {
|
|
// If length is 1, that means that we need to schedule an async flush.
|
|
// If additional callbacks are queued before the queue is flushed, they
|
|
// will be processed by this flush that we are scheduling.
|
|
scheduleFlush();
|
|
}
|
|
}
|
|
|
|
|
|
__exports__.async = async;
|
|
});
|
|
define("rsvp/config",
|
|
["rsvp/async","exports"],
|
|
function(__dependency1__, __exports__) {
|
|
"use strict";
|
|
var async = __dependency1__.async;
|
|
|
|
var config = {};
|
|
config.async = async;
|
|
|
|
|
|
__exports__.config = config;
|
|
});
|
|
define("rsvp/defer",
|
|
["rsvp/promise","exports"],
|
|
function(__dependency1__, __exports__) {
|
|
"use strict";
|
|
var Promise = __dependency1__.Promise;
|
|
|
|
function defer() {
|
|
var deferred = {
|
|
// pre-allocate shape
|
|
resolve: undefined,
|
|
reject: undefined,
|
|
promise: undefined
|
|
};
|
|
|
|
deferred.promise = new Promise(function(resolve, reject) {
|
|
deferred.resolve = resolve;
|
|
deferred.reject = reject;
|
|
});
|
|
|
|
return deferred;
|
|
}
|
|
|
|
|
|
__exports__.defer = defer;
|
|
});
|
|
define("rsvp/events",
|
|
["exports"],
|
|
function(__exports__) {
|
|
"use strict";
|
|
var Event = function(type, options) {
|
|
this.type = type;
|
|
|
|
for (var option in options) {
|
|
if (!options.hasOwnProperty(option)) { continue; }
|
|
|
|
this[option] = options[option];
|
|
}
|
|
};
|
|
|
|
var indexOf = function(callbacks, callback) {
|
|
for (var i=0, l=callbacks.length; i<l; i++) {
|
|
if (callbacks[i][0] === callback) { return i; }
|
|
}
|
|
|
|
return -1;
|
|
};
|
|
|
|
var callbacksFor = function(object) {
|
|
var callbacks = object._promiseCallbacks;
|
|
|
|
if (!callbacks) {
|
|
callbacks = object._promiseCallbacks = {};
|
|
}
|
|
|
|
return callbacks;
|
|
};
|
|
|
|
var EventTarget = {
|
|
mixin: function(object) {
|
|
object.on = this.on;
|
|
object.off = this.off;
|
|
object.trigger = this.trigger;
|
|
return object;
|
|
},
|
|
|
|
on: function(eventNames, callback, binding) {
|
|
var allCallbacks = callbacksFor(this), callbacks, eventName;
|
|
eventNames = eventNames.split(/\s+/);
|
|
binding = binding || this;
|
|
|
|
while (eventName = eventNames.shift()) {
|
|
callbacks = allCallbacks[eventName];
|
|
|
|
if (!callbacks) {
|
|
callbacks = allCallbacks[eventName] = [];
|
|
}
|
|
|
|
if (indexOf(callbacks, callback) === -1) {
|
|
callbacks.push([callback, binding]);
|
|
}
|
|
}
|
|
},
|
|
|
|
off: function(eventNames, callback) {
|
|
var allCallbacks = callbacksFor(this), callbacks, eventName, index;
|
|
eventNames = eventNames.split(/\s+/);
|
|
|
|
while (eventName = eventNames.shift()) {
|
|
if (!callback) {
|
|
allCallbacks[eventName] = [];
|
|
continue;
|
|
}
|
|
|
|
callbacks = allCallbacks[eventName];
|
|
|
|
index = indexOf(callbacks, callback);
|
|
|
|
if (index !== -1) { callbacks.splice(index, 1); }
|
|
}
|
|
},
|
|
|
|
trigger: function(eventName, options) {
|
|
var allCallbacks = callbacksFor(this),
|
|
callbacks, callbackTuple, callback, binding, event;
|
|
|
|
if (callbacks = allCallbacks[eventName]) {
|
|
// Don't cache the callbacks.length since it may grow
|
|
for (var i=0; i<callbacks.length; i++) {
|
|
callbackTuple = callbacks[i];
|
|
callback = callbackTuple[0];
|
|
binding = callbackTuple[1];
|
|
|
|
if (typeof options !== 'object') {
|
|
options = { detail: options };
|
|
}
|
|
|
|
event = new Event(eventName, options);
|
|
callback.call(binding, event);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
__exports__.EventTarget = EventTarget;
|
|
});
|
|
define("rsvp/hash",
|
|
["rsvp/defer","exports"],
|
|
function(__dependency1__, __exports__) {
|
|
"use strict";
|
|
var defer = __dependency1__.defer;
|
|
|
|
function size(object) {
|
|
var s = 0;
|
|
|
|
for (var prop in object) {
|
|
s++;
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
function hash(promises) {
|
|
var results = {}, deferred = defer(), remaining = size(promises);
|
|
|
|
if (remaining === 0) {
|
|
deferred.resolve({});
|
|
}
|
|
|
|
var resolver = function(prop) {
|
|
return function(value) {
|
|
resolveAll(prop, value);
|
|
};
|
|
};
|
|
|
|
var resolveAll = function(prop, value) {
|
|
results[prop] = value;
|
|
if (--remaining === 0) {
|
|
deferred.resolve(results);
|
|
}
|
|
};
|
|
|
|
var rejectAll = function(error) {
|
|
deferred.reject(error);
|
|
};
|
|
|
|
for (var prop in promises) {
|
|
if (promises[prop] && typeof promises[prop].then === 'function') {
|
|
promises[prop].then(resolver(prop), rejectAll);
|
|
} else {
|
|
resolveAll(prop, promises[prop]);
|
|
}
|
|
}
|
|
|
|
return deferred.promise;
|
|
}
|
|
|
|
|
|
__exports__.hash = hash;
|
|
});
|
|
define("rsvp/node",
|
|
["rsvp/promise","rsvp/all","exports"],
|
|
function(__dependency1__, __dependency2__, __exports__) {
|
|
"use strict";
|
|
var Promise = __dependency1__.Promise;
|
|
var all = __dependency2__.all;
|
|
|
|
function makeNodeCallbackFor(resolve, reject) {
|
|
return function (error, value) {
|
|
if (error) {
|
|
reject(error);
|
|
} else if (arguments.length > 2) {
|
|
resolve(Array.prototype.slice.call(arguments, 1));
|
|
} else {
|
|
resolve(value);
|
|
}
|
|
};
|
|
}
|
|
|
|
function denodeify(nodeFunc) {
|
|
return function() {
|
|
var nodeArgs = Array.prototype.slice.call(arguments), resolve, reject;
|
|
var thisArg = this;
|
|
|
|
var promise = new Promise(function(nodeResolve, nodeReject) {
|
|
resolve = nodeResolve;
|
|
reject = nodeReject;
|
|
});
|
|
|
|
all(nodeArgs).then(function(nodeArgs) {
|
|
nodeArgs.push(makeNodeCallbackFor(resolve, reject));
|
|
|
|
try {
|
|
nodeFunc.apply(thisArg, nodeArgs);
|
|
} catch(e) {
|
|
reject(e);
|
|
}
|
|
});
|
|
|
|
return promise;
|
|
};
|
|
}
|
|
|
|
|
|
__exports__.denodeify = denodeify;
|
|
});
|
|
define("rsvp/promise",
|
|
["rsvp/config","rsvp/events","exports"],
|
|
function(__dependency1__, __dependency2__, __exports__) {
|
|
"use strict";
|
|
var config = __dependency1__.config;
|
|
var EventTarget = __dependency2__.EventTarget;
|
|
|
|
function objectOrFunction(x) {
|
|
return isFunction(x) || (typeof x === "object" && x !== null);
|
|
}
|
|
|
|
function isFunction(x){
|
|
return typeof x === "function";
|
|
}
|
|
|
|
var Promise = function(resolver) {
|
|
var promise = this,
|
|
resolved = false;
|
|
|
|
if (typeof resolver !== 'function') {
|
|
throw new TypeError('You must pass a resolver function as the sole argument to the promise constructor');
|
|
}
|
|
|
|
if (!(promise instanceof Promise)) {
|
|
return new Promise(resolver);
|
|
}
|
|
|
|
var resolvePromise = function(value) {
|
|
if (resolved) { return; }
|
|
resolved = true;
|
|
resolve(promise, value);
|
|
};
|
|
|
|
var rejectPromise = function(value) {
|
|
if (resolved) { return; }
|
|
resolved = true;
|
|
reject(promise, value);
|
|
};
|
|
|
|
this.on('promise:failed', function(event) {
|
|
this.trigger('error', { detail: event.detail });
|
|
}, this);
|
|
|
|
this.on('error', onerror);
|
|
|
|
try {
|
|
resolver(resolvePromise, rejectPromise);
|
|
} catch(e) {
|
|
rejectPromise(e);
|
|
}
|
|
};
|
|
|
|
function onerror(event) {
|
|
if (config.onerror) {
|
|
config.onerror(event.detail);
|
|
}
|
|
}
|
|
|
|
var invokeCallback = function(type, promise, callback, event) {
|
|
var hasCallback = isFunction(callback),
|
|
value, error, succeeded, failed;
|
|
|
|
if (hasCallback) {
|
|
try {
|
|
value = callback(event.detail);
|
|
succeeded = true;
|
|
} catch(e) {
|
|
failed = true;
|
|
error = e;
|
|
}
|
|
} else {
|
|
value = event.detail;
|
|
succeeded = true;
|
|
}
|
|
|
|
if (handleThenable(promise, value)) {
|
|
return;
|
|
} else if (hasCallback && succeeded) {
|
|
resolve(promise, value);
|
|
} else if (failed) {
|
|
reject(promise, error);
|
|
} else if (type === 'resolve') {
|
|
resolve(promise, value);
|
|
} else if (type === 'reject') {
|
|
reject(promise, value);
|
|
}
|
|
};
|
|
|
|
Promise.prototype = {
|
|
constructor: Promise,
|
|
|
|
isRejected: undefined,
|
|
isFulfilled: undefined,
|
|
rejectedReason: undefined,
|
|
fulfillmentValue: undefined,
|
|
|
|
then: function(done, fail) {
|
|
this.off('error', onerror);
|
|
|
|
var thenPromise = new this.constructor(function() {});
|
|
|
|
if (this.isFulfilled) {
|
|
config.async(function(promise) {
|
|
invokeCallback('resolve', thenPromise, done, { detail: promise.fulfillmentValue });
|
|
}, this);
|
|
}
|
|
|
|
if (this.isRejected) {
|
|
config.async(function(promise) {
|
|
invokeCallback('reject', thenPromise, fail, { detail: promise.rejectedReason });
|
|
}, this);
|
|
}
|
|
|
|
this.on('promise:resolved', function(event) {
|
|
invokeCallback('resolve', thenPromise, done, event);
|
|
});
|
|
|
|
this.on('promise:failed', function(event) {
|
|
invokeCallback('reject', thenPromise, fail, event);
|
|
});
|
|
|
|
return thenPromise;
|
|
},
|
|
|
|
fail: function(fail) {
|
|
return this.then(null, fail);
|
|
}
|
|
};
|
|
|
|
EventTarget.mixin(Promise.prototype);
|
|
|
|
function resolve(promise, value) {
|
|
if (promise === value) {
|
|
fulfill(promise, value);
|
|
} else if (!handleThenable(promise, value)) {
|
|
fulfill(promise, value);
|
|
}
|
|
}
|
|
|
|
function handleThenable(promise, value) {
|
|
var then = null,
|
|
resolved;
|
|
|
|
try {
|
|
if (promise === value) {
|
|
throw new TypeError("A promises callback cannot return that same promise.");
|
|
}
|
|
|
|
if (objectOrFunction(value)) {
|
|
then = value.then;
|
|
|
|
if (isFunction(then)) {
|
|
then.call(value, function(val) {
|
|
if (resolved) { return true; }
|
|
resolved = true;
|
|
|
|
if (value !== val) {
|
|
resolve(promise, val);
|
|
} else {
|
|
fulfill(promise, val);
|
|
}
|
|
}, function(val) {
|
|
if (resolved) { return true; }
|
|
resolved = true;
|
|
|
|
reject(promise, val);
|
|
});
|
|
|
|
return true;
|
|
}
|
|
}
|
|
} catch (error) {
|
|
reject(promise, error);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function fulfill(promise, value) {
|
|
config.async(function() {
|
|
promise.trigger('promise:resolved', { detail: value });
|
|
promise.isFulfilled = true;
|
|
promise.fulfillmentValue = value;
|
|
});
|
|
}
|
|
|
|
function reject(promise, value) {
|
|
config.async(function() {
|
|
promise.trigger('promise:failed', { detail: value });
|
|
promise.isRejected = true;
|
|
promise.rejectedReason = value;
|
|
});
|
|
}
|
|
|
|
|
|
__exports__.Promise = Promise;
|
|
});
|
|
define("rsvp/reject",
|
|
["rsvp/promise","exports"],
|
|
function(__dependency1__, __exports__) {
|
|
"use strict";
|
|
var Promise = __dependency1__.Promise;
|
|
|
|
function reject(reason) {
|
|
return new Promise(function (resolve, reject) {
|
|
reject(reason);
|
|
});
|
|
}
|
|
|
|
|
|
__exports__.reject = reject;
|
|
});
|
|
define("rsvp/resolve",
|
|
["rsvp/promise","exports"],
|
|
function(__dependency1__, __exports__) {
|
|
"use strict";
|
|
var Promise = __dependency1__.Promise;
|
|
|
|
function resolve(thenable) {
|
|
return new Promise(function(resolve, reject) {
|
|
resolve(thenable);
|
|
});
|
|
}
|
|
|
|
|
|
__exports__.resolve = resolve;
|
|
});
|
|
define("rsvp/rethrow",
|
|
["exports"],
|
|
function(__exports__) {
|
|
"use strict";
|
|
var local = (typeof global === "undefined") ? this : global;
|
|
|
|
function rethrow(reason) {
|
|
local.setTimeout(function() {
|
|
throw reason;
|
|
});
|
|
throw reason;
|
|
}
|
|
|
|
|
|
__exports__.rethrow = rethrow;
|
|
});
|
|
define("rsvp",
|
|
["rsvp/events","rsvp/promise","rsvp/node","rsvp/all","rsvp/hash","rsvp/rethrow","rsvp/defer","rsvp/config","rsvp/resolve","rsvp/reject","exports"],
|
|
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __exports__) {
|
|
"use strict";
|
|
var EventTarget = __dependency1__.EventTarget;
|
|
var Promise = __dependency2__.Promise;
|
|
var denodeify = __dependency3__.denodeify;
|
|
var all = __dependency4__.all;
|
|
var hash = __dependency5__.hash;
|
|
var rethrow = __dependency6__.rethrow;
|
|
var defer = __dependency7__.defer;
|
|
var config = __dependency8__.config;
|
|
var resolve = __dependency9__.resolve;
|
|
var reject = __dependency10__.reject;
|
|
|
|
function configure(name, value) {
|
|
config[name] = value;
|
|
}
|
|
|
|
|
|
__exports__.Promise = Promise;
|
|
__exports__.EventTarget = EventTarget;
|
|
__exports__.all = all;
|
|
__exports__.hash = hash;
|
|
__exports__.rethrow = rethrow;
|
|
__exports__.defer = defer;
|
|
__exports__.denodeify = denodeify;
|
|
__exports__.configure = configure;
|
|
__exports__.resolve = resolve;
|
|
__exports__.reject = reject;
|
|
});
|
|
window.RSVP = requireModule("rsvp");
|
|
})(window); |