Merge branch 'split-muc' into bootstrap4

This commit is contained in:
JC Brand 2018-03-05 16:45:02 +01:00
commit d4d3d4c838
64 changed files with 14802 additions and 7484 deletions

View File

@ -19,13 +19,26 @@ with regards to sponsoring development on reintroducing them.
* Removed the `xhr_user_search` and `xhr_user_search_url` configuration options.
## 3.3.4 (Unreleased)
## 3.3.4 (2018-03-05)
- Avoid `eval` (via `_.template` from lodash).
- Bugfix. Avatars weren't being shown.
- Bugfix. Bookmarks list and open rooms list weren't recreated after logging in for a 2nd time (without reloading the browser).
- Don't show bookmark toggles when PEP bookmarking not supported by the XMPP server.
- Add LibreJS support
- Emojis are now sent in unicode instead of short names (also in MUCs)
### Bugfixes
- Server field in `Rooms` tab showed MUC supporting clients instead of only components.
- Avatars weren't being shown.
- Bookmarks list and open rooms list weren't recreated after logging in for a 2nd time (without reloading the browser).
- #1022 Status message not sent out on subsequent presences
- #1024 null reference on MUC Invite
- #1025 OTR lock icon disappears
- #1027 `new Event` not supported in IE11
- #1028 Avoid `eval` (crept in via `_.template` from lodash).
### Translation changes
- New locale: Bulgarian
- Updated German, Russian, Chinese (traditional), Norwegian Bokmål and French translations.
## 3.3.3 (2018-02-14)

View File

@ -2,7 +2,7 @@
*
* An XMPP chat client that runs in the browser.
*
* Version: 3.3.3
* Version: 3.3.4
*
* Copyright: JC Brand 2012-2017
* Except for 3rd party dependencies.

View File

@ -72,7 +72,7 @@ serve_bg: dev
########################################################################
## Translation machinery
GETTEXT = xgettext --language="JavaScript" --keyword=__ --keyword=___ --from-code=UTF-8 --output=locale/converse.pot dist/converse-no-dependencies.js --package-name=Converse.js --copyright-holder="Jan-Carel Brand" --package-version=3.3.3 -c
GETTEXT = xgettext --language="JavaScript" --keyword=__ --keyword=___ --from-code=UTF-8 --output=locale/converse.pot dist/converse-no-dependencies.js --package-name=Converse.js --copyright-holder="Jan-Carel Brand" --package-version=3.3.4 -c
.PHONY: pot
pot: dist/converse-no-dependencies.js

View File

@ -149,8 +149,8 @@
#converse-embedded-chat .icon-legal:before,
#conversejs .icon-legal:before {
content: "\f0e3"; }
#converse-embedded-chat .icon-lock-2:before,
#conversejs .icon-lock-2:before {
#converse-embedded-chat .icon-lock:before,
#conversejs .icon-lock:before {
content: "\e027"; }
#converse-embedded-chat .icon-minus:before,
#conversejs .icon-minus:before {

View File

@ -142,8 +142,8 @@
#converse-embedded-chat .icon-legal:before,
#conversejs .icon-legal:before {
content: "\f0e3"; }
#converse-embedded-chat .icon-lock-2:before,
#conversejs .icon-lock-2:before {
#converse-embedded-chat .icon-lock:before,
#conversejs .icon-lock:before {
content: "\e027"; }
#converse-embedded-chat .icon-minus:before,
#conversejs .icon-minus:before {

View File

@ -149,8 +149,8 @@
#converse-embedded-chat .icon-legal:before,
#conversejs .icon-legal:before {
content: "\f0e3"; }
#converse-embedded-chat .icon-lock-2:before,
#conversejs .icon-lock-2:before {
#converse-embedded-chat .icon-lock:before,
#conversejs .icon-lock:before {
content: "\e027"; }
#converse-embedded-chat .icon-minus:before,
#conversejs .icon-minus:before {

View File

@ -2,7 +2,7 @@
*
* An XMPP chat client that runs in the browser.
*
* Version: 3.3.3
* Version: 3.3.4
*/
/* jshint ignore:start */
@ -22063,6 +22063,17 @@ define('lodash.fp',['lodash', 'lodash.converter'], function (_, lodashConverter)
return fp;
});
function CustomEvent ( event, params ) {
params = params || { bubbles: false, cancelable: false, detail: undefined };
var evt = document.createEvent( 'CustomEvent' );
evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
return evt;
}
if ( typeof window.CustomEvent !== "function" ) {
CustomEvent.prototype = window.Event.prototype;
window.CustomEvent = CustomEvent;
}
if (!String.prototype.includes) {
String.prototype.includes = function(search, start) {
'use strict';
@ -27679,6 +27690,97 @@ return af;
})));
//! moment.js locale configuration
//! locale : Bulgarian [bg]
//! author : Krasen Borisov : https://github.com/kraz
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define('moment/locale/bg',['../moment'], factory) :
factory(global.moment)
}(this, (function (moment) { 'use strict';
var bg = moment.defineLocale('bg', {
months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),
monthsShort : 'янрев_мар_апрай_юни_юли_авг_сеп_окт_ноеек'.split('_'),
weekdays : еделя_понеделник_вторник_срядаетвъртък_петък_събота'.split('_'),
weekdaysShort : ед_пон_вто_сря_чет_пет_съб'.split('_'),
weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
longDateFormat : {
LT : 'H:mm',
LTS : 'H:mm:ss',
L : 'D.MM.YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY H:mm',
LLLL : 'dddd, D MMMM YYYY H:mm'
},
calendar : {
sameDay : '[Днес в] LT',
nextDay : '[Утре в] LT',
nextWeek : 'dddd [в] LT',
lastDay : '[Вчера в] LT',
lastWeek : function () {
switch (this.day()) {
case 0:
case 3:
case 6:
return '[В изминалата] dddd [в] LT';
case 1:
case 2:
case 4:
case 5:
return '[В изминалия] dddd [в] LT';
}
},
sameElse : 'L'
},
relativeTime : {
future : 'след %s',
past : 'преди %s',
s : 'няколко секунди',
m : 'минута',
mm : '%d минути',
h : 'час',
hh : '%d часа',
d : 'ден',
dd : '%d дни',
M : 'месец',
MM : '%d месеца',
y : 'година',
yy : '%d години'
},
dayOfMonthOrdinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/,
ordinal : function (number) {
var lastDigit = number % 10,
last2Digits = number % 100;
if (number === 0) {
return number + '-ев';
} else if (last2Digits === 0) {
return number + '-ен';
} else if (last2Digits > 10 && last2Digits < 20) {
return number + '-ти';
} else if (lastDigit === 1) {
return number + '-ви';
} else if (lastDigit === 2) {
return number + '-ри';
} else if (lastDigit === 7 || lastDigit === 8) {
return number + '-ми';
} else {
return number + '-ти';
}
},
week : {
dow : 1, // Monday is the first day of the week.
doy : 7 // The week that contains Jan 1st is the first week of the year.
}
});
return bg;
})));
//! moment.js locale configuration
//! locale : Catalan [ca]
//! author : Juan G. Hurtado : https://github.com/juanghurtado
@ -28968,6 +29070,97 @@ return ru;
})));
//! moment.js locale configuration
//! locale : Turkish [tr]
//! authors : Erhan Gundogan : https://github.com/erhangundogan,
//! Burak Yiğit Kaya: https://github.com/BYK
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define('moment/locale/tr',['../moment'], factory) :
factory(global.moment)
}(this, (function (moment) { 'use strict';
var suffixes = {
1: '\'inci',
5: '\'inci',
8: '\'inci',
70: '\'inci',
80: '\'inci',
2: '\'nci',
7: '\'nci',
20: '\'nci',
50: '\'nci',
3: '\'üncü',
4: '\'üncü',
100: '\'üncü',
6: '\'ncı',
9: '\'uncu',
10: '\'uncu',
30: '\'uncu',
60: '\'ıncı',
90: '\'ıncı'
};
var tr = moment.defineLocale('tr', {
months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'),
monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),
weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'),
weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),
weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),
longDateFormat : {
LT : 'HH:mm',
LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY HH:mm',
LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[bugün saat] LT',
nextDay : '[yarın saat] LT',
nextWeek : '[haftaya] dddd [saat] LT',
lastDay : '[dün] LT',
lastWeek : '[geçen hafta] dddd [saat] LT',
sameElse : 'L'
},
relativeTime : {
future : '%s sonra',
past : '%s önce',
s : 'birkaç saniye',
m : 'bir dakika',
mm : '%d dakika',
h : 'bir saat',
hh : '%d saat',
d : 'bir gün',
dd : '%d gün',
M : 'bir ay',
MM : '%d ay',
y : 'bir yıl',
yy : '%d yıl'
},
dayOfMonthOrdinalParse: /\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,
ordinal : function (number) {
if (number === 0) { // special case for zero
return number + '\'ıncı';
}
var a = number % 10,
b = number % 100 - a,
c = number >= 100 ? 100 : null;
return number + (suffixes[a] || suffixes[b] || suffixes[c]);
},
week : {
dow : 1, // Monday is the first day of the week.
doy : 7 // The week that contains Jan 1st is the first week of the year.
}
});
return tr;
})));
//! moment.js locale configuration
//! locale : Ukrainian [uk]
//! author : zemlanin : https://github.com/zemlanin
@ -29348,7 +29541,7 @@ return zhTw;
/*global define */
(function (root, factory) {
define('i18n',["es6-promise", "jed", "lodash.noconflict", "moment", 'moment/locale/af', 'moment/locale/ca', 'moment/locale/de', 'moment/locale/es', 'moment/locale/fr', 'moment/locale/he', 'moment/locale/hu', 'moment/locale/id', 'moment/locale/it', 'moment/locale/ja', 'moment/locale/nb', 'moment/locale/nl', 'moment/locale/pl', 'moment/locale/pt-br', 'moment/locale/ru', 'moment/locale/uk', 'moment/locale/zh-cn', 'moment/locale/zh-tw'], factory);
define('i18n',["es6-promise", "jed", "lodash.noconflict", "moment", 'moment/locale/af', 'moment/locale/bg', 'moment/locale/ca', 'moment/locale/de', 'moment/locale/es', 'moment/locale/fr', 'moment/locale/he', 'moment/locale/hu', 'moment/locale/id', 'moment/locale/it', 'moment/locale/ja', 'moment/locale/nb', 'moment/locale/nl', 'moment/locale/pl', 'moment/locale/pt-br', 'moment/locale/ru', 'moment/locale/tr', 'moment/locale/uk', 'moment/locale/zh-cn', 'moment/locale/zh-tw'], factory);
})(this, function (Promise, Jed, _, moment) {
'use strict';
@ -36494,6 +36687,42 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
return promise;
};
u.interpolate = function (string, o) {
return string.replace(/{{{([^{}]*)}}}/g, function (a, b) {
var r = o[b];
return typeof r === 'string' || typeof r === 'number' ? r : a;
});
};
u.onMultipleEvents = function () {
var events = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
var callback = arguments.length > 1 ? arguments[1] : undefined;
/* Call the callback once all the events have been triggered
*
* Parameters:
* (Array) events: An array of objects, with keys `object` and
* `event`, representing the event name and the object it's
* triggered upon.
* (Function) callback: The function to call once all events have
* been triggered.
*/
var triggered = [];
function handler(result) {
triggered.push(result);
if (events.length === triggered.length) {
callback(triggered);
triggered = [];
}
}
_.each(events, function (map) {
return map.object.on(map.event, handler);
});
};
u.safeSave = function (model, attributes) {
if (u.isPersistableModel(model)) {
model.save(attributes);
@ -36503,7 +36732,11 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
};
u.isVisible = function (el) {
// XXX: Taken from jQuery's "visible" implementation
if (u.hasClass('hidden', el)) {
return false;
} // XXX: Taken from jQuery's "visible" implementation
return el.offsetWidth > 0 || el.offsetHeight > 0 || el.getClientRects().length > 0;
};
@ -39196,7 +39429,7 @@ return Backbone.BrowserStorage;
/*global Backbone, define, window, JSON */
(function (root, factory) {
define('converse-core',["sizzle", "es6-promise", "lodash.noconflict", "lodash.fp", "polyfill", "i18n", "utils", "moment", "strophe", "pluggable", "backbone.noconflict", "backbone.nativeview", "backbone.browserStorage"], factory);
})(this, function (sizzle, Promise, _, f, polyfill, i18n, utils, moment, Strophe, pluggable, Backbone) {
})(this, function (sizzle, Promise, _, f, polyfill, i18n, u, moment, Strophe, pluggable, Backbone) {
/* Cannot use this due to Safari bug.
* See https://github.com/jcbrand/converse.js/issues/196
*/
@ -39368,7 +39601,7 @@ return Backbone.BrowserStorage;
/* Private function, used to add a new promise to the ones already
* available via the `waitUntil` api method.
*/
_converse.promises[promise] = utils.getResolveablePromise();
_converse.promises[promise] = u.getResolveablePromise();
}
_converse.emit = function (name) {
@ -39390,7 +39623,7 @@ return Backbone.BrowserStorage;
var _this = this;
settings = !_.isUndefined(settings) ? settings : {};
var init_promise = utils.getResolveablePromise();
var init_promise = u.getResolveablePromise();
_.each(PROMISES, addPromise);
@ -39474,7 +39707,7 @@ return Backbone.BrowserStorage;
jid: undefined,
keepalive: true,
locales_url: 'locale/{{{locale}}}/LC_MESSAGES/converse.json',
locales: ['af', 'ca', 'de', 'es', 'en', 'fr', 'he', 'hu', 'id', 'it', 'ja', 'nb', 'nl', 'pl', 'pt_BR', 'ru', 'uk', 'zh_CN', 'zh_TW'],
locales: ['af', 'bg', 'ca', 'de', 'es', 'en', 'fr', 'he', 'hu', 'id', 'it', 'ja', 'nb', 'nl', 'pl', 'pt_BR', 'ru', 'tr', 'uk', 'zh_CN', 'zh_TW'],
message_carbons: true,
message_storage: 'session',
password: undefined,
@ -39821,7 +40054,7 @@ return Backbone.BrowserStorage;
this.initStatus = function () {
return new Promise(function (resolve, reject) {
var promise = new utils.getResolveablePromise();
var promise = new u.getResolveablePromise();
_this.xmppstatus = new _this.XMPPStatus();
var id = b64_sha1("converse.xmppstatus-".concat(_converse.bare_jid));
_this.xmppstatus.id = id; // Appears to be necessary for backbone.browserStorage
@ -39866,7 +40099,10 @@ return Backbone.BrowserStorage;
_converse.connection.disconnect();
} else {
_converse._tearDown();
}
} // Recreate all the promises
_.each(_.keys(_converse.promises), addPromise);
_converse.emit('logout');
};
@ -40117,9 +40353,9 @@ return Backbone.BrowserStorage;
initialize: function initialize(attributes) {
var _this3 = this;
var jid = attributes.jid;
var bare_jid = Strophe.getBareJidFromJid(jid).toLowerCase();
var resource = Strophe.getResourceFromJid(jid);
var jid = attributes.jid,
bare_jid = Strophe.getBareJidFromJid(jid).toLowerCase(),
resource = Strophe.getResourceFromJid(jid);
attributes.jid = bare_jid;
this.set(_.assignIn({
'fullname': bare_jid,
@ -40392,7 +40628,7 @@ return Backbone.BrowserStorage;
return true;
},
isSelf: function isSelf(jid) {
return utils.isSameBareJID(jid, _converse.connection.jid);
return u.isSameBareJID(jid, _converse.connection.jid);
},
addAndSubscribe: function addAndSubscribe(jid, name, groups, message, attributes) {
/* Add a roster contact and then once we have confirmation from
@ -40796,7 +41032,7 @@ return Backbone.BrowserStorage;
constructPresence: function constructPresence(type, status_message) {
var presence;
type = _.isString(type) ? type : this.get('status') || _converse.default_state;
status_message = _.isString(status_message) ? status_message : undefined; // Most of these presence types are actually not explicitly sent,
status_message = _.isString(status_message) ? status_message : this.get('status_message'); // Most of these presence types are actually not explicitly sent,
// but I add all of them here for reference and future proofing.
if (type === 'unavailable' || type === 'probe' || type === 'error' || type === 'unsubscribe' || type === 'unsubscribed' || type === 'subscribe' || type === 'subscribed') {
@ -41165,7 +41401,7 @@ return Backbone.BrowserStorage;
} else if (_.isUndefined(i18n)) {
finishInitialization();
} else {
i18n.fetchTranslations(_converse.locale, _converse.locales, _.template(_converse.locales_url)({
i18n.fetchTranslations(_converse.locale, _converse.locales, u.interpolate(_converse.locales_url, {
'locale': _converse.locale
})).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL)).then(finishInitialization).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}
@ -41233,9 +41469,9 @@ return Backbone.BrowserStorage;
},
'settings': {
'update': function update(settings) {
utils.merge(_converse.default_settings, settings);
utils.merge(_converse, settings);
utils.applyUserSettings(_converse, settings, _converse.user_settings);
u.merge(_converse.default_settings, settings);
u.merge(_converse, settings);
u.applyUserSettings(_converse, settings, _converse.user_settings);
},
'get': function get(key) {
if (_.includes(_.keys(_converse.default_settings), key)) {
@ -41359,10 +41595,10 @@ return Backbone.BrowserStorage;
'b64_sha1': b64_sha1,
'moment': moment,
'sizzle': sizzle,
'utils': utils
'utils': u
}
};
window.dispatchEvent(new Event('converse-loaded'));
window.dispatchEvent(new CustomEvent('converse-loaded'));
return window.converse;
});
//# sourceMappingURL=converse-core.js.map;
@ -41617,6 +41853,7 @@ return Backbone.BrowserStorage;
_converse.ChatBox = Backbone.Model.extend({
defaults: {
'type': 'chatbox',
'show_avatar': true,
'bookmarked': false,
'chat_state': undefined,
'num_unread': 0,
@ -44470,9 +44707,9 @@ __e(o.avatar_height) +
'px" width="' +
__e(o.avatar_width) +
'px"\n src="data:' +
__e(o.image_type) +
__e(o.image_type || o._converse.DEFAULT_IMAGE_TYPE) +
';base64,' +
__e(o.image) +
__e(o.image || o._converse.DEFAULT_IMAGE) +
'"/>\n ';
} ;
__p += '\n <div class="chat-title">\n ';
@ -44938,6 +45175,7 @@ return __p
},
render: function render() {
this.el.innerHTML = tpl_chatbox_head(_.extend(this.model.toJSON(), {
'_converse': _converse,
'avatar_width': _converse.chatview_avatar_width,
'avatar_height': _converse.chatview_avatar_height,
'info_close': __('Close this chat box')
@ -46266,7 +46504,7 @@ Strophe.addConnectionPlugin('disco',
this.waitUntilFeaturesDiscovered = utils.getResolveablePromise();
this.features = new Backbone.Collection();
this.features.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.features-".concat(this.get('jid'))));
this.features.on('add', this.onFeatureAdded);
this.features.on('add', this.onFeatureAdded, this);
this.identities = new Backbone.Collection();
this.identities.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.identities-".concat(this.get('jid'))));
this.fetchFeatures();
@ -46323,6 +46561,8 @@ Strophe.addConnectionPlugin('disco',
});
},
onFeatureAdded: function onFeatureAdded(feature) {
feature.entity = this;
_converse.emit('serviceDiscovered', feature);
},
fetchFeatures: function fetchFeatures() {
@ -47531,7 +47771,7 @@ __p += '\n<ul class="features-list">\n';
if (o.passwordprotected) { ;
__p += '\n<li class="feature" title="' +
__e( o.tt_passwordprotected ) +
'"><span class="icon-lock-2"></span>' +
'"><span class="icon-lock"></span>' +
__e( o.label_passwordprotected ) +
'</li>\n';
} ;
@ -49598,8 +49838,8 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
* specified in XEP-0045 Multi-user chat.
*/
(function (root, factory) {
define('converse-muc',["form-utils", "converse-core", "lodash.fp", "tpl!chatarea", "tpl!chatroom", "tpl!chatroom_disconnect", "tpl!chatroom_features", "tpl!chatroom_form", "tpl!chatroom_head", "tpl!chatroom_invite", "tpl!chatroom_join_form", "tpl!chatroom_nickname_form", "tpl!chatroom_password_form", "tpl!chatroom_sidebar", "tpl!chatroom_toolbar", "tpl!chatrooms_tab", "tpl!info", "tpl!occupant", "tpl!room_description", "tpl!room_item", "tpl!room_panel", "tpl!rooms_results", "tpl!spinner", "awesomplete", "converse-chatview", "converse-disco", "backbone.overview", "backbone.orderedlistview", "backbone.vdomview"], factory);
})(this, function (u, converse, fp, tpl_chatarea, tpl_chatroom, tpl_chatroom_disconnect, tpl_chatroom_features, tpl_chatroom_form, tpl_chatroom_head, tpl_chatroom_invite, tpl_chatroom_join_form, tpl_chatroom_nickname_form, tpl_chatroom_password_form, tpl_chatroom_sidebar, tpl_chatroom_toolbar, tpl_chatrooms_tab, tpl_info, tpl_occupant, tpl_room_description, tpl_room_item, tpl_room_panel, tpl_rooms_results, tpl_spinner, Awesomplete) {
define('converse-muc',["form-utils", "converse-core", "emojione", "lodash.fp", "tpl!chatarea", "tpl!chatroom", "tpl!chatroom_disconnect", "tpl!chatroom_features", "tpl!chatroom_form", "tpl!chatroom_head", "tpl!chatroom_invite", "tpl!chatroom_join_form", "tpl!chatroom_nickname_form", "tpl!chatroom_password_form", "tpl!chatroom_sidebar", "tpl!chatroom_toolbar", "tpl!chatrooms_tab", "tpl!info", "tpl!occupant", "tpl!room_description", "tpl!room_item", "tpl!room_panel", "tpl!rooms_results", "tpl!spinner", "awesomplete", "converse-chatview", "converse-disco", "backbone.overview", "backbone.orderedlistview", "backbone.vdomview"], factory);
})(this, function (u, converse, emojione, f, tpl_chatarea, tpl_chatroom, tpl_chatroom_disconnect, tpl_chatroom_features, tpl_chatroom_form, tpl_chatroom_head, tpl_chatroom_invite, tpl_chatroom_join_form, tpl_chatroom_nickname_form, tpl_chatroom_password_form, tpl_chatroom_sidebar, tpl_chatroom_toolbar, tpl_chatrooms_tab, tpl_info, tpl_occupant, tpl_room_description, tpl_room_item, tpl_room_panel, tpl_rooms_results, tpl_spinner, Awesomplete) {
"use strict";
var ROOMS_PANEL_ID = 'chatrooms';
@ -50526,6 +50766,8 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
* Parameters:
* (String) text: The message text to be sent.
*/
text = emojione.shortnameToUnicode(text);
var msgid = _converse.connection.getUniqueId();
var msg = $msg({
@ -52255,11 +52497,11 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
renderTab: function renderTab() {
var controlbox = _converse.chatboxes.get('controlbox');
var chatrooms = fp.filter(_.partial(u.isOfType, CHATROOMS_TYPE), _converse.chatboxes.models);
var chatrooms = f.filter(_.partial(u.isOfType, CHATROOMS_TYPE), _converse.chatboxes.models);
this.tab_el.innerHTML = tpl_chatrooms_tab({
'label_rooms': __('Rooms'),
'is_current': controlbox.get('active-panel') === ROOMS_PANEL_ID,
'num_unread': fp.sum(fp.map(fp.curry(u.getAttribute)('num_unread'), chatrooms))
'num_unread': f.sum(f.map(f.curry(u.getAttribute)('num_unread'), chatrooms))
});
},
insertIntoDOM: function insertIntoDOM() {
@ -52491,7 +52733,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
* (XMLElement) message: The message stanza containing the
* invitation.
*/
var x_el = message.querySelector('x[xmlns="jabber:x:conference"]'),
var x_el = sizzle('x[xmlns="jabber:x:conference"]', message).pop(),
from = Strophe.getBareJidFromJid(message.getAttribute('from')),
room_jid = x_el.getAttribute('jid'),
reason = x_el.getAttribute('reason');
@ -52695,11 +52937,11 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
function setMUCDomainFromDisco(controlboxview) {
/* Check whether service discovery for the user's domain
* returned MUC information and use that to automatically
* set the MUC domain for the "Rooms" panel of the controlbox.
*/
* returned MUC information and use that to automatically
* set the MUC domain for the "Rooms" panel of the controlbox.
*/
function featureAdded(feature) {
if (feature.get('var') === Strophe.NS.MUC) {
if (feature.get('var') === Strophe.NS.MUC && f.includes('conference', feature.entity.identities.pluck('category'))) {
setMUCDomain(feature.get('from'), controlboxview);
}
}

View File

@ -2,7 +2,7 @@
*
* An XMPP chat client that runs in the browser.
*
* Version: 3.3.3
* Version: 3.3.4
*/
/* jshint ignore:start */
@ -2735,6 +2735,17 @@ define('lodash.fp',['lodash', 'lodash.converter'], function (_, lodashConverter)
return fp;
});
function CustomEvent ( event, params ) {
params = params || { bubbles: false, cancelable: false, detail: undefined };
var evt = document.createEvent( 'CustomEvent' );
evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
return evt;
}
if ( typeof window.CustomEvent !== "function" ) {
CustomEvent.prototype = window.Event.prototype;
window.CustomEvent = CustomEvent;
}
if (!String.prototype.includes) {
String.prototype.includes = function(search, start) {
'use strict';
@ -3885,6 +3896,97 @@ return af;
})));
//! moment.js locale configuration
//! locale : Bulgarian [bg]
//! author : Krasen Borisov : https://github.com/kraz
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define('moment/locale/bg',['../moment'], factory) :
factory(global.moment)
}(this, (function (moment) { 'use strict';
var bg = moment.defineLocale('bg', {
months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),
monthsShort : 'янрев_мар_апрай_юни_юли_авг_сеп_окт_ноеек'.split('_'),
weekdays : еделя_понеделник_вторник_срядаетвъртък_петък_събота'.split('_'),
weekdaysShort : ед_пон_вто_сря_чет_пет_съб'.split('_'),
weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
longDateFormat : {
LT : 'H:mm',
LTS : 'H:mm:ss',
L : 'D.MM.YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY H:mm',
LLLL : 'dddd, D MMMM YYYY H:mm'
},
calendar : {
sameDay : '[Днес в] LT',
nextDay : '[Утре в] LT',
nextWeek : 'dddd [в] LT',
lastDay : '[Вчера в] LT',
lastWeek : function () {
switch (this.day()) {
case 0:
case 3:
case 6:
return '[В изминалата] dddd [в] LT';
case 1:
case 2:
case 4:
case 5:
return '[В изминалия] dddd [в] LT';
}
},
sameElse : 'L'
},
relativeTime : {
future : 'след %s',
past : 'преди %s',
s : 'няколко секунди',
m : 'минута',
mm : '%d минути',
h : 'час',
hh : '%d часа',
d : 'ден',
dd : '%d дни',
M : 'месец',
MM : '%d месеца',
y : 'година',
yy : '%d години'
},
dayOfMonthOrdinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/,
ordinal : function (number) {
var lastDigit = number % 10,
last2Digits = number % 100;
if (number === 0) {
return number + '-ев';
} else if (last2Digits === 0) {
return number + '-ен';
} else if (last2Digits > 10 && last2Digits < 20) {
return number + '-ти';
} else if (lastDigit === 1) {
return number + '-ви';
} else if (lastDigit === 2) {
return number + '-ри';
} else if (lastDigit === 7 || lastDigit === 8) {
return number + '-ми';
} else {
return number + '-ти';
}
},
week : {
dow : 1, // Monday is the first day of the week.
doy : 7 // The week that contains Jan 1st is the first week of the year.
}
});
return bg;
})));
//! moment.js locale configuration
//! locale : Catalan [ca]
//! author : Juan G. Hurtado : https://github.com/juanghurtado
@ -5174,6 +5276,97 @@ return ru;
})));
//! moment.js locale configuration
//! locale : Turkish [tr]
//! authors : Erhan Gundogan : https://github.com/erhangundogan,
//! Burak Yiğit Kaya: https://github.com/BYK
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define('moment/locale/tr',['../moment'], factory) :
factory(global.moment)
}(this, (function (moment) { 'use strict';
var suffixes = {
1: '\'inci',
5: '\'inci',
8: '\'inci',
70: '\'inci',
80: '\'inci',
2: '\'nci',
7: '\'nci',
20: '\'nci',
50: '\'nci',
3: '\'üncü',
4: '\'üncü',
100: '\'üncü',
6: '\'ncı',
9: '\'uncu',
10: '\'uncu',
30: '\'uncu',
60: '\'ıncı',
90: '\'ıncı'
};
var tr = moment.defineLocale('tr', {
months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'),
monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),
weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'),
weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),
weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),
longDateFormat : {
LT : 'HH:mm',
LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY HH:mm',
LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[bugün saat] LT',
nextDay : '[yarın saat] LT',
nextWeek : '[haftaya] dddd [saat] LT',
lastDay : '[dün] LT',
lastWeek : '[geçen hafta] dddd [saat] LT',
sameElse : 'L'
},
relativeTime : {
future : '%s sonra',
past : '%s önce',
s : 'birkaç saniye',
m : 'bir dakika',
mm : '%d dakika',
h : 'bir saat',
hh : '%d saat',
d : 'bir gün',
dd : '%d gün',
M : 'bir ay',
MM : '%d ay',
y : 'bir yıl',
yy : '%d yıl'
},
dayOfMonthOrdinalParse: /\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,
ordinal : function (number) {
if (number === 0) { // special case for zero
return number + '\'ıncı';
}
var a = number % 10,
b = number % 100 - a,
c = number >= 100 ? 100 : null;
return number + (suffixes[a] || suffixes[b] || suffixes[c]);
},
week : {
dow : 1, // Monday is the first day of the week.
doy : 7 // The week that contains Jan 1st is the first week of the year.
}
});
return tr;
})));
//! moment.js locale configuration
//! locale : Ukrainian [uk]
//! author : zemlanin : https://github.com/zemlanin
@ -5554,7 +5747,7 @@ return zhTw;
/*global define */
(function (root, factory) {
define('i18n',["es6-promise", "jed", "lodash.noconflict", "moment", 'moment/locale/af', 'moment/locale/ca', 'moment/locale/de', 'moment/locale/es', 'moment/locale/fr', 'moment/locale/he', 'moment/locale/hu', 'moment/locale/id', 'moment/locale/it', 'moment/locale/ja', 'moment/locale/nb', 'moment/locale/nl', 'moment/locale/pl', 'moment/locale/pt-br', 'moment/locale/ru', 'moment/locale/uk', 'moment/locale/zh-cn', 'moment/locale/zh-tw'], factory);
define('i18n',["es6-promise", "jed", "lodash.noconflict", "moment", 'moment/locale/af', 'moment/locale/bg', 'moment/locale/ca', 'moment/locale/de', 'moment/locale/es', 'moment/locale/fr', 'moment/locale/he', 'moment/locale/hu', 'moment/locale/id', 'moment/locale/it', 'moment/locale/ja', 'moment/locale/nb', 'moment/locale/nl', 'moment/locale/pl', 'moment/locale/pt-br', 'moment/locale/ru', 'moment/locale/tr', 'moment/locale/uk', 'moment/locale/zh-cn', 'moment/locale/zh-tw'], factory);
})(this, function (Promise, Jed, _, moment) {
'use strict';
@ -6356,6 +6549,42 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
return promise;
};
u.interpolate = function (string, o) {
return string.replace(/{{{([^{}]*)}}}/g, function (a, b) {
var r = o[b];
return typeof r === 'string' || typeof r === 'number' ? r : a;
});
};
u.onMultipleEvents = function () {
var events = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
var callback = arguments.length > 1 ? arguments[1] : undefined;
/* Call the callback once all the events have been triggered
*
* Parameters:
* (Array) events: An array of objects, with keys `object` and
* `event`, representing the event name and the object it's
* triggered upon.
* (Function) callback: The function to call once all events have
* been triggered.
*/
var triggered = [];
function handler(result) {
triggered.push(result);
if (events.length === triggered.length) {
callback(triggered);
triggered = [];
}
}
_.each(events, function (map) {
return map.object.on(map.event, handler);
});
};
u.safeSave = function (model, attributes) {
if (u.isPersistableModel(model)) {
model.save(attributes);
@ -6365,7 +6594,11 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
};
u.isVisible = function (el) {
// XXX: Taken from jQuery's "visible" implementation
if (u.hasClass('hidden', el)) {
return false;
} // XXX: Taken from jQuery's "visible" implementation
return el.offsetWidth > 0 || el.offsetHeight > 0 || el.getClientRects().length > 0;
};
@ -6845,7 +7078,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
/*global Backbone, define, window, JSON */
(function (root, factory) {
define('converse-core',["sizzle", "es6-promise", "lodash.noconflict", "lodash.fp", "polyfill", "i18n", "utils", "moment", "strophe", "pluggable", "backbone.noconflict", "backbone.nativeview", "backbone.browserStorage"], factory);
})(this, function (sizzle, Promise, _, f, polyfill, i18n, utils, moment, Strophe, pluggable, Backbone) {
})(this, function (sizzle, Promise, _, f, polyfill, i18n, u, moment, Strophe, pluggable, Backbone) {
/* Cannot use this due to Safari bug.
* See https://github.com/jcbrand/converse.js/issues/196
*/
@ -7017,7 +7250,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
/* Private function, used to add a new promise to the ones already
* available via the `waitUntil` api method.
*/
_converse.promises[promise] = utils.getResolveablePromise();
_converse.promises[promise] = u.getResolveablePromise();
}
_converse.emit = function (name) {
@ -7039,7 +7272,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
var _this = this;
settings = !_.isUndefined(settings) ? settings : {};
var init_promise = utils.getResolveablePromise();
var init_promise = u.getResolveablePromise();
_.each(PROMISES, addPromise);
@ -7123,7 +7356,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
jid: undefined,
keepalive: true,
locales_url: 'locale/{{{locale}}}/LC_MESSAGES/converse.json',
locales: ['af', 'ca', 'de', 'es', 'en', 'fr', 'he', 'hu', 'id', 'it', 'ja', 'nb', 'nl', 'pl', 'pt_BR', 'ru', 'uk', 'zh_CN', 'zh_TW'],
locales: ['af', 'bg', 'ca', 'de', 'es', 'en', 'fr', 'he', 'hu', 'id', 'it', 'ja', 'nb', 'nl', 'pl', 'pt_BR', 'ru', 'tr', 'uk', 'zh_CN', 'zh_TW'],
message_carbons: true,
message_storage: 'session',
password: undefined,
@ -7470,7 +7703,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
this.initStatus = function () {
return new Promise(function (resolve, reject) {
var promise = new utils.getResolveablePromise();
var promise = new u.getResolveablePromise();
_this.xmppstatus = new _this.XMPPStatus();
var id = b64_sha1("converse.xmppstatus-".concat(_converse.bare_jid));
_this.xmppstatus.id = id; // Appears to be necessary for backbone.browserStorage
@ -7515,7 +7748,10 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
_converse.connection.disconnect();
} else {
_converse._tearDown();
}
} // Recreate all the promises
_.each(_.keys(_converse.promises), addPromise);
_converse.emit('logout');
};
@ -7766,9 +8002,9 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
initialize: function initialize(attributes) {
var _this3 = this;
var jid = attributes.jid;
var bare_jid = Strophe.getBareJidFromJid(jid).toLowerCase();
var resource = Strophe.getResourceFromJid(jid);
var jid = attributes.jid,
bare_jid = Strophe.getBareJidFromJid(jid).toLowerCase(),
resource = Strophe.getResourceFromJid(jid);
attributes.jid = bare_jid;
this.set(_.assignIn({
'fullname': bare_jid,
@ -8041,7 +8277,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
return true;
},
isSelf: function isSelf(jid) {
return utils.isSameBareJID(jid, _converse.connection.jid);
return u.isSameBareJID(jid, _converse.connection.jid);
},
addAndSubscribe: function addAndSubscribe(jid, name, groups, message, attributes) {
/* Add a roster contact and then once we have confirmation from
@ -8445,7 +8681,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
constructPresence: function constructPresence(type, status_message) {
var presence;
type = _.isString(type) ? type : this.get('status') || _converse.default_state;
status_message = _.isString(status_message) ? status_message : undefined; // Most of these presence types are actually not explicitly sent,
status_message = _.isString(status_message) ? status_message : this.get('status_message'); // Most of these presence types are actually not explicitly sent,
// but I add all of them here for reference and future proofing.
if (type === 'unavailable' || type === 'probe' || type === 'error' || type === 'unsubscribe' || type === 'unsubscribed' || type === 'subscribe' || type === 'subscribed') {
@ -8814,7 +9050,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
} else if (_.isUndefined(i18n)) {
finishInitialization();
} else {
i18n.fetchTranslations(_converse.locale, _converse.locales, _.template(_converse.locales_url)({
i18n.fetchTranslations(_converse.locale, _converse.locales, u.interpolate(_converse.locales_url, {
'locale': _converse.locale
})).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL)).then(finishInitialization).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}
@ -8882,9 +9118,9 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
},
'settings': {
'update': function update(settings) {
utils.merge(_converse.default_settings, settings);
utils.merge(_converse, settings);
utils.applyUserSettings(_converse, settings, _converse.user_settings);
u.merge(_converse.default_settings, settings);
u.merge(_converse, settings);
u.applyUserSettings(_converse, settings, _converse.user_settings);
},
'get': function get(key) {
if (_.includes(_.keys(_converse.default_settings), key)) {
@ -9008,10 +9244,10 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
'b64_sha1': b64_sha1,
'moment': moment,
'sizzle': sizzle,
'utils': utils
'utils': u
}
};
window.dispatchEvent(new Event('converse-loaded'));
window.dispatchEvent(new CustomEvent('converse-loaded'));
return window.converse;
});
//# sourceMappingURL=converse-core.js.map;
@ -9104,6 +9340,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
_converse.ChatBox = Backbone.Model.extend({
defaults: {
'type': 'chatbox',
'show_avatar': true,
'bookmarked': false,
'chat_state': undefined,
'num_unread': 0,
@ -11957,9 +12194,9 @@ __e(o.avatar_height) +
'px" width="' +
__e(o.avatar_width) +
'px"\n src="data:' +
__e(o.image_type) +
__e(o.image_type || o._converse.DEFAULT_IMAGE_TYPE) +
';base64,' +
__e(o.image) +
__e(o.image || o._converse.DEFAULT_IMAGE) +
'"/>\n ';
} ;
__p += '\n <div class="chat-title">\n ';
@ -12425,6 +12662,7 @@ return __p
},
render: function render() {
this.el.innerHTML = tpl_chatbox_head(_.extend(this.model.toJSON(), {
'_converse': _converse,
'avatar_width': _converse.chatview_avatar_width,
'avatar_height': _converse.chatview_avatar_height,
'info_close': __('Close this chat box')
@ -15585,7 +15823,7 @@ return __p
ev.preventDefault();
}
var tab = ev.target,
var tab = u.hasClass('msgs-indicator', ev.target) ? ev.target.parentNode : ev.target,
sibling_li = tab.parentNode.nextElementSibling || tab.parentNode.previousElementSibling,
sibling = sibling_li.firstChild,
sibling_panel = _converse.root.querySelector(sibling.getAttribute('href')),
@ -16385,7 +16623,7 @@ __p += '\n<ul class="features-list">\n';
if (o.passwordprotected) { ;
__p += '\n<li class="feature" title="' +
__e( o.tt_passwordprotected ) +
'"><span class="icon-lock-2"></span>' +
'"><span class="icon-lock"></span>' +
__e( o.label_passwordprotected ) +
'</li>\n';
} ;
@ -16904,7 +17142,7 @@ return __p
this.waitUntilFeaturesDiscovered = utils.getResolveablePromise();
this.features = new Backbone.Collection();
this.features.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.features-".concat(this.get('jid'))));
this.features.on('add', this.onFeatureAdded);
this.features.on('add', this.onFeatureAdded, this);
this.identities = new Backbone.Collection();
this.identities.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.identities-".concat(this.get('jid'))));
this.fetchFeatures();
@ -16961,6 +17199,8 @@ return __p
});
},
onFeatureAdded: function onFeatureAdded(feature) {
feature.entity = this;
_converse.emit('serviceDiscovered', feature);
},
fetchFeatures: function fetchFeatures() {
@ -18256,8 +18496,8 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
* specified in XEP-0045 Multi-user chat.
*/
(function (root, factory) {
define('converse-muc',["form-utils", "converse-core", "lodash.fp", "tpl!chatarea", "tpl!chatroom", "tpl!chatroom_disconnect", "tpl!chatroom_features", "tpl!chatroom_form", "tpl!chatroom_head", "tpl!chatroom_invite", "tpl!chatroom_join_form", "tpl!chatroom_nickname_form", "tpl!chatroom_password_form", "tpl!chatroom_sidebar", "tpl!chatroom_toolbar", "tpl!chatrooms_tab", "tpl!info", "tpl!occupant", "tpl!room_description", "tpl!room_item", "tpl!room_panel", "tpl!rooms_results", "tpl!spinner", "awesomplete", "converse-chatview", "converse-disco", "backbone.overview", "backbone.orderedlistview", "backbone.vdomview"], factory);
})(this, function (u, converse, fp, tpl_chatarea, tpl_chatroom, tpl_chatroom_disconnect, tpl_chatroom_features, tpl_chatroom_form, tpl_chatroom_head, tpl_chatroom_invite, tpl_chatroom_join_form, tpl_chatroom_nickname_form, tpl_chatroom_password_form, tpl_chatroom_sidebar, tpl_chatroom_toolbar, tpl_chatrooms_tab, tpl_info, tpl_occupant, tpl_room_description, tpl_room_item, tpl_room_panel, tpl_rooms_results, tpl_spinner, Awesomplete) {
define('converse-muc',["form-utils", "converse-core", "emojione", "lodash.fp", "tpl!chatarea", "tpl!chatroom", "tpl!chatroom_disconnect", "tpl!chatroom_features", "tpl!chatroom_form", "tpl!chatroom_head", "tpl!chatroom_invite", "tpl!chatroom_join_form", "tpl!chatroom_nickname_form", "tpl!chatroom_password_form", "tpl!chatroom_sidebar", "tpl!chatroom_toolbar", "tpl!chatrooms_tab", "tpl!info", "tpl!occupant", "tpl!room_description", "tpl!room_item", "tpl!room_panel", "tpl!rooms_results", "tpl!spinner", "awesomplete", "converse-chatview", "converse-disco", "backbone.overview", "backbone.orderedlistview", "backbone.vdomview"], factory);
})(this, function (u, converse, emojione, f, tpl_chatarea, tpl_chatroom, tpl_chatroom_disconnect, tpl_chatroom_features, tpl_chatroom_form, tpl_chatroom_head, tpl_chatroom_invite, tpl_chatroom_join_form, tpl_chatroom_nickname_form, tpl_chatroom_password_form, tpl_chatroom_sidebar, tpl_chatroom_toolbar, tpl_chatrooms_tab, tpl_info, tpl_occupant, tpl_room_description, tpl_room_item, tpl_room_panel, tpl_rooms_results, tpl_spinner, Awesomplete) {
"use strict";
var ROOMS_PANEL_ID = 'chatrooms';
@ -19184,6 +19424,8 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
* Parameters:
* (String) text: The message text to be sent.
*/
text = emojione.shortnameToUnicode(text);
var msgid = _converse.connection.getUniqueId();
var msg = $msg({
@ -20913,11 +21155,11 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
renderTab: function renderTab() {
var controlbox = _converse.chatboxes.get('controlbox');
var chatrooms = fp.filter(_.partial(u.isOfType, CHATROOMS_TYPE), _converse.chatboxes.models);
var chatrooms = f.filter(_.partial(u.isOfType, CHATROOMS_TYPE), _converse.chatboxes.models);
this.tab_el.innerHTML = tpl_chatrooms_tab({
'label_rooms': __('Rooms'),
'is_current': controlbox.get('active-panel') === ROOMS_PANEL_ID,
'num_unread': fp.sum(fp.map(fp.curry(u.getAttribute)('num_unread'), chatrooms))
'num_unread': f.sum(f.map(f.curry(u.getAttribute)('num_unread'), chatrooms))
});
},
insertIntoDOM: function insertIntoDOM() {
@ -21149,7 +21391,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
* (XMLElement) message: The message stanza containing the
* invitation.
*/
var x_el = message.querySelector('x[xmlns="jabber:x:conference"]'),
var x_el = sizzle('x[xmlns="jabber:x:conference"]', message).pop(),
from = Strophe.getBareJidFromJid(message.getAttribute('from')),
room_jid = x_el.getAttribute('jid'),
reason = x_el.getAttribute('reason');
@ -21353,11 +21595,11 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
function setMUCDomainFromDisco(controlboxview) {
/* Check whether service discovery for the user's domain
* returned MUC information and use that to automatically
* set the MUC domain for the "Rooms" panel of the controlbox.
*/
* returned MUC information and use that to automatically
* set the MUC domain for the "Rooms" panel of the controlbox.
*/
function featureAdded(feature) {
if (feature.get('var') === Strophe.NS.MUC) {
if (feature.get('var') === Strophe.NS.MUC && f.includes('conference', feature.entity.identities.pluck('category'))) {
setMUCDomain(feature.get('from'), controlboxview);
}
}
@ -21594,12 +21836,10 @@ return __p
var _converse = this.__super__._converse;
if (_converse.allow_bookmarks) {
_converse.api.disco.getIdentity('pubsub', 'pep', _converse.bare_jid).then(function (identity) {
if (_.isNil(identity)) {
return;
_converse.checkBookmarksSupport().then(function (supported) {
if (supported) {
_this.renderBookmarkToggle();
}
_this.renderBookmarkToggle();
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}
},
@ -22050,38 +22290,42 @@ return __p
}
});
_converse.checkBookmarksSupport = function () {
return new Promise(function (resolve, reject) {
Promise.all([_converse.api.disco.getIdentity('pubsub', 'pep', _converse.bare_jid), _converse.api.disco.supports(Strophe.NS.PUBSUB + '#publish-options', _converse.bare_jid)]).then(function (args) {
resolve(args[0] && (args[1].supported || _converse.allow_public_bookmarks));
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
};
var initBookmarks = function initBookmarks() {
if (!_converse.allow_bookmarks) {
return;
}
Promise.all([_converse.api.disco.getIdentity('pubsub', 'pep', _converse.bare_jid), _converse.api.disco.supports(Strophe.NS.PUBSUB + '#publish-options', _converse.bare_jid)]).then(function (args) {
var identity = args[0],
options_support = args[1];
if (_.isNil(identity) || !options_support.supported && !_converse.allow_public_bookmarks) {
_converse.emit('bookmarksInitialized');
return;
}
_converse.bookmarks = new _converse.Bookmarks();
_converse.bookmarks.fetchBookmarks().then(function () {
_converse.checkBookmarksSupport().then(function (supported) {
if (supported) {
_converse.bookmarks = new _converse.Bookmarks();
_converse.bookmarksview = new _converse.BookmarksView({
'model': _converse.bookmarks
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.ERROR)).then(function () {
_converse.emit('bookmarksInitialized');
});
}).catch(function (e) {
_converse.log(e, Strophe.LogLevel.ERROR);
_converse.emit('bookmarksInitialized');
_converse.bookmarks.fetchBookmarks().catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL)).then(function () {
return _converse.emit('bookmarksInitialized');
});
} else {
_converse.emit('bookmarksInitialized');
}
});
};
Promise.all([_converse.api.waitUntil('chatBoxesFetched'), _converse.api.waitUntil('roomsPanelRendered')]).then(initBookmarks).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
u.onMultipleEvents([{
'object': _converse,
'event': 'chatBoxesFetched'
}, {
'object': _converse,
'event': 'roomsPanelRendered'
}], initBookmarks);
_converse.on('connected', function () {
// Add a handler for bookmarks pushed from other connected clients
@ -22300,7 +22544,11 @@ return __p
},
toHTML: function toHTML() {
return tpl_rooms_list_item(_.extend(this.model.toJSON(), {
'allow_bookmarks': _converse.allow_bookmarks,
// XXX: By the time this renders, the _converse.bookmarks
// collection should already exist if bookmarks are
// supported by the XMPP server. So we can use it
// as a check for support (other ways of checking are async).
'allow_bookmarks': _converse.allow_bookmarks && _converse.bookmarks,
'info_leave_room': __('Leave this room'),
'info_remove_bookmark': __('Unbookmark this room'),
'info_add_bookmark': __('Bookmark this room'),
@ -22421,13 +22669,26 @@ return __p
});
};
Promise.all([_converse.api.waitUntil('chatBoxesFetched'), _converse.api.waitUntil('roomsPanelRendered')]).then(function () {
if (_converse.allow_bookmarks) {
_converse.api.waitUntil('bookmarksInitialized').then(initRoomsListView);
} else {
initRoomsListView();
}
});
if (_converse.allow_bookmarks) {
u.onMultipleEvents([{
'object': _converse,
'event': 'chatBoxesFetched'
}, {
'object': _converse,
'event': 'roomsPanelRendered'
}, {
'object': _converse,
'event': 'bookmarksInitialized'
}], initRoomsListView);
} else {
u.onMultipleEvents([{
'object': _converse,
'event': 'chatBoxesFetched'
}, {
'object': _converse,
'event': 'roomsPanelRendered'
}], initRoomsListView);
}
_converse.api.listen.on('reconnected', initRoomsListView);
}
@ -23039,7 +23300,9 @@ __p += '\n <li class="toggle-toolbar-menu toggle-otr ' +
__e(o.otr_status_class) +
'" title="' +
__e(o.otr_tooltip) +
'">\n ';
'">\n <span class="chat-toolbar-text">' +
__e(o.otr_translated_status) +
'</span>\n ';
if (o.otr_status == o.UNENCRYPTED) { ;
__p += '\n <span class="icon-unlocked"></span>\n ';
} ;
@ -23554,7 +23817,7 @@ return __p
otr_tooltip: this.getOTRTooltip(),
otr_translated_status: OTR_TRANSLATED_MAPPING[data.otr_status]
});
this.el.querySelector('.chat-toolbar').insertAdjacentHTML('beforeend', tpl_toolbar_otr(_.extend(this.model.toJSON(), options || {})));
this.el.querySelector('.chat-toolbar').insertAdjacentHTML('beforeend', tpl_toolbar_otr(_.extend(data, options || {})));
},
getToolbarOptions: function getToolbarOptions(options) {
options = this.__super__.getToolbarOptions();
@ -25451,12 +25714,6 @@ return __p
_converse.chatboxviews.trimChats(chatbox);
}
});
var logOut = function logOut() {
_converse.minimized_chats.remove();
};
_converse.on('logout', logOut);
}
});
});
@ -26170,7 +26427,7 @@ return __p
_ = _converse$env._;
converse.plugins.add('converse-fullscreen', {
enabled: function enabled(_converse) {
return _.includes(['mobile', 'fullscreen', 'embedded'], _converse.view_mode);
return _.includes(['fullscreen', 'embedded'], _converse.view_mode);
},
overrides: {
// overrides mentioned here will be picked up by converse.js's

409
dist/converse.js vendored
View File

@ -2,7 +2,7 @@
*
* An XMPP chat client that runs in the browser.
*
* Version: 3.3.3
* Version: 3.3.4
*/
/* jshint ignore:start */
@ -22063,6 +22063,17 @@ define('lodash.fp',['lodash', 'lodash.converter'], function (_, lodashConverter)
return fp;
});
function CustomEvent ( event, params ) {
params = params || { bubbles: false, cancelable: false, detail: undefined };
var evt = document.createEvent( 'CustomEvent' );
evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
return evt;
}
if ( typeof window.CustomEvent !== "function" ) {
CustomEvent.prototype = window.Event.prototype;
window.CustomEvent = CustomEvent;
}
if (!String.prototype.includes) {
String.prototype.includes = function(search, start) {
'use strict';
@ -27679,6 +27690,97 @@ return af;
})));
//! moment.js locale configuration
//! locale : Bulgarian [bg]
//! author : Krasen Borisov : https://github.com/kraz
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define('moment/locale/bg',['../moment'], factory) :
factory(global.moment)
}(this, (function (moment) { 'use strict';
var bg = moment.defineLocale('bg', {
months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),
monthsShort : 'янрев_мар_апрай_юни_юли_авг_сеп_окт_ноеек'.split('_'),
weekdays : еделя_понеделник_вторник_срядаетвъртък_петък_събота'.split('_'),
weekdaysShort : ед_пон_вто_сря_чет_пет_съб'.split('_'),
weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
longDateFormat : {
LT : 'H:mm',
LTS : 'H:mm:ss',
L : 'D.MM.YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY H:mm',
LLLL : 'dddd, D MMMM YYYY H:mm'
},
calendar : {
sameDay : '[Днес в] LT',
nextDay : '[Утре в] LT',
nextWeek : 'dddd [в] LT',
lastDay : '[Вчера в] LT',
lastWeek : function () {
switch (this.day()) {
case 0:
case 3:
case 6:
return '[В изминалата] dddd [в] LT';
case 1:
case 2:
case 4:
case 5:
return '[В изминалия] dddd [в] LT';
}
},
sameElse : 'L'
},
relativeTime : {
future : 'след %s',
past : 'преди %s',
s : 'няколко секунди',
m : 'минута',
mm : '%d минути',
h : 'час',
hh : '%d часа',
d : 'ден',
dd : '%d дни',
M : 'месец',
MM : '%d месеца',
y : 'година',
yy : '%d години'
},
dayOfMonthOrdinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/,
ordinal : function (number) {
var lastDigit = number % 10,
last2Digits = number % 100;
if (number === 0) {
return number + '-ев';
} else if (last2Digits === 0) {
return number + '-ен';
} else if (last2Digits > 10 && last2Digits < 20) {
return number + '-ти';
} else if (lastDigit === 1) {
return number + '-ви';
} else if (lastDigit === 2) {
return number + '-ри';
} else if (lastDigit === 7 || lastDigit === 8) {
return number + '-ми';
} else {
return number + '-ти';
}
},
week : {
dow : 1, // Monday is the first day of the week.
doy : 7 // The week that contains Jan 1st is the first week of the year.
}
});
return bg;
})));
//! moment.js locale configuration
//! locale : Catalan [ca]
//! author : Juan G. Hurtado : https://github.com/juanghurtado
@ -28968,6 +29070,97 @@ return ru;
})));
//! moment.js locale configuration
//! locale : Turkish [tr]
//! authors : Erhan Gundogan : https://github.com/erhangundogan,
//! Burak Yiğit Kaya: https://github.com/BYK
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define('moment/locale/tr',['../moment'], factory) :
factory(global.moment)
}(this, (function (moment) { 'use strict';
var suffixes = {
1: '\'inci',
5: '\'inci',
8: '\'inci',
70: '\'inci',
80: '\'inci',
2: '\'nci',
7: '\'nci',
20: '\'nci',
50: '\'nci',
3: '\'üncü',
4: '\'üncü',
100: '\'üncü',
6: '\'ncı',
9: '\'uncu',
10: '\'uncu',
30: '\'uncu',
60: '\'ıncı',
90: '\'ıncı'
};
var tr = moment.defineLocale('tr', {
months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'),
monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),
weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'),
weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),
weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),
longDateFormat : {
LT : 'HH:mm',
LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY HH:mm',
LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[bugün saat] LT',
nextDay : '[yarın saat] LT',
nextWeek : '[haftaya] dddd [saat] LT',
lastDay : '[dün] LT',
lastWeek : '[geçen hafta] dddd [saat] LT',
sameElse : 'L'
},
relativeTime : {
future : '%s sonra',
past : '%s önce',
s : 'birkaç saniye',
m : 'bir dakika',
mm : '%d dakika',
h : 'bir saat',
hh : '%d saat',
d : 'bir gün',
dd : '%d gün',
M : 'bir ay',
MM : '%d ay',
y : 'bir yıl',
yy : '%d yıl'
},
dayOfMonthOrdinalParse: /\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,
ordinal : function (number) {
if (number === 0) { // special case for zero
return number + '\'ıncı';
}
var a = number % 10,
b = number % 100 - a,
c = number >= 100 ? 100 : null;
return number + (suffixes[a] || suffixes[b] || suffixes[c]);
},
week : {
dow : 1, // Monday is the first day of the week.
doy : 7 // The week that contains Jan 1st is the first week of the year.
}
});
return tr;
})));
//! moment.js locale configuration
//! locale : Ukrainian [uk]
//! author : zemlanin : https://github.com/zemlanin
@ -29348,7 +29541,7 @@ return zhTw;
/*global define */
(function (root, factory) {
define('i18n',["es6-promise", "jed", "lodash.noconflict", "moment", 'moment/locale/af', 'moment/locale/ca', 'moment/locale/de', 'moment/locale/es', 'moment/locale/fr', 'moment/locale/he', 'moment/locale/hu', 'moment/locale/id', 'moment/locale/it', 'moment/locale/ja', 'moment/locale/nb', 'moment/locale/nl', 'moment/locale/pl', 'moment/locale/pt-br', 'moment/locale/ru', 'moment/locale/uk', 'moment/locale/zh-cn', 'moment/locale/zh-tw'], factory);
define('i18n',["es6-promise", "jed", "lodash.noconflict", "moment", 'moment/locale/af', 'moment/locale/bg', 'moment/locale/ca', 'moment/locale/de', 'moment/locale/es', 'moment/locale/fr', 'moment/locale/he', 'moment/locale/hu', 'moment/locale/id', 'moment/locale/it', 'moment/locale/ja', 'moment/locale/nb', 'moment/locale/nl', 'moment/locale/pl', 'moment/locale/pt-br', 'moment/locale/ru', 'moment/locale/tr', 'moment/locale/uk', 'moment/locale/zh-cn', 'moment/locale/zh-tw'], factory);
})(this, function (Promise, Jed, _, moment) {
'use strict';
@ -36494,6 +36687,42 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
return promise;
};
u.interpolate = function (string, o) {
return string.replace(/{{{([^{}]*)}}}/g, function (a, b) {
var r = o[b];
return typeof r === 'string' || typeof r === 'number' ? r : a;
});
};
u.onMultipleEvents = function () {
var events = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
var callback = arguments.length > 1 ? arguments[1] : undefined;
/* Call the callback once all the events have been triggered
*
* Parameters:
* (Array) events: An array of objects, with keys `object` and
* `event`, representing the event name and the object it's
* triggered upon.
* (Function) callback: The function to call once all events have
* been triggered.
*/
var triggered = [];
function handler(result) {
triggered.push(result);
if (events.length === triggered.length) {
callback(triggered);
triggered = [];
}
}
_.each(events, function (map) {
return map.object.on(map.event, handler);
});
};
u.safeSave = function (model, attributes) {
if (u.isPersistableModel(model)) {
model.save(attributes);
@ -36503,7 +36732,11 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
};
u.isVisible = function (el) {
// XXX: Taken from jQuery's "visible" implementation
if (u.hasClass('hidden', el)) {
return false;
} // XXX: Taken from jQuery's "visible" implementation
return el.offsetWidth > 0 || el.offsetHeight > 0 || el.getClientRects().length > 0;
};
@ -39196,7 +39429,7 @@ return Backbone.BrowserStorage;
/*global Backbone, define, window, JSON */
(function (root, factory) {
define('converse-core',["sizzle", "es6-promise", "lodash.noconflict", "lodash.fp", "polyfill", "i18n", "utils", "moment", "strophe", "pluggable", "backbone.noconflict", "backbone.nativeview", "backbone.browserStorage"], factory);
})(this, function (sizzle, Promise, _, f, polyfill, i18n, utils, moment, Strophe, pluggable, Backbone) {
})(this, function (sizzle, Promise, _, f, polyfill, i18n, u, moment, Strophe, pluggable, Backbone) {
/* Cannot use this due to Safari bug.
* See https://github.com/jcbrand/converse.js/issues/196
*/
@ -39368,7 +39601,7 @@ return Backbone.BrowserStorage;
/* Private function, used to add a new promise to the ones already
* available via the `waitUntil` api method.
*/
_converse.promises[promise] = utils.getResolveablePromise();
_converse.promises[promise] = u.getResolveablePromise();
}
_converse.emit = function (name) {
@ -39390,7 +39623,7 @@ return Backbone.BrowserStorage;
var _this = this;
settings = !_.isUndefined(settings) ? settings : {};
var init_promise = utils.getResolveablePromise();
var init_promise = u.getResolveablePromise();
_.each(PROMISES, addPromise);
@ -39474,7 +39707,7 @@ return Backbone.BrowserStorage;
jid: undefined,
keepalive: true,
locales_url: 'locale/{{{locale}}}/LC_MESSAGES/converse.json',
locales: ['af', 'ca', 'de', 'es', 'en', 'fr', 'he', 'hu', 'id', 'it', 'ja', 'nb', 'nl', 'pl', 'pt_BR', 'ru', 'uk', 'zh_CN', 'zh_TW'],
locales: ['af', 'bg', 'ca', 'de', 'es', 'en', 'fr', 'he', 'hu', 'id', 'it', 'ja', 'nb', 'nl', 'pl', 'pt_BR', 'ru', 'tr', 'uk', 'zh_CN', 'zh_TW'],
message_carbons: true,
message_storage: 'session',
password: undefined,
@ -39821,7 +40054,7 @@ return Backbone.BrowserStorage;
this.initStatus = function () {
return new Promise(function (resolve, reject) {
var promise = new utils.getResolveablePromise();
var promise = new u.getResolveablePromise();
_this.xmppstatus = new _this.XMPPStatus();
var id = b64_sha1("converse.xmppstatus-".concat(_converse.bare_jid));
_this.xmppstatus.id = id; // Appears to be necessary for backbone.browserStorage
@ -39866,7 +40099,10 @@ return Backbone.BrowserStorage;
_converse.connection.disconnect();
} else {
_converse._tearDown();
}
} // Recreate all the promises
_.each(_.keys(_converse.promises), addPromise);
_converse.emit('logout');
};
@ -40117,9 +40353,9 @@ return Backbone.BrowserStorage;
initialize: function initialize(attributes) {
var _this3 = this;
var jid = attributes.jid;
var bare_jid = Strophe.getBareJidFromJid(jid).toLowerCase();
var resource = Strophe.getResourceFromJid(jid);
var jid = attributes.jid,
bare_jid = Strophe.getBareJidFromJid(jid).toLowerCase(),
resource = Strophe.getResourceFromJid(jid);
attributes.jid = bare_jid;
this.set(_.assignIn({
'fullname': bare_jid,
@ -40392,7 +40628,7 @@ return Backbone.BrowserStorage;
return true;
},
isSelf: function isSelf(jid) {
return utils.isSameBareJID(jid, _converse.connection.jid);
return u.isSameBareJID(jid, _converse.connection.jid);
},
addAndSubscribe: function addAndSubscribe(jid, name, groups, message, attributes) {
/* Add a roster contact and then once we have confirmation from
@ -40796,7 +41032,7 @@ return Backbone.BrowserStorage;
constructPresence: function constructPresence(type, status_message) {
var presence;
type = _.isString(type) ? type : this.get('status') || _converse.default_state;
status_message = _.isString(status_message) ? status_message : undefined; // Most of these presence types are actually not explicitly sent,
status_message = _.isString(status_message) ? status_message : this.get('status_message'); // Most of these presence types are actually not explicitly sent,
// but I add all of them here for reference and future proofing.
if (type === 'unavailable' || type === 'probe' || type === 'error' || type === 'unsubscribe' || type === 'unsubscribed' || type === 'subscribe' || type === 'subscribed') {
@ -41165,7 +41401,7 @@ return Backbone.BrowserStorage;
} else if (_.isUndefined(i18n)) {
finishInitialization();
} else {
i18n.fetchTranslations(_converse.locale, _converse.locales, _.template(_converse.locales_url)({
i18n.fetchTranslations(_converse.locale, _converse.locales, u.interpolate(_converse.locales_url, {
'locale': _converse.locale
})).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL)).then(finishInitialization).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}
@ -41233,9 +41469,9 @@ return Backbone.BrowserStorage;
},
'settings': {
'update': function update(settings) {
utils.merge(_converse.default_settings, settings);
utils.merge(_converse, settings);
utils.applyUserSettings(_converse, settings, _converse.user_settings);
u.merge(_converse.default_settings, settings);
u.merge(_converse, settings);
u.applyUserSettings(_converse, settings, _converse.user_settings);
},
'get': function get(key) {
if (_.includes(_.keys(_converse.default_settings), key)) {
@ -41359,10 +41595,10 @@ return Backbone.BrowserStorage;
'b64_sha1': b64_sha1,
'moment': moment,
'sizzle': sizzle,
'utils': utils
'utils': u
}
};
window.dispatchEvent(new Event('converse-loaded'));
window.dispatchEvent(new CustomEvent('converse-loaded'));
return window.converse;
});
//# sourceMappingURL=converse-core.js.map;
@ -41617,6 +41853,7 @@ return Backbone.BrowserStorage;
_converse.ChatBox = Backbone.Model.extend({
defaults: {
'type': 'chatbox',
'show_avatar': true,
'bookmarked': false,
'chat_state': undefined,
'num_unread': 0,
@ -44470,9 +44707,9 @@ __e(o.avatar_height) +
'px" width="' +
__e(o.avatar_width) +
'px"\n src="data:' +
__e(o.image_type) +
__e(o.image_type || o._converse.DEFAULT_IMAGE_TYPE) +
';base64,' +
__e(o.image) +
__e(o.image || o._converse.DEFAULT_IMAGE) +
'"/>\n ';
} ;
__p += '\n <div class="chat-title">\n ';
@ -44938,6 +45175,7 @@ return __p
},
render: function render() {
this.el.innerHTML = tpl_chatbox_head(_.extend(this.model.toJSON(), {
'_converse': _converse,
'avatar_width': _converse.chatview_avatar_width,
'avatar_height': _converse.chatview_avatar_height,
'info_close': __('Close this chat box')
@ -48169,7 +48407,7 @@ return __p
ev.preventDefault();
}
var tab = ev.target,
var tab = u.hasClass('msgs-indicator', ev.target) ? ev.target.parentNode : ev.target,
sibling_li = tab.parentNode.nextElementSibling || tab.parentNode.previousElementSibling,
sibling = sibling_li.firstChild,
sibling_panel = _converse.root.querySelector(sibling.getAttribute('href')),
@ -48969,7 +49207,7 @@ __p += '\n<ul class="features-list">\n';
if (o.passwordprotected) { ;
__p += '\n<li class="feature" title="' +
__e( o.tt_passwordprotected ) +
'"><span class="icon-lock-2"></span>' +
'"><span class="icon-lock"></span>' +
__e( o.label_passwordprotected ) +
'</li>\n';
} ;
@ -50268,7 +50506,7 @@ Strophe.addConnectionPlugin('disco',
this.waitUntilFeaturesDiscovered = utils.getResolveablePromise();
this.features = new Backbone.Collection();
this.features.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.features-".concat(this.get('jid'))));
this.features.on('add', this.onFeatureAdded);
this.features.on('add', this.onFeatureAdded, this);
this.identities = new Backbone.Collection();
this.identities.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.identities-".concat(this.get('jid'))));
this.fetchFeatures();
@ -50325,6 +50563,8 @@ Strophe.addConnectionPlugin('disco',
});
},
onFeatureAdded: function onFeatureAdded(feature) {
feature.entity = this;
_converse.emit('serviceDiscovered', feature);
},
fetchFeatures: function fetchFeatures() {
@ -51620,8 +51860,8 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
* specified in XEP-0045 Multi-user chat.
*/
(function (root, factory) {
define('converse-muc',["form-utils", "converse-core", "lodash.fp", "tpl!chatarea", "tpl!chatroom", "tpl!chatroom_disconnect", "tpl!chatroom_features", "tpl!chatroom_form", "tpl!chatroom_head", "tpl!chatroom_invite", "tpl!chatroom_join_form", "tpl!chatroom_nickname_form", "tpl!chatroom_password_form", "tpl!chatroom_sidebar", "tpl!chatroom_toolbar", "tpl!chatrooms_tab", "tpl!info", "tpl!occupant", "tpl!room_description", "tpl!room_item", "tpl!room_panel", "tpl!rooms_results", "tpl!spinner", "awesomplete", "converse-chatview", "converse-disco", "backbone.overview", "backbone.orderedlistview", "backbone.vdomview"], factory);
})(this, function (u, converse, fp, tpl_chatarea, tpl_chatroom, tpl_chatroom_disconnect, tpl_chatroom_features, tpl_chatroom_form, tpl_chatroom_head, tpl_chatroom_invite, tpl_chatroom_join_form, tpl_chatroom_nickname_form, tpl_chatroom_password_form, tpl_chatroom_sidebar, tpl_chatroom_toolbar, tpl_chatrooms_tab, tpl_info, tpl_occupant, tpl_room_description, tpl_room_item, tpl_room_panel, tpl_rooms_results, tpl_spinner, Awesomplete) {
define('converse-muc',["form-utils", "converse-core", "emojione", "lodash.fp", "tpl!chatarea", "tpl!chatroom", "tpl!chatroom_disconnect", "tpl!chatroom_features", "tpl!chatroom_form", "tpl!chatroom_head", "tpl!chatroom_invite", "tpl!chatroom_join_form", "tpl!chatroom_nickname_form", "tpl!chatroom_password_form", "tpl!chatroom_sidebar", "tpl!chatroom_toolbar", "tpl!chatrooms_tab", "tpl!info", "tpl!occupant", "tpl!room_description", "tpl!room_item", "tpl!room_panel", "tpl!rooms_results", "tpl!spinner", "awesomplete", "converse-chatview", "converse-disco", "backbone.overview", "backbone.orderedlistview", "backbone.vdomview"], factory);
})(this, function (u, converse, emojione, f, tpl_chatarea, tpl_chatroom, tpl_chatroom_disconnect, tpl_chatroom_features, tpl_chatroom_form, tpl_chatroom_head, tpl_chatroom_invite, tpl_chatroom_join_form, tpl_chatroom_nickname_form, tpl_chatroom_password_form, tpl_chatroom_sidebar, tpl_chatroom_toolbar, tpl_chatrooms_tab, tpl_info, tpl_occupant, tpl_room_description, tpl_room_item, tpl_room_panel, tpl_rooms_results, tpl_spinner, Awesomplete) {
"use strict";
var ROOMS_PANEL_ID = 'chatrooms';
@ -52548,6 +52788,8 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
* Parameters:
* (String) text: The message text to be sent.
*/
text = emojione.shortnameToUnicode(text);
var msgid = _converse.connection.getUniqueId();
var msg = $msg({
@ -54277,11 +54519,11 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
renderTab: function renderTab() {
var controlbox = _converse.chatboxes.get('controlbox');
var chatrooms = fp.filter(_.partial(u.isOfType, CHATROOMS_TYPE), _converse.chatboxes.models);
var chatrooms = f.filter(_.partial(u.isOfType, CHATROOMS_TYPE), _converse.chatboxes.models);
this.tab_el.innerHTML = tpl_chatrooms_tab({
'label_rooms': __('Rooms'),
'is_current': controlbox.get('active-panel') === ROOMS_PANEL_ID,
'num_unread': fp.sum(fp.map(fp.curry(u.getAttribute)('num_unread'), chatrooms))
'num_unread': f.sum(f.map(f.curry(u.getAttribute)('num_unread'), chatrooms))
});
},
insertIntoDOM: function insertIntoDOM() {
@ -54513,7 +54755,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
* (XMLElement) message: The message stanza containing the
* invitation.
*/
var x_el = message.querySelector('x[xmlns="jabber:x:conference"]'),
var x_el = sizzle('x[xmlns="jabber:x:conference"]', message).pop(),
from = Strophe.getBareJidFromJid(message.getAttribute('from')),
room_jid = x_el.getAttribute('jid'),
reason = x_el.getAttribute('reason');
@ -54717,11 +54959,11 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
function setMUCDomainFromDisco(controlboxview) {
/* Check whether service discovery for the user's domain
* returned MUC information and use that to automatically
* set the MUC domain for the "Rooms" panel of the controlbox.
*/
* returned MUC information and use that to automatically
* set the MUC domain for the "Rooms" panel of the controlbox.
*/
function featureAdded(feature) {
if (feature.get('var') === Strophe.NS.MUC) {
if (feature.get('var') === Strophe.NS.MUC && f.includes('conference', feature.entity.identities.pluck('category'))) {
setMUCDomain(feature.get('from'), controlboxview);
}
}
@ -54958,12 +55200,10 @@ return __p
var _converse = this.__super__._converse;
if (_converse.allow_bookmarks) {
_converse.api.disco.getIdentity('pubsub', 'pep', _converse.bare_jid).then(function (identity) {
if (_.isNil(identity)) {
return;
_converse.checkBookmarksSupport().then(function (supported) {
if (supported) {
_this.renderBookmarkToggle();
}
_this.renderBookmarkToggle();
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}
},
@ -55414,38 +55654,42 @@ return __p
}
});
_converse.checkBookmarksSupport = function () {
return new Promise(function (resolve, reject) {
Promise.all([_converse.api.disco.getIdentity('pubsub', 'pep', _converse.bare_jid), _converse.api.disco.supports(Strophe.NS.PUBSUB + '#publish-options', _converse.bare_jid)]).then(function (args) {
resolve(args[0] && (args[1].supported || _converse.allow_public_bookmarks));
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
};
var initBookmarks = function initBookmarks() {
if (!_converse.allow_bookmarks) {
return;
}
Promise.all([_converse.api.disco.getIdentity('pubsub', 'pep', _converse.bare_jid), _converse.api.disco.supports(Strophe.NS.PUBSUB + '#publish-options', _converse.bare_jid)]).then(function (args) {
var identity = args[0],
options_support = args[1];
if (_.isNil(identity) || !options_support.supported && !_converse.allow_public_bookmarks) {
_converse.emit('bookmarksInitialized');
return;
}
_converse.bookmarks = new _converse.Bookmarks();
_converse.bookmarks.fetchBookmarks().then(function () {
_converse.checkBookmarksSupport().then(function (supported) {
if (supported) {
_converse.bookmarks = new _converse.Bookmarks();
_converse.bookmarksview = new _converse.BookmarksView({
'model': _converse.bookmarks
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.ERROR)).then(function () {
_converse.emit('bookmarksInitialized');
});
}).catch(function (e) {
_converse.log(e, Strophe.LogLevel.ERROR);
_converse.emit('bookmarksInitialized');
_converse.bookmarks.fetchBookmarks().catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL)).then(function () {
return _converse.emit('bookmarksInitialized');
});
} else {
_converse.emit('bookmarksInitialized');
}
});
};
Promise.all([_converse.api.waitUntil('chatBoxesFetched'), _converse.api.waitUntil('roomsPanelRendered')]).then(initBookmarks).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
u.onMultipleEvents([{
'object': _converse,
'event': 'chatBoxesFetched'
}, {
'object': _converse,
'event': 'roomsPanelRendered'
}], initBookmarks);
_converse.on('connected', function () {
// Add a handler for bookmarks pushed from other connected clients
@ -55664,7 +55908,11 @@ return __p
},
toHTML: function toHTML() {
return tpl_rooms_list_item(_.extend(this.model.toJSON(), {
'allow_bookmarks': _converse.allow_bookmarks,
// XXX: By the time this renders, the _converse.bookmarks
// collection should already exist if bookmarks are
// supported by the XMPP server. So we can use it
// as a check for support (other ways of checking are async).
'allow_bookmarks': _converse.allow_bookmarks && _converse.bookmarks,
'info_leave_room': __('Leave this room'),
'info_remove_bookmark': __('Unbookmark this room'),
'info_add_bookmark': __('Bookmark this room'),
@ -55785,13 +56033,26 @@ return __p
});
};
Promise.all([_converse.api.waitUntil('chatBoxesFetched'), _converse.api.waitUntil('roomsPanelRendered')]).then(function () {
if (_converse.allow_bookmarks) {
_converse.api.waitUntil('bookmarksInitialized').then(initRoomsListView);
} else {
initRoomsListView();
}
});
if (_converse.allow_bookmarks) {
u.onMultipleEvents([{
'object': _converse,
'event': 'chatBoxesFetched'
}, {
'object': _converse,
'event': 'roomsPanelRendered'
}, {
'object': _converse,
'event': 'bookmarksInitialized'
}], initRoomsListView);
} else {
u.onMultipleEvents([{
'object': _converse,
'event': 'chatBoxesFetched'
}, {
'object': _converse,
'event': 'roomsPanelRendered'
}], initRoomsListView);
}
_converse.api.listen.on('reconnected', initRoomsListView);
}
@ -56484,7 +56745,9 @@ __p += '\n <li class="toggle-toolbar-menu toggle-otr ' +
__e(o.otr_status_class) +
'" title="' +
__e(o.otr_tooltip) +
'">\n ';
'">\n <span class="chat-toolbar-text">' +
__e(o.otr_translated_status) +
'</span>\n ';
if (o.otr_status == o.UNENCRYPTED) { ;
__p += '\n <span class="icon-unlocked"></span>\n ';
} ;
@ -64238,7 +64501,7 @@ CryptoJS.mode.CTR = (function () {
otr_tooltip: this.getOTRTooltip(),
otr_translated_status: OTR_TRANSLATED_MAPPING[data.otr_status]
});
this.el.querySelector('.chat-toolbar').insertAdjacentHTML('beforeend', tpl_toolbar_otr(_.extend(this.model.toJSON(), options || {})));
this.el.querySelector('.chat-toolbar').insertAdjacentHTML('beforeend', tpl_toolbar_otr(_.extend(data, options || {})));
},
getToolbarOptions: function getToolbarOptions(options) {
options = this.__super__.getToolbarOptions();
@ -66227,12 +66490,6 @@ return __p
_converse.chatboxviews.trimChats(chatbox);
}
});
var logOut = function logOut() {
_converse.minimized_chats.remove();
};
_converse.on('logout', logOut);
}
});
});
@ -66946,7 +67203,7 @@ return __p
_ = _converse$env._;
converse.plugins.add('converse-fullscreen', {
enabled: function enabled(_converse) {
return _.includes(['mobile', 'fullscreen', 'embedded'], _converse.view_mode);
return _.includes(['fullscreen', 'embedded'], _converse.view_mode);
},
overrides: {
// overrides mentioned here will be picked up by converse.js's

View File

@ -48,9 +48,9 @@ copyright = u'2017, JC Brand'
# built documents.
#
# The short X.Y version.
version = '3.3.3'
version = '3.3.4'
# The full version, including alpha/beta/rc tags.
release = '3.3.3'
release = '3.3.4'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@ -22,8 +22,8 @@ The latest versions of these files are available at these URLs:
To load a specific version of Converse.js you can put the version in the URL, like so:
* https://cdn.conversejs.org/3.3.3/dist/converse.min.js
* https://cdn.conversejs.org/3.3.3/css/converse.min.css
* https://cdn.conversejs.org/3.3.4/dist/converse.min.js
* https://cdn.conversejs.org/3.3.4/css/converse.min.css
You can include these two URLs inside the *<head>* element of your website
via the *script* and *link* tags:

View File

@ -58,9 +58,6 @@
<li>
<a href="/docs/html/index.html">Documentation</a>
</li>
<li>
<a href="jslicenses.html" rel="jslicense">Licences</a>
</li>
<li>
<a href="https://github.com/jcbrand/converse.js/releases" class="button" target="_blank" rel="noopener">Download</a>
</li>

View File

@ -7,8 +7,8 @@
<link rel="shortcut icon" type="image/ico" href="css/images/favicon.ico"/>
<script type="text/javascript" src="inverse-analytics.js"></script>
<noscript><p><img src="//stats.opkode.com/piwik.php?idsite=5" style="border:0;" alt="" /></p></noscript>
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/3.3.1/css/inverse.min.css" />
<script src="https://cdn.conversejs.org/3.3.1/dist/converse.min.js"></script>
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/css/inverse.min.css" />
<script src="/cdn.conversejs.org/dist/converse.min.js"></script>
</head>
<body>
<div class="content">

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

5246
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "converse.js",
"version": "3.3.3",
"version": "3.3.4",
"description": "Browser based XMPP instant messaging client",
"main": "main.js",
"directories": {
@ -77,5 +77,7 @@
"wait-until-promise": "^1.0.0",
"xss": "^0.3.3"
},
"dependencies": {}
"dependencies": {
"npm": "^5.7.1"
}
}

View File

@ -68,7 +68,7 @@
.icon-italic:before { content: "\e04f"; }
.icon-key:before { content: "\e028"; }
.icon-legal:before { content: "\f0e3"; }
.icon-lock-2:before { content: "\e027"; }
.icon-lock:before { content: "\e027"; }
.icon-minus:before { content: "\e05a"; }
.icon-music:before { content: "\266b"; }
.icon-newtab:before { content: "\e053"; }

View File

@ -1423,16 +1423,15 @@
var from_jid = name.replace(/ /g,'.').toLowerCase() + '@localhost';
var room_jid = 'lounge@localhost';
var reason = "Please join this chat room";
var message = $(
"<message from='"+from_jid+"' to='"+_converse.bare_jid+"'>" +
"<x xmlns='jabber:x:conference'" +
"jid='"+room_jid+"'" +
"reason='"+reason+"'/>"+
"</message>"
)[0];
expect(_converse.chatboxes.models.length).toBe(1);
expect(_converse.chatboxes.models[0].id).toBe("controlbox");
_converse.onDirectMUCInvitation(message);
var stanza = Strophe.xmlHtmlNode(
'<message xmlns="jabber:client" to="'+_converse.bare_jid+'" from="'+from_jid+'" id="9bceb415-f34b-4fa4-80d5-c0d076a24231">'+
'<x xmlns="jabber:x:conference" jid="'+room_jid+'" reason="'+reason+'"/>'+
'</message>').firstChild;
_converse.onDirectMUCInvitation(stanza);
expect(window.confirm).toHaveBeenCalledWith(
name + ' has invited you to join a chat room: '+ room_jid +
', and left the following reason: "'+reason+'"');
@ -3142,26 +3141,41 @@
null, ['rosterGroupsFetched'], {},
function (done, _converse) {
var sendIQ = _converse.connection.sendIQ;
var sent_stanza, IQ_id;
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_stanza = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback);
});
test_utils.openControlBox();
var panel = _converse.chatboxviews.get('controlbox').roomspanel;
$(panel.tabs).find('li').last().find('a')[0].click(); // Click the chatrooms tab
panel.model.set({'muc_domain': 'muc.localhost'}); // Make sure the domain is set
// See: http://xmpp.org/extensions/xep-0045.html#disco-rooms
expect($('#available-chatrooms').children('dt').length).toBe(0);
expect($('#available-chatrooms').children('dd').length).toBe(0);
expect(document.querySelectorAll('#available-chatrooms dt').length).toBe(0);
expect(document.querySelectorAll('#available-chatrooms dd').length).toBe(0);
document.querySelector('input#show-rooms').click();
expect(sent_stanza.toLocaleString()).toBe(
"<iq to='muc.localhost' from='dummy@localhost/resource' type='get' xmlns='jabber:client' id='"+IQ_id+"'>"+
"<query xmlns='http://jabber.org/protocol/disco#items'/>"+
"</iq>"
);
var iq = $iq({
from:'muc.localhost',
to:'dummy@localhost/pda',
id: IQ_id,
type:'result'
}).c('query')
.c('item', { jid:'heath@chat.shakespeare.lit', name:'A Lonely Heath'}).up()
.c('item', { jid:'coven@chat.shakespeare.lit', name:'A Dark Cave'}).up()
.c('item', { jid:'forres@chat.shakespeare.lit', name:'The Palace'}).up()
.c('item', { jid:'inverness@chat.shakespeare.lit', name:'Macbeth&apos;s Castle'}).nodeTree;
_converse.connection._dataRecv(test_utils.createRequest(iq));
panel.onRoomsFound(iq);
expect($(panel.el.querySelector('#available-chatrooms')).children('dt').length).toBe(1);
expect(document.querySelectorAll('#available-chatrooms dt').length).toBe(1);
expect($(panel.el.querySelector('#available-chatrooms')).children('dt').first().text()).toBe("Rooms found");
expect($(panel.el.querySelector('#available-chatrooms')).children('dd').length).toBe(4);
done();

View File

@ -45,6 +45,33 @@
"</presence>"
);
}));
it("includes the saved status message",
mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {},
function (done, _converse) {
test_utils.openControlBox();
var view = _converse.xmppstatusview;
spyOn(view.model, 'sendPresence').and.callThrough();
spyOn(_converse.connection, 'send').and.callThrough();
view.el.querySelector('a.change-xmpp-status-message').click();
var msg = 'My custom status';
view.el.querySelector('input.custom-xmpp-status').value = msg;
view.el.querySelector('[type="submit"]').click();
expect(view.model.sendPresence).toHaveBeenCalled();
expect(_converse.connection.send.calls.mostRecent().args[0].toLocaleString())
.toBe("<presence xmlns='jabber:client'><status>My custom status</status><priority>0</priority></presence>")
view.el.querySelector('a.choose-xmpp-status').click();
view.el.querySelectorAll('.dropdown dd ul li a')[1].click(); // Change status to "dnd"
expect(_converse.connection.send.calls.mostRecent().args[0].toLocaleString())
.toBe("<presence xmlns='jabber:client'><show>dnd</show><status>My custom status</status><priority>0</priority></presence>")
done();
}));
});
describe("A received presence stanza", function () {

View File

@ -539,8 +539,8 @@
_converse.api.disco.supports(Strophe.NS.PUBSUB+'#publish-options', _converse.bare_jid)
]).then((args) => {
resolve(args[0] && (args[1].supported || _converse.allow_public_bookmarks));
});
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}
const initBookmarks = function () {

View File

@ -249,6 +249,7 @@
render () {
this.el.innerHTML = tpl_chatbox_head(
_.extend(this.model.toJSON(), {
'_converse': _converse,
'avatar_width': _converse.chatview_avatar_width,
'avatar_height': _converse.chatview_avatar_height,
'info_close': __('Close this chat box'),

View File

@ -310,9 +310,9 @@
keepalive: true,
locales_url: 'locale/{{{locale}}}/LC_MESSAGES/converse.json',
locales: [
'af', 'ca', 'de', 'es', 'en', 'fr', 'he',
'af', 'bg', 'ca', 'de', 'es', 'en', 'fr', 'he',
'hu', 'id', 'it', 'ja', 'nb', 'nl',
'pl', 'pt_BR', 'ru', 'uk', 'zh_CN', 'zh_TW'
'pl', 'pt_BR', 'ru', 'tr', 'uk', 'zh_CN', 'zh_TW'
],
message_carbons: true,
message_storage: 'session',
@ -870,9 +870,10 @@
},
initialize (attributes) {
const { jid } = attributes;
const bare_jid = Strophe.getBareJidFromJid(jid).toLowerCase();
const resource = Strophe.getResourceFromJid(jid);
const { jid } = attributes,
bare_jid = Strophe.getBareJidFromJid(jid).toLowerCase(),
resource = Strophe.getResourceFromJid(jid);
attributes.jid = bare_jid;
this.set(_.assignIn({
'fullname': bare_jid,
@ -1503,7 +1504,7 @@
constructPresence (type, status_message) {
let presence;
type = _.isString(type) ? type : (this.get('status') || _converse.default_state);
status_message = _.isString(status_message) ? status_message : undefined;
status_message = _.isString(status_message) ? status_message : this.get('status_message');
// Most of these presence types are actually not explicitly sent,
// but I add all of them here for reference and future proofing.
if ((type === 'unavailable') ||
@ -2027,6 +2028,6 @@
'utils': u
}
};
window.dispatchEvent(new Event('converse-loaded'));
window.dispatchEvent(new CustomEvent('converse-loaded'));
return window.converse;
}));

View File

@ -55,7 +55,7 @@
this.features.browserStorage = new Backbone.BrowserStorage[_converse.storage](
b64_sha1(`converse.features-${this.get('jid')}`)
);
this.features.on('add', this.onFeatureAdded);
this.features.on('add', this.onFeatureAdded, this);
this.identities = new Backbone.Collection();
this.identities.browserStorage = new Backbone.BrowserStorage[_converse.storage](
@ -118,6 +118,7 @@
},
onFeatureAdded (feature) {
feature.entity = this;
_converse.emit('serviceDiscovered', feature);
},

View File

@ -21,7 +21,7 @@
converse.plugins.add('converse-fullscreen', {
enabled (_converse) {
return _.includes(['mobile', 'fullscreen', 'embedded'], _converse.view_mode);
return _.includes(['fullscreen', 'embedded'], _converse.view_mode);
},
overrides: {

View File

@ -119,7 +119,7 @@
converse.plugins.add('converse-mam', {
dependencies: ['converse-chatview', 'converse-muc'],
dependencies: ['converse-chatview', 'converse-muc', 'converse-muc-views'],
overrides: {
// Overrides mentioned here will be picked up by converse.js's

View File

@ -39,7 +39,7 @@
*
* NB: These plugins need to have already been loaded via require.js.
*/
dependencies: ["converse-chatview", "converse-controlbox", "converse-muc", "converse-headline"],
dependencies: ["converse-chatview", "converse-controlbox", "converse-muc", "converse-muc-views", "converse-headline"],
enabled (_converse) {
return _converse.view_mode == 'overlayed';

View File

@ -12,6 +12,7 @@
define([
"converse-core",
"bootstrap",
"emojione",
"tpl!add_chatroom_modal",
"tpl!chatarea",
"tpl!chatroom",
@ -38,6 +39,7 @@
}(this, function (
converse,
bootstrap,
emojione,
tpl_add_chatroom_modal,
tpl_chatarea,
tpl_chatroom,
@ -93,7 +95,7 @@
* If the setting "strict_plugin_dependencies" is set to true,
* an error will be raised if the plugin is not found.
*/
dependencies: ["converse-modal", "converse-controlbox"],
dependencies: ["converse-modal", "converse-controlbox", "converse-chatview"],
overrides: {
@ -109,7 +111,6 @@
}))()
});
this.roomspanel.model.fetch();
this.el.querySelector('.controlbox-pane').insertAdjacentElement(
'beforeEnd', this.roomspanel.render().el);
@ -949,6 +950,7 @@
* Parameters:
* (String) text: The message text to be sent.
*/
text = emojione.shortnameToUnicode(text)
const msgid = _converse.connection.getUniqueId();
const msg = $msg({
to: this.model.get('jid'),

View File

@ -13,14 +13,13 @@
define([
"form-utils",
"converse-core",
"lodash.fp",
"converse-chatview",
"converse-disco",
"backbone.overview",
"backbone.orderedlistview",
"backbone.vdomview"
], factory);
}(this, function (u, converse, fp) {
}(this, function (u, converse) {
"use strict";
const MUC_ROLE_WEIGHTS = {
@ -353,7 +352,7 @@
* (XMLElement) message: The message stanza containing the
* invitation.
*/
const x_el = message.querySelector('x[xmlns="jabber:x:conference"]'),
const x_el = sizzle('x[xmlns="jabber:x:conference"]', message).pop(),
from = Strophe.getBareJidFromJid(message.getAttribute('from')),
room_jid = x_el.getAttribute('jid'),
reason = x_el.getAttribute('reason');

View File

@ -452,9 +452,7 @@
});
this.el.querySelector('.chat-toolbar').insertAdjacentHTML(
'beforeend',
tpl_toolbar_otr(
_.extend(this.model.toJSON(), options || {})
));
tpl_toolbar_otr(_.extend(data, options || {})));
},
getToolbarOptions (options) {

View File

@ -141,7 +141,7 @@
'click .close-room': 'closeRoom',
'click .open-rooms-toggle': 'toggleRoomsList',
'click .remove-bookmark': 'removeBookmark',
'click a.open-room': 'openRoom',
'click .open-room': 'openRoom',
},
listSelector: '.rooms-list',
ItemView: _converse.RoomsListElementView,

View File

@ -15,6 +15,7 @@ if (typeof define !== 'undefined') {
"converse-muc", // XEP-0045 Multi-user chat
"converse-muc-views", // Views related to MUC
"converse-muc-embedded",
"converse-muc-views",
"converse-vcard", // XEP-0054 VCard-temp
"converse-otr", // Off-the-record encryption for one-on-one messages
"converse-register", // XEP-0077 In-band registration

View File

@ -15,6 +15,7 @@
"lodash.noconflict",
"moment",
'moment/locale/af',
'moment/locale/bg',
'moment/locale/ca',
'moment/locale/de',
'moment/locale/es',
@ -29,6 +30,7 @@
'moment/locale/pl',
'moment/locale/pt-br',
'moment/locale/ru',
'moment/locale/tr',
'moment/locale/uk',
'moment/locale/zh-cn',
'moment/locale/zh-tw'

View File

@ -1,3 +1,14 @@
function CustomEvent ( event, params ) {
params = params || { bubbles: false, cancelable: false, detail: undefined };
var evt = document.createEvent( 'CustomEvent' );
evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
return evt;
}
if ( typeof window.CustomEvent !== "function" ) {
CustomEvent.prototype = window.Event.prototype;
window.CustomEvent = CustomEvent;
}
if (!String.prototype.includes) {
String.prototype.includes = function(search, start) {
'use strict';

View File

@ -2,7 +2,7 @@
*
* An XMPP chat client that runs in the browser.
*
* Version: 3.3.3
* Version: 3.3.4
*/
/* jshint ignore:start */

View File

@ -3,7 +3,7 @@
{[ } ]}
<ul class="features-list">
{[ if (o.passwordprotected) { ]}
<li class="feature" title="{{{ o.tt_passwordprotected }}}"><span class="icon-lock-2"></span>{{{ o.label_passwordprotected }}}</li>
<li class="feature" title="{{{ o.tt_passwordprotected }}}"><span class="icon-lock"></span>{{{ o.label_passwordprotected }}}</li>
{[ } ]}
{[ if (o.unsecured) { ]}
<li class="feature" title="{{{ o.tt_unsecured }}}"><span class="icon-unlocked"></span>{{{ o.label_unsecured }}}</li>

View File

@ -1,5 +1,6 @@
{[ if (o.allow_otr) { ]}
<li class="toggle-toolbar-menu toggle-otr {{{o.otr_status_class}}}" title="{{{o.otr_tooltip}}}">
<span class="chat-toolbar-text">{{{o.otr_translated_status}}}</span>
{[ if (o.otr_status == o.UNENCRYPTED) { ]}
<span class="icon-unlocked"></span>
{[ } ]}

View File

@ -4,15 +4,15 @@
<head>
<title>Converse.js Tests</title>
<meta name="description" content="Converse.js: A chat client for your website" />
<link rel="shortcut icon" type="image/png" href="node_modules/jasmine-core/images/jasmine_favicon.png">
<link rel="shortcut icon" type="image/png" href="../node_modules/jasmine-core/images/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" media="screen" href="node_modules/jasmine-core/lib/jasmine-core/jasmine.css">
<link rel="stylesheet" type="text/css" media="screen" href="css/jasmine.css">
<link type="text/css" rel="stylesheet" media="screen" href="css/theme.css" />
<link type="text/css" rel="stylesheet" media="screen" href="css/converse.css" />
<link rel="stylesheet" type="text/css" media="screen" href="../node_modules/jasmine-core/lib/jasmine-core/jasmine.css">
<link rel="stylesheet" type="text/css" media="screen" href="../css/jasmine.css">
<link type="text/css" rel="stylesheet" media="screen" href="../css/theme.css" />
<link type="text/css" rel="stylesheet" media="screen" href="../css/converse.css" />
<script src="src/config.js"></script>
<script data-main="tests/runner-transpiled" src="node_modules/requirejs/require.js"></script>
<script src="../src/config.js"></script>
<script data-main="runner-transpiled" src="../node_modules/requirejs/require.js"></script>
<style>
.tests-brand-heading {