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