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:
parent
bc49465787
commit
9a94f151f9
33 changed files with 24764 additions and 0 deletions
11
epubjs/hooks/embedh.js
Normal file
11
epubjs/hooks/embedh.js
Normal 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
154
epubjs/hooks/endnotes.js
Normal 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();
|
||||||
|
|
||||||
|
}
|
78
epubjs/hooks/extras/annotate.js
Normal file
78
epubjs/hooks/extras/annotate.js
Normal 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
43
epubjs/hooks/extras/example.js
Normal file
43
epubjs/hooks/extras/example.js
Normal 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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
68
epubjs/hooks/extras/music.js
Normal file
68
epubjs/hooks/extras/music.js
Normal 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();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
45
epubjs/hooks/smartimages.js
Normal file
45
epubjs/hooks/smartimages.js
Normal 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();
|
||||||
|
|
||||||
|
}
|
59
epubjs/hooks/transculsions.js
Normal file
59
epubjs/hooks/transculsions.js
Normal 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();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
2759
epubjs/libs/annotator-full-o.js
Normal file
2759
epubjs/libs/annotator-full-o.js
Normal file
File diff suppressed because it is too large
Load diff
2761
epubjs/libs/annotator-full.js
Normal file
2761
epubjs/libs/annotator-full.js
Normal file
File diff suppressed because it is too large
Load diff
11
epubjs/libs/annotator-full.min.js
vendored
Normal file
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
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
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
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
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
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
4
epubjs/libs/jquery-1.9.0.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
511
epubjs/libs/jquery-migrate-1.1.1.js
Normal file
511
epubjs/libs/jquery-migrate-1.1.1.js
Normal 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
20
epubjs/libs/jquery.touchy.min.js
vendored
Executable 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);
|
2
epubjs/libs/loader_filesystem.js
Normal file
2
epubjs/libs/loader_filesystem.js
Normal 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
972
epubjs/libs/mime-types.js
Normal 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
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
553
epubjs/libs/zip-fs.js
Normal 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
976
epubjs/libs/zip.js
Normal 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
380
epubjs/reader/app.js
Normal 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
21
epubjs/reader/utils.js
Normal 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
6
epubjs/render/base.js
Normal 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
755
epubjs/render/book.js
Normal 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
337
epubjs/render/chapter.js
Normal 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
222
epubjs/render/core.js
Normal 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
69
epubjs/render/events.js
Normal 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
11
epubjs/render/hooks.js
Normal 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
0
epubjs/render/shims.js
Normal file
77
epubjs/render/unarchiver.js
Normal file
77
epubjs/render/unarchiver.js
Normal 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);
|
||||||
|
});
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue