/** * waits until queue is finished, meaning the book is done loading * @param callback */ function qFinished(callback){ let timeout=setInterval(()=>{ if(reader.rendition.q.running===undefined) clearInterval(timeout); callback(); },300 ) } function calculateProgress(){ let data=reader.rendition.location.end; return Math.round(epub.locations.percentageFromCfi(data.cfi)*100); } // register new event emitter locationchange that fires on urlchange // source: https://stackoverflow.com/a/52809105/21941129 (() => { let oldPushState = history.pushState; history.pushState = function pushState() { let ret = oldPushState.apply(this, arguments); window.dispatchEvent(new Event('locationchange')); return ret; }; let oldReplaceState = history.replaceState; history.replaceState = function replaceState() { let ret = oldReplaceState.apply(this, arguments); window.dispatchEvent(new Event('locationchange')); return ret; }; window.addEventListener('popstate', () => { window.dispatchEvent(new Event('locationchange')); }); })(); window.addEventListener('locationchange',()=>{ let newPos=calculateProgress(); progressDiv.textContent=newPos+"%"; }); var epub=ePub(calibre.bookUrl) let progressDiv=document.getElementById("progress"); qFinished(()=>{ epub.locations.generate().then(()=> { window.dispatchEvent(new Event('locationchange')) }); })