diff --git a/spec/chatbox.js b/spec/chatbox.js index 3abe0f3f1..a869ad275 100644 --- a/spec/chatbox.js +++ b/spec/chatbox.js @@ -1616,6 +1616,7 @@ // See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions spyOn(_converse, 'emit'); var sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost'; + test_utils.openChatBoxFor(_converse, sender_jid); // state var msg = $msg({ diff --git a/spec/chatroom.js b/spec/chatroom.js index ebe2d4c07..1458c75d7 100644 --- a/spec/chatroom.js +++ b/spec/chatroom.js @@ -1708,9 +1708,7 @@ .c('status', {code: '172'}); _converse.connection._dataRecv(test_utils.createRequest(message)); var $chat_body = view.$('.chatroom-body'); - expect($chat_body.html().trim().indexOf( - '
This room is now no longer anonymous
' - )).not.toBe(-1); + expect($chat_body.find('.message:last').text()).toBe('This room is now no longer anonymous'); done(); }); })); diff --git a/src/converse-chatview.js b/src/converse-chatview.js index 3d7fbf947..7933f9775 100644 --- a/src/converse-chatview.js +++ b/src/converse-chatview.js @@ -13,15 +13,16 @@ "converse-chatboxes", "emojione", "xss", + "tpl!action", "tpl!chatbox", "tpl!chatbox_head", - "tpl!new_day", - "tpl!action", "tpl!emojis", - "tpl!message", "tpl!help_message", - "tpl!toolbar", - "tpl!spinner" + "tpl!info", + "tpl!message", + "tpl!new_day", + "tpl!spinner", + "tpl!toolbar" ], factory); }(this, function ( $, @@ -29,15 +30,16 @@ dummy, emojione, xss, + tpl_action, tpl_chatbox, tpl_chatbox_head, - tpl_new_day, - tpl_action, tpl_emojis, - tpl_message, tpl_help_message, - tpl_toolbar, - tpl_spinner + tpl_info, + tpl_message, + tpl_new_day, + tpl_spinner, + tpl_toolbar ) { "use strict"; const { $msg, Backbone, Strophe, _, b64_sha1, moment } = converse.env; @@ -321,9 +323,7 @@ afterMessagesFetched () { this.insertIntoDOM(); this.scrollDown(); - // We only start listening for the scroll event after - // cached messages have been fetched - this.$content.on('scroll', this.markScrolled.bind(this)); + this.content.addEventListener('scroll', this.markScrolled.bind(this)); _converse.emit('afterMessagesFetched', this); }, @@ -349,18 +349,21 @@ }, clearStatusNotification () { - this.$content.find('div.chat-event').remove(); + u.removeElement(this.content.querySelector('div.chat-event')); }, showStatusNotification (message, keep_old, permanent) { if (!keep_old) { this.clearStatusNotification(); } - const $el = $('
').text(message); - if (!permanent) { - $el.addClass('chat-event'); - } - this.content.insertAdjacentElement('beforeend', $el[0]); + this.content.insertAdjacentHTML( + 'beforeend', + tpl_info({ + 'extra_classes': !permanent ? 'chat-event' : '', + 'message': message, + 'isodate': moment().format(), + 'data': '' + })); this.scrollDown(); }, @@ -391,8 +394,8 @@ * (String) date - An ISO8601 date string. */ const day_date = moment(date).startOf('day'); - const insert = prepend ? this.$content.prepend: this.$content.append; - insert.call(this.$content, tpl_new_day({ + const insert = prepend ? $(this.content).prepend: $(this.content).append; + insert.call($(this.content), tpl_new_day({ isodate: day_date.format(), datestring: day_date.format("dddd MMM Do YYYY") })); @@ -406,9 +409,9 @@ * Parameters: * (Object) attrs: An object containing the message attributes. */ - const insert = prepend ? this.$content.prepend : this.$content.append; + const insert = prepend ? $(this.content).prepend : $(this.content).append; _.flow(($el) => { - insert.call(this.$content, $el); + insert.call($(this.content), $el); return $el; }, this.scrollDown.bind(this) @@ -428,8 +431,8 @@ * attributes. */ let current_msg_date = moment(attrs.time) || moment; - const $first_msg = this.$content.find('.chat-message:first'), - first_msg_date = $first_msg.data('isodate'); + const first_msg_el = this.content.firstElementChild, + first_msg_date = first_msg_el ? first_msg_el.getAttribute('data-isodate') : null; if (!first_msg_date) { // This is the first received message, so we insert a @@ -439,7 +442,8 @@ return; } - const last_msg_date = this.$content.find('.chat-message:last').data('isodate'); + const last_msg_el = this.content.lastElementChild, + last_msg_date = last_msg_el.getAttribute('data-isodate'); if (current_msg_date.isAfter(last_msg_date) || current_msg_date.isSame(last_msg_date)) { // The new message is after the last message @@ -466,17 +470,18 @@ } // Find the correct place to position the message current_msg_date = current_msg_date.format(); - const msg_dates = _.map( - this.$content.find('.chat-message'), - (el) => $(el).data('isodate') - ); + const msg_dates = _.invokeMap( + this.content.querySelector('.message'), + Element.prototype.getAttribute, + 'data-isodate' + ) msg_dates.push(current_msg_date); msg_dates.sort(); const idx = msg_dates.indexOf(current_msg_date)-1; - const $latest_message = this.$content.find(`.chat-message[data-isodate="${msg_dates[idx]}"]:last`); + const latest_msg_el = this.content.querySelector(`.message[data-isodate="${msg_dates[idx]}"]`); _.flow(($el) => { - $el.insertAfter($latest_message); + $el.insertAfter(latest_msg_el); return $el; }, this.scrollDown.bind(this) @@ -524,7 +529,7 @@ template = tpl_message; username = attrs.sender === 'me' && __('me') || fullname; } - this.$content.find('div.chat-event').remove(); + $(this.content).find('div.chat-event').remove(); if (text.length > 8000) { text = text.substring(0, 10) + '...'; @@ -564,9 +569,9 @@ ); }); if (spinner === true) { - this.$content.append(tpl_spinner); + $(this.content).append(tpl_spinner); } else if (spinner === false) { - this.$content.find('span.spinner').remove(); + $(this.content).find('span.spinner').remove(); } return this.scrollDown(); }, @@ -589,7 +594,7 @@ this.showStatusNotification(message.get('fullname')+' '+__('has stopped typing')); } } else if (_.includes([_converse.INACTIVE, _converse.ACTIVE], message.get('chat_state'))) { - this.$content.find('div.chat-event').remove(); + $(this.content).find('div.chat-event').remove(); } else if (message.get('chat_state') === _converse.GONE) { this.showStatusNotification(message.get('fullname')+' '+__('has gone away')); } @@ -620,9 +625,16 @@ }, handleErrorMessage (message) { - const $message = $(`[data-msgid=${message.get('msgid')}]`); - if ($message.length) { - $message.after($('
').text(message.get('message'))); + const message_el = this.content.querySelector(`[data-msgid="${message.get('msgid')}"]`); + if (!_.isNull(message_el)) { + message_el.insertAdjacentHTML( + 'afterend', + tpl_info({ + 'extra_classes': 'chat-error', + 'message': message.get('message'), + 'isodate': moment().format(), + 'data': '' + })); this.scrollDown(); } }, @@ -799,7 +811,7 @@ if (ev && ev.preventDefault) { ev.preventDefault(); } const result = confirm(__("Are you sure you want to clear the messages from this chat box?")); if (result === true) { - this.$content.empty(); + this.content.innerHTML = ''; this.model.messages.reset(); this.model.messages.browserStorage._clear(); } @@ -992,8 +1004,8 @@ } let scrolled = true; const is_at_bottom = - (this.$content.scrollTop() + this.$content.innerHeight()) >= - this.$content[0].scrollHeight-10; + ($(this.content).scrollTop() + $(this.content).innerHeight()) >= + $(this.content)[0].scrollHeight-10; if (is_at_bottom) { scrolled = false; diff --git a/src/converse-dragresize.js b/src/converse-dragresize.js index f007418ba..39edbd203 100644 --- a/src/converse-dragresize.js +++ b/src/converse-dragresize.js @@ -186,7 +186,7 @@ } else { width = ""; } - this.$el[0].style.width = width; + this.el.style.width = width; this.$el.children('.box-flyout')[0].style.width = width; }, diff --git a/src/converse-muc.js b/src/converse-muc.js index aae355bca..43d339915 100644 --- a/src/converse-muc.js +++ b/src/converse-muc.js @@ -1306,7 +1306,7 @@ container_el.insertAdjacentHTML('beforeend', tpl_chatroom_form()); const form_el = container_el.querySelector('form.chatroom-form'), - fieldset_el = form_el.querySelector('fieldset:first-child'), + fieldset_el = form_el.querySelector('fieldset'), fields = stanza.querySelectorAll('field'), title = _.get(stanza.querySelector('title'), 'textContent'), instructions = _.get(stanza.querySelector('instructions'), 'textContent'); @@ -1817,7 +1817,13 @@ return; } _.each(notification.messages, (message) => { - this.content.insertAdjacentHTML('beforeend', tpl_info({'message': message, 'data': ''})); + this.content.insertAdjacentHTML( + 'beforeend', + tpl_info({ + 'data': '', + 'isodate': moment().format(), + 'message': message + })); }); if (notification.reason) { this.showStatusNotification(__('The reason given is: "%1$s".', notification.reason), true); @@ -1830,13 +1836,14 @@ displayJoinNotification (stanza) { const nick = Strophe.getResourceFromJid(stanza.getAttribute('from')); const stat = stanza.querySelector('status'); - const last_el = this.content.querySelector('.message:last-child'); + const last_el = this.content.lastElementChild; if (_.includes(_.get(last_el, 'classList', []), 'chat-info') && _.get(last_el, 'dataset', {}).leave === `"${nick}"`) { last_el.outerHTML = tpl_info({ - 'message': __(nick+' has left and re-entered the room.'), - 'data': `data-leavejoin="${nick}"` + 'data': `data-leavejoin="${nick}"`, + 'isodate': moment().format(), + 'message': __(nick+' has left and re-entered the room.') }); } else { let message = __(nick+' has entered the room.'); @@ -1844,8 +1851,9 @@ message = message + ' "' + stat.textContent + '"'; } const data = { - 'message': message, - 'data': `data-join="${nick}"` + 'data': `data-join="${nick}"`, + 'isodate': moment().format(), + 'message': message }; if (_.includes(_.get(last_el, 'classList', []), 'chat-info') && _.get(last_el, 'dataset', {}).joinleave === `"${nick}"`) { @@ -1861,7 +1869,7 @@ displayLeaveNotification (stanza) { const nick = Strophe.getResourceFromJid(stanza.getAttribute('from')); const stat = stanza.querySelector('status'); - const last_el = this.content.querySelector(':last-child'); + const last_el = this.content.lastElementChild; if (_.includes(_.get(last_el, 'classList', []), 'chat-info') && _.get(last_el, 'dataset', {}).join === `"${nick}"`) { @@ -1871,8 +1879,9 @@ } last_el.outerHTML = tpl_info({ - 'message': message, - 'data': `data-joinleave="${nick}"` + 'data': `data-joinleave="${nick}"`, + 'isodate': moment().format(), + 'message': message }); } else { let message = __('%1$s has left the room.', nick); @@ -2078,8 +2087,9 @@ this.content.insertAdjacentHTML( 'beforeend', tpl_info({ - 'message': __('Topic set by %1$s to: %2$s', sender, subject), - 'data': '' + 'data': '', + 'isodate': moment().format(), + 'message': __('Topic set by %1$s to: %2$s', sender, subject) })); this.scrollDown(); }, diff --git a/src/templates/action.html b/src/templates/action.html index c95432af8..8d5608ae5 100644 --- a/src/templates/action.html +++ b/src/templates/action.html @@ -1,4 +1,4 @@ -
+
{{{o.time}}} **{{{o.username}}} 
diff --git a/src/templates/info.html b/src/templates/info.html index f074e198c..704fd13ac 100644 --- a/src/templates/info.html +++ b/src/templates/info.html @@ -1 +1 @@ -
{{{o.message}}}
+
{{{o.message}}}