/** * Bridget makes jQuery widgets * v1.1.0 * MIT license */ ( function( window ) { 'use strict'; // -------------------------- utils -------------------------- // var slice = Array.prototype.slice; function noop() {} // -------------------------- definition -------------------------- // function defineBridget( $ ) { // bail if no jQuery if ( !$ ) { return; } // -------------------------- addOptionMethod -------------------------- // /** * adds option method -> $().plugin('option', {...}) * @param {Function} PluginClass - constructor class */ function addOptionMethod( PluginClass ) { // don't overwrite original option method if ( PluginClass.prototype.option ) { return; } // option setter PluginClass.prototype.option = function( opts ) { // bail out if not an object if ( !$.isPlainObject( opts ) ){ return; } this.options = $.extend( true, this.options, opts ); }; } // -------------------------- plugin bridge -------------------------- // // helper function for logging errors // $.error breaks jQuery chaining var logError = typeof console === 'undefined' ? noop : function( message ) { console.error( message ); }; /** * jQuery plugin bridge, access methods like $elem.plugin('method') * @param {String} namespace - plugin name * @param {Function} PluginClass - constructor class */ function bridge( namespace, PluginClass ) { // add to jQuery fn namespace $.fn[ namespace ] = function( options ) { if ( typeof options === 'string' ) { // call plugin method when first argument is a string // get arguments for method var args = slice.call( arguments, 1 ); for ( var i=0, len = this.length; i < len; i++ ) { var elem = this[i]; var instance = $.data( elem, namespace ); if ( !instance ) { logError( "cannot call methods on " + namespace + " prior to initialization; " + "attempted to call '" + options + "'" ); continue; } if ( !$.isFunction( instance[options] ) || options.charAt(0) === '_' ) { logError( "no such method '" + options + "' for " + namespace + " instance" ); continue; } // trigger method with arguments var returnValue = instance[ options ].apply( instance, args ); // break look and return first value if provided if ( returnValue !== undefined ) { return returnValue; } } // return this if no return value return this; } else { return this.each( function() { var instance = $.data( this, namespace ); if ( instance ) { // apply options & init instance.option( options ); instance._init(); } else { // initialize new instance instance = new PluginClass( this, options ); $.data( this, namespace, instance ); } }); } }; } // -------------------------- bridget -------------------------- // /** * converts a Prototypical class into a proper jQuery plugin * the class must have a ._init method * @param {String} namespace - plugin name, used in $().pluginName * @param {Function} PluginClass - constructor class */ $.bridget = function( namespace, PluginClass ) { addOptionMethod( PluginClass ); bridge( namespace, PluginClass ); }; return $.bridget; } // transport if ( typeof define === 'function' && define.amd ) { // AMD define( [ 'jquery' ], defineBridget ); } else if ( typeof exports === 'object' ) { defineBridget( require('jquery') ); } else { // get jquery from browser global defineBridget( window.jQuery ); } })( window );