diff --git a/src/foliate-js b/src/foliate-js index ae61c5e8..022ea7da 160000 --- a/src/foliate-js +++ b/src/foliate-js @@ -1 +1 @@ -Subproject commit ae61c5e85fb31ff4f46cd6bc74ebc6ac5971cca8 +Subproject commit 022ea7da8787c397976042e4f7c743c0cd5a097c diff --git a/src/reader/reader.js b/src/reader/reader.js index 5c4731d0..34a6d22b 100644 --- a/src/reader/reader.js +++ b/src/reader/reader.js @@ -1,4 +1,4 @@ -import '../foliate-js/view.js' +import { makeBook, NotFoundError, UnsupportedTypeError } from '../foliate-js/view.js' import { Overlayer } from '../foliate-js/overlayer.js' import { FootnoteHandler } from '../foliate-js/footnotes.js' import { toPangoMarkup } from './markup.js' @@ -48,90 +48,21 @@ const getHTML = async range => { return new XMLSerializer().serializeToString(fragment) } -const isZip = async file => { - const arr = new Uint8Array(await file.slice(0, 4).arrayBuffer()) - return arr[0] === 0x50 && arr[1] === 0x4b && arr[2] === 0x03 && arr[3] === 0x04 -} - -const isPDF = async file => { - const arr = new Uint8Array(await file.slice(0, 5).arrayBuffer()) - return arr[0] === 0x25 - && arr[1] === 0x50 && arr[2] === 0x44 && arr[3] === 0x46 - && arr[4] === 0x2d -} - -const makeZipLoader = async file => { - const { configure, ZipReader, BlobReader, TextWriter, BlobWriter } = - await import('../foliate-js/vendor/zip.js') - configure({ useWebWorkers: false }) - const reader = new ZipReader(new BlobReader(file)) - const entries = await reader.getEntries() - const map = new Map(entries.map(entry => [entry.filename, entry])) - const load = f => (name, ...args) => - map.has(name) ? f(map.get(name), ...args) : null - const loadText = load(entry => entry.getData(new TextWriter())) - const loadBlob = load((entry, type) => entry.getData(new BlobWriter(type))) - const getSize = name => map.get(name)?.uncompressedSize ?? 0 - return { entries, loadText, loadBlob, getSize } -} - -const isCBZ = ({ name, type }) => - type === 'application/vnd.comicbook+zip' || name.endsWith('.cbz') - -const isFB2 = ({ name, type }) => - type === 'application/x-fictionbook+xml' || name.endsWith('.fb2') - -const isFBZ = ({ name, type }) => - type === 'application/x-zip-compressed-fb2' - || name.endsWith('.fb2.zip') || name.endsWith('.fbz') - const open = async file => { - if (!file.size) { - emit({ type: 'book-error', id: 'not-found' }) - return + try { + const book = await makeBook(file) + const reader = new Reader(book) + globalThis.reader = reader + await reader.init() + emit({ type: 'book-ready', book, reader }) } - - let book - if (await isZip(file)) { - const loader = await makeZipLoader(file) - const { entries } = loader - if (isCBZ(file)) { - const { makeComicBook } = await import('../foliate-js/comic-book.js') - book = makeComicBook(loader, file) - } else if (isFBZ(file)) { - const { makeFB2 } = await import('../foliate-js/fb2.js') - const entry = entries.find(entry => entry.filename.endsWith('.fb2')) - const blob = await loader.loadBlob((entry ?? entries[0]).filename) - book = await makeFB2(blob) - } else { - const { EPUB } = await import('../foliate-js/epub.js') - book = await new EPUB(loader).init() - } - } - else if (await isPDF(file)) { - const { makePDF } = await import('../foliate-js/pdf.js') - book = await makePDF(file) - } - else { - const { isMOBI, MOBI } = await import('../foliate-js/mobi.js') - if (await isMOBI(file)) { - const fflate = await import('../foliate-js/vendor/fflate.js') - book = await new MOBI({ unzlib: fflate.unzlibSync }).open(file) - } else if (isFB2(file)) { - const { makeFB2 } = await import('../foliate-js/fb2.js') - book = await makeFB2(file) - } - } - - if (!book) { - emit({ type: 'book-error', id: 'unsupported-type' }) - return + catch (e) { + if (e instanceof NotFoundError) + emit({ type: 'book-error', id: 'not-found' }) + else if (e instanceof UnsupportedTypeError) + emit({ type: 'book-error', id: 'unsupported-type' }) + else throw e } - - const reader = new Reader(book) - globalThis.reader = reader - await reader.init() - emit({ type: 'book-ready', book, reader }) } const getCSS = ({