implemented current file process, needs testing but looks good

This commit is contained in:
quarz12 2023-05-18 22:37:09 +02:00
parent b25c024b66
commit dbac685985

View File

@ -20,6 +20,7 @@ class EpubParser {
} }
/** /**
* gets file from files and returns decompressed content as string
* @param {string} filename name of the file in filelist * @param {string} filename name of the file in filelist
* @return {string} string representation of decompressed bytes * @return {string} string representation of decompressed bytes
*/ */
@ -44,7 +45,7 @@ class EpubParser {
resolves an idref in content.opf to its file resolves an idref in content.opf to its file
*/ */
resolveIDref(idref) { resolveIDref(idref) {
return this.opfXml.getElementById(idref).getAttribute("href"); return this.absPath(this.opfXml.getElementById(idref).getAttribute("href"));
} }
/** /**
@ -67,7 +68,7 @@ class EpubParser {
let bytesize = 0; let bytesize = 0;
for (let file of this.getSpine()) { for (let file of this.getSpine()) {
if (file !== currentFile) { if (file !== currentFile) {
let filepath = this.absPath(this.resolveIDref(file)); let filepath = this.resolveIDref(file);
//ignore non text files //ignore non text files
if (filepath.endsWith("html")) { if (filepath.endsWith("html")) {
console.log(filepath + " " + bytesize) console.log(filepath + " " + bytesize)
@ -79,25 +80,80 @@ class EpubParser {
} }
return bytesize; return bytesize;
} }
cfiToXmlNode(file,cfi){
/**
* resolves the given cfi to the xml node it points to
* @param {string} cfi epub-cfi string in the form: epubcfi(/6/16[id13]!/4[id2]/4/2[doc12]/1:0)
* @return XML Text-Node
*/
cfiToXmlNode(cfi) {
let cfiPath = cfi.split("(")[1].split(")")[0];
let fileId = cfiPath.split("!")[0].split("[")[1].split("]")[0];
let xml = this.parser.parseFromString(this.decompress(this.resolveIDref(fileId)), "text/xml");
let components = cfiPath.split("!")[1].split("/").slice(1);
let currentNode = xml.getElementsByTagName("html")[0];
for (const component of components) {
this.validateChildNodes(currentNode);
console.log(currentNode);
console.log(component);
let index = 0;
if (component.includes("[")) {
index = parseInt(component.split("[")[0]) - 1;
currentNode = currentNode.childNodes[index];
console.assert(currentNode.getAttribute("id") === component.split("[")[1].split("]")[0], "failed to resolve node");
} else if (component.includes(":")) {
index = component.split(":")[0] - 1;
return currentNode.childNodes[index]; //exit point
} else {
index = parseInt(component);
currentNode = currentNode.childNodes[index - 1];
}
}
}
/**
* inserts missing text/element nodes to keep them alternating
* @param {*} parentNode
*/
validateChildNodes(parentNode) {
for (let index = 0; index < parentNode.childNodes.length;) {
const element = parentNode.childNodes[index];
if (index % 2 === 0 && element.nodeType === 1) {
element.parentNode.insertBefore(parentNode.ownerDocument.createTextNode(""), element);
continue;
}
if (index % 2 === 1 && element.nodeType === 3) {
element.insertBefore(parentNode.ownerDocument.createElement("")); //TODO check
continue;
}
index++;
}
} }
/** /**
takes the node that the cfi points at and counts the bytes of all nodes before that takes the node that the cfi points at and counts the bytes of all nodes before that
*/ */
getCurrentFileProgress(currentFile, CFI) { getCurrentFileProgress(CFI) {
let size = 0 let size = parseInt(CFI.split(":")[1])//text offset in node
let startnode = this.cfiToXmlNode(currentFile,CFI); let startnode = this.cfiToXmlNode(CFI); //returns text node
let prev = startnode.previousElementSibling; let xmlnsLength = startnode.parentNode.namespaceURI.length;
let prev = startnode.parentNode.previousElementSibling;
while (prev !== null) { while (prev !== null) {
size += this.encoder.encode(prev.outerHTML).length; console.log("size: "+size)
console.log(prev.outerHTML)
console.log(this.encoder.encode(prev.outerHTML).length - xmlnsLength)
size += this.encoder.encode(prev.outerHTML).length - xmlnsLength;
prev = prev.previousElementSibling; prev = prev.previousElementSibling;
} }
let parent = startnode.parentElement; let parent = startnode.parentElement.parentElement;
while (parent !== null) { while (parent !== null) {
let parentPrev = parent.previousElementSibling; let parentPrev = parent.previousElementSibling;
while (parentPrev !== null) { while (parentPrev !== null) {
size += this.encoder.encode(parentPrev.outerHTML).length; console.log(parentPrev.outerHTML)
console.log(this.encoder.encode(parentPrev.outerHTML).length - xmlnsLength)
size += this.encoder.encode(parentPrev.outerHTML).length - xmlnsLength;
parentPrev = parentPrev.previousElementSibling; parentPrev = parentPrev.previousElementSibling;
} }
parent = parent.parentElement; parent = parent.parentElement;
@ -106,7 +162,7 @@ class EpubParser {
} }
getProgress(currentFile, CFI) { getProgress(currentFile, CFI) {
let percentage = this.getTotalByteLength() / (this.getPreviousFilesSize(currentFile) + this.getCurrentFileProgress(currentFile, CFI)); let percentage = this.getTotalByteLength() / (this.getPreviousFilesSize(currentFile) + this.getCurrentFileProgress(CFI));
if (percentage === Infinity) { if (percentage === Infinity) {
return 0; return 0;
} else { } else {
@ -114,3 +170,5 @@ class EpubParser {
} }
} }
} }
e = new EpubParser(reader.book.archive.zip.files)