@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/react.js
CHANGED
|
@@ -342,8 +342,39 @@ function createElement(tag, attrs, ...children) {
|
|
|
342
342
|
}
|
|
343
343
|
return el;
|
|
344
344
|
}
|
|
345
|
+
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>`;
|
|
346
|
+
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>`;
|
|
347
|
+
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>`;
|
|
348
|
+
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>`;
|
|
349
|
+
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>`;
|
|
350
|
+
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>`;
|
|
351
|
+
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>`;
|
|
345
352
|
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>`;
|
|
346
353
|
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>`;
|
|
354
|
+
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>`;
|
|
355
|
+
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>`;
|
|
356
|
+
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>`;
|
|
357
|
+
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>`;
|
|
358
|
+
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>`;
|
|
359
|
+
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>`;
|
|
360
|
+
var ICON_MAP = {
|
|
361
|
+
"zoom-in": ICON_ZOOM_IN,
|
|
362
|
+
"zoom-out": ICON_ZOOM_OUT,
|
|
363
|
+
"fit-page": ICON_FIT_PAGE,
|
|
364
|
+
"fit-slide": ICON_FIT_PAGE,
|
|
365
|
+
"rotate-cw": ICON_ROTATE_CW,
|
|
366
|
+
"rotate-ccw": ICON_ROTATE_CCW,
|
|
367
|
+
"download": ICON_DOWNLOAD,
|
|
368
|
+
"print": ICON_PRINT,
|
|
369
|
+
"thumbnails": ICON_THUMBNAILS,
|
|
370
|
+
"fullscreen": ICON_FULLSCREEN,
|
|
371
|
+
"play": ICON_PLAY,
|
|
372
|
+
"pause": ICON_PAUSE,
|
|
373
|
+
"close": ICON_CLOSE,
|
|
374
|
+
"copy": ICON_COPY,
|
|
375
|
+
"prev": ICON_PAGE_PREV,
|
|
376
|
+
"next": ICON_PAGE_NEXT
|
|
377
|
+
};
|
|
347
378
|
var ToolbarController = class {
|
|
348
379
|
el;
|
|
349
380
|
toolbarEl;
|
|
@@ -454,10 +485,11 @@ var ToolbarController = class {
|
|
|
454
485
|
type: "button",
|
|
455
486
|
"data-action-id": id
|
|
456
487
|
});
|
|
457
|
-
|
|
458
|
-
|
|
488
|
+
const svg = ICON_MAP[iconHtml] || iconHtml;
|
|
489
|
+
if (svg && svg.startsWith("<svg")) {
|
|
490
|
+
btn.innerHTML = sanitizeSVG(svg);
|
|
459
491
|
} else {
|
|
460
|
-
btn.textContent =
|
|
492
|
+
btn.textContent = svg || title;
|
|
461
493
|
}
|
|
462
494
|
btn.addEventListener("click", onClick);
|
|
463
495
|
return btn;
|
|
@@ -538,6 +570,9 @@ var FilePreviewViewer = class {
|
|
|
538
570
|
contentEl = null;
|
|
539
571
|
currentBuffer = null;
|
|
540
572
|
currentMetadata = null;
|
|
573
|
+
keyHandler = null;
|
|
574
|
+
currentContainer = null;
|
|
575
|
+
currentOptions = {};
|
|
541
576
|
/**
|
|
542
577
|
* Register a preview plugin.
|
|
543
578
|
*/
|
|
@@ -592,24 +627,47 @@ var FilePreviewViewer = class {
|
|
|
592
627
|
emit: (event, payload) => this.eventEmitter.emit(event, payload)
|
|
593
628
|
});
|
|
594
629
|
this.activeInstance = instance;
|
|
630
|
+
this.hideLoading();
|
|
631
|
+
this.eventEmitter.emit("loaded", { metadata, plugin: matchedPlugin.id });
|
|
595
632
|
if (options.showToolbar !== false && this.toolbar) {
|
|
596
633
|
const actions = matchedPlugin.getToolbarActions(instance);
|
|
634
|
+
const hasFullscreen = actions.some((a) => a.id === "fullscreen");
|
|
635
|
+
if (!hasFullscreen && this.wrapperEl) {
|
|
636
|
+
actions.push({
|
|
637
|
+
id: "fullscreen",
|
|
638
|
+
icon: "fullscreen",
|
|
639
|
+
label: "Toggle Fullscreen",
|
|
640
|
+
type: "button",
|
|
641
|
+
group: "view",
|
|
642
|
+
execute: () => {
|
|
643
|
+
if (!document.fullscreenElement) {
|
|
644
|
+
this.wrapperEl?.requestFullscreen?.();
|
|
645
|
+
} else {
|
|
646
|
+
document.exitFullscreen?.();
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
});
|
|
650
|
+
}
|
|
597
651
|
this.toolbar.update(actions);
|
|
598
652
|
this.toolbar.show();
|
|
599
653
|
}
|
|
600
654
|
if (instance.getThumbnails && this.thumbnailPanel) {
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
655
|
+
Promise.resolve().then(async () => {
|
|
656
|
+
try {
|
|
657
|
+
const thumbnails = await Promise.resolve(instance.getThumbnails());
|
|
658
|
+
if (thumbnails && thumbnails.length > 0 && this.thumbnailPanel) {
|
|
659
|
+
this.thumbnailPanel.update(thumbnails, (index) => {
|
|
660
|
+
instance.goToPage?.(index + 1);
|
|
661
|
+
});
|
|
662
|
+
if (options.showThumbnails) {
|
|
663
|
+
this.thumbnailPanel.show();
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
} catch (e) {
|
|
667
|
+
console.warn("[FilePreview] Non-critical thumbnail load error:", e);
|
|
608
668
|
}
|
|
609
|
-
}
|
|
669
|
+
});
|
|
610
670
|
}
|
|
611
|
-
this.hideLoading();
|
|
612
|
-
this.eventEmitter.emit("loaded", { metadata, plugin: matchedPlugin.id });
|
|
613
671
|
return instance;
|
|
614
672
|
} catch (error) {
|
|
615
673
|
this.hideLoading();
|
|
@@ -631,6 +689,10 @@ var FilePreviewViewer = class {
|
|
|
631
689
|
* Destroy the viewer and clean up all resources.
|
|
632
690
|
*/
|
|
633
691
|
destroy() {
|
|
692
|
+
if (this.keyHandler) {
|
|
693
|
+
window.removeEventListener("keydown", this.keyHandler);
|
|
694
|
+
this.keyHandler = null;
|
|
695
|
+
}
|
|
634
696
|
this.abort();
|
|
635
697
|
this.destroyInstance();
|
|
636
698
|
this.toolbar?.destroy();
|
|
@@ -646,6 +708,7 @@ var FilePreviewViewer = class {
|
|
|
646
708
|
this.thumbnailPanel = null;
|
|
647
709
|
this.currentBuffer = null;
|
|
648
710
|
this.currentMetadata = null;
|
|
711
|
+
this.currentContainer = null;
|
|
649
712
|
}
|
|
650
713
|
/**
|
|
651
714
|
* Get the currently active preview instance.
|
|
@@ -675,6 +738,8 @@ var FilePreviewViewer = class {
|
|
|
675
738
|
return null;
|
|
676
739
|
}
|
|
677
740
|
setupDOM(container, options) {
|
|
741
|
+
this.currentContainer = container;
|
|
742
|
+
this.currentOptions = options;
|
|
678
743
|
if (this.wrapperEl?.parentNode === container) return;
|
|
679
744
|
if (this.wrapperEl?.parentNode) {
|
|
680
745
|
this.wrapperEl.parentNode.removeChild(this.wrapperEl);
|
|
@@ -683,6 +748,7 @@ var FilePreviewViewer = class {
|
|
|
683
748
|
const toolbarPos = options.toolbarPosition ?? "top";
|
|
684
749
|
this.wrapperEl = document.createElement("div");
|
|
685
750
|
this.wrapperEl.className = `fp-viewer ${themeClass} ${options.className ?? ""}`.trim();
|
|
751
|
+
this.wrapperEl.tabIndex = 0;
|
|
686
752
|
const toolbarEl = document.createElement("div");
|
|
687
753
|
toolbarEl.className = "fp-toolbar-container";
|
|
688
754
|
this.contentEl = document.createElement("div");
|
|
@@ -704,6 +770,59 @@ var FilePreviewViewer = class {
|
|
|
704
770
|
container.appendChild(this.wrapperEl);
|
|
705
771
|
this.toolbar = new ToolbarController(toolbarEl);
|
|
706
772
|
this.thumbnailPanel = new ThumbnailPanel(thumbnailEl);
|
|
773
|
+
this.setupKeyboardShortcuts();
|
|
774
|
+
this.setupDragAndDrop(container, options);
|
|
775
|
+
}
|
|
776
|
+
setupKeyboardShortcuts() {
|
|
777
|
+
if (this.keyHandler) return;
|
|
778
|
+
this.keyHandler = (e) => {
|
|
779
|
+
if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement || e.target?.isContentEditable) {
|
|
780
|
+
return;
|
|
781
|
+
}
|
|
782
|
+
if (!this.activeInstance) return;
|
|
783
|
+
if (e.key === "ArrowRight" || e.key === "PageDown") {
|
|
784
|
+
const cur = this.activeInstance.getCurrentPage?.() ?? 1;
|
|
785
|
+
this.activeInstance.goToPage?.(cur + 1);
|
|
786
|
+
} else if (e.key === "ArrowLeft" || e.key === "PageUp") {
|
|
787
|
+
const cur = this.activeInstance.getCurrentPage?.() ?? 1;
|
|
788
|
+
this.activeInstance.goToPage?.(Math.max(1, cur - 1));
|
|
789
|
+
} else if (e.key === "+" || e.key === "=") {
|
|
790
|
+
this.activeInstance.zoomIn?.();
|
|
791
|
+
} else if (e.key === "-" || e.key === "_") {
|
|
792
|
+
this.activeInstance.zoomOut?.();
|
|
793
|
+
} else if (e.key === "0") {
|
|
794
|
+
this.activeInstance.fitToPage?.();
|
|
795
|
+
} else if (e.key === "r" || e.key === "R") {
|
|
796
|
+
this.activeInstance.rotateCW?.();
|
|
797
|
+
} else if (e.key === "f" || e.key === "F") {
|
|
798
|
+
if (!document.fullscreenElement) {
|
|
799
|
+
this.wrapperEl?.requestFullscreen?.();
|
|
800
|
+
} else {
|
|
801
|
+
document.exitFullscreen?.();
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
};
|
|
805
|
+
window.addEventListener("keydown", this.keyHandler);
|
|
806
|
+
}
|
|
807
|
+
setupDragAndDrop(container, options) {
|
|
808
|
+
if (!this.wrapperEl) return;
|
|
809
|
+
this.wrapperEl.addEventListener("dragover", (e) => {
|
|
810
|
+
e.preventDefault();
|
|
811
|
+
this.wrapperEl?.classList.add("fp-dragover");
|
|
812
|
+
});
|
|
813
|
+
this.wrapperEl.addEventListener("dragleave", (e) => {
|
|
814
|
+
if (e.relatedTarget === null || !this.wrapperEl?.contains(e.relatedTarget)) {
|
|
815
|
+
this.wrapperEl?.classList.remove("fp-dragover");
|
|
816
|
+
}
|
|
817
|
+
});
|
|
818
|
+
this.wrapperEl.addEventListener("drop", (e) => {
|
|
819
|
+
e.preventDefault();
|
|
820
|
+
this.wrapperEl?.classList.remove("fp-dragover");
|
|
821
|
+
const file = e.dataTransfer?.files?.[0];
|
|
822
|
+
if (file) {
|
|
823
|
+
this.preview(container, file, options);
|
|
824
|
+
}
|
|
825
|
+
});
|
|
707
826
|
}
|
|
708
827
|
showLoading() {
|
|
709
828
|
if (!this.contentEl) return;
|
|
@@ -722,10 +841,27 @@ var FilePreviewViewer = class {
|
|
|
722
841
|
this.contentEl.innerHTML = "";
|
|
723
842
|
const errorEl = document.createElement("div");
|
|
724
843
|
errorEl.className = "fp-error";
|
|
844
|
+
errorEl.style.display = "flex";
|
|
845
|
+
errorEl.style.flexDirection = "column";
|
|
846
|
+
errorEl.style.alignItems = "center";
|
|
847
|
+
errorEl.style.justifyContent = "center";
|
|
848
|
+
errorEl.style.padding = "32px";
|
|
849
|
+
errorEl.style.textAlign = "center";
|
|
850
|
+
const hasDownload = !!(this.currentBuffer && this.currentMetadata);
|
|
725
851
|
errorEl.innerHTML = `
|
|
726
|
-
<div class="fp-error-icon">\u26A0\uFE0F</div>
|
|
727
|
-
<div class="fp-error-message"
|
|
852
|
+
<div class="fp-error-icon" style="font-size:36px;margin-bottom:8px;">\u26A0\uFE0F</div>
|
|
853
|
+
<div class="fp-error-message" style="font-size:16px;font-weight:600;margin-bottom:6px;">Cannot preview file</div>
|
|
854
|
+
<div class="fp-error-sub" style="font-size:13px;color:#64748b;max-width:420px;line-height:1.5;margin-bottom:16px;">${message}</div>
|
|
855
|
+
${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>' : ""}
|
|
728
856
|
`;
|
|
857
|
+
if (hasDownload && this.currentBuffer) {
|
|
858
|
+
const btn = errorEl.querySelector(".fp-error-download-btn");
|
|
859
|
+
if (btn) {
|
|
860
|
+
btn.addEventListener("click", () => {
|
|
861
|
+
downloadFile(this.currentBuffer, this.currentMetadata?.name || "download", this.currentMetadata?.mimeType);
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
}
|
|
729
865
|
this.contentEl.appendChild(errorEl);
|
|
730
866
|
}
|
|
731
867
|
};
|
|
@@ -1646,6 +1782,16 @@ var CodePlugin = class {
|
|
|
1646
1782
|
instance.zoomIn?.();
|
|
1647
1783
|
}
|
|
1648
1784
|
},
|
|
1785
|
+
{
|
|
1786
|
+
id: "copy",
|
|
1787
|
+
icon: "copy",
|
|
1788
|
+
label: "Copy Content",
|
|
1789
|
+
type: "button",
|
|
1790
|
+
group: "actions",
|
|
1791
|
+
execute: () => {
|
|
1792
|
+
instance.copy?.();
|
|
1793
|
+
}
|
|
1794
|
+
},
|
|
1649
1795
|
{
|
|
1650
1796
|
id: "download",
|
|
1651
1797
|
icon: "download",
|
|
@@ -1733,6 +1879,9 @@ var CodePlugin = class {
|
|
|
1733
1879
|
},
|
|
1734
1880
|
print: () => {
|
|
1735
1881
|
window.print();
|
|
1882
|
+
},
|
|
1883
|
+
copy: () => {
|
|
1884
|
+
navigator.clipboard?.writeText(text);
|
|
1736
1885
|
}
|
|
1737
1886
|
};
|
|
1738
1887
|
}
|
|
@@ -1983,6 +2132,14 @@ var MarkdownPlugin = class {
|
|
|
1983
2132
|
group: "zoom",
|
|
1984
2133
|
execute: () => instance.fitToPage?.()
|
|
1985
2134
|
},
|
|
2135
|
+
{
|
|
2136
|
+
id: "copy",
|
|
2137
|
+
icon: "copy",
|
|
2138
|
+
label: "Copy Markdown",
|
|
2139
|
+
type: "button",
|
|
2140
|
+
group: "actions",
|
|
2141
|
+
execute: () => instance.copy?.()
|
|
2142
|
+
},
|
|
1986
2143
|
{
|
|
1987
2144
|
id: "download",
|
|
1988
2145
|
icon: "download",
|
|
@@ -2133,6 +2290,9 @@ var MarkdownPlugin = class {
|
|
|
2133
2290
|
},
|
|
2134
2291
|
print: () => {
|
|
2135
2292
|
window.print();
|
|
2293
|
+
},
|
|
2294
|
+
copy: () => {
|
|
2295
|
+
navigator.clipboard?.writeText(text);
|
|
2136
2296
|
}
|
|
2137
2297
|
};
|
|
2138
2298
|
}
|