flipbookengine 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +113 -94
- package/README.md +427 -421
- package/dist/components/AnnotationPlacement.d.ts +5 -0
- package/dist/components/AnnotationPopover.d.ts +10 -0
- package/dist/components/App.d.ts +9 -2
- package/dist/components/NoteEditor.d.ts +13 -0
- package/dist/components/NotePlacementLayer.d.ts +11 -0
- package/dist/components/NotesPanel.d.ts +9 -6
- package/dist/components/ReaderHelp.d.ts +3 -0
- package/dist/components/ReaderShortcuts.d.ts +16 -0
- package/dist/components/TableOfContents.d.ts +1 -0
- package/dist/components/TextLayer.d.ts +8 -0
- package/dist/components/Toolbar.d.ts +1 -1
- package/dist/components/ToolbarMore.d.ts +6 -0
- package/dist/components/Viewer.d.ts +2 -0
- package/dist/core/TextLayerLoader.d.ts +5 -0
- package/dist/core/domSignal.d.ts +2 -0
- package/dist/core-entry.d.ts +1 -0
- package/dist/engine-DD5qEHLm.js +4657 -0
- package/dist/engine-DD5qEHLm.js.map +1 -0
- package/dist/engine.d.ts +23 -0
- package/dist/flipbook-engine.core.js +1 -1
- package/dist/flipbook-engine.css +1 -1
- package/dist/flipbook-engine.iife.js +34 -47
- package/dist/flipbook-engine.iife.js.map +1 -1
- package/dist/flipbook-engine.js +1 -1
- package/dist/flipbook-engine.react.js +1 -1
- package/dist/flipbook-engine.vue.js +1 -1
- package/dist/i18n/locales/en.d.ts +22 -0
- package/dist/i18n/locales/tr.d.ts +22 -0
- package/dist/i18n/service.d.ts +66 -0
- package/dist/index.d.ts +3 -0
- package/dist/model/annotations.d.ts +1 -0
- package/dist/model/backend.d.ts +8 -0
- package/dist/model/note-editor.d.ts +22 -0
- package/dist/model/text-layer.d.ts +21 -0
- package/dist/state/store.d.ts +16 -0
- package/docs/api-reference.md +227 -205
- package/docs/backend-text-layers.md +40 -0
- package/package.json +165 -165
- package/dist/engine-Dt2Fn6O-.js +0 -4060
- package/dist/engine-Dt2Fn6O-.js.map +0 -1
package/docs/api-reference.md
CHANGED
|
@@ -1,206 +1,228 @@
|
|
|
1
|
-
# API Reference
|
|
2
|
-
|
|
3
|
-
This document describes the options, methods, and events exposed by the `FlipbookEngine` class.
|
|
4
|
-
|
|
5
|
-
## Constructor Options
|
|
6
|
-
|
|
7
|
-
When instantiating `new FlipbookEngine(selector, options)`, you can configure the following options:
|
|
8
|
-
|
|
9
|
-
| Property | Type | Default | Description |
|
|
10
|
-
|---|---|---|---|
|
|
11
|
-
| `allowDownload` | `boolean` | `true` | Exposes a download button in the toolbar. |
|
|
12
|
-
| `showThumbs` | `boolean` | `false` | Starts the viewer with the thumbnail navigation rail hidden. |
|
|
13
|
-
| `showToc` | `boolean` | `false` | Shows the supplied table of contents panel when it contains entries. |
|
|
14
|
-
| `toc` | `FlipbookTocEntry[]` | `[]` | Host-provided chapter/category entries using zero-based page indexes. |
|
|
15
|
-
| `showArrows` | `boolean` | `true` | Shows the previous/next navigation arrows. |
|
|
16
|
-
| `primaryColor` | `string` | `'#7367f0'` | Sets the primary theme accent color. |
|
|
17
|
-
| `theme` | `'auto' \| 'light' \| 'dark'` | `'auto'` | Force light/dark mode or let it respond automatically. |
|
|
18
|
-
| `locale` | `'en' \| 'tr' \| string` | `'en'` | Active language interface. |
|
|
19
|
-
| `soundEnabled` | `boolean` | `true` | Enables page turning sound effect. |
|
|
20
|
-
| `soundUrl` | `string` | `'https://flipbookengine.com/Content/page-flip.mp3'` | URL of the page turning audio file. |
|
|
21
|
-
| `autoPlayInterval` | `number` | `3000` | Duration (ms) before automatically turning to the next page in Autoplay mode. |
|
|
22
|
-
| `flippingTime` | `number` | `1000` | Duration (ms) of the page turning animation; automatically set to `0` when reduced motion is preferred. |
|
|
23
|
-
| `maxShadowOpacity` | `number` | `0.5` | Maximum opacity of the shadow during page turn (0 to 1). |
|
|
24
|
-
| `messages` | `Record<string, PartialFlipbookMessages>` | `null` | Custom localization overrides. |
|
|
25
|
-
| `cssVariables` | `Record<string, string>` | `null` | Per-instance custom CSS property overrides. |
|
|
26
|
-
| `whiteLabel` | `boolean` | `false` | If true, hides the "Powered by FlipbookEngine" watermark. |
|
|
27
|
-
| `watermarkUrl` | `string` | `null` | Custom image logo URL for watermark attribution. |
|
|
28
|
-
| `pdfRenderConcurrency` | `number` | `3` | Maximum number of PDF pages rendered concurrently when on-demand pages are requested. |
|
|
29
|
-
| `pdfRenderCacheSize` | `number` | `32` | Maximum number of rendered PDF page images retained per engine instance (LRU); `0` disables caching. |
|
|
30
|
-
| `pdfPageMode` | `'auto' \| 'single' \| 'split'` | `'auto'` | Automatically split A3 landscape pages, split every landscape page, or keep source pages intact. |
|
|
31
|
-
| `background` | `FlipbookBackgrounds \| null` | `null` | Optional per-theme viewer background styles. |
|
|
32
|
-
| `deepLink` | `boolean` | `false` | Synchronizes the active page with a `?page=` URL parameter and browser history. |
|
|
33
|
-
| `onShare` | `(url: string) => void` | `null` | Optional callback invoked after the localized toolbar Share control shares or copies the generated page URL. |
|
|
34
|
-
| `bookmarks` | `number[]` | `[]` | Initial zero-based page indexes marked as bookmarks; persistence remains with the host application. |
|
|
35
|
-
| `notes` | `Record<number, string>` | `{}` | Initial page notes keyed by zero-based page index; the localized toolbar editor is host-storage agnostic. |
|
|
36
|
-
| `hotspots` | `FlipbookHotspot[]` | `[]` | Normalized page overlays with accessible labels, media/gallery previews, plain-text content, and optional commerce links. |
|
|
37
|
-
| `annotations` | `FlipbookAnnotation[]` | `[]` | Host-managed page note markers with normalized coordinates and plain-text popup content. |
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## Public Methods
|
|
42
|
-
|
|
43
|
-
### `init(pdfUrl: string, imageList?: FlipbookPageAsset[])`
|
|
44
|
-
Initializes and mounts the viewer into the container element. Returns a `Promise<void>`.
|
|
45
|
-
|
|
46
|
-
### `goToPage(pageIndex: number)`
|
|
47
|
-
Programmatically turns to the specified 0-based page index.
|
|
48
|
-
|
|
49
|
-
### `getCurrentPage()`
|
|
50
|
-
Returns the 0-based index of the currently active page.
|
|
51
|
-
|
|
52
|
-
### `getTotalPages()`
|
|
53
|
-
Returns the total count of normalized pages.
|
|
54
|
-
|
|
55
|
-
### `getZoom()`
|
|
56
|
-
Returns the current zoom scale (usually `1` to `5`).
|
|
57
|
-
|
|
58
|
-
### `setZoom(zoomLevel: number)`
|
|
59
|
-
Sets the zoom scale. Acceptable bounds are `0.5` to `5`.
|
|
60
|
-
|
|
61
|
-
### `setSingleMode(isSingle: boolean)`
|
|
62
|
-
Enforces single page layout (typically for mobile viewports) or spread mode.
|
|
63
|
-
|
|
64
|
-
### `toggleFullscreen()`
|
|
65
|
-
Toggles browser fullscreen.
|
|
66
|
-
|
|
67
|
-
### `updateOptions(options: Partial<FlipbookEngineOptions>)`
|
|
68
|
-
Updates options dynamically at runtime.
|
|
69
|
-
|
|
70
|
-
### `setLocale(locale: string, messages?: PartialFlipbookMessages | Record<string, PartialFlipbookMessages>)`
|
|
71
|
-
Changes the UI language programmatically.
|
|
72
|
-
|
|
73
|
-
### `getPageUrl(pageIndex = getCurrentPage())`
|
|
74
|
-
Returns a shareable URL with a 1-based `?page=` parameter for the requested 0-based page index.
|
|
75
|
-
|
|
76
|
-
### `sharePage(pageIndex = getCurrentPage())`
|
|
77
|
-
Uses the native share dialog when available, otherwise copies the page URL to the clipboard. The toolbar exposes this behavior through a localized Share button. Enable `deepLink: true` in the receiving viewer to resolve the `?page=` parameter.
|
|
78
|
-
|
|
79
|
-
### Bookmark methods
|
|
80
|
-
|
|
81
|
-
`getBookmarkedPages()`, `isBookmarked()`, `setBookmark(pageIndex, bookmarked)`, and `toggleBookmark(pageIndex)` manage zero-based bookmark state. The `bookmarkChange` event payload is `{ pageIndex, pageNumber, bookmarked }`; hosts should persist this payload in their own storage.
|
|
82
|
-
|
|
83
|
-
`getNotes()`, `getNote(pageIndex)`, `setNote(pageIndex, note)`, and `clearNote(pageIndex)` manage host-owned notes. The toolbar's localized **Page note** button opens an inline editor; empty notes are removed; `noteChange` emits `{ pageIndex, pageNumber, note }` with `null` when a note is cleared. Hosts can persist that payload in a database or other storage.
|
|
84
|
-
|
|
85
|
-
### `connectEmbed(options?: FlipbookEmbedOptions)`
|
|
86
|
-
Connects an origin-validated postMessage bridge for iframe integrations. Call this from the document loaded inside the iframe.
|
|
87
|
-
|
|
88
|
-
### `destroy(keepContainer = false)`
|
|
89
|
-
Tears down the instance, unsubscribes all event handlers, and optionally clears the container element HTML.
|
|
90
|
-
|
|
91
|
-
---
|
|
92
|
-
|
|
93
|
-
## Iframe embedding
|
|
94
|
-
|
|
95
|
-
Embed integrations use a small, origin-validated `postMessage` bridge. The viewer page (inside the iframe) connects the bridge:
|
|
96
|
-
|
|
97
|
-
```ts
|
|
98
|
-
const engine = new FlipbookEngine('#viewer', { showThumbs: false });
|
|
99
|
-
const embedBridge = engine.connectEmbed({
|
|
100
|
-
allowedOrigins: ['https://catalog.example.com']
|
|
101
|
-
});
|
|
102
|
-
await engine.init('/files/catalog.pdf');
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
The parent page can control the iframe with the exported controller:
|
|
106
|
-
|
|
107
|
-
```ts
|
|
108
|
-
import { createFlipbookEmbedController } from 'flipbookengine';
|
|
109
|
-
|
|
110
|
-
const iframe = document.querySelector('#catalog-frame') as HTMLIFrameElement;
|
|
111
|
-
const catalog = createFlipbookEmbedController(iframe, {
|
|
112
|
-
targetOrigin: 'https://viewer.example.com'
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
await catalog.goToPage(3);
|
|
116
|
-
await catalog.setZoom(1.5);
|
|
117
|
-
catalog.on('pageChange', (state) => console.log(state.pageNumber));
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
Commands are restricted to navigation, zoom, single-mode, option updates, fullscreen, TOC read/update, search, and state queries. Configure an explicit `allowedOrigins` value in the iframe and `targetOrigin` value in the parent for cross-origin deployments. The bridge rejects messages from other windows or origins.
|
|
121
|
-
|
|
122
|
-
## Event Subscriptions
|
|
123
|
-
|
|
124
|
-
Use `.on(eventName, handler)` to listen to runtime events:
|
|
125
|
-
|
|
126
|
-
```javascript
|
|
127
|
-
const unsubscribe = engine.on('pageChange', ({ currentPage, pageNumber, totalPages, isSingle }) => {
|
|
128
|
-
console.log(`Now on page ${pageNumber} of ${totalPages}`);
|
|
129
|
-
});
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
### Supported Events
|
|
133
|
-
|
|
134
|
-
- **`pageChange`**: Emitted when page is changed.
|
|
135
|
-
- Payload: `{ currentPage: number; pageNumber: number; totalPages: number; isSingle: boolean }`
|
|
136
|
-
- **`zoomChange`**: Emitted when zoom factor changes.
|
|
137
|
-
- Payload: `{ zoom: number; isActive: boolean }`
|
|
138
|
-
- **`singlePageModeChange`**: Emitted when switching layout mode.
|
|
139
|
-
- Payload: `{ isSingle: boolean }`
|
|
140
|
-
- **`thumbsToggle`**: Emitted when thumbnail rail is toggled.
|
|
141
|
-
- **`tocToggle`**: Emitted when the table of contents panel is toggled.
|
|
142
|
-
- Payload: `{ showToc: boolean }`
|
|
143
|
-
- Payload: `{ showThumbs: boolean }`
|
|
144
|
-
- **`init`**: Emitted after the viewer is ready. Payload: `{ totalPages: number }`
|
|
145
|
-
- **`progress`**: Emitted during PDF loading/rendering. Payload: `{ phase: 'loading' | 'rendering'; completed: number; total: number }`
|
|
146
|
-
- **`orientationChange`**: Emitted when layout orientation changes. Payload: `{ orientation: 'landscape' | 'portrait' }`.
|
|
147
|
-
- **`deepLinkChange`**: Emitted when the active page updates the shareable URL. Payload: `{ pageIndex: number; pageNumber: number; url: string }`.
|
|
148
|
-
- **`bookmarkChange`**: Emitted when a page bookmark is added or removed. Payload: `{ pageIndex: number; pageNumber: number; bookmarked: boolean }`.
|
|
149
|
-
- **`noteChange`**: Emitted when a page note is added, updated, or cleared. Payload: `{ pageIndex: number; pageNumber: number; note: string | null }`.
|
|
150
|
-
- **`error`**: Emitted when PDF loading/rendering fails. Payload: `{ code: 'PDF_LOAD_FAILED' | 'PDF_RENDER_FAILED'; message: string; cause?: unknown }`
|
|
151
|
-
- **`destroy`**: Emitted when the engine is destroyed.
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
## PDF rendering lifecycle
|
|
155
|
-
|
|
156
|
-
When `pdfUrl` is supplied without a `pages` list, the engine creates lightweight page placeholders immediately after the document metadata loads. The first page is rendered before `init()` resolves, and the next page is prefetched. Remaining pages render on demand as they become visible or are selected. Rendering requests are deduplicated per page and cancelled when initialization is superseded or the engine is destroyed.
|
|
157
|
-
|
|
158
|
-
Use `pdfRenderConcurrency` to bound concurrent PDF.js work and `pdfRenderCacheSize` to configure the per-instance LRU cache. Set the cache size to `0` when rendered page data should not be retained. `pdfPageMode: 'auto'` detects ISO A3 landscape pages and exposes their left/right halves as two logical pages; `'single'` disables splitting and `'split'` splits every landscape page.
|
|
159
|
-
|
|
160
|
-
## PDF page formats
|
|
161
|
-
|
|
162
|
-
The viewer derives its page ratio from PDF.js metadata or the supplied image asset. Portrait A4 and landscape A4 are both supported. For a landscape A3 page that contains two A4 pages, use the default `pdfPageMode: 'auto'` or explicit `'split'`; each half becomes a navigable logical page.
|
|
163
|
-
|
|
164
|
-
## Table of contents
|
|
165
|
-
|
|
166
|
-
TOC entries are supplied by the host application so the viewer stays backend-agnostic. `pageIndex` is zero-based and is clamped to the loaded page range. Nested `children` entries are supported.
|
|
167
|
-
|
|
168
|
-
Use `engine.getToc()` to read the normalized tree or `engine.setToc(entries, show?)` to replace it at runtime. The open-source viewer consumes this manifest; it does not extract PDF outline destinations or generate OCR metadata.
|
|
169
|
-
|
|
170
|
-
```ts
|
|
171
|
-
const engine = new FlipbookEngine('#viewer', {
|
|
172
|
-
toc: [
|
|
173
|
-
{ title: 'Introduction', pageIndex: 0 },
|
|
174
|
-
{ title: 'Products', pageIndex: 4, children: [
|
|
175
|
-
{ title: 'Category A', pageIndex: 5 }
|
|
176
|
-
] }
|
|
177
|
-
],
|
|
178
|
-
showToc: true
|
|
179
|
-
});
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
### Search
|
|
183
|
-
|
|
184
|
-
- **`search(query, options?)`**: Extracts and searches PDF text client-side. Returns `{ pageIndex, pageNumber, matches, snippet, sourcePageNumber, highlights? }[]`, stores results for the built-in search panel, and overlays matching text rectangles. `pageIndex` is zero-based; `pageNumber` is one-based. `highlights` coordinates are normalized to the logical page (0..1), including left/right mapping for split PDF pages.
|
|
185
|
-
- **`clearSearch()`** / **`getSearchResults()`**: Clears or reads the current search state.
|
|
186
|
-
|
|
187
|
-
### Hotspots
|
|
188
|
-
|
|
189
|
-
- **`getHotspots(pageIndex = getCurrentPage())`**: Returns host-provided overlays for a logical page.
|
|
190
|
-
- **`activateHotspot(id)`** / **`closeHotspot()`**: Opens or closes a hotspot popup. Activation emits `hotspotActivate`. Hotspots may include `kind`, `media` (`image`, `video`, `audio`), `gallery` image items, and an optional `href` for commerce/product links; popup text is always rendered as plain text.
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
### Page annotations
|
|
194
|
-
|
|
195
|
-
Host uygulamaları, kullanıcı notunu sayfa üzerindeki normalize koordinata bağlamak için `annotations` seçeneğini kullanabilir. Marker tıklaması popup açar ve `annotationActivate` olayı yayınlanır. Bu sözleşme şimdilik host-managed'dir; annotation kayıtlarının backend koordinatlarına taşınması tüketici uygulamanın sorumluluğundadır.
|
|
196
|
-
|
|
197
|
-
```ts
|
|
198
|
-
const engine = new FlipbookEngine('#viewer', {
|
|
199
|
-
annotations: [{ id: 'note-1', pageIndex: 4, x: .42, y: .36, text: 'Review pricing' }]
|
|
200
|
-
});
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
## Plugins
|
|
204
|
-
|
|
205
|
-
See [Plugin architecture](./plugin-architecture.md) for the v1 plugin contract and lifecycle.
|
|
1
|
+
# API Reference
|
|
206
2
|
|
|
3
|
+
This document describes the options, methods, and events exposed by the `FlipbookEngine` class.
|
|
4
|
+
|
|
5
|
+
## Constructor Options
|
|
6
|
+
|
|
7
|
+
When instantiating `new FlipbookEngine(selector, options)`, you can configure the following options:
|
|
8
|
+
|
|
9
|
+
| Property | Type | Default | Description |
|
|
10
|
+
|---|---|---|---|
|
|
11
|
+
| `allowDownload` | `boolean` | `true` | Exposes a download button in the toolbar. |
|
|
12
|
+
| `showThumbs` | `boolean` | `false` | Starts the viewer with the thumbnail navigation rail hidden. |
|
|
13
|
+
| `showToc` | `boolean` | `false` | Shows the supplied table of contents panel when it contains entries. |
|
|
14
|
+
| `toc` | `FlipbookTocEntry[]` | `[]` | Host-provided chapter/category entries using zero-based page indexes. |
|
|
15
|
+
| `showArrows` | `boolean` | `true` | Shows the previous/next navigation arrows. |
|
|
16
|
+
| `primaryColor` | `string` | `'#7367f0'` | Sets the primary theme accent color. |
|
|
17
|
+
| `theme` | `'auto' \| 'light' \| 'dark'` | `'auto'` | Force light/dark mode or let it respond automatically. |
|
|
18
|
+
| `locale` | `'en' \| 'tr' \| string` | `'en'` | Active language interface. |
|
|
19
|
+
| `soundEnabled` | `boolean` | `true` | Enables page turning sound effect. |
|
|
20
|
+
| `soundUrl` | `string` | `'https://flipbookengine.com/Content/page-flip.mp3'` | URL of the page turning audio file. |
|
|
21
|
+
| `autoPlayInterval` | `number` | `3000` | Duration (ms) before automatically turning to the next page in Autoplay mode. |
|
|
22
|
+
| `flippingTime` | `number` | `1000` | Duration (ms) of the page turning animation; automatically set to `0` when reduced motion is preferred. |
|
|
23
|
+
| `maxShadowOpacity` | `number` | `0.5` | Maximum opacity of the shadow during page turn (0 to 1). |
|
|
24
|
+
| `messages` | `Record<string, PartialFlipbookMessages>` | `null` | Custom localization overrides. |
|
|
25
|
+
| `cssVariables` | `Record<string, string>` | `null` | Per-instance custom CSS property overrides. |
|
|
26
|
+
| `whiteLabel` | `boolean` | `false` | If true, hides the "Powered by FlipbookEngine" watermark. |
|
|
27
|
+
| `watermarkUrl` | `string` | `null` | Custom image logo URL for watermark attribution. |
|
|
28
|
+
| `pdfRenderConcurrency` | `number` | `3` | Maximum number of PDF pages rendered concurrently when on-demand pages are requested. |
|
|
29
|
+
| `pdfRenderCacheSize` | `number` | `32` | Maximum number of rendered PDF page images retained per engine instance (LRU); `0` disables caching. |
|
|
30
|
+
| `pdfPageMode` | `'auto' \| 'single' \| 'split'` | `'auto'` | Automatically split A3 landscape pages, split every landscape page, or keep source pages intact. |
|
|
31
|
+
| `background` | `FlipbookBackgrounds \| null` | `null` | Optional per-theme viewer background styles. |
|
|
32
|
+
| `deepLink` | `boolean` | `false` | Synchronizes the active page with a `?page=` URL parameter and browser history. |
|
|
33
|
+
| `onShare` | `(url: string) => void` | `null` | Optional callback invoked after the localized toolbar Share control shares or copies the generated page URL. |
|
|
34
|
+
| `bookmarks` | `number[]` | `[]` | Initial zero-based page indexes marked as bookmarks; persistence remains with the host application. |
|
|
35
|
+
| `notes` | `Record<number, string>` | `{}` | Initial page notes keyed by zero-based page index; the localized toolbar editor is host-storage agnostic. |
|
|
36
|
+
| `hotspots` | `FlipbookHotspot[]` | `[]` | Normalized page overlays with accessible labels, media/gallery previews, plain-text content, and optional commerce links. |
|
|
37
|
+
| `annotations` | `FlipbookAnnotation[]` | `[]` | Host-managed page note markers with normalized coordinates and plain-text popup content. |
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Public Methods
|
|
42
|
+
|
|
43
|
+
### `init(pdfUrl: string, imageList?: FlipbookPageAsset[])`
|
|
44
|
+
Initializes and mounts the viewer into the container element. Returns a `Promise<void>`.
|
|
45
|
+
|
|
46
|
+
### `goToPage(pageIndex: number)`
|
|
47
|
+
Programmatically turns to the specified 0-based page index.
|
|
48
|
+
|
|
49
|
+
### `getCurrentPage()`
|
|
50
|
+
Returns the 0-based index of the currently active page.
|
|
51
|
+
|
|
52
|
+
### `getTotalPages()`
|
|
53
|
+
Returns the total count of normalized pages.
|
|
54
|
+
|
|
55
|
+
### `getZoom()`
|
|
56
|
+
Returns the current zoom scale (usually `1` to `5`).
|
|
57
|
+
|
|
58
|
+
### `setZoom(zoomLevel: number)`
|
|
59
|
+
Sets the zoom scale. Acceptable bounds are `0.5` to `5`.
|
|
60
|
+
|
|
61
|
+
### `setSingleMode(isSingle: boolean)`
|
|
62
|
+
Enforces single page layout (typically for mobile viewports) or spread mode.
|
|
63
|
+
|
|
64
|
+
### `toggleFullscreen()`
|
|
65
|
+
Toggles browser fullscreen.
|
|
66
|
+
|
|
67
|
+
### `updateOptions(options: Partial<FlipbookEngineOptions>)`
|
|
68
|
+
Updates options dynamically at runtime.
|
|
69
|
+
|
|
70
|
+
### `setLocale(locale: string, messages?: PartialFlipbookMessages | Record<string, PartialFlipbookMessages>)`
|
|
71
|
+
Changes the UI language programmatically.
|
|
72
|
+
|
|
73
|
+
### `getPageUrl(pageIndex = getCurrentPage())`
|
|
74
|
+
Returns a shareable URL with a 1-based `?page=` parameter for the requested 0-based page index.
|
|
75
|
+
|
|
76
|
+
### `sharePage(pageIndex = getCurrentPage())`
|
|
77
|
+
Uses the native share dialog when available, otherwise copies the page URL to the clipboard. The toolbar exposes this behavior through a localized Share button. Enable `deepLink: true` in the receiving viewer to resolve the `?page=` parameter.
|
|
78
|
+
|
|
79
|
+
### Bookmark methods
|
|
80
|
+
|
|
81
|
+
`getBookmarkedPages()`, `isBookmarked()`, `setBookmark(pageIndex, bookmarked)`, and `toggleBookmark(pageIndex)` manage zero-based bookmark state. The `bookmarkChange` event payload is `{ pageIndex, pageNumber, bookmarked }`; hosts should persist this payload in their own storage.
|
|
82
|
+
|
|
83
|
+
`getNotes()`, `getNote(pageIndex)`, `setNote(pageIndex, note)`, and `clearNote(pageIndex)` manage host-owned notes. The toolbar's localized **Page note** button opens an inline editor; empty notes are removed; `noteChange` emits `{ pageIndex, pageNumber, note }` with `null` when a note is cleared. Hosts can persist that payload in a database or other storage.
|
|
84
|
+
|
|
85
|
+
### `connectEmbed(options?: FlipbookEmbedOptions)`
|
|
86
|
+
Connects an origin-validated postMessage bridge for iframe integrations. Call this from the document loaded inside the iframe.
|
|
87
|
+
|
|
88
|
+
### `destroy(keepContainer = false)`
|
|
89
|
+
Tears down the instance, unsubscribes all event handlers, and optionally clears the container element HTML.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Iframe embedding
|
|
94
|
+
|
|
95
|
+
Embed integrations use a small, origin-validated `postMessage` bridge. The viewer page (inside the iframe) connects the bridge:
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
const engine = new FlipbookEngine('#viewer', { showThumbs: false });
|
|
99
|
+
const embedBridge = engine.connectEmbed({
|
|
100
|
+
allowedOrigins: ['https://catalog.example.com']
|
|
101
|
+
});
|
|
102
|
+
await engine.init('/files/catalog.pdf');
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The parent page can control the iframe with the exported controller:
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
import { createFlipbookEmbedController } from 'flipbookengine';
|
|
109
|
+
|
|
110
|
+
const iframe = document.querySelector('#catalog-frame') as HTMLIFrameElement;
|
|
111
|
+
const catalog = createFlipbookEmbedController(iframe, {
|
|
112
|
+
targetOrigin: 'https://viewer.example.com'
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
await catalog.goToPage(3);
|
|
116
|
+
await catalog.setZoom(1.5);
|
|
117
|
+
catalog.on('pageChange', (state) => console.log(state.pageNumber));
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Commands are restricted to navigation, zoom, single-mode, option updates, fullscreen, TOC read/update, search, and state queries. Configure an explicit `allowedOrigins` value in the iframe and `targetOrigin` value in the parent for cross-origin deployments. The bridge rejects messages from other windows or origins.
|
|
121
|
+
|
|
122
|
+
## Event Subscriptions
|
|
123
|
+
|
|
124
|
+
Use `.on(eventName, handler)` to listen to runtime events:
|
|
125
|
+
|
|
126
|
+
```javascript
|
|
127
|
+
const unsubscribe = engine.on('pageChange', ({ currentPage, pageNumber, totalPages, isSingle }) => {
|
|
128
|
+
console.log(`Now on page ${pageNumber} of ${totalPages}`);
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Supported Events
|
|
133
|
+
|
|
134
|
+
- **`pageChange`**: Emitted when page is changed.
|
|
135
|
+
- Payload: `{ currentPage: number; pageNumber: number; totalPages: number; isSingle: boolean }`
|
|
136
|
+
- **`zoomChange`**: Emitted when zoom factor changes.
|
|
137
|
+
- Payload: `{ zoom: number; isActive: boolean }`
|
|
138
|
+
- **`singlePageModeChange`**: Emitted when switching layout mode.
|
|
139
|
+
- Payload: `{ isSingle: boolean }`
|
|
140
|
+
- **`thumbsToggle`**: Emitted when thumbnail rail is toggled.
|
|
141
|
+
- **`tocToggle`**: Emitted when the table of contents panel is toggled.
|
|
142
|
+
- Payload: `{ showToc: boolean }`
|
|
143
|
+
- Payload: `{ showThumbs: boolean }`
|
|
144
|
+
- **`init`**: Emitted after the viewer is ready. Payload: `{ totalPages: number }`
|
|
145
|
+
- **`progress`**: Emitted during PDF loading/rendering. Payload: `{ phase: 'loading' | 'rendering'; completed: number; total: number }`
|
|
146
|
+
- **`orientationChange`**: Emitted when layout orientation changes. Payload: `{ orientation: 'landscape' | 'portrait' }`.
|
|
147
|
+
- **`deepLinkChange`**: Emitted when the active page updates the shareable URL. Payload: `{ pageIndex: number; pageNumber: number; url: string }`.
|
|
148
|
+
- **`bookmarkChange`**: Emitted when a page bookmark is added or removed. Payload: `{ pageIndex: number; pageNumber: number; bookmarked: boolean }`.
|
|
149
|
+
- **`noteChange`**: Emitted when a page note is added, updated, or cleared. Payload: `{ pageIndex: number; pageNumber: number; note: string | null }`.
|
|
150
|
+
- **`error`**: Emitted when PDF loading/rendering fails. Payload: `{ code: 'PDF_LOAD_FAILED' | 'PDF_RENDER_FAILED'; message: string; cause?: unknown }`
|
|
151
|
+
- **`destroy`**: Emitted when the engine is destroyed.
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
## PDF rendering lifecycle
|
|
155
|
+
|
|
156
|
+
When `pdfUrl` is supplied without a `pages` list, the engine creates lightweight page placeholders immediately after the document metadata loads. The first page is rendered before `init()` resolves, and the next page is prefetched. Remaining pages render on demand as they become visible or are selected. Rendering requests are deduplicated per page and cancelled when initialization is superseded or the engine is destroyed.
|
|
157
|
+
|
|
158
|
+
Use `pdfRenderConcurrency` to bound concurrent PDF.js work and `pdfRenderCacheSize` to configure the per-instance LRU cache. Set the cache size to `0` when rendered page data should not be retained. `pdfPageMode: 'auto'` detects ISO A3 landscape pages and exposes their left/right halves as two logical pages; `'single'` disables splitting and `'split'` splits every landscape page.
|
|
159
|
+
|
|
160
|
+
## PDF page formats
|
|
161
|
+
|
|
162
|
+
The viewer derives its page ratio from PDF.js metadata or the supplied image asset. Portrait A4 and landscape A4 are both supported. For a landscape A3 page that contains two A4 pages, use the default `pdfPageMode: 'auto'` or explicit `'split'`; each half becomes a navigable logical page.
|
|
163
|
+
|
|
164
|
+
## Table of contents
|
|
165
|
+
|
|
166
|
+
TOC entries are supplied by the host application so the viewer stays backend-agnostic. `pageIndex` is zero-based and is clamped to the loaded page range. Nested `children` entries are supported.
|
|
167
|
+
|
|
168
|
+
Use `engine.getToc()` to read the normalized tree or `engine.setToc(entries, show?)` to replace it at runtime. The open-source viewer consumes this manifest; it does not extract PDF outline destinations or generate OCR metadata.
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
const engine = new FlipbookEngine('#viewer', {
|
|
172
|
+
toc: [
|
|
173
|
+
{ title: 'Introduction', pageIndex: 0 },
|
|
174
|
+
{ title: 'Products', pageIndex: 4, children: [
|
|
175
|
+
{ title: 'Category A', pageIndex: 5 }
|
|
176
|
+
] }
|
|
177
|
+
],
|
|
178
|
+
showToc: true
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Search
|
|
183
|
+
|
|
184
|
+
- **`search(query, options?)`**: Extracts and searches PDF text client-side. Returns `{ pageIndex, pageNumber, matches, snippet, sourcePageNumber, highlights? }[]`, stores results for the built-in search panel, and overlays matching text rectangles. `pageIndex` is zero-based; `pageNumber` is one-based. `highlights` coordinates are normalized to the logical page (0..1), including left/right mapping for split PDF pages.
|
|
185
|
+
- **`clearSearch()`** / **`getSearchResults()`**: Clears or reads the current search state.
|
|
186
|
+
|
|
187
|
+
### Hotspots
|
|
188
|
+
|
|
189
|
+
- **`getHotspots(pageIndex = getCurrentPage())`**: Returns host-provided overlays for a logical page.
|
|
190
|
+
- **`activateHotspot(id)`** / **`closeHotspot()`**: Opens or closes a hotspot popup. Activation emits `hotspotActivate`. Hotspots may include `kind`, `media` (`image`, `video`, `audio`), `gallery` image items, and an optional `href` for commerce/product links; popup text is always rendered as plain text.
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
### Page annotations
|
|
194
|
+
|
|
195
|
+
Host uygulamaları, kullanıcı notunu sayfa üzerindeki normalize koordinata bağlamak için `annotations` seçeneğini kullanabilir. Marker tıklaması popup açar ve `annotationActivate` olayı yayınlanır. Bu sözleşme şimdilik host-managed'dir; annotation kayıtlarının backend koordinatlarına taşınması tüketici uygulamanın sorumluluğundadır.
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
const engine = new FlipbookEngine('#viewer', {
|
|
199
|
+
annotations: [{ id: 'note-1', pageIndex: 4, x: .42, y: .36, text: 'Review pricing' }]
|
|
200
|
+
});
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Plugins
|
|
204
|
+
|
|
205
|
+
See [Plugin architecture](./plugin-architecture.md) for the v1 plugin contract and lifecycle.
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
## Host backend providers
|
|
209
|
+
|
|
210
|
+
The native search panel also works with pre-rendered page images. Supply `searchProvider(query, options, signal)` returning logical page results (`pageIndex` is zero-based, `pageNumber` is one-based, plus `matches`, `snippet` and optional normalized `highlights`). The host owns authentication, document identity and authorization. Stale responses are ignored; destroy aborts the session signal. Without a provider, Direct PDF search retains its existing behavior.
|
|
211
|
+
|
|
212
|
+
Supply initial `notes` and `noteProvider(pageIndex, note, signal)` to persist the native note editor. A cleared note is `null`. The editor awaits the provider before changing the saved note or emitting `noteChange`. On failure it retains the draft and offers another save. `saveNote(pageIndex, note)` exposes the same asynchronous workflow; `setNote` remains a synchronous programmatic update for compatibility.
|
|
213
|
+
|
|
214
|
+
Contents, search and notes are mutually exclusive panels. Canvas arrows hide while a panel is open; the pager remains available. Contents has a close control. Secondary toolbar commands are in the accessible More actions menu; mobile navigation and primary controls occupy two rows.
|
|
215
|
+
|
|
216
|
+
## Personal coordinate notes
|
|
217
|
+
|
|
218
|
+
`annotationProvider(annotation, action, signal)` persists native coordinate notes (`action` is `save` or `delete`). Initial `annotations` load existing notes. `beginAnnotation()` enters a dedicated placement mode; `placeAnnotation(pageIndex,x,y)` uses normalized logical-page coordinates in [0,1]. `saveAnnotation()` commits only after the host succeeds. Multiple note IDs may share a page. The host remains responsible for authentication, ownership and document identity. Right click and a stationary touch/pen hold open an editor at the selected point; movement beyond10px or another pointer cancels long press. A placement overlay consumes page-flip gestures. Escape cancels placement. Markers are available in both single-page and spread views.
|
|
219
|
+
|
|
220
|
+
The My notes panel includes existing page notes and coordinate notes, navigation, an empty state and a total count. The toolbar shows the count and highlights pages containing notes. Selecting a marker opens a readable popover outside the scaled paper; editing and deletion remain in that popover. Delete requires a second explicit action.
|
|
221
|
+
|
|
222
|
+
`noteEditor(container,value,signal)` is an optional host editor factory returning `getValue`, `setReadOnly` and `destroy`. `value` contains plain `text` and an optional structured `document`; the base engine retains a textarea fallback and has no Tiptap dependency. Legacy page notes can supply `noteDocuments`; noteProvider receives the document as an optional fourth argument. The built-in viewer renders only doc/paragraph/text/hardBreak nodes with bold, italic, font-size and hex foreground/background marks. It never renders raw note HTML.
|
|
223
|
+
|
|
224
|
+
When the viewer owns keyboard focus: arrows/PageUp/PageDown navigate, Home/End jump, +/- zoom,0 resets, N places a note, Shift+N opens My notes, / searches, I opens contents, T toggles thumbnails, F toggles fullscreen, and ? shows help. Text inputs and rich editors keep their own shortcuts. Toolbar arrows move focus among visible commands; Tab/Shift+Tab preserve native focus order. Closing panels returns focus. Pinch zoom and one-finger pan suppress page turning; only predominantly horizontal unzoomed single-page swipes turn pages. Ctrl/wheel zoom is scoped to the paper. Native touch behavior still requires real-device acceptance.
|
|
225
|
+
|
|
226
|
+
## Backend text layer API
|
|
227
|
+
|
|
228
|
+
Optional `textLayerProvider`, `textSelection` and `setTextSelection(enabled)` add fixed-layout selectable text to image books. Public `FlipbookTextPage`, `FlipbookTextRun` and `FlipbookTextLayerProvider` types are exported from root and core entrypoints. See [schema, lifecycle, geometry and backend responsibilities](backend-text-layers.md). Existing search highlights remain independent. No backend, OCR engine or database is bundled.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Backend text layers
|
|
2
|
+
|
|
3
|
+
## Ownership and compatibility
|
|
4
|
+
|
|
5
|
+
The viewer consumes host-generated text; it never uploads a PDF, runs OCR, writes a database or supplies authoritative extraction results. Existing image books and Direct PDF books work without a text provider. The API is available from 1.0.2.
|
|
6
|
+
|
|
7
|
+
## Schema v1
|
|
8
|
+
|
|
9
|
+
`textLayerProvider(pageIndex, signal): Promise<FlipbookTextPage | null>` returns a logical-page payload. Indexes are zero-based. Return null for unavailable/OCR-pending text. Provider errors do not break image navigation. Providers must honor AbortSignal for network cancellation. Reinitialize to change document identity/provider or retry failed pages.
|
|
10
|
+
|
|
11
|
+
`FlipbookTextPage`: schemaVersion:1, pageIndex, revision:string, text:string, runs:FlipbookTextRun[]. Revision identifies an immutable source/extraction generation. Hosts must reject a text/image source mismatch before returning data.
|
|
12
|
+
|
|
13
|
+
`FlipbookTextRun`: text, start (UTF-16 code units into page text), x, y, width, height (finite 0..1 values), optional direction:ltr|rtl. Runs are ordered, nonoverlapping in text offsets and must match their source substring. Max 100,000 page characters and 20,000 runs; invalid pages are rejected. Do not pass user HTML.
|
|
14
|
+
|
|
15
|
+
Coordinates use top-left origin in the **displayed logical page**, after PDF CropBox and rotation. All image variants must depict precisely that same viewport. Spread/cropped assets require the host to remap each logical half; full-source coordinates must never be applied unchanged to a half-page. Provider geometry precision is explicit: PDF text-run boxes highlight runs, not exact glyphs or words. Rotated/vertical text needs a provider-specific oriented layer for exact selection; schema v1 provides enclosing rectangles.
|
|
16
|
+
|
|
17
|
+
## Selection and loading
|
|
18
|
+
|
|
19
|
+
`textSelection?: boolean` defaults false. `engine.setTextSelection(enabled)` changes the mode. More actions provides the same control only when a provider exists. Escape exits. Selection uses native browser text selection over transparent runs; page flipping/long-press note placement are suppressed in selection mode. Toolbar and keyboard pagination remain available. Use a page's text payload directly for a separate accessible reading view when necessary; transparent fixed-layout spans are not a reflowable document.
|
|
20
|
+
|
|
21
|
+
At most three pages are retained: current and immediate neighbors. Navigating away aborts pending calls. Destroy and reinitialization abort the session and reject stale completions. null/error pages are retried after leaving their visible range or reinitializing. This API is independent of image resolution and optional backend search.
|
|
22
|
+
|
|
23
|
+
## Example
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
const engine = new FlipbookEngine(container, {
|
|
27
|
+
textLayerProvider: async (pageIndex, signal) => {
|
|
28
|
+
const response = await fetch('/books/42/versions/3/pages/' + pageIndex + '/text', { signal });
|
|
29
|
+
if (!response.ok) throw new Error('Text unavailable');
|
|
30
|
+
return response.json();
|
|
31
|
+
},
|
|
32
|
+
searchProvider: async (query, options, signal) => {
|
|
33
|
+
// Host endpoint returns pageIndex, pageNumber, matches, snippet and normalized highlights.
|
|
34
|
+
return searchBook(query, { ...options, signal });
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
await engine.init('', [{ id:'page-0', pageNumber:1, normal:'/normal/1.webp', low:'/small/1.webp', thumb:'/thumb/1.webp' }]);
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Hosts must authorize every manifest/text/search request, protect against stale source generations and keep extraction bounded. OCR-produced runs can use the same contract once normalized to the displayed page geometry.
|