Skip to content

Instantly share code, notes, and snippets.

@mgvez
Created November 30, 2012 21:13
Show Gist options
  • Save mgvez/4178664 to your computer and use it in GitHub Desktop.
Save mgvez/4178664 to your computer and use it in GitHub Desktop.
Abstract plugin pattern
/**
A pattern for abstract jQuery plugins
Author: Martin Vézina 2012 http://la-grange.ca
Licensed under the MIT license
*/
;(function ( $, window, document, undefined ) {
//shim
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
}
var pluginName = 'myPlugin';
var pluginNameSpace = 'myNamespace';
var defaults = {
autoActivate : true
};
var PluginPrototype = {
init : function(el, options) {
this.el = el;
this.$el = $(el);
this.options = $.extend({}, defaults, options);
},
foo : function(){
}
};
$[pluginName] = function ( concreteName, bar, baz ) {
var fullName = pluginNameSpace + '_' + concreteName;
//create the concrete object (empty for now) which will become the prototype of all plugins for this type. This object's prototype is the Plugin prototype.
var ConcretePlugin = Object.create(PluginPrototype);
//now add concrete definition to our prototype
ConcretePlugin.bar = bar;
ConcretePlugin.baz = baz;
ConcretePlugin.name = fullName;
$.fn[fullName] = function(options) {
var input = arguments;
if ( this.length ) {
return this.each(function () {
//plugin is not instanciated. Create it (requires an object or null as arguments)
if (!$.data(this, fullName)) {
if(typeof options === 'object' || !options){
//create an instance of our concrete plugin
var instance = Object.create(ConcretePlugin);
instance.init(this, options);
$.data(this, fullName, instance);
} else {
$.error( 'Plugin jQuery.' + fullName + " has not yet been instanciated." );
}
} else if(typeof options === 'string') {
//methods that begin with _ are private
if(options[0]==='_') {
$.error( 'Plugin jQuery.' + fullName + ' : method ' + options + ' is private');
return;
}
//plugin is instanciated, get it
var controller = $.data(this, fullName);
if(controller[options]) {
controller[options](Array.prototype.slice.call(input, 1));
} else {
$.error( 'Plugin jQuery.' + fullName + " has no method " + options);
}
} else {
$.error( 'Plugin jQuery.' + fullName + " has already been instanciated.");
}
});
}
}
}
})( jQuery, window, document );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment