From 16fec3d88805c0dafdf354a3b7a7277bfc0f080b Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Fri, 20 Mar 2020 14:01:06 +0100 Subject: [PATCH] Fixed issue #2976 - Not possible to copy inline images text from article to article (copy text and image image - via clipboard ctrl+c/ctrl+v). --- .../javascripts/app/lib/app_post/utils.coffee | 39 +++++++++++++------ .../app/lib/base/jquery.contenteditable.js | 1 + public/assets/tests/html_utils.js | 16 +++++--- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/app/assets/javascripts/app/lib/app_post/utils.coffee b/app/assets/javascripts/app/lib/app_post/utils.coffee index 02fa7b4b8..5539dbef2 100644 --- a/app/assets/javascripts/app/lib/app_post/utils.coffee +++ b/app/assets/javascripts/app/lib/app_post/utils.coffee @@ -1217,25 +1217,38 @@ class App.Utils ) html.get(0).innerHTML - @_htmlImage2DataUrl: (img) -> + @_htmlImage2DataUrl: (img, params = {}) -> canvas = document.createElement('canvas') canvas.width = img.width canvas.height = img.height ctx = canvas.getContext('2d') ctx.drawImage(img, 0, 0) - canvas.toDataURL('image/png') + try + data = canvas.toDataURL('image/png') + params.success(img, data) if params.success + return data + catch e + App.Log.notice('Utils', "Can\'t insert image from #{img.src}", e) + params.fail(img) if params.fail + return - @htmlImage2DataUrlAsyncInline: (html, callback) -> + # convert image urls info data urls in element + @htmlImage2DataUrlAsyncInline: (html, params = {}) -> html.find('img').each( (index) -> element = $(@) src = element.attr('src') # or an empty src attribute may mean broken emails (see issue #2305 / #2701) return if !src? or src.match(/^(data|cid):/i) - - App.Utils._htmlImage2DataUrlAsync(@, (data) -> - element.attr('src', data) - callback(element) if callback + App.Utils._htmlImage2DataUrlAsync(@, + success: (img, data) -> + $img = $(img) + $img.attr('src', data) + $img.css('max-width','100%') + params.success(img, data) if params.success + fail: (img) -> + img.remove() + params.fail(img) if params.fail ) ) @@ -1253,7 +1266,7 @@ class App.Utils cacheOrDone = -> if (nextElem = elems.pop()) - App.Utils._htmlImage2DataUrlAsync(nextElem, (data) -> + App.Utils._htmlImage2DataUrlAsync(nextElem, success: (data) -> $(nextElem).attr('src', data) cacheOrDone() ) @@ -1262,12 +1275,14 @@ class App.Utils cacheOrDone() - @_htmlImage2DataUrlAsync: (originalImage, callback) -> + @_htmlImage2DataUrlAsync: (originalImage, params = {}) -> imageCache = new Image() + imageCache.crossOrigin = 'anonymous' imageCache.onload = -> - data = App.Utils._htmlImage2DataUrl(originalImage) - callback(data) if callback - + App.Utils._htmlImage2DataUrl(originalImage, params) + imageCache.onerror = -> + App.Log.notice('Utils', "Unable to load image from #{originalImage.src}") + params.fail(originalImage) if params.fail imageCache.src = originalImage.src @baseUrl: -> diff --git a/app/assets/javascripts/app/lib/base/jquery.contenteditable.js b/app/assets/javascripts/app/lib/base/jquery.contenteditable.js index 985d3d4ef..e4f6f8338 100644 --- a/app/assets/javascripts/app/lib/base/jquery.contenteditable.js +++ b/app/assets/javascripts/app/lib/base/jquery.contenteditable.js @@ -382,6 +382,7 @@ if (htmlString) { this.log('insert html from clipboard', htmlString) this.paste(htmlString) + App.Utils.htmlImage2DataUrlAsyncInline(this.$element) return true } } diff --git a/public/assets/tests/html_utils.js b/public/assets/tests/html_utils.js index edc69683e..2431bbef4 100644 --- a/public/assets/tests/html_utils.js +++ b/public/assets/tests/html_utils.js @@ -3278,13 +3278,19 @@ $('#image2data1 img').one('load', htmlImage2DataUrlTest1) var source2 = 'some test' $('#image2data2').html(source2) -var htmlImage2DataUrlTest2 = function(element) { - test("htmlImage2DataUrl2 async", function() { - ok(!element.html().match(/chat-demo-avatar/), source2) - ok(element.get(0).outerHTML.match(/^\