@file-viewer/core 2.2.4 → 2.2.5

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.
@@ -22,13 +22,18 @@ const imageStyle = `
22
22
  .image-viewer{position:relative;width:100%;height:100%;overflow:auto;background:var(--file-viewer-render-surface-background,#eef1f4);box-sizing:border-box}
23
23
  .image-stage{min-width:100%;min-height:100%;display:flex;align-items:center;justify-content:center;padding:24px;box-sizing:border-box}
24
24
  .image-stage img{display:block;width:auto;max-width:none;margin:0 auto;border:0;box-shadow:0 18px 48px rgba(15,23,42,.16);background:#fff;cursor:zoom-in}
25
- .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}
26
- .image-lightbox[hidden]{display:none}
27
- .image-lightbox img{display:block;max-width:100%;max-height:100%;object-fit:contain;background:#fff;box-shadow:0 30px 80px rgba(0,0,0,.4);cursor:zoom-out}
28
- .image-lightbox button{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 12px 28px rgba(0,0,0,.18)}
25
+ .image-stage img:focus-visible{outline:3px solid #2563eb;outline-offset:4px}
26
+ .image-lightbox{position:absolute;inset:0;z-index:40;display:flex;align-items:center;justify-content:center;padding:40px;background:rgba(15,23,42,.9);box-sizing:border-box;opacity:0;visibility:hidden;pointer-events:none;transition:opacity .18s ease,visibility 0s linear .18s}
27
+ .image-lightbox[data-open='true']{opacity:1;visibility:visible;pointer-events:auto;transition-delay:0s}
28
+ .image-lightbox img{display:block;max-width:100%;max-height:100%;object-fit:contain;background:#fff;box-shadow:0 30px 80px rgba(0,0,0,.4);cursor:default;transform:scale(.985);transition:transform .18s ease}
29
+ .image-lightbox[data-open='true'] img{transform:scale(1)}
30
+ .image-lightbox button{position:absolute;top:16px;right:16px;display:grid;width:40px;height:40px;place-items:center;padding:0;border:1px solid rgba(255,255,255,.7);border-radius:999px;background:rgba(255,255,255,.96);color:#172033;font:400 27px/1 Arial,sans-serif;cursor:pointer;box-shadow:0 12px 28px rgba(0,0,0,.24);transition:background-color .14s ease,transform .14s ease}
31
+ .image-lightbox button:hover{background:#fff;transform:scale(1.04)}
32
+ .image-lightbox button:focus-visible{outline:3px solid #60a5fa;outline-offset:2px}
29
33
  [data-viewer-theme='dark'] .image-viewer{background:var(--file-viewer-render-surface-background,#101820)}
30
34
  @media (prefers-color-scheme:dark){[data-viewer-theme='system'] .image-viewer{background:var(--file-viewer-render-surface-background,#101820)}}
31
35
  @media (max-width:767px){.image-stage{padding:12px}.image-lightbox{padding:16px}.image-lightbox button{top:12px;right:12px}}
36
+ @media (prefers-reduced-motion:reduce){.image-lightbox,.image-lightbox img,.image-lightbox button{transition:none}}
32
37
  `;
33
38
  const createStyle = (documentRef) => {
34
39
  const style = documentRef.createElement('style');
@@ -68,35 +73,55 @@ const roundImageScale = (value) => {
68
73
  const createLightbox = (documentRef, src, t) => {
69
74
  const lightbox = documentRef.createElement('div');
70
75
  lightbox.className = 'image-lightbox';
71
- lightbox.hidden = true;
76
+ lightbox.dataset.open = 'false';
72
77
  lightbox.setAttribute('role', 'dialog');
73
78
  lightbox.setAttribute('aria-modal', 'true');
79
+ lightbox.setAttribute('aria-hidden', 'true');
74
80
  const image = documentRef.createElement('img');
75
81
  image.alt = t('image.lightbox.alt');
76
82
  image.src = src;
77
83
  const closeButton = documentRef.createElement('button');
78
84
  closeButton.type = 'button';
79
85
  closeButton.setAttribute('aria-label', t('image.lightbox.close'));
80
- closeButton.textContent = 'x';
86
+ closeButton.textContent = '×';
87
+ let previousFocus = null;
81
88
  const close = () => {
82
- lightbox.hidden = true;
89
+ if (lightbox.dataset.open !== 'true')
90
+ return;
91
+ lightbox.dataset.open = 'false';
92
+ lightbox.setAttribute('aria-hidden', 'true');
93
+ if (previousFocus === null || previousFocus === void 0 ? void 0 : previousFocus.isConnected) {
94
+ previousFocus.focus({ preventScroll: true });
95
+ }
96
+ previousFocus = null;
97
+ };
98
+ const onKeyDown = (event) => {
99
+ if (event.key === 'Escape' && lightbox.dataset.open === 'true') {
100
+ event.preventDefault();
101
+ close();
102
+ }
83
103
  };
84
104
  closeButton.addEventListener('click', close);
85
- image.addEventListener('click', close);
86
105
  lightbox.addEventListener('click', event => {
87
106
  if (event.target === lightbox) {
88
107
  close();
89
108
  }
90
109
  });
110
+ documentRef.addEventListener('keydown', onKeyDown);
91
111
  lightbox.append(image, closeButton);
92
112
  return {
93
113
  element: lightbox,
94
- open() {
95
- lightbox.hidden = false;
114
+ open(invoker) {
115
+ previousFocus =
116
+ invoker ||
117
+ (documentRef.activeElement instanceof HTMLElement ? documentRef.activeElement : null);
118
+ lightbox.dataset.open = 'true';
119
+ lightbox.setAttribute('aria-hidden', 'false');
120
+ closeButton.focus({ preventScroll: true });
96
121
  },
97
122
  destroy() {
98
123
  closeButton.removeEventListener('click', close);
99
- image.removeEventListener('click', close);
124
+ documentRef.removeEventListener('keydown', onKeyDown);
100
125
  lightbox.remove();
101
126
  },
102
127
  };
@@ -122,11 +147,21 @@ export default async function renderImage(buffer, target, type, context) {
122
147
  const image = documentRef.createElement('img');
123
148
  image.alt = t('image.alt');
124
149
  image.src = src;
150
+ image.tabIndex = 0;
151
+ image.setAttribute('role', 'button');
152
+ image.setAttribute('aria-haspopup', 'dialog');
125
153
  stage.append(image);
126
154
  root.append(stage);
127
155
  const lightbox = createLightbox(documentRef, src, t);
128
- const openLightbox = () => lightbox.open();
156
+ const openLightbox = () => lightbox.open(image);
157
+ const openLightboxFromKeyboard = (event) => {
158
+ if (event.key === 'Enter' || event.key === ' ') {
159
+ event.preventDefault();
160
+ lightbox.open(image);
161
+ }
162
+ };
129
163
  image.addEventListener('click', openLightbox);
164
+ image.addEventListener('keydown', openLightboxFromKeyboard);
130
165
  const getMinScale = () => Math.min(0.1, fitScale || 0.1);
131
166
  const clampScale = (value) => {
132
167
  const minScale = getMinScale();
@@ -250,6 +285,7 @@ export default async function renderImage(buffer, target, type, context) {
250
285
  resizeObserver.disconnect();
251
286
  image.removeEventListener('load', updateViewportSize);
252
287
  image.removeEventListener('click', openLightbox);
288
+ image.removeEventListener('keydown', openLightboxFromKeyboard);
253
289
  lightbox.destroy();
254
290
  target.replaceChildren();
255
291
  },
@@ -0,0 +1,36 @@
1
+ import type { FileViewerFileRef, FileViewerSource } from '../contracts/types';
2
+ export type FileViewerPrecheckStatus = 'ready' | 'invalid' | 'unsupported';
3
+ export type FileViewerPrecheckReason = 'content-valid' | 'content-not-inspected' | 'content-inconclusive' | 'empty-structured-file' | 'signature-mismatch' | 'invalid-package' | 'missing-package-part' | 'unsupported-extension';
4
+ export interface FileViewerPrecheckOptions {
5
+ /** Filename used when a Blob or ArrayBuffer has no name. */
6
+ filename?: string;
7
+ /** Explicit extension, with or without a leading dot. */
8
+ type?: string;
9
+ /** Restricts the result to the renderers installed by the host application. */
10
+ supportedExtensions?: Iterable<string>;
11
+ /** Maximum ZIP central-directory bytes read from a Blob. Defaults to 8 MiB. */
12
+ maxPackageMetadataBytes?: number;
13
+ }
14
+ export interface FileViewerPrecheckResult {
15
+ filename: string;
16
+ extension: string;
17
+ rendererId: string | null;
18
+ supported: boolean;
19
+ inspected: boolean;
20
+ /** `null` means the extension is supported but no structural validator exists. */
21
+ valid: boolean | null;
22
+ previewable: boolean;
23
+ status: FileViewerPrecheckStatus;
24
+ reason: FileViewerPrecheckReason;
25
+ missingParts: string[];
26
+ }
27
+ type FileViewerPrecheckInput = FileViewerSource | FileViewerFileRef;
28
+ /**
29
+ * Performs a cheap, renderer-free capability and structure check.
30
+ *
31
+ * This intentionally does not promise rendering fidelity. A `ready` result
32
+ * means the extension is available and any known container/signature checks
33
+ * passed; the real renderer remains the final authority for malformed content.
34
+ */
35
+ export declare const precheckFileViewerSource: (input: FileViewerPrecheckInput, options?: FileViewerPrecheckOptions) => Promise<FileViewerPrecheckResult>;
36
+ export {};
@@ -0,0 +1,250 @@
1
+ import { DEFAULT_RENDERER_DEFINITIONS, DEFAULT_SUPPORTED_EXTENSIONS } from '../registry/formats.js';
2
+ import { getExtension, normalizeFileExtension, normalizeFilename, normalizeSource, } from './index.js';
3
+ const DEFAULT_MAX_PACKAGE_METADATA_BYTES = 8 * 1024 * 1024;
4
+ const ZIP_LOCAL_SIGNATURE = 0x04034b50;
5
+ const ZIP_CENTRAL_SIGNATURE = 0x02014b50;
6
+ const ZIP_END_SIGNATURE = 0x06054b50;
7
+ const ZIP64_SENTINEL = 0xffffffff;
8
+ const OLE_SIGNATURE = [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1];
9
+ const OPEN_XML_REQUIRED_PARTS = {
10
+ docx: ['[content_types].xml', 'word/document.xml'],
11
+ docm: ['[content_types].xml', 'word/document.xml'],
12
+ dotx: ['[content_types].xml', 'word/document.xml'],
13
+ dotm: ['[content_types].xml', 'word/document.xml'],
14
+ xlsx: ['[content_types].xml', 'xl/workbook.xml'],
15
+ xltx: ['[content_types].xml', 'xl/workbook.xml'],
16
+ xlsm: ['[content_types].xml', 'xl/workbook.xml'],
17
+ xltm: ['[content_types].xml', 'xl/workbook.xml'],
18
+ xlsb: ['[content_types].xml', 'xl/workbook.bin'],
19
+ pptx: ['[content_types].xml', 'ppt/presentation.xml'],
20
+ pptm: ['[content_types].xml', 'ppt/presentation.xml'],
21
+ potx: ['[content_types].xml', 'ppt/presentation.xml'],
22
+ potm: ['[content_types].xml', 'ppt/presentation.xml'],
23
+ ppsx: ['[content_types].xml', 'ppt/presentation.xml'],
24
+ ppsm: ['[content_types].xml', 'ppt/presentation.xml'],
25
+ odt: ['content.xml'],
26
+ ods: ['content.xml'],
27
+ odp: ['content.xml'],
28
+ ofd: ['ofd.xml'],
29
+ numbers: ['index/document.iwa'],
30
+ epub: ['meta-inf/container.xml'],
31
+ xps: ['[content_types].xml'],
32
+ dwfx: ['[content_types].xml'],
33
+ };
34
+ const ZIP_EXTENSIONS = new Set([
35
+ ...Object.keys(OPEN_XML_REQUIRED_PARTS),
36
+ 'zip', 'zipx', 'jar', 'war', 'ear', 'apk', 'cbz',
37
+ ]);
38
+ const OLE_EXTENSIONS = new Set(['doc', 'dot', 'xls', 'xlt', 'ppt', 'msg']);
39
+ const TEXT_DECODER = new TextDecoder('utf-8');
40
+ const isArrayBuffer = (value) => value instanceof ArrayBuffer;
41
+ const isBlob = (value) => (typeof Blob !== 'undefined' && value instanceof Blob);
42
+ const toSource = (input, options) => {
43
+ if (isArrayBuffer(input)) {
44
+ return { buffer: input, filename: options.filename, type: options.type };
45
+ }
46
+ if (isBlob(input)) {
47
+ return { file: input, filename: options.filename, type: options.type };
48
+ }
49
+ return {
50
+ ...input,
51
+ filename: options.filename || input.filename,
52
+ type: options.type || input.type,
53
+ };
54
+ };
55
+ const startsWithBytes = (bytes, expected) => (expected.every((value, index) => bytes[index] === value));
56
+ const findEndOfCentralDirectory = (bytes) => {
57
+ for (let offset = bytes.byteLength - 22; offset >= 0; offset -= 1) {
58
+ if (bytes[offset] === 0x50 &&
59
+ bytes[offset + 1] === 0x4b &&
60
+ bytes[offset + 2] === 0x05 &&
61
+ bytes[offset + 3] === 0x06) {
62
+ return offset;
63
+ }
64
+ }
65
+ return -1;
66
+ };
67
+ const collectCentralDirectoryEntries = (bytes) => {
68
+ const entries = new Set();
69
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
70
+ let offset = 0;
71
+ while (offset + 46 <= bytes.byteLength) {
72
+ if (view.getUint32(offset, true) !== ZIP_CENTRAL_SIGNATURE) {
73
+ break;
74
+ }
75
+ const filenameLength = view.getUint16(offset + 28, true);
76
+ const extraLength = view.getUint16(offset + 30, true);
77
+ const commentLength = view.getUint16(offset + 32, true);
78
+ const end = offset + 46 + filenameLength;
79
+ if (end > bytes.byteLength) {
80
+ return { entries, complete: false };
81
+ }
82
+ entries.add(TEXT_DECODER.decode(bytes.subarray(offset + 46, end)).replace(/^\/+/, '').toLowerCase());
83
+ offset = end + extraLength + commentLength;
84
+ }
85
+ return { entries, complete: offset === bytes.byteLength };
86
+ };
87
+ const inspectZipBuffer = (buffer) => {
88
+ const bytes = new Uint8Array(buffer);
89
+ if (bytes.byteLength < 22) {
90
+ return { signatureValid: false, complete: true, entries: new Set() };
91
+ }
92
+ const view = new DataView(buffer);
93
+ const firstSignature = view.getUint32(0, true);
94
+ if (firstSignature !== ZIP_LOCAL_SIGNATURE && firstSignature !== ZIP_END_SIGNATURE) {
95
+ return { signatureValid: false, complete: true, entries: new Set() };
96
+ }
97
+ const endOffset = findEndOfCentralDirectory(bytes);
98
+ if (endOffset < 0) {
99
+ return { signatureValid: true, complete: false, entries: new Set() };
100
+ }
101
+ const centralSize = view.getUint32(endOffset + 12, true);
102
+ const centralOffset = view.getUint32(endOffset + 16, true);
103
+ if (centralSize === ZIP64_SENTINEL || centralOffset === ZIP64_SENTINEL) {
104
+ return { signatureValid: true, complete: false, entries: new Set() };
105
+ }
106
+ if (centralOffset + centralSize > bytes.byteLength) {
107
+ return { signatureValid: true, complete: false, entries: new Set() };
108
+ }
109
+ const result = collectCentralDirectoryEntries(bytes.subarray(centralOffset, centralOffset + centralSize));
110
+ return { signatureValid: true, complete: result.complete, entries: result.entries };
111
+ };
112
+ const inspectZipBlob = async (blob, maxPackageMetadataBytes) => {
113
+ if (blob.size < 22) {
114
+ return { signatureValid: false, complete: true, entries: new Set() };
115
+ }
116
+ const prefix = new Uint8Array(await blob.slice(0, 4).arrayBuffer());
117
+ const prefixView = new DataView(prefix.buffer, prefix.byteOffset, prefix.byteLength);
118
+ const firstSignature = prefixView.getUint32(0, true);
119
+ if (firstSignature !== ZIP_LOCAL_SIGNATURE && firstSignature !== ZIP_END_SIGNATURE) {
120
+ return { signatureValid: false, complete: true, entries: new Set() };
121
+ }
122
+ const tailStart = Math.max(0, blob.size - 65557);
123
+ const tail = new Uint8Array(await blob.slice(tailStart).arrayBuffer());
124
+ const endOffset = findEndOfCentralDirectory(tail);
125
+ if (endOffset < 0) {
126
+ return { signatureValid: true, complete: false, entries: new Set() };
127
+ }
128
+ const tailView = new DataView(tail.buffer, tail.byteOffset, tail.byteLength);
129
+ const centralSize = tailView.getUint32(endOffset + 12, true);
130
+ const centralOffset = tailView.getUint32(endOffset + 16, true);
131
+ if (centralSize === ZIP64_SENTINEL ||
132
+ centralOffset === ZIP64_SENTINEL ||
133
+ centralSize > maxPackageMetadataBytes ||
134
+ centralOffset + centralSize > blob.size) {
135
+ return { signatureValid: true, complete: false, entries: new Set() };
136
+ }
137
+ const central = new Uint8Array(await blob.slice(centralOffset, centralOffset + centralSize).arrayBuffer());
138
+ const result = collectCentralDirectoryEntries(central);
139
+ return { signatureValid: true, complete: result.complete, entries: result.entries };
140
+ };
141
+ const inspectZip = async (source, maxPackageMetadataBytes) => {
142
+ if (source.buffer) {
143
+ return inspectZipBuffer(source.buffer);
144
+ }
145
+ if (source.file) {
146
+ return inspectZipBlob(source.file, maxPackageMetadataBytes);
147
+ }
148
+ return null;
149
+ };
150
+ const readPrefix = async (source, byteLength = 1024) => {
151
+ if (source.buffer) {
152
+ return new Uint8Array(source.buffer, 0, Math.min(source.buffer.byteLength, byteLength));
153
+ }
154
+ if (source.file) {
155
+ return new Uint8Array(await source.file.slice(0, byteLength).arrayBuffer());
156
+ }
157
+ return null;
158
+ };
159
+ const inspectStructuredContent = async (source, extension, maxPackageMetadataBytes) => {
160
+ var _a, _b, _c;
161
+ const size = (_b = (_a = source.buffer) === null || _a === void 0 ? void 0 : _a.byteLength) !== null && _b !== void 0 ? _b : (_c = source.file) === null || _c === void 0 ? void 0 : _c.size;
162
+ if (size === 0 && (ZIP_EXTENSIONS.has(extension) || OLE_EXTENSIONS.has(extension) || extension === 'pdf')) {
163
+ return { inspected: true, valid: false, reason: 'empty-structured-file' };
164
+ }
165
+ if (ZIP_EXTENSIONS.has(extension)) {
166
+ const zip = await inspectZip(source, maxPackageMetadataBytes);
167
+ if (!zip) {
168
+ return { inspected: false, valid: null, reason: 'content-not-inspected' };
169
+ }
170
+ if (!zip.signatureValid) {
171
+ return { inspected: true, valid: false, reason: 'signature-mismatch' };
172
+ }
173
+ const required = OPEN_XML_REQUIRED_PARTS[extension] || [];
174
+ if (!zip.complete) {
175
+ return { inspected: true, valid: null, reason: 'content-inconclusive' };
176
+ }
177
+ const missingParts = required.filter(part => !zip.entries.has(part));
178
+ if (missingParts.length) {
179
+ return { inspected: true, valid: false, reason: 'missing-package-part', missingParts };
180
+ }
181
+ return { inspected: true, valid: true, reason: 'content-valid' };
182
+ }
183
+ const prefix = await readPrefix(source);
184
+ if (!prefix) {
185
+ return { inspected: false, valid: null, reason: 'content-not-inspected' };
186
+ }
187
+ if (OLE_EXTENSIONS.has(extension)) {
188
+ return startsWithBytes(prefix, OLE_SIGNATURE)
189
+ ? { inspected: true, valid: true, reason: 'content-valid' }
190
+ : { inspected: true, valid: false, reason: 'signature-mismatch' };
191
+ }
192
+ if (extension === 'pdf') {
193
+ const header = TEXT_DECODER.decode(prefix);
194
+ return /%PDF-\d\.\d/.test(header)
195
+ ? { inspected: true, valid: true, reason: 'content-valid' }
196
+ : { inspected: true, valid: false, reason: 'signature-mismatch' };
197
+ }
198
+ if (extension === 'rtf') {
199
+ const header = TEXT_DECODER.decode(prefix);
200
+ return /^\s*\{\\rtf\d/.test(header)
201
+ ? { inspected: true, valid: true, reason: 'content-valid' }
202
+ : { inspected: true, valid: false, reason: 'signature-mismatch' };
203
+ }
204
+ return { inspected: false, valid: null, reason: 'content-not-inspected' };
205
+ };
206
+ /**
207
+ * Performs a cheap, renderer-free capability and structure check.
208
+ *
209
+ * This intentionally does not promise rendering fidelity. A `ready` result
210
+ * means the extension is available and any known container/signature checks
211
+ * passed; the real renderer remains the final authority for malformed content.
212
+ */
213
+ export const precheckFileViewerSource = async (input, options = {}) => {
214
+ var _a;
215
+ const source = toSource(input, options);
216
+ const normalized = normalizeSource(source);
217
+ const extension = normalizeFileExtension(options.type || normalized.extension || getExtension(options.filename || normalized.filename));
218
+ const filename = normalizeFilename(options.filename || normalized.filename);
219
+ const supportedExtensions = new Set(Array.from(options.supportedExtensions || DEFAULT_SUPPORTED_EXTENSIONS, normalizeFileExtension));
220
+ const supported = supportedExtensions.has(extension);
221
+ const rendererId = ((_a = DEFAULT_RENDERER_DEFINITIONS.find(definition => definition.extensions.some(candidate => normalizeFileExtension(candidate) === extension))) === null || _a === void 0 ? void 0 : _a.id) || null;
222
+ if (!supported) {
223
+ return {
224
+ filename,
225
+ extension,
226
+ rendererId,
227
+ supported: false,
228
+ inspected: false,
229
+ valid: null,
230
+ previewable: false,
231
+ status: 'unsupported',
232
+ reason: 'unsupported-extension',
233
+ missingParts: [],
234
+ };
235
+ }
236
+ const inspection = await inspectStructuredContent(source, extension, Math.max(64 * 1024, options.maxPackageMetadataBytes || DEFAULT_MAX_PACKAGE_METADATA_BYTES));
237
+ const valid = inspection.valid;
238
+ return {
239
+ filename,
240
+ extension,
241
+ rendererId,
242
+ supported: true,
243
+ inspected: inspection.inspected,
244
+ valid,
245
+ previewable: valid !== false,
246
+ status: valid === false ? 'invalid' : 'ready',
247
+ reason: inspection.reason,
248
+ missingParts: inspection.missingParts || [],
249
+ };
250
+ };
@@ -636,13 +636,14 @@ export const createViewer = (container, createOptions = {}) => {
636
636
  });
637
637
  },
638
638
  async printWithMask(printOptions = {}) {
639
- var _a, _b, _c, _d;
639
+ var _a, _b, _c, _d, _e;
640
640
  const result = await openFileViewerPrintMaskDesignerAsync({
641
641
  root: container,
642
642
  pages: (_b = (_a = renderSurfaceState.exportAdapter) === null || _a === void 0 ? void 0 : _a.getPrintMaskPages) === null || _b === void 0 ? void 0 : _b.call(_a),
643
643
  i18n: options,
644
644
  color: (_c = printOptions.mask) === null || _c === void 0 ? void 0 : _c.color,
645
645
  initialRegions: (_d = printOptions.mask) === null || _d === void 0 ? void 0 : _d.regions,
646
+ initialStamps: (_e = printOptions.mask) === null || _e === void 0 ? void 0 : _e.stamps,
646
647
  });
647
648
  if (!(result === null || result === void 0 ? void 0 : result.mask)) {
648
649
  return;
@@ -262,7 +262,7 @@ export const createFileViewerOperationActionHandlers = ({ getBuffer, getFile, ge
262
262
  }
263
263
  },
264
264
  async printWithMask(options = {}) {
265
- var _a, _b, _c, _d, _e, _f, _g;
265
+ var _a, _b, _c, _d, _e, _f, _g, _h;
266
266
  try {
267
267
  const source = getRenderedSource();
268
268
  if (!source) {
@@ -276,6 +276,7 @@ export const createFileViewerOperationActionHandlers = ({ getBuffer, getFile, ge
276
276
  i18n: resolveI18n(),
277
277
  color: (_c = options.mask) === null || _c === void 0 ? void 0 : _c.color,
278
278
  initialRegions: (_d = options.mask) === null || _d === void 0 ? void 0 : _d.regions,
279
+ initialStamps: (_e = options.mask) === null || _e === void 0 ? void 0 : _e.stamps,
279
280
  });
280
281
  if (!(result === null || result === void 0 ? void 0 : result.mask)) {
281
282
  return undefined;
@@ -283,9 +284,9 @@ export const createFileViewerOperationActionHandlers = ({ getBuffer, getFile, ge
283
284
  return await executeFileViewerPrintOperation({
284
285
  ...getRenderedOperationInput(),
285
286
  ...options,
286
- watermarkInlineStyle: (_f = (_e = options.watermarkInlineStyle) !== null && _e !== void 0 ? _e : getWatermarkInlineStyle === null || getWatermarkInlineStyle === void 0 ? void 0 : getWatermarkInlineStyle()) !== null && _f !== void 0 ? _f : undefined,
287
+ watermarkInlineStyle: (_g = (_f = options.watermarkInlineStyle) !== null && _f !== void 0 ? _f : getWatermarkInlineStyle === null || getWatermarkInlineStyle === void 0 ? void 0 : getWatermarkInlineStyle()) !== null && _g !== void 0 ? _g : undefined,
287
288
  mask: result.mask,
288
- printAvailable: (_g = getPrintAvailable === null || getPrintAvailable === void 0 ? void 0 : getPrintAvailable()) !== null && _g !== void 0 ? _g : true,
289
+ printAvailable: (_h = getPrintAvailable === null || getPrintAvailable === void 0 ? void 0 : getPrintAvailable()) !== null && _h !== void 0 ? _h : true,
289
290
  });
290
291
  }
291
292
  catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@file-viewer/core",
3
- "version": "2.2.4",
3
+ "version": "2.2.5",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Framework-neutral modular TypeScript core for File Viewer renderer orchestration, lifecycle APIs, search, zoom, print, and export",