Allow plugins to have optional dependencies.
This change refactors out the plugin code from converse-core into src/converse-puggable.js Additionally, plugins now have an optional attribute `optional_dependencies` which is an array of dependencies which are "nice-to-have" but not essential. Work has also been done to ensure that a plugins' dependencies are first loaded before the plugin itself.
This commit is contained in:
parent
3ca6108083
commit
62c170273e
|
@ -56,6 +56,7 @@ require.config({
|
|||
"converse-notification": "src/converse-notification",
|
||||
"converse-otr": "src/converse-otr",
|
||||
"converse-ping": "src/converse-ping",
|
||||
"converse-pluggable": "src/converse-pluggable",
|
||||
"converse-register": "src/converse-register",
|
||||
"converse-rosterview": "src/converse-rosterview",
|
||||
"converse-templates": "src/converse-templates",
|
||||
|
@ -235,11 +236,11 @@ if (typeof define !== 'undefined') {
|
|||
// translations that you care about.
|
||||
|
||||
"converse-chatview", // Renders standalone chat boxes for single user chat
|
||||
"converse-controlbox", // The control box
|
||||
"converse-mam", // XEP-0313 Message Archive Management
|
||||
"converse-muc", // XEP-0045 Multi-user chat
|
||||
"converse-vcard", // XEP-0054 VCard-temp
|
||||
"converse-otr", // Off-the-record encryption for one-on-one messages
|
||||
"converse-controlbox", // The control box
|
||||
"converse-register", // XEP-0077 In-band registration
|
||||
"converse-ping", // XEP-0199 XMPP Ping
|
||||
"converse-notification",// HTML5 Notifications
|
||||
|
|
1
dev.html
1
dev.html
|
@ -68,6 +68,7 @@
|
|||
play_sounds: true,
|
||||
roster_groups: true,
|
||||
show_controlbox_by_default: true,
|
||||
strict_plugin_dependencies: false,
|
||||
chatstate_notification_blacklist: ['mulles@movim.eu'],
|
||||
xhr_user_search: false,
|
||||
debug: true
|
||||
|
|
|
@ -406,11 +406,13 @@
|
|||
describe("A Chat Message", function () {
|
||||
|
||||
beforeEach(function () {
|
||||
runs(function () {
|
||||
test_utils.closeAllChatBoxes();
|
||||
});
|
||||
waits(250);
|
||||
runs(function () {});
|
||||
test_utils.removeControlBox();
|
||||
converse.roster.browserStorage._clear();
|
||||
test_utils.initConverse();
|
||||
test_utils.createContacts('current');
|
||||
test_utils.openControlBox();
|
||||
test_utils.openContactsPanel();
|
||||
});
|
||||
|
||||
describe("when received from someone else", function () {
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
var connection = converse.connection;
|
||||
delete converse.bosh_service_url;
|
||||
delete converse.connection;
|
||||
expect(converse.initConnection.bind({})).toThrow(
|
||||
expect(converse.initConnection.bind(converse)).toThrow(
|
||||
new Error("initConnection: you must supply a value for either the bosh_service_url or websocket_url or both."));
|
||||
converse.bosh_service_url = url;
|
||||
converse.connection = connection;
|
||||
|
|
|
@ -17,6 +17,12 @@
|
|||
// https://xmpp.org/rfcs/rfc3921.html
|
||||
|
||||
describe("The Protocol", $.proxy(function (mock, test_utils) {
|
||||
beforeEach(function () {
|
||||
test_utils.removeControlBox();
|
||||
converse.roster.browserStorage._clear();
|
||||
test_utils.initConverse();
|
||||
});
|
||||
|
||||
describe("Integration of Roster Items and Presence Subscriptions", $.proxy(function (mock, test_utils) {
|
||||
/* Some level of integration between roster items and presence
|
||||
* subscriptions is normally expected by an instant messaging user
|
||||
|
@ -48,9 +54,6 @@
|
|||
*/
|
||||
beforeEach(function () {
|
||||
test_utils.closeAllChatBoxes();
|
||||
test_utils.removeControlBox();
|
||||
converse.roster.browserStorage._clear();
|
||||
test_utils.initConverse();
|
||||
test_utils.openControlBox();
|
||||
test_utils.openContactsPanel();
|
||||
});
|
||||
|
|
|
@ -133,7 +133,13 @@
|
|||
} else if (typeof jids === "string") {
|
||||
return converse.wrappedChatBox(converse.chatboxes.getChatBox(jids, true));
|
||||
}
|
||||
return _.map(jids, _.partial(_.compose(converse.wrappedChatBox, converse.chatboxes.getChatBox.bind(converse.chatboxes)), _, true));
|
||||
return _.map(jids,
|
||||
_.partial(
|
||||
_.compose(
|
||||
converse.wrappedChatBox.bind(converse), converse.chatboxes.getChatBox.bind(converse.chatboxes)
|
||||
), _, true
|
||||
)
|
||||
);
|
||||
}
|
||||
},
|
||||
'tokens': {
|
||||
|
@ -181,7 +187,8 @@
|
|||
},
|
||||
'plugins': {
|
||||
'add': function (name, plugin) {
|
||||
converse.plugins[name] = plugin;
|
||||
plugin.__name__ = name;
|
||||
converse.pluggable.plugins[name] = plugin;
|
||||
},
|
||||
'remove': function (name) {
|
||||
delete converse.plugins[name];
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
};
|
||||
|
||||
|
||||
converse_api.plugins.add('chatview', {
|
||||
converse_api.plugins.add('converse-chatview', {
|
||||
|
||||
overrides: {
|
||||
// Overrides mentioned here will be picked up by converse.js's
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
moment = converse_api.env.moment;
|
||||
|
||||
|
||||
converse_api.plugins.add('controlbox', {
|
||||
converse_api.plugins.add('converse-controlbox', {
|
||||
|
||||
overrides: {
|
||||
// Overrides mentioned here will be picked up by converse.js's
|
||||
|
|
|
@ -23,11 +23,12 @@
|
|||
"moment_with_locales",
|
||||
"strophe",
|
||||
"converse-templates",
|
||||
"converse-pluggable",
|
||||
"strophe.disco",
|
||||
"backbone.browserStorage",
|
||||
"backbone.overview",
|
||||
], factory);
|
||||
}(this, function ($, _, dummy, utils, moment, Strophe, templates) {
|
||||
}(this, function ($, _, dummy, utils, moment, Strophe, templates, pluggable) {
|
||||
/*
|
||||
* Cannot use this due to Safari bug.
|
||||
* See https://github.com/jcbrand/converse.js/issues/196
|
||||
|
@ -58,26 +59,31 @@
|
|||
var event_context = {};
|
||||
|
||||
var converse = {
|
||||
plugins: {},
|
||||
initialized_plugins: [],
|
||||
templates: templates,
|
||||
|
||||
emit: function (evt, data) {
|
||||
$(event_context).trigger(evt, data);
|
||||
},
|
||||
|
||||
once: function (evt, handler) {
|
||||
$(event_context).one(evt, handler);
|
||||
},
|
||||
|
||||
on: function (evt, handler) {
|
||||
if (_.contains(['ready', 'initialized'], evt)) {
|
||||
converse.log('Warning: The "'+evt+'" event has been deprecated and will be removed, please use "connected".');
|
||||
}
|
||||
$(event_context).bind(evt, handler);
|
||||
},
|
||||
|
||||
off: function (evt, handler) {
|
||||
$(event_context).unbind(evt, handler);
|
||||
}
|
||||
};
|
||||
|
||||
// Make converse pluggable
|
||||
pluggable.enable(converse);
|
||||
|
||||
// Module-level constants
|
||||
converse.STATUS_WEIGHTS = {
|
||||
'offline': 6,
|
||||
|
@ -1770,60 +1776,12 @@
|
|||
return this;
|
||||
};
|
||||
|
||||
this.wrappedOverride = function (key, value, super_method) {
|
||||
// We create a partially applied wrapper function, that
|
||||
// makes sure to set the proper super method when the
|
||||
// overriding method is called. This is done to enable
|
||||
// chaining of plugin methods, all the way up to the
|
||||
// original method.
|
||||
this._super[key] = super_method;
|
||||
return value.apply(this, _.rest(arguments, 3));
|
||||
};
|
||||
|
||||
this._overrideAttribute = function (key, plugin) {
|
||||
// See converse.plugins.override
|
||||
var value = plugin.overrides[key];
|
||||
if (typeof value === "function") {
|
||||
var wrapped_function = _.partial(
|
||||
converse.wrappedOverride.bind(converse),
|
||||
key, value, converse[key].bind(converse)
|
||||
);
|
||||
converse[key] = wrapped_function;
|
||||
} else {
|
||||
converse[key] = value;
|
||||
// Initialization
|
||||
// --------------
|
||||
// This is the end of the initialize method.
|
||||
if (settings.connection) {
|
||||
this.connection = settings.connection;
|
||||
}
|
||||
};
|
||||
|
||||
this._extendObject = function (obj, attributes) {
|
||||
// See converse.plugins.extend
|
||||
if (!obj.prototype._super) {
|
||||
obj.prototype._super = {'converse': converse};
|
||||
}
|
||||
_.each(attributes, function (value, key) {
|
||||
if (key === 'events') {
|
||||
obj.prototype[key] = _.extend(value, obj.prototype[key]);
|
||||
} else if (typeof value === 'function') {
|
||||
// We create a partially applied wrapper function, that
|
||||
// makes sure to set the proper super method when the
|
||||
// overriding method is called. This is done to enable
|
||||
// chaining of plugin methods, all the way up to the
|
||||
// original method.
|
||||
var wrapped_function = _.partial(
|
||||
converse.wrappedOverride,
|
||||
key, value, obj.prototype[key]
|
||||
);
|
||||
obj.prototype[key] = wrapped_function;
|
||||
} else {
|
||||
obj.prototype[key] = value;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
this.initializePlugins = function () {
|
||||
if (typeof converse._super === 'undefined') {
|
||||
converse._super = { 'converse': converse };
|
||||
}
|
||||
|
||||
var updateSettings = function (settings) {
|
||||
/* Helper method which gets put on the plugin and allows it to
|
||||
* add more user-facing config settings to converse.js.
|
||||
|
@ -1832,55 +1790,13 @@
|
|||
_.extend(converse, settings);
|
||||
_.extend(converse, _.pick(converse.user_settings, Object.keys(settings)));
|
||||
};
|
||||
|
||||
_.each(_.keys(this.plugins), function (name) {
|
||||
var plugin = this.plugins[name];
|
||||
plugin.updateSettings = updateSettings;
|
||||
|
||||
if (_.contains(this.initialized_plugins, name)) {
|
||||
// Don't initialize plugins twice, otherwise we get
|
||||
// infinite recursion in overridden methods.
|
||||
return;
|
||||
}
|
||||
plugin.converse = converse;
|
||||
_.each(Object.keys(plugin.overrides || {}), function (key) {
|
||||
/* We automatically override all methods and Backbone views and
|
||||
* models that are in the "overrides" namespace.
|
||||
*/
|
||||
var msg,
|
||||
override = plugin.overrides[key];
|
||||
if (typeof override === "object") {
|
||||
if (typeof converse[key] === 'undefined') {
|
||||
msg = "Error: Plugin tried to override "+key+" but it's not found.";
|
||||
if (converse.strict_plugin_dependencies) {
|
||||
throw msg;
|
||||
} else {
|
||||
converse.log(msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
this._extendObject(converse[key], override);
|
||||
} else {
|
||||
this._overrideAttribute(key, plugin);
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
if (typeof plugin.initialize === "function") {
|
||||
plugin.initialize.bind(plugin)(this);
|
||||
}
|
||||
this.initialized_plugins.push(name);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
// Initialization
|
||||
// --------------
|
||||
// This is the end of the initialize method.
|
||||
if (settings.connection) {
|
||||
this.connection = settings.connection;
|
||||
}
|
||||
this.initializePlugins();
|
||||
this._initialize();
|
||||
this.registerGlobalEventHandlers();
|
||||
converse.pluggable.initializePlugins({
|
||||
'updateSettings': updateSettings,
|
||||
'converse': converse
|
||||
}).then(function () {
|
||||
converse._initialize();
|
||||
converse.registerGlobalEventHandlers();
|
||||
});
|
||||
};
|
||||
return converse;
|
||||
}));
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
var $ = converse_api.env.jQuery,
|
||||
_ = converse_api.env._;
|
||||
|
||||
converse_api.plugins.add('dragresize', {
|
||||
converse_api.plugins.add('converse-dragresize', {
|
||||
|
||||
overrides: {
|
||||
// Overrides mentioned here will be picked up by converse.js's
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
return true;
|
||||
};
|
||||
|
||||
converse_api.plugins.add('headline', {
|
||||
converse_api.plugins.add('converse-headline', {
|
||||
|
||||
overrides: {
|
||||
// Overrides mentioned here will be picked up by converse.js's
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
Strophe.addNamespace('RSM', 'http://jabber.org/protocol/rsm');
|
||||
|
||||
|
||||
converse_api.plugins.add('mam', {
|
||||
converse_api.plugins.add('converse-mam', {
|
||||
|
||||
overrides: {
|
||||
// Overrides mentioned here will be picked up by converse.js's
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
utils = converse_api.env.utils,
|
||||
__ = utils.__.bind(converse);
|
||||
|
||||
converse_api.plugins.add('minimize', {
|
||||
converse_api.plugins.add('converse-minimize', {
|
||||
|
||||
overrides: {
|
||||
// Overrides mentioned here will be picked up by converse.js's
|
||||
|
|
|
@ -14,8 +14,7 @@
|
|||
"converse-core",
|
||||
"converse-api",
|
||||
"typeahead",
|
||||
"converse-chatview",
|
||||
"converse-controlbox"
|
||||
"converse-chatview"
|
||||
], factory);
|
||||
}(this, function (converse, converse_api) {
|
||||
"use strict";
|
||||
|
@ -43,7 +42,17 @@
|
|||
Strophe.addNamespace('MUC_ROOMCONF', Strophe.NS.MUC + "#roomconfig");
|
||||
Strophe.addNamespace('MUC_USER', Strophe.NS.MUC + "#user");
|
||||
|
||||
converse_api.plugins.add('muc', {
|
||||
converse_api.plugins.add('converse-muc', {
|
||||
/* Optional dependencies are require.js dependencies which might be
|
||||
* overridden or relied upon if they exist, but otherwise ignored.
|
||||
*
|
||||
* However, if the setting "strict_plugin_dependencies" is set to true,
|
||||
* then these dependencies will be considered required.
|
||||
*
|
||||
* Optional dependencies will be available in the initialize method as
|
||||
* a the "optional_dependencies" attribute of the plugin.
|
||||
*/
|
||||
optional_dependencies: ["converse-controlbox"],
|
||||
|
||||
overrides: {
|
||||
// Overrides mentioned here will be picked up by converse.js's
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
var supports_html5_notification = "Notification" in window;
|
||||
|
||||
|
||||
converse_api.plugins.add('notification', {
|
||||
converse_api.plugins.add('converse-notification', {
|
||||
|
||||
initialize: function () {
|
||||
/* The initialize function gets called as soon as the plugin is
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
OTR_CLASS_MAPPING[VERIFIED] = 'verified';
|
||||
OTR_CLASS_MAPPING[FINISHED] = 'finished';
|
||||
|
||||
converse_api.plugins.add('otr', {
|
||||
converse_api.plugins.add('converse-otr', {
|
||||
|
||||
overrides: {
|
||||
// Overrides mentioned here will be picked up by converse.js's
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
// Other necessary globals
|
||||
var _ = converse_api.env._;
|
||||
|
||||
converse_api.plugins.add('ping', {
|
||||
converse_api.plugins.add('converse-ping', {
|
||||
|
||||
initialize: function () {
|
||||
/* The initialize function gets called as soon as the plugin is
|
||||
|
|
208
src/converse-pluggable.js
Normal file
208
src/converse-pluggable.js
Normal file
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
* ____ __ __ __ _
|
||||
* / __ \/ /_ __ ___ ___ ____ _/ /_ / /__ (_)____
|
||||
* / /_/ / / / / / __ \/ __ \/ __/ / __ \/ / _ \ / / ___/
|
||||
* / ____/ / /_/ / /_/ / /_/ / /_/ / /_/ / / __/ / (__ )
|
||||
* /_/ /_/\__,_/\__, /\__, /\__/_/_.___/_/\___(_)_/ /____/
|
||||
* /____//____/ /___/
|
||||
*
|
||||
*/
|
||||
(function (root, factory) {
|
||||
define("converse-pluggable", ["jquery", "underscore"], factory);
|
||||
}(this, function ($, _) {
|
||||
"use strict";
|
||||
|
||||
function Pluggable (plugged) {
|
||||
this.plugged = plugged;
|
||||
this.plugged._super = {};
|
||||
this.plugins = {};
|
||||
this.initialized_plugins = [];
|
||||
}
|
||||
_.extend(Pluggable.prototype, {
|
||||
wrappedOverride: function (key, value, super_method) {
|
||||
/* We create a partially applied wrapper function, that
|
||||
* makes sure to set the proper super method when the
|
||||
* overriding method is called. This is done to enable
|
||||
* chaining of plugin methods, all the way up to the
|
||||
* original method.
|
||||
*/
|
||||
if (typeof super_method === "function") {
|
||||
this._super[key] = super_method.bind(this);
|
||||
}
|
||||
return value.apply(this, _.rest(arguments, 3));
|
||||
},
|
||||
|
||||
_overrideAttribute: function (key, plugin) {
|
||||
/* Overrides an attribute on the original object (the thing being
|
||||
* plugged into).
|
||||
*
|
||||
* If the attribute being overridden is a function, then the original
|
||||
* function will still be available via the _super attribute.
|
||||
*
|
||||
* If the same function is being overridden multiple times, then
|
||||
* the original function will be available at the end of a chain of
|
||||
* functions, starting from the most recent override, all the way
|
||||
* back to the original function, each being referenced by the
|
||||
* previous' _super attribute.
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* plugin2.MyFunc._super.myFunc => * plugin1.MyFunc._super.myFunc => original.myFunc
|
||||
*/
|
||||
var value = plugin.overrides[key];
|
||||
if (typeof value === "function") {
|
||||
var wrapped_function = _.partial(
|
||||
this.wrappedOverride, key, value, this.plugged[key]
|
||||
);
|
||||
this.plugged[key] = wrapped_function;
|
||||
} else {
|
||||
this.plugged[key] = value;
|
||||
}
|
||||
},
|
||||
|
||||
_extendObject: function (obj, attributes) {
|
||||
if (!obj.prototype._super) {
|
||||
// FIXME: make generic
|
||||
obj.prototype._super = {'converse': this.plugged };
|
||||
}
|
||||
_.each(attributes, function (value, key) {
|
||||
if (key === 'events') {
|
||||
obj.prototype[key] = _.extend(value, obj.prototype[key]);
|
||||
} else if (typeof value === 'function') {
|
||||
// We create a partially applied wrapper function, that
|
||||
// makes sure to set the proper super method when the
|
||||
// overriding method is called. This is done to enable
|
||||
// chaining of plugin methods, all the way up to the
|
||||
// original method.
|
||||
var wrapped_function = _.partial(
|
||||
this.wrappedOverride, key, value, obj.prototype[key]
|
||||
);
|
||||
obj.prototype[key] = wrapped_function;
|
||||
} else {
|
||||
obj.prototype[key] = value;
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
setOptionalDependencies: function (plugin, dependencies) {
|
||||
plugin.optional_dependencies = dependencies;
|
||||
return plugin;
|
||||
},
|
||||
|
||||
loadOptionalDependencies: function (plugins) {
|
||||
var deferred = new $.Deferred();
|
||||
require(plugins,
|
||||
function () {
|
||||
_.each(plugins, function (name) {
|
||||
var plugin = this.plugins[name];
|
||||
if (plugin) {
|
||||
this.initializePlugin(plugin).then(
|
||||
deferred.resolve.bind(this, plugins)
|
||||
);
|
||||
}
|
||||
}.bind(this));
|
||||
}.bind(this),
|
||||
function () {
|
||||
if (this.plugged.strict_plugin_dependencies) {
|
||||
deferred.fail.apply(this, arguments);
|
||||
this.throwUndefinedDependencyError(arguments[0]);
|
||||
} else {
|
||||
deferred.resolve.apply(this, [plugins]);
|
||||
}
|
||||
}.bind(this));
|
||||
return deferred.promise();
|
||||
},
|
||||
|
||||
throwUndefinedDependencyError: function (msg) {
|
||||
if (this.plugged.strict_plugin_dependencies) {
|
||||
throw msg;
|
||||
} else {
|
||||
console.log(msg);
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
applyOverrides: function (plugin) {
|
||||
_.each(Object.keys(plugin.overrides || {}), function (key) {
|
||||
/* We automatically override all methods and Backbone views and
|
||||
* models that are in the "overrides" namespace.
|
||||
*/
|
||||
var override = plugin.overrides[key];
|
||||
if (typeof override === "object") {
|
||||
if (typeof this.plugged[key] === 'undefined') {
|
||||
this.throwUndefinedDependencyError("Error: Plugin \""+plugin.__name__+"\" tried to override "+key+" but it's not found.");
|
||||
} else {
|
||||
this._extendObject(this.plugged[key], override);
|
||||
}
|
||||
} else {
|
||||
this._overrideAttribute(key, plugin);
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
_initializePlugin: function (plugin) {
|
||||
this.applyOverrides(plugin);
|
||||
if (typeof plugin.initialize === "function") {
|
||||
plugin.initialize.bind(plugin)(this);
|
||||
}
|
||||
this.initialized_plugins.push(plugin.__name__);
|
||||
},
|
||||
|
||||
asyncInitializePlugin: function (plugin) {
|
||||
var deferred = new $.Deferred();
|
||||
this.loadOptionalDependencies(plugin.optional_dependencies).then(
|
||||
_.compose(
|
||||
deferred.resolve,
|
||||
this._initializePlugin.bind(this),
|
||||
_.partial(this.setOptionalDependencies, plugin)
|
||||
));
|
||||
return deferred.promise();
|
||||
},
|
||||
|
||||
initializePlugin: function (plugin) {
|
||||
var deferred = new $.Deferred();
|
||||
if (_.contains(this.initialized_plugins, plugin.__name__)) {
|
||||
// Don't initialize plugins twice, otherwise we get
|
||||
// infinite recursion in overridden methods.
|
||||
return deferred.resolve().promise();
|
||||
}
|
||||
_.extend(plugin, this.properties);
|
||||
if (plugin.optional_dependencies) {
|
||||
this.asyncInitializePlugin(plugin).then(deferred.resolve);
|
||||
} else {
|
||||
this._initializePlugin(plugin);
|
||||
deferred.resolve();
|
||||
}
|
||||
return deferred.promise();
|
||||
},
|
||||
|
||||
initNextPlugin: function (remaining, deferred) {
|
||||
if (remaining.length === 0) {
|
||||
deferred.resolve();
|
||||
return;
|
||||
}
|
||||
var plugin = remaining.pop();
|
||||
this.initializePlugin(plugin).then(
|
||||
this.initNextPlugin.bind(this, remaining, deferred));
|
||||
},
|
||||
|
||||
initializePlugins: function (properties) {
|
||||
/* The properties variable is an object of attributes and methods
|
||||
* which will be attached to the plugins.
|
||||
*/
|
||||
var deferred = new $.Deferred();
|
||||
if (!_.size(this.plugins)) {
|
||||
return deferred.promise();
|
||||
}
|
||||
this.properties = properties;
|
||||
this.initNextPlugin(_.values(this.plugins).reverse(), deferred);
|
||||
return deferred;
|
||||
}
|
||||
});
|
||||
return {
|
||||
'enable': function (object) {
|
||||
/* Call this method to make an object pluggable */
|
||||
return _.extend(object, {'pluggable': new Pluggable(object)});
|
||||
}
|
||||
};
|
||||
}));
|
|
@ -40,7 +40,7 @@
|
|||
Strophe.Status.CONFLICT = i + 3;
|
||||
Strophe.Status.NOTACCEPTABLE = i + 5;
|
||||
|
||||
converse_api.plugins.add('register', {
|
||||
converse_api.plugins.add('converse-register', {
|
||||
|
||||
overrides: {
|
||||
// Overrides mentioned here will be picked up by converse.js's
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
moment = converse_api.env.moment;
|
||||
|
||||
|
||||
converse_api.plugins.add('vcard', {
|
||||
converse_api.plugins.add('converse-vcard', {
|
||||
|
||||
overrides: {
|
||||
// Overrides mentioned here will be picked up by converse.js's
|
||||
|
|
|
@ -149,7 +149,6 @@
|
|||
return str;
|
||||
},
|
||||
|
||||
|
||||
isOTRMessage: function (message) {
|
||||
var $body = $(message).children('body'),
|
||||
text = ($body.length > 0 ? $body.text() : undefined);
|
||||
|
|
Loading…
Reference in New Issue
Block a user