diff options
Diffstat (limited to 'js')
-rw-r--r-- | js/reader.js | 934 |
1 files changed, 485 insertions, 449 deletions
diff --git a/js/reader.js b/js/reader.js index aa05703..b8549c5 100644 --- a/js/reader.js +++ b/js/reader.js @@ -28,7 +28,7 @@ const Reader = { onOfflineModeChanged: function(offline) { console.log('onOfflineModeChanged', offline); - if (!offline) { + if (!offline && window.book) { const book = window.book; console.log("we're online, storing lastread"); @@ -66,631 +66,666 @@ const Reader = { Reader.applyTheme(); - localforage.getItem(Reader.cacheId("book")).then(function(item) { + return localforage.getItem(Reader.cacheId()).then(function(item) { + if (!item) { + console.log('requesting bookinfo...') - // ios doesn't work with FileReader for whatever reason - if (/*!_is_ios &&*/ item) { + return new Promise((resolve, reject) => { + const bookId = $.urlParam("b"); - console.log("loading from local storage"); + $.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(); + }) + } - const fileReader = new FileReader(); + reject(new Error("unable to load book info: blank")); - fileReader.onload = function() { - try { - book.open(this.result); - } catch (e) { - $(".loading_message").html("Unable to load book (local)."); - console.log(e); - } - }; + }).error(function(xhr) { + $(".loading_message").html("Unable to load book info.<br/><small>" + xhr.status + "</small>"); - fileReader.readAsArrayBuffer(item); + reject(new Error("unable to load book info: " + e)); + }); + }); } else { + console.log('bookinfo already stored'); + } + }).then(function() { - console.log("loading from network"); + console.log('trying to load book...'); - if (App.isOnline()) { - const book_url = "backend.php?op=download&id=" + $.urlParam("id"); + localforage.getItem(Reader.cacheId("book")).then(function(item) { - $(".loading_message").html("Downloading..."); + if (item) { - fetch(book_url, {credentials: 'same-origin'}).then(function(resp) { + console.log("loading from local storage"); - if (resp.status == 200) { - const bookId = $.urlParam("b"); + return new Promise(function (resolve, reject) { - resp.blob().then(function(blob) { + const fileReader = new FileReader(); - // if there's no base information cached yet, let's do that too - localforage.getItem(Reader.cacheId()).then(function(info) { - if (!info) { - $.post("backend.php", {op: "getinfo", id: bookId }, function(data) { - if (data) { - localforage.setItem(Reader.cacheId(), data); + 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); - 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()); - } - }); - } - } - }); - } - }); + reject(new Error("Unable to load book (local):" + e)); + } + }; - const fileReader = new FileReader(); + fileReader.readAsArrayBuffer(item); + }); - fileReader.onload = function() { - book.open(this.result).then(() => { + } else { - // let's store this for later - localforage.setItem(Reader.cacheId('book'), blob); + console.log("loading from network"); - }).catch((e) => { - $(".loading_message").html("Unable to open book.<br/><small>" + e + "</small>"); - }); - }; + if (App.isOnline()) { + const book_url = "backend.php?op=download&id=" + $.urlParam("id"); - fileReader.onerror = function(e) { - console.log('filereader error', e); - $(".loading_message").html("Unable to open book.<br/><small>" + e + "</small>"); - }; + $(".loading_message").html("Downloading..."); - fileReader.readAsArrayBuffer(blob); + return fetch(book_url, {credentials: 'same-origin'}).then(function(resp) { - }).catch((e) => { - console.log('blob error', e); - $(".loading_message").html("Unable to download book.<br/><small>" + e + "</small>"); - }); - } else { - $(".loading_message").html("Unable to download book: " + resp.status + "."); - } - }).catch(function(e) { - console.warn(e); + if (resp.status == 200) { + return resp.blob().then(function(blob) { - if ($(".loading").is(":visible")) { - $(".loading_message").html("Unable to load book (remote).<br/><small>" + e + "</small>"); - } - }); + return new Promise(function(resolve, reject) { - } else { - $(".loading_message").html("This book is not available offline."); - } - } - }); + const fileReader = new FileReader(); - /* global ePub */ - const book = ePub(); - window.book = book; + fileReader.onload = function() { + book.open(this.result).then(function() { - const rendition = book.renderTo("reader", { - width: '100%', - height: '100%', - minSpreadWidth: 961 - }); + // let's store this for later + localforage.setItem(Reader.cacheId('book'), blob).then(function() { + resolve(); + }) - localforage.getItem("epube.enable-hyphens").then(function(enable_hyphens) { - if (enable_hyphens) { - /* global hyphenationPatternsEnUs, createHyphenator */ - Reader.hyphenateHTML = createHyphenator(hyphenationPatternsEnUs, { html: true }); - } - - Reader.applyStyles(true); + }).catch((e) => { + $(".loading_message").html("Unable to open book.<br/><small>" + e + "</small>"); - /* rendition.hooks.content.register(function() { - Reader.applyStyles(); - }); */ + reject(new Error("Unable to open book: " + e)); + }); + }; - rendition.display().then(function() { - console.log("book displayed"); - }); + fileReader.onerror = function(e) { + console.log('filereader error', e); + $(".loading_message").html("Unable to open book.<br/><small>" + e + "</small>"); - }); + reject(new Error("Unable to open book: " + e)); + }; - rendition.hooks.content.register(function(contents) { + fileReader.readAsArrayBuffer(blob); + }); - contents.on("linkClicked", function(href) { - console.log('linkClicked', href); + }).catch((e) => { + console.log('blob error', e); + $(".loading_message").html("Unable to download book.<br/><small>" + e + "</small>"); + }); + } else { + $(".loading_message").html("Unable to download book: " + resp.status + "."); + } + }).catch(function(e) { + console.warn(e); - if (href.indexOf("://") == -1) { - $(".prev_location_btn") - .attr("data-location-cfi", book.rendition.currentLocation().start.cfi) - .show(); + if ($(".loading").is(":visible")) { + $(".loading_message").html("Unable to load book (remote).<br/><small>" + e + "</small>"); + } + }); - window.setTimeout(function() { - Reader.showUI(true); - }, 50); + } else { + $(".loading_message").html("This book is not available offline."); + } } - }); - 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++) { + /* global ePub */ + const book = ePub(); + window.book = book; - // 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]]; + const rendition = book.renderTo("reader", { + width: '100%', + height: '100%', + minSpreadWidth: 961 + }); - doc.head.appendChild(elem); - } + localforage.getItem("epube.enable-hyphens").then(function(enable_hyphens) { + if (enable_hyphens) { + /* global hyphenationPatternsEnUs, createHyphenator */ + Reader.hyphenateHTML = createHyphenator(hyphenationPatternsEnUs, { html: true }); + } - $(contents.document.head) - .append($("<style type='text/css'>") - .text(Reader.Loader._res_data[base_url + 'dist/reader_iframe.min.css'])); + Reader.applyStyles(true); - return localforage.getItem("epube.theme").then(function(theme) { - if (!theme) theme = 'default'; + /* rendition.hooks.content.register(function() { + Reader.applyStyles(); + }); */ - $(contents.document).find("body") - .attr("class", typeof EpubeApp != "undefined" ? "is-epube-app" : "") - .addClass("theme-" + theme); + rendition.display().then(function() { + console.log("book displayed"); + }); }); - }); + rendition.hooks.content.register(function(contents) { - $('#settings-modal').on('shown.bs.modal', function() { + contents.on("linkClicked", function(href) { + console.log('linkClicked', href); - localforage.getItem(Reader.cacheId("lastread")).then((item) => { - if (item && item.cfi) { - $(".lastread_input").val(item.page + '%'); - } + if (href.indexOf("://") == -1) { + $(".prev_location_btn") + .attr("data-location-cfi", book.rendition.currentLocation().start.cfi) + .show(); + + window.setTimeout(function() { + Reader.showUI(true); + }, 50); + } - $.post("backend.php", { op: "getlastread", id: $.urlParam("id") }, function(data) { - $(".lastread_input").val(data.page + '%'); }); - }); + 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; - localforage.getItem("epube.enable-hyphens").then(function(enable) { - $(".enable_hyphens_checkbox") - .attr("checked", enable) - .off("click") - .on("click", function(evt) { - localforage.setItem("epube.enable-hyphens", evt.target.checked); + for (let i = 0; i < res_names.length; i++) { - if (confirm("Toggling hyphens requires page reload. Reload now?")) { - window.location.reload(); - } - }); - }); + // 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]]; - localforage.getItem("epube.keep-ui-visible").then(function(keep) { - $(".keep_ui_checkbox") - .attr("checked", keep) - .off("click") - .on("click", function(evt) { - localforage.setItem("epube.keep-ui-visible", evt.target.checked); - }); - }); + doc.head.appendChild(elem); + } + + $(contents.document.head) + .append($("<style type='text/css'>") + .text(Reader.Loader._res_data[base_url + 'dist/reader_iframe.min.css'])); - localforage.getItem("epube.cache-timestamp").then(function(stamp) { - let msg = "V: "; + return localforage.getItem("epube.theme").then(function(theme) { + if (!theme) theme = 'default'; - if (parseInt(stamp)) - msg += new Date(stamp*1000).toLocaleString("en-GB"); - else - msg += "Unknown"; + $(contents.document).find("body") + .attr("class", typeof EpubeApp != "undefined" ? "is-epube-app" : "") + .addClass("theme-" + theme); - msg += " (" + (App.isOnline() ? "Online" : "Offline") + ")"; + }); - $(".last-mod-timestamp").text(msg) }); - localforage.getItem("epube.fontFamily").then(function(font) { - if (!font) font = DEFAULT_FONT_FAMILY; + $('#settings-modal').on('shown.bs.modal', function() { - $(".font_family").val(font); - }); + localforage.getItem(Reader.cacheId("lastread")).then((item) => { + if (item && item.cfi) { + $(".lastread_input").val(item.page + '%'); + } - localforage.getItem("epube.theme").then(function(theme) { - $(".theme_name").val(theme); - }); + $.post("backend.php", { op: "getlastread", id: $.urlParam("id") }, function(data) { + $(".lastread_input").val(data.page + '%'); + }); - localforage.getItem("epube.fontSize").then(function(size) { + }); - if (!size) size = DEFAULT_FONT_SIZE; + localforage.getItem("epube.enable-hyphens").then(function(enable) { + $(".enable_hyphens_checkbox") + .attr("checked", enable) + .off("click") + .on("click", function(evt) { + localforage.setItem("epube.enable-hyphens", evt.target.checked); - const zoom = $(".font_size").html(""); + if (confirm("Toggling hyphens requires page reload. Reload now?")) { + window.location.reload(); + } + }); + }); - for (let i = 10; i <= 32; i++) { - const opt = $("<option>").val(i).html(i + " px"); - zoom.append(opt); - } + localforage.getItem("epube.keep-ui-visible").then(function(keep) { + $(".keep_ui_checkbox") + .attr("checked", keep) + .off("click") + .on("click", function(evt) { + localforage.setItem("epube.keep-ui-visible", evt.target.checked); + }); + }); - zoom.val(size); + localforage.getItem("epube.cache-timestamp").then(function(stamp) { + let msg = "V: "; - }); + if (parseInt(stamp)) + msg += new Date(stamp*1000).toLocaleString("en-GB"); + else + msg += "Unknown"; - localforage.getItem("epube.lineHeight").then(function(height) { + msg += " (" + (App.isOnline() ? "Online" : "Offline") + ")"; - if (!height) height = DEFAULT_LINE_HEIGHT; + $(".last-mod-timestamp").text(msg) + }); - const zoom = $(".line_height").html(""); + localforage.getItem("epube.fontFamily").then(function(font) { + if (!font) font = DEFAULT_FONT_FAMILY; - for (let i = 100; i <= 220; i += 10) { - const opt = $("<option>").val(i).html(i + "%"); - zoom.append(opt); - } + $(".font_family").val(font); + }); - zoom.val(height); + localforage.getItem("epube.theme").then(function(theme) { + $(".theme_name").val(theme); + }); - }); - }); + localforage.getItem("epube.fontSize").then(function(size) { - $('#dict-modal').on('shown.bs.modal', function() { - $(".dict_result").scrollTop(0); - }); + if (!size) size = DEFAULT_FONT_SIZE; - // TODO: make configurable - $(".dict_search_btn").on("click", function() { - $("#dict-modal").modal('hide'); - window.open("https://duckduckgo.com/?q=" + $(".dict_query").val()); - }); + const zoom = $(".font_size").html(""); - $(".wiki_search_btn").on("click", function() { - $(".dict_result").html("Loading, please wait..."); + for (let i = 10; i <= 32; i++) { + const opt = $("<option>").val(i).html(i + " px"); + zoom.append(opt); + } - $.post("backend.php", {op: "wikisearch", query: $(".dict_query").val()}) - .then((resp) => { - try { - let tmp = ""; + zoom.val(size); - $.each(resp.query.pages, (i,p) => { - tmp += p.extract; - }); + }); - $(".dict_result").html(tmp && tmp != "undefined" ? tmp : "No definition found for " + $(".dict_query").val() + "."); - } catch (e) { - console.error(e); - $(".dict_result").text("Error while processing data: " + e); + localforage.getItem("epube.lineHeight").then(function(height) { + + if (!height) height = DEFAULT_LINE_HEIGHT; + + const zoom = $(".line_height").html(""); + + for (let i = 100; i <= 220; i += 10) { + const opt = $("<option>").val(i).html(i + "%"); + zoom.append(opt); } - }) - .fail((e) => { - console.error(e); - $(".dict_result").text("Error while retrieving data."); - }) - }); - function toc_loc_msg(href) { - try { - const cfiBase = book.spine.get(href).cfiBase; + zoom.val(height); - const loc = book.locations._locations.find(function(k) { - return k.indexOf(cfiBase) != -1 }); + }); - return window.book.locations.locationFromCfi(loc); + $('#dict-modal').on('shown.bs.modal', function() { + $(".dict_result").scrollTop(0); + }); - } catch (e) { - console.warn(e); - } + // TODO: make configurable + $(".dict_search_btn").on("click", function() { + $("#dict-modal").modal('hide'); + window.open("https://duckduckgo.com/?q=" + $(".dict_query").val()); + }); - return ""; - } + $(".wiki_search_btn").on("click", function() { + $(".dict_result").html("Loading, please wait..."); - function process_toc_sublist(row, list, nest) { + $.post("backend.php", {op: "wikisearch", query: $(".dict_query").val()}) + .then((resp) => { + try { + let tmp = ""; - if (nest == 3) return false; + $.each(resp.query.pages, (i,p) => { + tmp += p.extract; + }); - if (row.subitems) { + $(".dict_result").html(tmp && tmp != "undefined" ? tmp : "No definition found for " + $(".dict_query").val() + "."); + } catch (e) { + console.error(e); + $(".dict_result").text("Error while processing data: " + e); + } + }) + .fail((e) => { + console.error(e); + $(".dict_result").text("Error while retrieving data."); + }) + }); - const sublist = $("<ul class='toc_sublist list-unstyled'>"); + function toc_loc_msg(href) { + try { + const cfiBase = book.spine.get(href).cfiBase; - $.each(row.subitems, function(i, row) { + const loc = book.locations._locations.find(function(k) { + return k.indexOf(cfiBase) != -1 + }); - const a = $("<a>") - .attr('href', '#') - .html("<b class='pull-right'>" + toc_loc_msg(row.href) + "</b>" + row.label) - .attr('data-href', row.href) - .click(function() { - book.rendition.display(a.attr('data-href')); - }); + return window.book.locations.locationFromCfi(loc); - sublist.append($("<li>").append(a)); + } catch (e) { + console.warn(e); + } - process_toc_sublist(row, sublist, nest + 1); + return ""; + } - }); + function process_toc_sublist(row, list, nest) { - list.append(sublist); - } - } + if (nest == 3) return false; - $('#toc-modal').on('shown.bs.modal', function() { + if (row.subitems) { - const toc = book.navigation.toc; + const sublist = $("<ul class='toc_sublist list-unstyled'>"); - const list = $(".toc_list"); - list.html(""); + $.each(row.subitems, function(i, row) { - $.each(toc, function(i, row) { + const a = $("<a>") + .attr('href', '#') + .html("<b class='pull-right'>" + toc_loc_msg(row.href) + "</b>" + row.label) + .attr('data-href', row.href) + .click(function() { + book.rendition.display(a.attr('data-href')); + }); - // if anything fails here the toc entry is likely useless anyway (i.e. no cfi) - try { - const a = $("<a>") - .attr('href', '#') - .html("<b class='pull-right'>" + toc_loc_msg(row.href) + "</b>" + row.label) - .attr('data-href', row.href) - .click(function() { - book.rendition.display(a.attr('data-href')); - }); + sublist.append($("<li>").append(a)); - list.append($("<li>").append(a)); + process_toc_sublist(row, sublist, nest + 1); - process_toc_sublist(row, list, 0); + }); - } catch (e) { - console.warn(e); + list.append(sublist); } - }); + } + + $('#toc-modal').on('shown.bs.modal', function() { - // well the toc didn't work out, might as well generate one - if (list.children().length <= 1) { + const toc = book.navigation.toc; + const list = $(".toc_list"); list.html(""); - $.each(book.spine.items, function (i, row) { + $.each(toc, function(i, row) { - const a = $("<a>") - .attr('href', '#') - .attr('title', row.url) - .html("Section " + (i+1)) - .attr('data-href', row.href) - .click(function() { - book.rendition.display(a.attr('data-href')); - }); + // if anything fails here the toc entry is likely useless anyway (i.e. no cfi) + try { + const a = $("<a>") + .attr('href', '#') + .html("<b class='pull-right'>" + toc_loc_msg(row.href) + "</b>" + row.label) + .attr('data-href', row.href) + .click(function() { + book.rendition.display(a.attr('data-href')); + }); - list.append($("<li>").append(a)); + list.append($("<li>").append(a)); - }); - } + process_toc_sublist(row, list, 0); - }); + } catch (e) { + console.warn(e); + } + }); - /* embedded styles may conflict with our font sizes, etc */ - book.spine.hooks.content.register(function(doc/*, section */) { + // well the toc didn't work out, might as well generate one + if (list.children().length <= 1) { - $(doc).find("p") - .filter((i, e) => { if ($(e).text().length >= MIN_LENGTH_TO_JUSTIFY) return e; }) - .css("text-align", "justify"); + list.html(""); - $(doc).find("a, p, span, em, i, strong, b, body, div, big, small") - .attr("class", "") - .css("color", "") - .css("background", "") - .css("background-color", ""); + $.each(book.spine.items, function (i, row) { - if (typeof Reader.hyphenateHTML != "undefined") { - $(doc).find('p').each((i,p) => { - p = $(p); + const a = $("<a>") + .attr('href', '#') + .attr('title', row.url) + .html("Section " + (i+1)) + .attr('data-href', row.href) + .click(function() { + book.rendition.display(a.attr('data-href')); + }); - p.html(Reader.hyphenateHTML(p.html())); - }); - } - }); + list.append($("<li>").append(a)); - book.ready.then(function() { + }); + } - return localforage.getItem(Reader.cacheId()).then((bookinfo) => { + }); - let title; - let author; + /* embedded styles may conflict with our font sizes, etc */ + book.spine.hooks.content.register(function(doc/*, section */) { - if (bookinfo) { - title = bookinfo.title; - author = bookinfo.author_sort; - } else { - const metadata = book.package.metadata; + $(doc).find("p") + .filter((i, e) => { if ($(e).text().length >= MIN_LENGTH_TO_JUSTIFY) return e; }) + .css("text-align", "justify"); - title = metadata.title; - author = metadata.creator; - } + $(doc).find("a, p, span, em, i, strong, b, body, div, big, small") + .attr("class", "") + .css("color", "") + .css("background", "") + .css("background-color", ""); - document.title = title + " – " + author + " – The Epube"; - $(".title") - .text(title) - .attr("title", title + " – " + author); + if (typeof Reader.hyphenateHTML != "undefined") { + $(doc).find('p').each((i,p) => { + p = $(p); - if (typeof EpubeApp != "undefined") { - EpubeApp.setTitle(title); - EpubeApp.showActionBar(false); + p.html(Reader.hyphenateHTML(p.html())); + }); } + }); + + book.ready.then(function() { - return localforage.getItem(Reader.cacheId("locations")).then(function(locations) { + return localforage.getItem(Reader.cacheId()).then((bookinfo) => { - console.log('stored pagination', locations != null); + let title; + let author; - // legacy format is array of objects {cfi: ..., page: ...} - if (locations && typeof locations[0] == "string") { - Reader.Page._pagination_stored = 1; - return book.locations.load(locations); + if (bookinfo) { + title = bookinfo.title; + author = bookinfo.author_sort; } else { - console.log("requesting pagination..."); + const metadata = book.package.metadata; - const url = "backend.php?op=getpagination&id=" + encodeURIComponent($.urlParam("id")); + title = metadata.title; + author = metadata.creator; + } - return fetch(url, {credentials:'same-origin'}).then(function(resp) { + document.title = title + " – " + author + " – The Epube"; + $(".title") + .text(title) + .attr("title", title + " – " + author); - if (resp.ok) { - return resp.json().then(function(locations) { - if (locations && typeof locations[0] == "string") { - Reader.Page._pagination_stored = 1; - return book.locations.load(locations); - } else { - $(".loading_message").html("Paginating..."); - return book.locations.generate(1600); - } - }); - } else { - $(".loading_message").html("Paginating..."); - return book.locations.generate(1600); - } - }).catch(function() { - $(".loading_message").html("Paginating..."); - return book.locations.generate(1600); - }); + if (typeof EpubeApp != "undefined") { + EpubeApp.setTitle(title); + EpubeApp.showActionBar(false); } - }); - }); + return localforage.getItem(Reader.cacheId("locations")).then(function(locations) { - }).then(function(locations) { + console.log('stored pagination', locations != null); - console.log("locations ready, stored=", Reader.Page._pagination_stored); + // legacy format is array of objects {cfi: ..., page: ...} + if (locations && typeof locations[0] == "string") { + Reader.Page._pagination_stored = 1; + return book.locations.load(locations); + } else { + console.log("requesting pagination..."); - if (locations) { - if (App.isOnline() && !Reader.Page._pagination_stored) { - $.post("backend.php", { op: "storepagination", id: $.urlParam("id"), - payload: JSON.stringify(locations), total: 100}); - } + const url = "backend.php?op=getpagination&id=" + encodeURIComponent($.urlParam("id")); + + return fetch(url, {credentials:'same-origin'}).then(function(resp) { + + if (resp.ok) { + return resp.json().then(function(locations) { + if (locations && typeof locations[0] == "string") { + Reader.Page._pagination_stored = 1; + return book.locations.load(locations); + } else { + $(".loading_message").html("Paginating..."); + return book.locations.generate(1600); + } + }); + } else { + $(".loading_message").html("Paginating..."); + return book.locations.generate(1600); + } + }).catch(function() { + $(".loading_message").html("Paginating..."); + return book.locations.generate(1600); + }); + } + }); - // store if needed - localforage.getItem(Reader.cacheId("locations")).then(function(item) { - if (!item) localforage.setItem(Reader.cacheId("locations"), locations); }); - } else { - $(".loading_message").html("Pagination failed."); - return; - } + }).then(function(locations) { - $(".location").click(function() { - const current = book.rendition.currentLocation().start.location; - const total = book.locations.length(); + console.log("locations ready, stored=", Reader.Page._pagination_stored); - const page = prompt("Jump to location [1-" + total + "]", current); + if (locations) { + if (App.isOnline() && !Reader.Page._pagination_stored) { + $.post("backend.php", { op: "storepagination", id: $.urlParam("id"), + payload: JSON.stringify(locations), total: 100}); + } - if (page) { - book.rendition.display(book.locations._locations[page]); + // store if needed + localforage.getItem(Reader.cacheId("locations")).then(function(item) { + if (!item) localforage.setItem(Reader.cacheId("locations"), locations); + }); + + } else { + $(".loading_message").html("Pagination failed."); + return; } - }); - Reader.Page.openLastRead(); - window.setTimeout(function() { + $(".location").click(function() { + const current = book.rendition.currentLocation().start.location; + const total = book.locations.length(); + + const page = prompt("Jump to location [1-" + total + "]", current); + + if (page) { + book.rendition.display(book.locations._locations[page]); + } + }); Reader.Page.openLastRead(); - $(".loading").hide(); - }, 250); - }); + window.setTimeout(function() { + Reader.Page.openLastRead(); - rendition.on("keyup", (e) => { - Reader.hotkeyHandler(e); - }); + $(".loading").hide(); + }, 250); + }); - rendition.on('resized', function() { - console.log('resized'); + rendition.on("keyup", (e) => { + Reader.hotkeyHandler(e); + }); - $(".loading").show(); - $(".loading_message").html("Opening chapter..."); + rendition.on('resized', function() { + console.log('resized'); - window.setTimeout(function() { - Reader.resizeSideColumns(); - Reader.Page.openLastRead(); + $(".loading").show(); + $(".loading_message").html("Opening chapter..."); - $(".loading").hide(); - }, 250); - }); + window.setTimeout(function() { + Reader.resizeSideColumns(); + Reader.Page.openLastRead(); - rendition.on('rendered', function(/*chapter*/) { - $(".chapter").html($("<span>").addClass("glyphicon glyphicon-th-list")); + $(".loading").hide(); + }, 250); + }); - Reader.applyTheme(); + rendition.on('rendered', function(/*chapter*/) { + $(".chapter").html($("<span>").addClass("glyphicon glyphicon-th-list")); - Reader.resizeSideColumns(); + Reader.applyTheme(); - try { - const location = book.rendition.currentLocation(); + Reader.resizeSideColumns(); - if (location.start) { - const cur_href = book.canonical(location.start.href); - let toc_entry = false; + try { + const location = book.rendition.currentLocation(); - $.each(Reader.flattenToc(book), function(i, r) { + if (location.start) { + const cur_href = book.canonical(location.start.href); + let toc_entry = false; - if (book.spine.get(r.href).canonical == cur_href) { - toc_entry = r; - return; - } - }); + $.each(Reader.flattenToc(book), function(i, r) { - if (toc_entry && toc_entry.label) - $(".chapter").append(" " + toc_entry.label.trim() + " | "); + if (book.spine.get(r.href).canonical == cur_href) { + toc_entry = r; + return; + } + }); - Reader.generateTocBar(book, Reader.flattenToc(book)); - } + if (toc_entry && toc_entry.label) + $(".chapter").append(" " + toc_entry.label.trim() + " | "); - } catch (e) { - console.warn(e); - } - }); + Reader.generateTocBar(book, Reader.flattenToc(book)); + } - rendition.on('relocated', function(location) { + } catch (e) { + console.warn(e); + } + }); - // locations not generated yet - if (book.locations.length() == 0) - return; + rendition.on('relocated', function(location) { - const currentCfi = location.start.cfi; - const currentPct = parseInt(book.locations.percentageFromCfi(currentCfi) * 100); + // locations not generated yet + if (book.locations.length() == 0) + return; - $("#cur_page").text(location.start.location); - $("#total_pages").text(book.locations.length()); - $("#page_pct").text(parseInt(book.locations.percentageFromCfi(currentCfi)*100) + '%'); + const currentCfi = location.start.cfi; + const currentPct = parseInt(book.locations.percentageFromCfi(currentCfi) * 100); - Reader.updateTocBarPosition(book, location); + $("#cur_page").text(location.start.location); + $("#total_pages").text(book.locations.length()); + $("#page_pct").text(parseInt(book.locations.percentageFromCfi(currentCfi)*100) + '%'); - const displayed = location.start.displayed; + Reader.updateTocBarPosition(book, location); - if (displayed) { - $("#chapter_cur_page").text(displayed.page); - $("#chapter_total_pages").text(displayed.total); + const displayed = location.start.displayed; - if (displayed.total > 0) - $("#chapter_pct").text(parseInt(displayed.page / displayed.total * 100) + '%') - } + if (displayed) { + $("#chapter_cur_page").text(displayed.page); + $("#chapter_total_pages").text(displayed.total); - if (Reader.Page._store_position) { - Reader.Page._store_position = 0; + if (displayed.total > 0) + $("#chapter_pct").text(parseInt(displayed.page / displayed.total * 100) + '%') + } - const lastread_timestamp = new Date().getTime(); + if (Reader.Page._store_position) { + Reader.Page._store_position = 0; - console.log("storing lastread", currentPct, currentCfi, lastread_timestamp); + const lastread_timestamp = new Date().getTime(); - localforage.setItem(Reader.cacheId("lastread"), - {cfi: currentCfi, page: currentPct, total: 100, timestamp: lastread_timestamp}); + console.log("storing lastread", currentPct, currentCfi, lastread_timestamp); - if (new Date().getTime()/1000 - Reader.Page._last_position_sync > 15) { + localforage.setItem(Reader.cacheId("lastread"), + {cfi: currentCfi, page: currentPct, total: 100, timestamp: lastread_timestamp}); - if (App.isOnline()) { - console.log("updating remote lastread...") + if (new Date().getTime()/1000 - Reader.Page._last_position_sync > 15) { - $.post("backend.php", { op: "storelastread", id: $.urlParam("id"), page: currentPct, - cfi: currentCfi, timestamp: lastread_timestamp }, function(data) { + if (App.isOnline()) { + console.log("updating remote lastread...") - if (data.cfi) { - Reader.Page._last_position_sync = new Date().getTime()/1000; - } + $.post("backend.php", { op: "storelastread", id: $.urlParam("id"), page: currentPct, + cfi: currentCfi, timestamp: lastread_timestamp }, function(data) { - }) - .fail(function(e) { - if (e && e.status == 401) { - window.location = "index.php"; - } - }); + if (data.cfi) { + Reader.Page._last_position_sync = new Date().getTime()/1000; + } - } else { - Reader.Page._last_position_sync = 0; + }) + .fail(function(e) { + if (e && e.status == 401) { + window.location = "index.php"; + } + }); + + } else { + Reader.Page._last_position_sync = 0; + } } } - } + }); + }); }, flattenTocSubItems: function(entry, nest) { @@ -841,13 +876,14 @@ const Reader = { }, 250); } - $.each(window.book.rendition.getContents(), function(i, c) { - console.log('applying rendition theme', theme, 'to', c, c.document); + if (window.book) + $.each(window.book.rendition.getContents(), function(i, c) { + console.log('applying rendition theme', theme, 'to', c, c.document); - $(c.document).find("body") - .attr("class", typeof EpubeApp != "undefined" ? "is-epube-app" : "") - .addClass("theme-" + theme); - }); + $(c.document).find("body") + .attr("class", typeof EpubeApp != "undefined" ? "is-epube-app" : "") + .addClass("theme-" + theme); + }); }); }, |