1 2 function imgViewGetCheckboxes() { 3 return document.querySelectorAll('input[name="selectImgViewItem"]'); 4 } 5 6 function imgViewSyncCardState(checkbox) { 7 if (!checkbox) return; 8 var card = checkbox.closest('.itemPreview'); 9 if (card) card.classList.toggle('selected', checkbox.checked); 10 imgViewUpdateToolbar(); 11 } 12 13 function imgViewToggleCard(evt, card) { 14 if (!card) return false; 15 var target = evt ? evt.target : null; 16 if (target && target.closest && (target.closest('.itemPreviewDetail') || target.closest('input') || target.closest('label'))) { 17 return true; 18 } 19 var checkbox = card.querySelector('input[name="selectImgViewItem"]'); 20 if (!checkbox) return false; 21 checkbox.checked = !checkbox.checked; 22 imgViewSyncCardState(checkbox); 23 return false; 24 } 25 26 function imgViewUpdateToolbar() { 27 var checkboxes = imgViewGetCheckboxes(); 28 var selected = 0; 29 var allChecked = checkboxes.length > 0; 30 for (var i = 0; i < checkboxes.length; i++) { 31 if (checkboxes[i].checked) selected++; 32 else allChecked = false; 33 } 34 var counter = document.getElementById('imgViewSelectedCount'); 35 if (counter) counter.innerHTML = 'å·²é ' + selected + ' å¼ '; 36 37 var toggleBtn = document.getElementById('imgViewToggleAllLink'); 38 if (toggleBtn) toggleBtn.innerHTML = allChecked ? 'åæ¶å ¨é' : 'å ¨é'; 39 } 40 41 function imgViewToggleAll(v) { 42 var checkboxes = imgViewGetCheckboxes(); 43 if (!checkboxes.length) return false; 44 45 var allChecked = true; 46 for (var i = 0; i < checkboxes.length; i++) { 47 if (!checkboxes[i].checked) { 48 allChecked = false; 49 break; 50 } 51 } 52 53 var targetChecked = !allChecked; 54 for (var j = 0; j < checkboxes.length; j++) { 55 checkboxes[j].checked = targetChecked; 56 imgViewSyncCardState(checkboxes[j]); 57 } 58 imgViewUpdateToolbar(); 59 return false; 60 } 61 62 function imgViewGetSelectedUrls() { 63 var checkboxes = imgViewGetCheckboxes(); 64 var urls = []; 65 var exists = {}; 66 for (var i = 0; i < checkboxes.length; i++) { 67 if (!checkboxes[i].checked) continue; 68 var url = imgViewToOriginalUrl((checkboxes[i].value || '').trim()); 69 if (!url || exists[url]) continue; 70 urls.push(url); 71 exists[url] = 1; 72 } 73 return urls; 74 } 75 76 function imgViewToOriginalUrl(url) { 77 if (!url) return ''; 78 var raw = String(url).trim(); 79 if (!raw) return ''; 80 81 var base = raw; 82 var query = ''; 83 var queryIdx = raw.indexOf('?'); 84 if (queryIdx >= 0) { 85 base = raw.substring(0, queryIdx); 86 query = raw.substring(queryIdx); 87 } 88 89 base = base.replace(/\/(200|512)\/?$/, ''); 90 return base + query; 91 } 92 93 function imgViewBuildFilename(url, index) { 94 var fallback = 'imgview_' + String(index + 1) + '.jpg'; 95 if (!url) return fallback; 96 try { 97 var clean = String(url).split('#')[0].split('?')[0]; 98 var name = clean.substring(clean.lastIndexOf('/') + 1); 99 if (!name) return fallback; 100 return decodeURIComponent(name); 101 } catch (e) { 102 return fallback; 103 } 104 } 105 106 function imgViewTriggerDirectDownload(url, fileName) { 107 var a = document.createElement('a'); 108 a.style.display = 'none'; 109 a.href = url; 110 a.download = fileName || 'image.jpg'; 111 document.body.appendChild(a); 112 a.click(); 113 document.body.removeChild(a); 114 } 115 116 function imgViewDownloadOne(url, index) { 117 if (!url) return Promise.resolve(); 118 119 var fileName = imgViewBuildFilename(url, index || 0); 120 return fetch(url, { credentials: 'same-origin' }) 121 .then(function (resp) { 122 if (!resp.ok) throw new Error('download failed'); 123 return resp.blob(); 124 }) 125 .then(function (blob) { 126 var blobUrl = window.URL.createObjectURL(blob); 127 if (typeof downloadBlobByUrl === 'function') { 128 downloadBlobByUrl(blobUrl, fileName); 129 } else { 130 imgViewTriggerDirectDownload(blobUrl, fileName); 131 } 132 window.URL.revokeObjectURL(blobUrl); 133 }) 134 .catch(function () { 135 imgViewTriggerDirectDownload(url, fileName); 136 }); 137 } 138
139 function imgViewBatchDownload(v) { 140 var urls = imgViewGetSelectedUrls(); 141 if (!urls.length) { 142 alert('请å éæ©éè¦ä¸è½½çå¾ç'); 143 return false; 144 } 145 146 v.innerHTML = 'æ£å¨ä¸è½½...'; 147 148 var index = 0; 149 function runNext() { 150 if (index >= urls.length) return; 151 var currentIndex = index; 152 imgViewDownloadOne(urls[currentIndex], currentIndex); 153 index++; 154 setTimeout(runNext, 300); 155 } 156 157 //2ç§é忢夿鮿å 158 setTimeout(function(){ 159 v.innerHTML = 'æ¹éä¸è½½'; 160 }, 2000); 161 162 runNext(); 163 return false; 164 } 165 166 function initTemplateCategoryTabs(){ 167 var tabBox = document.getElementById('templateCategoryTabs'); 168 if (!tabBox) return; 169 tabBox.innerHTML = ''; 170 nanoBananaTemplateCategoryList.forEach(function(category){ 171 appendTemplateCategoryTab(tabBox, category.id, category.name); 172 }); 173 } 174 175 function appendTemplateCategoryTab(tabBox, cateId, cateName){ 176 var link = document.createElement('a'); 177 link.href = '#'; 178 link.className = 'template-category-tab' + (String(cateId) === '' ? ' active' : ''); 179 link.setAttribute('data-cate-id', cateId); 180 link.textContent = cateName; 181 link.onclick = function(){ 182 return selectTemplateCate(cateId); 183 }; 184 tabBox.appendChild(link); 185 } 186 187 function selectTemplateCate(cateId){ 188 currentTemplateCateId = String(cateId || ''); 189 document.querySelectorAll('#templateCategoryTabs .template-category-tab').forEach(function(tab){ 190 tab.classList.toggle('active', tab.getAttribute('data-cate-id') === currentTemplateCateId); 191 }); 192 getTemplates('Nano Banana', currentTemplateCateId); 193 return false; 194 } 195 196 function buildTemplateItemHtml(img){ 197 var json = {}; 198 var addImgs = []; 199 try { 200 json = img.json ? JSON.parse(img.json) : {}; 201 addImgs = Array.isArray(json.addImgs) ? json.addImgs : []; 202 } catch (e) { 203 addImgs = []; 204 } 205 206 var addHtml = ''; 207 if (addImgs.length > 0){ 208 addHtml = '<small>'; 209 for (var j=0; j<addImgs.length; j++){ 210 addHtml += '<img src="'+addImgs[j].replace("myqcloud.com", "myqcloud.com/200")+'">'; 211 } 212 addHtml += '</small>'; 213 } 214 215 return '<li><a href="/template/show/'+encodeURIComponent(img.id)+'" target="_blank">'+addHtml+'<img src="'+img.smallImgUrl+'"><span>'+escapeHtml(img.name)+'</span></a></li>'; 216 } 217 218 function buildMoreTemplateHtml(){ 219 var moreUrl = '/template/' + encodeURIComponent(currentTemplateCateId) + '?action=Nano%20Banana'; 220 if (currentTemplateCateId === '') { 221 moreUrl = '/template/?action=Nano%20Banana'; 222 } 223 return '<li class="template-more-item"><a href="'+moreUrl+'" target="_blank">æ¥çæ´å¤æ¨¡ç</a></li>'; 224 } 225 226 function renderTemplateList(templateData, emptyText){ 227 var templateList = document.getElementById('templateList'); 228 var templateEmptyState = document.getElementById('templateEmptyState'); 229 if (!templateList || !templateEmptyState) return; 230 231 var html = ''; 232 for (var i=0; i<templateData.length; i++){ 233 html += buildTemplateItemHtml(templateData[i]); 234 } 235 html += buildMoreTemplateHtml(); 236 templateList.innerHTML = html; 237 238 if (templateData.length > 0){ 239 templateEmptyState.style.display = 'none'; 240 } else { 241 templateEmptyState.textContent = emptyText || 'ææ è¯¥å类模ç'; 242 templateEmptyState.style.display = 'block'; 243 } 244 } 245 246 function escapeHtml(text) { 247 var map = { 248 '&': '&', 249 '<': '<', 250 '>': '>', 251 '"': '"', 252 "'": ''' 253 }; 254 return text.replace(/[&<>"']/g, function(m) { return map[m]; }); 255 } 256 257 function getTemplates(templateId, cateId){ 258 renderTemplateList([], '模çå è½½ä¸...'); 259 var url = '/template/api_template_action/?pv=50&actionName='+encodeURIComponent(templateId); 260 if (cateId) { 261 url += '&cateId='+encodeURIComponent(cateId); 262 } 263 $.ajax({ 264 type: 'GET', 265 url: url, 266 cache: false, 267 contentType: false, 268 processData: false, 269 success: function (re) { 270 if (re && re.data && re.data.data) { 271 renderTemplateList(re.data.data, 'ææ è¯¥å类模ç'); 272 } else { 273 renderTemplateList([], 'ææ è¯¥å类模ç'); 274 } 275 }, 276 error: function(){ 277 renderTemplateList([], '模çå 载失败ï¼è¯·ç¨åéè¯'); 278 } 279 }); 280 }
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.