Enhance plugin notification system

Change the plugin notification behavior: this method now returns false as soon as a plugin *explicitly* returns false, else returns true. Also, plugins are now called in their own scope (so remove the never used `scope` parameter).
This commit is contained in:
Simon Brunel 2016-06-10 22:26:55 +02:00
parent 7a419af4c2
commit a55c17d73f
2 changed files with 50 additions and 20 deletions

View File

@ -2,8 +2,7 @@
module.exports = function(Chart) {
var helpers = Chart.helpers;
var noop = helpers.noop;
var noop = Chart.helpers.noop;
/**
* The plugin service singleton
@ -30,21 +29,33 @@ module.exports = function(Chart) {
},
/**
* Calls registered plugins on the specified method, with the given args. This
* method immediately returns as soon as a plugin explicitly returns false.
* Calls registered plugins on the specified extension, with the given args. This
* method immediately returns as soon as a plugin explicitly returns false. The
* returned value can be used, for instance, to interrupt the current action.
* @param {String} extension the name of the plugin method to call (e.g. 'beforeUpdate').
* @param {Array} [args] extra arguments to apply to the extension call.
* @returns {Boolean} false if any of the plugins return false, else returns true.
*/
notify: function(method, args, scope) {
helpers.each(this._plugins, function(plugin) {
if (plugin[method] && typeof plugin[method] === 'function') {
plugin[method].apply(scope, args);
notify: function(extension, args) {
var plugins = this._plugins;
var ilen = plugins.length;
var i, plugin;
for (i=0; i<ilen; ++i) {
plugin = plugins[i];
if (typeof plugin[extension] === 'function') {
if (plugin[extension].apply(plugin, args || []) === false) {
return false;
}
}, scope);
}
}
return true;
}
};
Chart.PluginBase = Chart.Element.extend({
// Plugin methods. All functions are passed the chart instance
// Plugin extensions. All functions are passed the chart instance
// Called at start of chart init
beforeInit: noop,

View File

@ -37,17 +37,36 @@ describe('Test the plugin system', function() {
Chart.plugins.remove(myplugin);
});
it ('Should allow notifying plugins', function() {
describe('Chart.plugins.notify', function() {
it ('should call plugins with arguments', function() {
var myplugin = {
count: 0,
trigger: function(chart) {
myplugin.count = chart.count;
}
};
Chart.plugins.register(myplugin);
Chart.plugins.notify('trigger', [{ count: 10 }]);
expect(myplugin.count).toBe(10);
});
it('should return TRUE if no plugin explicitly returns FALSE', function() {
Chart.plugins.register({ check: function() {} });
Chart.plugins.register({ check: function() { return; } });
Chart.plugins.register({ check: function() { return null; } });
Chart.plugins.register({ check: function() { return 42 } });
var res = Chart.plugins.notify('check');
expect(res).toBeTruthy();
});
it('should return FALSE if no plugin explicitly returns FALSE', function() {
Chart.plugins.register({ check: function() {} });
Chart.plugins.register({ check: function() { return; } });
Chart.plugins.register({ check: function() { return false; } });
Chart.plugins.register({ check: function() { return 42 } });
var res = Chart.plugins.notify('check');
expect(res).toBeFalsy();
});
});
});