@file-viewer/vue3 2.2.2 → 2.2.4

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/README.en.md CHANGED
@@ -43,7 +43,7 @@ The Vue 3 component follows host lifecycle teardown. Inside Element Plus `el-dia
43
43
  <!-- FILE_VIEWER_GENERATED:START -->
44
44
  ## Ecosystem Matrix
45
45
 
46
- Every standard component package shares `@file-viewer/core` as the only common foundation, and no framework component package depends on another framework implementation. Core owns format metadata, source loading, the renderer protocol, events, operation APIs, search, zoom, print, and export. Heavy PDF, Word, PPT/PPTX, CAD, Typst, and similar pipelines are assembled explicitly through renderer packages or presets; each framework package owns its local controller, component lifecycle, type exports, and ecosystem-specific interaction layer.
46
+ Every standard component package shares `@file-viewer/core` as the only common foundation, and no framework component package depends on another framework implementation. Core owns format metadata, source loading, the renderer protocol, events, operation APIs, search, zoom, print, export, and the framework-neutral browser shell. Heavy PDF, Word, PPT/PPTX, CAD, Typst, and similar pipelines are assembled explicitly through renderer packages or presets; each framework package owns its component lifecycle, type exports, compatibility defaults, and ecosystem-specific interaction layer.
47
47
 
48
48
  | Framework | Standard npm package | Entrypoints | GitHub | Gitee | Historical aliases |
49
49
  | --- | --- | --- | --- | --- | --- |
@@ -213,7 +213,7 @@ Every ecosystem package uses the same `ViewerMountOptions` and `FileViewerOption
213
213
  | `type` | Explicit extension or MIME hint that overrides automatic detection. |
214
214
  | `size` | File size hint used in lifecycle context, loading states, and safety limits. |
215
215
  | `options` | The shared `FileViewerOptions` surface. Every component package keeps the same semantics. |
216
- | `options.styleIsolation` | `auto`, `shadow`, `scoped`, or `none`. Pure Web / IIFE / Custom Element entries default to strong isolation; framework packages keep compatibility by default and can opt renderer content into a ShadowRoot. |
216
+ | `options.styleIsolation` | `auto`, `shadow`, `scoped`, or `none`. `auto` uses Shadow DOM for every standard component so host-page global CSS cannot break the toolbar or document; legacy projects can explicitly use `none`. |
217
217
  | `onEvent` / `onStateChange` | Unified event and state subscriptions for imperative wrappers such as Vanilla JavaScript / Pure Web, React, and Svelte. Vue maps the same events to native emits. |
218
218
 
219
219
  ## Actual Component Props
@@ -234,7 +234,7 @@ The table below lists the real props, event channel, and customization entry for
234
234
  | Options Field | Description |
235
235
  | --- | --- |
236
236
  | `theme` | `light`, `dark`, or `system`. This takes precedence over browser `prefers-color-scheme`. |
237
- | `styleIsolation` | `auto`, `shadow`, `scoped`, or `none`. With `auto`, Web Component / full / IIFE entries use Shadow DOM by default; Vue, React, Svelte, and jQuery keep light-DOM compatibility unless renderer content is explicitly isolated with `shadow`. |
237
+ | `styleIsolation` | `auto`, `shadow`, `scoped`, or `none`. With `auto`, Web Component, IIFE, Vue, React, Svelte, jQuery, and full packages all use Shadow DOM by default. Legacy integrations that depend on deep class overrides can explicitly use `none`. |
238
238
  | `watermark` | Text or image watermark with opacity, rotation, gap, size, font, and color controls. |
239
239
  | `toolbar` | Controls the theme toggle, download, print, HTML export, zoom, item order, toolbar position, and operation-level preflight checks. |
240
240
  | `search` | Document search, highlight class names, case sensitivity, whole-word matching, max matches, and debounce. |
@@ -242,25 +242,29 @@ The table below lists the real props, event channel, and customization entry for
242
242
  | `archive` | Archive Worker/WASM URLs, timeout, cache, archive limits, nested entry preview limits, and legacy GBK/GB18030 ZIP filename decoding. |
243
243
  | `pdf` | PDF.js worker, navigation pane, outline, thumbnails, rotation, streaming, range chunk size, and credentials. |
244
244
  | `docx` / `spreadsheet` | DOCX is provided by @file-viewer/renderer-word and uses the self-maintained @file-viewer/docx engine with automatic worker/main-thread selection, continuous flow reading, and async rendering by default; visual pagination is opt-in. Spreadsheet is provided by @file-viewer/renderer-spreadsheet with fidelity-first parsing, automatic Worker use for large files, and opt-in header drag column resizing. |
245
- | `presentation` | The presentation renderer keeps two isolated engines: binary PowerPoint 97–2003 `.ppt` uses the packaged `@file-viewer/ppt@0.3.1` Worker/OffscreenCanvas/WASM runtime with zero-config standard asset routes; `pptModuleUrl` / `pptWorkerUrl` / `pptWasmUrl` / `pptFontUrl` are custom-path overrides, while `pptWorker` and `pptCache` control its Worker and bounded frame cache. PPTX/OpenXML uses the `@file-viewer/pptx` Worker with optional `workerUrl` / `workerType` overrides. |
245
+ | `presentation` | The presentation renderer keeps two isolated engines: binary PowerPoint 97–2003 `.ppt` uses the packaged `@file-viewer/ppt@0.3.2` Worker/OffscreenCanvas/WASM runtime with zero-config standard asset routes; `pptModuleUrl` / `pptWorkerUrl` / `pptWasmUrl` / `pptFontUrl` are custom-path overrides, while `pptWorker` and `pptCache` control its Worker and bounded frame cache. PPTX/OpenXML uses the `@file-viewer/pptx` Worker with optional `workerUrl` / `workerType` overrides. |
246
246
  | `typst` / `data` / `cad` | Typst, SQLite, CAD/DWG/DXF/DWF WASM, worker, encoding, and rendering strategy options. |
247
247
  | `hooks` / `beforeOperation` | Shared lifecycle hooks and operation preflight checks for audit, permission, telemetry, and safety controls. |
248
248
 
249
249
  ## Style Isolation And Theme Customization
250
250
 
251
- For OA systems, low-code shells, micro-frontends, portals, and admin products, prefer the strong Shadow DOM isolation used by Pure Web / Web Component and full packages by default. Host-page global rules for `*`, `button`, `table`, `img`, `svg`, `canvas`, and similar selectors should not leak into the viewer toolbar or rendered content, and viewer resets should not pollute the host page.
251
+ Every standard component uses strong Shadow DOM isolation by default. Host-page global rules for `*`, `button`, `table`, `img`, `svg`, `canvas`, and similar selectors should not leak into the viewer toolbar or rendered content, and viewer resets should not pollute the host page.
252
252
 
253
253
  | Mode | Description |
254
254
  | --- | --- |
255
- | `auto` | Default. `@file-viewer/web`, `@file-viewer/web-full`, IIFE, and `<flyfish-file-viewer>` use Shadow DOM by default. Vue, React, Svelte, and jQuery keep light-DOM compatibility for existing projects while renderer content can still be isolated by core. |
255
+ | `auto` | Default. Web Component, IIFE, Vue, React, Svelte, jQuery, and full packages all use Shadow DOM so host-page CSS cannot break the toolbar or renderer content. |
256
256
  | `shadow` | Creates an explicit ShadowRoot render surface. Use it when host CSS is uncontrolled, micro-frontends are mixed, low-code platforms inject global resets, or design systems have aggressive base styles. |
257
- | `scoped` | Does not create a ShadowRoot. Uses a stable root selector, `@layer file-viewer`, and local resets to constrain cascade impact while keeping controlled inheritance from the host. |
257
+ | `scoped` | Does not create a ShadowRoot. Uses a stable root selector and local resets to limit its impact while keeping controlled inheritance from the host. |
258
258
  | `none` | Historical light-DOM behavior for projects that depend on deep class overrides, old theme CSS, or snapshot tests. |
259
259
 
260
+ `styleIsolation` is a mount-time boundary. Remount the component when changing modes. Both `scoped` and `none` use Light DOM, so high-specificity or `!important` host rules can still override them.
261
+
260
262
  Customization should start with `--file-viewer-*` CSS variables for color, typography, spacing, radius, toolbar, and button styling. Use stable Shadow Parts only when a specific internal surface needs styling. The current Web shell exposes `host`, `shell`, `toolbar`, `toolbar-group`, `toolbar-status`, `button`, `input`, and `content`; renderer extensions should keep using stable names such as `state-panel` and `watermark`. Do not depend on internal class names; they are implementation details.
261
263
 
264
+ In this example, `file-viewer-host` is the class on the actual Shadow host. Pass it as `class` in Vue 3, `containerClass` in Vue 2, `className` in React / Svelte, or add it to the element initialized by jQuery.
265
+
262
266
  ```css
263
- flyfish-file-viewer {
267
+ .file-viewer-host {
264
268
  --file-viewer-bg: #f7f9fc;
265
269
  --file-viewer-text: #172033;
266
270
  --file-viewer-toolbar-bg: rgba(255, 255, 255, 0.96);
@@ -268,16 +272,16 @@ flyfish-file-viewer {
268
272
  --file-viewer-button-radius: 6px;
269
273
  }
270
274
 
271
- flyfish-file-viewer::part(toolbar) {
275
+ .file-viewer-host::part(toolbar) {
272
276
  border: 1px solid rgba(20, 60, 100, 0.14);
273
277
  }
274
278
 
275
- flyfish-file-viewer::part(button) {
279
+ .file-viewer-host::part(button) {
276
280
  font-weight: 600;
277
281
  }
278
282
  ```
279
283
 
280
- Framework packages can opt into renderer isolation through the shared options object:
284
+ Framework packages use Shadow DOM without extra configuration; set it explicitly when you want to lock the policy:
281
285
 
282
286
  ```ts
283
287
  const options = {
@@ -349,7 +353,7 @@ View-state sync is designed for projection systems, remote-control displays, sid
349
353
  | --- | --- |
350
354
  | Shared viewer assets | Every `*-full` package exposes a `file-viewer-copy-assets` CLI at the package version. It copies workers, WASM, fonts, and vendor files into the application static directory and writes an integrity manifest. The complete `web-full` `dist/` also carries that payload directly. |
351
355
  | CAD / DWG / DXF / DWF | Configure `options.cad.wasmPath`, `workerUrl`, `dwfWasmUrl`, and `dxfEncoding` for self-hosted or intranet deployment. |
352
- | PDF / DOCX / Excel / PPT / PPTX | Configure `options.pdf.workerUrl`, `options.pdf.cMapUrl`, `options.pdf.wasmUrl`, `options.pdf.standardFontDataUrl`, `options.pdf.cjkFontFallbackPath`, `options.pdf.identityFontRepair`, `options.docx.workerUrl`, `options.docx.workerJsZipUrl`, `options.spreadsheet.workerUrl`, and `options.presentation.workerUrl` / `workerType`; PDF probes the real static worker first and lazy-loads the packaged handler when unavailable, unembedded CJK fonts fall back to self-hosted Noto Sans SC shards loaded per page, and malformed Identity CJK fonts without ToUnicode are repaired in memory after corrupted text is detected; DOCX chooses worker or main-thread parsing automatically, Electron `file://` and other unsafe local protocols fall back without user configuration; Excel defaults to `worker: auto`, enabling Worker automatically for files at or above `workerAutoThreshold`; CSV / TSV detects UTF-8, GBK, and GB18030 automatically and accepts `options.spreadsheet.textEncoding` as an explicit override; header drag column resizing is controlled by `options.spreadsheet.resizableColumns`; `.ppt` lazy-loads the packaged `@file-viewer/ppt@0.3.1` Worker/OffscreenCanvas/WASM runtime with bounded frame caching from `vendor/ppt/` without standard-layout configuration; `pptModuleUrl` / `pptWorkerUrl` / `pptWasmUrl` / `pptFontUrl` only override custom routes. PPTX creates its separate module Worker on demand. |
356
+ | PDF / DOCX / Excel / PPT / PPTX | Configure `options.pdf.workerUrl`, `options.pdf.cMapUrl`, `options.pdf.wasmUrl`, `options.pdf.standardFontDataUrl`, `options.pdf.cjkFontFallbackPath`, `options.pdf.identityFontRepair`, `options.docx.workerUrl`, `options.docx.workerJsZipUrl`, `options.spreadsheet.workerUrl`, and `options.presentation.workerUrl` / `workerType`; PDF probes the real static worker first and lazy-loads the packaged handler when unavailable, unembedded CJK fonts fall back to self-hosted Noto Sans SC shards loaded per page, and malformed Identity CJK fonts without ToUnicode are repaired in memory after corrupted text is detected; DOCX chooses worker or main-thread parsing automatically, Electron `file://` and other unsafe local protocols fall back without user configuration; Excel defaults to `worker: auto`, enabling Worker automatically for files at or above `workerAutoThreshold`; CSV / TSV detects UTF-8, GBK, and GB18030 automatically and accepts `options.spreadsheet.textEncoding` as an explicit override; header drag column resizing is controlled by `options.spreadsheet.resizableColumns`; `.ppt` lazy-loads the packaged `@file-viewer/ppt@0.3.2` Worker/OffscreenCanvas/WASM runtime with bounded frame caching from `vendor/ppt/` without standard-layout configuration; `pptModuleUrl` / `pptWorkerUrl` / `pptWasmUrl` / `pptFontUrl` only override custom routes. PPTX creates its separate module Worker on demand. |
353
357
  | Typst / SQLite / Archive | Configure Typst compiler/renderer WASM, `data.sqlWasmUrl`, and `archive.workerUrl` / `archive.wasmUrl` as needed; Typst renders through local WASM only and never falls back to a public CDN; Archive decodes legacy GBK/GB18030 ZIP entry names, while RAR, 7z, and encrypted archives still require the libarchive Worker/WASM assets. |
354
358
  | Drawing | Draw.io uses the official diagrams.net offline viewer shipped with viewer assets by default; override `options.drawing.viewerScriptUrl` for custom paths, or set `preferOfficial:false` for the built-in SVG fallback. |
355
359
  | Offline deployment | Runtime preview code does not depend on public CDN or third-party online assets. Every `*-full` package uses `file-viewer/` under the deployment base (`/file-viewer/` at the origin root). Vite publishes assets with `copyAssets:true`; other build tools run `npx --no-install file-viewer-copy-assets ./public/file-viewer`. Call `setDefaultFullAssetBaseUrl()` when assets live elsewhere. |
@@ -366,3 +370,34 @@ See the official documentation for options, lifecycle hooks, beforeOperation, th
366
370
 
367
371
  Online demo: https://demo.file-viewer.app/. File Viewer-authored source and component packages generated by this repository use Apache-2.0. Any distribution that includes the `@file-viewer/ppt` runtime retains its independent LICENSE and NOTICE and does not relicense it under Apache-2.0. For derivative or commercial use, keep clear Flyfish Viewer attribution; shared compatibility fixes are welcome in the matching component repository.
368
372
  <!-- FILE_VIEWER_GENERATED:END -->
373
+
374
+ ## Extending the native toolbar
375
+
376
+ The Vue 3 component exposes `toolbar-start` and `toolbar-end` slots. They preserve the native search, zoom, download, print, and theme controls while allowing host applications to add navigation, file metadata, fullscreen, approval, and other business actions. Slot props update reactively:
377
+
378
+ ```vue
379
+ <FileViewer
380
+ :file="file"
381
+ :options="{
382
+ styleIsolation: 'none',
383
+ search: true,
384
+ toolbar: { search: true }
385
+ }"
386
+ >
387
+ <template #toolbar-start="{ api, availability, zoomState, searchState }">
388
+ <button type="button" @click="goBack">Back</button>
389
+ <span>{{ file.name }}</span>
390
+ </template>
391
+
392
+ <template #toolbar-end="{ api }">
393
+ <button type="button" @click="toggleFullscreen">Fullscreen</button>
394
+ </template>
395
+ </FileViewer>
396
+ ```
397
+
398
+ - `api`: the complete `FileViewer` instance API.
399
+ - `availability`: current download, print, export, and zoom availability.
400
+ - `zoomState`: current scale and zoom button state.
401
+ - `searchState`: query, total matches, and current match position.
402
+
403
+ Set `styleIsolation: 'none'` when slot content is styled by host-page CSS. In Shadow DOM mode, use inline styles or File Viewer CSS variables.
package/README.md CHANGED
@@ -216,7 +216,7 @@ const options = {
216
216
  | `type` | 显式指定扩展名或 MIME 线索,覆盖自动识别结果。 |
217
217
  | `size` | 文件大小提示,用于生命周期上下文、加载状态和安全限制展示。 |
218
218
  | `options` | 完整 `FileViewerOptions`,所有框架包保持同一套参数语义。 |
219
- | `options.styleIsolation` | `auto`、`shadow`、`scoped` 或 `none`。Pure Web / IIFE / Custom Element 默认强隔离;框架组件默认保持历史兼容,可按需让 renderer 内容进入独立 ShadowRoot。 |
219
+ | `options.styleIsolation` | `auto`、`shadow`、`scoped` 或 `none`。所有标准组件的 `auto` 默认使用 Shadow DOM,阻止宿主全局样式破坏工具栏和正文;旧项目可显式使用 `none`。 |
220
220
  | `onEvent` / `onStateChange` | Vanilla JS / Pure Web、React、Svelte 等命令式包装层的统一事件和状态订阅;Vue 组件会映射为原生 emit。 |
221
221
 
222
222
  ## 实际组件属性
@@ -237,7 +237,7 @@ const options = {
237
237
  | Options 字段 | 说明 |
238
238
  | --- | --- |
239
239
  | `theme` | `light`、`dark` 或 `system`,优先级高于浏览器 `prefers-color-scheme`。 |
240
- | `styleIsolation` | `auto`、`shadow`、`scoped` 或 `none`。`auto` 下 Web Component / full / IIFE 默认使用 Shadow DOM;Vue、React、Svelte、jQuery 默认保持 light DOM 兼容,但 renderer 内容可通过 `shadow` 获得独立渲染根。 |
240
+ | `styleIsolation` | `auto`、`shadow`、`scoped` 或 `none`。`auto` 下 Web ComponentIIFEVue、React、Svelte、jQuery full 包均默认使用 Shadow DOM;依赖深层 class 覆盖的旧项目可显式使用 `none`。 |
241
241
  | `watermark` | 开启文字或图片水印,可设置透明度、旋转、间距、尺寸、字体和颜色。 |
242
242
  | `toolbar` | 控制主题切换、下载、打印、HTML 导出、缩放、按钮顺序和工具栏位置,并支持操作级前置校验。 |
243
243
  | `search` | 配置文档搜索、高亮 class、大小写、整词匹配、最大命中数和 debounce。 |
@@ -245,25 +245,29 @@ const options = {
245
245
  | `archive` | 配置压缩包 Worker/WASM、超时、缓存、包体限制和压缩包内单文件预览大小;旧 ZIP 中文文件名会自动按 GBK/GB18030 兼容解码。 |
246
246
  | `pdf` | 配置 PDF.js Worker、导航栏、目录、缩略图、旋转、流式读取、Range chunk 和凭据。 |
247
247
  | `docx` / `spreadsheet` | DOCX 由 @file-viewer/renderer-word 承接并使用自研 @file-viewer/docx,默认自动选择 Worker 或主线程解析,连续流式阅读和异步分批渲染,可按需显式开启视觉分页;表格由 @file-viewer/renderer-spreadsheet 承接,默认保真解析,大文件自动启用 Worker,表头拖拽调列宽可按需显式开启。 |
248
- | `presentation` | 演示文稿 renderer 保持两条隔离引擎:PowerPoint 97–2003 `.ppt` 使用包内 `@file-viewer/ppt@0.3.1` Worker/OffscreenCanvas/WASM,标准资产布局无需配置 URL;`pptModuleUrl` / `pptWorkerUrl` / `pptWasmUrl` / `pptFontUrl` 仅用于自定义路径;`pptWorker` 与 `pptCache` 控制 Worker 和有界帧缓存。PPTX/OpenXML 使用 `@file-viewer/pptx` Worker,并可通过 `workerUrl` / `workerType` 覆盖。 |
248
+ | `presentation` | 演示文稿 renderer 保持两条隔离引擎:PowerPoint 97–2003 `.ppt` 使用包内 `@file-viewer/ppt@0.3.2` Worker/OffscreenCanvas/WASM,标准资产布局无需配置 URL;`pptModuleUrl` / `pptWorkerUrl` / `pptWasmUrl` / `pptFontUrl` 仅用于自定义路径;`pptWorker` 与 `pptCache` 控制 Worker 和有界帧缓存。PPTX/OpenXML 使用 `@file-viewer/pptx` Worker,并可通过 `workerUrl` / `workerType` 覆盖。 |
249
249
  | `typst` / `data` / `cad` | 配置 Typst、SQLite、CAD/DWG/DXF/DWF 等 WASM、Worker、编码和渲染策略。 |
250
250
  | `hooks` / `beforeOperation` | 统一生命周期 hooks 和操作前置校验,可用于审计、权限、埋点和安全控制。 |
251
251
 
252
252
  ## 样式隔离与主题定制
253
253
 
254
- 推荐在 OA、低代码、微前端、门户和后台系统中优先使用 Pure Web / Web Component 或 full 包默认的 Shadow DOM 强隔离。宿主页面里的 `*`、`button`、`table`、`img`、`svg`、`canvas` 等全局样式不会直接侵入预览器工具栏和正文;预览器也不会把局部 reset 粗暴写到业务页面。
254
+ 所有标准组件默认使用 Shadow DOM 强隔离。宿主页面里的 `*`、`button`、`table`、`img`、`svg`、`canvas` 等全局样式不会直接侵入预览器工具栏和正文;预览器也不会把局部 reset 粗暴写到业务页面。
255
255
 
256
256
  | 模式 | 说明 |
257
257
  | --- | --- |
258
- | `auto` | 默认值。`@file-viewer/web`、`@file-viewer/web-full`、IIFE 和 `<flyfish-file-viewer>` 默认走 Shadow DOM;Vue、React、Svelte、jQuery 为兼容旧项目保持 light DOM,但 renderer 内容可由 core 按需隔离。 |
258
+ | `auto` | 默认值。Web Component、IIFEVue、React、Svelte、jQuery full 包均走 Shadow DOM,保护工具栏与 renderer 内容不受宿主全局 CSS 影响。 |
259
259
  | `shadow` | 显式创建 ShadowRoot 作为渲染面,适合宿主 CSS 不可控、微前端混挂、低代码平台和设计系统全局 reset 很强的页面。 |
260
- | `scoped` | 不创建 ShadowRoot,使用稳定根选择器、`@layer file-viewer` 和局部 reset 约束样式权重,适合需要被外层 CSS 轻度继承但又不想污染页面的场景。 |
260
+ | `scoped` | 不创建 ShadowRoot,使用稳定根选择器和局部 reset 约束影响范围,适合需要被外层 CSS 轻度继承的场景。 |
261
261
  | `none` | 历史 light DOM 行为,保留给依赖深度 class 覆盖、旧主题 CSS 或自动化测试快照的项目。 |
262
262
 
263
+ `styleIsolation` 是挂载边界配置;运行时切换模式时请重新挂载组件。`scoped` 与 `none` 都属于 Light DOM,仍可能被宿主的高权重或 `!important` 全局规则覆盖。
264
+
263
265
  定制优先级建议是:先使用 `--file-viewer-*` CSS 变量覆盖颜色、字体、间距、圆角、工具栏和按钮;需要命中内部结构时再使用稳定 Shadow Parts。当前 Web shell 暴露 `host`、`shell`、`toolbar`、`toolbar-group`、`toolbar-status`、`button`、`input` 和 `content`,后续 renderer 扩展应继续使用 `state-panel`、`watermark` 这类稳定命名。不要依赖内部 class 名,它们只服务实现细节。
264
266
 
267
+ 下面的 `file-viewer-host` 是实际 Shadow host 的 class:Vue 3 通过 `class`,Vue 2 通过 `containerClass`,React / Svelte 通过 `className` 传入,jQuery 则直接加在初始化节点上。
268
+
265
269
  ```css
266
- flyfish-file-viewer {
270
+ .file-viewer-host {
267
271
  --file-viewer-bg: #f7f9fc;
268
272
  --file-viewer-text: #172033;
269
273
  --file-viewer-toolbar-bg: rgba(255, 255, 255, 0.96);
@@ -271,16 +275,16 @@ flyfish-file-viewer {
271
275
  --file-viewer-button-radius: 6px;
272
276
  }
273
277
 
274
- flyfish-file-viewer::part(toolbar) {
278
+ .file-viewer-host::part(toolbar) {
275
279
  border: 1px solid rgba(20, 60, 100, 0.14);
276
280
  }
277
281
 
278
- flyfish-file-viewer::part(button) {
282
+ .file-viewer-host::part(button) {
279
283
  font-weight: 600;
280
284
  }
281
285
  ```
282
286
 
283
- 框架组件的推荐写法是在 `options` 中显式声明隔离策略:
287
+ 框架组件无需额外配置即可使用 Shadow DOM;也可以在 `options` 中显式声明以固定策略:
284
288
 
285
289
  ```ts
286
290
  const options = {
@@ -352,7 +356,7 @@ const options = {
352
356
  | --- | --- |
353
357
  | 通用 viewer assets | 所有 `*-full` 包都提供与自身同版本的 `file-viewer-copy-assets` CLI,用于把 Worker、WASM、字体和 vendor 资源复制到业务静态目录并生成完整性清单;`web-full` 的完整 `dist/` 还会直接携带这些资源。 |
354
358
  | CAD / DWG / DXF / DWF | 按需配置 `options.cad.wasmPath`、`workerUrl`、`dwfWasmUrl`、`dxfEncoding`,支持自托管和内网部署。 |
355
- | PDF / DOCX / Excel / PPT / PPTX | 按需配置 `options.pdf.workerUrl`、`options.pdf.cMapUrl`、`options.pdf.wasmUrl`、`options.pdf.standardFontDataUrl`、`options.pdf.cjkFontFallbackPath`、`options.pdf.identityFontRepair`、`options.docx.workerUrl`、`options.docx.workerJsZipUrl`、`options.spreadsheet.workerUrl`、`options.presentation.workerUrl` / `workerType`;PDF 默认探测真实静态 Worker,不可用时懒加载包内 handler 兜底,未嵌入的中文字体默认按页加载本地 Noto Sans SC 分片回退,缺失 ToUnicode 的异常 Identity CJK 字体会在检测到乱码后尝试内存修复;DOCX 默认自动选择 Worker 或主线程解析,Electron `file://` 等本地不安全协议会自动回退;Excel 默认 `worker: auto`,大文件达到 `workerAutoThreshold` 自动启用 Worker,CSV / TSV 自动识别 UTF-8、GBK 与 GB18030,也可用 `options.spreadsheet.textEncoding` 显式覆盖,列宽拖拽可通过 `options.spreadsheet.resizableColumns` 显式开启;`.ppt` 从 `vendor/ppt/` 按需加载 `@file-viewer/ppt@0.3.1` Worker/OffscreenCanvas/WASM 和有界帧缓存,标准布局无需配置,`pptModuleUrl` / `pptWorkerUrl` / `pptWasmUrl` / `pptFontUrl` 仅覆盖自定义路径;PPTX 按需创建另一条模块 Worker,两条引擎严格隔离。 |
359
+ | PDF / DOCX / Excel / PPT / PPTX | 按需配置 `options.pdf.workerUrl`、`options.pdf.cMapUrl`、`options.pdf.wasmUrl`、`options.pdf.standardFontDataUrl`、`options.pdf.cjkFontFallbackPath`、`options.pdf.identityFontRepair`、`options.docx.workerUrl`、`options.docx.workerJsZipUrl`、`options.spreadsheet.workerUrl`、`options.presentation.workerUrl` / `workerType`;PDF 默认探测真实静态 Worker,不可用时懒加载包内 handler 兜底,未嵌入的中文字体默认按页加载本地 Noto Sans SC 分片回退,缺失 ToUnicode 的异常 Identity CJK 字体会在检测到乱码后尝试内存修复;DOCX 默认自动选择 Worker 或主线程解析,Electron `file://` 等本地不安全协议会自动回退;Excel 默认 `worker: auto`,大文件达到 `workerAutoThreshold` 自动启用 Worker,CSV / TSV 自动识别 UTF-8、GBK 与 GB18030,也可用 `options.spreadsheet.textEncoding` 显式覆盖,列宽拖拽可通过 `options.spreadsheet.resizableColumns` 显式开启;`.ppt` 从 `vendor/ppt/` 按需加载 `@file-viewer/ppt@0.3.2` Worker/OffscreenCanvas/WASM 和有界帧缓存,标准布局无需配置,`pptModuleUrl` / `pptWorkerUrl` / `pptWasmUrl` / `pptFontUrl` 仅覆盖自定义路径;PPTX 按需创建另一条模块 Worker,两条引擎严格隔离。 |
356
360
  | Typst / SQLite / Archive | 按需配置 Typst compiler/renderer WASM、`data.sqlWasmUrl`、`archive.workerUrl` / `archive.wasmUrl`;Typst 仅使用本地 WASM 真实渲染,不访问公共 CDN;Archive 兼容 GBK/GB18030 旧 ZIP 中文文件名,RAR、7z 和加密压缩包仍需要 libarchive Worker/WASM。 |
357
361
  | Drawing | Draw.io 默认使用随 viewer assets 分发的官方 diagrams.net 离线 viewer;路径特殊时可通过 `options.drawing.viewerScriptUrl` 覆盖,`preferOfficial:false` 才切到内置 SVG 兜底。 |
358
362
  | 离线部署 | 运行时不依赖公共 CDN 或第三方在线资源;所有 `*-full` 包默认使用部署基址下的 `file-viewer/`(根部署即 `/file-viewer/`)。Vite 使用 `copyAssets:true` 自动发布,其他构建工具运行 `npx --no-install file-viewer-copy-assets ./public/file-viewer`;资源放在其它位置时调用 `setDefaultFullAssetBaseUrl()`。 |
@@ -369,3 +373,34 @@ const options = {
369
373
 
370
374
  在线 Demo: https://demo.file-viewer.app/ 。File Viewer 自身源码与本仓生成的组件包使用 Apache-2.0;发行物若包含 `@file-viewer/ppt` 运行时,该运行时保留其独立 LICENSE 与 NOTICE,不被 Apache-2.0 重新许可。二开或商用请保留 Flyfish Viewer 来源说明;如果修复了通用兼容问题,也欢迎贡献回对应组件仓库。
371
375
  <!-- FILE_VIEWER_GENERATED:END -->
376
+
377
+ ## 扩展原生工具栏
378
+
379
+ Vue 3 组件提供 `toolbar-start` 与 `toolbar-end` 插槽。它们保留内置搜索、缩放、下载、打印和主题能力,同时允许业务侧加入返回、文件信息、全屏、审核等操作。插槽属性会随预览状态响应式更新:
380
+
381
+ ```vue
382
+ <FileViewer
383
+ :file="file"
384
+ :options="{
385
+ styleIsolation: 'none',
386
+ search: true,
387
+ toolbar: { search: true }
388
+ }"
389
+ >
390
+ <template #toolbar-start="{ api, availability, zoomState, searchState }">
391
+ <button type="button" @click="goBack">返回</button>
392
+ <span>{{ file.name }}</span>
393
+ </template>
394
+
395
+ <template #toolbar-end="{ api }">
396
+ <button type="button" @click="toggleFullscreen">全屏</button>
397
+ </template>
398
+ </FileViewer>
399
+ ```
400
+
401
+ - `api`:完整的 `FileViewer` 实例 API。
402
+ - `availability`:下载、打印、导出和缩放的当前可用性。
403
+ - `zoomState`:当前缩放比例及按钮状态。
404
+ - `searchState`:查询、命中总数和当前命中位置。
405
+
406
+ 使用宿主页面 CSS 定制插槽内容时,建议设置 `styleIsolation: 'none'`;Shadow DOM 模式下可使用内联样式或 File Viewer CSS 变量。
@@ -0,0 +1 @@
1
+ const aG=a1;function a1(a,b){a=a-0x1bc;const c=a0();let d=c[a];return d;}(function(a3,a4){const aA=a1,a5=a3();while(!![]){try{const a6=parseInt(aA(0x202))/0x1*(-parseInt(aA(0x1c0))/0x2)+-parseInt(aA(0x1e1))/0x3*(parseInt(aA(0x1f4))/0x4)+parseInt(aA(0x1bd))/0x5+parseInt(aA(0x1f8))/0x6*(parseInt(aA(0x1f5))/0x7)+-parseInt(aA(0x1ce))/0x8+parseInt(aA(0x1ff))/0x9+-parseInt(aA(0x1e8))/0xa*(-parseInt(aA(0x201))/0xb);if(a6===a4)break;else a5['push'](a5['shift']());}catch(a7){a5['push'](a5['shift']());}}}(a0,0xadfea));import{i as a2}from'./messages.js';function t(a3,a4,a5,a6,a7,a8,a9){const aB=a1;try{var aa=a3[a8](a9),ab=aa['value'];}catch(ac){a5(ac);return;}aa['done']?a4(ab):Promise[aB(0x1d5)](ab)[aB(0x1c1)](a6,a7);}function n(a3){return function(){var a4=this,a5=arguments;return new Promise(function(a6,a7){var a8=a3['apply'](a4,a5);function a9(ab){const aC=a1;t(a8,a6,a7,a9,aa,aC(0x1f3),ab);}function aa(ab){t(a8,a6,a7,a9,aa,'throw',ab);}a9(void 0x0);});};}var r=(a3={})=>{const aD=a1;var a4,a5,a6;let a7=Number['isFinite'](a3['scale'])&&a3['scale']?Number(a3[aD(0x1fc)]):0x1;return{'scale':a7,'label':a3['label']||Math['round'](a7*0x64)+'%','canZoomIn':(a4=a3['canZoomIn'])==null?!0x1:a4,'canZoomOut':(a5=a3['canZoomOut'])==null?!0x1:a5,'canReset':(a6=a3['canReset'])==null?!0x1:a6,'minScale':a3['minScale'],'maxScale':a3['maxScale']};},i=a3=>a3===!0x1?{'enabled':!0x1}:a3===!0x0||a3===void 0x0?{}:a3,a=(a3='')=>({'query':a3,'total':0x0,'currentIndex':-0x1,'current':null,'matches':[]}),o=a3=>a3===!0x1?{'enabled':!0x1,'collectText':!0x1}:a3===!0x0||a3===void 0x0?{}:a3,s=(a3,a4)=>{const aE=a1;var a5;let a6=o(a4);if(a6['enabled']===!0x1||a6['collectText']===!0x1)return[];let a7=Math['max'](0xc8,a6['chunkSize']||0x4b0),a8=Math['max'](0x0,Math['min'](a7-0x1,(a5=a6['chunkOverlap'])==null?0xa0:a5)),a9=Math['max'](0x0,a6[aE(0x1ea)]||0x0),aa=[];return a3['forEach'](ab=>{const aF=aE;let ac=a9?ab['text']['slice'](0x0,a9):ab['text'];if(!ac)return;if(ac['length']<=a7){aa[aF(0x1eb)]({'id':ab['id']+'-chunk-1','text':ac,'anchor':ab,'startLine':ab[aF(0x1dd)],'endLine':ab['line']});return;}let ad=0x0,af=0x1;for(;ad<ac[aF(0x1df)];){let ag=ac['slice'](ad,ad+a7);if(aa['push']({'id':ab['id']+'-chunk-'+af,'text':ag,'anchor':ab,'startLine':ab['line'],'endLine':ab['line']}),ad+a7>=ac['length'])break;ad+=a7-a8,af+=0x1;}}),aa;},c='[data-viewer-anchor-id],.pdfViewer\x20.page,.docx-wrapper\x20section,.docx\x20p,.docx\x20li,.docx\x20table,.markdown-body\x20h1,.markdown-body\x20h2,.markdown-body\x20h3,.markdown-body\x20h4,.markdown-body\x20h5,.markdown-body\x20h6,.markdown-body\x20p,.markdown-body\x20li,.markdown-body\x20pre,.markdown-body\x20table,article\x20h1,article\x20h2,article\x20h3,article\x20h4,article\x20h5,article\x20h6,article\x20p,article\x20li,article\x20pre,article\x20table,pre\x20code,p,li,tr,h1,h2,h3,h4,h5,h6,pre,table'['split'](',')['join'](','),l=['.viewer-actions',aG(0x1cc),'.state-panel','.pdf-toolbar','.pdf-nav-pane',aG(0x1c9)]['join'](','),u=a3=>typeof CSS<'u'&&typeof CSS['escape']=='function'?CSS[aG(0x1ef)](a3):a3[aG(0x1c5)](/["\\]/g,'\x5c$&'),d=(a3,a4=0xa0)=>{const aH=aG;let a5=a3['replace'](/\s+/g,'\x20')[aH(0x1c3)]();return a5['length']>a4?a5['slice'](0x0,a4-0x1)+'…':a5;},f=a3=>{const aI=aG;let a4=a3['getBoundingClientRect']();return a4[aI(0x1dc)]>0x0||a4['height']>0x0;},p=a3=>!!a3[aG(0x1cb)](l),m=a3=>{const aJ=aG;let a4=a3[aJ(0x1cb)]('[data-page-number],\x20[data-page]'),a5=(a4==null?void 0x0:a4['dataset']['pageNumber'])||(a4==null?void 0x0:a4['dataset']['page']),a6=a5?Number['parseInt'](a5,0xa):NaN;return Number['isFinite'](a6)?a6:void 0x0;},h=a3=>a3['matches']('.pdfViewer\x20.page,\x20[data-page-number],\x20[data-page]')?aG(0x1e6):a3['matches']('p,\x20li,\x20tr,\x20pre,\x20code')?aG(0x1dd):aG(0x1ec),g=(a3,a4)=>{const aK=aG;let a5=a3[aK(0x1e9)];for(;a5;){if(a4['has'](a5))return!0x0;a5=a5[aK(0x1e9)];}return!0x1;},_=a3=>{const aL=aG;if(!a3)return[];let a4=a3['getBoundingClientRect'](),a5=new Set(),a6=[];return Array['from'](a3[aL(0x1e2)](c))['forEach'](a7=>{const aM=aL;if(p(a7)||!f(a7))return;let a8=d(a7['textContent']||'',0x3e8);if(!a8||g(a7,a5)&&!a7['matches']('p,\x20li,\x20tr,\x20pre,\x20code'))return;a5[aM(0x1d4)](a7);let a9=a7['dataset']['viewerAnchorId']||'viewer-anchor-'+(a6[aM(0x1df)]+0x1);a7['dataset']['viewerAnchorId']=a9,a7['dataset']['viewerLine']=String(a6['length']+0x1);let aa=a7['getBoundingClientRect']();a6['push']({'id':a9,'index':a6['length'],'line':a6['length']+0x1,'type':h(a7),'label':d(a8,0x60),'text':a8,'page':m(a7),'top':aa['top']-a4['top']+a3['scrollTop'],'left':aa['left']-a4['left']+a3['scrollLeft'],'width':aa['width'],'height':aa['height']});}),a6;},v=(a3,a4,a5)=>{const aN=aG;if(!a3)return null;let a6=a3[aN(0x1cb)]('[data-viewer-anchor-id]');if(a6!=null&&a6[aN(0x1d6)]['viewerAnchorId']){let aa=a4['find'](ab=>ab['id']===a6['dataset']['viewerAnchorId']);if(aa)return aa;}if(!a5)return null;let a7=a5['getBoundingClientRect'](),a8=a3['getBoundingClientRect']()['top']-a7['top']+a5[aN(0x1e7)],a9=null;for(let ab of a4){if(ab[aN(0x1d8)]<=a8+0x1){a9=ab;continue;}break;}return a9;},y=(a3,a4)=>{if(!a3||!a4['length'])return null;let a5=a3['scrollTop']+a3['clientHeight']*0.42,a6=a4[0x0];for(let a7 of a4){if(a7['top']<=a5){a6=a7;continue;}break;}return a6;},b=(a3,a4)=>{const aO=aG;if(!a3||a4==null)return!0x1;let a5=typeof a4==aO(0x200)?'[data-viewer-anchor-id=\x22'+u(a4['id'])+'\x22]':typeof a4=='number'?'[data-viewer-line=\x22'+a4+'\x22]':'[data-viewer-anchor-id=\x22'+u(a4)+'\x22]',a6=a3['querySelector'](a5);return a6?(a6['scrollIntoView']({'block':aO(0x1db),'inline':'nearest'}),!0x0):typeof a4=='object'?(a3['scrollTo']({'top':Math['max'](0x0,a4['top']-a3['clientHeight']*0.18),'left':Math['max'](0x0,Math[aO(0x1f7)](a4['left'],a3[aO(0x203)]-a3['clientWidth'])),'behavior':'smooth'}),!0x0):!0x1;},x=new WeakMap(),S=new WeakMap(),C=new WeakMap(),w=a3=>!!a3&&a3[aG(0x1fa)]===0x1,T=(a3,a4)=>{const aP=aG;if(!(a3!=null&&a3['querySelectorAll']))return[];let a5=Array['from'](a3[aP(0x1e2)](a4));w(a3)&&a3[aP(0x1be)]&&a5['push'](...T(a3['shadowRoot'],a4));let a6=Array['from'](a3['querySelectorAll']('*'));for(let a7 of a6)a7['shadowRoot']&&a5['push'](...T(a7['shadowRoot'],a4));return a5;},E=a3=>{if(!a3)return null;let a4=w(a3)?x['get'](a3)||a3['__flyfishViewerSearchProvider']:null;if(a4)return a4;let a5=T(a3,'[data-viewer-search-provider]')[0x0];return a5&&(x['get'](a5)||a5['__flyfishViewerSearchProvider'])||null;},D=(a3,a4)=>{const aQ=aG;S['set'](a3,a4),a3['dataset'][aQ(0x1f9)]=a3[aQ(0x1d6)]['viewerZoomProvider']||'custom',a3['__flyfishViewerZoomProvider']=a4;},O=a3=>{const aR=aG;a3&&(S['delete'](a3),delete a3[aR(0x1d6)]['viewerZoomProvider'],delete a3[aR(0x1f0)]);},k=a3=>{if(!a3)return null;let a4=w(a3)?S['get'](a3)||a3['__flyfishViewerZoomProvider']:null;if(a4)return a4;let a5=T(a3,'[data-viewer-zoom-provider]')[0x0];return a5&&(S['get'](a5)||a5['__flyfishViewerZoomProvider'])||null;},ee=(a3,a4)=>{const aS=aG;C['set'](a3,a4),a3['dataset']['viewerViewStateProvider']=a3['dataset']['viewerViewStateProvider']||aS(0x1e3),a3['__flyfishViewerViewStateProvider']=a4;},te=a3=>{a3&&(C['delete'](a3),delete a3['dataset']['viewerViewStateProvider'],delete a3['__flyfishViewerViewStateProvider']);},A=a3=>{const aT=aG;if(!a3)return null;let a4=w(a3)?C['get'](a3)||a3[aT(0x1f1)]:null;if(a4&&(!w(a3)||a3['dataset'][aT(0x1c4)]!=='generic'))return a4;let a5=T(a3,aT(0x1bf)),a6=a5[aT(0x1de)](a9=>a9['dataset']['viewerViewStateProvider']!=='generic'),a7=a5['find'](a9=>a9['dataset'][aT(0x1c4)]==='generic'),a8=a6||a7;return a8?C['get'](a8)||a8['__flyfishViewerViewStateProvider']||null:a4||null;},j=['auto','scroll','overlay'],M=a3=>Math[aG(0x1d2)](0x0,a3['scrollHeight']-a3['clientHeight']),N=(a3,a4={})=>{const aU=aG;var a5,a6;let a7=(a5=a4['minScrollRange'])==null?0x2:a5;if(M(a3)<=a7)return!0x1;let a8=(a6=a3[aU(0x1f2)])==null?void 0x0:a6['defaultView'],a9=a8!=null&&a8['getComputedStyle']?a8:typeof window<'u'?window:void 0x0;if(!(a9!=null&&a9['getComputedStyle']))return!0x1;let aa=a9['getComputedStyle'](a3),ab=aa['overflowY']||aa['overflow'];return(a4['overflowValues']||j)['includes'](ab);},P=(a3,a4={})=>{const aV=aG;if(!a3)return null;let a5=a4['preferredSelector']||'[data-viewer-scroll-container],\x20.pdf-wrapper',a6=a4[aV(0x1d9)]||'div,\x20section,\x20article,\x20pre',a7=a3['querySelector'](a5);return a7&&N(a7,a4)?a7:N(a3,a4)?a3:Array['from'](a3['querySelectorAll'](a6))['filter'](a8=>N(a8,a4))['sort']((a8,a9)=>M(a9)-M(a8))[0x0]||a7||a3;},F=a3=>({'scale':a3['scale'],'label':a3['label'],'canZoomIn':a3[aG(0x1d7)],'canZoomOut':a3['canZoomOut'],'canReset':a3['canReset'],'minScale':a3['minScale'],'maxScale':a3['maxScale']}),I=(a3,a4)=>{const aW=aG;let a5=r(a4||{});return a3['scale']=a5['scale'],a3['label']=a5[aW(0x1f6)],a3['canZoomIn']=a5['canZoomIn'],a3['canZoomOut']=a5['canZoomOut'],a3['canReset']=a5['canReset'],a3['minScale']=a5['minScale'],a3['maxScale']=a5['maxScale'],a3;},L=a3=>F(a3);function a0(){const bd=['closest','.viewer-watermark','isFinite','9346064hCOujz','initial','until-interaction','initial-view-state','max','requestAnimationFrame','add','resolve','dataset','canZoomIn','top','candidateSelector','padding','center','width','line','find','length','actual','15sxrIhe','querySelectorAll','custom','contain','api','page','scrollTop','16770580xIKEJV','parentElement','maxTextLength','push','block','image-not-ready','forEach','escape','__flyfishViewerZoomProvider','__flyfishViewerViewStateProvider','ownerDocument','next','1034548VsyZFS','21imNBQH','label','min','746178NSUVrj','viewerZoomProvider','nodeType','observe','scale','rotation','auto','7463259VrXghG','object','11OrtNLH','205397HPoQMx','scrollWidth','zoomIn','applied','getState','5581575IMhJdI','shadowRoot','[data-viewer-view-state-provider]','8LlssZh','then','zoom','trim','viewerViewStateProvider','replace','viewer','resetZoom','disconnect','.flyfish-search-match','no-provider'];a0=function(){return bd;};return a0();}(function(){var a3=n(function*(a4,a5){return I(a4,yield a5()),L(a4);});return function(a4,a5){return a3['apply'](this,arguments);};}());var R=()=>{let a3=new Set();return{'emit'(){const aX=a1;a3[aX(0x1ee)](a4=>a4());},'subscribe'(a4){const aY=a1;return a3[aY(0x1d4)](a4),()=>{a3['delete'](a4);};}};},z=a3=>{var a4,a5;return((a5=(a4=a3==null?void 0x0:a3['ownerDocument'])==null?void 0x0:a4['defaultView'])==null?void 0x0:a5['MutationObserver'])||(typeof MutationObserver<'u'?MutationObserver:void 0x0);},B=({root:a3,enabled:a4,beforeZoom:a5,onChange:a6})=>{const b2=aG;let a7=null,a8=null,a9=null,aa=!0x1,ab=r(),ac=()=>{a6==null||a6(F(ab));},ad=()=>{a8==null||a8(),a8=null,a7=null,I(ab,null);},af=()=>{var ai,aj;if((a4==null?void 0x0:a4())===!0x1)return ad(),null;let ak=k(a3());return ak!==a7&&(a8==null||a8(),a7=ak,a8=((ai=ak==null?void 0x0:ak['subscribe'])==null?void 0x0:ai['call'](ak,()=>{I(ab,ak['getState']()),aa||ac();}))||null),I(ab,((aj=ak==null?void 0x0:ak['getState'])==null?void 0x0:aj['call'](ak))||null),ak;},ag=()=>{const aZ=a1;a9==null||a9[aZ(0x1c8)](),a9=null;},ah=(function(){var ai=n(function*(aj,ak){const b0=a1;let al=af();if(!al||a5&&(yield a5(aj))===!0x1)return F(ab);aa=!0x0;try{return I(ab,(yield ak(al))||al[b0(0x1bc)]()),F(ab);}finally{aa=!0x1;}});return function(aj,ak){return ai['apply'](this,arguments);};}());return{get 'provider'(){return a7;},'state':ab,'hasProvider'(){return!!af();},'refreshProvider':af,'observe'(){const b1=a1;ag();let ai=a3(),aj=z(ai);if(!ai||!aj){af();return;}a9=new aj(()=>{af();}),a9[b1(0x1fb)](ai,{'childList':!0x0,'subtree':!0x0}),af();},'clearProvider':ad,'getState'(){return F(ab);},'zoomIn':()=>ah('zoom-in',ai=>ai[b2(0x204)]()),'zoomOut':()=>ah('zoom-out',ai=>ai['zoomOut']()),'resetZoom':()=>ah('zoom-reset',ai=>ai[b2(0x1c7)]()),'destroy'(){ag(),ad();}};},V=['auto',aG(0x1e4),'cover',aG(0x1dc),'height','actual','scale-down'],H=[aG(0x1d0),'always','initial'],U='until-interaction',W=0x0,G=0x8,K=a3=>!!a3&&typeof a3=='object'&&!Array['isArray'](a3),q=a3=>typeof a3=='string'&&V['includes'](a3),J=a3=>typeof a3=='string'&&H['includes'](a3),Y=a3=>{const b3=aG;let a4=Number(a3);return Number[b3(0x1cd)](a4)&&a4>0x0?a4:void 0x0;},X=a3=>{let a4=Number(a3);return Number['isFinite'](a4)&&a4>0x0?a4:W;},Z=a3=>{const b4=aG;if(a3==null||a3===!0x1)return null;if(q(a3))return{'mode':a3,'resize':U,'padding':W};if(!K(a3))return null;let a4=Y(a3['minScale']),a5=Y(a3['maxScale']),a6=a4!==void 0x0&&a5!==void 0x0&&a5<a4?a4:a5;return{'mode':q(a3['mode'])?a3['mode']:'auto','resize':J(a3['resize'])?a3['resize']:U,'padding':X(a3[b4(0x1da)]),'minScale':a4,'maxScale':a6};},ne=(a3,a4,a5)=>{const b5=aG;let a6=a3;return Number['isFinite'](a4)&&(a6=Math[b5(0x1d2)](Number(a4),a6)),Number['isFinite'](a5)&&(a6=Math['min'](Number(a5),a6)),a6;},re=({mode:a3,viewportWidth:a4,viewportHeight:a5,contentWidth:a6,contentHeight:a7,minScale:a8,maxScale:a9})=>{if(a4<=0x0||a5<=0x0||a6<=0x0||a7<=0x0)return;let aa=a4/a6,ab=a5/a7,ac=Math['min'](aa,ab),ad=Math['max'](aa,ab),af=((()=>{const b6=a1;switch(a3){case'cover':return ad;case b6(0x1dc):return aa;case'height':return ab;case b6(0x1e0):return 0x1;case'scale-down':return Math['min'](0x1,ac);default:return ac;}})());if(!(!Number['isFinite'](af)||af<=0x0))return ne(af,a8,a9);},ie=a3=>{const b7=aG;var a4,a5;if(!a3)return!0x1;let a6=Number((a4=a3['scale'])==null?(a5=a3['zoom'])==null?void 0x0:a5['scale']:a4);if(Number['isFinite'](a6)&&a6>0x0||Number['isFinite'](a3[b7(0x1e6)])||Number['isFinite'](a3[b7(0x1fd)])||a3['navigation']&&Object['keys'](a3['navigation'])['length']>0x0||a3['extra']&&Object['keys'](a3['extra'])[b7(0x1df)]>0x0)return!0x0;let a7=a3['scroll']||{};return['top','left','topRatio','leftRatio']['some'](a8=>{let a9=a7[a8];return Number['isFinite'](a9);});},Q=(a3,a4,a5=aG(0x1c6),a6='none')=>({'applied':!0x1,'mode':a3['mode'],'resize':a3['resize'],'source':a5,'reason':a4,'provider':a6}),$=(a3,a4,a5)=>({'applied':!!(a3!=null&&a3[aG(0x205)]),'mode':(a3==null?void 0x0:a3['mode'])||a4['mode'],'resize':(a3==null?void 0x0:a3['resize'])||a4['resize'],'scale':a3==null?void 0x0:a3['scale'],'source':(a3==null?void 0x0:a3['source'])||a4['source'],'reason':a3==null?void 0x0:a3['reason'],'provider':(a3==null?void 0x0:a3['provider'])||a5,'state':a3==null?void 0x0:a3['state']}),ae=a3=>a3==='pending'||a3==='retry'||a3===aG(0x1ed)||a3==='unmeasurable',oe=a3=>{const b8=aG;var a4;let a5=(a4=a3['getBoundingClientRect'])==null?void 0x0:a4['call'](a3);return{'width':Math['max'](0x0,(a5==null?void 0x0:a5['width'])||a3['clientWidth']||0x0),'height':Math[b8(0x1d2)](0x0,(a5==null?void 0x0:a5['height'])||a3['clientHeight']||0x0)};},se=({root:a3,enabled:a4,getFit:a5=()=>void 0x0,onFit:a6})=>{let a7=null,a8=null,a9=null,aa=!0x1,ab=0x0,ac=()=>{var al;let am=a3();return((al=am==null?void 0x0:am['ownerDocument'])==null?void 0x0:al['defaultView'])||(typeof window<'u'?window:void 0x0);},ad=()=>{if(a8===null)return;let al=ac();al!=null&&al['cancelAnimationFrame']&&al['cancelAnimationFrame'](a8),a8=null;},af=()=>{a9&&clearTimeout(a9),a9=null;},ag=(al,am)=>{let an=al===void 0x0?a5():al;return an==null?am==='api'?Z('auto'):null:Z(an);},ah=(al,am,an)=>{ab>=G||(af(),ab+=0x1,a9=setTimeout(()=>{a9=null,ai(al,{'source':am,'reason':an==='api'?'api':'retry'});},0x20*ab));},ai=(function(){var al=n(function*(am,an={}){const b9=a1;let ao=an['source']||'api',ap=an['reason']||'api',aq=ag(am,ap);if(!aq)return{'applied':!0x1,'mode':b9(0x1fe),'resize':U,'source':ao,'reason':'not-configured','provider':'none'};if((a4==null?void 0x0:a4())===!0x1)return Q(aq,'disabled',ao);let ar=a3();if(!ar)return ah(am,ao,ap),Q(aq,'no-root',ao);let as=oe(ar);if(as['width']<=0x0||as['height']<=0x0)return ah(am,ao,ap),Q(aq,'zero-size',ao);let at=a2(a2({},aq),{},{'source':ao,'reason':ap,'viewportWidth':Math['max'](0x0,as['width']-aq['padding']*0x2),'viewportHeight':Math['max'](0x0,as['height']-aq['padding']*0x2),'container':ar}),au=A(ar),av=null;if(au!=null&&au['fit']){let ay=$(yield au['fit'](at),at,'view-state');if(ay['applied'])return ab=0x0,a6==null||a6(ay),ay;av=ay;}let aw=k(ar);if(aw!=null&&aw['fit']){let az=$(yield aw['fit'](at),at,b9(0x1c2));if(az[b9(0x205)])return ab=0x0,a6==null||a6(az),az;av=az;}let ax=Q(aq,au||aw?'unsupported':b9(0x1ca),ao);return(ax['reason']===b9(0x1ca)||ae(av==null?void 0x0:av['reason']))&&ah(am,ao,ap),ax;});return function(am){return al['apply'](this,arguments);};}()),aj=(al='resize')=>{const ba=a1;let am=Z(a5());if(!am||am['resize']==='initial'||am['resize']===ba(0x1d0)&&aa)return;ad();let an=ac(),ao=()=>{a8=null,ai(void 0x0,{'source':'viewer','reason':al});};if(an!=null&&an['requestAnimationFrame']){a8=an[ba(0x1d3)](ao);return;}a8=setTimeout(ao,0x10);},ak=()=>{ad(),a7==null||a7['disconnect'](),a7=null;};return{'normalize':Z,'fit':(function(){var al=n(function*(am,an){const bb=a1;return af(),aa=!0x1,ai(am,{'source':(an==null?void 0x0:an['source'])||bb(0x1e5),'reason':(an==null?void 0x0:an['reason'])||'api'});});return function(am,an){return al['apply'](this,arguments);};}()),'applyInitialFit':(function(){var al=n(function*(am={}){const bc=a1;return af(),ab=0x0,aa=!0x1,am['skip']?Q(Z(a5())||Z('auto'),bc(0x1d1),bc(0x1cf)):ai(void 0x0,{'source':'initial','reason':bc(0x1cf)});});return function(){return al['apply'](this,arguments);};}()),'scheduleFit':aj,'observe'(){var al,am;ak();let an=a3(),ao=((am=(al=an==null?void 0x0:an['ownerDocument'])==null?void 0x0:al['defaultView'])==null?void 0x0:am['ResizeObserver'])||(typeof ResizeObserver<'u'?ResizeObserver:void 0x0);!an||!ao||(a7=new ao(()=>aj('resize')),a7['observe'](an));},'markUserInteraction'(){aa=!0x0,af();},'resetAutoFit'(){aa=!0x1,ab=0x0;},'destroy'(){ak(),af(),ab=0x0;}};};export{b as _,B as a,i as b,A as c,D as d,te as f,y as g,v as h,R as i,k as l,_ as m,ie as n,P as o,O as p,re as r,E as s,se as t,ee as u,s as v,n as x,a as y};
@@ -0,0 +1 @@
1
+ const ak=g;(function(y,z){const aj=g,A=y();while(!![]){try{const B=parseInt(aj(0x123))/0x1*(parseInt(aj(0x11a))/0x2)+parseInt(aj(0x121))/0x3*(parseInt(aj(0x11c))/0x4)+-parseInt(aj(0x137))/0x5+-parseInt(aj(0x136))/0x6+-parseInt(aj(0x128))/0x7+parseInt(aj(0x12e))/0x8*(-parseInt(aj(0x125))/0x9)+parseInt(aj(0x11e))/0xa;if(B===z)break;else A['push'](A['shift']());}catch(C){A['push'](A['shift']());}}}(b,0x9ca24));import{t as j}from'./messages.js';import{d as k,i as q,p as v,r as w,x}from'./fit.js';function g(a,c){a=a-0x110;const d=b();let e=d[a];return e;}var o={'avif':'image/avif','bmp':ak(0x130),'gif':'image/gif','heic':'image/heic','heif':'image/heif','ico':'image/x-icon','jxl':'image/jxl','jpg':'image/jpeg','jpeg':'image/jpeg','png':'image/png','svg':ak(0x117),'tif':'image/tiff','tiff':'image/tiff','webp':'image/webp'},s=ak(0x131),c=y=>{const al=ak;let z=y['createElement'](al(0x135));return z[al(0x110)]=s,z;},l=y=>o[(y||'')['trim']()['toLowerCase']()]||'image/*',u=(function(){var y=x(function*(z){return yield new Promise((A,B)=>{const am=g;let C=new FileReader();C[am(0x139)]=D=>{const an=am;var E;let F=(E=D['target'])==null?void 0x0:E['result'];if(typeof F==an(0x129)){A(F);return;}B(Error('Unable\x20to\x20read\x20image\x20data\x20URL.'));},C['onerror']=()=>B(C['error']||Error(am(0x132))),C['readAsDataURL'](z);});});return function(z){const ao=g;return y[ao(0x134)](this,arguments);};}()),d=(function(){var y=x(function*(z,A){let B=(A||'')['trim']()['toLowerCase']();if(B==='heic'||B==='heif')throw Error('HEIC/HEIF\x20image\x20conversion\x20has\x20moved\x20out\x20of\x20@file-viewer/core.\x20Install\x20and\x20pass\x20@file-viewer/renderer-image,\x20or\x20use\x20@file-viewer/preset-all.');return u(new Blob([z],{'type':l(B)}));});return function(z,A){return y['apply'](this,arguments);};}()),f=y=>Number(y['toFixed'](0x3)),p=(y,z,A)=>{const ap=ak;let B=y[ap(0x114)]('div');B['className']='image-lightbox',B['hidden']=!0x0,B['setAttribute']('role',ap(0x133)),B['setAttribute']('aria-modal','true');let C=y[ap(0x114)]('img');C['alt']=A('image.lightbox.alt'),C['src']=z;let D=y['createElement']('button');D['type']='button',D[ap(0x113)]('aria-label',A('image.lightbox.close')),D['textContent']='x';let E=()=>{B['hidden']=!0x0;};return D['addEventListener']('click',E),C['addEventListener']('click',E),B['addEventListener']('click',F=>{F['target']===B&&E();}),B[ap(0x138)](C,D),{'element':B,'open'(){B['hidden']=!0x1;},'destroy'(){const aq=ap;D['removeEventListener']('click',E),C['removeEventListener'](aq(0x12a),E),B['remove']();}};};function m(y,z,A,B){const ar=ak;return h[ar(0x134)](this,arguments);}function h(){return h=x(function*(z,B,G,H){const as=g;var J,K;let L=j(H==null?void 0x0:H['options']),Q=B['ownerDocument']||document,R=yield d(z,G);(J=H==null?void 0x0:H['registerThumbnailAdapter'])==null||J['call'](H,{'capture':()=>new Blob([z],{'type':l(G)})});let U=0x1,V=0x1,W=0x1,X=0x0,Y=q(),Z=Q['createElement']('div');Z['className']='image-viewer',Z[as(0x12b)]['viewerZoomProvider']='image';let a0=Q['createElement']('div');a0[as(0x122)]=as(0x11f);let a1=Q['createElement']('img');a1['alt']=L(as(0x111)),a1['src']=R,a0['append'](a1),Z[as(0x138)](a0);let a2=p(Q,R,L),a3=()=>a2[as(0x120)]();a1['addEventListener']('click',a3);let a4=()=>Math['min'](0.1,V||0.1),a5=ac=>{let ad=a4();return Math['min'](0x5,Math['max'](ad,f(ac)));},a6=()=>{const at=as;let ac=a1[at(0x127)]||0x0,ad=a1['naturalHeight']||0x0;if(!ac||!ad)return 0x1;let ae=Math['max']((Z[at(0x11b)]||0x0)-0x30,0x1),af=Math['max']((Z['clientHeight']||X||0x0)-0x30,0x1);return Math['min'](0x1,ae/ac,af/ad);},a7=()=>{const au=as;if(V=a6(),W=a5(V*U),a1['naturalWidth']&&a1['naturalHeight']){a1[au(0x135)]['width']=Math['max'](0x1,Math['round'](a1['naturalWidth']*W))+'px',a1['style']['height']=Math['max'](0x1,Math[au(0x119)](a1['naturalHeight']*W))+'px';return;}a1['style']['width']='auto',a1[au(0x135)]['height']=X>0x0?Math['max'](0x1,Math['round'](X*U))+'px':U*0x64+'%';},a8=()=>{X=Z['clientHeight']||0x0,a7(),Y['emit']();},a9=new ResizeObserver(a8);a9[as(0x115)](Z),a1['addEventListener']('load',a8);let aa=()=>({'scale':W,'label':Math['round'](W*0x64)+'%','canZoomIn':W<0x5,'canZoomOut':W>a4(),'canReset':Math['abs'](U-0x1)>0.001,'minScale':a4(),'maxScale':0x5}),ab=ac=>(U=a5(ac)/Math['max'](V,0.001),a7(),Y[as(0x12d)](),aa());return k(Z,{'zoomIn':()=>ab(W+0.15),'zoomOut':()=>ab(W-0.15),'resetZoom':()=>(U=0x1,a7(),Y[as(0x12d)](),aa()),'setZoom':ab,'fit':ac=>{const av=as;var ad,ae;let af=a1[av(0x127)]||0x0,ag=a1['naturalHeight']||0x0;if(!af||!ag)return{'applied':!0x1,'mode':ac['mode'],'resize':ac[av(0x12c)],'source':ac['source'],'reason':'image-not-ready','provider':'zoom'};let ah=w({'mode':ac['mode']==='auto'?'scale-down':ac['mode'],'viewportWidth':Math['max'](0x1,ac['viewportWidth']||Z['clientWidth']||0x0),'viewportHeight':Math['max'](0x1,ac['viewportHeight']||Z['clientHeight']||X||0x0),'contentWidth':af,'contentHeight':ag,'currentScale':W,'minScale':(ad=ac[av(0x118)])==null?a4():ad,'maxScale':(ae=ac['maxScale'])==null?0x5:ae});if(!ah)return{'applied':!0x1,'mode':ac['mode'],'resize':ac['resize'],'source':ac['source'],'reason':av(0x12f),'provider':av(0x112)};let ai=ab(ah);return{'applied':!0x0,'mode':ac['mode'],'resize':ac['resize'],'scale':ai[av(0x124)],'source':ac['source'],'provider':'zoom'};},'getState':aa,'subscribe':Y[as(0x126)]}),B['replaceChildren'](c(Q),Z),(((K=H==null?void 0x0:H['surface'])==null?void 0x0:K['shadowRoot'])||B)['append'](a2[as(0x116)]),a8(),{'$el':B,'unmount'(){const aw=as;var ac;(ac=H==null?void 0x0:H['registerThumbnailAdapter'])==null||ac['call'](H,null),v(Z),a9[aw(0x11d)](),a1['removeEventListener']('load',a8),a1['removeEventListener'](aw(0x12a),a3),a2['destroy'](),B['replaceChildren']();}};}),h['apply'](this,arguments);}function b(){const ax=['subscribe','naturalWidth','1058568XrpAXw','string','click','dataset','resize','emit','16myLWvU','unmeasurable','image/bmp','\x0a.image-viewer{position:relative;width:100%;height:100%;overflow:auto;background:var(--file-viewer-render-surface-background,#eef1f4);box-sizing:border-box}\x0a.image-stage{min-width:100%;min-height:100%;display:flex;align-items:center;justify-content:center;padding:24px;box-sizing:border-box}\x0a.image-stage\x20img{display:block;width:auto;max-width:none;margin:0\x20auto;border:0;box-shadow:0\x2018px\x2048px\x20rgba(15,23,42,.16);background:#fff;cursor:zoom-in}\x0a.image-lightbox{position:fixed;inset:0;z-index:2147483000;display:flex;align-items:center;justify-content:center;padding:40px;background:rgba(15,23,42,.88);box-sizing:border-box}\x0a.image-lightbox[hidden]{display:none}\x0a.image-lightbox\x20img{display:block;max-width:100%;max-height:100%;object-fit:contain;background:#fff;box-shadow:0\x2030px\x2080px\x20rgba(0,0,0,.4);cursor:zoom-out}\x0a.image-lightbox\x20button{position:absolute;top:20px;right:20px;width:40px;height:40px;border:0;border-radius:999px;background:rgba(255,255,255,.92);color:#172033;font-size:24px;line-height:40px;cursor:pointer;box-shadow:0\x2012px\x2028px\x20rgba(0,0,0,.18)}\x0a[data-viewer-theme=\x27dark\x27]\x20.image-viewer{background:var(--file-viewer-render-surface-background,#101820)}\x0a@media\x20(prefers-color-scheme:dark){[data-viewer-theme=\x27system\x27]\x20.image-viewer{background:var(--file-viewer-render-surface-background,#101820)}}\x0a@media\x20(max-width:767px){.image-stage{padding:12px}.image-lightbox{padding:16px}.image-lightbox\x20button{top:12px;right:12px}}\x0a','Unable\x20to\x20read\x20image\x20data\x20URL.','dialog','apply','style','2461710IZHdbV','625660fvjPxU','append','onload','textContent','image.alt','zoom','setAttribute','createElement','observe','element','image/svg+xml','minScale','round','46iGoptO','clientWidth','4EYOCNL','disconnect','9481750dEoLov','image-stage','open','3777063ZYTvJQ','className','3473DnTSjU','scale','4314879VKJMmC'];b=function(){return ax;};return b();}export{m as default};