`:
//----------------------------------
data.wrap.append(data.toggle);
//----------------------------------
// Clone?
//----------------------------------
if (data.options.clone) {
data.wrap.append($menu);
}
//----------------------------------
// Clone?
//----------------------------------
data.wrap.insertBefore(data.target);
//----------------------------------
// Callback:
//----------------------------------
data.options.onAfterInit.call(data.target);
} else {
//----------------------------------
// Problemos:
//----------------------------------
console.warn('jQuery.' + constants.NS, 'thinks there\'s a problem with your markup');
}
}
}, // _main
//----------------------------------
/**
* Get menu.
*
* @private
* @type { function }
* @this { object.jquery }
* @return { object.jquery } Returns clone of @this.
*/
_getClone = function() {
//----------------------------------
// Declare/initialize:
//----------------------------------
var data = this.data(constants.NS),
$clone = this.clone(),
id;
//----------------------------------
// ID?
//----------------------------------
if (typeof data.options.cloneId == 'string') {
//----------------------------------
// Use provided ID string:
//----------------------------------
$clone.attr('id', data.options.cloneId);
} else if (data.options.cloneId) {
//----------------------------------
// Instead, get ID of `target`:
//----------------------------------
id = $clone.attr('id');
//----------------------------------
// Auto-generate id with prefix:
//----------------------------------
if (id) {
$clone.attr('id', constants.PREFIX + '-' + id);
}
} else {
//----------------------------------
// Just remove the cloned ID:
//----------------------------------
$clone.removeAttr('id');
}
//----------------------------------
// Remove cloned children elements?
//----------------------------------
if (data.options.cloneRemove) {
$clone.find(data.options.cloneRemove).remove();
}
$clone
//----------------------------------
// Add "clone" class:
//----------------------------------
.addClass(settings.internal.cloneClass)
//----------------------------------
// Hide:
//----------------------------------
.hide();
//----------------------------------
// Return the cloned menu:
//----------------------------------
return $clone;
}, // _getClone
//----------------------------------
/**
* Get menu.
*
* @private
* @type { function }
* @param { object.jquery } $a jQuery `
` object.
* @param { object.jquery } $menu jQuery `` object.
* @this { object.jquery }
*/
_makeToggle = function($a, $menu) {
//----------------------------------
// Declare/initialize:
//----------------------------------
var data = this.data(constants.NS);
//----------------------------------
// Setup toggle:
//----------------------------------
$a.on('click.' + constants.NS + ' touchstart.' + constants.NS, function(e) {
//----------------------------------
// Declare:
//----------------------------------
var $this,
toggled;
//----------------------------------
// Handle event type:
//----------------------------------
if ( ! e.handled) { // http://stackoverflow.com/questions/11548862/when-touching-html-button-on-iphone-the-href-occasionally-adds-to-the-url-wh
//----------------------------------
// Initialize:
//----------------------------------
$this = $(this);
toggled = $this.data(constants.NS + '.toggled'); // http://stackoverflow.com/questions/3841788/how-to-use-toggle-event-with-live/3842172#3842172
//----------------------------------
// Toggle state:
//----------------------------------
$this.data(constants.NS + '.toggled', ( ! toggled));
if ( ! toggled) {
//----------------------------------
// Callback:
//----------------------------------
data.options.onBeforeShow.call($menu);
$this
//----------------------------------
// Remove existing classes:
//----------------------------------
.removeClass()
//----------------------------------
// Add "opened" class:
//----------------------------------
.addClass(settings.internal.openedClass);
//----------------------------------
// Menu:
//----------------------------------
$menu
//----------------------------------
// Stop and clear queue:
//----------------------------------
.stop(true)
//----------------------------------
// Animate open:
//----------------------------------
.animate(data.options.animIn, data.options.speedIn, data.options.easeIn, function() {
//----------------------------------
// Callback:
//----------------------------------
data.options.onShow.call($(this));
});
} else {
//----------------------------------
// Callback:
//----------------------------------
data.options.onBeforeHide.call($menu);
//----------------------------------
// Menu:
//----------------------------------
$menu
//----------------------------------
// Stop and clear queue:
//----------------------------------
.stop(true)
//----------------------------------
// Animate closed:
//----------------------------------
.animate(data.options.animOut, data.options.speedOut, data.options.easeOut, function() {
//----------------------------------
// Toggle:
//----------------------------------
$this // Double check that this is what it's supposed to be.
//----------------------------------
// Remove existing classes:
//----------------------------------
.removeClass()
//----------------------------------
// Add "closed" class:
//----------------------------------
.addClass(settings.internal.closedClass);
//----------------------------------
// Callback:
//----------------------------------
data.options.onHide.call($(this));
});
}
//----------------------------------
// Event has been handled:
//----------------------------------
e.handled = true;
}
//----------------------------------
// Prevent default & stop bubbling:
//----------------------------------
e.preventDefault();
e.stopPropagation();
});
}; // _makeToggle
//--------------------------------------------------------------------------
//
// Method calling logic:
//
//--------------------------------------------------------------------------
/**
* Boilerplate plugin logic.
*
* @constructor
* @see http://learn.jquery.com/plugins/
* @type { function }
* @param { string } method String method identifier.
* @return { method } Calls plugin method with supplied params.
*/
$.fn[constants.NS] = function(method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if ((typeof method == 'object') || ( ! method)) {
return methods.init.apply(this, arguments);
} else {
$.error('jQuery.' + constants.NS + ' thinks that ' + method + ' doesn\'t exist'); // Should I override? http://api.jquery.com/jQuery.error/
}
}; // constructor
//--------------------------------------------------------------------------
//
// Default settings:
//
//--------------------------------------------------------------------------
/**
* Private settings.
*
* @type { object }
*/
settings.internal = {
cloneClass : constants.PREFIX + '-clone',
closedClass : constants.PREFIX + '-closed',
openedClass : constants.PREFIX + '-opened',
toggleClass : constants.PREFIX + '-toggle'
}; // settings.internal
//----------------------------------
/**
* Public settings.
*
* @type { object }
*/
settings.external = {
animIn : { height: 'toggle' }, // What animation object to use to show the submenus.
animOut : { height: 'toggle' }, // IBID, but for hiding.
clone : true, // Set to false if you don't want to clone target object.
cloneId : true, // Auto clone id? One of ``, `true` or `false`.
easeIn : 'swing', // Easing function in.
easeOut : 'swing', // Easing function out.
cloneRemove : false, // Element(s) for the clone to remove.
speedIn : 'normal', // Animation speed in.
speedOut : 'normal', // Animation speed out.
// Callbacks:
onInit : $.noop, // After plugin data initialized.
onAfterInit : $.noop, // After plugin initialization.
onBeforeShow : $.noop, // Before reveal animation begins.
onShow : $.noop, // After reveal animation ends.
onBeforeHide : $.noop, // Before hide animation begins.
onHide : $.noop // After hide animation ends.
}; // settings.external
//----------------------------------
/**
* Assign defaults to external.
*
* @type { object }
*/
$.fn[constants.NS].defaults = settings.external; // http://stackoverflow.com/questions/11306375/plugin-authoring-how-to-allow-myplugin-defaults-key-value
}(jQuery, window, document));