From 0d13f9d412890db242799cd0c57ffb7007bb74e1 Mon Sep 17 00:00:00 2001 From: Protected Date: Wed, 28 May 2025 16:52:44 +0100 Subject: [PATCH 1/2] Adds book format identifier string to the book interface. --- README.md | 1 + comic-book.js | 1 + epub.js | 1 + fb2.js | 2 ++ mobi.js | 2 ++ pdf.js | 1 + 6 files changed, 8 insertions(+) diff --git a/README.md b/README.md index a3fe2d5..d168f5d 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,7 @@ It is therefore imperative that you use [Content Security Policy (CSP)](https:// ### The Main Interface for Books Processors for each book format return an object that implements the following interface: +- `.type`: a string that identifies the book format. - `.sections`: an array of sections in the book. Each item has the following properties: - `.load()`: returns a string containing the URL that will be rendered. May be async. - `.unload()`: returns nothing. If present, can be used to free the section. diff --git a/comic-book.js b/comic-book.js index 88c7a35..83b7a92 100644 --- a/comic-book.js +++ b/comic-book.js @@ -24,6 +24,7 @@ export const makeComicBook = ({ entries, loadBlob, getSize }, file) => { if (!files.length) throw new Error('No supported image files in archive') const book = {} + Object.defineProperty(book, "type", {get: () => 'comic-book'}) book.getCover = () => loadBlob(files[0]) book.metadata = { title: file.name } book.sections = files.map(name => ({ diff --git a/epub.js b/epub.js index ea6e91a..0cde19e 100644 --- a/epub.js +++ b/epub.js @@ -930,6 +930,7 @@ export class EPUB { this.getSize = getSize this.#encryption = new Encryption(deobfuscators(sha1)) } + get type() { return 'epub'; } async #loadXML(uri) { const str = await this.loadText(uri) if (!str) return null diff --git a/fb2.js b/fb2.js index ce9bdc0..af8c097 100644 --- a/fb2.js +++ b/fb2.js @@ -231,6 +231,8 @@ const dataID = 'data-foliate-id' export const makeFB2 = async blob => { const book = {} + Object.defineProperty(book, "type", {get: () => 'fb2'}) + const doc = await parseXML(blob) const converter = new FB2Converter(doc) diff --git a/mobi.js b/mobi.js index 116477d..dae6958 100644 --- a/mobi.js +++ b/mobi.js @@ -670,6 +670,7 @@ class MOBI6 { constructor(mobi) { this.mobi = mobi } + get type() { return 'mobi'; } async init() { // load all text records in an array let array = new Uint8Array() @@ -940,6 +941,7 @@ class KF8 { constructor(mobi) { this.mobi = mobi } + get type() { return 'kf8'; } async init() { const loadRecord = this.mobi.loadRecord.bind(this.mobi) const { kf8 } = this.mobi.headers diff --git a/pdf.js b/pdf.js index 5abf583..04adb1d 100644 --- a/pdf.js +++ b/pdf.js @@ -119,6 +119,7 @@ export const makePDF = async file => { }).promise const book = { rendition: { layout: 'pre-paginated' } } + Object.defineProperty(book, "type", {get: () => 'pdf'}) const { metadata, info } = await pdf.getMetadata() ?? {} // TODO: for better results, parse `metadata.getRaw()` From 473b003932e50977cb449adba3390ed121fc3fe6 Mon Sep 17 00:00:00 2001 From: Protected Date: Fri, 30 May 2025 16:07:53 +0100 Subject: [PATCH 2/2] Moved book format identifier assignment to makeBook. --- comic-book.js | 1 - epub.js | 1 - fb2.js | 1 - mobi.js | 2 -- pdf.js | 1 - view.js | 7 +++++++ 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/comic-book.js b/comic-book.js index 83b7a92..88c7a35 100644 --- a/comic-book.js +++ b/comic-book.js @@ -24,7 +24,6 @@ export const makeComicBook = ({ entries, loadBlob, getSize }, file) => { if (!files.length) throw new Error('No supported image files in archive') const book = {} - Object.defineProperty(book, "type", {get: () => 'comic-book'}) book.getCover = () => loadBlob(files[0]) book.metadata = { title: file.name } book.sections = files.map(name => ({ diff --git a/epub.js b/epub.js index 0cde19e..ea6e91a 100644 --- a/epub.js +++ b/epub.js @@ -930,7 +930,6 @@ export class EPUB { this.getSize = getSize this.#encryption = new Encryption(deobfuscators(sha1)) } - get type() { return 'epub'; } async #loadXML(uri) { const str = await this.loadText(uri) if (!str) return null diff --git a/fb2.js b/fb2.js index af8c097..722b852 100644 --- a/fb2.js +++ b/fb2.js @@ -231,7 +231,6 @@ const dataID = 'data-foliate-id' export const makeFB2 = async blob => { const book = {} - Object.defineProperty(book, "type", {get: () => 'fb2'}) const doc = await parseXML(blob) const converter = new FB2Converter(doc) diff --git a/mobi.js b/mobi.js index dae6958..116477d 100644 --- a/mobi.js +++ b/mobi.js @@ -670,7 +670,6 @@ class MOBI6 { constructor(mobi) { this.mobi = mobi } - get type() { return 'mobi'; } async init() { // load all text records in an array let array = new Uint8Array() @@ -941,7 +940,6 @@ class KF8 { constructor(mobi) { this.mobi = mobi } - get type() { return 'kf8'; } async init() { const loadRecord = this.mobi.loadRecord.bind(this.mobi) const { kf8 } = this.mobi.headers diff --git a/pdf.js b/pdf.js index 04adb1d..5abf583 100644 --- a/pdf.js +++ b/pdf.js @@ -119,7 +119,6 @@ export const makePDF = async file => { }).promise const book = { rendition: { layout: 'pre-paginated' } } - Object.defineProperty(book, "type", {get: () => 'pdf'}) const { metadata, info } = await pdf.getMetadata() ?? {} // TODO: for better results, parse `metadata.getRaw()` diff --git a/view.js b/view.js index 55c818f..a833ac6 100644 --- a/view.js +++ b/view.js @@ -83,6 +83,7 @@ export const makeBook = async file => { const loader = await makeDirectoryLoader(file) const { EPUB } = await import('./epub.js') book = await new EPUB(loader).init() + book.type = 'epub' } else if (!file.size) throw new NotFoundError('File not found') else if (await isZip(file)) { @@ -90,6 +91,7 @@ export const makeBook = async file => { if (isCBZ(file)) { const { makeComicBook } = await import('./comic-book.js') book = makeComicBook(loader, file) + book.type = 'comic-book' } else if (isFBZ(file)) { const { makeFB2 } = await import('./fb2.js') @@ -97,25 +99,30 @@ export const makeBook = async file => { const entry = entries.find(entry => entry.filename.endsWith('.fb2')) const blob = await loader.loadBlob((entry ?? entries[0]).filename) book = await makeFB2(blob) + book.type = 'fb2' } else { const { EPUB } = await import('./epub.js') book = await new EPUB(loader).init() + book.type = 'epub' } } else if (await isPDF(file)) { const { makePDF } = await import('./pdf.js') book = await makePDF(file) + book.type = 'pdf' } else { const { isMOBI, MOBI } = await import('./mobi.js') if (await isMOBI(file)) { const fflate = await import('./vendor/fflate.js') book = await new MOBI({ unzlib: fflate.unzlibSync }).open(file) + book.type = 'mobi' } else if (isFB2(file)) { const { makeFB2 } = await import('./fb2.js') book = await makeFB2(file) + book.type = 'fb2' } } if (!book) throw new UnsupportedTypeError('File type not supported')