Commit 9a9eae3f authored by JC Brand's avatar JC Brand

Use esnext to auto-generate es2015 syntax

parent ac1475ed
......@@ -30,12 +30,7 @@
) {
const $ = converse.env.jQuery,
Backbone = converse.env.Backbone,
Strophe = converse.env.Strophe,
$iq = converse.env.$iq,
b64_sha1 = converse.env.b64_sha1,
sizzle = converse.env.sizzle,
_ = converse.env._;
{ Backbone, Strophe, $iq, b64_sha1, sizzle, _ } = converse.env;
converse.plugins.add('converse-bookmarks', {
overrides: {
......@@ -45,7 +40,7 @@
//
// New functions which don't exist yet can also be added.
clearSession: function () {
clearSession () {
this.__super__.clearSession.apply(this, arguments);
if (!_.isUndefined(this.bookmarks)) {
this.bookmarks.reset();
......@@ -59,20 +54,20 @@
'click .toggle-bookmark': 'toggleBookmark'
},
initialize: function () {
initialize () {
this.__super__.initialize.apply(this, arguments);
this.model.on('change:bookmarked', this.onBookmarked, this);
this.setBookmarkState();
},
generateHeadingHTML: function () {
const _converse = this.__super__._converse,
__ = _converse.__,
generateHeadingHTML () {
const { _converse } = this.__super__,
{ __ } = _converse,
html = this.__super__.generateHeadingHTML.apply(this, arguments);
if (_converse.allow_bookmarks) {
var div = document.createElement('div');
const div = document.createElement('div');
div.innerHTML = html;
var bookmark_button = tpl_chatroom_bookmark_toggle(
const bookmark_button = tpl_chatroom_bookmark_toggle(
_.assignIn(
this.model.toJSON(),
{
......@@ -80,19 +75,19 @@
bookmarked: this.model.get('bookmarked')
}
));
var close_button = div.querySelector('.close-chatbox-button');
const close_button = div.querySelector('.close-chatbox-button');
close_button.insertAdjacentHTML('afterend', bookmark_button);
return div.innerHTML;
}
return html;
},
checkForReservedNick: function () {
checkForReservedNick () {
/* Check if the user has a bookmark with a saved nickanme
* for this room, and if so use it.
* Otherwise delegate to the super method.
*/
const _converse = this.__super__._converse;
const { _converse } = this.__super__;
if (_.isUndefined(_converse.bookmarks) || !_converse.allow_bookmarks) {
return this.__super__.checkForReservedNick.apply(this, arguments);
}
......@@ -104,7 +99,7 @@
}
},
onBookmarked: function () {
onBookmarked () {
if (this.model.get('bookmarked')) {
this.$('.icon-pushpin').addClass('button-on');
} else {
......@@ -112,12 +107,12 @@
}
},
setBookmarkState: function () {
setBookmarkState () {
/* Set whether the room is bookmarked or not.
*/
var _converse = this.__super__._converse;
const { _converse } = this.__super__;
if (!_.isUndefined(_converse.bookmarks)) {
var models = _converse.bookmarks.where({'jid': this.model.get('jid')});
const models = _converse.bookmarks.where({'jid': this.model.get('jid')});
if (!models.length) {
this.model.save('bookmarked', false);
} else {
......@@ -126,9 +121,9 @@
}
},
renderBookmarkForm: function () {
var _converse = this.__super__._converse,
__ = _converse.__,
renderBookmarkForm () {
const { _converse } = this.__super__,
{ __ } = _converse,
$body = this.$('.chatroom-body');
$body.children().addClass('hidden');
// Remove any existing forms
......@@ -147,10 +142,10 @@
this.$('.chatroom-form .button-cancel').on('click', this.cancelConfiguration.bind(this));
},
onBookmarkFormSubmitted: function (ev) {
onBookmarkFormSubmitted (ev) {
ev.preventDefault();
var _converse = this.__super__._converse;
var $form = $(ev.target), that = this;
const { _converse } = this.__super__;
const $form = $(ev.target), that = this;
_converse.bookmarks.createBookmark({
'jid': this.model.get('jid'),
'autojoin': $form.find('input[name="autojoin"]').prop('checked'),
......@@ -164,13 +159,13 @@
});
},
toggleBookmark: function (ev) {
toggleBookmark (ev) {
if (ev) {
ev.preventDefault();
ev.stopPropagation();
}
var _converse = this.__super__._converse;
var models = _converse.bookmarks.where({'jid': this.model.get('jid')});
const { _converse } = this.__super__;
const models = _converse.bookmarks.where({'jid': this.model.get('jid')});
if (!models.length) {
this.renderBookmarkForm();
} else {
......@@ -183,13 +178,13 @@
}
},
initialize: function () {
initialize () {
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
var _converse = this._converse,
__ = _converse.__,
___ = _converse.___;
const { _converse } = this,
{ __,
___ } = _converse;
// Configuration values for this plugin
// ====================================
......@@ -213,28 +208,28 @@
_converse.Bookmarks = Backbone.Collection.extend({
model: _converse.Bookmark,
initialize: function () {
initialize () {
this.on('add', _.flow(this.openBookmarkedRoom, this.markRoomAsBookmarked));
this.on('remove', this.markRoomAsUnbookmarked, this);
this.on('remove', this.sendBookmarkStanza, this);
var cache_key = 'converse.room-bookmarks'+_converse.bare_jid;
const cache_key = `converse.room-bookmarks${_converse.bare_jid}`;
this.fetched_flag = b64_sha1(cache_key+'fetched');
this.browserStorage = new Backbone.BrowserStorage[_converse.storage](
b64_sha1(cache_key)
);
},
openBookmarkedRoom: function (bookmark) {
openBookmarkedRoom (bookmark) {
if (bookmark.get('autojoin')) {
_converse.api.rooms.open(bookmark.get('jid'), bookmark.get('nick'));
}
return bookmark;
},
fetchBookmarks: function () {
var deferred = new $.Deferred();
var promise = deferred.promise();
fetchBookmarks () {
const deferred = new $.Deferred();
const promise = deferred.promise();
if (this.browserStorage.records.length > 0) {
this.fetch({
'success': _.bind(this.onCachedBookmarksFetched, this, deferred),
......@@ -252,17 +247,17 @@
return promise;
},
onCachedBookmarksFetched: function (deferred) {
onCachedBookmarksFetched (deferred) {
return deferred.resolve();
},
createBookmark: function (options) {
createBookmark (options) {
_converse.bookmarks.create(options);
_converse.bookmarks.sendBookmarkStanza();
},
sendBookmarkStanza: function () {
var stanza = $iq({
sendBookmarkStanza () {
let stanza = $iq({
'type': 'set',
'from': _converse.connection.jid,
})
......@@ -289,7 +284,7 @@
_converse.connection.sendIQ(stanza, null, this.onBookmarkError.bind(this));
},
onBookmarkError: function (iq) {
onBookmarkError (iq) {
_converse.log("Error while trying to add bookmark", Strophe.LogLevel.ERROR);
_converse.log(iq);
// We remove all locally cached bookmarks and fetch them
......@@ -299,8 +294,8 @@
window.alert(__("Sorry, something went wrong while trying to save your bookmark."));
},
fetchBookmarksFromServer: function (deferred) {
var stanza = $iq({
fetchBookmarksFromServer (deferred) {
const stanza = $iq({
'from': _converse.connection.jid,
'type': 'get',
}).c('pubsub', {'xmlns': Strophe.NS.PUBSUB})
......@@ -312,25 +307,25 @@
);
},
markRoomAsBookmarked: function (bookmark) {
var room = _converse.chatboxes.get(bookmark.get('jid'));
markRoomAsBookmarked (bookmark) {
const room = _converse.chatboxes.get(bookmark.get('jid'));
if (!_.isUndefined(room)) {
room.save('bookmarked', true);
}
},
markRoomAsUnbookmarked: function (bookmark) {
var room = _converse.chatboxes.get(bookmark.get('jid'));
markRoomAsUnbookmarked (bookmark) {
const room = _converse.chatboxes.get(bookmark.get('jid'));
if (!_.isUndefined(room)) {
room.save('bookmarked', false);
}
},
onBookmarksReceived: function (deferred, iq) {
var bookmarks = $(iq).find(
onBookmarksReceived (deferred, iq) {
const bookmarks = $(iq).find(
'items[node="storage:bookmarks"] item[id="current"] storage conference'
);
var that = this;
const that = this;
_.forEach(bookmarks, function (bookmark) {
that.create({
'jid': bookmark.getAttribute('jid'),
......@@ -344,7 +339,7 @@
}
},
onBookmarksReceivedError: function (deferred, iq) {
onBookmarksReceivedError (deferred, iq) {
window.sessionStorage.setItem(this.fetched_flag, true);
_converse.log('Error while fetching bookmarks', Strophe.LogLevel.ERROR);
_converse.log(iq, Strophe.LogLevel.DEBUG);
......@@ -362,13 +357,13 @@
'click .bookmarks-toggle': 'toggleBookmarksList'
},
initialize: function () {
initialize () {
this.model.on('add', this.renderBookmarkListElement, this);
this.model.on('remove', this.removeBookmarkListElement, this);
_converse.chatboxes.on('add', this.renderBookmarkListElement, this);
_converse.chatboxes.on('remove', this.renderBookmarkListElement, this);
var cachekey = 'converse.room-bookmarks'+_converse.bare_jid+'-list-model';
const cachekey = `converse.room-bookmarks${_converse.bare_jid}-list-model`;
this.list_model = new _converse.BookmarksList();
this.list_model.id = cachekey;
this.list_model.browserStorage = new Backbone.BrowserStorage[_converse.storage](
......@@ -378,7 +373,7 @@
this.render();
},
render: function () {
render () {
this.$el.html(tpl_bookmarks_list({
'toggle_state': this.list_model.get('toggle-state'),
'desc_bookmarks': __('Click to toggle the bookmarks list'),
......@@ -388,23 +383,23 @@
this.$('.bookmarks').hide();
}
this.model.each(this.renderBookmarkListElement.bind(this));
var controlboxview = _converse.chatboxviews.get('controlbox');
const controlboxview = _converse.chatboxviews.get('controlbox');
if (!_.isUndefined(controlboxview)) {
this.$el.prependTo(controlboxview.$('#chatrooms'));
}
return this.$el;
},
removeBookmark: function (ev) {
removeBookmark (ev) {
ev.preventDefault();
var name = $(ev.target).data('bookmarkName');
var jid = $(ev.target).data('roomJid');
const name = $(ev.target).data('bookmarkName');
const jid = $(ev.target).data('roomJid');
if (confirm(__(___("Are you sure you want to remove the bookmark \"%1$s\"?"), name))) {
_.invokeMap(_converse.bookmarks.where({'jid': jid}), Backbone.Model.prototype.destroy);
}
},
renderBookmarkListElement: function (item) {
renderBookmarkListElement (item) {
if (item instanceof _converse.ChatBox) {
item = _.head(this.model.where({'jid': item.get('jid')}));
if (_.isNil(item)) {
......@@ -421,8 +416,8 @@
return;
}
var list_el = this.el.querySelector('.bookmarks');
var div = document.createElement('div');
const list_el = this.el.querySelector('.bookmarks');
const div = document.createElement('div');
div.innerHTML = tpl_bookmark({
'bookmarked': true,
'info_leave_room': __('Leave this room'),
......@@ -433,8 +428,8 @@
'name': item.get('name'),
'open_title': __('Click to open this room')
});
var el = _.head(sizzle(
'.available-chatroom[data-room-jid="'+item.get('jid')+'"]',
const el = _.head(sizzle(
`.available-chatroom[data-room-jid="${item.get('jid')}"]`,
list_el));
if (el) {
......@@ -445,19 +440,19 @@
this.show();
},
show: function () {
show () {
if (!this.$el.is(':visible')) {
this.$el.show();
}
},
hide: function () {
hide () {
this.$el.hide();
},
removeBookmarkListElement: function (item) {
var list_el = this.el.querySelector('.bookmarks');
var el = _.head(sizzle('.available-chatroom[data-room-jid="'+item.get('jid')+'"]', list_el));
removeBookmarkListElement (item) {
const list_el = this.el.querySelector('.bookmarks');
const el = _.head(sizzle(`.available-chatroom[data-room-jid="${item.get('jid')}"]`, list_el));
if (el) {
list_el.removeChild(el);
}
......@@ -466,9 +461,9 @@
}
},
toggleBookmarksList: function (ev) {
toggleBookmarksList (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
var $el = $(ev.target);
const $el = $(ev.target);
if ($el.hasClass("icon-opened")) {
this.$('.bookmarks').slideUp('fast');
this.list_model.save({'toggle-state': _converse.CLOSED});
......@@ -481,7 +476,7 @@
}
});
var initBookmarks = function () {
const initBookmarks = function () {
if (!_converse.allow_bookmarks) {
return;
}
......@@ -496,7 +491,7 @@
$.when(_converse.api.waitUntil('chatBoxesFetched'),
_converse.api.waitUntil('roomsPanelRendered')).then(initBookmarks);
var afterReconnection = function () {
const afterReconnection = function () {
if (!_converse.allow_bookmarks) {
return;
}
......
......@@ -31,12 +31,7 @@
) {
"use strict";
const $ = converse.env.jQuery,
$msg = converse.env.$msg,
Backbone = converse.env.Backbone,
Strophe = converse.env.Strophe,
_ = converse.env._,
moment = converse.env.moment,
utils = converse.env.utils;
{ $msg, Backbone, Strophe, _, moment, utils } = converse.env;
const KEY = {
ENTER: 13,
......@@ -54,8 +49,8 @@
// New functions which don't exist yet can also be added.
ChatBoxViews: {
onChatBoxAdded: function (item) {
const _converse = this.__super__._converse;
onChatBoxAdded (item) {
const { _converse } = this.__super__;
let view = this.get(item.get('id'));
if (!view) {
view = new _converse.ChatBoxView({model: item});
......@@ -69,12 +64,12 @@
},
initialize: function () {
initialize () {
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
const _converse = this._converse,
__ = _converse.__;
const { _converse } = this,
{ __ } = _converse;
_converse.api.settings.update({
chatview_avatar_height: 32,
......@@ -113,7 +108,7 @@
'click .new-msgs-indicator': 'viewUnreadMessages'
},
initialize: function () {
initialize () {
this.model.messages.on('add', this.onMessageAdded, this);
this.model.on('show', this.show, this);
this.model.on('destroy', this.hide, this);
......@@ -128,7 +123,7 @@
_converse.emit('chatBoxInitialized', this);
},
render: function () {
render () {
this.$el.attr('id', this.model.get('box_id'))
.html(tpl_chatbox(
_.extend(this.model.toJSON(), {
......@@ -151,7 +146,7 @@
return this.showStatusMessage();
},
afterMessagesFetched: function () {
afterMessagesFetched () {
this.insertIntoDOM();
this.scrollDown();
// We only start listening for the scroll event after
......@@ -159,7 +154,7 @@
this.$content.on('scroll', this.markScrolled.bind(this));
},
fetchMessages: function () {
fetchMessages () {
this.model.messages.fetch({
'add': true,
'success': this.afterMessagesFetched.bind(this),
......@@ -168,7 +163,7 @@
return this;
},
insertIntoDOM: function () {
insertIntoDOM () {
/* This method gets overridden in src/converse-controlbox.js if
* the controlbox plugin is active.
*/
......@@ -179,11 +174,11 @@
return this;
},
clearStatusNotification: function () {
clearStatusNotification () {
this.$content.find('div.chat-event').remove();
},
showStatusNotification: function (message, keep_old, permanent) {
showStatusNotification (message, keep_old, permanent) {
if (!keep_old) {
this.clearStatusNotification();
}
......@@ -195,19 +190,19 @@
this.scrollDown();
},
addSpinner: function () {
addSpinner () {
if (_.isNull(this.el.querySelector('.spinner'))) {
this.$content.prepend(tpl_spinner);
}
},
clearSpinner: function () {
clearSpinner () {
if (this.$content.children(':first').is('span.spinner')) {
this.$content.children(':first').remove();
}
},
insertDayIndicator: function (date, prepend) {
insertDayIndicator (date, prepend) {
/* Appends (or prepends if "prepend" is truthy) an indicator
* into the chat area, showing the day as given by the
* passed in date.
......@@ -223,7 +218,7 @@
}));
},
insertMessage: function (attrs, prepend) {
insertMessage (attrs, prepend) {
/* Helper method which appends a message (or prepends if the
* 2nd parameter is set to true) to the end of the chat box's
* content area.
......@@ -240,7 +235,7 @@
)(this.renderMessage(attrs));
},
showMessage: function (attrs) {
showMessage (attrs) {
/* Inserts a chat message into the content area of the chat box.
* Will also insert a new day indicator if the message is on a
* different day.
......@@ -291,14 +286,15 @@
}
// Find the correct place to position the message
current_msg_date = current_msg_date.format();
const msg_dates = _.map(this.$content.find('.chat-message'), function (el) {
return $(el).data('isodate');
});
const msg_dates = _.map(
this.$content.find('.chat-message'),
(el) => $(el).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_message = this.$content.find(`.chat-message[data-isodate="${msg_dates[idx]}"]:last`);
_.flow(($el) => {
$el.insertAfter($latest_message);
return $el;
......@@ -307,7 +303,7 @@
)(this.renderMessage(attrs));
},
getExtraMessageTemplateAttributes: function () {
getExtraMessageTemplateAttributes () {
/* Provides a hook for sending more attributes to the
* message template.
*
......@@ -317,11 +313,11 @@
return {};
},
getExtraMessageClasses: function (attrs) {
getExtraMessageClasses (attrs) {
return attrs.delayed && 'delayed' || '';
},
renderMessage: function (attrs) {
renderMessage (attrs) {
/* Renders a chat message based on the passed in attributes.
*
* Parameters:
......@@ -376,7 +372,7 @@
return $msg;
},
showHelpMessages: function (msgs, type, spinner) {
showHelpMessages (msgs, type, spinner) {
_.each(msgs, (msg) => {
this.$content.append($(tpl_help_message({
'type': type||'info',
......@@ -391,7 +387,7 @@
return this.scrollDown();
},
handleChatStateMessage: function (message) {
handleChatStateMessage (message) {
if (message.get('chat_state') === _converse.COMPOSING) {
if (message.get('sender') === 'me') {
this.showStatusNotification(__('Typing from another device'));
......@@ -412,11 +408,11 @@
}
},
shouldShowOnTextMessage: function () {
shouldShowOnTextMessage () {
return !this.$el.is(':visible');
},
handleTextMessage: function (message) {
handleTextMessage (message) {
this.showMessage(_.clone(message.attributes));
if (utils.isNewMessage(message) && message.get('sender') === 'me') {
// We remove the "scrolled" flag so that the chat area
......@@ -436,15 +432,15 @@
}
},
handleErrorMessage: function (message) {
const $message = $('[data-msgid='+message.get('msgid')+']');
handleErrorMessage (message) {
const $message = $(`[data-msgid=${message.get('msgid')}]`);
if ($message.length) {
$message.after($('<div class="chat-info chat-error"></div>').text(message.get('message')));
this.scrollDown();
}
},
onMessageAdded: function (message) {
onMessageAdded (message) {
/* Handler that gets called when a new message object is created.
*
* Parameters:
......@@ -467,7 +463,7 @@
});
},
createMessageStanza: function (message) {
createMessageStanza (message) {
return $msg({
from: _converse.connection.jid,
to: this.model.get('jid'),
......@@ -477,7 +473,7 @@
.c(_converse.ACTIVE, {'xmlns': Strophe.NS.CHATSTATES}).up();
},
sendMessage: function (message) {
sendMessage (message) {
/* Responsible for sending off a text message.
*
* Parameters:
......@@ -498,7 +494,7 @@
}
},
onMessageSubmitted: function (text) {
onMessageSubmitted (text) {
/* This method gets called once the user has typed a message
* and then pressed enter in a chat box.
*
......@@ -519,9 +515,9 @@
}
else if (match[1] === "help") {
const msgs = [
'<strong>/help</strong>:'+__('Show this menu')+'',
'<strong>/me</strong>:'+__('Write in the third person')+'',
'<strong>/clear</strong>:'+__('Remove messages')+''
`<strong>/help</strong>:${__('Show this menu')}`,
`<strong>/me</strong>:${__('Write in the third person')}`,
`<strong>/clear</strong>:${__('Remove messages')}`
];
this.showHelpMessages(msgs);
return;
......@@ -531,7 +527,7 @@
fullname = _.isEmpty(fullname)? _converse.bare_jid: fullname;
const message = this.model.messages.create({
fullname: fullname,
fullname,
sender: 'me',
time: moment().format(),
message: text
......@@ -539,7 +535,7 @@
this.sendMessage(message);
},
sendChatState: function () {
sendChatState () {
/* Sends a message with the status of the user in this chat session
* as taken from the 'chat_state' attribute of the chat box.
* See XEP-0085 Chat State Notifications.
......@@ -552,7 +548,7 @@
);
},
setChatState: function (state, no_save) {
setChatState (state, no_save) {
/* Mutator for setting the chat state of this chat session.
* Handles clearing of any chat state notification timeouts and
* setting new ones if necessary.
......@@ -581,7 +577,7 @@
return this;
},
keyPressed: function (ev) {
keyPressed (ev) {
/* Event handler for when a key is pressed in a chat box textarea.
*/
if (ev.keyCode === KEY.ENTER) {
......@@ -602,7 +598,7 @@
}
},
onSendButtonClicked: function(ev) {
onSendButtonClicked(ev) {
/* Event handler for when a send button is clicked in a chat box textarea.
*/
ev.preventDefault();
......@@ -618,7 +614,7 @@
this.setChatState(_converse.ACTIVE);
},
clearMessages: function (ev) {
clearMessages (ev) {
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) {
......@@ -629,7 +625,7 @@
return this;
},
insertIntoTextArea: function (value) {
insertIntoTextArea (value) {
const $textbox = this.$el.find('textarea.chat-textarea');
let existing = $textbox.val();
if (existing && (existing[existing.length-1] !== ' ')) {
......@@ -638,7 +634,7 @@
$textbox.focus().val(existing+value+' ');
},
insertEmoticon: function (ev) {
insertEmoticon (ev) {
ev.stopPropagation();
this.$el.find('.toggle-smiley ul').slideToggle(200);
let $target = $(ev.target);
......@@ -646,12 +642,12 @@
this.insertIntoTextArea($target.data('emoticon'));
},
toggleEmoticonMenu: function (ev) {
toggleEmoticonMenu (ev) {
ev.stopPropagation();
this.$el.find('.toggle-smiley ul').slideToggle(200);
},
toggleCall: function (ev) {
toggleCall (ev) {
ev.stopPropagation();
_converse.emit('callButtonClicked', {
connection: _converse.connection,
......@@ -659,7 +655,7 @@
});
},
onChatStatusChanged: function (item) {
onChatStatusChanged (item) {
const chat_status = item.get('chat_status');
let fullname = item.get('fullname');
fullname = _.isEmpty(fullname)? item.get('jid'): fullname;
......@@ -676,7 +672,7 @@
}
},
onStatusChanged: function (item) {
onStatusChanged (item) {
this.showStatusMessage();
_converse.emit('contactStatusMessageChanged', {
'contact': item.attributes,
......@@ -684,7 +680,7 @@
});
},
showStatusMessage: function (msg) {
showStatusMessage (msg) {
msg = msg || this.model.get('status');
if (_.isString(msg)) {
this.$el.find('p.user-custom-message').text(msg).attr('title', msg);
......@@ -692,7 +688,7 @@
return this;
},
close: function (ev) {
close (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
if (_converse.connection.connected) {
// Immediately sending the chat state, because the
......@@ -710,7 +706,7 @@
return this;
},
getToolbarOptions: function (options) {
getToolbarOptions (options) {
return _.extend(options || {}, {
'label_clear': __('Clear all messages'),
'label_insert_smiley': __('Insert a smiley'),
......@@ -721,7 +717,7 @@
});
},
renderToolbar: function (toolbar, options) {
renderToolbar (toolbar, options) {
if (!_converse.show_toolbar) { return; }
toolbar = toolbar || tpl_toolbar;
options = _.extend(
......@@ -732,13 +728,13 @@
return this;
},
renderAvatar: function () {
renderAvatar () {
if (!this.model.get('image')) {
return;
}
const width = _converse.chatview_avatar_width;
const height = _converse.chatview_avatar_height;
const img_src = 'data:'+this.model.get('image_type')+';base64,'+this.model.get('image'),
const img_src = `data:${this.model.get('image_type')};base64,${this.model.get('image')}`,
canvas = $(tpl_avatar({
'width': width,
'height': height
......@@ -763,19 +759,19 @@
return this;
},
focus: function () {
focus () {
this.$el.find('.chat-textarea').focus();
_converse.emit('chatBoxFocused', this);
return this;
},
hide: function () {
hide () {
this.el.classList.add('hidden');
utils.refreshWebkit();
return this;
},
afterShown: function (focus) {
afterShown (focus) {
if (utils.isPersistableModel(this.model)) {
this.model.save();
}
......@@ -786,7 +782,7 @@
}
},
_show: function (focus) {
_show (focus) {
/* Inner show method that gets debounced */
if (this.$el.is(':visible') && this.$el.css('opacity') === "1") {
if (focus) { this.focus(); }
......@@ -795,7 +791,7 @@
utils.fadeIn(this.el, _.bind(this.afterShown, this, focus));
},
show: function (focus) {
show (focus) {
if (_.isUndefined(this.debouncedShow)) {
/* We wrap the method in a debouncer and set it on the
* instance, so that we have it debounced per instance.
......@@ -807,7 +803,7 @@
return this;
},
hideNewMessagesIndicator: function () {
hideNewMessagesIndicator () {
const new_msgs_indicator = this.el.querySelector('.new-msgs-indicator');
if (!_.isNull(new_msgs_indicator)) {
new_msgs_indicator.classList.add('hidden');
......@@ -840,12 +836,12 @@
utils.safeSave(this.model, {'scrolled': scrolled});
}, 150),
viewUnreadMessages: function () {
viewUnreadMessages () {
this.model.save('scrolled', false);
this.scrollDown();
},
_scrollDown: function () {
_scrollDown () {
/* Inner method that gets debounced */
if (this.$content.is(':visible') && !this.model.get('scrolled')) {
this.$content.scrollTop(this.$content[0].scrollHeight);
......@@ -854,7 +850,7 @@
}
},
onScrolledDown: function() {
onScrolledDown() {
this.hideNewMessagesIndicator();
if (_converse.windowState !== 'hidden') {
this.model.clearUnreadMsgCounter();
......@@ -862,7 +858,7 @@
_converse.emit('chatBoxScrolledDown', {'chatbox': this.model});
},
scrollDown: function () {
scrollDown () {
if (_.isUndefined(this.debouncedScrollDown)) {
/* We wrap the method in a debouncer and set it on the
* instance, so that we have it debounced per instance.
......@@ -874,7 +870,7 @@
return this;
},
onWindowStateChanged: function (state) {
onWindowStateChanged (state) {
if (this.model.get('num_unread', 0) && !this.model.newMessageWillBeHidden()) {
this.model.clearUnreadMsgCounter();
}
......
......@@ -45,14 +45,12 @@
const USERS_PANEL_ID = 'users';
const CHATBOX_TYPE = 'chatbox';
// Strophe methods for building stanzas
const Strophe = converse.env.Strophe,
Backbone = converse.env.Backbone,
utils = converse.env.utils;
const { Strophe } = converse.env,
{ Backbone } = converse.env,
{ utils } = converse.env;
// Other necessary globals
const $ = converse.env.jQuery,
_ = converse.env._,
fp = converse.env.fp,
moment = converse.env.moment;
{ _, fp, moment } = converse.env;
converse.plugins.add('converse-controlbox', {
......@@ -64,19 +62,19 @@
//
// New functions which don't exist yet can also be added.
initChatBoxes: function () {
initChatBoxes () {
this.__super__.initChatBoxes.apply(this, arguments);
this.controlboxtoggle = new this.ControlBoxToggle();
},
initConnection: function () {
initConnection () {
this.__super__.initConnection.apply(this, arguments);
if (this.connection) {
this.addControlBox();
}
},
_tearDown: function () {
_tearDown () {
this.__super__._tearDown.apply(this, arguments);
if (this.rosterview) {
// Removes roster groups
......@@ -89,9 +87,9 @@
}
},
clearSession: function () {
clearSession () {
this.__super__.clearSession.apply(this, arguments);
var controlbox = this.chatboxes.get('controlbox');
const controlbox = this.chatboxes.get('controlbox');
if (controlbox &&
controlbox.collection &&
controlbox.collection.browserStorage) {
......@@ -100,13 +98,13 @@
},
ChatBoxes: {
chatBoxMayBeShown: function (chatbox) {
chatBoxMayBeShown (chatbox) {
return this.__super__.chatBoxMayBeShown.apply(this, arguments) &&
chatbox.get('id') !== 'controlbox';
},
onChatBoxesFetched: function (collection, resp) {
var _converse = this.__super__._converse;
onChatBoxesFetched (collection, resp) {
const { _converse } = this.__super__;
this.__super__.onChatBoxesFetched.apply(this, arguments);
if (!_.includes(_.map(collection, 'id'), 'controlbox')) {
_converse.addControlBox();
......@@ -116,10 +114,10 @@
},
ChatBoxViews: {
onChatBoxAdded: function (item) {
var _converse = this.__super__._converse;
onChatBoxAdded (item) {
const { _converse } = this.__super__;
if (item.get('box_id') === 'controlbox') {
var view = this.get(item.get('id'));
let view = this.get(item.get('id'));
if (view) {
view.model = item;
view.initialize();
......@@ -133,8 +131,8 @@
}
},
closeAllChatBoxes: function () {
var _converse = this.__super__._converse;
closeAllChatBoxes () {
const { _converse } = this.__super__;
this.each(function (view) {
if (view.model.get('id') === 'controlbox' &&
(_converse.disconnection_cause !== _converse.LOGOUT || _converse.show_controlbox_by_default)) {
......@@ -145,9 +143,9 @@
return this;
},
getChatBoxWidth: function (view) {
var _converse = this.__super__._converse;
var controlbox = this.get('controlbox');
getChatBoxWidth (view) {
const { _converse } = this.__super__;
const controlbox = this.get('controlbox');
if (view.model.get('id') === 'controlbox') {
/* We return the width of the controlbox or its toggle,
* depending on which is visible.
......@@ -165,7 +163,7 @@
ChatBox: {
initialize: function () {
initialize () {
if (this.get('id') === 'controlbox') {
this.set({'time_opened': moment(0).valueOf()});
} else {
......@@ -176,20 +174,20 @@
ChatBoxView: {
insertIntoDOM: function () {
var _converse = this.__super__._converse;
insertIntoDOM () {
const { _converse } = this.__super__;
this.$el.insertAfter(_converse.chatboxviews.get("controlbox").$el);
return this;
}
}
},
initialize: function () {
initialize () {
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
const _converse = this._converse,
__ = _converse.__;
const { _converse } = this,
{ __ } = _converse;
_converse.api.settings.update({
allow_logout: true,
......@@ -202,14 +200,14 @@
const LABEL_CONTACTS = __('Contacts');
_converse.addControlBox = function () {
return _converse.chatboxes.add({
_converse.addControlBox = () =>
_converse.chatboxes.add({
id: 'controlbox',
box_id: 'controlbox',
type: 'controlbox',
closed: !_converse.show_controlbox_by_default
});
};
})
;
_converse.ControlBoxView = _converse.ChatBoxView.extend({
tagName: 'div',
......@@ -220,7 +218,7 @@
'click ul#controlbox-tabs li a': 'switchTab',
},
initialize: function () {
initialize () {
this.$el.insertAfter(_converse.controlboxtoggle.$el);
this.model.on('change:connected', this.onConnected, this);
this.model.on('destroy', this.hide, this);
......@@ -233,7 +231,7 @@
}
},
render: function () {
render () {
if (this.model.get('connected')) {
if (_.isUndefined(this.model.get('closed'))) {
this.model.set('closed', !_converse.show_controlbox_by_default);
......@@ -260,21 +258,21 @@
return this;
},
onConnected: function () {
onConnected () {
if (this.model.get('connected')) {
this.render().insertRoster();
this.model.save();
}
},
insertRoster: function () {
insertRoster () {
/* Place the rosterview inside the "Contacts" panel.
*/
this.contactspanel.$el.append(_converse.rosterview.$el);
return this;
},
renderLoginPanel: function () {
renderLoginPanel () {
this.loginpanel = new _converse.LoginPanel({
'$parent': this.$el.find('.controlbox-panes'),
'model': this
......@@ -283,7 +281,7 @@
return this;
},
renderContactsPanel: function () {
renderContactsPanel () {
if (_.isUndefined(this.model.get('active-panel'))) {
this.model.save({'active-panel': USERS_PANEL_ID});
}
......@@ -298,7 +296,7 @@
_converse.xmppstatusview.render();
},
close: function (ev) {
close (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
if (_converse.sticky_controlbox) {
return;
......@@ -312,7 +310,7 @@
return this;
},
ensureClosedState: function () {
ensureClosedState () {
if (this.model.get('closed')) {
this.hide();
} else {
......@@ -320,7 +318,7 @@
}
},
hide: function (callback) {
hide (callback) {
if (_converse.sticky_controlbox) {
return;
}
......@@ -334,8 +332,8 @@
return this;
},
onControlBoxToggleHidden: function () {
var that = this;
onControlBoxToggleHidden () {
const that = this;
utils.fadeIn(this.el, function () {
_converse.controlboxtoggle.updateOnlineCount();
utils.refreshWebkit();
......@@ -344,17 +342,17 @@
});
},
show: function () {
show () {
_converse.controlboxtoggle.hide(
this.onControlBoxToggleHidden.bind(this)
);
return this;
},
switchTab: function (ev) {
switchTab (ev) {
// TODO: automatically focus the relevant input
if (ev && ev.preventDefault) { ev.preventDefault(); }
var $tab = $(ev.target),
const $tab = $(ev.target),
$sibling = $tab.parent().siblings('li').children('a'),
$tab_panel = $($tab.attr('href'));
$($sibling.attr('href')).addClass('hidden');
......@@ -367,7 +365,7 @@
return this;
},
showHelpMessages: function () {
showHelpMessages () {
/* Override showHelpMessages in ChatBoxView, for now do nothing.
*
* Parameters:
......@@ -386,7 +384,7 @@
'submit form#converse-login': 'authenticate'
},
initialize: function (cfg) {
initialize (cfg) {
cfg.$parent.html(this.$el.html(
tpl_login_panel({
'ANONYMOUS': _converse.ANONYMOUS,
......@@ -406,7 +404,7 @@
this.$tabs = cfg.$parent.parent().find('#controlbox-tabs');
},
render: function () {
render () {
this.$tabs.append(tpl_login_tab({label_sign_in: __('Sign in')}));
this.$el.find('input#jid').focus();
if (!this.$el.is(':visible')) {
......@@ -415,17 +413,18 @@
return this;
},
authenticate: function (ev) {
authenticate (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
var $form = $(ev.target);
const $form = $(ev.target);
if (_converse.authentication === _converse.ANONYMOUS) {
this.connect($form, _converse.jid, null);
return;
}
var $jid_input = $form.find('input[name=jid]'),
jid = $jid_input.val(),
$pw_input = $form.find('input[name=password]'),
password = $pw_input.val(),
const $jid_input = $form.find('input[name=jid]');
const $pw_input = $form.find('input[name=password]');
const password = $pw_input.val();
let jid = $jid_input.val(),
errors = false;
if (!jid) {
......@@ -446,8 +445,8 @@
return false;
},
connect: function ($form, jid, password) {
var resource;
connect ($form, jid, password) {
let resource;
if ($form) {
$form.find('input[type=submit]').hide().after('<span class="spinner login-submit"/>');
}
......@@ -463,7 +462,7 @@
_converse.connection.connect(jid, password, _converse.onConnectStatusChanged);
},
remove: function () {
remove () {
this.$tabs.empty();
this.$el.parent().empty();
}
......@@ -479,19 +478,18 @@
"click .dropdown dd ul li a": "setStatus"
},
initialize: function () {
initialize () {
this.model.on("change:status", this.updateStatusUI, this);
this.model.on("change:status_message", this.updateStatusUI, this);
this.model.on("update-status-ui", this.updateStatusUI, this);
},
render: function () {
render () {
// Replace the default dropdown with something nicer
var $select = this.$el.find('select#select-xmpp-status'),
chat_status = this.model.get('status') || 'offline',
options = $('option', $select),
$options_target,
options_list = [];
const $select = this.$el.find('select#select-xmpp-status');
const chat_status = this.model.get('status') || 'offline';
const options = $('option', $select);
const options_list = [];
this.$el.html(tpl_choose_status());
this.$el.find('#fancy-xmpp-status-select')
.html(tpl_chat_status({
......@@ -507,39 +505,39 @@
'text': this.text
}));
});
$options_target = this.$el.find("#target dd ul").hide();
const $options_target = this.$el.find("#target dd ul").hide();
$options_target.append(options_list.join(''));
$select.remove();
return this;
},
toggleOptions: function (ev) {
toggleOptions (ev) {
ev.preventDefault();
$(ev.target).parent().parent().siblings('dd').find('ul').toggle('fast');
},
renderStatusChangeForm: function (ev) {
renderStatusChangeForm (ev) {
ev.preventDefault();
var status_message = _converse.xmppstatus.get('status_message') || '';
var input = tpl_change_status_message({
const status_message = _converse.xmppstatus.get('status_message') || '';
const input = tpl_change_status_message({
'status_message': status_message,
'label_custom_status': __('Custom status'),
'label_save': __('Save')
});
var $xmppstatus = this.$el.find('.xmpp-status');
const $xmppstatus = this.$el.find('.xmpp-status');
$xmppstatus.parent().addClass('no-border');
$xmppstatus.replaceWith(input);
this.$el.find('.custom-xmpp-status').focus().focus();
},
setStatusMessage: function (ev) {
setStatusMessage (ev) {
ev.preventDefault();
this.model.setStatusMessage($(ev.target).find('input').val());
},
setStatus: function (ev) {
setStatus (ev) {
ev.preventDefault();
var $el = $(ev.currentTarget),
const $el = $(ev.currentTarget),
value = $el.attr('data-value');
if (value === 'logout') {
this.$el.find(".dropdown dd ul").hide();
......@@ -550,7 +548,7 @@
}
},
getPrettyStatus: function (stat) {
getPrettyStatus (stat) {
if (stat === 'chat') {
return __('online');
} else if (stat === 'dnd') {
......@@ -566,11 +564,11 @@
}
},
updateStatusUI: function (model) {
var stat = model.get('status');
updateStatusUI (model) {
const stat = model.get('status');
// For translators: the %1$s part gets replaced with the status
// Example, I am online
var status_message = model.get('status_message') || __("I am %1$s", this.getPrettyStatus(stat));
const status_message = model.get('status_message') || __("I am %1$s", this.getPrettyStatus(stat));
this.$el.find('#fancy-xmpp-status-select').removeClass('no-border').html(
tpl_chat_status({
'chat_status': stat,
......@@ -593,17 +591,17 @@
'click a.subscribe-to-user': 'addContactFromList'
},
initialize: function (cfg) {
initialize (cfg) {
this.parent_el = cfg.$parent[0];
this.tab_el = document.createElement('li');
_converse.chatboxes.on('change:num_unread', this.renderTab, this);
_converse.chatboxes.on('add', _.debounce(this.renderTab, 100), this);
},
render: function () {
render () {
this.renderTab();
var widgets = tpl_contacts_panel({
let widgets = tpl_contacts_panel({
label_online: __('Online'),
label_busy: __('Busy'),
label_away: __('Away'),
......@@ -620,16 +618,16 @@
}
this.el.innerHTML = widgets;
var controlbox = _converse.chatboxes.get('controlbox');
const controlbox = _converse.chatboxes.get('controlbox');
if (controlbox.get('active-panel') !== USERS_PANEL_ID) {
this.el.classList.add('hidden');
}
return this;
},
renderTab: function () {
var controlbox = _converse.chatboxes.get('controlbox');
var chats = fp.filter(_.partial(utils.isOfType, CHATBOX_TYPE), _converse.chatboxes.models);
renderTab () {
const controlbox = _converse.chatboxes.get('controlbox');
const chats = fp.filter(_.partial(utils.isOfType, CHATBOX_TYPE), _converse.chatboxes.models);
this.tab_el.innerHTML = tpl_contacts_tab({
'label_contacts': LABEL_CONTACTS,
'is_current': controlbox.get('active-panel') === USERS_PANEL_ID,
......@@ -637,7 +635,7 @@
});
},
insertIntoDOM: function () {
insertIntoDOM () {
this.parent_el.appendChild(this.render().el);
this.tabs = this.parent_el.parentNode.querySelector('#controlbox-tabs');
this.tabs.appendChild(this.tab_el);
......@@ -647,7 +645,7 @@
return this;
},
generateAddContactHTML: function () {
generateAddContactHTML () {
if (_converse.xhr_user_search) {
return tpl_search_contact({
label_contact_name: __('Contact name'),
......@@ -661,7 +659,7 @@
}
},
toggleContactForm: function (ev) {
toggleContactForm (ev) {
ev.preventDefault();
this.$el.find('.search-xmpp').toggle('fast', function () {
if ($(this).is(':visible')) {
......@@ -670,20 +668,20 @@
});
},
searchContacts: function (ev) {
searchContacts (ev) {
ev.preventDefault();
$.getJSON(_converse.xhr_user_search_url+ "?q=" + $(ev.target).find('input.username').val(), function (data) {
var $ul= $('.search-xmpp ul');
const $ul= $('.search-xmpp ul');
$ul.find('li.found-user').remove();
$ul.find('li.chat-info').remove();
if (!data.length) {
$ul.append('<li class="chat-info">'+__('No users found')+'</li>');
$ul.append(`<li class="chat-info">${__('No users found')}</li>`);
}
$(data).each(function (idx, obj) {
$ul.append(
$('<li class="found-user"></li>')
.append(
$('<a class="subscribe-to-user" href="#" title="'+__('Click to add as a chat contact')+'"></a>')
$(`<a class="subscribe-to-user" href="#" title="${__('Click to add as a chat contact')}"></a>`)
.attr('data-recipient', Strophe.getNodeFromJid(obj.id)+"@"+Strophe.getDomainFromJid(obj.id))
.text(obj.fullname)
)
......@@ -692,10 +690,10 @@
});
},
addContactFromForm: function (ev) {
addContactFromForm (ev) {
ev.preventDefault();
var $input = $(ev.target).find('input');
var jid = $input.val();
const $input = $(ev.target).find('input');
const jid = $input.val();
if (! jid) {
// this is not a valid JID
$input.addClass('error');
......@@ -705,9 +703,9 @@
$('.search-xmpp').hide();
},
addContactFromList: function (ev) {
addContactFromList (ev) {
ev.preventDefault();
var $target = $(ev.target),
const $target = $(ev.target),
jid = $target.attr('data-recipient'),
name = $target.text();
_converse.roster.addAndSubscribe(jid, name);
......@@ -728,10 +726,10 @@
'href': "#"
},
initialize: function () {
initialize () {
_converse.chatboxviews.$el.prepend(this.render());
this.updateOnlineCount();
var that = this;
const that = this;
_converse.on('initialized', function () {
_converse.roster.on("add", that.updateOnlineCount, that);
_converse.roster.on('change', that.updateOnlineCount, that);
......@@ -740,7 +738,7 @@
});
},
render: function () {
render () {
// We let the render method of ControlBoxView decide whether
// the ControlBox or the Toggle must be shown. This prevents
// artifacts (i.e. on page load the toggle is shown only to then
......@@ -756,24 +754,24 @@
if (_.isUndefined(_converse.roster)) {
return;
}
var $count = this.$('#online-count');
$count.text('('+_converse.roster.getNumOnlineContacts()+')');
const $count = this.$('#online-count');
$count.text(`(${_converse.roster.getNumOnlineContacts()})`);
if (!$count.is(':visible')) {
$count.show();
}
}, _converse.animate ? 100 : 0),
hide: function (callback) {
hide (callback) {
this.el.classList.add('hidden');
callback();
},
show: function (callback) {
show (callback) {
utils.fadeIn(this.el, callback);
},
showControlBox: function () {
var controlbox = _converse.chatboxes.get('controlbox');
showControlBox () {
let controlbox = _converse.chatboxes.get('controlbox');
if (!controlbox) {
controlbox = _converse.addControlBox();
}
......@@ -784,10 +782,10 @@
}
},
onClick: function (e) {
onClick (e) {
e.preventDefault();
if ($("div#controlbox").is(':visible')) {
var controlbox = _converse.chatboxes.get('controlbox');
const controlbox = _converse.chatboxes.get('controlbox');
if (_converse.connection.connected) {
controlbox.save({closed: true});
} else {
......@@ -799,23 +797,23 @@
}
});
var disconnect = function () {
const disconnect = function () {
/* Upon disconnection, set connected to `false`, so that if
* we reconnect,
* "onConnected" will be called, to fetch the roster again and
* to send out a presence stanza.
*/
var view = _converse.chatboxviews.get('controlbox');
const view = _converse.chatboxviews.get('controlbox');
view.model.set({connected:false});
view.$('#controlbox-tabs').empty();
view.renderLoginPanel();
};
_converse.on('disconnected', disconnect);
var afterReconnected = function () {
const afterReconnected = function () {
/* After reconnection makes sure the controlbox's is aware.
*/
var view = _converse.chatboxviews.get('controlbox');
const view = _converse.chatboxviews.get('controlbox');
if (view.model.get('connected')) {
_converse.chatboxviews.get("controlbox").onConnected();
} else {
......
......@@ -33,12 +33,9 @@
const fp = lodashConverter(_.runInContext());
// Strophe globals
const $build = Strophe.$build;
const $iq = Strophe.$iq;
const $msg = Strophe.$msg;
const $pres = Strophe.$pres;
const b64_sha1 = Strophe.SHA1.b64_sha1;
Strophe = Strophe.Strophe;
const { $build, $iq, $msg, $pres } = Strophe;
const { b64_sha1 } = Strophe.SHA1;
({ Strophe } = Strophe);
// Use Mustache style syntax for variable interpolation
/* Configuration of Lodash templates (this config is distinct to the
......@@ -146,23 +143,23 @@
}, console);
if (level === Strophe.LogLevel.ERROR) {
if (_converse.debug) {
logger.trace('ERROR: '+txt);
logger.trace(`ERROR: ${txt}`);
} else {
logger.error('ERROR: '+txt);
logger.error(`ERROR: ${txt}`);
}
} else if (level === Strophe.LogLevel.WARN) {
logger.warn('WARNING: '+txt);
logger.warn(`WARNING: ${txt}`);
} else if (level === Strophe.LogLevel.FATAL) {
if (_converse.debug) {
logger.trace('FATAL: '+txt);
logger.trace(`FATAL: ${txt}`);
} else {
logger.error('FATAL: '+txt);
logger.error(`FATAL: ${txt}`);
}
} else if (_converse.debug) {
if (level === Strophe.LogLevel.DEBUG) {
logger.debug('DEBUG: '+txt);
logger.debug(`DEBUG: ${txt}`);
} else {
logger.info('INFO: '+txt);
logger.info(`INFO: ${txt}`);
}
}
};
......@@ -318,9 +315,7 @@
return _converse.chatboxviews.get(chatbox.get('id'));
};
this.generateResource = function () {
return '/converse.js-' + Math.floor(Math.random()*139749825).toString();
};
this.generateResource = () => `/converse.js-${Math.floor(Math.random()*139749825).toString()}`;
this.sendCSI = function (stat) {
/* Send out a Chat Status Notification (XEP-0352)
......@@ -497,7 +492,7 @@
* through various states while establishing or tearing down a
* connection.
*/
_converse.log("Status changed to: "+PRETTY_CONNECTION_STATUS[status]);
_converse.log(`Status changed to: ${PRETTY_CONNECTION_STATUS[status]}`);
if (status === Strophe.Status.CONNECTED || status === Strophe.Status.ATTACHED) {
// By default we always want to send out an initial presence stanza.
_converse.send_initial_presence = true;
......@@ -533,7 +528,7 @@
} else if (status === Strophe.Status.CONNFAIL) {
_converse.giveFeedback(
__('Connection failed'), 'error',
__('An error occurred while connecting to the chat server: '+condition)
__(`An error occurred while connecting to the chat server: ${condition}`)
);
_converse.setDisconnectionCause(status, condition);
} else if (status === Strophe.Status.DISCONNECTING) {
......@@ -545,9 +540,11 @@
this.msg_counter += 1;
const unreadMsgCount = this.msg_counter;
if (document.title.search(/^Messages \(\d+\) /) === -1) {
document.title = "Messages (" + unreadMsgCount + ") " + document.title;
document.title = `Messages (${unreadMsgCount}) ${document.title}`;
} else {
document.title = document.title.replace(/^Messages \(\d+\) /, "Messages (" + unreadMsgCount + ") ");
document.title = document.title.replace(
/^Messages \(\d+\) /, `Messages (${unreadMsgCount}) `
);
}
};
......@@ -561,7 +558,7 @@
this.initStatus = function () {
const deferred = new $.Deferred();
this.xmppstatus = new this.XMPPStatus();
const id = b64_sha1('converse.xmppstatus-'+_converse.bare_jid);
const id = b64_sha1(`converse.xmppstatus-${_converse.bare_jid}`);
this.xmppstatus.id = id; // Appears to be necessary for backbone.browserStorage
this.xmppstatus.browserStorage = new Backbone.BrowserStorage[_converse.storage](id);
this.xmppstatus.fetch({
......@@ -625,7 +622,7 @@
_converse.clearMsgCounter();
}
_converse.windowState = state;
_converse.emit('windowStateChanged', {state: state});
_converse.emit('windowStateChanged', {state});
};
this.registerGlobalEventHandlers = function () {
......@@ -667,7 +664,7 @@
type: 'set'
})
.c('enable', {xmlns: Strophe.NS.CARBONS});
this.connection.addHandler(function (iq) {
this.connection.addHandler((iq) => {
if (iq.querySelectorAll('error').length > 0) {
_converse.log(
'An error occured while trying to enable message carbons.',
......@@ -676,7 +673,7 @@
this.session.save({carbons_enabled: true});
_converse.log('Message carbons have been enabled.');
}
}.bind(this), null, "iq", null, "enablecarbons");
}, null, "iq", null, "enablecarbons");
this.connection.send(carbons_iq);
};
......@@ -686,10 +683,10 @@
*/
_converse.roster = new _converse.RosterContacts();
_converse.roster.browserStorage = new Backbone.BrowserStorage.session(
b64_sha1('converse.contacts-'+_converse.bare_jid));
b64_sha1(`converse.contacts-${_converse.bare_jid}`));
_converse.rostergroups = new _converse.RosterGroups();
_converse.rostergroups.browserStorage = new Backbone.BrowserStorage.session(
b64_sha1('converse.roster.groups'+_converse.bare_jid));
b64_sha1(`converse.roster.groups${_converse.bare_jid}`));
_converse.emit('rosterInitialized');
};
......@@ -809,8 +806,8 @@
'status': '',
},
initialize: function (attributes) {
const jid = attributes.jid;
initialize (attributes) {
const { jid } = attributes;
const bare_jid = Strophe.getBareJidFromJid(jid).toLowerCase();
const resource = Strophe.getResourceFromJid(jid);
attributes.jid = bare_jid;
......@@ -822,13 +819,13 @@
'resources': resource ? {resource :0} : {},
}, attributes));
this.on('destroy', function () { this.removeFromRoster(); }.bind(this));
this.on('destroy', () => { this.removeFromRoster(); });
this.on('change:chat_status', function (item) {
_converse.emit('contactStatusChanged', item.attributes);
});
},
subscribe: function (message) {
subscribe (message) {
/* Send a presence subscription request to this roster contact
*
* Parameters:
......@@ -848,7 +845,7 @@
return this;
},
ackSubscribe: function () {
ackSubscribe () {
/* Upon receiving the presence stanza of type "subscribed",
* the user SHOULD acknowledge receipt of that subscription
* state notification by sending a presence stanza of type
......@@ -860,7 +857,7 @@
}));
},
ackUnsubscribe: function () {
ackUnsubscribe () {
/* Upon receiving the presence stanza of type "unsubscribed",
* the user SHOULD acknowledge receipt of that subscription state
* notification by sending a presence stanza of type "unsubscribe"
......@@ -873,7 +870,7 @@
this.destroy(); // Will cause removeFromRoster to be called.
},
unauthorize: function (message) {
unauthorize (message) {
/* Unauthorize this contact's presence subscription
* Parameters:
* (String) message - Optional message to send to the person being unauthorized
......@@ -882,7 +879,7 @@
return this;
},
authorize: function (message) {
authorize (message) {
/* Authorize presence subscription
* Parameters:
* (String) message - Optional message to send to the person being authorized
......@@ -895,7 +892,7 @@
return this;
},
addResource: function (presence) {
addResource (presence) {
/* Adds a new resource and it's associated attributes as taken
* from the passed in presence stanza.
*
......@@ -905,7 +902,9 @@
const jid = presence.getAttribute('from'),
chat_status = _.propertyOf(presence.querySelector('show'))('textContent') || 'online',
resource = Strophe.getResourceFromJid(jid),
delay = presence.querySelector('delay[xmlns="'+Strophe.NS.DELAY+'"]'),
delay = presence.querySelector(
`delay[xmlns="${Strophe.NS.DELAY}"]`
),
timestamp = _.isNull(delay) ? moment().format() : moment(delay.getAttribute('stamp')).format();
let priority = _.propertyOf(presence.querySelector('priority'))('textContent') || 0;
......@@ -928,7 +927,7 @@
return resources;
},
removeResource: function (resource) {
removeResource (resource) {
/* Remove the passed in resource from the contact's resources map.
*
* Also recomputes the chat_status given that there's one less
......@@ -947,7 +946,7 @@
});
},
getHighestPriorityResource: function () {
getHighestPriorityResource () {
/* Return the resource with the highest priority.
*
* If multiple resources have the same priority, take the
......@@ -966,7 +965,7 @@
}
},
removeFromRoster: function (callback) {
removeFromRoster (callback) {
/* Instruct the XMPP server to remove this contact from our roster
* Parameters:
* (Function) callback
......@@ -983,7 +982,7 @@
this.RosterContacts = Backbone.Collection.extend({
model: _converse.RosterContact,
comparator: function (contact1, contact2) {
comparator (contact1, contact2) {
const status1 = contact1.get('chat_status') || 'offline';
const status2 = contact2.get('chat_status') || 'offline';
if (_converse.STATUS_WEIGHTS[status1] === _converse.STATUS_WEIGHTS[status2]) {
......@@ -995,7 +994,7 @@
}
},
onConnected: function () {
onConnected () {
/* Called as soon as the connection has been established
* (either after initial login, or after reconnection).
*
......@@ -1005,7 +1004,7 @@
this.registerRosterXHandler();
},
registerRosterHandler: function () {
registerRosterHandler () {
/* Register a handler for roster IQ "set" stanzas, which update
* roster contacts.
*/
......@@ -1015,11 +1014,11 @@
);
},
registerRosterXHandler: function () {
registerRosterXHandler () {
/* Register a handler for RosterX message stanzas, which are
* used to suggest roster contacts to a user.
*/
var t = 0;
let t = 0;
_converse.connection.addHandler(
function (msg) {
window.setTimeout(
......@@ -1034,7 +1033,7 @@
);
},
fetchRosterContacts: function () {
fetchRosterContacts () {
/* Fetches the roster contacts, first by trying the
* sessionStorage cache, and if that's empty, then by querying
* the XMPP server.
......@@ -1045,7 +1044,7 @@
const deferred = new $.Deferred();
this.fetch({
add: true,
success: function (collection) {
success (collection) {
if (collection.length === 0) {
/* We don't have any roster contacts stored in sessionStorage,
* so lets fetch the roster from the XMPP server. We pass in
......@@ -1064,7 +1063,7 @@
return deferred.promise();
},
subscribeToSuggestedItems: function (msg) {
subscribeToSuggestedItems (msg) {
_.each(msg.querySelectorAll('item'), function (item) {
if (item.getAttribute('action') === 'add') {
_converse.roster.addAndSubscribe(
......@@ -1077,11 +1076,11 @@
return true;
},
isSelf: function (jid) {
isSelf (jid) {
return utils.isSameBareJID(jid, _converse.connection.jid);
},
addAndSubscribe: function (jid, name, groups, message, attributes) {
addAndSubscribe (jid, name, groups, message, attributes) {
/* Add a roster contact and then once we have confirmation from
* the XMPP server we subscribe to that contact's presence updates.
* Parameters:
......@@ -1099,7 +1098,7 @@
});
},
sendContactAddIQ: function (jid, name, groups, callback, errback) {
sendContactAddIQ (jid, name, groups, callback, errback) {
/* Send an IQ stanza to the XMPP server to add a new roster contact.
*
* Parameters:
......@@ -1112,12 +1111,12 @@
name = _.isEmpty(name)? jid: name;
const iq = $iq({type: 'set'})
.c('query', {xmlns: Strophe.NS.ROSTER})
.c('item', { jid: jid, name: name });
.c('item', { jid, name });
_.each(groups, function (group) { iq.c('group').t(group).up(); });
_converse.connection.sendIQ(iq, callback, errback);
},
addContact: function (jid, name, groups, attributes) {
addContact (jid, name, groups, attributes) {
/* Adds a RosterContact instance to _converse.roster and
* registers the contact on the XMPP server.
* Returns a promise which is resolved once the XMPP server has
......@@ -1133,19 +1132,19 @@
groups = groups || [];
name = _.isEmpty(name)? jid: name;
this.sendContactAddIQ(jid, name, groups,
function () {
() => {
const contact = this.create(_.assignIn({
ask: undefined,
fullname: name,
groups: groups,
jid: jid,
groups,
jid,
requesting: false,
subscription: 'none'
}, attributes), {sort: false});
deferred.resolve(contact);
}.bind(this),
},
function (err) {
alert(__("Sorry, there was an error while trying to add "+name+" as a contact."));
alert(__(`Sorry, there was an error while trying to add ${name} as a contact.`));
_converse.log(err, Strophe.LogLevel.ERROR);
deferred.resolve(err);
}
......@@ -1153,7 +1152,7 @@
return deferred.promise();
},
subscribeBack: function (bare_jid) {
subscribeBack (bare_jid) {
const contact = this.get(bare_jid);
if (contact instanceof _converse.RosterContact) {
contact.authorize().subscribe();
......@@ -1167,17 +1166,15 @@
}
},
getNumOnlineContacts: function () {
getNumOnlineContacts () {
let ignored = ['offline', 'unavailable'];
if (_converse.show_only_online_users) {
ignored = _.union(ignored, ['dnd', 'xa', 'away']);
}
return _.sum(this.models.filter(function (model) {
return !_.includes(ignored, model.get('chat_status'));
}));
return _.sum(this.models.filter((model) => !_.includes(ignored, model.get('chat_status'))));
},
onRosterPush: function (iq) {
onRosterPush (iq) {
/* Handle roster updates from the XMPP server.
* See: https://xmpp.org/rfcs/rfc6121.html#roster-syntax-actions-push
*
......@@ -1192,20 +1189,20 @@
// JID so we need to explicitly compare bare jids here.
// https://github.com/jcbrand/converse.js/issues/493
_converse.connection.send(
$iq({type: 'error', id: id, from: _converse.connection.jid})
$iq({type: 'error', id, from: _converse.connection.jid})
.c('error', {'type': 'cancel'})
.c('service-unavailable', {'xmlns': Strophe.NS.ROSTER })
);
return true;
}
_converse.connection.send($iq({type: 'result', id: id, from: _converse.connection.jid}));
const items = sizzle('query[xmlns="'+Strophe.NS.ROSTER+'"] item', iq);
_converse.connection.send($iq({type: 'result', id, from: _converse.connection.jid}));
const items = sizzle(`query[xmlns="${Strophe.NS.ROSTER}"] item`, iq);
_.each(items, this.updateContact.bind(this));
_converse.emit('rosterPush', iq);
return true;
},
fetchFromServer: function (callback) {
fetchFromServer (callback) {
/* Get the roster from the XMPP server */
const iq = $iq({type: 'get', 'id': _converse.connection.getUniqueId('roster')})
.c('query', {xmlns: Strophe.NS.ROSTER});
......@@ -1215,16 +1212,16 @@
});
},
onReceivedFromServer: function (iq) {
onReceivedFromServer (iq) {
/* An IQ stanza containing the roster has been received from
* the XMPP server.
*/
const items = sizzle('query[xmlns="'+Strophe.NS.ROSTER+'"] item', iq);
const items = sizzle(`query[xmlns="${Strophe.NS.ROSTER}"] item`, iq);
_.each(items, this.updateContact.bind(this));
_converse.emit('roster', iq);
},
updateContact: function (item) {
updateContact (item) {
/* Update or create RosterContact models based on items
* received in the IQ from the server.
*/
......@@ -1241,11 +1238,11 @@
return; // We're lazy when adding contacts.
}
this.create({
ask: ask,
ask,
fullname: item.getAttribute("name") || jid,
groups: groups,
jid: jid,
subscription: subscription
groups,
jid,
subscription
}, {sort: false});
} else {
if (subscription === "remove") {
......@@ -1256,21 +1253,21 @@
// here, we know they aren't requesting anymore.
// see docs/DEVELOPER.rst
contact.save({
subscription: subscription,
ask: ask,
subscription,
ask,
requesting: null,
groups: groups
groups
});
}
},
createRequestingContact: function (presence) {
createRequestingContact (presence) {
/* Creates a Requesting Contact.
*
* Note: this method gets completely overridden by converse-vcard.js
*/
const bare_jid = Strophe.getBareJidFromJid(presence.getAttribute('from')),
nick_el = presence.querySelector('nick[xmlns="'+Strophe.NS.NICK+'"]');
nick_el = presence.querySelector(`nick[xmlns="${Strophe.NS.NICK}"]`);
const user_data = {
jid: bare_jid,
subscription: 'none',
......@@ -1282,7 +1279,7 @@
_converse.emit('contactRequest', user_data);
},
handleIncomingSubscription: function (presence) {
handleIncomingSubscription (presence) {
const jid = presence.getAttribute('from'),
bare_jid = Strophe.getBareJidFromJid(jid),
contact = this.get(bare_jid);
......@@ -1312,7 +1309,7 @@
}
},
presenceHandler: function (presence) {
presenceHandler (presence) {
const presence_type = presence.getAttribute('type');
if (presence_type === 'error') { return true; }
......@@ -1337,7 +1334,7 @@
}
}
return;
} else if (sizzle('query[xmlns="'+Strophe.NS.MUC+'"]', presence).length) {
} else if (sizzle(`query[xmlns="${Strophe.NS.MUC}"]`, presence).length) {
return; // Ignore MUC
}
if (contact && (status_message !== contact.get('status'))) {
......@@ -1362,7 +1359,7 @@
this.RosterGroup = Backbone.Model.extend({
initialize: function (attributes) {
initialize (attributes) {
this.set(_.assignIn({
description: __('Click to hide these contacts'),
state: _converse.OPENED
......@@ -1376,7 +1373,7 @@
this.RosterGroups = Backbone.Collection.extend({
model: _converse.RosterGroup,
fetchRosterGroups: function () {
fetchRosterGroups () {
/* Fetches all the roster groups from sessionStorage.
*
* Returns a promise which resolves once the groups have been
......@@ -1395,7 +1392,7 @@
this.Message = Backbone.Model.extend({
defaults: function(){
defaults(){
return {
msgid: _converse.connection.getUniqueId()
};
......@@ -1419,10 +1416,10 @@
'url': ''
},
initialize: function () {
initialize () {
this.messages = new _converse.Messages();
this.messages.browserStorage = new Backbone.BrowserStorage[_converse.message_storage](
b64_sha1('converse.messages'+this.get('jid')+_converse.bare_jid));
b64_sha1(`converse.messages${this.get('jid')}${_converse.bare_jid}`));
this.save({
// The chat_state will be set to ACTIVE once the chat box is opened
// and we listen for change:chat_state, so shouldn't set it to ACTIVE here.
......@@ -1432,7 +1429,7 @@
});
},
getMessageAttributes: function (message, delay, original_stanza) {
getMessageAttributes (message, delay, original_stanza) {
delay = delay || message.querySelector('delay');
const type = message.getAttribute('type');
......@@ -1476,11 +1473,11 @@
};
},
createMessage: function (message, delay, original_stanza) {
createMessage (message, delay, original_stanza) {
return this.messages.create(this.getMessageAttributes.apply(this, arguments));
},
newMessageWillBeHidden: function () {
newMessageWillBeHidden () {
/* Returns a boolean to indicate whether a newly received
* message will be visible to the user or not.
*/
......@@ -1490,7 +1487,7 @@
_converse.windowState === 'hidden';
},
incrementUnreadMsgCounter: function (stanza) {
incrementUnreadMsgCounter (stanza) {
/* Given a newly received message, update the unread counter if
* necessary.
*/
......@@ -1503,11 +1500,11 @@
}
},
clearUnreadMsgCounter: function() {
clearUnreadMsgCounter() {
this.save({'num_unread': 0});
},
isScrolledUp: function () {
isScrolledUp () {
return this.get('scrolled', true);
}
});
......@@ -1515,20 +1512,20 @@
this.ChatBoxes = Backbone.Collection.extend({
comparator: 'time_opened',
model: function (attrs, options) {
model (attrs, options) {
return new _converse.ChatBox(attrs, options);
},
registerMessageHandler: function () {
registerMessageHandler () {
_converse.connection.addHandler(this.onMessage.bind(this), null, 'message', 'chat');
_converse.connection.addHandler(this.onErrorMessage.bind(this), null, 'message', 'error');
},
chatBoxMayBeShown: function (chatbox) {
chatBoxMayBeShown (chatbox) {
return true;
},
onChatBoxesFetched: function (collection) {
onChatBoxesFetched (collection) {
/* Show chat boxes upon receiving them from sessionStorage
*
* This method gets overridden entirely in src/converse-controlbox.js
......@@ -1542,9 +1539,9 @@
_converse.emit('chatBoxesFetched');
},
onConnected: function () {
onConnected () {
this.browserStorage = new Backbone.BrowserStorage[_converse.storage](
b64_sha1('converse.chatboxes-'+_converse.bare_jid));
b64_sha1(`converse.chatboxes-${_converse.bare_jid}`));
this.registerMessageHandler();
this.fetch({
add: true,
......@@ -1552,7 +1549,7 @@
});
},
onErrorMessage: function (message) {
onErrorMessage (message) {
/* Handler method for all incoming error message stanzas
*/
// TODO: we can likely just reuse "onMessage" below
......@@ -1569,7 +1566,7 @@
return true;
},
onMessage: function (message) {
onMessage (message) {
/* Handler method for all incoming single-user chat "message"
* stanzas.
*/
......@@ -1580,11 +1577,11 @@
const original_stanza = message,
to_resource = Strophe.getResourceFromJid(to_jid),
is_carbon = !_.isNull(message.querySelector('received[xmlns="'+Strophe.NS.CARBONS+'"]'));
is_carbon = !_.isNull(message.querySelector(`received[xmlns="${Strophe.NS.CARBONS}"]`));
if (_converse.filter_by_resource && (to_resource && to_resource !== _converse.resource)) {
_converse.log(
'onMessage: Ignoring incoming message intended for a different resource: '+to_jid,
`onMessage: Ignoring incoming message intended for a different resource: ${to_jid}`,
Strophe.LogLevel.INFO
);
return true;
......@@ -1593,7 +1590,7 @@
// messages, but Prosody sends headline messages with the
// wrong type ('chat'), so we need to filter them out here.
_converse.log(
"onMessage: Ignoring incoming headline message sent with type 'chat' from JID: "+from_jid,
`onMessage: Ignoring incoming headline message sent with type 'chat' from JID: ${from_jid}`,
Strophe.LogLevel.INFO
);
return true;
......@@ -1631,7 +1628,7 @@
msgid = message.getAttribute('id');
if (chatbox) {
const messages = msgid && chatbox.messages.findWhere({msgid: msgid}) || [];
const messages = msgid && chatbox.messages.findWhere({msgid}) || [];
if (_.isEmpty(messages)) {
// Only create the message when we're sure it's not a
// duplicate
......@@ -1643,7 +1640,7 @@
return true;
},
createChatBox: function (jid, attrs) {
createChatBox (jid, attrs) {
/* Creates a chat box
*
* Parameters:
......@@ -1663,7 +1660,7 @@
'url': roster_item.get('url'),
};
} else if (!_converse.allow_non_roster_messaging) {
_converse.log('Could not get roster item for JID '+bare_jid+
_converse.log(`Could not get roster item for JID ${bare_jid}`+
' and allow_non_roster_messaging is set to false',
Strophe.LogLevel.ERROR);
return;
......@@ -1678,7 +1675,7 @@
}, roster_info, attrs || {}));
},
getChatBox: function (jid, create, attrs) {
getChatBox (jid, create, attrs) {
/* Returns a chat box or optionally return a newly
* created one if one doesn't exist.
*
......@@ -1698,12 +1695,12 @@
this.ChatBoxViews = Backbone.Overview.extend({
initialize: function () {
initialize () {
this.model.on("add", this.onChatBoxAdded, this);
this.model.on("destroy", this.removeChat, this);
},
_ensureElement: function () {
_ensureElement () {
/* Override method from backbone.js
* If the #conversejs element doesn't exist, create it.
*/
......@@ -1722,18 +1719,18 @@
}
},
onChatBoxAdded: function (item) {
onChatBoxAdded (item) {
// Views aren't created here, since the core code doesn't
// contain any views. Instead, they're created in overrides in
// plugins, such as in converse-chatview.js and converse-muc.js
return this.get(item.get('id'));
},
removeChat: function (item) {
removeChat (item) {
this.remove(item.get('id'));
},
closeAllChatBoxes: function () {
closeAllChatBoxes () {
/* This method gets overridden in src/converse-controlbox.js if
* the controlbox plugin is active.
*/
......@@ -1741,15 +1738,15 @@
return this;
},
chatBoxMayBeShown: function (chatbox) {
chatBoxMayBeShown (chatbox) {
return this.model.chatBoxMayBeShown(chatbox);
},
getChatBox: function (attrs, create) {
getChatBox (attrs, create) {
let chatbox = this.model.get(attrs.jid);
if (!chatbox && create) {
chatbox = this.model.create(attrs, {
'error': function (model, response) {
'error' (model, response) {
_converse.log(response.responseText);
}
});
......@@ -1757,7 +1754,7 @@
return chatbox;
},
showChat: function (attrs) {
showChat (attrs) {
/* Find the chat box and show it (if it may be shown).
* If it doesn't exist, create it.
*/
......@@ -1771,21 +1768,21 @@
this.XMPPStatus = Backbone.Model.extend({
initialize: function () {
initialize () {
this.set({
'status' : this.getStatus()
});
this.on('change', function (item) {
this.on('change', (item) => {
if (_.has(item.changed, 'status')) {
_converse.emit('statusChanged', this.get('status'));
}
if (_.has(item.changed, 'status_message')) {
_converse.emit('statusMessageChanged', this.get('status_message'));
}
}.bind(this));
});
},
constructPresence: function (type, status_message) {
constructPresence (type, status_message) {
let presence;
type = _.isString(type) ? type : (this.get('status') || _converse.default_state);
status_message = _.isString(status_message) ? status_message : undefined;
......@@ -1815,20 +1812,20 @@
return presence;
},
sendPresence: function (type, status_message) {
sendPresence (type, status_message) {
_converse.connection.send(this.constructPresence(type, status_message));
},
setStatus: function (value) {
setStatus (value) {
this.sendPresence(value);
this.save({'status': value});
},
getStatus: function () {
getStatus () {
return this.get('status') || _converse.default_state;
},
setStatusMessage: function (status_message) {
setStatusMessage (status_message) {
this.sendPresence(this.getStatus(), status_message);
this.save({'status_message': status_message});
if (this.xhr_custom_status) {
......@@ -1855,10 +1852,10 @@
* All features are shown here: http://xmpp.org/registrar/disco-features.html
*/
model: _converse.Feature,
initialize: function () {
initialize () {
this.addClientIdentities().addClientFeatures();
this.browserStorage = new Backbone.BrowserStorage[_converse.storage](
b64_sha1('converse.features'+_converse.bare_jid)
b64_sha1(`converse.features${_converse.bare_jid}`)
);
this.on('add', this.onFeatureAdded, this);
if (this.browserStorage.records.length === 0) {
......@@ -1871,18 +1868,18 @@
}
},
onFeatureAdded: function (feature) {
onFeatureAdded (feature) {
_converse.emit('serviceDiscovered', feature);
},
addClientIdentities: function () {
addClientIdentities () {
/* See http://xmpp.org/registrar/disco-categories.html
*/
_converse.connection.disco.addIdentity('client', 'web', 'Converse.js');
return this;
},
addClientFeatures: function () {
addClientFeatures () {
/* The strophe.disco.js plugin keeps a list of features which
* it will advertise to any #info queries made to it.
*
......@@ -1898,7 +1895,7 @@
return this;
},
onItems: function (stanza) {
onItems (stanza) {
_.each(stanza.querySelectorAll('query item'), (item) => {
_converse.connection.disco.info(
item.getAttribute('jid'),
......@@ -1907,7 +1904,7 @@
});
},
onInfo: function (stanza) {
onInfo (stanza) {
if ((sizzle('identity[category=server][type=im]', stanza).length === 0) &&
(sizzle('identity[category=conference][type=text]', stanza).length === 0)) {
// This isn't an IM server component
......@@ -2175,7 +2172,7 @@
_converse.whitelisted_plugins);
_converse.pluggable.initializePlugins({
'updateSettings': function () {
'updateSettings' () {
_converse.log(
"(DEPRECATION) "+
"The `updateSettings` method has been deprecated. "+
......@@ -2213,32 +2210,32 @@
// API methods only available to plugins
_converse.api = {
'connection': {
'connected': function () {
'connected' () {
return _converse.connection && _converse.connection.connected || false;
},
'disconnect': function () {
'disconnect' () {
_converse.connection.disconnect();
},
},
'emit': function () {
'emit' () {
_converse.emit.apply(_converse, arguments);
},
'user': {
'jid': function () {
'jid' () {
return _converse.connection.jid;
},
'login': function (credentials) {
'login' (credentials) {
_converse.initConnection();
_converse.logIn(credentials);
},
'logout': function () {
'logout' () {
_converse.logOut();
},
'status': {
'get': function () {
'get' () {
return _converse.xmppstatus.get('status');
},
'set': function (value, message) {
'set' (value, message) {
const data = {'status': value};
if (!_.includes(_.keys(_converse.STATUS_WEIGHTS), value)) {
throw new Error('Invalid availability value. See https://xmpp.org/rfcs/rfc3921.html#rfc.section.2.2.2.1');
......@@ -2250,27 +2247,27 @@
_converse.xmppstatus.save(data);
},
'message': {
'get': function () {
'get' () {
return _converse.xmppstatus.get('status_message');
},
'set': function (stat) {
'set' (stat) {
_converse.xmppstatus.save({'status_message': stat});
}
}
},
},
'settings': {
'update': function (settings) {
'update' (settings) {
utils.merge(_converse.default_settings, settings);
utils.merge(_converse, settings);
utils.applyUserSettings(_converse, settings, _converse.user_settings);
},
'get': function (key) {
'get' (key) {
if (_.includes(_.keys(_converse.default_settings), key)) {
return _converse[key];
}
},
'set': function (key, val) {
'set' (key, val) {
const o = {};
if (_.isObject(key)) {
_.assignIn(_converse, _.pick(key, _.keys(_converse.default_settings)));
......@@ -2281,7 +2278,7 @@
}
},
'promises': {
'add': function (promises) {
'add' (promises) {
promises = _.isArray(promises) ? promises : [promises]
_.each(promises, function (promise) {
_converse.promises[promise] = new $.Deferred();
......@@ -2289,7 +2286,7 @@
}
},
'contacts': {
'get': function (jids) {
'get' (jids) {
const _transform = function (jid) {
const contact = _converse.roster.get(Strophe.getBareJidFromJid(jid));
if (contact) {
......@@ -2304,7 +2301,7 @@
}
return _.map(jids, _transform);
},
'add': function (jid, name) {
'add' (jid, name) {
if (!_.isString(jid) || !_.includes(jid, '@')) {
throw new TypeError('contacts.add: invalid jid');
}
......@@ -2312,7 +2309,7 @@
}
},
'chats': {
'open': function (jids, attrs) {
'open' (jids, attrs) {
if (_.isUndefined(jids)) {
_converse.log("chats.open: You need to provide at least one JID", Strophe.LogLevel.ERROR);
return null;
......@@ -2321,13 +2318,13 @@
_converse.chatboxes.getChatBox(jids, true, attrs).trigger('show')
);
}
return _.map(jids, function (jid) {
return _converse.getViewForChatBox(
return _.map(jids, (jid) =>
_converse.getViewForChatBox(
_converse.chatboxes.getChatBox(jid, true, attrs).trigger('show')
)
);
});
},
'get': function (jids) {
'get' (jids) {
if (_.isUndefined(jids)) {
const result = [];
_converse.chatboxes.each(function (chatbox) {
......@@ -2352,7 +2349,7 @@
}
},
'tokens': {
'get': function (id) {
'get' (id) {
if (!_converse.expose_rid_and_sid || _.isUndefined(_converse.connection)) {
return null;
}
......@@ -2367,7 +2364,7 @@
'once': _converse.once.bind(_converse),
'on': _converse.on.bind(_converse),
'not': _converse.off.bind(_converse),
'stanza': function (name, options, handler) {
'stanza' (name, options, handler) {
if (_.isFunction(options)) {
handler = options;
options = {};
......@@ -2385,29 +2382,29 @@
);
},
},
'waitUntil': function (name) {
'waitUntil' (name) {
const promise = _converse.promises[name];
if (_.isUndefined(promise)) {
return null;
}
return _converse.promises[name].promise();
},
'send': function (stanza) {
'send' (stanza) {
_converse.connection.send(stanza);
},
};
// The public API
return {
'initialize': function (settings, callback) {
'initialize' (settings, callback) {
return _converse.initialize(settings, callback);
},
'plugins': {
'add': function (name, plugin) {
'add' (name, plugin) {
plugin.__name__ = name;
if (!_.isUndefined(_converse.pluggable.plugins[name])) {
throw new TypeError(
'Error: plugin with name "'+name+'" has already been '+
`Error: plugin with name "${name}" has already been `+
'registered!');
} else {
_converse.pluggable.plugins[name] = plugin;
......
......@@ -17,11 +17,11 @@
}(this, function (converse, tpl_dragresize) {
"use strict";
const $ = converse.env.jQuery,
_ = converse.env._;
{ _ } = converse.env;
function renderDragResizeHandles (_converse, view) {
var flyout = view.el.querySelector('.box-flyout');
var div = document.createElement('div');
const flyout = view.el.querySelector('.box-flyout');
const div = document.createElement('div');
div.innerHTML = tpl_dragresize();
flyout.insertBefore(
div,
......@@ -52,8 +52,8 @@
//
// New functions which don't exist yet can also be added.
registerGlobalEventHandlers: function () {
var that = this;
registerGlobalEventHandlers () {
const that = this;
$(document).on('mousemove', function (ev) {
if (!that.resizing || !that.allow_dragresize) { return true; }
......@@ -64,11 +64,11 @@
$(document).on('mouseup', function (ev) {
if (!that.resizing || !that.allow_dragresize) { return true; }
ev.preventDefault();
var height = that.applyDragResistance(
const height = that.applyDragResistance(
that.resizing.chatbox.height,
that.resizing.chatbox.model.get('default_height')
);
var width = that.applyDragResistance(
const width = that.applyDragResistance(
that.resizing.chatbox.width,
that.resizing.chatbox.model.get('default_width')
);
......@@ -86,9 +86,9 @@
},
ChatBox: {
initialize: function () {
var _converse = this.__super__._converse;
var result = this.__super__.initialize.apply(this, arguments),
initialize () {
const { _converse } = this.__super__;
const result = this.__super__.initialize.apply(this, arguments),
height = this.get('height'), width = this.get('width'),
save = this.get('id') === 'controlbox' ? this.set.bind(this) : this.save.bind(this);
save({
......@@ -106,19 +106,19 @@
'mousedown .dragresize-topleft': 'onStartDiagonalResize'
},
initialize: function () {
initialize () {
$(window).on('resize', _.debounce(this.setDimensions.bind(this), 100));
this.__super__.initialize.apply(this, arguments);
},
render: function () {
var result = this.__super__.render.apply(this, arguments);
render () {
const result = this.__super__.render.apply(this, arguments);
renderDragResizeHandles(this.__super__._converse, this);
this.setWidth();
return result;
},
setWidth: function () {
setWidth () {
// If a custom width is applied (due to drag-resizing),
// then we need to set the width of the .chatbox element as well.
if (this.model.get('width')) {
......@@ -126,27 +126,27 @@
}
},
_show: function () {
_show () {
this.initDragResize().setDimensions();
this.__super__._show.apply(this, arguments);
},
initDragResize: function () {
initDragResize () {
/* Determine and store the default box size.
* We need this information for the drag-resizing feature.
*/
var _converse = this.__super__._converse;
var $flyout = this.$el.find('.box-flyout');
const { _converse } = this.__super__;
const $flyout = this.$el.find('.box-flyout');
if (_.isUndefined(this.model.get('height'))) {
var height = $flyout.height();
var width = $flyout.width();
const height = $flyout.height();
const width = $flyout.width();
this.model.set('height', height);
this.model.set('default_height', height);
this.model.set('width', width);
this.model.set('default_width', width);
}
var min_width = $flyout.css('min-width');
var min_height = $flyout.css('min-height');
const min_width = $flyout.css('min-width');
const min_height = $flyout.css('min-height');
this.model.set('min_width', min_width.endsWith('px') ? Number(min_width.replace(/px$/, '')) :0);
this.model.set('min_height', min_height.endsWith('px') ? Number(min_height.replace(/px$/, '')) :0);
// Initialize last known mouse position
......@@ -159,15 +159,15 @@
return this;
},
setDimensions: function () {
setDimensions () {
// Make sure the chat box has the right height and width.
this.adjustToViewport();
this.setChatBoxHeight(this.model.get('height'));
this.setChatBoxWidth(this.model.get('width'));
},
setChatBoxHeight: function (height) {
var _converse = this.__super__._converse;
setChatBoxHeight (height) {
const { _converse } = this.__super__;
if (height) {
height = _converse.applyDragResistance(height, this.model.get('default_height'))+'px';
} else {
......@@ -176,8 +176,8 @@
this.$el.children('.box-flyout')[0].style.height = height;
},
setChatBoxWidth: function (width) {
var _converse = this.__super__._converse;
setChatBoxWidth (width) {
const { _converse } = this.__super__;
if (width) {
width = _converse.applyDragResistance(width, this.model.get('default_width'))+'px';
} else {
......@@ -188,12 +188,12 @@
},
adjustToViewport: function () {
adjustToViewport () {
/* Event handler called when viewport gets resized. We remove
* custom width/height from chat boxes.
*/
var viewport_width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var viewport_height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
const viewport_width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
const viewport_height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
if (viewport_width <= 480) {
this.model.set('height', undefined);
this.model.set('width', undefined);
......@@ -204,8 +204,8 @@
}
},
onStartVerticalResize: function (ev) {
var _converse = this.__super__._converse;
onStartVerticalResize (ev) {
const { _converse } = this.__super__;
if (!_converse.allow_dragresize) { return true; }
// Record element attributes for mouseMove().
this.height = this.$el.children('.box-flyout').height();
......@@ -216,8 +216,8 @@
this.prev_pageY = ev.pageY;
},
onStartHorizontalResize: function (ev) {
var _converse = this.__super__._converse;
onStartHorizontalResize (ev) {
const { _converse } = this.__super__;
if (!_converse.allow_dragresize) { return true; }
this.width = this.$el.children('.box-flyout').width();
_converse.resizing = {
......@@ -227,16 +227,16 @@
this.prev_pageX = ev.pageX;
},
onStartDiagonalResize: function (ev) {
var _converse = this.__super__._converse;
onStartDiagonalResize (ev) {
const { _converse } = this.__super__;
this.onStartHorizontalResize(ev);
this.onStartVerticalResize(ev);
_converse.resizing.direction = 'topleft';
},
resizeChatBox: function (ev) {
var diff;
var _converse = this.__super__._converse;
resizeChatBox (ev) {
let diff;
const { _converse } = this.__super__;
if (_converse.resizing.direction.indexOf('top') === 0) {
diff = ev.pageY - this.prev_pageY;
if (diff) {
......@@ -263,13 +263,13 @@
'mousedown .dragresize-topleft': 'onStartDiagonalResize'
},
initialize: function () {
initialize () {
$(window).on('resize', _.debounce(this.setDimensions.bind(this), 100));
return this.__super__.initialize.apply(this, arguments);
},
render: function () {
var result = this.__super__.render.apply(this, arguments);
render () {
const result = this.__super__.render.apply(this, arguments);
renderDragResizeHandles(this.__super__._converse, this);
this.setWidth();
return result;
......@@ -283,26 +283,26 @@
'mousedown .dragresize-topleft': 'onStartDiagonalResize'
},
initialize: function () {
initialize () {
$(window).on('resize', _.debounce(this.setDimensions.bind(this), 100));
this.__super__.initialize.apply(this, arguments);
},
render: function () {
var result = this.__super__.render.apply(this, arguments);
render () {
const result = this.__super__.render.apply(this, arguments);
renderDragResizeHandles(this.__super__._converse, this);
this.setWidth();
return result;
},
renderLoginPanel: function () {
var result = this.__super__.renderLoginPanel.apply(this, arguments);
renderLoginPanel () {
const result = this.__super__.renderLoginPanel.apply(this, arguments);
this.initDragResize().setDimensions();
return result;
},
renderContactsPanel: function () {
var result = this.__super__.renderContactsPanel.apply(this, arguments);
renderContactsPanel () {
const result = this.__super__.renderContactsPanel.apply(this, arguments);
this.initDragResize().setDimensions();
return result;
}
......@@ -315,13 +315,13 @@
'mousedown .dragresize-topleft': 'onStartDiagonalResize'
},
initialize: function () {
initialize () {
$(window).on('resize', _.debounce(this.setDimensions.bind(this), 100));
this.__super__.initialize.apply(this, arguments);
},
render: function () {
var result = this.__super__.render.apply(this, arguments);
render () {
const result = this.__super__.render.apply(this, arguments);
renderDragResizeHandles(this.__super__._converse, this);
this.setWidth();
return result;
......@@ -329,11 +329,11 @@
}
},
initialize: function () {
initialize () {
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
var _converse = this._converse;
const { _converse } = this;
_converse.api.settings.update({
allow_dragresize: true,
......@@ -349,7 +349,7 @@
} else if (_.isUndefined(default_value)) {
return value;
}
var resistance = 10;
const resistance = 10;
if ((value !== default_value) &&
(Math.abs(value- default_value) < resistance)) {
return default_value;
......
......@@ -14,8 +14,7 @@
], factory);
}(this, function (converse, tpl_chatbox) {
"use strict";
const _ = converse.env._,
utils = converse.env.utils;
const { _, utils } = converse.env;
converse.plugins.add('converse-headline', {
......@@ -27,8 +26,8 @@
// New functions which don't exist yet can also be added.
ChatBoxViews: {
onChatBoxAdded: function (item) {
const _converse = this.__super__._converse;
onChatBoxAdded (item) {
const { _converse } = this.__super__;
let view = this.get(item.get('id'));
if (!view && item.get('type') === 'headline') {
view = new _converse.HeadlinesBoxView({model: item});
......@@ -41,12 +40,12 @@
}
},
initialize: function () {
initialize () {
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
const _converse = this._converse,
__ = _converse.__;
const { _converse } = this,
{ __ } = _converse;
_converse.HeadlinesBoxView = _converse.ChatBoxView.extend({
className: 'chatbox headlines',
......@@ -57,7 +56,7 @@
'keypress textarea.chat-textarea': 'keyPressed'
},
initialize: function () {
initialize () {
this.disable_mam = true; // Don't do MAM queries for this box
this.model.messages.on('add', this.onMessageAdded, this);
this.model.on('show', this.show, this);
......@@ -67,7 +66,7 @@
_converse.emit('chatBoxInitialized', this);
},
render: function () {
render () {
this.$el.attr('id', this.model.get('box_id'))
.html(tpl_chatbox(
_.extend(this.model.toJSON(), {
......
......@@ -16,19 +16,18 @@
], factory);
}(this, function (converse, tpl_brand_heading) {
"use strict";
var $ = converse.env.jQuery,
Strophe = converse.env.Strophe,
_ = converse.env._;
const $ = converse.env.jQuery,
{ Strophe, _ } = converse.env;
function createBrandHeadingElement () {
var div = document.createElement('div');
const div = document.createElement('div');
div.innerHTML = tpl_brand_heading();
return div.firstChild;
}
function isMessageToHiddenChat (_converse, message) {
var jid = Strophe.getBareJidFromJid(message.getAttribute('from'));
var model = _converse.chatboxes.get(jid);
const jid = Strophe.getBareJidFromJid(message.getAttribute('from'));
const model = _converse.chatboxes.get(jid);
if (!_.isNil(model)) {
return model.get('hidden');
}
......@@ -46,45 +45,45 @@
//
// new functions which don't exist yet can also be added.
areDesktopNotificationsEnabled: function () {
areDesktopNotificationsEnabled () {
// Call with "ignore_hidden" as true, so that it doesn't check
// if the windowState is hidden.
return this.__super__.areDesktopNotificationsEnabled.call(this, true);
},
shouldNotifyOfMessage: function (message) {
var _converse = this.__super__._converse;
var result = this.__super__.shouldNotifyOfMessage.apply(this, arguments);
shouldNotifyOfMessage (message) {
const { _converse } = this.__super__;
const result = this.__super__.shouldNotifyOfMessage.apply(this, arguments);
return result && isMessageToHiddenChat(_converse, message);
},
ControlBoxView: {
renderContactsPanel: function () {
renderContactsPanel () {
this.__super__.renderContactsPanel.apply(this, arguments);
this.el.classList.remove("fullscreen");
return this;
},
renderRegistrationPanel: function () {
renderRegistrationPanel () {
this.__super__.renderRegistrationPanel.apply(this, arguments);
var el = document.getElementById('converse-register');
const el = document.getElementById('converse-register');
el.parentNode.insertBefore(createBrandHeadingElement(), el);
return this;
},
renderLoginPanel: function () {
renderLoginPanel () {
this.__super__.renderLoginPanel.apply(this, arguments);
this.el.classList.add("fullscreen");
var el = document.getElementById('converse-login');
const el = document.getElementById('converse-login');
el.parentNode.insertBefore(createBrandHeadingElement(), el);
return this;
}
},
ChatRoomView: {
afterShown: function (focus) {
afterShown (focus) {
/* Make sure chat rooms are scrolled down when opened
*/
this.scrollDown();
......@@ -96,7 +95,7 @@
}
},
initialize: function () {
initialize () {
this._converse.api.settings.update({
chatview_avatar_height: 44,
chatview_avatar_width: 44,
......
......@@ -17,15 +17,12 @@
], factory);
}(this, function (converse) {
"use strict";
var $ = converse.env.jQuery,
Strophe = converse.env.Strophe,
$iq = converse.env.$iq,
_ = converse.env._,
moment = converse.env.moment;
const $ = converse.env.jQuery,
{ Strophe, $iq, _, moment } = converse.env;
var RSM_ATTRIBUTES = ['max', 'first', 'last', 'after', 'before', 'index', 'count'];
const RSM_ATTRIBUTES = ['max', 'first', 'last', 'after', 'before', 'index', 'count'];
// XEP-0313 Message Archive Management
var MAM_ATTRIBUTES = ['with', 'start', 'end'];
const MAM_ATTRIBUTES = ['with', 'start', 'end'];
converse.plugins.add('converse-mam', {
......@@ -37,32 +34,32 @@
// New functions which don't exist yet can also be added.
Features: {
addClientFeatures: function () {
var _converse = this.__super__._converse;
addClientFeatures () {
const { _converse } = this.__super__;
_converse.connection.disco.addFeature(Strophe.NS.MAM);
return this.__super__.addClientFeatures.apply(this, arguments);
}
},
ChatBox: {
getMessageAttributes: function ($message, $delay, original_stanza) {
var attrs = this.__super__.getMessageAttributes.apply(this, arguments);
attrs.archive_id = $(original_stanza).find('result[xmlns="'+Strophe.NS.MAM+'"]').attr('id');
getMessageAttributes ($message, $delay, original_stanza) {
const attrs = this.__super__.getMessageAttributes.apply(this, arguments);
attrs.archive_id = $(original_stanza).find(`result[xmlns="${Strophe.NS.MAM}"]`).attr('id');
return attrs;
}
},
ChatBoxView: {
render: function () {
var result = this.__super__.render.apply(this, arguments);
render () {
const result = this.__super__.render.apply(this, arguments);
if (!this.disable_mam) {
this.$content.on('scroll', _.debounce(this.onScroll.bind(this), 100));
}
return result;
},
afterMessagesFetched: function () {
var _converse = this.__super__._converse;
afterMessagesFetched () {
const { _converse } = this.__super__;
if (this.disable_mam ||
!_converse.features.findWhere({'var': Strophe.NS.MAM})) {
return this.__super__.afterMessagesFetched.apply(this, arguments);
......@@ -80,13 +77,13 @@
return this.__super__.afterMessagesFetched.apply(this, arguments);
},
fetchArchivedMessages: function (options) {
fetchArchivedMessages (options) {
/* Fetch archived chat messages from the XMPP server.
*
* Then, upon receiving them, call onMessage on the chat
* box, so that they are displayed inside it.
*/
var _converse = this.__super__._converse;
const { _converse } = this.__super__;
if (!_converse.features.findWhere({'var': Strophe.NS.MAM})) {
_converse.log(
"Attempted to fetch archived messages but this "+
......@@ -98,23 +95,25 @@
return;
}
this.addSpinner();
_converse.queryForArchivedMessages(options, function (messages) {
_converse.queryForArchivedMessages(
options,
(messages) => { // Success
this.clearSpinner();
if (messages.length) {
_.each(messages, _converse.chatboxes.onMessage.bind(_converse.chatboxes));
}
}.bind(this),
function () {
},
() => { // Error
this.clearSpinner();
_converse.log(
"Error or timeout while trying to fetch "+
"archived messages", Strophe.LogLevel.ERROR);
}.bind(this)
}
);
},
onScroll: function (ev) {
var _converse = this.__super__._converse;
onScroll (ev) {
const { _converse } = this.__super__;
if ($(ev.target).scrollTop() === 0 && this.model.messages.length) {
this.fetchArchivedMessages({
'before': this.model.messages.at(0).get('archive_id'),
......@@ -127,8 +126,8 @@
ChatRoomView: {
initialize: function () {
var _converse = this.__super__._converse;
initialize () {
const { _converse } = this.__super__;
this.__super__.initialize.apply(this, arguments);
this.model.on('change:mam_enabled', function () {
// Fetch messages again if we find out that mam has
......@@ -143,32 +142,32 @@
}, this);
},
render: function () {
var result = this.__super__.render.apply(this, arguments);
render () {
const result = this.__super__.render.apply(this, arguments);
if (!this.disable_mam) {
this.$content.on('scroll', _.debounce(this.onScroll.bind(this), 100));
}
return result;
},
handleMUCMessage: function (stanza) {
handleMUCMessage (stanza) {
/* MAM (message archive management XEP-0313) messages are
* ignored, since they're handled separately.
*/
var is_mam = $(stanza).find('[xmlns="'+Strophe.NS.MAM+'"]').length > 0;
const is_mam = $(stanza).find(`[xmlns="${Strophe.NS.MAM}"]`).length > 0;
if (is_mam) {
return true;
}
return this.__super__.handleMUCMessage.apply(this, arguments);
},
fetchArchivedMessages: function (options) {
fetchArchivedMessages (options) {
/* Fetch archived chat messages from the XMPP server.
*
* Then, upon receiving them, call onChatRoomMessage
* so that they are displayed inside it.
*/
var _converse = this.__super__._converse;
const { _converse } = this.__super__;
if (!_converse.features.findWhere({'var': Strophe.NS.MAM})) {
_converse.log(
"Attempted to fetch archived messages but this "+
......@@ -181,7 +180,7 @@
}
this.addSpinner();
var that = this;
const that = this;
_converse.api.archive.query(_.extend(options, {'groupchat': true}),
function (messages) {
that.clearSpinner();
......@@ -201,11 +200,11 @@
},
initialize: function () {
initialize () {
/* The initialize function gets called as soon as the plugin is
* loaded by Converse.js's plugin machinery.
*/
var _converse = this._converse;
const { _converse } = this;
_converse.api.settings.update({
archived_messages_page_size: '50',
......@@ -231,13 +230,13 @@
* can be called before passing it in again to this method, to
* get the next or previous page in the result set.
*/
var date, messages = [];
let date;
if (_.isFunction(options)) {
callback = options;
errback = callback;
}
var queryid = _converse.connection.getUniqueId();
var attrs = {'type':'set'};
const queryid = _converse.connection.getUniqueId();
const attrs = {'type':'set'};
if (!_.isUndefined(options) && options.groupchat) {
if (!options['with']) {
throw new Error(
......@@ -246,7 +245,7 @@
}
attrs.to = options['with'];
}
var stanza = $iq(attrs).c('query', {'xmlns':Strophe.NS.MAM, 'queryid':queryid});
const stanza = $iq(attrs).c('query', {'xmlns':Strophe.NS.MAM, 'queryid':queryid});
if (!_.isUndefined(options)) {
stanza.c('x', {'xmlns':Strophe.NS.XFORM, 'type': 'submit'})
.c('field', {'var':'FORM_TYPE', 'type': 'hidden'})
......@@ -261,7 +260,7 @@
if (date.isValid()) {
stanza.c('field', {'var':t}).c('value').t(date.format()).up().up();
} else {
throw new TypeError('archive.query: invalid date provided for: '+t);
throw new TypeError(`archive.query: invalid date provided for: ${t}`);
}
}
});
......@@ -273,8 +272,9 @@
}
}
var message_handler = _converse.connection.addHandler(function (message) {
var result = message.querySelector('result');
const messages = [];
const message_handler = _converse.connection.addHandler(function (message) {
const result = message.querySelector('result');
if (!_.isNull(result) && result.getAttribute('queryid') === queryid) {
messages.push(message);
}
......@@ -286,8 +286,8 @@
function (iq) {
_converse.connection.deleteHandler(message_handler);
if (_.isFunction(callback)) {
var set = iq.querySelector('set');
var rsm = new Strophe.RSM({xml: set});
const set = iq.querySelector('set');
const rsm = new Strophe.RSM({xml: set});
_.extend(rsm, _.pick(options, _.concat(MAM_ATTRIBUTES, ['max'])));
callback(messages, rsm);
}
......@@ -332,9 +332,9 @@
* Per JID preferences will be set in chat boxes, so it'll
* probbaly be handled elsewhere in any case.
*/
var $prefs = $(iq).find('prefs[xmlns="'+Strophe.NS.MAM+'"]');
var default_pref = $prefs.attr('default');
var stanza;
const $prefs = $(iq).find(`prefs[xmlns="${Strophe.NS.MAM}"]`);
const default_pref = $prefs.attr('default');
let stanza;
if (default_pref !== _converse.message_archiving) {
stanza = $iq({'type': 'set'}).c('prefs', {'xmlns':Strophe.NS.MAM, 'default':_converse.message_archiving});
$prefs.children().each(function (idx, child) {
......@@ -354,8 +354,8 @@
};
var onFeatureAdded = function (feature) {
var prefs = feature.get('preferences') || {};
const onFeatureAdded = function (feature) {
const prefs = feature.get('preferences') || {};
if (feature.get('var') === Strophe.NS.MAM &&
prefs['default'] !== _converse.message_archiving &&
!_.isUndefined(_converse.message_archiving) ) {
......
......@@ -26,11 +26,7 @@
"use strict";
const $ = converse.env.jQuery,
_ = converse.env._,
utils = converse.env.utils,
Backbone = converse.env.Backbone,
b64_sha1 = converse.env.b64_sha1,
moment = converse.env.moment;
{ _ , utils, Backbone, b64_sha1, moment } = converse.env;
converse.plugins.add('converse-minimize', {
overrides: {
......@@ -40,8 +36,8 @@
//
// New functions which don't exist yet can also be added.
initChatBoxes: function () {
const _converse = this.__super__._converse;
initChatBoxes () {
const { _converse } = this.__super__;
const result = this.__super__.initChatBoxes.apply(this, arguments);
_converse.minimized_chats = new _converse.MinimizedChats({
model: _converse.chatboxes
......@@ -49,8 +45,8 @@
return result;
},
registerGlobalEventHandlers: function () {
const _converse = this.__super__._converse;
registerGlobalEventHandlers () {
const { _converse } = this.__super__;
$(window).on("resize", _.debounce(function (ev) {
if (_converse.connection.connected) {
_converse.chatboxviews.trimChats();
......@@ -60,7 +56,7 @@
},
ChatBox: {
initialize: function () {
initialize () {
this.__super__.initialize.apply(this, arguments);
if (this.get('id') === 'controlbox') {
return;
......@@ -71,14 +67,14 @@
});
},
maximize: function () {
maximize () {
utils.safeSave(this, {
'minimized': false,
'time_opened': moment().valueOf()
});
},
minimize: function () {
minimize () {
utils.safeSave(this, {
'minimized': true,
'time_minimized': moment().format()
......@@ -91,13 +87,13 @@
'click .toggle-chatbox-button': 'minimize',
},
initialize: function () {
initialize () {
this.model.on('change:minimized', this.onMinimizedChanged, this);
return this.__super__.initialize.apply(this, arguments);
},
_show: function () {
const _converse = this.__super__._converse;
_show () {
const { _converse } = this.__super__;
if (!this.model.get('minimized')) {
this.__super__._show.apply(this, arguments);
_converse.chatboxviews.trimChats(this);
......@@ -106,29 +102,29 @@
}
},
isNewMessageHidden: function () {
isNewMessageHidden () {
return this.model.get('minimized') ||
this.__super__.isNewMessageHidden.apply(this, arguments);
},
shouldShowOnTextMessage: function () {
shouldShowOnTextMessage () {
return !this.model.get('minimized') &&
this.__super__.shouldShowOnTextMessage.apply(this, arguments);
},
setChatBoxHeight: function (height) {
setChatBoxHeight (height) {
if (!this.model.get('minimized')) {
return this.__super__.setChatBoxHeight.apply(this, arguments);
}
},
setChatBoxWidth: function (width) {
setChatBoxWidth (width) {
if (!this.model.get('minimized')) {
return this.__super__.setChatBoxWidth.apply(this, arguments);
}
},
onMinimizedChanged: function (item) {
onMinimizedChanged (item) {
if (item.get('minimized')) {
this.minimize();
} else {
......@@ -136,9 +132,9 @@
}
},
maximize: function () {
maximize () {
// Restores a minimized chat box
var _converse = this.__super__._converse;
const { _converse } = this.__super__;
this.$el.insertAfter(_converse.chatboxviews.get("controlbox").$el);
if (!this.model.isScrolledUp()) {
this.model.clearUnreadMsgCounter();
......@@ -148,8 +144,8 @@
return this;
},
minimize: function (ev) {
var _converse = this.__super__._converse;
minimize (ev) {
const { _converse } = this.__super__;
if (ev && ev.preventDefault) { ev.preventDefault(); }
// save the scroll position to restore it on maximize
if (this.model.collection && this.model.collection.browserStorage) {
......@@ -168,7 +164,7 @@
'click .toggle-chatbox-button': 'minimize',
},
initialize: function () {
initialize () {
this.model.on('change:minimized', function (item) {
if (item.get('minimized')) {
this.hide();
......@@ -176,68 +172,66 @@
this.maximize();
}
}, this);
var result = this.__super__.initialize.apply(this, arguments);
const result = this.__super__.initialize.apply(this, arguments);
if (this.model.get('minimized')) {
this.hide();
}
return result;
},
generateHeadingHTML: function () {
var _converse = this.__super__._converse,
__ = _converse.__;
var html = this.__super__.generateHeadingHTML.apply(this, arguments);
var div = document.createElement('div');
generateHeadingHTML () {
const { _converse } = this.__super__,
{ __ } = _converse;
const html = this.__super__.generateHeadingHTML.apply(this, arguments);
const div = document.createElement('div');
div.innerHTML = html;
var el = tpl_chatbox_minimize(
const el = tpl_chatbox_minimize(
{info_minimize: __('Minimize this chat box')}
);
var button = div.querySelector('.close-chatbox-button');
const button = div.querySelector('.close-chatbox-button');
button.insertAdjacentHTML('afterend', el);
return div.innerHTML;
}
},
ChatBoxes: {
chatBoxMayBeShown: function (chatbox) {
chatBoxMayBeShown (chatbox) {
return this.__super__.chatBoxMayBeShown.apply(this, arguments) &&
!chatbox.get('minimized');
},
},
ChatBoxViews: {
showChat: function (attrs) {
showChat (attrs) {
/* Find the chat box and show it. If it doesn't exist, create it.
*/
var chatbox = this.__super__.showChat.apply(this, arguments);
var maximize = _.isUndefined(attrs.maximize) ? true : attrs.maximize;
const chatbox = this.__super__.showChat.apply(this, arguments);
const maximize = _.isUndefined(attrs.maximize) ? true : attrs.maximize;
if (chatbox.get('minimized') && maximize) {
chatbox.maximize();
}
return chatbox;
},
getChatBoxWidth: function (view) {
getChatBoxWidth (view) {
if (!view.model.get('minimized') && view.$el.is(':visible')) {
return view.$el.outerWidth(true);
}
return 0;
},
getShownChats: function () {
return this.filter(function (view) {
getShownChats () {
return this.filter((view) =>
// The controlbox can take a while to close,
// so we need to check its state. That's why we checked
// the 'closed' state.
return (
!view.model.get('minimized') &&
!view.model.get('closed') &&
view.$el.is(':visible')
);
});
},
trimChats: function (newchat) {
trimChats (newchat) {
/* This method is called when a newly created chat box will
* be shown.
*
......@@ -245,8 +239,8 @@
* another chat box. Otherwise it minimizes the oldest chat box
* to create space.
*/
var _converse = this.__super__._converse;
var shown_chats = this.getShownChats();
const { _converse } = this.__super__;
const shown_chats = this.getShownChats();
if (_converse.no_trimming || shown_chats.length <= 1) {
return;
}
......@@ -256,23 +250,23 @@
// fullscreen. In this case we don't trim.
return;
}
var oldest_chat, boxes_width, view,
$minimized = _converse.minimized_chats.$el,
const $minimized = _converse.minimized_chats.$el,
minimized_width = _.includes(this.model.pluck('minimized'), true) ? $minimized.outerWidth(true) : 0,
new_id = newchat ? newchat.model.get('id') : null;
boxes_width = _.reduce(this.xget(new_id), function (memo, view) {
return memo + this.getChatBoxWidth(view);
}.bind(this), newchat ? newchat.$el.outerWidth(true) : 0);
const boxes_width = _.reduce(
this.xget(new_id),
(memo, view) => memo + this.getChatBoxWidth(view),
newchat ? newchat.$el.outerWidth(true) : 0);
if ((minimized_width + boxes_width) > $('body').outerWidth(true)) {
oldest_chat = this.getOldestMaximizedChat([new_id]);
const oldest_chat = this.getOldestMaximizedChat([new_id]);
if (oldest_chat) {
// We hide the chat immediately, because waiting
// for the event to fire (and letting the
// ChatBoxView hide it then) causes race
// conditions.
view = this.get(oldest_chat.get('id'));
const view = this.get(oldest_chat.get('id'));
if (view) {
view.hide();
}
......@@ -281,11 +275,11 @@
}
},
getOldestMaximizedChat: function (exclude_ids) {
getOldestMaximizedChat (exclude_ids) {
// Get oldest view (if its id is not excluded)
exclude_ids.push('controlbox');
var i = 0;
var model = this.model.sort().at(i);
let i = 0;
let model = this.model.sort().at(i);
while (_.includes(exclude_ids, model.get('id')) ||
model.get('minimized') === true) {
i++;
......@@ -300,12 +294,12 @@
},
initialize: function () {
initialize () {
/* The initialize function gets called as soon as the plugin is
* loaded by Converse.js's plugin machinery.
*/
var _converse = this._converse,
__ = _converse.__;
const { _converse } = this,
{ __ } = _converse;
// Add new HTML templates.
_converse.templates.chatbox_minimize = tpl_chatbox_minimize;
......@@ -325,12 +319,12 @@
'click .restore-chat': 'restore'
},
initialize: function () {
initialize () {
this.model.on('change:num_unread', this.render, this);
},
render: function () {
var data = _.extend(
render () {
const data = _.extend(
this.model.toJSON(),
{ 'tooltip': __('Click to restore this chat') }
);
......@@ -344,10 +338,10 @@
return this.$el.html(tpl_trimmed_chat(data));
},
close: function (ev) {
close (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
this.remove();
var view = _converse.chatboxviews.get(this.model.get('id'));
const view = _converse.chatboxviews.get(this.model.get('id'));
if (view) {
// This will call model.destroy(), removing it from the
// collection and will also emit 'chatBoxClosed'
......@@ -376,7 +370,7 @@
"click #toggle-minimized-chats": "toggle"
},
initialize: function () {
initialize () {
this.render();
this.initToggle();
this.model.on("add", this.onChanged, this);
......@@ -385,7 +379,7 @@
this.model.on('change:num_unread', this.updateUnreadMessagesCounter, this);
},
tearDown: function () {
tearDown () {
this.model.off("add", this.onChanged);
this.model.off("destroy", this.removeChat);
this.model.off("change:minimized", this.onChanged);
......@@ -393,17 +387,17 @@
return this;
},
initToggle: function () {
initToggle () {
this.toggleview = new _converse.MinimizedChatsToggleView({
model: new _converse.MinimizedChatsToggle()
});
var id = b64_sha1('converse.minchatstoggle'+_converse.bare_jid);
const id = b64_sha1(`converse.minchatstoggle${_converse.bare_jid}`);
this.toggleview.model.id = id; // Appears to be necessary for backbone.browserStorage
this.toggleview.model.browserStorage = new Backbone.BrowserStorage[_converse.storage](id);
this.toggleview.model.fetch();
},
render: function () {
render () {
if (!this.el.parentElement) {
this.el.innerHTML = tpl_chats_panel();
_converse.chatboxviews.el.appendChild(this.el);
......@@ -418,13 +412,13 @@
return this.$el;
},
toggle: function (ev) {
toggle (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
this.toggleview.model.save({'collapsed': !this.toggleview.model.get('collapsed')});
this.$('.minimized-chats-flyout').toggle();
},
onChanged: function (item) {
onChanged (item) {
if (item.get('id') === 'controlbox') {
// The ControlBox has it's own minimize toggle
return;
......@@ -436,27 +430,27 @@
}
},
addChat: function (item) {
var existing = this.get(item.get('id'));
addChat (item) {
const existing = this.get(item.get('id'));
if (existing && existing.$el.parent().length !== 0) {
return;
}
var view = new _converse.MinimizedChatBoxView({model: item});
const view = new _converse.MinimizedChatBoxView({model: item});
this.$('.minimized-chats-flyout').append(view.render());
this.add(item.get('id'), view);
this.toggleview.model.set({'num_minimized': this.keys().length});
this.render();
},
removeChat: function (item) {
removeChat (item) {
this.remove(item.get('id'));
this.toggleview.model.set({'num_minimized': this.keys().length});
this.render();
},
updateUnreadMessagesCounter: function () {
var ls = this.model.pluck('num_unread'),
count = 0, i;
updateUnreadMessagesCounter () {
const ls = this.model.pluck('num_unread');
let count = 0, i;
for (i=0; i<ls.length; i++) { count += ls[i]; }
this.toggleview.model.save({'num_unread': count});
this.render();
......@@ -476,13 +470,13 @@
_converse.MinimizedChatsToggleView = Backbone.View.extend({
el: '#toggle-minimized-chats',
initialize: function () {
initialize () {
this.model.on('change:num_minimized', this.render, this);
this.model.on('change:num_unread', this.render, this);
this.$flyout = this.$el.siblings('.minimized-chats-flyout');
},
render: function () {
render () {
this.$el.html(tpl_toggle_chats(
_.extend(this.model.toJSON(), {
'Minimized': __('Minimized')
......@@ -497,10 +491,10 @@
}
});
var renderMinimizeButton = function (view) {
const renderMinimizeButton = function (view) {
// Inserts a "minimize" button in the chatview's header
var $el = view.$el.find('.toggle-chatbox-button');
var $new_el = tpl_chatbox_minimize(
const $el = view.$el.find('.toggle-chatbox-button');
const $new_el = tpl_chatbox_minimize(
{info_minimize: __('Minimize this chat box')}
);
if ($el.length) {
......@@ -519,7 +513,7 @@
}
});
var logOut = function () {
const logOut = function () {
_converse.minimized_chats.remove();
};
_converse.on('logout', logOut);
......
......@@ -8,8 +8,7 @@
define(["converse-core", "converse-muc"], factory);
}(this, function (converse) {
"use strict";
const Backbone = converse.env.Backbone,
_ = converse.env._;
const { Backbone, _ } = converse.env;
converse.plugins.add('converse-muc-embedded', {
overrides: {
......@@ -20,12 +19,12 @@
// New functions which don't exist yet can also be added.
ChatBoxes: {
onConnected: function () {
onConnected () {
// Override to avoid storing or fetching chat boxes from session
// storage.
const _converse = this.__super__._converse;
const { _converse } = this.__super__;
this.browserStorage = new Backbone.BrowserStorage[_converse.storage](
converse.env.b64_sha1('converse.chatboxes-'+_converse.bare_jid));
converse.env.b64_sha1(`converse.chatboxes-${_converse.bare_jid}`));
this.registerMessageHandler();
/* This is disabled:
*
......@@ -39,7 +38,7 @@
},
ChatRoomView: {
insertIntoDOM: function () {
insertIntoDOM () {
if (!document.body.contains(this.el)) {
const container = document.querySelector('#converse-embedded-chat');
container.innerHTML = '';
......@@ -50,11 +49,11 @@
}
},
initialize: function () {
initialize () {
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
const _converse = this._converse;
const { _converse } = this;
if (!_.isArray(_converse.auto_join_rooms)) {
throw new Error("converse-muc-embedded: auto_join_rooms must be an Array");
}
......
......@@ -60,21 +60,8 @@
const ROOMS_PANEL_ID = 'chatrooms';
const CHATROOMS_TYPE = 'chatroom';
// Strophe methods for building stanzas
const Strophe = converse.env.Strophe,
Backbone = converse.env.Backbone,
$iq = converse.env.$iq,
$build = converse.env.$build,
$msg = converse.env.$msg,
$pres = converse.env.$pres,
b64_sha1 = converse.env.b64_sha1,
sizzle = converse.env.sizzle,
utils = converse.env.utils;
// Other necessary globals
const $ = converse.env.jQuery,
_ = converse.env._,
fp = converse.env.fp,
moment = converse.env.moment;
const { Strophe, Backbone, $iq, $build, $msg, $pres, b64_sha1, sizzle, utils, _, fp, moment } = converse.env;
const $ = converse.env.jQuery;
// Add Strophe Namespaces
Strophe.addNamespace('MUC_ADMIN', Strophe.NS.MUC + "#admin");
......@@ -134,8 +121,8 @@
//
// New functions which don't exist yet can also be added.
_tearDown: function () {
var rooms = this.chatboxes.where({'type': CHATROOMS_TYPE});
_tearDown () {
const rooms = this.chatboxes.where({'type': CHATROOMS_TYPE});
_.each(rooms, function (room) {
utils.safeSave(room, {'connection_status': ROOMSTATUS.DISCONNECTED});
});
......@@ -143,8 +130,8 @@
},
Features: {
addClientFeatures: function () {
const _converse = this.__super__._converse;
addClientFeatures () {
const { _converse } = this.__super__;
this.__super__.addClientFeatures.apply(this, arguments);
if (_converse.allow_muc_invitations) {
_converse.connection.disco.addFeature('jabber:x:conference'); // Invites
......@@ -156,8 +143,8 @@
},
ChatBoxes: {
model: function (attrs, options) {
const _converse = this.__super__._converse;
model (attrs, options) {
const { _converse } = this.__super__;
if (attrs.type == CHATROOMS_TYPE) {
return new _converse.ChatRoom(attrs, options);
} else {
......@@ -167,14 +154,14 @@
},
ControlBoxView: {
renderRoomsPanel: function () {
const _converse = this.__super__._converse;
renderRoomsPanel () {
const { _converse } = this.__super__;
this.roomspanel = new _converse.RoomsPanel({
'$parent': this.$el.find('.controlbox-panes'),
'model': new (Backbone.Model.extend({
id: b64_sha1('converse.roomspanel'+_converse.bare_jid), // Required by sessionStorage
id: b64_sha1(`converse.roomspanel${_converse.bare_jid}`), // Required by sessionStorage
browserStorage: new Backbone.BrowserStorage[_converse.storage](
b64_sha1('converse.roomspanel'+_converse.bare_jid))
b64_sha1(`converse.roomspanel${_converse.bare_jid}`))
}))()
});
this.roomspanel.insertIntoDOM().model.fetch();
......@@ -186,16 +173,16 @@
_converse.emit('roomsPanelRendered');
},
renderContactsPanel: function () {
const _converse = this.__super__._converse;
renderContactsPanel () {
const { _converse } = this.__super__;
this.__super__.renderContactsPanel.apply(this, arguments);
if (_converse.allow_muc) {
this.renderRoomsPanel();
}
},
onConnected: function () {
const _converse = this.__super__._converse;
onConnected () {
const { _converse } = this.__super__;
this.__super__.onConnected.apply(this, arguments);
if (!this.model.get('connected')) {
return;
......@@ -216,7 +203,7 @@
}
},
setMUCDomain: function (domain) {
setMUCDomain (domain) {
this.roomspanel.model.save({'muc_domain': domain});
const $server= this.$el.find('input.new-chatroom-server');
if (!$server.is(':focus')) {
......@@ -224,8 +211,8 @@
}
},
featureAdded: function (feature) {
const _converse = this.__super__._converse;
featureAdded (feature) {
const { _converse } = this.__super__;
if ((feature.get('var') === Strophe.NS.MUC) && (_converse.allow_muc)) {
this.setMUCDomain(feature.get('from'));
}
......@@ -233,8 +220,8 @@
},
ChatBoxViews: {
onChatBoxAdded: function (item) {
const _converse = this.__super__._converse;
onChatBoxAdded (item) {
const { _converse } = this.__super__;
let view = this.get(item.get('id'));
if (!view && item.get('type') === CHATROOMS_TYPE) {
view = new _converse.ChatRoomView({'model': item});
......@@ -246,13 +233,13 @@
}
},
initialize: function () {
initialize () {
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
const _converse = this._converse,
__ = _converse.__,
___ = _converse.___;
const { _converse } = this,
{ __,
___ } = _converse;
// XXX: Inside plugins, all calls to the translation machinery
// (e.g. utils.__) should only be done in the initialize function.
// If called before, we won't know what language the user wants,
......@@ -360,7 +347,7 @@
_converse.ChatRoom = _converse.ChatBox.extend({
defaults: function () {
defaults () {
return _.assign(
_.clone(_converse.ChatBox.prototype.defaults),
_.zipObject(ROOM_FEATURES, _.map(ROOM_FEATURES, _.stubFalse)),
......@@ -385,17 +372,17 @@
);
},
isUserMentioned: function (message) {
isUserMentioned (message) {
/* Returns a boolean to indicate whether the current user
* was mentioned in a message.
*
* Parameters:
* (String): The text message
*/
return (new RegExp("\\b"+this.get('nick')+"\\b")).test(message);
return (new RegExp(`\\b${this.get('nick')}\\b`)).test(message);
},
incrementUnreadMsgCounter: function (stanza) {
incrementUnreadMsgCounter (stanza) {
/* Given a newly received message, update the unread counter if
* necessary.
*
......@@ -415,7 +402,7 @@
}
},
clearUnreadMsgCounter: function() {
clearUnreadMsgCounter() {
utils.safeSave(this, {
'num_unread': 0,
'num_unread_general': 0
......@@ -445,7 +432,7 @@
'click .send-button': 'onSendButtonClicked'
},
initialize: function () {
initialize () {
this.model.messages.on('add', this.onMessageAdded, this);
this.model.on('show', this.show, this);
this.model.on('destroy', this.hide, this);
......@@ -471,7 +458,7 @@
}
},
render: function () {
render () {
this.el.setAttribute('id', this.model.get('box_id'));
this.el.innerHTML = tpl_chatroom();
this.renderHeading();
......@@ -483,12 +470,12 @@
return this;
},
renderHeading: function () {
renderHeading () {
/* Render the heading UI of the chat room. */
this.el.querySelector('.chat-head-chatroom').innerHTML = this.generateHeadingHTML();
},
renderChatArea: function () {
renderChatArea () {
/* Render the UI container in which chat room messages will
* appear.
*/
......@@ -509,20 +496,20 @@
return this;
},
createOccupantsView: function () {
createOccupantsView () {
/* Create the ChatRoomOccupantsView Backbone.View
*/
const model = new _converse.ChatRoomOccupants();
model.chatroomview = this;
this.occupantsview = new _converse.ChatRoomOccupantsView({'model': model});
const id = b64_sha1('converse.occupants'+_converse.bare_jid+this.model.get('jid'));
const id = b64_sha1(`converse.occupants${_converse.bare_jid}${this.model.get('jid')}`);
this.occupantsview.model.browserStorage = new Backbone.BrowserStorage.session(id);
this.occupantsview.render();
this.occupantsview.model.fetch({add:true});
return this;
},
insertIntoDOM: function () {
insertIntoDOM () {
if (document.querySelector('body').contains(this.el)) {
return;
}
......@@ -535,7 +522,7 @@
return this;
},
generateHeadingHTML: function () {
generateHeadingHTML () {
/* Returns the heading HTML to be rendered.
*/
return tpl_chatroom_head(
......@@ -546,7 +533,7 @@
}));
},
afterShown: function () {
afterShown () {
/* Override from converse-chatview, specifically to avoid
* the 'active' chat state from being sent out prematurely.
*
......@@ -560,7 +547,7 @@
this.occupantsview.setOccupantsHeight();
},
afterConnected: function () {
afterConnected () {
if (this.model.get('connection_status') === ROOMSTATUS.ENTERED) {
this.setChatState(_converse.ACTIVE);
this.scrollDown();
......@@ -568,7 +555,7 @@
}
},
getExtraMessageClasses: function (attrs) {
getExtraMessageClasses (attrs) {
let extra_classes = _converse.ChatBoxView.prototype
.getExtraMessageClasses.apply(this, arguments);
......@@ -581,7 +568,7 @@
return extra_classes;
},
getToolbarOptions: function () {
getToolbarOptions () {
return _.extend(
_converse.ChatBoxView.prototype.getToolbarOptions.apply(this, arguments),
{
......@@ -591,14 +578,14 @@
);
},
close: function (ev) {
close (ev) {
/* Close this chat box, which implies leaving the room as
* well.
*/
this.leave();
},
toggleOccupants: function (ev, preserve_state) {
toggleOccupants (ev, preserve_state) {
/* Show or hide the right sidebar containing the chat
* occupants (and the invite widget).
*/
......@@ -625,14 +612,14 @@
}
},
onOccupantClicked: function (ev) {
onOccupantClicked (ev) {
/* When an occupant is clicked, insert their nickname into
* the chat textarea input.
*/
this.insertIntoTextArea(ev.target.textContent);
},
requestMemberList: function (chatroom_jid, affiliation) {
requestMemberList (chatroom_jid, affiliation) {
/* Send an IQ stanza to the server, asking it for the
* member-list of this room.
*
......@@ -657,22 +644,20 @@
return deferred.promise();
},
parseMemberListIQ: function (iq) {
parseMemberListIQ (iq) {
/* Given an IQ stanza with a member list, create an array of member
* objects.
*/
return _.map(
$(iq).find('query[xmlns="'+Strophe.NS.MUC_ADMIN+'"] item'),
function (item) {
return {
$(iq).find(`query[xmlns="${Strophe.NS.MUC_ADMIN}"] item`),
(item) => ({
'jid': item.getAttribute('jid'),
'affiliation': item.getAttribute('affiliation'),
};
}
})
);
},
computeAffiliationsDelta: function (exclude_existing, remove_absentees, new_list, old_list) {
computeAffiliationsDelta (exclude_existing, remove_absentees, new_list, old_list) {
/* Given two lists of objects with 'jid', 'affiliation' and
* 'reason' properties, return a new list containing
* those objects that are new, changed or removed
......@@ -703,9 +688,10 @@
const old_jids = _.map(old_list, 'jid');
// Get the new affiliations
let delta = _.map(_.difference(new_jids, old_jids), function (jid) {
return new_list[_.indexOf(new_jids, jid)];
});
let delta = _.map(
_.difference(new_jids, old_jids),
(jid) => new_list[_.indexOf(new_jids, jid)]
);
if (!exclude_existing) {
// Get the changed affiliations
delta = delta.concat(_.filter(new_list, function (item) {
......@@ -718,14 +704,17 @@
}
if (remove_absentees) {
// Get the removed affiliations
delta = delta.concat(_.map(_.difference(old_jids, new_jids), function (jid) {
return {'jid': jid, 'affiliation': 'none'};
}));
delta = delta.concat(
_.map(
_.difference(old_jids, new_jids),
(jid) => ({'jid': jid, 'affiliation': 'none'})
)
);
}
return delta;
},
sendAffiliationIQ: function (chatroom_jid, affiliation, member) {
sendAffiliationIQ (chatroom_jid, affiliation, member) {
/* Send an IQ stanza specifying an affiliation change.
*
* Paremeters:
......@@ -749,7 +738,7 @@
return deferred;
},
setAffiliation: function (affiliation, members) {
setAffiliation (affiliation, members) {
/* Send IQ stanzas to the server to set an affiliation for
* the provided JIDs.
*
......@@ -771,13 +760,13 @@
* A promise which resolves and fails depending on the
* XMPP server response.
*/
members = _.filter(members, function (member) {
members = _.filter(members, (member) =>
// We only want those members who have the right
// affiliation (or none, which implies the provided
// one).
return _.isUndefined(member.affiliation) ||
member.affiliation === affiliation;
});
_.isUndefined(member.affiliation) ||
member.affiliation === affiliation
);
const promises = _.map(
members,
_.partial(this.sendAffiliationIQ, this.model.get('jid'), affiliation)
......@@ -785,7 +774,7 @@
return $.when.apply($, promises);
},
setAffiliations: function (members, onSuccess, onError) {
setAffiliations (members, onSuccess, onError) {
/* Send IQ stanzas to the server to modify the
* affiliations in this room.
*
......@@ -806,7 +795,7 @@
$.when.apply($, promises).done(onSuccess).fail(onError);
},
marshallAffiliationIQs: function () {
marshallAffiliationIQs () {
/* Marshall a list of IQ stanzas into a map of JIDs and
* affiliations.
*
......@@ -817,7 +806,7 @@
return _.flatMap(arguments, this.parseMemberListIQ);
},
getJidsWithAffiliations: function (affiliations) {
getJidsWithAffiliations (affiliations) {
/* Returns a map of JIDs that have the affiliations
* as provided.
*/
......@@ -832,7 +821,7 @@
return deferred.promise();
},
updateMemberLists: function (members, affiliations, deltaFunc) {
updateMemberLists (members, affiliations, deltaFunc) {
/* Fetch the lists of users with the given affiliations.
* Then compute the delta between those users and
* the passed in members, and if it exists, send the delta
......@@ -861,7 +850,7 @@
return deferred.promise();
},
directInvite: function (recipient, reason) {
directInvite (recipient, reason) {
/* Send a direct invitation as per XEP-0249
*
* Parameters:
......@@ -900,7 +889,7 @@
});
},
handleChatStateMessage: function (message) {
handleChatStateMessage (message) {
/* Override the method on the ChatBoxView base class to
* ignore <gone/> notifications in groupchats.
*
......@@ -918,7 +907,7 @@
}
},
sendChatState: function () {
sendChatState () {
/* Sends a message with the status of the user in this chat session
* as taken from the 'chat_state' attribute of the chat box.
* See XEP-0085 Chat State Notifications.
......@@ -939,7 +928,7 @@
);
},
sendChatRoomMessage: function (text) {
sendChatRoomMessage (text) {
/* Constuct a message stanza to be sent to this chat room,
* and send it to the server.
*
......@@ -960,25 +949,25 @@
sender: 'me',
time: moment().format(),
message: text,
msgid: msgid
msgid
});
},
modifyRole: function(room, nick, role, reason, onSuccess, onError) {
const item = $build("item", {nick: nick, role: role});
modifyRole(room, nick, role, reason, onSuccess, onError) {
const item = $build("item", {nick, role});
const iq = $iq({to: room, type: "set"}).c("query", {xmlns: Strophe.NS.MUC_ADMIN}).cnode(item.node);
if (reason !== null) { iq.c("reason", reason); }
return _converse.connection.sendIQ(iq.tree(), onSuccess, onError);
},
validateRoleChangeCommand: function (command, args) {
validateRoleChangeCommand (command, args) {
/* Check that a command to change a chat room user's role or
* affiliation has anough arguments.
*/
// TODO check if first argument is valid
if (args.length < 1 || args.length > 2) {
this.showStatusNotification(
__("Error: the \""+command+"\" command takes two arguments, the user's nickname and optionally a reason."),
__(`Error: the "${command}" command takes two arguments, the user's nickname and optionally a reason.`),
true
);
return false;
......@@ -986,7 +975,7 @@
return true;
},
clearChatRoomMessages: function (ev) {
clearChatRoomMessages (ev) {
/* Remove all messages from the chat room UI.
*/
if (!_.isUndefined(ev)) { ev.stopPropagation(); }
......@@ -997,11 +986,11 @@
return this;
},
onCommandError: function () {
onCommandError () {
this.showStatusNotification(__("Error: could not execute the command"), true);
},
onMessageSubmitted: function (text) {
onMessageSubmitted (text) {
/* Gets called when the user presses enter to send off a
* message in a chat room.
*
......@@ -1040,22 +1029,22 @@
break;
case 'help':
this.showHelpMessages([
'<strong>/admin</strong>: ' +__("Change user's affiliation to admin"),
'<strong>/ban</strong>: ' +__('Ban user from room'),
'<strong>/clear</strong>: ' +__('Remove messages'),
'<strong>/deop</strong>: ' +__('Change user role to occupant'),
'<strong>/help</strong>: ' +__('Show this menu'),
'<strong>/kick</strong>: ' +__('Kick user from room'),
'<strong>/me</strong>: ' +__('Write in 3rd person'),
'<strong>/member</strong>: ' +__('Grant membership to a user'),
'<strong>/mute</strong>: ' +__("Remove user's ability to post messages"),
'<strong>/nick</strong>: ' +__('Change your nickname'),
'<strong>/op</strong>: ' +__('Grant moderator role to user'),
'<strong>/owner</strong>: ' +__('Grant ownership of this room'),
'<strong>/revoke</strong>: ' +__("Revoke user's membership"),
'<strong>/subject</strong>: ' +__('Set room subject'),
'<strong>/topic</strong>: ' +__('Set room subject (alias for /subject)'),
'<strong>/voice</strong>: ' +__('Allow muted user to post messages')
`<strong>/admin</strong>: ${__("Change user's affiliation to admin")}`,
`<strong>/ban</strong>: ${__('Ban user from room')}`,
`<strong>/clear</strong>: ${__('Remove messages')}`,
`<strong>/deop</strong>: ${__('Change user role to occupant')}`,
`<strong>/help</strong>: ${__('Show this menu')}`,
`<strong>/kick</strong>: ${__('Kick user from room')}`,
`<strong>/me</strong>: ${__('Write in 3rd person')}`,
`<strong>/member</strong>: ${__('Grant membership to a user')}`,
`<strong>/mute</strong>: ${__("Remove user's ability to post messages")}`,
`<strong>/nick</strong>: ${__('Change your nickname')}`,
`<strong>/op</strong>: ${__('Grant moderator role to user')}`,
`<strong>/owner</strong>: ${__('Grant ownership of this room')}`,
`<strong>/revoke</strong>: ${__("Revoke user's membership")}`,
`<strong>/subject</strong>: ${__('Set room subject')}`,
`<strong>/topic</strong>: ${__('Set room subject (alias for /subject)')}`,
`<strong>/voice</strong>: ${__('Allow muted user to post messages')}`
]);
break;
case 'kick':
......@@ -1126,7 +1115,7 @@
}
},
handleMUCMessage: function (stanza) {
handleMUCMessage (stanza) {
/* Handler for all MUC messages sent to this chat room.
*
* Parameters:
......@@ -1146,7 +1135,7 @@
return true;
},
getRoomJIDAndNick: function (nick) {
getRoomJIDAndNick (nick) {
/* Utility method to construct the JID for the current user
* as occupant of the room.
*
......@@ -1163,10 +1152,10 @@
const room = this.model.get('jid');
const node = Strophe.getNodeFromJid(room);
const domain = Strophe.getDomainFromJid(room);
return node + "@" + domain + (nick !== null ? "/" + nick : "");
return node + "@" + domain + (nick !== null ? `/${nick}` : "");
},
registerHandlers: function () {
registerHandlers () {
/* Register presence and message handlers for this chat
* room
*/
......@@ -1184,7 +1173,7 @@
);
},
removeHandlers: function () {
removeHandlers () {
/* Remove the presence and message handlers that were
* registered for this chat room.
*/
......@@ -1199,7 +1188,7 @@
return this;
},
join: function (nick, password) {
join (nick, password) {
/* Join the chat room.
*
* Parameters:
......@@ -1229,8 +1218,8 @@
return this;
},
sendUnavailablePresence: function (exit_msg) {
var presence = $pres({
sendUnavailablePresence (exit_msg) {
const presence = $pres({
type: "unavailable",
from: _converse.connection.jid,
to: this.getRoomJIDAndNick()
......@@ -1241,7 +1230,7 @@
_converse.connection.sendPresence(presence);
},
leave: function(exit_msg) {
leave(exit_msg) {
/* Leave the chat room.
*
* Parameters:
......@@ -1262,7 +1251,7 @@
_converse.ChatBoxView.prototype.close.apply(this, arguments);
},
renderConfigurationForm: function (stanza) {
renderConfigurationForm (stanza) {
/* Renders a form given an IQ stanza containing the current
* room configuration.
*
......@@ -1295,8 +1284,8 @@
});
$form.append('<fieldset></fieldset>');
$fieldset = $form.children('fieldset:last');
$fieldset.append('<input type="submit" class="pure-button button-primary" value="'+__('Save')+'"/>');
$fieldset.append('<input type="button" class="pure-button button-cancel" value="'+__('Cancel')+'"/>');
$fieldset.append(`<input type="submit" class="pure-button button-primary" value="${__('Save')}"/>`);
$fieldset.append(`<input type="button" class="pure-button button-cancel" value="${__('Cancel')}"/>`);
$fieldset.find('input[type=button]').on('click', (ev) => {
ev.preventDefault();
this.cancelConfiguration();
......@@ -1307,7 +1296,7 @@
});
},
sendConfiguration: function(config, onSuccess, onError) {
sendConfiguration(config, onSuccess, onError) {
/* Send an IQ stanza with the room configuration.
*
* Parameters:
......@@ -1330,7 +1319,7 @@
return _converse.connection.sendIQ(iq, onSuccess, onError);
},
saveConfiguration: function (form) {
saveConfiguration (form) {
/* Submit the room configuration form by sending an IQ
* stanza to the server.
*
......@@ -1358,7 +1347,7 @@
return deferred.promise();
},
autoConfigureChatRoom: function () {
autoConfigureChatRoom () {
/* Automatically configure room based on the
* 'roomconfig' data on this view's model.
*
......@@ -1369,19 +1358,20 @@
* (XMLElement) stanza: IQ stanza from the server,
* containing the configuration.
*/
var that = this;
const that = this;
const deferred = new $.Deferred();
this.fetchRoomConfiguration().then(function (stanza) {
var configArray = [],
const configArray = [],
fields = stanza.querySelectorAll('field'),
count = fields.length,
config = that.model.get('roomconfig');
let count = fields.length;
_.each(fields, function (field) {
var fieldname = field.getAttribute('var').replace('muc#roomconfig_', ''),
type = field.getAttribute('type'),
value;
const fieldname = field.getAttribute('var').replace('muc#roomconfig_', ''),
type = field.getAttribute('type');
let value;
if (fieldname in config) {
switch (type) {
case 'boolean':
......@@ -1409,7 +1399,7 @@
return deferred;
},
cancelConfiguration: function () {
cancelConfiguration () {
/* Remove the configuration form without submitting and
* return to the chat view.
*/
......@@ -1420,7 +1410,7 @@
});
},
fetchRoomConfiguration: function (handler) {
fetchRoomConfiguration (handler) {
/* Send an IQ stanza to fetch the room configuration data.
* Returns a promise which resolves once the response IQ
* has been received.
......@@ -1445,12 +1435,12 @@
return deferred.promise();
},
getRoomFeatures: function () {
getRoomFeatures () {
/* Fetch the room disco info, parse it and then
* save it on the Backbone.Model of this chat rooms.
*/
const deferred = new $.Deferred();
var that = this;
const that = this;
_converse.connection.disco.info(this.model.get('jid'), null,
function (iq) {
/* See http://xmpp.org/extensions/xep-0045.html#disco-roominfo
......@@ -1494,7 +1484,7 @@
return deferred.promise();
},
getAndRenderConfigurationForm: function (ev) {
getAndRenderConfigurationForm (ev) {
/* Start the process of configuring a chat room, either by
* rendering a configuration form, or by auto-configuring
* based on the "roomconfig" data stored on the
......@@ -1514,7 +1504,7 @@
this.renderConfigurationForm.bind(this));
},
submitNickname: function (ev) {
submitNickname (ev) {
/* Get the nickname value from the form and then join the
* chat room with it.
*/
......@@ -1533,7 +1523,7 @@
this.join(nick);
},
checkForReservedNick: function () {
checkForReservedNick () {
/* User service-discovery to ask the XMPP server whether
* this user has a reserved nickname for this room.
* If so, we'll use that, otherwise we render the nickname
......@@ -1555,7 +1545,7 @@
return this;
},
onNickNameFound: function (iq) {
onNickNameFound (iq) {
/* We've received an IQ response from the server which
* might contain the user's reserved nickname.
* If no nickname is found we either render a form for
......@@ -1575,7 +1565,7 @@
}
},
onNickNameNotFound: function (message) {
onNickNameNotFound (message) {
if (_converse.muc_nickname_from_jid) {
// We try to enter the room with the node part of
// the user's JID.
......@@ -1585,7 +1575,7 @@
}
},
getDefaultNickName: function () {
getDefaultNickName () {
/* The default nickname (used when muc_nickname_from_jid is true)
* is the node part of the user's JID.
* We put this in a separate method so that it can be
......@@ -1594,7 +1584,7 @@
return Strophe.unescapeNode(Strophe.getNodeFromJid(_converse.bare_jid));
},
onNicknameClash: function (presence) {
onNicknameClash (presence) {
/* When the nickname is already taken, we either render a
* form for the user to choose a new nickname, or we
* try to make the nickname unique by adding an integer to
......@@ -1620,7 +1610,7 @@
}
},
renderNicknameForm: function (message) {
renderNicknameForm (message) {
/* Render a form which allows the user to choose their
* nickname.
*/
......@@ -1640,14 +1630,14 @@
this.$('.chatroom-form').on('submit', this.submitNickname.bind(this));
},
submitPassword: function (ev) {
submitPassword (ev) {
ev.preventDefault();
const password = this.$el.find('.chatroom-form').find('input[type=password]').val();
this.$el.find('.chatroom-form-container').replaceWith(tpl_spinner);
this.join(this.model.get('nick'), password);
},
renderPasswordForm: function () {
renderPasswordForm () {
this.$('.chatroom-body').children().addClass('hidden');
this.$('span.centered.spinner').remove();
this.$('.chatroom-body').append(
......@@ -1660,7 +1650,7 @@
this.$('.chatroom-form').on('submit', this.submitPassword.bind(this));
},
showDisconnectMessage: function (msg) {
showDisconnectMessage (msg) {
this.$('.chat-area').addClass('hidden');
this.$('.occupants').addClass('hidden');
this.$('span.centered.spinner').remove();
......@@ -1669,7 +1659,7 @@
}));
},
getMessageFromStatus: function (stat, stanza, is_self) {
getMessageFromStatus (stat, stanza, is_self) {
/* Parameters:
* (XMLElement) stat: A <status> element.
* (Boolean) is_self: Whether the element refers to the
......@@ -1698,14 +1688,14 @@
return;
},
saveAffiliationAndRole: function (pres) {
saveAffiliationAndRole (pres) {
/* Parse the presence stanza for the current user's
* affiliation.
*
* Parameters:
* (XMLElement) pres: A <presence> stanza.
*/
const item = sizzle('x[xmlns="'+Strophe.NS.MUC_USER+'"] item', pres).pop();
const item = sizzle(`x[xmlns="${Strophe.NS.MUC_USER}"] item`, pres).pop();
const is_self = pres.querySelector("status[code='110']");
if (is_self && !_.isNil(item)) {
const affiliation = item.getAttribute('affiliation');
......@@ -1719,7 +1709,7 @@
}
},
parseXUserElement: function (x, stanza, is_self) {
parseXUserElement (x, stanza, is_self) {
/* Parse the passed-in <x xmlns='http://jabber.org/protocol/muc#user'>
* element and construct a map containing relevant
* information.
......@@ -1759,7 +1749,7 @@
return notification;
},
displayNotificationsforUser: function (notification) {
displayNotificationsforUser (notification) {
/* Given the notification object generated by
* parseXUserElement, display any relevant messages and
* information to the user.
......@@ -1779,14 +1769,14 @@
this.$content.append(tpl_info({'message': message}));
});
if (notification.reason) {
this.showStatusNotification(__('The reason given is: "'+notification.reason+'"'), true);
this.showStatusNotification(__(`The reason given is: "${notification.reason}"`), true);
}
if (notification.messages.length) {
this.scrollDown();
}
},
getJoinLeaveMessages: function (stanza) {
getJoinLeaveMessages (stanza) {
/* Parse the given stanza and return notification messages
* for join/leave events.
*/
......@@ -1814,7 +1804,7 @@
}
},
showStatusMessages: function (stanza) {
showStatusMessages (stanza) {
/* Check for status codes and communicate their purpose to the user.
* See: http://xmpp.org/registrar/mucstatus.html
*
......@@ -1822,7 +1812,7 @@
* (XMLElement) stanza: The message or presence stanza
* containing the status codes.
*/
const elements = sizzle('x[xmlns="'+Strophe.NS.MUC_USER+'"]', stanza);
const elements = sizzle(`x[xmlns="${Strophe.NS.MUC_USER}"]`, stanza);
const is_self = stanza.querySelectorAll("status[code='110']").length;
const iteratee = _.partial(this.parseXUserElement.bind(this), _, stanza, is_self);
let notifications = _.reject(_.map(elements, iteratee), _.isEmpty);
......@@ -1837,7 +1827,7 @@
return stanza;
},
showErrorMessage: function (presence) {
showErrorMessage (presence) {
// We didn't enter the room, so we must remove it from the MUC add-on
const error = presence.querySelector('error');
if (error.getAttribute('type') === 'auth') {
......@@ -1867,7 +1857,7 @@
}
},
renderAfterTransition: function () {
renderAfterTransition () {
/* Rerender the room after some kind of transition. For
* example after the spinner has been removed or after a
* form has been submitted and removed.
......@@ -1884,12 +1874,12 @@
}
},
showSpinner: function () {
showSpinner () {
this.$('.chatroom-body').children().addClass('hidden');
this.$el.find('.chatroom-body').prepend(tpl_spinner);
},
hideSpinner: function () {
hideSpinner () {
/* Check if the spinner is being shown and if so, hide it.
* Also make sure then that the chat area and occupants
* list are both visible.
......@@ -1902,7 +1892,7 @@
return this;
},
onOwnChatRoomPresence: function (pres) {
onOwnChatRoomPresence (pres) {
/* Handles a received presence relating to the current
* user.
*
......@@ -1946,7 +1936,7 @@
this.model.save('connection_status', ROOMSTATUS.ENTERED);
},
onChatRoomPresence: function (pres) {
onChatRoomPresence (pres) {
/* Handles all MUC presence stanzas.
*
* Parameters:
......@@ -1972,7 +1962,7 @@
return true;
},
setChatRoomSubject: function (sender, subject) {
setChatRoomSubject (sender, subject) {
// For translators: the %1$s and %2$s parts will get
// replaced by the user and topic text respectively
// Example: Topic set by JC Brand to: Hello World!
......@@ -1981,32 +1971,32 @@
this.scrollDown();
},
onChatRoomMessage: function (message) {
onChatRoomMessage (message) {
/* Given a <message> stanza, create a message
* Backbone.Model if appropriate.
*
* Parameters:
* (XMLElement) msg: The received message stanza
*/
var original_stanza = message,
forwarded = message.querySelector('forwarded'),
delay;
const original_stanza = message,
forwarded = message.querySelector('forwarded');
let delay;
if (!_.isNull(forwarded)) {
message = forwarded.querySelector('message');
delay = forwarded.querySelector('delay');
}
var jid = message.getAttribute('from'),
const jid = message.getAttribute('from'),
msgid = message.getAttribute('id'),
resource = Strophe.getResourceFromJid(jid),
sender = resource && Strophe.unescapeNode(resource) || '',
subject = _.propertyOf(message.querySelector('subject'))('textContent'),
dupes = msgid && this.model.messages.filter(function (msg) {
dupes = msgid && this.model.messages.filter(
// Find duplicates.
// Some bots (like HAL in the prosody chatroom)
// respond to commands with the same ID as the
// original message. So we also check the sender.
return msg.get('msgid') === msgid && msg.get('fullname') === sender;
});
(msg) => msg.get('msgid') === msgid && msg.get('fullname') === sender
);
if (dupes && dupes.length) {
return true;
}
......@@ -2030,7 +2020,7 @@
});
_converse.ChatRoomOccupant = Backbone.Model.extend({
initialize: function (attributes) {
initialize (attributes) {
this.set(_.extend({
'id': _converse.connection.getUniqueId(),
}, attributes));
......@@ -2039,19 +2029,19 @@
_converse.ChatRoomOccupantView = Backbone.View.extend({
tagName: 'li',
initialize: function () {
initialize () {
this.model.on('change', this.render, this);
this.model.on('destroy', this.destroy, this);
},
render: function () {
render () {
const show = this.model.get('show') || 'online';
const new_el = tpl_occupant(
_.extend(
{ 'jid': '',
'show': show,
'hint_show': _converse.PRETTY_CHAT_STATUS[show],
'hint_occupant': __('Click to mention '+this.model.get('nick')+' in your message.'),
'hint_occupant': __(`Click to mention ${this.model.get('nick')} in your message.`),
'desc_moderator': __('This user is a moderator.'),
'desc_occupant': __('This user can send messages in this room.'),
'desc_visitor': __('This user can NOT send messages in this room.')
......@@ -2061,7 +2051,7 @@
const $parents = this.$el.parents();
if ($parents.length) {
this.$el.replaceWith(new_el);
this.setElement($parents.first().children('#'+this.model.get('id')), true);
this.setElement($parents.first().children(`#${this.model.get('id')}`), true);
this.delegateEvents();
} else {
this.$el.replaceWith(new_el);
......@@ -2070,7 +2060,7 @@
return this;
},
destroy: function () {
destroy () {
this.$el.remove();
}
});
......@@ -2083,7 +2073,7 @@
tagName: 'div',
className: 'occupants',
initialize: function () {
initialize () {
this.model.on("add", this.onOccupantAdded, this);
this.chatroomview = this.model.chatroomview;
this.chatroomview.model.on('change:open', this.renderInviteWidget, this);
......@@ -2103,7 +2093,7 @@
this.chatroomview.model.on('change:unsecured', this.onFeatureChanged, this);
},
render: function () {
render () {
this.el.innerHTML = tpl_chatroom_sidebar(
_.extend(this.chatroomview.model.toJSON(), {
'allow_muc_invitations': _converse.allow_muc_invitations,
......@@ -2118,7 +2108,7 @@
return this.renderRoomFeatures();
},
renderInviteWidget: function () {
renderInviteWidget () {
let form = this.el.querySelector('form.room-invite');
if (this.shouldInviteWidgetBeShown()) {
if (_.isNull(form)) {
......@@ -2137,9 +2127,9 @@
return this;
},
renderRoomFeatures: function () {
renderRoomFeatures () {
const picks = _.pick(this.chatroomview.model.attributes, ROOM_FEATURES),
iteratee = function (a, v) { return a || v; },
iteratee = (a, v) => a || v,
el = this.el.querySelector('.chatroom-features');
el.innerHTML = tpl_chatroom_features(
......@@ -2177,7 +2167,7 @@
return this;
},
onFeatureChanged: function (model) {
onFeatureChanged (model) {
/* When a feature has been changed, it's logical opposite
* must be set to the opposite value.
*
......@@ -2203,13 +2193,13 @@
},
setOccupantsHeight: function () {
setOccupantsHeight () {
const el = this.el.querySelector('.chatroom-features');
this.el.querySelector('.occupant-list').style.cssText =
'height: calc(100% - '+el.offsetHeight+'px - 5em);';
`height: calc(100% - ${el.offsetHeight}px - 5em);`;
},
onOccupantAdded: function (item) {
onOccupantAdded (item) {
let view = this.get(item.get('id'));
if (!view) {
view = this.add(
......@@ -2224,7 +2214,7 @@
this.$('.occupant-list').append(view.render().$el);
},
parsePresence: function (pres) {
parsePresence (pres) {
const id = Strophe.getResourceFromJid(pres.getAttribute("from"));
const data = {
nick: id,
......@@ -2261,7 +2251,7 @@
return data;
},
findOccupant: function (data) {
findOccupant (data) {
/* Try to find an existing occupant based on the passed in
* data object.
*
......@@ -2277,7 +2267,7 @@
}
},
updateOccupantsOnPresence: function (pres) {
updateOccupantsOnPresence (pres) {
/* Given a presence stanza, update the occupant models
* based on its contents.
*
......@@ -2305,7 +2295,7 @@
}
},
promptForInvite: function (suggestion) {
promptForInvite (suggestion) {
const reason = prompt(
__(___('You are about to invite %1$s to the chat room "%2$s". '), suggestion.text.label, this.model.get('id')) +
__("You may optionally include a message, explaining the reason for the invitation.")
......@@ -2316,7 +2306,7 @@
suggestion.target.value = '';
},
inviteFormSubmitted: function (evt) {
inviteFormSubmitted (evt) {
evt.preventDefault();
const el = evt.target.querySelector('input.invited-contact');
this.promptForInvite({
......@@ -2327,14 +2317,14 @@
}});
},
shouldInviteWidgetBeShown: function () {
shouldInviteWidgetBeShown () {
return _converse.allow_muc_invitations &&
(this.chatroomview.model.get('open') ||
this.chatroomview.model.get('affiliation') === "owner"
);
},
initInviteWidget: function () {
initInviteWidget () {
const form = this.el.querySelector('form.room-invite');
if (_.isNull(form)) {
return;
......@@ -2372,7 +2362,7 @@
'change input[name=nick]': 'setNick'
},
initialize: function (cfg) {
initialize (cfg) {
this.parent_el = cfg.$parent[0];
this.tab_el = document.createElement('li');
this.model.on('change:muc_domain', this.onDomainChange, this);
......@@ -2381,7 +2371,7 @@
_converse.chatboxes.on('add', _.debounce(this.renderTab, 100), this);
},
render: function () {
render () {
this.el.innerHTML = tpl_room_panel({
'server_input_type': _converse.hide_muc_server && 'hidden' || 'text',
'server_label_global_attr': _converse.hide_muc_server && ' hidden' || '',
......@@ -2399,7 +2389,7 @@
return this;
},
renderTab: function () {
renderTab () {
const controlbox = _converse.chatboxes.get('controlbox');
const chatrooms = fp.filter(
_.partial(utils.isOfType, CHATROOMS_TYPE),
......@@ -2412,14 +2402,14 @@
});
},
insertIntoDOM: function () {
insertIntoDOM () {
this.parent_el.appendChild(this.render().el);
this.tabs = this.parent_el.parentNode.querySelector('#controlbox-tabs');
this.tabs.appendChild(this.tab_el);
return this;
},
onDomainChange: function (model) {
onDomainChange (model) {
const $server = this.$el.find('input.new-chatroom-server');
$server.val(model.get('muc_domain'));
if (_converse.auto_list_rooms) {
......@@ -2427,33 +2417,34 @@
}
},
onNickChange: function (model) {
onNickChange (model) {
const $nick = this.$el.find('input.new-chatroom-nick');
$nick.val(model.get('nick'));
},
informNoRoomsFound: function () {
informNoRoomsFound () {
const $available_chatrooms = this.$el.find('#available-chatrooms');
// For translators: %1$s is a variable and will be replaced with the XMPP server name
$available_chatrooms.html('<dt>'+__('No rooms on %1$s',this.model.get('muc_domain'))+'</dt>');
$available_chatrooms.html(`<dt>${__('No rooms on %1$s',this.model.get('muc_domain'))}</dt>`);
$('input#show-rooms').show().siblings('span.spinner').remove();
},
onRoomsFound: function (iq) {
onRoomsFound (iq) {
/* Handle the IQ stanza returned from the server, containing
* all its public rooms.
*/
var name, jid, i, fragment,
$available_chatrooms = this.$el.find('#available-chatrooms');
const $available_chatrooms = this.$el.find('#available-chatrooms');
this.rooms = $(iq).find('query').find('item');
if (this.rooms.length) {
// For translators: %1$s is a variable and will be
// replaced with the XMPP server name
$available_chatrooms.html('<dt>'+__('Rooms on %1$s',this.model.get('muc_domain'))+'</dt>');
fragment = document.createDocumentFragment();
for (i=0; i<this.rooms.length; i++) {
name = Strophe.unescapeNode($(this.rooms[i]).attr('name')||$(this.rooms[i]).attr('jid'));
jid = $(this.rooms[i]).attr('jid');
$available_chatrooms.html(`<dt>${__('Rooms on %1$s',this.model.get('muc_domain'))}</dt>`);
const fragment = document.createDocumentFragment();
for (let i=0; i<this.rooms.length; i++) {
const name = Strophe.unescapeNode(
$(this.rooms[i]).attr('name')||$(this.rooms[i]).attr('jid')
);
const jid = $(this.rooms[i]).attr('jid');
fragment.appendChild($(
tpl_room_item({
'name':name,
......@@ -2471,7 +2462,7 @@
return true;
},
updateRoomsList: function () {
updateRoomsList () {
/* Send and IQ stanza to the server asking for all rooms
*/
_converse.connection.sendIQ(
......@@ -2485,7 +2476,7 @@
);
},
showRooms: function () {
showRooms () {
const $available_chatrooms = this.$el.find('#available-chatrooms');
const $server = this.$el.find('input.new-chatroom-server');
const server = $server.val();
......@@ -2501,7 +2492,7 @@
this.updateRoomsList();
},
insertRoomInfo: function (el, stanza) {
insertRoomInfo (el, stanza) {
/* Insert room info (based on returned #disco IQ stanza)
*
* Parameters:
......@@ -2547,10 +2538,10 @@
);
},
toggleRoomInfo: function (ev) {
toggleRoomInfo (ev) {
/* Show/hide extra information about a room in the listing.
*/
const target = ev.target,
const { target } = ev,
$parent = $(target).parent('dd'),
$div = $parent.find('div.room-info');
if ($div.length) {
......@@ -2564,8 +2555,8 @@
}
},
parseRoomDataFromEvent: function (ev) {
var name, $name, server, $server, jid;
parseRoomDataFromEvent (ev) {
let name, $name, server, $server, jid;
if (ev.type === 'click') {
name = $(ev.target).text();
jid = $(ev.target).attr('data-room-jid');
......@@ -2595,16 +2586,16 @@
}
},
openChatRoom: function (ev) {
openChatRoom (ev) {
ev.preventDefault();
_converse.openChatRoom(this.parseRoomDataFromEvent(ev));
},
setDomain: function (ev) {
setDomain (ev) {
this.model.save({muc_domain: ev.target.value});
},
setNick: function (ev) {
setNick (ev) {
this.model.save({nick: ev.target.value});
}
});
......@@ -2619,12 +2610,12 @@
* (XMLElement) message: The message stanza containing the
* invitation.
*/
var $message = $(message),
const $message = $(message),
$x = $message.children('x[xmlns="jabber:x:conference"]'),
from = Strophe.getBareJidFromJid($message.attr('from')),
room_jid = $x.attr('jid'),
reason = $x.attr('reason'),
contact = _converse.roster.get(from),
reason = $x.attr('reason');
let contact = _converse.roster.get(from),
result;
if (_converse.auto_join_on_invite) {
......@@ -2645,7 +2636,7 @@
}
}
if (result === true) {
var chatroom = _converse.openChatRoom({
const chatroom = _converse.openChatRoom({
'id': room_jid,
'jid': room_jid,
'name': Strophe.unescapeNode(Strophe.getNodeFromJid(room_jid)),
......@@ -2707,7 +2698,7 @@
*/
_.extend(_converse.api, {
'rooms': {
'close': function (jids) {
'close' (jids) {
if (_.isUndefined(jids)) {
_converse.chatboxviews.each(function (view) {
if (view.is_chatroom && view.model) {
......@@ -2724,7 +2715,7 @@
});
}
},
'open': function (jids, attrs) {
'open' (jids, attrs) {
if (_.isString(attrs)) {
attrs = {'nick': attrs};
} else if (_.isUndefined(attrs)) {
......@@ -2743,7 +2734,7 @@
}
return _.map(jids, _.partial(_converse.getChatRoom, _, attrs, _converse.openChatRoom));
},
'get': function (jids, attrs, create) {
'get' (jids, attrs, create) {
if (_.isString(attrs)) {
attrs = {'nick': attrs};
} else if (_.isUndefined(attrs)) {
......
......@@ -10,21 +10,19 @@
define(["converse-core"], factory);
}(this, function (converse) {
"use strict";
const utils = converse.env.utils,
Strophe = converse.env.Strophe,
_ = converse.env._;
const { utils, Strophe, _ } = converse.env;
converse.plugins.add('converse-notification', {
initialize: function () {
initialize () {
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
const _converse = this._converse;
const { _converse } = this;
// For translations
const __ = _converse.__;
const ___ = _converse.___;
const { __ } = _converse;
const { ___ } = _converse;
_converse.supports_html5_notification = "Notification" in window;
......@@ -39,9 +37,8 @@
notification_icon: '/logo/conversejs128.png'
});
_converse.isOnlyChatStateNotification = function (msg) {
_converse.isOnlyChatStateNotification = (msg) =>
// See XEP-0085 Chat State Notification
return (
_.isNull(msg.querySelector('body')) && (
_.isNull(msg.querySelector(_converse.ACTIVE)) ||
_.isNull(msg.querySelector(_converse.COMPOSING)) ||
......@@ -49,26 +46,25 @@
_.isNull(msg.querySelector(_converse.PAUSED)) ||
_.isNull(msg.querySelector(_converse.GONE))
)
);
};
;
_converse.shouldNotifyOfGroupMessage = function (message) {
/* Is this a group message worthy of notification?
*/
var notify_all = _converse.notify_all_room_messages,
jid = message.getAttribute('from'),
let notify_all = _converse.notify_all_room_messages;
const jid = message.getAttribute('from'),
resource = Strophe.getResourceFromJid(jid),
room_jid = Strophe.getBareJidFromJid(jid),
sender = resource && Strophe.unescapeNode(resource) || '';
if (sender === '' || message.querySelectorAll('delay').length > 0) {
return false;
}
var room = _converse.chatboxes.get(room_jid);
var body = message.querySelector('body');
const room = _converse.chatboxes.get(room_jid);
const body = message.querySelector('body');
if (_.isNull(body)) {
return false;
}
var mentioned = (new RegExp("\\b"+room.get('nick')+"\\b")).test(body.textContent);
const mentioned = (new RegExp(`\\b${room.get('nick')}\\b`)).test(body.textContent);
notify_all = notify_all === true ||
(_.isArray(notify_all) && _.includes(notify_all, room_jid));
if (sender === room.get('nick') || (!notify_all && !mentioned)) {
......@@ -83,7 +79,7 @@
if (utils.isOTRMessage(message)) {
return false;
}
var forwarded = message.querySelector('forwarded');
const forwarded = message.querySelector('forwarded');
if (!_.isNull(forwarded)) {
return false;
} else if (message.getAttribute('type') === 'groupchat') {
......@@ -92,7 +88,7 @@
// We want to show notifications for headline messages.
return true;
}
var is_me = Strophe.getBareJidFromJid(
const is_me = Strophe.getBareJidFromJid(
message.getAttribute('from')) === _converse.bare_jid;
return !_converse.isOnlyChatStateNotification(message) && !is_me;
};
......@@ -103,7 +99,7 @@
// XXX Eventually this can be refactored to use Notification's sound
// feature, but no browser currently supports it.
// https://developer.mozilla.org/en-US/docs/Web/API/notification/sound
var audio;
let audio;
if (_converse.play_sounds && !_.isUndefined(window.Audio)) {
audio = new Audio(_converse.sounds_path+"msg_received.ogg");
if (audio.canPlayType('/audio/ogg')) {
......@@ -116,7 +112,7 @@
};
_converse.areDesktopNotificationsEnabled = function (ignore_hidden) {
var enabled = _converse.supports_html5_notification &&
const enabled = _converse.supports_html5_notification &&
_converse.show_desktop_notifications &&
Notification.permission === "granted";
if (ignore_hidden) {
......@@ -130,8 +126,8 @@
/* Shows an HTML5 Notification to indicate that a new chat
* message was received.
*/
var title, roster_item,
full_from_jid = message.getAttribute('from'),
let title, roster_item;
const full_from_jid = message.getAttribute('from'),
from_jid = Strophe.getBareJidFromJid(full_from_jid);
if (message.getAttribute('type') === 'headline') {
if (!_.includes(from_jid, '@') || _converse.allow_non_roster_messaging) {
......@@ -162,7 +158,7 @@
}
}
}
var n = new Notification(title, {
const n = new Notification(title, {
body: message.querySelector('body').textContent,
lang: _converse.locale,
icon: _converse.notification_icon
......@@ -178,8 +174,8 @@
// Don't notify if the user is being ignored.
return;
}
var chat_state = contact.chat_status,
message = null;
const chat_state = contact.chat_status;
let message = null;
if (chat_state === 'offline') {
message = __('has gone offline');
} else if (chat_state === 'away') {
......@@ -192,7 +188,7 @@
if (message === null) {
return;
}
var n = new Notification(contact.fullname, {
const n = new Notification(contact.fullname, {
body: message,
lang: _converse.locale,
icon: _converse.notification_icon
......@@ -201,7 +197,7 @@
};
_converse.showContactRequestNotification = function (contact) {
var n = new Notification(contact.fullname, {
const n = new Notification(contact.fullname, {
body: __('wants to be your contact'),
lang: _converse.locale,
icon: _converse.notification_icon
......@@ -211,7 +207,7 @@
_converse.showFeedbackNotification = function (data) {
if (data.klass === 'error' || data.klass === 'warn') {
var n = new Notification(data.subject, {
const n = new Notification(data.subject, {
body: data.message,
lang: _converse.locale,
icon: _converse.notification_icon
......@@ -235,7 +231,7 @@
/* Event handler for the on('message') event. Will call methods
* to play sounds and show HTML5 notifications.
*/
var message = data.stanza;
const message = data.stanza;
if (!_converse.shouldNotifyOfMessage(message)) {
return false;
}
......
......@@ -18,13 +18,8 @@
}(this, function (converse, tpl_toolbar_otr, otr) {
"use strict";
// Strophe methods for building stanzas
const Strophe = converse.env.Strophe,
utils = converse.env.utils,
b64_sha1 = converse.env.b64_sha1;
// Other necessary globals
const $ = converse.env.jQuery,
_ = converse.env._;
const { Strophe, utils, b64_sha1, _ } = converse.env;
const $ = converse.env.jQuery;
const HAS_CSPRNG = ((!_.isUndefined(crypto)) &&
((_.isFunction(crypto.randomBytes)) || (_.isFunction(crypto.getRandomValues))
......@@ -56,7 +51,7 @@
//
// New functions which don't exist yet can also be added.
registerGlobalEventHandlers: function () {
registerGlobalEventHandlers () {
this.__super__.registerGlobalEventHandlers();
$(document).click(function () {
if ($('.toggle-otr ul').is(':visible')) {
......@@ -69,14 +64,14 @@
},
ChatBox: {
initialize: function () {
initialize () {
this.__super__.initialize.apply(this, arguments);
if (this.get('box_id') !== 'controlbox') {
this.save({'otr_status': this.get('otr_status') || UNENCRYPTED});
}
},
shouldPlayNotification: function ($message) {
shouldPlayNotification ($message) {
/* Don't play a notification if this is an OTR message but
* encryption is not yet set up. That would mean that the
* OTR session is still being established, so there are no
......@@ -86,8 +81,8 @@
!(utils.isOTRMessage($message[0]) && !_.includes([UNVERIFIED, VERIFIED], this.get('otr_status')));
},
createMessage: function (message, delay, original_stanza) {
var _converse = this.__super__._converse,
createMessage (message, delay, original_stanza) {
const { _converse } = this.__super__,
text = _.propertyOf(message.querySelector('body'))('textContent');
if ((!text) || (!_converse.allow_otr)) {
......@@ -111,10 +106,10 @@
return this.__super__.createMessage.apply(this, arguments);
},
generatePrivateKey: function (instance_tag) {
var _converse = this.__super__._converse;
var key = new otr.DSA();
var jid = _converse.connection.jid;
generatePrivateKey (instance_tag) {
const { _converse } = this.__super__;
const key = new otr.DSA();
const { jid } = _converse.connection;
if (_converse.cache_otr_key) {
this.save({
'otr_priv_key': key.packPrivate(),
......@@ -124,10 +119,10 @@
return key;
},
getSession: function (callback) {
var _converse = this.__super__._converse,
__ = _converse.__;
var instance_tag, saved_key, encrypted_key;
getSession (callback) {
const { _converse } = this.__super__,
{ __ } = _converse;
let instance_tag, saved_key, encrypted_key;
if (_converse.cache_otr_key) {
encrypted_key = this.get('otr_priv_key');
if (_.isString(encrypted_key)) {
......@@ -150,7 +145,7 @@
null,
true // show spinner
);
var that = this;
const that = this;
window.setTimeout(function () {
callback({
'key': that.generatePrivateKey(instance_tag),
......@@ -159,7 +154,7 @@
}, 500);
},
updateOTRStatus: function (state) {
updateOTRStatus (state) {
switch (state) {
case otr.OTR.CONST.STATUS_AKE_SUCCESS:
if (this.otr.msgstate === otr.OTR.CONST.MSGSTATE_ENCRYPTED) {
......@@ -176,11 +171,11 @@
}
},
onSMP: function (type, data) {
onSMP (type, data) {
// Event handler for SMP (Socialist's Millionaire Protocol)
// used by OTR (off-the-record).
var _converse = this.__super__._converse,
__ = _converse.__;
const { _converse } = this.__super__,
{ __ } = _converse;
switch (type) {
case 'question':
this.otr.smpSecret(prompt(__(
......@@ -203,18 +198,18 @@
}
},
initiateOTR: function (query_msg) {
initiateOTR (query_msg) {
// Sets up an OTR object through which we can send and receive
// encrypted messages.
//
// If 'query_msg' is passed in, it means there is an alread incoming
// query message from our contact. Otherwise, it is us who will
// send the query message to them.
var _converse = this.__super__._converse,
__ = _converse.__;
const { _converse } = this.__super__,
{ __ } = _converse;
this.save({'otr_status': UNENCRYPTED});
this.getSession(function (session) {
var _converse = this.__super__._converse;
this.getSession((session) => {
const { _converse } = this.__super__;
this.otr = new otr.OTR({
fragment_size: 140,
send_interval: 200,
......@@ -225,15 +220,15 @@
this.otr.on('status', this.updateOTRStatus.bind(this));
this.otr.on('smp', this.onSMP.bind(this));
this.otr.on('ui', function (msg) {
this.otr.on('ui', (msg) => {
this.trigger('showReceivedOTRMessage', msg);
}.bind(this));
this.otr.on('io', function (msg) {
});
this.otr.on('io', (msg) => {
this.trigger('sendMessage', new _converse.Message({ message: msg }));
}.bind(this));
this.otr.on('error', function (msg) {
});
this.otr.on('error', (msg) => {
this.trigger('showOTRError', msg);
}.bind(this));
});
this.trigger('showHelpMessages', [__('Exchanging private key with contact.')]);
if (query_msg) {
......@@ -241,10 +236,10 @@
} else {
this.otr.sendQueryMsg();
}
}.bind(this));
});
},
endOTR: function () {
endOTR () {
if (this.otr) {
this.otr.endOtr();
}
......@@ -260,8 +255,8 @@
'click .auth-otr': 'authOTR'
},
initialize: function () {
var _converse = this.__super__._converse;
initialize () {
const { _converse } = this.__super__;
this.__super__.initialize.apply(this, arguments);
this.model.on('change:otr_status', this.onOTRStatusChanged, this);
this.model.on('showOTRError', this.showOTRError, this);
......@@ -276,8 +271,8 @@
}
},
createMessageStanza: function () {
var stanza = this.__super__.createMessageStanza.apply(this, arguments);
createMessageStanza () {
const stanza = this.__super__.createMessageStanza.apply(this, arguments);
if (this.model.get('otr_status') !== UNENCRYPTED || utils.isOTRMessage(stanza.nodeTree)) {
// OTR messages aren't carbon copied
stanza.c('private', {'xmlns': Strophe.NS.CARBONS}).up()
......@@ -288,8 +283,8 @@
return stanza;
},
onMessageSubmitted: function (text) {
var _converse = this.__super__._converse;
onMessageSubmitted (text) {
const { _converse } = this.__super__;
if (!_converse.connection.authenticated) {
return this.showHelpMessages(
['Sorry, the connection has been lost, '+
......@@ -297,7 +292,7 @@
'error'
);
}
var match = text.replace(/^\s*/, "").match(/^\/(.*)\s*$/);
const match = text.replace(/^\s*/, "").match(/^\/(.*)\s*$/);
if (match) {
if ((_converse.allow_otr) && (match[1] === "endotr")) {
return this.endOTR();
......@@ -314,13 +309,13 @@
}
},
onOTRStatusChanged: function () {
onOTRStatusChanged () {
this.renderToolbar().informOTRChange();
},
informOTRChange: function () {
var _converse = this.__super__._converse,
__ = _converse.__,
informOTRChange () {
const { _converse } = this.__super__,
{ __ } = _converse,
data = this.model.toJSON(),
msgs = [];
if (data.otr_status === UNENCRYPTED) {
......@@ -335,9 +330,9 @@
return this.showHelpMessages(msgs, 'info', false);
},
showOTRError: function (msg) {
var _converse = this.__super__._converse,
__ = _converse.__;
showOTRError (msg) {
const { _converse } = this.__super__,
{ __ } = _converse;
if (msg === 'Message cannot be sent at this time.') {
this.showHelpMessages(
[__('Your message could not be sent')], 'error');
......@@ -349,18 +344,18 @@
[__('We received an unreadable encrypted message')],
'error');
} else {
this.showHelpMessages(['Encryption error occured: '+msg], 'error');
this.showHelpMessages([`Encryption error occured: ${msg}`], 'error');
}
_converse.log("OTR ERROR:"+msg, Strophe.LogLevel.ERROR);
_converse.log(`OTR ERROR:${msg}`, Strophe.LogLevel.ERROR);
},
startOTRFromToolbar: function (ev) {
startOTRFromToolbar (ev) {
$(ev.target).parent().parent().slideUp();
ev.stopPropagation();
this.model.initiateOTR();
},
endOTR: function (ev) {
endOTR (ev) {
if (!_.isUndefined(ev)) {
ev.preventDefault();
ev.stopPropagation();
......@@ -368,11 +363,11 @@
this.model.endOTR();
},
authOTR: function (ev) {
var _converse = this.__super__._converse,
__ = _converse.__,
scheme = $(ev.target).data().scheme,
result, question, answer;
authOTR (ev) {
const { _converse } = this.__super__,
{ __ } = _converse,
{ scheme } = $(ev.target).data();
let result, question, answer;
if (scheme === 'fingerprint') {
result = confirm(__('Here are the fingerprints, please confirm them with %1$s, outside of this chat.\n\nFingerprint for you, %2$s: %3$s\n\nFingerprint for %1$s: %4$s\n\nIf you have confirmed that the fingerprints match, click OK, otherwise click Cancel.', [
this.model.get('fullname'),
......@@ -398,14 +393,14 @@
}
},
toggleOTRMenu: function (ev) {
toggleOTRMenu (ev) {
ev.stopPropagation();
this.$el.find('.toggle-otr ul').slideToggle(200);
},
getOTRTooltip: function () {
var _converse = this.__super__._converse,
__ = _converse.__,
getOTRTooltip () {
const { _converse } = this.__super__,
{ __ } = _converse,
data = this.model.toJSON();
if (data.otr_status === UNENCRYPTED) {
return __('Your messages are not encrypted. Click here to enable OTR encryption.');
......@@ -418,18 +413,18 @@
}
},
renderToolbar: function (toolbar, options) {
var _converse = this.__super__._converse,
__ = _converse.__;
renderToolbar (toolbar, options) {
const { _converse } = this.__super__,
{ __ } = _converse;
if (!_converse.show_toolbar) {
return;
}
var data = this.model.toJSON();
const data = this.model.toJSON();
options = _.extend(options || {}, {
FINISHED: FINISHED,
UNENCRYPTED: UNENCRYPTED,
UNVERIFIED: UNVERIFIED,
VERIFIED: VERIFIED,
FINISHED,
UNENCRYPTED,
UNVERIFIED,
VERIFIED,
// FIXME: Leaky abstraction MUC
allow_otr: _converse.allow_otr && !this.is_chatroom,
label_end_encrypted_conversation: __('End encrypted conversation'),
......@@ -452,12 +447,12 @@
}
},
initialize: function () {
initialize () {
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
var _converse = this._converse,
__ = _converse.__;
const { _converse } = this,
{ __ } = _converse;
_converse.api.settings.update({
allow_otr: true,
......
......@@ -14,16 +14,15 @@
}(this, function (converse) {
"use strict";
// Strophe methods for building stanzas
const Strophe = converse.env.Strophe,
_ = converse.env._;
const { Strophe, _ } = converse.env;
converse.plugins.add('converse-ping', {
initialize: function () {
initialize () {
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
const _converse = this._converse;
const { _converse } = this;
_converse.api.settings.update({
ping_interval: 180 //in seconds
......@@ -72,7 +71,7 @@
return true;
});
_converse.connection.addTimedHandler(1000, function () {
var now = new Date();
const now = new Date();
if (!_converse.lastStanzaDate) {
_converse.lastStanzaDate = now;
}
......@@ -84,7 +83,7 @@
}
};
var onConnected = function () {
const onConnected = function () {
// Wrapper so that we can spy on registerPingHandler in tests
_converse.registerPingHandler();
};
......
......@@ -32,19 +32,14 @@
"use strict";
// Strophe methods for building stanzas
const Strophe = converse.env.Strophe,
Backbone = converse.env.Backbone,
utils = converse.env.utils,
$iq = converse.env.$iq;
// Other necessary globals
const $ = converse.env.jQuery,
_ = converse.env._;
const { Strophe, Backbone, utils, $iq, _ } = converse.env;
const $ = converse.env.jQuery;
// Add Strophe Namespaces
Strophe.addNamespace('REGISTER', 'jabber:iq:register');
// Add Strophe Statuses
var i = 0;
let i = 0;
_.each(_.keys(Strophe.Status), function (key) {
i = Math.max(i, Strophe.Status[key]);
});
......@@ -64,9 +59,9 @@
ControlBoxView: {
switchTab: function (ev) {
var _converse = this.__super__._converse;
var result = this.__super__.switchTab.apply(this, arguments);
switchTab (ev) {
const { _converse } = this.__super__;
const result = this.__super__.switchTab.apply(this, arguments);
if (_converse.registration_domain &&
ev.target.getAttribute('data-id') === "register" &&
!this.model.get('registration_form_rendered')) {
......@@ -75,8 +70,8 @@
return result;
},
renderRegistrationPanel: function () {
var _converse = this.__super__._converse;
renderRegistrationPanel () {
const { _converse } = this.__super__;
if (_converse.allow_registration) {
this.registerpanel = new _converse.RegisterPanel({
'$parent': this.$el.find('.controlbox-panes'),
......@@ -87,7 +82,7 @@
return this;
},
renderLoginPanel: function () {
renderLoginPanel () {
/* Also render a registration panel, when rendering the
* login panel.
*/
......@@ -98,12 +93,12 @@
}
},
initialize: function () {
initialize () {
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
var _converse = this._converse,
__ = _converse.__;
const { _converse } = this,
{ __ } = _converse;
// Add new templates
_converse.templates.form_username = tpl_form_username;
......@@ -126,14 +121,14 @@
'submit form#converse-register': 'onProviderChosen'
},
initialize: function (cfg) {
initialize (cfg) {
this.reset();
this.$parent = cfg.$parent;
this.$tabs = cfg.$parent.parent().find('#controlbox-tabs');
this.registerHooks();
},
render: function () {
render () {
this.model.set('registration_form_rendered', false);
this.$parent.append(this.$el.html(
tpl_register_panel({
......@@ -150,13 +145,13 @@
return this;
},
registerHooks: function () {
registerHooks () {
/* Hook into Strophe's _connect_cb, so that we can send an IQ
* requesting the registration fields.
*/
var conn = _converse.connection;
var connect_cb = conn._connect_cb.bind(conn);
conn._connect_cb = function (req, callback, raw) {
const conn = _converse.connection;
const connect_cb = conn._connect_cb.bind(conn);
conn._connect_cb = (req, callback, raw) => {
if (!this._registering) {
connect_cb(req, callback, raw);
} else {
......@@ -164,26 +159,26 @@
this._registering = false;
}
}
}.bind(this);
};
},
getRegistrationFields: function (req, _callback, raw) {
getRegistrationFields (req, _callback, raw) {
/* Send an IQ stanza to the XMPP server asking for the
* registration fields.
* Parameters:
* (Strophe.Request) req - The current request
* (Function) callback
*/
var conn = _converse.connection;
const conn = _converse.connection;
conn.connected = true;
var body = conn._proto._reqToData(req);
const body = conn._proto._reqToData(req);
if (!body) { return; }
if (conn._proto._connect_cb(body) === Strophe.Status.CONNFAIL) {
return false;
}
var register = body.getElementsByTagName("register");
var mechanisms = body.getElementsByTagName("mechanism");
const register = body.getElementsByTagName("register");
const mechanisms = body.getElementsByTagName("mechanism");
if (register.length === 0 && mechanisms.length === 0) {
conn._proto._no_auth_received(_callback);
return false;
......@@ -204,7 +199,7 @@
return true;
},
onRegistrationFields: function (stanza) {
onRegistrationFields (stanza) {
/* Handler for Registration Fields Request.
*
* Parameters:
......@@ -219,8 +214,8 @@
return false;
},
reset: function (settings) {
var defaults = {
reset (settings) {
const defaults = {
fields: {},
urls: [],
title: "",
......@@ -236,7 +231,7 @@
}
},
onProviderChosen: function (ev) {
onProviderChosen (ev) {
/* Callback method that gets called when the user has chosen an
* XMPP provider.
*
......@@ -244,7 +239,7 @@
* (Submit Event) ev - Form submission event.
*/
if (ev && ev.preventDefault) { ev.preventDefault(); }
var $form = $(ev.target),
const $form = $(ev.target),
$domain_input = $form.find('input[name=domain]'),
domain = $domain_input.val();
if (!domain) {
......@@ -255,7 +250,7 @@
this.fetchRegistrationForm(domain, __('Cancel'));
},
fetchRegistrationForm: function (domain_name, cancel_label) {
fetchRegistrationForm (domain_name, cancel_label) {
/* This is called with a domain name based on which, it fetches a
* registration form from the requested domain.
*
......@@ -271,8 +266,8 @@
return false;
},
renderRegistrationRequest: function (cancel_label) {
var form = this.el.querySelector('#converse-register');
renderRegistrationRequest (cancel_label) {
const form = this.el.querySelector('#converse-register');
utils.createElementsFromString(
form,
tpl_registration_request({
......@@ -281,20 +276,20 @@
})
);
if (!_converse.registration_domain) {
var cancel_button = document.querySelector('button.button-cancel');
const cancel_button = document.querySelector('button.button-cancel');
cancel_button.addEventListener('click', this.cancelRegistration.bind(this));
}
},
giveFeedback: function (message, klass) {
giveFeedback (message, klass) {
this.$('.reg-feedback').attr('class', 'reg-feedback').text(message);
if (klass) {
$('.reg-feedback').addClass(klass);
}
},
onRegistering: function (status, error) {
var that;
onRegistering (status, error) {
let that;
_converse.log('onRegistering');
if (_.includes([
Strophe.Status.DISCONNECTED,
......@@ -305,7 +300,7 @@
], status)) {
_converse.log(
'Problem during registration: Strophe.Status is: '+status,
`Problem during registration: Strophe.Status is: ${status}`,
Strophe.LogLevel.ERROR
);
this.cancelRegistration();
......@@ -342,7 +337,7 @@
}
},
renderRegistrationForm: function (stanza) {
renderRegistrationForm (stanza) {
/* Renders the registration form based on the XForm fields
* received from the XMPP server.
*
......@@ -351,9 +346,9 @@
*/
this.model.set('registration_form_rendered', true);
var $form = this.$('form'),
$stanza = $(stanza),
$fields, $input;
const $form = this.$('form'),
$stanza = $(stanza);
let $fields, $input;
$form.empty().append(tpl_registration_form({
'domain': this.domain,
'title': this.title,
......@@ -361,15 +356,15 @@
}));
if (this.form_type === 'xform') {
$fields = $stanza.find('field');
_.each($fields, function (field) {
_.each($fields, (field) => {
$form.append(utils.xForm2webForm.bind(this, $(field), $stanza));
}.bind(this));
});
} else {
// Show fields
_.each(_.keys(this.fields), function (key) {
_.each(_.keys(this.fields), (key) => {
if (key === "username") {
$input = tpl_form_username({
domain: ' @'+this.domain,
domain: ` @${this.domain}`,
name: key,
type: "text",
label: key,
......@@ -377,26 +372,26 @@
required: 1
});
} else {
$form.append('<label>'+key+'</label>');
$input = $('<input placeholder="'+key+'" name="'+key+'"></input>');
$form.append(`<label>${key}</label>`);
$input = $(`<input placeholder="${key}" name="${key}"></input>`);
if (key === 'password' || key === 'email') {
$input.attr('type', key);
}
}
$form.append($input);
}.bind(this));
});
// Show urls
_.each(this.urls, function (url) {
_.each(this.urls, (url) => {
$form.append($('<a target="blank"></a>').attr('href', url).text(url));
}.bind(this));
});
}
if (this.fields) {
$form.append('<input type="submit" class="pure-button button-primary" value="'+__('Register')+'"/>');
$form.append(`<input type="submit" class="pure-button button-primary" value="${__('Register')}"/>`);
$form.on('submit', this.submitRegistrationForm.bind(this));
$form.append('<input type="button" class="pure-button button-cancel" value="'+__('Cancel')+'"/>');
$form.append(`<input type="button" class="pure-button button-cancel" value="${__('Cancel')}"/>`);
$form.find('input[type=button]').on('click', this.cancelRegistration.bind(this));
} else {
$form.append('<input type="button" class="submit" value="'+__('Return')+'"/>');
$form.append(`<input type="button" class="submit" value="${__('Return')}"/>`);
$form.find('input[type=button]').on('click', this.cancelRegistration.bind(this));
}
if (_converse.registration_domain) {
......@@ -404,7 +399,7 @@
}
},
reportErrors: function (stanza) {
reportErrors (stanza) {
/* Report back to the user any error messages received from the
* XMPP server after attempted registration.
*
......@@ -412,11 +407,12 @@
* (XMLElement) stanza - The IQ stanza received from the
* XMPP server.
*/
var $form= this.$('form'), flash;
var $errmsgs = $(stanza).find('error text');
var $flash = $form.find('.form-errors');
const $form= this.$('form'),
$errmsgs = $(stanza).find('error text');
let $flash = $form.find('.form-errors');
if (!$flash.length) {
flash = '<legend class="form-errors"></legend>';
const flash = '<legend class="form-errors"></legend>';
if ($form.find('p.instructions').length) {
$form.find('p.instructions').append(flash);
} else {
......@@ -437,7 +433,7 @@
$flash.show();
},
cancelRegistration: function (ev) {
cancelRegistration (ev) {
/* Handler, when the user cancels the registration form.
*/
if (ev && ev.preventDefault) { ev.preventDefault(); }
......@@ -453,7 +449,7 @@
}
},
submitRegistrationForm: function (ev) {
submitRegistrationForm (ev) {
/* Handler, when the user submits the registration form.
* Provides form error feedback or starts the registration
* process.
......@@ -462,7 +458,7 @@
* (Event) ev - the submit event.
*/
if (ev && ev.preventDefault) { ev.preventDefault(); }
var has_empty_inputs = _.reduce(this.el.querySelectorAll('input.required'),
const has_empty_inputs = _.reduce(this.el.querySelectorAll('input.required'),
function (result, input) {
if (input.value === '') {
input.classList.add('error');
......@@ -471,7 +467,7 @@
return result;
}, 0);
if (has_empty_inputs) { return; }
var $inputs = $(ev.target).find(':input:not([type=button]):not([type=submit])'),
const $inputs = $(ev.target).find(':input:not([type=button]):not([type=submit])'),
iq = $iq({type: "set"}).c("query", {xmlns:Strophe.NS.REGISTER});
if (this.form_type === 'xform') {
......@@ -481,7 +477,7 @@
});
} else {
$inputs.each(function () {
var $input = $(this);
const $input = $(this);
iq.c($input.attr('name'), {}, $input.val());
});
}
......@@ -491,16 +487,16 @@
this.setFields(iq.tree());
},
setFields: function (stanza) {
setFields (stanza) {
/* Stores the values that will be sent to the XMPP server
* during attempted registration.
*
* Parameters:
* (XMLElement) stanza - the IQ stanza that will be sent to the XMPP server.
*/
var $query = $(stanza).find('query'), $xform;
const $query = $(stanza).find('query');
if ($query.length > 0) {
$xform = $query.find('x[xmlns="'+Strophe.NS.XFORM+'"]');
const $xform = $query.find(`x[xmlns="${Strophe.NS.XFORM}"]`);
if ($xform.length > 0) {
this._setFieldsFromXForm($xform);
} else {
......@@ -509,41 +505,41 @@
}
},
_setFieldsFromLegacy: function ($query) {
$query.children().each(function (idx, field) {
var $field = $(field);
_setFieldsFromLegacy ($query) {
$query.children().each((idx, field) => {
const $field = $(field);
if (field.tagName.toLowerCase() === 'instructions') {
this.instructions = Strophe.getText(field);
return;
} else if (field.tagName.toLowerCase() === 'x') {
if ($field.attr('xmlns') === 'jabber:x:oob') {
$field.find('url').each(function (idx, url) {
$field.find('url').each((idx, url) => {
this.urls.push($(url).text());
}.bind(this));
});
}
return;
}
this.fields[field.tagName.toLowerCase()] = Strophe.getText(field);
}.bind(this));
});
this.form_type = 'legacy';
},
_setFieldsFromXForm: function ($xform) {
_setFieldsFromXForm ($xform) {
this.title = $xform.find('title').text();
this.instructions = $xform.find('instructions').text();
$xform.find('field').each(function (idx, field) {
var _var = field.getAttribute('var');
$xform.find('field').each((idx, field) => {
const _var = field.getAttribute('var');
if (_var) {
this.fields[_var.toLowerCase()] = $(field).children('value').text();
} else {
// TODO: other option seems to be type="fixed"
_converse.log("Found field we couldn't parse", Strophe.LogLevel.WARN);
}
}.bind(this));
});
this.form_type = 'xform';
},
_onRegisterIQ: function (stanza) {
_onRegisterIQ (stanza) {
/* Callback method that gets called when a return IQ stanza
* is received from the XMPP server, after attempting to
* register a new user.
......@@ -551,7 +547,7 @@
* Parameters:
* (XMLElement) stanza - The IQ stanza.
*/
var error = null,
let error = null,
query = stanza.getElementsByTagName("query");
if (query.length > 0) {
query = query[0];
......@@ -578,7 +574,7 @@
return false;
},
remove: function () {
remove () {
this.$tabs.empty();
this.$el.parent().empty();
}
......
......@@ -17,20 +17,17 @@
"tpl!rooms_list_item"
], factory);
}(this, function (utils, converse, muc, tpl_rooms_list, tpl_rooms_list_item) {
var $ = converse.env.jQuery,
Backbone = converse.env.Backbone,
b64_sha1 = converse.env.b64_sha1,
sizzle = converse.env.sizzle,
_ = converse.env._;
const $ = converse.env.jQuery,
{ Backbone, b64_sha1, sizzle, _ } = converse.env;
converse.plugins.add('converse-roomslist', {
initialize: function () {
initialize () {
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
var _converse = this._converse,
__ = _converse.__,
___ = _converse.___;
const { _converse } = this,
{ __,
___ } = _converse;
_converse.RoomsList = Backbone.Model.extend({
defaults: {
......@@ -46,7 +43,7 @@
'click .open-rooms-toggle': 'toggleRoomsList'
},
initialize: function () {
initialize () {
this.model.on('add', this.renderRoomsListElement, this);
this.model.on('change:bookmarked', this.renderRoomsListElement, this);
this.model.on('change:name', this.renderRoomsListElement, this);
......@@ -54,7 +51,7 @@
this.model.on('change:num_unread_general', this.renderRoomsListElement, this);
this.model.on('remove', this.removeRoomsListElement, this);
var cachekey = 'converse.roomslist'+_converse.bare_jid;
const cachekey = `converse.roomslist${_converse.bare_jid}`;
this.list_model = new _converse.RoomsList();
this.list_model.id = cachekey;
this.list_model.browserStorage = new Backbone.BrowserStorage[_converse.storage](
......@@ -64,7 +61,7 @@
this.render();
},
render: function () {
render () {
this.el.innerHTML =
tpl_rooms_list({
'toggle_state': this.list_model.get('toggle-state'),
......@@ -76,11 +73,11 @@
this.$('.open-rooms-list').hide();
}
this.model.each(this.renderRoomsListElement.bind(this));
var controlboxview = _converse.chatboxviews.get('controlbox');
const controlboxview = _converse.chatboxviews.get('controlbox');
if (!_.isUndefined(controlboxview) &&
!document.body.contains(this.el)) {
var container = controlboxview.el.querySelector('#chatrooms');
const container = controlboxview.el.querySelector('#chatrooms');
if (!_.isNull(container)) {
container.insertBefore(this.el, container.firstChild);
}
......@@ -88,37 +85,37 @@
return this.el;
},
hide: function () {
hide () {
this.el.classList.add('hidden');
},
show: function () {
show () {
this.el.classList.remove('hidden');
},
closeRoom: function (ev) {
closeRoom (ev) {
ev.preventDefault();
var name = $(ev.target).data('roomName');
var jid = $(ev.target).data('roomJid');
const name = $(ev.target).data('roomName');
const jid = $(ev.target).data('roomJid');
if (confirm(__(___("Are you sure you want to leave the room \"%1$s\"?"), name))) {
_converse.chatboxviews.get(jid).leave();
}
},
renderRoomsListElement: function (item) {
renderRoomsListElement (item) {
if (item.get('type') !== 'chatroom') {
return;
}
this.removeRoomsListElement(item);
var name, bookmark;
let name, bookmark;
if (item.get('bookmarked')) {
bookmark = _.head(_converse.bookmarksview.model.where({'jid': item.get('jid')}));
name = bookmark.get('name');
} else {
name = item.get('name');
}
var div = document.createElement('div');
const div = document.createElement('div');
div.innerHTML = tpl_rooms_list_item(_.extend(item.toJSON(), {
'info_leave_room': __('Leave this room'),
'info_remove_bookmark': __('Unbookmark this room'),
......@@ -130,9 +127,9 @@
this.show();
},
removeRoomsListElement: function (item) {
var list_el = this.el.querySelector('.open-rooms-list');
var el = _.head(sizzle('.available-chatroom[data-room-jid="'+item.get('jid')+'"]', list_el));
removeRoomsListElement (item) {
const list_el = this.el.querySelector('.open-rooms-list');
const el = _.head(sizzle(`.available-chatroom[data-room-jid="${item.get('jid')}"]`, list_el));
if (el) {
list_el.removeChild(el);
}
......@@ -141,9 +138,9 @@
}
},
toggleRoomsList: function (ev) {
toggleRoomsList (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
var el = ev.target;
const el = ev.target;
if (el.classList.contains("icon-opened")) {
this.$('.open-rooms-list').slideUp('fast');
this.list_model.save({'toggle-state': _converse.CLOSED});
......@@ -158,7 +155,7 @@
}
});
var initRoomsListView = function () {
const initRoomsListView = function () {
_converse.rooms_list_view = new _converse.RoomsListView(
{'model': _converse.chatboxes}
);
......@@ -174,7 +171,7 @@
}
});
var afterReconnection = function () {
const afterReconnection = function () {
if (_.isUndefined(_converse.rooms_list_view)) {
initRoomsListView();
} else {
......
......@@ -24,14 +24,8 @@
tpl_roster_filter,
tpl_roster_item) {
"use strict";
var $ = converse.env.jQuery,
Backbone = converse.env.Backbone,
utils = converse.env.utils,
Strophe = converse.env.Strophe,
$iq = converse.env.$iq,
b64_sha1 = converse.env.b64_sha1,
sizzle = converse.env.sizzle,
_ = converse.env._;
const $ = converse.env.jQuery,
{ Backbone, utils, Strophe, $iq, b64_sha1, sizzle, _ } = converse.env;
converse.plugins.add('converse-rosterview', {
......@@ -42,11 +36,11 @@
// relevant objects or classes.
//
// New functions which don't exist yet can also be added.
afterReconnected: function () {
afterReconnected () {
this.__super__.afterReconnected.apply(this, arguments);
},
_tearDown: function () {
_tearDown () {
/* Remove the rosterview when tearing down. It gets created
* anew when reconnecting or logging in.
*/
......@@ -57,23 +51,23 @@
},
RosterGroups: {
comparator: function () {
comparator () {
// RosterGroupsComparator only gets set later (once i18n is
// set up), so we need to wrap it in this nameless function.
var _converse = this.__super__._converse;
const { _converse } = this.__super__;
return _converse.RosterGroupsComparator.apply(this, arguments);
}
}
},
initialize: function () {
initialize () {
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
var _converse = this._converse,
__ = _converse.__,
___ = _converse.___;
const { _converse } = this,
{ __,
___ } = _converse;
_converse.api.settings.update({
allow_chat_pending_contacts: true,
......@@ -81,7 +75,7 @@
show_toolbar: true,
});
var STATUSES = {
const STATUSES = {
'dnd': __('This contact is busy'),
'online': __('This contact is online'),
'offline': __('This contact is offline'),
......@@ -89,13 +83,13 @@
'xa': __('This contact is away for an extended period'),
'away': __('This contact is away')
};
var LABEL_CONTACTS = __('Contacts');
var LABEL_GROUPS = __('Groups');
var HEADER_CURRENT_CONTACTS = __('My contacts');
var HEADER_PENDING_CONTACTS = __('Pending contacts');
var HEADER_REQUESTING_CONTACTS = __('Contact requests');
var HEADER_UNGROUPED = __('Ungrouped');
var HEADER_WEIGHTS = {};
const LABEL_CONTACTS = __('Contacts');
const LABEL_GROUPS = __('Groups');
const HEADER_CURRENT_CONTACTS = __('My contacts');
const HEADER_PENDING_CONTACTS = __('Pending contacts');
const HEADER_REQUESTING_CONTACTS = __('Contact requests');
const HEADER_UNGROUPED = __('Ungrouped');
const HEADER_WEIGHTS = {};
HEADER_WEIGHTS[HEADER_REQUESTING_CONTACTS] = 0;
HEADER_WEIGHTS[HEADER_CURRENT_CONTACTS] = 1;
HEADER_WEIGHTS[HEADER_UNGROUPED] = 2;
......@@ -108,9 +102,9 @@
*/
a = a.get('name');
b = b.get('name');
var special_groups = _.keys(HEADER_WEIGHTS);
var a_is_special = _.includes(special_groups, a);
var b_is_special = _.includes(special_groups, b);
const special_groups = _.keys(HEADER_WEIGHTS);
const a_is_special = _.includes(special_groups, a);
const b_is_special = _.includes(special_groups, b);
if (!a_is_special && !b_is_special ) {
return a.toLowerCase() < b.toLowerCase() ? -1 : (a.toLowerCase() > b.toLowerCase() ? 1 : 0);
} else if (a_is_special && b_is_special) {
......@@ -124,7 +118,7 @@
_converse.RosterFilter = Backbone.Model.extend({
initialize: function () {
initialize () {
this.set({
'filter_text': '',
'filter_type': 'contacts',
......@@ -144,12 +138,12 @@
"change .state-type": "changeChatStateFilter"
},
initialize: function () {
initialize () {
this.model.on('change:filter_type', this.render, this);
this.model.on('change:filter_text', this.renderClearButton, this);
},
render: function () {
render () {
this.el.innerHTML = tpl_roster_filter(
_.extend(this.model.toJSON(), {
placeholder: __('Filter'),
......@@ -169,34 +163,34 @@
return this.$el;
},
renderClearButton: function () {
var roster_filter = this.el.querySelector('.roster-filter');
renderClearButton () {
const roster_filter = this.el.querySelector('.roster-filter');
if (_.isNull(roster_filter)) {
return;
}
roster_filter.classList[this.tog(roster_filter.value)]('x');
},
tog: function (v) {
tog (v) {
return v?'add':'remove';
},
toggleX: function (ev) {
toggleX (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
var el = ev.target;
const el = ev.target;
el.classList[this.tog(el.offsetWidth-18 < ev.clientX-el.getBoundingClientRect().left)]('onX');
},
changeChatStateFilter: function (ev) {
changeChatStateFilter (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
this.model.save({
'chat_state': this.el.querySelector('.state-type').value
});
},
changeTypeFilter: function (ev) {
changeTypeFilter (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
var type = ev.target.value;
const type = ev.target.value;
if (type === 'state') {
this.model.save({
'filter_type': type,
......@@ -217,13 +211,13 @@
});
}, 250),
submitFilter: function (ev) {
submitFilter (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
this.liveFilter();
this.render();
},
isActive: function () {
isActive () {
/* Returns true if the filter is enabled (i.e. if the user
* has added values to the filter).
*/
......@@ -234,13 +228,13 @@
return false;
},
show: function () {
show () {
if (this.$el.is(':visible')) { return this; }
this.$el.show();
return this;
},
hide: function () {
hide () {
if (!this.$el.is(':visible')) { return this; }
if (this.el.querySelector('.roster-filter').value.length > 0) {
// Don't hide if user is currently filtering.
......@@ -254,7 +248,7 @@
return this;
},
clearFilter: function (ev) {
clearFilter (ev) {
if (ev && ev.preventDefault) {
ev.preventDefault();
$(ev.target).removeClass('x onX').val('');
......@@ -269,7 +263,7 @@
tagName: 'div',
id: 'converse-roster',
initialize: function () {
initialize () {
_converse.roster.on("add", this.onContactAdd, this);
_converse.roster.on('change', this.onContactChange, this);
_converse.roster.on("destroy", this.update, this);
......@@ -281,7 +275,7 @@
this.createRosterFilter();
},
render: function () {
render () {
this.renderRoster();
this.$el.html(this.filter_view.render());
if (!_converse.allow_contact_requests) {
......@@ -292,15 +286,15 @@
return this;
},
renderRoster: function () {
renderRoster () {
this.$roster = $(tpl_roster());
this.roster = this.$roster[0];
},
createRosterFilter: function () {
createRosterFilter () {
// Create a model on which we can store filter properties
var model = new _converse.RosterFilter();
model.id = b64_sha1('_converse.rosterfilter'+_converse.bare_jid);
const model = new _converse.RosterFilter();
model.id = b64_sha1(`_converse.rosterfilter${_converse.bare_jid}`);
model.browserStorage = new Backbone.BrowserStorage.local(this.filter.id);
this.filter_view = new _converse.RosterFilterView({'model': model});
this.filter_view.model.on('change', this.updateFilter, this);
......@@ -315,7 +309,7 @@
* Debounced so that it doesn't get called for every
* contact fetched from browser storage.
*/
var type = this.filter_view.model.get('filter_type');
const type = this.filter_view.model.get('filter_type');
if (type === 'state') {
this.filter(this.filter_view.model.get('chat_state'), type);
} else {
......@@ -330,7 +324,7 @@
return this.showHideFilter();
}, _converse.animate ? 100 : 0),
showHideFilter: function () {
showHideFilter () {
if (!this.$el.is(':visible')) {
return;
}
......@@ -342,7 +336,7 @@
return this;
},
filter: function (query, type) {
filter (query, type) {
// First we make sure the filter is restored to its
// original state
_.each(this.getAll(), function (view) {
......@@ -367,7 +361,7 @@
}
},
reset: function () {
reset () {
_converse.roster.reset();
this.removeAll();
this.renderRoster();
......@@ -375,18 +369,18 @@
return this;
},
onGroupAdd: function (group) {
var view = new _converse.RosterGroupView({model: group});
onGroupAdd (group) {
const view = new _converse.RosterGroupView({model: group});
this.add(group.get('name'), view.render());
this.positionGroup(view);
},
onContactAdd: function (contact) {
onContactAdd (contact) {
this.addRosterContact(contact).update();
this.updateFilter();
},
onContactChange: function (contact) {
onContactChange (contact) {
this.updateChatBox(contact).update();
if (_.has(contact.changed, 'subscription')) {
if (contact.changed.subscription === 'from') {
......@@ -404,8 +398,8 @@
this.updateFilter();
},
updateChatBox: function (contact) {
var chatbox = _converse.chatboxes.get(contact.get('jid')),
updateChatBox (contact) {
const chatbox = _converse.chatboxes.get(contact.get('jid')),
changes = {};
if (!chatbox) {
return this;
......@@ -420,7 +414,7 @@
return this;
},
positionFetchedGroups: function () {
positionFetchedGroups () {
/* Instead of throwing an add event for each group
* fetched, we wait until they're all fetched and then
* we position them.
......@@ -429,10 +423,10 @@
* positioned aren't already in inserted into the
* roster DOM element.
*/
var that = this;
const that = this;
this.model.sort();
this.model.each(function (group, idx) {
var view = that.get(group.get('name'));
let view = that.get(group.get('name'));
if (!view) {
view = new _converse.RosterGroupView({model: group});
that.add(group.get('name'), view.render());
......@@ -445,11 +439,11 @@
});
},
positionGroup: function (view) {
positionGroup (view) {
/* Place the group's DOM element in the correct alphabetical
* position amongst the other groups in the roster.
*/
var $groups = this.$roster.find('.roster-group'),
const $groups = this.$roster.find('.roster-group'),
index = $groups.length ? this.model.indexOf(view.model) : 0;
if (index === 0) {
this.$roster.prepend(view.$el);
......@@ -461,11 +455,11 @@
return this;
},
appendGroup: function (view) {
appendGroup (view) {
/* Add the group at the bottom of the roster
*/
var $last = this.$roster.find('.roster-group').last();
var $siblings = $last.siblings('dd');
const $last = this.$roster.find('.roster-group').last();
const $siblings = $last.siblings('dd');
if ($siblings.length > 0) {
$siblings.last().after(view.$el);
} else {
......@@ -474,23 +468,23 @@
return this;
},
getGroup: function (name) {
getGroup (name) {
/* Returns the group as specified by name.
* Creates the group if it doesn't exist.
*/
var view = this.get(name);
const view = this.get(name);
if (view) {
return view.model;
}
return this.model.create({name: name, id: b64_sha1(name)});
return this.model.create({name, id: b64_sha1(name)});
},
addContactToGroup: function (contact, name) {
addContactToGroup (contact, name) {
this.getGroup(name).contacts.add(contact);
},
addExistingContact: function (contact) {
var groups;
addExistingContact (contact) {
let groups;
if (_converse.roster_groups) {
groups = contact.get('groups');
if (groups.length === 0) {
......@@ -502,7 +496,7 @@
_.each(groups, _.bind(this.addContactToGroup, this, contact));
},
addRosterContact: function (contact) {
addRosterContact (contact) {
if (contact.get('subscription') === 'both' || contact.get('subscription') === 'to') {
this.addExistingContact(contact);
} else {
......@@ -527,26 +521,26 @@
"click .remove-xmpp-contact": "removeContact"
},
initialize: function () {
initialize () {
this.model.on("change", this.render, this);
this.model.on("remove", this.remove, this);
this.model.on("destroy", this.remove, this);
this.model.on("open", this.openChat, this);
},
render: function () {
var that = this;
render () {
const that = this;
if (!this.mayBeShown()) {
this.$el.hide();
return this;
}
var item = this.model,
const item = this.model,
ask = item.get('ask'),
chat_status = item.get('chat_status'),
requesting = item.get('requesting'),
subscription = item.get('subscription');
var classes_to_remove = [
const classes_to_remove = [
'current-xmpp-contact',
'pending-xmpp-contact',
'requesting-xmpp-contact'
......@@ -597,8 +591,8 @@
return this;
},
renderRosterItem: function (item) {
var chat_status = item.get('chat_status');
renderRosterItem (item) {
const chat_status = item.get('chat_status');
this.$el.html(tpl_roster_item(
_.extend(item.toJSON(), {
'desc_status': STATUSES[chat_status||'offline'],
......@@ -612,7 +606,7 @@
return this;
},
isGroupCollapsed: function () {
isGroupCollapsed () {
/* Check whether the group in which this contact appears is
* collapsed.
*/
......@@ -622,22 +616,22 @@
// If roster group items were inside the group elements, we
// would simplify things by not having to check whether the
// group is collapsed or not.
var name = this.$el.prevAll('dt:first').data('group');
var group = _.head(_converse.rosterview.model.where({'name': name.toString()}));
const name = this.$el.prevAll('dt:first').data('group');
const group = _.head(_converse.rosterview.model.where({'name': name.toString()}));
if (group.get('state') === _converse.CLOSED) {
return true;
}
return false;
},
mayBeShown: function () {
mayBeShown () {
/* Return a boolean indicating whether this contact should
* generally be visible in the roster.
*
* It doesn't check for the more specific case of whether
* the group it's in is collapsed (see isGroupCollapsed).
*/
var chatStatus = this.model.get('chat_status');
const chatStatus = this.model.get('chat_status');
if ((_converse.show_only_online_users && chatStatus !== 'online') ||
(_converse.hide_offline_users && chatStatus === 'offline')) {
// If pending or requesting, show
......@@ -651,45 +645,45 @@
return true;
},
openChat: function (ev) {
openChat (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
return _converse.chatboxviews.showChat(this.model.attributes, true);
},
removeContact: function (ev) {
removeContact (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
if (!_converse.allow_contact_removal) { return; }
var result = confirm(__("Are you sure you want to remove this contact?"));
const result = confirm(__("Are you sure you want to remove this contact?"));
if (result === true) {
var iq = $iq({type: 'set'})
const iq = $iq({type: 'set'})
.c('query', {xmlns: Strophe.NS.ROSTER})
.c('item', {jid: this.model.get('jid'), subscription: "remove"});
_converse.connection.sendIQ(iq,
function (iq) {
(iq) => {
this.model.destroy();
this.remove();
}.bind(this),
},
function (err) {
alert(__("Sorry, there was an error while trying to remove "+name+" as a contact."));
alert(__(`Sorry, there was an error while trying to remove ${name} as a contact.`));
_converse.log(err, Strophe.LogLevel.ERROR);
}
);
}
},
acceptRequest: function (ev) {
acceptRequest (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
_converse.roster.sendContactAddIQ(
this.model.get('jid'),
this.model.get('fullname'),
[],
function () { this.model.authorize().subscribe(); }.bind(this)
() => { this.model.authorize().subscribe(); }
);
},
declineRequest: function (ev) {
declineRequest (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
var result = confirm(__("Are you sure you want to decline this contact request?"));
const result = confirm(__("Are you sure you want to decline this contact request?"));
if (result === true) {
this.model.unauthorize().destroy();
}
......@@ -705,7 +699,7 @@
"click a.group-toggle": "toggle"
},
initialize: function () {
initialize () {
this.model.contacts.on("add", this.addContact, this);
this.model.contacts.on("change:subscription", this.onContactSubscriptionChange, this);
this.model.contacts.on("change:requesting", this.onContactRequestChange, this);
......@@ -720,9 +714,9 @@
_converse.roster.on('change:groups', this.onContactGroupChange, this);
},
render: function () {
render () {
this.el.setAttribute('data-group', this.model.get('name'));
var html = tpl_group_header({
const html = tpl_group_header({
label_group: this.model.get('name'),
desc_group_toggle: this.model.get('description'),
toggle_state: this.model.get('state')
......@@ -731,8 +725,8 @@
return this;
},
addContact: function (contact) {
var view = new _converse.RosterContactView({model: contact});
addContact (contact) {
let view = new _converse.RosterContactView({model: contact});
this.add(contact.get('id'), view);
view = this.positionContact(contact).render();
if (view.mayBeShown()) {
......@@ -745,12 +739,12 @@
}
},
positionContact: function (contact) {
positionContact (contact) {
/* Place the contact's DOM element in the correct alphabetical
* position amongst the other contacts in this group.
*/
var view = this.get(contact.get('id'));
var index = this.model.contacts.indexOf(contact);
const view = this.get(contact.get('id'));
const index = this.model.contacts.indexOf(contact);
view.$el.detach();
if (index === 0) {
this.$el.after(view.$el);
......@@ -762,7 +756,7 @@
return view;
},
show: function () {
show () {
this.$el.show();
_.each(this.getAll(), function (view) {
if (view.mayBeShown() && !view.isGroupCollapsed()) {
......@@ -772,25 +766,27 @@
return this;
},
hide: function () {
hide () {
this.$el.nextUntil('dt').addBack().hide();
},
filter: function (q, type) {
filter (q, type) {
/* Filter the group's contacts based on the query "q".
* The query is matched against the contact's full name.
* If all contacts are filtered out (i.e. hidden), then the
* group must be filtered out as well.
*/
var matches;
let matches;
if (q.length === 0) {
if (this.model.get('state') === _converse.OPENED) {
this.model.contacts.each(function (item) {
var view = this.get(item.get('id'));
this.model.contacts.each(
(item) => {
const view = this.get(item.get('id'));
if (view.mayBeShown() && !view.isGroupCollapsed()) {
view.$el.show();
}
}.bind(this));
}
);
}
this.showIfNecessary();
} else {
......@@ -801,9 +797,7 @@
// show requesting contacts, even though they don't
// have the state in question.
matches = this.model.contacts.filter(
function (contact) {
return utils.contains.not('chat_status', q)(contact) && !contact.get('requesting');
}
(contact) => utils.contains.not('chat_status', q)(contact) && !contact.get('requesting')
);
} else if (q === 'unread_messages') {
matches = this.model.contacts.filter({'num_unread': 0});
......@@ -821,26 +815,26 @@
// hide the whole group
this.hide();
} else {
_.each(matches, function (item) {
_.each(matches, (item) => {
this.get(item.get('id')).$el.hide();
}.bind(this));
_.each(this.model.contacts.reject(utils.contains.not('fullname', q)), function (item) {
this.get(item.get('id')).$el.show();
}.bind(this));
});
_.each(this.model.contacts.reject(
utils.contains.not('fullname', q)),
(item) => { this.get(item.get('id')).$el.show(); });
this.showIfNecessary();
}
}
},
showIfNecessary: function () {
showIfNecessary () {
if (!this.$el.is(':visible') && this.model.contacts.length > 0) {
this.$el.show();
}
},
toggle: function (ev) {
toggle (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
var $el = $(ev.target);
const $el = $(ev.target);
if ($el.hasClass("icon-opened")) {
this.$el.nextUntil('dt').slideUp();
this.model.save({state: _converse.CLOSED});
......@@ -855,10 +849,10 @@
}
},
onContactGroupChange: function (contact) {
var in_this_group = _.includes(contact.get('groups'), this.model.get('name'));
var cid = contact.get('id');
var in_this_overview = !this.get(cid);
onContactGroupChange (contact) {
const in_this_group = _.includes(contact.get('groups'), this.model.get('name'));
const cid = contact.get('id');
const in_this_overview = !this.get(cid);
if (in_this_group && !in_this_overview) {
this.model.contacts.remove(cid);
} else if (!in_this_group && in_this_overview) {
......@@ -866,13 +860,13 @@
}
},
onContactSubscriptionChange: function (contact) {
onContactSubscriptionChange (contact) {
if ((this.model.get('name') === HEADER_PENDING_CONTACTS) && contact.get('subscription') !== 'from') {
this.model.contacts.remove(contact.get('id'));
}
},
onContactRequestChange: function (contact) {
onContactRequestChange (contact) {
if ((this.model.get('name') === HEADER_REQUESTING_CONTACTS) && !contact.get('requesting')) {
/* We suppress events, otherwise the remove event will
* also cause the contact's view to be removed from the
......@@ -886,7 +880,7 @@
}
},
onRemove: function (contact) {
onRemove (contact) {
this.remove(contact.get('id'));
if (this.model.contacts.length === 0) {
this.$el.hide();
......@@ -896,24 +890,24 @@
/* -------- Event Handlers ----------- */
var onChatBoxMaximized = function (chatboxview) {
const onChatBoxMaximized = function (chatboxview) {
/* When a chat box gets maximized, the num_unread counter needs
* to be cleared, but if chatbox is scrolled up, then num_unread should not be cleared.
*/
var chatbox = chatboxview.model;
const chatbox = chatboxview.model;
if (chatbox.get('type') !== 'chatroom') {
var contact = _.head(_converse.roster.where({'jid': chatbox.get('jid')}));
const contact = _.head(_converse.roster.where({'jid': chatbox.get('jid')}));
if (!_.isUndefined(contact) && !chatbox.isScrolledUp()) {
contact.save({'num_unread': 0});
}
}
};
var onMessageReceived = function (data) {
const onMessageReceived = function (data) {
/* Given a newly received message, update the unread counter on
* the relevant roster contact.
*/
var chatbox = data.chatbox;
const { chatbox } = data;
if (_.isUndefined(chatbox)) {
return;
}
......@@ -924,25 +918,25 @@
utils.isNewMessage(data.stanza) &&
chatbox.newMessageWillBeHidden()) {
var contact = _.head(_converse.roster.where({'jid': chatbox.get('jid')}));
const contact = _.head(_converse.roster.where({'jid': chatbox.get('jid')}));
if (!_.isUndefined(contact)) {
contact.save({'num_unread': contact.get('num_unread') + 1});
}
}
};
var onChatBoxScrolledDown = function (data) {
var chatbox = data.chatbox;
const onChatBoxScrolledDown = function (data) {
const { chatbox } = data;
if (_.isUndefined(chatbox)) {
return;
}
var contact = _.head(_converse.roster.where({'jid': chatbox.get('jid')}));
const contact = _.head(_converse.roster.where({'jid': chatbox.get('jid')}));
if (!_.isUndefined(contact)) {
contact.save({'num_unread': 0});
}
};
var initRoster = function () {
const initRoster = function () {
/* Create an instance of RosterView once the RosterGroups
* collection has been created (in converse-core.js)
*/
......
......@@ -21,8 +21,7 @@
factory);
}(this, function (converse) {
"use strict";
var _ = converse.env._,
Strophe = converse.env.Strophe;
const { _, Strophe } = converse.env;
function hideChat (view) {
if (view.model.get('id') === 'controlbox') { return; }
......@@ -46,7 +45,7 @@
// new functions which don't exist yet can also be added.
ChatBoxes: {
createChatBox: function (jid, attrs) {
createChatBox (jid, attrs) {
/* Make sure new chat boxes are hidden by default.
*/
attrs = attrs || {};
......@@ -56,23 +55,23 @@
},
RoomsPanel: {
parseRoomDataFromEvent: function (ev) {
parseRoomDataFromEvent (ev) {
/* We set hidden to false for rooms opened manually by the
* user. They should always be shown.
*/
var result = this.__super__.parseRoomDataFromEvent.apply(this, arguments);
const result = this.__super__.parseRoomDataFromEvent.apply(this, arguments);
result.hidden = false;
return result;
}
},
ChatBoxViews: {
showChat: function (attrs, force) {
showChat (attrs, force) {
/* We only have one chat visible at any one
* time. So before opening a chat, we make sure all other
* chats are hidden.
*/
const _converse = this.__super__._converse;
const { _converse } = this.__super__;
const chatbox = this.getChatBox(attrs, true);
const hidden = _.isUndefined(attrs.hidden) ? chatbox.get('hidden') : attrs.hidden;
if ((force || !hidden) && _converse.connection.authenticated) {
......@@ -84,7 +83,7 @@
},
ChatBoxView: {
_show: function (focus) {
_show (focus) {
/* We only have one chat visible at any one
* time. So before opening a chat, we make sure all other
* chats are hidden.
......@@ -97,7 +96,7 @@
},
RosterContactView: {
openChat: function (ev) {
openChat (ev) {
/* We only have one chat visible at any one
* time. So before opening a chat, we make sure all other
* chats are hidden.
......
......@@ -10,10 +10,8 @@
define(["converse-core", "strophe.vcard"], factory);
}(this, function (converse) {
"use strict";
const Strophe = converse.env.Strophe,
$ = converse.env.jQuery,
_ = converse.env._,
moment = converse.env.moment;
const { Strophe, _, moment } = converse.env,
$ = converse.env.jQuery;
converse.plugins.add('converse-vcard', {
......@@ -25,8 +23,8 @@
// New functions which don't exist yet can also be added.
Features: {
addClientFeatures: function () {
const _converse = this.__super__._converse;
addClientFeatures () {
const { _converse } = this.__super__;
this.__super__.addClientFeatures.apply(this, arguments);
if (_converse.use_vcards) {
_converse.connection.disco.addFeature(Strophe.NS.VCARD);
......@@ -35,15 +33,15 @@
},
RosterContacts: {
createRequestingContact: function (presence) {
const _converse = this.__super__._converse;
createRequestingContact (presence) {
const { _converse } = this.__super__;
const bare_jid = Strophe.getBareJidFromJid(presence.getAttribute('from'));
_converse.getVCard(
bare_jid,
_.partial(_converse.createRequestingContactFromVCard, presence),
function (iq, jid) {
_converse.log(
"Error while retrieving vcard for "+jid,
`Error while retrieving vcard for ${jid}`,
Strophe.LogLevel.ERROR
);
_converse.createRequestingContactFromVCard(presence, iq, jid);
......@@ -54,18 +52,18 @@
},
initialize: function () {
initialize () {
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
const _converse = this._converse;
const { _converse } = this;
_converse.api.settings.update({
use_vcards: true,
});
_converse.createRequestingContactFromVCard = function (presence, iq, jid, fullname, img, img_type, url) {
const bare_jid = Strophe.getBareJidFromJid(jid);
const nick = $(presence).children('nick[xmlns="'+Strophe.NS.NICK+'"]').text();
const nick = $(presence).children(`nick[xmlns="${Strophe.NS.NICK}"]`).text();
const user_data = {
jid: bare_jid,
subscription: 'none',
......@@ -74,7 +72,7 @@
fullname: fullname || nick || bare_jid,
image: img,
image_type: img_type,
url: url,
url,
vcard_updated: moment().format()
};
_converse.roster.create(user_data);
......@@ -90,13 +88,14 @@
};
_converse.onVCardData = function (jid, iq, callback) {
var $vcard = $(iq).find('vCard'),
fullname = $vcard.find('FN').text(),
img = $vcard.find('BINVAL').text(),
const $vcard = $(iq).find('vCard'),
img_type = $vcard.find('TYPE').text(),
img = $vcard.find('BINVAL').text(),
url = $vcard.find('URL').text();
let fullname = $vcard.find('FN').text();
if (jid) {
var contact = _converse.roster.get(jid);
const contact = _converse.roster.get(jid);
if (contact) {
fullname = _.isEmpty(fullname)? contact.get('fullname') || jid: fullname;
contact.save({
......@@ -134,9 +133,9 @@
}
};
var updateVCardForChatBox = function (chatbox) {
const updateVCardForChatBox = function (chatbox) {
if (!_converse.use_vcards) { return; }
var jid = chatbox.model.get('jid'),
const jid = chatbox.model.get('jid'),
contact = _converse.roster.get(jid);
if ((contact) && (!contact.get('vcard_updated'))) {
_converse.getVCard(
......@@ -161,7 +160,7 @@
_converse.on('chatBoxInitialized', updateVCardForChatBox);
var onContactAdd = function (contact) {
const onContactAdd = function (contact) {
if (!contact.get('vcard_updated')) {
// This will update the vcard, which triggers a change
// request which will rerender the roster contact.
......@@ -172,7 +171,7 @@
_converse.roster.on("add", onContactAdd);
});
var fetchOwnVCard = function () {
const fetchOwnVCard = function () {
if (_converse.xmppstatus.get('fullname') === undefined) {
_converse.getVCard(
null, // No 'to' attr when getting one's own vCard
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment