@file-viewer/core 3.1.1 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/README.en.md +3 -121
  2. package/README.md +3 -126
  3. package/dist/assets.d.ts +2 -2
  4. package/dist/assets.js +1 -5
  5. package/dist/browser/controller.d.ts +1 -2
  6. package/dist/browser/controller.js +2 -34
  7. package/dist/browser.d.ts +2 -2
  8. package/dist/browser.js +2 -2
  9. package/dist/config/options.d.ts +1 -1
  10. package/dist/contracts/types.d.ts +30 -416
  11. package/dist/contracts/xml.d.ts +48 -0
  12. package/dist/contracts/xml.js +1 -0
  13. package/dist/export.d.ts +3 -10
  14. package/dist/export.js +2 -9
  15. package/dist/exportDocument.d.ts +1 -12
  16. package/dist/exportDocument.js +7 -31
  17. package/dist/features/document/dom/anchors.d.ts +1 -1
  18. package/dist/features/document/dom/index.d.ts +5 -5
  19. package/dist/features/document/dom/index.js +3 -3
  20. package/dist/features/document/dom/providers.d.ts +1 -1
  21. package/dist/features/document/events.d.ts +2 -2
  22. package/dist/features/document/events.js +3 -3
  23. package/dist/features/document/fit.d.ts +1 -1
  24. package/dist/features/document/fit.js +1 -1
  25. package/dist/features/document/model.d.ts +1 -1
  26. package/dist/features/document/search.d.ts +1 -1
  27. package/dist/features/document/search.js +2 -2
  28. package/dist/features/document/viewState.d.ts +1 -1
  29. package/dist/features/document/viewState.js +2 -2
  30. package/dist/features/document/zoom.d.ts +3 -2
  31. package/dist/features/document/zoom.js +19 -3
  32. package/dist/features/document/zoomGestures.d.ts +11 -0
  33. package/dist/features/document/zoomGestures.js +111 -0
  34. package/dist/features/printMask.d.ts +1 -1
  35. package/dist/features/printMaskDesigner.d.ts +2 -6
  36. package/dist/features/printMaskDesigner.js +2 -11
  37. package/dist/features/printMaskLoader.d.ts +1 -7
  38. package/dist/features/printMaskLoader.js +1 -7
  39. package/dist/features/watermark.d.ts +1 -1
  40. package/dist/headless.d.ts +29 -29
  41. package/dist/headless.js +16 -21
  42. package/dist/i18n/messages.d.ts +1 -1
  43. package/dist/i18n/messages.de.d.ts +1 -5
  44. package/dist/i18n/messages.de.js +0 -4
  45. package/dist/i18n/messages.ja.d.ts +1 -6
  46. package/dist/i18n/messages.ja.js +0 -5
  47. package/dist/i18n/messages.js +2 -2
  48. package/dist/index.d.ts +74 -73
  49. package/dist/index.js +37 -37
  50. package/dist/lifecycle/facade.d.ts +4 -4
  51. package/dist/lifecycle/facade.js +2 -2
  52. package/dist/lifecycle/operations.d.ts +4 -4
  53. package/dist/lifecycle/operations.js +4 -9
  54. package/dist/output/canvasImage.d.ts +1 -2
  55. package/dist/output/canvasImage.js +1 -4
  56. package/dist/output/export.d.ts +2 -4
  57. package/dist/output/export.js +133 -81
  58. package/dist/output/printLayout.d.ts +2 -5
  59. package/dist/output/printLayout.js +37 -9
  60. package/dist/output/snapshotDownload.d.ts +1 -2
  61. package/dist/output/snapshotDownload.js +2 -3
  62. package/dist/platform/assets.d.ts +9 -16
  63. package/dist/platform/assets.js +60 -17
  64. package/dist/platform/copiedAssets.d.ts +0 -1
  65. package/dist/platform/copiedAssets.js +1 -2
  66. package/dist/presentation/state.d.ts +1 -1
  67. package/dist/presentation/state.js +3 -3
  68. package/dist/print-mask.d.ts +2 -2
  69. package/dist/print-mask.js +1 -1
  70. package/dist/registry/capabilities.d.ts +3 -16
  71. package/dist/registry/capabilities.js +2 -15
  72. package/dist/registry/formats.d.ts +5 -5
  73. package/dist/registry/formats.generated.d.ts +26 -8
  74. package/dist/registry/formats.generated.js +36 -4
  75. package/dist/registry/formats.js +2 -2
  76. package/dist/registry/registry.d.ts +6 -15
  77. package/dist/registry/registry.js +24 -10
  78. package/dist/renderers/image.d.ts +1 -1
  79. package/dist/renderers/image.js +26 -5
  80. package/dist/renderers/index.d.ts +30 -11
  81. package/dist/renderers/index.js +5 -11
  82. package/dist/rendering/dispatcher.d.ts +1 -6
  83. package/dist/rendering/dispatcher.js +3 -3
  84. package/dist/rendering/handler.d.ts +10 -15
  85. package/dist/rendering/handler.js +20 -27
  86. package/dist/security/svgResources.d.ts +0 -10
  87. package/dist/security/svgResources.js +2 -11
  88. package/dist/source/index.d.ts +3 -3
  89. package/dist/source/index.js +1 -1
  90. package/dist/source/loading.d.ts +56 -15
  91. package/dist/source/loading.js +177 -87
  92. package/dist/source/precheck.d.ts +1 -13
  93. package/dist/source/precheck.js +2 -9
  94. package/dist/source/textEncoding.d.ts +6 -3
  95. package/dist/source/textEncoding.js +58 -8
  96. package/dist/viewer/createViewer.d.ts +1 -1
  97. package/dist/viewer/createViewer.js +103 -33
  98. package/dist/viewer/loading.d.ts +2 -6
  99. package/dist/viewer/loading.js +1 -9
  100. package/dist/viewer/operations.d.ts +3 -3
  101. package/dist/viewer/operations.js +6 -14
  102. package/dist/viewer/state.d.ts +2 -6
  103. package/dist/viewer/state.js +3 -8
  104. package/package.json +127 -19
@@ -1,7 +1,7 @@
1
- import { buildFileViewerLifecycleContext, } from '../lifecycle/operations.js';
2
- import { resolveFileViewerPreviewMessages, } from '../viewer/state.js';
3
- import { translateFileViewerMessage } from '../i18n/messages.js';
4
- import { DEFAULT_FILE_VIEWER_SOURCE_FILENAME, getExtension, normalizeFilename, readFileViewerBuffer, resolveFileViewerSourceFilename, wrapFileViewerFileRef, } from './index.js';
1
+ import { buildFileViewerLifecycleContext, } from "../lifecycle/operations.js";
2
+ import { resolveFileViewerPreviewMessages, } from "../viewer/state.js";
3
+ import { translateFileViewerMessage } from "../i18n/messages.js";
4
+ import { DEFAULT_FILE_VIEWER_SOURCE_FILENAME, getExtension, normalizeFilename, readFileViewerBuffer, resolveFileViewerSourceFilename, wrapFileViewerFileRef, } from "./index.js";
5
5
  export const DEFAULT_PDF_RANGE_CHUNK_SIZE = 64 * 1024;
6
6
  export const DEFAULT_FILE_VIEWER_STREAMING_PDF_FILENAME = 'preview.pdf';
7
7
  export const FILE_VIEWER_REMOTE_MISSING_DATA_ERROR_MESSAGE = '文件下载失败';
@@ -117,7 +117,6 @@ const encodeFileViewerUrlPathSegment = (segment) => {
117
117
  decoded = decodeURIComponent(segment);
118
118
  }
119
119
  catch {
120
- // Invalid percent escapes are treated as literal filename characters.
121
120
  }
122
121
  return encodeURIComponent(decoded)
123
122
  .replace(/%3A/gi, ':')
@@ -360,9 +359,9 @@ export const commitFileViewerRenderCompleteState = ({ version, session, buildSta
360
359
  onClearLoadStarted === null || onClearLoadStarted === void 0 ? void 0 : onClearLoadStarted(version);
361
360
  return completeState;
362
361
  };
363
- export const runFileViewerReadAndRenderFile = async ({ file, version, sourceUrl, source = sourceUrl ? 'url' : 'file', fallbackFilename = '', previewTarget, isCurrent, mountRenderedContent, destroyRenderSession, buildRenderCompleteState, onSession, onActiveDocumentContext, onLifecycle, onClearLoadStarted, }) => {
362
+ export const runFileViewerReadAndRenderFile = async ({ file, version, signal, sourceUrl, source = sourceUrl ? 'url' : 'file', fallbackFilename = '', previewTarget, isCurrent, mountRenderedContent, destroyRenderSession, buildRenderCompleteState, onSession, onActiveDocumentContext, onLifecycle, onClearLoadStarted, }) => {
364
363
  const buffer = await readFileViewerBuffer(file);
365
- if (!isCurrent(version)) {
364
+ if (!isCurrent(version) || (signal === null || signal === void 0 ? void 0 : signal.aborted)) {
366
365
  return {
367
366
  stale: true,
368
367
  buffer,
@@ -377,7 +376,7 @@ export const runFileViewerReadAndRenderFile = async ({ file, version, sourceUrl,
377
376
  fallbackFilename,
378
377
  }));
379
378
  const session = await mountRenderedContent(buffer, file, version, sourceUrl);
380
- if (!isCurrent(version)) {
379
+ if (!isCurrent(version) || (signal === null || signal === void 0 ? void 0 : signal.aborted)) {
381
380
  destroyRenderSession === null || destroyRenderSession === void 0 ? void 0 : destroyRenderSession(session);
382
381
  return {
383
382
  stale: true,
@@ -408,15 +407,15 @@ export const runFileViewerReadAndRenderFile = async ({ file, version, sourceUrl,
408
407
  complete,
409
408
  };
410
409
  };
411
- export const runFileViewerStreamingPdfPreview = async ({ url, version, filename, previewTarget, isCurrent, mountRenderedContent, destroyRenderSession, buildRenderCompleteState, loadingMessage, i18n, onStartLoading, onSession, onActiveDocumentContext, onLifecycle, onClearLoadStarted, onStopLoading, onError, }) => {
410
+ export const runFileViewerStreamingPdfPreview = async ({ url, version, filename, previewTarget, isCurrent, mountRenderedContent, destroyRenderSession, buildRenderCompleteState, loadingMessage, signal, typeOverride, i18n, onStartLoading, onSession, onActiveDocumentContext, onLifecycle, onClearLoadStarted, onStopLoading, onError, }) => {
412
411
  let placeholderFile = null;
413
412
  onStartLoading === null || onStartLoading === void 0 ? void 0 : onStartLoading(loadingMessage || resolveFileViewerPreviewMessages(i18n).streamingPdf);
414
413
  try {
415
414
  placeholderFile = createFileViewerStreamingPdfPlaceholderFile(filename);
416
415
  applyFileViewerPreviewSourceUrlState(previewTarget, url);
417
- const session = await mountRenderedContent(new ArrayBuffer(0), placeholderFile, version, url, url);
418
- if (!isCurrent(version)) {
419
- destroyRenderSession === null || destroyRenderSession === void 0 ? void 0 : destroyRenderSession(session);
416
+ const session = await mountRenderedContent(new ArrayBuffer(0), placeholderFile, version, url, url, signal, typeOverride);
417
+ if (!isCurrent(version) || (signal === null || signal === void 0 ? void 0 : signal.aborted)) {
418
+ await (destroyRenderSession === null || destroyRenderSession === void 0 ? void 0 : destroyRenderSession(session));
420
419
  return {
421
420
  status: 'stale',
422
421
  placeholderFile,
@@ -448,7 +447,7 @@ export const runFileViewerStreamingPdfPreview = async ({ url, version, filename,
448
447
  };
449
448
  }
450
449
  catch (error) {
451
- if (!isCurrent(version)) {
450
+ if (!isCurrent(version) || (signal === null || signal === void 0 ? void 0 : signal.aborted) || isFileViewerAbortError(error)) {
452
451
  return {
453
452
  status: 'stale',
454
453
  placeholderFile,
@@ -475,7 +474,7 @@ export const runFileViewerStreamingPdfPreview = async ({ url, version, filename,
475
474
  });
476
475
  }
477
476
  };
478
- export const runFileViewerLocalFilePreview = async ({ source, version, currentFilename, fallbackFilename, previewTarget, isCurrent, mountRenderedContent, destroyRenderSession, buildLoadStartState, buildRenderCompleteState, onMarkLoadStarted, onStartLoading, onSession, onActiveDocumentContext, onLifecycle, onClearLoadStarted, onStopLoading, onError, }) => {
477
+ export const runFileViewerLocalFilePreview = async ({ source, version, currentFilename, fallbackFilename, shouldStreamLocalFile, requestController, previewTarget, isCurrent, mountRenderedContent, destroyRenderSession, buildLoadStartState, buildRenderCompleteState, onMarkLoadStarted, onStartLoading, onSession, onActiveDocumentContext, onLifecycle, onClearLoadStarted, onStopLoading, onError, }) => {
479
478
  const localSource = resolveFileViewerFileRefSourcePlan({
480
479
  source,
481
480
  currentFilename,
@@ -495,14 +494,55 @@ export const runFileViewerLocalFilePreview = async ({ source, version, currentFi
495
494
  onLifecycle,
496
495
  onStartLoading,
497
496
  });
497
+ const controller = (requestController === null || requestController === void 0 ? void 0 : requestController.createAbortController()) || null;
498
498
  try {
499
+ const streamDecision = await (shouldStreamLocalFile === null || shouldStreamLocalFile === void 0 ? void 0 : shouldStreamLocalFile({
500
+ file,
501
+ filename: localSource.filename,
502
+ extension: getExtension(localSource.filename),
503
+ signal: controller === null || controller === void 0 ? void 0 : controller.signal,
504
+ }));
505
+ if (!isCurrent(version) || (controller === null || controller === void 0 ? void 0 : controller.signal.aborted)) {
506
+ return { status: 'stale', source: localSource, read: null, error: null };
507
+ }
508
+ if (streamDecision) {
509
+ const buffer = new ArrayBuffer(0);
510
+ const typeOverride = typeof streamDecision === 'string' ? streamDecision : undefined;
511
+ applyFileViewerReadPreviewState(previewTarget, createFileViewerReadPreviewState({
512
+ file,
513
+ buffer,
514
+ fallbackFilename: localSource.filename,
515
+ }));
516
+ const session = await mountRenderedContent(buffer, file, version, undefined, undefined, controller === null || controller === void 0 ? void 0 : controller.signal, typeOverride);
517
+ if (!isCurrent(version) || (controller === null || controller === void 0 ? void 0 : controller.signal.aborted)) {
518
+ destroyRenderSession === null || destroyRenderSession === void 0 ? void 0 : destroyRenderSession(session);
519
+ return { status: 'stale', source: localSource, read: null, error: null };
520
+ }
521
+ const complete = commitFileViewerRenderCompleteState({
522
+ version,
523
+ session,
524
+ readinessTarget: previewTarget,
525
+ buildState: () => buildRenderCompleteState({ version, source: 'file', file }),
526
+ onSession,
527
+ onActiveDocumentContext,
528
+ onLifecycle,
529
+ onClearLoadStarted,
530
+ });
531
+ return {
532
+ status: 'ready',
533
+ source: localSource,
534
+ read: { stale: false, buffer, session, complete },
535
+ error: null,
536
+ };
537
+ }
499
538
  const read = await runFileViewerReadAndRenderFile({
500
539
  file,
501
540
  version,
541
+ signal: controller === null || controller === void 0 ? void 0 : controller.signal,
502
542
  source: 'file',
503
543
  previewTarget,
504
544
  isCurrent,
505
- mountRenderedContent,
545
+ mountRenderedContent: (buffer, file, version, sourceUrl) => mountRenderedContent(buffer, file, version, sourceUrl, undefined, controller === null || controller === void 0 ? void 0 : controller.signal),
506
546
  destroyRenderSession,
507
547
  buildRenderCompleteState: input => buildRenderCompleteState({
508
548
  version: input.version,
@@ -530,7 +570,7 @@ export const runFileViewerLocalFilePreview = async ({ source, version, currentFi
530
570
  };
531
571
  }
532
572
  catch (error) {
533
- if (!isCurrent(version)) {
573
+ if (!isCurrent(version) || (controller === null || controller === void 0 ? void 0 : controller.signal.aborted)) {
534
574
  return {
535
575
  status: 'stale',
536
576
  source: localSource,
@@ -547,6 +587,7 @@ export const runFileViewerLocalFilePreview = async ({ source, version, currentFi
547
587
  };
548
588
  }
549
589
  finally {
590
+ requestController === null || requestController === void 0 ? void 0 : requestController.clearAbortController(controller);
550
591
  finalizeFileViewerPreviewLoadState({
551
592
  version,
552
593
  isCurrent,
@@ -555,52 +596,106 @@ export const runFileViewerLocalFilePreview = async ({ source, version, currentFi
555
596
  });
556
597
  }
557
598
  };
558
- export const runFileViewerRemoteFilePreview = async ({ url, version, pageHref, streaming, previewTarget, requestController, isCurrent, downloadFile, mountRenderedContent, destroyRenderSession, buildLoadStartState, buildRenderCompleteState, i18n, onMarkLoadStarted, onStartLoading, onSetLoadingMessage, onSession, onActiveDocumentContext, onLifecycle, onClearLoadStarted, onStopLoading, onMissingData, onError, }) => {
559
- const remoteSource = resolveFileViewerRemoteSourcePlan({
599
+ export const runFileViewerRemoteFilePreview = async ({ url, version, pageHref, streaming, shouldStreamRemoteUrl, previewTarget, requestController, isCurrent, downloadFile, mountRenderedContent, destroyRenderSession, buildLoadStartState, buildRenderCompleteState, i18n, onMarkLoadStarted, onStartLoading, onSetLoadingMessage, onSession, onActiveDocumentContext, onLifecycle, onClearLoadStarted, onStopLoading, onMissingData, onError, }) => {
600
+ let remoteSource = resolveFileViewerRemoteSourcePlan({
560
601
  pageHref,
561
602
  streaming,
562
603
  url,
563
604
  });
564
605
  const sourceUrl = remoteSource.url;
565
- commitFileViewerLoadStartState({
566
- version,
567
- filename: remoteSource.filename,
568
- filenameTarget: previewTarget,
569
- buildState: () => buildLoadStartState({
570
- version,
571
- source: 'url',
572
- sourceUrl,
573
- }),
574
- onMarkLoadStarted,
575
- onLifecycle,
576
- onStartLoading,
577
- });
578
- if (remoteSource.streamPdf) {
579
- const stream = await runFileViewerStreamingPdfPreview({
580
- url: sourceUrl,
606
+ const controller = requestController.createAbortController();
607
+ let streamFinalized = false;
608
+ try {
609
+ if (!remoteSource.streamPdf && shouldStreamRemoteUrl) {
610
+ const streamDecision = await shouldStreamRemoteUrl({
611
+ url: sourceUrl,
612
+ filename: remoteSource.filename,
613
+ extension: remoteSource.extension,
614
+ pageHref,
615
+ signal: controller === null || controller === void 0 ? void 0 : controller.signal,
616
+ });
617
+ if (streamDecision) {
618
+ remoteSource = {
619
+ ...remoteSource,
620
+ streamRenderer: true,
621
+ streamType: typeof streamDecision === 'string' ? streamDecision : remoteSource.extension,
622
+ };
623
+ }
624
+ }
625
+ if (!isCurrent(version) || (controller === null || controller === void 0 ? void 0 : controller.signal.aborted)) {
626
+ return {
627
+ status: 'stale',
628
+ remoteSource,
629
+ download: null,
630
+ read: null,
631
+ stream: null,
632
+ error: null,
633
+ };
634
+ }
635
+ commitFileViewerLoadStartState({
581
636
  version,
582
637
  filename: remoteSource.filename,
583
- previewTarget,
584
- isCurrent,
585
- mountRenderedContent,
586
- destroyRenderSession,
587
- buildRenderCompleteState: input => buildRenderCompleteState({
588
- version: input.version,
638
+ filenameTarget: previewTarget,
639
+ buildState: () => buildLoadStartState({
640
+ version,
589
641
  source: 'url',
590
642
  sourceUrl,
591
643
  }),
592
- i18n,
593
- onStartLoading,
594
- onSession,
595
- onActiveDocumentContext,
644
+ onMarkLoadStarted,
596
645
  onLifecycle,
597
- onClearLoadStarted,
598
- onStopLoading,
599
- onError: error => onError === null || onError === void 0 ? void 0 : onError(error, 'stream'),
646
+ onStartLoading,
600
647
  });
601
- if (stream.status === 'ready') {
648
+ if (remoteSource.streamPdf || remoteSource.streamRenderer) {
649
+ const stream = await runFileViewerStreamingPdfPreview({
650
+ url: sourceUrl,
651
+ version,
652
+ filename: remoteSource.filename,
653
+ previewTarget,
654
+ isCurrent,
655
+ mountRenderedContent,
656
+ destroyRenderSession,
657
+ buildRenderCompleteState: (input) => buildRenderCompleteState({
658
+ version: input.version,
659
+ source: 'url',
660
+ sourceUrl,
661
+ }),
662
+ i18n,
663
+ loadingMessage: remoteSource.streamPdf
664
+ ? undefined
665
+ : resolveFileViewerPreviewMessages(i18n).downloading,
666
+ signal: controller === null || controller === void 0 ? void 0 : controller.signal,
667
+ typeOverride: remoteSource.streamType,
668
+ onStartLoading,
669
+ onSession,
670
+ onActiveDocumentContext,
671
+ onLifecycle,
672
+ onClearLoadStarted,
673
+ onStopLoading,
674
+ onError: (error) => onError === null || onError === void 0 ? void 0 : onError(error, 'stream'),
675
+ });
676
+ streamFinalized = true;
677
+ if (stream.status === 'ready') {
678
+ return {
679
+ status: 'stream',
680
+ remoteSource,
681
+ download: null,
682
+ read: null,
683
+ stream,
684
+ error: null,
685
+ };
686
+ }
687
+ if (stream.status === 'error') {
688
+ return {
689
+ status: 'error',
690
+ remoteSource,
691
+ download: null,
692
+ read: null,
693
+ stream,
694
+ error: stream.error,
695
+ };
696
+ }
602
697
  return {
603
- status: 'stream',
698
+ status: 'stale',
604
699
  remoteSource,
605
700
  download: null,
606
701
  read: null,
@@ -608,27 +703,6 @@ export const runFileViewerRemoteFilePreview = async ({ url, version, pageHref, s
608
703
  error: null,
609
704
  };
610
705
  }
611
- if (stream.status === 'error') {
612
- return {
613
- status: 'error',
614
- remoteSource,
615
- download: null,
616
- read: null,
617
- stream,
618
- error: stream.error,
619
- };
620
- }
621
- return {
622
- status: 'stale',
623
- remoteSource,
624
- download: null,
625
- read: null,
626
- stream,
627
- error: null,
628
- };
629
- }
630
- const controller = requestController.createAbortController();
631
- try {
632
706
  const data = await downloadFile({
633
707
  url: sourceUrl,
634
708
  signal: controller === null || controller === void 0 ? void 0 : controller.signal,
@@ -671,7 +745,7 @@ export const runFileViewerRemoteFilePreview = async ({ url, version, pageHref, s
671
745
  isCurrent,
672
746
  mountRenderedContent,
673
747
  destroyRenderSession,
674
- buildRenderCompleteState: input => buildRenderCompleteState({
748
+ buildRenderCompleteState: (input) => buildRenderCompleteState({
675
749
  version: input.version,
676
750
  source: 'url',
677
751
  file: input.file,
@@ -724,15 +798,17 @@ export const runFileViewerRemoteFilePreview = async ({ url, version, pageHref, s
724
798
  }
725
799
  finally {
726
800
  requestController.clearAbortController(controller);
727
- finalizeFileViewerPreviewLoadState({
728
- version,
729
- isCurrent,
730
- onClearLoadStarted,
731
- onStopLoading,
732
- });
801
+ if (!streamFinalized) {
802
+ finalizeFileViewerPreviewLoadState({
803
+ version,
804
+ isCurrent,
805
+ onClearLoadStarted,
806
+ onStopLoading,
807
+ });
808
+ }
733
809
  }
734
810
  };
735
- export const createFileViewerSourceLoadingActionHandlers = ({ getFile, getUrl, getCurrentFilename, getPdfStreaming, getI18n, getPageHref, previewTarget, requestController, downloadFile, mountRenderedContent, destroyRenderSession, buildLoadStartState, buildRenderCompleteState, formatErrorMessage, onMarkLoadStarted, onClearLoadStarted, onStartLoading, onSetLoadingMessage, onStopLoading, onShowError, onClearError, onResetLoading, onClearRenderedContent, onSession, onActiveDocumentContext, onLifecycle, }) => {
811
+ export const createFileViewerSourceLoadingActionHandlers = ({ getFile, getUrl, getCurrentFilename, shouldStreamLocalFile, getPdfStreaming, shouldStreamRemoteUrl, getI18n, getPageHref, previewTarget, requestController, downloadFile, mountRenderedContent, destroyRenderSession, buildLoadStartState, buildRenderCompleteState, formatErrorMessage, onMarkLoadStarted, onClearLoadStarted, onStartLoading, onSetLoadingMessage, onStopLoading, onShowError, onClearError, onResetLoading, onClearRenderedContent, onSession, onActiveDocumentContext, onLifecycle, }) => {
736
812
  const isCurrentRequest = (version) => requestController.isCurrent(version);
737
813
  const previewLocalFile = async (source, version) => {
738
814
  var _a;
@@ -740,6 +816,8 @@ export const createFileViewerSourceLoadingActionHandlers = ({ getFile, getUrl, g
740
816
  source,
741
817
  version,
742
818
  currentFilename: (_a = getCurrentFilename === null || getCurrentFilename === void 0 ? void 0 : getCurrentFilename()) !== null && _a !== void 0 ? _a : previewTarget.filename,
819
+ shouldStreamLocalFile,
820
+ requestController,
743
821
  previewTarget,
744
822
  isCurrent: isCurrentRequest,
745
823
  mountRenderedContent,
@@ -778,6 +856,7 @@ export const createFileViewerSourceLoadingActionHandlers = ({ getFile, getUrl, g
778
856
  version,
779
857
  pageHref: getPageHref === null || getPageHref === void 0 ? void 0 : getPageHref(),
780
858
  streaming: getPdfStreaming === null || getPdfStreaming === void 0 ? void 0 : getPdfStreaming(),
859
+ shouldStreamRemoteUrl,
781
860
  i18n: getI18n === null || getI18n === void 0 ? void 0 : getI18n(),
782
861
  previewTarget,
783
862
  requestController,
@@ -955,22 +1034,33 @@ export const shouldStreamPdfUrl = ({ extension, pageHref, streaming, url, }) =>
955
1034
  export const resolveFileViewerPageHref = (locationLike) => {
956
1035
  return (locationLike === null || locationLike === void 0 ? void 0 : locationLike.href) || undefined;
957
1036
  };
958
- export const resolveFileViewerRemoteSourcePlan = ({ filename, fallbackFilename = DEFAULT_FILE_VIEWER_SOURCE_FILENAME, pageHref, streaming, url, }) => {
1037
+ export const resolveFileViewerRemoteSourcePlan = ({ filename, fallbackFilename = DEFAULT_FILE_VIEWER_SOURCE_FILENAME, pageHref, streaming, shouldStreamRemoteUrl, url, }) => {
959
1038
  const sourceUrl = normalizeFileViewerSourceUrl(url) || url;
960
1039
  const nextFilename = normalizeFilename(filename || url, fallbackFilename);
961
1040
  const extension = getExtension(nextFilename);
1041
+ const streamPdf = pageHref
1042
+ ? shouldStreamPdfUrl({
1043
+ extension,
1044
+ pageHref,
1045
+ streaming,
1046
+ url: sourceUrl,
1047
+ })
1048
+ : false;
1049
+ const streamDecision = !streamPdf
1050
+ ? shouldStreamRemoteUrl === null || shouldStreamRemoteUrl === void 0 ? void 0 : shouldStreamRemoteUrl({
1051
+ url: sourceUrl,
1052
+ filename: nextFilename,
1053
+ extension,
1054
+ pageHref,
1055
+ })
1056
+ : false;
962
1057
  return {
963
1058
  url: sourceUrl,
964
1059
  filename: nextFilename,
965
1060
  extension,
966
- streamPdf: pageHref
967
- ? shouldStreamPdfUrl({
968
- extension,
969
- pageHref,
970
- streaming,
971
- url: sourceUrl,
972
- })
973
- : false,
1061
+ streamPdf,
1062
+ streamRenderer: streamDecision === true || typeof streamDecision === 'string',
1063
+ streamType: typeof streamDecision === 'string' ? streamDecision : undefined,
974
1064
  };
975
1065
  };
976
1066
  export const commitFileViewerRemoteDownloadState = ({ version, data, currentFilename, fallbackFilename, isCurrent, i18n, onMissingData, onSetLoadingMessage, }) => {
@@ -1,14 +1,10 @@
1
- import type { FileViewerFileRef, FileViewerSource } from '../contracts/types';
1
+ import type { FileViewerFileRef, FileViewerSource } from "../contracts/types.js";
2
2
  export type FileViewerPrecheckStatus = 'ready' | 'invalid' | 'unsupported';
3
3
  export type FileViewerPrecheckReason = 'content-valid' | 'content-not-inspected' | 'content-inconclusive' | 'empty-structured-file' | 'signature-mismatch' | 'invalid-package' | 'missing-package-part' | 'unsupported-extension';
4
4
  export interface FileViewerPrecheckOptions {
5
- /** Filename used when a Blob or ArrayBuffer has no name. */
6
5
  filename?: string;
7
- /** Explicit extension, with or without a leading dot. */
8
6
  type?: string;
9
- /** Restricts the result to the renderers installed by the host application. */
10
7
  supportedExtensions?: Iterable<string>;
11
- /** Maximum ZIP central-directory bytes read from a Blob. Defaults to 8 MiB. */
12
8
  maxPackageMetadataBytes?: number;
13
9
  }
14
10
  export interface FileViewerPrecheckResult {
@@ -17,7 +13,6 @@ export interface FileViewerPrecheckResult {
17
13
  rendererId: string | null;
18
14
  supported: boolean;
19
15
  inspected: boolean;
20
- /** `null` means the extension is supported but no structural validator exists. */
21
16
  valid: boolean | null;
22
17
  previewable: boolean;
23
18
  status: FileViewerPrecheckStatus;
@@ -25,12 +20,5 @@ export interface FileViewerPrecheckResult {
25
20
  missingParts: string[];
26
21
  }
27
22
  type FileViewerPrecheckInput = FileViewerSource | FileViewerFileRef;
28
- /**
29
- * Performs a cheap, renderer-free capability and structure check.
30
- *
31
- * This intentionally does not promise rendering fidelity. A `ready` result
32
- * means the extension is available and any known container/signature checks
33
- * passed; the real renderer remains the final authority for malformed content.
34
- */
35
23
  export declare const precheckFileViewerSource: (input: FileViewerPrecheckInput, options?: FileViewerPrecheckOptions) => Promise<FileViewerPrecheckResult>;
36
24
  export {};
@@ -1,5 +1,5 @@
1
- import { DEFAULT_RENDERER_DEFINITIONS, DEFAULT_SUPPORTED_EXTENSIONS } from '../registry/formats.js';
2
- import { getExtension, normalizeFileExtension, normalizeFilename, normalizeSource, } from './index.js';
1
+ import { DEFAULT_RENDERER_DEFINITIONS, DEFAULT_SUPPORTED_EXTENSIONS } from "../registry/formats.js";
2
+ import { getExtension, normalizeFileExtension, normalizeFilename, normalizeSource, } from "./index.js";
3
3
  const DEFAULT_MAX_PACKAGE_METADATA_BYTES = 8 * 1024 * 1024;
4
4
  const ZIP_LOCAL_SIGNATURE = 0x04034b50;
5
5
  const ZIP_CENTRAL_SIGNATURE = 0x02014b50;
@@ -203,13 +203,6 @@ const inspectStructuredContent = async (source, extension, maxPackageMetadataByt
203
203
  }
204
204
  return { inspected: false, valid: null, reason: 'content-not-inspected' };
205
205
  };
206
- /**
207
- * Performs a cheap, renderer-free capability and structure check.
208
- *
209
- * This intentionally does not promise rendering fidelity. A `ready` result
210
- * means the extension is available and any known container/signature checks
211
- * passed; the real renderer remains the final authority for malformed content.
212
- */
213
206
  export const precheckFileViewerSource = async (input, options = {}) => {
214
207
  var _a;
215
208
  const source = toSource(input, options);
@@ -1,5 +1,8 @@
1
- export type FileViewerTextEncoding = 'auto' | 'utf-8' | 'utf-16le' | 'utf-16be' | 'gbk' | 'gb18030';
1
+ export type FileViewerSingleByteTextEncoding = 'iso-8859-1' | 'iso-8859-2' | 'iso-8859-15' | 'windows-1250' | 'windows-1251' | 'windows-1252';
2
+ export type FileViewerTextEncoding = 'auto' | 'utf-8' | 'utf-16le' | 'utf-16be' | 'gbk' | 'gb18030' | FileViewerSingleByteTextEncoding;
2
3
  export type ResolvedFileViewerTextEncoding = Exclude<FileViewerTextEncoding, 'auto' | 'gbk'>;
4
+ export declare const DEFAULT_FILE_VIEWER_TEXT_FALLBACK_ENCODING: ResolvedFileViewerTextEncoding;
5
+ export declare const isSingleByteFileViewerTextEncoding: (encoding: string | undefined) => encoding is FileViewerSingleByteTextEncoding;
3
6
  export interface DecodedFileViewerText {
4
7
  text: string;
5
8
  encoding: ResolvedFileViewerTextEncoding;
@@ -9,6 +12,6 @@ export interface ResolvedFileViewerTextSource {
9
12
  bomLength: number;
10
13
  }
11
14
  export declare const isValidFileViewerUtf8: (bytes: Uint8Array) => boolean;
12
- export declare const resolveFileViewerTextEncoding: (bytes: Uint8Array, encoding?: FileViewerTextEncoding | string) => ResolvedFileViewerTextSource;
15
+ export declare const resolveFileViewerTextEncoding: (bytes: Uint8Array, encoding?: FileViewerTextEncoding | string, fallbackEncoding?: FileViewerTextEncoding | string) => ResolvedFileViewerTextSource;
13
16
  export declare const createFileViewerTextDecoder: (encoding: ResolvedFileViewerTextEncoding) => TextDecoder;
14
- export declare const decodeFileViewerTextBuffer: (data: ArrayBuffer, encoding?: FileViewerTextEncoding | string) => DecodedFileViewerText;
17
+ export declare const decodeFileViewerTextBuffer: (data: ArrayBuffer, encoding?: FileViewerTextEncoding | string, fallbackEncoding?: FileViewerTextEncoding | string) => DecodedFileViewerText;
@@ -1,5 +1,44 @@
1
+ export const DEFAULT_FILE_VIEWER_TEXT_FALLBACK_ENCODING = 'gb18030';
2
+ const SINGLE_BYTE_ENCODING_ALIASES = new Map([
3
+ ['iso-8859-1', 'iso-8859-1'],
4
+ ['iso8859-1', 'iso-8859-1'],
5
+ ['iso88591', 'iso-8859-1'],
6
+ ['latin1', 'iso-8859-1'],
7
+ ['latin-1', 'iso-8859-1'],
8
+ ['l1', 'iso-8859-1'],
9
+ ['cp819', 'iso-8859-1'],
10
+ ['ibm819', 'iso-8859-1'],
11
+ ['iso-8859-2', 'iso-8859-2'],
12
+ ['iso8859-2', 'iso-8859-2'],
13
+ ['iso88592', 'iso-8859-2'],
14
+ ['latin2', 'iso-8859-2'],
15
+ ['latin-2', 'iso-8859-2'],
16
+ ['l2', 'iso-8859-2'],
17
+ ['iso-8859-15', 'iso-8859-15'],
18
+ ['iso8859-15', 'iso-8859-15'],
19
+ ['iso885915', 'iso-8859-15'],
20
+ ['latin9', 'iso-8859-15'],
21
+ ['latin-9', 'iso-8859-15'],
22
+ ['l9', 'iso-8859-15'],
23
+ ['windows-1250', 'windows-1250'],
24
+ ['windows1250', 'windows-1250'],
25
+ ['cp1250', 'windows-1250'],
26
+ ['x-cp1250', 'windows-1250'],
27
+ ['windows-1251', 'windows-1251'],
28
+ ['windows1251', 'windows-1251'],
29
+ ['cp1251', 'windows-1251'],
30
+ ['x-cp1251', 'windows-1251'],
31
+ ['windows-1252', 'windows-1252'],
32
+ ['windows1252', 'windows-1252'],
33
+ ['cp1252', 'windows-1252'],
34
+ ['x-cp1252', 'windows-1252']
35
+ ]);
36
+ const SINGLE_BYTE_ENCODINGS = new Set(SINGLE_BYTE_ENCODING_ALIASES.values());
37
+ export const isSingleByteFileViewerTextEncoding = (encoding) => {
38
+ return encoding !== undefined && SINGLE_BYTE_ENCODINGS.has(encoding);
39
+ };
1
40
  const normalizeEncoding = (encoding) => {
2
- const normalized = String(encoding || 'auto').trim().toLowerCase().replace('_', '-');
41
+ const normalized = String(encoding || 'auto').trim().toLowerCase().replace(/_/g, '-');
3
42
  if (normalized === 'utf8' || normalized === 'utf-8') {
4
43
  return 'utf-8';
5
44
  }
@@ -15,13 +54,24 @@ const normalizeEncoding = (encoding) => {
15
54
  if (normalized === 'gb18030') {
16
55
  return 'gb18030';
17
56
  }
57
+ const singleByte = SINGLE_BYTE_ENCODING_ALIASES.get(normalized);
58
+ if (singleByte) {
59
+ return singleByte;
60
+ }
18
61
  return 'auto';
19
62
  };
63
+ const toResolvedEncoding = (encoding) => {
64
+ return encoding === 'gbk' ? 'gb18030' : encoding;
65
+ };
66
+ const normalizeFallbackEncoding = (fallbackEncoding) => {
67
+ const normalized = normalizeEncoding(fallbackEncoding);
68
+ return normalized === 'auto'
69
+ ? DEFAULT_FILE_VIEWER_TEXT_FALLBACK_ENCODING
70
+ : toResolvedEncoding(normalized);
71
+ };
20
72
  const isContinuationByte = (value) => {
21
73
  return value !== undefined && value >= 0x80 && value <= 0xbf;
22
74
  };
23
- // Validate bytes directly because older WebViews can accept the fatal option
24
- // while still replacing malformed input. That would hide the GB18030 fallback.
25
75
  export const isValidFileViewerUtf8 = (bytes) => {
26
76
  for (let index = 0; index < bytes.length;) {
27
77
  const first = bytes[index];
@@ -102,11 +152,11 @@ const inferBomlessUtf16 = (bytes) => {
102
152
  }
103
153
  return null;
104
154
  };
105
- export const resolveFileViewerTextEncoding = (bytes, encoding = 'auto') => {
155
+ export const resolveFileViewerTextEncoding = (bytes, encoding = 'auto', fallbackEncoding = DEFAULT_FILE_VIEWER_TEXT_FALLBACK_ENCODING) => {
106
156
  const normalized = normalizeEncoding(encoding);
107
157
  if (normalized !== 'auto') {
108
158
  return {
109
- encoding: normalized === 'gbk' ? 'gb18030' : normalized,
159
+ encoding: toResolvedEncoding(normalized),
110
160
  bomLength: normalized === 'utf-8' && bytes[0] === 0xef && bytes[1] === 0xbb && bytes[2] === 0xbf
111
161
  ? 3
112
162
  : (normalized === 'utf-16le' && bytes[0] === 0xff && bytes[1] === 0xfe) ||
@@ -130,7 +180,7 @@ export const resolveFileViewerTextEncoding = (bytes, encoding = 'auto') => {
130
180
  }
131
181
  return isValidFileViewerUtf8(bytes)
132
182
  ? { encoding: 'utf-8', bomLength: 0 }
133
- : { encoding: 'gb18030', bomLength: 0 };
183
+ : { encoding: normalizeFallbackEncoding(fallbackEncoding), bomLength: 0 };
134
184
  };
135
185
  export const createFileViewerTextDecoder = (encoding) => {
136
186
  if (typeof TextDecoder === 'undefined') {
@@ -146,9 +196,9 @@ export const createFileViewerTextDecoder = (encoding) => {
146
196
  throw error;
147
197
  }
148
198
  };
149
- export const decodeFileViewerTextBuffer = (data, encoding = 'auto') => {
199
+ export const decodeFileViewerTextBuffer = (data, encoding = 'auto', fallbackEncoding = DEFAULT_FILE_VIEWER_TEXT_FALLBACK_ENCODING) => {
150
200
  const bytes = new Uint8Array(data);
151
- const resolved = resolveFileViewerTextEncoding(bytes, encoding);
201
+ const resolved = resolveFileViewerTextEncoding(bytes, encoding, fallbackEncoding);
152
202
  return {
153
203
  text: createFileViewerTextDecoder(resolved.encoding).decode(bytes.subarray(resolved.bomLength)),
154
204
  encoding: resolved.encoding
@@ -1,4 +1,4 @@
1
- import type { FileViewerEventHandler, FileViewerInstance, FileViewerOptions, FileViewerRenderPurpose, RendererRegistry } from '../contracts/types';
1
+ import type { FileViewerEventHandler, FileViewerInstance, FileViewerOptions, FileViewerRenderPurpose, RendererRegistry } from "../contracts/types.js";
2
2
  export interface CreateViewerOptions {
3
3
  registry?: RendererRegistry;
4
4
  options?: FileViewerOptions;