diff --git a/plugin/js/Library.js b/plugin/js/Library.js
index 7e477883..1c02077c 100644
--- a/plugin/js/Library.js
+++ b/plugin/js/Library.js
@@ -565,6 +565,7 @@ class Library { // eslint-disable-line no-unused-vars
let LibTemplateMetadataSubject = document.getElementById("LibTemplateMetadataSubject").innerHTML;
let LibTemplateMetadataDescription = document.getElementById("LibTemplateMetadataDescription").innerHTML;
let LibTemplateMetadataPublisher = document.getElementById("LibTemplateMetadataPublisher").innerHTML;
+ let LibTemplateMetadataCoverImageUrl = document.getElementById("LibTemplateMetadataCoverImageUrl").innerHTML;
let LibRenderResult = document.getElementById("LibRenderMetadata" + objbtn.dataset.libepubid);
let LibMetadata = await Library.LibGetMetadata(objbtn.dataset.libepubid);
let LibRenderString = "";
@@ -604,6 +605,10 @@ class Library { // eslint-disable-line no-unused-vars
LibRenderString += "
"+LibTemplateMetadataPublisher+" | ";
LibRenderString += " | ";
LibRenderString += "";
+ LibRenderString += "";
+ LibRenderString += "| "+LibTemplateMetadataCoverImageUrl+" | ";
+ LibRenderString += " | ";
+ LibRenderString += "
";
LibRenderString += "";
LibRenderString += "";
LibRenderString += "";
@@ -631,7 +636,33 @@ class Library { // eslint-disable-line no-unused-vars
let LibSubjectInput = document.getElementById("LibSubjectInput"+obj.dataset.libepubid).value;
let LibDescriptionInput = document.getElementById("LibDescriptionInput"+obj.dataset.libepubid).value;
let LibPublisherInput = document.getElementById("LibPublisherInput"+obj.dataset.libepubid).value;
+ let LibCoverImageUrlInput = document.getElementById("LibCoverImageUrlInput"+obj.dataset.libepubid).value;
Library.LibShowLoadingText();
+
+ let newCoverBlob = null;
+ let newCoverMimeType = null;
+
+ // Update cover image in storage if a new URL was provided
+ if (LibCoverImageUrlInput.trim() !== "") {
+ try {
+ let response = await fetch(LibCoverImageUrlInput);
+ newCoverBlob = await response.blob();
+ newCoverMimeType = newCoverBlob.type;
+ let reader = new FileReader();
+ let coverDataUrl = await new Promise((resolve, reject) => {
+ reader.onload = () => resolve(reader.result);
+ reader.onerror = reject;
+ reader.readAsDataURL(newCoverBlob);
+ });
+ chrome.storage.local.set({
+ ["LibCover" + obj.dataset.libepubid]: coverDataUrl
+ });
+ } catch {
+ // If fetching the image fails, continue with the metadata save
+ newCoverBlob = null;
+ }
+ }
+
let LibDateCreated = new EpubPacker().getDateForMetaData();
try {
let EpubReader = await new zip.Data64URIReader(await Library.LibGetFromStorage("LibEpub"+obj.dataset.libepubid));
@@ -639,14 +670,104 @@ class Library { // eslint-disable-line no-unused-vars
let EpubContent = await EpubZipRead.getEntries();
EpubContent = EpubContent.filter(a => a.directory == false);
let opfFile = await EpubContent.filter(a => a.filename == "OEBPS/content.opf")[0].getData(new zip.TextWriter());
+
+ // Handle new cover embedding in EPUB
+ let oldCoverimgPath = null;
+ let newCoverimgPath = null;
+ let coverXhtmlFile = EpubContent.filter(a => a.filename == "OEBPS/Text/Cover.xhtml");
+
+ if (newCoverBlob != null) {
+ let extension = "jpg";
+ if (newCoverMimeType && newCoverMimeType.includes("png")) {
+ extension = "png";
+ } else if (newCoverMimeType && newCoverMimeType.includes("gif")) {
+ extension = "gif";
+ } else if (newCoverMimeType && newCoverMimeType.includes("webp")) {
+ extension = "webp";
+ }
+
+ if (coverXhtmlFile.length > 0) {
+ try {
+ let Coverxml = await coverXhtmlFile[0].getData(new zip.TextWriter());
+ let match = Coverxml.match(/"..\/Images\/000.+?"/);
+ if (match) {
+ oldCoverimgPath = "OEBPS" + match[0].replace(/"../, "").replace("\"", "");
+ let baseName = oldCoverimgPath.substring(0, oldCoverimgPath.lastIndexOf("."));
+ newCoverimgPath = baseName + "." + extension;
+
+ let oldHref = oldCoverimgPath.replace("OEBPS/", "");
+ let newHref = newCoverimgPath.replace("OEBPS/", "");
+
+ // Update OPF
+ let itemRegexStr = "- ]+href=\"" + oldHref.replace(/\./g, "\\.") + "\"[^>]*>";
+ let itemRegex = new RegExp(itemRegexStr, "g");
+ let itemMatch = opfFile.match(itemRegex);
+ if (itemMatch) {
+ let oldItem = itemMatch[0];
+ let newItem = oldItem.replace(oldHref, newHref);
+ if (newCoverMimeType) {
+ newItem = newItem.replace(/media-type="[^"]+"/, "media-type=\"" + newCoverMimeType + "\"");
+ }
+ opfFile = opfFile.replace(oldItem, newItem);
+ }
+
+ // Update Cover.xhtml
+ let oldSrc = oldHref.replace("Images/", "../Images/");
+ let newSrc = newHref.replace("Images/", "../Images/");
+ coverXhtmlFile[0].newXmlData = Coverxml.replace(oldSrc, newSrc);
+ }
+ } catch (e) {
+ // Ignore if cover modification fails
+ oldCoverimgPath = null;
+ newCoverimgPath = null;
+ }
+ } else {
+ // EPUB had no cover previously, inject one
+ newCoverimgPath = "OEBPS/Images/0000_cover." + extension;
+
+ let newManifestItems = `\n
\n \n`;
+ opfFile = opfFile.replace("", "" + newManifestItems);
+
+ opfFile = opfFile.replace(/]*>/, "$&\n\n");
+
+ if (opfFile.includes("")) {
+ opfFile = opfFile.replace("", "\n\n");
+ } else {
+ opfFile = opfFile.replace("", "\n\n\n");
+ }
+
+ opfFile = opfFile.replace(/]*>/, "$&\n\n");
+
+ let newCoverxml = `\n\n\n\n Cover\n\n\n \n

\n
\n\n`;
+
+ coverXhtmlFile = [{
+ filename: "OEBPS/Text/Cover.xhtml",
+ newXmlData: newCoverxml
+ }];
+ }
+ }
let EpubWriter = new zip.BlobWriter("application/epub+zip");
let EpubZipWrite = new zip.ZipWriter(EpubWriter,{useWebWorkers: false,compressionMethod: 8});
//Copy Epub in NewEpub
for (let element of EpubContent.filter(a => a.filename != "OEBPS/content.opf")) {
+ if (oldCoverimgPath != null && element.filename === oldCoverimgPath) {
+ continue; // Skip old image
+ }
+ if (newCoverBlob != null && element.filename === "OEBPS/Text/Cover.xhtml") {
+ // Original cover existed, skip adding it here (we add the modified one below)
+ continue;
+ }
EpubZipWrite.add(element.filename, new zip.BlobReader(await element.getData(new zip.BlobWriter())));
}
+ if (newCoverBlob != null && newCoverimgPath != null) {
+ EpubZipWrite.add(newCoverimgPath, new zip.BlobReader(newCoverBlob));
+ }
+ if (newCoverBlob != null && coverXhtmlFile.length > 0 && coverXhtmlFile[0].newXmlData) {
+ EpubZipWrite.add(coverXhtmlFile[0].filename, new zip.TextReader(coverXhtmlFile[0].newXmlData));
+ }
+
let regex1 = opfFile.match(new RegExp(".+?", "gs"));
if ( regex1 == null) {
ErrorLog.showErrorMessage(UIText.Error.errorEditMetadata);
diff --git a/plugin/popup.html b/plugin/popup.html
index 5a73dfb9..846625c8 100644
--- a/plugin/popup.html
+++ b/plugin/popup.html
@@ -244,6 +244,9 @@ Instructions
| __MSG_label_Metadata_publisher__ |
+
+ | __MSG_label_Cover_Image_URL__ |
+