1
0
mirror of https://github.com/janeczku/calibre-web synced 2024-12-19 06:30:29 +00:00

switched to using epub.min.js, deleted now unnecessary dependencies

This commit is contained in:
quarz12 2023-06-05 15:39:09 +02:00
parent 99c05650a1
commit d0551274dc
4 changed files with 29 additions and 1226 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,160 +1,19 @@
class EpubParser {
constructor(filesList) {
this.files = filesList;
this.parser = new DOMParser();
this.opfXml = this.getOPFXml();
this.encoder = new TextEncoder();
}
getTotalByteLength() {
let size = 0;
for (let key of Object.keys(this.files)) {
let file = this.files[key];
if (file.name.endsWith("html")) {
// console.log(file.name + " " + file._data.uncompressedSize)
size += file._data.uncompressedSize;
}
}
return size;
}
/**
* gets file from files and returns decompressed content as string
* @param {string} filename name of the file in filelist
* @return {string} string representation of decompressed bytes
*/
decompress(filename) {
return pako.inflate(this.files[filename]._data.compressedContent, {raw: true, to: "string"});
}
getOPFXml() {
let content = this.decompress("META-INF/container.xml");
let xml = this.parser.parseFromString(content, "text/xml");
let path = xml.getElementsByTagName("rootfile")[0].getAttribute("full-path");
this.opfDir = path.split("/").slice(0, -1).join("/");
return this.parser.parseFromString(this.decompress(path), "text/xml");
}
getSpine() {
return Array.from(this.opfXml.getElementsByTagName("spine")[0].children).map(node => node.getAttribute("idref"));
}
/**
resolves an idref in content.opf to its file
*/
resolveIDref(idref) {
return this.absPath(this.opfXml.getElementById(idref).getAttribute("href"));
}
/**
* returns absolute path from path relative to content.opf
* @param path
*/
absPath(path) {
if (this.opfDir) {
return [this.opfDir, path].join("/");
} else {
return path;
}
}
/**
returns the sum of the bytesize of all html files that are located before it in the spine
@param {string} filepath path of the current file, also part of the CFI, e.g. here: #epubcfi(/6/2[titlepage]!/4/1:0) it would be "titlepage"
*/
getPreviousFilesSize(filepath) {
let currentFile=this.getIdRef(filepath);
let bytesize = 0;
for (let file of this.getSpine()) {
if (file !== currentFile) {
let filepath = this.resolveIDref(file);
//ignore non text files
if (filepath.endsWith("html")) {
// console.log(filepath + " " + bytesize)
bytesize += this.files[filepath]._data.uncompressedSize;
}
} else {
break;
}
}
return bytesize;
}
getIdRef(filepath){
return this.opfXml.querySelector(`[href="${filepath}"]`).getAttribute("id");
}
/**
* resolves the given cfi to the xml node it points to
* @param {string} cfistr epub-cfi string in the form: epubcfi(/6/16[id13]!/4[id2]/4/2[doc12]/1:0)
* @return object with attributes "node" and "offset"
*/
cfiToXmlNode(cfistr) {
let cfi = new CFI(cfistr);
let cfiPath = cfistr.split("(")[1].split(")")[0];
let fileId = cfiPath.split("!")[0].split("[")[1].split("]")[0];
return cfi.resolveLast(this.parser.parseFromString(this.decompress(this.resolveIDref(fileId)),"text/xml"));
}
/**
takes the node that the cfi points at and counts the bytes of all nodes before that
*/
getCurrentFileProgress(CFI) {
let parse=this.cfiToXmlNode(CFI);
let size=parse.offset;
let startnode = parse.node//returns text node
let xmlnsLength = startnode.parentNode.namespaceURI.length;
let prev = startnode.parentNode.previousElementSibling;
while (prev !== null) {
size += this.encoder.encode(prev.outerHTML).length - xmlnsLength;
prev = prev.previousElementSibling;
}
let parent = startnode.parentElement.parentElement;
while (parent !== null) {
let parentPrev = parent.previousElementSibling;
while (parentPrev !== null) {
size += this.encoder.encode(parentPrev.outerHTML).length - xmlnsLength;
parentPrev = parentPrev.previousElementSibling;
}
parent = parent.parentElement;
}
return size;
}
/**
* @param currentFile filepath
* @param CFI
* @return {number} percentage as decimal
*/
getProgress(currentFile, CFI) {
let percentage = (this.getPreviousFilesSize(currentFile) + this.getCurrentFileProgress(CFI))/this.getTotalByteLength();
if (percentage === Infinity) {
return 0;
} else if (percentage>1){
return 1;
}
else{
return percentage;
}
}
}
//wait until variable is assigned a value
function waitFor(variable, callback) {
const interval = setInterval(function() {
if (variable!==undefined) {
clearInterval(interval);
callback();
}
}, 200);
}
/**
* returns progress percentage
* @return {number}
* 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.currentLocation().end;
return Math.round(epubParser.getProgress(data.href,data.cfi)*100);
let data=reader.rendition.location.end;
return Math.round(epub.locations.percentageFromCfi(data.cfi)*100);
}
// register new event emitter locationchange that fires on urlchange
@ -179,13 +38,21 @@ function calculateProgress(){
});
})();
var epubParser;
waitFor(reader.book,()=>{
epubParser = new EpubParser(reader.book.archive.zip.files);
});
let progressDiv=document.getElementById("progress");
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'))
});
})

View File

@ -152,8 +152,8 @@
<script src="{{ url_for('static', filename='js/libs/screenfull.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/reader.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/reading/epub.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/epub.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/reading/epub-progress.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/pako.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/epub-cfi-resolver.js') }}"></script>
</body>
</html>