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 + '';