1class Utils_io { 2 3 /** 4 * å°ä¸ä¸ª url è§£æä¸ºå¾ç å¹¶å°ä¸è½½æä½ç»å®å°ä¸ä¸ªå ç´ ä¸ï¼é常æä»¬ä¼ç¨äºè¿è¡æäºç¹å®å 容çä¸è½½æä½ 5 * @param element{Element[]|NodeListOf<Element>} éè¦è¢«å为ç¹å»å³ä¸è½½çå ç´ å¦ææ¯ a æ ç¾ï¼åä¼ç´æ¥å°æ¤å ç´ å为ä¸è½½çå ç´ èä¸ä¼é¢å¤åå»ºï¼ 6 * @param url{string} å ç´ ç url 7 * @param filename{string} æä»¶å 8 * @param jokerPopup{JokerBox_popUp} ä¸è½½å®æ¯æä¸è½½åºéçç¶æå¼¹çª 9 * @param mobileDownloadFun å¦ææ£æµå° æ¯ ç§»å¨ç«¯ä¸è½½ï¼åå¯è½ base çæ¹å¼ä¸è¢«æ¯æï¼ä¼ä¼å è°ç¨æ¤æä½ï¼è¿éå°è¿åä¸ä¸ª å å« url ç a æ ç¾ å url å¯¹åºæä»¶ç blob 对象 10 */ 11 static downloadImageDataAsFile(element, 12 url, 13 filename, 14 jokerPopup, 15 mobileDownloadFun = (a, _) => a.click()) { 16 // è§£æData URL 17 const parts = url.split(','); 18 if (parts.length !== 2) { 19 console.error('Invalid data URL', url); 20 jokerPopup.show("æ æçä¸è½½é¾æ¥"); 21 return; 22 } 23 const base64Data = parts[1]; 24 25 // æ£æ¥Base64æ°æ®æ¯å¦ææ 26 if (base64Data.length === 0) { 27 console.error('Empty Base64 data'); 28 jokerPopup.show("ä¸è½½é¾æ¥ä¸ºç©º"); 29 return; 30 } 31 32 try { 33 const byteString = atob(base64Data); 34 const arrayBuffer = new ArrayBuffer(byteString.length); 35 const uint8Array = new Uint8Array(arrayBuffer); 36 for (let i = 0; i < byteString.length; i++) { 37 uint8Array[i] = byteString.charCodeAt(i); 38 } 39 40 // å设å¾çæ¯JPEGæ ¼å¼çï¼æ¨å¯è½éè¦æ ¹æ®å®é æ åµä¿®æ¹è¿ä¸ªMIMEç±»å 41 const blob = new Blob([uint8Array], {type: 'image/png'}); 42 43 const link = document.createElement('a'); 44 link.href = window.URL.createObjectURL(blob); 45 link.download = filename; 46 47 for (let htmlElement of element) { 48 if (htmlElement.tagName === 'A') { 49 htmlElement.href = link.href; 50 htmlElement.download = link.download; 51 continue; 52 } 53 htmlElement.addEventListener('click', function (e) { 54 try { 55 if (isMobileDevice() && mobileDownloadFun) { 56 mobileDownloadFun(link, blob); 57 jokerPopup.show("å¼å§ä¸è½½å¦!") 58 return; 59 } 60 link.click(); 61 jokerPopup.show(filename + " å¼å§ä¸è½½...") 62 } catch (e) { 63 jokerPopup.show("ä¸è½½å¤±è´¥ï¼æ¨å¯ä»¥å°è¯é¿æ/å³é®å¾çä¸è½½!!"); 64 } 65 }); 66 } 67 } catch (error) { 68 console.error('Error decoding Base64 data:', error); 69 jokerPopup.show("ä¸è½½å¤±è´¥"); 70 } 71 } 72 73 /** 74 * 75 * @param fileObject éè¦è¢«è§£æçæä»¶å¯¹è±¡ 76 * @param handleFile æä»¶å¯¹è±¡çå¤ç彿° è¾å ¥çæ¯ å½åæä»¶æ°é æä»¶å¯¹è±¡ å æä»¶è·¯å¾ ä»¥åä¸ä¸ªæ è®°ä½ å½æ¨å¨åè°å½æ°ä¸å°æ è®°ä½ç0ç´¢å¼å¼è®¾ç½®ä¸º true æä¼ç»§ç»æ§è¡ä¸ä¸ä¸ª 77 * @param endCallback è§£å宿¯çåè°å½æ° è¾å ¥çæ¯ä¸ä¼ 宿¯çæä»¶å¯¹è±¡ 78 * @returns {Promise<void>} æ è¿å 79 */ 80 static async unzipFile(fileObject, handleFile, endCallback = (f) => { 81 }) { 82 // Create a new JSZip instance 83 const zip = new JSZip(); 84 85 // è¿è¡ä¸ä¸ªæ è®° 代表ä¸ä¸ä¸ªå¤çæ¯å¦å®æ¯ 86 let backOk = [true]; 87 let length = 0; 88 89 let c = 0; 90 let layer_c = 0; 91 92 // Load the zip file from the provided file object 93 zip.loadAsync(fileObject).then( 94 d => { 95 { 96 for (const fileName in d.files) { 97 length++; 98 } 99 } 100 console.info(length) 101 traverseDirectory(d, '', endCallback); 102 } 103 ) 104 105 106 /** 107 * éåç®å½ 108 * @param directory 109 * @param pathPrefix 110 * @param endCallback {function} 111 */ 112 function traverseDirectory(directory, pathPrefix = '', endCallback = null) { 113 114 for (const fileName in directory.files) { 115 const filePath = `${pathPrefix}/${fileName}`; 116 const entry = directory.files[fileName]; 117 118 if (entry.dir) { // If it's a directory, traverse further 119 traverseDirectory(entry, filePath); 120 ++layer_c; 121 } else { // If it's a file, pass the file and path to the handler function 122 entry.async('blob').then( 123 blob => { 124 // 妿ä¸ä¸ä¸ªæä»¶/æä»¶ç®å½æ²¡æå¤ç宿¯ å°±å¨è¿éçä¸ä¼ 125 const timeout = setInterval(() => { 126 if (backOk[0]) { 127 // å½ä¸ä¸ä¸ªå¤ç宿¯äºåå¤çå½åç 128 backOk[0] = false; 129 handleFile(++c, blob, filePath, backOk); 130 clearInterval(timeout); 131 if (endCallback) { 132 ++layer_c; 133 } 134 } 135 }, 1000); 136 } 137 ).catch( 138 error => { 139 console.error(`Error processing file ${filePath}:`, error) 140 } 141 ) 142 } 143 } 144 145 if (endCallback !== null) { 146 // 设置ä¸ä¸ªå®æ¶å¨ 夿å½åæ¯å¦å·²ç»å¤ç宿¯ 147 const interval = setInterval(() => { 148 if (layer_c === length) { 149 endCallback(fileObject); 150 clearInterval(interval) 151 } 152 }, 1000); 153 } 154 } 155 } 156}
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.