### Minimal Setup for Foliate.js View Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/quick-reference.md Demonstrates the basic steps to create, append, and open a book with the foliate-view element. Includes an example of listening for relocation events and navigating. ```javascript import { View } from './foliate-js/view.js' // Create and display const view = document.createElement('foliate-view') document.body.append(view) // Load book await view.open('book.epub') // Listen for progress view.addEventListener('relocate', e => { console.log(`${e.detail.index}: ${Math.round(e.detail.fraction * 100)}%`) }) // Navigate await view.goTo(0) await view.next() ``` -------------------------------- ### makeBook Example Usage Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/view.md An example demonstrating how to use the makeBook function to create a book object from a File object. ```javascript import { makeBook } from './view.js' const file = new File([/* ... */], 'book.epub', { type: 'application/epub+zip' }) const book = await makeBook(file) ``` -------------------------------- ### MOBI File Check and Open Example Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/mobi-fb2-comic.md Example demonstrating how to check if a file is MOBI, instantiate the MOBI parser, open the file, and access its metadata. ```javascript import { MOBI, isMOBI } from './mobi.js' if (await isMOBI(file)) { const mobi = new MOBI({ unzlib: window.fflate.unzlibSync }) await mobi.open(file) console.log('Title:', mobi.metadata.title) } ``` -------------------------------- ### FictionBook 2 Parsing and Opening Example Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/mobi-fb2-comic.md Example showing how to fetch an FB2 file, parse it using makeFB2, and then open it in a viewer. ```javascript import { makeFB2 } from './fb2.js' const blob = await fetch('book.fb2').then(r => r.blob()) const book = await makeFB2(blob) console.log('Title:', book.metadata.title) console.log('Sections:', book.sections.length) // Navigate to first section await view.open(book) await view.goTo(0) ``` -------------------------------- ### Beginner Usage Example Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/README.md Shows the minimal code required to initialize and open a book using the View element. ```javascript import { View } from './foliate-js/view.js' const view = document.createElement('foliate-view') document.body.append(view) await view.open('book.epub') ``` -------------------------------- ### Overlayer Usage Example Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/utilities.md Demonstrates how to use the Overlayer class to add, manage, and detect clicks on various types of overlays. Includes examples for highlighting, underlining, custom drawing, and hit testing. ```javascript import { Overlayer } from './overlayer.js' const overlayer = new Overlayer() // Add highlight const range = document.createRange() range.selectNodeContents(someElement) overlayer.add('highlight-1', range, Overlayer.highlight, { color: 'yellow' }) // Add underline with custom color overlayer.add('underline-1', range, Overlayer.underline, { color: 'red', width: 2 }) // Custom draw function overlayer.add('custom', range, (rects, options) => { const g = document.createElementNS('http://www.w3.org/2000/svg', 'g') for (const rect of rects) { // Custom drawing logic } return g }) // Detect click on overlay document.addEventListener('click', e => { const [key, range] = overlayer.hitTest(e) if (key) { console.log('Clicked overlay:', key) } }) // Remove overlay overlayer.remove('highlight-1') // Redraw after zoom/resize overlayer.redraw() ``` -------------------------------- ### Usage Example for DictZip Loading Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/errors.md Demonstrates how to load a DictZip dictionary and catch potential loading errors. ```javascript try { const dict = new DictdDict() await dict.loadDict(file, inflate) } catch (e) { console.error('Dictionary error:', e) } ``` -------------------------------- ### EPUB Loader Interface Example Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/epub.md Demonstrates how to create a loader object from a ZIP file using zip.js for the EPUB parser. ```javascript import { EPUB } from './epub.js' import { ZipReader, BlobReader, TextWriter, BlobWriter } from 'zip.js' // Create loader from ZIP file const reader = new ZipReader(new BlobReader(epubFile)) const entries = await reader.getEntries() const map = new Map(entries.map(e => [e.filename, e])) const loader = { entries, loadText: (name) => map.get(name)?.getData(new TextWriter()), loadBlob: (name, type) => map.get(name)?.getData(new BlobWriter(type)), getSize: (name) => map.get(name)?.uncompressedSize ?? 0, } const epub = new EPUB(loader) ``` -------------------------------- ### Paginator Usage Example Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/paginator.md Demonstrates initializing the paginator, configuring headers, listening for reading progress, opening a book, switching display modes, and basic navigation. ```javascript import { Paginator } from './paginator.js' import { makeBook } from './view.js' // Create paginator const paginator = document.createElement('foliate-paginator') paginator.setAttribute('animated', '') paginator.setAttribute('flow', 'paginated') paginator.setAttribute('gap', '5%') paginator.setAttribute('max-inline-size', '800px') document.body.append(paginator) // Configure headers/footers paginator.addEventListener('load', e => { const { doc, index } = e.detail if (paginator.heads.length) { paginator.heads[0].textContent = doc.title || `Page ${index}` } }) // Listen for reading progress paginator.addEventListener('relocate', e => { const { index, fraction, range } = e.detail const startNode = range.startContainer saveProgress({ index, fraction, text: startNode.textContent }) }) // Open book const book = await makeBook('book.epub') await paginator.open(book) // Switch between paginated and scrolled document.querySelector('#toggle-scroll').addEventListener('click', () => { const current = paginator.getAttribute('flow') || 'paginated' const next = current === 'paginated' ? 'scrolled' : 'paginated' paginator.setAttribute('flow', next) }) // Navigate await paginator.goTo({ index: 0 }) document.querySelector('#next').addEventListener('click', () => paginator.next()) document.querySelector('#prev').addEventListener('click', () => paginator.prev()) ``` -------------------------------- ### Dual-Pane Display Setup Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/quick-reference.md Illustrates setting up a dual-pane display using `foliate-fixed-layout` elements. It shows how to synchronize navigation between the two panes. ```javascript const left = document.createElement('foliate-fixed-layout') const right = document.createElement('foliate-fixed-layout') left.spread = 'left' right.spread = 'right' // Sync navigation left.addEventListener('load', () => right.goTo(/* ... */)) ``` -------------------------------- ### JavaScript Object Example Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/README.md Demonstrates the actual usage pattern for a book object in JavaScript. ```javascript const book = { sections: [/* ... */], metadata: { title: '...' }, toc: [/* ... */] } ``` -------------------------------- ### Text-to-Speech (TTS) Integration Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/quick-reference.md Provides an example of using the TTS utility to get text fragments with marks and generate SSML. It outlines how to then use the browser's SpeechSynthesis API to speak the text. ```javascript import { getFragmentWithMarks } from './tts.js' const { entries, ssml } = getFragmentWithMarks(range, textWalker, 'word') // Convert SSML to audio with your TTS engine const audio = await window.speechSynthesis.speak( new SpeechSynthesisUtterance(ssml.documentElement.textContent) ) ``` -------------------------------- ### EPUB Book Handler Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/quick-reference.md Provides an example of how to load and initialize an EPUB book using the EPUB handler. It shows how to access book metadata and table of contents. ```javascript import { EPUB } from './epub.js' const loader = await createZipLoader(epubFile) const epub = new EPUB(loader) await epub.init() console.log(epub.metadata.title) console.log(epub.toc) await view.open(epub) ``` -------------------------------- ### View Element API Examples Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/quick-reference.md Illustrates common tasks performed with the View element, such as opening files or URLs, navigating sections, and listening for events. ```javascript await view.open(file) ``` ```javascript await view.open('http://...') ``` ```javascript await view.goTo(5) ``` ```javascript await view.goTo('epubcfi(/6/4!/4)') ``` ```javascript await view.next() ``` ```javascript await view.prev() ``` ```javascript view.addEventListener('relocate', e => {}) ``` -------------------------------- ### MOBI/KF8 Book Handler Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/quick-reference.md Illustrates the setup for handling MOBI/KF8 book formats, including the necessary import and initialization with a decompression function. ```javascript import { MOBI } from './mobi.js' import { unzlibSync } from 'fflate' const mobi = new MOBI({ unzlib: unzlibSync }) await mobi.open(file) ``` -------------------------------- ### Progressive Loading Example Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/quick-reference.md Demonstrates how to progressively load book sections and navigate after the book is opened. Listen for the 'load' event to show loading indicators and 'relocate' to perform actions after initial loading. ```javascript const view = document.createElement('foliate-view') document.body.append(view) // Show loading indicator view.addEventListener('load', () => { console.log('Section loaded') }) // Navigate after book opens view.addEventListener('relocate', async (e) => { if (e.detail.index === 0 && e.detail.fraction === 0) { // Book just opened, now safe to navigate setTimeout(() => view.goTo(savedLocation), 0) } }) await view.open(book) ``` -------------------------------- ### Handle NotFoundError Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/errors.md Example of catching a NotFoundError to gracefully handle cases where a file is not found. ```javascript try { const file = /* ... */ await view.open(file) } catch (e) { if (e instanceof NotFoundError) { console.error('File not found:', e.message) } } ``` -------------------------------- ### TypeScript Interface Example Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/README.md Illustrates the type notation used for defining book structures in TypeScript. ```typescript interface Book { sections: Section[] metadata: Metadata toc: TOCItem[] } ``` -------------------------------- ### Fixed Layout Element Setup Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/quick-reference.md Demonstrates the creation and initialization of a foliate-fixed-layout element, which is used for displaying books with a fixed layout. It supports various zoom levels. ```javascript const viewer = document.createElement('foliate-fixed-layout') viewer.setAttribute('zoom', 'fit-width') document.body.append(viewer) await viewer.open(book) ``` -------------------------------- ### Load StarDict Dictionary Example Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/utilities.md Loads a StarDict dictionary from files. Requires metadata, dictionary data, and index files. An optional decompression function is needed for compressed dictionary data. ```javascript import { StarDict } from './dict.js' import { inflate } from 'fflate' // or other inflate impl const dict = new StarDict() await dict.loadIfo(ifoFile) await dict.loadDict(dzFile, inflate) await dict.loadIdx(idxFile) const results = await dict.lookup('hello') results.forEach(({ word, data }) => { console.log(`${word}:`, data) }) ``` -------------------------------- ### Handle UnsupportedTypeError Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/errors.md Example of catching an UnsupportedTypeError to inform the user about unsupported file formats. ```javascript try { const file = /* unknown format */ await view.open(file) } catch (e) { if (e instanceof UnsupportedTypeError) { console.error('Format not supported:', e.message) // Show user a list of supported formats } } ``` -------------------------------- ### View Component Usage Example Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/view.md Demonstrates how to create, append, and interact with a foliate-view element. Includes event listeners for loading and navigation, opening a book, navigating to specific locations, and saving/restoring the current location. ```javascript import { View } from './view.js' // Create and append view element const view = document.createElement('foliate-view') document.body.append(view) // Listen for loading and navigation view.addEventListener('load', e => { console.log('Section loaded:', e.detail.index) }) view.addEventListener('relocate', e => { const percent = Math.round(e.detail.fraction * 100) console.log(`At ${percent}% of section ${e.detail.index}`) }) // Open and navigate const file = await fetch('book.epub').then(r => r.blob()) await view.open(file) await view.goTo(0) // Get current location for saving const loc = view.getCurrentLocation() localStorage.setItem('lastLocation', JSON.stringify(loc)) // Restore last location const saved = JSON.parse(localStorage.getItem('lastLocation')) await view.goTo(saved) ``` -------------------------------- ### Example CFI Strings Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/epubcfi.md Illustrates various valid CFI string formats, including basic locations, text assertions, temporal/spatial offsets, ranges, and escape sequences. ```text epubcfi(/6/4!/4) // 4th char in 4th child of 6th child epubcfi(/6/4!/4[chapter]) // With element ID epubcfi(/6/4!,/2/4) // Range CFI ``` -------------------------------- ### Set FixedLayout Zoom Attribute Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/fixed-layout.md Provides an example of setting the zoom attribute for a FixedLayout element in HTML. ```html ``` -------------------------------- ### EPUB Class Constructor Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/epub.md Initializes a new EPUB parser instance with a provided loader object. The loader must implement methods for loading text and blobs, getting file sizes, and optionally provide a list of entries. ```APIDOC ## new EPUB(loader) ### Description Initializes a new EPUB parser instance. ### Parameters #### Path Parameters - **loader** (object) - Required - Loader object implementing the archive loader interface. The loader interface requires `loadText(filename)`, `loadBlob(filename)`, `getSize(filename)`, and optionally `entries`. ### Request Example ```javascript import { EPUB } from './epub.js' import { ZipReader, BlobReader, TextWriter, BlobWriter } from 'zip.js' const reader = new ZipReader(new BlobReader(epubFile)) const entries = await reader.getEntries() const map = new Map(entries.map(e => [e.filename, e])) const loader = { entries, loadText: (name) => map.get(name)?.getData(new TextWriter()), loadBlob: (name, type) => map.get(name)?.getData(new BlobWriter(type)), getSize: (name) => map.get(name)?.uncompressedSize ?? 0, } const epub = new EPUB(loader) ``` ``` -------------------------------- ### Custom Inflate Function for StarDict Source: https://github.com/johnfactotum/foliate-js/blob/main/README.md Example of a custom inflate function using fflate for loading StarDict dictionaries. This function should be passed to the StarDict constructor. ```javascript const inflate = data => new Promise(resolve => { const inflate = new fflate.Inflate() inflate.ondata = data => resolve(data) inflate.push(data) }) ``` -------------------------------- ### Handle EPUB Parse Errors Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/errors.md Example of catching general EPUB parsing errors that may occur due to invalid document structure. ```javascript try { const epub = new EPUB(loader) await epub.init() } catch (e) { console.error('EPUB parse error:', e) } ``` -------------------------------- ### Print and Navigate Table of Contents Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/quick-reference.md Recursively prints the table of contents (TOC) with indentation and provides an example of navigating to a specific TOC item. ```javascript const printTOC = (items, level = 0) => { for (const item of items) { const indent = ' '.repeat(level) console.log(`${indent}${item.label}`) if (item.subitems) printTOC(item.subitems, level + 1) } } printTOC(book.toc) // Navigate to TOC item const tocItem = book.toc[0] const location = book.resolveHref(tocItem.href) await view.goTo(location) ``` -------------------------------- ### Paginator Element Setup and Attributes Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/quick-reference.md Shows how to create and configure a foliate-paginator element, including setting flow, layout, and margin attributes. The paginator is used for paginated book display. ```javascript const paginator = document.createElement('foliate-paginator') paginator.setAttribute('flow', 'paginated') paginator.setAttribute('max-inline-size', '800px') paginator.setAttribute('max-column-count', '2') document.body.append(paginator) await paginator.open(book) ``` -------------------------------- ### Text Search Utility Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/quick-reference.md Example of using the search utility to find occurrences of a query within an array of text. It demonstrates how to configure search parameters and iterate over results. ```javascript import { search } from './search.js' const results = Array.from(search(textArray, 'query', { locales: 'en', granularity: 'word', sensitivity: 'base', })) for (const { range, excerpt } of results) { console.log(excerpt.match) } ``` -------------------------------- ### Configure Paginator with HTML Attributes Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/paginator.md Example of configuring the paginator using HTML attributes directly in the element tag. This sets display modes, margins, gaps, and size constraints. ```html ``` -------------------------------- ### Create Custom Book Loader Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/configuration.md Defines a custom loader object with methods for loading text, blobs, and getting file sizes, which can be passed to book parsers like EPUB. ```javascript const loader = { loadText: async (filename) => { /* ... */ }, loadBlob: async (filename, type) => { /* ... */ }, getSize: (filename) => { /* ... */ }, entries: [ /* array of { filename } */ ] // Optional } const epub = new EPUB(loader) ``` -------------------------------- ### Debugging Foliate.js Events and Book Structure Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/quick-reference.md Provides examples for debugging Foliate.js applications by logging all events, inspecting book structure (sections, metadata, TOC), and checking CFI support. ```javascript // Log all events ['load', 'relocate', 'create-overlayer'].forEach(event => { view.addEventListener(event, e => console.log(event, e.detail)) }) // Inspect book structure console.table(book.sections) console.table(book.metadata) console.table(book.toc) ``` -------------------------------- ### Styling Paginator CSS Parts Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/paginator.md Provides examples of how to style specific parts of the paginator component using CSS pseudo-elements like `::part()`. This allows customization of the filter, head, and foot elements. ```css foliate-paginator::part(filter) { filter: invert(1); } foliate-paginator::part(head) { border-bottom: 1px solid gray; padding-bottom: 4px; font-size: 0.9em; } foliate-paginator::part(foot) { border-top: 1px solid gray; padding-top: 4px; } ``` -------------------------------- ### Reading Progress Tracking Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/quick-reference.md Shows how to use SectionProgress and TOCProgress to track reading progress within a book. It provides examples for getting progress information for a specific section and tracking the current TOC item. ```javascript import { SectionProgress, TOCProgress } from './progress.js' const progress = new SectionProgress(sections, 1500, 1600) const info = progress.getProgress(5, 0.75) // Section 5, 75% through console.log(info.fraction) // Overall progress 0-1 console.log(info.location.current) // Location number console.log(info.time.total) // Estimated minutes remaining // Track TOC item const tocProgress = new TOCProgress() await tocProgress.init({ toc, ids, splitHref, getFragment }) const currentTOCItem = tocProgress.getProgress(5, range) ``` -------------------------------- ### Initialize and Use EPUB Parser Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/epub.md Demonstrates the basic usage pattern for parsing an EPUB file, accessing its metadata, and navigating the table of contents. ```javascript import { EPUB } from './epub.js' // Create loader for ZIP file const loader = await createZipLoader(epubFile) // Parse EPUB const epub = new EPUB(loader) await epub.init() // Access metadata console.log('Title:', epub.metadata.title) console.log('Author:', epub.metadata.author[0]?.name) console.log('Language:', epub.metadata.language) // Explore table of contents function printTOC(items, level = 0) { for (const item of items) { console.log(' '.repeat(level) + item.label) if (item.subitems) printTOC(item.subitems, level + 1) } } printTOC(epub.toc) // Navigate using TOC const tocItem = epub.toc[2] const location = epub.resolveHref(tocItem.href) await view.goTo(location) // Check if link is external const link = 'https://example.com' if (epub.isExternal(link)) { window.open(link) } // Get progress info for TOC item const [sectionId, fragment] = await epub.splitTOCHref(tocItem.href) const el = epub.getTOCFragment(doc, fragment) ``` -------------------------------- ### Handle ResponseError Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/errors.md Example of catching a ResponseError and accessing its message (status) and cause (response object). ```javascript try { await view.open('https://example.com/book.epub') } catch (e) { if (e instanceof ResponseError) { console.error('Status:', e.message) console.error('Response object:', e.cause) } } ``` -------------------------------- ### EPUB.init() Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/epub.md Initializes the EPUB parser, extracts metadata, and prepares the book for use. This method should be called after creating an EPUB instance and before accessing book properties or methods. ```APIDOC ## EPUB.init() ### Description Initializes the EPUB parser and extracts metadata. ### Returns - Promise - Returns `this` for chaining. ### Throws - Error if EPUB is malformed. ### Request Example ```javascript const epub = new EPUB(loader) await epub.init() const book = epub ``` ``` -------------------------------- ### Initialize and Use FixedLayout Viewer Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/fixed-layout.md This snippet demonstrates how to create, configure, and interact with the FixedLayout viewer. It includes setting attributes, listening for page load events, opening a book, navigating pages, and implementing various zoom and spread controls. ```javascript import { FixedLayout } from './fixed-layout.js' import { makeBook } from './view.js' // Create fixed-layout viewer const viewer = document.createElement('foliate-fixed-layout') viewer.setAttribute('zoom', 'fit-width') viewer.spread = 'both' document.body.append(viewer) // Listen for page loads viewer.addEventListener('load', e => { console.log('Page', e.detail.index, 'loaded') }) // Open book (PDF, CBZ, etc.) const book = await makeBook('comic.cbz') await viewer.open(book) // Navigate await viewer.goTo({ index: 0 }) // Create navigation controls document.querySelector('#next-page').addEventListener('click', () => { viewer.next() }) document.querySelector('#prev-page').addEventListener('click', () => { viewer.prev() }) // Create zoom controls document.querySelector('#zoom-fit-width').addEventListener('click', () => { viewer.setAttribute('zoom', 'fit-width') }) document.querySelector('#zoom-fit-page').addEventListener('click', () => { viewer.setAttribute('zoom', 'fit-page') }) document.querySelector('#zoom-100').addEventListener('click', () => { viewer.setAttribute('zoom', '1') }) document.querySelector('#zoom-in').addEventListener('click', () => { const current = parseFloat(viewer.getAttribute('zoom')) || 1 viewer.setAttribute('zoom', String(current + 0.25)) }) document.querySelector('#zoom-out').addEventListener('click', () => { const current = parseFloat(viewer.getAttribute('zoom')) || 1 viewer.setAttribute('zoom', String(Math.max(0.25, current - 0.25))) }) // Change spread mode document.querySelector('#toggle-spread').addEventListener('click', () => { viewer.spread = viewer.spread === 'both' ? 'right' : 'both' }) ``` -------------------------------- ### Handle FictionBook Parse Errors Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/errors.md Example of catching FictionBook (FB2) parsing errors, which can arise from invalid XML or encoding issues. ```javascript try { const book = await makeFB2(blob) } catch (e) { console.error('FB2 parse error:', e) } ``` -------------------------------- ### EPUB Initialization Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/epub.md Initializes the EPUB parser to extract metadata and prepare the book object for use. Chaining is supported. ```javascript const epub = new EPUB(loader) await epub.init() const book = epub // Now book is ready to use ``` -------------------------------- ### Development Module Loading Strategy Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/module-map.md Shows how to use direct ESM imports for development without bundling, allowing for easier debugging and iteration. ```javascript // ESM direct import (no bundling) import { View } from './view.js' import { EPUB } from './epub.js' import { Paginator } from './paginator.js' ``` -------------------------------- ### Get TOC Fragment Element Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/epub.md Retrieves the DOM element or Range corresponding to a fragment identifier within a given section document. ```javascript const el = book.getTOCFragment(doc, 'intro') range.selectNode(el) ``` -------------------------------- ### Handle CFI Resolution Errors Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/errors.md Example of handling errors or null returns when a CFI (Canonical Fragment Identifier) cannot be resolved within the document. ```javascript try { const range = CFI.toRange(doc, cfiString) if (!range) { console.error('CFI could not be resolved') } } catch (e) { console.error('CFI error:', e) } ``` -------------------------------- ### EPUB Constructor Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/epub.md Initializes a new EPUB parser instance with a provided loader object. ```javascript new EPUB(loader) ``` -------------------------------- ### Basic Usage of Foliate.js View Source: https://github.com/johnfactotum/foliate-js/blob/main/README.md Import and use the `foliate-view` element to render e-books. Listen for the 'relocate' event to track location changes and use `open` and `goTo` methods to manage book content. Ensure the library is included as a git submodule for stable integration. ```javascript import './foliate-js/view.js' const view = document.createElement('foliate-view') document.body.append(view) view.addEventListener('relocate', e => { console.log('location changed') console.log(e.detail) }) // can open a File/Blob object or a URL // or any object that implements the "book" interface await view.open('example.epub') await view.goTo(/* path, section index, or CFI */) ``` -------------------------------- ### Handle MOBI Parse Errors Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/errors.md Example of catching MOBI/KF8 parsing errors, often related to corrupted files or missing decompression utilities. ```javascript try { const mobi = new MOBI({ unzlib: fflate.unzlibSync }) await mobi.open(file) } catch (e) { console.error('MOBI parse error:', e) } ``` -------------------------------- ### Get EPUB Metadata Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/epub.md Extracts metadata from an OPF document. Handles Dublin Core, EPUB 3, language variants, and ONIX identifiers. ```javascript const metadata = getMetadata(opfDocument) ``` -------------------------------- ### MOBI Open Method Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/mobi-fb2-comic.md Opens and parses a MOBI or KF8 file. Returns a Promise that resolves to the MOBI instance for chaining. ```javascript async open(file) ``` -------------------------------- ### Handle Search Errors Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/errors.md Example of catching general search errors. The library logs warnings for missing Intl.Segmenter or invalid locales but catches other errors. ```javascript try { for (const result of searchMatcher(textWalker, opts)(doc, query)) { // Process results } } catch (e) { console.error('Search error:', e) } ``` -------------------------------- ### EPUBcfi.js Usage Pattern Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/epubcfi.md Demonstrates common usage patterns for the EPUBcfi.js library, including parsing, converting to/from DOM Ranges, comparing positions, and building range CFIs. ```javascript import * as CFI from './epubcfi.js' // Parse a CFI const parsed = CFI.parse('epubcfi(/6/4!/4)') // Convert to DOM Range const doc = await section.createDocument() const range = CFI.toRange(doc, 'epubcfi(/6/4!/4)') // Display the selected text console.log('Selected:', range.toString()) // Get CFI for current selection const selection = window.getSelection() if (selection.rangeCount > 0) { const currentCFI = CFI.fromRange(selection.getRangeAt(0)) console.log('Current location:', currentCFI) } // Compare CFI positions const cfi1 = 'epubcfi(/6/4!/2)' const cfi2 = 'epubcfi(/6/4!/4)' if (CFI.compare(cfi1, cfi2) < 0) { console.log('cfi1 comes before cfi2') } // Collapse range CFI to start const rangeCFI = 'epubcfi(/6/4!/2,/4)' const startCFI = CFI.collapse(rangeCFI, false) const endCFI = CFI.collapse(rangeCFI, true) // Create range from two separate CFIs const fromCFI = 'epubcfi(/6/4!/2)' const toCFI = 'epubcfi(/6/4!/8)' const combined = CFI.buildRange(fromCFI, toCFI) ``` -------------------------------- ### Configure Search Options Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/configuration.md Sets up search parameters such as locale, granularity, sensitivity, and matching behavior. An optional acceptNode function can filter nodes during the search. ```javascript const options = { locales: 'en-US', // BCP 47 language tag(s) granularity: 'word', // 'word' or 'grapheme' sensitivity: 'base', // 'base', 'accent', 'case', 'variant' matchCase: false, // (for searchMatcher) matchDiacritics: false, // (for searchMatcher) matchWholeWords: true, // (for searchMatcher) acceptNode: (node) => { return NodeFilter.FILTER_ACCEPT } } for (const result of search(textArray, query, options)) { // Process result } ``` -------------------------------- ### Open a Book with Paginator Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/paginator.md Shows how to open a book object using the paginator's `open` method. Ensure the book object implements the required book interface. ```javascript const paginator = document.querySelector('foliate-paginator') await paginator.open(book) ``` -------------------------------- ### collapse(cfi, toEnd) Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/epubcfi.md Collapses a range CFI into a single position, either the start or the end of the range. This simplifies range representations into a single point. ```APIDOC ## collapse(cfi, toEnd) ### Description Collapse a range CFI to a single position. ### Method `collapse(cfi: string | object, toEnd: boolean)` ### Parameters #### Path Parameters - **cfi** (string | object) - Required - CFI string or parsed CFI - **toEnd** (boolean) - Required - If true, collapse to end position; otherwise start ### Response #### Success Response - **string** (if input was string) or **object** (if input was parsed) - Collapsed CFI ### Example ```javascript const rangeCFI = 'epubcfi(/6/4!/2,/2,/4)' const start = CFI.collapse(rangeCFI, false) // Collapse to start const end = CFI.collapse(rangeCFI, true) // Collapse to end ``` ``` -------------------------------- ### Annotation Persistence with Local Storage Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/quick-reference.md Shows how to manage and persist annotations using a `Map` and `localStorage`. It covers adding highlights, saving annotations, and loading them back. ```javascript const annotations = new Map() // key -> { range, color, type } overlayer.add(key, range, Overlayer.highlight, { color }) antations.set(key, { range, color, type: 'highlight' }) // Save localStorage.setItem('annotations', JSON.stringify([...annotations])) // Load const saved = JSON.JSON.parse(localStorage.getItem('annotations')) for (const { key, range, color } of saved) { overlayer.add(key, range, Overlayer.highlight, { color }) } ``` -------------------------------- ### Style Running Heads in Foliate Paginator Source: https://github.com/johnfactotum/foliate-js/blob/main/README.md Example CSS to style the header region of the paginator, adding padding and a border. This targets the ::part(head) pseudo-element. ```css foliate-view::part(head) { padding-bottom: 4px; border-bottom: 1px solid graytext; } ``` -------------------------------- ### Create and Append FixedLayout Element Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/fixed-layout.md Demonstrates how to create a new instance of the FixedLayout custom element and append it to the document body. ```javascript const viewer = document.createElement('foliate-fixed-layout') document.body.append(viewer) ``` -------------------------------- ### Collapse Range CFI Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/epubcfi.md Collapses a range CFI into a single position, either the start or the end. Can accept a CFI string or a parsed CFI object as input. ```javascript const rangeCFI = 'epubcfi(/6/4!/2,/2,/4)' const start = CFI.collapse(rangeCFI, false) // Collapse to start const end = CFI.collapse(rangeCFI, true) // Collapse to end ``` -------------------------------- ### Recommended foliate-paginator configuration for minimal layout Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/configuration.md Achieve a minimal or full-screen layout with foliate-paginator by setting gap and margin to 0 and specifying max-column-count. ```html ``` -------------------------------- ### View Constructor Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/paginator.md Demonstrates the constructor for the internal View class, which manages iframe and rendering logic. It requires a container element and an optional `onExpand` callback. ```javascript new View({ container, onExpand }) ``` -------------------------------- ### MOBI/KF8 Handler Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/quick-reference.md Handles the loading and initialization of MOBI/KF8 files. Requires an unzipping function for decompression. ```APIDOC ## MOBI/KF8 Handler ### Description Provides functionality to load and process MOBI/KF8 files. ### Initialization - `new MOBI({ unzlib: function })`: Creates a new MOBI instance, requiring an `unzlib` function for decompression. - `mobi.open(file)`: Opens and processes the MOBI/KF8 file. ``` -------------------------------- ### Annotations (Highlights, Underlines) with Overlayer Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/quick-reference.md Demonstrates how to use the Overlayer class to add and manage annotations like highlights and underlines on book content. It covers adding presets, custom drawing, and hit testing. ```javascript import { Overlayer } from './overlayer.js' const overlayer = new Overlayer() // Add highlight overlayer.add('key1', range, Overlayer.highlight, { color: 'yellow' }) // Add underline overlayer.add('key2', range, Overlayer.underline, { color: 'red', width: 2 }) // Preset styles: highlight, underline, strikethrough, squiggly, outline, copyImage // Custom draw overlayer.add('key3', range, (rects, options) => { const g = document.createElementNS('http://www.w3.org/2000/svg', 'g') // Custom drawing return g }) // Hit test const [key, range] = overlayer.hitTest(mouseEvent) // Redraw on resize overlayer.redraw() ``` -------------------------------- ### MOBI Constructor Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/mobi-fb2-comic.md Initializes a new MOBI parser instance. Requires a decompression function for KF8 files. ```javascript new MOBI(options) ``` -------------------------------- ### FictionBook 2 (FB2) Handler Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/quick-reference.md Shows how to create a FictionBook 2 book object from a blob using the makeFB2 utility function. ```javascript import { makeFB2 } from './fb2.js' const book = await makeFB2(blob) ``` -------------------------------- ### Loader Interface Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/types.md Interface for reading files from archives like ZIPs or directories. It requires methods for loading text and blobs, and getting file sizes, with an optional list of entries. ```typescript interface Loader { // Required loadText(filename: string): string | Promise loadBlob(filename: string, type?: string): Blob | Promise getSize(filename: string): number // Optional entries?: Array<{ filename: string }> } ``` -------------------------------- ### Open a Book in FixedLayout Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/fixed-layout.md Shows how to open a book object within an existing FixedLayout viewer instance. This is an asynchronous operation. ```javascript const viewer = document.querySelector('foliate-fixed-layout') await viewer.open(book) ``` -------------------------------- ### TOCProgress init Method Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/utilities.md Initializes the TOCProgress class with table of contents data and helper functions for parsing hrefs and retrieving DOM fragments. This is required before calling getProgress. ```javascript async init(options) ``` -------------------------------- ### Comic Book Archive Loader Interface Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/mobi-fb2-comic.md Defines the interface for the loader object required by makeComicBook, including archive entries and methods to load blobs and get file sizes. ```javascript { entries: Array, // Archive entries with `filename` property loadBlob(filename) // Load file as Blob getSize(filename) // Get file size in bytes } ``` -------------------------------- ### EPUB CFI Range Representation Source: https://github.com/johnfactotum/foliate-js/blob/main/README.md JSON structure representing an EPUB CFI range, including parent, start, and end properties. Each property follows the collapsed CFI structure. ```json { "parent": [ [ { "index": 6 }, { "index": 4 } ], [ { "index": 2 } ] ], "start": [ [ { "index": 2 } ] ], "end": [ [ { "index": 4 } ] ] } ``` -------------------------------- ### Open Book from Directory Handle Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/view.md Opens a book for reading from a directory handle obtained via the File System API. ```javascript const handle = await showDirectoryPicker() await view.open(handle) ``` -------------------------------- ### Importing Foliate.js Modules Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/module-map.md Demonstrates different levels of module import, from high-level to low-level utilities, showcasing the library's modular design. ```javascript // Option 1: High-level (everything) import { View } from './view.js' ``` ```javascript // Option 2: Mid-level (specific parsers + renderer) import { EPUB } from './epub.js' import { Paginator } from './paginator.js' ``` ```javascript // Option 3: Low-level (utilities) import * as CFI from './epubcfi.js' import { search } from './search.js' import { Overlayer } from './overlayer.js' ``` -------------------------------- ### EPUB Handler Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/quick-reference.md Handles the loading and initialization of EPUB files. Provides access to book metadata and table of contents. ```APIDOC ## EPUB Handler ### Description Provides functionality to load and process EPUB files. ### Initialization - `new EPUB(loader)`: Creates a new EPUB instance with a provided loader. - `epub.init()`: Initializes the EPUB, loading metadata and table of contents. ### Properties - `metadata`: Object containing book metadata (e.g., `title`). - `toc`: Array representing the table of contents. ``` -------------------------------- ### Listen for Page Load Event Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/fixed-layout.md Example of adding an event listener to the FixedLayout viewer to detect when a page has finished loading. The event detail includes the loaded Document object and its index. ```javascript viewer.addEventListener('load', e => { console.log('Page', e.detail.index, 'loaded') }) ``` -------------------------------- ### Load StarDict Dictionary Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/quick-reference.md Load a StarDict dictionary with its associated .ifo, .dz, and .idx files. Requires the `fflate` library for decompression. ```javascript import { StarDict } from './dict.js' import { unzlib } from 'fflate' const dict = new StarDict() await dict.loadIfo(ifoFile) await dict.loadDict(dzFile, unzlib) await dict.loadIdx(idxFile) const results = await dict.lookup('word') ``` -------------------------------- ### CFI Fallback to Section Start Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/errors.md Implements a fallback strategy for CFI (Common Intermediate Format) resolution. If CFI to Range conversion fails or results in an invalid range, it defaults to the beginning of the document's body. ```javascript async function goToCFI(cfi) { const doc = await section.createDocument() try { const range = CFI.toRange(doc, cfi) if (range) { // Found it return range } } catch (e) { console.warn('CFI resolution failed:', cfi) } // Fallback: go to section start const range = doc.createRange() range.setStart(doc.body, 0) return range } ``` -------------------------------- ### Implement Custom Book Parser Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/mobi-fb2-comic.md Provides a template for implementing a custom parser for a new format. It defines the required structure for sections, directory, table of contents, metadata, and rendition. Includes essential methods like resolveHref and isExternal. ```javascript export const makeCustomBook = async (blob) => { // Parse format const parsed = await parseFormat(blob) return { // Required sections: [ { id: 'chapter-1', load: async () => { // Return URL or HTML string return `data:text/html,...` }, size: 5000, }, // ... more sections ], dir: 'ltr', toc: [ { label: 'Chapter 1', href: 'chapter-1' }, { label: 'Chapter 2', href: 'chapter-2' }, ], metadata: { title: 'Book Title', author: 'Author Name', language: ['en'], }, rendition: { layout: 'reflowable', // or 'pre-paginated' }, // Required methods resolveHref: (href) => { // Find section index by id const index = sections.findIndex(s => s.id === href); return { index: index, anchor: null, }; }, isExternal: (href) => /^\w+:/ .test(href), // Optional resolveCFI: (cfi) => { /* ... */ }, splitTOCHref: (href) => [id, fragment], getTOCFragment: (doc, fragment) => el, } } ``` -------------------------------- ### Comic Book (CBZ) Handler Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/quick-reference.md Demonstrates how to create a Comic Book object from a loader and file using the makeComicBook utility function. ```javascript import { makeComicBook } from './comic-book.js' const book = makeComicBook(loader, file) ``` -------------------------------- ### Configure Paginator Programmatically with setAttribute Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/paginator.md Demonstrates how to programmatically configure the paginator's attributes using `setAttribute`. Note that there is no direct JS property API for these settings. ```javascript const paginator = document.querySelector('foliate-paginator') paginator.setAttribute('flow', 'scrolled') paginator.setAttribute('gap', '10%') paginator.setAttribute('max-inline-size', '900px') ``` -------------------------------- ### Recommended foliate-paginator configuration for two columns Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/configuration.md Configure foliate-paginator for a two-column layout on larger screens by setting gap, max-inline-size, and max-column-count. ```html ``` -------------------------------- ### Create and Append Paginator Element Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/paginator.md Demonstrates how to create a new instance of the Paginator custom element and append it to the document body. ```javascript const paginator = document.createElement('foliate-paginator') document.body.append(paginator) ``` -------------------------------- ### Initialize SVG Overlay System Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/utilities.md Constructor for the Overlayer class, which manages SVG overlays for annotations like highlights and underlines within a web page. ```javascript export class Overlayer ``` ```javascript new Overlayer() ``` -------------------------------- ### getRenditionProperties(opf) Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/epub.md Extracts rendition-specific properties from the OPF document, which define how the book should be rendered. ```APIDOC ## Function getRenditionProperties(opf) ### Description Extracts rendition-specific properties from the OPF document, such as layout, orientation, and spread. ### Parameters #### Path Parameters - **opf** (Document) - Required - The OPF manifest Document object. ### Returns - **Rendition object**: An object detailing the rendition properties of the EPUB. ``` -------------------------------- ### Handling ResponseError Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/view.md Demonstrates how to catch and handle a ResponseError when opening a book fails due to a network issue. ```javascript try { await view.open('https://invalid-url.example.com/book.epub') } catch (e) { if (e instanceof ResponseError) { console.error('Network error:', e.message) } } ``` -------------------------------- ### Listen for Relocate Event Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/paginator.md Shows how to add an event listener to the paginator to react to the 'relocate' event. This event provides details about the currently visible location within the book, including section index and progress fraction. ```javascript paginator.addEventListener('relocate', e => { const { index, fraction, range } = e.detail const percent = Math.round(fraction * 100) console.log(`Reading: ${index}/${total} (${percent}%)`) }) ``` -------------------------------- ### Open Book from URL Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/api-reference/view.md Opens a book for reading from a URL string. ```javascript await view.open('https://example.com/book.epub') ``` -------------------------------- ### Initialize MOBI Parser without KF8 Support Source: https://github.com/johnfactotum/foliate-js/blob/main/_autodocs/configuration.md Initializes the MOBI parser without providing a decompression function, enabling support only for standard MOBI files and failing on KF8 (AZW3) files. ```javascript const mobi = new MOBI({}) // MOBI-only support await mobi.open(file) // Works for MOBI, fails for KF8 ```