@file-viewer/core
Advanced tools
| import type { FileViewerFileRef, FileViewerSource } from '../contracts/types'; | ||
| export type FileViewerPrecheckStatus = 'ready' | 'invalid' | 'unsupported'; | ||
| export type FileViewerPrecheckReason = 'content-valid' | 'content-not-inspected' | 'content-inconclusive' | 'empty-structured-file' | 'signature-mismatch' | 'invalid-package' | 'missing-package-part' | 'unsupported-extension'; | ||
| export interface FileViewerPrecheckOptions { | ||
| /** Filename used when a Blob or ArrayBuffer has no name. */ | ||
| filename?: string; | ||
| /** Explicit extension, with or without a leading dot. */ | ||
| type?: string; | ||
| /** Restricts the result to the renderers installed by the host application. */ | ||
| supportedExtensions?: Iterable<string>; | ||
| /** Maximum ZIP central-directory bytes read from a Blob. Defaults to 8 MiB. */ | ||
| maxPackageMetadataBytes?: number; | ||
| } | ||
| export interface FileViewerPrecheckResult { | ||
| filename: string; | ||
| extension: string; | ||
| rendererId: string | null; | ||
| supported: boolean; | ||
| inspected: boolean; | ||
| /** `null` means the extension is supported but no structural validator exists. */ | ||
| valid: boolean | null; | ||
| previewable: boolean; | ||
| status: FileViewerPrecheckStatus; | ||
| reason: FileViewerPrecheckReason; | ||
| missingParts: string[]; | ||
| } | ||
| type FileViewerPrecheckInput = FileViewerSource | FileViewerFileRef; | ||
| /** | ||
| * Performs a cheap, renderer-free capability and structure check. | ||
| * | ||
| * This intentionally does not promise rendering fidelity. A `ready` result | ||
| * means the extension is available and any known container/signature checks | ||
| * passed; the real renderer remains the final authority for malformed content. | ||
| */ | ||
| export declare const precheckFileViewerSource: (input: FileViewerPrecheckInput, options?: FileViewerPrecheckOptions) => Promise<FileViewerPrecheckResult>; | ||
| export {}; |
| import { DEFAULT_RENDERER_DEFINITIONS, DEFAULT_SUPPORTED_EXTENSIONS } from '../registry/formats.js'; | ||
| import { getExtension, normalizeFileExtension, normalizeFilename, normalizeSource, } from './index.js'; | ||
| const DEFAULT_MAX_PACKAGE_METADATA_BYTES = 8 * 1024 * 1024; | ||
| const ZIP_LOCAL_SIGNATURE = 0x04034b50; | ||
| const ZIP_CENTRAL_SIGNATURE = 0x02014b50; | ||
| const ZIP_END_SIGNATURE = 0x06054b50; | ||
| const ZIP64_SENTINEL = 0xffffffff; | ||
| const OLE_SIGNATURE = [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1]; | ||
| const OPEN_XML_REQUIRED_PARTS = { | ||
| docx: ['[content_types].xml', 'word/document.xml'], | ||
| docm: ['[content_types].xml', 'word/document.xml'], | ||
| dotx: ['[content_types].xml', 'word/document.xml'], | ||
| dotm: ['[content_types].xml', 'word/document.xml'], | ||
| xlsx: ['[content_types].xml', 'xl/workbook.xml'], | ||
| xltx: ['[content_types].xml', 'xl/workbook.xml'], | ||
| xlsm: ['[content_types].xml', 'xl/workbook.xml'], | ||
| xltm: ['[content_types].xml', 'xl/workbook.xml'], | ||
| xlsb: ['[content_types].xml', 'xl/workbook.bin'], | ||
| pptx: ['[content_types].xml', 'ppt/presentation.xml'], | ||
| pptm: ['[content_types].xml', 'ppt/presentation.xml'], | ||
| potx: ['[content_types].xml', 'ppt/presentation.xml'], | ||
| potm: ['[content_types].xml', 'ppt/presentation.xml'], | ||
| ppsx: ['[content_types].xml', 'ppt/presentation.xml'], | ||
| ppsm: ['[content_types].xml', 'ppt/presentation.xml'], | ||
| odt: ['content.xml'], | ||
| ods: ['content.xml'], | ||
| odp: ['content.xml'], | ||
| ofd: ['ofd.xml'], | ||
| numbers: ['index/document.iwa'], | ||
| epub: ['meta-inf/container.xml'], | ||
| xps: ['[content_types].xml'], | ||
| dwfx: ['[content_types].xml'], | ||
| }; | ||
| const ZIP_EXTENSIONS = new Set([ | ||
| ...Object.keys(OPEN_XML_REQUIRED_PARTS), | ||
| 'zip', 'zipx', 'jar', 'war', 'ear', 'apk', 'cbz', | ||
| ]); | ||
| const OLE_EXTENSIONS = new Set(['doc', 'dot', 'xls', 'xlt', 'ppt', 'msg']); | ||
| const TEXT_DECODER = new TextDecoder('utf-8'); | ||
| const isArrayBuffer = (value) => value instanceof ArrayBuffer; | ||
| const isBlob = (value) => (typeof Blob !== 'undefined' && value instanceof Blob); | ||
| const toSource = (input, options) => { | ||
| if (isArrayBuffer(input)) { | ||
| return { buffer: input, filename: options.filename, type: options.type }; | ||
| } | ||
| if (isBlob(input)) { | ||
| return { file: input, filename: options.filename, type: options.type }; | ||
| } | ||
| return { | ||
| ...input, | ||
| filename: options.filename || input.filename, | ||
| type: options.type || input.type, | ||
| }; | ||
| }; | ||
| const startsWithBytes = (bytes, expected) => (expected.every((value, index) => bytes[index] === value)); | ||
| const findEndOfCentralDirectory = (bytes) => { | ||
| for (let offset = bytes.byteLength - 22; offset >= 0; offset -= 1) { | ||
| if (bytes[offset] === 0x50 && | ||
| bytes[offset + 1] === 0x4b && | ||
| bytes[offset + 2] === 0x05 && | ||
| bytes[offset + 3] === 0x06) { | ||
| return offset; | ||
| } | ||
| } | ||
| return -1; | ||
| }; | ||
| const collectCentralDirectoryEntries = (bytes) => { | ||
| const entries = new Set(); | ||
| const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength); | ||
| let offset = 0; | ||
| while (offset + 46 <= bytes.byteLength) { | ||
| if (view.getUint32(offset, true) !== ZIP_CENTRAL_SIGNATURE) { | ||
| break; | ||
| } | ||
| const filenameLength = view.getUint16(offset + 28, true); | ||
| const extraLength = view.getUint16(offset + 30, true); | ||
| const commentLength = view.getUint16(offset + 32, true); | ||
| const end = offset + 46 + filenameLength; | ||
| if (end > bytes.byteLength) { | ||
| return { entries, complete: false }; | ||
| } | ||
| entries.add(TEXT_DECODER.decode(bytes.subarray(offset + 46, end)).replace(/^\/+/, '').toLowerCase()); | ||
| offset = end + extraLength + commentLength; | ||
| } | ||
| return { entries, complete: offset === bytes.byteLength }; | ||
| }; | ||
| const inspectZipBuffer = (buffer) => { | ||
| const bytes = new Uint8Array(buffer); | ||
| if (bytes.byteLength < 22) { | ||
| return { signatureValid: false, complete: true, entries: new Set() }; | ||
| } | ||
| const view = new DataView(buffer); | ||
| const firstSignature = view.getUint32(0, true); | ||
| if (firstSignature !== ZIP_LOCAL_SIGNATURE && firstSignature !== ZIP_END_SIGNATURE) { | ||
| return { signatureValid: false, complete: true, entries: new Set() }; | ||
| } | ||
| const endOffset = findEndOfCentralDirectory(bytes); | ||
| if (endOffset < 0) { | ||
| return { signatureValid: true, complete: false, entries: new Set() }; | ||
| } | ||
| const centralSize = view.getUint32(endOffset + 12, true); | ||
| const centralOffset = view.getUint32(endOffset + 16, true); | ||
| if (centralSize === ZIP64_SENTINEL || centralOffset === ZIP64_SENTINEL) { | ||
| return { signatureValid: true, complete: false, entries: new Set() }; | ||
| } | ||
| if (centralOffset + centralSize > bytes.byteLength) { | ||
| return { signatureValid: true, complete: false, entries: new Set() }; | ||
| } | ||
| const result = collectCentralDirectoryEntries(bytes.subarray(centralOffset, centralOffset + centralSize)); | ||
| return { signatureValid: true, complete: result.complete, entries: result.entries }; | ||
| }; | ||
| const inspectZipBlob = async (blob, maxPackageMetadataBytes) => { | ||
| if (blob.size < 22) { | ||
| return { signatureValid: false, complete: true, entries: new Set() }; | ||
| } | ||
| const prefix = new Uint8Array(await blob.slice(0, 4).arrayBuffer()); | ||
| const prefixView = new DataView(prefix.buffer, prefix.byteOffset, prefix.byteLength); | ||
| const firstSignature = prefixView.getUint32(0, true); | ||
| if (firstSignature !== ZIP_LOCAL_SIGNATURE && firstSignature !== ZIP_END_SIGNATURE) { | ||
| return { signatureValid: false, complete: true, entries: new Set() }; | ||
| } | ||
| const tailStart = Math.max(0, blob.size - 65557); | ||
| const tail = new Uint8Array(await blob.slice(tailStart).arrayBuffer()); | ||
| const endOffset = findEndOfCentralDirectory(tail); | ||
| if (endOffset < 0) { | ||
| return { signatureValid: true, complete: false, entries: new Set() }; | ||
| } | ||
| const tailView = new DataView(tail.buffer, tail.byteOffset, tail.byteLength); | ||
| const centralSize = tailView.getUint32(endOffset + 12, true); | ||
| const centralOffset = tailView.getUint32(endOffset + 16, true); | ||
| if (centralSize === ZIP64_SENTINEL || | ||
| centralOffset === ZIP64_SENTINEL || | ||
| centralSize > maxPackageMetadataBytes || | ||
| centralOffset + centralSize > blob.size) { | ||
| return { signatureValid: true, complete: false, entries: new Set() }; | ||
| } | ||
| const central = new Uint8Array(await blob.slice(centralOffset, centralOffset + centralSize).arrayBuffer()); | ||
| const result = collectCentralDirectoryEntries(central); | ||
| return { signatureValid: true, complete: result.complete, entries: result.entries }; | ||
| }; | ||
| const inspectZip = async (source, maxPackageMetadataBytes) => { | ||
| if (source.buffer) { | ||
| return inspectZipBuffer(source.buffer); | ||
| } | ||
| if (source.file) { | ||
| return inspectZipBlob(source.file, maxPackageMetadataBytes); | ||
| } | ||
| return null; | ||
| }; | ||
| const readPrefix = async (source, byteLength = 1024) => { | ||
| if (source.buffer) { | ||
| return new Uint8Array(source.buffer, 0, Math.min(source.buffer.byteLength, byteLength)); | ||
| } | ||
| if (source.file) { | ||
| return new Uint8Array(await source.file.slice(0, byteLength).arrayBuffer()); | ||
| } | ||
| return null; | ||
| }; | ||
| const inspectStructuredContent = async (source, extension, maxPackageMetadataBytes) => { | ||
| var _a, _b, _c; | ||
| 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; | ||
| if (size === 0 && (ZIP_EXTENSIONS.has(extension) || OLE_EXTENSIONS.has(extension) || extension === 'pdf')) { | ||
| return { inspected: true, valid: false, reason: 'empty-structured-file' }; | ||
| } | ||
| if (ZIP_EXTENSIONS.has(extension)) { | ||
| const zip = await inspectZip(source, maxPackageMetadataBytes); | ||
| if (!zip) { | ||
| return { inspected: false, valid: null, reason: 'content-not-inspected' }; | ||
| } | ||
| if (!zip.signatureValid) { | ||
| return { inspected: true, valid: false, reason: 'signature-mismatch' }; | ||
| } | ||
| const required = OPEN_XML_REQUIRED_PARTS[extension] || []; | ||
| if (!zip.complete) { | ||
| return { inspected: true, valid: null, reason: 'content-inconclusive' }; | ||
| } | ||
| const missingParts = required.filter(part => !zip.entries.has(part)); | ||
| if (missingParts.length) { | ||
| return { inspected: true, valid: false, reason: 'missing-package-part', missingParts }; | ||
| } | ||
| return { inspected: true, valid: true, reason: 'content-valid' }; | ||
| } | ||
| const prefix = await readPrefix(source); | ||
| if (!prefix) { | ||
| return { inspected: false, valid: null, reason: 'content-not-inspected' }; | ||
| } | ||
| if (OLE_EXTENSIONS.has(extension)) { | ||
| return startsWithBytes(prefix, OLE_SIGNATURE) | ||
| ? { inspected: true, valid: true, reason: 'content-valid' } | ||
| : { inspected: true, valid: false, reason: 'signature-mismatch' }; | ||
| } | ||
| if (extension === 'pdf') { | ||
| const header = TEXT_DECODER.decode(prefix); | ||
| return /%PDF-\d\.\d/.test(header) | ||
| ? { inspected: true, valid: true, reason: 'content-valid' } | ||
| : { inspected: true, valid: false, reason: 'signature-mismatch' }; | ||
| } | ||
| if (extension === 'rtf') { | ||
| const header = TEXT_DECODER.decode(prefix); | ||
| return /^\s*\{\\rtf\d/.test(header) | ||
| ? { inspected: true, valid: true, reason: 'content-valid' } | ||
| : { inspected: true, valid: false, reason: 'signature-mismatch' }; | ||
| } | ||
| return { inspected: false, valid: null, reason: 'content-not-inspected' }; | ||
| }; | ||
| /** | ||
| * Performs a cheap, renderer-free capability and structure check. | ||
| * | ||
| * This intentionally does not promise rendering fidelity. A `ready` result | ||
| * means the extension is available and any known container/signature checks | ||
| * passed; the real renderer remains the final authority for malformed content. | ||
| */ | ||
| export const precheckFileViewerSource = async (input, options = {}) => { | ||
| var _a; | ||
| const source = toSource(input, options); | ||
| const normalized = normalizeSource(source); | ||
| const extension = normalizeFileExtension(options.type || normalized.extension || getExtension(options.filename || normalized.filename)); | ||
| const filename = normalizeFilename(options.filename || normalized.filename); | ||
| const supportedExtensions = new Set(Array.from(options.supportedExtensions || DEFAULT_SUPPORTED_EXTENSIONS, normalizeFileExtension)); | ||
| const supported = supportedExtensions.has(extension); | ||
| const rendererId = ((_a = DEFAULT_RENDERER_DEFINITIONS.find(definition => definition.extensions.some(candidate => normalizeFileExtension(candidate) === extension))) === null || _a === void 0 ? void 0 : _a.id) || null; | ||
| if (!supported) { | ||
| return { | ||
| filename, | ||
| extension, | ||
| rendererId, | ||
| supported: false, | ||
| inspected: false, | ||
| valid: null, | ||
| previewable: false, | ||
| status: 'unsupported', | ||
| reason: 'unsupported-extension', | ||
| missingParts: [], | ||
| }; | ||
| } | ||
| const inspection = await inspectStructuredContent(source, extension, Math.max(64 * 1024, options.maxPackageMetadataBytes || DEFAULT_MAX_PACKAGE_METADATA_BYTES)); | ||
| const valid = inspection.valid; | ||
| return { | ||
| filename, | ||
| extension, | ||
| rendererId, | ||
| supported: true, | ||
| inspected: inspection.inspected, | ||
| valid, | ||
| previewable: valid !== false, | ||
| status: valid === false ? 'invalid' : 'ready', | ||
| reason: inspection.reason, | ||
| missingParts: inspection.missingParts || [], | ||
| }; | ||
| }; |
@@ -6,3 +6,3 @@ export type FileViewerSourceKind = 'file' | 'url' | 'buffer' | 'empty'; | ||
| export type FileViewerStyleIsolation = 'auto' | 'shadow' | 'scoped' | 'none'; | ||
| 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.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.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' | '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.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.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.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.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'; | ||
| 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.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' | '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.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.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.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'; | ||
| export type FileViewerMessageParams = Record<string, string | number | boolean | null | undefined>; | ||
@@ -119,2 +119,8 @@ export type FileViewerMessageResolver = (key: FileViewerMessageKey, params: FileViewerMessageParams, locale: FileViewerLocale) => string | undefined; | ||
| /** | ||
| * Highlights and focuses one or more PDF regions after the document loads. | ||
| * Use `pixel` with `sourceWidth` / `sourceHeight` for OCR coordinates, or | ||
| * `pdf-point` for native PDF coordinates. Page numbers are one-based. | ||
| */ | ||
| bbox?: FileViewerPdfBoundingBox | readonly FileViewerPdfBoundingBox[]; | ||
| /** | ||
| * Initial PDF view position. Prefer the top-level `initialViewState` when the | ||
@@ -155,2 +161,25 @@ * same state should be passed through framework-neutral viewer APIs. | ||
| } | ||
| export type FileViewerPdfBoundingBoxUnit = 'ratio' | 'percent' | 'pixel' | 'pdf-point'; | ||
| export type FileViewerPdfBoundingBoxOrigin = 'top-left' | 'bottom-left'; | ||
| export interface FileViewerPdfBoundingBox { | ||
| id?: string; | ||
| /** One-based PDF page number. Defaults to the current page, then page 1. */ | ||
| page?: number; | ||
| x: number; | ||
| y: number; | ||
| width: number; | ||
| height: number; | ||
| /** Defaults to `pdf-point`. */ | ||
| unit?: FileViewerPdfBoundingBoxUnit; | ||
| /** Defaults to `bottom-left` for PDF points and `top-left` otherwise. */ | ||
| origin?: FileViewerPdfBoundingBoxOrigin; | ||
| /** Required when `unit` is `pixel`; this is the OCR/source image width. */ | ||
| sourceWidth?: number; | ||
| /** Required when `unit` is `pixel`; this is the OCR/source image height. */ | ||
| sourceHeight?: number; | ||
| /** CSS color used for the outline and translucent fill. */ | ||
| color?: string; | ||
| /** Optional accessible description for the highlighted region. */ | ||
| label?: string; | ||
| } | ||
| export interface FileViewerDocxOptions { | ||
@@ -322,3 +351,4 @@ worker?: boolean; | ||
| } | ||
| export type FileViewerGeoBasemapPreset = 'none' | 'offline' | 'openfreemap' | 'openfreemap-liberty' | 'openfreemap-bright' | 'openfreemap-positron' | 'openfreemap-dark' | 'openfreemap-fiord' | 'osm-raster'; | ||
| export type FileViewerGeoBasemapPreset = 'none' | 'offline' | 'openfreemap' | 'openfreemap-liberty' | 'openfreemap-bright' | 'openfreemap-positron' | 'openfreemap-dark' | 'openfreemap-fiord' | 'osm-raster' | 'tianditu-vector' | 'tianditu-imagery' | 'tianditu-terrain'; | ||
| export type FileViewerTiandituMapStyle = 'vector' | 'imagery' | 'terrain'; | ||
| export interface FileViewerGeoBasemapOptions { | ||
@@ -328,4 +358,6 @@ /** | ||
| * object or URL, which is the best path for OpenFreeMap/OpenMapTiles stacks. | ||
| * `tianditu` builds the official base and annotation raster layers from the | ||
| * caller-provided Tianditu token. | ||
| */ | ||
| type?: 'raster' | 'vector-style'; | ||
| type?: 'raster' | 'vector-style' | 'tianditu'; | ||
| /** | ||
@@ -354,2 +386,8 @@ * Raster XYZ/TMS tile template, for example `/tiles/{z}/{x}/{y}.png`. | ||
| rasterOpacity?: number; | ||
| /** Tianditu API token. Required when `type` is `tianditu`. */ | ||
| token?: string; | ||
| /** Tianditu map family. Defaults to `vector`. */ | ||
| mapStyle?: FileViewerTiandituMapStyle; | ||
| /** Include the matching Tianditu annotation layer. Defaults to true. */ | ||
| labels?: boolean; | ||
| } | ||
@@ -381,2 +419,7 @@ export interface FileViewerGeoOptions { | ||
| /** | ||
| * Tianditu API token used by the `tianditu-*` presets. The viewer never | ||
| * supplies or persists a token; obtain one for the deployment's own domain. | ||
| */ | ||
| tiandituToken?: string; | ||
| /** | ||
| * Defaults to true. When no CRS is declared and coordinates exceed longitude | ||
@@ -901,5 +944,17 @@ * or latitude ranges, the geo renderer treats Web Mercator-sized values as | ||
| } | ||
| /** Page-aware image placed above rendered content for printing, such as a seal or signature. */ | ||
| export interface FileViewerPrintStamp extends FileViewerPrintMaskRegion { | ||
| /** Image URL. Uploaded stamps are converted to a local data URL by the designer. */ | ||
| src: string; | ||
| /** Image opacity from 0 to 1. Defaults to 1. */ | ||
| opacity?: number; | ||
| /** Clockwise rotation in degrees. Defaults to 0. */ | ||
| rotate?: number; | ||
| alt?: string; | ||
| } | ||
| export interface FileViewerPrintMaskOptions { | ||
| /** Solid black cover blocks, matching common OFD/business redaction UX. */ | ||
| regions?: FileViewerPrintMaskRegion[]; | ||
| /** Image overlays, including locally uploaded seals and signatures. */ | ||
| stamps?: FileViewerPrintStamp[]; | ||
| /** Fill color for print masks. Defaults to opaque black. */ | ||
@@ -906,0 +961,0 @@ color?: string; |
@@ -1,6 +0,7 @@ | ||
| import type { FileViewerPrintMaskOptions, FileViewerPrintMaskRegion } from '../contracts/types'; | ||
| import type { FileViewerPrintMaskOptions, FileViewerPrintMaskRegion, FileViewerPrintStamp } from '../contracts/types'; | ||
| export declare const normalizeFileViewerPrintMaskRegion: (region: Partial<FileViewerPrintMaskRegion> | null | undefined) => FileViewerPrintMaskRegion | null; | ||
| export declare const normalizeFileViewerPrintStamp: (stamp: Partial<FileViewerPrintStamp> | null | undefined) => FileViewerPrintStamp | null; | ||
| export declare const normalizeFileViewerPrintMaskOptions: (mask?: FileViewerPrintMaskOptions | null) => FileViewerPrintMaskOptions | null; | ||
| export declare const buildFileViewerPrintMaskOverlayHtml: (mask?: FileViewerPrintMaskOptions | null, pageScoped?: boolean) => string; | ||
| export declare const FILE_VIEWER_PRINT_MASK_STYLE = "\n .viewer-export-print-mask{position:absolute;inset:0;z-index:15;pointer-events:none;print-color-adjust:exact;-webkit-print-color-adjust:exact;}\n .viewer-export-print-mask--page{z-index:2147483647;}\n .viewer-export-print-mask-block{position:absolute;box-sizing:border-box;print-color-adjust:exact;-webkit-print-color-adjust:exact;}\n [data-viewer-print-page-index]{position:relative!important;isolation:isolate;}\n"; | ||
| export declare const FILE_VIEWER_PRINT_MASK_STYLE = "\n .viewer-export-print-mask{position:absolute;inset:0;z-index:15;pointer-events:none;print-color-adjust:exact;-webkit-print-color-adjust:exact;}\n .viewer-export-print-mask--page{z-index:2147483647;}\n .viewer-export-print-mask-block{position:absolute;box-sizing:border-box;print-color-adjust:exact;-webkit-print-color-adjust:exact;}\n .viewer-export-print-stamp{position:absolute;display:block;object-fit:contain;transform-origin:center center;print-color-adjust:exact;-webkit-print-color-adjust:exact;}\n [data-viewer-print-page-index]{position:relative!important;isolation:isolate;}\n"; | ||
| export declare const applyFileViewerPagePrintMasksToHtml: (contentHtml: string, mask?: FileViewerPrintMaskOptions | null) => string; |
@@ -26,29 +26,79 @@ const clampPercent = (value) => Math.max(0, Math.min(100, value)); | ||
| }; | ||
| const normalizeStampSource = (value) => { | ||
| if (typeof value !== 'string') { | ||
| return ''; | ||
| } | ||
| const source = value.trim(); | ||
| if (/^data:image\/(?:png|jpe?g|webp|gif|svg\+xml);/i.test(source) || | ||
| /^(?:blob:|https?:\/\/|\/|\.\.?\/)/i.test(source)) { | ||
| return source; | ||
| } | ||
| return ''; | ||
| }; | ||
| const clampOpacity = (value) => { | ||
| const opacity = Number(value); | ||
| return Number.isFinite(opacity) ? Math.max(0, Math.min(1, opacity)) : 1; | ||
| }; | ||
| const normalizeRotation = (value) => { | ||
| const rotation = Number(value); | ||
| if (!Number.isFinite(rotation)) { | ||
| return 0; | ||
| } | ||
| return ((rotation % 360) + 360) % 360; | ||
| }; | ||
| export const normalizeFileViewerPrintStamp = (stamp) => { | ||
| const region = normalizeFileViewerPrintMaskRegion(stamp); | ||
| const src = normalizeStampSource(stamp === null || stamp === void 0 ? void 0 : stamp.src); | ||
| if (!region || !src) { | ||
| return null; | ||
| } | ||
| return { | ||
| ...region, | ||
| src, | ||
| opacity: clampOpacity(stamp === null || stamp === void 0 ? void 0 : stamp.opacity), | ||
| rotate: normalizeRotation(stamp === null || stamp === void 0 ? void 0 : stamp.rotate), | ||
| ...(typeof (stamp === null || stamp === void 0 ? void 0 : stamp.alt) === 'string' && stamp.alt.trim() | ||
| ? { alt: stamp.alt.trim() } | ||
| : {}), | ||
| }; | ||
| }; | ||
| export const normalizeFileViewerPrintMaskOptions = (mask) => { | ||
| if (!mask || !Array.isArray(mask.regions) || !mask.regions.length) { | ||
| if (!mask) { | ||
| return null; | ||
| } | ||
| const regions = mask.regions | ||
| const regions = (mask.regions || []) | ||
| .map(region => normalizeFileViewerPrintMaskRegion(region)) | ||
| .filter((region) => !!region); | ||
| if (!regions.length) { | ||
| const stamps = (mask.stamps || []) | ||
| .map(stamp => normalizeFileViewerPrintStamp(stamp)) | ||
| .filter((stamp) => !!stamp); | ||
| if (!regions.length && !stamps.length) { | ||
| return null; | ||
| } | ||
| return { | ||
| regions, | ||
| ...(regions.length ? { regions } : {}), | ||
| ...(stamps.length ? { stamps } : {}), | ||
| color: mask.color || '#000000', | ||
| }; | ||
| }; | ||
| const escapeHtmlAttribute = (value) => value | ||
| .replace(/&/g, '&') | ||
| .replace(/"/g, '"') | ||
| .replace(/</g, '<') | ||
| .replace(/>/g, '>'); | ||
| export const buildFileViewerPrintMaskOverlayHtml = (mask, pageScoped = false) => { | ||
| var _a; | ||
| const normalized = normalizeFileViewerPrintMaskOptions(mask); | ||
| if (!((_a = normalized === null || normalized === void 0 ? void 0 : normalized.regions) === null || _a === void 0 ? void 0 : _a.length)) { | ||
| if (!normalized) { | ||
| return ''; | ||
| } | ||
| const color = normalized.color || '#000000'; | ||
| const blocks = normalized.regions.map(region => (`<div class="viewer-export-print-mask-block" style="left:${region.left}%;top:${region.top}%;width:${region.width}%;height:${region.height}%;background:${color};"></div>`)).join(''); | ||
| const blocks = (normalized.regions || []).map(region => (`<div class="viewer-export-print-mask-block" style="left:${region.left}%;top:${region.top}%;width:${region.width}%;height:${region.height}%;background:${color};"></div>`)).join(''); | ||
| const stamps = (normalized.stamps || []).map(stamp => { | ||
| var _a, _b; | ||
| return (`<img class="viewer-export-print-stamp" src="${escapeHtmlAttribute(stamp.src)}" alt="${escapeHtmlAttribute(stamp.alt || '')}" draggable="false" style="left:${stamp.left}%;top:${stamp.top}%;width:${stamp.width}%;height:${stamp.height}%;opacity:${(_a = stamp.opacity) !== null && _a !== void 0 ? _a : 1};transform:rotate(${(_b = stamp.rotate) !== null && _b !== void 0 ? _b : 0}deg);" />`); | ||
| }).join(''); | ||
| const className = pageScoped | ||
| ? 'viewer-export-print-mask viewer-export-print-mask--page' | ||
| : 'viewer-export-print-mask'; | ||
| return `<div class="${className}" aria-hidden="true">${blocks}</div>`; | ||
| return `<div class="${className}" aria-hidden="true">${blocks}${stamps}</div>`; | ||
| }; | ||
@@ -59,6 +109,7 @@ export const FILE_VIEWER_PRINT_MASK_STYLE = ` | ||
| .viewer-export-print-mask-block{position:absolute;box-sizing:border-box;print-color-adjust:exact;-webkit-print-color-adjust:exact;} | ||
| .viewer-export-print-stamp{position:absolute;display:block;object-fit:contain;transform-origin:center center;print-color-adjust:exact;-webkit-print-color-adjust:exact;} | ||
| [data-viewer-print-page-index]{position:relative!important;isolation:isolate;} | ||
| `; | ||
| export const applyFileViewerPagePrintMasksToHtml = (contentHtml, mask) => { | ||
| var _a; | ||
| var _a, _b; | ||
| const normalized = normalizeFileViewerPrintMaskOptions(mask); | ||
@@ -69,2 +120,3 @@ if (!normalized) { | ||
| const regionsByPage = new Map(); | ||
| const stampsByPage = new Map(); | ||
| (_a = normalized.regions) === null || _a === void 0 ? void 0 : _a.forEach(region => { | ||
@@ -78,3 +130,11 @@ if (region.pageIndex === undefined) { | ||
| }); | ||
| if (!regionsByPage.size) { | ||
| (_b = normalized.stamps) === null || _b === void 0 ? void 0 : _b.forEach(stamp => { | ||
| if (stamp.pageIndex === undefined) { | ||
| return; | ||
| } | ||
| const pageStamps = stampsByPage.get(stamp.pageIndex) || []; | ||
| pageStamps.push(stamp); | ||
| stampsByPage.set(stamp.pageIndex, pageStamps); | ||
| }); | ||
| if (!regionsByPage.size && !stampsByPage.size) { | ||
| return contentHtml; | ||
@@ -84,7 +144,9 @@ } | ||
| const pageRegions = regionsByPage.get(Number(rawPageIndex)); | ||
| if (!(pageRegions === null || pageRegions === void 0 ? void 0 : pageRegions.length)) { | ||
| const pageStamps = stampsByPage.get(Number(rawPageIndex)); | ||
| if (!(pageRegions === null || pageRegions === void 0 ? void 0 : pageRegions.length) && !(pageStamps === null || pageStamps === void 0 ? void 0 : pageStamps.length)) { | ||
| return match; | ||
| } | ||
| return `${openingTag}${buildFileViewerPrintMaskOverlayHtml({ | ||
| regions: pageRegions, | ||
| regions: pageRegions || [], | ||
| stamps: pageStamps || [], | ||
| color: normalized.color, | ||
@@ -91,0 +153,0 @@ }, true)}`; |
@@ -1,2 +0,2 @@ | ||
| import type { FileViewerPrintMaskOptions, FileViewerPrintMaskRegion } from '../contracts/types'; | ||
| import type { FileViewerPrintMaskOptions, FileViewerPrintMaskRegion, FileViewerPrintStamp } from '../contracts/types'; | ||
| import { type FileViewerI18nInput } from '../i18n/messages'; | ||
@@ -9,2 +9,3 @@ export interface OpenFileViewerPrintMaskDesignerOptions { | ||
| initialRegions?: FileViewerPrintMaskRegion[]; | ||
| initialStamps?: FileViewerPrintStamp[]; | ||
| } | ||
@@ -11,0 +12,0 @@ export interface FileViewerPrintMaskDesignerResult { |
| import { createFileViewerTranslator } from '../i18n/messages.js'; | ||
| import { normalizeFileViewerPrintMaskRegion } from './printMask.js'; | ||
| import { normalizeFileViewerPrintMaskRegion, normalizeFileViewerPrintStamp, } from './printMask.js'; | ||
| const DESIGNER_STYLE = ` | ||
@@ -9,2 +9,6 @@ .fv-print-mask-layer{position:absolute;inset:0;z-index:2147483000;pointer-events:none;} | ||
| .fv-print-mask-block-remove{position:absolute;right:-8px;top:-8px;width:18px;height:18px;border:0;border-radius:999px;background:#111;color:#fff;font:700 12px/18px system-ui,sans-serif;cursor:pointer;padding:0;} | ||
| .fv-print-stamp{position:absolute;box-sizing:border-box;border:1px dashed rgba(22,119,76,.7);border-radius:4px;pointer-events:auto;touch-action:none;cursor:move;transform-origin:center center;} | ||
| .fv-print-stamp img{display:block;width:100%;height:100%;object-fit:contain;pointer-events:none;user-select:none;} | ||
| .fv-print-stamp-resize{position:absolute;right:-7px;bottom:-7px;width:15px;height:15px;border:2px solid #fff;border-radius:4px;background:#16774c;box-shadow:0 1px 5px rgba(15,23,42,.22);cursor:nwse-resize;touch-action:none;} | ||
| .fv-print-stamp-input{display:none!important;} | ||
| .fv-print-mask-toolbar{position:absolute;left:50%;bottom:16px;transform:translateX(-50%);z-index:2147483001;display:inline-flex;align-items:center;gap:6px;padding:6px 8px;border:1px solid rgba(20,35,53,.12);border-radius:999px;background:rgba(255,255,255,.94);box-shadow:0 12px 28px rgba(15,23,42,.16);pointer-events:auto;max-width:calc(100% - 24px);flex-wrap:wrap;justify-content:center;} | ||
@@ -56,2 +60,20 @@ .fv-print-mask-toolbar span{font:600 12px/1.2 system-ui,sans-serif;color:#40546a;white-space:nowrap;} | ||
| }; | ||
| const MAX_PRINT_STAMP_BYTES = 10 * 1024 * 1024; | ||
| const readStampFileAsDataUrl = (file, windowRef) => new Promise((resolve, reject) => { | ||
| if (!/^image\/(?:png|jpe?g|webp|gif|svg\+xml)$/i.test(file.type) || file.size > MAX_PRINT_STAMP_BYTES) { | ||
| reject(new Error('Unsupported print stamp image')); | ||
| return; | ||
| } | ||
| const Reader = (windowRef === null || windowRef === void 0 ? void 0 : windowRef.FileReader) || globalThis.FileReader; | ||
| const reader = new Reader(); | ||
| reader.addEventListener('load', () => { | ||
| if (typeof reader.result === 'string' && reader.result.startsWith('data:image/')) { | ||
| resolve(reader.result); | ||
| return; | ||
| } | ||
| reject(new Error('Invalid print stamp image')); | ||
| }); | ||
| reader.addEventListener('error', () => reject(reader.error || new Error('Failed to read print stamp image'))); | ||
| reader.readAsDataURL(file); | ||
| }); | ||
| /** | ||
@@ -69,2 +91,5 @@ * Opens a page-aware print-mask designer. Browsing remains the default mode; | ||
| .filter((region) => !!region); | ||
| const stamps = [...(options.initialStamps || [])] | ||
| .map(stamp => normalizeFileViewerPrintStamp(stamp)) | ||
| .filter((stamp) => !!stamp); | ||
| const providedPages = Array.from(new Set(options.pages || [])) | ||
@@ -110,3 +135,4 @@ .filter(page => page === root || root.contains(page)); | ||
| !surfaces.some(surface => surface.element === root) && | ||
| regions.some(region => region.pageIndex === undefined) | ||
| (regions.some(region => region.pageIndex === undefined) || | ||
| stamps.some(stamp => stamp.pageIndex === undefined)) | ||
| ? createSurface(root) | ||
@@ -124,2 +150,10 @@ : null; | ||
| addButton.textContent = t('toolbar.printMaskAdd'); | ||
| const stampInput = documentRef.createElement('input'); | ||
| stampInput.type = 'file'; | ||
| stampInput.accept = 'image/png,image/jpeg,image/webp,image/gif,image/svg+xml'; | ||
| stampInput.className = 'fv-print-stamp-input'; | ||
| stampInput.setAttribute('data-viewer-print-stamp-input', 'true'); | ||
| const stampButton = documentRef.createElement('button'); | ||
| stampButton.type = 'button'; | ||
| stampButton.textContent = t('toolbar.printStampUpload'); | ||
| const clearButton = documentRef.createElement('button'); | ||
@@ -135,4 +169,4 @@ clearButton.type = 'button'; | ||
| confirmButton.textContent = t('toolbar.printMaskConfirm'); | ||
| toolbar.append(hint, addButton, clearButton, cancelButton, confirmButton); | ||
| layer.append(toolbar); | ||
| toolbar.append(hint, addButton, stampButton, clearButton, cancelButton, confirmButton); | ||
| layer.append(stampInput, toolbar); | ||
| root.appendChild(layer); | ||
@@ -166,7 +200,7 @@ const disarm = () => { | ||
| }; | ||
| const surfaceForRegion = (region) => { | ||
| if (region.pageIndex === undefined) { | ||
| const surfaceForItem = (item) => { | ||
| if (item.pageIndex === undefined) { | ||
| return legacySurface || surfaces[0]; | ||
| } | ||
| return surfaces.find(surface => surface.pageIndex === region.pageIndex) || null; | ||
| return surfaces.find(surface => surface.pageIndex === item.pageIndex) || null; | ||
| }; | ||
@@ -176,3 +210,3 @@ const renderRegions = () => { | ||
| regions.forEach((region, index) => { | ||
| const surface = surfaceForRegion(region); | ||
| const surface = surfaceForItem(region); | ||
| if (!surface) { | ||
@@ -203,2 +237,101 @@ return; | ||
| }); | ||
| stamps.forEach((stamp, index) => { | ||
| const surface = surfaceForItem(stamp); | ||
| if (!surface) { | ||
| return; | ||
| } | ||
| const stampElement = documentRef.createElement('div'); | ||
| stampElement.className = 'fv-print-stamp'; | ||
| stampElement.setAttribute('data-viewer-print-stamp', String(index)); | ||
| const applyStampStyle = () => { | ||
| var _a, _b; | ||
| stampElement.style.left = `${stamp.left}%`; | ||
| stampElement.style.top = `${stamp.top}%`; | ||
| stampElement.style.width = `${stamp.width}%`; | ||
| stampElement.style.height = `${stamp.height}%`; | ||
| stampElement.style.opacity = String((_a = stamp.opacity) !== null && _a !== void 0 ? _a : 1); | ||
| stampElement.style.transform = `rotate(${(_b = stamp.rotate) !== null && _b !== void 0 ? _b : 0}deg)`; | ||
| }; | ||
| applyStampStyle(); | ||
| const image = documentRef.createElement('img'); | ||
| image.src = stamp.src; | ||
| image.alt = stamp.alt || ''; | ||
| image.draggable = false; | ||
| const remove = documentRef.createElement('button'); | ||
| remove.type = 'button'; | ||
| remove.className = 'fv-print-mask-block-remove'; | ||
| remove.title = t('toolbar.printStampRemove'); | ||
| remove.setAttribute('aria-label', t('toolbar.printStampRemove')); | ||
| remove.textContent = '−'; | ||
| remove.addEventListener('pointerdown', event => event.stopPropagation()); | ||
| remove.addEventListener('click', event => { | ||
| event.preventDefault(); | ||
| event.stopPropagation(); | ||
| stamps.splice(index, 1); | ||
| renderRegions(); | ||
| }); | ||
| const resize = documentRef.createElement('span'); | ||
| resize.className = 'fv-print-stamp-resize'; | ||
| resize.setAttribute('role', 'button'); | ||
| resize.setAttribute('aria-label', t('toolbar.printStampResize')); | ||
| resize.title = t('toolbar.printStampResize'); | ||
| let interaction = null; | ||
| stampElement.addEventListener('pointerdown', event => { | ||
| var _a; | ||
| if (event.button !== 0 || event.target.closest('button')) { | ||
| return; | ||
| } | ||
| event.preventDefault(); | ||
| event.stopPropagation(); | ||
| interaction = { | ||
| pointerId: event.pointerId, | ||
| mode: event.target === resize ? 'resize' : 'move', | ||
| startX: event.clientX, | ||
| startY: event.clientY, | ||
| left: stamp.left, | ||
| top: stamp.top, | ||
| width: stamp.width, | ||
| height: stamp.height, | ||
| }; | ||
| (_a = stampElement.setPointerCapture) === null || _a === void 0 ? void 0 : _a.call(stampElement, event.pointerId); | ||
| }); | ||
| stampElement.addEventListener('pointermove', event => { | ||
| if (!interaction || interaction.pointerId !== event.pointerId) { | ||
| return; | ||
| } | ||
| event.preventDefault(); | ||
| const bounds = surface.canvas.getBoundingClientRect(); | ||
| if (!bounds.width || !bounds.height) { | ||
| return; | ||
| } | ||
| const deltaX = ((event.clientX - interaction.startX) / bounds.width) * 100; | ||
| const deltaY = ((event.clientY - interaction.startY) / bounds.height) * 100; | ||
| if (interaction.mode === 'move') { | ||
| stamp.left = Math.max(0, Math.min(100 - stamp.width, interaction.left + deltaX)); | ||
| stamp.top = Math.max(0, Math.min(100 - stamp.height, interaction.top + deltaY)); | ||
| } | ||
| else { | ||
| stamp.width = Math.max(4, Math.min(100 - stamp.left, interaction.width + deltaX)); | ||
| stamp.height = Math.max(4, Math.min(100 - stamp.top, interaction.height + deltaY)); | ||
| } | ||
| applyStampStyle(); | ||
| }); | ||
| const endInteraction = (event) => { | ||
| var _a; | ||
| if (!interaction || interaction.pointerId !== event.pointerId) { | ||
| return; | ||
| } | ||
| try { | ||
| (_a = stampElement.releasePointerCapture) === null || _a === void 0 ? void 0 : _a.call(stampElement, interaction.pointerId); | ||
| } | ||
| catch { | ||
| // Pointer capture may already be released by the browser. | ||
| } | ||
| interaction = null; | ||
| }; | ||
| stampElement.addEventListener('pointerup', endInteraction); | ||
| stampElement.addEventListener('pointercancel', endInteraction); | ||
| stampElement.append(image, remove, resize); | ||
| surface.canvas.appendChild(stampElement); | ||
| }); | ||
| }; | ||
@@ -269,14 +402,53 @@ const pointFromEvent = (event, canvas) => { | ||
| }); | ||
| addButton.addEventListener('click', () => { | ||
| const getActiveSurface = () => { | ||
| var _a; | ||
| disarm(); | ||
| const viewport = root.getBoundingClientRect(); | ||
| const activeSurface = ((_a = surfaces | ||
| return ((_a = surfaces | ||
| .map(surface => ({ surface, area: visibleArea(surface.element, viewport) })) | ||
| .sort((left, right) => right.area - left.area)[0]) === null || _a === void 0 ? void 0 : _a.surface) || surfaces[0]; | ||
| }; | ||
| addButton.addEventListener('click', () => { | ||
| disarm(); | ||
| const activeSurface = getActiveSurface(); | ||
| activeSurface === null || activeSurface === void 0 ? void 0 : activeSurface.canvas.classList.add('is-armed'); | ||
| addButton.classList.toggle('is-active', Boolean(activeSurface)); | ||
| }); | ||
| stampButton.addEventListener('click', () => { | ||
| disarm(); | ||
| stampInput.click(); | ||
| }); | ||
| stampInput.addEventListener('change', async () => { | ||
| var _a; | ||
| const file = (_a = stampInput.files) === null || _a === void 0 ? void 0 : _a[0]; | ||
| stampInput.value = ''; | ||
| if (!file) { | ||
| return; | ||
| } | ||
| try { | ||
| const src = await readStampFileAsDataUrl(file, documentRef.defaultView); | ||
| const activeSurface = getActiveSurface(); | ||
| if (!activeSurface) { | ||
| return; | ||
| } | ||
| const stamp = normalizeFileViewerPrintStamp({ | ||
| src, | ||
| alt: file.name, | ||
| left: 38, | ||
| top: 38, | ||
| width: 24, | ||
| height: 18, | ||
| pageIndex: activeSurface.pageIndex, | ||
| }); | ||
| if (stamp) { | ||
| stamps.push(stamp); | ||
| renderRegions(); | ||
| } | ||
| } | ||
| catch { | ||
| // Unsupported or unreadable images are ignored; the document stays untouched. | ||
| } | ||
| }); | ||
| clearButton.addEventListener('click', () => { | ||
| regions.splice(0, regions.length); | ||
| stamps.splice(0, stamps.length); | ||
| disarm(); | ||
@@ -287,3 +459,3 @@ renderRegions(); | ||
| confirmButton.addEventListener('click', () => { | ||
| if (!regions.length) { | ||
| if (!regions.length && !stamps.length) { | ||
| finish(null); | ||
@@ -294,3 +466,4 @@ return; | ||
| mask: { | ||
| regions: regions.map(region => ({ ...region })), | ||
| ...(regions.length ? { regions: regions.map(region => ({ ...region })) } : {}), | ||
| ...(stamps.length ? { stamps: stamps.map(stamp => ({ ...stamp })) } : {}), | ||
| color, | ||
@@ -297,0 +470,0 @@ }, |
@@ -6,2 +6,4 @@ export { DEFAULT_FILE_VIEWER_ARCHIVE_WORKER_PATH, DEFAULT_FILE_VIEWER_ARCHIVE_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_DWF_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_LIBREDWG_SCRIPT_PATH, DEFAULT_FILE_VIEWER_CAD_LIBREDWG_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_RUNTIME_VERSION, DEFAULT_FILE_VIEWER_CAD_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_WORKER_PATH, DEFAULT_FILE_VIEWER_DATA_SQL_WASM_URL, DEFAULT_FILE_VIEWER_DOCX_WORKER_JSZIP_PATH, DEFAULT_FILE_VIEWER_DOCX_WORKER_PATH, DEFAULT_FILE_VIEWER_DOCX_RUNTIME_VERSION, DEFAULT_FILE_VIEWER_PPT_FONT_PATH, DEFAULT_FILE_VIEWER_PPT_FRAME_CACHE_PATH, DEFAULT_FILE_VIEWER_PPT_MODULE_PATH, DEFAULT_FILE_VIEWER_PPT_RUNTIME_PATH, DEFAULT_FILE_VIEWER_PPT_RUNTIME_VERSION, DEFAULT_FILE_VIEWER_PPT_WASM_PATH, DEFAULT_FILE_VIEWER_PPT_WORKER_PATH, DEFAULT_FILE_VIEWER_PRESENTATION_WORKER_PATH, DEFAULT_FILE_VIEWER_RENDERER_ASSET_MANIFESTS, DEFAULT_FILE_VIEWER_SPREADSHEET_WORKER_PATH, DEFAULT_FILE_VIEWER_TYPST_COMPILER_WASM_URL, DEFAULT_FILE_VIEWER_TYPST_RENDERER_WASM_PACKAGE_PATH, DEFAULT_FILE_VIEWER_TYPST_RENDERER_WASM_URL, getFileViewerRendererAssetManifest, listFileViewerRendererAssetManifests, resolveFileViewerArchiveWasmUrl, resolveFileViewerArchiveWorkerUrl, resolveFileViewerAssetUrl, resolveFileViewerCadAssetUrls, resolveFileViewerDataSqlWasmUrl, resolveFileViewerDocxWorkerJsZipUrl, resolveFileViewerDocxWorkerUrl, resolveFileViewerDrawioViewerScriptUrl, resolveFileViewerPresentationWorkerUrl, resolveFileViewerRendererAssets, resolveFileViewerSpreadsheetWorkerUrl, resolveFileViewerTypstCompilerWasmUrl, resolveFileViewerTypstRendererWasmUrl, } from './assets'; | ||
| export { ARCHIVE_EXTENSIONS, DEFAULT_RENDERER_DEFINITIONS, DEFAULT_SUPPORTED_EXTENSIONS, IMAGE_EXTENSIONS, MODEL_EXTENSIONS, TEXT_EXTENSIONS, } from './registry/formats'; | ||
| export { precheckFileViewerSource } from './source/precheck'; | ||
| export type { FileViewerPrecheckOptions, FileViewerPrecheckReason, FileViewerPrecheckResult, FileViewerPrecheckStatus, } from './source/precheck'; | ||
| export { FILE_VIEWER_BEFORE_OPERATION_ERROR_PREFIX, DEFAULT_FILE_VIEWER_TOOLBAR_ORDER, FILE_VIEWER_LIFECYCLE_HOOK_ERROR_MESSAGE_PREFIX, FILE_VIEWER_LIFECYCLE_HOOKS, FILE_VIEWER_OPERATION_LABELS, buildFileViewerLifecycleContext, buildFileViewerLifecycleContextFromNormalizedSource, buildFileViewerOperationContext, buildFileViewerOperationContextFromLifecycleState, cloneFileViewerOperationAvailability, createFileViewerLifecycleActions, createFileViewerLifecycleStateController, createFileViewerPublicApi, createFileViewerToolbarActions, createFileViewerToolbarControllerActionHandlers, createFileViewerToolbarZoomSyncSnapshot, DEFAULT_FILE_VIEWER_LIFECYCLE_HOOK_ERROR_LOGGER, DEFAULT_FILE_VIEWER_OPERATION_ERROR_LOGGER, dispatchFileViewerLifecycleEvent, dispatchFileViewerOperationAvailabilityChange, dispatchFileViewerOperationContextEvent, dispatchFileViewerZoomChange, emitFileViewerComponentLifecycleEvent, getFileViewerBeforeOperationHooks, getFileViewerLifecycleHookName, hasVisibleFileViewerToolbarActions, isFileViewerToolbarOperationPermitted, isFileViewerZoomButtonDisabled, normalizeFileViewerToolbar, reportFileViewerLifecycleHookError, reportFileViewerOperationError, resolveFileViewerBeforeOperationErrorMessage, resolveFileViewerLifecycleFallbackSource, resolveFileViewerLifecycleHookErrorMessage, resolveFileViewerOperationAvailability, resolveFileViewerToolbarPosition, resolveFileViewerToolbarOrder, resolveFileViewerToolbarState, resolveVisibleFileViewerToolbar, runFileViewerActiveUnloadComplete, runFileViewerActiveUnloadStart, runFileViewerBeforeOperation, runFileViewerLifecycleHook, runFileViewerToolbarAvailabilitySync, runFileViewerToolbarZoomSync, serializeFileViewerContext, } from './lifecycle/operations'; | ||
@@ -28,2 +30,2 @@ export { FILE_VIEWER_BUILTIN_MESSAGES, FILE_VIEWER_DEFAULT_LOCALE, FILE_VIEWER_FALLBACK_LOCALE, FILE_VIEWER_SUPPORTED_LOCALES, createFileViewerTranslator, formatFileViewerMessage, normalizeFileViewerLocale, resolveFileViewerLocale, translateFileViewerMessage, } from './i18n/messages'; | ||
| export type { FileViewerWatermarkPresentationState, FileViewerWatermarkStyle, } from './features/watermark'; | ||
| export type { FileRenderContext, FileRenderExportAdapter, FileRenderExportMode, FileRenderExportOptions, FileRenderHandler, FileRenderHandlerComposite, FileViewerBuiltinRendererPreset, FileViewerAiOptions, FileViewerArchiveEntryActionContext, FileViewerArchiveEntryActionPolicy, FileViewerArchiveEntryActionsOptions, FileViewerArchiveOptions, FileViewerApplyViewStateOptions, FileViewerBeforeOperation, FileViewerCadDwfLineWeightMode, FileViewerCadOptions, FileViewerCadRenderer, FileViewerComponentEmits, FileViewerComponentEventMap, FileViewerComponentProps, FileViewerDocumentAnchor, FileViewerDocumentChunk, FileViewerDocxOptions, FileViewerDrawingOptions, FileViewerDownloadOptions, FileViewerEvent, FileViewerEventHandler, FileViewerEventType, FileViewerExportHtmlOptions, FileViewerFileRef, FileViewerFitMode, FileViewerFitOptions, FileViewerFitRequest, FileViewerFitResize, FileViewerFitResult, FileViewerGeoOptions, FileViewerInstance, FileViewerLifecycleContext, FileViewerLifecycleHooks, FileViewerLifecyclePhase, FileViewerI18nOptions, FileViewerLocale, FileViewerMessageKey, FileViewerMessageParams, FileViewerMessageResolver, FileViewerMessages, FileViewerNavigationState, FileViewerOperationAvailability, FileViewerOperationContext, FileViewerOperationType, FileViewerOptions, FileViewerPdfOptions, FileViewerPresentationOptions, FileViewerPrintOptions, FileViewerPublicApi, FileViewerRenderStateKind, FileViewerRenderedInstance, FileViewerRendererCategory, FileViewerSearchMatch, FileViewerSearchOptions, FileViewerSearchProvider, FileViewerSearchState, FileViewerSource, FileViewerSourceKind, FileViewerSpreadsheetOptions, FileViewerStateDescriptor, FileViewerStateTheme, FileViewerTextOptions, FileViewerResolvedThemeMode, FileViewerThemeMode, FileViewerToolbarActionMap, FileViewerToolbarItem, FileViewerToolbarOptions, FileViewerToolbarPosition, FileViewerResolvedToolbarItem, FileViewerUiDensity, FileViewerUiOptions, FileViewerTypstOptions, FileViewerViewScrollState, FileViewerViewState, FileViewerViewStateChange, FileViewerViewStateChangeAction, FileViewerViewStateChangeSource, FileViewerViewStateProvider, FileViewerWatermarkOptions, FileViewerZoomProvider, FileViewerZoomState, NormalizedFileViewerSource, RenderSurface, RendererCapability, RendererDefinition, RendererLoadContext, RendererLoader, RendererPlugin, RendererRegistry, RendererSession, ViewerCapabilityState, ViewerLifecycleContext, ViewerOperationContext, } from './contracts/types'; | ||
| export type { FileRenderContext, FileRenderExportAdapter, FileRenderExportMode, FileRenderExportOptions, FileRenderHandler, FileRenderHandlerComposite, FileViewerBuiltinRendererPreset, FileViewerAiOptions, FileViewerArchiveEntryActionContext, FileViewerArchiveEntryActionPolicy, FileViewerArchiveEntryActionsOptions, FileViewerArchiveOptions, FileViewerApplyViewStateOptions, FileViewerBeforeOperation, FileViewerCadDwfLineWeightMode, FileViewerCadOptions, FileViewerCadRenderer, FileViewerComponentEmits, FileViewerComponentEventMap, FileViewerComponentProps, FileViewerDocumentAnchor, FileViewerDocumentChunk, FileViewerDocxOptions, FileViewerDrawingOptions, FileViewerDownloadOptions, FileViewerEvent, FileViewerEventHandler, FileViewerEventType, FileViewerExportHtmlOptions, FileViewerFileRef, FileViewerFitMode, FileViewerFitOptions, FileViewerFitRequest, FileViewerFitResize, FileViewerFitResult, FileViewerGeoOptions, FileViewerInstance, FileViewerLifecycleContext, FileViewerLifecycleHooks, FileViewerLifecyclePhase, FileViewerI18nOptions, FileViewerLocale, FileViewerMessageKey, FileViewerMessageParams, FileViewerMessageResolver, FileViewerMessages, FileViewerNavigationState, FileViewerOperationAvailability, FileViewerOperationContext, FileViewerOperationType, FileViewerOptions, FileViewerPdfBoundingBox, FileViewerPdfBoundingBoxOrigin, FileViewerPdfBoundingBoxUnit, FileViewerPdfOptions, FileViewerPresentationOptions, FileViewerPrintMaskOptions, FileViewerPrintMaskRegion, FileViewerPrintOptions, FileViewerPrintStamp, FileViewerPublicApi, FileViewerRenderStateKind, FileViewerRenderedInstance, FileViewerRendererCategory, FileViewerSearchMatch, FileViewerSearchOptions, FileViewerSearchProvider, FileViewerSearchState, FileViewerSource, FileViewerSourceKind, FileViewerSpreadsheetOptions, FileViewerStateDescriptor, FileViewerStateTheme, FileViewerTextOptions, FileViewerResolvedThemeMode, FileViewerThemeMode, FileViewerToolbarActionMap, FileViewerToolbarItem, FileViewerToolbarOptions, FileViewerToolbarPosition, FileViewerResolvedToolbarItem, FileViewerUiDensity, FileViewerUiOptions, FileViewerTypstOptions, FileViewerViewScrollState, FileViewerViewState, FileViewerViewStateChange, FileViewerViewStateChangeAction, FileViewerViewStateChangeSource, FileViewerViewStateProvider, FileViewerWatermarkOptions, FileViewerZoomProvider, FileViewerZoomState, NormalizedFileViewerSource, RenderSurface, RendererCapability, RendererDefinition, RendererLoadContext, RendererLoader, RendererPlugin, RendererRegistry, RendererSession, ViewerCapabilityState, ViewerLifecycleContext, ViewerOperationContext, } from './contracts/types'; |
+1
-0
@@ -10,2 +10,3 @@ // Headless API surface for adapters and non-DOM orchestration. | ||
| export { ARCHIVE_EXTENSIONS, DEFAULT_RENDERER_DEFINITIONS, DEFAULT_SUPPORTED_EXTENSIONS, IMAGE_EXTENSIONS, MODEL_EXTENSIONS, TEXT_EXTENSIONS, } from './registry/formats.js'; | ||
| export { precheckFileViewerSource } from './source/precheck.js'; | ||
| export { FILE_VIEWER_BEFORE_OPERATION_ERROR_PREFIX, DEFAULT_FILE_VIEWER_TOOLBAR_ORDER, FILE_VIEWER_LIFECYCLE_HOOK_ERROR_MESSAGE_PREFIX, FILE_VIEWER_LIFECYCLE_HOOKS, FILE_VIEWER_OPERATION_LABELS, buildFileViewerLifecycleContext, buildFileViewerLifecycleContextFromNormalizedSource, buildFileViewerOperationContext, buildFileViewerOperationContextFromLifecycleState, cloneFileViewerOperationAvailability, createFileViewerLifecycleActions, createFileViewerLifecycleStateController, createFileViewerPublicApi, createFileViewerToolbarActions, createFileViewerToolbarControllerActionHandlers, createFileViewerToolbarZoomSyncSnapshot, DEFAULT_FILE_VIEWER_LIFECYCLE_HOOK_ERROR_LOGGER, DEFAULT_FILE_VIEWER_OPERATION_ERROR_LOGGER, dispatchFileViewerLifecycleEvent, dispatchFileViewerOperationAvailabilityChange, dispatchFileViewerOperationContextEvent, dispatchFileViewerZoomChange, emitFileViewerComponentLifecycleEvent, getFileViewerBeforeOperationHooks, getFileViewerLifecycleHookName, hasVisibleFileViewerToolbarActions, isFileViewerToolbarOperationPermitted, isFileViewerZoomButtonDisabled, normalizeFileViewerToolbar, reportFileViewerLifecycleHookError, reportFileViewerOperationError, resolveFileViewerBeforeOperationErrorMessage, resolveFileViewerLifecycleFallbackSource, resolveFileViewerLifecycleHookErrorMessage, resolveFileViewerOperationAvailability, resolveFileViewerToolbarPosition, resolveFileViewerToolbarOrder, resolveFileViewerToolbarState, resolveVisibleFileViewerToolbar, runFileViewerActiveUnloadComplete, runFileViewerActiveUnloadStart, runFileViewerBeforeOperation, runFileViewerLifecycleHook, runFileViewerToolbarAvailabilitySync, runFileViewerToolbarZoomSync, serializeFileViewerContext, } from './lifecycle/operations.js'; | ||
@@ -12,0 +13,0 @@ export { FILE_VIEWER_BUILTIN_MESSAGES, FILE_VIEWER_DEFAULT_LOCALE, FILE_VIEWER_FALLBACK_LOCALE, FILE_VIEWER_SUPPORTED_LOCALES, createFileViewerTranslator, formatFileViewerMessage, normalizeFileViewerLocale, resolveFileViewerLocale, translateFileViewerMessage, } from './i18n/messages.js'; |
@@ -16,4 +16,4 @@ /** | ||
| 'toolbar.printDirect': '直接印刷', | ||
| 'toolbar.printMask': 'マスクして印刷', | ||
| 'toolbar.printMaskTitle': '機密領域を隠してから印刷', | ||
| 'toolbar.printMask': 'マスク・印章付き印刷', | ||
| 'toolbar.printMaskTitle': '機密領域を隠すか印章を追加してから印刷', | ||
| 'toolbar.printMaskAdd': 'マスクを追加', | ||
@@ -23,3 +23,6 @@ 'toolbar.printMaskClear': 'クリア', | ||
| 'toolbar.printMaskConfirm': '印刷を確定', | ||
| 'toolbar.printMaskHint': 'ドラッグして黒いマスクを描画します。削除して再調整できます。', | ||
| 'toolbar.printMaskHint': 'マスクを描画するか、印章をアップロードして移動・サイズ変更します。', | ||
| 'toolbar.printStampUpload': '印章をアップロード', | ||
| 'toolbar.printStampRemove': '印章を削除', | ||
| 'toolbar.printStampResize': '印章のサイズ変更', | ||
| 'toolbar.exportHtml': 'HTML', | ||
@@ -337,2 +340,5 @@ 'toolbar.exportHtmlTitle': '現在のレンダリング結果を HTML として書き出す', | ||
| 'image.alt': '画像', | ||
| 'image.toolbar.rotation': '画像の回転', | ||
| 'image.toolbar.rotateLeft': '画像を左に回転', | ||
| 'image.toolbar.rotateRight': '画像を右に回転', | ||
| 'image.lightbox.alt': '画像プレビュー', | ||
@@ -339,0 +345,0 @@ 'image.lightbox.close': '画像プレビューを閉じる', |
@@ -15,4 +15,4 @@ import { JA_JP_MESSAGES } from './messages.ja.js'; | ||
| 'toolbar.printDirect': '直接打印', | ||
| 'toolbar.printMask': '掩膜打印', | ||
| 'toolbar.printMaskTitle': '遮盖敏感区域后再打印', | ||
| 'toolbar.printMask': '遮罩/盖章打印', | ||
| 'toolbar.printMaskTitle': '遮盖敏感区域或上传印章后再打印', | ||
| 'toolbar.printMaskAdd': '添加掩膜', | ||
@@ -22,3 +22,6 @@ 'toolbar.printMaskClear': '清空', | ||
| 'toolbar.printMaskConfirm': '确认打印', | ||
| 'toolbar.printMaskHint': '拖拽绘制黑色遮盖块,可删除后继续调整', | ||
| 'toolbar.printMaskHint': '绘制遮盖块,或上传印章后拖动和缩放', | ||
| 'toolbar.printStampUpload': '上传印章', | ||
| 'toolbar.printStampRemove': '删除印章', | ||
| 'toolbar.printStampResize': '缩放印章', | ||
| 'toolbar.exportHtml': 'HTML', | ||
@@ -336,2 +339,5 @@ 'toolbar.exportHtmlTitle': '导出当前渲染后的 HTML', | ||
| 'image.alt': '图片', | ||
| 'image.toolbar.rotation': '图片旋转', | ||
| 'image.toolbar.rotateLeft': '向左旋转图片', | ||
| 'image.toolbar.rotateRight': '向右旋转图片', | ||
| 'image.lightbox.alt': '图片预览', | ||
@@ -442,4 +448,4 @@ 'image.lightbox.close': '关闭图片预览', | ||
| 'toolbar.printDirect': 'Print now', | ||
| 'toolbar.printMask': 'Mask & print', | ||
| 'toolbar.printMaskTitle': 'Cover sensitive areas before printing', | ||
| 'toolbar.printMask': 'Mask / stamp & print', | ||
| 'toolbar.printMaskTitle': 'Cover sensitive areas or add a stamp before printing', | ||
| 'toolbar.printMaskAdd': 'Add mask', | ||
@@ -449,3 +455,6 @@ 'toolbar.printMaskClear': 'Clear', | ||
| 'toolbar.printMaskConfirm': 'Print', | ||
| 'toolbar.printMaskHint': 'Drag to draw black cover blocks. Delete and adjust as needed.', | ||
| 'toolbar.printMaskHint': 'Draw cover blocks, or upload a stamp and drag or resize it.', | ||
| 'toolbar.printStampUpload': 'Upload stamp', | ||
| 'toolbar.printStampRemove': 'Remove stamp', | ||
| 'toolbar.printStampResize': 'Resize stamp', | ||
| 'toolbar.exportHtml': 'HTML', | ||
@@ -763,2 +772,5 @@ 'toolbar.exportHtmlTitle': 'Export the rendered HTML', | ||
| 'image.alt': 'Image', | ||
| 'image.toolbar.rotation': 'Image rotation', | ||
| 'image.toolbar.rotateLeft': 'Rotate image left', | ||
| 'image.toolbar.rotateRight': 'Rotate image right', | ||
| 'image.lightbox.alt': 'Image preview', | ||
@@ -765,0 +777,0 @@ 'image.lightbox.close': 'Close image preview', |
+4
-2
| import type { FileRenderContext, FileViewerRenderedInstance } from './contracts/types'; | ||
| export { DEFAULT_FILE_VIEWER_ARCHIVE_WORKER_PATH, DEFAULT_FILE_VIEWER_ARCHIVE_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_DWF_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_LIBREDWG_SCRIPT_PATH, DEFAULT_FILE_VIEWER_CAD_LIBREDWG_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_RUNTIME_VERSION, DEFAULT_FILE_VIEWER_CAD_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_WORKER_PATH, DEFAULT_FILE_VIEWER_DATA_SQL_WASM_URL, DEFAULT_FILE_VIEWER_MODEL_RUNTIME_PACKAGE_PATH, DEFAULT_FILE_VIEWER_MODEL_RUNTIME_URL, DEFAULT_FILE_VIEWER_MODEL_IMPORT_LICENSE_PACKAGE_PATH, DEFAULT_FILE_VIEWER_MODEL_IMPORT_LICENSE_URL, DEFAULT_FILE_VIEWER_MODEL_OCCT_LICENSE_PACKAGE_PATH, DEFAULT_FILE_VIEWER_MODEL_OCCT_LICENSE_URL, DEFAULT_FILE_VIEWER_MODEL_WASM_PACKAGE_PATH, DEFAULT_FILE_VIEWER_MODEL_WASM_URL, DEFAULT_FILE_VIEWER_MODEL_WORKER_URL, DEFAULT_FILE_VIEWER_DOCX_WORKER_JSZIP_PATH, DEFAULT_FILE_VIEWER_DOCX_WORKER_PATH, DEFAULT_FILE_VIEWER_DOCX_RUNTIME_VERSION, DEFAULT_FILE_VIEWER_PDF_CMAP_PATH, DEFAULT_FILE_VIEWER_PDF_STANDARD_FONT_PATH, DEFAULT_FILE_VIEWER_PDF_WASM_PATH, DEFAULT_FILE_VIEWER_PDF_WORKER_PATH, DEFAULT_FILE_VIEWER_PPT_FONT_PATH, DEFAULT_FILE_VIEWER_PPT_FRAME_CACHE_PATH, DEFAULT_FILE_VIEWER_PPT_MODULE_PATH, DEFAULT_FILE_VIEWER_PPT_RUNTIME_PATH, DEFAULT_FILE_VIEWER_PPT_RUNTIME_VERSION, DEFAULT_FILE_VIEWER_PPT_WASM_PATH, DEFAULT_FILE_VIEWER_PPT_WORKER_PATH, DEFAULT_FILE_VIEWER_PRESENTATION_WORKER_PATH, DEFAULT_FILE_VIEWER_RENDERER_ASSET_MANIFESTS, DEFAULT_FILE_VIEWER_SPREADSHEET_WORKER_PATH, DEFAULT_FILE_VIEWER_TYPST_COMPILER_WASM_URL, DEFAULT_FILE_VIEWER_TYPST_RENDERER_WASM_URL, DEFAULT_FILE_VIEWER_TYPST_RENDERER_WASM_PACKAGE_PATH, getDefaultFileViewerAssetBaseUrl, getFileViewerRendererAssetManifest, listFileViewerRendererAssetManifests, normalizeFileViewerAssetBaseUrl, resetDefaultFileViewerAssetBaseUrl, resolveFileViewerArchiveWasmUrl, resolveFileViewerArchiveWorkerUrl, resolveFileViewerAssetUrl, resolveFileViewerCadAssetUrls, resolveFileViewerDataSqlWasmUrl, resolveFileViewerDocxWorkerJsZipUrl, resolveFileViewerDocxWorkerUrl, resolveFileViewerDrawioViewerScriptUrl, resolveFileViewerModelAssetUrls, resolveFileViewerPdfAssetUrls, resolveFileViewerPresentationWorkerUrl, resolveFileViewerRendererAssets, resolveFileViewerRuntimeAssetBaseUrl, resolveFileViewerSpreadsheetWorkerUrl, resolveFileViewerTypstCompilerWasmUrl, resolveFileViewerTypstRendererWasmUrl, setDefaultFileViewerAssetBaseUrl, } from './assets'; | ||
| export { ARCHIVE_EXTENSIONS, DEFAULT_RENDERER_DEFINITIONS, DEFAULT_SUPPORTED_EXTENSIONS, IMAGE_EXTENSIONS, MODEL_EXTENSIONS, TEXT_EXTENSIONS, } from './registry/formats'; | ||
| export { precheckFileViewerSource } from './source/precheck'; | ||
| export type { FileViewerPrecheckOptions, FileViewerPrecheckReason, FileViewerPrecheckResult, FileViewerPrecheckStatus, } from './source/precheck'; | ||
| export { DEFAULT_FILE_VIEWER_TEXT_CHUNK_OVERLAP, DEFAULT_FILE_VIEWER_TEXT_CHUNK_SIZE, DEFAULT_FILE_VIEWER_ZOOM_SCALE, buildFileViewerDocumentTextChunks, createEmptyFileViewerSearchState, createFileViewerZoomState, normalizeFileViewerAiOptions, normalizeFileViewerSearchOptions, } from './features/document/model'; | ||
@@ -70,3 +72,3 @@ export { DEFAULT_FILE_VIEWER_SEARCH_ACTIVE_CLASS, DEFAULT_FILE_VIEWER_SEARCH_MATCH_CLASS, DEFAULT_FILE_VIEWER_SEARCH_MAX_MATCHES, applyFileViewerSearchState, cloneFileViewerSearchState, createFileViewerDomSearchController, createFileViewerDomSearchControllerActionHandlers, destroyFileViewerDomSearchController, observeFileViewerDomSearchController, runFileViewerDomSearchControllerAction, syncFileViewerDomSearchControllerState, } from './features/document/search'; | ||
| export type { FileViewerWatermarkPresentationState, FileViewerWatermarkStyle, } from './features/watermark'; | ||
| export { buildFileViewerPrintMaskOverlayHtml, applyFileViewerPagePrintMasksToHtml, normalizeFileViewerPrintMaskOptions, normalizeFileViewerPrintMaskRegion, FILE_VIEWER_PRINT_MASK_STYLE, } from './features/printMask'; | ||
| export { buildFileViewerPrintMaskOverlayHtml, applyFileViewerPagePrintMasksToHtml, normalizeFileViewerPrintMaskOptions, normalizeFileViewerPrintMaskRegion, normalizeFileViewerPrintStamp, FILE_VIEWER_PRINT_MASK_STYLE, } from './features/printMask'; | ||
| export { openFileViewerPrintMaskDesignerAsync, } from './features/printMaskLoader'; | ||
@@ -92,2 +94,2 @@ export type { FileViewerPrintMaskDesignerResult, OpenFileViewerPrintMaskDesignerOptions, } from './features/printMaskDesigner'; | ||
| export type { CreateFileViewerWorkerControllerOptions, FileViewerWorkerContext, FileViewerWorkerController, FileViewerWorkerErrorHook, FileViewerWorkerEventHandler, FileViewerWorkerFactory, FileViewerWorkerMessageHook, WorkerProvider, WorkerRef, } from './platform/worker'; | ||
| export type { FileViewerAiOptions, FileViewerArchiveEntryActionContext, FileViewerArchiveEntryActionPolicy, FileViewerArchiveEntryActionsOptions, FileViewerArchivePasswordRequestContext, FileViewerArchivePasswordRequestReason, FileViewerArchiveOptions, FileViewerApplyViewStateOptions, FileViewerBeforeOperation, FileViewerCadDwfLineWeightMode, FileViewerCadOptions, FileViewerCadRenderer, FileViewerModelLinearUnit, FileViewerModelOptions, FileViewerComponentEmits, FileViewerComponentEventMap, FileViewerComponentProps, FileViewerDocumentAnchor, FileViewerDocumentChunk, FileViewerDownloadOptions, FileViewerDocxOptions, FileViewerDrawingOptions, FileViewerEvent, FileViewerEventHandler, FileViewerEventType, FileViewerExportHtmlOptions, FileViewerFileRef, FileViewerFitMode, FileViewerFitOptions, FileViewerFitRequest, FileViewerFitResize, FileViewerFitResult, FileViewerGeoBasemapOptions, FileViewerGeoBasemapPreset, FileViewerGeoOptions, FileRenderContext, FileRenderExportAdapter, FileRenderThumbnailAdapter, FileRenderExportMode, FileRenderExportOptions, FileRenderHandler, FileRenderHandlerComposite, FileViewerBuiltinRendererPreset, FileViewerInstance, FileViewerLoadOptions, FileViewerLifecycleContext, FileViewerLifecycleHooks, FileViewerLifecyclePhase, FileViewerI18nOptions, FileViewerLocale, FileViewerMessageKey, FileViewerMessageParams, FileViewerMessageResolver, FileViewerMessages, FileViewerNavigationState, FileViewerOperationAvailability, FileViewerOperationContext, FileViewerOperationType, FileViewerOptions, FileViewerPdfOptions, FileViewerPresentationOptions, FileViewerPrintOptions, 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, FileViewerZoomProvider, FileViewerZoomState, NormalizedFileViewerSource, RendererCapability, RendererDefinition, RendererPlugin, RendererLoadContext, RendererLoader, RendererRegistry, RendererSession, RenderSurface, ViewerCapabilityState, ViewerLifecycleContext, ViewerOperationContext, } from './contracts/types'; | ||
| export type { FileViewerAiOptions, FileViewerArchiveEntryActionContext, FileViewerArchiveEntryActionPolicy, FileViewerArchiveEntryActionsOptions, FileViewerArchivePasswordRequestContext, FileViewerArchivePasswordRequestReason, FileViewerArchiveOptions, FileViewerApplyViewStateOptions, FileViewerBeforeOperation, FileViewerCadDwfLineWeightMode, FileViewerCadOptions, FileViewerCadRenderer, FileViewerModelLinearUnit, FileViewerModelOptions, FileViewerComponentEmits, FileViewerComponentEventMap, FileViewerComponentProps, FileViewerDocumentAnchor, FileViewerDocumentChunk, FileViewerDownloadOptions, FileViewerDocxOptions, FileViewerDrawingOptions, FileViewerEvent, FileViewerEventHandler, FileViewerEventType, FileViewerExportHtmlOptions, FileViewerFileRef, FileViewerFitMode, FileViewerFitOptions, FileViewerFitRequest, FileViewerFitResize, FileViewerFitResult, FileViewerGeoBasemapOptions, FileViewerGeoBasemapPreset, FileViewerGeoOptions, FileViewerTiandituMapStyle, FileRenderContext, FileRenderExportAdapter, FileRenderThumbnailAdapter, FileRenderExportMode, FileRenderExportOptions, FileRenderHandler, FileRenderHandlerComposite, FileViewerBuiltinRendererPreset, FileViewerInstance, FileViewerLoadOptions, FileViewerLifecycleContext, FileViewerLifecycleHooks, FileViewerLifecyclePhase, FileViewerI18nOptions, 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, FileViewerZoomProvider, FileViewerZoomState, NormalizedFileViewerSource, RendererCapability, RendererDefinition, RendererPlugin, RendererLoadContext, RendererLoader, RendererRegistry, RendererSession, RenderSurface, ViewerCapabilityState, ViewerLifecycleContext, ViewerOperationContext, } from './contracts/types'; |
+2
-1
| export { DEFAULT_FILE_VIEWER_ARCHIVE_WORKER_PATH, DEFAULT_FILE_VIEWER_ARCHIVE_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_DWF_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_LIBREDWG_SCRIPT_PATH, DEFAULT_FILE_VIEWER_CAD_LIBREDWG_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_RUNTIME_VERSION, DEFAULT_FILE_VIEWER_CAD_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_WORKER_PATH, DEFAULT_FILE_VIEWER_DATA_SQL_WASM_URL, DEFAULT_FILE_VIEWER_MODEL_RUNTIME_PACKAGE_PATH, DEFAULT_FILE_VIEWER_MODEL_RUNTIME_URL, DEFAULT_FILE_VIEWER_MODEL_IMPORT_LICENSE_PACKAGE_PATH, DEFAULT_FILE_VIEWER_MODEL_IMPORT_LICENSE_URL, DEFAULT_FILE_VIEWER_MODEL_OCCT_LICENSE_PACKAGE_PATH, DEFAULT_FILE_VIEWER_MODEL_OCCT_LICENSE_URL, DEFAULT_FILE_VIEWER_MODEL_WASM_PACKAGE_PATH, DEFAULT_FILE_VIEWER_MODEL_WASM_URL, DEFAULT_FILE_VIEWER_MODEL_WORKER_URL, DEFAULT_FILE_VIEWER_DOCX_WORKER_JSZIP_PATH, DEFAULT_FILE_VIEWER_DOCX_WORKER_PATH, DEFAULT_FILE_VIEWER_DOCX_RUNTIME_VERSION, DEFAULT_FILE_VIEWER_PDF_CMAP_PATH, DEFAULT_FILE_VIEWER_PDF_STANDARD_FONT_PATH, DEFAULT_FILE_VIEWER_PDF_WASM_PATH, DEFAULT_FILE_VIEWER_PDF_WORKER_PATH, DEFAULT_FILE_VIEWER_PPT_FONT_PATH, DEFAULT_FILE_VIEWER_PPT_FRAME_CACHE_PATH, DEFAULT_FILE_VIEWER_PPT_MODULE_PATH, DEFAULT_FILE_VIEWER_PPT_RUNTIME_PATH, DEFAULT_FILE_VIEWER_PPT_RUNTIME_VERSION, DEFAULT_FILE_VIEWER_PPT_WASM_PATH, DEFAULT_FILE_VIEWER_PPT_WORKER_PATH, DEFAULT_FILE_VIEWER_PRESENTATION_WORKER_PATH, DEFAULT_FILE_VIEWER_RENDERER_ASSET_MANIFESTS, DEFAULT_FILE_VIEWER_SPREADSHEET_WORKER_PATH, DEFAULT_FILE_VIEWER_TYPST_COMPILER_WASM_URL, DEFAULT_FILE_VIEWER_TYPST_RENDERER_WASM_URL, DEFAULT_FILE_VIEWER_TYPST_RENDERER_WASM_PACKAGE_PATH, getDefaultFileViewerAssetBaseUrl, getFileViewerRendererAssetManifest, listFileViewerRendererAssetManifests, normalizeFileViewerAssetBaseUrl, resetDefaultFileViewerAssetBaseUrl, resolveFileViewerArchiveWasmUrl, resolveFileViewerArchiveWorkerUrl, resolveFileViewerAssetUrl, resolveFileViewerCadAssetUrls, resolveFileViewerDataSqlWasmUrl, resolveFileViewerDocxWorkerJsZipUrl, resolveFileViewerDocxWorkerUrl, resolveFileViewerDrawioViewerScriptUrl, resolveFileViewerModelAssetUrls, resolveFileViewerPdfAssetUrls, resolveFileViewerPresentationWorkerUrl, resolveFileViewerRendererAssets, resolveFileViewerRuntimeAssetBaseUrl, resolveFileViewerSpreadsheetWorkerUrl, resolveFileViewerTypstCompilerWasmUrl, resolveFileViewerTypstRendererWasmUrl, setDefaultFileViewerAssetBaseUrl, } from './assets.js'; | ||
| export { ARCHIVE_EXTENSIONS, DEFAULT_RENDERER_DEFINITIONS, DEFAULT_SUPPORTED_EXTENSIONS, IMAGE_EXTENSIONS, MODEL_EXTENSIONS, TEXT_EXTENSIONS, } from './registry/formats.js'; | ||
| export { precheckFileViewerSource } from './source/precheck.js'; | ||
| export { DEFAULT_FILE_VIEWER_TEXT_CHUNK_OVERLAP, DEFAULT_FILE_VIEWER_TEXT_CHUNK_SIZE, DEFAULT_FILE_VIEWER_ZOOM_SCALE, buildFileViewerDocumentTextChunks, createEmptyFileViewerSearchState, createFileViewerZoomState, normalizeFileViewerAiOptions, normalizeFileViewerSearchOptions, } from './features/document/model.js'; | ||
@@ -176,3 +177,3 @@ export { DEFAULT_FILE_VIEWER_SEARCH_ACTIVE_CLASS, DEFAULT_FILE_VIEWER_SEARCH_MATCH_CLASS, DEFAULT_FILE_VIEWER_SEARCH_MAX_MATCHES, applyFileViewerSearchState, cloneFileViewerSearchState, createFileViewerDomSearchController, createFileViewerDomSearchControllerActionHandlers, destroyFileViewerDomSearchController, observeFileViewerDomSearchController, runFileViewerDomSearchControllerAction, syncFileViewerDomSearchControllerState, } from './features/document/search.js'; | ||
| export { buildFileViewerWatermarkBackgroundImage, buildFileViewerWatermarkInlineStyle, buildFileViewerWatermarkStyle, buildFileViewerWatermarkSvg, normalizeFileViewerWatermark, resolveFileViewerWatermarkPresentationState, } from './features/watermark.js'; | ||
| export { buildFileViewerPrintMaskOverlayHtml, applyFileViewerPagePrintMasksToHtml, normalizeFileViewerPrintMaskOptions, normalizeFileViewerPrintMaskRegion, FILE_VIEWER_PRINT_MASK_STYLE, } from './features/printMask.js'; | ||
| export { buildFileViewerPrintMaskOverlayHtml, applyFileViewerPagePrintMasksToHtml, normalizeFileViewerPrintMaskOptions, normalizeFileViewerPrintMaskRegion, normalizeFileViewerPrintStamp, FILE_VIEWER_PRINT_MASK_STYLE, } from './features/printMask.js'; | ||
| export { openFileViewerPrintMaskDesignerAsync, } from './features/printMaskLoader.js'; | ||
@@ -179,0 +180,0 @@ 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'; |
@@ -292,3 +292,3 @@ import { applyFileViewerPagePrintMasksToHtml, buildFileViewerPrintMaskOverlayHtml, FILE_VIEWER_PRINT_MASK_STYLE, normalizeFileViewerPrintMaskOptions, } from '../features/printMask.js'; | ||
| export const buildExportHtmlDocument = ({ contentHtml, includeDocumentStyles = true, printStyle = '', title, watermarkInlineStyle = '', mask = null, }) => { | ||
| var _a; | ||
| var _a, _b; | ||
| const watermark = watermarkInlineStyle | ||
@@ -302,2 +302,3 @@ ? `<div class="viewer-export-watermark" style="${watermarkInlineStyle}"></div>` | ||
| regions: (_a = normalizedMask.regions) === null || _a === void 0 ? void 0 : _a.filter(region => region.pageIndex === undefined), | ||
| stamps: (_b = normalizedMask.stamps) === null || _b === void 0 ? void 0 : _b.filter(stamp => stamp.pageIndex === undefined), | ||
| } | ||
@@ -304,0 +305,0 @@ : null; |
+48
-12
@@ -25,9 +25,14 @@ import { registerFileViewerZoomProvider, unregisterFileViewerZoomProvider, } from '../features/document/dom/index.js'; | ||
| .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} | ||
| .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} | ||
| .image-lightbox[hidden]{display:none} | ||
| .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} | ||
| .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)} | ||
| .image-stage img:focus-visible{outline:3px solid #2563eb;outline-offset:4px} | ||
| .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} | ||
| .image-lightbox[data-open='true']{opacity:1;visibility:visible;pointer-events:auto;transition-delay:0s} | ||
| .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} | ||
| .image-lightbox[data-open='true'] img{transform:scale(1)} | ||
| .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} | ||
| .image-lightbox button:hover{background:#fff;transform:scale(1.04)} | ||
| .image-lightbox button:focus-visible{outline:3px solid #60a5fa;outline-offset:2px} | ||
| [data-viewer-theme='dark'] .image-viewer{background:var(--file-viewer-render-surface-background,#101820)} | ||
| @media (prefers-color-scheme:dark){[data-viewer-theme='system'] .image-viewer{background:var(--file-viewer-render-surface-background,#101820)}} | ||
| @media (max-width:767px){.image-stage{padding:12px}.image-lightbox{padding:16px}.image-lightbox button{top:12px;right:12px}} | ||
| @media (prefers-reduced-motion:reduce){.image-lightbox,.image-lightbox img,.image-lightbox button{transition:none}} | ||
| `; | ||
@@ -72,5 +77,6 @@ const createStyle = (documentRef) => { | ||
| lightbox.className = 'image-lightbox'; | ||
| lightbox.hidden = true; | ||
| lightbox.dataset.open = 'false'; | ||
| lightbox.setAttribute('role', 'dialog'); | ||
| lightbox.setAttribute('aria-modal', 'true'); | ||
| lightbox.setAttribute('aria-hidden', 'true'); | ||
| const image = documentRef.createElement('img'); | ||
@@ -82,8 +88,21 @@ image.alt = t('image.lightbox.alt'); | ||
| closeButton.setAttribute('aria-label', t('image.lightbox.close')); | ||
| closeButton.textContent = 'x'; | ||
| closeButton.textContent = '×'; | ||
| let previousFocus = null; | ||
| const close = () => { | ||
| lightbox.hidden = true; | ||
| if (lightbox.dataset.open !== 'true') | ||
| return; | ||
| lightbox.dataset.open = 'false'; | ||
| lightbox.setAttribute('aria-hidden', 'true'); | ||
| if (previousFocus === null || previousFocus === void 0 ? void 0 : previousFocus.isConnected) { | ||
| previousFocus.focus({ preventScroll: true }); | ||
| } | ||
| previousFocus = null; | ||
| }; | ||
| const onKeyDown = (event) => { | ||
| if (event.key === 'Escape' && lightbox.dataset.open === 'true') { | ||
| event.preventDefault(); | ||
| close(); | ||
| } | ||
| }; | ||
| closeButton.addEventListener('click', close); | ||
| image.addEventListener('click', close); | ||
| lightbox.addEventListener('click', event => { | ||
@@ -94,11 +113,17 @@ if (event.target === lightbox) { | ||
| }); | ||
| documentRef.addEventListener('keydown', onKeyDown); | ||
| lightbox.append(image, closeButton); | ||
| return { | ||
| element: lightbox, | ||
| open() { | ||
| lightbox.hidden = false; | ||
| open(invoker) { | ||
| previousFocus = | ||
| invoker || | ||
| (documentRef.activeElement instanceof HTMLElement ? documentRef.activeElement : null); | ||
| lightbox.dataset.open = 'true'; | ||
| lightbox.setAttribute('aria-hidden', 'false'); | ||
| closeButton.focus({ preventScroll: true }); | ||
| }, | ||
| destroy() { | ||
| closeButton.removeEventListener('click', close); | ||
| image.removeEventListener('click', close); | ||
| documentRef.removeEventListener('keydown', onKeyDown); | ||
| lightbox.remove(); | ||
@@ -129,7 +154,17 @@ }, | ||
| image.src = src; | ||
| image.tabIndex = 0; | ||
| image.setAttribute('role', 'button'); | ||
| image.setAttribute('aria-haspopup', 'dialog'); | ||
| stage.append(image); | ||
| root.append(stage); | ||
| const lightbox = createLightbox(documentRef, src, t); | ||
| const openLightbox = () => lightbox.open(); | ||
| const openLightbox = () => lightbox.open(image); | ||
| const openLightboxFromKeyboard = (event) => { | ||
| if (event.key === 'Enter' || event.key === ' ') { | ||
| event.preventDefault(); | ||
| lightbox.open(image); | ||
| } | ||
| }; | ||
| image.addEventListener('click', openLightbox); | ||
| image.addEventListener('keydown', openLightboxFromKeyboard); | ||
| const getMinScale = () => Math.min(0.1, fitScale || 0.1); | ||
@@ -258,2 +293,3 @@ const clampScale = (value) => { | ||
| image.removeEventListener('click', openLightbox); | ||
| image.removeEventListener('keydown', openLightboxFromKeyboard); | ||
| lightbox.destroy(); | ||
@@ -260,0 +296,0 @@ target.replaceChildren(); |
@@ -639,3 +639,3 @@ // Imperative viewer composition root. | ||
| async printWithMask(printOptions = {}) { | ||
| var _a, _b, _c, _d; | ||
| var _a, _b, _c, _d, _e; | ||
| const result = await openFileViewerPrintMaskDesignerAsync({ | ||
@@ -647,2 +647,3 @@ root: container, | ||
| initialRegions: (_d = printOptions.mask) === null || _d === void 0 ? void 0 : _d.regions, | ||
| initialStamps: (_e = printOptions.mask) === null || _e === void 0 ? void 0 : _e.stamps, | ||
| }); | ||
@@ -649,0 +650,0 @@ if (!(result === null || result === void 0 ? void 0 : result.mask)) { |
@@ -265,3 +265,3 @@ import { buildFileViewerRenderedHtmlDocument, triggerFileViewerBlobDownload, triggerFileViewerUrlDownload, waitForFileViewerPrintWindowReady, } from '../output/export.js'; | ||
| async printWithMask(options = {}) { | ||
| var _a, _b, _c, _d, _e, _f, _g; | ||
| var _a, _b, _c, _d, _e, _f, _g, _h; | ||
| try { | ||
@@ -280,2 +280,3 @@ const source = getRenderedSource(); | ||
| initialRegions: (_d = options.mask) === null || _d === void 0 ? void 0 : _d.regions, | ||
| initialStamps: (_e = options.mask) === null || _e === void 0 ? void 0 : _e.stamps, | ||
| }); | ||
@@ -288,5 +289,5 @@ if (!(result === null || result === void 0 ? void 0 : result.mask)) { | ||
| ...options, | ||
| watermarkInlineStyle: (_f = (_e = options.watermarkInlineStyle) !== null && _e !== void 0 ? _e : getWatermarkInlineStyle === null || getWatermarkInlineStyle === void 0 ? void 0 : getWatermarkInlineStyle()) !== null && _f !== void 0 ? _f : undefined, | ||
| watermarkInlineStyle: (_g = (_f = options.watermarkInlineStyle) !== null && _f !== void 0 ? _f : getWatermarkInlineStyle === null || getWatermarkInlineStyle === void 0 ? void 0 : getWatermarkInlineStyle()) !== null && _g !== void 0 ? _g : undefined, | ||
| mask: result.mask, | ||
| printAvailable: (_g = getPrintAvailable === null || getPrintAvailable === void 0 ? void 0 : getPrintAvailable()) !== null && _g !== void 0 ? _g : true, | ||
| printAvailable: (_h = getPrintAvailable === null || getPrintAvailable === void 0 ? void 0 : getPrintAvailable()) !== null && _h !== void 0 ? _h : true, | ||
| }); | ||
@@ -293,0 +294,0 @@ } |
+1
-1
| { | ||
| "name": "@file-viewer/core", | ||
| "version": "2.2.4", | ||
| "version": "2.2.5", | ||
| "private": false, | ||
@@ -5,0 +5,0 @@ "type": "module", |
+17
-0
@@ -17,2 +17,19 @@ # @file-viewer/core | ||
| ## Preflight Before Rendering | ||
| `precheckFileViewerSource()` does not create a viewer or load a heavy renderer. It checks whether the extension is available and validates known PDF, OpenXML / OpenDocument, legacy OLE Office, and RTF signatures or package parts. `valid: null` explicitly means capability-only detection, not a full parse; the real renderer remains the final authority for malformed content. | ||
| ```ts | ||
| import { precheckFileViewerSource } from '@file-viewer/core/headless' | ||
| const result = await precheckFileViewerSource(file, { | ||
| // Restrict this to the extensions actually installed by this product. | ||
| supportedExtensions: ['pdf', 'docx', 'xlsx', 'pptx'] | ||
| }) | ||
| if (!result.previewable) { | ||
| console.warn(result.reason, result.missingParts) | ||
| } | ||
| ``` | ||
| ## Entry points | ||
@@ -19,0 +36,0 @@ |
+17
-0
@@ -17,2 +17,19 @@ # @file-viewer/core | ||
| ## 渲染前预检 | ||
| `precheckFileViewerSource()` 不会创建 viewer,也不会加载重型 renderer。它先检查当前扩展名是否在能力范围内,并对 PDF、OpenXML / OpenDocument、旧版 OLE Office、RTF 等格式执行签名或包结构检查。`valid: null` 明确表示该格式只有能力检查、没有做完整解析;真实 renderer 仍是畸形文件的最终判断者。 | ||
| ```ts | ||
| import { precheckFileViewerSource } from '@file-viewer/core/headless' | ||
| const result = await precheckFileViewerSource(file, { | ||
| // 可传当前产品实际安装的扩展名列表,避免把未装 preset 的格式报成可预览 | ||
| supportedExtensions: ['pdf', 'docx', 'xlsx', 'pptx'] | ||
| }) | ||
| if (!result.previewable) { | ||
| console.warn(result.reason, result.missingParts) | ||
| } | ||
| ``` | ||
| ## Entry points | ||
@@ -19,0 +36,0 @@ |
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
903863
3.98%102
2%16957
3.96%114
17.53%