@files-preview-app/preview-file 1.1.4 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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.cjs
CHANGED
|
@@ -412,8 +412,39 @@ function createElement(tag, attrs, ...children) {
|
|
|
412
412
|
}
|
|
413
413
|
return el;
|
|
414
414
|
}
|
|
415
|
+
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>`;
|
|
416
|
+
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>`;
|
|
417
|
+
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>`;
|
|
418
|
+
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>`;
|
|
419
|
+
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>`;
|
|
420
|
+
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>`;
|
|
421
|
+
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>`;
|
|
415
422
|
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>`;
|
|
416
423
|
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>`;
|
|
424
|
+
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>`;
|
|
425
|
+
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>`;
|
|
426
|
+
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>`;
|
|
427
|
+
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>`;
|
|
428
|
+
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>`;
|
|
429
|
+
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>`;
|
|
430
|
+
var ICON_MAP = {
|
|
431
|
+
"zoom-in": ICON_ZOOM_IN,
|
|
432
|
+
"zoom-out": ICON_ZOOM_OUT,
|
|
433
|
+
"fit-page": ICON_FIT_PAGE,
|
|
434
|
+
"fit-slide": ICON_FIT_PAGE,
|
|
435
|
+
"rotate-cw": ICON_ROTATE_CW,
|
|
436
|
+
"rotate-ccw": ICON_ROTATE_CCW,
|
|
437
|
+
"download": ICON_DOWNLOAD,
|
|
438
|
+
"print": ICON_PRINT,
|
|
439
|
+
"thumbnails": ICON_THUMBNAILS,
|
|
440
|
+
"fullscreen": ICON_FULLSCREEN,
|
|
441
|
+
"play": ICON_PLAY,
|
|
442
|
+
"pause": ICON_PAUSE,
|
|
443
|
+
"close": ICON_CLOSE,
|
|
444
|
+
"copy": ICON_COPY,
|
|
445
|
+
"prev": ICON_PAGE_PREV,
|
|
446
|
+
"next": ICON_PAGE_NEXT
|
|
447
|
+
};
|
|
417
448
|
var ToolbarController = class {
|
|
418
449
|
el;
|
|
419
450
|
toolbarEl;
|
|
@@ -524,10 +555,11 @@ var ToolbarController = class {
|
|
|
524
555
|
type: "button",
|
|
525
556
|
"data-action-id": id
|
|
526
557
|
});
|
|
527
|
-
|
|
528
|
-
|
|
558
|
+
const svg = ICON_MAP[iconHtml] || iconHtml;
|
|
559
|
+
if (svg && svg.startsWith("<svg")) {
|
|
560
|
+
btn.innerHTML = sanitizeSVG(svg);
|
|
529
561
|
} else {
|
|
530
|
-
btn.textContent =
|
|
562
|
+
btn.textContent = svg || title;
|
|
531
563
|
}
|
|
532
564
|
btn.addEventListener("click", onClick);
|
|
533
565
|
return btn;
|
|
@@ -608,6 +640,9 @@ var FilePreviewViewer = class {
|
|
|
608
640
|
contentEl = null;
|
|
609
641
|
currentBuffer = null;
|
|
610
642
|
currentMetadata = null;
|
|
643
|
+
keyHandler = null;
|
|
644
|
+
currentContainer = null;
|
|
645
|
+
currentOptions = {};
|
|
611
646
|
/**
|
|
612
647
|
* Register a preview plugin.
|
|
613
648
|
*/
|
|
@@ -662,24 +697,47 @@ var FilePreviewViewer = class {
|
|
|
662
697
|
emit: (event, payload) => this.eventEmitter.emit(event, payload)
|
|
663
698
|
});
|
|
664
699
|
this.activeInstance = instance;
|
|
700
|
+
this.hideLoading();
|
|
701
|
+
this.eventEmitter.emit("loaded", { metadata, plugin: matchedPlugin.id });
|
|
665
702
|
if (options.showToolbar !== false && this.toolbar) {
|
|
666
703
|
const actions = matchedPlugin.getToolbarActions(instance);
|
|
704
|
+
const hasFullscreen = actions.some((a) => a.id === "fullscreen");
|
|
705
|
+
if (!hasFullscreen && this.wrapperEl) {
|
|
706
|
+
actions.push({
|
|
707
|
+
id: "fullscreen",
|
|
708
|
+
icon: "fullscreen",
|
|
709
|
+
label: "Toggle Fullscreen",
|
|
710
|
+
type: "button",
|
|
711
|
+
group: "view",
|
|
712
|
+
execute: () => {
|
|
713
|
+
if (!document.fullscreenElement) {
|
|
714
|
+
this.wrapperEl?.requestFullscreen?.();
|
|
715
|
+
} else {
|
|
716
|
+
document.exitFullscreen?.();
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
});
|
|
720
|
+
}
|
|
667
721
|
this.toolbar.update(actions);
|
|
668
722
|
this.toolbar.show();
|
|
669
723
|
}
|
|
670
724
|
if (instance.getThumbnails && this.thumbnailPanel) {
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
725
|
+
Promise.resolve().then(async () => {
|
|
726
|
+
try {
|
|
727
|
+
const thumbnails = await Promise.resolve(instance.getThumbnails());
|
|
728
|
+
if (thumbnails && thumbnails.length > 0 && this.thumbnailPanel) {
|
|
729
|
+
this.thumbnailPanel.update(thumbnails, (index) => {
|
|
730
|
+
instance.goToPage?.(index + 1);
|
|
731
|
+
});
|
|
732
|
+
if (options.showThumbnails) {
|
|
733
|
+
this.thumbnailPanel.show();
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
} catch (e) {
|
|
737
|
+
console.warn("[FilePreview] Non-critical thumbnail load error:", e);
|
|
678
738
|
}
|
|
679
|
-
}
|
|
739
|
+
});
|
|
680
740
|
}
|
|
681
|
-
this.hideLoading();
|
|
682
|
-
this.eventEmitter.emit("loaded", { metadata, plugin: matchedPlugin.id });
|
|
683
741
|
return instance;
|
|
684
742
|
} catch (error) {
|
|
685
743
|
this.hideLoading();
|
|
@@ -701,6 +759,10 @@ var FilePreviewViewer = class {
|
|
|
701
759
|
* Destroy the viewer and clean up all resources.
|
|
702
760
|
*/
|
|
703
761
|
destroy() {
|
|
762
|
+
if (this.keyHandler) {
|
|
763
|
+
window.removeEventListener("keydown", this.keyHandler);
|
|
764
|
+
this.keyHandler = null;
|
|
765
|
+
}
|
|
704
766
|
this.abort();
|
|
705
767
|
this.destroyInstance();
|
|
706
768
|
this.toolbar?.destroy();
|
|
@@ -716,6 +778,7 @@ var FilePreviewViewer = class {
|
|
|
716
778
|
this.thumbnailPanel = null;
|
|
717
779
|
this.currentBuffer = null;
|
|
718
780
|
this.currentMetadata = null;
|
|
781
|
+
this.currentContainer = null;
|
|
719
782
|
}
|
|
720
783
|
/**
|
|
721
784
|
* Get the currently active preview instance.
|
|
@@ -745,6 +808,8 @@ var FilePreviewViewer = class {
|
|
|
745
808
|
return null;
|
|
746
809
|
}
|
|
747
810
|
setupDOM(container, options) {
|
|
811
|
+
this.currentContainer = container;
|
|
812
|
+
this.currentOptions = options;
|
|
748
813
|
if (this.wrapperEl?.parentNode === container) return;
|
|
749
814
|
if (this.wrapperEl?.parentNode) {
|
|
750
815
|
this.wrapperEl.parentNode.removeChild(this.wrapperEl);
|
|
@@ -753,6 +818,7 @@ var FilePreviewViewer = class {
|
|
|
753
818
|
const toolbarPos = options.toolbarPosition ?? "top";
|
|
754
819
|
this.wrapperEl = document.createElement("div");
|
|
755
820
|
this.wrapperEl.className = `fp-viewer ${themeClass} ${options.className ?? ""}`.trim();
|
|
821
|
+
this.wrapperEl.tabIndex = 0;
|
|
756
822
|
const toolbarEl = document.createElement("div");
|
|
757
823
|
toolbarEl.className = "fp-toolbar-container";
|
|
758
824
|
this.contentEl = document.createElement("div");
|
|
@@ -774,6 +840,59 @@ var FilePreviewViewer = class {
|
|
|
774
840
|
container.appendChild(this.wrapperEl);
|
|
775
841
|
this.toolbar = new ToolbarController(toolbarEl);
|
|
776
842
|
this.thumbnailPanel = new ThumbnailPanel(thumbnailEl);
|
|
843
|
+
this.setupKeyboardShortcuts();
|
|
844
|
+
this.setupDragAndDrop(container, options);
|
|
845
|
+
}
|
|
846
|
+
setupKeyboardShortcuts() {
|
|
847
|
+
if (this.keyHandler) return;
|
|
848
|
+
this.keyHandler = (e) => {
|
|
849
|
+
if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement || e.target?.isContentEditable) {
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
if (!this.activeInstance) return;
|
|
853
|
+
if (e.key === "ArrowRight" || e.key === "PageDown") {
|
|
854
|
+
const cur = this.activeInstance.getCurrentPage?.() ?? 1;
|
|
855
|
+
this.activeInstance.goToPage?.(cur + 1);
|
|
856
|
+
} else if (e.key === "ArrowLeft" || e.key === "PageUp") {
|
|
857
|
+
const cur = this.activeInstance.getCurrentPage?.() ?? 1;
|
|
858
|
+
this.activeInstance.goToPage?.(Math.max(1, cur - 1));
|
|
859
|
+
} else if (e.key === "+" || e.key === "=") {
|
|
860
|
+
this.activeInstance.zoomIn?.();
|
|
861
|
+
} else if (e.key === "-" || e.key === "_") {
|
|
862
|
+
this.activeInstance.zoomOut?.();
|
|
863
|
+
} else if (e.key === "0") {
|
|
864
|
+
this.activeInstance.fitToPage?.();
|
|
865
|
+
} else if (e.key === "r" || e.key === "R") {
|
|
866
|
+
this.activeInstance.rotateCW?.();
|
|
867
|
+
} else if (e.key === "f" || e.key === "F") {
|
|
868
|
+
if (!document.fullscreenElement) {
|
|
869
|
+
this.wrapperEl?.requestFullscreen?.();
|
|
870
|
+
} else {
|
|
871
|
+
document.exitFullscreen?.();
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
};
|
|
875
|
+
window.addEventListener("keydown", this.keyHandler);
|
|
876
|
+
}
|
|
877
|
+
setupDragAndDrop(container, options) {
|
|
878
|
+
if (!this.wrapperEl) return;
|
|
879
|
+
this.wrapperEl.addEventListener("dragover", (e) => {
|
|
880
|
+
e.preventDefault();
|
|
881
|
+
this.wrapperEl?.classList.add("fp-dragover");
|
|
882
|
+
});
|
|
883
|
+
this.wrapperEl.addEventListener("dragleave", (e) => {
|
|
884
|
+
if (e.relatedTarget === null || !this.wrapperEl?.contains(e.relatedTarget)) {
|
|
885
|
+
this.wrapperEl?.classList.remove("fp-dragover");
|
|
886
|
+
}
|
|
887
|
+
});
|
|
888
|
+
this.wrapperEl.addEventListener("drop", (e) => {
|
|
889
|
+
e.preventDefault();
|
|
890
|
+
this.wrapperEl?.classList.remove("fp-dragover");
|
|
891
|
+
const file = e.dataTransfer?.files?.[0];
|
|
892
|
+
if (file) {
|
|
893
|
+
this.preview(container, file, options);
|
|
894
|
+
}
|
|
895
|
+
});
|
|
777
896
|
}
|
|
778
897
|
showLoading() {
|
|
779
898
|
if (!this.contentEl) return;
|
|
@@ -792,10 +911,27 @@ var FilePreviewViewer = class {
|
|
|
792
911
|
this.contentEl.innerHTML = "";
|
|
793
912
|
const errorEl = document.createElement("div");
|
|
794
913
|
errorEl.className = "fp-error";
|
|
914
|
+
errorEl.style.display = "flex";
|
|
915
|
+
errorEl.style.flexDirection = "column";
|
|
916
|
+
errorEl.style.alignItems = "center";
|
|
917
|
+
errorEl.style.justifyContent = "center";
|
|
918
|
+
errorEl.style.padding = "32px";
|
|
919
|
+
errorEl.style.textAlign = "center";
|
|
920
|
+
const hasDownload = !!(this.currentBuffer && this.currentMetadata);
|
|
795
921
|
errorEl.innerHTML = `
|
|
796
|
-
<div class="fp-error-icon">\u26A0\uFE0F</div>
|
|
797
|
-
<div class="fp-error-message"
|
|
922
|
+
<div class="fp-error-icon" style="font-size:36px;margin-bottom:8px;">\u26A0\uFE0F</div>
|
|
923
|
+
<div class="fp-error-message" style="font-size:16px;font-weight:600;margin-bottom:6px;">Cannot preview file</div>
|
|
924
|
+
<div class="fp-error-sub" style="font-size:13px;color:#64748b;max-width:420px;line-height:1.5;margin-bottom:16px;">${message}</div>
|
|
925
|
+
${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>' : ""}
|
|
798
926
|
`;
|
|
927
|
+
if (hasDownload && this.currentBuffer) {
|
|
928
|
+
const btn = errorEl.querySelector(".fp-error-download-btn");
|
|
929
|
+
if (btn) {
|
|
930
|
+
btn.addEventListener("click", () => {
|
|
931
|
+
downloadFile(this.currentBuffer, this.currentMetadata?.name || "download", this.currentMetadata?.mimeType);
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
}
|
|
799
935
|
this.contentEl.appendChild(errorEl);
|
|
800
936
|
}
|
|
801
937
|
};
|
|
@@ -1716,6 +1852,16 @@ var CodePlugin = class {
|
|
|
1716
1852
|
instance.zoomIn?.();
|
|
1717
1853
|
}
|
|
1718
1854
|
},
|
|
1855
|
+
{
|
|
1856
|
+
id: "copy",
|
|
1857
|
+
icon: "copy",
|
|
1858
|
+
label: "Copy Content",
|
|
1859
|
+
type: "button",
|
|
1860
|
+
group: "actions",
|
|
1861
|
+
execute: () => {
|
|
1862
|
+
instance.copy?.();
|
|
1863
|
+
}
|
|
1864
|
+
},
|
|
1719
1865
|
{
|
|
1720
1866
|
id: "download",
|
|
1721
1867
|
icon: "download",
|
|
@@ -1803,6 +1949,9 @@ var CodePlugin = class {
|
|
|
1803
1949
|
},
|
|
1804
1950
|
print: () => {
|
|
1805
1951
|
window.print();
|
|
1952
|
+
},
|
|
1953
|
+
copy: () => {
|
|
1954
|
+
navigator.clipboard?.writeText(text);
|
|
1806
1955
|
}
|
|
1807
1956
|
};
|
|
1808
1957
|
}
|
|
@@ -2053,6 +2202,14 @@ var MarkdownPlugin = class {
|
|
|
2053
2202
|
group: "zoom",
|
|
2054
2203
|
execute: () => instance.fitToPage?.()
|
|
2055
2204
|
},
|
|
2205
|
+
{
|
|
2206
|
+
id: "copy",
|
|
2207
|
+
icon: "copy",
|
|
2208
|
+
label: "Copy Markdown",
|
|
2209
|
+
type: "button",
|
|
2210
|
+
group: "actions",
|
|
2211
|
+
execute: () => instance.copy?.()
|
|
2212
|
+
},
|
|
2056
2213
|
{
|
|
2057
2214
|
id: "download",
|
|
2058
2215
|
icon: "download",
|
|
@@ -2203,6 +2360,9 @@ var MarkdownPlugin = class {
|
|
|
2203
2360
|
},
|
|
2204
2361
|
print: () => {
|
|
2205
2362
|
window.print();
|
|
2363
|
+
},
|
|
2364
|
+
copy: () => {
|
|
2365
|
+
navigator.clipboard?.writeText(text);
|
|
2206
2366
|
}
|
|
2207
2367
|
};
|
|
2208
2368
|
}
|