Update to pluggable.js 0.0.2

This commit is contained in:
JC Brand 2016-08-31 10:06:17 +00:00
parent 66c7c41888
commit 89e5bd7c54
16 changed files with 96 additions and 88 deletions

View File

@ -1,6 +1,7 @@
# Changelog
## 1.0.7 (Unreleased)
## 2.0.0 (Unreleased)
- Backwards incompatible change: the `_super` attribute in plugins is now named `__super__`. [jcbrand]
- Continuously attempt to resurrect dead connections when `auto_reconnect` is `true`. [jcbrand]
- Update the 'rooms' API to allow user to pass in room attributes. [jcbrand]
- Add new configuration setting [message_storage](https://conversejs.org/docs/html/configuration.html#message_storage) [jcbrand]

View File

@ -1030,14 +1030,21 @@ When converse.js has learned of a service provided by the XMPP server. See XEP-0
``converse.listen.on('serviceDiscovered', function (event, service) { ... });``
Writing a converse.js plugin
============================
Converse.js exposes a plugin mechanism which allows developers to extend and
override its functionality.
Developers are able to extend and override the objects, functions and the
Backbone models and views that make up converse.js by means of writing plugins.
You register a plugin as follows:
Converse.js uses `pluggable.js <https://github.com/jcbrand/pluggable.js/>`_ as
its plugin architecture.
To understand how this plugin architecture works, please read the
`pluggable.js documentation <https://jcbrand.github.io/pluggable.js/>`_
and to grok its inner workins, please refer to the `annotated source code
<https://jcbrand.github.io/pluggable.js/docs/pluggable.html>`_.
You register a converse.js plugin as follows:
.. code-block:: javascript
@ -1146,28 +1153,28 @@ An example plugin
// ...
// You can access the original function being overridden
// via the _super attribute.
// via the __super__ attribute.
// Make sure to pass on the arguments supplied to this
// function and also to apply the proper "this" object.
this._super.onConnected.apply(this, arguments);
this.__super__.onConnected.apply(this, arguments);
},
XMPPStatus: {
// Override converse.js's XMPPStatus Backbone model so that we can override the
// function that sends out the presence stanza.
sendPresence: function (type, status_message, jid) {
// The "converse" object is available via the _super
// The "converse" object is available via the __super__
// attribute.
var converse = this._super.converse;
var converse = this.__super__.converse;
// Custom code can come here
// ...
// You can call the original overridden method, by
// accessing it via the _super attribute.
// accessing it via the __super__ attribute.
// When calling it, you need to apply the proper
// context as reference by the "this" variable.
this._super.sendPresence.apply(this, arguments);
this.__super__.sendPresence.apply(this, arguments);
}
},
}

View File

@ -46,7 +46,7 @@
},
"dependencies": {
"requirejs": "~2.2.0",
"pluggable.js": "https://github.com/jcbrand/pluggable.js.git#0a43995de5186b6a575719127a28eda2f3f2fb86",
"pluggable.js": "0.0.2",
"jquery": "1.12.3",
"jed": "0.5.4",
"underscore": "~1.8.3",

View File

@ -204,7 +204,7 @@
* method.
*
* If a method is overridden, then the original method will still be
* available via the _super attribute.
* available via the __super__ attribute.
*
* name: The attribute being overridden.
* value: The value of the attribute being overridden.
@ -215,7 +215,7 @@
/* Helper method for overriding or extending Converse's Backbone Views or Models
*
* When a method is overriden, the original will still be available
* on the _super attribute of the object being overridden.
* on the __super__ attribute of the object being overridden.
*
* obj: The Backbone View or Model
* attributes: A hash of attributes, such as you would pass to Backbone.Model.extend or Backbone.View.extend

View File

@ -41,7 +41,7 @@
this.add(item.get('id'), view);
return view;
} else {
return this._super.onChatBoxAdded.apply(this, arguments);
return this.__super__.onChatBoxAdded.apply(this, arguments);
}
}
}

View File

@ -37,18 +37,18 @@
initSession: function () {
this.controlboxtoggle = new this.ControlBoxToggle();
this._super.initSession.apply(this, arguments);
this.__super__.initSession.apply(this, arguments);
},
initConnection: function () {
this._super.initConnection.apply(this, arguments);
this.__super__.initConnection.apply(this, arguments);
if (this.connection) {
this.addControlBox();
}
},
onDisconnected: function () {
var result = this._super.onDisconnected.apply(this, arguments);
var result = this.__super__.onDisconnected.apply(this, arguments);
// Set connected to `false`, so that if we reconnect,
// "onConnected" will be called, to fetch the roster again and
// to send out a presence stanza.
@ -64,7 +64,7 @@
},
afterReconnected: function () {
this._super.afterReconnected.apply(this, arguments);
this.__super__.afterReconnected.apply(this, arguments);
var view = converse.chatboxviews.get('controlbox');
if (view.model.get('connected')) {
converse.chatboxviews.get("controlbox").onConnected();
@ -74,7 +74,7 @@
},
_tearDown: function () {
this._super._tearDown.apply(this, arguments);
this.__super__._tearDown.apply(this, arguments);
if (this.rosterview) {
this.rosterview.unregisterHandlers();
// Removes roster groups
@ -84,7 +84,7 @@
},
clearSession: function () {
this._super.clearSession.apply(this, arguments);
this.__super__.clearSession.apply(this, arguments);
if (typeof this.connection !== 'undefined' && this.connection.connected) {
this.chatboxes.get('controlbox').save({'connected': false});
}
@ -92,12 +92,12 @@
ChatBoxes: {
chatBoxMayBeShown: function (chatbox) {
return this._super.chatBoxMayBeShown.apply(this, arguments) &&
return this.__super__.chatBoxMayBeShown.apply(this, arguments) &&
chatbox.get('id') !== 'controlbox';
},
onChatBoxesFetched: function (collection, resp) {
this._super.onChatBoxesFetched.apply(this, arguments);
this.__super__.onChatBoxesFetched.apply(this, arguments);
if (!_.include(_.pluck(resp, 'id'), 'controlbox')) {
this.add({
id: 'controlbox',
@ -121,7 +121,7 @@
return this.add(item.get('id'), view);
}
} else {
return this._super.onChatBoxAdded.apply(this, arguments);
return this.__super__.onChatBoxAdded.apply(this, arguments);
}
},
@ -146,7 +146,7 @@
return controlbox.$el.outerWidth(true);
}
} else {
return this._super.getChatBoxWidth.apply(this, arguments);
return this.__super__.getChatBoxWidth.apply(this, arguments);
}
}
},
@ -160,7 +160,7 @@
'num_unread': 0
});
} else {
this._super.initialize.apply(this, arguments);
this.__super__.initialize.apply(this, arguments);
}
},
},

View File

@ -82,7 +82,7 @@
};
// Make converse pluggable
pluggable.enable(converse, 'converse');
pluggable.enable(converse, 'converse', 'pluggable');
// Module-level constants
converse.STATUS_WEIGHTS = {

View File

@ -56,12 +56,12 @@
this.resizing = null;
}.bind(this));
return this._super.registerGlobalEventHandlers.apply(this, arguments);
return this.__super__.registerGlobalEventHandlers.apply(this, arguments);
},
ChatBox: {
initialize: function () {
var result = this._super.initialize.apply(this, arguments),
var result = this.__super__.initialize.apply(this, arguments),
height = this.get('height'), width = this.get('width'),
save = this.get('id') === 'controlbox' ? this.set.bind(this) : this.save.bind(this);
save({
@ -81,11 +81,11 @@
initialize: function () {
$(window).on('resize', _.debounce(this.setDimensions.bind(this), 100));
this._super.initialize.apply(this, arguments);
this.__super__.initialize.apply(this, arguments);
},
render: function () {
var result = this._super.render.apply(this, arguments);
var result = this.__super__.render.apply(this, arguments);
this.setWidth();
return result;
},
@ -100,7 +100,7 @@
_show: function () {
this.initDragResize().setDimensions();
this._super._show.apply(this, arguments);
this.__super__._show.apply(this, arguments);
},
initDragResize: function () {
@ -230,17 +230,17 @@
initialize: function () {
$(window).on('resize', _.debounce(this.setDimensions.bind(this), 100));
this._super.initialize.apply(this, arguments);
this.__super__.initialize.apply(this, arguments);
},
renderLoginPanel: function () {
var result = this._super.renderLoginPanel.apply(this, arguments);
var result = this.__super__.renderLoginPanel.apply(this, arguments);
this.initDragResize().setDimensions();
return result;
},
renderContactsPanel: function () {
var result = this._super.renderContactsPanel.apply(this, arguments);
var result = this.__super__.renderContactsPanel.apply(this, arguments);
this.initDragResize().setDimensions();
return result;
}
@ -255,11 +255,11 @@
initialize: function () {
$(window).on('resize', _.debounce(this.setDimensions.bind(this), 100));
this._super.initialize.apply(this, arguments);
this.__super__.initialize.apply(this, arguments);
},
render: function () {
var result = this._super.render.apply(this, arguments);
var result = this.__super__.render.apply(this, arguments);
this.setWidth();
return result;
}

View File

@ -53,7 +53,7 @@
this.add(item.get('id'), view);
return view;
} else {
return this._super.onChatBoxAdded.apply(this, arguments);
return this.__super__.onChatBoxAdded.apply(this, arguments);
}
}
}

View File

@ -44,13 +44,13 @@
Features: {
addClientFeatures: function () {
converse.connection.disco.addFeature(Strophe.NS.MAM);
return this._super.addClientFeatures.apply(this, arguments);
return this.__super__.addClientFeatures.apply(this, arguments);
}
},
ChatBox: {
getMessageAttributes: function ($message, $delay, original_stanza) {
var attrs = this._super.getMessageAttributes.apply(this, arguments);
var attrs = this.__super__.getMessageAttributes.apply(this, arguments);
attrs.archive_id = $(original_stanza).find('result[xmlns="'+Strophe.NS.MAM+'"]').attr('id');
return attrs;
}
@ -58,7 +58,7 @@
ChatBoxView: {
render: function () {
var result = this._super.render.apply(this, arguments);
var result = this.__super__.render.apply(this, arguments);
if (!this.disable_mam) {
this.$content.on('scroll', _.debounce(this.onScroll.bind(this), 100));
}
@ -67,7 +67,7 @@
afterMessagesFetched: function () {
if (this.disable_mam || !converse.features.findWhere({'var': Strophe.NS.MAM})) {
return this._super.afterMessagesFetched.apply(this, arguments);
return this.__super__.afterMessagesFetched.apply(this, arguments);
}
if (this.model.messages.length < converse.archived_messages_page_size) {
this.fetchArchivedMessages({
@ -76,7 +76,7 @@
'max': converse.archived_messages_page_size
});
}
return this._super.afterMessagesFetched.apply(this, arguments);
return this.__super__.afterMessagesFetched.apply(this, arguments);
},
fetchArchivedMessages: function (options) {
@ -119,7 +119,7 @@
ChatRoomView: {
render: function () {
var result = this._super.render.apply(this, arguments);
var result = this.__super__.render.apply(this, arguments);
if (!this.disable_mam) {
this.$content.on('scroll', _.debounce(this.onScroll.bind(this), 100));
}

View File

@ -33,7 +33,7 @@
// New functions which don't exist yet can also be added.
_initialize: function () {
this._super._initialize.apply(this, arguments);
this.__super__._initialize.apply(this, arguments);
converse.minimized_chats = new converse.MinimizedChats({
model: converse.chatboxes
});
@ -46,7 +46,7 @@
converse.chatboxviews.trimChats();
}
}, 200));
return this._super.registerGlobalEventHandlers.apply(this, arguments);
return this.__super__.registerGlobalEventHandlers.apply(this, arguments);
},
wrappedChatBox: function (chatbox) {
@ -54,7 +54,7 @@
* returned via the API.
*/
if (!chatbox) { return; }
var box = this._super.wrappedChatBox.apply(this, arguments);
var box = this.__super__.wrappedChatBox.apply(this, arguments);
box.maximize = chatbox.maximize.bind(chatbox);
box.minimize = chatbox.minimize.bind(chatbox);
return box;
@ -62,7 +62,7 @@
ChatBox: {
initialize: function () {
this._super.initialize.apply(this, arguments);
this.__super__.initialize.apply(this, arguments);
if (this.get('id') === 'controlbox') {
return;
}
@ -94,11 +94,11 @@
initialize: function () {
this.model.on('change:minimized', this.onMinimizedChanged, this);
return this._super.initialize.apply(this, arguments);
return this.__super__.initialize.apply(this, arguments);
},
afterShown: function () {
this._super.afterShown.apply(this, arguments);
this.__super__.afterShown.apply(this, arguments);
if (!this.model.get('minimized')) {
converse.chatboxviews.trimChats(this);
}
@ -106,18 +106,18 @@
shouldShowOnTextMessage: function () {
return !this.model.get('minimized') &&
this._super.shouldShowOnTextMessage.apply(this, arguments);
this.__super__.shouldShowOnTextMessage.apply(this, arguments);
},
setChatBoxHeight: function (height) {
if (!this.model.get('minimized')) {
return this._super.setChatBoxHeight.apply(this, arguments);
return this.__super__.setChatBoxHeight.apply(this, arguments);
}
},
setChatBoxWidth: function (width) {
if (!this.model.get('minimized')) {
return this._super.setChatBoxWidth.apply(this, arguments);
return this.__super__.setChatBoxWidth.apply(this, arguments);
}
},
@ -173,7 +173,7 @@
this.maximize();
}
}, this);
var result = this._super.initialize.apply(this, arguments);
var result = this.__super__.initialize.apply(this, arguments);
if (this.model.get('minimized')) {
this.hide();
}
@ -183,7 +183,7 @@
ChatBoxes: {
chatBoxMayBeShown: function (chatbox) {
return this._super.chatBoxMayBeShown.apply(this, arguments) &&
return this.__super__.chatBoxMayBeShown.apply(this, arguments) &&
!chatbox.get('minimized');
},
},
@ -192,7 +192,7 @@
showChat: function (attrs) {
/* Find the chat box and show it. If it doesn't exist, create it.
*/
var chatbox = this._super.showChat.apply(this, arguments);
var chatbox = this.__super__.showChat.apply(this, arguments);
if (chatbox.get('minimized')) {
chatbox.maximize();
}

View File

@ -66,14 +66,14 @@
*/
if (!chatbox) { return; }
var view = converse.chatboxviews.get(chatbox.get('id'));
var box = this._super.wrappedChatBox.apply(this, arguments);
var box = this.__super__.wrappedChatBox.apply(this, arguments);
box.is_chatroom = view.is_chatroom;
return box;
},
Features: {
addClientFeatures: function () {
this._super.addClientFeatures.apply(this, arguments);
this.__super__.addClientFeatures.apply(this, arguments);
if (converse.allow_muc_invitations) {
converse.connection.disco.addFeature('jabber:x:conference'); // Invites
}
@ -85,8 +85,8 @@
ControlBoxView: {
renderContactsPanel: function () {
var converse = this._super.converse;
this._super.renderContactsPanel.apply(this, arguments);
var converse = this.__super__.converse;
this.__super__.renderContactsPanel.apply(this, arguments);
if (converse.allow_muc) {
this.roomspanel = new converse.RoomsPanel({
'$parent': this.$el.find('.controlbox-panes'),
@ -108,8 +108,8 @@
onConnected: function () {
// TODO: This can probably be refactored to be an event
// handler (and therefore removed from overrides)
var converse = this._super.converse;
this._super.onConnected.apply(this, arguments);
var converse = this.__super__.converse;
this.__super__.onConnected.apply(this, arguments);
if (this.model.get('connected')) {
converse.features.off('add', this.featureAdded, this);
@ -126,7 +126,7 @@
},
featureAdded: function (feature) {
var converse = this._super.converse;
var converse = this.__super__.converse;
if ((feature.get('var') === Strophe.NS.MUC) && (converse.allow_muc)) {
this.roomspanel.model.save({muc_domain: feature.get('from')});
var $server= this.$el.find('input.new-chatroom-server');
@ -144,7 +144,7 @@
view = new converse.ChatRoomView({'model': item});
return this.add(item.get('id'), view);
} else {
return this._super.onChatBoxAdded.apply(this, arguments);
return this.__super__.onChatBoxAdded.apply(this, arguments);
}
}
}

View File

@ -60,12 +60,12 @@
// New functions which don't exist yet can also be added.
_initialize: function () {
this._super._initialize.apply(this, arguments);
this.__super__._initialize.apply(this, arguments);
this.otr = new this.OTR();
},
registerGlobalEventHandlers: function () {
this._super.registerGlobalEventHandlers();
this.__super__.registerGlobalEventHandlers();
$(document).click(function () {
if ($('.toggle-otr ul').is(':visible')) {
@ -78,7 +78,7 @@
},
wrappedChatBox: function (chatbox) {
var wrapped_chatbox = this._super.wrappedChatBox.apply(this, arguments);
var wrapped_chatbox = this.__super__.wrappedChatBox.apply(this, arguments);
if (!chatbox) { return; }
return _.extend(wrapped_chatbox, {
'endOTR': chatbox.endOTR.bind(chatbox),
@ -88,7 +88,7 @@
ChatBox: {
initialize: function () {
this._super.initialize.apply(this, arguments);
this.__super__.initialize.apply(this, arguments);
if (this.get('box_id') !== 'controlbox') {
this.save({
'otr_status': this.get('otr_status') || UNENCRYPTED
@ -102,17 +102,17 @@
* OTR session is still being established, so there are no
* "visible" OTR messages being exchanged.
*/
return this._super.shouldPlayNotification.apply(this, arguments) &&
return this.__super__.shouldPlayNotification.apply(this, arguments) &&
!(utils.isOTRMessage($message[0]) && !_.contains([UNVERIFIED, VERIFIED], this.get('otr_status')));
},
createMessage: function ($message, $delay, original_stanza) {
var converse = this._super.converse,
var converse = this.__super__.converse,
$body = $message.children('body'),
text = ($body.length > 0 ? $body.text() : undefined);
if ((!text) || (!converse.allow_otr)) {
return this._super.createMessage.apply(this, arguments);
return this.__super__.createMessage.apply(this, arguments);
}
if (text.match(/^\?OTRv23?/)) {
this.initiateOTR(text);
@ -128,14 +128,14 @@
}
} else {
// Normal unencrypted message.
return this._super.createMessage.apply(this, arguments);
return this.__super__.createMessage.apply(this, arguments);
}
}
}
},
getSession: function (callback) {
var converse = this._super.converse;
var converse = this.__super__.converse;
var cipher = CryptoJS.lib.PasswordBasedCipher;
var pass, instance_tag, saved_key, pass_check;
if (converse.cache_otr_key) {
@ -226,7 +226,7 @@
// send the query message to them.
this.save({'otr_status': UNENCRYPTED});
this.getSession(function (session) {
var converse = this._super.converse;
var converse = this.__super__.converse;
this.otr = new otr.OTR({
fragment_size: 140,
send_interval: 200,
@ -273,8 +273,8 @@
},
initialize: function () {
var converse = this._super.converse;
this._super.initialize.apply(this, arguments);
var converse = this.__super__.converse;
this.__super__.initialize.apply(this, arguments);
this.model.on('change:otr_status', this.onOTRStatusChanged, this);
this.model.on('showOTRError', this.showOTRError, this);
this.model.on('showSentOTRMessage', function (text) {
@ -289,7 +289,7 @@
},
createMessageStanza: function () {
var stanza = this._super.createMessageStanza.apply(this, arguments);
var stanza = this.__super__.createMessageStanza.apply(this, arguments);
if (this.model.get('otr_status') !== UNENCRYPTED || utils.isOTRMessage(stanza.nodeTree)) {
// OTR messages aren't carbon copied
stanza.c('private', {'xmlns': Strophe.NS.CARBONS}).up()
@ -301,7 +301,7 @@
},
onMessageSubmitted: function (text) {
var converse = this._super.converse;
var converse = this.__super__.converse;
if (!converse.connection.authenticated) {
return this.showHelpMessages(
['Sorry, the connection has been lost, '+
@ -322,7 +322,7 @@
this.model.otr.sendMsg(text);
this.model.trigger('showSentOTRMessage', text);
} else {
this._super.onMessageSubmitted.apply(this, arguments);
this.__super__.onMessageSubmitted.apply(this, arguments);
}
},
@ -346,7 +346,7 @@
},
showOTRError: function (msg) {
var converse = this._super.converse;
var converse = this.__super__.converse;
if (msg === 'Message cannot be sent at this time.') {
this.showHelpMessages(
[__('Your message could not be sent')], 'error');
@ -378,7 +378,7 @@
},
authOTR: function (ev) {
var converse = this._super.converse;
var converse = this.__super__.converse;
var scheme = $(ev.target).data().scheme;
var result, question, answer;
if (scheme === 'fingerprint') {
@ -425,7 +425,7 @@
},
renderToolbar: function (options) {
var converse = this._super.converse;
var converse = this.__super__.converse;
if (!converse.show_toolbar) {
return;
}
@ -447,7 +447,7 @@
otr_tooltip: this.getOTRTooltip(),
otr_translated_status: OTR_TRANSLATED_MAPPING[data.otr_status],
});
this._super.renderToolbar.call(this, options);
this.__super__.renderToolbar.call(this, options);
this.$el.find('.chat-toolbar').append(
converse.templates.toolbar_otr(
_.extend(this.model.toJSON(), options || {})

View File

@ -55,8 +55,8 @@
/* Also render a registration panel, when rendering the
* login panel.
*/
this._super.renderLoginPanel.apply(this, arguments);
var converse = this._super.converse;
this.__super__.renderLoginPanel.apply(this, arguments);
var converse = this.__super__.converse;
if (converse.allow_registration) {
this.registerpanel = new converse.RegisterPanel({
'$parent': this.$el.find('.controlbox-panes'),

View File

@ -28,7 +28,7 @@
// New functions which don't exist yet can also be added.
afterReconnected: function () {
this.rosterview.registerRosterXHandler();
this._super.afterReconnected.apply(this, arguments);
this.__super__.afterReconnected.apply(this, arguments);
},
RosterGroups: {
@ -126,7 +126,7 @@
label_state: __('State'),
label_any: __('Any'),
label_online: __('Online'),
label_chatty: __('Chat'),
label_chatty: __('Chatty'),
label_busy: __('Busy'),
label_away: __('Away'),
label_xa: __('Extended Away'),

View File

@ -31,7 +31,7 @@
Features: {
addClientFeatures: function () {
this._super.addClientFeatures.apply(this, arguments);
this.__super__.addClientFeatures.apply(this, arguments);
if (converse.use_vcards) {
converse.connection.disco.addFeature(Strophe.NS.VCARD);
}