@files-preview-app/preview-file 1.1.4 → 1.1.6
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.
- package/dist/angular.cjs +175 -15
- package/dist/angular.cjs.map +1 -1
- package/dist/angular.js +175 -15
- package/dist/angular.js.map +1 -1
- package/dist/index.cjs +175 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +175 -15
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +175 -15
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +175 -15
- package/dist/react.js.map +1 -1
- package/dist/styles.css +12 -0
- package/dist/vue.cjs +175 -15
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.js +175 -15
- package/dist/vue.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -384,8 +384,39 @@ function createElement(tag, attrs, ...children) {
|
|
|
384
384
|
}
|
|
385
385
|
return el;
|
|
386
386
|
}
|
|
387
|
+
var ICON_ZOOM_IN = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line><line x1="11" y1="8" x2="11" y2="14"></line><line x1="8" y1="11" x2="14" y2="11"></line></svg>`;
|
|
388
|
+
var ICON_ZOOM_OUT = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line><line x1="8" y1="11" x2="14" y2="11"></line></svg>`;
|
|
389
|
+
var ICON_FIT_PAGE = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" y1="3" x2="14" y2="10"></line><line x1="3" y1="21" x2="10" y2="14"></line></svg>`;
|
|
390
|
+
var ICON_ROTATE_CW = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"></polyline><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"></path></svg>`;
|
|
391
|
+
var ICON_ROTATE_CCW = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="1 4 1 10 7 10"></polyline><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"></path></svg>`;
|
|
392
|
+
var ICON_DOWNLOAD = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>`;
|
|
393
|
+
var ICON_PRINT = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 6 2 18 2 18 9"></polyline><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path><rect x="6" y="14" width="12" height="8"></rect></svg>`;
|
|
387
394
|
var ICON_PAGE_PREV = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"></polyline></svg>`;
|
|
388
395
|
var ICON_PAGE_NEXT = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg>`;
|
|
396
|
+
var ICON_PLAY = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>`;
|
|
397
|
+
var ICON_PAUSE = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="6" y="4" width="4" height="16"></rect><rect x="14" y="4" width="4" height="16"></rect></svg>`;
|
|
398
|
+
var ICON_THUMBNAILS = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7"></rect><rect x="14" y="3" width="7" height="7"></rect><rect x="14" y="14" width="7" height="7"></rect><rect x="3" y="14" width="7" height="7"></rect></svg>`;
|
|
399
|
+
var ICON_CLOSE = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>`;
|
|
400
|
+
var ICON_FULLSCREEN = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"></path></svg>`;
|
|
401
|
+
var ICON_COPY = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>`;
|
|
402
|
+
var ICON_MAP = {
|
|
403
|
+
"zoom-in": ICON_ZOOM_IN,
|
|
404
|
+
"zoom-out": ICON_ZOOM_OUT,
|
|
405
|
+
"fit-page": ICON_FIT_PAGE,
|
|
406
|
+
"fit-slide": ICON_FIT_PAGE,
|
|
407
|
+
"rotate-cw": ICON_ROTATE_CW,
|
|
408
|
+
"rotate-ccw": ICON_ROTATE_CCW,
|
|
409
|
+
"download": ICON_DOWNLOAD,
|
|
410
|
+
"print": ICON_PRINT,
|
|
411
|
+
"thumbnails": ICON_THUMBNAILS,
|
|
412
|
+
"fullscreen": ICON_FULLSCREEN,
|
|
413
|
+
"play": ICON_PLAY,
|
|
414
|
+
"pause": ICON_PAUSE,
|
|
415
|
+
"close": ICON_CLOSE,
|
|
416
|
+
"copy": ICON_COPY,
|
|
417
|
+
"prev": ICON_PAGE_PREV,
|
|
418
|
+
"next": ICON_PAGE_NEXT
|
|
419
|
+
};
|
|
389
420
|
var ToolbarController = class {
|
|
390
421
|
el;
|
|
391
422
|
toolbarEl;
|
|
@@ -496,10 +527,11 @@ var ToolbarController = class {
|
|
|
496
527
|
type: "button",
|
|
497
528
|
"data-action-id": id
|
|
498
529
|
});
|
|
499
|
-
|
|
500
|
-
|
|
530
|
+
const svg = ICON_MAP[iconHtml] || iconHtml;
|
|
531
|
+
if (svg && svg.startsWith("<svg")) {
|
|
532
|
+
btn.innerHTML = sanitizeSVG(svg);
|
|
501
533
|
} else {
|
|
502
|
-
btn.textContent =
|
|
534
|
+
btn.textContent = svg || title;
|
|
503
535
|
}
|
|
504
536
|
btn.addEventListener("click", onClick);
|
|
505
537
|
return btn;
|
|
@@ -580,6 +612,9 @@ var FilePreviewViewer = class {
|
|
|
580
612
|
contentEl = null;
|
|
581
613
|
currentBuffer = null;
|
|
582
614
|
currentMetadata = null;
|
|
615
|
+
keyHandler = null;
|
|
616
|
+
currentContainer = null;
|
|
617
|
+
currentOptions = {};
|
|
583
618
|
/**
|
|
584
619
|
* Register a preview plugin.
|
|
585
620
|
*/
|
|
@@ -634,24 +669,47 @@ var FilePreviewViewer = class {
|
|
|
634
669
|
emit: (event, payload) => this.eventEmitter.emit(event, payload)
|
|
635
670
|
});
|
|
636
671
|
this.activeInstance = instance;
|
|
672
|
+
this.hideLoading();
|
|
673
|
+
this.eventEmitter.emit("loaded", { metadata, plugin: matchedPlugin.id });
|
|
637
674
|
if (options.showToolbar !== false && this.toolbar) {
|
|
638
675
|
const actions = matchedPlugin.getToolbarActions(instance);
|
|
676
|
+
const hasFullscreen = actions.some((a) => a.id === "fullscreen");
|
|
677
|
+
if (!hasFullscreen && this.wrapperEl) {
|
|
678
|
+
actions.push({
|
|
679
|
+
id: "fullscreen",
|
|
680
|
+
icon: "fullscreen",
|
|
681
|
+
label: "Toggle Fullscreen",
|
|
682
|
+
type: "button",
|
|
683
|
+
group: "view",
|
|
684
|
+
execute: () => {
|
|
685
|
+
if (!document.fullscreenElement) {
|
|
686
|
+
this.wrapperEl?.requestFullscreen?.();
|
|
687
|
+
} else {
|
|
688
|
+
document.exitFullscreen?.();
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
});
|
|
692
|
+
}
|
|
639
693
|
this.toolbar.update(actions);
|
|
640
694
|
this.toolbar.show();
|
|
641
695
|
}
|
|
642
696
|
if (instance.getThumbnails && this.thumbnailPanel) {
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
697
|
+
Promise.resolve().then(async () => {
|
|
698
|
+
try {
|
|
699
|
+
const thumbnails = await Promise.resolve(instance.getThumbnails());
|
|
700
|
+
if (thumbnails && thumbnails.length > 0 && this.thumbnailPanel) {
|
|
701
|
+
this.thumbnailPanel.update(thumbnails, (index) => {
|
|
702
|
+
instance.goToPage?.(index + 1);
|
|
703
|
+
});
|
|
704
|
+
if (options.showThumbnails) {
|
|
705
|
+
this.thumbnailPanel.show();
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
} catch (e) {
|
|
709
|
+
console.warn("[FilePreview] Non-critical thumbnail load error:", e);
|
|
650
710
|
}
|
|
651
|
-
}
|
|
711
|
+
});
|
|
652
712
|
}
|
|
653
|
-
this.hideLoading();
|
|
654
|
-
this.eventEmitter.emit("loaded", { metadata, plugin: matchedPlugin.id });
|
|
655
713
|
return instance;
|
|
656
714
|
} catch (error) {
|
|
657
715
|
this.hideLoading();
|
|
@@ -673,6 +731,10 @@ var FilePreviewViewer = class {
|
|
|
673
731
|
* Destroy the viewer and clean up all resources.
|
|
674
732
|
*/
|
|
675
733
|
destroy() {
|
|
734
|
+
if (this.keyHandler) {
|
|
735
|
+
window.removeEventListener("keydown", this.keyHandler);
|
|
736
|
+
this.keyHandler = null;
|
|
737
|
+
}
|
|
676
738
|
this.abort();
|
|
677
739
|
this.destroyInstance();
|
|
678
740
|
this.toolbar?.destroy();
|
|
@@ -688,6 +750,7 @@ var FilePreviewViewer = class {
|
|
|
688
750
|
this.thumbnailPanel = null;
|
|
689
751
|
this.currentBuffer = null;
|
|
690
752
|
this.currentMetadata = null;
|
|
753
|
+
this.currentContainer = null;
|
|
691
754
|
}
|
|
692
755
|
/**
|
|
693
756
|
* Get the currently active preview instance.
|
|
@@ -717,6 +780,8 @@ var FilePreviewViewer = class {
|
|
|
717
780
|
return null;
|
|
718
781
|
}
|
|
719
782
|
setupDOM(container, options) {
|
|
783
|
+
this.currentContainer = container;
|
|
784
|
+
this.currentOptions = options;
|
|
720
785
|
if (this.wrapperEl?.parentNode === container) return;
|
|
721
786
|
if (this.wrapperEl?.parentNode) {
|
|
722
787
|
this.wrapperEl.parentNode.removeChild(this.wrapperEl);
|
|
@@ -725,6 +790,7 @@ var FilePreviewViewer = class {
|
|
|
725
790
|
const toolbarPos = options.toolbarPosition ?? "top";
|
|
726
791
|
this.wrapperEl = document.createElement("div");
|
|
727
792
|
this.wrapperEl.className = `fp-viewer ${themeClass} ${options.className ?? ""}`.trim();
|
|
793
|
+
this.wrapperEl.tabIndex = 0;
|
|
728
794
|
const toolbarEl = document.createElement("div");
|
|
729
795
|
toolbarEl.className = "fp-toolbar-container";
|
|
730
796
|
this.contentEl = document.createElement("div");
|
|
@@ -746,6 +812,59 @@ var FilePreviewViewer = class {
|
|
|
746
812
|
container.appendChild(this.wrapperEl);
|
|
747
813
|
this.toolbar = new ToolbarController(toolbarEl);
|
|
748
814
|
this.thumbnailPanel = new ThumbnailPanel(thumbnailEl);
|
|
815
|
+
this.setupKeyboardShortcuts();
|
|
816
|
+
this.setupDragAndDrop(container, options);
|
|
817
|
+
}
|
|
818
|
+
setupKeyboardShortcuts() {
|
|
819
|
+
if (this.keyHandler) return;
|
|
820
|
+
this.keyHandler = (e) => {
|
|
821
|
+
if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement || e.target?.isContentEditable) {
|
|
822
|
+
return;
|
|
823
|
+
}
|
|
824
|
+
if (!this.activeInstance) return;
|
|
825
|
+
if (e.key === "ArrowRight" || e.key === "PageDown") {
|
|
826
|
+
const cur = this.activeInstance.getCurrentPage?.() ?? 1;
|
|
827
|
+
this.activeInstance.goToPage?.(cur + 1);
|
|
828
|
+
} else if (e.key === "ArrowLeft" || e.key === "PageUp") {
|
|
829
|
+
const cur = this.activeInstance.getCurrentPage?.() ?? 1;
|
|
830
|
+
this.activeInstance.goToPage?.(Math.max(1, cur - 1));
|
|
831
|
+
} else if (e.key === "+" || e.key === "=") {
|
|
832
|
+
this.activeInstance.zoomIn?.();
|
|
833
|
+
} else if (e.key === "-" || e.key === "_") {
|
|
834
|
+
this.activeInstance.zoomOut?.();
|
|
835
|
+
} else if (e.key === "0") {
|
|
836
|
+
this.activeInstance.fitToPage?.();
|
|
837
|
+
} else if (e.key === "r" || e.key === "R") {
|
|
838
|
+
this.activeInstance.rotateCW?.();
|
|
839
|
+
} else if (e.key === "f" || e.key === "F") {
|
|
840
|
+
if (!document.fullscreenElement) {
|
|
841
|
+
this.wrapperEl?.requestFullscreen?.();
|
|
842
|
+
} else {
|
|
843
|
+
document.exitFullscreen?.();
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
};
|
|
847
|
+
window.addEventListener("keydown", this.keyHandler);
|
|
848
|
+
}
|
|
849
|
+
setupDragAndDrop(container, options) {
|
|
850
|
+
if (!this.wrapperEl) return;
|
|
851
|
+
this.wrapperEl.addEventListener("dragover", (e) => {
|
|
852
|
+
e.preventDefault();
|
|
853
|
+
this.wrapperEl?.classList.add("fp-dragover");
|
|
854
|
+
});
|
|
855
|
+
this.wrapperEl.addEventListener("dragleave", (e) => {
|
|
856
|
+
if (e.relatedTarget === null || !this.wrapperEl?.contains(e.relatedTarget)) {
|
|
857
|
+
this.wrapperEl?.classList.remove("fp-dragover");
|
|
858
|
+
}
|
|
859
|
+
});
|
|
860
|
+
this.wrapperEl.addEventListener("drop", (e) => {
|
|
861
|
+
e.preventDefault();
|
|
862
|
+
this.wrapperEl?.classList.remove("fp-dragover");
|
|
863
|
+
const file = e.dataTransfer?.files?.[0];
|
|
864
|
+
if (file) {
|
|
865
|
+
this.preview(container, file, options);
|
|
866
|
+
}
|
|
867
|
+
});
|
|
749
868
|
}
|
|
750
869
|
showLoading() {
|
|
751
870
|
if (!this.contentEl) return;
|
|
@@ -764,10 +883,27 @@ var FilePreviewViewer = class {
|
|
|
764
883
|
this.contentEl.innerHTML = "";
|
|
765
884
|
const errorEl = document.createElement("div");
|
|
766
885
|
errorEl.className = "fp-error";
|
|
886
|
+
errorEl.style.display = "flex";
|
|
887
|
+
errorEl.style.flexDirection = "column";
|
|
888
|
+
errorEl.style.alignItems = "center";
|
|
889
|
+
errorEl.style.justifyContent = "center";
|
|
890
|
+
errorEl.style.padding = "32px";
|
|
891
|
+
errorEl.style.textAlign = "center";
|
|
892
|
+
const hasDownload = !!(this.currentBuffer && this.currentMetadata);
|
|
767
893
|
errorEl.innerHTML = `
|
|
768
|
-
<div class="fp-error-icon">\u26A0\uFE0F</div>
|
|
769
|
-
<div class="fp-error-message"
|
|
894
|
+
<div class="fp-error-icon" style="font-size:36px;margin-bottom:8px;">\u26A0\uFE0F</div>
|
|
895
|
+
<div class="fp-error-message" style="font-size:16px;font-weight:600;margin-bottom:6px;">Cannot preview file</div>
|
|
896
|
+
<div class="fp-error-sub" style="font-size:13px;color:#64748b;max-width:420px;line-height:1.5;margin-bottom:16px;">${message}</div>
|
|
897
|
+
${hasDownload ? '<button class="fp-error-download-btn" style="padding:8px 16px;background:#3b82f6;color:#ffffff;border:none;border-radius:6px;cursor:pointer;font-weight:500;font-size:13px;transition:background 0.2s;">Download Original File</button>' : ""}
|
|
770
898
|
`;
|
|
899
|
+
if (hasDownload && this.currentBuffer) {
|
|
900
|
+
const btn = errorEl.querySelector(".fp-error-download-btn");
|
|
901
|
+
if (btn) {
|
|
902
|
+
btn.addEventListener("click", () => {
|
|
903
|
+
downloadFile(this.currentBuffer, this.currentMetadata?.name || "download", this.currentMetadata?.mimeType);
|
|
904
|
+
});
|
|
905
|
+
}
|
|
906
|
+
}
|
|
771
907
|
this.contentEl.appendChild(errorEl);
|
|
772
908
|
}
|
|
773
909
|
};
|
|
@@ -1688,6 +1824,16 @@ var CodePlugin = class {
|
|
|
1688
1824
|
instance.zoomIn?.();
|
|
1689
1825
|
}
|
|
1690
1826
|
},
|
|
1827
|
+
{
|
|
1828
|
+
id: "copy",
|
|
1829
|
+
icon: "copy",
|
|
1830
|
+
label: "Copy Content",
|
|
1831
|
+
type: "button",
|
|
1832
|
+
group: "actions",
|
|
1833
|
+
execute: () => {
|
|
1834
|
+
instance.copy?.();
|
|
1835
|
+
}
|
|
1836
|
+
},
|
|
1691
1837
|
{
|
|
1692
1838
|
id: "download",
|
|
1693
1839
|
icon: "download",
|
|
@@ -1775,6 +1921,9 @@ var CodePlugin = class {
|
|
|
1775
1921
|
},
|
|
1776
1922
|
print: () => {
|
|
1777
1923
|
window.print();
|
|
1924
|
+
},
|
|
1925
|
+
copy: () => {
|
|
1926
|
+
navigator.clipboard?.writeText(text);
|
|
1778
1927
|
}
|
|
1779
1928
|
};
|
|
1780
1929
|
}
|
|
@@ -2025,6 +2174,14 @@ var MarkdownPlugin = class {
|
|
|
2025
2174
|
group: "zoom",
|
|
2026
2175
|
execute: () => instance.fitToPage?.()
|
|
2027
2176
|
},
|
|
2177
|
+
{
|
|
2178
|
+
id: "copy",
|
|
2179
|
+
icon: "copy",
|
|
2180
|
+
label: "Copy Markdown",
|
|
2181
|
+
type: "button",
|
|
2182
|
+
group: "actions",
|
|
2183
|
+
execute: () => instance.copy?.()
|
|
2184
|
+
},
|
|
2028
2185
|
{
|
|
2029
2186
|
id: "download",
|
|
2030
2187
|
icon: "download",
|
|
@@ -2175,6 +2332,9 @@ var MarkdownPlugin = class {
|
|
|
2175
2332
|
},
|
|
2176
2333
|
print: () => {
|
|
2177
2334
|
window.print();
|
|
2335
|
+
},
|
|
2336
|
+
copy: () => {
|
|
2337
|
+
navigator.clipboard?.writeText(text);
|
|
2178
2338
|
}
|
|
2179
2339
|
};
|
|
2180
2340
|
}
|