From 7278372388d5482cdedf1d247999f38569479553 Mon Sep 17 00:00:00 2001 From: Lauris BH Date: Thu, 15 Nov 2018 03:20:13 +0200 Subject: [PATCH] Implement pasting image from clipboard for browsers that supports that (#5317) --- public/js/index.js | 82 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/public/js/index.js b/public/js/index.js index c6531cb22..9e33ac7de 100644 --- a/public/js/index.js +++ b/public/js/index.js @@ -171,6 +171,87 @@ function initReactionSelector(parent) { }); } +function insertAtCursor(field, value) { + if (field.selectionStart || field.selectionStart === 0) { + var startPos = field.selectionStart; + var endPos = field.selectionEnd; + field.value = field.value.substring(0, startPos) + + value + + field.value.substring(endPos, field.value.length); + field.selectionStart = startPos + value.length; + field.selectionEnd = startPos + value.length; + } else { + field.value += value; + } +} + +function replaceAndKeepCursor(field, oldval, newval) { + if (field.selectionStart || field.selectionStart === 0) { + var startPos = field.selectionStart; + var endPos = field.selectionEnd; + field.value = field.value.replace(oldval, newval); + field.selectionStart = startPos + newval.length - oldval.length; + field.selectionEnd = endPos + newval.length - oldval.length; + } else { + field.value = field.value.replace(oldval, newval); + } +} + +function retrieveImageFromClipboardAsBlob(pasteEvent, callback){ + if (!pasteEvent.clipboardData) { + return; + } + + var items = pasteEvent.clipboardData.items; + if (typeof(items) === "undefined") { + return; + } + + for (var i = 0; i < items.length; i++) { + if (items[i].type.indexOf("image") === -1) continue; + var blob = items[i].getAsFile(); + + if (typeof(callback) === "function") { + pasteEvent.preventDefault(); + pasteEvent.stopPropagation(); + callback(blob); + } + } +} + +function uploadFile(file, callback) { + var xhr = new XMLHttpRequest(); + + xhr.onload = function() { + if (xhr.status == 200) { + callback(xhr.responseText); + } + }; + + xhr.open("post", suburl + "/attachments", true); + xhr.setRequestHeader("X-Csrf-Token", csrf); + var formData = new FormData(); + formData.append('file', file, file.name); + xhr.send(formData); +} + +function initImagePaste(target) { + target.each(function(i, field) { + field.addEventListener('paste', function(event){ + retrieveImageFromClipboardAsBlob(event, function(img) { + var name = img.name.substr(0, img.name.lastIndexOf('.')); + insertAtCursor(field, '![' + name + ']()'); + uploadFile(img, function(res) { + var data = JSON.parse(res); + replaceAndKeepCursor(field, '![' + name + ']()', '![' + name + '](' + suburl + '/attachments/' + data.uuid + ')'); + var input = $('').val(data.uuid); + $('.files').append(input); + }); + }); + }, false); + }); +} + function initCommentForm() { if ($('.comment.form').length == 0) { return @@ -178,6 +259,7 @@ function initCommentForm() { initBranchSelector(); initCommentPreviewTab($('.comment.form')); + initImagePaste($('.comment.form textarea')); // Listsubmit function initListSubmits(selector, outerSelector) {