/** * jQuery Harmonia * Replace an (un)ordered list with a form select. * * @author Micky Hulse * @link http://mky.io * @docs https://github.com/mhulse/jquery-harmonia * @copyright Copyright (c) 2014 Micky Hulse. * @license Released under the Apache License, Version 2.0. * @version 1.1.1 * @date 2014/07/20 */ //---------------------------------- // Notes to self: //console.profile('profile foo'); // ... code here ... //console.profileEnd('profile foo'); // ... or: // console.time('timing foo'); // ... code here ... // console.timeEnd('timing foo'); //---------------------------------- ;(function($, window) { /** * Function-level strict mode syntax. * * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode */ 'use strict'; //-------------------------------------------------------------------------- // // Local "globals": // //-------------------------------------------------------------------------- /** * Javascript console detection protection. * * @see http://www.paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/ */ var console = window.console || { log : $.noop, warn : $.noop }, //---------------------------------- /** * The plugin namespace. */ NS = 'harmonia', //-------------------------------------------------------------------------- // // Defaults/settings: // //-------------------------------------------------------------------------- /** * Public defaults. * * @type { object } */ defaults = { currentPage : false, // Select the current page? Default: `false`. optionDefault : 'Choose ...', // Default option for ``; class applied to generated `` to the DOM. Allowed values are `after`, `append`, `before` (default), `html`, and `prepend`. // Best if set via `data-` attribute options object: idSelect : '', // ID name for ``; defaults to `before` (see `use` option) the current instantiated element. // Callbacks: onInit : $.noop, // Callback after plugin data initialized. onAfterInit : $.noop, // Callback after plugin initialization. onAddOption : $.noop, // Callback when a new option has been added. onChange : $.noop // Callback when `', { 'class' : settings.classSelect }), element : ((settings.elementTarget) ? $(settings.elementTarget) : ''), use : ((settings.use && (/^(?:after|append|before|html|prepend|text)$/).test(settings.use)) ? settings.use : 'before') // If input is valid method name, use that; otherwise, default to `before` method. }); //---------------------------------- // Easy access: //---------------------------------- data = $this.data(NS); } //---------------------------------- // Data initialization check: //---------------------------------- if ( ! data.init) { //---------------------------------- // Call main: //---------------------------------- _main.call($this, data); } else { //---------------------------------- // Ouch! //---------------------------------- console.warn('jQuery.%s thinks it\'s already initialized on %o.', NS, this); } }); }, // init //---------------------------------- /** * Removes plugin from element. * * @type { function } * @this { object.jquery } * @return { object.jquery } Returns target object(s) for chaining purposes. */ destroy : function() { //---------------------------------- // Loop & return each this: //---------------------------------- return this.each(function() { //---------------------------------- // Declare, hoist and initialize: //---------------------------------- var $this = $(this), data = $this.data(NS); // Get instance data. //---------------------------------- // Data? //---------------------------------- if (data) { //---------------------------------- // Remove root menu CSS class: //---------------------------------- $this.removeClass(data.settings.classInit); //---------------------------------- // Remove generated HTML: //---------------------------------- data.select.remove(); // All bound events and jQuery data associated with the elements are removed: http://api.jquery.com/remove/ //---------------------------------- // Namespaced instance data: //---------------------------------- $this.removeData(NS); } }); } // destroy }, // methods //-------------------------------------------------------------------------- // // Private methods: // //-------------------------------------------------------------------------- /** * Called after plugin initialization. * * @private * @type { function } * @this { object.jquery } */ _main = function(data) { //---------------------------------- // Declare, hoist and initialize: //---------------------------------- var $default; //---------------------------------- // Data? //---------------------------------- if (typeof data == 'undefined') { //---------------------------------- // Attempt to determine data: //---------------------------------- data = this.data(NS); } //---------------------------------- // Data? //---------------------------------- if (data) { //---------------------------------- // Yup! //---------------------------------- data.init = true; // Data initialization flag. //---------------------------------- // Callback: //---------------------------------- data.settings.onInit.call(data.target, data); //---------------------------------- // Check for object(s): //---------------------------------- if (data.lis.length) { //---------------------------------- // Root menu CSS class: //---------------------------------- data.target.addClass(data.settings.classInit); //---------------------------------- // Is there a ``: //---------------------------------- data.select.attr('id', data.settings.idSelect); } //---------------------------------- // Default ``: //---------------------------------- $default.appendTo(data.select); } //---------------------------------- // Create the other ``? //---------------------------------- if ($children.filter('ul, ol').length) { // Allow for `