/** * Plugin generator plugin. Doesn't allow for chaining directly, but preserves public * methods and namespaces, and supports multiple elements. * * @copyright Jamie Talbot 2010 (http://jamietalbot.com) * Licensed as per jQuery (http://jquery.org/license). Keep my name and you're all good :) * * Example Usage: * * Step 1: Define your plugin interface * ------------------------------------ * * MyPluginDefinition = function() { * * var _privateMember; * * function _privateMethod() {} * * return { * setup: function() { * // Initialisation Code * }, * * publicMethodWithArguments: function(name) { * console.log(name); * }, * * publicMethod: function() {} * } * } * * Step 2: Register your plugin * ---------------------------- * * $.fn.myplugin = function(options) { * return $.fn.encapsulatedPlugin('myplugin', MyPluginDefinition, this, options); * }; * * Step 3: Profit * -------------- * * $('#foo').myplugin().publicMethod(); * $('#bar').myplugin().publicMethodWithArguments('Jamie'); * */ (function($) { $.fn.encapsulatedPlugin = function(plugin, definition, objects, options) { // Creates a function that calls the function of the same name on each member of the supplied set. function makeIteratorFunction(f, set) { return function() { for ( var i = 0; i < set.length; i++) { set[i][f].apply(set[i][f], arguments); } }; } var result = []; objects.each(function() { var element = $(this); if (!element.data(plugin)) { // Initialise var instance = new definition(this, options); if (instance.setup) { // If there is a setup function supplied, call it. instance.setup(); } // Store the new functions in a validation data object. element.data(plugin, instance); } result.push(element.data(plugin)); }); // We now have a set of plugin instances. result = $(result); // Take the public functions from the definition and make them available across the set. var template = result[0]; if (template) { for ( var i in template) { if (typeof (template[i]) == 'function') { result[i] = makeIteratorFunction(i, result); } } } // Finally mix-in a convenient reference back to the objects, to allow for chaining. result.$ = objects; return result; }; })(jQuery);