Use esnext to auto-generate es2015 syntax

This commit is contained in:
JC Brand 2017-07-10 17:46:22 +02:00
parent ac1475ed43
commit 9a9eae3fcf
19 changed files with 1212 additions and 1269 deletions

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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 {

File diff suppressed because it is too large Load Diff

View File

@ -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;

View File

@ -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(), {

View File

@ -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,

View File

@ -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) ) {

View File

@ -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('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);

View File

@ -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");
}

File diff suppressed because it is too large Load Diff

View File

@ -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,36 +37,34 @@
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('body')) && (
_.isNull(msg.querySelector(_converse.ACTIVE)) ||
_.isNull(msg.querySelector(_converse.COMPOSING)) ||
_.isNull(msg.querySelector(_converse.INACTIVE)) ||
_.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,9 +126,9 @@
/* Shows an HTML5 Notification to indicate that a new chat
* message was received.
*/
var title, roster_item,
full_from_jid = message.getAttribute('from'),
from_jid = Strophe.getBareJidFromJid(full_from_jid);
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) {
title = __(___("Notification from %1$s"), from_jid);
@ -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;
}

View File

@ -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,

View File

@ -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();
};

View File

@ -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();
}

View File

@ -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 {

View File

@ -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'));
if (view.mayBeShown() && !view.isGroupCollapsed()) {
view.$el.show();
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)
*/

View File

@ -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.

View File

@ -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