Improve paste-to-upload UX with a modal dialog; drop media file preview in My Projects

This commit is contained in:
2026-07-08 14:27:07 +02:00
parent 0ccbef45a1
commit 8ec6e3fd50
7 changed files with 108 additions and 53 deletions
+67 -29
View File
@@ -1,37 +1,75 @@
function enablePasteUpload(inputSelector, previewSelector) {
var input = document.querySelector(inputSelector);
if (!input) return;
var PasteImageModal = (function () {
var bsModal, targetEl, previewEl, defaultText;
var currentInputSelector, currentPreviewSelector;
document.addEventListener('paste', function (e) {
var clipboard = e.clipboardData || window.clipboardData;
var items = clipboard ? clipboard.items : null;
if (!items) return;
function init() {
var modalEl = document.getElementById('pasteImageModal');
if (!modalEl || typeof bootstrap === 'undefined') return false;
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (item.kind === 'file' && item.type.indexOf('image/') === 0) {
var blob = item.getAsFile();
if (!blob) continue;
targetEl = document.getElementById('pasteImageTarget');
previewEl = document.getElementById('pasteImageModalPreview');
defaultText = targetEl.textContent;
bsModal = new bootstrap.Modal(modalEl);
var ext = (blob.type.split('/')[1] || 'png').toLowerCase();
var pastedFile = new File([blob], 'pasted-image-' + Date.now() + '.' + ext, { type: blob.type });
modalEl.addEventListener('shown.bs.modal', function () {
targetEl.textContent = defaultText;
previewEl.style.display = 'none';
previewEl.removeAttribute('src');
targetEl.focus();
});
var dt = new DataTransfer();
dt.items.add(pastedFile);
input.files = dt.files;
input.dispatchEvent(new Event('change', { bubbles: true }));
targetEl.addEventListener('paste', function (e) {
var clipboard = e.clipboardData || window.clipboardData;
var items = clipboard ? clipboard.items : null;
if (!items) return;
if (previewSelector) {
var preview = document.querySelector(previewSelector);
if (preview) {
preview.src = URL.createObjectURL(pastedFile);
preview.style.display = '';
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (item.kind === 'file' && item.type.indexOf('image/') === 0) {
e.preventDefault();
var blob = item.getAsFile();
if (!blob) continue;
var ext = (blob.type.split('/')[1] || 'png').toLowerCase();
var pastedFile = new File([blob], 'pasted-image-' + Date.now() + '.' + ext, { type: blob.type });
var input = document.querySelector(currentInputSelector);
if (input) {
var dt = new DataTransfer();
dt.items.add(pastedFile);
input.files = dt.files;
input.dispatchEvent(new Event('change', { bubbles: true }));
}
}
e.preventDefault();
break;
var url = URL.createObjectURL(pastedFile);
previewEl.src = url;
previewEl.style.display = '';
targetEl.textContent = 'Image pasted!';
if (currentPreviewSelector) {
var extPreview = document.querySelector(currentPreviewSelector);
if (extPreview) {
extPreview.src = url;
extPreview.style.display = '';
}
}
setTimeout(function () { bsModal.hide(); }, 400);
break;
}
}
}
});
}
});
return true;
}
function open(inputSelector, previewSelector) {
if (!bsModal && !init()) return;
currentInputSelector = inputSelector;
currentPreviewSelector = previewSelector || null;
bsModal.show();
}
return { open: open };
})();