1
0
Fork 0
mirror of https://github.com/futurepress/epub.js.git synced 2025-10-04 15:09:16 +02:00

Changed FP to EPUBJS for the entire project.

This commit is contained in:
RawKStar77 2013-06-04 18:23:11 -07:00
parent bc49465787
commit 9a94f151f9
33 changed files with 24764 additions and 0 deletions

11
epubjs/hooks/embedh.js Normal file
View file

@ -0,0 +1,11 @@
EPUBJS.Hooks.register("beforeChapterDisplay").example = function(callback, chapter){
var s = document.createElement("script");
s.type = 'text/javascript';
s.src ="https://test.hypothes.is/app/embed.js"
chapter.doc.body.appendChild(s);
//-- Continue to other hooks
if(callback) callback();}

154
epubjs/hooks/endnotes.js Normal file
View file

@ -0,0 +1,154 @@
EPUBJS.Hooks.register("beforeChapterDisplay").endnotes = function(callback, chapter){
var notes = chapter.doc.querySelectorAll('a[href]'),
items = Array.prototype.slice.call(notes), //[].slice.call()
attr = "epub:type",
type = "noteref",
popups = {};
EPUBJS.core.addCss("css/popup.css", false, chapter.doc.head);
//console.log("notes", items)
items.forEach(function(item){
var epubType = item.getAttribute(attr),
href,
id,
el,
pop,
pos,
left,
top,
txt;
if(epubType != type) return;
href = item.getAttribute("href");
id = href.replace("#", '');
el = chapter.doc.getElementById(id);
item.addEventListener("mouseover", showPop, false);
item.addEventListener("mouseout", hidePop, false);
function showPop(){
var poppos,
iheight = chapter.iframe.height,
iwidth = chapter.iframe.width,
tip,
pop,
maxHeight = 225;
if(!txt) {
pop = el.cloneNode(true);
txt = pop.querySelector("p");
}
//-- create a popup with endnote inside of it
if(!popups[id]) {
popups[id] = document.createElement("div");
popups[id].setAttribute("class", "popup");
pop_content = document.createElement("div");
popups[id].appendChild(pop_content);
pop_content.appendChild(txt);
pop_content.setAttribute("class", "pop_content");
chapter.bodyEl.appendChild(popups[id]);
//-- TODO: will these leak memory? - Fred
popups[id].addEventListener("mouseover", onPop, false);
popups[id].addEventListener("mouseout", offPop, false);
//-- Add hide on page change
chapter.book.listenUntil("book:pageChanged", "book:chapterDestroy", hidePop);
chapter.book.listenUntil("book:pageChanged", "book:chapterDestroy", offPop);
}
pop = popups[id];
//-- get location of item
itemRect = item.getBoundingClientRect();
left = itemRect.left;
top = itemRect.top;
//-- show the popup
pop.classList.add("show");
//-- locations of popup
popRect = pop.getBoundingClientRect();
//-- position the popup
pop.style.left = left - popRect.width / 2 + "px";
pop.style.top = top + "px";
//-- Adjust max height
if(maxHeight > iheight / 2.5) {
maxHeight = iheight / 2.5;
pop_content.style.maxHeight = maxHeight + "px";
}
//-- switch above / below
if(popRect.height + top >= iheight - 25) {
pop.style.top = top - popRect.height + "px";
pop.classList.add("above");
}else{
pop.classList.remove("above");
}
//-- switch left
if(left - popRect.width <= 0) {
pop.style.left = left + "px";
pop.classList.add("left");
}else{
pop.classList.remove("left");
}
//-- switch right
if(left + popRect.width / 2 >= iwidth) {
//-- TEMP MOVE: 300
pop.style.left = left - 300 + "px";
popRect = pop.getBoundingClientRect();
pop.style.left = left - popRect.width + "px";
//-- switch above / below again
if(popRect.height + top >= iheight - 25) {
pop.style.top = top - popRect.height + "px";
pop.classList.add("above");
}else{
pop.classList.remove("above");
}
pop.classList.add("right");
}else{
pop.classList.remove("right");
}
}
function onPop(){
popups[id].classList.add("on");
}
function offPop(){
popups[id].classList.remove("on");
}
function hidePop(){
setTimeout(function(){
popups[id].classList.remove("show");
}, 100);
}
});
if(callback) callback();
}

View file

@ -0,0 +1,78 @@
EPUBJS.Hooks.register("beforeChapterDisplay").annotate = function(callback, chapter){
var chap = chapter.bodyEl,
server = 'http://127.0.0.1:5000/';
files = [
EPUBJS.filePath + "libs/jquery-1.9.0.js",
EPUBJS.filePath + "libs/jquery-migrate-1.1.1.js",
EPUBJS.filePath + "libs/annotator-full.js"
];
//EPUBJS.core.loadScripts(files, annotate, chapter.doc.head);
$(chapter.doc.body).annotator().annotator('setupPlugins', {}, {
Filter:false,
Store: {
annotationData: {
'uri': chapter.path
},
loadFromSearch: {
'limit': 100,
'uri': chapter.path
}
}
});
EPUBJS.core.addCss("css/annotator.css", false, chapter.doc.head);
if(callback) callback();
function annotate(){
EPUBJS.core.addCss("css/annotator.css", false, chapter.doc.head);
var s = document.createElement("script");
s.type = 'text/javascript';
var a = "jQuery.migrateTrace = false;";
//a += "console.log(document.getElementById('c001p0002').getBoundingClientRect());";
a += "var content = $('body').annotator().annotator('setupPlugins', {}, {Filter:false});";
//-- Use Local Server:
// a += "var content = $('body').annotator(),";
// a += " server = '" + server + "';";
// a += " path = '" + chapter.path + "';";
//
// a += " content.annotator('addPlugin', 'Store', {";
// // The endpoint of the store on your server.
// a += " prefix: server,";
//
// // Attach the uri of the current page to all annotations to allow search.
// a += " annotationData: {";
// a += " 'uri': path";
// a += " }";
// This will perform a search action rather than read when the plugin
// loads. Will request the last 20 annotations for the current url.
// eg. /store/endpoint/search?limit=20&uri=http://this/document/only
// a += ","
// a += " loadFromSearch: {";
// a += " 'limit': 20,";
// a += " 'uri': path";
// a += " }";
//a += "});";
s.innerHTML = a;
chapter.doc.body.appendChild(s);
if(callback) callback();
}
}

View file

@ -0,0 +1,43 @@
EPUBJS.Hooks.register("beforeChapterDisplay").example = function(callback, chapter){
EPUBJS.core.addCss("css/annotator.css", false, chapter.doc.head);
EPUBJS.core.addScript(EPUBJS.filePath + "libs/annotator-full.js", function() {
//-- Config script
var s = document.createElement("script");
s.type = 'text/javascript';
a = '/* -*- js -*- */
/*{literal}<![CDATA[*/
/*yepnope1.5.x|WTEPUBJSL*/
(function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f<d;f++)g=a[f].split("="),(e=z[g.shift()])&&(c=e(c,g));for(f=0;f<b;f++)c=x[f](c);return c}function g(a,e,f,g,h){var i=b(a),j=i.autoCallback;i.url.split(".").pop().split("?").shift(),i.bypass||(e&&(e=d(e)?e:e[a]||e[g]||e[a.split("/").pop().split("?")[0]]),i.instead?i.instead(a,e,f,g,h):(y[i.url]?i.noexec=!0:y[i.url]=1,f.load(i.url,i.forceCSS||!i.forceJS&&"css"==i.url.split(".").pop().split("?").shift()?"c":c,i.noexec,i.attrs,i.timeout),(d(e)||d(j))&&f.load(function(){k(),e&&e(i.origUrl,h,g),j&&j(i.origUrl,h,g),y[i.url]=2})))}function h(a,b){function c(a,c){if(a){if(e(a))c||(j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}),g(a,j,b,0,h);else if(Object(a)===a)for(n in m=function(){var b=0,c;for(c in a)a.hasOwnProperty(c)&&b++;return b}(),a)a.hasOwnProperty(n)&&(!c&&!--m&&(d(j)?j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}:j[n]=function(a){return function(){var b=[].slice.call(arguments);a&&a.apply(this,b),l()}}(k[n])),g(a[n],j,b,n,h))}else!c&&l()}var h=!!a.test,i=a.load||a.both,j=a.callback||f,k=j,l=a.complete||f,m,n;c(h?a.yep:a.nope,!!i),i&&c(i)}var i,j,l=this.yepnope.loader;if(e(a))g(a,0,l,0);else if(w(a))for(i=0;i<a.length;i++)j=a[i],e(j)?g(j,0,l,0):w(j)?B(j):Object(j)===j&&h(j,l);else Object(a)===a&&h(a,l)},B.addPrefix=function(a,b){z[a]=b},B.addFilter=function(a){x.push(a)},B.errorTimeout=1e4,null==b.readyState&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",A=function(){b.removeEventListener("DOMContentLoaded",A,0),b.readyState="complete"},0)),a.yepnope=k(),a.yepnope.executeStack=h,a.yepnope.injectJs=function(a,c,d,e,i,j){var k=b.createElement("script"),l,o,e=e||B.errorTimeout;k.src=a;for(o in d)k.setAttribute(o,d[o]);c=j?h:c||f,k.onreadystatechange=k.onload=function(){!l&&g(k.readyState)&&(l=1,c(),k.onload=k.onreadystatechange=null)},m(function(){l||(l=1,c(1))},e),i?k.onload():n.parentNode.insertBefore(k,n)},a.yepnope.injectCss=function(a,c,d,e,g,i){var e=b.createElement("link"),j,c=i?h:c||f;e.href=a,e.rel="stylesheet",e.type="text/css";for(j in d)e.setAttribute(j,d[j]);g||(n.parentNode.insertBefore(e,n),m(c,0))}})(this,document);
yepnope([
{
test: window.annotator,
nope: Array.prototype.concat.call(["https://test.hypothes.is/assets/lib/jquery-1.8.3.min.js?f38b3719", "https://test.hypothes.is/assets/lib/jschannel.min.js?a3050e46", "https://test.hypothes.is/assets/lib/annotator.min.js?c383f214", "https://test.hypothes.is/assets/js/plugin/bridge.js?0be67f72", "https://test.hypothes.is/assets/lib/dom_text.min.js?83381202", "https://test.hypothes.is/assets/js/host.min.js?b382f10e", "https://test.hypothes.is/assets/css/inject.css?ff831c08"]),
complete: function () {
window.annotator = new Annotator.Host(document.body, {
/* @@ reflect routes with crossroads.js?? */
app: "https://test.hypothes.is/app/",
});
window.Annotator.noConflict().$.noConflict(true);
}
},
{
test: window.requestAnimationFrame,
nope: ["https://test.hypothes.is/assets/lib/polyfills/raf.js.min?6d9ee12a"],
}
]);'
s.innerHTML = a;
chapter.doc.body.appendChild(s);
//-- Continue to other hooks
if(callback) callback();
}, chapter.doc.head);
}

View file

@ -0,0 +1,68 @@
EPUBJS.Hooks.register("beforeChapterDisplay").music = function(callback, chapter){
var trans = chapter.doc.querySelectorAll('audio'),
items = Array.prototype.slice.call(trans),
playing = false;
items.forEach(function(item){
var onSpread = 0;
function getPage() {
left = item.getBoundingClientRect().left;
onSpread = Math.floor(left / chapter.spreadWidth) + 1; //-- pages start at 1
//console.log("left", left, onPage)
// width = orginal_width;
// height = orginal_height;
//
// if(width > chapter.colWidth){
// ratio = chapter.colWidth / width;
//
// width = chapter.colWidth;
// height = height * ratio;
// }
//
// iframe.width = width;
// iframe.height = height;
}
function shouldPlay(e) {
page = 1;
if(e) page = e.msg;
if(page != onSpread) return;
if(playing) playing.pause();
item.play();
playing = item;
console.log("start", item.src)
}
//-- resize event
chapter.book.listenUntil("book:resized", "book:chapterDestroy", getPage);
chapter.book.listenUntil("book:pageChanged", "book:chapterDestroy", shouldPlay);
item.removeAttribute("controls");
getPage();
shouldPlay();
});
if(callback) callback();
}

View file

@ -0,0 +1,45 @@
EPUBJS.Hooks.register("beforeChapterDisplay").smartimages = function(callback, chapter){
var image = chapter.doc.querySelectorAll('img'),
items = Array.prototype.slice.call(image),
iheight = chapter.iframe.height,
oheight;
items.forEach(function(item){
function size() {
var itemRect = item.getBoundingClientRect(),
height = itemRect.height,
top = itemRect.top;
iheight = chapter.iframe.height;
if(height + top >= iheight) {
if(top < iheight/2) {
item.style.maxHeight = iheight - top + "px";
item.style.width= "auto";
}else{
item.style.maxHeight = (height < iheight ? height : iheight) + "px";
item.style.marginTop = iheight - top + "px";
item.style.width= "auto";
}
}else{
item.style.removeProperty('max-height');
item.style.removeProperty('margin-top');
}
}
chapter.book.listenUntil("book:resized", "book:chapterDestroy", size);
size();
});
if(callback) callback();
}

View file

@ -0,0 +1,59 @@
EPUBJS.Hooks.register("beforeChapterDisplay").transculsions = function(callback, chapter){
/*
<aside ref="http://www.youtube.com/embed/DUL6MBVKVLI?html5=1" transclusion="video" width="560" height="315">
<a href="http://www.youtube.com/embed/DUL6MBVKVLI"> Watch the National Geographic: The Last Roll of Kodachrome</a>
</aside>
*/
var trans = chapter.doc.querySelectorAll('[transclusion]'),
items = Array.prototype.slice.call(trans);
items.forEach(function(item){
var src = item.getAttribute("ref"),
iframe = document.createElement('iframe'),
orginal_width = item.getAttribute("width"),
orginal_height = item.getAttribute("height"),
parent = item.parentNode,
width = orginal_width,
height = orginal_height,
ratio;
function size() {
width = orginal_width;
height = orginal_height;
if(width > chapter.colWidth){
ratio = chapter.colWidth / width;
width = chapter.colWidth;
height = height * ratio;
}
iframe.width = width;
iframe.height = height;
}
size();
//-- resize event
chapter.book.listenUntil("book:resized", "book:chapterDestroy", size);
iframe.src = src;
//<iframe width="560" height="315" src="http://www.youtube.com/embed/DUL6MBVKVLI" frameborder="0" allowfullscreen="true"></iframe>
parent.replaceChild(iframe, item);
});
if(callback) callback();
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

11
epubjs/libs/annotator-full.min.js vendored Normal file

File diff suppressed because one or more lines are too long

2127
epubjs/libs/deflate.js Normal file

File diff suppressed because it is too large Load diff

2
epubjs/libs/fileStorage.min.js vendored Normal file

File diff suppressed because one or more lines are too long

2169
epubjs/libs/inflate.js Normal file

File diff suppressed because it is too large Load diff

2
epubjs/libs/jquery-1.8.2.min.js vendored Executable file

File diff suppressed because one or more lines are too long

9555
epubjs/libs/jquery-1.9.0.js vendored Normal file

File diff suppressed because it is too large Load diff

4
epubjs/libs/jquery-1.9.0.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,511 @@
/*!
* jQuery Migrate - v1.1.1 - 2013-02-16
* https://github.com/jquery/jquery-migrate
* Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors; Licensed MIT
*/
(function( jQuery, window, undefined ) {
// See http://bugs.jquery.com/ticket/13335
// "use strict";
var warnedAbout = {};
// List of warnings already given; public read only
jQuery.migrateWarnings = [];
// Set to true to prevent console output; migrateWarnings still maintained
// jQuery.migrateMute = false;
// Show a message on the console so devs know we're active
if ( !jQuery.migrateMute && window.console && console.log ) {
console.log("JQMIGRATE: Logging is active");
}
// Set to false to disable traces that appear with warnings
if ( jQuery.migrateTrace === undefined ) {
jQuery.migrateTrace = true;
}
// Forget any warnings we've already given; public
jQuery.migrateReset = function() {
warnedAbout = {};
jQuery.migrateWarnings.length = 0;
};
function migrateWarn( msg) {
if ( !warnedAbout[ msg ] ) {
warnedAbout[ msg ] = true;
jQuery.migrateWarnings.push( msg );
if ( window.console && console.warn && !jQuery.migrateMute ) {
console.warn( "JQMIGRATE: " + msg );
if ( jQuery.migrateTrace && console.trace ) {
console.trace();
}
}
}
}
function migrateWarnProp( obj, prop, value, msg ) {
if ( Object.defineProperty ) {
// On ES5 browsers (non-oldIE), warn if the code tries to get prop;
// allow property to be overwritten in case some other plugin wants it
try {
Object.defineProperty( obj, prop, {
configurable: true,
enumerable: true,
get: function() {
migrateWarn( msg );
return value;
},
set: function( newValue ) {
migrateWarn( msg );
value = newValue;
}
});
return;
} catch( err ) {
// IE8 is a dope about Object.defineProperty, can't warn there
}
}
// Non-ES5 (or broken) browser; just set the property
jQuery._definePropertyBroken = true;
obj[ prop ] = value;
}
if ( document.compatMode === "BackCompat" ) {
// jQuery has never supported or tested Quirks Mode
migrateWarn( "jQuery is not compatible with Quirks Mode" );
}
var attrFn = jQuery( "<input/>", { size: 1 } ).attr("size") && jQuery.attrFn,
oldAttr = jQuery.attr,
valueAttrGet = jQuery.attrHooks.value && jQuery.attrHooks.value.get ||
function() { return null; },
valueAttrSet = jQuery.attrHooks.value && jQuery.attrHooks.value.set ||
function() { return undefined; },
rnoType = /^(?:input|button)$/i,
rnoAttrNodeType = /^[238]$/,
rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
ruseDefault = /^(?:checked|selected)$/i;
// jQuery.attrFn
migrateWarnProp( jQuery, "attrFn", attrFn || {}, "jQuery.attrFn is deprecated" );
jQuery.attr = function( elem, name, value, pass ) {
var lowerName = name.toLowerCase(),
nType = elem && elem.nodeType;
if ( pass ) {
// Since pass is used internally, we only warn for new jQuery
// versions where there isn't a pass arg in the formal params
if ( oldAttr.length < 4 ) {
migrateWarn("jQuery.fn.attr( props, pass ) is deprecated");
}
if ( elem && !rnoAttrNodeType.test( nType ) &&
(attrFn ? name in attrFn : jQuery.isFunction(jQuery.fn[name])) ) {
return jQuery( elem )[ name ]( value );
}
}
// Warn if user tries to set `type`, since it breaks on IE 6/7/8; by checking
// for disconnected elements we don't warn on $( "<button>", { type: "button" } ).
if ( name === "type" && value !== undefined && rnoType.test( elem.nodeName ) && elem.parentNode ) {
migrateWarn("Can't change the 'type' of an input or button in IE 6/7/8");
}
// Restore boolHook for boolean property/attribute synchronization
if ( !jQuery.attrHooks[ lowerName ] && rboolean.test( lowerName ) ) {
jQuery.attrHooks[ lowerName ] = {
get: function( elem, name ) {
// Align boolean attributes with corresponding properties
// Fall back to attribute presence where some booleans are not supported
var attrNode,
property = jQuery.prop( elem, name );
return property === true || typeof property !== "boolean" &&
( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
name.toLowerCase() :
undefined;
},
set: function( elem, value, name ) {
var propName;
if ( value === false ) {
// Remove boolean attributes when set to false
jQuery.removeAttr( elem, name );
} else {
// value is true since we know at this point it's type boolean and not false
// Set boolean attributes to the same name and set the DOM property
propName = jQuery.propFix[ name ] || name;
if ( propName in elem ) {
// Only set the IDL specifically if it already exists on the element
elem[ propName ] = true;
}
elem.setAttribute( name, name.toLowerCase() );
}
return name;
}
};
// Warn only for attributes that can remain distinct from their properties post-1.9
if ( ruseDefault.test( lowerName ) ) {
migrateWarn( "jQuery.fn.attr('" + lowerName + "') may use property instead of attribute" );
}
}
return oldAttr.call( jQuery, elem, name, value );
};
// attrHooks: value
jQuery.attrHooks.value = {
get: function( elem, name ) {
var nodeName = ( elem.nodeName || "" ).toLowerCase();
if ( nodeName === "button" ) {
return valueAttrGet.apply( this, arguments );
}
if ( nodeName !== "input" && nodeName !== "option" ) {
migrateWarn("jQuery.fn.attr('value') no longer gets properties");
}
return name in elem ?
elem.value :
null;
},
set: function( elem, value ) {
var nodeName = ( elem.nodeName || "" ).toLowerCase();
if ( nodeName === "button" ) {
return valueAttrSet.apply( this, arguments );
}
if ( nodeName !== "input" && nodeName !== "option" ) {
migrateWarn("jQuery.fn.attr('value', val) no longer sets properties");
}
// Does not return so that setAttribute is also used
elem.value = value;
}
};
var matched, browser,
oldInit = jQuery.fn.init,
oldParseJSON = jQuery.parseJSON,
// Note this does NOT include the #9521 XSS fix from 1.7!
rquickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*|#([\w\-]*))$/;
// $(html) "looks like html" rule change
jQuery.fn.init = function( selector, context, rootjQuery ) {
var match;
if ( selector && typeof selector === "string" && !jQuery.isPlainObject( context ) &&
(match = rquickExpr.exec( selector )) && match[1] ) {
// This is an HTML string according to the "old" rules; is it still?
if ( selector.charAt( 0 ) !== "<" ) {
migrateWarn("$(html) HTML strings must start with '<' character");
}
// Now process using loose rules; let pre-1.8 play too
if ( context && context.context ) {
// jQuery object as context; parseHTML expects a DOM object
context = context.context;
}
if ( jQuery.parseHTML ) {
return oldInit.call( this, jQuery.parseHTML( jQuery.trim(selector), context, true ),
context, rootjQuery );
}
}
return oldInit.apply( this, arguments );
};
jQuery.fn.init.prototype = jQuery.fn;
// Let $.parseJSON(falsy_value) return null
jQuery.parseJSON = function( json ) {
if ( !json && json !== null ) {
migrateWarn("jQuery.parseJSON requires a valid JSON string");
return null;
}
return oldParseJSON.apply( this, arguments );
};
jQuery.uaMatch = function( ua ) {
ua = ua.toLowerCase();
var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
/(webkit)[ \/]([\w.]+)/.exec( ua ) ||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
/(msie) ([\w.]+)/.exec( ua ) ||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
[];
return {
browser: match[ 1 ] || "",
version: match[ 2 ] || "0"
};
};
// Don't clobber any existing jQuery.browser in case it's different
if ( !jQuery.browser ) {
matched = jQuery.uaMatch( navigator.userAgent );
browser = {};
if ( matched.browser ) {
browser[ matched.browser ] = true;
browser.version = matched.version;
}
// Chrome is Webkit, but Webkit is also Safari.
if ( browser.chrome ) {
browser.webkit = true;
} else if ( browser.webkit ) {
browser.safari = true;
}
jQuery.browser = browser;
}
// Warn if the code tries to get jQuery.browser
migrateWarnProp( jQuery, "browser", jQuery.browser, "jQuery.browser is deprecated" );
jQuery.sub = function() {
function jQuerySub( selector, context ) {
return new jQuerySub.fn.init( selector, context );
}
jQuery.extend( true, jQuerySub, this );
jQuerySub.superclass = this;
jQuerySub.fn = jQuerySub.prototype = this();
jQuerySub.fn.constructor = jQuerySub;
jQuerySub.sub = this.sub;
jQuerySub.fn.init = function init( selector, context ) {
if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
context = jQuerySub( context );
}
return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
};
jQuerySub.fn.init.prototype = jQuerySub.fn;
var rootjQuerySub = jQuerySub(document);
migrateWarn( "jQuery.sub() is deprecated" );
return jQuerySub;
};
// Ensure that $.ajax gets the new parseJSON defined in core.js
jQuery.ajaxSetup({
converters: {
"text json": jQuery.parseJSON
}
});
var oldFnData = jQuery.fn.data;
jQuery.fn.data = function( name ) {
var ret, evt,
elem = this[0];
// Handles 1.7 which has this behavior and 1.8 which doesn't
if ( elem && name === "events" && arguments.length === 1 ) {
ret = jQuery.data( elem, name );
evt = jQuery._data( elem, name );
if ( ( ret === undefined || ret === evt ) && evt !== undefined ) {
migrateWarn("Use of jQuery.fn.data('events') is deprecated");
return evt;
}
}
return oldFnData.apply( this, arguments );
};
var rscriptType = /\/(java|ecma)script/i,
oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack;
jQuery.fn.andSelf = function() {
migrateWarn("jQuery.fn.andSelf() replaced by jQuery.fn.addBack()");
return oldSelf.apply( this, arguments );
};
// Since jQuery.clean is used internally on older versions, we only shim if it's missing
if ( !jQuery.clean ) {
jQuery.clean = function( elems, context, fragment, scripts ) {
// Set context per 1.8 logic
context = context || document;
context = !context.nodeType && context[0] || context;
context = context.ownerDocument || context;
migrateWarn("jQuery.clean() is deprecated");
var i, elem, handleScript, jsTags,
ret = [];
jQuery.merge( ret, jQuery.buildFragment( elems, context ).childNodes );
// Complex logic lifted directly from jQuery 1.8
if ( fragment ) {
// Special handling of each script element
handleScript = function( elem ) {
// Check if we consider it executable
if ( !elem.type || rscriptType.test( elem.type ) ) {
// Detach the script and store it in the scripts array (if provided) or the fragment
// Return truthy to indicate that it has been handled
return scripts ?
scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) :
fragment.appendChild( elem );
}
};
for ( i = 0; (elem = ret[i]) != null; i++ ) {
// Check if we're done after handling an executable script
if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) {
// Append to fragment and handle embedded scripts
fragment.appendChild( elem );
if ( typeof elem.getElementsByTagName !== "undefined" ) {
// handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration
jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript );
// Splice the scripts into ret after their former ancestor and advance our index beyond them
ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
i += jsTags.length;
}
}
}
}
return ret;
};
}
var eventAdd = jQuery.event.add,
eventRemove = jQuery.event.remove,
eventTrigger = jQuery.event.trigger,
oldToggle = jQuery.fn.toggle,
oldLive = jQuery.fn.live,
oldDie = jQuery.fn.die,
ajaxEvents = "ajaxStart|ajaxStop|ajaxSend|ajaxComplete|ajaxError|ajaxSuccess",
rajaxEvent = new RegExp( "\\b(?:" + ajaxEvents + ")\\b" ),
rhoverHack = /(?:^|\s)hover(\.\S+|)\b/,
hoverHack = function( events ) {
if ( typeof( events ) !== "string" || jQuery.event.special.hover ) {
return events;
}
if ( rhoverHack.test( events ) ) {
migrateWarn("'hover' pseudo-event is deprecated, use 'mouseenter mouseleave'");
}
return events && events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
};
// Event props removed in 1.9, put them back if needed; no practical way to warn them
if ( jQuery.event.props && jQuery.event.props[ 0 ] !== "attrChange" ) {
jQuery.event.props.unshift( "attrChange", "attrName", "relatedNode", "srcElement" );
}
// Undocumented jQuery.event.handle was "deprecated" in jQuery 1.7
if ( jQuery.event.dispatch ) {
migrateWarnProp( jQuery.event, "handle", jQuery.event.dispatch, "jQuery.event.handle is undocumented and deprecated" );
}
// Support for 'hover' pseudo-event and ajax event warnings
jQuery.event.add = function( elem, types, handler, data, selector ){
if ( elem !== document && rajaxEvent.test( types ) ) {
migrateWarn( "AJAX events should be attached to document: " + types );
}
eventAdd.call( this, elem, hoverHack( types || "" ), handler, data, selector );
};
jQuery.event.remove = function( elem, types, handler, selector, mappedTypes ){
eventRemove.call( this, elem, hoverHack( types ) || "", handler, selector, mappedTypes );
};
jQuery.fn.error = function() {
var args = Array.prototype.slice.call( arguments, 0);
migrateWarn("jQuery.fn.error() is deprecated");
args.splice( 0, 0, "error" );
if ( arguments.length ) {
return this.bind.apply( this, args );
}
// error event should not bubble to window, although it does pre-1.7
this.triggerHandler.apply( this, args );
return this;
};
jQuery.fn.toggle = function( fn, fn2 ) {
// Don't mess with animation or css toggles
if ( !jQuery.isFunction( fn ) || !jQuery.isFunction( fn2 ) ) {
return oldToggle.apply( this, arguments );
}
migrateWarn("jQuery.fn.toggle(handler, handler...) is deprecated");
// Save reference to arguments for access in closure
var args = arguments,
guid = fn.guid || jQuery.guid++,
i = 0,
toggler = function( event ) {
// Figure out which function to execute
var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
// Make sure that clicks stop
event.preventDefault();
// and execute the function
return args[ lastToggle ].apply( this, arguments ) || false;
};
// link all the functions, so any of them can unbind this click handler
toggler.guid = guid;
while ( i < args.length ) {
args[ i++ ].guid = guid;
}
return this.click( toggler );
};
jQuery.fn.live = function( types, data, fn ) {
migrateWarn("jQuery.fn.live() is deprecated");
if ( oldLive ) {
return oldLive.apply( this, arguments );
}
jQuery( this.context ).on( types, this.selector, data, fn );
return this;
};
jQuery.fn.die = function( types, fn ) {
migrateWarn("jQuery.fn.die() is deprecated");
if ( oldDie ) {
return oldDie.apply( this, arguments );
}
jQuery( this.context ).off( types, this.selector || "**", fn );
return this;
};
// Turn global events into document-triggered events
jQuery.event.trigger = function( event, data, elem, onlyHandlers ){
if ( !elem && !rajaxEvent.test( event ) ) {
migrateWarn( "Global events are undocumented and deprecated" );
}
return eventTrigger.call( this, event, data, elem || document, onlyHandlers );
};
jQuery.each( ajaxEvents.split("|"),
function( _, name ) {
jQuery.event.special[ name ] = {
setup: function() {
var elem = this;
// The document needs no shimming; must be !== for oldIE
if ( elem !== document ) {
jQuery.event.add( document, name + "." + jQuery.guid, function() {
jQuery.event.trigger( name, null, elem, true );
});
jQuery._data( this, name, jQuery.guid++ );
}
return false;
},
teardown: function() {
if ( this !== document ) {
jQuery.event.remove( document, name + "." + jQuery._data( this, name ) );
}
return false;
}
};
}
);
})( jQuery, window );

20
epubjs/libs/jquery.touchy.min.js vendored Executable file
View file

@ -0,0 +1,20 @@
(function(e){e.touchyOptions={useDelegation:!1,longpress:{requiredTouches:1,msThresh:800,triggerStartPhase:!1,data:{startDate:null},proxyEvents:["TouchStart","TouchEnd"]},drag:{requiredTouches:1,msHoldThresh:100,data:{startPoint:null,startDate:null,movePoint:null,moveDate:null,held:!1},proxyEvents:["TouchStart","TouchMove","TouchEnd"]},pinch:{pxThresh:0,data:{startPoint:null,startDate:null,movePoint:null,moveDate:null},proxyEvents:["TouchStart","TouchMove","GestureChange","TouchEnd"]},rotate:{requiredTouches:1,
data:{},proxyEvents:["TouchStart","TouchMove","GestureChange","TouchEnd"]},swipe:{requiredTouches:1,velocityThresh:1,triggerOn:"touchmove",data:{startPoint:null,startDate:null,movePoint:null,moveDate:null},proxyEvents:["TouchStart","TouchMove","TouchEnd"]}};var t={handleTouchStart:function(a){var b=l(a,this.context);if(b){var d=a.originalEvent,c=d.targetTouches;d.preventDefault();switch(this.context){case "drag":d=b.data("touchyDrag");c.length===d.settings.requiredTouches&&(o(d,c,a.timeStamp),a=d.startPoint,
b.trigger("touchy-drag",["start",b,{movePoint:a,lastMovePoint:a,startPoint:a,velocity:0}]));break;case "swipe":d=b.data("touchySwipe");c.length===d.settings.requiredTouches&&p(d,c,a.timeStamp);break;case "pinch":d=b.data("touchyPinch");if(c=m(a))d.startPoint={x:c.centerX,y:c.centerY},d.startDistance=Math.sqrt(Math.pow(c.x2-c.x1,2)+Math.pow(c.y2-c.y1,2));break;case "longpress":d=b.data("touchyLongpress");c.length===d.settings.requiredTouches&&(d.startPoint={x:c[0].pageX,y:c[0].pageY},d.startDate=a.timeStamp,
d.settings.triggerStartPhase&&b.trigger("touchy-longpress",["start",b]),d.timer=setTimeout(e.proxy(function(){b.trigger("touchy-longpress",["end",b])},this),d.settings.msThresh));break;case "rotate":d=b.data("touchyRotate"),c.length===d.settings.requiredTouches&&(1===c.length?n(d,c,a.timeStamp):(c=m(a),d.startPoint={x:c.centerX,y:c.centerY},d.startDate=a.timeStamp),a=d.startPoint,b.trigger("touchy-rotate",["start",b,{startPoint:a,movePoint:a,lastMovePoint:a,velocity:0,degrees:0}]))}}},handleTouchMove:function(a){var b=
this.context,d=l(a,b);if(d){var c=a.originalEvent,f=c.targetTouches;c.preventDefault();switch(b){case "drag":b=d.data("touchyDrag");if(f.length===b.settings.requiredTouches){o(b,f,a.timeStamp);var c=b.movePoint,g=b.lastMovePoint,e=c.x===g.x&&c.y===g.y?0:Math.sqrt(Math.pow(c.x-g.x,2)+Math.pow(c.y-g.y,2)),h=b.moveDate-b.lastMoveDate;b.held&&d.trigger("touchy-drag",["move",d,{movePoint:c,lastMovePoint:g,startPoint:b.startPoint,velocity:0===h?0:e/h}])}break;case "swipe":b=d.data("touchySwipe");f.length===
b.settings.requiredTouches&&(p(b,f,a.timeStamp),!b.swipeExecuted&&(b.swiped&&"touchmove"===b.settings.triggerOn)&&(b.swipeExecuted=!0,q(b,d)));break;case "pinch":b=d.data("touchyPinch");if(a=m(a))b.currentPoint={x:a.centerX,y:a.centerY},"object"!=typeof window.ongesturechange&&(h=Math.sqrt(Math.pow(a.x2-a.x1,2)+Math.pow(a.y2-a.y1,2)),c=b.previousScale=b.scale||1,g=b.startDistance,h=b.scale=h/g,h*g>b.settings.pxThresh&&d.trigger("touchy-pinch",[d,{scale:h,previousScale:c,currentPoint:b.currentPoint,
startPoint:b.startPoint,startDistance:g}]));break;case "rotate":if(b=d.data("touchyRotate"),f.length===b.settings.requiredTouches){var i,g=b.lastMovePoint=b.movePoint||b.startPoint,h=b.lastMoveDate=b.moveDate||b.startDate,c=b.movePoint={x:f[0].pageX,y:f[0].pageY},e=b.moveDate=a.timeStamp;if(1===f.length)a=b.targetPageCoords=b.targetPageCoords||s(a.target),a=b.centerCoords=b.centerCoords||{x:a.x+0.5*d.width(),y:a.y+0.5*d.height()};else if(a=m(a),a=b.centerCoords={x:a.centerX,y:a.centerY},"object"==
typeof window.ongesturechange)break;f=Math.atan2(c.y-a.y,c.x-a.x);i=b.lastDegrees=b.degrees;f=b.degrees=f*(180/Math.PI);i=i?f-i:0;h=e-h;h=b.velocity=0===h?0:i/h;d.trigger("touchy-rotate",["move",d,{startPoint:b.startPoint,startDate:b.startDate,movePoint:c,lastMovePoint:g,centerCoords:a,degrees:f,degreeDelta:i,velocity:h}])}}}},handleGestureChange:function(a){var b=this.context,d=l(a,b);if(d){var d=e(a.target),c=a.originalEvent;c.preventDefault();switch(b){case "pinch":var b=d.data("touchyPinch"),
a=b.previousScale=b.scale||1,c=b.scale=c.scale,f=b.startPoint,g=b.currentPoint||f,k=b.startDistance;c*k>b.settings.pxThresh&&d.trigger("touchy-pinch",[d,{scale:c,previousScale:a,currentPoint:g,startPoint:f,startDistance:k}]);break;case "rotate":b=d.data("touchyRotate"),f=b.lastDegrees=b.degrees,a=b.degrees=c.rotation,c=f?a-f:0,f=b.moveDate-b.lastMoveDate,f=b.velocity=0===f?0:c/f,d.trigger("touchy-rotate",["move",d,{startPoint:b.startPoint,startDate:b.startDate,movePoint:b.movePoint,lastMovePoint:b.lastMovePoint,
centerCoords:b.centerCoords,degrees:a,degreeDelta:c,velocity:f}])}}},handleTouchEnd:function(a){var b=this.context,d=l(a,b);if(d)switch(a.originalEvent.preventDefault(),b){case "drag":a=d.data("touchyDrag");if(a.held){var b=a.movePoint||a.startPoint,c=a.lastMovePoint||a.startPoint,f=b.x===c.x&&b.y===c.y?0:Math.sqrt(Math.pow(b.x-c.x,2)+Math.pow(b.y-c.y,2)),g=a.moveDate-a.lastMoveDate;d.trigger("touchy-drag",["end",d,{movePoint:b,lastMovePoint:c,startPoint:a.startPoint,velocity:0===g?0:f/g}])}e.extend(a,
{startPoint:null,startDate:null,movePoint:null,moveDate:null,lastMovePoint:null,lastMoveDate:null,held:!1});break;case "swipe":a=d.data("touchySwipe");a.swiped&&"touchend"===a.settings.triggerOn&&q(a,d);e.extend(a,{startPoint:null,startDate:null,movePoint:null,moveDate:null,lastMovePoint:null,lastMoveDate:null,swiped:!1,swipeExecuted:!1});break;case "pinch":a=d.data("touchyPinch");e.extend(a,{startPoint:null,startDistance:0,currentPoint:null,pinched:!1,scale:1,previousScale:null});break;case "longpress":a=
d.data("touchyLongpress");clearTimeout(a.timer);e.extend(a,{startDate:null});break;case "rotate":a=d.data("touchyRotate"),d.trigger("touchy-rotate",["end",d,{startPoint:a.startPoint,startDate:a.startDate,movePoint:a.movePoint,lastMovePoint:a.lastMovePoint,degrees:a.degrees,degreeDelta:a.lastDegrees?a.degrees-a.lastDegrees:0,velocity:a.velocity}]),e.extend(a,{startPoint:null,startDate:null,movePoint:null,moveDate:null,lastMovePoint:null,lastMoveDate:null,targetPageCoords:null,centerCoords:null,degrees:null,
lastDegrees:null,velocity:null})}}},o=function(a,b,d){n(a,b,d);var c=a.moveDate||a.startDate;a.held||d-c>a.settings.msHoldThresh?e.extend(a,{held:!0,lastMoveDate:c,lastMovePoint:a.movePoint&&a.movePoint.x?a.movePoint:a.startPoint,moveDate:d,movePoint:{x:b[0].pageX,y:b[0].pageY}}):e.extend(a,{held:!1,lastMoveDate:0,lastMovePoint:a.startPoint,moveDate:0,movePoint:a.startPoint})},p=function(a,b,d){n(a,b,d);var c=a.startPoint,f=a.moveDate||a.startDate,b={x:b[0].pageX,y:b[0].pageY},g=b.x-c.x,c=b.y-c.y,
k=d-f;e.extend(a,{lastMoveDate:f,lastMovePoint:a.movePoint&&a.movePoint.x?a.movePoint:a.startPoint,moveDate:d,movePoint:b,hDistance:g,vDistance:c});if(!a.swiped&&(Math.abs(g)/k>a.settings.velocityThresh||Math.abs(c)/k>a.settings.velocityThresh))a.swiped=!0},q=function(a,b){var d=a.movePoint,c=a.lastMovePoint,f=d.x===c.x&&d.y===c.y?0:Math.sqrt(Math.pow(d.x-c.x,2)+Math.pow(d.y-c.y,2)),g=a.moveDate-a.lastMoveDate,f=0===g?0:f/g,g=a.hDistance,e=a.vDistance;f>a.settings.velocityThresh&&(g=Math.abs(g)>Math.abs(e)?
0<g?"right":"left":0<e?"down":"up",b.trigger("touchy-swipe",[b,{direction:g,movePoint:d,lastMovePoint:c,startPoint:a.startPoint,velocity:f}]))},n=function(a,b,d){a.startPoint||(a.startPoint={x:b[0].pageX,y:b[0].pageY});a.startDate||(a.startDate=d)},m=function(a){var b=!1,a=a.originalEvent.touches;2===a.length&&(b={x1:a[0].pageX,y1:a[0].pageY,x2:a[1].pageX,y2:a[1].pageY},b.centerX=(b.x1+b.x2)/2,b.centerY=(b.y1+b.y2)/2);return b},l=function(a,b){var d,c=!1,f=0,g=j[b].length;if(e.touchyOptions.useDelegation)for(;f<
g;f+=1){if(d=e(j[b][f]).has(a.target),0<d.length){c=d;break}}else j[b]&&j[b].index(a.target)!=-1&&(c=e(a.target));return c},s=function(a,b){function d(a,c,e){var h=a.offsetParent;c.x+=a.offsetLeft-(h?h.scrollLeft:0);c.y+=a.offsetTop-(h?h.scrollTop:0);if(h){if(1==h.nodeType){var i=e.getComputedStyle(h,"");"static"!=i.position?(c.x+=parseInt(i.borderLeftWidth),c.y+=parseInt(i.borderTopWidth),"TABLE"==h.localName?(c.x+=parseInt(i.paddingLeft),c.y+=parseInt(i.paddingTop)):"BODY"==h.localName&&(i=e.getComputedStyle(a,
""),c.x+=parseInt(i.marginLeft),c.y+=parseInt(i.marginTop))):"BODY"==h.localName&&(c.x+=parseInt(i.borderLeftWidth),c.y+=parseInt(i.borderTopWidth));for(a=a.parentNode;h!=a;)c.x-=a.scrollLeft,c.y-=a.scrollTop,a=a.parentNode;d(h,c,e)}}else"BODY"==a.localName&&(i=e.getComputedStyle(a,""),c.x+=parseInt(i.borderLeftWidth),c.y+=parseInt(i.borderTopWidth),e=e.getComputedStyle(a.parentNode,""),c.x-=parseInt(e.paddingLeft),c.y-=parseInt(e.paddingTop)),a.scrollLeft&&(c.x+=a.scrollLeft),a.scrollTop&&(c.y+=
a.scrollTop),(a=a.ownerDocument.defaultView)&&(!b&&a.frameElement)&&d(a.frameElement,c,a)}var c={x:0,y:0};a&&d(a,c,a.ownerDocument.defaultView);return c},j={},r={};e.each(e.touchyOptions,function(a){if("useDelegation"!==a){var b=a.charAt(0).toUpperCase()+a.slice(1);j[a]=e([]);r[a]=new function(){this.context=a};e.event.special["touchy-"+a]={setup:function(){j[a]=j[a].add(this);e(this).data("touchy"+b,e.extend({},e.touchyOptions[a].data));e(this).data("touchy"+b).settings=e.extend({},e.touchyOptions[a]);
delete e(this).data("touchy"+b).settings.data;1===j[a].length&&e.each(e.touchyOptions[a].proxyEvents,function(b,c){e(document).bind(c.toLowerCase()+".touchy."+a,e.proxy(t["handle"+c],r[a]))})},teardown:function(){j[a]=j[a].not(this);e(this).removeData("touchy"+b);0===j[a].length&&e.each(e.touchyOptions[a].proxyEvents,function(b,c){e(document).unbind(c.toLowerCase()+".touchy."+a)})},add:function(a){e.extend(e(this).data("touchy"+b).settings,a.data);var c=a.handler;a.handler=function(a){return c.apply(this,
arguments)}}}}})})(jQuery);

View file

@ -0,0 +1,2 @@
/*! fileStorage - v0.1.0 - 2013-03-28 */var fileStorage = fileStorage || {};
var _requestFileSystem=self.requestFileSystem||self.webkitRequestFileSystem;const DBSIZE=5242880,DBTYPE=TEMPORARY;self.onmessage=function(e){var t=e.data;self.request(t,function(e){self.save(t,e,function(){self.postMessage(t)})})},self.openFs=function(e){if(self._fs){e&&e(self._fs);return}_requestFileSystem(DBTYPE,DBSIZE,function(t){self._fs=t,e&&e(t)},self.failure)},self.request=function(e,t){var n=new self.loadFile(e);n.succeeded=function(e){t&&t(e)},n.failed=function(e){self.postMessage("failed: "+e.toString())},n.start()},self.save=function(e,t,n){self.openFs(function(r){var i=e.split("/").slice(0,-1);self.createDir(r.root,i),r.root.getFile(e,{create:!0},function(r){r.createWriter(function(r){r.onwriteend=function(e){n(e)},r.onerror=function(t){self.postMessage("write error:"+self.errorHandler(err)+" path="+e)},r.write(t)})},self.failure)})},self.createDir=function(e,t){if(t[0]=="."||t[0]=="")t=t.slice(1);e.getDirectory(t[0],{create:!0},function(e){t.length&&createDir(e,t.slice(1))},self.failure)},self.failure=function(e){self.postMessage("failed: "+self.errorHandler(e))},self.errorHandler=function(e){switch(e.code){case FileError.QUOTA_EXCEEDED_ERR:return"QUOTA_EXCEEDED_ERR";case FileError.NOT_FOUND_ERR:return"NOT_FOUND_ERR";case FileError.SECURITY_ERR:return"SECURITY_ERR";case FileError.INVALID_MODIFICATION_ERR:return"INVALID_MODIFICATION_ERR";case FileError.INVALID_STATE_ERR:return"INVALID_STATE_ERR";default:return"Unknown Error"}},self.loadFile=function(e,t){var n=new XMLHttpRequest;return this.succeeded=function(e){t&&t(e)},this.failed=function(e){console.log("Error:",e)},this.start=function(){var t=this;n.open("GET",e,!0),n.responseType="blob",n.onload=function(e){this.status==200&&t.succeeded(this.response)},n.onerror=function(e){t.failed(this.status)},n.send()},{start:this.start,succeeded:this.succeeded,failed:this.failed}},self.openFs();

972
epubjs/libs/mime-types.js Normal file
View file

@ -0,0 +1,972 @@
(function() {
var table = {
"application" : {
"andrew-inset" : "ez",
"annodex" : "anx",
"atom+xml" : "atom",
"atomcat+xml" : "atomcat",
"atomserv+xml" : "atomsrv",
"bbolin" : "lin",
"cap" : [ "cap", "pcap" ],
"cu-seeme" : "cu",
"davmount+xml" : "davmount",
"dsptype" : "tsp",
"ecmascript" : [ "es", "ecma" ],
"futuresplash" : "spl",
"hta" : "hta",
"java-archive" : "jar",
"java-serialized-object" : "ser",
"java-vm" : "class",
"javascript" : "js",
"m3g" : "m3g",
"mac-binhex40" : "hqx",
"mathematica" : [ "nb", "ma", "mb" ],
"msaccess" : "mdb",
"msword" : [ "doc", "dot" ],
"mxf" : "mxf",
"oda" : "oda",
"ogg" : "ogx",
"pdf" : "pdf",
"pgp-keys" : "key",
"pgp-signature" : [ "asc", "sig" ],
"pics-rules" : "prf",
"postscript" : [ "ps", "ai", "eps", "epsi", "epsf", "eps2", "eps3" ],
"rar" : "rar",
"rdf+xml" : "rdf",
"rss+xml" : "rss",
"rtf" : "rtf",
"smil" : [ "smi", "smil" ],
"xhtml+xml" : [ "xhtml", "xht" ],
"xml" : [ "xml", "xsl", "xsd" ],
"xspf+xml" : "xspf",
"zip" : "zip",
"vnd.android.package-archive" : "apk",
"vnd.cinderella" : "cdy",
"vnd.google-earth.kml+xml" : "kml",
"vnd.google-earth.kmz" : "kmz",
"vnd.mozilla.xul+xml" : "xul",
"vnd.ms-excel" : [ "xls", "xlb", "xlt", "xlm", "xla", "xlc", "xlw" ],
"vnd.ms-pki.seccat" : "cat",
"vnd.ms-pki.stl" : "stl",
"vnd.ms-powerpoint" : [ "ppt", "pps", "pot" ],
"vnd.oasis.opendocument.chart" : "odc",
"vnd.oasis.opendocument.database" : "odb",
"vnd.oasis.opendocument.formula" : "odf",
"vnd.oasis.opendocument.graphics" : "odg",
"vnd.oasis.opendocument.graphics-template" : "otg",
"vnd.oasis.opendocument.image" : "odi",
"vnd.oasis.opendocument.presentation" : "odp",
"vnd.oasis.opendocument.presentation-template" : "otp",
"vnd.oasis.opendocument.spreadsheet" : "ods",
"vnd.oasis.opendocument.spreadsheet-template" : "ots",
"vnd.oasis.opendocument.text" : "odt",
"vnd.oasis.opendocument.text-master" : "odm",
"vnd.oasis.opendocument.text-template" : "ott",
"vnd.oasis.opendocument.text-web" : "oth",
"vnd.openxmlformats-officedocument.spreadsheetml.sheet" : "xlsx",
"vnd.openxmlformats-officedocument.spreadsheetml.template" : "xltx",
"vnd.openxmlformats-officedocument.presentationml.presentation" : "pptx",
"vnd.openxmlformats-officedocument.presentationml.slideshow" : "ppsx",
"vnd.openxmlformats-officedocument.presentationml.template" : "potx",
"vnd.openxmlformats-officedocument.wordprocessingml.document" : "docx",
"vnd.openxmlformats-officedocument.wordprocessingml.template" : "dotx",
"vnd.smaf" : "mmf",
"vnd.stardivision.calc" : "sdc",
"vnd.stardivision.chart" : "sds",
"vnd.stardivision.draw" : "sda",
"vnd.stardivision.impress" : "sdd",
"vnd.stardivision.math" : [ "sdf", "smf" ],
"vnd.stardivision.writer" : [ "sdw", "vor" ],
"vnd.stardivision.writer-global" : "sgl",
"vnd.sun.xml.calc" : "sxc",
"vnd.sun.xml.calc.template" : "stc",
"vnd.sun.xml.draw" : "sxd",
"vnd.sun.xml.draw.template" : "std",
"vnd.sun.xml.impress" : "sxi",
"vnd.sun.xml.impress.template" : "sti",
"vnd.sun.xml.math" : "sxm",
"vnd.sun.xml.writer" : "sxw",
"vnd.sun.xml.writer.global" : "sxg",
"vnd.sun.xml.writer.template" : "stw",
"vnd.symbian.install" : [ "sis", "sisx" ],
"vnd.visio" : [ "vsd", "vst", "vss", "vsw" ],
"vnd.wap.wbxml" : "wbxml",
"vnd.wap.wmlc" : "wmlc",
"vnd.wap.wmlscriptc" : "wmlsc",
"vnd.wordperfect" : "wpd",
"vnd.wordperfect5.1" : "wp5",
"x-123" : "wk",
"x-7z-compressed" : "7z",
"x-abiword" : "abw",
"x-apple-diskimage" : "dmg",
"x-bcpio" : "bcpio",
"x-bittorrent" : "torrent",
"x-cbr" : [ "cbr", "cba", "cbt", "cb7" ],
"x-cbz" : "cbz",
"x-cdf" : [ "cdf", "cda" ],
"x-cdlink" : "vcd",
"x-chess-pgn" : "pgn",
"x-cpio" : "cpio",
"x-csh" : "csh",
"x-debian-package" : [ "deb", "udeb" ],
"x-director" : [ "dcr", "dir", "dxr", "cst", "cct", "cxt", "w3d", "fgd", "swa" ],
"x-dms" : "dms",
"x-doom" : "wad",
"x-dvi" : "dvi",
"x-httpd-eruby" : "rhtml",
"x-font" : "pcf.Z",
"x-freemind" : "mm",
"x-gnumeric" : "gnumeric",
"x-go-sgf" : "sgf",
"x-graphing-calculator" : "gcf",
"x-gtar" : [ "gtar", "taz" ],
"x-hdf" : "hdf",
"x-httpd-php" : [ "phtml", "pht", "php" ],
"x-httpd-php-source" : "phps",
"x-httpd-php3" : "php3",
"x-httpd-php3-preprocessed" : "php3p",
"x-httpd-php4" : "php4",
"x-httpd-php5" : "php5",
"x-ica" : "ica",
"x-info" : "info",
"x-internet-signup" : [ "ins", "isp" ],
"x-iphone" : "iii",
"x-iso9660-image" : "iso",
"x-java-jnlp-file" : "jnlp",
"x-jmol" : "jmz",
"x-killustrator" : "kil",
"x-koan" : [ "skp", "skd", "skt", "skm" ],
"x-kpresenter" : [ "kpr", "kpt" ],
"x-kword" : [ "kwd", "kwt" ],
"x-latex" : "latex",
"x-lha" : "lha",
"x-lyx" : "lyx",
"x-lzh" : "lzh",
"x-lzx" : "lzx",
"x-maker" : [ "frm", "maker", "frame", "fm", "fb", "book", "fbdoc" ],
"x-ms-wmd" : "wmd",
"x-ms-wmz" : "wmz",
"x-msdos-program" : [ "com", "exe", "bat", "dll" ],
"x-msi" : "msi",
"x-netcdf" : [ "nc", "cdf" ],
"x-ns-proxy-autoconfig" : [ "pac", "dat" ],
"x-nwc" : "nwc",
"x-object" : "o",
"x-oz-application" : "oza",
"x-pkcs7-certreqresp" : "p7r",
"x-python-code" : [ "pyc", "pyo" ],
"x-qgis" : [ "qgs", "shp", "shx" ],
"x-quicktimeplayer" : "qtl",
"x-redhat-package-manager" : "rpm",
"x-ruby" : "rb",
"x-sh" : "sh",
"x-shar" : "shar",
"x-shockwave-flash" : [ "swf", "swfl" ],
"x-silverlight" : "scr",
"x-stuffit" : "sit",
"x-sv4cpio" : "sv4cpio",
"x-sv4crc" : "sv4crc",
"x-tar" : "tar",
"x-tcl" : "tcl",
"x-tex-gf" : "gf",
"x-tex-pk" : "pk",
"x-texinfo" : [ "texinfo", "texi" ],
"x-trash" : [ "~", "%", "bak", "old", "sik" ],
"x-troff" : [ "t", "tr", "roff" ],
"x-troff-man" : "man",
"x-troff-me" : "me",
"x-troff-ms" : "ms",
"x-ustar" : "ustar",
"x-wais-source" : "src",
"x-wingz" : "wz",
"x-x509-ca-cert" : [ "crt", "der", "cer" ],
"x-xcf" : "xcf",
"x-xfig" : "fig",
"x-xpinstall" : "xpi",
"applixware" : "aw",
"atomsvc+xml" : "atomsvc",
"ccxml+xml" : "ccxml",
"cdmi-capability" : "cdmia",
"cdmi-container" : "cdmic",
"cdmi-domain" : "cdmid",
"cdmi-object" : "cdmio",
"cdmi-queue" : "cdmiq",
"docbook+xml" : "dbk",
"dssc+der" : "dssc",
"dssc+xml" : "xdssc",
"emma+xml" : "emma",
"epub+zip" : "epub",
"exi" : "exi",
"font-tdpfr" : "pfr",
"gml+xml" : "gml",
"gpx+xml" : "gpx",
"gxf" : "gxf",
"hyperstudio" : "stk",
"inkml+xml" : [ "ink", "inkml" ],
"ipfix" : "ipfix",
"json" : "json",
"jsonml+json" : "jsonml",
"lost+xml" : "lostxml",
"mads+xml" : "mads",
"marc" : "mrc",
"marcxml+xml" : "mrcx",
"mathml+xml" : "mathml",
"mbox" : "mbox",
"mediaservercontrol+xml" : "mscml",
"metalink+xml" : "metalink",
"metalink4+xml" : "meta4",
"mets+xml" : "mets",
"mods+xml" : "mods",
"mp21" : [ "m21", "mp21" ],
"mp4" : "mp4s",
"oebps-package+xml" : "opf",
"omdoc+xml" : "omdoc",
"onenote" : [ "onetoc", "onetoc2", "onetmp", "onepkg" ],
"oxps" : "oxps",
"patch-ops-error+xml" : "xer",
"pgp-encrypted" : "pgp",
"pkcs10" : "p10",
"pkcs7-mime" : [ "p7m", "p7c" ],
"pkcs7-signature" : "p7s",
"pkcs8" : "p8",
"pkix-attr-cert" : "ac",
"pkix-crl" : "crl",
"pkix-pkipath" : "pkipath",
"pkixcmp" : "pki",
"pls+xml" : "pls",
"prs.cww" : "cww",
"pskc+xml" : "pskcxml",
"reginfo+xml" : "rif",
"relax-ng-compact-syntax" : "rnc",
"resource-lists+xml" : "rl",
"resource-lists-diff+xml" : "rld",
"rls-services+xml" : "rs",
"rpki-ghostbusters" : "gbr",
"rpki-manifest" : "mft",
"rpki-roa" : "roa",
"rsd+xml" : "rsd",
"sbml+xml" : "sbml",
"scvp-cv-request" : "scq",
"scvp-cv-response" : "scs",
"scvp-vp-request" : "spq",
"scvp-vp-response" : "spp",
"sdp" : "sdp",
"set-payment-initiation" : "setpay",
"set-registration-initiation" : "setreg",
"shf+xml" : "shf",
"sparql-query" : "rq",
"sparql-results+xml" : "srx",
"srgs" : "gram",
"srgs+xml" : "grxml",
"sru+xml" : "sru",
"ssdl+xml" : "ssdl",
"ssml+xml" : "ssml",
"tei+xml" : [ "tei", "teicorpus" ],
"thraud+xml" : "tfi",
"timestamped-data" : "tsd",
"vnd.3gpp.pic-bw-large" : "plb",
"vnd.3gpp.pic-bw-small" : "psb",
"vnd.3gpp.pic-bw-var" : "pvb",
"vnd.3gpp2.tcap" : "tcap",
"vnd.3m.post-it-notes" : "pwn",
"vnd.accpac.simply.aso" : "aso",
"vnd.accpac.simply.imp" : "imp",
"vnd.acucobol" : "acu",
"vnd.acucorp" : [ "atc", "acutc" ],
"vnd.adobe.air-application-installer-package+zip" : "air",
"vnd.adobe.formscentral.fcdt" : "fcdt",
"vnd.adobe.fxp" : [ "fxp", "fxpl" ],
"vnd.adobe.xdp+xml" : "xdp",
"vnd.adobe.xfdf" : "xfdf",
"vnd.ahead.space" : "ahead",
"vnd.airzip.filesecure.azf" : "azf",
"vnd.airzip.filesecure.azs" : "azs",
"vnd.amazon.ebook" : "azw",
"vnd.americandynamics.acc" : "acc",
"vnd.amiga.ami" : "ami",
"vnd.anser-web-certificate-issue-initiation" : "cii",
"vnd.anser-web-funds-transfer-initiation" : "fti",
"vnd.antix.game-component" : "atx",
"vnd.apple.installer+xml" : "mpkg",
"vnd.apple.mpegurl" : "m3u8",
"vnd.aristanetworks.swi" : "swi",
"vnd.astraea-software.iota" : "iota",
"vnd.audiograph" : "aep",
"vnd.blueice.multipass" : "mpm",
"vnd.bmi" : "bmi",
"vnd.businessobjects" : "rep",
"vnd.chemdraw+xml" : "cdxml",
"vnd.chipnuts.karaoke-mmd" : "mmd",
"vnd.claymore" : "cla",
"vnd.cloanto.rp9" : "rp9",
"vnd.clonk.c4group" : [ "c4g", "c4d", "c4f", "c4p", "c4u" ],
"vnd.cluetrust.cartomobile-config" : "c11amc",
"vnd.cluetrust.cartomobile-config-pkg" : "c11amz",
"vnd.commonspace" : "csp",
"vnd.contact.cmsg" : "cdbcmsg",
"vnd.cosmocaller" : "cmc",
"vnd.crick.clicker" : "clkx",
"vnd.crick.clicker.keyboard" : "clkk",
"vnd.crick.clicker.palette" : "clkp",
"vnd.crick.clicker.template" : "clkt",
"vnd.crick.clicker.wordbank" : "clkw",
"vnd.criticaltools.wbs+xml" : "wbs",
"vnd.ctc-posml" : "pml",
"vnd.cups-ppd" : "ppd",
"vnd.curl.car" : "car",
"vnd.curl.pcurl" : "pcurl",
"vnd.dart" : "dart",
"vnd.data-vision.rdz" : "rdz",
"vnd.dece.data" : [ "uvf", "uvvf", "uvd", "uvvd" ],
"vnd.dece.ttml+xml" : [ "uvt", "uvvt" ],
"vnd.dece.unspecified" : [ "uvx", "uvvx" ],
"vnd.dece.zip" : [ "uvz", "uvvz" ],
"vnd.denovo.fcselayout-link" : "fe_launch",
"vnd.dna" : "dna",
"vnd.dolby.mlp" : "mlp",
"vnd.dpgraph" : "dpg",
"vnd.dreamfactory" : "dfac",
"vnd.ds-keypoint" : "kpxx",
"vnd.dvb.ait" : "ait",
"vnd.dvb.service" : "svc",
"vnd.dynageo" : "geo",
"vnd.ecowin.chart" : "mag",
"vnd.enliven" : "nml",
"vnd.epson.esf" : "esf",
"vnd.epson.msf" : "msf",
"vnd.epson.quickanime" : "qam",
"vnd.epson.salt" : "slt",
"vnd.epson.ssf" : "ssf",
"vnd.eszigno3+xml" : [ "es3", "et3" ],
"vnd.ezpix-album" : "ez2",
"vnd.ezpix-package" : "ez3",
"vnd.fdf" : "fdf",
"vnd.fdsn.mseed" : "mseed",
"vnd.fdsn.seed" : [ "seed", "dataless" ],
"vnd.flographit" : "gph",
"vnd.fluxtime.clip" : "ftc",
"vnd.framemaker" : [ "fm", "frame", "maker", "book" ],
"vnd.frogans.fnc" : "fnc",
"vnd.frogans.ltf" : "ltf",
"vnd.fsc.weblaunch" : "fsc",
"vnd.fujitsu.oasys" : "oas",
"vnd.fujitsu.oasys2" : "oa2",
"vnd.fujitsu.oasys3" : "oa3",
"vnd.fujitsu.oasysgp" : "fg5",
"vnd.fujitsu.oasysprs" : "bh2",
"vnd.fujixerox.ddd" : "ddd",
"vnd.fujixerox.docuworks" : "xdw",
"vnd.fujixerox.docuworks.binder" : "xbd",
"vnd.fuzzysheet" : "fzs",
"vnd.genomatix.tuxedo" : "txd",
"vnd.geogebra.file" : "ggb",
"vnd.geogebra.tool" : "ggt",
"vnd.geometry-explorer" : [ "gex", "gre" ],
"vnd.geonext" : "gxt",
"vnd.geoplan" : "g2w",
"vnd.geospace" : "g3w",
"vnd.gmx" : "gmx",
"vnd.grafeq" : [ "gqf", "gqs" ],
"vnd.groove-account" : "gac",
"vnd.groove-help" : "ghf",
"vnd.groove-identity-message" : "gim",
"vnd.groove-injector" : "grv",
"vnd.groove-tool-message" : "gtm",
"vnd.groove-tool-template" : "tpl",
"vnd.groove-vcard" : "vcg",
"vnd.hal+xml" : "hal",
"vnd.handheld-entertainment+xml" : "zmm",
"vnd.hbci" : "hbci",
"vnd.hhe.lesson-player" : "les",
"vnd.hp-hpgl" : "hpgl",
"vnd.hp-hpid" : "hpid",
"vnd.hp-hps" : "hps",
"vnd.hp-jlyt" : "jlt",
"vnd.hp-pcl" : "pcl",
"vnd.hp-pclxl" : "pclxl",
"vnd.hydrostatix.sof-data" : "sfd-hdstx",
"vnd.ibm.minipay" : "mpy",
"vnd.ibm.modcap" : [ "afp", "listafp", "list3820" ],
"vnd.ibm.rights-management" : "irm",
"vnd.ibm.secure-container" : "sc",
"vnd.iccprofile" : [ "icc", "icm" ],
"vnd.igloader" : "igl",
"vnd.immervision-ivp" : "ivp",
"vnd.immervision-ivu" : "ivu",
"vnd.insors.igm" : "igm",
"vnd.intercon.formnet" : [ "xpw", "xpx" ],
"vnd.intergeo" : "i2g",
"vnd.intu.qbo" : "qbo",
"vnd.intu.qfx" : "qfx",
"vnd.ipunplugged.rcprofile" : "rcprofile",
"vnd.irepository.package+xml" : "irp",
"vnd.is-xpr" : "xpr",
"vnd.isac.fcs" : "fcs",
"vnd.jam" : "jam",
"vnd.jcp.javame.midlet-rms" : "rms",
"vnd.jisp" : "jisp",
"vnd.joost.joda-archive" : "joda",
"vnd.kahootz" : [ "ktz", "ktr" ],
"vnd.kde.karbon" : "karbon",
"vnd.kde.kchart" : "chrt",
"vnd.kde.kformula" : "kfo",
"vnd.kde.kivio" : "flw",
"vnd.kde.kontour" : "kon",
"vnd.kde.kpresenter" : [ "kpr", "kpt" ],
"vnd.kde.kspread" : "ksp",
"vnd.kde.kword" : [ "kwd", "kwt" ],
"vnd.kenameaapp" : "htke",
"vnd.kidspiration" : "kia",
"vnd.kinar" : [ "kne", "knp" ],
"vnd.koan" : [ "skp", "skd", "skt", "skm" ],
"vnd.kodak-descriptor" : "sse",
"vnd.las.las+xml" : "lasxml",
"vnd.llamagraphics.life-balance.desktop" : "lbd",
"vnd.llamagraphics.life-balance.exchange+xml" : "lbe",
"vnd.lotus-1-2-3" : "123",
"vnd.lotus-approach" : "apr",
"vnd.lotus-freelance" : "pre",
"vnd.lotus-notes" : "nsf",
"vnd.lotus-organizer" : "org",
"vnd.lotus-screencam" : "scm",
"vnd.lotus-wordpro" : "lwp",
"vnd.macports.portpkg" : "portpkg",
"vnd.mcd" : "mcd",
"vnd.medcalcdata" : "mc1",
"vnd.mediastation.cdkey" : "cdkey",
"vnd.mfer" : "mwf",
"vnd.mfmp" : "mfm",
"vnd.micrografx.flo" : "flo",
"vnd.micrografx.igx" : "igx",
"vnd.mif" : "mif",
"vnd.mobius.daf" : "daf",
"vnd.mobius.dis" : "dis",
"vnd.mobius.mbk" : "mbk",
"vnd.mobius.mqy" : "mqy",
"vnd.mobius.msl" : "msl",
"vnd.mobius.plc" : "plc",
"vnd.mobius.txf" : "txf",
"vnd.mophun.application" : "mpn",
"vnd.mophun.certificate" : "mpc",
"vnd.ms-artgalry" : "cil",
"vnd.ms-cab-compressed" : "cab",
"vnd.ms-excel.addin.macroenabled.12" : "xlam",
"vnd.ms-excel.sheet.binary.macroenabled.12" : "xlsb",
"vnd.ms-excel.sheet.macroenabled.12" : "xlsm",
"vnd.ms-excel.template.macroenabled.12" : "xltm",
"vnd.ms-fontobject" : "eot",
"vnd.ms-htmlhelp" : "chm",
"vnd.ms-ims" : "ims",
"vnd.ms-lrm" : "lrm",
"vnd.ms-officetheme" : "thmx",
"vnd.ms-powerpoint.addin.macroenabled.12" : "ppam",
"vnd.ms-powerpoint.presentation.macroenabled.12" : "pptm",
"vnd.ms-powerpoint.slide.macroenabled.12" : "sldm",
"vnd.ms-powerpoint.slideshow.macroenabled.12" : "ppsm",
"vnd.ms-powerpoint.template.macroenabled.12" : "potm",
"vnd.ms-project" : [ "mpp", "mpt" ],
"vnd.ms-word.document.macroenabled.12" : "docm",
"vnd.ms-word.template.macroenabled.12" : "dotm",
"vnd.ms-works" : [ "wps", "wks", "wcm", "wdb" ],
"vnd.ms-wpl" : "wpl",
"vnd.ms-xpsdocument" : "xps",
"vnd.mseq" : "mseq",
"vnd.musician" : "mus",
"vnd.muvee.style" : "msty",
"vnd.mynfc" : "taglet",
"vnd.neurolanguage.nlu" : "nlu",
"vnd.nitf" : [ "ntf", "nitf" ],
"vnd.noblenet-directory" : "nnd",
"vnd.noblenet-sealer" : "nns",
"vnd.noblenet-web" : "nnw",
"vnd.nokia.n-gage.data" : "ngdat",
"vnd.nokia.n-gage.symbian.install" : "n-gage",
"vnd.nokia.radio-preset" : "rpst",
"vnd.nokia.radio-presets" : "rpss",
"vnd.novadigm.edm" : "edm",
"vnd.novadigm.edx" : "edx",
"vnd.novadigm.ext" : "ext",
"vnd.oasis.opendocument.chart-template" : "otc",
"vnd.oasis.opendocument.formula-template" : "odft",
"vnd.oasis.opendocument.image-template" : "oti",
"vnd.olpc-sugar" : "xo",
"vnd.oma.dd2+xml" : "dd2",
"vnd.openofficeorg.extension" : "oxt",
"vnd.openxmlformats-officedocument.presentationml.slide" : "sldx",
"vnd.osgeo.mapguide.package" : "mgp",
"vnd.osgi.dp" : "dp",
"vnd.osgi.subsystem" : "esa",
"vnd.palm" : [ "pdb", "pqa", "oprc" ],
"vnd.pawaafile" : "paw",
"vnd.pg.format" : "str",
"vnd.pg.osasli" : "ei6",
"vnd.picsel" : "efif",
"vnd.pmi.widget" : "wg",
"vnd.pocketlearn" : "plf",
"vnd.powerbuilder6" : "pbd",
"vnd.previewsystems.box" : "box",
"vnd.proteus.magazine" : "mgz",
"vnd.publishare-delta-tree" : "qps",
"vnd.pvi.ptid1" : "ptid",
"vnd.quark.quarkxpress" : [ "qxd", "qxt", "qwd", "qwt", "qxl", "qxb" ],
"vnd.realvnc.bed" : "bed",
"vnd.recordare.musicxml" : "mxl",
"vnd.recordare.musicxml+xml" : "musicxml",
"vnd.rig.cryptonote" : "cryptonote",
"vnd.rn-realmedia" : "rm",
"vnd.rn-realmedia-vbr" : "rmvb",
"vnd.route66.link66+xml" : "link66",
"vnd.sailingtracker.track" : "st",
"vnd.seemail" : "see",
"vnd.sema" : "sema",
"vnd.semd" : "semd",
"vnd.semf" : "semf",
"vnd.shana.informed.formdata" : "ifm",
"vnd.shana.informed.formtemplate" : "itp",
"vnd.shana.informed.interchange" : "iif",
"vnd.shana.informed.package" : "ipk",
"vnd.simtech-mindmapper" : [ "twd", "twds" ],
"vnd.smart.teacher" : "teacher",
"vnd.solent.sdkm+xml" : [ "sdkm", "sdkd" ],
"vnd.spotfire.dxp" : "dxp",
"vnd.spotfire.sfs" : "sfs",
"vnd.stepmania.package" : "smzip",
"vnd.stepmania.stepchart" : "sm",
"vnd.sus-calendar" : [ "sus", "susp" ],
"vnd.svd" : "svd",
"vnd.syncml+xml" : "xsm",
"vnd.syncml.dm+wbxml" : "bdm",
"vnd.syncml.dm+xml" : "xdm",
"vnd.tao.intent-module-archive" : "tao",
"vnd.tcpdump.pcap" : [ "pcap", "cap", "dmp" ],
"vnd.tmobile-livetv" : "tmo",
"vnd.trid.tpt" : "tpt",
"vnd.triscape.mxs" : "mxs",
"vnd.trueapp" : "tra",
"vnd.ufdl" : [ "ufd", "ufdl" ],
"vnd.uiq.theme" : "utz",
"vnd.umajin" : "umj",
"vnd.unity" : "unityweb",
"vnd.uoml+xml" : "uoml",
"vnd.vcx" : "vcx",
"vnd.visionary" : "vis",
"vnd.vsf" : "vsf",
"vnd.webturbo" : "wtb",
"vnd.wolfram.player" : "nbp",
"vnd.wqd" : "wqd",
"vnd.wt.stf" : "stf",
"vnd.xara" : "xar",
"vnd.xfdl" : "xfdl",
"vnd.yamaha.hv-dic" : "hvd",
"vnd.yamaha.hv-script" : "hvs",
"vnd.yamaha.hv-voice" : "hvp",
"vnd.yamaha.openscoreformat" : "osf",
"vnd.yamaha.openscoreformat.osfpvg+xml" : "osfpvg",
"vnd.yamaha.smaf-audio" : "saf",
"vnd.yamaha.smaf-phrase" : "spf",
"vnd.yellowriver-custom-menu" : "cmp",
"vnd.zul" : [ "zir", "zirz" ],
"vnd.zzazz.deck+xml" : "zaz",
"voicexml+xml" : "vxml",
"widget" : "wgt",
"winhlp" : "hlp",
"wsdl+xml" : "wsdl",
"wspolicy+xml" : "wspolicy",
"x-ace-compressed" : "ace",
"x-authorware-bin" : [ "aab", "x32", "u32", "vox" ],
"x-authorware-map" : "aam",
"x-authorware-seg" : "aas",
"x-blorb" : [ "blb", "blorb" ],
"x-bzip" : "bz",
"x-bzip2" : [ "bz2", "boz" ],
"x-cfs-compressed" : "cfs",
"x-chat" : "chat",
"x-conference" : "nsc",
"x-dgc-compressed" : "dgc",
"x-dtbncx+xml" : "ncx",
"x-dtbook+xml" : "dtb",
"x-dtbresource+xml" : "res",
"x-eva" : "eva",
"x-font-bdf" : "bdf",
"x-font-ghostscript" : "gsf",
"x-font-linux-psf" : "psf",
"x-font-otf" : "otf",
"x-font-pcf" : "pcf",
"x-font-snf" : "snf",
"x-font-ttf" : [ "ttf", "ttc" ],
"x-font-type1" : [ "pfa", "pfb", "pfm", "afm" ],
"x-font-woff" : "woff",
"x-freearc" : "arc",
"x-gca-compressed" : "gca",
"x-glulx" : "ulx",
"x-gramps-xml" : "gramps",
"x-install-instructions" : "install",
"x-lzh-compressed" : [ "lzh", "lha" ],
"x-mie" : "mie",
"x-mobipocket-ebook" : [ "prc", "mobi" ],
"x-ms-application" : "application",
"x-ms-shortcut" : "lnk",
"x-ms-xbap" : "xbap",
"x-msbinder" : "obd",
"x-mscardfile" : "crd",
"x-msclip" : "clp",
"x-msdownload" : [ "exe", "dll", "com", "bat", "msi" ],
"x-msmediaview" : [ "mvb", "m13", "m14" ],
"x-msmetafile" : [ "wmf", "wmz", "emf", "emz" ],
"x-msmoney" : "mny",
"x-mspublisher" : "pub",
"x-msschedule" : "scd",
"x-msterminal" : "trm",
"x-mswrite" : "wri",
"x-nzb" : "nzb",
"x-pkcs12" : [ "p12", "pfx" ],
"x-pkcs7-certificates" : [ "p7b", "spc" ],
"x-research-info-systems" : "ris",
"x-silverlight-app" : "xap",
"x-sql" : "sql",
"x-stuffitx" : "sitx",
"x-subrip" : "srt",
"x-t3vm-image" : "t3",
"x-tads" : "gam",
"x-tex" : "tex",
"x-tex-tfm" : "tfm",
"x-tgif" : "obj",
"x-xliff+xml" : "xlf",
"x-xz" : "xz",
"x-zmachine" : [ "z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8" ],
"xaml+xml" : "xaml",
"xcap-diff+xml" : "xdf",
"xenc+xml" : "xenc",
"xml-dtd" : "dtd",
"xop+xml" : "xop",
"xproc+xml" : "xpl",
"xslt+xml" : "xslt",
"xv+xml" : [ "mxml", "xhvml", "xvml", "xvm" ],
"yang" : "yang",
"yin+xml" : "yin",
"envoy" : "evy",
"fractals" : "fif",
"internet-property-stream" : "acx",
"olescript" : "axs",
"vnd.ms-outlook" : "msg",
"vnd.ms-pkicertstore" : "sst",
"x-compress" : "z",
"x-compressed" : "tgz",
"x-gzip" : "gz",
"x-perfmon" : [ "pma", "pmc", "pml", "pmr", "pmw" ],
"x-pkcs7-mime" : [ "p7c", "p7m" ],
"ynd.ms-pkipko" : "pko"
},
"audio" : {
"amr" : "amr",
"amr-wb" : "awb",
"annodex" : "axa",
"basic" : [ "au", "snd" ],
"flac" : "flac",
"midi" : [ "mid", "midi", "kar", "rmi" ],
"mpeg" : [ "mpga", "mpega", "mp2", "mp3", "m4a", "mp2a", "m2a", "m3a" ],
"mpegurl" : "m3u",
"ogg" : [ "oga", "ogg", "spx" ],
"prs.sid" : "sid",
"x-aiff" : [ "aif", "aiff", "aifc" ],
"x-gsm" : "gsm",
"x-ms-wma" : "wma",
"x-ms-wax" : "wax",
"x-pn-realaudio" : "ram",
"x-realaudio" : "ra",
"x-sd2" : "sd2",
"x-wav" : "wav",
"adpcm" : "adp",
"mp4" : "mp4a",
"s3m" : "s3m",
"silk" : "sil",
"vnd.dece.audio" : [ "uva", "uvva" ],
"vnd.digital-winds" : "eol",
"vnd.dra" : "dra",
"vnd.dts" : "dts",
"vnd.dts.hd" : "dtshd",
"vnd.lucent.voice" : "lvp",
"vnd.ms-playready.media.pya" : "pya",
"vnd.nuera.ecelp4800" : "ecelp4800",
"vnd.nuera.ecelp7470" : "ecelp7470",
"vnd.nuera.ecelp9600" : "ecelp9600",
"vnd.rip" : "rip",
"webm" : "weba",
"x-aac" : "aac",
"x-caf" : "caf",
"x-matroska" : "mka",
"x-pn-realaudio-plugin" : "rmp",
"xm" : "xm",
"mid" : [ "mid", "rmi" ]
},
"chemical" : {
"x-alchemy" : "alc",
"x-cache" : [ "cac", "cache" ],
"x-cache-csf" : "csf",
"x-cactvs-binary" : [ "cbin", "cascii", "ctab" ],
"x-cdx" : "cdx",
"x-chem3d" : "c3d",
"x-cif" : "cif",
"x-cmdf" : "cmdf",
"x-cml" : "cml",
"x-compass" : "cpa",
"x-crossfire" : "bsd",
"x-csml" : [ "csml", "csm" ],
"x-ctx" : "ctx",
"x-cxf" : [ "cxf", "cef" ],
"x-embl-dl-nucleotide" : [ "emb", "embl" ],
"x-gamess-input" : [ "inp", "gam", "gamin" ],
"x-gaussian-checkpoint" : [ "fch", "fchk" ],
"x-gaussian-cube" : "cub",
"x-gaussian-input" : [ "gau", "gjc", "gjf" ],
"x-gaussian-log" : "gal",
"x-gcg8-sequence" : "gcg",
"x-genbank" : "gen",
"x-hin" : "hin",
"x-isostar" : [ "istr", "ist" ],
"x-jcamp-dx" : [ "jdx", "dx" ],
"x-kinemage" : "kin",
"x-macmolecule" : "mcm",
"x-macromodel-input" : [ "mmd", "mmod" ],
"x-mdl-molfile" : "mol",
"x-mdl-rdfile" : "rd",
"x-mdl-rxnfile" : "rxn",
"x-mdl-sdfile" : [ "sd", "sdf" ],
"x-mdl-tgf" : "tgf",
"x-mmcif" : "mcif",
"x-mol2" : "mol2",
"x-molconn-Z" : "b",
"x-mopac-graph" : "gpt",
"x-mopac-input" : [ "mop", "mopcrt", "mpc", "zmt" ],
"x-mopac-out" : "moo",
"x-ncbi-asn1" : "asn",
"x-ncbi-asn1-ascii" : [ "prt", "ent" ],
"x-ncbi-asn1-binary" : [ "val", "aso" ],
"x-pdb" : [ "pdb", "ent" ],
"x-rosdal" : "ros",
"x-swissprot" : "sw",
"x-vamas-iso14976" : "vms",
"x-vmd" : "vmd",
"x-xtel" : "xtel",
"x-xyz" : "xyz"
},
"image" : {
"gif" : "gif",
"ief" : "ief",
"jpeg" : [ "jpeg", "jpg", "jpe" ],
"pcx" : "pcx",
"png" : "png",
"svg+xml" : [ "svg", "svgz" ],
"tiff" : [ "tiff", "tif" ],
"vnd.djvu" : [ "djvu", "djv" ],
"vnd.wap.wbmp" : "wbmp",
"x-canon-cr2" : "cr2",
"x-canon-crw" : "crw",
"x-cmu-raster" : "ras",
"x-coreldraw" : "cdr",
"x-coreldrawpattern" : "pat",
"x-coreldrawtemplate" : "cdt",
"x-corelphotopaint" : "cpt",
"x-epson-erf" : "erf",
"x-icon" : "ico",
"x-jg" : "art",
"x-jng" : "jng",
"x-nikon-nef" : "nef",
"x-olympus-orf" : "orf",
"x-photoshop" : "psd",
"x-portable-anymap" : "pnm",
"x-portable-bitmap" : "pbm",
"x-portable-graymap" : "pgm",
"x-portable-pixmap" : "ppm",
"x-rgb" : "rgb",
"x-xbitmap" : "xbm",
"x-xpixmap" : "xpm",
"x-xwindowdump" : "xwd",
"bmp" : "bmp",
"cgm" : "cgm",
"g3fax" : "g3",
"ktx" : "ktx",
"prs.btif" : "btif",
"sgi" : "sgi",
"vnd.dece.graphic" : [ "uvi", "uvvi", "uvg", "uvvg" ],
"vnd.dwg" : "dwg",
"vnd.dxf" : "dxf",
"vnd.fastbidsheet" : "fbs",
"vnd.fpx" : "fpx",
"vnd.fst" : "fst",
"vnd.fujixerox.edmics-mmr" : "mmr",
"vnd.fujixerox.edmics-rlc" : "rlc",
"vnd.ms-modi" : "mdi",
"vnd.ms-photo" : "wdp",
"vnd.net-fpx" : "npx",
"vnd.xiff" : "xif",
"webp" : "webp",
"x-3ds" : "3ds",
"x-cmx" : "cmx",
"x-freehand" : [ "fh", "fhc", "fh4", "fh5", "fh7" ],
"x-pict" : [ "pic", "pct" ],
"x-tga" : "tga",
"cis-cod" : "cod",
"pipeg" : "jfif"
},
"message" : {
"rfc822" : [ "eml", "mime", "mht", "mhtml", "nws" ]
},
"model" : {
"iges" : [ "igs", "iges" ],
"mesh" : [ "msh", "mesh", "silo" ],
"vrml" : [ "wrl", "vrml" ],
"x3d+vrml" : [ "x3dv", "x3dvz" ],
"x3d+xml" : [ "x3d", "x3dz" ],
"x3d+binary" : [ "x3db", "x3dbz" ],
"vnd.collada+xml" : "dae",
"vnd.dwf" : "dwf",
"vnd.gdl" : "gdl",
"vnd.gtw" : "gtw",
"vnd.mts" : "mts",
"vnd.vtu" : "vtu"
},
"text" : {
"cache-manifest" : [ "manifest", "appcache" ],
"calendar" : [ "ics", "icz", "ifb" ],
"css" : "css",
"csv" : "csv",
"h323" : "323",
"html" : [ "html", "htm", "shtml", "stm" ],
"iuls" : "uls",
"mathml" : "mml",
"plain" : [ "txt", "text", "brf", "conf", "def", "list", "log", "in", "bas" ],
"richtext" : "rtx",
"scriptlet" : [ "sct", "wsc" ],
"texmacs" : [ "tm", "ts" ],
"tab-separated-values" : "tsv",
"vnd.sun.j2me.app-descriptor" : "jad",
"vnd.wap.wml" : "wml",
"vnd.wap.wmlscript" : "wmls",
"x-bibtex" : "bib",
"x-boo" : "boo",
"x-c++hdr" : [ "h++", "hpp", "hxx", "hh" ],
"x-c++src" : [ "c++", "cpp", "cxx", "cc" ],
"x-component" : "htc",
"x-dsrc" : "d",
"x-diff" : [ "diff", "patch" ],
"x-haskell" : "hs",
"x-java" : "java",
"x-literate-haskell" : "lhs",
"x-moc" : "moc",
"x-pascal" : [ "p", "pas" ],
"x-pcs-gcd" : "gcd",
"x-perl" : [ "pl", "pm" ],
"x-python" : "py",
"x-scala" : "scala",
"x-setext" : "etx",
"x-tcl" : [ "tcl", "tk" ],
"x-tex" : [ "tex", "ltx", "sty", "cls" ],
"x-vcalendar" : "vcs",
"x-vcard" : "vcf",
"n3" : "n3",
"prs.lines.tag" : "dsc",
"sgml" : [ "sgml", "sgm" ],
"troff" : [ "t", "tr", "roff", "man", "me", "ms" ],
"turtle" : "ttl",
"uri-list" : [ "uri", "uris", "urls" ],
"vcard" : "vcard",
"vnd.curl" : "curl",
"vnd.curl.dcurl" : "dcurl",
"vnd.curl.scurl" : "scurl",
"vnd.curl.mcurl" : "mcurl",
"vnd.dvb.subtitle" : "sub",
"vnd.fly" : "fly",
"vnd.fmi.flexstor" : "flx",
"vnd.graphviz" : "gv",
"vnd.in3d.3dml" : "3dml",
"vnd.in3d.spot" : "spot",
"x-asm" : [ "s", "asm" ],
"x-c" : [ "c", "cc", "cxx", "cpp", "h", "hh", "dic" ],
"x-fortran" : [ "f", "for", "f77", "f90" ],
"x-opml" : "opml",
"x-nfo" : "nfo",
"x-sfv" : "sfv",
"x-uuencode" : "uu",
"webviewhtml" : "htt"
},
"video" : {
"3gpp" : "3gp",
"annodex" : "axv",
"dl" : "dl",
"dv" : [ "dif", "dv" ],
"fli" : "fli",
"gl" : "gl",
"mpeg" : [ "mpeg", "mpg", "mpe", "m1v", "m2v", "mp2", "mpa", "mpv2" ],
"mp4" : [ "mp4", "mp4v", "mpg4" ],
"quicktime" : [ "qt", "mov" ],
"ogg" : "ogv",
"vnd.mpegurl" : [ "mxu", "m4u" ],
"x-flv" : "flv",
"x-la-asf" : [ "lsf", "lsx" ],
"x-mng" : "mng",
"x-ms-asf" : [ "asf", "asx", "asr" ],
"x-ms-wm" : "wm",
"x-ms-wmv" : "wmv",
"x-ms-wmx" : "wmx",
"x-ms-wvx" : "wvx",
"x-msvideo" : "avi",
"x-sgi-movie" : "movie",
"x-matroska" : [ "mpv", "mkv", "mk3d", "mks" ],
"3gpp2" : "3g2",
"h261" : "h261",
"h263" : "h263",
"h264" : "h264",
"jpeg" : "jpgv",
"jpm" : [ "jpm", "jpgm" ],
"mj2" : [ "mj2", "mjp2" ],
"vnd.dece.hd" : [ "uvh", "uvvh" ],
"vnd.dece.mobile" : [ "uvm", "uvvm" ],
"vnd.dece.pd" : [ "uvp", "uvvp" ],
"vnd.dece.sd" : [ "uvs", "uvvs" ],
"vnd.dece.video" : [ "uvv", "uvvv" ],
"vnd.dvb.file" : "dvb",
"vnd.fvt" : "fvt",
"vnd.ms-playready.media.pyv" : "pyv",
"vnd.uvvu.mp4" : [ "uvu", "uvvu" ],
"vnd.vivo" : "viv",
"webm" : "webm",
"x-f4v" : "f4v",
"x-m4v" : "m4v",
"x-ms-vob" : "vob",
"x-smv" : "smv"
},
"x-conference" : {
"x-cooltalk" : "ice"
},
"x-world" : {
"x-vrml" : [ "vrm", "vrml", "wrl", "flr", "wrz", "xaf", "xof" ]
}
};
var mimeTypes = (function() {
var type, subtype, val, index, mimeTypes = {};
for (type in table) {
if (table.hasOwnProperty(type)) {
for (subtype in table[type]) {
if (table[type].hasOwnProperty(subtype)) {
val = table[type][subtype];
if (typeof val == "string") {
mimeTypes[val] = type + "/" + subtype;
} else {
for (index = 0; index < val.length; index++) {
mimeTypes[val[index]] = type + "/" + subtype;
}
}
}
}
}
}
return mimeTypes;
})();
zip.getMimeType = function(filename) {
return mimeTypes[filename.split(".").pop()] || "application/octet-stream";
};
})();

4
epubjs/libs/modernizr-2.6.2.min.js vendored Executable file

File diff suppressed because one or more lines are too long

553
epubjs/libs/zip-fs.js Normal file
View file

@ -0,0 +1,553 @@
/*
Copyright (c) 2012 Gildas Lormeau. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
(function() {
var CHUNK_SIZE = 512 * 1024;
var FileWriter = zip.FileWriter, //
TextWriter = zip.TextWriter, //
BlobWriter = zip.BlobWriter, //
Data64URIWriter = zip.Data64URIWriter, //
Reader = zip.Reader, //
TextReader = zip.TextReader, //
BlobReader = zip.BlobReader, //
Data64URIReader = zip.Data64URIReader, //
HttpRangeReader = zip.HttpRangeReader, //
HttpReader = zip.HttpReader, //
createReader = zip.createReader, //
createWriter = zip.createWriter;
function ZipBlobReader(entry) {
var that = this, blobReader;
function init(callback, onerror) {
this.size = entry.uncompressedSize;
callback();
}
function getData(callback) {
if (that.data)
callback();
else
entry.getData(new BlobWriter(), function(data) {
that.data = data;
blobReader = new BlobReader(data);
callback();
}, null, that.checkCrc32);
}
function readUint8Array(index, length, callback, onerror) {
getData(function() {
blobReader.readUint8Array(index, length, callback, onerror);
}, onerror);
}
that.size = 0;
that.init = init;
that.readUint8Array = readUint8Array;
}
ZipBlobReader.prototype = new Reader();
ZipBlobReader.prototype.constructor = ZipBlobReader;
ZipBlobReader.prototype.checkCrc32 = false;
function getTotalSize(entry) {
var size = 0;
function process(entry) {
size += entry.uncompressedSize || 0;
entry.children.forEach(process);
}
process(entry);
return size;
}
function initReaders(entry, onend, onerror) {
var index = 0;
function next() {
var child = entry.children[index];
index++;
if (index < entry.children.length)
process(entry.children[index]);
else
onend();
}
function process(child) {
if (child.directory)
initReaders(child, next, onerror);
else {
child.reader = new child.Reader(child.data, onerror);
child.reader.init(function() {
child.uncompressedSize = child.reader.size;
next();
});
}
}
if (entry.children.length)
process(entry.children[index]);
else
onend();
}
function detach(entry) {
var children = entry.parent.children;
children.forEach(function(child, index) {
if (child.id == entry.id)
children.splice(index, 1);
});
}
function exportZip(zipWriter, entry, onend, onprogress, totalSize) {
var currentIndex = 0;
function process(zipWriter, entry, onend, onprogress, totalSize) {
var childIndex = 0;
function exportChild() {
var child = entry.children[childIndex];
if (child)
zipWriter.add(child.getFullname(), child.reader, function() {
currentIndex += child.uncompressedSize || 0;
process(zipWriter, child, function() {
childIndex++;
exportChild();
}, onprogress, totalSize);
}, function(index) {
if (onprogress)
onprogress(currentIndex + index, totalSize);
}, {
directory : child.directory,
version : child.zipVersion
});
else
onend();
}
exportChild();
}
process(zipWriter, entry, onend, onprogress, totalSize);
}
function addFileEntry(zipEntry, fileEntry, onend, onerror) {
function getChildren(fileEntry, callback) {
if (fileEntry.isDirectory)
fileEntry.createReader().readEntries(callback);
if (fileEntry.isFile)
callback([]);
}
function process(zipEntry, fileEntry, onend) {
getChildren(fileEntry, function(children) {
var childIndex = 0;
function addChild(child) {
function nextChild(childFileEntry) {
process(childFileEntry, child, function() {
childIndex++;
processChild();
});
}
if (child.isDirectory)
nextChild(zipEntry.addDirectory(child.name));
if (child.isFile)
child.file(function(file) {
var childZipEntry = zipEntry.addBlob(child.name, file);
childZipEntry.uncompressedSize = file.size;
nextChild(childZipEntry);
}, onerror);
}
function processChild() {
var child = children[childIndex];
if (child)
addChild(child);
else
onend();
}
processChild();
});
}
if (fileEntry.isDirectory)
process(zipEntry, fileEntry, onend);
else
fileEntry.file(function(file) {
zipEntry.addBlob(fileEntry.name, file);
onend();
}, onerror);
}
function getFileEntry(fileEntry, entry, onend, onprogress, totalSize, checkCrc32) {
var currentIndex = 0, rootEntry;
function process(fileEntry, entry, onend, onprogress, totalSize) {
var childIndex = 0;
function addChild(child) {
function nextChild(childFileEntry) {
currentIndex += child.uncompressedSize || 0;
process(childFileEntry, child, function() {
childIndex++;
processChild();
}, onprogress, totalSize);
}
if (child.directory)
fileEntry.getDirectory(child.name, {
create : true
}, nextChild, onerror);
else
fileEntry.getFile(child.name, {
create : true
}, function(file) {
child.getData(new FileWriter(file, zip.getMimeType(child.name)), nextChild, function(index, max) {
if (onprogress)
onprogress(currentIndex + index, totalSize);
}, checkCrc32);
}, onerror);
}
function processChild() {
var child = entry.children[childIndex];
if (child)
addChild(child);
else
onend();
}
processChild();
}
if (entry.directory)
process(fileEntry, entry, onend, onprogress, totalSize);
else
entry.getData(new FileWriter(fileEntry, zip.getMimeType(entry.name)), onend, onprogress, checkCrc32);
}
function resetFS(fs) {
fs.entries = [];
fs.root = new ZipDirectoryEntry(fs);
}
function bufferedCopy(reader, writer, onend, onprogress, onerror) {
var chunkIndex = 0;
function stepCopy() {
var index = chunkIndex * CHUNK_SIZE;
if (onprogress)
onprogress(index, reader.size);
if (index < reader.size)
reader.readUint8Array(index, Math.min(CHUNK_SIZE, reader.size - index), function(array) {
writer.writeUint8Array(new Uint8Array(array), function() {
chunkIndex++;
stepCopy();
});
}, onerror);
else
writer.getData(onend);
}
stepCopy();
}
function getEntryData(writer, onend, onprogress, onerror) {
var that = this;
if (!writer || (writer.constructor == that.Writer && that.data))
onend(that.data);
else {
if (!that.reader)
that.reader = new that.Reader(that.data, onerror);
that.reader.init(function() {
writer.init(function() {
bufferedCopy(that.reader, writer, onend, onprogress, onerror);
}, onerror);
});
}
}
function addChild(parent, name, params, directory) {
if (parent.directory)
return directory ? new ZipDirectoryEntry(parent.fs, name, params, parent) : new ZipFileEntry(parent.fs, name, params, parent);
else
throw "Parent entry is not a directory.";
}
function ZipEntry() {
}
ZipEntry.prototype = {
init : function(fs, name, params, parent) {
var that = this;
if (fs.root && parent && parent.getChildByName(name))
throw "Entry filename already exists.";
if (!params)
params = {};
that.fs = fs;
that.name = name;
that.id = fs.entries.length;
that.parent = parent;
that.children = [];
that.zipVersion = params.zipVersion || 0x14;
that.uncompressedSize = 0;
fs.entries.push(that);
if (parent)
that.parent.children.push(that);
},
getFileEntry : function(fileEntry, onend, onprogress, onerror, checkCrc32) {
var that = this;
initReaders(that, function() {
getFileEntry(fileEntry, that, onend, onprogress, getTotalSize(that), checkCrc32);
}, onerror);
},
moveTo : function(target) {
var that = this;
if (target.directory) {
if (!target.isDescendantOf(that)) {
if (that != target) {
if (target.getChildByName(that.name))
throw "Entry filename already exists.";
detach(that);
that.parent = target;
target.children.push(that);
}
} else
throw "Entry is a ancestor of target entry.";
} else
throw "Target entry is not a directory.";
},
getFullname : function() {
var that = this, fullname = that.name, entry = that.parent;
while (entry) {
fullname = (entry.name ? entry.name + "/" : "") + fullname;
entry = entry.parent;
}
return fullname;
},
isDescendantOf : function(ancestor) {
var entry = this.parent;
while (entry && entry.id != ancestor.id)
entry = entry.parent;
return !!entry;
}
};
ZipEntry.prototype.constructor = ZipEntry;
var ZipFileEntryProto;
function ZipFileEntry(fs, name, params, parent) {
var that = this;
ZipEntry.prototype.init.call(that, fs, name, params, parent);
that.Reader = params.Reader;
that.Writer = params.Writer;
that.data = params.data;
that.getData = params.getData || getEntryData;
}
ZipFileEntry.prototype = ZipFileEntryProto = new ZipEntry();
ZipFileEntryProto.constructor = ZipFileEntry;
ZipFileEntryProto.getText = function(onend, onprogress, checkCrc32) {
this.getData(new TextWriter(), onend, onprogress, checkCrc32);
};
ZipFileEntryProto.getBlob = function(mimeType, onend, onprogress, checkCrc32) {
this.getData(new BlobWriter(mimeType), onend, onprogress, checkCrc32);
};
ZipFileEntryProto.getData64URI = function(mimeType, onend, onprogress, checkCrc32) {
this.getData(new Data64URIWriter(mimeType), onend, onprogress, checkCrc32);
};
var ZipDirectoryEntryProto;
function ZipDirectoryEntry(fs, name, params, parent) {
var that = this;
ZipEntry.prototype.init.call(that, fs, name, params, parent);
that.directory = true;
}
ZipDirectoryEntry.prototype = ZipDirectoryEntryProto = new ZipEntry();
ZipDirectoryEntryProto.constructor = ZipDirectoryEntry;
ZipDirectoryEntryProto.addDirectory = function(name) {
return addChild(this, name, null, true);
};
ZipDirectoryEntryProto.addText = function(name, text) {
return addChild(this, name, {
data : text,
Reader : TextReader,
Writer : TextWriter
});
};
ZipDirectoryEntryProto.addBlob = function(name, blob) {
return addChild(this, name, {
data : blob,
Reader : BlobReader,
Writer : BlobWriter
});
};
ZipDirectoryEntryProto.addData64URI = function(name, dataURI) {
return addChild(this, name, {
data : dataURI,
Reader : Data64URIReader,
Writer : Data64URIWriter
});
};
ZipDirectoryEntryProto.addHttpContent = function(name, URL, useRangeHeader) {
return addChild(this, name, {
data : URL,
Reader : useRangeHeader ? HttpRangeReader : HttpReader
});
};
ZipDirectoryEntryProto.addFileEntry = function(fileEntry, onend, onerror) {
addFileEntry(this, fileEntry, onend, onerror);
};
ZipDirectoryEntryProto.addData = function(name, params) {
return addChild(this, name, params);
};
ZipDirectoryEntryProto.importBlob = function(blob, onend, onerror) {
this.importZip(new BlobReader(blob), onend, onerror);
};
ZipDirectoryEntryProto.importText = function(text, onend, onerror) {
this.importZip(new TextReader(text), onend, onerror);
};
ZipDirectoryEntryProto.importData64URI = function(dataURI, onend, onerror) {
this.importZip(new Data64URIReader(dataURI), onend, onerror);
};
ZipDirectoryEntryProto.importHttpContent = function(URL, useRangeHeader, onend, onerror) {
this.importZip(useRangeHeader ? new HttpRangeReader(URL) : new HttpReader(URL), onend, onerror);
};
ZipDirectoryEntryProto.exportBlob = function(onend, onprogress, onerror) {
this.exportZip(new BlobWriter("application/zip"), onend, onprogress, onerror);
};
ZipDirectoryEntryProto.exportText = function(onend, onprogress, onerror) {
this.exportZip(new TextWriter(), onend, onprogress, onerror);
};
ZipDirectoryEntryProto.exportFileEntry = function(fileEntry, onend, onprogress, onerror) {
this.exportZip(new FileWriter(fileEntry, "application/zip"), onend, onprogress, onerror);
};
ZipDirectoryEntryProto.exportData64URI = function(onend, onprogress, onerror) {
this.exportZip(new Data64URIWriter("application/zip"), onend, onprogress, onerror);
};
ZipDirectoryEntryProto.importZip = function(reader, onend, onerror) {
var that = this;
createReader(reader, function(zipReader) {
zipReader.getEntries(function(entries) {
entries.forEach(function(entry) {
var parent = that, path = entry.filename.split("/"), name = path.pop();
path.forEach(function(pathPart) {
parent = parent.getChildByName(pathPart) || new ZipDirectoryEntry(that.fs, pathPart, null, parent);
});
if (!entry.directory)
addChild(parent, name, {
data : entry,
Reader : ZipBlobReader
});
});
onend();
});
}, onerror);
};
ZipDirectoryEntryProto.exportZip = function(writer, onend, onprogress, onerror) {
var that = this;
initReaders(that, function() {
createWriter(writer, function(zipWriter) {
exportZip(zipWriter, that, function() {
zipWriter.close(onend);
}, onprogress, getTotalSize(that));
}, onerror);
}, onerror);
};
ZipDirectoryEntryProto.getChildByName = function(name) {
var childIndex, child, that = this;
for (childIndex = 0; childIndex < that.children.length; childIndex++) {
child = that.children[childIndex];
if (child.name == name)
return child;
}
};
function FS() {
resetFS(this);
}
FS.prototype = {
remove : function(entry) {
detach(entry);
this.entries[entry.id] = null;
},
find : function(fullname) {
var index, path = fullname.split("/"), node = this.root;
for (index = 0; node && index < path.length; index++)
node = node.getChildByName(path[index]);
return node;
},
getById : function(id) {
return this.entries[id];
},
importBlob : function(blob, onend, onerror) {
resetFS(this);
this.root.importBlob(blob, onend, onerror);
},
importText : function(text, onend, onerror) {
resetFS(this);
this.root.importText(text, onend, onerror);
},
importData64URI : function(dataURI, onend, onerror) {
resetFS(this);
this.root.importData64URI(dataURI, onend, onerror);
},
importHttpContent : function(URL, useRangeHeader, onend, onerror) {
resetFS(this);
this.root.importHttpContent(URL, useRangeHeader, onend, onerror);
},
exportBlob : function(onend, onprogress, onerror) {
this.root.exportBlob(onend, onprogress, onerror);
},
exportText : function(onend, onprogress, onerror) {
this.root.exportText(onend, onprogress, onerror);
},
exportFileEntry : function(fileEntry, onend, onprogress, onerror) {
this.root.exportFileEntry(fileEntry, onend, onprogress, onerror);
},
exportData64URI : function(onend, onprogress, onerror) {
this.root.exportData64URI(onend, onprogress, onerror);
}
};
zip.fs = {
FS : FS
};
zip.getMimeType = function() {
return "application/octet-stream";
};
})();

976
epubjs/libs/zip.js Normal file
View file

@ -0,0 +1,976 @@
/*
Copyright (c) 2012 Gildas Lormeau. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
(function(obj) {
var ERR_BAD_FORMAT = "File format is not recognized.";
var ERR_ENCRYPTED = "File contains encrypted entry.";
var ERR_ZIP64 = "File is using Zip64 (4gb+ file size).";
var ERR_READ = "Error while reading zip file.";
var ERR_WRITE = "Error while writing zip file.";
var ERR_WRITE_DATA = "Error while writing file data.";
var ERR_READ_DATA = "Error while reading file data.";
var ERR_DUPLICATED_NAME = "File already exists.";
var ERR_HTTP_RANGE = "HTTP Range not supported.";
var CHUNK_SIZE = 512 * 1024;
var INFLATE_JS = "inflate.js";
var DEFLATE_JS = "deflate.js";
var BlobBuilder = obj.WebKitBlobBuilder || obj.MozBlobBuilder || obj.MSBlobBuilder || obj.BlobBuilder;
var appendABViewSupported;
function isAppendABViewSupported() {
if (typeof appendABViewSupported == "undefined") {
var blobBuilder;
blobBuilder = new BlobBuilder();
blobBuilder.append(getDataHelper(0).view);
appendABViewSupported = blobBuilder.getBlob().size == 0;
}
return appendABViewSupported;
}
function Crc32() {
var crc = -1, that = this;
that.append = function(data) {
var offset, table = that.table;
for (offset = 0; offset < data.length; offset++)
crc = (crc >>> 8) ^ table[(crc ^ data[offset]) & 0xFF];
};
that.get = function() {
return ~crc;
};
}
Crc32.prototype.table = (function() {
var i, j, t, table = [];
for (i = 0; i < 256; i++) {
t = i;
for (j = 0; j < 8; j++)
if (t & 1)
t = (t >>> 1) ^ 0xEDB88320;
else
t = t >>> 1;
table[i] = t;
}
return table;
})();
function blobSlice(blob, index, length) {
if (blob.slice)
return blob.slice(index, index + length);
else if (blob.webkitSlice)
return blob.webkitSlice(index, index + length);
else if (blob.mozSlice)
return blob.mozSlice(index, index + length);
else if (blob.msSlice)
return blob.msSlice(index, index + length);
}
function getDataHelper(byteLength, bytes) {
var dataBuffer, dataArray;
dataBuffer = new ArrayBuffer(byteLength);
dataArray = new Uint8Array(dataBuffer);
if (bytes)
dataArray.set(bytes, 0);
return {
buffer : dataBuffer,
array : dataArray,
view : new DataView(dataBuffer)
};
}
// Readers
function Reader() {
}
function TextReader(text) {
var that = this, blobReader;
function init(callback, onerror) {
var blobBuilder = new BlobBuilder();
blobBuilder.append(text);
blobReader = new BlobReader(blobBuilder.getBlob("text/plain"));
blobReader.init(function() {
that.size = blobReader.size;
callback();
}, onerror);
}
function readUint8Array(index, length, callback, onerror) {
blobReader.readUint8Array(index, length, callback, onerror);
}
that.size = 0;
that.init = init;
that.readUint8Array = readUint8Array;
}
TextReader.prototype = new Reader();
TextReader.prototype.constructor = TextReader;
function Data64URIReader(dataURI) {
var that = this, dataStart;
function init(callback, onerror) {
var dataEnd = dataURI.length;
while (dataURI.charAt(dataEnd - 1) == "=")
dataEnd--;
dataStart = dataURI.indexOf(",") + 1;
that.size = Math.floor((dataEnd - dataStart) * 0.75);
callback();
}
function readUint8Array(index, length, callback, onerror) {
var i, data = getDataHelper(length);
var start = Math.floor(index / 3) * 4;
var end = Math.ceil((index + length) / 3) * 4;
var bytes = obj.atob(dataURI.substring(start + dataStart, end + dataStart));
var delta = index - Math.floor(start / 4) * 3;
for (i = delta; i < delta + length; i++)
data.array[i - delta] = bytes.charCodeAt(i);
callback(data.array);
}
that.size = 0;
that.init = init;
that.readUint8Array = readUint8Array;
}
Data64URIReader.prototype = new Reader();
Data64URIReader.prototype.constructor = Data64URIReader;
function BlobReader(blob) {
var that = this;
function init(callback, onerror) {
this.size = blob.size;
callback();
}
function readUint8Array(index, length, callback, onerror) {
var reader = new FileReader();
reader.onload = function(e) {
callback(new Uint8Array(e.target.result));
};
reader.onerror = onerror;
reader.readAsArrayBuffer(blobSlice(blob, index, length));
}
that.size = 0;
that.init = init;
that.readUint8Array = readUint8Array;
}
BlobReader.prototype = new Reader();
BlobReader.prototype.constructor = BlobReader;
function HttpReader(url) {
var that = this;
function getData(callback, onerror) {
var request;
if (!that.data) {
request = new XMLHttpRequest();
request.addEventListener("load", function() {
if (!that.size)
that.size = Number(request.getResponseHeader("Content-Length"));
that.data = new Uint8Array(request.response);
callback();
}, false);
request.addEventListener("error", onerror, false);
request.open("GET", url);
request.responseType = "arraybuffer";
request.send();
} else
callback();
}
function init(callback, onerror) {
var request = new XMLHttpRequest();
request.addEventListener("load", function() {
that.size = Number(request.getResponseHeader("Content-Length"));
callback();
}, false);
request.addEventListener("error", onerror, false);
request.open("HEAD", url);
request.send();
}
function readUint8Array(index, length, callback, onerror) {
getData(function() {
callback(new Uint8Array(that.data.subarray(index, index + length)));
}, onerror);
}
that.size = 0;
that.init = init;
that.readUint8Array = readUint8Array;
}
HttpReader.prototype = new Reader();
HttpReader.prototype.constructor = HttpReader;
function HttpRangeReader(url) {
var that = this;
function init(callback, onerror) {
var request = new XMLHttpRequest();
request.addEventListener("load", function() {
that.size = Number(request.getResponseHeader("Content-Length"));
if (request.getResponseHeader("Accept-Ranges") == "bytes")
callback();
else
onerror(ERR_HTTP_RANGE);
}, false);
request.addEventListener("error", onerror, false);
request.open("HEAD", url);
request.send();
}
function readArrayBuffer(index, length, callback, onerror) {
var request = new XMLHttpRequest();
request.open("GET", url);
request.responseType = "arraybuffer";
request.setRequestHeader("Range", "bytes=" + index + "-" + (index + length - 1));
request.addEventListener("load", function() {
callback(request.response);
}, false);
request.addEventListener("error", onerror, false);
request.send();
}
function readUint8Array(index, length, callback, onerror) {
readArrayBuffer(index, length, function(arraybuffer) {
callback(new Uint8Array(arraybuffer));
}, onerror);
}
that.size = 0;
that.init = init;
that.readUint8Array = readUint8Array;
}
HttpRangeReader.prototype = new Reader();
HttpRangeReader.prototype.constructor = HttpRangeReader;
// Writers
function Writer() {
}
Writer.prototype.getData = function(callback) {
callback(this.data);
};
function TextWriter() {
var that = this, blobBuilder;
function init(callback, onerror) {
blobBuilder = new BlobBuilder();
callback();
}
function writeUint8Array(array, callback, onerror) {
blobBuilder.append(isAppendABViewSupported() ? array : array.buffer);
callback();
}
function getData(callback) {
var reader = new FileReader();
reader.onload = function(e) {
callback(e.target.result);
};
reader.onerror = onerror;
reader.readAsText(blobBuilder.getBlob("text/plain"));
}
that.init = init;
that.writeUint8Array = writeUint8Array;
that.getData = getData;
}
TextWriter.prototype = new Writer();
TextWriter.prototype.constructor = TextWriter;
function Data64URIWriter(contentType) {
var that = this, data = "", pending = "";
function init(callback, onerror) {
data += "data:" + (contentType || "") + ";base64,";
callback();
}
function writeUint8Array(array, callback, onerror) {
var i, delta = pending.length, dataString = pending;
pending = "";
for (i = 0; i < (Math.floor((delta + array.length) / 3) * 3) - delta; i++)
dataString += String.fromCharCode(array[i]);
for (; i < array.length; i++)
pending += String.fromCharCode(array[i]);
if (dataString.length > 2)
data += obj.btoa(dataString);
else
pending = dataString;
callback();
}
function getData(callback) {
callback(data + obj.btoa(pending));
}
that.init = init;
that.writeUint8Array = writeUint8Array;
that.getData = getData;
}
Data64URIWriter.prototype = new Writer();
Data64URIWriter.prototype.constructor = Data64URIWriter;
function FileWriter(fileEntry, contentType) {
var writer, that = this;
function init(callback, onerror) {
fileEntry.createWriter(function(fileWriter) {
writer = fileWriter;
callback();
}, onerror);
}
function writeUint8Array(array, callback, onerror) {
var blobBuilder = new BlobBuilder();
blobBuilder.append(isAppendABViewSupported() ? array : array.buffer);
writer.onwrite = function() {
writer.onwrite = null;
callback();
};
writer.onerror = onerror;
writer.write(blobBuilder.getBlob(contentType));
}
function getData(callback) {
fileEntry.file(callback);
}
that.init = init;
that.writeUint8Array = writeUint8Array;
that.getData = getData;
}
FileWriter.prototype = new Writer();
FileWriter.prototype.constructor = FileWriter;
function BlobWriter(contentType) {
var blobBuilder, that = this;
function init(callback, onerror) {
blobBuilder = new BlobBuilder();
callback();
}
function writeUint8Array(array, callback, onerror) {
blobBuilder.append(isAppendABViewSupported() ? array : array.buffer);
callback();
}
function getData(callback) {
callback(blobBuilder.getBlob(contentType));
}
that.init = init;
that.writeUint8Array = writeUint8Array;
that.getData = getData;
}
BlobWriter.prototype = new Writer();
BlobWriter.prototype.constructor = BlobWriter;
// inflate/deflate core functions
function launchWorkerProcess(worker, reader, writer, offset, size, onappend, onprogress, onend, onreaderror, onwriteerror) {
var chunkIndex = 0, index, outputSize;
function onflush() {
worker.removeEventListener("message", onmessage, false);
onend(outputSize);
}
function onmessage(event) {
var message = event.data, data = message.data;
if (message.onappend) {
outputSize += data.length;
writer.writeUint8Array(data, function() {
onappend(false, data);
step();
}, onwriteerror);
}
if (message.onflush)
if (data) {
outputSize += data.length;
writer.writeUint8Array(data, function() {
onappend(false, data);
onflush();
}, onwriteerror);
} else
onflush();
if (message.progress && onprogress)
onprogress(index + message.current, size);
}
function step() {
index = chunkIndex * CHUNK_SIZE;
if (index < size)
reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function(array) {
worker.postMessage({
append : true,
data : array
});
chunkIndex++;
if (onprogress)
onprogress(index, size);
onappend(true, array);
}, onreaderror);
else
worker.postMessage({
flush : true
});
}
outputSize = 0;
worker.addEventListener("message", onmessage, false);
step();
}
function launchProcess(process, reader, writer, offset, size, onappend, onprogress, onend, onreaderror, onwriteerror) {
var chunkIndex = 0, index, outputSize = 0;
function step() {
var outputData;
index = chunkIndex * CHUNK_SIZE;
if (index < size)
reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function(inputData) {
var outputData = process.append(inputData, function() {
if (onprogress)
onprogress(offset + index, size);
});
outputSize += outputData.length;
onappend(true, inputData);
writer.writeUint8Array(outputData, function() {
onappend(false, outputData);
chunkIndex++;
setTimeout(step, 1);
}, onwriteerror);
if (onprogress)
onprogress(index, size);
}, onreaderror);
else {
outputData = process.flush();
if (outputData) {
outputSize += outputData.length;
writer.writeUint8Array(outputData, function() {
onappend(false, outputData);
onend(outputSize);
}, onwriteerror);
} else
onend(outputSize);
}
}
step();
}
function inflate(reader, writer, offset, size, computeCrc32, onend, onprogress, onreaderror, onwriteerror) {
var worker, crc32 = new Crc32();
function oninflateappend(sending, array) {
if (computeCrc32 && !sending)
crc32.append(array);
}
function oninflateend(outputSize) {
onend(outputSize, crc32.get());
}
if (obj.zip.useWebWorkers) {
worker = new Worker(obj.zip.workerScriptsPath + INFLATE_JS);
launchWorkerProcess(worker, reader, writer, offset, size, oninflateappend, onprogress, oninflateend, onreaderror, onwriteerror);
} else
launchProcess(new obj.zip.Inflater(), reader, writer, offset, size, oninflateappend, onprogress, oninflateend, onreaderror, onwriteerror);
return worker;
}
function deflate(reader, writer, level, onend, onprogress, onreaderror, onwriteerror) {
var worker, crc32 = new Crc32();
function ondeflateappend(sending, array) {
if (sending)
crc32.append(array);
}
function ondeflateend(outputSize) {
onend(outputSize, crc32.get());
}
function onmessage() {
worker.removeEventListener("message", onmessage, false);
launchWorkerProcess(worker, reader, writer, 0, reader.size, ondeflateappend, onprogress, ondeflateend, onreaderror, onwriteerror);
}
if (obj.zip.useWebWorkers) {
worker = new Worker(obj.zip.workerScriptsPath + DEFLATE_JS);
worker.addEventListener("message", onmessage, false);
worker.postMessage({
init : true,
level : level
});
} else
launchProcess(new obj.zip.Deflater(), reader, writer, 0, reader.size, ondeflateappend, onprogress, ondeflateend, onreaderror, onwriteerror);
return worker;
}
function copy(reader, writer, offset, size, computeCrc32, onend, onprogress, onreaderror, onwriteerror) {
var chunkIndex = 0, crc32 = new Crc32();
function step() {
var index = chunkIndex * CHUNK_SIZE;
if (index < size)
reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function(array) {
if (computeCrc32)
crc32.append(array);
if (onprogress)
onprogress(index, size, array);
writer.writeUint8Array(array, function() {
chunkIndex++;
step();
}, onwriteerror);
}, onreaderror);
else
onend(size, crc32.get());
}
step();
}
// ZipReader
function decodeASCII(str) {
var i, out = "", charCode, extendedASCII = [ '\u00C7', '\u00FC', '\u00E9', '\u00E2', '\u00E4', '\u00E0', '\u00E5', '\u00E7', '\u00EA', '\u00EB',
'\u00E8', '\u00EF', '\u00EE', '\u00EC', '\u00C4', '\u00C5', '\u00C9', '\u00E6', '\u00C6', '\u00F4', '\u00F6', '\u00F2', '\u00FB', '\u00F9',
'\u00FF', '\u00D6', '\u00DC', '\u00F8', '\u00A3', '\u00D8', '\u00D7', '\u0192', '\u00E1', '\u00ED', '\u00F3', '\u00FA', '\u00F1', '\u00D1',
'\u00AA', '\u00BA', '\u00BF', '\u00AE', '\u00AC', '\u00BD', '\u00BC', '\u00A1', '\u00AB', '\u00BB', '_', '_', '_', '\u00A6', '\u00A6',
'\u00C1', '\u00C2', '\u00C0', '\u00A9', '\u00A6', '\u00A6', '+', '+', '\u00A2', '\u00A5', '+', '+', '-', '-', '+', '-', '+', '\u00E3',
'\u00C3', '+', '+', '-', '-', '\u00A6', '-', '+', '\u00A4', '\u00F0', '\u00D0', '\u00CA', '\u00CB', '\u00C8', 'i', '\u00CD', '\u00CE',
'\u00CF', '+', '+', '_', '_', '\u00A6', '\u00CC', '_', '\u00D3', '\u00DF', '\u00D4', '\u00D2', '\u00F5', '\u00D5', '\u00B5', '\u00FE',
'\u00DE', '\u00DA', '\u00DB', '\u00D9', '\u00FD', '\u00DD', '\u00AF', '\u00B4', '\u00AD', '\u00B1', '_', '\u00BE', '\u00B6', '\u00A7',
'\u00F7', '\u00B8', '\u00B0', '\u00A8', '\u00B7', '\u00B9', '\u00B3', '\u00B2', '_', ' ' ];
for (i = 0; i < str.length; i++) {
charCode = str.charCodeAt(i) & 0xFF;
if (charCode > 127)
out += extendedASCII[charCode - 128];
else
out += String.fromCharCode(charCode);
}
return out;
}
function decodeUTF8(str_data) {
var tmp_arr = [], i = 0, ac = 0, c1 = 0, c2 = 0, c3 = 0;
str_data += '';
while (i < str_data.length) {
c1 = str_data.charCodeAt(i);
if (c1 < 128) {
tmp_arr[ac++] = String.fromCharCode(c1);
i++;
} else if (c1 > 191 && c1 < 224) {
c2 = str_data.charCodeAt(i + 1);
tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = str_data.charCodeAt(i + 1);
c3 = str_data.charCodeAt(i + 2);
tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return tmp_arr.join('');
}
function getString(bytes) {
var i, str = "";
for (i = 0; i < bytes.length; i++)
str += String.fromCharCode(bytes[i]);
return str;
}
function getDate(timeRaw) {
var date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & 0x0000ffff;
try {
return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5,
(time & 0x001F) * 2, 0);
} catch (e) {
}
}
function readCommonHeader(entry, data, index, centralDirectory) {
entry.version = data.view.getUint16(index, true);
entry.bitFlag = data.view.getUint16(index + 2, true);
entry.compressionMethod = data.view.getUint16(index + 4, true);
entry.lastModDateRaw = data.view.getUint32(index + 6, true);
entry.lastModDate = getDate(entry.lastModDateRaw);
if ((entry.bitFlag & 0x01) === 0x01) {
onerror(ERR_ENCRYPTED);
return;
}
if (centralDirectory || (entry.bitFlag & 0x0008) != 0x0008) {
entry.crc32 = data.view.getUint32(index + 10, true);
entry.compressedSize = data.view.getUint32(index + 14, true);
entry.uncompressedSize = data.view.getUint32(index + 18, true);
}
if (entry.compressedSize === 0xFFFFFFFF || entry.uncompressedSize === 0xFFFFFFFF) {
onerror(ERR_ZIP64);
return;
}
entry.filenameLength = data.view.getUint16(index + 22, true);
entry.extraFieldLength = data.view.getUint16(index + 24, true);
}
function createZipReader(reader, onerror) {
function Entry() {
}
Entry.prototype.getData = function(writer, onend, onprogress, checkCrc32) {
var that = this, worker;
function terminate(callback, param) {
if (worker)
worker.terminate();
worker = null;
if (callback)
callback(param);
}
function testCrc32(crc32) {
var dataCrc32 = getDataHelper(4);
dataCrc32.view.setUint32(0, crc32);
return that.crc32 == dataCrc32.view.getUint32(0);
}
function getWriterData(uncompressedSize, crc32) {
if (checkCrc32 && !testCrc32(crc32))
onreaderror();
else
writer.getData(function(data) {
terminate(onend, data);
});
}
function onreaderror() {
terminate(onerror, ERR_READ_DATA);
}
function onwriteerror() {
terminate(onerror, ERR_WRITE_DATA);
}
reader.readUint8Array(that.offset, 30, function(bytes) {
var data = getDataHelper(bytes.length, bytes), dataOffset;
if (data.view.getUint32(0) != 0x504b0304) {
onerror(ERR_BAD_FORMAT);
return;
}
readCommonHeader(that, data, 4);
dataOffset = that.offset + 30 + that.filenameLength + that.extraFieldLength;
writer.init(function() {
if (that.compressionMethod === 0)
copy(reader, writer, dataOffset, that.compressedSize, checkCrc32, getWriterData, onprogress, onreaderror, onwriteerror);
else
worker = inflate(reader, writer, dataOffset, that.compressedSize, checkCrc32, getWriterData, onprogress, onreaderror, onwriteerror);
}, onwriteerror);
}, onreaderror);
};
return {
getEntries : function(callback) {
if (reader.size < 22) {
onerror(ERR_BAD_FORMAT);
return;
}
reader.readUint8Array(reader.size - 22, 22, function(bytes) {
var dataView = getDataHelper(bytes.length, bytes).view, datalength, fileslength;
if (dataView.getUint32(0) != 0x504b0506) {
onerror(ERR_BAD_FORMAT);
return;
}
datalength = dataView.getUint32(16, true);
fileslength = dataView.getUint16(8, true);
reader.readUint8Array(datalength, reader.size - datalength, function(bytes) {
var i, index = 0, entries = [], entry, filename, comment, data = getDataHelper(bytes.length, bytes);
for (i = 0; i < fileslength; i++) {
entry = new Entry();
if (data.view.getUint32(index) != 0x504b0102) {
onerror(ERR_BAD_FORMAT);
return;
}
readCommonHeader(entry, data, index + 6, true);
entry.commentLength = data.view.getUint16(index + 32, true);
entry.directory = ((data.view.getUint8(index + 38) & 0x10) == 0x10);
entry.offset = data.view.getUint32(index + 42, true);
filename = getString(data.array.subarray(index + 46, index + 46 + entry.filenameLength));
entry.filename = ((entry.bitFlag & 0x0800) === 0x0800) ? decodeUTF8(filename) : decodeASCII(filename);
if (!entry.directory && entry.filename.charAt(entry.filename.length - 1) == "/")
entry.directory = true;
comment = getString(data.array.subarray(index + 46 + entry.filenameLength + entry.extraFieldLength, index + 46
+ entry.filenameLength + entry.extraFieldLength + entry.commentLength));
entry.comment = ((entry.bitFlag & 0x0800) === 0x0800) ? decodeUTF8(comment) : decodeASCII(comment);
entries.push(entry);
index += 46 + entry.filenameLength + entry.extraFieldLength + entry.commentLength;
}
callback(entries);
}, function() {
onerror(ERR_READ);
});
}, function() {
onerror(ERR_READ);
});
},
close : function(callback) {
if (callback)
callback();
}
};
}
// ZipWriter
function encodeUTF8(string) {
var n, c1, enc, utftext = [], start = 0, end = 0, stringl = string.length;
for (n = 0; n < stringl; n++) {
c1 = string.charCodeAt(n);
enc = null;
if (c1 < 128)
end++;
else if (c1 > 127 && c1 < 2048)
enc = String.fromCharCode((c1 >> 6) | 192) + String.fromCharCode((c1 & 63) | 128);
else
enc = String.fromCharCode((c1 >> 12) | 224) + String.fromCharCode(((c1 >> 6) & 63) | 128) + String.fromCharCode((c1 & 63) | 128);
if (enc != null) {
if (end > start)
utftext += string.slice(start, end);
utftext += enc;
start = end = n + 1;
}
}
if (end > start)
utftext += string.slice(start, stringl);
return utftext;
}
function getBytes(str) {
var i, array = [];
for (i = 0; i < str.length; i++)
array.push(str.charCodeAt(i));
return array;
}
function createZipWriter(writer, onerror, dontDeflate) {
var worker, files = [], filenames = [], datalength = 0;
function terminate(callback, message) {
if (worker)
worker.terminate();
worker = null;
if (callback)
callback(message);
}
function onwriteerror() {
terminate(onerror, ERR_WRITE);
}
function onreaderror() {
terminate(onerror, ERR_READ_DATA);
}
return {
add : function(name, reader, onend, onprogress, options) {
var header, filename, date;
function writeHeader(callback) {
var data;
date = options.lastModDate || new Date();
header = getDataHelper(26);
files[name] = {
headerArray : header.array,
directory : options.directory,
filename : filename,
offset : datalength,
comment : getBytes(encodeUTF8(options.comment || ""))
};
header.view.setUint32(0, 0x14000808);
if (options.version)
header.view.setUint8(0, options.version);
if (!dontDeflate && options.level != 0)
header.view.setUint16(4, 0x0800);
header.view.setUint16(6, (((date.getHours() << 6) | date.getMinutes()) << 5) | date.getSeconds() / 2, true);
header.view.setUint16(8, ((((date.getFullYear() - 1980) << 4) | (date.getMonth() + 1)) << 5) | date.getDate(), true);
header.view.setUint16(22, filename.length, true);
data = getDataHelper(30 + filename.length);
data.view.setUint32(0, 0x504b0304);
data.array.set(header.array, 4);
data.array.set([], 30); // FIXME: remove when chrome 18 will be stable (14: OK, 16: KO, 17: OK)
data.array.set(filename, 30);
datalength += data.array.length;
writer.writeUint8Array(data.array, callback, onwriteerror);
}
function writeFooter(compressedLength, crc32) {
var footer = getDataHelper(16);
datalength += compressedLength || 0;
footer.view.setUint32(0, 0x504b0708);
if (typeof crc32 != "undefined") {
header.view.setUint32(10, crc32, true);
footer.view.setUint32(4, crc32, true);
}
if (reader) {
footer.view.setUint32(8, compressedLength, true);
header.view.setUint32(14, compressedLength, true);
footer.view.setUint32(12, reader.size, true);
header.view.setUint32(18, reader.size, true);
}
writer.writeUint8Array(footer.array, function() {
datalength += 16;
terminate(onend);
}, onwriteerror);
}
function writeFile() {
options = options || {};
name = name.trim();
if (options.directory && name.charAt(name.length - 1) != "/")
name += "/";
if (files[name])
throw ERR_DUPLICATED_NAME;
filename = getBytes(encodeUTF8(name));
filenames.push(name);
writeHeader(function() {
if (reader)
if (dontDeflate || options.level == 0)
copy(reader, writer, 0, reader.size, true, writeFooter, onprogress, onreaderror, onwriteerror);
else
worker = deflate(reader, writer, options.level, writeFooter, onprogress, onreaderror, onwriteerror);
else
writeFooter();
}, onwriteerror);
}
if (reader)
reader.init(writeFile, onreaderror);
else
writeFile();
},
close : function(callback) {
var data, length = 0, index = 0;
filenames.forEach(function(name) {
var file = files[name];
length += 46 + file.filename.length + file.comment.length;
});
data = getDataHelper(length + 22);
filenames.forEach(function(name) {
var file = files[name];
data.view.setUint32(index, 0x504b0102);
data.view.setUint16(index + 4, 0x1400);
data.array.set(file.headerArray, index + 6);
data.view.setUint16(index + 32, file.comment.length, true);
if (file.directory)
data.view.setUint8(index + 38, 0x10);
data.view.setUint32(index + 42, file.offset, true);
data.array.set(file.filename, index + 46);
data.array.set(file.comment, index + 46 + file.filename.length);
index += 46 + file.filename.length + file.comment.length;
});
data.view.setUint32(index, 0x504b0506);
data.view.setUint16(index + 8, filenames.length, true);
data.view.setUint16(index + 10, filenames.length, true);
data.view.setUint32(index + 12, length, true);
data.view.setUint32(index + 16, datalength, true);
writer.writeUint8Array(data.array, function() {
terminate(function() {
writer.getData(callback);
});
}, onwriteerror);
}
};
}
if (typeof BlobBuilder == "undefined") {
BlobBuilder = function() {
var that = this, blobParts;
function initBlobParts() {
if (!blobParts) {
blobParts = [ new Blob() ]
}
}
that.append = function(data) {
initBlobParts();
blobParts.push(data);
};
that.getBlob = function(contentType) {
initBlobParts();
if (blobParts.length > 1 || blobParts[0].type != contentType) {
blobParts = [ contentType ? new Blob(blobParts, {
type : contentType
}) : new Blob(blobParts) ];
}
return blobParts[0];
};
};
}
obj.zip = {
Reader : Reader,
Writer : Writer,
BlobReader : BlobReader,
HttpReader : HttpReader,
HttpRangeReader : HttpRangeReader,
Data64URIReader : Data64URIReader,
TextReader : TextReader,
BlobWriter : BlobWriter,
FileWriter : FileWriter,
Data64URIWriter : Data64URIWriter,
TextWriter : TextWriter,
createReader : function(reader, callback, onerror) {
reader.init(function() {
callback(createZipReader(reader, onerror));
}, onerror);
},
createWriter : function(writer, callback, onerror, dontDeflate) {
writer.init(function() {
callback(createZipWriter(writer, onerror, dontDeflate));
}, onerror);
},
workerScriptsPath : "",
useWebWorkers : true
};
})(this);

380
epubjs/reader/app.js Normal file
View file

@ -0,0 +1,380 @@
var EPUBJSR = EPUBJSR || {};
EPUBJSR.app = {};
EPUBJSR.app.init = (function($){
"use strict";
var Book,
offline = false,
sidebarWidth = 0,
windowWidth;
function init(bookURL){
var search = window.location.search.match(/book=(.*)/),
bookURL = bookURL || (search ? search[1] : "moby-dick");
//-- Setup the browser prefixes
EPUBJS.core.crossBrowserColumnCss();
//-- Set up our sidebar
windowWidth = $(window).width();
if(windowWidth > 550){
$("#main").width(windowWidth-sidebarWidth);
}else{
$("#main").width(windowWidth);
}
loadSettings();
//-- Create a new book object,
// this will create an iframe in the el with the ID provided
Book = new EPUBJS.Book("area");
Book.single = true;
//-- Add listeners to handle book events
//-- Full list of event are at start of book.js
Book.listen("book:metadataReady", meta);
Book.listen("book:tocReady", toc);
Book.listen("book:bookReady", bookReady);
Book.listen("book:chapterReady", chapterChange);
Book.listen("book:online", goOnline);
Book.listen("book:offline", goOffline);
//Book.registerHook("beforeChapterDisplay", EPUBJS.Hooks.transculsions.insert);
//-- Start loading / parsing of the book.
// This must be done AFTER adding listeners or hooks
Book.start(bookURL);
//-- Wait for Dom ready to handle jquery
$(function() {
controls();
});
}
function meta(){
var title = Book.getTitle(),
author = Book.getCreator(),
$title = $("#book-title"),
$author = $("#chapter-title"),
$dash = $("#title-seperator");
document.title = title+" "+author;
$title.html(title);
$author.html(author);
$dash.show();
}
function toc(){
var contents = Book.getTOC(),
$toc = $("#toc"),
$links,
$items;
$toc.empty();
//-- Recursively generate TOC levels
$items = generateTocItems(contents, 1);
$toc.append($items);
$links = $(".toc_link");
$links.on("click", function(e){
var $this = $(this),
url = $this.data("url");
$(".openChapter").removeClass("openChapter");
$this.parents('li').addClass("openChapter");
//-- Provide the Book with the url to show
// The Url must be found in the books manifest
if(!Book.useHash){
Book.show(url);
e.preventDefault();
}
});
}
function loadSettings() {
var userFont = "";
if (!localStorage.getItem("fontSize")) {
userFont = "medium";
localStorage.setItem("fontSize", userFont);
} else {
userFont = localStorage.getItem("fontSize");
}
var $settings = $("#settingsPanel");
$settings.append("<ul></ul>");
var $settingsItem = $("<li><h3></h3></li>");
var $fontSizes = $("<input type='radio' name='fontSize' value='x-small'><span class='xsmall'>Extra Small</span><br>" +
"<input type='radio' name='fontSize' value='small'><span class='small'>Small</span><br>" +
"<input type='radio' name='fontSize' value='medium'><span class='medium'>Medium</span><br>" +
"<input type='radio' name='fontSize' value='large'><span class='large'>Large</span><br>" +
"<input type='radio' name='fontSize' value='x-large'><span class='xlarge'>Extra Large</span>");
$settingsItem.find("h3").text('Font Size').after($fontSizes);
$settings.find("ul").append($settingsItem);
var $fontSizeButtons = $('input[name="fontSize"]');
$fontSizeButtons.each(function() {
if ($(this).attr("value") == userFont) {
$(this).attr("checked", "checked");
}
$(this).on("click", function() {
localStorage.setItem("fontSize", $(this).attr("value"));
//reload the page after selecting a new font
Book.iframe.contentDocument.location.reload(true);
});
});
//Single or double column
var userLayout = "";
if (!localStorage.getItem("layout")) {
userLayout = "medium";
localStorage.setItem("layout", userLayout);
} else {
userLayout = localStorage.getItem("layout");
}
var $settings = $("#settingsPanel");
$settings.append("<ul></ul>");
var $settingsItem = $("<li><h3></h3></li>");
var $layout = $("<input type='radio' name='layout' value='singleColumn'><span class=''>Single Column</span><br>" +
"<input type='radio' name='layout' value='doubleColumn'><span class=''>Double Column</span><br>");
$settingsItem.find("h3").text('Font Size').after($layout);
$settings.find("ul").append($settingsItem);
var $layoutButtons = $('input[name="layout"]');
$layoutButtons.each(function() {
if ($(this).attr("value") == userLayout) {
$(this).attr("checked", "checked");
}
$(this).on("click", function() {
localStorage.setItem("layout", $(this).attr("value"));
//reload the page after selecting a new font
Book.iframe.contentDocument.location.reload(true);
});
});
//LineSpacing
var userLineSpacing = "";
//Contrast
var userContrast = "";
//Font Type
var userFontType = "";
}
function generateTocItems(contents, level){
var $container = $("<ul>");
var type = (level == 1) ? "chapter" : "section";
contents.forEach(function(item){
var $subitems,
$wrapper = $("<li id='toc-"+item.id+"'>"),
$item = $("<a class='toc_link " + type + "' href='#/"+item.href+"' data-url='"+item.href+"'>"+item.label+"</a>");
$wrapper.append($item);
if(item.subitems && item.subitems.length){
level++;
$subitems = generateTocItems(item.subitems, level);
$wrapper.append($subitems);
}
$container.append($wrapper);
});
return $container;
}
function bookReady(){
var $divider = $("#divider"),
$loader = $("#loader");
$loader.hide();
if(!Book.single) {
$divider.addClass("show");
}
}
function goOnline(){
var $icon = $("#store");
offline = false;
$icon.attr("src", "img/save.png");
}
function goOffline(){
var $icon = $("#store");
offline = true;
$icon.attr("src", "img/saved.png");
}
function chapterChange(e) {
var id = e.msg,
$item = $("#toc-"+id),
$current = $(".currentChapter");
if($item.length){
$current.removeClass("currentChapter");
$item.addClass("currentChapter");
}
}
function controls(){
var $next = $("#next"),
$prev = $("#prev"),
$main = $("#main"),
$book = $("#area"),
$sidebar = $("#sidebar"),
$open = $("#open"),
$icon = $open.find("img"),
$network = $("#network"),
$settingLink = $("#setting"),
$settings = $("#settingsPanel"),
$toc = $("#toc"),
$window = $(window);
$window.on("resize", function(){
windowWidth = $(window).width();
if(windowWidth > 550){
$main.width(windowWidth-sidebarWidth);
}else{
$main.width(windowWidth);
}
});
$next.on("click", function(){
Book.nextPage();
});
$prev.on("click", function(){
Book.prevPage();
});
$settingLink.on("click", function() {
if (!$settings.is(":visible")) {
showSettings();
} else {
hideSettings();
}
});
//-- TODO: This doesn't seem to work
$window.bind("touchy-swipe", function(event, phase, $target, data){
if(data.direction = "left"){
Book.nextPage();
}
if(data.direction = "right"){
Book.prevPage();
}
});
var lock = false;
$(document).keydown(function(e){
if(lock) return;
if (e.keyCode == 37) {
$prev.trigger("click");
lock = true;
setTimeout(function(){
lock = false;
}, 100);
return false;
}
if (e.keyCode == 39) {
$next.trigger("click");
lock = true;
setTimeout(function(){
lock = false;
}, 100);
return false;
}
});
function showSidebar(){
//$book.css("pointer-events", "none"); //-- Avoid capture by ifrmae
$sidebar.addClass("open");
$main.addClass("closed");
$icon.attr("src", "img/close.png");
}
function hideSidebar(){
$book.css("pointer-events", "visible");
$sidebar.removeClass("open");
$main.removeClass("closed");
$icon.attr("src", "img/menu-icon.png");
}
function showSettings(){
$toc.hide();
$settings.show();
}
function hideSettings(){
$settings.hide();
$toc.show();
}
$open.on("click", function(){
if($sidebar.hasClass("open")){
hideSidebar();
}else{
showSidebar();
// $open.clickOutside(function(){
// hideSidebar();
// });
}
});
$network.on("click", function(){
offline = !offline;
Book.fromStorage(offline);
});
}
return init;
})(jQuery);

21
epubjs/reader/utils.js Normal file
View file

@ -0,0 +1,21 @@
//-- http://stackoverflow.com/questions/2124684/jquery-how-click-anywhere-outside-of-the-div-the-div-fades-out
jQuery.fn.extend({
// Calls the handler function if the user has clicked outside the object (and not on any of the exceptions)
clickOutside: function(handler, exceptions) {
var $this = this;
jQuery(document).on("click.offer", function(event) {
if (exceptions && jQuery.inArray(event.target, exceptions) > -1) {
return;
} else if (jQuery.contains($this[0], event.target)) {
return;
} else {
jQuery(document).off("click.offer");
handler(event, $this);
}
});
return this;
}
});

6
epubjs/render/base.js Normal file
View file

@ -0,0 +1,6 @@
var EPUBJS = EPUBJS || {};
EPUBJS.VERSION = "0.1.5";
EPUBJS.plugins = EPUBJS.plugins || {};
EPUBJS.filePath = EPUBJS.filePath || "/epubjs/";

755
epubjs/render/book.js Normal file
View file

@ -0,0 +1,755 @@
EPUBJS.Book = function(elem, bookPath){
//-- Takes a string or a element
if (typeof elem == "string") {
this.el = EPUBJS.core.getEl(elem);
} else {
this.el = elem;
}
this.events = new EPUBJS.Events(this, this.el);
//-- All Book events for listening
this.createEvent("book:tocReady");
this.createEvent("book:metadataReady");
this.createEvent("book:spineReady");
this.createEvent("book:bookReady");
this.createEvent("book:chapterReady");
this.createEvent("book:chapterDisplayed");
this.createEvent("book:chapterDestroy");
this.createEvent("book:resized");
this.createEvent("book:stored");
this.createEvent("book:online");
this.createEvent("book:offline");
this.createEvent("book:pageChanged");
//-- All hooks to add functions (with a callback) to
this.hooks = {
"beforeChapterDisplay" : []
};
//-- Get pre-registered hooks
this.getHooks();
this.useHash = true;
this.initialize(this.el);
this.online = navigator.onLine;
this.listeners();
//-- Determine storage method
//-- Override options: none | ram | websqldatabase | indexeddb | filesystem
EPUBJS.storageOverride = "none"
EPUBJS.storage = new fileStorage.storage(EPUBJS.storageOverride);
// BookUrl is optional, but if present start loading process
if(bookPath) {
this.display(bookPath);
}
}
//-- Build up any html needed
EPUBJS.Book.prototype.initialize = function(el){
this.iframe = document.createElement('iframe');
this.iframe.id = "epubjsiframe";
this.resizeIframe(false, this.el.clientWidth, this.el.clientHeight);
this.listen("book:resized", this.resizeIframe, this);
this.el.appendChild(this.iframe);
}
//-- Listeners for browser events
EPUBJS.Book.prototype.listeners = function(){
var that = this;
window.addEventListener("resize", that.onResized.bind(this), false);
window.addEventListener("offline", function(e) {
that.online = false;
that.tell("book:offline");
}, false);
window.addEventListener("online", function(e) {
that.online = true;
that.tell("book:online");
}, false);
window.addEventListener("hashchange", that.route.bind(this), false);
}
//-- Check bookUrl and start parsing book Assets or load them from storage
EPUBJS.Book.prototype.start = function(bookPath){
var location = window.location,
pathname = location.pathname,
absolute = bookPath.search("://") != -1,
fromRoot = pathname[0] == "/",
cleaned = [],
folder = "/",
origin,
split;
if(bookPath[bookPath.length - 1] != "/") bookPath += "/";
//-- Checks if the url is a zip file and unpack
if(this.isContained(bookPath)){
this.bookPath = bookPath;
this.bookUrl = "";
this.contained = true;
this.tell("book:offline");
if(this.online) this.unarchive(bookPath);
return;
}
this.bookPath = bookPath;
//-- Get URL orgin, try for native or combine
origin = location.origin || location.protocol + "//" + location.host;
//-- 1. Check if url is absolute
if(absolute){
this.bookUrl = bookPath;
}
//-- 2. Check if url starts with /, add base url
if(!absolute && fromRoot){
this.bookUrl = origin + "/" + bookPath;
}
//-- 3. Or find full path to url and add that
if(!absolute && !fromRoot){
pathname.split('/').forEach(function(part){
if(part.indexOf(".") == -1){
cleaned.push(part);
}
});
folder = cleaned.join("/") + "/";
this.bookUrl = origin + folder + bookPath;
}
if(!this.isSaved()){
if(!this.online) {
console.error("Not Online");
return;
}
//-- Gets the root of the book and url of the opf
this.parseContainer();
}else{
//-- Events for elements loaded from storage
this.tell("book:tocReady");
this.tell("book:metadataReady");
this.tell("book:spineReady");
//-- Info is saved, start display
this.startDisplay();
}
}
EPUBJS.Book.prototype.unarchive = function(bookPath){
var unzipped;
//-- TODO: make more DRY
if(!this.isSaved()){
unzipped = new EPUBJS.Unarchiver(bookPath, function(){
EPUBJS.storage.get("META-INF/container.xml", function(url){
this.parseContainer(url);
}.bind(this));
}.bind(this));
}else{
//-- Events for elements loaded from storage
this.tell("book:tocReady");
this.tell("book:metadataReady");
this.tell("book:spineReady");
//-- Info is saved, start display
this.startDisplay();
}
}
EPUBJS.Book.prototype.isSaved = function(force) {
//-- If url or version has changed invalidate stored data and reset
if (localStorage.getItem("bookPath") != this.bookPath ||
localStorage.getItem("fpjs-version") != EPUBJS.VERSION ||
force == true) {
localStorage.setItem("fpjs-version", EPUBJS.VERSION);
localStorage.setItem("bookPath", this.bookPath);
localStorage.setItem("stored", 0);
localStorage.setItem("spinePos", 0);
localStorage.setItem("chapterPos", 0);
localStorage.setItem("displayedPages", 0);
this.spinePos = 0;
this.stored = 0;
return false;
}else{
//-- get previous saved positions
this.spinePos = parseInt(localStorage.getItem("spinePos")) || 0;
this.stored = parseInt(localStorage.getItem("stored")) || 0;
//-- get previous saved paths
this.basePath = localStorage.getItem("basePath");
this.contentsPath = localStorage.getItem("contentsPath");
//-- get previous saved content
this.metadata = JSON.parse(localStorage.getItem("metadata"));
this.assets = JSON.parse(localStorage.getItem("assets"));
this.spine = JSON.parse(localStorage.getItem("spine"));
this.spineIndexByURL = JSON.parse(localStorage.getItem("spineIndexByURL"));
this.toc = JSON.parse(localStorage.getItem("toc"));
//-- Get previous page
this.prevChapterPos = parseInt(localStorage.getItem("chapterPos"));
this.prevDisplayedPages = parseInt(localStorage.getItem("displayedPages"));
//-- Check that retrieved object aren't null
if(!this.assets || !this.spine || !this.spineIndexByURL || !this.toc){
this.stored = 0;
return false;
}
return true;
}
}
EPUBJS.Book.prototype.isContained = function(bookUrl){
var tester=/\.[0-9a-z]+$/i,
ext = tester.exec(bookUrl);
if(ext && (ext[0] == ".epub" || ext[0] == ".zip")){
return true;
}
return false;
}
EPUBJS.Book.prototype.onResized = function(){
this.tell("book:resized", {
width: this.el.clientWidth,
height: this.el.clientHeight
});
}
EPUBJS.Book.prototype.resizeIframe = function(e, cWidth, cHeight){
var width, height;
//-- Can be resized by the window resize event, or by passed height
if(!e){
width = cWidth;
height = cHeight;
}else{
width = e.msg.width;
height = e.msg.height;
}
this.iframe.height = height;
if(width % 2 != 0){
width += 1; //-- Prevent cutting off edges of text in columns
}
this.iframe.width = width;
}
EPUBJS.Book.prototype.parseContainer = function(path){
var that = this,
url = path || this.bookUrl + "META-INF/container.xml";
EPUBJS.core.loadXML(url, function(container){
var fullpath;
//-- <rootfile full-path="OPS/package.opf" media-type="application/oebps-package+xml"/>
rootfile = container.querySelector("rootfile");
fullpath = rootfile.getAttribute('full-path').split("/");
if(fullpath[1]){
that.basePath = that.bookUrl + fullpath[0] + "/";
that.contentsPath = that.basePath + fullpath[1];
}else{
that.basePath = that.bookUrl;
that.contentsPath = that.bookUrl + fullpath;
}
if(that.contained){
that.basePath = fullpath[0] + "/";
}
localStorage.setItem("basePath", that.basePath);
localStorage.setItem("contentsPath", that.contentsPath);
//-- Now that we have the path we can parse the contents
//-- TODO: move this and handle errors
if(that.contained){
EPUBJS.storage.get(that.contentsPath, function(url){
that.parseContents(url);
});
}else{
//-- Gets the root of the book and url of the opf
that.parseContents();
}
});
}
EPUBJS.Book.prototype.parseContents = function(path){
var that = this,
url = path || this.contentsPath;
EPUBJS.core.loadXML(url, function(contents){
var metadata = contents.querySelector("metadata"),
manifest = contents.querySelector("manifest"),
spine = contents.querySelector("spine");
that.parseMetadata(metadata);
that.parseManifest(manifest);
that.parseSpine(spine);
that.startDisplay();
});
}
EPUBJS.Book.prototype.parseMetadata = function(metadata){
var that = this,
title = metadata.getElementsByTagNameNS("http://purl.org/dc/elements/1.1/","title")[0]
creator = metadata.getElementsByTagNameNS("http://purl.org/dc/elements/1.1/","creator")[0];
this.metadata = {};
this.metadata["bookTitle"] = title ? title.childNodes[0].nodeValue : "";
this.metadata["creator"] = creator ? creator.childNodes[0].nodeValue : "";
//-- TODO: add more meta data items, such as ISBN
localStorage.setItem("metadata", JSON.stringify(this.metadata));
this.tell("book:metadataReady");
}
EPUBJS.Book.prototype.parseManifest = function(manifest){
var that = this;
this.assets = {};
//-- Turn items into an array
items = Array.prototype.slice.call(manifest.querySelectorAll("item"));
//-- Create an object with the id as key
items.forEach(function(item){
var id = item.getAttribute('id'),
href = item.getAttribute('href');
that.assets[id] = that.basePath + href; //-- Absolute URL for loading with a web worker
//-- Find NCX: media-type="application/x-dtbncx+xml" href="toc.ncx"
if(item.getAttribute('media-type') == "application/x-dtbncx+xml"){
if(that.contained){
EPUBJS.storage.get(that.basePath + href, function(url){
that.parseTOC(url);
});
}else{
that.parseTOC(that.basePath + href);
}
}
});
localStorage.setItem("assets", JSON.stringify(this.assets));
}
EPUBJS.Book.prototype.parseSpine = function(spine){
var that = this;
this.spine = [];
this.spineIndexByID = {}; //-- For quick reference by id and url, might be a better way
this.spineIndexByURL = {};
//-- Turn items into an array
items = Array.prototype.slice.call(spine.getElementsByTagName("itemref"));
//-- Add to array to mantain ordering and cross reference with manifest
items.forEach(function(item, index){
var id = item.getAttribute('idref'),
href = that.assets[id];
that.spine.push({"id": id, "href": href});
that.spineIndexByID[id] = index;
that.spineIndexByURL[href] = index;
});
localStorage.setItem("spine", JSON.stringify(this.spine));
localStorage.setItem("spineIndexByURL", JSON.stringify(this.spineIndexByURL));
this.tell("book:spineReady");
}
EPUBJS.Book.prototype.parseTOC = function(path){
var that = this,
url = path;
this.toc = [];
EPUBJS.core.loadXML(url, function(contents){
var navMap = contents.querySelector("navMap"),
cover = contents.querySelector("meta[name='cover']"),
coverID;
//-- Add cover
if(cover){
coverID = cover.getAttribute("content");
that.toc.push({
"id": coverID,
"href": that.assets[coverID],
"label": coverID
});
}
function getTOC(nodes, parent){
var list = [];
//-- Turn items into an array
items = Array.prototype.slice.call(nodes);
items.forEach(function(item){
var id = item.getAttribute('id'),
content = item.querySelector("content"),
src = content.getAttribute('src'),
split = src.split("#"),
navLabel = item.querySelector("navLabel"),
text = navLabel.textContent ? navLabel.textContent : "",
subitems = item.querySelectorAll("navPoint") || false,
subs = false,
childof = (item.parentNode == parent);
if(!childof) return; //-- Only get direct children, should xpath for this eventually?
if(subitems){
subs = getTOC(subitems, item)
}
list.push({
"id": id,
"href": src,
"label": text,
"subitems" : subs || false
});
});
return list;
}
that.toc = that.toc.concat( getTOC(navMap.querySelectorAll("navPoint"), navMap) );
localStorage.setItem("toc", JSON.stringify(that.toc));
that.tell("book:tocReady");
/*
<navPoint class="chapter" id="xtitlepage" playOrder="1">
<navLabel><text>Moby-Dick</text></navLabel>
<content src="titlepage.xhtml"/>
</navPoint>
*/
});
}
EPUBJS.Book.prototype.destroy = function(){
window.removeEventListener("resize", this.onResized, false);
}
EPUBJS.Book.prototype.getTitle = function(){
return this.metadata.bookTitle;
}
EPUBJS.Book.prototype.getCreator = function(){
return this.metadata.creator;
}
EPUBJS.Book.prototype.chapterTitle = function(){
return this.spine[this.spinePos].id; //-- TODO: clarify that this is returning title
}
EPUBJS.Book.prototype.startDisplay = function(chapter){
var routed,
prevChapter = this.spinePos,
loaded = function(chapter){
//-- If there is a saved page, and the pages haven't changed go to it
if( this.prevChapterPos
&& prevChapter == chapter.pos
&& this.prevDisplayedPages == chapter.displayedPages) {
chapter.page(this.prevChapterPos);
}
//-- If there is network connection, store the books contents
if(this.online && !this.contained){
this.storeOffline();
}
}.bind(this);
this.tell("book:bookReady");
//-- Go to hashed page if present
if(this.useHash){
routed = this.route(false, loaded);
}
if(!this.useHash || !routed){
this.displayChapter(this.spinePos, loaded);
}
}
EPUBJS.Book.prototype.show = function(url, callback){
var split = url.split("#"),
chapter = split[0],
section = split[1] || false,
absoluteURL = (chapter.search("://") == -1) ? this.basePath + chapter : chapter,
spinePos = this.spineIndexByURL[absoluteURL];
//-- If link fragment only stay on current chapter
if(!chapter){
spinePos = this.spinePos;
}
//-- Check that URL is present in the index, or stop
if(typeof(spinePos) != "number") return false;
if(spinePos != this.spinePos || !this.currentChapter){
//-- Load new chapter if different than current
this.displayChapter(spinePos, function(chap){
if(section) chap.section(section);
if(callback) callback(chap);
});
}else{
//-- Only goto section
if(section) this.currentChapter.section(section);
if(callback) callback(this.currentChapter);
}
}
EPUBJS.Book.prototype.displayChapter = function(pos, callback){
var that = this;
if(pos >= this.spine.length){
console.log("Reached End of Book")
return false;
}
if(pos < 0){
console.log("Reached Start of Book")
return false;
}
localStorage.setItem("spinePos", pos);
this.spinePos = pos;
//-- Destroy previous
if(this.currentChapter) {
this.tell("book:chapterDestroy", this.currentChapter.getID());
}
//-- Create a new chapter
this.currentChapter = new EPUBJS.Chapter(this);
this.currentChapter.afterLoaded = function(chapter) {
that.tell("book:chapterReady", chapter.getID());
if(callback){
callback(chapter);
}
}
}
EPUBJS.Book.prototype.nextPage = function(){
var next = this.currentChapter.nextPage();
if(!next){
this.nextChapter();
}
}
EPUBJS.Book.prototype.prevPage = function() {
var prev = this.currentChapter.prevPage();
if(!prev){
this.prevChapter();
}
}
EPUBJS.Book.prototype.nextChapter = function() {
this.spinePos++;
this.displayChapter(this.spinePos);
}
EPUBJS.Book.prototype.prevChapter = function() {
this.spinePos--;
this.displayChapter(this.spinePos, function(chapter){
chapter.goToChapterEnd();
});
}
EPUBJS.Book.prototype.getTOC = function() {
return this.toc;
}
/* TODO: Remove, replace by batch queue
EPUBJS.Book.prototype.preloadNextChapter = function() {
var next = this.spinePos + 1,
path = this.spine[next].href;
file = EPUBJS.storage.preload(path);
}
*/
EPUBJS.Book.prototype.storeOffline = function(callback) {
var assets = EPUBJS.core.toArray(this.assets);
//-- Creates a queue of all items to load
EPUBJS.storage.batch(assets, function(){
this.stored = 1;
localStorage.setItem("stored", 1);
this.tell("book:stored");
if(callback) callback();
}.bind(this));
}
EPUBJS.Book.prototype.availableOffline = function() {
return this.stored > 0 ? true : false;
}
EPUBJS.Book.prototype.fromStorage = function(stored) {
if(this.contained) return;
if(!stored){
this.online = true;
this.tell("book:online");
}else{
if(!this.availableOffline){
//-- If book hasn't been cached yet, store offline
this.storeOffline(function(){
this.online = false;
this.tell("book:offline");
}.bind(this));
}else{
this.online = false;
this.tell("book:offline");
}
}
}
EPUBJS.Book.prototype.route = function(hash, callback){
var location = window.location.hash.replace('#/', '');
if(this.useHash && location.length && location != this.prevLocation){
this.show(location, callback);
this.prevLocation = location;
return true;
}
return false;
}
EPUBJS.Book.prototype.hideHashChanges = function(){
this.useHash = false;
}
//-- Get pre-registered hooks
EPUBJS.Book.prototype.getHooks = function(){
var that = this;
plugTypes = EPUBJS.core.toArray(this.hooks);
plugTypes.forEach(function(plug){
var type = plug.ident;
plugs = EPUBJS.core.toArray(EPUBJS.Hooks[type]);
plugs.forEach(function(hook){
that.registerHook(type, hook);
});
});
}
//-- Hooks allow for injecting async functions that must all complete before continuing
// Functions must have a callback as their first argument.
EPUBJS.Book.prototype.registerHook = function(type, toAdd){
var that = this;
if(typeof(this.hooks[type]) != "undefined"){
if(typeof(toAdd) === "function"){
this.hooks[type].push(toAdd);
}else if(Array.isArray(toAdd)){
toAdd.forEach(function(hook){
that.hooks[type].push(hook);
});
}
}else{
//-- Allows for undefined hooks, but maybe this should error?
this.hooks[type] = [func];
}
}
EPUBJS.Book.prototype.triggerHooks = function(type, callback, passed){
var hooks, count;
if(typeof(this.hooks[type]) == "undefined") return false;
hooks = this.hooks[type];
count = hooks.length;
function countdown(){
count--;
if(count <= 0 && callback) callback();
}
hooks.forEach(function(hook){
hook(countdown, passed);
});
}

337
epubjs/render/chapter.js Normal file
View file

@ -0,0 +1,337 @@
EPUBJS.Chapter = function(book, pos){
this.book = book;
this.iframe = this.book.iframe;
this.pos = pos || this.book.spinePos
this.chapInfo = this.book.spine[this.pos];
//-- Get the url to the book from the spine
this.path = this.chapInfo.href;
this.ID = this.chapInfo.id;
this.chapterPos = 1;
this.leftPos = 0;
localStorage.setItem("chapterPos", this.chapterPos);
this.book.registerHook("beforeChapterDisplay",
[this.replaceLinks.bind(this), this.replaceResources.bind(this)]);
this.load();
return this;
}
EPUBJS.Chapter.prototype.load = function(){
var path = this.path;
if(this.book.online && !this.book.contained){
this.setIframeSrc(path);
}else{
this.loadFromStorage(path);
}
}
EPUBJS.Chapter.prototype.loadFromStorage = function(path){
var file = EPUBJS.storage.get(path, this.setIframeSrc.bind(this));
}
EPUBJS.Chapter.prototype.setIframeSrc = function(url){
var that = this;
this.visible(false);
this.iframe.src = url;
this.iframe.onload = function() {
that.doc = that.iframe.contentDocument;
that.bodyEl = that.doc.body;
that.formatSpread();
//-- Trigger registered hooks before displaying
that.beforeDisplay(function(){
that.calcPages();
that.book.tell("book:chapterDisplayed");
that.visible(true);
});
that.afterLoaded(that);
that.book.listen("book:resized", that.formatSpread, that);
}
}
EPUBJS.Chapter.prototype.afterLoaded = function(chapter){
//-- This is overwritten by the book object
}
EPUBJS.Chapter.prototype.error = function(err){
console.log("error", error)
}
EPUBJS.Chapter.prototype.formatSpread = function(){
var divisor = 2,
cutoff = 800;
if(this.colWidth){
this.OldcolWidth = this.colWidth;
this.OldspreadWidth = this.spreadWidth;
}
//-- Check the width and decied on columns
//-- Todo: a better place for this?
this.elWidth = this.iframe.width;
this.gap = this.gap || Math.ceil(this.elWidth / 8);
if(this.elWidth < cutoff || this.book.single) {
this.spread = false; //-- Single Page
divisor = 1;
this.colWidth = Math.floor(this.elWidth / divisor);
}else{
this.spread = true; //-- Double Page
this.colWidth = Math.floor((this.elWidth - this.gap) / divisor);
/* - Was causing jumps, doesn't seem to be needed anymore
//-- Must be even for firefox
if(this.colWidth % 2 != 0){
this.colWidth -= 1;
}
*/
}
this.spreadWidth = (this.colWidth + this.gap) * divisor;
this.bodyEl.style.fontSize = localStorage.getItem("fontSize") || "medium";
//-- Clear Margins
//this.bodyEl.style.visibility = "hidden";
this.bodyEl.style.margin = "0";
this.bodyEl.style.overflow = "hidden";
this.bodyEl.style.width = this.elWidth;
//-- Adjust height
this.bodyEl.style.height = this.book.el.clientHeight + "px";
//-- Add columns
this.bodyEl.style[EPUBJS.core.columnAxis] = "horizontal";
this.bodyEl.style[EPUBJS.core.columnGap] = this.gap+"px";
this.bodyEl.style[EPUBJS.core.columnWidth] = this.colWidth+"px";
//-- Go to current page after resize
if(this.OldcolWidth){
this.setLeft((this.chapterPos - 1 ) * this.spreadWidth);
}
}
EPUBJS.Chapter.prototype.fixedLayout = function(){
this.paginated = false;
console.log("off")
this.setLeft(0);
this.bodyEl.style.width = this.elWidth;
//-- Adjust height
this.bodyEl.style.height = "auto";
//-- Remove columns
this.bodyEl.style[EPUBJS.core.columnWidth] = "auto";
//-- Scroll
this.bodyEl.style.overflow = "auto";
this.displayedPages = 1;
}
EPUBJS.Chapter.prototype.goToChapterEnd = function(){
this.chapterEnd();
}
EPUBJS.Chapter.prototype.visible = function(bool){
if(typeof(bool) == "undefined") {
return this.iframe.style.visibility;
}
if(bool == true){
this.iframe.style.visibility = "visible";
}else if(bool == false){
this.iframe.style.visibility = "hidden";
}
}
EPUBJS.Chapter.prototype.calcPages = function(){
this.totalWidth = this.iframe.contentDocument.documentElement.scrollWidth; //this.bodyEl.scrollWidth;
this.displayedPages = Math.ceil(this.totalWidth / this.spreadWidth);
localStorage.setItem("displayedPages", this.displayedPages);
//console.log("Pages:", this.displayedPages)
}
EPUBJS.Chapter.prototype.nextPage = function(){
if(this.chapterPos < this.displayedPages){
this.chapterPos++;
this.leftPos += this.spreadWidth;
this.setLeft(this.leftPos);
localStorage.setItem("chapterPos", this.chapterPos);
this.book.tell("book:pageChanged", this.chapterPos);
return this.chapterPos;
}else{
return false;
}
}
EPUBJS.Chapter.prototype.prevPage = function(){
if(this.chapterPos > 1){
this.chapterPos--;
this.leftPos -= this.spreadWidth;
this.setLeft(this.leftPos);
localStorage.setItem("chapterPos", this.chapterPos);
this.book.tell("book:pageChanged", this.chapterPos);
return this.chapterPos;
}else{
return false;
}
}
EPUBJS.Chapter.prototype.chapterEnd = function(){
this.page(this.displayedPages);
}
EPUBJS.Chapter.prototype.setLeft = function(leftPos){
this.bodyEl.style.marginLeft = -leftPos + "px";
/*
var left = "transform: " + (-leftPos) + "px";
//-- Need to stardize this
this.bodyEl.style.webkitTransform = left; //Chrome and Safari
this.bodyEl.style.MozTransform = left; //Firefox
this.bodyEl.style.msTransform = left; //IE
this.bodyEl.style.OTransform = left; //Opera
this.bodyEl.style.transform = left;
*/
}
//-- Replaces the relative links within the book to use our internal page changer
EPUBJS.Chapter.prototype.replaceLinks = function(callback){
var hrefs = this.doc.querySelectorAll('[href]'),
links = Array.prototype.slice.call(hrefs),
that = this;
links.forEach(function(link){
var path,
href = link.getAttribute("href"),
relative = href.search("://"),
fragment = href[0] == "#";
if(relative != -1){
link.setAttribute("target", "_blank");
}else{
link.onclick = function(){
if(that.book.useHash){
window.location.hash = "#/"+href;
}else{
that.book.show(href);
}
}
}
});
if(callback) callback();
}
//-- Replaces assets src's to point to stored version if browser is offline
EPUBJS.Chapter.prototype.replaceResources = function(callback){
var srcs, resources, count;
//-- No need to replace if there is network connectivity
//-- also Filesystem api links are relative, so no need to replace them
if((this.book.online && !this.book.contained) || EPUBJS.storage.getStorageType() == "filesystem") {
if(callback) callback();
return false;
}
srcs = this.doc.querySelectorAll('[src]');
resources = Array.prototype.slice.call(srcs);
count = resources.length;
resources.forEach(function(link){
var src = link.getAttribute("src"),
full = this.book.basePath + src;
EPUBJS.storage.get(full, function(url){
link.setAttribute("src", url);
count--;
if(count <= 0 && callback) callback();
});
}.bind(this));
}
EPUBJS.Chapter.prototype.getID = function(){
return this.ID;
}
EPUBJS.Chapter.prototype.page = function(pg){
if(pg >= 1 && pg <= this.displayedPages){
this.chapterPos = pg;
this.leftPos = this.spreadWidth * (pg-1); //-- pages start at 1
this.setLeft(this.leftPos);
localStorage.setItem("chapterPos", pg);
return true;
}
//-- Return false if page is greater than the total
return false;
}
//-- Find a section by fragement id
EPUBJS.Chapter.prototype.section = function(fragment){
var el = this.doc.getElementById(fragment),
left, pg;
if(el){
left = this.leftPos + el.getBoundingClientRect().left, //-- Calculate left offset compaired to scrolled position
pg = Math.floor(left / this.spreadWidth) + 1; //-- pages start at 1
this.page(pg);
}
}
EPUBJS.Chapter.prototype.beforeDisplay = function(callback){
this.book.triggerHooks("beforeChapterDisplay", callback.bind(this), this);
}

222
epubjs/render/core.js Normal file
View file

@ -0,0 +1,222 @@
var EPUBJS = EPUBJS || {};
EPUBJS.core = {}
//-- Get a element for an id
EPUBJS.core.getEl = function(elem) {
return document.getElementById(elem);
}
//-- Get all elements for a class
EPUBJS.core.getEls = function(classes) {
return document.getElementsByClassName(classes);
}
EPUBJS.core.loadXML = function(url, callback){
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.overrideMimeType('text/xml');
xhr.onload = function(e) {
if (this.status == 200) {
callback(this.responseXML);
}
};
xhr.send();
}
// EPUBJS.core.loadFile = function(url){
// var xhr = new XMLHttpRequest(),
// succeeded,
// failed;
//
// function _loaded(response){
// console.log("response")
// }
//
// function _error(err){
// console.log("Error:", err);
// }
//
// function start(){
// //xhr.open('GET', url, true);
// //xhr.responseType = 'blob';
//
// xhr.onload = function(e) {
// if (this.status == 200) {
// succeeded(this.response);
// }
// };
//
// xhr.onerror = function(e) {
// _error(this.status); //-- TODO: better error message
// };
//
// //xhr.send();
// console.log(succeeded)
// }
//
// return {
// "start": start,
// "loaded" : succeeded,
// "error" : failed
// }
// }
EPUBJS.core.loadFile = function(url, callback){
var xhr = new XMLHttpRequest();
this.succeeded = function(response){
if(callback){
callback(response);
}
}
this.failed = function(err){
console.log("Error:", err);
}
this.start = function(){
var that = this;
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
that.succeeded(this.response);
}
};
xhr.onerror = function(e) {
that.failed(this.status); //-- TODO: better error message
};
xhr.send();
}
return {
"start": this.start,
"succeeded" : this.succeeded,
"failed" : this.failed
}
}
EPUBJS.core.crossBrowserColumnCss = function(){
//-- From Readium: reflowable_pagination_view.js
var cssIfy = function(str) {
return str.replace(/([A-Z])/g, function(str,m1){
return '-' + m1.toLowerCase();
}).replace(/^ms-/,'-ms-');
};
// ask modernizr for the vendor prefixed version
EPUBJS.core.columnAxis = Modernizr.prefixed('columnAxis') || 'columnAxis';
EPUBJS.core.columnGap = Modernizr.prefixed('columnGap') || 'columnGap';
EPUBJS.core.columnWidth = Modernizr.prefixed('columnWidth') || 'columnWidth';
// we are interested in the css prefixed version
// EPUBJS.core.columnAxis = cssIfy(EPUBJS.core.columnAxis);
// EPUBJS.core.columnGap = cssIfy(EPUBJS.core.columnGap);
// EPUBJS.core.columnWidth = cssIfy(EPUBJS.core.columnWidth);
}
EPUBJS.core.toArray = function(obj) {
var arr = [];
for (member in obj) {
var newitm;
if ( obj.hasOwnProperty(member) ) {
newitm = obj[member];
newitm.ident = member;
arr.push(newitm);
}
}
return arr;
};
//-- https://github.com/ebidel/filer.js/blob/master/src/filer.js#L128
EPUBJS.core.dataURLToBlob = function(dataURL) {
var BASE64_MARKER = ';base64,';
if (dataURL.indexOf(BASE64_MARKER) == -1) {
var parts = dataURL.split(',');
var contentType = parts[0].split(':')[1];
var raw = parts[1];
return new Blob([raw], {type: contentType});
}
var parts = dataURL.split(BASE64_MARKER);
var contentType = parts[0].split(':')[1];
var raw = window.atob(parts[1]);
var rawLength = raw.length;
var uInt8Array = new Uint8Array(rawLength);
for (var i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], {type: contentType});
}
//-- Load scripts async: http://stackoverflow.com/questions/7718935/load-scripts-asynchronously
EPUBJS.core.addScript = function(src, callback, target) {
var s, r;
r = false;
s = document.createElement('script');
s.type = 'text/javascript';
s.async = false;
s.src = src;
s.onload = s.onreadystatechange = function() {
//console.log( this.readyState ); //uncomment this line to see which ready states are called.
if ( !r && (!this.readyState || this.readyState == 'complete') )
{
r = true;
if(callback) callback();
}
},
target = target || document.body;
target.appendChild(s);
}
EPUBJS.core.addScripts = function(srcArr, callback, target) {
var total = srcArr.length,
curr = 0,
cb = function(){
curr++;
if(total == curr){
if(callback) callback();
}else{
EPUBJS.core.loadScript(srcArr[curr], cb, target);
}
};
// srcArr.forEach(function(src){
// EPUBJS.core.loadScript(src, cb, target);
// });
EPUBJS.core.addScript(srcArr[curr], cb, target);
}
EPUBJS.core.addCss = function(src, callback, target) {
var s, r;
r = false;
s = document.createElement('link');
s.type = 'text/css';
s.rel = "stylesheet";
s.href = src;
s.onload = s.onreadystatechange = function() {
if ( !r && (!this.readyState || this.readyState == 'complete') )
{
r = true;
if(callback) callback();
}
},
target = target || document.body;
target.appendChild(s);
}

69
epubjs/render/events.js Normal file
View file

@ -0,0 +1,69 @@
EPUBJS.Events = function(obj, el){
this.events = {};
if(!el){
this.el = document.createElement('div');
}else{
this.el = el;
}
obj.createEvent = this.createEvent;
obj.tell = this.tell;
obj.listen = this.listen;
obj.deafen = this.deafen;
obj.listenUntil = this.listenUntil;
return this;
}
EPUBJS.Events.prototype.createEvent = function(evt){
var e = new CustomEvent(evt);
this.events[evt] = e;
return e;
}
EPUBJS.Events.prototype.tell = function(evt, msg){
var e;
if(!this.events[evt]){
console.warn("No event:", evt, "defined yet, creating.");
e = this.createEvent(evt)
}else{
e = this.events[evt];
}
if(msg) e.msg = msg;
this.el.dispatchEvent(e);
}
EPUBJS.Events.prototype.listen = function(evt, func, bindto){
if(!this.events[evt]){
console.warn("No event:", evt, "defined yet, creating.");
this.createEvent(evt);
return;
}
if(bindto){
this.el.addEventListener(evt, func.bind(bindto), false);
}else{
this.el.addEventListener(evt, func, false);
}
}
EPUBJS.Events.prototype.deafen = function(evt, func){
this.el.removeEventListener(evt, func, false);
}
EPUBJS.Events.prototype.listenUntil = function(OnEvt, OffEvt, func, bindto){
this.listen(OnEvt, func, bindto);
function unlisten(){
this.deafen(OnEvt, func);
this.deafen(OffEvt, unlisten);
}
this.listen(OffEvt, unlisten, this);
}

11
epubjs/render/hooks.js Normal file
View file

@ -0,0 +1,11 @@
EPUBJS.Hooks = (function(){
"use strict";
return {
register: function(name) {
if(this[name] === undefined) { this[name] = {}; }
if(typeof this[name] !== 'object') { throw "Already registered: "+name; }
return this[name];
}
};
})();

0
epubjs/render/shims.js Normal file
View file

View file

@ -0,0 +1,77 @@
EPUBJS.Unarchiver = function(url, callback){
this.libPath = EPUBJS.filePath + "libs/";
this.zipUrl = url;
this.callback = callback;
this.loadLib(function(){
this.getZip(this.zipUrl);
}.bind(this));
}
EPUBJS.Unarchiver.prototype.loadLib = function(callback){
if(typeof(zip) != "undefined") callback();
//-- load script
EPUBJS.core.loadScript(this.libPath+"zip.js", function(){
//-- Tell zip where it is located
zip.workerScriptsPath = this.libPath;
callback();
}.bind(this));
}
EPUBJS.Unarchiver.prototype.getZip = function(zipUrl){
var xhr = new EPUBJS.core.loadFile(zipUrl);
xhr.succeeded = function(file) {
this.getEntries(file, this.toStorage.bind(this));
}.bind(this);
xhr.failed = this.failed;
xhr.start();
}
EPUBJS.Unarchiver.prototype.getEntries = function(file, callback){
zip.createReader(new zip.BlobReader(file), function(zipReader) {
zipReader.getEntries(callback);
}, this.failed);
}
EPUBJS.Unarchiver.prototype.failed = function(error){
console.log("Error:", error);
}
EPUBJS.Unarchiver.prototype.afterSaved = function(error){
this.callback();
}
EPUBJS.Unarchiver.prototype.toStorage = function(entries){
var timeout = 0,
delay = 20,
that = this,
count = entries.length;
function callback(){
count--;
if(count == 0) that.afterSaved();
}
entries.forEach(function(entry){
setTimeout(function(entry){
that.saveEntryFileToStorage(entry, callback);
}, timeout, entry);
timeout += delay;
});
console.log("time", timeout);
//entries.forEach(this.saveEntryFileToStorage.bind(this));
}
EPUBJS.Unarchiver.prototype.saveEntryFileToStorage = function(entry, callback){
var that = this;
entry.getData(new zip.BlobWriter(), function(blob) {
EPUBJS.storage.save(entry.filename, blob, callback);
});
}