1function updateThumbnailButton(el) { 2 const hidden = el.querySelector("#_thumbnail_id"); 3 const submitButton = el.closest("form")?.querySelector('[type="submit"]'); 4 if (!hidden || !submitButton) return; 5 submitButton.classList.toggle("no-thumbnail", !hidden.value); 6} 7document.addEventListener("DOMContentLoaded", function () { 8 document.querySelectorAll(".wpuf-el").forEach((el) => { 9 const fileInput = el.querySelector(".js-upload"); 10 const btn = el.querySelector(".js-upload-btn"); 11 const preview = el.querySelector(".js-preview"); 12 const hidden = el.querySelector("input[type='text']"); 13 if (!btn || !fileInput) { 14 return; 15 } 16 btn.addEventListener("click", function (e) { 17 e.preventDefault(); 18 fileInput.click(); 19 }); 20 fileInput.addEventListener("change", async function (e) { 21 const files = Array.from(e.target.files); 22 if (!files.length) return; 23 24 const isThumbnail = el.classList.contains("is-thumbnail"); 25 26 for (const file of files) { 27 if (isThumbnail) { 28 await handleThumbnailUpload(file, el); 29 updateThumbnailButton(el); 30 } else { 31 await handleUpload(file, el); 32 } 33 } 34 e.target.value = ""; 35 }); 36 }); 37 document.querySelectorAll(".wpuf-el").forEach(async (el) => { 38 const hidden = el.querySelector("input[type='text']"); 39 const preview = el.querySelector(".js-preview"); 40 const btn = el.querySelector(".js-upload-btn"); 41 if (!hidden || !hidden.value) return; 42 const formData = new FormData(); 43 formData.append("action", "get_attachment_preview"); 44 formData.append("attachment_id", hidden.value); 45 formData.append("nonce", simpleUploadNonce); 46 const res = await fetch("/wp-admin/admin-ajax.php", { 47 method: "POST", 48 body: formData, 49 credentials: "same-origin", 50 }); 51 const json = await res.json(); 52 if (!json.success) return; 53 const url = json.data.url; 54 const box = document.createElement("div"); 55 box.className = "wpuf-image-wrap"; 56 box.innerHTML = ` 57 <img src="${url}?t=${Date.now()}"> 58 <button type="button" class="attachment-delete"><i class="icon-close"></i></button> 59 `; 60 preview.appendChild(box); 61 btn.style.display = "none"; 62 }); 63 document.addEventListener( 64 "click", 65 function (e) { 66 const submitButton = e.target.closest(".wpuf-submit-button"); 67 68 if (!submitButton) return; 69 70 if (!submitButton.classList.contains("no-thumbnail")) { 71 return; 72 } 73 74 console.log("no-thumbnail: éä¿¡ã黿¢"); 75 76 e.preventDefault(); 77 e.stopPropagation(); 78 e.stopImmediatePropagation(); 79 80 const form = submitButton.closest("form"); 81 if (!form) return; 82 83 // ------------------------- 84 // â ã¡ã¤ã³åçã®ã¨ã©ã¼ 85 // ------------------------- 86 87 const input = form.querySelector("#_thumbnail_id"); 88 const field = input?.closest(".wpuf-el"); 89 90 if (field) { 91 field.querySelectorAll(".wpuf-error-msg").forEach((el) => el.remove()); 92 93 const error = document.createElement("div"); 94 error.className = "wpuf-error-msg"; 95 error.textContent = "ã¡ã¤ã³åçã¯å¿ é ã§ã"; 96 97 const help = [...field.querySelectorAll(".wpuf-help")].find((el) => 98 el.querySelector(".js-upload-btn"), 99 ); 100 101 if (help) { 102 help.insertAdjacentElement("afterend", error); 103 } else { 104 field.appendChild(error); 105 } 106 } 107 108 // ------------------------- 109 // â¡ WPUFã®å ¨ä½ã¨ã©ã¼ 110 // ------------------------- 111 112 const wpufErrors = form.querySelector(".wpuf-errors"); 113 114 if (wpufErrors) { 115 wpufErrors.style.display = "block"; 116 } else { 117 // ãªããã°ä½ã 118 const submitArea = submitButton.closest(".wpuf-submit"); 119 120 if (submitArea) { 121 const error = document.createElement("div"); 122 error.className = "wpuf-errors"; 123 error.textContent = 124 "æªå ¥åã®ã¨ã©ã¼çãããã¾ããã確èªã®ä¸ãæç¨¿ãã ãã"; 125 126 submitArea.appendChild(error); 127 } 128 } 129 }, 130 true, 131 ); 132 document.querySelectorAll(".wpuf-el.is-thumbnail").forEach((el) => { 133 updateThumbnailButton(el); 134 }); 135}); 136async function handleUpload(file, el) { 137 const MAX_SIZE = 20 * 1024 * 1024; 138 if (file.size > MAX_SIZE) { 139 alert("ãã¡ã¤ã«ãµã¤ãºã20MBãè¶ ãã¦ãã¾ã"); 140 return; 141 } 142 const preview = el.querySelector(".js-preview"); 143 const btn = el.querySelector(".js-upload-btn"); 144 const hidden = el.querySelector("input[type='text']"); 145 const isGif = file.type === "image/gif"; 146 if (isGif) { 147 cleanFile = file; // â ãã®ã¾ã¾ 148 } else { 149 cleanFile = await compress(file); 150 } 151 const box = document.createElement("div"); 152 box.className = "wpuf-image-wrap"; 153 box.innerHTML = `<div class="upload-item"><div class="progress progress-striped active"><div class="bar" style="width: 80%;"></div></div><div class="filename original"><b><img src="/wp-content/themes/gush/img/icon_loading.gif"></b>
153ã¢ãããã¼ãä¸ï¼ãã°ãããå¾ ã¡ãã ããï¼</div></div>`; 154 preview.appendChild(box); 155 try { 156 const json = await uploadToServer(cleanFile); 157 if (!json.success) throw new Error("upload failed"); 158 const url = json.sizes?.large?.url || json.url; 159 hidden.value = json.attachment_id; 160 btn.style.display = "none"; 161 box.innerHTML = ` 162 <img src="${url}?t=${Date.now()}"> 163 <button type="button" class="attachment-delete"><i class="icon-close"></i></button> 164 `; 165 } catch (e) { 166 console.error(e); 167 box.innerHTML = `<span>upload failed</span>`; 168 } 169} 170async function uploadToServer(file) { 171 const formData = new FormData(); 172 formData.append("action", "simple_upload"); 173 formData.append("file", file, file.name); 174 formData.append("nonce", simpleUploadNonce); 175 const res = await fetch("/wp-admin/admin-ajax.php", { 176 method: "POST", 177 body: formData, 178 credentials: "same-origin", 179 }); 180 return await res.json(); 181} 182async function compress(file) { 183 const isGif = file.type === "image/gif"; 184 if (isGif) return file; 185 const isJpeg = file.type === "image/jpeg"; 186 const compressedBlob = await imageCompression(file, { 187 maxSizeMB: 1, 188 maxWidthOrHeight: 2048, 189 useWebWorker: true, 190 fileType: file.type, 191 initialQuality: 0.9, 192 exifOrientation: -1, 193 }); 194 const originalName = file.name.replace(/\.[^/.]+$/, ""); 195 const ext = file.name.split(".").pop(); 196 return new File([compressedBlob], `${originalName}.${ext}`, { 197 type: file.type, 198 lastModified: Date.now(), 199 }); 200} 201async function handleThumbnailUpload(file, el) { 202 const preview = el.querySelector(".js-preview"); 203 const btn = el.querySelector(".js-upload-btn"); 204 const hidden = el.querySelector("input[type='text']"); 205 const originalInput = el.querySelector(".original-id"); 206 207 preview.innerHTML = ` 208 <div class="upload-item"> 209 <div class="progress progress-striped active"> 210 <div class="bar" style="width: 80%;"></div> 211 </div> 212 <div class="filename original"> 213 <b><img src="/wp-content/themes/gush/img/icon_loading.gif"></b> 214 ã¢ãããã¼ãä¸ï¼ãã°ãããå¾ ã¡ãã ããï¼ 215 </div> 216 </div> 217 `; 218 219 const cleanFile = await compress(file); 220 const originalJson = await uploadToServer(cleanFile); 221 if (!originalJson.success) { 222 alert("ã¢ãããã¼ã失æ"); 223 return; 224 } 225 const originalId = originalJson.attachment_id; 226 const imageUrl = originalJson.url; 227 const filename = imageUrl.split("/").pop(); 228 const originalName = filename.replace(/\.[^/.]+$/, ""); 229 openCropModal(imageUrl, { 230 el, 231 hidden, 232 btn, 233 preview, 234 originalId, 235 originalInput, 236 originalName, 237 mimeType: file?.type, 238 }); 239} 240let cropperInstance = null; 241let cropState = null; 242function createCropModal() { 243 if (document.getElementById("cropModal")) return; 244 const modal = document.createElement("div"); 245 modal.id = "cropModal"; 246 modal.innerHTML = ` 247 <div class="crop-overlay"></div> 248 <div class="c-daalog__modal"> 249 <div class="c-dialog__header"> 250 <h3 class="c-dialog__header-title">
250ç»åã®åãæã</h3> 251 </div> 252 <div class="crop-body"> 253 <div class="crop-container"> 254 <img id="cropModalTarget"> 255 </div> 256 </div> 257 <ul class="inner_margin crop-bottom-list"> 258 <li class="crop-bottom-item"> 259 <button id="cropConfirmBtn" class="c-button__regist">ä¿å</button> 260 </li> 261 <li class="crop-bottom-item"> 262 <button id="cropCancelBtn" class="c-button__login">ãã£ã³ã»ã«</button> 263 </li> 264 </ul> 265 </div> 266 `; 267 modal.style.cssText = ` 268 position:fixed; 269 inset:0; 270 z-index:99999; 271 display:none; 272 `; 273 document.body.appendChild(modal); 274 bindCropModalEvents(modal); 275} 276function openCropModal(imageUrl, state) { 277 createCropModal(); 278 cropState = state; 279 const modal = document.getElementById("cropModal"); 280 const img = document.getElementById("cropModalTarget"); 281 modal.style.display = "block"; 282 document.body.style.overflow = "hidden"; 283 img.onload = () => { 284 const ratio = img.naturalWidth / img.naturalHeight; 285 const modal = document.getElementById("cropModal"); 286 const body = modal.querySelector(".crop-body"); 287 const maxWidth = Math.min(window.innerWidth * 0.9, 600); 288 const maxHeight = window.innerHeight * 0.8; 289 let width = maxWidth; 290 let height = width / ratio; 291 if (height > maxHeight) { 292 height = maxHeight; 293 width = height * ratio; 294 } 295 body.style.width = width + "px"; 296 body.style.height = height + "px"; 297 if (cropperInstance) { 298 cropperInstance.destroy(); 299 } 300 cropperInstance = new Cropper(img, { 301 aspectRatio: 1, 302 viewMode: 1, 303 autoCropArea: 1, 304 movable: false, 305 zoomable: false, 306 background: false, 307 }); 308 }; 309 img.src = imageUrl; 310} 311function bindCropModalEvents(modal) { 312 const confirmBtn = modal.querySelector("#cropConfirmBtn"); 313 const cancelBtn = modal.querySelector("#cropCancelBtn"); 314 confirmBtn.addEventListener("click", async () => { 315 if (!cropperInstance) return; 316 const canvas = cropperInstance.getCroppedCanvas({ 317 width: 750, 318 height: 750, 319 }); 320 const baseName = cropState.originalName || "image"; 321 const isGif = cropState.mimeType === "image/gif"; 322 let file; 323 if (isGif) { 324 const gif = new GIF({ 325 workers: 2, 326 quality: 10, 327 width: canvas.width, 328 height: canvas.height, 329 workerScript: "/wp-content/themes/gush/assets/js/gif.worker.js", 330 }); 331 gif.addFrame(canvas, { delay: 200 }); 332 file = await new Promise((resolve) => { 333 gif.on("finished", function (blob) { 334 const f = new File([blob], `${baseName}-aspect-ratio-750-750.gif`, { 335 type: "image/gif", 336 }); 337 resolve(f); 338 }); 339 gif.render(); 340 }); 341 } else { 342 let mime = "image/jpeg"; 343 let ext = "jpg"; 344 if (cropState.mimeType === "image/png") { 345 mime = "image/png"; 346 ext = "png"; 347 } 348 const blob = await new Promise((resolve) => { 349 canvas.toBlob(resolve, mime, 0.9); 350 }); 351 file = new File([blob], `${baseName}-aspect-ratio-750-750.${ext}`, { 352 type: mime, 353 }); 354 } 355 const json = await uploadToServer(file); 356 const { hidden, btn, preview, originalId, originalInput } = cropState; 357 hidden.value = json.attachment_id; 358 updateThumbnailButton(cropState.el); 359 if (originalInput) { 360 originalInput.value = originalId; 361 } 362 preview.innerHTML = ` 363 <div class="wpuf-image-wrap"> 364 <img src="${json.url}?t=${Date.now()}"> 365 <button type="button" class="attachment-delete"> 366 <i class="icon-close"></i> 367 </button> 368 </div> 369 `; 370 btn.style.display = "none"; 371 closeCropModal(); 372 }); 373 cancelBtn.addEventListener("click", async () => { 374 const { preview, hidden, btn, originalId } = cropState; 375 closeCropModal(); 376 preview.innerHTML = ""; 377 hidden.value = ""; 378 btn.style.display = ""; 379 if (originalId) { 380 const formData = new FormData(); 381 formData.append("action", "delete_image"); 382 formData.append("attachment_id", originalId); 383 formData.append("nonce", simpleUploadNonce); 384 await fetch("/wp-admin/admin-ajax.php", { 385 method: "POST", 386 body: formData, 387 credentials: "same-origin", 388 }); 389 } 390 }); 391} 392function closeCropModal() { 393 const modal = document.getElementById("cropModal"); 394 if (cropperInstance) { 395 cropperInstance.destroy(); 396 cropperInstance = null; 397 } 398 if (modal) { 399 modal.style.display = "none"; 400 } 401 document.body.style.overflow = "";
402 cropState = null; 403} 404document.addEventListener("click", async (e) => { 405 const btn = e.target.closest(".attachment-delete"); 406 if (!btn) return; 407 const wrap = btn.closest(".wpuf-image-wrap"); 408 const el = btn.closest(".wpuf-el"); 409 if (!wrap || !el) return; 410 const hidden = el.querySelector("input[type='text']"); 411 const mainBtn = el.querySelector(".js-upload-btn"); 412 const attachmentId = hidden.value; 413 if (!attachmentId) return; 414 const ok = confirm( 415 "ãã®ç»åãåé¤ãã¾ããå ã«æ»ãã¾ãããæ¬å½ã«ããããã§ããï¼", 416 ); 417 if (!ok) return; 418 const isThumbnail = el.classList.contains("is-thumbnail"); 419 if (isThumbnail) { 420 wrap.remove(); 421 hidden.value = ""; 422 mainBtn.style.display = ""; 423 updateThumbnailButton(el); 424 return; 425 } 426 const formData = new FormData(); 427 formData.append("action", "delete_image"); 428 formData.append("attachment_id", attachmentId); 429 formData.append("nonce", simpleUploadNonce); 430 const res = await fetch("/wp-admin/admin-ajax.php", { 431 method: "POST", 432 body: formData, 433 credentials: "same-origin", 434 }); 435 const result = await res.json(); 436 if (result.success) { 437 wrap.remove(); 438 hidden.value = ""; 439 mainBtn.style.display = ""; 440 } 441});
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.