'use strict';
/* global localforage, EpubeApp, App, Cookie, $ */
const DEFAULT_FONT_SIZE = 16;
const DEFAULT_FONT_FAMILY = "Georgia";
const DEFAULT_LINE_HEIGHT = 140;
const MIN_LENGTH_TO_JUSTIFY = 32; /* characters */
const LOCATION_DIVISOR = 10;
const PAGE_RESET_PROGRESS = -1;
const Reader = {
csrf_token: "",
last_stored_cfi: "",
prevent_lastread_update: false,
hyphenate: {},
init: function() {
this.csrf_token = Cookie.get('epube_csrf_token');
console.log('setting prefilter for token', this.csrf_token);
$.ajaxPrefilter(function(options, originalOptions/*, jqXHR*/) {
if (originalOptions.type !== 'post' || options.type !== 'post') {
return;
}
const datatype = typeof originalOptions.data;
if (datatype == 'object')
options.data = $.param($.extend(originalOptions.data, {"csrf_token": Reader.csrf_token}));
else if (datatype == 'string')
options.data = originalOptions.data + "&csrf_token=" + encodeURIComponent(Reader.srf_token);
console.log('>>>', options);
});
$(document).on("keyup", function(e) {
Reader.hotkeyHandler(e);
});
$("#left").on("mouseup", function() {
Reader.Page.prev();
});
$("#right").on("mouseup", function() {
Reader.Page.next();
});
Reader.Loader.init();
},
onOfflineModeChanged: function(offline) {
console.log('onOfflineModeChanged', offline);
if (!offline && window.book) {
const book = window.book;
console.log("we're online, storing lastread");
const currentCfi = book.rendition.currentLocation().start.cfi;
const currentPage = parseInt(book.locations.percentageFromCfi(currentCfi) * 100);
$.post("backend.php", { op: "storelastread", id: $.urlParam("id"), page: currentPage,
cfi: currentCfi, timestamp: new Date().getTime() }, function() {
//
})
.fail(function(e) {
if (e && e.status == 401) {
window.location = "index.php";
}
});
}
},
initSecondStage: function() {
if (typeof EpubeApp != "undefined") {
EpubeApp.setPage("PAGE_READER");
} else {
$(window).on('online', function() {
Reader.onOfflineModeChanged(false);
});
$(window).on('offline', function() {
Reader.onOfflineModeChanged(true);
});
}
Reader.applyTheme();
return localforage.getItem(Reader.cacheId()).then(function(item) {
if (!item) {
console.log('requesting bookinfo...')
return new Promise((resolve, reject) => {
const bookId = $.urlParam("b");
$.post("backend.php", {op: "getinfo", id: bookId }).success(function(data) {
if (data) {
if (data.has_cover) {
fetch("backend.php?op=cover&id=" + bookId, {credentials: 'same-origin'}).then(function(resp) {
if (resp.status == 200) {
localforage.setItem(Reader.cacheId('cover'), resp.blob());
}
});
}
return localforage.setItem(Reader.cacheId(), data).then(function() {
console.log('bookinfo saved');
resolve();
})
}
reject(new Error("unable to load book info: blank"));
}).error(function(xhr) {
$(".loading-message").html("Unable to load book info.
" + xhr.status + "");
reject(new Error("unable to load book info: " + xhr.status));
});
});
} else {
console.log('bookinfo already stored');
}
}).then(function() {
console.log('trying to load book...');
localforage.getItem(Reader.cacheId("book")).then(function(item) {
if (item) {
console.log("loading from local storage");
return new Promise(function (resolve, reject) {
const fileReader = new FileReader();
fileReader.onload = function() {
try {
return book.open(this.result).then(function() {
resolve();
})
} catch (e) {
$(".loading-message").html("Unable to load book (local).");
console.log(e);
reject(new Error("Unable to load book (local):" + e));
}
};
fileReader.readAsArrayBuffer(item);
});
} else {
console.log("loading from network");
if (App.isOnline()) {
const book_url = "backend.php?op=download&id=" + $.urlParam("id");
$(".loading-message").html("Downloading…");
return fetch(book_url, {credentials: 'same-origin'}).then(function(resp) {
if (resp.status == 200) {
return resp.blob().then(function(blob) {
return new Promise(function(resolve, reject) {
const fileReader = new FileReader();
fileReader.onload = function() {
book.open(this.result).then(function() {
// let's store this for later
localforage.setItem(Reader.cacheId('book'), blob).then(function() {
resolve();
})
}).catch((e) => {
$(".loading-message").html("Unable to open book.
" + e + "");
reject(new Error("Unable to open book: " + e));
});
};
fileReader.onerror = function(e) {
console.log('filereader error', e);
$(".loading-message").html("Unable to open book.
" + e + "");
reject(new Error("Unable to open book: " + e));
};
fileReader.readAsArrayBuffer(blob);
});
}).catch((e) => {
console.log('blob error', e);
$(".loading-message").html("Unable to download book.
" + e + "");
});
} else {
$(".loading-message").html("Unable to download book: " + resp.status + ".");
}
}).catch(function(e) {
console.warn(e);
if ($(".loading").is(":visible")) {
$(".loading-message").html("Unable to load book (remote).
" + e + "");
}
});
} else {
$(".loading-message").html("This book is not available offline.");
}
}
});
/* global ePub */
const book = ePub();
window.book = book;
const rendition = book.renderTo("reader", {
width: '100%',
height: '100%',
minSpreadWidth: 961
});
localforage.getItem("epube.enable-hyphens").then(function(enable_hyphens) {
if (enable_hyphens) {
/* global hyphenationPatternsEnUs, hyphenationPatternsRu, createHyphenator */
Reader.hyphenate.en = createHyphenator(hyphenationPatternsEnUs, { html: true });
Reader.hyphenate.ru = createHyphenator(hyphenationPatternsRu, { html: true });
}
Reader.applyStyles(true);
/* rendition.hooks.content.register(function() {
Reader.applyStyles();
}); */
rendition.display().then(function() {
console.log("book displayed");
});
});
rendition.hooks.content.register(function(contents) {
contents.on("linkClicked", function(href) {
console.log('linkClicked', href);
Reader.prevent_lastread_update = true;
if (href.indexOf("://") == -1) {
$(".prev_location_btn")
.attr("data-location-cfi", book.rendition.currentLocation().start.cfi)
.show();
window.setTimeout(function() {
Reader.showUI(true);
}, 50);
}
});
const base_url = window.location.href.match(/^.*\//)[0];
const res_names = [ "dist/app-libs.min.js", "dist/reader_iframe.min.js" ];
const doc = contents.document;
for (let i = 0; i < res_names.length; i++) {
// we need to create script element with proper context, that is inside the iframe
const elem = doc.createElement("script");
elem.type = 'text/javascript';
elem.text = Reader.Loader._res_data[base_url + res_names[i]];
doc.head.appendChild(elem);
}
$(contents.document.head)
.append($("