diff --git a/app/assets/javascripts/app/controllers/agent_ticket_create.coffee b/app/assets/javascripts/app/controllers/agent_ticket_create.coffee index 090be32ac..cd828e6c3 100644 --- a/app/assets/javascripts/app/controllers/agent_ticket_create.coffee +++ b/app/assets/javascripts/app/controllers/agent_ticket_create.coffee @@ -231,7 +231,6 @@ class App.TicketCreate extends App.Controller # convert non text/html from text 2 html if a.content_type.match(/\/html/) t.body = a.body - t.body = App.Utils.htmlImage2DataUrl(t.body) else t.body = App.Utils.text2html(a.body) @@ -345,6 +344,10 @@ class App.TicketCreate extends App.Controller params: params taskKey: @taskKey ) + + # convert remote images into data urls + App.Utils.htmlImage2DataUrlAsyncInline(@$('[contenteditable=true]')) + App.Ticket.configure_attributes.pop() # set type selector diff --git a/app/assets/javascripts/app/controllers/ticket_zoom/article_action/email_reply.coffee b/app/assets/javascripts/app/controllers/ticket_zoom/article_action/email_reply.coffee index d5ca6a00f..1e13ac968 100644 --- a/app/assets/javascripts/app/controllers/ticket_zoom/article_action/email_reply.coffee +++ b/app/assets/javascripts/app/controllers/ticket_zoom/article_action/email_reply.coffee @@ -132,7 +132,6 @@ class EmailReply extends App.Controller selected = App.ClipBoard.getSelected('html') if selected selected = App.Utils.htmlCleanup(selected).html() - selected = App.Utils.htmlImage2DataUrl(selected) if !selected selected = App.ClipBoard.getSelected('text') if selected @@ -197,7 +196,6 @@ class EmailReply extends App.Controller body = '' if article.content_type.match('html') body = App.Utils.textCleanup(article.body) - body = App.Utils.htmlImage2DataUrl(article.body) if article.content_type.match('plain') body = App.Utils.textCleanup(article.body) @@ -308,6 +306,9 @@ class EmailReply extends App.Controller body.append(signature) ui.$('[data-name=body]').replaceWith(body) + # convert remote images into data urls + App.Utils.htmlImage2DataUrlAsyncInline(ui.$('[contenteditable=true]')) + @validation: (type, params, ui) -> return true if type isnt 'email' diff --git a/app/assets/javascripts/app/lib/app_post/utils.coffee b/app/assets/javascripts/app/lib/app_post/utils.coffee index fd9b23bef..02fa7b4b8 100644 --- a/app/assets/javascripts/app/lib/app_post/utils.coffee +++ b/app/assets/javascripts/app/lib/app_post/utils.coffee @@ -1225,6 +1225,20 @@ class App.Utils ctx.drawImage(img, 0, 0) canvas.toDataURL('image/png') + @htmlImage2DataUrlAsyncInline: (html, callback) -> + 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 + ) + ) + # works asynchronously to make sure images are loaded before converting to base64 # output is passed to callback @htmlImage2DataUrlAsync: (html, callback) -> @@ -1252,7 +1266,7 @@ class App.Utils imageCache = new Image() imageCache.onload = -> data = App.Utils._htmlImage2DataUrl(originalImage) - callback(data) + callback(data) if callback imageCache.src = originalImage.src diff --git a/app/views/tests/html_utils.html.erb b/app/views/tests/html_utils.html.erb index c5faea044..0bb0c9792 100644 --- a/app/views/tests/html_utils.html.erb +++ b/app/views/tests/html_utils.html.erb @@ -13,4 +13,6 @@ body {
-
+
+ +
diff --git a/public/assets/tests/html_utils.js b/public/assets/tests/html_utils.js index d208dd8cc..edc69683e 100644 --- a/public/assets/tests/html_utils.js +++ b/public/assets/tests/html_utils.js @@ -3263,20 +3263,28 @@ test('App.Utils.icon()', function() { equal(App.Utils.icon('arrow-{end}'), svgTag, 'for rtl locale / name includes "{end}"') }); -source = 'some test' -$('#image2text').html(source) -var htmlImage2DataUrlTest = function() { - - var result = App.Utils.htmlImage2DataUrl(source) - test("htmlImage2DataUrl async", function() { - var result = App.Utils.htmlImage2DataUrl(source) - ok(result.match(/some test/), source) - ok(!result.match(/avatar-bg.png/), source) - ok(result.match(/^\