diff --git a/docs/CHANGES.md b/docs/CHANGES.md index 23f6611df..498e1f402 100755 --- a/docs/CHANGES.md +++ b/docs/CHANGES.md @@ -18,6 +18,7 @@ - #806 The `_converse.listen` API event listeners aren't triggered. [jcbrand] - #807 Error: Plugin "converse-dragresize" tried to override HeadlinesBoxView but it's not found. [jcbrand] - #811 jQuery wasn't being closured in builds. [jcbrand] +- #814 Images from URLs with query strings aren't being rendered. [novokrest] - #820 Inconsistency in displaying room features. [jcbrand] ## 3.0.0 (2017-03-05) diff --git a/spec/chatbox.js b/spec/chatbox.js index 306e853a8..75cb705f0 100644 --- a/spec/chatbox.js +++ b/spec/chatbox.js @@ -1240,6 +1240,33 @@ }); })); + it("will render images from their URLs with query strings containing HTML-escaping characters", mock.initConverse(function (_converse) { + test_utils.createContacts(_converse, 'current'); + test_utils.openControlBox(); + test_utils.openContactsPanel(_converse); + + if (/PhantomJS/.test(window.navigator.userAgent)) { + // Doesn't work when running tests in PhantomJS, since + // the page is loaded via file:/// + return; + } + var message = document.URL.split(window.location.pathname)[0] + "/logo/conversejs.svg?param1=val1¶m2=val2", + htmlEscapedMessage = message.replace(/&/g, '&'); + var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; + test_utils.openChatBoxFor(_converse, contact_jid); + var view = _converse.chatboxviews.get(contact_jid); + spyOn(view, 'sendMessage').andCallThrough(); + runs(function () { + test_utils.sendMessage(view, message); + }); + waits(500); + runs(function () { + expect(view.sendMessage).toHaveBeenCalled(); + var msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-msg-content'); + expect(msg.html()).toEqual(''); + }); + })); + it("will render the message time as configured", mock.initConverse(function (_converse) { test_utils.createContacts(_converse, 'current'); diff --git a/src/utils.js b/src/utils.js index 9469e4547..0d1b223e2 100755 --- a/src/utils.js +++ b/src/utils.js @@ -44,6 +44,18 @@ } }; + var unescapeHTML = function (htmlEscapedText) { + /* Helper method that replace HTML-escaped symbols with equivalent characters + * (e.g. transform occurrences of '&' to '&') + * + * Parameters: + * (String) htmlEscapedText: a String containing the HTML-escaped symbols. + */ + var div = document.createElement('div'); + div.innerHTML = htmlEscapedText; + return div.innerText; + } + var isImage = function (url) { var deferred = new $.Deferred(); var img = new Image(); @@ -91,7 +103,7 @@ } $obj.html(x); _.forEach(list, function (url) { - isImage(url).then(function (img) { + isImage(unescapeHTML(url)).then(function (img) { var prot = url.indexOf('http://') === 0 || url.indexOf('https://') === 0 ? '' : 'http://'; var escaped_url = encodeURI(decodeURI(url)).replace(/[!'()]/g, escape).replace(/\*/g, "%2A"); var new_url = ''+ url + '';