diff options
author | Andrew Dolgov <[email protected]> | 2021-01-20 16:50:40 +0300 |
---|---|---|
committer | Andrew Dolgov <[email protected]> | 2021-01-20 16:50:40 +0300 |
commit | ecc201dbf0e2d8674ca2ecf529526e93a1f6e348 (patch) | |
tree | ea2823e3f164e2401a095627cbc74524b6f74a82 | |
parent | 8b815a3b42d08e48c70ec147b9043d7d4fc80bde (diff) |
better promise chain for startup, fix some minor bugs
-rw-r--r-- | dist/app.min.js | 2 | ||||
-rw-r--r-- | js/reader.js | 934 |
2 files changed, 486 insertions, 450 deletions
diff --git a/dist/app.min.js b/dist/app.min.js index 7f26d83..b55cd63 100644 --- a/dist/app.min.js +++ b/dist/app.min.js @@ -1 +1 @@ -"use strict";$.urlParam=function(e){try{const t=new RegExp("[?&]"+e+"=([^&#]*)").exec(window.location.href);return decodeURIComponent(t[1].replace(/\+/g," "))||0}catch(e){return 0}};const Cookie={set:function(e,t,o){const n=new Date;n.setTime(n.getTime()+1e3*o);const a="expires="+n.toUTCString();document.cookie=e+"="+encodeURIComponent(t)+"; "+a},get:function(e){e+="=";const t=document.cookie.split(";");for(let o=0;o<t.length;o++){let n=t[o];for(;" "==n.charAt(0);)n=n.substring(1);if(0==n.indexOf(e))return decodeURIComponent(n.substring(e.length,n.length))}return""},delete:function(e){document.cookie=e+"=; expires=Thu, 01-Jan-1970 00:00:01 GMT"}},App={_dl_progress_timeout:!1,index_mode:"",last_mtime:-1,init:function(){let e=0;"undefined"!=typeof EpubeApp&&($(".navbar").hide(),$(".epube-app-filler").show(),$(".separate-search").show(),"favorites"==$.urlParam("mode")?EpubeApp.setPage("PAGE_FAVORITES"):EpubeApp.setPage("PAGE_LIBRARY")),App.initNightMode(),"serviceWorker"in navigator?navigator.serviceWorker.addEventListener("message",(function(t){"refresh-started"==t.data&&(console.log("cache refresh started"),e=0,$(".dl-progress").fadeIn().text("Loading, please wait...")),t.data&&0==t.data.indexOf("refreshed:")&&(++e,$(".dl-progress").fadeIn().text("Updated "+e+" files...")),"client-reload"==t.data&&(localforage.setItem("epube.cache-timestamp",App.last_mtime),window.location.reload())})):$(".container-main").addClass("alert alert-danger").html("Service worker support missing in browser (are you using plain HTTP?)."),App.showCovers(),App.Offline.markBooks(),App.refreshCache()},showSummary:function(e){const t=e.getAttribute("data-book-id");return $.post("backend.php",{op:"getinfo",id:t},(function(e){const t=e.comment?e.comment:"No description available";$("#summary-modal .modal-title").html(e.title),$("#summary-modal .book-summary").html(t),$("#summary-modal").modal()})),!1},showCovers:function(){$("img[data-book-id]").each((e,t)=>{if((t=$(t)).attr("data-cover-link")){const e=$("<img>").on("load",(function(){t.css("background-image","url("+t.attr("data-cover-link")+")").fadeIn(),e.attr("src",null)})).attr("src",t.attr("data-cover-link"))}else t.attr("src","holder.js/130x190?auto=yes").fadeIn()}),Holder.run()},toggleFavorite:function(e){const t=e.getAttribute("data-book-id");return("0"==e.getAttribute("data-is-fav")||confirm("Remove favorite?"))&&$.post("backend.php",{op:"togglefav",id:t},(function(o){if(o){let n="[Error]";0==o.status?n="Add to favorites":1==o.status&&(n="Remove from favorites"),$(e).html(n).attr("data-is-fav",o.status),"favorites"==App.index_mode&&0==o.status&&$("#cell-"+t).remove()}})),!1},refreshCache:function(e){"serviceWorker"in navigator?localforage.getItem("epube.cache-timestamp").then((function(t){(e||t!=App.last_mtime)&&(console.log("asking worker to refresh cache"),navigator.serviceWorker.controller?navigator.serviceWorker.controller.postMessage("refresh-cache"):localforage.getItem("epube.initial-load-done").then((function(e){console.log("initial load done",e),e?$(".dl-progress").show().addClass("alert-danger").html("Could not communicate with service worker. Try reloading the page."):localforage.setItem("epube.initial-load-done",!0).then((function(){$(".dl-progress").show().addClass("alert-info").html("Page will reload to activate service worker..."),window.setTimeout((function(){window.location.reload()}),3e3)}))})))})):$(".dl-progress").show().addClass("alert-danger").html("Could not communicate with service worker. Try reloading the page.")},isOnline:function(){return"undefined"!=typeof EpubeApp&&void 0!==EpubeApp.isOnline?EpubeApp.isOnline():navigator.onLine},appCheckOffline:function(){EpubeApp.setOffline(!App.isOnline)},initNightMode:function(){if("undefined"==typeof EpubeApp){if(window.matchMedia){const e=window.matchMedia("(prefers-color-scheme: dark)");e.addEventListener("change",()=>{App.applyNightMode(e.matches)}),App.applyNightMode(e.matches)}}else App.applyNightMode(EpubeApp.isNightMode())},applyNightMode:function(e){console.log("night mode changed to",e),$("#theme_css").attr("href","lib/bootstrap/v3/css/"+(e?"theme-dark.min.css":"bootstrap-theme.min.css"))},Offline:{init:function(){"undefined"!=typeof EpubeApp&&($(".navbar").hide(),$(".epube-app-filler").show(),EpubeApp.setPage("PAGE_OFFLINE")),App.initNightMode();const e=$.urlParam("query");e&&$(".search_query").val(e),App.Offline.populateList()},get:function(e,t){console.log("offline cache: "+e),$.post("backend.php",{op:"getinfo",id:e},(function(o){if(o){const n="epube-book."+e;localforage.setItem(n,o).then((function(o){console.log(n+" got data");const a=[];a.push(fetch("backend.php?op=download&id="+o.epub_id,{credentials:"same-origin"}).then((function(e){200==e.status&&(console.log(n+" got book"),t(),localforage.setItem(n+".book",e.blob()))}))),a.push(fetch("backend.php?op=getpagination&id="+o.epub_id,{credentials:"same-origin"}).then((function(e){200==e.status&&(console.log(n+" got pagination"),e.text().then((function(e){localforage.setItem(n+".locations",JSON.parse(e))})))}))),a.push(fetch("backend.php?op=getlastread&id="+o.epub_id,{credentials:"same-origin"}).then((function(e){200==e.status&&(console.log(n+" got lastread"),e.text().then((function(e){localforage.setItem(n+".lastread",JSON.parse(e))})))}))),o.has_cover&&a.push(fetch("backend.php?op=cover&id="+e,{credentials:"same-origin"}).then((function(e){200==e.status&&(console.log(n+" got cover"),localforage.setItem(n+".cover",e.blob()))}))),Promise.all(a).then((function(){$(".dl-progress").show().html("Finished downloading <b>"+o.title+"</b>"),window.clearTimeout(App._dl_progress_timeout),App._dl_progress_timeout=window.setTimeout((function(){$(".dl-progress").fadeOut()}),5e3)}))}))}}))},getAll:function(){confirm("Download all books on this page?")&&$(".row > div").each((function(e,t){const o=$(t).attr("id").replace("cell-",""),n=$(t).find(".offline_dropitem")[0];if(o){const e="epube-book."+o;localforage.getItem(e).then((function(e){e||App.Offline.get(o,(function(){App.Offline.mark(n)}))}))}}))},markBooks:function(){const e=$(".offline_dropitem");$.each(e,(function(e,t){App.Offline.mark(t)}))},mark:function(e){const t=e.getAttribute("data-book-id"),o="epube-book."+t;localforage.getItem(o).then((function(o){o?(e.onclick=function(){return App.Offline.remove(t,(function(){App.Offline.mark(e)})),!1},e.innerHTML="Remove offline data"):(e.onclick=function(){return App.Offline.get(t,(function(){App.Offline.mark(e)})),!1},e.innerHTML="Make available offline")}))},removeFromList:function(e){const t=e.getAttribute("data-book-id");return App.Offline.remove(t,(function(){$("#cell-"+t).remove()}))},remove:function(e,t){if(confirm("Remove download?")){const o="epube-book."+e,n=[];console.log("offline remove: "+e),localforage.iterate((function(e,t){t.match(o)&&n.push(localforage.removeItem(t))})),Promise.all(n).then((function(){window.setTimeout((function(){t()}),500)}))}},search:function(){const e=$(".search_query").val();return localforage.setItem("epube.search-query",e).then((function(){App.Offline.populateList()})),!1},removeAll:function(){if(confirm("Remove all downloaded books?")){const e=[];localforage.iterate((function(t,o){o.match("epube-book")&&e.push(localforage.removeItem(o))})),Promise.all(e).then((function(){window.setTimeout((function(){App.Offline.populateList()}),500)}))}},showSummary:function(e){const t=e.getAttribute("data-book-id");return localforage.getItem("epube-book."+t).then((function(e){const t=e.comment?e.comment:"No description available";$("#summary-modal .modal-title").html(e.title),$("#summary-modal .book-summary").html(t),$("#summary-modal").modal()})),!1},populateList:function(){let e=$.urlParam("query");e&&(e=e.toLowerCase());const t=$("#books_container");t.html(""),localforage.iterate((function(o,n){n.match(/epube-book\.\d{1,}$/)&&Promise.all([localforage.getItem(n),localforage.getItem(n+".cover"),localforage.getItem(n+".lastread"),localforage.getItem(n+".book")]).then((function(o){if(o[0]&&o[3]){const n=o[0];if(e){if(!(n.series_name&&n.series_name.toLowerCase().match(e)||n.title&&n.title.toLowerCase().match(e)||n.author_sort&&n.author_sort.toLowerCase().match(e)))return}let a=!1;o&&o[1]&&(a=URL.createObjectURL(o[1]));let i=!1,r=!1;const l=o[2];l&&(i=l.page>0,r=l.total>0&&l.total-l.page<5);const c=r?"read":"",s=i?"in_progress":"",d=n.series_name?`<div><a class="series_link" href="#">${n.series_name+" ["+n.series_index+"]"}</a></div>`:"",p=$(`<div class="col-xxs-6 col-xs-4 col-sm-3 col-md-2" id="cell-${n.id}">\n\t\t\t\t\t\t\t<a class="thumbnail ${c}" href="read.html?id=${n.epub_id}&b=${n.id}">\n\t\t\t\t\t\t\t\t<img style="display : none">\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t<div class="caption">\n\t\t\t\t\t\t\t\t<div><a class="${s}" href="read.html?id=${n.epub_id}&b=${n.id}">${n.title}</a></div>\n\t\t\t\t\t\t\t\t<div><a class="author_link" href="#">${n.author_sort}</a></div>\n\t\t\t\t\t\t\t\t${d}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class="dropdown" style="white-space : nowrap">\n\t\t\t\t\t\t\t\t<a href="#" data-toggle="dropdown" role="button">More...<span class="caret"></span></a>\n\t\t\t\t\t\t\t\t<ul class="dropdown-menu">\n\t\t\t\t\t\t\t\t\t<li><a href="#" data-book-id="${n.id}" onclick="return App.Offline.showSummary(this)">Summary</a></li>\n\t\t\t\t\t\t\t\t\t<li><a href="#" data-book-id="${n.id}" onclick="App.Offline.removeFromList(this)">Remove offline data</a></li>\n\t\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>`);a?p.find("img").css("background-image","url("+a+")").fadeIn():p.find("img").attr("data-src","holder.js/130x190?auto=yes").fadeIn(),p.find(".series_link").attr("title",n.series_name+" ["+n.series_index+"]").attr("href","offline.html?query="+encodeURIComponent(n.series_name)),p.find(".author_link").attr("title",n.author_sort).attr("href","offline.html?query="+encodeURIComponent(n.author_sort)),t.append(p),Holder.run()}}))}))}}},DEFAULT_FONT_SIZE=16,DEFAULT_FONT_FAMILY="Georgia",DEFAULT_LINE_HEIGHT=140,MIN_LENGTH_TO_JUSTIFY=32,PAGE_RESET_PROGRESS=-1,Reader={init:function(){$(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(e){if(console.log("onOfflineModeChanged",e),!e){const e=window.book;console.log("we're online, storing lastread");const t=e.rendition.currentLocation().start.cfi,o=parseInt(100*e.locations.percentageFromCfi(t));$.post("backend.php",{op:"storelastread",id:$.urlParam("id"),page:o,cfi:t,timestamp:(new Date).getTime()},(function(e){e.cfi&&(Reader.Page._last_position_sync=(new Date).getTime()/1e3)})).fail((function(e){e&&401==e.status&&(window.location="index.php")}))}},initSecondStage:function(){"undefined"!=typeof EpubeApp?EpubeApp.setPage("PAGE_READER"):($(window).on("online",(function(){Reader.onOfflineModeChanged(!1)})),$(window).on("offline",(function(){Reader.onOfflineModeChanged(!0)}))),Reader.applyTheme(),localforage.getItem(Reader.cacheId("book")).then((function(t){if(/*!_is_ios &&*/t){console.log("loading from local storage");const o=new FileReader;o.onload=function(){try{e.open(this.result)}catch(e){$(".loading_message").html("Unable to load book (local)."),console.log(e)}},o.readAsArrayBuffer(t)}else if(console.log("loading from network"),App.isOnline()){const t="backend.php?op=download&id="+$.urlParam("id");$(".loading_message").html("Downloading..."),fetch(t,{credentials:"same-origin"}).then((function(t){if(200==t.status){const o=$.urlParam("b");t.blob().then((function(t){localforage.getItem(Reader.cacheId()).then((function(e){e||$.post("backend.php",{op:"getinfo",id:o},(function(e){e&&(localforage.setItem(Reader.cacheId(),e),e.has_cover&&fetch("backend.php?op=cover&id="+o,{credentials:"same-origin"}).then((function(e){200==e.status&&localforage.setItem(Reader.cacheId("cover"),e.blob())})))}))}));const n=new FileReader;n.onload=function(){e.open(this.result).then(()=>{localforage.setItem(Reader.cacheId("book"),t)}).catch(e=>{$(".loading_message").html("Unable to open book.<br/><small>"+e+"</small>")})},n.onerror=function(e){console.log("filereader error",e),$(".loading_message").html("Unable to open book.<br/><small>"+e+"</small>")},n.readAsArrayBuffer(t)})).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: "+t.status+".")})).catch((function(e){console.warn(e),$(".loading").is(":visible")&&$(".loading_message").html("Unable to load book (remote).<br/><small>"+e+"</small>")}))}else $(".loading_message").html("This book is not available offline.")}));const e=ePub();window.book=e;const t=e.renderTo("reader",{width:"100%",height:"100%",minSpreadWidth:961});function o(t){try{const o=e.spine.get(t).cfiBase,n=e.locations._locations.find((function(e){return-1!=e.indexOf(o)}));return window.book.locations.locationFromCfi(n)}catch(e){console.warn(e)}return""}localforage.getItem("epube.enable-hyphens").then((function(e){e&&(Reader.hyphenateHTML=createHyphenator(hyphenationPatternsEnUs,{html:!0})),Reader.applyStyles(!0),t.display().then((function(){console.log("book displayed")}))})),t.hooks.content.register((function(t){t.on("linkClicked",(function(t){console.log("linkClicked",t),-1==t.indexOf("://")&&($(".prev_location_btn").attr("data-location-cfi",e.rendition.currentLocation().start.cfi).show(),window.setTimeout((function(){Reader.showUI(!0)}),50))}));const o=window.location.href.match(/^.*\//)[0],n=["dist/app-libs.min.js","dist/reader_iframe.min.js"],a=t.document;for(let e=0;e<n.length;e++){const t=a.createElement("script");t.type="text/javascript",t.text=Reader.Loader._res_data[o+n[e]],a.head.appendChild(t)}return $(t.document.head).append($("<style type='text/css'>").text(Reader.Loader._res_data[o+"dist/reader_iframe.min.css"])),localforage.getItem("epube.theme").then((function(e){e||(e="default"),$(t.document).find("body").attr("class","undefined"!=typeof EpubeApp?"is-epube-app":"").addClass("theme-"+e)}))})),$("#settings-modal").on("shown.bs.modal",(function(){localforage.getItem(Reader.cacheId("lastread")).then(e=>{e&&e.cfi&&$(".lastread_input").val(e.page+"%"),$.post("backend.php",{op:"getlastread",id:$.urlParam("id")},(function(e){$(".lastread_input").val(e.page+"%")}))}),localforage.getItem("epube.enable-hyphens").then((function(e){$(".enable_hyphens_checkbox").attr("checked",e).off("click").on("click",(function(e){localforage.setItem("epube.enable-hyphens",e.target.checked),confirm("Toggling hyphens requires page reload. Reload now?")&&window.location.reload()}))})),localforage.getItem("epube.keep-ui-visible").then((function(e){$(".keep_ui_checkbox").attr("checked",e).off("click").on("click",(function(e){localforage.setItem("epube.keep-ui-visible",e.target.checked)}))})),localforage.getItem("epube.cache-timestamp").then((function(e){let t="V: ";parseInt(e)?t+=new Date(1e3*e).toLocaleString("en-GB"):t+="Unknown",t+=" ("+(App.isOnline()?"Online":"Offline")+")",$(".last-mod-timestamp").text(t)})),localforage.getItem("epube.fontFamily").then((function(e){e||(e="Georgia"),$(".font_family").val(e)})),localforage.getItem("epube.theme").then((function(e){$(".theme_name").val(e)})),localforage.getItem("epube.fontSize").then((function(e){e||(e=16);const t=$(".font_size").html("");for(let e=10;e<=32;e++){const o=$("<option>").val(e).html(e+" px");t.append(o)}t.val(e)})),localforage.getItem("epube.lineHeight").then((function(e){e||(e=140);const t=$(".line_height").html("");for(let e=100;e<=220;e+=10){const o=$("<option>").val(e).html(e+"%");t.append(o)}t.val(e)}))})),$("#dict-modal").on("shown.bs.modal",(function(){$(".dict_result").scrollTop(0)})),$(".dict_search_btn").on("click",(function(){$("#dict-modal").modal("hide"),window.open("https://duckduckgo.com/?q="+$(".dict_query").val())})),$(".wiki_search_btn").on("click",(function(){$(".dict_result").html("Loading, please wait..."),$.post("backend.php",{op:"wikisearch",query:$(".dict_query").val()}).then(e=>{try{let t="";$.each(e.query.pages,(e,o)=>{t+=o.extract}),$(".dict_result").html(t&&"undefined"!=t?t:"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.")})})),$("#toc-modal").on("shown.bs.modal",(function(){const t=e.navigation.toc,n=$(".toc_list");n.html(""),$.each(t,(function(t,a){try{const t=$("<a>").attr("href","#").html("<b class='pull-right'>"+o(a.href)+"</b>"+a.label).attr("data-href",a.href).click((function(){e.rendition.display(t.attr("data-href"))}));n.append($("<li>").append(t)),function t(n,a,i){if(3==i)return!1;if(n.subitems){const r=$("<ul class='toc_sublist list-unstyled'>");$.each(n.subitems,(function(n,a){const l=$("<a>").attr("href","#").html("<b class='pull-right'>"+o(a.href)+"</b>"+a.label).attr("data-href",a.href).click((function(){e.rendition.display(l.attr("data-href"))}));r.append($("<li>").append(l)),t(a,r,i+1)})),a.append(r)}}(a,n,0)}catch(e){console.warn(e)}})),n.children().length<=1&&(n.html(""),$.each(e.spine.items,(function(t,o){const a=$("<a>").attr("href","#").attr("title",o.url).html("Section "+(t+1)).attr("data-href",o.href).click((function(){e.rendition.display(a.attr("data-href"))}));n.append($("<li>").append(a))})))})),e.spine.hooks.content.register((function(e){$(e).find("p").filter((e,t)=>{if($(t).text().length>=32)return t}).css("text-align","justify"),$(e).find("a, p, span, em, i, strong, b, body, div, big, small").attr("class","").css("color","").css("background","").css("background-color",""),void 0!==Reader.hyphenateHTML&&$(e).find("p").each((e,t)=>{(t=$(t)).html(Reader.hyphenateHTML(t.html()))})})),e.ready.then((function(){return localforage.getItem(Reader.cacheId()).then(t=>{let o,n;if(t)o=t.title,n=t.author_sort;else{const t=e.package.metadata;o=t.title,n=t.creator}return document.title=o+" – "+n+" – The Epube",$(".title").text(o).attr("title",o+" – "+n),"undefined"!=typeof EpubeApp&&(EpubeApp.setTitle(o),EpubeApp.showActionBar(!1)),localforage.getItem(Reader.cacheId("locations")).then((function(t){if(console.log("stored pagination",null!=t),t&&"string"==typeof t[0])return Reader.Page._pagination_stored=1,e.locations.load(t);{console.log("requesting pagination...");const t="backend.php?op=getpagination&id="+encodeURIComponent($.urlParam("id"));return fetch(t,{credentials:"same-origin"}).then((function(t){return t.ok?t.json().then((function(t){return t&&"string"==typeof t[0]?(Reader.Page._pagination_stored=1,e.locations.load(t)):($(".loading_message").html("Paginating..."),e.locations.generate(1600))})):($(".loading_message").html("Paginating..."),e.locations.generate(1600))})).catch((function(){return $(".loading_message").html("Paginating..."),e.locations.generate(1600)}))}}))})})).then((function(t){console.log("locations ready, stored=",Reader.Page._pagination_stored),t?(App.isOnline()&&!Reader.Page._pagination_stored&&$.post("backend.php",{op:"storepagination",id:$.urlParam("id"),payload:JSON.stringify(t),total:100}),localforage.getItem(Reader.cacheId("locations")).then((function(e){e||localforage.setItem(Reader.cacheId("locations"),t)})),$(".location").click((function(){const t=e.rendition.currentLocation().start.location,o=e.locations.length(),n=prompt("Jump to location [1-"+o+"]",t);n&&e.rendition.display(e.locations._locations[n])})),Reader.Page.openLastRead(),window.setTimeout((function(){Reader.Page.openLastRead(),$(".loading").hide()}),250)):$(".loading_message").html("Pagination failed.")})),t.on("keyup",e=>{Reader.hotkeyHandler(e)}),t.on("resized",(function(){console.log("resized"),$(".loading").show(),$(".loading_message").html("Opening chapter..."),window.setTimeout((function(){Reader.resizeSideColumns(),Reader.Page.openLastRead(),$(".loading").hide()}),250)})),t.on("rendered",(function(){$(".chapter").html($("<span>").addClass("glyphicon glyphicon-th-list")),Reader.applyTheme(),Reader.resizeSideColumns();try{const t=e.rendition.currentLocation();if(t.start){const o=e.canonical(t.start.href);let n=!1;$.each(Reader.flattenToc(e),(function(t,a){e.spine.get(a.href).canonical!=o||(n=a)})),n&&n.label&&$(".chapter").append(" "+n.label.trim()+" | "),Reader.generateTocBar(e,Reader.flattenToc(e))}}catch(e){console.warn(e)}})),t.on("relocated",(function(t){if(0==e.locations.length())return;const o=t.start.cfi,n=parseInt(100*e.locations.percentageFromCfi(o));$("#cur_page").text(t.start.location),$("#total_pages").text(e.locations.length()),$("#page_pct").text(parseInt(100*e.locations.percentageFromCfi(o))+"%"),Reader.updateTocBarPosition(e,t);const a=t.start.displayed;if(a&&($("#chapter_cur_page").text(a.page),$("#chapter_total_pages").text(a.total),a.total>0&&$("#chapter_pct").text(parseInt(a.page/a.total*100)+"%")),Reader.Page._store_position){Reader.Page._store_position=0;const e=(new Date).getTime();console.log("storing lastread",n,o,e),localforage.setItem(Reader.cacheId("lastread"),{cfi:o,page:n,total:100,timestamp:e}),(new Date).getTime()/1e3-Reader.Page._last_position_sync>15&&(App.isOnline()?(console.log("updating remote lastread..."),$.post("backend.php",{op:"storelastread",id:$.urlParam("id"),page:n,cfi:o,timestamp:e},(function(e){e.cfi&&(Reader.Page._last_position_sync=(new Date).getTime()/1e3)})).fail((function(e){e&&401==e.status&&(window.location="index.php")}))):Reader.Page._last_position_sync=0)}}))},flattenTocSubItems:function(e,t){let o=[];return 3!=t&&(e.subitems&&$.each(e.subitems,(function(e,n){n._nest=t,o.push(n),o=o.concat(Reader.flattenTocSubItems(n,t+1))})),o)},flattenToc:function(e){if(this._flattened_toc)return this._flattened_toc;{let t=[];return $.each(e.navigation.toc,(function(e,o){o._nest=0,t.push(o),t=t.concat(Reader.flattenTocSubItems(o,1))})),this._flattened_toc=t,t}},generateTocBar:function(e,t){$(".spacer").html(""),$.each(t,(function(t,o){try{const t=e.spine.get(o.href).cfiBase,n=e.locations._locations.find((function(e){return-1!=e.indexOf(t)}));if(n){const t=Math.round(100*e.locations.percentageFromCfi(n));$(".spacer").append($("<div class='toc-bar-entry'>").attr("data-nest-level",o._nest).css("left",t+"%").css("_width",3-o._nest+"px").attr("title",o.label))}}catch(e){console.warn(e)}})),$(".spacer").append($("<div class='toc-bar-entry current-position'>")),Reader.updateTocBarPosition(e,e.rendition.currentLocation())},updateTocBarPosition:function(e,t){const o=Math.round(t.start.location/e.locations.length()*100);$(".toc-bar-entry.current-position").css("left",o+"%")},applyStyles:function(e){Promise.all([localforage.getItem("epube.fontSize"),localforage.getItem("epube.fontFamily"),localforage.getItem("epube.lineHeight"),localforage.getItem("epube.theme")]).then((function(t){const o=t[0]?t[0]+"px":"16px",n=t[1]?t[1]:"Georgia",a=t[2]?t[2]+"%":"140%";console.log("style",n,o,a),console.log("applying default theme..."),window.book.rendition.themes.default({html:{"font-size":o,"font-family":"'"+n+"'","line-height":a,"text-align":"justify","text-indent":"1em"}}),e||(console.log("applying rendition themes..."),$.each(window.book.rendition.getContents(),(function(e,t){t.css("font-size",o),t.css("font-family","'"+n+"'"),t.css("line-height",a),t.css("text-align","justify")}))),Reader.applyTheme()}))},applyTheme:function(){localforage.getItem("epube.theme").then((function(e){e||(e="default"),console.log("called for theme",e),"default"==e&&"undefined"!=typeof EpubeApp&&EpubeApp.isNightMode()&&(e="night"),console.log("setting main UI theme",e),$("body").attr("class","undefined"!=typeof EpubeApp?"is-epube-app":"").addClass("epube-reader theme-"+e),"undefined"!=typeof EpubeApp&&window.setTimeout((function(){const e=window.getComputedStyle(document.querySelector("body"),null).getPropertyValue("background-color").match(/rgb\((\d{1,}), (\d{1,}), (\d{1,})\)/);e&&(console.log("sending bgcolor",e),EpubeApp.setStatusBarColor(parseInt(e[1]),parseInt(e[2]),parseInt(e[3])))}),250),$.each(window.book.rendition.getContents(),(function(t,o){console.log("applying rendition theme",e,"to",o,o.document),$(o.document).find("body").attr("class","undefined"!=typeof EpubeApp?"is-epube-app":"").addClass("theme-"+e)}))}))},hotkeyHandler:function(e){try{if($(".modal").is(":visible"))return;39!=e.which&&32!=e.which&&34!=e.which||(e.preventDefault(),Reader.Page.next()),37!=e.which&&33!=e.which||(e.preventDefault(),Reader.Page.prev()),27==e.which&&(e.preventDefault(),Reader.showUI(!0))}catch(e){console.warn(e)}},resizeSideColumns:function(){let e=$("#reader").position().left;const t=$("#reader iframe")[0];t&&t.contentWindow.$&&(e+=parseInt(t.contentWindow.$("body").css("padding-left"))),$("#left, #right").width(e)},markAsRead:function(){if(confirm("Mark book as read?")){const e=100,t=window.book.locations.cfiFromPercentage(1),o=(new Date).getTime();App.isOnline()&&$.post("backend.php",{op:"storelastread",page:e,cfi:t,id:$.urlParam("id"),timestamp:o},(function(e){$(".lastread_input").val(e.page+"%")})),localforage.setItem(Reader.cacheId("lastread"),{cfi:t,page:e,total:e,timestamp:o})}},close:function(){const e=window.book.rendition.currentLocation().start.cfi,t=parseInt(100*window.book.locations.percentageFromCfi(e)),o=(new Date).getTime();localforage.setItem(Reader.cacheId("lastread"),{cfi:e,page:t,total:100,timestamp:o}),App.isOnline()?$.post("backend.php",{op:"storelastread",id:$.urlParam("id"),page:t,cfi:e,timestamp:o},(function(){window.location=$.urlParam("rt")?"index.php?mode="+$.urlParam("rt"):"index.php"})).fail((function(){window.location="index.php"})):window.location="index.php"},cacheId:function(e){return"epube-book."+$.urlParam("b")+(e?"."+e:"")},toggleFullscreen:function(){if("undefined"!=typeof EpubeApp);else{const e=document.documentElement,t=document.webkitIsFullScreen||document.mozFullScreen||!1;e.requestFullScreen=e.requestFullScreen||e.webkitRequestFullScreen||e.mozRequestFullScreen||function(){return!1},document.cancelFullScreen=document.cancelFullScreen||document.webkitCancelFullScreen||document.mozCancelFullScreen||function(){return!1},t?document.cancelFullScreen():e.requestFullScreen()}},showUI:function(e){e?$(".header,.footer").fadeIn():$(".header,.footer").fadeOut()},toggleUI:function(){$(".header").is(":visible")?$(".header,.footer").fadeOut():$(".header,.footer").fadeIn()},lookupWord:function(e,t){e=e.replace(//g,""),$(".dict_result").html("Loading, please wait..."),$("#dict-modal").modal("show"),$.post("backend.php",{op:"define",word:e},(function(o){o&&($(".dict_result").html(o.result.join("<br/>")),$(".dict_query").val(e),t&&t())})).fail((function(e){console.warn(e),$(".dict_result").html("Network error while looking up word: "+e.statusText)}))},search:function(){const e=$(".search_input").val(),t=$(".search_results");t.html(""),e&&Promise.all(window.book.spine.spineItems.map(t=>t.load(window.book.load.bind(window.book)).then(t.find.bind(t,e)).finally(t.unload.bind(t)))).then(e=>Promise.resolve([].concat.apply([],e))).then((function(e){$.each(e,(function(e,o){const n=$("<a>").attr("href","#").html("<b class='pull-right'>"+window.book.locations.locationFromCfi(o.cfi)+"</b>"+o.excerpt).attr("data-cfi",o.cfi).attr("data-id",o.id).click((function(){window.book.rendition.display(n.attr("data-cfi"))}));t.append($("<li>").append(n))}))}))},Loader:{_res_data:[],init:function(){const e=["dist/app-libs.min.js","dist/reader_iframe.min.js","dist/reader_iframe.min.css"];for(let t=0;t<e.length;t++)fetch(e[t],{credentials:"same-origin"}).then((function(o){200==o.status?o.text().then((function(e){const t=new URL(o.url);t.searchParams.delete("ts"),Reader.Loader._res_data[t.toString()]=e})):console.warn("loader failed for resource",e[t],o)}));Reader.Loader.checkProgress(e,Reader.Loader._res_data,0)},checkProgress:function(e,t,o){console.log("check_resource_load",o,e.length,Object.keys(t).length,Reader,Reader.Loader),5!=o?e.length!=Object.keys(t).length?window.setTimeout((function(){Reader.Loader.checkProgress(e,t,o+1)}),250):Reader.initSecondStage():$(".loading_message").html("Unable to load resources.")}},Page:{_store_position:0,_last_position_sync:0,_pagination_stored:0,next:function(){Reader.Page._store_position=1,window.book.rendition.next(),"undefined"!=typeof EpubeApp?EpubeApp.showActionBar(!1):localforage.getItem("epube.keep-ui-visible").then((function(e){e||Reader.showUI(!1)}))},prev:function(){window.book.rendition.prev(),"undefined"!=typeof EpubeApp?EpubeApp.showActionBar(!1):localforage.getItem("epube.keep-ui-visible").then((function(e){e||Reader.showUI(!1)}))},openPrevious:function(e){const t=$(e).attr("data-location-cfi");t&&window.book.rendition.display(t),$(e).fadeOut()},clearLastRead:function(){if(confirm("Clear stored last read location?")){const e=window.book.locations.length(),t=(new Date).getTime();App.isOnline()&&$.post("backend.php",{op:"storelastread",page:-1,cfi:"",id:$.urlParam("id"),timestamp:t},(function(e){$(".lastread_input").val(e.page+"%")})),localforage.setItem(Reader.cacheId("lastread"),{cfi:"",page:0,total:e,timestamp:t}),window.setTimeout((function(){window.book.rendition.display(window.book.locations.cfiFromPercentage(0))}),250)}},openLastRead:function(e){localforage.getItem(Reader.cacheId("lastread")).then((function(t){console.log("lr local",t),t=t||{};try{t.cfi&&window.book.rendition.display(t.cfi).then(()=>{$(".loading").hide(),t.cfi&&window.book.rendition.display(t.cfi)})}catch(e){console.warn(e)}App.isOnline()&&!e&&$.post("backend.php",{op:"getlastread",id:$.urlParam("id")},(function(e){if(console.log("lr remote",e),App.isOnline()&&e)try{e.cfi&&t.cfi!=e.cfi&&e.timestamp>t.timestamp&&console.log("using remote lastread (timestamp is newer)"),localforage.setItem(Reader.cacheId("lastread"),{cfi:e.cfi,page:e.page,total:e.total,timestamp:e.timestamp}),window.book.rendition.display(e.cfi).then(()=>{window.book.rendition.display(e.cfi)})}catch(e){console.warn(e)}})).fail((function(e){e&&401==e.status&&(window.location="index.php")}))}))}},Settings:{onThemeChanged:function(e){const t=$(e).val();localforage.setItem("epube.theme",t).then((function(){Reader.applyTheme()}))},onLineHeightChanged:function(e){const t=$(e).val();localforage.setItem("epube.lineHeight",t).then((function(){Reader.applyStyles()}))},onTextSizeChanged:function(e){const t=$(e).val();localforage.setItem("epube.fontSize",t).then((function(){Reader.applyStyles()}))},onFontChanged:function(e){const t=$(e).val();localforage.setItem("epube.fontFamily",t).then((function(){Reader.applyStyles()}))}}};function __get_reader(){return Reader}function __get_app(){return App}
\ No newline at end of file +"use strict";$.urlParam=function(e){try{const t=new RegExp("[?&]"+e+"=([^&#]*)").exec(window.location.href);return decodeURIComponent(t[1].replace(/\+/g," "))||0}catch(e){return 0}};const Cookie={set:function(e,t,o){const n=new Date;n.setTime(n.getTime()+1e3*o);const a="expires="+n.toUTCString();document.cookie=e+"="+encodeURIComponent(t)+"; "+a},get:function(e){e+="=";const t=document.cookie.split(";");for(let o=0;o<t.length;o++){let n=t[o];for(;" "==n.charAt(0);)n=n.substring(1);if(0==n.indexOf(e))return decodeURIComponent(n.substring(e.length,n.length))}return""},delete:function(e){document.cookie=e+"=; expires=Thu, 01-Jan-1970 00:00:01 GMT"}},App={_dl_progress_timeout:!1,index_mode:"",last_mtime:-1,init:function(){let e=0;"undefined"!=typeof EpubeApp&&($(".navbar").hide(),$(".epube-app-filler").show(),$(".separate-search").show(),"favorites"==$.urlParam("mode")?EpubeApp.setPage("PAGE_FAVORITES"):EpubeApp.setPage("PAGE_LIBRARY")),App.initNightMode(),"serviceWorker"in navigator?navigator.serviceWorker.addEventListener("message",(function(t){"refresh-started"==t.data&&(console.log("cache refresh started"),e=0,$(".dl-progress").fadeIn().text("Loading, please wait...")),t.data&&0==t.data.indexOf("refreshed:")&&(++e,$(".dl-progress").fadeIn().text("Updated "+e+" files...")),"client-reload"==t.data&&(localforage.setItem("epube.cache-timestamp",App.last_mtime),window.location.reload())})):$(".container-main").addClass("alert alert-danger").html("Service worker support missing in browser (are you using plain HTTP?)."),App.showCovers(),App.Offline.markBooks(),App.refreshCache()},showSummary:function(e){const t=e.getAttribute("data-book-id");return $.post("backend.php",{op:"getinfo",id:t},(function(e){const t=e.comment?e.comment:"No description available";$("#summary-modal .modal-title").html(e.title),$("#summary-modal .book-summary").html(t),$("#summary-modal").modal()})),!1},showCovers:function(){$("img[data-book-id]").each((e,t)=>{if((t=$(t)).attr("data-cover-link")){const e=$("<img>").on("load",(function(){t.css("background-image","url("+t.attr("data-cover-link")+")").fadeIn(),e.attr("src",null)})).attr("src",t.attr("data-cover-link"))}else t.attr("src","holder.js/130x190?auto=yes").fadeIn()}),Holder.run()},toggleFavorite:function(e){const t=e.getAttribute("data-book-id");return("0"==e.getAttribute("data-is-fav")||confirm("Remove favorite?"))&&$.post("backend.php",{op:"togglefav",id:t},(function(o){if(o){let n="[Error]";0==o.status?n="Add to favorites":1==o.status&&(n="Remove from favorites"),$(e).html(n).attr("data-is-fav",o.status),"favorites"==App.index_mode&&0==o.status&&$("#cell-"+t).remove()}})),!1},refreshCache:function(e){"serviceWorker"in navigator?localforage.getItem("epube.cache-timestamp").then((function(t){(e||t!=App.last_mtime)&&(console.log("asking worker to refresh cache"),navigator.serviceWorker.controller?navigator.serviceWorker.controller.postMessage("refresh-cache"):localforage.getItem("epube.initial-load-done").then((function(e){console.log("initial load done",e),e?$(".dl-progress").show().addClass("alert-danger").html("Could not communicate with service worker. Try reloading the page."):localforage.setItem("epube.initial-load-done",!0).then((function(){$(".dl-progress").show().addClass("alert-info").html("Page will reload to activate service worker..."),window.setTimeout((function(){window.location.reload()}),3e3)}))})))})):$(".dl-progress").show().addClass("alert-danger").html("Could not communicate with service worker. Try reloading the page.")},isOnline:function(){return"undefined"!=typeof EpubeApp&&void 0!==EpubeApp.isOnline?EpubeApp.isOnline():navigator.onLine},appCheckOffline:function(){EpubeApp.setOffline(!App.isOnline)},initNightMode:function(){if("undefined"==typeof EpubeApp){if(window.matchMedia){const e=window.matchMedia("(prefers-color-scheme: dark)");e.addEventListener("change",()=>{App.applyNightMode(e.matches)}),App.applyNightMode(e.matches)}}else App.applyNightMode(EpubeApp.isNightMode())},applyNightMode:function(e){console.log("night mode changed to",e),$("#theme_css").attr("href","lib/bootstrap/v3/css/"+(e?"theme-dark.min.css":"bootstrap-theme.min.css"))},Offline:{init:function(){"undefined"!=typeof EpubeApp&&($(".navbar").hide(),$(".epube-app-filler").show(),EpubeApp.setPage("PAGE_OFFLINE")),App.initNightMode();const e=$.urlParam("query");e&&$(".search_query").val(e),App.Offline.populateList()},get:function(e,t){console.log("offline cache: "+e),$.post("backend.php",{op:"getinfo",id:e},(function(o){if(o){const n="epube-book."+e;localforage.setItem(n,o).then((function(o){console.log(n+" got data");const a=[];a.push(fetch("backend.php?op=download&id="+o.epub_id,{credentials:"same-origin"}).then((function(e){200==e.status&&(console.log(n+" got book"),t(),localforage.setItem(n+".book",e.blob()))}))),a.push(fetch("backend.php?op=getpagination&id="+o.epub_id,{credentials:"same-origin"}).then((function(e){200==e.status&&(console.log(n+" got pagination"),e.text().then((function(e){localforage.setItem(n+".locations",JSON.parse(e))})))}))),a.push(fetch("backend.php?op=getlastread&id="+o.epub_id,{credentials:"same-origin"}).then((function(e){200==e.status&&(console.log(n+" got lastread"),e.text().then((function(e){localforage.setItem(n+".lastread",JSON.parse(e))})))}))),o.has_cover&&a.push(fetch("backend.php?op=cover&id="+e,{credentials:"same-origin"}).then((function(e){200==e.status&&(console.log(n+" got cover"),localforage.setItem(n+".cover",e.blob()))}))),Promise.all(a).then((function(){$(".dl-progress").show().html("Finished downloading <b>"+o.title+"</b>"),window.clearTimeout(App._dl_progress_timeout),App._dl_progress_timeout=window.setTimeout((function(){$(".dl-progress").fadeOut()}),5e3)}))}))}}))},getAll:function(){confirm("Download all books on this page?")&&$(".row > div").each((function(e,t){const o=$(t).attr("id").replace("cell-",""),n=$(t).find(".offline_dropitem")[0];if(o){const e="epube-book."+o;localforage.getItem(e).then((function(e){e||App.Offline.get(o,(function(){App.Offline.mark(n)}))}))}}))},markBooks:function(){const e=$(".offline_dropitem");$.each(e,(function(e,t){App.Offline.mark(t)}))},mark:function(e){const t=e.getAttribute("data-book-id"),o="epube-book."+t;localforage.getItem(o).then((function(o){o?(e.onclick=function(){return App.Offline.remove(t,(function(){App.Offline.mark(e)})),!1},e.innerHTML="Remove offline data"):(e.onclick=function(){return App.Offline.get(t,(function(){App.Offline.mark(e)})),!1},e.innerHTML="Make available offline")}))},removeFromList:function(e){const t=e.getAttribute("data-book-id");return App.Offline.remove(t,(function(){$("#cell-"+t).remove()}))},remove:function(e,t){if(confirm("Remove download?")){const o="epube-book."+e,n=[];console.log("offline remove: "+e),localforage.iterate((function(e,t){t.match(o)&&n.push(localforage.removeItem(t))})),Promise.all(n).then((function(){window.setTimeout((function(){t()}),500)}))}},search:function(){const e=$(".search_query").val();return localforage.setItem("epube.search-query",e).then((function(){App.Offline.populateList()})),!1},removeAll:function(){if(confirm("Remove all downloaded books?")){const e=[];localforage.iterate((function(t,o){o.match("epube-book")&&e.push(localforage.removeItem(o))})),Promise.all(e).then((function(){window.setTimeout((function(){App.Offline.populateList()}),500)}))}},showSummary:function(e){const t=e.getAttribute("data-book-id");return localforage.getItem("epube-book."+t).then((function(e){const t=e.comment?e.comment:"No description available";$("#summary-modal .modal-title").html(e.title),$("#summary-modal .book-summary").html(t),$("#summary-modal").modal()})),!1},populateList:function(){let e=$.urlParam("query");e&&(e=e.toLowerCase());const t=$("#books_container");t.html(""),localforage.iterate((function(o,n){n.match(/epube-book\.\d{1,}$/)&&Promise.all([localforage.getItem(n),localforage.getItem(n+".cover"),localforage.getItem(n+".lastread"),localforage.getItem(n+".book")]).then((function(o){if(o[0]&&o[3]){const n=o[0];if(e){if(!(n.series_name&&n.series_name.toLowerCase().match(e)||n.title&&n.title.toLowerCase().match(e)||n.author_sort&&n.author_sort.toLowerCase().match(e)))return}let a=!1;o&&o[1]&&(a=URL.createObjectURL(o[1]));let i=!1,r=!1;const l=o[2];l&&(i=l.page>0,r=l.total>0&&l.total-l.page<5);const c=r?"read":"",s=i?"in_progress":"",d=n.series_name?`<div><a class="series_link" href="#">${n.series_name+" ["+n.series_index+"]"}</a></div>`:"",p=$(`<div class="col-xxs-6 col-xs-4 col-sm-3 col-md-2" id="cell-${n.id}">\n\t\t\t\t\t\t\t<a class="thumbnail ${c}" href="read.html?id=${n.epub_id}&b=${n.id}">\n\t\t\t\t\t\t\t\t<img style="display : none">\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t<div class="caption">\n\t\t\t\t\t\t\t\t<div><a class="${s}" href="read.html?id=${n.epub_id}&b=${n.id}">${n.title}</a></div>\n\t\t\t\t\t\t\t\t<div><a class="author_link" href="#">${n.author_sort}</a></div>\n\t\t\t\t\t\t\t\t${d}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class="dropdown" style="white-space : nowrap">\n\t\t\t\t\t\t\t\t<a href="#" data-toggle="dropdown" role="button">More...<span class="caret"></span></a>\n\t\t\t\t\t\t\t\t<ul class="dropdown-menu">\n\t\t\t\t\t\t\t\t\t<li><a href="#" data-book-id="${n.id}" onclick="return App.Offline.showSummary(this)">Summary</a></li>\n\t\t\t\t\t\t\t\t\t<li><a href="#" data-book-id="${n.id}" onclick="App.Offline.removeFromList(this)">Remove offline data</a></li>\n\t\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>`);a?p.find("img").css("background-image","url("+a+")").fadeIn():p.find("img").attr("data-src","holder.js/130x190?auto=yes").fadeIn(),p.find(".series_link").attr("title",n.series_name+" ["+n.series_index+"]").attr("href","offline.html?query="+encodeURIComponent(n.series_name)),p.find(".author_link").attr("title",n.author_sort).attr("href","offline.html?query="+encodeURIComponent(n.author_sort)),t.append(p),Holder.run()}}))}))}}},DEFAULT_FONT_SIZE=16,DEFAULT_FONT_FAMILY="Georgia",DEFAULT_LINE_HEIGHT=140,MIN_LENGTH_TO_JUSTIFY=32,PAGE_RESET_PROGRESS=-1,Reader={init:function(){$(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(e){if(console.log("onOfflineModeChanged",e),!e&&window.book){const e=window.book;console.log("we're online, storing lastread");const t=e.rendition.currentLocation().start.cfi,o=parseInt(100*e.locations.percentageFromCfi(t));$.post("backend.php",{op:"storelastread",id:$.urlParam("id"),page:o,cfi:t,timestamp:(new Date).getTime()},(function(e){e.cfi&&(Reader.Page._last_position_sync=(new Date).getTime()/1e3)})).fail((function(e){e&&401==e.status&&(window.location="index.php")}))}},initSecondStage:function(){return"undefined"!=typeof EpubeApp?EpubeApp.setPage("PAGE_READER"):($(window).on("online",(function(){Reader.onOfflineModeChanged(!1)})),$(window).on("offline",(function(){Reader.onOfflineModeChanged(!0)}))),Reader.applyTheme(),localforage.getItem(Reader.cacheId()).then((function(t){if(!t)return console.log("requesting bookinfo..."),new Promise((t,o)=>{const n=$.urlParam("b");$.post("backend.php",{op:"getinfo",id:n}).success((function(e){if(e)return e.has_cover&&fetch("backend.php?op=cover&id="+n,{credentials:"same-origin"}).then((function(e){200==e.status&&localforage.setItem(Reader.cacheId("cover"),e.blob())})),localforage.setItem(Reader.cacheId(),e).then((function(){console.log("bookinfo saved"),t()}));o(new Error("unable to load book info: blank"))})).error((function(t){$(".loading_message").html("Unable to load book info.<br/><small>"+t.status+"</small>"),o(new Error("unable to load book info: "+e))}))});console.log("bookinfo already stored")})).then((function(){console.log("trying to load book..."),localforage.getItem(Reader.cacheId("book")).then((function(t){if(t)return console.log("loading from local storage"),new Promise((function(o,n){const a=new FileReader;a.onload=function(){try{return e.open(this.result).then((function(){o()}))}catch(e){$(".loading_message").html("Unable to load book (local)."),console.log(e),n(new Error("Unable to load book (local):"+e))}},a.readAsArrayBuffer(t)}));if(console.log("loading from network"),App.isOnline()){const t="backend.php?op=download&id="+$.urlParam("id");return $(".loading_message").html("Downloading..."),fetch(t,{credentials:"same-origin"}).then((function(t){if(200==t.status)return t.blob().then((function(t){return new Promise((function(o,n){const a=new FileReader;a.onload=function(){e.open(this.result).then((function(){localforage.setItem(Reader.cacheId("book"),t).then((function(){o()}))})).catch(e=>{$(".loading_message").html("Unable to open book.<br/><small>"+e+"</small>"),n(new Error("Unable to open book: "+e))})},a.onerror=function(e){console.log("filereader error",e),$(".loading_message").html("Unable to open book.<br/><small>"+e+"</small>"),n(new Error("Unable to open book: "+e))},a.readAsArrayBuffer(t)}))})).catch(e=>{console.log("blob error",e),$(".loading_message").html("Unable to download book.<br/><small>"+e+"</small>")});$(".loading_message").html("Unable to download book: "+t.status+".")})).catch((function(e){console.warn(e),$(".loading").is(":visible")&&$(".loading_message").html("Unable to load book (remote).<br/><small>"+e+"</small>")}))}$(".loading_message").html("This book is not available offline.")}));const e=ePub();window.book=e;const t=e.renderTo("reader",{width:"100%",height:"100%",minSpreadWidth:961});function o(t){try{const o=e.spine.get(t).cfiBase,n=e.locations._locations.find((function(e){return-1!=e.indexOf(o)}));return window.book.locations.locationFromCfi(n)}catch(e){console.warn(e)}return""}localforage.getItem("epube.enable-hyphens").then((function(e){e&&(Reader.hyphenateHTML=createHyphenator(hyphenationPatternsEnUs,{html:!0})),Reader.applyStyles(!0),t.display().then((function(){console.log("book displayed")}))})),t.hooks.content.register((function(t){t.on("linkClicked",(function(t){console.log("linkClicked",t),-1==t.indexOf("://")&&($(".prev_location_btn").attr("data-location-cfi",e.rendition.currentLocation().start.cfi).show(),window.setTimeout((function(){Reader.showUI(!0)}),50))}));const o=window.location.href.match(/^.*\//)[0],n=["dist/app-libs.min.js","dist/reader_iframe.min.js"],a=t.document;for(let e=0;e<n.length;e++){const t=a.createElement("script");t.type="text/javascript",t.text=Reader.Loader._res_data[o+n[e]],a.head.appendChild(t)}return $(t.document.head).append($("<style type='text/css'>").text(Reader.Loader._res_data[o+"dist/reader_iframe.min.css"])),localforage.getItem("epube.theme").then((function(e){e||(e="default"),$(t.document).find("body").attr("class","undefined"!=typeof EpubeApp?"is-epube-app":"").addClass("theme-"+e)}))})),$("#settings-modal").on("shown.bs.modal",(function(){localforage.getItem(Reader.cacheId("lastread")).then(e=>{e&&e.cfi&&$(".lastread_input").val(e.page+"%"),$.post("backend.php",{op:"getlastread",id:$.urlParam("id")},(function(e){$(".lastread_input").val(e.page+"%")}))}),localforage.getItem("epube.enable-hyphens").then((function(e){$(".enable_hyphens_checkbox").attr("checked",e).off("click").on("click",(function(e){localforage.setItem("epube.enable-hyphens",e.target.checked),confirm("Toggling hyphens requires page reload. Reload now?")&&window.location.reload()}))})),localforage.getItem("epube.keep-ui-visible").then((function(e){$(".keep_ui_checkbox").attr("checked",e).off("click").on("click",(function(e){localforage.setItem("epube.keep-ui-visible",e.target.checked)}))})),localforage.getItem("epube.cache-timestamp").then((function(e){let t="V: ";parseInt(e)?t+=new Date(1e3*e).toLocaleString("en-GB"):t+="Unknown",t+=" ("+(App.isOnline()?"Online":"Offline")+")",$(".last-mod-timestamp").text(t)})),localforage.getItem("epube.fontFamily").then((function(e){e||(e="Georgia"),$(".font_family").val(e)})),localforage.getItem("epube.theme").then((function(e){$(".theme_name").val(e)})),localforage.getItem("epube.fontSize").then((function(e){e||(e=16);const t=$(".font_size").html("");for(let e=10;e<=32;e++){const o=$("<option>").val(e).html(e+" px");t.append(o)}t.val(e)})),localforage.getItem("epube.lineHeight").then((function(e){e||(e=140);const t=$(".line_height").html("");for(let e=100;e<=220;e+=10){const o=$("<option>").val(e).html(e+"%");t.append(o)}t.val(e)}))})),$("#dict-modal").on("shown.bs.modal",(function(){$(".dict_result").scrollTop(0)})),$(".dict_search_btn").on("click",(function(){$("#dict-modal").modal("hide"),window.open("https://duckduckgo.com/?q="+$(".dict_query").val())})),$(".wiki_search_btn").on("click",(function(){$(".dict_result").html("Loading, please wait..."),$.post("backend.php",{op:"wikisearch",query:$(".dict_query").val()}).then(e=>{try{let t="";$.each(e.query.pages,(e,o)=>{t+=o.extract}),$(".dict_result").html(t&&"undefined"!=t?t:"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.")})})),$("#toc-modal").on("shown.bs.modal",(function(){const t=e.navigation.toc,n=$(".toc_list");n.html(""),$.each(t,(function(t,a){try{const t=$("<a>").attr("href","#").html("<b class='pull-right'>"+o(a.href)+"</b>"+a.label).attr("data-href",a.href).click((function(){e.rendition.display(t.attr("data-href"))}));n.append($("<li>").append(t)),function t(n,a,i){if(3==i)return!1;if(n.subitems){const r=$("<ul class='toc_sublist list-unstyled'>");$.each(n.subitems,(function(n,a){const l=$("<a>").attr("href","#").html("<b class='pull-right'>"+o(a.href)+"</b>"+a.label).attr("data-href",a.href).click((function(){e.rendition.display(l.attr("data-href"))}));r.append($("<li>").append(l)),t(a,r,i+1)})),a.append(r)}}(a,n,0)}catch(e){console.warn(e)}})),n.children().length<=1&&(n.html(""),$.each(e.spine.items,(function(t,o){const a=$("<a>").attr("href","#").attr("title",o.url).html("Section "+(t+1)).attr("data-href",o.href).click((function(){e.rendition.display(a.attr("data-href"))}));n.append($("<li>").append(a))})))})),e.spine.hooks.content.register((function(e){$(e).find("p").filter((e,t)=>{if($(t).text().length>=32)return t}).css("text-align","justify"),$(e).find("a, p, span, em, i, strong, b, body, div, big, small").attr("class","").css("color","").css("background","").css("background-color",""),void 0!==Reader.hyphenateHTML&&$(e).find("p").each((e,t)=>{(t=$(t)).html(Reader.hyphenateHTML(t.html()))})})),e.ready.then((function(){return localforage.getItem(Reader.cacheId()).then(t=>{let o,n;if(t)o=t.title,n=t.author_sort;else{const t=e.package.metadata;o=t.title,n=t.creator}return document.title=o+" – "+n+" – The Epube",$(".title").text(o).attr("title",o+" – "+n),"undefined"!=typeof EpubeApp&&(EpubeApp.setTitle(o),EpubeApp.showActionBar(!1)),localforage.getItem(Reader.cacheId("locations")).then((function(t){if(console.log("stored pagination",null!=t),t&&"string"==typeof t[0])return Reader.Page._pagination_stored=1,e.locations.load(t);{console.log("requesting pagination...");const t="backend.php?op=getpagination&id="+encodeURIComponent($.urlParam("id"));return fetch(t,{credentials:"same-origin"}).then((function(t){return t.ok?t.json().then((function(t){return t&&"string"==typeof t[0]?(Reader.Page._pagination_stored=1,e.locations.load(t)):($(".loading_message").html("Paginating..."),e.locations.generate(1600))})):($(".loading_message").html("Paginating..."),e.locations.generate(1600))})).catch((function(){return $(".loading_message").html("Paginating..."),e.locations.generate(1600)}))}}))})})).then((function(t){console.log("locations ready, stored=",Reader.Page._pagination_stored),t?(App.isOnline()&&!Reader.Page._pagination_stored&&$.post("backend.php",{op:"storepagination",id:$.urlParam("id"),payload:JSON.stringify(t),total:100}),localforage.getItem(Reader.cacheId("locations")).then((function(e){e||localforage.setItem(Reader.cacheId("locations"),t)})),$(".location").click((function(){const t=e.rendition.currentLocation().start.location,o=e.locations.length(),n=prompt("Jump to location [1-"+o+"]",t);n&&e.rendition.display(e.locations._locations[n])})),Reader.Page.openLastRead(),window.setTimeout((function(){Reader.Page.openLastRead(),$(".loading").hide()}),250)):$(".loading_message").html("Pagination failed.")})),t.on("keyup",e=>{Reader.hotkeyHandler(e)}),t.on("resized",(function(){console.log("resized"),$(".loading").show(),$(".loading_message").html("Opening chapter..."),window.setTimeout((function(){Reader.resizeSideColumns(),Reader.Page.openLastRead(),$(".loading").hide()}),250)})),t.on("rendered",(function(){$(".chapter").html($("<span>").addClass("glyphicon glyphicon-th-list")),Reader.applyTheme(),Reader.resizeSideColumns();try{const t=e.rendition.currentLocation();if(t.start){const o=e.canonical(t.start.href);let n=!1;$.each(Reader.flattenToc(e),(function(t,a){e.spine.get(a.href).canonical!=o||(n=a)})),n&&n.label&&$(".chapter").append(" "+n.label.trim()+" | "),Reader.generateTocBar(e,Reader.flattenToc(e))}}catch(e){console.warn(e)}})),t.on("relocated",(function(t){if(0==e.locations.length())return;const o=t.start.cfi,n=parseInt(100*e.locations.percentageFromCfi(o));$("#cur_page").text(t.start.location),$("#total_pages").text(e.locations.length()),$("#page_pct").text(parseInt(100*e.locations.percentageFromCfi(o))+"%"),Reader.updateTocBarPosition(e,t);const a=t.start.displayed;if(a&&($("#chapter_cur_page").text(a.page),$("#chapter_total_pages").text(a.total),a.total>0&&$("#chapter_pct").text(parseInt(a.page/a.total*100)+"%")),Reader.Page._store_position){Reader.Page._store_position=0;const e=(new Date).getTime();console.log("storing lastread",n,o,e),localforage.setItem(Reader.cacheId("lastread"),{cfi:o,page:n,total:100,timestamp:e}),(new Date).getTime()/1e3-Reader.Page._last_position_sync>15&&(App.isOnline()?(console.log("updating remote lastread..."),$.post("backend.php",{op:"storelastread",id:$.urlParam("id"),page:n,cfi:o,timestamp:e},(function(e){e.cfi&&(Reader.Page._last_position_sync=(new Date).getTime()/1e3)})).fail((function(e){e&&401==e.status&&(window.location="index.php")}))):Reader.Page._last_position_sync=0)}}))}))},flattenTocSubItems:function(e,t){let o=[];return 3!=t&&(e.subitems&&$.each(e.subitems,(function(e,n){n._nest=t,o.push(n),o=o.concat(Reader.flattenTocSubItems(n,t+1))})),o)},flattenToc:function(e){if(this._flattened_toc)return this._flattened_toc;{let t=[];return $.each(e.navigation.toc,(function(e,o){o._nest=0,t.push(o),t=t.concat(Reader.flattenTocSubItems(o,1))})),this._flattened_toc=t,t}},generateTocBar:function(e,t){$(".spacer").html(""),$.each(t,(function(t,o){try{const t=e.spine.get(o.href).cfiBase,n=e.locations._locations.find((function(e){return-1!=e.indexOf(t)}));if(n){const t=Math.round(100*e.locations.percentageFromCfi(n));$(".spacer").append($("<div class='toc-bar-entry'>").attr("data-nest-level",o._nest).css("left",t+"%").css("_width",3-o._nest+"px").attr("title",o.label))}}catch(e){console.warn(e)}})),$(".spacer").append($("<div class='toc-bar-entry current-position'>")),Reader.updateTocBarPosition(e,e.rendition.currentLocation())},updateTocBarPosition:function(e,t){const o=Math.round(t.start.location/e.locations.length()*100);$(".toc-bar-entry.current-position").css("left",o+"%")},applyStyles:function(e){Promise.all([localforage.getItem("epube.fontSize"),localforage.getItem("epube.fontFamily"),localforage.getItem("epube.lineHeight"),localforage.getItem("epube.theme")]).then((function(t){const o=t[0]?t[0]+"px":"16px",n=t[1]?t[1]:"Georgia",a=t[2]?t[2]+"%":"140%";console.log("style",n,o,a),console.log("applying default theme..."),window.book.rendition.themes.default({html:{"font-size":o,"font-family":"'"+n+"'","line-height":a,"text-align":"justify","text-indent":"1em"}}),e||(console.log("applying rendition themes..."),$.each(window.book.rendition.getContents(),(function(e,t){t.css("font-size",o),t.css("font-family","'"+n+"'"),t.css("line-height",a),t.css("text-align","justify")}))),Reader.applyTheme()}))},applyTheme:function(){localforage.getItem("epube.theme").then((function(e){e||(e="default"),console.log("called for theme",e),"default"==e&&"undefined"!=typeof EpubeApp&&EpubeApp.isNightMode()&&(e="night"),console.log("setting main UI theme",e),$("body").attr("class","undefined"!=typeof EpubeApp?"is-epube-app":"").addClass("epube-reader theme-"+e),"undefined"!=typeof EpubeApp&&window.setTimeout((function(){const e=window.getComputedStyle(document.querySelector("body"),null).getPropertyValue("background-color").match(/rgb\((\d{1,}), (\d{1,}), (\d{1,})\)/);e&&(console.log("sending bgcolor",e),EpubeApp.setStatusBarColor(parseInt(e[1]),parseInt(e[2]),parseInt(e[3])))}),250),window.book&&$.each(window.book.rendition.getContents(),(function(t,o){console.log("applying rendition theme",e,"to",o,o.document),$(o.document).find("body").attr("class","undefined"!=typeof EpubeApp?"is-epube-app":"").addClass("theme-"+e)}))}))},hotkeyHandler:function(e){try{if($(".modal").is(":visible"))return;39!=e.which&&32!=e.which&&34!=e.which||(e.preventDefault(),Reader.Page.next()),37!=e.which&&33!=e.which||(e.preventDefault(),Reader.Page.prev()),27==e.which&&(e.preventDefault(),Reader.showUI(!0))}catch(e){console.warn(e)}},resizeSideColumns:function(){let e=$("#reader").position().left;const t=$("#reader iframe")[0];t&&t.contentWindow.$&&(e+=parseInt(t.contentWindow.$("body").css("padding-left"))),$("#left, #right").width(e)},markAsRead:function(){if(confirm("Mark book as read?")){const e=100,t=window.book.locations.cfiFromPercentage(1),o=(new Date).getTime();App.isOnline()&&$.post("backend.php",{op:"storelastread",page:e,cfi:t,id:$.urlParam("id"),timestamp:o},(function(e){$(".lastread_input").val(e.page+"%")})),localforage.setItem(Reader.cacheId("lastread"),{cfi:t,page:e,total:e,timestamp:o})}},close:function(){const e=window.book.rendition.currentLocation().start.cfi,t=parseInt(100*window.book.locations.percentageFromCfi(e)),o=(new Date).getTime();localforage.setItem(Reader.cacheId("lastread"),{cfi:e,page:t,total:100,timestamp:o}),App.isOnline()?$.post("backend.php",{op:"storelastread",id:$.urlParam("id"),page:t,cfi:e,timestamp:o},(function(){window.location=$.urlParam("rt")?"index.php?mode="+$.urlParam("rt"):"index.php"})).fail((function(){window.location="index.php"})):window.location="index.php"},cacheId:function(e){return"epube-book."+$.urlParam("b")+(e?"."+e:"")},toggleFullscreen:function(){if("undefined"!=typeof EpubeApp);else{const e=document.documentElement,t=document.webkitIsFullScreen||document.mozFullScreen||!1;e.requestFullScreen=e.requestFullScreen||e.webkitRequestFullScreen||e.mozRequestFullScreen||function(){return!1},document.cancelFullScreen=document.cancelFullScreen||document.webkitCancelFullScreen||document.mozCancelFullScreen||function(){return!1},t?document.cancelFullScreen():e.requestFullScreen()}},showUI:function(e){e?$(".header,.footer").fadeIn():$(".header,.footer").fadeOut()},toggleUI:function(){$(".header").is(":visible")?$(".header,.footer").fadeOut():$(".header,.footer").fadeIn()},lookupWord:function(e,t){e=e.replace(//g,""),$(".dict_result").html("Loading, please wait..."),$("#dict-modal").modal("show"),$.post("backend.php",{op:"define",word:e},(function(o){o&&($(".dict_result").html(o.result.join("<br/>")),$(".dict_query").val(e),t&&t())})).fail((function(e){console.warn(e),$(".dict_result").html("Network error while looking up word: "+e.statusText)}))},search:function(){const e=$(".search_input").val(),t=$(".search_results");t.html(""),e&&Promise.all(window.book.spine.spineItems.map(t=>t.load(window.book.load.bind(window.book)).then(t.find.bind(t,e)).finally(t.unload.bind(t)))).then(e=>Promise.resolve([].concat.apply([],e))).then((function(e){$.each(e,(function(e,o){const n=$("<a>").attr("href","#").html("<b class='pull-right'>"+window.book.locations.locationFromCfi(o.cfi)+"</b>"+o.excerpt).attr("data-cfi",o.cfi).attr("data-id",o.id).click((function(){window.book.rendition.display(n.attr("data-cfi"))}));t.append($("<li>").append(n))}))}))},Loader:{_res_data:[],init:function(){const e=["dist/app-libs.min.js","dist/reader_iframe.min.js","dist/reader_iframe.min.css"];for(let t=0;t<e.length;t++)fetch(e[t],{credentials:"same-origin"}).then((function(o){200==o.status?o.text().then((function(e){const t=new URL(o.url);t.searchParams.delete("ts"),Reader.Loader._res_data[t.toString()]=e})):console.warn("loader failed for resource",e[t],o)}));Reader.Loader.checkProgress(e,Reader.Loader._res_data,0)},checkProgress:function(e,t,o){console.log("check_resource_load",o,e.length,Object.keys(t).length,Reader,Reader.Loader),5!=o?e.length!=Object.keys(t).length?window.setTimeout((function(){Reader.Loader.checkProgress(e,t,o+1)}),250):Reader.initSecondStage():$(".loading_message").html("Unable to load resources.")}},Page:{_store_position:0,_last_position_sync:0,_pagination_stored:0,next:function(){Reader.Page._store_position=1,window.book.rendition.next(),"undefined"!=typeof EpubeApp?EpubeApp.showActionBar(!1):localforage.getItem("epube.keep-ui-visible").then((function(e){e||Reader.showUI(!1)}))},prev:function(){window.book.rendition.prev(),"undefined"!=typeof EpubeApp?EpubeApp.showActionBar(!1):localforage.getItem("epube.keep-ui-visible").then((function(e){e||Reader.showUI(!1)}))},openPrevious:function(e){const t=$(e).attr("data-location-cfi");t&&window.book.rendition.display(t),$(e).fadeOut()},clearLastRead:function(){if(confirm("Clear stored last read location?")){const e=window.book.locations.length(),t=(new Date).getTime();App.isOnline()&&$.post("backend.php",{op:"storelastread",page:-1,cfi:"",id:$.urlParam("id"),timestamp:t},(function(e){$(".lastread_input").val(e.page+"%")})),localforage.setItem(Reader.cacheId("lastread"),{cfi:"",page:0,total:e,timestamp:t}),window.setTimeout((function(){window.book.rendition.display(window.book.locations.cfiFromPercentage(0))}),250)}},openLastRead:function(e){localforage.getItem(Reader.cacheId("lastread")).then((function(t){console.log("lr local",t),t=t||{};try{t.cfi&&window.book.rendition.display(t.cfi).then(()=>{$(".loading").hide(),t.cfi&&window.book.rendition.display(t.cfi)})}catch(e){console.warn(e)}App.isOnline()&&!e&&$.post("backend.php",{op:"getlastread",id:$.urlParam("id")},(function(e){if(console.log("lr remote",e),App.isOnline()&&e)try{e.cfi&&t.cfi!=e.cfi&&e.timestamp>t.timestamp&&console.log("using remote lastread (timestamp is newer)"),localforage.setItem(Reader.cacheId("lastread"),{cfi:e.cfi,page:e.page,total:e.total,timestamp:e.timestamp}),window.book.rendition.display(e.cfi).then(()=>{window.book.rendition.display(e.cfi)})}catch(e){console.warn(e)}})).fail((function(e){e&&401==e.status&&(window.location="index.php")}))}))}},Settings:{onThemeChanged:function(e){const t=$(e).val();localforage.setItem("epube.theme",t).then((function(){Reader.applyTheme()}))},onLineHeightChanged:function(e){const t=$(e).val();localforage.setItem("epube.lineHeight",t).then((function(){Reader.applyStyles()}))},onTextSizeChanged:function(e){const t=$(e).val();localforage.setItem("epube.fontSize",t).then((function(){Reader.applyStyles()}))},onFontChanged:function(e){const t=$(e).val();localforage.setItem("epube.fontFamily",t).then((function(){Reader.applyStyles()}))}}};function __get_reader(){return Reader}function __get_app(){return App}
\ No newline at end of file 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); + }); }); }, |