/* * Enable direct copy & paste and drag & drop to upload files. * Works in Chrome and Edge. * Upload functionality courtesy of http://www.unionpaper.net * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software * Foundation; either version 3 of the License, or (at your * option) any later version. Available at * https://www.gnu.org/licenses/gpl.txt * * Copyright 2016 Ling-San Meng (f95942117@gmail.com) * Modified 2025-04-17 by Gemini (for drag & drop and cross-browser compatibility) * Version 20250417 */ window.addEventListener('load', function () { var _PasteImgUploadPubUrl = PasteImgUploadPubUrl + '/pasteimgupload/upload.png'; var uploadImgInnerHTML = ''; var uploadImgDiv = document.createElement('div'); uploadImgDiv.style.position = 'fixed'; uploadImgDiv.style.bottom = Math.round(window.innerHeight / 2) - 25 + 'px'; // Start in the vertical center (adjust for height) uploadImgDiv.style.display = 'none'; uploadImgDiv.style.left = Math.round(window.innerWidth / 5) + 'px'; document.body.appendChild(uploadImgDiv); var targetElement = document.getElementById('text'); // Handle paste events targetElement.onpaste = function (e) { var items = e.clipboardData.items; if (typeof items === 'undefined') { return true; } var file = null; for (var i = 0; i < items.length; i++) { if (items[i].kind === 'file') { file = items[i].getAsFile(); break; } } if (file) { uploadFile(file); return false; } }; // Prevent default drag and drop behavior targetElement.ondragover = function (e) { e.preventDefault(); }; // Handle drop events targetElement.ondrop = function (e) { e.preventDefault(); var files = e.dataTransfer.files; if (files.length > 0) { uploadFile(files[0]); // Only handle the first dropped file } }; function sanitizeFilename(filename) { // Remove any characters that are not letters, numbers, or periods let name = filename.substring(0, filename.lastIndexOf('.')) || filename; name = name.replace(/[^a-zA-Z0-9.]/g, '_'); // Replace spaces with underscores name = name.replace(/\s+/g, '_'); return name; } function uploadFile(file) { if (!file || file.size === 0) { return true; } const originalName = file.name; const extension = originalName.slice((originalName.lastIndexOf(".") - 1 >>> 0) + 2); const sanitizedName = sanitizeFilename(originalName); const timestamp = PasteImgUploadGetFormatTime(); const newFilename = `${sanitizedName}_${timestamp}.${extension}`; var formData = new FormData(); formData.append('uploadfile', file, newFilename); var req = new XMLHttpRequest(); req.open('POST', PasteImgUploadUrl, true); req.setRequestHeader('AJAXUPLOAD', 'TRUE'); req.send(formData); req.onreadystatechange = function () { if (this.readyState === 4) { if (this.status === 200) { var response = this.getResponseHeader("UpResult"); if (response === 'successfully uploaded') { var textElement = document.getElementById('text'); textElement.value += (textElement.value ? '\n' : '') + 'Attach:' + newFilename; // Use the new filename // Optionally trigger an input or change event var event = new Event('input', { bubbles: true, cancelable: true, }); textElement.dispatchEvent(event); uploadImgDiv.innerHTML = uploadImgInnerHTML; PasteImgUploadSlideUpElement( uploadImgDiv, parseInt(uploadImgDiv.style.bottom, 10), 10, 0.4 ); } else { alert('Upload failed: ' + response + '!'); } } else { alert('Upload failed: HTTP error!'); } } }; } function getFileExtension(filename) { return filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2); } }, false); // Move up an element by changing its style property "bottom" from "startPx" px to "endPx" // px within "duration" When it's finished, it fades out the element by calling another // function. function PasteImgUploadSlideUpElement(element, startPx, endPx, duration) { try { clearInterval(slideTimerID); } catch (errorMsg) {} try { clearInterval(fadeTimerID); } catch (errorMsg2) {} var stepDuration = 20; element.style.display = 'initial'; var position = startPx; var diff = endPx - startPx; element.style.bottom = position + 'px'; element.style.opacity = 1; var stepPosition = diff * (stepDuration / (duration * 1000)); slideTimerID = setInterval(function () { if (position > endPx) { clearInterval(slideTimerID); PasteImgUploadFadeElement(element, 'out', 4); } element.style.bottom = position + 'px'; position += stepPosition; }, stepDuration); } // Fade out an element by changing its style property "opacity" from 1.0 to 0 within // "duration". function PasteImgUploadFadeElement(element, style, duration) { var stepDuration = 20; var op = 0; if (style === 'out') { op = 1; } element.style.opacity = op; element.style.display = 'initial'; var stepOp = stepDuration / (duration * 1000); fadeTimerID = setInterval(function () { if (op > 1 || op < 0) { clearInterval(fadeTimerID); } element.style.opacity = op; if (style === 'in') { op += stepOp; } else { op -= stepOp; } }, stepDuration); } // Return a formatted date/time as YYYYMMDD_HHMMSS function PasteImgUploadGetFormatTime() { var clock = new Date(); var year = clock.getFullYear(), mon = clock.getMonth() + 1, date = clock.getDate(), hour = clock.getHours(), min = clock.getMinutes(), sec = clock.getSeconds(); return year + (mon < 10 ? '0' + mon : mon) + (date < 10 ? '0' + date : date) + '_' + (hour < 10 ? '0' + hour : hour) + (min < 10 ? '0' + min : min) + (sec < 10 ? '0' + sec : sec); }