@file-viewer/core 3.3.0 → 3.3.1

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.
Files changed (112) hide show
  1. package/README.en.md +14 -14
  2. package/README.md +14 -14
  3. package/README.zh-CN.md +4 -0
  4. package/dist/assets.d.ts +2 -2
  5. package/dist/assets.js +5 -1
  6. package/dist/browser/controller.d.ts +2 -1
  7. package/dist/browser/controller.js +109 -26
  8. package/dist/browser/source-feedback.d.ts +4 -0
  9. package/dist/browser/source-feedback.js +40 -0
  10. package/dist/browser/toolbar-focus.d.ts +1 -0
  11. package/dist/browser/toolbar-focus.js +3 -0
  12. package/dist/browser.d.ts +2 -2
  13. package/dist/browser.js +2 -2
  14. package/dist/config/options.d.ts +1 -1
  15. package/dist/contracts/types.d.ts +470 -1
  16. package/dist/contracts/xml.d.ts +11 -0
  17. package/dist/export.d.ts +10 -3
  18. package/dist/export.js +9 -2
  19. package/dist/exportDocument.d.ts +12 -1
  20. package/dist/exportDocument.js +31 -2
  21. package/dist/features/document/dom/anchors.d.ts +1 -1
  22. package/dist/features/document/dom/index.d.ts +5 -5
  23. package/dist/features/document/dom/index.js +3 -3
  24. package/dist/features/document/dom/providers.d.ts +1 -1
  25. package/dist/features/document/events.d.ts +2 -2
  26. package/dist/features/document/events.js +3 -3
  27. package/dist/features/document/fit.d.ts +1 -1
  28. package/dist/features/document/fit.js +1 -1
  29. package/dist/features/document/imageHandTool.d.ts +2 -0
  30. package/dist/features/document/imageHandTool.js +5 -1
  31. package/dist/features/document/model.d.ts +1 -1
  32. package/dist/features/document/search.d.ts +1 -1
  33. package/dist/features/document/search.js +2 -2
  34. package/dist/features/document/viewState.d.ts +1 -1
  35. package/dist/features/document/viewState.js +2 -2
  36. package/dist/features/document/zoom.d.ts +1 -1
  37. package/dist/features/document/zoom.js +3 -3
  38. package/dist/features/document/zoomGestures.d.ts +2 -2
  39. package/dist/features/document/zoomGestures.js +2 -0
  40. package/dist/features/printMask.d.ts +1 -1
  41. package/dist/features/printMaskDesigner.d.ts +6 -2
  42. package/dist/features/printMaskDesigner.js +11 -2
  43. package/dist/features/printMaskLoader.d.ts +7 -1
  44. package/dist/features/printMaskLoader.js +7 -1
  45. package/dist/features/watermark.d.ts +1 -1
  46. package/dist/headless.d.ts +29 -29
  47. package/dist/headless.js +21 -16
  48. package/dist/i18n/messages.d.ts +1 -1
  49. package/dist/i18n/messages.de.d.ts +5 -1
  50. package/dist/i18n/messages.de.js +4 -0
  51. package/dist/i18n/messages.ja.d.ts +6 -1
  52. package/dist/i18n/messages.ja.js +5 -0
  53. package/dist/i18n/messages.js +2 -2
  54. package/dist/index.d.ts +77 -77
  55. package/dist/index.js +39 -39
  56. package/dist/lifecycle/facade.d.ts +4 -4
  57. package/dist/lifecycle/facade.js +2 -2
  58. package/dist/lifecycle/operations.d.ts +5 -4
  59. package/dist/lifecycle/operations.js +10 -4
  60. package/dist/output/canvasImage.d.ts +2 -1
  61. package/dist/output/canvasImage.js +4 -1
  62. package/dist/output/export.d.ts +3 -1
  63. package/dist/output/export.js +12 -0
  64. package/dist/output/printLayout.d.ts +5 -0
  65. package/dist/output/printLayout.js +4 -0
  66. package/dist/output/snapshotDownload.d.ts +2 -1
  67. package/dist/output/snapshotDownload.js +3 -2
  68. package/dist/platform/assets.d.ts +8 -1
  69. package/dist/platform/assets.js +14 -0
  70. package/dist/platform/copiedAssets.d.ts +1 -0
  71. package/dist/platform/copiedAssets.js +2 -1
  72. package/dist/presentation/colorScheme.d.ts +2 -1
  73. package/dist/presentation/colorScheme.js +2 -1
  74. package/dist/presentation/state.d.ts +1 -1
  75. package/dist/presentation/state.js +3 -3
  76. package/dist/print-mask.d.ts +2 -2
  77. package/dist/print-mask.js +1 -1
  78. package/dist/registry/capabilities.d.ts +14 -1
  79. package/dist/registry/capabilities.js +15 -2
  80. package/dist/registry/formats.d.ts +1 -1
  81. package/dist/registry/formats.generated.d.ts +1 -0
  82. package/dist/registry/formats.generated.js +1 -0
  83. package/dist/registry/formats.js +2 -2
  84. package/dist/registry/registry.d.ts +15 -1
  85. package/dist/registry/registry.js +10 -2
  86. package/dist/renderers/image.d.ts +1 -1
  87. package/dist/renderers/image.js +7 -5
  88. package/dist/renderers/index.d.ts +1 -1
  89. package/dist/renderers/index.js +11 -5
  90. package/dist/rendering/dispatcher.d.ts +6 -1
  91. package/dist/rendering/dispatcher.js +3 -3
  92. package/dist/rendering/handler.d.ts +13 -3
  93. package/dist/rendering/handler.js +21 -9
  94. package/dist/security/svgResources.d.ts +10 -0
  95. package/dist/security/svgResources.js +12 -0
  96. package/dist/source/index.d.ts +3 -3
  97. package/dist/source/index.js +1 -1
  98. package/dist/source/loading.d.ts +4 -4
  99. package/dist/source/loading.js +7 -4
  100. package/dist/source/precheck.d.ts +13 -1
  101. package/dist/source/precheck.js +9 -2
  102. package/dist/source/textEncoding.d.ts +18 -0
  103. package/dist/source/textEncoding.js +15 -0
  104. package/dist/viewer/createViewer.d.ts +1 -1
  105. package/dist/viewer/createViewer.js +28 -17
  106. package/dist/viewer/loading.d.ts +6 -2
  107. package/dist/viewer/loading.js +9 -1
  108. package/dist/viewer/operations.d.ts +3 -3
  109. package/dist/viewer/operations.js +14 -6
  110. package/dist/viewer/state.d.ts +6 -2
  111. package/dist/viewer/state.js +8 -3
  112. package/package.json +5 -3
@@ -1,3 +1,4 @@
1
+ /** Optional, self-hosted XML Schema 1.0 / XSLT 1.0 profiles. */
1
2
  export interface FileViewerXmlProfile {
2
3
  id: string;
3
4
  match: {
@@ -10,6 +11,7 @@ export interface FileViewerXmlProfile {
10
11
  enabled: boolean;
11
12
  };
12
13
  };
14
+ /** Relative to the manifest URL (or baseUrl for inline profiles). */
13
15
  xsd?: string;
14
16
  xslt: string;
15
17
  }
@@ -23,14 +25,21 @@ export interface FileViewerXmlDiagnostic {
23
25
  profileId?: string;
24
26
  }
25
27
  export interface FileViewerXmlOptions {
28
+ /** Opt in with a same-origin HTTP(S) manifest. Redirects are rejected. */
26
29
  profilesUrl?: string;
30
+ /** Alternative to profilesUrl. Supplying both is a configuration error. */
27
31
  profiles?: FileViewerXmlProfile[];
32
+ /** Base for inline profiles' resource paths; defaults to the document URL. */
28
33
  baseUrl?: string;
29
34
  runtime?: {
35
+ /** xmllint-wasm@5.3.0 browser worker; xmllint.wasm must be beside it. */
30
36
  xsdWorkerUrl?: string;
37
+ /** xslt-polyfill@1.0.29 dist/xslt-wasm.js, containing embedded WASM. */
31
38
  xsltModuleUrl?: string;
32
39
  };
40
+ /** Whole profile operation, including downloads; default 15s, ceiling 60s. */
33
41
  timeoutMs?: number;
42
+ /** Limits may lower the hard ceilings but cannot disable them. */
34
43
  limits?: {
35
44
  maxXmlBytes?: number;
36
45
  maxResourceBytes?: number;
@@ -39,10 +48,12 @@ export interface FileViewerXmlOptions {
39
48
  maxTotalResourceBytes?: number;
40
49
  };
41
50
  initialView?: 'source' | 'rendered';
51
+ /** Labels can be localized without replacing the source renderer. */
42
52
  labels?: {
43
53
  viewSource?: string;
44
54
  viewRendered?: string;
45
55
  diagnostics?: string;
46
56
  };
57
+ /** Also available on the rendered instance; never contains generated HTML. */
47
58
  onDiagnostic?: (diagnostic: FileViewerXmlDiagnostic) => void;
48
59
  }
package/dist/export.d.ts CHANGED
@@ -1,3 +1,10 @@
1
- export { buildFileViewerRenderedDomDocument, buildFileViewerRenderedHtmlDocument, buildExportDomDocument, buildExportHtmlDocument, collectDocumentStyles, sanitizeFileViewerExportDocumentDom, sanitizeFileViewerExportDocumentHtml, } from "./exportDocument.js";
2
- export type { BuildExportHtmlDocumentOptions, BuildFileViewerRenderedHtmlDocumentOptions, } from "./exportDocument.js";
3
- export { inlineFileViewerBlobUrlsInHtml, prepareFileViewerRenderedContentForSnapshot, replaceFileViewerCanvasWithImages, resolveFileViewerPrintStyle, triggerFileViewerBlobDownload, triggerFileViewerUrlDownload, waitForFileViewerImages, waitForFileViewerNextPaint, waitForFileViewerPrintWindowReady, } from "./output/export.js";
1
+ /**
2
+ * Explicit HTML export and print-document entrypoint.
3
+ *
4
+ * This subpath owns the DOM sanitizer and is intentionally excluded from the
5
+ * normal viewer/headless graph. Viewer operations load it only when the user
6
+ * starts an HTML export or print operation.
7
+ */
8
+ export { buildFileViewerRenderedDomDocument, buildFileViewerRenderedHtmlDocument, buildExportDomDocument, buildExportHtmlDocument, collectDocumentStyles, sanitizeFileViewerExportDocumentDom, sanitizeFileViewerExportDocumentHtml, } from './exportDocument.js';
9
+ export type { BuildExportHtmlDocumentOptions, BuildFileViewerRenderedHtmlDocumentOptions, } from './exportDocument.js';
10
+ export { inlineFileViewerBlobUrlsInHtml, prepareFileViewerRenderedContentForSnapshot, replaceFileViewerCanvasWithImages, resolveFileViewerPrintStyle, triggerFileViewerBlobDownload, triggerFileViewerUrlDownload, waitForFileViewerImages, waitForFileViewerNextPaint, waitForFileViewerPrintWindowReady, } from './output/export.js';
package/dist/export.js CHANGED
@@ -1,2 +1,9 @@
1
- export { buildFileViewerRenderedDomDocument, buildFileViewerRenderedHtmlDocument, buildExportDomDocument, buildExportHtmlDocument, collectDocumentStyles, sanitizeFileViewerExportDocumentDom, sanitizeFileViewerExportDocumentHtml, } from "./exportDocument.js";
2
- export { inlineFileViewerBlobUrlsInHtml, prepareFileViewerRenderedContentForSnapshot, replaceFileViewerCanvasWithImages, resolveFileViewerPrintStyle, triggerFileViewerBlobDownload, triggerFileViewerUrlDownload, waitForFileViewerImages, waitForFileViewerNextPaint, waitForFileViewerPrintWindowReady, } from "./output/export.js";
1
+ /**
2
+ * Explicit HTML export and print-document entrypoint.
3
+ *
4
+ * This subpath owns the DOM sanitizer and is intentionally excluded from the
5
+ * normal viewer/headless graph. Viewer operations load it only when the user
6
+ * starts an HTML export or print operation.
7
+ */
8
+ export { buildFileViewerRenderedDomDocument, buildFileViewerRenderedHtmlDocument, buildExportDomDocument, buildExportHtmlDocument, collectDocumentStyles, sanitizeFileViewerExportDocumentDom, sanitizeFileViewerExportDocumentHtml, } from './exportDocument.js';
9
+ export { inlineFileViewerBlobUrlsInHtml, prepareFileViewerRenderedContentForSnapshot, replaceFileViewerCanvasWithImages, resolveFileViewerPrintStyle, triggerFileViewerBlobDownload, triggerFileViewerUrlDownload, waitForFileViewerImages, waitForFileViewerNextPaint, waitForFileViewerPrintWindowReady, } from './output/export.js';
@@ -1,5 +1,15 @@
1
- import type { FileRenderExportAdapter, FileRenderExportMode, FileViewerPrintMaskOptions } from "./contracts/types.js";
1
+ import type { FileRenderExportAdapter, FileRenderExportMode, FileViewerPrintMaskOptions } from './contracts/types.js';
2
+ /**
3
+ * Sanitize the complete standalone export document before it is downloaded or
4
+ * mounted into a print window. This is deliberately enforced in core because
5
+ * third-party render adapters and watermark overrides are library inputs.
6
+ */
2
7
  export declare const sanitizeFileViewerExportDocumentHtml: (html: string, documentRef?: Document) => string;
8
+ /**
9
+ * Produce a sanitized, inert document tree for the print-window mount path.
10
+ * Returning DOM here avoids reinterpreting the sanitized string through a
11
+ * second HTML sink such as document.write or innerHTML.
12
+ */
3
13
  export declare const sanitizeFileViewerExportDocumentDom: (html: string, documentRef?: Document) => HTMLHtmlElement;
4
14
  export interface BuildExportHtmlDocumentOptions {
5
15
  contentHtml: string;
@@ -8,6 +18,7 @@ export interface BuildExportHtmlDocumentOptions {
8
18
  title: string;
9
19
  watermarkInlineStyle?: string;
10
20
  mask?: FileViewerPrintMaskOptions | null;
21
+ /** Document whose Window owns the sanitizer. Defaults to the active document. */
11
22
  documentRef?: Document;
12
23
  }
13
24
  export declare const collectDocumentStyles: (documentRef?: Document) => string;
@@ -1,6 +1,6 @@
1
1
  import createDOMPurify from 'dompurify';
2
- import { applyFileViewerPagePrintMasksToHtml, buildFileViewerPrintMaskOverlayHtml, FILE_VIEWER_PRINT_MASK_STYLE, normalizeFileViewerPrintMaskOptions, } from "./features/printMask.js";
3
- import { inlineFileViewerBlobUrlsInHtml, prepareFileViewerRenderedContentForSnapshot, replaceFileViewerCanvasWithImages, resolveFileViewerPrintStyle, } from "./output/export.js";
2
+ import { applyFileViewerPagePrintMasksToHtml, buildFileViewerPrintMaskOverlayHtml, FILE_VIEWER_PRINT_MASK_STYLE, normalizeFileViewerPrintMaskOptions, } from './features/printMask.js';
3
+ import { inlineFileViewerBlobUrlsInHtml, prepareFileViewerRenderedContentForSnapshot, replaceFileViewerCanvasWithImages, resolveFileViewerPrintStyle, } from './output/export.js';
4
4
  const escapeHtmlAttribute = (value) => value
5
5
  .replace(/&/g, '&')
6
6
  .replace(/"/g, '"')
@@ -47,6 +47,11 @@ const decodeCssEscape = (value, slashIndex) => {
47
47
  }
48
48
  return { value: first, nextIndex: cursor + 1 };
49
49
  };
50
+ /**
51
+ * Remove CSS comments and decode identifier escapes before looking for URL
52
+ * functions. CSS comments and escapes may otherwise split security-sensitive
53
+ * tokens such as `url` or `@import` while the browser still accepts them.
54
+ */
50
55
  const canonicalizeCssForSecurity = (css) => {
51
56
  let output = '';
52
57
  let quote = '';
@@ -241,6 +246,12 @@ const inspectCssNetworkTokens = (css) => {
241
246
  }
242
247
  return { hasImport, hasUrl };
243
248
  };
249
+ /**
250
+ * Keep ordinary CSS and local embedded resources, but remove every construct
251
+ * that can make an exported document initiate a new network request. Imported
252
+ * stylesheets fail closed; unsafe url() values become `none` so the rest of a
253
+ * declaration can still render.
254
+ */
244
255
  const sanitizeExportCss = (css) => {
245
256
  const canonical = canonicalizeCssForSecurity(css);
246
257
  const canonicalTokens = inspectCssNetworkTokens(canonical);
@@ -342,9 +353,13 @@ const getExportPurifier = (documentRef) => {
342
353
  element.setAttribute('rel', 'noopener noreferrer');
343
354
  }
344
355
  if (localName === 'a' || localName === 'area') {
356
+ // Keep ordinary links, but never preserve document-controlled beacons.
345
357
  element.removeAttribute('ping');
346
358
  }
347
359
  if (element.hasAttribute('srcset')) {
360
+ // Candidate lists have their own comma/descriptor grammar. The export
361
+ // keeps the materialized src and drops candidates that could select a
362
+ // remote resource after the standalone document is opened.
348
363
  element.removeAttribute('srcset');
349
364
  }
350
365
  if (['img', 'audio', 'video', 'source', 'track', 'input'].includes(localName || '')) {
@@ -377,12 +392,19 @@ const EXPORT_STATIC_META = [
377
392
  '<meta charset="utf-8" />',
378
393
  '<meta name="viewport" content="width=device-width,initial-scale=1" />',
379
394
  ].join('\n ');
395
+ /**
396
+ * Sanitize the complete standalone export document before it is downloaded or
397
+ * mounted into a print window. This is deliberately enforced in core because
398
+ * third-party render adapters and watermark overrides are library inputs.
399
+ */
380
400
  export const sanitizeFileViewerExportDocumentHtml = (html, documentRef) => {
381
401
  const currentDocument = resolveExportDocument(documentRef);
382
402
  const purifier = currentDocument
383
403
  ? getExportPurifier(currentDocument)
384
404
  : null;
385
405
  if (!purifier) {
406
+ // Export is a browser feature. Fail closed rather than return executable
407
+ // markup when called without a usable DOM implementation.
386
408
  return '<!doctype html>\n<html lang="en"><head><meta charset="utf-8" /></head><body></body></html>';
387
409
  }
388
410
  const sanitized = String(purifier.sanitize(html, EXPORT_SANITIZER_OPTIONS));
@@ -417,6 +439,11 @@ const ensureFileViewerExportDocumentMeta = (root) => {
417
439
  }
418
440
  return root;
419
441
  };
442
+ /**
443
+ * Produce a sanitized, inert document tree for the print-window mount path.
444
+ * Returning DOM here avoids reinterpreting the sanitized string through a
445
+ * second HTML sink such as document.write or innerHTML.
446
+ */
420
447
  export const sanitizeFileViewerExportDocumentDom = (html, documentRef) => {
421
448
  const currentDocument = resolveExportDocument(documentRef);
422
449
  if (!currentDocument) {
@@ -779,6 +806,8 @@ export const collectDocumentStyles = (documentRef) => {
779
806
  : '';
780
807
  }
781
808
  catch {
809
+ // Cross-origin and unreadable stylesheets fail closed. Keeping their
810
+ // link would make a standalone export initiate a second request.
782
811
  return '';
783
812
  }
784
813
  })
@@ -1,4 +1,4 @@
1
- import type { FileViewerDocumentAnchor } from "../../../contracts/types.js";
1
+ import type { FileViewerDocumentAnchor } from '../../../contracts/types.js';
2
2
  export declare const DEFAULT_FILE_VIEWER_ANCHOR_SELECTOR: string;
3
3
  export declare const DEFAULT_FILE_VIEWER_ANCHOR_EXCLUDE_SELECTOR: string;
4
4
  export declare const collectFileViewerDocumentAnchors: (root: HTMLElement | null) => FileViewerDocumentAnchor[];
@@ -1,5 +1,5 @@
1
- export { DEFAULT_FILE_VIEWER_ANCHOR_EXCLUDE_SELECTOR, DEFAULT_FILE_VIEWER_ANCHOR_SELECTOR, collectFileViewerDocumentAnchors, findFileViewerAnchorForElement, getCurrentFileViewerDocumentAnchor, scrollToFileViewerDocumentAnchor, } from "./anchors.js";
2
- export { findFileViewerSearchProvider, findFileViewerViewStateProvider, findFileViewerZoomProvider, registerFileViewerSearchProvider, registerFileViewerViewStateProvider, registerFileViewerZoomProvider, unregisterFileViewerSearchProvider, unregisterFileViewerViewStateProvider, unregisterFileViewerZoomProvider, } from "./providers.js";
3
- export type { FileViewerSearchProviderHost, FileViewerViewStateProviderHost, FileViewerZoomProviderHost, } from "./providers.js";
4
- export { DEFAULT_FILE_VIEWER_SCROLL_CONTAINER_CANDIDATE_SELECTOR, DEFAULT_FILE_VIEWER_SCROLL_CONTAINER_SELECTOR, DEFAULT_FILE_VIEWER_SCROLLABLE_OVERFLOW_VALUES, getFileViewerScrollableRange, isFileViewerScrollableElement, resolveFileViewerScrollContainer, } from "./scroll.js";
5
- export type { ResolveFileViewerScrollContainerOptions, } from "./scroll.js";
1
+ export { DEFAULT_FILE_VIEWER_ANCHOR_EXCLUDE_SELECTOR, DEFAULT_FILE_VIEWER_ANCHOR_SELECTOR, collectFileViewerDocumentAnchors, findFileViewerAnchorForElement, getCurrentFileViewerDocumentAnchor, scrollToFileViewerDocumentAnchor, } from './anchors.js';
2
+ export { findFileViewerSearchProvider, findFileViewerViewStateProvider, findFileViewerZoomProvider, registerFileViewerSearchProvider, registerFileViewerViewStateProvider, registerFileViewerZoomProvider, unregisterFileViewerSearchProvider, unregisterFileViewerViewStateProvider, unregisterFileViewerZoomProvider, } from './providers.js';
3
+ export type { FileViewerSearchProviderHost, FileViewerViewStateProviderHost, FileViewerZoomProviderHost, } from './providers.js';
4
+ export { DEFAULT_FILE_VIEWER_SCROLL_CONTAINER_CANDIDATE_SELECTOR, DEFAULT_FILE_VIEWER_SCROLL_CONTAINER_SELECTOR, DEFAULT_FILE_VIEWER_SCROLLABLE_OVERFLOW_VALUES, getFileViewerScrollableRange, isFileViewerScrollableElement, resolveFileViewerScrollContainer, } from './scroll.js';
5
+ export type { ResolveFileViewerScrollContainerOptions, } from './scroll.js';
@@ -1,3 +1,3 @@
1
- export { DEFAULT_FILE_VIEWER_ANCHOR_EXCLUDE_SELECTOR, DEFAULT_FILE_VIEWER_ANCHOR_SELECTOR, collectFileViewerDocumentAnchors, findFileViewerAnchorForElement, getCurrentFileViewerDocumentAnchor, scrollToFileViewerDocumentAnchor, } from "./anchors.js";
2
- export { findFileViewerSearchProvider, findFileViewerViewStateProvider, findFileViewerZoomProvider, registerFileViewerSearchProvider, registerFileViewerViewStateProvider, registerFileViewerZoomProvider, unregisterFileViewerSearchProvider, unregisterFileViewerViewStateProvider, unregisterFileViewerZoomProvider, } from "./providers.js";
3
- export { DEFAULT_FILE_VIEWER_SCROLL_CONTAINER_CANDIDATE_SELECTOR, DEFAULT_FILE_VIEWER_SCROLL_CONTAINER_SELECTOR, DEFAULT_FILE_VIEWER_SCROLLABLE_OVERFLOW_VALUES, getFileViewerScrollableRange, isFileViewerScrollableElement, resolveFileViewerScrollContainer, } from "./scroll.js";
1
+ export { DEFAULT_FILE_VIEWER_ANCHOR_EXCLUDE_SELECTOR, DEFAULT_FILE_VIEWER_ANCHOR_SELECTOR, collectFileViewerDocumentAnchors, findFileViewerAnchorForElement, getCurrentFileViewerDocumentAnchor, scrollToFileViewerDocumentAnchor, } from './anchors.js';
2
+ export { findFileViewerSearchProvider, findFileViewerViewStateProvider, findFileViewerZoomProvider, registerFileViewerSearchProvider, registerFileViewerViewStateProvider, registerFileViewerZoomProvider, unregisterFileViewerSearchProvider, unregisterFileViewerViewStateProvider, unregisterFileViewerZoomProvider, } from './providers.js';
3
+ export { DEFAULT_FILE_VIEWER_SCROLL_CONTAINER_CANDIDATE_SELECTOR, DEFAULT_FILE_VIEWER_SCROLL_CONTAINER_SELECTOR, DEFAULT_FILE_VIEWER_SCROLLABLE_OVERFLOW_VALUES, getFileViewerScrollableRange, isFileViewerScrollableElement, resolveFileViewerScrollContainer, } from './scroll.js';
@@ -1,4 +1,4 @@
1
- import type { FileViewerSearchProvider, FileViewerViewStateProvider, FileViewerZoomProvider } from "../../../contracts/types.js";
1
+ import type { FileViewerSearchProvider, FileViewerViewStateProvider, FileViewerZoomProvider } from '../../../contracts/types.js';
2
2
  export interface FileViewerSearchProviderHost extends HTMLElement {
3
3
  __flyfishViewerSearchProvider?: FileViewerSearchProvider;
4
4
  }
@@ -1,5 +1,5 @@
1
- import { type FileViewerDomSearchControllerStateTarget } from "./search.js";
2
- import type { FileViewerAiOptions, FileViewerDocumentAnchor, FileViewerDocumentChunk, FileViewerSearchOptions, FileViewerSearchState } from "../../contracts/types.js";
1
+ import { type FileViewerDomSearchControllerStateTarget } from './search.js';
2
+ import type { FileViewerAiOptions, FileViewerDocumentAnchor, FileViewerDocumentChunk, FileViewerSearchOptions, FileViewerSearchState } from '../../contracts/types.js';
3
3
  export interface ResolveFileViewerLocationChangeAnchorInput {
4
4
  root: HTMLElement | null | undefined;
5
5
  anchors: FileViewerDocumentAnchor[];
@@ -1,6 +1,6 @@
1
- import { buildFileViewerDocumentTextChunks } from "./model.js";
2
- import { getCurrentFileViewerDocumentAnchor, resolveFileViewerScrollContainer, scrollToFileViewerDocumentAnchor, } from "./dom/index.js";
3
- import { cloneFileViewerSearchState, createFileViewerDomSearchController, createFileViewerDomSearchControllerActionHandlers, } from "./search.js";
1
+ import { buildFileViewerDocumentTextChunks } from './model.js';
2
+ import { getCurrentFileViewerDocumentAnchor, resolveFileViewerScrollContainer, scrollToFileViewerDocumentAnchor, } from './dom/index.js';
3
+ import { cloneFileViewerSearchState, createFileViewerDomSearchController, createFileViewerDomSearchControllerActionHandlers, } from './search.js';
4
4
  export const createFileViewerSearchChangeState = (state) => {
5
5
  return cloneFileViewerSearchState(state);
6
6
  };
@@ -1,4 +1,4 @@
1
- import type { FileViewerFitMode, FileViewerFitOptions, FileViewerFitRequest, FileViewerFitResize, FileViewerFitResult, FileViewerViewState, FileViewerViewStateChangeSource } from "../../contracts/types.js";
1
+ import type { FileViewerFitMode, FileViewerFitOptions, FileViewerFitRequest, FileViewerFitResize, FileViewerFitResult, FileViewerViewState, FileViewerViewStateChangeSource } from '../../contracts/types.js';
2
2
  export declare const FILE_VIEWER_FIT_MODES: readonly ["auto", "contain", "cover", "width", "height", "actual", "scale-down"];
3
3
  export declare const FILE_VIEWER_FIT_RESIZE_MODES: readonly ["until-interaction", "always", "initial"];
4
4
  export interface NormalizedFileViewerFitOptions extends Required<Pick<FileViewerFitOptions, 'mode' | 'resize' | 'padding'>> {
@@ -1,4 +1,4 @@
1
- import { findFileViewerViewStateProvider, findFileViewerZoomProvider, } from "./dom/index.js";
1
+ import { findFileViewerViewStateProvider, findFileViewerZoomProvider, } from './dom/index.js';
2
2
  export const FILE_VIEWER_FIT_MODES = [
3
3
  'auto',
4
4
  'contain',
@@ -1 +1,3 @@
1
+ /** Optional mouse panning for image previews. Touch/pinch, keyboard activation,
2
+ * controls and native scrollbars retain their normal browser behavior. */
1
3
  export declare function installFileViewerImageHandTool(container: HTMLElement, signal?: AbortSignal): () => void;
@@ -1,3 +1,5 @@
1
+ /** Optional mouse panning for image previews. Touch/pinch, keyboard activation,
2
+ * controls and native scrollbars retain their normal browser behavior. */
1
3
  export function installFileViewerImageHandTool(container, signal) {
2
4
  const view = container.ownerDocument.defaultView;
3
5
  if (!view || (signal === null || signal === void 0 ? void 0 : signal.aborted))
@@ -60,10 +62,12 @@ export function installFileViewerImageHandTool(container, signal) {
60
62
  container.setAttribute('data-viewer-image-panning', 'true');
61
63
  container.style.cursor = 'grabbing';
62
64
  container.style.setProperty('user-select', 'none');
65
+ // Delay capture until a drag starts so an ordinary click still reaches
66
+ // the image's lightbox handler instead of being retargeted to its parent.
63
67
  try {
64
68
  (_a = container.setPointerCapture) === null || _a === void 0 ? void 0 : _a.call(container, event.pointerId);
65
69
  }
66
- catch { }
70
+ catch { /* window listeners remain active */ }
67
71
  }
68
72
  container.scrollLeft = drag.left - dx;
69
73
  container.scrollTop = drag.top - dy;
@@ -1,4 +1,4 @@
1
- import type { FileViewerAiOptions, FileViewerDocumentAnchor, FileViewerDocumentChunk, FileViewerSearchOptions, FileViewerSearchState, FileViewerZoomState } from "../../contracts/types.js";
1
+ import type { FileViewerAiOptions, FileViewerDocumentAnchor, FileViewerDocumentChunk, FileViewerSearchOptions, FileViewerSearchState, FileViewerZoomState } from '../../contracts/types.js';
2
2
  export declare const DEFAULT_FILE_VIEWER_ZOOM_SCALE = 1;
3
3
  export declare const DEFAULT_FILE_VIEWER_TEXT_CHUNK_SIZE = 1200;
4
4
  export declare const DEFAULT_FILE_VIEWER_TEXT_CHUNK_OVERLAP = 160;
@@ -1,4 +1,4 @@
1
- import type { FileViewerDocumentAnchor, FileViewerSearchMatch, FileViewerSearchOptions, FileViewerSearchState } from "../../contracts/types.js";
1
+ import type { FileViewerDocumentAnchor, FileViewerSearchMatch, FileViewerSearchOptions, FileViewerSearchState } from '../../contracts/types.js';
2
2
  export interface CreateFileViewerDomSearchControllerOptions {
3
3
  root: () => HTMLElement | null | undefined;
4
4
  options?: () => boolean | FileViewerSearchOptions | undefined;
@@ -1,5 +1,5 @@
1
- import { collectFileViewerDocumentAnchors, findFileViewerAnchorForElement, findFileViewerSearchProvider, } from "./dom/index.js";
2
- import { createEmptyFileViewerSearchState, normalizeFileViewerSearchOptions, } from "./model.js";
1
+ import { collectFileViewerDocumentAnchors, findFileViewerAnchorForElement, findFileViewerSearchProvider, } from './dom/index.js';
2
+ import { createEmptyFileViewerSearchState, normalizeFileViewerSearchOptions, } from './model.js';
3
3
  export const DEFAULT_FILE_VIEWER_SEARCH_MATCH_CLASS = 'flyfish-search-match';
4
4
  export const DEFAULT_FILE_VIEWER_SEARCH_ACTIVE_CLASS = 'flyfish-search-match--active';
5
5
  export const DEFAULT_FILE_VIEWER_SEARCH_MAX_MATCHES = 1000;
@@ -1,4 +1,4 @@
1
- import type { FileViewerApplyViewStateOptions, FileViewerViewState, FileViewerViewStateChange, FileViewerViewStateProvider } from "../../contracts/types.js";
1
+ import type { FileViewerApplyViewStateOptions, FileViewerViewState, FileViewerViewStateChange, FileViewerViewStateProvider } from '../../contracts/types.js';
2
2
  export interface RegisterFileViewerGenericViewStateProviderOptions {
3
3
  host: HTMLElement;
4
4
  renderer?: string;
@@ -1,5 +1,5 @@
1
- import { findFileViewerViewStateProvider, findFileViewerZoomProvider, registerFileViewerViewStateProvider, resolveFileViewerScrollContainer, unregisterFileViewerViewStateProvider, } from "./dom/index.js";
2
- import { resolveFileViewerFitScale } from "./fit.js";
1
+ import { findFileViewerViewStateProvider, findFileViewerZoomProvider, registerFileViewerViewStateProvider, resolveFileViewerScrollContainer, unregisterFileViewerViewStateProvider, } from './dom/index.js';
2
+ import { resolveFileViewerFitScale } from './fit.js';
3
3
  export const cloneFileViewerViewState = (state) => {
4
4
  if (!state) {
5
5
  return null;
@@ -1,4 +1,4 @@
1
- import type { FileViewerOptions, FileViewerOperationType, FileViewerZoomProvider, FileViewerZoomState } from "../../contracts/types.js";
1
+ import type { FileViewerOptions, FileViewerOperationType, FileViewerZoomProvider, FileViewerZoomState } from '../../contracts/types.js';
2
2
  export type FileViewerZoomOperation = Extract<FileViewerOperationType, 'zoom-in' | 'zoom-out' | 'zoom-reset'>;
3
3
  export interface CreateFileViewerZoomControllerOptions {
4
4
  root: () => HTMLElement | null | undefined;
@@ -1,6 +1,6 @@
1
- import { createFileViewerZoomState } from "./model.js";
2
- import { findFileViewerZoomProvider } from "./dom/index.js";
3
- import { installFileViewerZoomGestures } from "./zoomGestures.js";
1
+ import { createFileViewerZoomState } from './model.js';
2
+ import { findFileViewerZoomProvider } from './dom/index.js';
3
+ import { installFileViewerZoomGestures } from './zoomGestures.js';
4
4
  export const cloneFileViewerZoomState = (state) => ({
5
5
  scale: state.scale,
6
6
  label: state.label,
@@ -1,5 +1,5 @@
1
- import type { FileViewerOptions, FileViewerZoomProvider } from "../../contracts/types.js";
2
- import type { FileViewerZoomOperation } from "./zoom.js";
1
+ import type { FileViewerOptions, FileViewerZoomProvider } from '../../contracts/types.js';
2
+ import type { FileViewerZoomOperation } from './zoom.js';
3
3
  interface ZoomGestureOptions {
4
4
  provider: () => FileViewerZoomProvider | null;
5
5
  enabled: () => boolean;
@@ -43,6 +43,8 @@ export function installFileViewerZoomGestures(container, options) {
43
43
  options.onZoom();
44
44
  }
45
45
  catch {
46
+ // Operation hooks report their errors. Native events have no caller to
47
+ // receive a rejected promise, so do not leak an unhandled rejection.
46
48
  }
47
49
  finally {
48
50
  busy = false;
@@ -1,4 +1,4 @@
1
- import type { FileViewerPrintMaskOptions, FileViewerPrintMaskRegion, FileViewerPrintStamp } from "../contracts/types.js";
1
+ import type { FileViewerPrintMaskOptions, FileViewerPrintMaskRegion, FileViewerPrintStamp } from '../contracts/types.js';
2
2
  export declare const normalizeFileViewerPrintMaskRegion: (region: Partial<FileViewerPrintMaskRegion> | null | undefined) => FileViewerPrintMaskRegion | null;
3
3
  export declare const normalizeFileViewerPrintStamp: (stamp: Partial<FileViewerPrintStamp> | null | undefined) => FileViewerPrintStamp | null;
4
4
  export declare const normalizeFileViewerPrintMaskOptions: (mask?: FileViewerPrintMaskOptions | null) => FileViewerPrintMaskOptions | null;
@@ -1,5 +1,5 @@
1
- import type { FileViewerPrintMaskOptions, FileViewerPrintMaskRegion, FileViewerPrintStamp } from "../contracts/types.js";
2
- import { type FileViewerI18nInput } from "../i18n/messages.js";
1
+ import type { FileViewerPrintMaskOptions, FileViewerPrintMaskRegion, FileViewerPrintStamp } from '../contracts/types.js';
2
+ import { type FileViewerI18nInput } from '../i18n/messages.js';
3
3
  export interface OpenFileViewerPrintMaskDesignerOptions {
4
4
  root: HTMLElement;
5
5
  pages?: readonly HTMLElement[];
@@ -11,4 +11,8 @@ export interface OpenFileViewerPrintMaskDesignerOptions {
11
11
  export interface FileViewerPrintMaskDesignerResult {
12
12
  mask: FileViewerPrintMaskOptions;
13
13
  }
14
+ /**
15
+ * Opens a page-aware print-mask designer. Browsing remains the default mode;
16
+ * drawing is armed for the currently visible page only and disarms after one block.
17
+ */
14
18
  export declare const openFileViewerPrintMaskDesigner: (options: OpenFileViewerPrintMaskDesignerOptions) => Promise<FileViewerPrintMaskDesignerResult | null>;
@@ -1,5 +1,5 @@
1
- import { createFileViewerTranslator } from "../i18n/messages.js";
2
- import { normalizeFileViewerPrintMaskRegion, normalizeFileViewerPrintStamp, } from "./printMask.js";
1
+ import { createFileViewerTranslator } from '../i18n/messages.js';
2
+ import { normalizeFileViewerPrintMaskRegion, normalizeFileViewerPrintStamp, } from './printMask.js';
3
3
  const DESIGNER_STYLE = `
4
4
  .fv-print-mask-layer{position:absolute;inset:0;z-index:2147483000;pointer-events:none;}
5
5
  .fv-print-mask-canvas{position:absolute;inset:0;z-index:2147483000;pointer-events:none;cursor:default;}
@@ -74,6 +74,10 @@ const readStampFileAsDataUrl = (file, windowRef) => new Promise((resolve, reject
74
74
  reader.addEventListener('error', () => reject(reader.error || new Error('Failed to read print stamp image')));
75
75
  reader.readAsDataURL(file);
76
76
  });
77
+ /**
78
+ * Opens a page-aware print-mask designer. Browsing remains the default mode;
79
+ * drawing is armed for the currently visible page only and disarms after one block.
80
+ */
77
81
  export const openFileViewerPrintMaskDesigner = (options) => {
78
82
  const root = options.root;
79
83
  const documentRef = root.ownerDocument;
@@ -101,6 +105,8 @@ export const openFileViewerPrintMaskDesigner = (options) => {
101
105
  }
102
106
  return previousPosition;
103
107
  };
108
+ // The toolbar layer is positioned against the viewer root even when page
109
+ // canvases live on child page elements.
104
110
  const previousRootPosition = ensureOverlayContainingBlock(root);
105
111
  return new Promise(resolve => {
106
112
  let settled = false;
@@ -310,6 +316,7 @@ export const openFileViewerPrintMaskDesigner = (options) => {
310
316
  (_a = stampElement.releasePointerCapture) === null || _a === void 0 ? void 0 : _a.call(stampElement, interaction.pointerId);
311
317
  }
312
318
  catch {
319
+ // Pointer capture may already be released by the browser.
313
320
  }
314
321
  interaction = null;
315
322
  };
@@ -364,6 +371,7 @@ export const openFileViewerPrintMaskDesigner = (options) => {
364
371
  surface.canvas.releasePointerCapture(drawing.pointerId);
365
372
  }
366
373
  catch {
374
+ // Pointer capture may already be released by the browser.
367
375
  }
368
376
  drawing = null;
369
377
  disarm();
@@ -427,6 +435,7 @@ export const openFileViewerPrintMaskDesigner = (options) => {
427
435
  }
428
436
  }
429
437
  catch {
438
+ // Unsupported or unreadable images are ignored; the document stays untouched.
430
439
  }
431
440
  });
432
441
  clearButton.addEventListener('click', () => {
@@ -1,2 +1,8 @@
1
- import type { FileViewerPrintMaskDesignerResult, OpenFileViewerPrintMaskDesignerOptions } from "./printMaskDesigner.js";
1
+ import type { FileViewerPrintMaskDesignerResult, OpenFileViewerPrintMaskDesignerOptions } from './printMaskDesigner.js';
2
+ /**
3
+ * Lazily opens the print-mask designer.
4
+ * Kept as a dynamic import so the designer stays out of the main core graph,
5
+ * while remaining reachable through the primary `@file-viewer/core` entry
6
+ * (no consumer alias / subpath setup required).
7
+ */
2
8
  export declare const openFileViewerPrintMaskDesignerAsync: (options: OpenFileViewerPrintMaskDesignerOptions) => Promise<FileViewerPrintMaskDesignerResult | null>;
@@ -1,4 +1,10 @@
1
+ /**
2
+ * Lazily opens the print-mask designer.
3
+ * Kept as a dynamic import so the designer stays out of the main core graph,
4
+ * while remaining reachable through the primary `@file-viewer/core` entry
5
+ * (no consumer alias / subpath setup required).
6
+ */
1
7
  export const openFileViewerPrintMaskDesignerAsync = async (options) => {
2
- const { openFileViewerPrintMaskDesigner } = await import("../print-mask.js");
8
+ const { openFileViewerPrintMaskDesigner } = await import('../print-mask.js');
3
9
  return openFileViewerPrintMaskDesigner(options);
4
10
  };
@@ -1,4 +1,4 @@
1
- import type { FileViewerWatermarkOptions } from "../contracts/types.js";
1
+ import type { FileViewerWatermarkOptions } from '../contracts/types.js';
2
2
  export type FileViewerWatermarkStyle = Record<string, string> & {
3
3
  backgroundImage: string;
4
4
  };