@file-viewer/core 3.0.2 → 3.0.3

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.
@@ -326,7 +326,9 @@ export const mountViewer = (container, initialOptions = {}, coreOptions = {}) =>
326
326
  // customer's ShadowRoot. Reusing the ancestor would let that component's
327
327
  // resets override the toolbar and would make our :host rules mutate the
328
328
  // customer's outer custom element.
329
- renderRoot = container.attachShadow({ mode: 'open', delegatesFocus: true });
329
+ // Delegated focus makes Safari taps on renderer controls focus the first
330
+ // toolbar input instead, triggering keyboard zoom and viewport scrolling.
331
+ renderRoot = container.attachShadow({ mode: 'open' });
330
332
  ownedViewerShadowRoots.set(container, renderRoot);
331
333
  }
332
334
  catch {
@@ -345,7 +347,7 @@ export const mountViewer = (container, initialOptions = {}, coreOptions = {}) =>
345
347
  existingHostShadowRoot.appendChild(mountBoundary);
346
348
  if (shouldUseShadowRoot && typeof mountBoundary.attachShadow === 'function') {
347
349
  try {
348
- renderRoot = mountBoundary.attachShadow({ mode: 'open', delegatesFocus: true });
350
+ renderRoot = mountBoundary.attachShadow({ mode: 'open' });
349
351
  }
350
352
  catch {
351
353
  renderRoot = mountBoundary;
@@ -3,7 +3,7 @@ export type FileViewerThemeMode = 'light' | 'dark' | 'system';
3
3
  export type FileViewerResolvedThemeMode = Exclude<FileViewerThemeMode, 'system'>;
4
4
  export type FileViewerLocale = 'auto' | 'zh-CN' | 'en-US' | 'ja-JP' | 'de-DE' | (string & {});
5
5
  export type FileViewerStyleIsolation = 'auto' | 'shadow' | 'scoped' | 'none';
6
- export type FileViewerMessageKey = 'toolbar.zoomGroup' | 'toolbar.zoomOut' | 'toolbar.zoomIn' | 'toolbar.zoomReset' | 'toolbar.download' | 'toolbar.downloadTitle' | 'toolbar.print' | 'toolbar.printTitle' | 'toolbar.printDirect' | 'toolbar.printMask' | 'toolbar.printMaskTitle' | 'toolbar.printMaskAdd' | 'toolbar.printMaskClear' | 'toolbar.printMaskCancel' | 'toolbar.printMaskConfirm' | 'toolbar.printMaskHint' | 'toolbar.printStampUpload' | 'toolbar.printStampRemove' | 'toolbar.printStampResize' | 'toolbar.exportHtml' | 'toolbar.exportHtmlTitle' | 'toolbar.search' | 'toolbar.searchPlaceholder' | 'toolbar.searchPrevious' | 'toolbar.searchNext' | 'toolbar.searchClear' | 'toolbar.theme' | 'toolbar.themeToLight' | 'toolbar.themeToDark' | 'state.ready.title' | 'state.ready.message' | 'state.empty.title' | 'state.empty.message' | 'state.unsupported.install.title' | 'state.unsupported.install.message' | 'state.unsupported.install.description' | 'state.unsupported.title' | 'state.unsupported.message' | 'state.unsupported.description' | 'state.error.title' | 'preview.downloading' | 'preview.streamingPdf' | 'preview.reading' | 'error.download' | 'error.print' | 'error.exportHtml' | 'error.noDownloadSource' | 'error.noExportContent' | 'error.printUnavailable' | 'error.printWindowBlocked' | 'error.remoteDownload' | 'error.localRead' | 'error.load' | 'error.stream' | 'error.beforeOperation' | 'error.unknown' | 'error.blobUnavailable' | 'error.sourceUnsupported' | 'error.fileReadArrayBuffer' | 'error.fileReadDataUrl' | 'error.fileReadText' | 'error.imageDataUrlRead' | 'operation.download' | 'operation.print' | 'operation.exportHtml' | 'operation.zoomIn' | 'operation.zoomOut' | 'operation.zoomReset' | 'pdf.toolbar.toggleNavigation' | 'pdf.toolbar.previousPage' | 'pdf.toolbar.nextPage' | 'pdf.toolbar.fitWidth' | 'pdf.toolbar.zoomOut' | 'pdf.toolbar.zoomIn' | 'pdf.toolbar.rotateLeft' | 'pdf.toolbar.rotateRight' | 'pdf.nav.typeLabel' | 'pdf.nav.pagesTab' | 'pdf.nav.outlineTab' | 'pdf.nav.pagesTitle' | 'pdf.nav.outlineTitle' | 'pdf.nav.pageCount' | 'pdf.nav.itemCount' | 'pdf.nav.pageLabel' | 'pdf.nav.outlineEmpty' | 'pdf.nav.outlineFallbackTitle' | 'pdf.thumbnail.alt' | 'pdf.state.loading' | 'pdf.error.browserWindow' | 'pdf.error.missingSource' | 'pdf.error.loadFailed' | 'pdf.error.notLoaded' | 'pdf.error.unloaded' | 'pdf.error.canvasUnavailable' | 'pdf.export.pageTitle' | 'spreadsheet.loading.kicker' | 'spreadsheet.loading.title' | 'spreadsheet.loading.hint' | 'spreadsheet.loading.streaming' | 'spreadsheet.tabs.ariaLabel' | 'spreadsheet.state.parsingWorkbook' | 'spreadsheet.state.preparingSheet' | 'spreadsheet.state.preparingSheetNamed' | 'spreadsheet.state.cachedRows' | 'spreadsheet.state.rows' | 'spreadsheet.state.rowsAndColumns' | 'spreadsheet.error.parseFailed' | 'spreadsheet.error.workerFailed' | 'word.error.invalidDocx' | 'word.error.missingOdfContent' | 'word.error.odfXmlParseFailed' | 'word.title.rtf' | 'word.title.openDocumentPresentation' | 'word.title.openDocumentText' | 'word.page.fallback' | 'word.page.empty' | 'word.body' | 'word.body.empty' | 'ofd.toolbar.pageNavigation' | 'ofd.toolbar.documentPages' | 'ofd.toolbar.previousPage' | 'ofd.toolbar.nextPage' | 'ofd.toolbar.pageStatus' | 'ofd.toolbar.noPages' | 'ofd.state.loading' | 'ofd.error.empty' | 'ofd.error.parseFailed' | 'presentation.state.loading' | 'presentation.error.title' | 'presentation.error.parseFailed' | 'presentation.ppt.state.loading' | 'presentation.ppt.error.title' | 'presentation.ppt.error.parseFailed' | 'presentation.ppt.error.assetHint' | 'presentation.slideshow.start' | 'presentation.slideshow.exit' | 'presentation.slideshow.hint' | 'archive.error.nestedUnsupported' | 'archive.loading.readingDirectory' | 'archive.loading.readingDirectoryHint' | 'archive.search.placeholder' | 'archive.sidebar.hide' | 'archive.sidebar.show' | 'archive.preview.title' | 'archive.preview.chooseFile' | 'archive.preview.downloadFile' | 'archive.error.title' | 'archive.stats.summary' | 'archive.warning.encrypted' | 'archive.password.title' | 'archive.password.description' | 'archive.password.placeholder' | 'archive.password.invalid' | 'archive.password.required' | 'archive.password.cancel' | 'archive.password.confirm' | 'archive.error.passwordRequired' | 'archive.error.encryptedRequiresWorker' | 'archive.empty.title' | 'archive.empty.message' | 'archive.loading.initializingCandidate' | 'archive.loading.initializingCandidateHint' | 'archive.error.candidateInitTimeout' | 'archive.error.encryptedCheckTimeout' | 'archive.loading.directoryReadyHint' | 'archive.error.candidateReadTimeout' | 'archive.loading.workerFallback' | 'archive.loading.workerFallbackHint' | 'archive.notice.workerFallback' | 'archive.error.tooLarge' | 'archive.loading.initializingWorker' | 'archive.loading.initializingWorkerHint' | 'archive.error.workerInitFailed' | 'archive.error.workerUnsupported' | 'archive.error.indexedDbUnavailable' | 'archive.error.entryTooLarge' | 'archive.loading.extracting' | 'archive.loading.rendering' | 'archive.loading.exporting' | 'media.audio.title' | 'media.audio.description' | 'media.audio.unsupported' | 'media.video.title' | 'media.video.unsupported' | 'media.video.hlsHint' | 'media.video.codecUnsupportedBadge' | 'media.video.codecUnsupportedTitle' | 'media.video.codecUnsupportedDescription' | 'media.video.codecUnsupportedAction' | 'media.video.softwareLoading' | 'media.video.softwareBadge' | 'media.video.play' | 'media.video.pause' | 'media.video.seek' | 'media.video.mute' | 'media.video.unmute' | 'media.video.fullscreen' | 'media.midi.title' | 'media.midi.loading' | 'media.midi.trackHeader' | 'media.midi.instrumentHeader' | 'media.midi.channelHeader' | 'media.midi.noteCountHeader' | 'media.midi.durationHeader' | 'media.midi.durationStat' | 'media.midi.trackStat' | 'media.midi.noteStat' | 'media.midi.parseFailed' | 'email.mbox.subject' | 'email.mbox.summary' | 'email.error.title' | 'email.meta.from' | 'email.meta.to' | 'email.meta.cc' | 'email.meta.date' | 'email.tabs.text' | 'email.tabs.headers' | 'email.attachments.title' | 'email.attachments.empty' | 'email.attachments.download' | 'email.attachments.opening' | 'email.attachments.nestedUnavailable' | 'email.loading.parsing' | 'data.font.sample' | 'data.error.fontFaceUnsupported' | 'data.title.font' | 'data.title.sqlite' | 'data.title.parquet' | 'data.title.avro' | 'data.title.wasm' | 'data.title.eps' | 'data.title.ai' | 'data.title.webarchive' | 'data.title.summary' | 'data.label.format' | 'data.label.size' | 'data.label.rendering' | 'data.label.objects' | 'data.label.sampleTable' | 'data.label.rows' | 'data.label.columns' | 'data.label.sampleRows' | 'data.label.imports' | 'data.label.exports' | 'data.label.magic' | 'data.label.note' | 'data.label.container' | 'data.value.schemaRead' | 'data.value.schemaUnread' | 'data.note.aiSummary' | 'data.note.postscriptSummary' | 'data.note.webarchive' | 'data.image.alt' | 'psd.title' | 'psd.action.fit' | 'psd.action.showAll' | 'psd.action.hideAll' | 'psd.layers.title' | 'psd.layers.redrawable' | 'psd.layers.empty' | 'psd.layers.hidden' | 'drawing.error.viewerLoadFailed' | 'drawing.error.excalidrawEmpty' | 'drawing.error.excalidrawTimeout' | 'drawing.error.drawioParseFailed' | 'drawing.error.drawioNoModel' | 'drawing.error.drawioNoElements' | 'drawing.error.viewerInitFailed' | 'drawing.error.drawioTimeout' | 'drawing.error.svgParseFailed' | 'drawing.error.plantumlRenderFailed' | 'drawing.title.excalidraw' | 'drawing.title.mermaid' | 'drawing.title.plantuml' | 'drawing.title.drawio' | 'drawing.toolbar.zoomOut' | 'drawing.toolbar.zoomIn' | 'drawing.toolbar.fit' | 'drawing.toolbar.fitWidth' | 'drawing.state.loading' | 'text.code.loadingHighlight' | 'text.code.formattedPreview' | 'text.code.showOriginal' | 'text.code.showFormatted' | 'text.code.indexingLargeFile' | 'text.code.virtualized' | 'text.code.firstSegment' | 'text.code.previousSegment' | 'text.code.nextSegment' | 'text.code.lastSegment' | 'ebook.toc' | 'ebook.reading' | 'ebook.itemCount' | 'epub.title' | 'epub.previousPage' | 'epub.nextPage' | 'epub.loading' | 'epub.chapterFallback' | 'epub.renderIncomplete' | 'umd.title' | 'umd.previousChapter' | 'umd.nextChapter' | 'umd.loading' | 'umd.emptyContent' | 'umd.chapterFallback' | 'umd.galleryFallback' | 'umd.warningBodyTooShort' | 'umd.error.unexpectedEnd' | 'umd.error.invalidFile' | 'typst.summaryRenderer' | 'typst.pageSummary.empty' | 'typst.pageSummary.ready' | 'typst.status.compiling' | 'typst.status.failed' | 'typst.status.rendered' | 'typst.loading.title' | 'typst.loading.hint' | 'typst.error.title' | 'typst.error.timeout' | 'typst.error.timeoutHint' | 'typst.error.assetHint' | 'typst.error.svgParseFailed' | 'typst.error.wasmLoadFailed' | 'xmind.toolbar.zoomOut' | 'xmind.toolbar.zoomIn' | 'xmind.toolbar.fit' | 'xmind.toolbar.fitTitle' | 'xmind.state.loading' | 'xmind.stats.nodes' | 'xmind.stats.depth' | 'xmind.stats.theme' | 'xmind.stats.template' | 'xmind.badge.paused' | 'xmind.badge.collapsed' | 'xmind.badge.floating' | 'xmind.badge.summary' | 'xmind.badge.callout' | 'xmind.imageResource' | 'xmind.error.unrecognized' | 'xmind.error.noCanvas' | 'cad.toolbar.fit' | 'cad.toolbar.zoomOut' | 'cad.toolbar.zoomIn' | 'cad.toolbar.colorSource' | 'cad.toolbar.monochrome' | 'cad.layers.title' | 'cad.layers.count' | 'cad.layers.merged' | 'cad.inspector.title' | 'cad.inspector.entities' | 'cad.inspector.blocks' | 'cad.inspector.pages' | 'cad.inspector.drawn' | 'cad.state.loadingViewer' | 'cad.state.parsing' | 'cad.error.parseFailed' | 'image.alt' | 'image.toolbar.rotation' | 'image.toolbar.rotateLeft' | 'image.toolbar.rotateRight' | 'image.lightbox.alt' | 'image.lightbox.close' | 'gitBundle.error.invalid' | 'gitBundle.error.missingPack' | 'gitBundle.notice.delta' | 'gitBundle.title.history' | 'gitBundle.title.fileTree' | 'gitBundle.file.choose' | 'gitBundle.file.noTree' | 'gitBundle.file.none' | 'gitBundle.history.empty' | 'gitBundle.toolbar.summary' | 'gitBundle.meta.bundle' | 'gitBundle.meta.refs' | 'gitBundle.meta.commits' | 'gitBundle.meta.objects' | 'gitBundle.meta.deltas' | 'gitBundle.meta.objectFormat' | 'gitBundle.meta.objectTypes' | 'geo.error.unrecognized' | 'geo.error.xmlParseFailed' | 'geo.error.unsupported' | 'geo.title' | 'geo.featureCount' | 'geo.bounds' | 'geo.geometryTypes' | 'geo.aria' | 'geo.loading' | 'geo.projection' | 'geo.engine' | 'geo.basemap' | 'geo.basemap.offline' | 'geo.basemap.custom' | 'geo.engine.maplibre' | 'geo.engine.svg' | 'geo.error.projection' | 'geo.action.fit' | 'model.toolbar.fit' | 'model.toolbar.rotate' | 'model.toolbar.wireframe' | 'model.toolbar.grid' | 'model.toolbar.axes' | 'model.state.loadingSummary' | 'model.state.loading' | 'model.state.loaded' | 'model.state.parseFailed' | 'model.summary.meshes' | 'model.summary.points' | 'model.error.daeEmpty' | 'model.error.unsupported' | 'model.error.parseFailed' | 'model.notice.signature' | 'loading.generic.label' | 'loading.generic.hint' | 'loading.word.label' | 'loading.word.hint' | 'loading.wordWorker.hint' | 'loading.sheet.label' | 'loading.sheet.hint' | 'loading.csv.label' | 'loading.csv.hint' | 'loading.presentation.label' | 'loading.presentation.hint' | 'loading.pdf.label' | 'loading.pdf.hint' | 'loading.ofd.label' | 'loading.ofd.hint' | 'loading.archive.label' | 'loading.archive.hint' | 'loading.email.label' | 'loading.email.hint' | 'loading.msg.hint' | 'loading.eda.label' | 'loading.eda.hint' | 'loading.cad.label' | 'loading.cad.hint' | 'loading.dwg.hint' | 'loading.dwf.hint' | 'loading.dwfx.hint' | 'loading.xps.hint' | 'loading.drawio.label' | 'loading.drawio.hint' | 'loading.excalidraw.label' | 'loading.excalidraw.hint' | 'loading.epub.label' | 'loading.epub.hint' | 'loading.umd.label' | 'loading.umd.hint' | 'loading.image.label' | 'loading.image.hint' | 'loading.video.label' | 'loading.video.hint' | 'loading.audio.label' | 'loading.audio.hint';
6
+ export type FileViewerMessageKey = 'toolbar.zoomGroup' | 'toolbar.zoomOut' | 'toolbar.zoomIn' | 'toolbar.zoomReset' | 'toolbar.download' | 'toolbar.downloadTitle' | 'toolbar.print' | 'toolbar.printTitle' | 'toolbar.printDirect' | 'toolbar.printMask' | 'toolbar.printMaskTitle' | 'toolbar.printMaskAdd' | 'toolbar.printMaskClear' | 'toolbar.printMaskCancel' | 'toolbar.printMaskConfirm' | 'toolbar.printMaskHint' | 'toolbar.printStampUpload' | 'toolbar.printStampRemove' | 'toolbar.printStampResize' | 'toolbar.exportHtml' | 'toolbar.exportHtmlTitle' | 'toolbar.search' | 'toolbar.searchPlaceholder' | 'toolbar.searchPrevious' | 'toolbar.searchNext' | 'toolbar.searchClear' | 'toolbar.searchClose' | 'toolbar.more' | 'toolbar.theme' | 'toolbar.themeToLight' | 'toolbar.themeToDark' | 'state.ready.title' | 'state.ready.message' | 'state.empty.title' | 'state.empty.message' | 'state.unsupported.install.title' | 'state.unsupported.install.message' | 'state.unsupported.install.description' | 'state.unsupported.title' | 'state.unsupported.message' | 'state.unsupported.description' | 'state.error.title' | 'preview.downloading' | 'preview.streamingPdf' | 'preview.reading' | 'error.download' | 'error.print' | 'error.exportHtml' | 'error.noDownloadSource' | 'error.noExportContent' | 'error.printUnavailable' | 'error.printWindowBlocked' | 'error.remoteDownload' | 'error.localRead' | 'error.load' | 'error.stream' | 'error.beforeOperation' | 'error.unknown' | 'error.blobUnavailable' | 'error.sourceUnsupported' | 'error.fileReadArrayBuffer' | 'error.fileReadDataUrl' | 'error.fileReadText' | 'error.imageDataUrlRead' | 'operation.download' | 'operation.print' | 'operation.exportHtml' | 'operation.zoomIn' | 'operation.zoomOut' | 'operation.zoomReset' | 'pdf.toolbar.toggleNavigation' | 'pdf.toolbar.previousPage' | 'pdf.toolbar.nextPage' | 'pdf.toolbar.fitWidth' | 'pdf.toolbar.zoomOut' | 'pdf.toolbar.zoomIn' | 'pdf.toolbar.rotateLeft' | 'pdf.toolbar.rotateRight' | 'pdf.nav.typeLabel' | 'pdf.nav.pagesTab' | 'pdf.nav.outlineTab' | 'pdf.nav.pagesTitle' | 'pdf.nav.outlineTitle' | 'pdf.nav.pageCount' | 'pdf.nav.itemCount' | 'pdf.nav.pageLabel' | 'pdf.nav.outlineEmpty' | 'pdf.nav.outlineFallbackTitle' | 'pdf.thumbnail.alt' | 'pdf.state.loading' | 'pdf.error.browserWindow' | 'pdf.error.missingSource' | 'pdf.error.loadFailed' | 'pdf.error.notLoaded' | 'pdf.error.unloaded' | 'pdf.error.canvasUnavailable' | 'pdf.export.pageTitle' | 'spreadsheet.loading.kicker' | 'spreadsheet.loading.title' | 'spreadsheet.loading.hint' | 'spreadsheet.loading.streaming' | 'spreadsheet.tabs.ariaLabel' | 'spreadsheet.state.parsingWorkbook' | 'spreadsheet.state.preparingSheet' | 'spreadsheet.state.preparingSheetNamed' | 'spreadsheet.state.cachedRows' | 'spreadsheet.state.rows' | 'spreadsheet.state.rowsAndColumns' | 'spreadsheet.error.parseFailed' | 'spreadsheet.error.workerFailed' | 'word.error.invalidDocx' | 'word.error.missingOdfContent' | 'word.error.odfXmlParseFailed' | 'word.title.rtf' | 'word.title.openDocumentPresentation' | 'word.title.openDocumentText' | 'word.page.fallback' | 'word.page.empty' | 'word.body' | 'word.body.empty' | 'ofd.toolbar.pageNavigation' | 'ofd.toolbar.documentPages' | 'ofd.toolbar.previousPage' | 'ofd.toolbar.nextPage' | 'ofd.toolbar.pageStatus' | 'ofd.toolbar.noPages' | 'ofd.state.loading' | 'ofd.error.empty' | 'ofd.error.parseFailed' | 'presentation.state.loading' | 'presentation.error.title' | 'presentation.error.parseFailed' | 'presentation.ppt.state.loading' | 'presentation.ppt.error.title' | 'presentation.ppt.error.parseFailed' | 'presentation.ppt.error.assetHint' | 'presentation.slideshow.start' | 'presentation.slideshow.exit' | 'presentation.slideshow.hint' | 'archive.error.nestedUnsupported' | 'archive.loading.readingDirectory' | 'archive.loading.readingDirectoryHint' | 'archive.search.placeholder' | 'archive.sidebar.hide' | 'archive.sidebar.show' | 'archive.preview.title' | 'archive.preview.chooseFile' | 'archive.preview.downloadFile' | 'archive.error.title' | 'archive.stats.summary' | 'archive.warning.encrypted' | 'archive.password.title' | 'archive.password.description' | 'archive.password.placeholder' | 'archive.password.invalid' | 'archive.password.required' | 'archive.password.cancel' | 'archive.password.confirm' | 'archive.error.passwordRequired' | 'archive.error.encryptedRequiresWorker' | 'archive.empty.title' | 'archive.empty.message' | 'archive.loading.initializingCandidate' | 'archive.loading.initializingCandidateHint' | 'archive.error.candidateInitTimeout' | 'archive.error.encryptedCheckTimeout' | 'archive.loading.directoryReadyHint' | 'archive.error.candidateReadTimeout' | 'archive.loading.workerFallback' | 'archive.loading.workerFallbackHint' | 'archive.notice.workerFallback' | 'archive.error.tooLarge' | 'archive.loading.initializingWorker' | 'archive.loading.initializingWorkerHint' | 'archive.error.workerInitFailed' | 'archive.error.workerUnsupported' | 'archive.error.indexedDbUnavailable' | 'archive.error.entryTooLarge' | 'archive.loading.extracting' | 'archive.loading.rendering' | 'archive.loading.exporting' | 'media.audio.title' | 'media.audio.description' | 'media.audio.unsupported' | 'media.video.title' | 'media.video.unsupported' | 'media.video.hlsHint' | 'media.video.codecUnsupportedBadge' | 'media.video.codecUnsupportedTitle' | 'media.video.codecUnsupportedDescription' | 'media.video.codecUnsupportedAction' | 'media.video.softwareLoading' | 'media.video.softwareBadge' | 'media.video.play' | 'media.video.pause' | 'media.video.seek' | 'media.video.mute' | 'media.video.unmute' | 'media.video.fullscreen' | 'media.midi.title' | 'media.midi.loading' | 'media.midi.trackHeader' | 'media.midi.instrumentHeader' | 'media.midi.channelHeader' | 'media.midi.noteCountHeader' | 'media.midi.durationHeader' | 'media.midi.durationStat' | 'media.midi.trackStat' | 'media.midi.noteStat' | 'media.midi.parseFailed' | 'email.mbox.subject' | 'email.mbox.summary' | 'email.error.title' | 'email.meta.from' | 'email.meta.to' | 'email.meta.cc' | 'email.meta.date' | 'email.tabs.text' | 'email.tabs.headers' | 'email.attachments.title' | 'email.attachments.empty' | 'email.attachments.download' | 'email.attachments.opening' | 'email.attachments.nestedUnavailable' | 'email.loading.parsing' | 'data.font.sample' | 'data.error.fontFaceUnsupported' | 'data.title.font' | 'data.title.sqlite' | 'data.title.parquet' | 'data.title.avro' | 'data.title.wasm' | 'data.title.eps' | 'data.title.ai' | 'data.title.webarchive' | 'data.title.summary' | 'data.label.format' | 'data.label.size' | 'data.label.rendering' | 'data.label.objects' | 'data.label.sampleTable' | 'data.label.rows' | 'data.label.columns' | 'data.label.sampleRows' | 'data.label.imports' | 'data.label.exports' | 'data.label.magic' | 'data.label.note' | 'data.label.container' | 'data.value.schemaRead' | 'data.value.schemaUnread' | 'data.note.aiSummary' | 'data.note.postscriptSummary' | 'data.note.webarchive' | 'data.image.alt' | 'psd.title' | 'psd.action.fit' | 'psd.action.showAll' | 'psd.action.hideAll' | 'psd.layers.title' | 'psd.layers.redrawable' | 'psd.layers.empty' | 'psd.layers.hidden' | 'drawing.error.viewerLoadFailed' | 'drawing.error.excalidrawEmpty' | 'drawing.error.excalidrawTimeout' | 'drawing.error.drawioParseFailed' | 'drawing.error.drawioNoModel' | 'drawing.error.drawioNoElements' | 'drawing.error.viewerInitFailed' | 'drawing.error.drawioTimeout' | 'drawing.error.svgParseFailed' | 'drawing.error.plantumlRenderFailed' | 'drawing.title.excalidraw' | 'drawing.title.mermaid' | 'drawing.title.plantuml' | 'drawing.title.drawio' | 'drawing.toolbar.zoomOut' | 'drawing.toolbar.zoomIn' | 'drawing.toolbar.fit' | 'drawing.toolbar.fitWidth' | 'drawing.state.loading' | 'text.code.loadingHighlight' | 'text.code.formattedPreview' | 'text.code.showOriginal' | 'text.html.preview' | 'text.html.source' | 'text.html.safePreview' | 'text.code.showFormatted' | 'text.code.indexingLargeFile' | 'text.code.virtualized' | 'text.code.firstSegment' | 'text.code.previousSegment' | 'text.code.nextSegment' | 'text.code.lastSegment' | 'ebook.toc' | 'ebook.reading' | 'ebook.itemCount' | 'epub.title' | 'epub.previousPage' | 'epub.nextPage' | 'epub.loading' | 'epub.chapterFallback' | 'epub.renderIncomplete' | 'umd.title' | 'umd.previousChapter' | 'umd.nextChapter' | 'umd.loading' | 'umd.emptyContent' | 'umd.chapterFallback' | 'umd.galleryFallback' | 'umd.warningBodyTooShort' | 'umd.error.unexpectedEnd' | 'umd.error.invalidFile' | 'typst.summaryRenderer' | 'typst.pageSummary.empty' | 'typst.pageSummary.ready' | 'typst.status.compiling' | 'typst.status.failed' | 'typst.status.rendered' | 'typst.loading.title' | 'typst.loading.hint' | 'typst.error.title' | 'typst.error.timeout' | 'typst.error.timeoutHint' | 'typst.error.assetHint' | 'typst.error.svgParseFailed' | 'typst.error.wasmLoadFailed' | 'xmind.toolbar.zoomOut' | 'xmind.toolbar.zoomIn' | 'xmind.toolbar.fit' | 'xmind.toolbar.fitTitle' | 'xmind.state.loading' | 'xmind.stats.nodes' | 'xmind.stats.depth' | 'xmind.stats.theme' | 'xmind.stats.template' | 'xmind.badge.paused' | 'xmind.badge.collapsed' | 'xmind.badge.floating' | 'xmind.badge.summary' | 'xmind.badge.callout' | 'xmind.imageResource' | 'xmind.error.unrecognized' | 'xmind.error.noCanvas' | 'cad.toolbar.fit' | 'cad.toolbar.zoomOut' | 'cad.toolbar.zoomIn' | 'cad.toolbar.colorSource' | 'cad.toolbar.monochrome' | 'cad.toolbar.exportImage' | 'cad.layers.title' | 'cad.layers.count' | 'cad.layers.merged' | 'cad.inspector.title' | 'cad.inspector.entities' | 'cad.inspector.blocks' | 'cad.inspector.pages' | 'cad.inspector.drawn' | 'cad.state.loadingViewer' | 'cad.state.parsing' | 'cad.error.parseFailed' | 'cad.error.exportFailed' | 'image.alt' | 'image.toolbar.rotation' | 'image.toolbar.rotateLeft' | 'image.toolbar.rotateRight' | 'image.lightbox.alt' | 'image.lightbox.close' | 'gitBundle.error.invalid' | 'gitBundle.error.missingPack' | 'gitBundle.notice.delta' | 'gitBundle.title.history' | 'gitBundle.title.fileTree' | 'gitBundle.file.choose' | 'gitBundle.file.noTree' | 'gitBundle.file.none' | 'gitBundle.history.empty' | 'gitBundle.toolbar.summary' | 'gitBundle.meta.bundle' | 'gitBundle.meta.refs' | 'gitBundle.meta.commits' | 'gitBundle.meta.objects' | 'gitBundle.meta.deltas' | 'gitBundle.meta.objectFormat' | 'gitBundle.meta.objectTypes' | 'geo.error.unrecognized' | 'geo.error.xmlParseFailed' | 'geo.error.unsupported' | 'geo.title' | 'geo.featureCount' | 'geo.bounds' | 'geo.geometryTypes' | 'geo.aria' | 'geo.loading' | 'geo.projection' | 'geo.engine' | 'geo.basemap' | 'geo.basemap.offline' | 'geo.basemap.custom' | 'geo.engine.maplibre' | 'geo.engine.svg' | 'geo.error.projection' | 'geo.action.fit' | 'model.toolbar.fit' | 'model.toolbar.rotate' | 'model.toolbar.wireframe' | 'model.toolbar.grid' | 'model.toolbar.axes' | 'model.state.loadingSummary' | 'model.state.loading' | 'model.state.loaded' | 'model.state.parseFailed' | 'model.summary.meshes' | 'model.summary.points' | 'model.error.daeEmpty' | 'model.error.unsupported' | 'model.error.parseFailed' | 'model.notice.signature' | 'loading.generic.label' | 'loading.generic.hint' | 'loading.word.label' | 'loading.word.hint' | 'loading.wordWorker.hint' | 'loading.sheet.label' | 'loading.sheet.hint' | 'loading.csv.label' | 'loading.csv.hint' | 'loading.presentation.label' | 'loading.presentation.hint' | 'loading.pdf.label' | 'loading.pdf.hint' | 'loading.ofd.label' | 'loading.ofd.hint' | 'loading.archive.label' | 'loading.archive.hint' | 'loading.email.label' | 'loading.email.hint' | 'loading.msg.hint' | 'loading.eda.label' | 'loading.eda.hint' | 'loading.cad.label' | 'loading.cad.hint' | 'loading.dwg.hint' | 'loading.dwf.hint' | 'loading.dwfx.hint' | 'loading.xps.hint' | 'loading.drawio.label' | 'loading.drawio.hint' | 'loading.excalidraw.label' | 'loading.excalidraw.hint' | 'loading.epub.label' | 'loading.epub.hint' | 'loading.umd.label' | 'loading.umd.hint' | 'loading.image.label' | 'loading.image.hint' | 'loading.video.label' | 'loading.video.hint' | 'loading.audio.label' | 'loading.audio.hint';
7
7
  export type FileViewerMessageParams = Record<string, string | number | boolean | null | undefined>;
8
8
  export type FileViewerMessageResolver = (key: FileViewerMessageKey, params: FileViewerMessageParams, locale: FileViewerLocale) => string | undefined;
9
9
  export type FileViewerMessages = Partial<Record<FileViewerMessageKey, string>> | FileViewerMessageResolver;
@@ -204,6 +204,8 @@ export interface FileViewerPdfBoundingBox {
204
204
  label?: string;
205
205
  }
206
206
  export interface FileViewerDocxOptions {
207
+ /** DOC/DOCX 默认保留插入和删除修订;final 显示定稿,original 显示修订前原稿。 */
208
+ reviewMode?: 'all' | 'final' | 'original';
207
209
  worker?: boolean;
208
210
  workerUrl?: string;
209
211
  workerJsZipUrl?: string;
@@ -371,6 +373,11 @@ export interface FileRenderContext {
371
373
  registerExportAdapter?: (adapter: FileRenderExportAdapter | null) => void;
372
374
  registerThumbnailAdapter?: (adapter: FileRenderThumbnailAdapter | null) => void;
373
375
  renderPurpose?: FileViewerRenderPurpose;
376
+ /** Derived-image download, guarded by the owning viewer's permissions, hooks and request version. */
377
+ requestSnapshotDownload?: (create: (watermark: FileViewerOptions['watermark']) => Promise<{
378
+ blob: Blob;
379
+ filename: string;
380
+ }>) => Promise<boolean>;
374
381
  onProgressiveRender?: () => void;
375
382
  renderNestedBuffer?: (buffer: ArrayBuffer, type: string, target: HTMLDivElement, context?: FileRenderContext) => Promise<FileViewerRenderedInstance | undefined>;
376
383
  }
@@ -740,10 +747,12 @@ export interface FileViewerCadOptions {
740
747
  renderer?: FileViewerCadRenderer;
741
748
  /** Initial CAD color policy. `monochrome` applies one plot color without mutating source data. */
742
749
  colorMode?: FileViewerCadColorMode;
743
- /** CSS color used by monochrome mode. Defaults to the CAD foreground color. */
750
+ /** CSS color used by monochrome mode. Defaults to black (#000000). */
744
751
  monochromeColor?: string;
745
752
  /** Shows the CAD toolbar color-mode toggle. Defaults to true. */
746
753
  showColorModeToggle?: boolean;
754
+ /** Show native PNG/JPEG snapshot downloads. Download/export permissions still apply. */
755
+ showImageExport?: boolean;
747
756
  preferDwgWasm?: boolean;
748
757
  includePaperSpace?: boolean;
749
758
  maxInsertDepth?: number;
@@ -761,6 +770,7 @@ export interface FileViewerCadOptions {
761
770
  fitPadding?: number;
762
771
  dwfPreferWebgl?: boolean;
763
772
  dwfPreferWasm?: boolean;
773
+ /** Explicit DWF background override; otherwise follows the current color mode. */
764
774
  dwfBackground?: string;
765
775
  dwfMaxDevicePixelRatio?: number;
766
776
  dwfMaxCanvasPixels?: number;
@@ -771,6 +781,7 @@ export interface FileViewerCadOptions {
771
781
  dwfMaxOverviewStrokeCssPx?: number;
772
782
  dwfMinTextCssPx?: number;
773
783
  dwfMinFilledAreaCssPx?: number;
784
+ /** Default background is dark for source colors and white for monochrome. Explicit colors are retained. */
774
785
  canvasOptions?: Record<string, unknown>;
775
786
  }
776
787
  export type FileViewerRendererMode = 'extend' | 'replace';
@@ -802,6 +813,8 @@ export interface FileViewerAiOptions {
802
813
  chunkOverlap?: number;
803
814
  }
804
815
  export interface FileViewerTextOptions {
816
+ /** Initial HTML/HTM view. Preview is static, sandboxed, and offline; defaults to preview. */
817
+ htmlView?: 'preview' | 'source';
805
818
  /**
806
819
  * Source encoding. Defaults to `auto`: BOM and UTF-16 structure first,
807
820
  * then strict UTF-8, with GB18030 (including GBK) as the final fallback.
@@ -29,6 +29,8 @@ export const DE_DE_MESSAGES = {
29
29
  "toolbar.searchPrevious": "Vorheriger Treffer",
30
30
  "toolbar.searchNext": "Nächster Treffer",
31
31
  "toolbar.searchClear": "Suche löschen",
32
+ "toolbar.searchClose": "Suche schließen",
33
+ "toolbar.more": "Weitere Aktionen",
32
34
  "toolbar.theme": "Thema",
33
35
  "toolbar.themeToLight": "Wechseln Sie in den Lichtmodus",
34
36
  "toolbar.themeToDark": "Wechseln Sie in den Dunkelmodus",
@@ -286,6 +288,9 @@ export const DE_DE_MESSAGES = {
286
288
  "text.code.loadingHighlight": "Syntaxhervorhebung wird geladen...",
287
289
  "text.code.formattedPreview": "Formatierte Vorschau",
288
290
  "text.code.showOriginal": "Originalquelltext anzeigen",
291
+ "text.html.preview": "Seitenvorschau",
292
+ "text.html.source": "HTML-Quelltext",
293
+ "text.html.safePreview": "Statische Vorschau. Skripte und externe Ressourcen sind gesperrt.",
289
294
  "text.code.showFormatted": "Formatierte Vorschau anzeigen",
290
295
  "text.code.indexingLargeFile": "Indizieren großer Dateien {progress}%",
291
296
  "text.code.virtualized": "Große Datei · virtuelles Scrollen · Hervorheben aus",
@@ -348,6 +353,7 @@ export const DE_DE_MESSAGES = {
348
353
  "cad.toolbar.zoomIn": "Vergrößern",
349
354
  "cad.toolbar.colorSource": "Originalfarben",
350
355
  "cad.toolbar.monochrome": "Monochrom",
356
+ "cad.toolbar.exportImage": "{format}-Bild herunterladen",
351
357
  "cad.layers.title": "Schichten",
352
358
  "cad.layers.count": "{count} Artikel",
353
359
  "cad.layers.merged": "{name} ({count} zusammengeführte Ebenen)",
@@ -359,6 +365,7 @@ export const DE_DE_MESSAGES = {
359
365
  "cad.state.loadingViewer": "CAD-Viewer wird geladen...",
360
366
  "cad.state.parsing": "CAD wird analysiert...",
361
367
  "cad.error.parseFailed": "Die CAD-Datei konnte nicht analysiert werden",
368
+ "cad.error.exportFailed": "Bildexport fehlgeschlagen: {message}",
362
369
  "image.alt": "Bild",
363
370
  "image.toolbar.rotation": "Bilddrehung",
364
371
  "image.toolbar.rotateLeft": "Bild nach links drehen",
@@ -30,6 +30,8 @@ export const JA_JP_MESSAGES = {
30
30
  'toolbar.searchPrevious': '前の一致',
31
31
  'toolbar.searchNext': '次の一致',
32
32
  'toolbar.searchClear': '検索をクリア',
33
+ 'toolbar.searchClose': '検索を閉じる',
34
+ 'toolbar.more': 'その他の操作',
33
35
  'toolbar.theme': 'テーマ',
34
36
  'toolbar.themeToLight': 'ライトモードに切り替え',
35
37
  'toolbar.themeToDark': 'ダークモードに切り替え',
@@ -287,6 +289,9 @@ export const JA_JP_MESSAGES = {
287
289
  'text.code.loadingHighlight': 'シンタックスハイライトを読み込んでいます...',
288
290
  'text.code.formattedPreview': '整形済みプレビュー',
289
291
  'text.code.showOriginal': '元のソースを表示',
292
+ 'text.html.preview': 'ページプレビュー',
293
+ 'text.html.source': 'HTML ソース',
294
+ 'text.html.safePreview': '静的プレビュー。スクリプトと外部リソースは無効です。',
290
295
  'text.code.showFormatted': '整形済みプレビューを表示',
291
296
  'text.code.indexingLargeFile': '大きなファイルを索引化しています {progress}%',
292
297
  'text.code.virtualized': '大きなファイル · 仮想スクロール · ハイライト無効',
@@ -349,6 +354,7 @@ export const JA_JP_MESSAGES = {
349
354
  'cad.toolbar.zoomIn': '拡大',
350
355
  'cad.toolbar.colorSource': '元の色',
351
356
  'cad.toolbar.monochrome': 'モノクロ',
357
+ 'cad.toolbar.exportImage': '{format} 画像をダウンロード',
352
358
  'cad.layers.title': 'レイヤー',
353
359
  'cad.layers.count': '{count} 件',
354
360
  'cad.layers.merged': '{name}(同名レイヤー {count} 件を統合)',
@@ -360,6 +366,7 @@ export const JA_JP_MESSAGES = {
360
366
  'cad.state.loadingViewer': 'CAD ビューアーを読み込んでいます...',
361
367
  'cad.state.parsing': 'CAD を解析しています...',
362
368
  'cad.error.parseFailed': 'CAD ファイルの解析に失敗しました',
369
+ 'cad.error.exportFailed': '画像を出力できませんでした: {message}',
363
370
  'image.alt': '画像',
364
371
  'image.toolbar.rotation': '画像の回転',
365
372
  'image.toolbar.rotateLeft': '画像を左に回転',
@@ -30,6 +30,8 @@ const ZH_CN_MESSAGES = {
30
30
  'toolbar.searchPrevious': '上一个匹配',
31
31
  'toolbar.searchNext': '下一个匹配',
32
32
  'toolbar.searchClear': '清除搜索',
33
+ 'toolbar.searchClose': '收起搜索',
34
+ 'toolbar.more': '更多操作',
33
35
  'toolbar.theme': '主题',
34
36
  'toolbar.themeToLight': '切换为浅色模式',
35
37
  'toolbar.themeToDark': '切换为深色模式',
@@ -287,6 +289,9 @@ const ZH_CN_MESSAGES = {
287
289
  'text.code.loadingHighlight': '正在加载高亮...',
288
290
  'text.code.formattedPreview': '格式化预览',
289
291
  'text.code.showOriginal': '查看原始源码',
292
+ 'text.html.preview': '页面预览',
293
+ 'text.html.source': 'HTML 源码',
294
+ 'text.html.safePreview': '静态预览,不执行脚本或加载外部资源',
290
295
  'text.code.showFormatted': '查看格式化预览',
291
296
  'text.code.indexingLargeFile': '正在建立大文件索引 {progress}%',
292
297
  'text.code.virtualized': '大文件 · 虚拟滚动 · 已关闭高亮',
@@ -349,6 +354,7 @@ const ZH_CN_MESSAGES = {
349
354
  'cad.toolbar.zoomIn': '放大',
350
355
  'cad.toolbar.colorSource': '彩色',
351
356
  'cad.toolbar.monochrome': '黑白',
357
+ 'cad.toolbar.exportImage': '下载 {format} 图片',
352
358
  'cad.layers.title': '图层',
353
359
  'cad.layers.count': '{count} 项',
354
360
  'cad.layers.merged': '{name}(已合并 {count} 个同名图层)',
@@ -360,6 +366,7 @@ const ZH_CN_MESSAGES = {
360
366
  'cad.state.loadingViewer': '正在加载 CAD 预览器...',
361
367
  'cad.state.parsing': '正在解析 CAD...',
362
368
  'cad.error.parseFailed': 'CAD 文件解析失败',
369
+ 'cad.error.exportFailed': '图片导出失败:{message}',
363
370
  'image.alt': '图片',
364
371
  'image.toolbar.rotation': '图片旋转',
365
372
  'image.toolbar.rotateLeft': '向左旋转图片',
@@ -486,6 +493,8 @@ const EN_US_MESSAGES = {
486
493
  'toolbar.searchPrevious': 'Previous match',
487
494
  'toolbar.searchNext': 'Next match',
488
495
  'toolbar.searchClear': 'Clear search',
496
+ 'toolbar.searchClose': 'Close search',
497
+ 'toolbar.more': 'More actions',
489
498
  'toolbar.theme': 'Theme',
490
499
  'toolbar.themeToLight': 'Switch to light mode',
491
500
  'toolbar.themeToDark': 'Switch to dark mode',
@@ -743,6 +752,9 @@ const EN_US_MESSAGES = {
743
752
  'text.code.loadingHighlight': 'Loading syntax highlighting...',
744
753
  'text.code.formattedPreview': 'Formatted preview',
745
754
  'text.code.showOriginal': 'Show original source',
755
+ 'text.html.preview': 'Page preview',
756
+ 'text.html.source': 'HTML source',
757
+ 'text.html.safePreview': 'Static preview. Scripts and external resources are blocked.',
746
758
  'text.code.showFormatted': 'Show formatted preview',
747
759
  'text.code.indexingLargeFile': 'Indexing large file {progress}%',
748
760
  'text.code.virtualized': 'Large file · virtual scrolling · highlighting off',
@@ -805,6 +817,7 @@ const EN_US_MESSAGES = {
805
817
  'cad.toolbar.zoomIn': 'Zoom in',
806
818
  'cad.toolbar.colorSource': 'Source colors',
807
819
  'cad.toolbar.monochrome': 'Monochrome',
820
+ 'cad.toolbar.exportImage': 'Download {format} image',
808
821
  'cad.layers.title': 'Layers',
809
822
  'cad.layers.count': '{count} items',
810
823
  'cad.layers.merged': '{name} ({count} merged layers)',
@@ -816,6 +829,7 @@ const EN_US_MESSAGES = {
816
829
  'cad.state.loadingViewer': 'Loading CAD viewer...',
817
830
  'cad.state.parsing': 'Parsing CAD...',
818
831
  'cad.error.parseFailed': 'Failed to parse CAD file',
832
+ 'cad.error.exportFailed': 'Image export failed: {message}',
819
833
  'image.alt': 'Image',
820
834
  'image.toolbar.rotation': 'Image rotation',
821
835
  'image.toolbar.rotateLeft': 'Rotate image left',
package/dist/index.d.ts CHANGED
@@ -16,6 +16,8 @@ export { cloneFileViewerViewState, createFileViewerViewStateChange, createFileVi
16
16
  export type { CreateFileViewerViewStateControllerOptions, FileViewerGenericViewStateProviderRegistration, FileViewerViewStateController, FileViewerViewStateControllerActionHandlers, RegisterFileViewerGenericViewStateProviderOptions, } from './features/document/viewState';
17
17
  export { DEFAULT_FILE_VIEWER_ANCHOR_EXCLUDE_SELECTOR, DEFAULT_FILE_VIEWER_ANCHOR_SELECTOR, DEFAULT_FILE_VIEWER_SCROLL_CONTAINER_CANDIDATE_SELECTOR, DEFAULT_FILE_VIEWER_SCROLL_CONTAINER_SELECTOR, DEFAULT_FILE_VIEWER_SCROLLABLE_OVERFLOW_VALUES, collectFileViewerDocumentAnchors, findFileViewerAnchorForElement, findFileViewerSearchProvider, findFileViewerViewStateProvider, findFileViewerZoomProvider, getCurrentFileViewerDocumentAnchor, getFileViewerScrollableRange, isFileViewerScrollableElement, registerFileViewerSearchProvider, registerFileViewerViewStateProvider, registerFileViewerZoomProvider, resolveFileViewerScrollContainer, scrollToFileViewerDocumentAnchor, unregisterFileViewerSearchProvider, unregisterFileViewerViewStateProvider, unregisterFileViewerZoomProvider, } from './features/document/dom';
18
18
  export { prepareFileViewerRenderedContentForSnapshot, inlineFileViewerBlobUrlsInHtml, replaceFileViewerCanvasWithImages, resolveFileViewerPrintStyle, triggerFileViewerBlobDownload, triggerFileViewerUrlDownload, waitForFileViewerImages, waitForFileViewerNextPaint, waitForFileViewerPrintWindowReady, } from './output/export';
19
+ export { createFileViewerCanvasImageBlob } from './output/canvasImage';
20
+ export { createFileViewerSnapshotDownload, isFileViewerSnapshotDownloadPermitted } from './output/snapshotDownload';
19
21
  export { applyPrintPageSize, buildPrintPageStyle, formatCssPixels, getElementPrintPageSize, } from './output/printLayout';
20
22
  export { assertFileViewerMermaidSourceHasNoExternalResources, sanitizeFileViewerSvgCss, sanitizeFileViewerSvgResources, } from './security/svgResources';
21
23
  export type { ApplyPrintPageSizeOptions, BuildPrintPageStyleOptions, PrintPageSize, } from './output/printLayout';
@@ -92,3 +94,4 @@ export type { CreateViewerOptions } from './viewer/createViewer';
92
94
  export type { BuildExportHtmlDocumentOptions, BuildFileViewerRenderedHtmlDocumentOptions, } from './exportDocument';
93
95
  export type { CreateFileViewerWorkerControllerOptions, FileViewerWorkerContext, FileViewerWorkerController, FileViewerWorkerErrorHook, FileViewerWorkerEventHandler, FileViewerWorkerFactory, FileViewerWorkerMessageHook, WorkerProvider, WorkerRef, } from './platform/worker';
94
96
  export type { FileViewerAiOptions, FileViewerArchiveEntryActionContext, FileViewerArchiveEntryActionPolicy, FileViewerArchiveEntryActionsOptions, FileViewerArchivePasswordRequestContext, FileViewerArchivePasswordRequestReason, FileViewerArchiveOptions, FileViewerChmOptions, FileViewerApplyViewStateOptions, FileViewerBeforeOperation, FileViewerCadColorMode, FileViewerCadDwfLineWeightMode, FileViewerCadOptions, FileViewerCadRenderer, FileViewerModelLinearUnit, FileViewerModelOptions, FileViewerComponentEmits, FileViewerComponentEventMap, FileViewerComponentProps, FileViewerDocumentAnchor, FileViewerDocumentChunk, FileViewerDownloadOptions, FileViewerDocxOptions, FileViewerDrawingOptions, FileViewerEvent, FileViewerEventHandler, FileViewerEventType, FileViewerExportHtmlOptions, FileViewerFileRef, FileViewerFitMode, FileViewerFitOptions, FileViewerFitRequest, FileViewerFitResize, FileViewerFitResult, FileViewerFormatStatus, FileViewerFormatSupportLevel, FileViewerGeoBasemapOptions, FileViewerGeoBasemapPreset, FileViewerGeoOptions, FileViewerTiandituMapStyle, FileRenderContext, FileRenderExportAdapter, FileRenderThumbnailAdapter, FileRenderExportMode, FileRenderExportOptions, FileRenderHandler, FileRenderHandlerComposite, FileViewerBuiltinRendererPreset, FileViewerInstance, FileViewerLoadOptions, FileViewerLifecycleContext, FileViewerLifecycleHooks, FileViewerLifecyclePhase, FileViewerI18nOptions, FileViewerIworkEmbeddedPreviewMode, FileViewerIworkOptions, FileViewerHangulOptions, FileViewerDiagnostic, FileViewerDesignOptions, FileViewerLocale, FileViewerMessageKey, FileViewerMessageParams, FileViewerMessageResolver, FileViewerMessages, FileViewerNavigationState, FileViewerOperationAvailability, FileViewerOperationContext, FileViewerOperationType, FileViewerOptions, FileViewerPdfBoundingBox, FileViewerPdfBoundingBoxOrigin, FileViewerPdfBoundingBoxUnit, FileViewerPdfOptions, FileViewerPresentationOptions, FileViewerPrintOptions, FileViewerPrintMaskOptions, FileViewerPrintMaskRegion, FileViewerPrintStamp, FileViewerPublicApi, FileViewerRenderedInstance, FileViewerRendererMode, FileViewerRendererPluginAssetKind, FileViewerRendererPluginAssetManifest, FileViewerRendererPluginAssetEntry, FileViewerRenderStateKind, FileViewerRenderPurpose, FileViewerRendererCategory, FileViewerRendererHandlerRegistration, FileViewerRendererInstallContext, FileViewerRendererPlugin, FileViewerRendererPluginInput, FileViewerRendererPresetInput, FileViewerRendererPresetName, FileViewerRendererPreset, FileViewerSearchMatch, FileViewerSearchOptions, FileViewerSearchProvider, FileViewerSearchState, FileViewerSource, FileViewerSourceKind, FileViewerThumbnailCaptureOptions, FileViewerThumbnailFit, FileViewerThumbnailFormat, FileViewerSpreadsheetOptions, FileViewerStateDescriptor, FileViewerStateTheme, FileViewerStyleIsolation, FileViewerTextOptions, FileViewerResolvedThemeMode, FileViewerThemeMode, FileViewerToolbarActionMap, FileViewerToolbarItem, FileViewerToolbarOptions, FileViewerToolbarPosition, FileViewerResolvedToolbarItem, FileViewerUiDensity, FileViewerUiOptions, FileViewerTypstOptions, FileViewerViewScrollState, FileViewerViewState, FileViewerViewStateChange, FileViewerViewStateChangeAction, FileViewerViewStateChangeSource, FileViewerViewStateProvider, FileViewerWatermarkOptions, FileViewerWordPerfectOptions, FileViewerZoomProvider, FileViewerZoomState, NormalizedFileViewerSource, RendererCapability, RendererDefinition, RendererPlugin, RendererLoadContext, RendererLoader, RendererRegistry, RendererSession, RenderSurface, ViewerCapabilityState, ViewerLifecycleContext, ViewerOperationContext, } from './contracts/types';
97
+ export { resolveFileViewerCopiedAssetUrl } from './platform/copiedAssets';
package/dist/index.js CHANGED
@@ -9,6 +9,8 @@ export { FILE_VIEWER_FIT_MODES, FILE_VIEWER_FIT_RESIZE_MODES, createFileViewerFi
9
9
  export { cloneFileViewerViewState, createFileViewerViewStateChange, createFileViewerViewStateChangeEmitter, createFileViewerViewStateController, createFileViewerViewStateControllerActionHandlers, registerFileViewerGenericViewStateProvider, } from './features/document/viewState.js';
10
10
  export { DEFAULT_FILE_VIEWER_ANCHOR_EXCLUDE_SELECTOR, DEFAULT_FILE_VIEWER_ANCHOR_SELECTOR, DEFAULT_FILE_VIEWER_SCROLL_CONTAINER_CANDIDATE_SELECTOR, DEFAULT_FILE_VIEWER_SCROLL_CONTAINER_SELECTOR, DEFAULT_FILE_VIEWER_SCROLLABLE_OVERFLOW_VALUES, collectFileViewerDocumentAnchors, findFileViewerAnchorForElement, findFileViewerSearchProvider, findFileViewerViewStateProvider, findFileViewerZoomProvider, getCurrentFileViewerDocumentAnchor, getFileViewerScrollableRange, isFileViewerScrollableElement, registerFileViewerSearchProvider, registerFileViewerViewStateProvider, registerFileViewerZoomProvider, resolveFileViewerScrollContainer, scrollToFileViewerDocumentAnchor, unregisterFileViewerSearchProvider, unregisterFileViewerViewStateProvider, unregisterFileViewerZoomProvider, } from './features/document/dom/index.js';
11
11
  export { prepareFileViewerRenderedContentForSnapshot, inlineFileViewerBlobUrlsInHtml, replaceFileViewerCanvasWithImages, resolveFileViewerPrintStyle, triggerFileViewerBlobDownload, triggerFileViewerUrlDownload, waitForFileViewerImages, waitForFileViewerNextPaint, waitForFileViewerPrintWindowReady, } from './output/export.js';
12
+ export { createFileViewerCanvasImageBlob } from './output/canvasImage.js';
13
+ export { createFileViewerSnapshotDownload, isFileViewerSnapshotDownloadPermitted } from './output/snapshotDownload.js';
12
14
  export { applyPrintPageSize, buildPrintPageStyle, formatCssPixels, getElementPrintPageSize, } from './output/printLayout.js';
13
15
  export { assertFileViewerMermaidSourceHasNoExternalResources, sanitizeFileViewerSvgCss, sanitizeFileViewerSvgResources, } from './security/svgResources.js';
14
16
  export { DEFAULT_FILE_VIEWER_DOWNLOAD_FILENAME, DEFAULT_FILE_VIEWER_EXPORT_FILENAME, DEFAULT_FILE_VIEWER_PREVIEW_TITLE, FILE_VIEWER_OPERATION_ACTION_ERROR_PREFIXES, createFileViewerOperationActionHandlers, createFileViewerOriginalSourceState, createFileViewerOriginalSourceStateFromNormalizedSource, createFileViewerPublicOperationActionHandlers, executeFileViewerDownloadOperation, executeFileViewerExportHtmlOperation, executeFileViewerPrintOperation, hasFileViewerOriginalSource, resolveFileViewerDisplayFilename, resolveFileViewerOperationActionErrorMessage, resolveFileViewerOperationFilename, resolveFileViewerOriginalFilename, } from './viewer/operations.js';
@@ -180,3 +182,4 @@ export { openFileViewerPrintMaskDesignerAsync, } from './features/printMaskLoade
180
182
  export { cancelFileViewerPreviewRequest, DEFAULT_FILE_VIEWER_STREAMING_PDF_FILENAME, DEFAULT_FILE_VIEWER_PREVIEW_LOAD_ERROR_LOGGER, DEFAULT_PDF_RANGE_CHUNK_SIZE, FILE_VIEWER_PREVIEW_LOAD_ERROR_PREFIXES, FILE_VIEWER_REMOTE_MISSING_DATA_ERROR_MESSAGE, applyFileViewerEmptyPreviewState, applyFileViewerPreviewFilenameState, applyFileViewerPreviewSourceUrlState, applyFileViewerReadPreviewState, applyFileViewerRenderReadinessState, applyFileViewerPreviewRequestResetState, commitFileViewerEmptyPreviewResetState, commitFileViewerLoadStartState, commitFileViewerPreviewRequestStartState, commitFileViewerRenderCompleteState, commitFileViewerRemoteDownloadState, createFileViewerEmptyPreviewState, createFileViewerLoadStartState, createFileViewerPreviewStateTarget, createFileViewerSourceLoadingActionHandlers, createFileViewerReadPreviewState, createFileViewerPreviewRequestResetState, createFileViewerRenderCompleteState, createFileViewerRequestController, createFileViewerRequestScope, createFileViewerStreamingPdfPlaceholderFile, finalizeFileViewerPreviewLoadState, hasFileViewerPreviewSource, isFileViewerAbortError, isSameOriginUrl, normalizeFileViewerSourceUrl, normalizePdfStreamingMode, resolveFileViewerFileRefSourcePlan, resolveFileViewerLoadStartMessage, resolveFileViewerMissingRemoteDataErrorMessage, resolveFileViewerPreviewLoadErrorMessage, resolveFileViewerPreviewRequestReason, resolveFileViewerRemoteSourcePlan, resolveFileViewerPageHref, reportFileViewerMissingRemoteData, reportFileViewerPreviewLoadError, runFileViewerLocalFilePreview, runFileViewerPreviewComponentUnmount, runFileViewerPreviewRequest, runFileViewerPreviewSourceChange, runFileViewerRemoteFilePreview, runFileViewerReadAndRenderFile, runFileViewerStreamingPdfPreview, shouldStreamPdfUrl, } from './source/loading.js';
181
183
  export { createViewer } from './viewer/createViewer.js';
182
184
  export { WorkerRefImpl, createFileViewerWorkerController, refWorker, } from './platform/worker.js';
185
+ export { resolveFileViewerCopiedAssetUrl } from './platform/copiedAssets.js';
@@ -0,0 +1,3 @@
1
+ import type { FileViewerWatermarkOptions } from '../contracts/types';
2
+ /** Encodes a detached snapshot without mutating the renderer or omitting its watermark. */
3
+ export declare function createFileViewerCanvasImageBlob(snapshot: HTMLCanvasElement, format: 'png' | 'jpeg', watermark?: boolean | FileViewerWatermarkOptions, pixelRatio?: number): Promise<Blob>;
@@ -0,0 +1,76 @@
1
+ import { buildFileViewerWatermarkSvg, normalizeFileViewerWatermark } from '../features/watermark.js';
2
+ const loadImage = (document, source) => new Promise((resolve, reject) => {
3
+ const image = document.createElement('img');
4
+ const timer = setTimeout(() => finish(new Error('Image export resource timed out.')), 30000);
5
+ const finish = (error) => {
6
+ clearTimeout(timer);
7
+ image.onload = image.onerror = null;
8
+ if (error)
9
+ reject(error);
10
+ else
11
+ resolve(image);
12
+ };
13
+ image.crossOrigin = 'anonymous';
14
+ image.onload = () => finish();
15
+ image.onerror = () => finish(new Error('Unable to render the export watermark.'));
16
+ image.src = source;
17
+ });
18
+ /** Encodes a detached snapshot without mutating the renderer or omitting its watermark. */
19
+ export async function createFileViewerCanvasImageBlob(snapshot, format, watermark, pixelRatio = 1) {
20
+ if (!['png', 'jpeg'].includes(format))
21
+ throw new Error('Unsupported image export format.');
22
+ if (!(snapshot.width > 0 && snapshot.height > 0) ||
23
+ snapshot.width * snapshot.height > 64000000) {
24
+ throw new Error('The image export size is empty or exceeds 64 million pixels.');
25
+ }
26
+ const document = snapshot.ownerDocument;
27
+ const canvas = document.createElement('canvas');
28
+ canvas.width = snapshot.width;
29
+ canvas.height = snapshot.height;
30
+ const context = canvas.getContext('2d');
31
+ if (!context)
32
+ throw new Error('A Canvas 2D context is required for image export.');
33
+ if (format === 'jpeg') {
34
+ context.fillStyle = '#ffffff';
35
+ context.fillRect(0, 0, canvas.width, canvas.height);
36
+ }
37
+ context.drawImage(snapshot, 0, 0);
38
+ let normalized = normalizeFileViewerWatermark(watermark);
39
+ if (normalized) {
40
+ if (normalized.image) {
41
+ // SVG image documents do not load nested remote images. Inline the configured
42
+ // watermark first; an unreadable/tainted image must fail, never disappear.
43
+ const image = await loadImage(document, normalized.image);
44
+ const tile = document.createElement('canvas');
45
+ tile.width = image.naturalWidth;
46
+ tile.height = image.naturalHeight;
47
+ if (!tile.width || !tile.height || tile.width * tile.height > 16000000) {
48
+ throw new Error('The watermark image size is invalid.');
49
+ }
50
+ const tileContext = tile.getContext('2d');
51
+ if (!tileContext)
52
+ throw new Error('Unable to render the export watermark.');
53
+ tileContext.drawImage(image, 0, 0);
54
+ normalized = { ...normalized, image: tile.toDataURL('image/png') };
55
+ }
56
+ const tile = await loadImage(document, `data:image/svg+xml;charset=utf-8,${encodeURIComponent(buildFileViewerWatermarkSvg(normalized))}`);
57
+ const pattern = context.createPattern(tile, 'repeat');
58
+ if (!pattern)
59
+ throw new Error('Unable to render the export watermark.');
60
+ const scale = Number.isFinite(pixelRatio) && pixelRatio > 0 ? pixelRatio : 1;
61
+ context.save();
62
+ context.scale(scale, scale);
63
+ context.fillStyle = pattern;
64
+ context.fillRect(0, 0, canvas.width / scale, canvas.height / scale);
65
+ context.restore();
66
+ }
67
+ const mime = `image/${format}`;
68
+ return new Promise((resolve, reject) => {
69
+ canvas.toBlob((blob) => {
70
+ if ((blob === null || blob === void 0 ? void 0 : blob.type) === mime && blob.size > 0)
71
+ resolve(blob);
72
+ else
73
+ reject(new Error(`Unable to encode ${format.toUpperCase()} output.`));
74
+ }, mime, 0.92);
75
+ });
76
+ }
@@ -0,0 +1,8 @@
1
+ import type { FileRenderContext, FileViewerOptions } from '../contracts/types';
2
+ export declare const isFileViewerSnapshotDownloadPermitted: (options?: FileViewerOptions) => boolean;
3
+ /** Renderer-local downloads still use the owning viewer's hooks and request version. */
4
+ export declare const createFileViewerSnapshotDownload: ({ getOptions, isCurrent, beforeDownload }: {
5
+ getOptions: () => FileViewerOptions | undefined;
6
+ isCurrent: () => boolean;
7
+ beforeDownload: () => Promise<boolean>;
8
+ }) => NonNullable<FileRenderContext["requestSnapshotDownload"]>;
@@ -0,0 +1,19 @@
1
+ import { isFileViewerToolbarOperationPermitted } from '../lifecycle/operations.js';
2
+ import { triggerFileViewerBlobDownload } from './export.js';
3
+ export const isFileViewerSnapshotDownloadPermitted = (options) => isFileViewerToolbarOperationPermitted(options === null || options === void 0 ? void 0 : options.toolbar, 'download') &&
4
+ isFileViewerToolbarOperationPermitted(options === null || options === void 0 ? void 0 : options.toolbar, 'export-html');
5
+ /** Renderer-local downloads still use the owning viewer's hooks and request version. */
6
+ export const createFileViewerSnapshotDownload = ({ getOptions, isCurrent, beforeDownload }) => async (create) => {
7
+ var _a, _b;
8
+ const allowed = () => isCurrent() && isFileViewerSnapshotDownloadPermitted(getOptions());
9
+ if (!allowed() || !(await beforeDownload()) || !allowed())
10
+ return false;
11
+ const watermark = (_a = getOptions()) === null || _a === void 0 ? void 0 : _a.watermark;
12
+ const watermarkState = JSON.stringify(watermark);
13
+ const capturedWatermark = watermark && typeof watermark === 'object' ? Object.freeze({ ...watermark }) : watermark;
14
+ const result = await create(capturedWatermark);
15
+ if (!allowed() || JSON.stringify((_b = getOptions()) === null || _b === void 0 ? void 0 : _b.watermark) !== watermarkState)
16
+ return false;
17
+ triggerFileViewerBlobDownload(result.blob, result.filename);
18
+ return true;
19
+ };
@@ -9,10 +9,10 @@ export declare const DEFAULT_FILE_VIEWER_CHM_WASM_PATH = "vendor/chm/chm_wasm_bg
9
9
  export declare const DEFAULT_FILE_VIEWER_CHM_WASM_PACKAGE_PATH = "@file-viewer/renderer-chm/wasm/chm_wasm_bg.wasm";
10
10
  export declare const DEFAULT_FILE_VIEWER_DOCX_WORKER_PATH = "vendor/docx/docx.worker.js";
11
11
  export declare const DEFAULT_FILE_VIEWER_DOCX_WORKER_JSZIP_PATH = "vendor/docx/jszip.min.js";
12
- export declare const DEFAULT_FILE_VIEWER_DOCX_RUNTIME_VERSION = "0.3.26";
12
+ export declare const DEFAULT_FILE_VIEWER_DOCX_RUNTIME_VERSION = "0.3.31";
13
13
  export declare const DEFAULT_FILE_VIEWER_PRESENTATION_WORKER_PATH = "vendor/pptx/pptx.worker.js";
14
14
  export declare const DEFAULT_FILE_VIEWER_PPT_RUNTIME_PATH = "vendor/ppt";
15
- export declare const DEFAULT_FILE_VIEWER_PPT_RUNTIME_VERSION = "0.3.3";
15
+ export declare const DEFAULT_FILE_VIEWER_PPT_RUNTIME_VERSION = "0.3.4";
16
16
  export declare const DEFAULT_FILE_VIEWER_PPT_MODULE_PATH = "vendor/ppt/index.mjs";
17
17
  export declare const DEFAULT_FILE_VIEWER_PPT_WORKER_PATH = "vendor/ppt/worker.mjs";
18
18
  export declare const DEFAULT_FILE_VIEWER_PPT_FRAME_CACHE_PATH = "vendor/ppt/frame-cache.mjs";
@@ -36,13 +36,13 @@ export declare const DEFAULT_FILE_VIEWER_PDF_STANDARD_FONT_PATH = "vendor/pdf/st
36
36
  export declare const DEFAULT_FILE_VIEWER_PDF_CJK_FONT_FALLBACK_PATH = "vendor/pdf/fonts/";
37
37
  export declare const DEFAULT_FILE_VIEWER_DRAWIO_VIEWER_SCRIPT_PATH = "vendor/drawio/viewer-static.min.js";
38
38
  export declare const DEFAULT_FILE_VIEWER_DRAWIO_ASSET_PATH = "vendor/drawio/";
39
- export declare const DEFAULT_FILE_VIEWER_CAD_RUNTIME_VERSION = "0.8.1";
39
+ export declare const DEFAULT_FILE_VIEWER_CAD_RUNTIME_VERSION = "0.8.2";
40
40
  export declare const COMPATIBILITY_FILE_VIEWER_CAD_RUNTIME_VERSION = "0.8.0";
41
- export declare const DEFAULT_FILE_VIEWER_CAD_WASM_PATH = "wasm/cad/0.8.1/";
42
- export declare const DEFAULT_FILE_VIEWER_CAD_WORKER_PATH = "wasm/cad/0.8.1/dwg-worker.js";
43
- export declare const DEFAULT_FILE_VIEWER_CAD_DWF_WASM_PATH = "wasm/cad/0.8.1/dwfv-render.wasm";
44
- export declare const DEFAULT_FILE_VIEWER_CAD_LIBREDWG_SCRIPT_PATH = "wasm/cad/0.8.1/libredwg-web.js";
45
- export declare const DEFAULT_FILE_VIEWER_CAD_LIBREDWG_WASM_PATH = "wasm/cad/0.8.1/libredwg-web.wasm";
41
+ export declare const DEFAULT_FILE_VIEWER_CAD_WASM_PATH = "wasm/cad/0.8.2/";
42
+ export declare const DEFAULT_FILE_VIEWER_CAD_WORKER_PATH = "wasm/cad/0.8.2/dwg-worker.js";
43
+ export declare const DEFAULT_FILE_VIEWER_CAD_DWF_WASM_PATH = "wasm/cad/0.8.2/dwfv-render.wasm";
44
+ export declare const DEFAULT_FILE_VIEWER_CAD_LIBREDWG_SCRIPT_PATH = "wasm/cad/0.8.2/libredwg-web.js";
45
+ export declare const DEFAULT_FILE_VIEWER_CAD_LIBREDWG_WASM_PATH = "wasm/cad/0.8.2/libredwg-web.wasm";
46
46
  export declare const DEFAULT_FILE_VIEWER_TYPST_COMPILER_WASM_URL = "wasm/typst/typst_ts_web_compiler_bg.wasm";
47
47
  export declare const DEFAULT_FILE_VIEWER_TYPST_RENDERER_WASM_URL = "wasm/typst/typst_ts_renderer_bg.wasm";
48
48
  export declare const DEFAULT_FILE_VIEWER_TYPST_FONT_ASSETS_URL = "wasm/typst/fonts/";
@@ -8,10 +8,10 @@ export const DEFAULT_FILE_VIEWER_CHM_WASM_PATH = 'vendor/chm/chm_wasm_bg.wasm';
8
8
  export const DEFAULT_FILE_VIEWER_CHM_WASM_PACKAGE_PATH = '@file-viewer/renderer-chm/wasm/chm_wasm_bg.wasm';
9
9
  export const DEFAULT_FILE_VIEWER_DOCX_WORKER_PATH = 'vendor/docx/docx.worker.js';
10
10
  export const DEFAULT_FILE_VIEWER_DOCX_WORKER_JSZIP_PATH = 'vendor/docx/jszip.min.js';
11
- export const DEFAULT_FILE_VIEWER_DOCX_RUNTIME_VERSION = '0.3.26';
11
+ export const DEFAULT_FILE_VIEWER_DOCX_RUNTIME_VERSION = '0.3.31';
12
12
  export const DEFAULT_FILE_VIEWER_PRESENTATION_WORKER_PATH = 'vendor/pptx/pptx.worker.js';
13
13
  export const DEFAULT_FILE_VIEWER_PPT_RUNTIME_PATH = 'vendor/ppt';
14
- export const DEFAULT_FILE_VIEWER_PPT_RUNTIME_VERSION = '0.3.3';
14
+ export const DEFAULT_FILE_VIEWER_PPT_RUNTIME_VERSION = '0.3.4';
15
15
  export const DEFAULT_FILE_VIEWER_PPT_MODULE_PATH = `${DEFAULT_FILE_VIEWER_PPT_RUNTIME_PATH}/index.mjs`;
16
16
  export const DEFAULT_FILE_VIEWER_PPT_WORKER_PATH = `${DEFAULT_FILE_VIEWER_PPT_RUNTIME_PATH}/worker.mjs`;
17
17
  export const DEFAULT_FILE_VIEWER_PPT_FRAME_CACHE_PATH = `${DEFAULT_FILE_VIEWER_PPT_RUNTIME_PATH}/frame-cache.mjs`;
@@ -35,7 +35,7 @@ export const DEFAULT_FILE_VIEWER_PDF_STANDARD_FONT_PATH = 'vendor/pdf/standard_f
35
35
  export const DEFAULT_FILE_VIEWER_PDF_CJK_FONT_FALLBACK_PATH = 'vendor/pdf/fonts/';
36
36
  export const DEFAULT_FILE_VIEWER_DRAWIO_VIEWER_SCRIPT_PATH = 'vendor/drawio/viewer-static.min.js';
37
37
  export const DEFAULT_FILE_VIEWER_DRAWIO_ASSET_PATH = 'vendor/drawio/';
38
- export const DEFAULT_FILE_VIEWER_CAD_RUNTIME_VERSION = '0.8.1';
38
+ export const DEFAULT_FILE_VIEWER_CAD_RUNTIME_VERSION = '0.8.2';
39
39
  export const COMPATIBILITY_FILE_VIEWER_CAD_RUNTIME_VERSION = '0.8.0';
40
40
  export const DEFAULT_FILE_VIEWER_CAD_WASM_PATH = `wasm/cad/${DEFAULT_FILE_VIEWER_CAD_RUNTIME_VERSION}/`;
41
41
  export const DEFAULT_FILE_VIEWER_CAD_WORKER_PATH = `${DEFAULT_FILE_VIEWER_CAD_WASM_PATH}dwg-worker.js`;
@@ -0,0 +1,2 @@
1
+ /** Finds assets copied by the standard CLI without trusting a SPA fallback or arbitrary manifest URLs. */
2
+ export declare function resolveFileViewerCopiedAssetUrl(documentRef: Document, rendererId: string, assetId: string, signal?: AbortSignal): Promise<string | undefined>;
@@ -0,0 +1,93 @@
1
+ import { getFileViewerRendererAssetManifest, resolveFileViewerRuntimeAssetBaseUrl } from './assets.js';
2
+ const manifests = new WeakMap();
3
+ const MAX_MANIFEST_BYTES = 1024 * 1024;
4
+ const readManifest = async (url, signal) => {
5
+ var _a, _b, _c;
6
+ const controller = new AbortController();
7
+ const abort = () => controller.abort(signal === null || signal === void 0 ? void 0 : signal.reason);
8
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted)
9
+ abort();
10
+ else
11
+ signal === null || signal === void 0 ? void 0 : signal.addEventListener('abort', abort, { once: true });
12
+ const timeout = setTimeout(() => controller.abort(), 3000);
13
+ try {
14
+ const response = await fetch(url, { signal: controller.signal, credentials: 'same-origin' });
15
+ if (!response.ok ||
16
+ !((_a = response.headers.get('content-type')) === null || _a === void 0 ? void 0 : _a.includes('json')) ||
17
+ Number(response.headers.get('content-length')) > MAX_MANIFEST_BYTES)
18
+ return null;
19
+ const reader = (_b = response.body) === null || _b === void 0 ? void 0 : _b.getReader();
20
+ if (!reader)
21
+ return null;
22
+ const chunks = [];
23
+ let size = 0;
24
+ try {
25
+ while (true) {
26
+ const { value, done } = await reader.read();
27
+ if (done)
28
+ break;
29
+ size += value.byteLength;
30
+ if (size > MAX_MANIFEST_BYTES)
31
+ return null;
32
+ chunks.push(value);
33
+ }
34
+ }
35
+ finally {
36
+ await reader.cancel();
37
+ }
38
+ const bytes = new Uint8Array(size);
39
+ let offset = 0;
40
+ for (const chunk of chunks) {
41
+ bytes.set(chunk, offset);
42
+ offset += chunk.byteLength;
43
+ }
44
+ const manifest = JSON.parse(new TextDecoder().decode(bytes));
45
+ return (manifest === null || manifest === void 0 ? void 0 : manifest.schemaVersion) === 1 &&
46
+ manifest.packageName === 'file-viewer-copy-assets' &&
47
+ Array.isArray((_c = manifest.validation) === null || _c === void 0 ? void 0 : _c.assets)
48
+ ? manifest
49
+ : null;
50
+ }
51
+ catch {
52
+ return null;
53
+ }
54
+ finally {
55
+ clearTimeout(timeout);
56
+ signal === null || signal === void 0 ? void 0 : signal.removeEventListener('abort', abort);
57
+ }
58
+ };
59
+ /** Finds assets copied by the standard CLI without trusting a SPA fallback or arbitrary manifest URLs. */
60
+ export async function resolveFileViewerCopiedAssetUrl(documentRef, rendererId, assetId, signal) {
61
+ var _a, _b, _c;
62
+ const asset = (_a = getFileViewerRendererAssetManifest(rendererId)) === null || _a === void 0 ? void 0 : _a.assets.find((item) => item.id === assetId);
63
+ if (!(asset === null || asset === void 0 ? void 0 : asset.defaultPath))
64
+ return undefined;
65
+ const base = new URL(resolveFileViewerRuntimeAssetBaseUrl(documentRef));
66
+ if (!['http:', 'https:'].includes(base.protocol))
67
+ return undefined;
68
+ const bases = base.pathname.endsWith('/file-viewer/')
69
+ ? [base]
70
+ : [new URL('file-viewer/', base), base];
71
+ let cache = manifests.get(documentRef);
72
+ if (!cache) {
73
+ cache = new Map();
74
+ manifests.set(documentRef, cache);
75
+ }
76
+ for (const directory of bases) {
77
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted)
78
+ return undefined;
79
+ const url = new URL('flyfish-viewer-assets.json', directory).href;
80
+ const manifest = cache.has(url) ? cache.get(url) : await readManifest(url, signal);
81
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted)
82
+ return undefined;
83
+ cache.set(url, manifest || null);
84
+ const copied = (_c = (_b = manifest === null || manifest === void 0 ? void 0 : manifest.validation) === null || _b === void 0 ? void 0 : _b.assets) === null || _c === void 0 ? void 0 : _c.find((item) => item &&
85
+ item.id === assetId &&
86
+ item.rendererId === rendererId &&
87
+ item.exists === true &&
88
+ item.relativePath === asset.defaultPath);
89
+ if (copied)
90
+ return new URL(asset.defaultPath, directory).href;
91
+ }
92
+ return undefined;
93
+ }
@@ -19,6 +19,7 @@ import { createFileViewerCoreRendererRegistry } from '../renderers/index.js';
19
19
  import { createFileViewerRequestScope } from '../source/loading.js';
20
20
  import { normalizeSource } from '../source/index.js';
21
21
  import { buildFileViewerWatermarkInlineStyle } from '../features/watermark.js';
22
+ import { createFileViewerSnapshotDownload } from '../output/snapshotDownload.js';
22
23
  import { createFileViewerUnsupportedState } from './state.js';
23
24
  const emitLifecycle = async (options, onEvent, phase, source, version, startedAt, reason) => {
24
25
  const now = Date.now();
@@ -556,6 +557,11 @@ export const createViewer = (container, createOptions = {}) => {
556
557
  renderContext: {
557
558
  renderPurpose: createOptions.renderPurpose || 'preview',
558
559
  renderNestedBuffer,
560
+ requestSnapshotDownload: createFileViewerSnapshotDownload({
561
+ getOptions: () => options,
562
+ isCurrent: () => requestScope.isCurrentRequest(version),
563
+ beforeDownload: () => runBeforeViewerOperation('download'),
564
+ }),
559
565
  },
560
566
  });
561
567
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@file-viewer/core",
3
- "version": "3.0.2",
3
+ "version": "3.0.3",
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",
@@ -90,7 +90,7 @@
90
90
  "LICENSE"
91
91
  ],
92
92
  "dependencies": {
93
- "dompurify": "3.4.14"
93
+ "dompurify": "3.4.15"
94
94
  },
95
95
  "devDependencies": {
96
96
  "typescript": "^6.0.3"