/**
|
* 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 );
|