@embedpdf-editor/chapter-snippet 0.3.0
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/LICENSE +22 -0
- package/NOTICE +7 -0
- package/README.md +68 -0
- package/dist/embedpdf-chapter.d.ts +806 -0
- package/dist/embedpdf-chapter.js +60724 -0
- package/dist/embedpdf-chapter.js.map +1 -0
- package/dist/pdfium.wasm +0 -0
- package/package.json +85 -0
|
@@ -0,0 +1,806 @@
|
|
|
1
|
+
import { AnnotationCapability } from '@embedpdf/plugin-annotation';
|
|
2
|
+
import { AnnotationTransferItem } from '@embedpdf/plugin-annotation';
|
|
3
|
+
import { BasePlugin } from '@embedpdf/core';
|
|
4
|
+
import { BasePluginConfig } from '@embedpdf/core';
|
|
5
|
+
import { ChapterTreeNode } from '../vue/chapter-tree';
|
|
6
|
+
import { ChapterViewerCatalog } from '../vue/chapter-tree';
|
|
7
|
+
import { Command } from '@embedpdf/plugin-commands';
|
|
8
|
+
import { EventHook } from '@embedpdf/core';
|
|
9
|
+
import { PluginBatchRegistration } from '@embedpdf/core';
|
|
10
|
+
import { PluginRegistry } from '@embedpdf/core';
|
|
11
|
+
import { ReactNode } from 'react';
|
|
12
|
+
import { Rect } from '@embedpdf/models';
|
|
13
|
+
import { SelectionCapability } from '@embedpdf/plugin-selection';
|
|
14
|
+
import { UISchema } from '@embedpdf/plugin-ui';
|
|
15
|
+
|
|
16
|
+
/** 对当前选区应用 PDF 划线/高亮,支持按类型自定义颜色、粗细与偏移 */
|
|
17
|
+
export declare function applySelectionMarkup(documentId: string, kind: SelectionMarkupKind, annotation: AnnotationCapability, selection: SelectionCapability, styles?: MarkupStylesConfig): boolean;
|
|
18
|
+
|
|
19
|
+
declare interface BookmarkMarkerUiConfig {
|
|
20
|
+
/** 自定义图标;提供时仅渲染图标,无默认蓝色圆角背景 */
|
|
21
|
+
renderIcon?: (ctx: {
|
|
22
|
+
bookmark: ParagraphBookmark;
|
|
23
|
+
}) => unknown;
|
|
24
|
+
iconSize?: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
declare interface BookmarkMarkerUiConfig_2 {
|
|
28
|
+
/** 自定义图标;提供时仅渲染图标,无默认蓝色背景按钮 */
|
|
29
|
+
renderIcon?: (ctx: {
|
|
30
|
+
bookmark: ParagraphBookmark;
|
|
31
|
+
}) => ReactNode;
|
|
32
|
+
iconSize?: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export declare function buildParagraphBookmarkAnchor(chapterId: string, localPageIndex: number, rectsPdfCoord: Rect[], virtualPage?: {
|
|
36
|
+
globalPageIndex: number;
|
|
37
|
+
globalPageNumber: number;
|
|
38
|
+
}): ParagraphBookmark['anchor'];
|
|
39
|
+
|
|
40
|
+
/** 选区浮窗 card 内置操作 */
|
|
41
|
+
declare type BuiltinSelectionToolbarAction = 'highlight' | 'underline' | 'squiggly' | 'strikeout' | 'note';
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 回调型:把决策交给业务侧异步函数(最常用)。
|
|
45
|
+
*/
|
|
46
|
+
export declare class CallbackPasswordProvider implements IPasswordProvider {
|
|
47
|
+
private readonly cb;
|
|
48
|
+
constructor(cb: (chapter: ChapterDescriptor, attempt: number) => Promise<string | null>);
|
|
49
|
+
resolvePassword(chapter: ChapterDescriptor, attempt: number): Promise<string | null>;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** 归档文件格式版本 */
|
|
53
|
+
export declare const CHAPTER_ANNOTATIONS_ARCHIVE_VERSION: 1;
|
|
54
|
+
|
|
55
|
+
export declare const CHAPTER_SNIPPET_EVENTS: {
|
|
56
|
+
readonly noteRequestCreate: "chapter-note-request-create";
|
|
57
|
+
readonly noteRequestEdit: "chapter-note-request-edit";
|
|
58
|
+
readonly selectionExtraAction: "chapter-selection-extra-action";
|
|
59
|
+
readonly ready: "chapter-viewer-ready";
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/** 全书按 chapterId 分组的归档 */
|
|
63
|
+
export declare interface ChapterAnnotationsArchive {
|
|
64
|
+
version: typeof CHAPTER_ANNOTATIONS_ARCHIVE_VERSION;
|
|
65
|
+
exportedAt: string;
|
|
66
|
+
chapters: Record<string, Omit<ChapterAnnotationsSnapshot, 'chapterId'>>;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export declare function chapterAnnotationsArchiveToJson(archive: ChapterAnnotationsArchive): string;
|
|
70
|
+
|
|
71
|
+
declare type ChapterAnnotationsContentFlags = {
|
|
72
|
+
/** 默认 true */
|
|
73
|
+
bookmarks?: boolean;
|
|
74
|
+
/** 默认 true */
|
|
75
|
+
notes?: boolean;
|
|
76
|
+
/** 默认 true;对应 @embedpdf/plugin-annotation 的 export/import */
|
|
77
|
+
markup?: boolean;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/** 单章用户标注快照 */
|
|
81
|
+
export declare interface ChapterAnnotationsSnapshot {
|
|
82
|
+
chapterId: string;
|
|
83
|
+
bookmarks?: ParagraphBookmark[];
|
|
84
|
+
notes?: NoteAnchor[];
|
|
85
|
+
markup?: SerializableAnnotationTransferItem[];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export declare function chapterAnnotationsSnapshotToJson(snapshot: ChapterAnnotationsSnapshot): string;
|
|
89
|
+
|
|
90
|
+
export declare interface ChapterDescriptor {
|
|
91
|
+
/** 业务唯一 ID;同时复用作 documentManager 的 documentId */
|
|
92
|
+
chapterId: string;
|
|
93
|
+
title: string;
|
|
94
|
+
/**
|
|
95
|
+
* 该章节在「整本」中的全局页范围(闭区间,业务页码,可 1-based 也可 0-based,
|
|
96
|
+
* 只要全局一致即可)。允许相邻章节重叠:`[a, b]` ∩ `[c, d]` ≠ ∅。
|
|
97
|
+
*/
|
|
98
|
+
globalPageRange: [number, number];
|
|
99
|
+
/**
|
|
100
|
+
* 该章节 PDF 文件内部的本地页范围(0-based 闭区间)。
|
|
101
|
+
* 必须满足:`localPageRange[1] - localPageRange[0] === globalPageRange[1] - globalPageRange[0]`
|
|
102
|
+
*/
|
|
103
|
+
localPageRange: [number, number];
|
|
104
|
+
/**
|
|
105
|
+
* PDF 来源。可省略:须在 ChapterManager 配置 `chapterPdfLoader` 中统一加载。
|
|
106
|
+
*/
|
|
107
|
+
source?: ChapterSource;
|
|
108
|
+
encrypted?: boolean;
|
|
109
|
+
/**
|
|
110
|
+
* 仅当 OverlapOwnerStrategy = 'explicit' 时使用:
|
|
111
|
+
* 该章节"声明拥有"的全局页号集合。
|
|
112
|
+
*/
|
|
113
|
+
ownedGlobalPages?: number[];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
declare const ChapterEmbedPDF: {
|
|
117
|
+
version: string;
|
|
118
|
+
init: (config: ContainerInitConfig) => EmbedPdfChapterContainer | undefined;
|
|
119
|
+
};
|
|
120
|
+
export default ChapterEmbedPDF;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* 章节级加载状态。区别于 `@embedpdf/core` 的 DocumentState:
|
|
124
|
+
* - `idle` = manifest 已注册但尚未触发 open
|
|
125
|
+
* - `password-required` = 用户取消/密码错误后停在等密码态
|
|
126
|
+
*/
|
|
127
|
+
export declare type ChapterLoadStatus = 'idle' | 'loading' | 'loaded' | 'error' | 'password-required' | 'closed';
|
|
128
|
+
|
|
129
|
+
declare interface ChapterManagerCapability {
|
|
130
|
+
/** 替换 manifest(会触发已不存在章节的卸载) */
|
|
131
|
+
setManifest(manifest: ChapterManifest, strategy?: OverlapOwnerStrategy): void;
|
|
132
|
+
getManifest(): ChapterManifest;
|
|
133
|
+
getVirtualPageMap(): VirtualPageMap;
|
|
134
|
+
/** ChapterScrollPlugin 在可见页位变化时调用,用以驱动按需加载 */
|
|
135
|
+
setVisibleGlobalPages(visiblePageIndices: number[]): void;
|
|
136
|
+
/** 显式触发某章节加载(如点击章节标题跳转时) */
|
|
137
|
+
ensureChapterLoaded(chapterId: string): Promise<ChapterLoadStatus>;
|
|
138
|
+
/** 状态查询 */
|
|
139
|
+
getChapterStatus(chapterId: string): ChapterLoadStatus;
|
|
140
|
+
getChapter(chapterId: string): ChapterDescriptor | null;
|
|
141
|
+
/** 事件 */
|
|
142
|
+
onChapterStatusChange: EventHook<ChapterStatusEvent>;
|
|
143
|
+
onManifestChange: EventHook<{
|
|
144
|
+
manifest: ChapterManifest;
|
|
145
|
+
map: VirtualPageMap;
|
|
146
|
+
}>;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* 章节生命周期管理:以章节为粒度懒加载/预取/卸载 PDF 文件,并屏蔽密码协议细节。
|
|
151
|
+
*
|
|
152
|
+
* 关键不变量:
|
|
153
|
+
* - 每个章节对 DocumentManager 用 `documentId === chapterId`,从而保持 1:1 缓存。
|
|
154
|
+
* - 视觉上的「activeDocumentId」由本插件根据当前可见页位维护;上层无须感知。
|
|
155
|
+
* - 渲染层最终始终通过 `(chapterId, localPageIndex)` 索引到 owner 章节的 PDF 文档。
|
|
156
|
+
*/
|
|
157
|
+
export declare class ChapterManagerPlugin extends BasePlugin<ChapterManagerPluginConfig, ChapterManagerCapability> {
|
|
158
|
+
static readonly id: "chapter-manager";
|
|
159
|
+
private readonly statusChange$;
|
|
160
|
+
private readonly manifestChange$;
|
|
161
|
+
private config;
|
|
162
|
+
private documentManager;
|
|
163
|
+
private passwordProvider?;
|
|
164
|
+
private manifest;
|
|
165
|
+
private overlapStrategy;
|
|
166
|
+
private virtualPageMap;
|
|
167
|
+
/** 每个章节当前状态(in-memory;不需要 redux 同步) */
|
|
168
|
+
private readonly chapterStatus;
|
|
169
|
+
/** 章节最近一次进入视口或被显式请求的时间戳,用于卸载判断 */
|
|
170
|
+
private readonly chapterLastUsed;
|
|
171
|
+
/** 章节密码累计尝试次数 */
|
|
172
|
+
private readonly passwordAttempts;
|
|
173
|
+
/** 等待 ensureChapterLoaded 完成的 Promise 列表(按章节去重) */
|
|
174
|
+
private readonly pendingLoadPromises;
|
|
175
|
+
/** unload tick 句柄 */
|
|
176
|
+
private unloadTimer;
|
|
177
|
+
private documentManagerUnsubs;
|
|
178
|
+
constructor(id: string, registry: PluginRegistry);
|
|
179
|
+
initialize(config: ChapterManagerPluginConfig): Promise<void>;
|
|
180
|
+
protected buildCapability(): ChapterManagerCapability;
|
|
181
|
+
destroy(): void;
|
|
182
|
+
private setManifestInternal;
|
|
183
|
+
/** manifest 就绪后预取前 N 章(不依赖滚动视口是否已算出可见页) */
|
|
184
|
+
private eagerPrefetchFromManifest;
|
|
185
|
+
private findChapter;
|
|
186
|
+
private isOwnedChapter;
|
|
187
|
+
private handleVisibleChange;
|
|
188
|
+
private collectIdleChapters;
|
|
189
|
+
ensureChapterLoaded(chapterId: string): Promise<ChapterLoadStatus>;
|
|
190
|
+
private resolvePdfPayload;
|
|
191
|
+
private startLoad;
|
|
192
|
+
/** 阻塞等待该章节状态进入 loaded / error / password-required / closed */
|
|
193
|
+
private waitForTerminalStatus;
|
|
194
|
+
private handleDocumentError;
|
|
195
|
+
private closeChapter;
|
|
196
|
+
private updateStatus;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
declare interface ChapterManagerPluginConfig extends BasePluginConfig {
|
|
200
|
+
manifest: ChapterManifest;
|
|
201
|
+
overlapStrategy?: OverlapOwnerStrategy;
|
|
202
|
+
passwordProvider?: IPasswordProvider;
|
|
203
|
+
/** 未在 descriptor.source 中指定 PDF 时,由此统一加载 */
|
|
204
|
+
chapterPdfLoader?: IChapterPdfLoader;
|
|
205
|
+
/** 视口前后预取多少章节,默认 1 */
|
|
206
|
+
prefetchChapters?: number;
|
|
207
|
+
/** 章节空闲多久后卸载(毫秒),默认 60s。设为 0 关闭卸载 */
|
|
208
|
+
unloadTimeoutMs?: number;
|
|
209
|
+
/** 第一个加载的章节是否自动设为 active,默认 true */
|
|
210
|
+
autoActivateOnLoad?: boolean;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export declare interface ChapterManifest {
|
|
214
|
+
chapters: ChapterDescriptor[];
|
|
215
|
+
/**
|
|
216
|
+
* 整本去重后的总页数。当未提供时由 VirtualPageMap 自动推导
|
|
217
|
+
* (取所有章节 globalPageRange 的并集大小)。
|
|
218
|
+
*/
|
|
219
|
+
totalGlobalPages?: number;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** 笔记创建请求(与 plugin-note 回调 payload 对齐) */
|
|
223
|
+
export declare type ChapterNoteRequestCreateDetail = {
|
|
224
|
+
draft: NoteDraft;
|
|
225
|
+
complete: (noteId: string) => void | Promise<void>;
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
/** 笔记编辑请求 */
|
|
229
|
+
export declare type ChapterNoteRequestEditDetail = {
|
|
230
|
+
noteId: string;
|
|
231
|
+
anchor: NoteAnchor;
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Backend-supplied chapter contract.
|
|
236
|
+
*
|
|
237
|
+
* 一个 PDF 整体被后端按章节切成若干独立 PDF 文件;前端将它们组装成一条
|
|
238
|
+
* 连续滚动流。相邻章节在 `globalPageRange` 上**允许重叠**(业务上下章
|
|
239
|
+
* 经常各含一个过渡页),由 OverlapResolver 决定每个全局页归属的「owner
|
|
240
|
+
* chapter」,渲染与标注都落在 owner 上以保持唯一性。
|
|
241
|
+
*/
|
|
242
|
+
/** 章节 PDF 解析结果 */
|
|
243
|
+
export declare type ChapterPdfPayload = {
|
|
244
|
+
url: string;
|
|
245
|
+
} | {
|
|
246
|
+
buffer: ArrayBuffer;
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
/** 划词工具栏扩展操作事件 */
|
|
250
|
+
export declare type ChapterSelectionActionDetail = {
|
|
251
|
+
actionId: string;
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* 章节 PDF 来源(由业务在 manifest 中提供):
|
|
256
|
+
* - `url`:直接打开该地址
|
|
257
|
+
* - `buffer`:已取回的 PDF 二进制
|
|
258
|
+
* - `load`:按章节自定义拉取(鉴权、本地 FS 等)
|
|
259
|
+
*/
|
|
260
|
+
export declare type ChapterSource = {
|
|
261
|
+
url: string;
|
|
262
|
+
} | {
|
|
263
|
+
buffer: ArrayBuffer;
|
|
264
|
+
} | {
|
|
265
|
+
load: () => Promise<ChapterPdfPayload>;
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
declare interface ChapterStatusEvent {
|
|
269
|
+
chapterId: string;
|
|
270
|
+
status: ChapterLoadStatus;
|
|
271
|
+
/** 仅在 status === 'error' 时有意义 */
|
|
272
|
+
error?: {
|
|
273
|
+
message: string;
|
|
274
|
+
code?: number;
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export { ChapterTreeNode }
|
|
279
|
+
|
|
280
|
+
export { ChapterViewerCatalog }
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* 用户侧功能配置(简化写法):
|
|
284
|
+
* - 省略或 `true`:开启并使用默认样式
|
|
285
|
+
* - `false`:关闭
|
|
286
|
+
* - 对象:开启并覆盖对应字段
|
|
287
|
+
*/
|
|
288
|
+
export declare type ChapterViewerConfig = {
|
|
289
|
+
markup?: boolean | {
|
|
290
|
+
styles?: MarkupStylesConfig;
|
|
291
|
+
};
|
|
292
|
+
bookmarks?: boolean | {
|
|
293
|
+
marker?: BookmarkMarkerUiConfig;
|
|
294
|
+
hover?: HoverBookmarkUiConfig;
|
|
295
|
+
};
|
|
296
|
+
notes?: boolean | {
|
|
297
|
+
marker?: NoteMarkerUiConfig;
|
|
298
|
+
};
|
|
299
|
+
zoom?: boolean | ChapterViewerZoomConfig;
|
|
300
|
+
/** 默认随划线/笔记开启;仅在有扩展按钮或需隐藏内置按钮时配置 */
|
|
301
|
+
selectionToolbar?: boolean | SelectionToolbarConfig;
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
export declare type ChapterViewerContainerConfig = ChapterViewerSnippetConfig;
|
|
305
|
+
|
|
306
|
+
/** 渲染器内部使用的规范化功能配置 */
|
|
307
|
+
export declare interface ChapterViewerFeaturesConfig {
|
|
308
|
+
/** 划线/高亮 */
|
|
309
|
+
markup?: {
|
|
310
|
+
enabled?: boolean;
|
|
311
|
+
styles?: MarkupStylesConfig;
|
|
312
|
+
};
|
|
313
|
+
/** 段落书签(含悬停添加) */
|
|
314
|
+
bookmarks?: {
|
|
315
|
+
enabled?: boolean;
|
|
316
|
+
marker?: BookmarkMarkerUiConfig;
|
|
317
|
+
hover?: HoverBookmarkUiConfig;
|
|
318
|
+
};
|
|
319
|
+
/** 笔记 */
|
|
320
|
+
notes?: {
|
|
321
|
+
enabled?: boolean;
|
|
322
|
+
marker?: NoteMarkerUiConfig;
|
|
323
|
+
};
|
|
324
|
+
/** 选区浮窗 */
|
|
325
|
+
selectionToolbar?: SelectionToolbarConfig;
|
|
326
|
+
/** 缩放 */
|
|
327
|
+
zoom?: ChapterViewerZoomConfig;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/** 章节阅读器统一配置(推荐入口) */
|
|
331
|
+
export declare interface ChapterViewerOptions {
|
|
332
|
+
manifest: ChapterManifest;
|
|
333
|
+
/** 笔记持久化与弹窗回调 */
|
|
334
|
+
notes: NoteCallbacks;
|
|
335
|
+
/** 书签持久化与删除回调 */
|
|
336
|
+
bookmarks: ParagraphBookmarkCallbacks;
|
|
337
|
+
chapterPdfLoader?: IChapterPdfLoader;
|
|
338
|
+
/** 功能开关与样式;省略则全开 */
|
|
339
|
+
features?: ChapterViewerConfig;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
export declare type ChapterViewerSnippetConfig = {
|
|
343
|
+
/** PDFium wasm 地址,默认 jsdelivr */
|
|
344
|
+
wasmUrl?: string;
|
|
345
|
+
/** 是否使用 worker 引擎,默认 true */
|
|
346
|
+
worker?: boolean;
|
|
347
|
+
/** worker 首章加载超时后是否自动降级到 direct engine,默认 true */
|
|
348
|
+
fallbackToDirectEngine?: boolean;
|
|
349
|
+
/** 首章加载超时时间;用于 worker fallback,默认 8000ms */
|
|
350
|
+
workerOpenTimeoutMs?: number;
|
|
351
|
+
/** 章节编辑器选项(manifest + 书签/笔记回调) */
|
|
352
|
+
editorInput: CreateChapterViewerEditorOptionsInput;
|
|
353
|
+
/** 阅读器功能开关,默认与 DEFAULT_CHAPTER_VIEWER_FEATURES 合并 */
|
|
354
|
+
features?: ChapterViewerFeaturesConfig;
|
|
355
|
+
className?: string;
|
|
356
|
+
viewportClassName?: string;
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
declare interface ChapterViewerZoomConfig {
|
|
360
|
+
/** 是否启用 Ctrl+滚轮 / 双指捏合等交互缩放,默认 true;为 false 时仍可用 pageWidth / initial 设置版面宽度 */
|
|
361
|
+
enabled?: boolean;
|
|
362
|
+
min?: number;
|
|
363
|
+
max?: number;
|
|
364
|
+
/** 文档 scale 初始值;未设置且配置了 pageWidth 时由 pageWidth 按首页宽度推导 */
|
|
365
|
+
initial?: number;
|
|
366
|
+
/**
|
|
367
|
+
* 页面布局目标宽度(CSS px)。
|
|
368
|
+
* 章节 PDF 加载后按 `pageWidth / pdfPageWidth` 设置 document scale,与 RenderLayer / 滚动占位一致。
|
|
369
|
+
*/
|
|
370
|
+
pageWidth?: number;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
export declare type ContainerInitConfig = ChapterViewerContainerConfig & {
|
|
374
|
+
type: 'container';
|
|
375
|
+
target: Element;
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
/** 生成插件列表 + 规范化后的 features(供 EmbedPDF / PdfChapterViewport 使用) */
|
|
379
|
+
export declare function createChapterViewerBundle(input: ChapterViewerOptions | CreateChapterViewerEditorOptionsInput): {
|
|
380
|
+
plugins: PluginBatchRegistration<any, any, any, any>[];
|
|
381
|
+
features: ChapterViewerFeaturesConfig;
|
|
382
|
+
editorOptions: CreatePdfChapterEditorOptions;
|
|
383
|
+
};
|
|
384
|
+
|
|
385
|
+
/** 进阶用法:仅生成 editor 配置(不含 features,需自行传给 PdfChapterViewport) */
|
|
386
|
+
export declare function createChapterViewerEditorOptions(input: ChapterViewerOptions | CreateChapterViewerEditorOptionsInput): Omit<CreatePdfChapterEditorOptions, 'features'>;
|
|
387
|
+
|
|
388
|
+
/** @deprecated 旧版嵌套 `callbacks` 写法,仍兼容 */
|
|
389
|
+
export declare type CreateChapterViewerEditorOptionsInput = {
|
|
390
|
+
manifest: ChapterManifest;
|
|
391
|
+
chapterPdfLoader?: IChapterPdfLoader;
|
|
392
|
+
bookmarks: {
|
|
393
|
+
callbacks: ParagraphBookmarkCallbacks;
|
|
394
|
+
};
|
|
395
|
+
notes: {
|
|
396
|
+
callbacks: NoteCallbacks;
|
|
397
|
+
};
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
declare interface CreateEditorUiSchemaOptions {
|
|
401
|
+
/** 默认全开 */
|
|
402
|
+
enabledModes?: EditorModeId[];
|
|
403
|
+
customOperations?: OperationSpec[];
|
|
404
|
+
/** 合并进最终 schema 的额外 toolbars / menus 等 */
|
|
405
|
+
extend?: Partial<Pick<UISchema, 'toolbars' | 'menus' | 'sidebars' | 'modals' | 'selectionMenus'>>;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
export declare interface CreatePdfChapterEditorOptions {
|
|
409
|
+
manifest: ChapterManifest;
|
|
410
|
+
overlapStrategy?: OverlapOwnerStrategy;
|
|
411
|
+
passwordProvider?: IPasswordProvider;
|
|
412
|
+
/** 章节未在 manifest 中写 source 时,由此加载 PDF */
|
|
413
|
+
chapterPdfLoader?: IChapterPdfLoader;
|
|
414
|
+
notes?: PdfChapterEditorNotesConfig;
|
|
415
|
+
bookmarks?: PdfChapterEditorBookmarksConfig;
|
|
416
|
+
toolbar?: PdfChapterEditorToolbarConfig;
|
|
417
|
+
/** 传给 chapter-manager;manifest 就绪后预取前 N 章 */
|
|
418
|
+
prefetchChapters?: number;
|
|
419
|
+
/** 为 false 时不拉取 CDN 默认图章库(@embedpdf/default-stamps) */
|
|
420
|
+
loadDefaultStampLibrary?: boolean;
|
|
421
|
+
unloadTimeoutMs?: number;
|
|
422
|
+
/** 传给 chapter-scroll */
|
|
423
|
+
placeholderPageHeight?: number;
|
|
424
|
+
placeholderPageWidth?: number;
|
|
425
|
+
/** 合并进 Commands 插件(如 mode / annotation / form 等) */
|
|
426
|
+
commands?: Record<string, Command>;
|
|
427
|
+
/**
|
|
428
|
+
* 章节阅读器集成功能(划线/笔记/书签/选区 card / 缩放)。
|
|
429
|
+
* 默认 demo 样式;各子项可单独关闭或扩展。
|
|
430
|
+
*/
|
|
431
|
+
features?: ChapterViewerFeaturesConfig;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/** 用户侧默认:省略 `options.features` 即等价于此空对象(全部功能开启) */
|
|
435
|
+
export declare const DEFAULT_CHAPTER_VIEWER_CONFIG: ChapterViewerConfig;
|
|
436
|
+
|
|
437
|
+
/** 默认全开的功能配置(内部规范化结果) */
|
|
438
|
+
export declare const DEFAULT_CHAPTER_VIEWER_FEATURES: ChapterViewerFeaturesConfig;
|
|
439
|
+
|
|
440
|
+
export declare function downloadChapterAnnotationsArchive(archive: ChapterAnnotationsArchive, filename?: string): void;
|
|
441
|
+
|
|
442
|
+
export declare function downloadChapterAnnotationsSnapshot(snapshot: ChapterAnnotationsSnapshot, filename?: string): void;
|
|
443
|
+
|
|
444
|
+
/** 触发浏览器下载 JSON 文件(仅浏览器环境) */
|
|
445
|
+
export declare function downloadJsonFile(filename: string, json: string): void;
|
|
446
|
+
|
|
447
|
+
/** 与 snippet 主工具栏 mode tabs 对齐的编辑模式 */
|
|
448
|
+
declare type EditorModeId = 'view' | 'annotate' | 'shapes' | 'insert' | 'form' | 'redact';
|
|
449
|
+
|
|
450
|
+
export declare class EmbedPdfChapterContainer extends EmbedPdfChapterContainer_base {
|
|
451
|
+
private root;
|
|
452
|
+
private mountEl;
|
|
453
|
+
private _config?;
|
|
454
|
+
private _registryPromise;
|
|
455
|
+
private _resolveRegistry;
|
|
456
|
+
constructor();
|
|
457
|
+
connectedCallback(): void;
|
|
458
|
+
private ensureMountEl;
|
|
459
|
+
/**
|
|
460
|
+
* Preact render() 会清空挂载点;样式作为 shadow 内兄弟节点,在每次 render 后注入。
|
|
461
|
+
*/
|
|
462
|
+
private ensureBaseStyles;
|
|
463
|
+
disconnectedCallback(): void;
|
|
464
|
+
set config(newConfig: ChapterViewerContainerConfig);
|
|
465
|
+
get config(): ChapterViewerContainerConfig | undefined;
|
|
466
|
+
get registry(): Promise<PluginRegistry>;
|
|
467
|
+
private handleRegistryReady;
|
|
468
|
+
private renderViewer;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
declare const EmbedPdfChapterContainer_base: typeof HTMLElement;
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* 导出 manifest 中全部章节(按 chapterId 存 JSON 对象)。
|
|
475
|
+
*/
|
|
476
|
+
export declare function exportAllChapterAnnotations(registry: PluginRegistry, manifest: ChapterManifest, options?: ExportChapterAnnotationsOptions): Promise<ChapterAnnotationsArchive>;
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* 导出单章用户标注(书签、笔记、划词划线)。
|
|
480
|
+
* `chapterId` 与章节 documentId 一致。
|
|
481
|
+
*/
|
|
482
|
+
export declare function exportChapterAnnotations(registry: PluginRegistry, chapterId: string, options?: ExportChapterAnnotationsOptions): Promise<ChapterAnnotationsSnapshot>;
|
|
483
|
+
|
|
484
|
+
export declare type ExportChapterAnnotationsOptions = ChapterAnnotationsContentFlags & {
|
|
485
|
+
/** 导出前确保章节 PDF 已加载(划线需要),默认 true */
|
|
486
|
+
ensureChapterLoaded?: boolean;
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
declare interface HoverBookmarkUiConfig {
|
|
490
|
+
/** 悬停行末「添加书签」自定义图标;无背景 */
|
|
491
|
+
renderAddIcon?: () => unknown;
|
|
492
|
+
iconSize?: number;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
declare interface HoverBookmarkUiConfig_2 {
|
|
496
|
+
renderAddIcon?: () => ReactNode;
|
|
497
|
+
iconSize?: number;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* 全局章节 PDF 加载器:当 `ChapterDescriptor.source` 未提供 url/buffer/load 时使用。
|
|
502
|
+
* 适合统一走业务 API、鉴权下载等场景。
|
|
503
|
+
*/
|
|
504
|
+
export declare interface IChapterPdfLoader {
|
|
505
|
+
loadPdf(chapter: ChapterDescriptor): Promise<ChapterPdfPayload>;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* 导入单章快照。
|
|
510
|
+
*/
|
|
511
|
+
export declare function importChapterAnnotations(registry: PluginRegistry, snapshot: ChapterAnnotationsSnapshot, options?: ImportChapterAnnotationsOptions): Promise<void>;
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* 导入全书归档(仅处理 archive.chapters 中存在的 chapterId)。
|
|
515
|
+
*/
|
|
516
|
+
export declare function importChapterAnnotationsArchive(registry: PluginRegistry, archive: ChapterAnnotationsArchive, options?: ImportChapterAnnotationsOptions): Promise<void>;
|
|
517
|
+
|
|
518
|
+
export declare type ImportChapterAnnotationsOptions = ChapterAnnotationsContentFlags & {
|
|
519
|
+
/**
|
|
520
|
+
* replace:先清空该章对应数据再写入;
|
|
521
|
+
* merge:划线/笔记/书签与现有合并(书签按 anchor 去重)。
|
|
522
|
+
*/
|
|
523
|
+
mode?: 'replace' | 'merge';
|
|
524
|
+
/** 导入前确保章节已加载,默认 true */
|
|
525
|
+
ensureChapterLoaded?: boolean;
|
|
526
|
+
/** 导入完成后回调,便于写入 localStorage / 后端 */
|
|
527
|
+
persistNotes?: (allNotes: NoteAnchor[]) => void | Promise<void>;
|
|
528
|
+
persistBookmarks?: (allBookmarks: ParagraphBookmark[]) => void | Promise<void>;
|
|
529
|
+
};
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* 章节加密的抽象接口:当某章节首次或重试加载因密码失败时,
|
|
533
|
+
* `ChapterManagerPlugin` 会向 provider 询问密码。
|
|
534
|
+
*
|
|
535
|
+
* 返回 `null` 表示用户/系统放弃,对应章节进入 `password-required` 状态。
|
|
536
|
+
*/
|
|
537
|
+
declare interface IPasswordProvider {
|
|
538
|
+
/**
|
|
539
|
+
* @param chapter 失败章节描述
|
|
540
|
+
* @param attempt 已经尝试次数(0 = 首次),可用于实现"输错三次锁定"等策略
|
|
541
|
+
*/
|
|
542
|
+
resolvePassword(chapter: ChapterDescriptor, attempt: number): Promise<string | null>;
|
|
543
|
+
/** 可选:同步快查缓存,避免显式 await */
|
|
544
|
+
getCachedPassword?(chapterId: string): string | null;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/** 单种划线的样式(颜色、粗细、垂直偏移,PDF 点) */
|
|
548
|
+
declare interface MarkupKindStyle {
|
|
549
|
+
/** 描边/填充色,如 #facc15 */
|
|
550
|
+
color?: string;
|
|
551
|
+
/** 线宽(下划线/删除线等),PDF 点 */
|
|
552
|
+
thickness?: number;
|
|
553
|
+
/** 相对字形底边的垂直偏移,正值向下(PDF 点) */
|
|
554
|
+
offsetY?: number;
|
|
555
|
+
opacity?: number;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
declare type MarkupStylesConfig = Partial<Record<SelectionMarkupKind, MarkupKindStyle>>;
|
|
559
|
+
|
|
560
|
+
/** 将用户侧简化配置规范为渲染器内部使用的结构 */
|
|
561
|
+
export declare function normalizeChapterViewerConfig(config?: ChapterViewerConfig): ChapterViewerFeaturesConfig;
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* 一条附注(note)的位置锚点。
|
|
565
|
+
* - `rectsPdfCoord` 来自 selection.getHighlightRectsForPage 的 PDF 坐标系
|
|
566
|
+
* - `endAnchor` 用于"末尾图标"渲染:取选区最后一行 right 边缘
|
|
567
|
+
* - `noteId` 由开发者回调返回(服务端 ID),插件本身不生成
|
|
568
|
+
*/
|
|
569
|
+
export declare interface NoteAnchor {
|
|
570
|
+
noteId: string;
|
|
571
|
+
chapterId: string;
|
|
572
|
+
globalPageIndex: number;
|
|
573
|
+
globalPageNumber: number;
|
|
574
|
+
localPageIndex: number;
|
|
575
|
+
rectsPdfCoord: Rect[];
|
|
576
|
+
endAnchor: {
|
|
577
|
+
x: number;
|
|
578
|
+
y: number;
|
|
579
|
+
};
|
|
580
|
+
selectedText: string;
|
|
581
|
+
/** 用户填写的笔记正文(由业务持久化) */
|
|
582
|
+
content?: string;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
declare interface NoteCallbacks {
|
|
586
|
+
/** 初次加载已有附注 */
|
|
587
|
+
loadNotes?: () => Promise<NoteAnchor[]>;
|
|
588
|
+
/**
|
|
589
|
+
* 内置创建:持久化后返回 noteId。
|
|
590
|
+
* 与 onRequestCreateNote 二选一(至少配置其一)。
|
|
591
|
+
*/
|
|
592
|
+
onCreateNote?: (draft: NoteDraft) => Promise<{
|
|
593
|
+
noteId: string;
|
|
594
|
+
} | null>;
|
|
595
|
+
/**
|
|
596
|
+
* 自定义创建弹窗:仅发出事件,由宿主 complete(noteId)。
|
|
597
|
+
* 配置后划词/默认流程不再调用 onCreateNote。
|
|
598
|
+
*/
|
|
599
|
+
onRequestCreateNote?: (payload: NoteCreateRequestPayload) => void;
|
|
600
|
+
/** 自定义编辑:传出 noteId */
|
|
601
|
+
onRequestEditNote?: (noteId: string, anchor: NoteAnchor) => void;
|
|
602
|
+
onUpdateNote?: (note: NoteAnchor) => Promise<void>;
|
|
603
|
+
onDeleteNote?: (noteId: string) => Promise<void>;
|
|
604
|
+
/** 点击编辑且未配置 onRequestEditNote 时回退 */
|
|
605
|
+
onActivateNote?: (noteId: string, anchor: NoteAnchor) => void;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
/** 自定义笔记创建:宿主打开 UI 后调用 complete(noteId) */
|
|
609
|
+
declare interface NoteCreateRequestPayload {
|
|
610
|
+
draft: NoteDraft;
|
|
611
|
+
complete: (noteId: string) => Promise<void>;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
/** 一个尚未持久化的草稿(开发者回调拿到的) */
|
|
615
|
+
export declare type NoteDraft = Omit<NoteAnchor, 'noteId'>;
|
|
616
|
+
|
|
617
|
+
declare interface NoteMarkerMenuActionCtx {
|
|
618
|
+
note: NoteAnchor;
|
|
619
|
+
onEdit: () => void;
|
|
620
|
+
onDelete: () => void;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
declare interface NoteMarkerUiConfig {
|
|
624
|
+
/** 自定义笔记标识图标;提供时无圆形背景 */
|
|
625
|
+
renderIcon?: (ctx: {
|
|
626
|
+
note: NoteAnchor;
|
|
627
|
+
}) => unknown;
|
|
628
|
+
/** 完全自定义编辑/删除区域;不提供则使用默认 card */
|
|
629
|
+
renderMenuActions?: (ctx: NoteMarkerMenuActionCtx) => unknown;
|
|
630
|
+
iconSize?: number;
|
|
631
|
+
/** 笔记高亮底色的 CSS 颜色,默认 rgba(245,158,11,0.08) */
|
|
632
|
+
highlightColor?: string;
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
declare interface OperationHandlerContext {
|
|
636
|
+
documentId: string | null;
|
|
637
|
+
chapterId: string | null;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/** 自定义操作挂载到某条 secondary toolbar */
|
|
641
|
+
declare interface OperationSpec {
|
|
642
|
+
id: string;
|
|
643
|
+
modeId: EditorModeId;
|
|
644
|
+
/** 对应 {@link editorSecondaryToolbars} 的 key */
|
|
645
|
+
toolbarSlot: 'annotation-toolbar' | 'shapes-toolbar' | 'insert-toolbar' | 'form-toolbar' | 'redaction-toolbar';
|
|
646
|
+
/** 插入到某 toolbar item 之后;缺省则追加到 tools group 末尾 */
|
|
647
|
+
position?: {
|
|
648
|
+
after?: string;
|
|
649
|
+
before?: string;
|
|
650
|
+
};
|
|
651
|
+
commandId: string;
|
|
652
|
+
icon?: string;
|
|
653
|
+
i18nKey?: string;
|
|
654
|
+
label?: string;
|
|
655
|
+
categories?: string[];
|
|
656
|
+
/** 注册到 Commands 插件时的执行体(由宿主在 createPdfChapterEditor 里注入) */
|
|
657
|
+
handler?: (ctx: OperationHandlerContext) => void | Promise<void>;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
/**
|
|
661
|
+
* 决定相邻章节在重叠页上谁拥有该页(owner)。
|
|
662
|
+
* - first-wins / last-wins:按 manifest 顺序的先到/后到
|
|
663
|
+
* - explicit:依赖 `ChapterDescriptor.ownedGlobalPages`
|
|
664
|
+
* - custom:开发者完全接管
|
|
665
|
+
*/
|
|
666
|
+
declare type OverlapOwnerStrategy = {
|
|
667
|
+
kind: 'first-wins';
|
|
668
|
+
} | {
|
|
669
|
+
kind: 'last-wins';
|
|
670
|
+
} | {
|
|
671
|
+
kind: 'explicit';
|
|
672
|
+
} | {
|
|
673
|
+
kind: 'custom';
|
|
674
|
+
resolve: (globalPage: number, candidates: ChapterDescriptor[]) => string;
|
|
675
|
+
};
|
|
676
|
+
|
|
677
|
+
export declare interface ParagraphBookmark {
|
|
678
|
+
id: string;
|
|
679
|
+
label: string;
|
|
680
|
+
/** 业务可选元数据;插件直接存不解释 */
|
|
681
|
+
metadata?: Record<string, unknown>;
|
|
682
|
+
anchor: {
|
|
683
|
+
chapterId: string;
|
|
684
|
+
localPageIndex: number;
|
|
685
|
+
/** 创建时虚拟页索引(与附注一致,避免 toGlobal 映射偏差) */
|
|
686
|
+
globalPageIndex?: number;
|
|
687
|
+
/** 创建时业务页号 */
|
|
688
|
+
globalPageNumber?: number;
|
|
689
|
+
/** PDF 坐标系包围盒(多行选区时为各行并集) */
|
|
690
|
+
rectPdfCoord: Rect;
|
|
691
|
+
/** 各行 PDF 矩形(划词书签时与选区高亮一致) */
|
|
692
|
+
rectsPdfCoord?: Rect[];
|
|
693
|
+
/** 书签图标锚点(通常为选区末行右下角,PDF 坐标) */
|
|
694
|
+
markerAnchor?: {
|
|
695
|
+
x: number;
|
|
696
|
+
y: number;
|
|
697
|
+
};
|
|
698
|
+
};
|
|
699
|
+
createdAt: number;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
declare interface ParagraphBookmarkCallbacks {
|
|
703
|
+
/** 初次加载已有书签 */
|
|
704
|
+
load?: () => Promise<ParagraphBookmark[]>;
|
|
705
|
+
/** 任意变更(新增 / 删除 / 改名)后回调,便于持久化 */
|
|
706
|
+
persist?: (entries: ParagraphBookmark[]) => Promise<void>;
|
|
707
|
+
/**
|
|
708
|
+
* 用户请求删除书签:由外部完成持久化删除。
|
|
709
|
+
* 返回 true 时插件会从渲染层移除该书签。
|
|
710
|
+
*/
|
|
711
|
+
onRequestRemove?: (bookmark: ParagraphBookmark) => Promise<boolean>;
|
|
712
|
+
/** 书签已从插件内存移除后通知(便于 UI 收尾) */
|
|
713
|
+
onRemoveSuccess?: (bookmarkId: string) => void;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
declare interface ParagraphBookmarkPluginConfig extends BasePluginConfig {
|
|
717
|
+
callbacks?: ParagraphBookmarkCallbacks;
|
|
718
|
+
ui?: BookmarkMarkerUiConfig_2;
|
|
719
|
+
hover?: HoverBookmarkUiConfig_2;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
export declare function parseChapterAnnotationsArchiveJson(json: string): ChapterAnnotationsArchive;
|
|
723
|
+
|
|
724
|
+
export declare function parseChapterAnnotationsSnapshotJson(json: string): ChapterAnnotationsSnapshot;
|
|
725
|
+
|
|
726
|
+
export declare interface PdfChapterEditorBookmarksConfig {
|
|
727
|
+
callbacks: NonNullable<ParagraphBookmarkPluginConfig['callbacks']>;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
export declare interface PdfChapterEditorNotesConfig {
|
|
731
|
+
callbacks: NoteCallbacks;
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
declare interface PdfChapterEditorToolbarConfig extends CreateEditorUiSchemaOptions {
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
/** 划线类型 */
|
|
738
|
+
declare type SelectionMarkupKind = 'highlight' | 'underline' | 'squiggly' | 'strikeout';
|
|
739
|
+
|
|
740
|
+
declare interface SelectionToolbarConfig {
|
|
741
|
+
/** 是否显示默认 card,默认 true */
|
|
742
|
+
enabled?: boolean;
|
|
743
|
+
/** 隐藏部分内置按钮 */
|
|
744
|
+
hiddenBuiltinActions?: BuiltinSelectionToolbarAction[];
|
|
745
|
+
/** 扩展操作(由宿主在 buildSelectionMenu 或 onExtraAction 中处理) */
|
|
746
|
+
extraActions?: SelectionToolbarExtraAction[];
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
/** 扩展选区操作 */
|
|
750
|
+
declare interface SelectionToolbarExtraAction {
|
|
751
|
+
id: string;
|
|
752
|
+
label: string;
|
|
753
|
+
/** 排序权重,越小越靠前(在内置 markup 之后、note 之前) */
|
|
754
|
+
order?: number;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
/** JSON 中可存储的划线(stamp 的 ArrayBuffer 转为 base64) */
|
|
758
|
+
export declare interface SerializableAnnotationTransferItem {
|
|
759
|
+
annotation: AnnotationTransferItem['annotation'];
|
|
760
|
+
ctx?: {
|
|
761
|
+
dataBase64?: string;
|
|
762
|
+
mimeType?: string;
|
|
763
|
+
};
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
export declare const version = "0.1.0";
|
|
767
|
+
|
|
768
|
+
/**
|
|
769
|
+
* 一个虚拟页位的解析结果。`localPageIndex` 是 owner 章节 PDF 内的 0-based 索引。
|
|
770
|
+
*/
|
|
771
|
+
declare interface VirtualPageLocation {
|
|
772
|
+
globalPageIndex: number;
|
|
773
|
+
globalPageNumber: number;
|
|
774
|
+
chapterId: string;
|
|
775
|
+
localPageIndex: number;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
/**
|
|
779
|
+
* 跨章节 PDF 的「全局页 ↔ (章节, 本地页)」映射。
|
|
780
|
+
*
|
|
781
|
+
* 设计要点:
|
|
782
|
+
* - 「globalPageNumber」是后端 manifest 里的业务页号,可能不连续(极端情况)。
|
|
783
|
+
* - 「globalPageIndex」是去重后排序的 0-based 紧凑索引,是滚动/虚拟列表使用的页位。
|
|
784
|
+
* 这样上层 `ChapterScroll` 不必关心业务页号是否连续。
|
|
785
|
+
*/
|
|
786
|
+
declare class VirtualPageMap {
|
|
787
|
+
private readonly _pages;
|
|
788
|
+
private readonly _byChapter;
|
|
789
|
+
private readonly _byGlobalNumber;
|
|
790
|
+
constructor(pages: VirtualPageLocation[]);
|
|
791
|
+
get totalPages(): number;
|
|
792
|
+
/** 顺序返回所有去重后的页位 */
|
|
793
|
+
list(): readonly VirtualPageLocation[];
|
|
794
|
+
/** 由 0-based 紧凑索引取页位 */
|
|
795
|
+
atIndex(globalPageIndex: number): VirtualPageLocation | null;
|
|
796
|
+
/** 由后端业务页号取页位 */
|
|
797
|
+
byGlobalNumber(globalPageNumber: number): VirtualPageLocation | null;
|
|
798
|
+
/** 由 (章节, 本地页) 反查到 owner 视图下的全局位置;非 owner 章节会返回 null */
|
|
799
|
+
toGlobal(chapterId: string, localPageIndex: number): VirtualPageLocation | null;
|
|
800
|
+
/** 该章节在虚拟视图中实际「被采用」的页(owner 命中的) */
|
|
801
|
+
pagesOfChapter(chapterId: string): readonly VirtualPageLocation[];
|
|
802
|
+
/** 拿一个章节首次出现的虚拟索引(用于 scrollToChapter) */
|
|
803
|
+
firstIndexOfChapter(chapterId: string): number;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
export { }
|