From 790da8deeb51617e40309cc5d0c36b793be70b31 Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Wed, 7 Jun 2017 23:43:14 +0200 Subject: [PATCH] Fix #14 and !5 Allow to paste images to upload them This wouldn't have been possible without the great work of Alexis Clairet (MR !5). I had to close the MR and report his work because of the many changes in Lutim since he worked on it. This commit is dedicated to Schoumi, who is supporting me on Tipeee. Many thanks :-) --- AUTHORS.md | 1 + CHANGELOG | 1 + themes/default/public/css/lutim.css | 9 ++ themes/default/public/js/lutim.js | 1 + themes/default/templates/partial/lutim.js.ep | 106 +++++++++++++++++++ 5 files changed, 118 insertions(+) diff --git a/AUTHORS.md b/AUTHORS.md index 61d58ff..15803cf 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -14,3 +14,4 @@ * Laura Arjona Reina (), spanish translation * Thor77 (), german translation, among other things * Quentin Pagès, occitan translation +* Alexis Clairet (), paste image to upload ability diff --git a/CHANGELOG b/CHANGELOG index bf3675f..a312516 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -12,6 +12,7 @@ Revision history for Lutim - Add gallery constructor to "my files" list (#33) - Handle too much images in zip download URL (#27) - LocalStorage is now updated if an image's delay is modified + - Allow user to paste image from clipboard to upload images (#14 and !5) 0.7.1 2016-06-21 - Fix dependency bug diff --git a/themes/default/public/css/lutim.css b/themes/default/public/css/lutim.css index 2d802aa..37da882 100644 --- a/themes/default/public/css/lutim.css +++ b/themes/default/public/css/lutim.css @@ -74,3 +74,12 @@ label.always-encrypt { line-height: 21px; margin-top: -5.33333px; } +.pasteZone { + position: absolute; + top: 0; + left: -100px; + z-index: -999; + height: 10000vh; + width: 0; + display: hidden; +} diff --git a/themes/default/public/js/lutim.js b/themes/default/public/js/lutim.js index 40d85cc..47affec 100644 --- a/themes/default/public/js/lutim.js +++ b/themes/default/public/js/lutim.js @@ -100,6 +100,7 @@ $('document').ready(function() { var deleteday = ($('#delete-day').prop('checked')) ? 1 : 0; bindddz(firstview, deleteday); + initPaste(); $('#file-url-button').on('click', upload_url); $('#lutim-file-url').keydown( function(e) { diff --git a/themes/default/templates/partial/lutim.js.ep b/themes/default/templates/partial/lutim.js.ep index 81f8075..ec5baae 100644 --- a/themes/default/templates/partial/lutim.js.ep +++ b/themes/default/templates/partial/lutim.js.ep @@ -352,4 +352,110 @@ }, }); } + + function initPaste() { + /* + actually FF and Chrome doesn't handle paste events the same way... + for ff we need to create a editable div and register an event to it. + When user paste, the image is "really" pasted in the div. Then, we need to iterate throught + the div childs to get images. Previsouly FF didn't have the paste event so it was esay to figure on wich browser we were. + But firefox now have a paste event so I test it... + + on Chrome the file object is directlyt in the clipboard. + */ + var b = 'FF'; + try { + //FF + var cbe = new ClipboardEvent('hop'); + } catch(hop) { + //under webkkit Clipboard doesn't have arguments... + b = 'WK' + } + if (b === 'FF') { + var pasteDiv = document.createElement('div'); + pasteDiv.addEventListener('paste', onPasteFF); + pasteDiv.setAttribute('class', 'pasteZone'); + pasteDiv.setAttribute('contenteditable', true); + + document.getElementsByTagName('body')[0].appendChild(pasteDiv); + pasteDiv.focus(); + + document.addEventListener('click', function(event) { + var t = $(event.target); + + switch (t[0].nodeName.toUpperCase()) { + case 'A': + case 'BUTTON': + case 'INPUT': + case 'SELECT': + case 'SPAN': + case 'LABEL': + break; + default: + if (t[0].parentNode.nodeName.toUpperCase() !== 'SELECT') { + pasteDiv.focus(); + } + } + }); + } else { + document.addEventListener('paste', onPaste); + } + } + + function waitforpastedata(elem, savedcontent) { + if (elem.childNodes && elem.childNodes.length > 0) { + processpaste(elem, savedcontent); + } else { + var that = { + e: elem, + s: savedcontent + }; + that.callself = function () { + waitforpastedata(that.e, that.s); + } + setTimeout(that.callself, 20); + } + } + + function processpaste(elem, savedcontent) { + var pasteZone = document.getElementsByClassName('pasteZone')[0]; + var f = new Image(); + + f.onload = function(){ + var canvas = document.createElement('canvas'); + canvas.width = f.width; + canvas.height = f.height; + + var ctx = canvas.getContext('2d'); + ctx.drawImage(f, 0, 0, canvas.width, canvas.height); + + canvas.toBlob(function(blob) { + var url = window.URL.createObjectURL(blob); + fileUpload(blob); + }); + } + + f.src = pasteZone.childNodes[0].src; + + pasteZone.innerHTML = ''; + } + + function onPasteFF(e) { + var pasteZone = document.getElementsByClassName('pasteZone')[0]; + waitforpastedata(pasteZone, 'savedcontent'); + } + + function onPaste(e) { + var items = e.clipboardData.items; + for(var i = 0; i < items.length; i++) { + console.log('toto'); + var item = items[i]; + if (/image/.test(item.type)) { + var file = item.getAsFile(); + fileUpload(file); + } else { + //not image.. + } + } + } % end