@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/angular.cjs
CHANGED
|
@@ -419,8 +419,39 @@ function createElement(tag, attrs, ...children) {
|
|
|
419
419
|
}
|
|
420
420
|
return el;
|
|
421
421
|
}
|
|
422
|
+
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>`;
|
|
423
|
+
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>`;
|
|
424
|
+
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>`;
|
|
425
|
+
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>`;
|
|
426
|
+
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>`;
|
|
427
|
+
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>`;
|
|
428
|
+
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>`;
|
|
422
429
|
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>`;
|
|
423
430
|
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>`;
|
|
431
|
+
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>`;
|
|
432
|
+
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>`;
|
|
433
|
+
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>`;
|
|
434
|
+
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>`;
|
|
435
|
+
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>`;
|
|
436
|
+
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>`;
|
|
437
|
+
var ICON_MAP = {
|
|
438
|
+
"zoom-in": ICON_ZOOM_IN,
|
|
439
|
+
"zoom-out": ICON_ZOOM_OUT,
|
|
440
|
+
"fit-page": ICON_FIT_PAGE,
|
|
441
|
+
"fit-slide": ICON_FIT_PAGE,
|
|
442
|
+
"rotate-cw": ICON_ROTATE_CW,
|
|
443
|
+
"rotate-ccw": ICON_ROTATE_CCW,
|
|
444
|
+
"download": ICON_DOWNLOAD,
|
|
445
|
+
"print": ICON_PRINT,
|
|
446
|
+
"thumbnails": ICON_THUMBNAILS,
|
|
447
|
+
"fullscreen": ICON_FULLSCREEN,
|
|
448
|
+
"play": ICON_PLAY,
|
|
449
|
+
"pause": ICON_PAUSE,
|
|
450
|
+
"close": ICON_CLOSE,
|
|
451
|
+
"copy": ICON_COPY,
|
|
452
|
+
"prev": ICON_PAGE_PREV,
|
|
453
|
+
"next": ICON_PAGE_NEXT
|
|
454
|
+
};
|
|
424
455
|
var ToolbarController = class {
|
|
425
456
|
el;
|
|
426
457
|
toolbarEl;
|
|
@@ -531,10 +562,11 @@ var ToolbarController = class {
|
|
|
531
562
|
type: "button",
|
|
532
563
|
"data-action-id": id
|
|
533
564
|
});
|
|
534
|
-
|
|
535
|
-
|
|
565
|
+
const svg = ICON_MAP[iconHtml] || iconHtml;
|
|
566
|
+
if (svg && svg.startsWith("<svg")) {
|
|
567
|
+
btn.innerHTML = sanitizeSVG(svg);
|
|
536
568
|
} else {
|
|
537
|
-
btn.textContent =
|
|
569
|
+
btn.textContent = svg || title;
|
|
538
570
|
}
|
|
539
571
|
btn.addEventListener("click", onClick);
|
|
540
572
|
return btn;
|
|
@@ -615,6 +647,9 @@ var FilePreviewViewer = class {
|
|
|
615
647
|
contentEl = null;
|
|
616
648
|
currentBuffer = null;
|
|
617
649
|
currentMetadata = null;
|
|
650
|
+
keyHandler = null;
|
|
651
|
+
currentContainer = null;
|
|
652
|
+
currentOptions = {};
|
|
618
653
|
/**
|
|
619
654
|
* Register a preview plugin.
|
|
620
655
|
*/
|
|
@@ -669,24 +704,47 @@ var FilePreviewViewer = class {
|
|
|
669
704
|
emit: (event, payload) => this.eventEmitter.emit(event, payload)
|
|
670
705
|
});
|
|
671
706
|
this.activeInstance = instance;
|
|
707
|
+
this.hideLoading();
|
|
708
|
+
this.eventEmitter.emit("loaded", { metadata, plugin: matchedPlugin.id });
|
|
672
709
|
if (options.showToolbar !== false && this.toolbar) {
|
|
673
710
|
const actions = matchedPlugin.getToolbarActions(instance);
|
|
711
|
+
const hasFullscreen = actions.some((a) => a.id === "fullscreen");
|
|
712
|
+
if (!hasFullscreen && this.wrapperEl) {
|
|
713
|
+
actions.push({
|
|
714
|
+
id: "fullscreen",
|
|
715
|
+
icon: "fullscreen",
|
|
716
|
+
label: "Toggle Fullscreen",
|
|
717
|
+
type: "button",
|
|
718
|
+
group: "view",
|
|
719
|
+
execute: () => {
|
|
720
|
+
if (!document.fullscreenElement) {
|
|
721
|
+
this.wrapperEl?.requestFullscreen?.();
|
|
722
|
+
} else {
|
|
723
|
+
document.exitFullscreen?.();
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
});
|
|
727
|
+
}
|
|
674
728
|
this.toolbar.update(actions);
|
|
675
729
|
this.toolbar.show();
|
|
676
730
|
}
|
|
677
731
|
if (instance.getThumbnails && this.thumbnailPanel) {
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
732
|
+
Promise.resolve().then(async () => {
|
|
733
|
+
try {
|
|
734
|
+
const thumbnails = await Promise.resolve(instance.getThumbnails());
|
|
735
|
+
if (thumbnails && thumbnails.length > 0 && this.thumbnailPanel) {
|
|
736
|
+
this.thumbnailPanel.update(thumbnails, (index) => {
|
|
737
|
+
instance.goToPage?.(index + 1);
|
|
738
|
+
});
|
|
739
|
+
if (options.showThumbnails) {
|
|
740
|
+
this.thumbnailPanel.show();
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
} catch (e) {
|
|
744
|
+
console.warn("[FilePreview] Non-critical thumbnail load error:", e);
|
|
685
745
|
}
|
|
686
|
-
}
|
|
746
|
+
});
|
|
687
747
|
}
|
|
688
|
-
this.hideLoading();
|
|
689
|
-
this.eventEmitter.emit("loaded", { metadata, plugin: matchedPlugin.id });
|
|
690
748
|
return instance;
|
|
691
749
|
} catch (error) {
|
|
692
750
|
this.hideLoading();
|
|
@@ -708,6 +766,10 @@ var FilePreviewViewer = class {
|
|
|
708
766
|
* Destroy the viewer and clean up all resources.
|
|
709
767
|
*/
|
|
710
768
|
destroy() {
|
|
769
|
+
if (this.keyHandler) {
|
|
770
|
+
window.removeEventListener("keydown", this.keyHandler);
|
|
771
|
+
this.keyHandler = null;
|
|
772
|
+
}
|
|
711
773
|
this.abort();
|
|
712
774
|
this.destroyInstance();
|
|
713
775
|
this.toolbar?.destroy();
|
|
@@ -723,6 +785,7 @@ var FilePreviewViewer = class {
|
|
|
723
785
|
this.thumbnailPanel = null;
|
|
724
786
|
this.currentBuffer = null;
|
|
725
787
|
this.currentMetadata = null;
|
|
788
|
+
this.currentContainer = null;
|
|
726
789
|
}
|
|
727
790
|
/**
|
|
728
791
|
* Get the currently active preview instance.
|
|
@@ -752,6 +815,8 @@ var FilePreviewViewer = class {
|
|
|
752
815
|
return null;
|
|
753
816
|
}
|
|
754
817
|
setupDOM(container, options) {
|
|
818
|
+
this.currentContainer = container;
|
|
819
|
+
this.currentOptions = options;
|
|
755
820
|
if (this.wrapperEl?.parentNode === container) return;
|
|
756
821
|
if (this.wrapperEl?.parentNode) {
|
|
757
822
|
this.wrapperEl.parentNode.removeChild(this.wrapperEl);
|
|
@@ -760,6 +825,7 @@ var FilePreviewViewer = class {
|
|
|
760
825
|
const toolbarPos = options.toolbarPosition ?? "top";
|
|
761
826
|
this.wrapperEl = document.createElement("div");
|
|
762
827
|
this.wrapperEl.className = `fp-viewer ${themeClass} ${options.className ?? ""}`.trim();
|
|
828
|
+
this.wrapperEl.tabIndex = 0;
|
|
763
829
|
const toolbarEl = document.createElement("div");
|
|
764
830
|
toolbarEl.className = "fp-toolbar-container";
|
|
765
831
|
this.contentEl = document.createElement("div");
|
|
@@ -781,6 +847,59 @@ var FilePreviewViewer = class {
|
|
|
781
847
|
container.appendChild(this.wrapperEl);
|
|
782
848
|
this.toolbar = new ToolbarController(toolbarEl);
|
|
783
849
|
this.thumbnailPanel = new ThumbnailPanel(thumbnailEl);
|
|
850
|
+
this.setupKeyboardShortcuts();
|
|
851
|
+
this.setupDragAndDrop(container, options);
|
|
852
|
+
}
|
|
853
|
+
setupKeyboardShortcuts() {
|
|
854
|
+
if (this.keyHandler) return;
|
|
855
|
+
this.keyHandler = (e) => {
|
|
856
|
+
if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement || e.target?.isContentEditable) {
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
if (!this.activeInstance) return;
|
|
860
|
+
if (e.key === "ArrowRight" || e.key === "PageDown") {
|
|
861
|
+
const cur = this.activeInstance.getCurrentPage?.() ?? 1;
|
|
862
|
+
this.activeInstance.goToPage?.(cur + 1);
|
|
863
|
+
} else if (e.key === "ArrowLeft" || e.key === "PageUp") {
|
|
864
|
+
const cur = this.activeInstance.getCurrentPage?.() ?? 1;
|
|
865
|
+
this.activeInstance.goToPage?.(Math.max(1, cur - 1));
|
|
866
|
+
} else if (e.key === "+" || e.key === "=") {
|
|
867
|
+
this.activeInstance.zoomIn?.();
|
|
868
|
+
} else if (e.key === "-" || e.key === "_") {
|
|
869
|
+
this.activeInstance.zoomOut?.();
|
|
870
|
+
} else if (e.key === "0") {
|
|
871
|
+
this.activeInstance.fitToPage?.();
|
|
872
|
+
} else if (e.key === "r" || e.key === "R") {
|
|
873
|
+
this.activeInstance.rotateCW?.();
|
|
874
|
+
} else if (e.key === "f" || e.key === "F") {
|
|
875
|
+
if (!document.fullscreenElement) {
|
|
876
|
+
this.wrapperEl?.requestFullscreen?.();
|
|
877
|
+
} else {
|
|
878
|
+
document.exitFullscreen?.();
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
};
|
|
882
|
+
window.addEventListener("keydown", this.keyHandler);
|
|
883
|
+
}
|
|
884
|
+
setupDragAndDrop(container, options) {
|
|
885
|
+
if (!this.wrapperEl) return;
|
|
886
|
+
this.wrapperEl.addEventListener("dragover", (e) => {
|
|
887
|
+
e.preventDefault();
|
|
888
|
+
this.wrapperEl?.classList.add("fp-dragover");
|
|
889
|
+
});
|
|
890
|
+
this.wrapperEl.addEventListener("dragleave", (e) => {
|
|
891
|
+
if (e.relatedTarget === null || !this.wrapperEl?.contains(e.relatedTarget)) {
|
|
892
|
+
this.wrapperEl?.classList.remove("fp-dragover");
|
|
893
|
+
}
|
|
894
|
+
});
|
|
895
|
+
this.wrapperEl.addEventListener("drop", (e) => {
|
|
896
|
+
e.preventDefault();
|
|
897
|
+
this.wrapperEl?.classList.remove("fp-dragover");
|
|
898
|
+
const file = e.dataTransfer?.files?.[0];
|
|
899
|
+
if (file) {
|
|
900
|
+
this.preview(container, file, options);
|
|
901
|
+
}
|
|
902
|
+
});
|
|
784
903
|
}
|
|
785
904
|
showLoading() {
|
|
786
905
|
if (!this.contentEl) return;
|
|
@@ -799,10 +918,27 @@ var FilePreviewViewer = class {
|
|
|
799
918
|
this.contentEl.innerHTML = "";
|
|
800
919
|
const errorEl = document.createElement("div");
|
|
801
920
|
errorEl.className = "fp-error";
|
|
921
|
+
errorEl.style.display = "flex";
|
|
922
|
+
errorEl.style.flexDirection = "column";
|
|
923
|
+
errorEl.style.alignItems = "center";
|
|
924
|
+
errorEl.style.justifyContent = "center";
|
|
925
|
+
errorEl.style.padding = "32px";
|
|
926
|
+
errorEl.style.textAlign = "center";
|
|
927
|
+
const hasDownload = !!(this.currentBuffer && this.currentMetadata);
|
|
802
928
|
errorEl.innerHTML = `
|
|
803
|
-
<div class="fp-error-icon">\u26A0\uFE0F</div>
|
|
804
|
-
<div class="fp-error-message"
|
|
929
|
+
<div class="fp-error-icon" style="font-size:36px;margin-bottom:8px;">\u26A0\uFE0F</div>
|
|
930
|
+
<div class="fp-error-message" style="font-size:16px;font-weight:600;margin-bottom:6px;">Cannot preview file</div>
|
|
931
|
+
<div class="fp-error-sub" style="font-size:13px;color:#64748b;max-width:420px;line-height:1.5;margin-bottom:16px;">${message}</div>
|
|
932
|
+
${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>' : ""}
|
|
805
933
|
`;
|
|
934
|
+
if (hasDownload && this.currentBuffer) {
|
|
935
|
+
const btn = errorEl.querySelector(".fp-error-download-btn");
|
|
936
|
+
if (btn) {
|
|
937
|
+
btn.addEventListener("click", () => {
|
|
938
|
+
downloadFile(this.currentBuffer, this.currentMetadata?.name || "download", this.currentMetadata?.mimeType);
|
|
939
|
+
});
|
|
940
|
+
}
|
|
941
|
+
}
|
|
806
942
|
this.contentEl.appendChild(errorEl);
|
|
807
943
|
}
|
|
808
944
|
};
|
|
@@ -1723,6 +1859,16 @@ var CodePlugin = class {
|
|
|
1723
1859
|
instance.zoomIn?.();
|
|
1724
1860
|
}
|
|
1725
1861
|
},
|
|
1862
|
+
{
|
|
1863
|
+
id: "copy",
|
|
1864
|
+
icon: "copy",
|
|
1865
|
+
label: "Copy Content",
|
|
1866
|
+
type: "button",
|
|
1867
|
+
group: "actions",
|
|
1868
|
+
execute: () => {
|
|
1869
|
+
instance.copy?.();
|
|
1870
|
+
}
|
|
1871
|
+
},
|
|
1726
1872
|
{
|
|
1727
1873
|
id: "download",
|
|
1728
1874
|
icon: "download",
|
|
@@ -1810,6 +1956,9 @@ var CodePlugin = class {
|
|
|
1810
1956
|
},
|
|
1811
1957
|
print: () => {
|
|
1812
1958
|
window.print();
|
|
1959
|
+
},
|
|
1960
|
+
copy: () => {
|
|
1961
|
+
navigator.clipboard?.writeText(text);
|
|
1813
1962
|
}
|
|
1814
1963
|
};
|
|
1815
1964
|
}
|
|
@@ -2060,6 +2209,14 @@ var MarkdownPlugin = class {
|
|
|
2060
2209
|
group: "zoom",
|
|
2061
2210
|
execute: () => instance.fitToPage?.()
|
|
2062
2211
|
},
|
|
2212
|
+
{
|
|
2213
|
+
id: "copy",
|
|
2214
|
+
icon: "copy",
|
|
2215
|
+
label: "Copy Markdown",
|
|
2216
|
+
type: "button",
|
|
2217
|
+
group: "actions",
|
|
2218
|
+
execute: () => instance.copy?.()
|
|
2219
|
+
},
|
|
2063
2220
|
{
|
|
2064
2221
|
id: "download",
|
|
2065
2222
|
icon: "download",
|
|
@@ -2210,6 +2367,9 @@ var MarkdownPlugin = class {
|
|
|
2210
2367
|
},
|
|
2211
2368
|
print: () => {
|
|
2212
2369
|
window.print();
|
|
2370
|
+
},
|
|
2371
|
+
copy: () => {
|
|
2372
|
+
navigator.clipboard?.writeText(text);
|
|
2213
2373
|
}
|
|
2214
2374
|
};
|
|
2215
2375
|
}
|