@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/angular.js
CHANGED
|
@@ -389,8 +389,39 @@ function createElement(tag, attrs, ...children) {
|
|
|
389
389
|
}
|
|
390
390
|
return el;
|
|
391
391
|
}
|
|
392
|
+
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>`;
|
|
393
|
+
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>`;
|
|
394
|
+
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>`;
|
|
395
|
+
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>`;
|
|
396
|
+
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>`;
|
|
397
|
+
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>`;
|
|
398
|
+
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>`;
|
|
392
399
|
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>`;
|
|
393
400
|
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>`;
|
|
401
|
+
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>`;
|
|
402
|
+
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>`;
|
|
403
|
+
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>`;
|
|
404
|
+
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>`;
|
|
405
|
+
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>`;
|
|
406
|
+
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>`;
|
|
407
|
+
var ICON_MAP = {
|
|
408
|
+
"zoom-in": ICON_ZOOM_IN,
|
|
409
|
+
"zoom-out": ICON_ZOOM_OUT,
|
|
410
|
+
"fit-page": ICON_FIT_PAGE,
|
|
411
|
+
"fit-slide": ICON_FIT_PAGE,
|
|
412
|
+
"rotate-cw": ICON_ROTATE_CW,
|
|
413
|
+
"rotate-ccw": ICON_ROTATE_CCW,
|
|
414
|
+
"download": ICON_DOWNLOAD,
|
|
415
|
+
"print": ICON_PRINT,
|
|
416
|
+
"thumbnails": ICON_THUMBNAILS,
|
|
417
|
+
"fullscreen": ICON_FULLSCREEN,
|
|
418
|
+
"play": ICON_PLAY,
|
|
419
|
+
"pause": ICON_PAUSE,
|
|
420
|
+
"close": ICON_CLOSE,
|
|
421
|
+
"copy": ICON_COPY,
|
|
422
|
+
"prev": ICON_PAGE_PREV,
|
|
423
|
+
"next": ICON_PAGE_NEXT
|
|
424
|
+
};
|
|
394
425
|
var ToolbarController = class {
|
|
395
426
|
el;
|
|
396
427
|
toolbarEl;
|
|
@@ -501,10 +532,11 @@ var ToolbarController = class {
|
|
|
501
532
|
type: "button",
|
|
502
533
|
"data-action-id": id
|
|
503
534
|
});
|
|
504
|
-
|
|
505
|
-
|
|
535
|
+
const svg = ICON_MAP[iconHtml] || iconHtml;
|
|
536
|
+
if (svg && svg.startsWith("<svg")) {
|
|
537
|
+
btn.innerHTML = sanitizeSVG(svg);
|
|
506
538
|
} else {
|
|
507
|
-
btn.textContent =
|
|
539
|
+
btn.textContent = svg || title;
|
|
508
540
|
}
|
|
509
541
|
btn.addEventListener("click", onClick);
|
|
510
542
|
return btn;
|
|
@@ -585,6 +617,9 @@ var FilePreviewViewer = class {
|
|
|
585
617
|
contentEl = null;
|
|
586
618
|
currentBuffer = null;
|
|
587
619
|
currentMetadata = null;
|
|
620
|
+
keyHandler = null;
|
|
621
|
+
currentContainer = null;
|
|
622
|
+
currentOptions = {};
|
|
588
623
|
/**
|
|
589
624
|
* Register a preview plugin.
|
|
590
625
|
*/
|
|
@@ -639,24 +674,47 @@ var FilePreviewViewer = class {
|
|
|
639
674
|
emit: (event, payload) => this.eventEmitter.emit(event, payload)
|
|
640
675
|
});
|
|
641
676
|
this.activeInstance = instance;
|
|
677
|
+
this.hideLoading();
|
|
678
|
+
this.eventEmitter.emit("loaded", { metadata, plugin: matchedPlugin.id });
|
|
642
679
|
if (options.showToolbar !== false && this.toolbar) {
|
|
643
680
|
const actions = matchedPlugin.getToolbarActions(instance);
|
|
681
|
+
const hasFullscreen = actions.some((a) => a.id === "fullscreen");
|
|
682
|
+
if (!hasFullscreen && this.wrapperEl) {
|
|
683
|
+
actions.push({
|
|
684
|
+
id: "fullscreen",
|
|
685
|
+
icon: "fullscreen",
|
|
686
|
+
label: "Toggle Fullscreen",
|
|
687
|
+
type: "button",
|
|
688
|
+
group: "view",
|
|
689
|
+
execute: () => {
|
|
690
|
+
if (!document.fullscreenElement) {
|
|
691
|
+
this.wrapperEl?.requestFullscreen?.();
|
|
692
|
+
} else {
|
|
693
|
+
document.exitFullscreen?.();
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
});
|
|
697
|
+
}
|
|
644
698
|
this.toolbar.update(actions);
|
|
645
699
|
this.toolbar.show();
|
|
646
700
|
}
|
|
647
701
|
if (instance.getThumbnails && this.thumbnailPanel) {
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
702
|
+
Promise.resolve().then(async () => {
|
|
703
|
+
try {
|
|
704
|
+
const thumbnails = await Promise.resolve(instance.getThumbnails());
|
|
705
|
+
if (thumbnails && thumbnails.length > 0 && this.thumbnailPanel) {
|
|
706
|
+
this.thumbnailPanel.update(thumbnails, (index) => {
|
|
707
|
+
instance.goToPage?.(index + 1);
|
|
708
|
+
});
|
|
709
|
+
if (options.showThumbnails) {
|
|
710
|
+
this.thumbnailPanel.show();
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
} catch (e) {
|
|
714
|
+
console.warn("[FilePreview] Non-critical thumbnail load error:", e);
|
|
655
715
|
}
|
|
656
|
-
}
|
|
716
|
+
});
|
|
657
717
|
}
|
|
658
|
-
this.hideLoading();
|
|
659
|
-
this.eventEmitter.emit("loaded", { metadata, plugin: matchedPlugin.id });
|
|
660
718
|
return instance;
|
|
661
719
|
} catch (error) {
|
|
662
720
|
this.hideLoading();
|
|
@@ -678,6 +736,10 @@ var FilePreviewViewer = class {
|
|
|
678
736
|
* Destroy the viewer and clean up all resources.
|
|
679
737
|
*/
|
|
680
738
|
destroy() {
|
|
739
|
+
if (this.keyHandler) {
|
|
740
|
+
window.removeEventListener("keydown", this.keyHandler);
|
|
741
|
+
this.keyHandler = null;
|
|
742
|
+
}
|
|
681
743
|
this.abort();
|
|
682
744
|
this.destroyInstance();
|
|
683
745
|
this.toolbar?.destroy();
|
|
@@ -693,6 +755,7 @@ var FilePreviewViewer = class {
|
|
|
693
755
|
this.thumbnailPanel = null;
|
|
694
756
|
this.currentBuffer = null;
|
|
695
757
|
this.currentMetadata = null;
|
|
758
|
+
this.currentContainer = null;
|
|
696
759
|
}
|
|
697
760
|
/**
|
|
698
761
|
* Get the currently active preview instance.
|
|
@@ -722,6 +785,8 @@ var FilePreviewViewer = class {
|
|
|
722
785
|
return null;
|
|
723
786
|
}
|
|
724
787
|
setupDOM(container, options) {
|
|
788
|
+
this.currentContainer = container;
|
|
789
|
+
this.currentOptions = options;
|
|
725
790
|
if (this.wrapperEl?.parentNode === container) return;
|
|
726
791
|
if (this.wrapperEl?.parentNode) {
|
|
727
792
|
this.wrapperEl.parentNode.removeChild(this.wrapperEl);
|
|
@@ -730,6 +795,7 @@ var FilePreviewViewer = class {
|
|
|
730
795
|
const toolbarPos = options.toolbarPosition ?? "top";
|
|
731
796
|
this.wrapperEl = document.createElement("div");
|
|
732
797
|
this.wrapperEl.className = `fp-viewer ${themeClass} ${options.className ?? ""}`.trim();
|
|
798
|
+
this.wrapperEl.tabIndex = 0;
|
|
733
799
|
const toolbarEl = document.createElement("div");
|
|
734
800
|
toolbarEl.className = "fp-toolbar-container";
|
|
735
801
|
this.contentEl = document.createElement("div");
|
|
@@ -751,6 +817,59 @@ var FilePreviewViewer = class {
|
|
|
751
817
|
container.appendChild(this.wrapperEl);
|
|
752
818
|
this.toolbar = new ToolbarController(toolbarEl);
|
|
753
819
|
this.thumbnailPanel = new ThumbnailPanel(thumbnailEl);
|
|
820
|
+
this.setupKeyboardShortcuts();
|
|
821
|
+
this.setupDragAndDrop(container, options);
|
|
822
|
+
}
|
|
823
|
+
setupKeyboardShortcuts() {
|
|
824
|
+
if (this.keyHandler) return;
|
|
825
|
+
this.keyHandler = (e) => {
|
|
826
|
+
if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement || e.target?.isContentEditable) {
|
|
827
|
+
return;
|
|
828
|
+
}
|
|
829
|
+
if (!this.activeInstance) return;
|
|
830
|
+
if (e.key === "ArrowRight" || e.key === "PageDown") {
|
|
831
|
+
const cur = this.activeInstance.getCurrentPage?.() ?? 1;
|
|
832
|
+
this.activeInstance.goToPage?.(cur + 1);
|
|
833
|
+
} else if (e.key === "ArrowLeft" || e.key === "PageUp") {
|
|
834
|
+
const cur = this.activeInstance.getCurrentPage?.() ?? 1;
|
|
835
|
+
this.activeInstance.goToPage?.(Math.max(1, cur - 1));
|
|
836
|
+
} else if (e.key === "+" || e.key === "=") {
|
|
837
|
+
this.activeInstance.zoomIn?.();
|
|
838
|
+
} else if (e.key === "-" || e.key === "_") {
|
|
839
|
+
this.activeInstance.zoomOut?.();
|
|
840
|
+
} else if (e.key === "0") {
|
|
841
|
+
this.activeInstance.fitToPage?.();
|
|
842
|
+
} else if (e.key === "r" || e.key === "R") {
|
|
843
|
+
this.activeInstance.rotateCW?.();
|
|
844
|
+
} else if (e.key === "f" || e.key === "F") {
|
|
845
|
+
if (!document.fullscreenElement) {
|
|
846
|
+
this.wrapperEl?.requestFullscreen?.();
|
|
847
|
+
} else {
|
|
848
|
+
document.exitFullscreen?.();
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
};
|
|
852
|
+
window.addEventListener("keydown", this.keyHandler);
|
|
853
|
+
}
|
|
854
|
+
setupDragAndDrop(container, options) {
|
|
855
|
+
if (!this.wrapperEl) return;
|
|
856
|
+
this.wrapperEl.addEventListener("dragover", (e) => {
|
|
857
|
+
e.preventDefault();
|
|
858
|
+
this.wrapperEl?.classList.add("fp-dragover");
|
|
859
|
+
});
|
|
860
|
+
this.wrapperEl.addEventListener("dragleave", (e) => {
|
|
861
|
+
if (e.relatedTarget === null || !this.wrapperEl?.contains(e.relatedTarget)) {
|
|
862
|
+
this.wrapperEl?.classList.remove("fp-dragover");
|
|
863
|
+
}
|
|
864
|
+
});
|
|
865
|
+
this.wrapperEl.addEventListener("drop", (e) => {
|
|
866
|
+
e.preventDefault();
|
|
867
|
+
this.wrapperEl?.classList.remove("fp-dragover");
|
|
868
|
+
const file = e.dataTransfer?.files?.[0];
|
|
869
|
+
if (file) {
|
|
870
|
+
this.preview(container, file, options);
|
|
871
|
+
}
|
|
872
|
+
});
|
|
754
873
|
}
|
|
755
874
|
showLoading() {
|
|
756
875
|
if (!this.contentEl) return;
|
|
@@ -769,10 +888,27 @@ var FilePreviewViewer = class {
|
|
|
769
888
|
this.contentEl.innerHTML = "";
|
|
770
889
|
const errorEl = document.createElement("div");
|
|
771
890
|
errorEl.className = "fp-error";
|
|
891
|
+
errorEl.style.display = "flex";
|
|
892
|
+
errorEl.style.flexDirection = "column";
|
|
893
|
+
errorEl.style.alignItems = "center";
|
|
894
|
+
errorEl.style.justifyContent = "center";
|
|
895
|
+
errorEl.style.padding = "32px";
|
|
896
|
+
errorEl.style.textAlign = "center";
|
|
897
|
+
const hasDownload = !!(this.currentBuffer && this.currentMetadata);
|
|
772
898
|
errorEl.innerHTML = `
|
|
773
|
-
<div class="fp-error-icon">\u26A0\uFE0F</div>
|
|
774
|
-
<div class="fp-error-message"
|
|
899
|
+
<div class="fp-error-icon" style="font-size:36px;margin-bottom:8px;">\u26A0\uFE0F</div>
|
|
900
|
+
<div class="fp-error-message" style="font-size:16px;font-weight:600;margin-bottom:6px;">Cannot preview file</div>
|
|
901
|
+
<div class="fp-error-sub" style="font-size:13px;color:#64748b;max-width:420px;line-height:1.5;margin-bottom:16px;">${message}</div>
|
|
902
|
+
${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>' : ""}
|
|
775
903
|
`;
|
|
904
|
+
if (hasDownload && this.currentBuffer) {
|
|
905
|
+
const btn = errorEl.querySelector(".fp-error-download-btn");
|
|
906
|
+
if (btn) {
|
|
907
|
+
btn.addEventListener("click", () => {
|
|
908
|
+
downloadFile(this.currentBuffer, this.currentMetadata?.name || "download", this.currentMetadata?.mimeType);
|
|
909
|
+
});
|
|
910
|
+
}
|
|
911
|
+
}
|
|
776
912
|
this.contentEl.appendChild(errorEl);
|
|
777
913
|
}
|
|
778
914
|
};
|
|
@@ -1693,6 +1829,16 @@ var CodePlugin = class {
|
|
|
1693
1829
|
instance.zoomIn?.();
|
|
1694
1830
|
}
|
|
1695
1831
|
},
|
|
1832
|
+
{
|
|
1833
|
+
id: "copy",
|
|
1834
|
+
icon: "copy",
|
|
1835
|
+
label: "Copy Content",
|
|
1836
|
+
type: "button",
|
|
1837
|
+
group: "actions",
|
|
1838
|
+
execute: () => {
|
|
1839
|
+
instance.copy?.();
|
|
1840
|
+
}
|
|
1841
|
+
},
|
|
1696
1842
|
{
|
|
1697
1843
|
id: "download",
|
|
1698
1844
|
icon: "download",
|
|
@@ -1780,6 +1926,9 @@ var CodePlugin = class {
|
|
|
1780
1926
|
},
|
|
1781
1927
|
print: () => {
|
|
1782
1928
|
window.print();
|
|
1929
|
+
},
|
|
1930
|
+
copy: () => {
|
|
1931
|
+
navigator.clipboard?.writeText(text);
|
|
1783
1932
|
}
|
|
1784
1933
|
};
|
|
1785
1934
|
}
|
|
@@ -2030,6 +2179,14 @@ var MarkdownPlugin = class {
|
|
|
2030
2179
|
group: "zoom",
|
|
2031
2180
|
execute: () => instance.fitToPage?.()
|
|
2032
2181
|
},
|
|
2182
|
+
{
|
|
2183
|
+
id: "copy",
|
|
2184
|
+
icon: "copy",
|
|
2185
|
+
label: "Copy Markdown",
|
|
2186
|
+
type: "button",
|
|
2187
|
+
group: "actions",
|
|
2188
|
+
execute: () => instance.copy?.()
|
|
2189
|
+
},
|
|
2033
2190
|
{
|
|
2034
2191
|
id: "download",
|
|
2035
2192
|
icon: "download",
|
|
@@ -2180,6 +2337,9 @@ var MarkdownPlugin = class {
|
|
|
2180
2337
|
},
|
|
2181
2338
|
print: () => {
|
|
2182
2339
|
window.print();
|
|
2340
|
+
},
|
|
2341
|
+
copy: () => {
|
|
2342
|
+
navigator.clipboard?.writeText(text);
|
|
2183
2343
|
}
|
|
2184
2344
|
};
|
|
2185
2345
|
}
|