1import { AppUtils } from "./AppUtils.js"; 2import { BaseApp } from "./BaseApp.js"; 3import { diag } from "./Services/DialogService.js"; 4import { pdf } from "./Services/PdfService.js"; 5class MergeApp extends BaseApp { 6 pnlFilePicker = this.querySelector(".panel-file-picker"); 7 lblNoFile = this.querySelector("#lbl-no-file"); 8 lstFiles = this.querySelector("#lst-files"); 9 pgbProgress = this.querySelector(".progress-bar"); 10 constructor() { 11 super(); 12 this.pnlFilePicker.addEventListener("change", () => void this.onFilePicked()); 13 this.lstFiles.addDelegate("click", `[data-command="remove"]`, (_, el) => void this.removeFileList(el)); 14 this.lstFiles.addDelegate("click", `[data-command="up"]`, (_, el) => void this.moveFileList(el, true)); 15 this.lstFiles.addDelegate("click", `[data-command="down"]`, (_, el) => void this.moveFileList(el, false)); 16 } 17 removeFileList(btn) { 18 btn.closest(".file-item")?.remove(); 19 this.refreshListButtons(); 20 } 21 moveFileList(btn, up) { 22 const item = btn.closest(".file-item"); 23 if (!item) { 24 return; 25 } 26 const anchor = (up ? 27 item.previousElementSibling : 28 item.nextElementSibling?.nextElementSibling) 29 ?? null; 30 item.parentElement?.insertBefore(item, anchor); 31 this.refreshListButtons(); 32 } 33 async onFilePicked() { 34 const files = this.pnlFilePicker.files; 35 const satisfied = files.length >= 2; 36 if (!satisfied) { 37 await diag.showErrorAsync("Merge_TwoOrMore".loc()); 38 this.lstFiles.innerHTML = "NoFileYet".loc(); 39 return; 40 } 41 const template = this.querySelector("#template-file").innerHTML; 42 const frag = new DocumentFragment(); 43 for (const file of files) { 44 const el = template.toElement(); 45 el.file = file; 46 frag.appendChild(el); 47 el.setChildContent("[data-name]", file.name); 48 el.setChildContent("[data-size]", AppUtils.formatFileSize(file.size)); 49 } 50 this.lstFiles.setContent(frag); 51 this.refreshListButtons(); 52 } 53 refreshListButtons() { 54 const count = this.lstFiles.childElementCount; 55 const canDelete = count > 2; 56 let counter = 0; 57 for (const el of this.lstFiles.children) { 58 el.querySelector(`[data-command="remove"]`) 59 .disabled = !canDelete; 60 el.querySelector(`[data-command="up"]`) 61 .disabled = counter == 0; 62 el.querySelector(`[data-command="down"]`) 63 .disabled = counter == count - 1; 64 counter++; 65 } 66 } 67 async processAsync() { 68 const files = this.files; 69 if (!files?.length) { 70 return 1; 71 } 72 const arrGenerators = files.map(file => { 73 switch (file.type) { 74 case "file": 75 return async () => await file.file.arrayBuffer(); 76 default: 77 throw new Error("Unknown file type: " + file.type); 78 } 79 }); 80 const pgb = this.pgbProgress; 81 pgb.style.width = "0"; 82 const blob = await pdf.mergeFilesAsync(arrGenerators, (curr, total) => pgb.style.width = Math.round(curr * 100 / total) + "%"); 83 this.currLocalResult = blob; 84 this.currLocalResultName = "merged.pdf"; 85 return blob ? 3 : 2; 86 } 87 get files() { 88 return Array.from(this.lstFiles.children) 89 .map(q => q.file); 90 } 91 static register() { 92 BaseApp.register(); 93 customElements.define("merge-app", this); 94 } 95} 96MergeApp.register(); 97//# sourceMappingURL=MergeApp.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.