diff options
| author | fat <[email protected]> | 2015-01-03 13:58:44 -0800 |
|---|---|---|
| committer | fat <[email protected]> | 2015-02-11 11:29:43 -0800 |
| commit | 834220ea20ce5b7cd31edfb624a28b4bf8b29a6a (patch) | |
| tree | 19bfdadb0c140df437e7b7034e5e1f5ce58343cc /js/tab.js | |
| parent | aed1cd31218113d67d2eca3296edf5d1700b19b8 (diff) | |
| download | bootstrap-834220ea20ce5b7cd31edfb624a28b4bf8b29a6a.tar.xz bootstrap-834220ea20ce5b7cd31edfb624a28b4bf8b29a6a.zip | |
bootstrap onto closure
Diffstat (limited to 'js/tab.js')
| -rw-r--r-- | js/tab.js | 395 |
1 files changed, 283 insertions, 112 deletions
@@ -1,153 +1,324 @@ -/* ======================================================================== - * Bootstrap: tab.js v3.3.2 +/** ======================================================================= + * Bootstrap: tab.js v4.0.0 * http://getbootstrap.com/javascript/#tabs * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ + * ======================================================================== + * @fileoverview - Bootstrap's tab plugin. Tab O_O + * + * Public Methods & Properties: + * + * + $.tab + * + $.tab.noConflict + * + $.tab.Constructor + * + $.tab.Constructor.VERSION + * + $.tab.Constructor.prototype.show + * + * ======================================================================== + */ + + +'use strict'; + +/** + * Our Tab class. + * @param {Element!} element + * @constructor + */ +var Tab = function (element) { + + /** @type {Element} */ + this._element = element + +} + + +/** + * @const + * @type {string} + */ +Tab['VERSION'] = '4.0.0' + + +/** + * @const + * @type {string} + * @private + */ +Tab._NAME = 'tab' + + +/** + * @const + * @type {string} + * @private + */ +Tab._DATA_KEY = 'bs.tab' + + +/** + * @const + * @type {number} + * @private + */ +Tab._TRANSITION_DURATION = 150 + + +/** + * @const + * @enum {string} + * @private + */ +Tab._Event = { + HIDE : 'hide.bs.tab', + HIDDEN : 'hidden.bs.tab', + SHOW : 'show.bs.tab', + SHOWN : 'shown.bs.tab' +} + + +/** + * @const + * @enum {string} + * @private + */ +Tab._ClassName = { + DROPDOWN_MENU : 'dropdown-menu', + ACTIVE : 'active', + FADE : 'fade', + IN : 'in' +} + + +/** + * @const + * @enum {string} + * @private + */ +Tab._Selector = { + A : 'a', + LI : 'li', + LI_DROPDOWN : 'li.dropdown', + UL : 'ul:not(.dropdown-menu)', + FADE_CHILD : ':scope > .fade', + ACTIVE : '.active', + ACTIVE_CHILD : ':scope > .active', + DATA_TOGGLE : '[data-toggle="tab"], [data-toggle="pill"]', + DROPDOWN_ACTIVE_CHILD : ':scope > .dropdown-menu > .active' +} + + +/** + * @param {Object|string=} opt_config + * @this {jQuery} + * @return {jQuery} + * @private + */ +Tab._jQueryInterface = function (opt_config) { + return this.each(function () { + var $this = $(this) + var data = $this.data(Tab._DATA_KEY) + + if (!data) { + data = data = new Tab(this) + $this.data(Tab._DATA_KEY, data) + } + if (typeof opt_config === 'string') { + data[opt_config]() + } + }) +} + + +/** + * Show the tab + */ +Tab.prototype['show'] = function () { + if ( this._element.parentNode + && this._element.parentNode.nodeType == Node.ELEMENT_NODE + && $(this._element).parent().hasClass(Tab._ClassName.ACTIVE)) { + return + } -+function ($) { - 'use strict'; + var ulElement = $(this._element).closest(Tab._Selector.UL)[0] + var selector = Bootstrap.getSelectorFromElement(this._element) - // TAB CLASS DEFINITION - // ==================== + if (ulElement) { + var previous = /** @type {Array.<Element>} */ ($.makeArray($(ulElement).find(Tab._Selector.ACTIVE))) + previous = previous[previous.length - 1] - var Tab = function (element) { - this.element = $(element) + if (previous) { + previous = $(previous).find('a')[0] + } } - Tab.VERSION = '3.3.2' + var hideEvent = $.Event(Tab._Event.HIDE, { + relatedTarget: this._element + }) + + var showEvent = $.Event(Tab._Event.SHOW, { + relatedTarget: previous + }) - Tab.TRANSITION_DURATION = 150 + if (previous) { + $(previous).trigger(hideEvent) + } - Tab.prototype.show = function () { - var $this = this.element - var $ul = $this.closest('ul:not(.dropdown-menu)') - var selector = $this.data('target') + $(this._element).trigger(showEvent) - if (!selector) { - selector = $this.attr('href') - selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 - } + if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return - if ($this.parent('li').hasClass('active')) return + if (selector) { + var target = $(selector)[0] + } - var $previous = $ul.find('.active:last a') - var hideEvent = $.Event('hide.bs.tab', { - relatedTarget: $this[0] - }) - var showEvent = $.Event('show.bs.tab', { - relatedTarget: $previous[0] + this._activate($(this._element).closest(Tab._Selector.LI)[0], ulElement) + + var complete = function () { + var hiddenEvent = $.Event(Tab._Event.HIDDEN, { + relatedTarget: this._element }) - $previous.trigger(hideEvent) - $this.trigger(showEvent) + var shownEvent = $.Event(Tab._Event.SHOWN, { + relatedTarget: previous + }) - if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return + $(previous).trigger(hiddenEvent) + $(this._element).trigger(shownEvent) + }.bind(this) - var $target = $(selector) + if (target) { + this._activate(target, /** @type {Element} */ (target.parentNode), complete) + } else { + complete() + } +} + + +/** + * @param {Element} element + * @param {Element} container + * @param {Function=} opt_callback + * @private + */ +Tab.prototype._activate = function (element, container, opt_callback) { + var active = $(container).find(Tab._Selector.ACTIVE_CHILD)[0] + var isTransitioning = opt_callback + && Bootstrap.transition + && ((active && $(active).hasClass(Tab._ClassName.FADE)) + || !!$(container).find(Tab._Selector.FADE_CHILD)[0]) + + var complete = this._transitionComplete.bind(this, element, active, isTransitioning, opt_callback) + + if (active && isTransitioning) { + $(active) + .one(Bootstrap.TRANSITION_END, complete) + .emulateTransitionEnd(Tab._TRANSITION_DURATION) + + } else { + complete() + } - this.activate($this.closest('li'), $ul) - this.activate($target, $target.parent(), function () { - $previous.trigger({ - type: 'hidden.bs.tab', - relatedTarget: $this[0] - }) - $this.trigger({ - type: 'shown.bs.tab', - relatedTarget: $previous[0] - }) - }) + if (active) { + $(active).removeClass(Tab._ClassName.IN) } +} + + +/** + * @param {Element} element + * @param {Element} active + * @param {boolean} isTransitioning + * @param {Function=} opt_callback + * @private + */ +Tab.prototype._transitionComplete = function (element, active, isTransitioning, opt_callback) { + if (active) { + $(active).removeClass(Tab._ClassName.ACTIVE) + + var dropdownChild = $(active).find(Tab._Selector.DROPDOWN_ACTIVE_CHILD)[0] + if (dropdownChild) { + $(dropdownChild).removeClass(Tab._ClassName.ACTIVE) + } - Tab.prototype.activate = function (element, container, callback) { - var $active = container.find('> .active') - var transition = callback - && $.support.transition - && (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length) - - function next() { - $active - .removeClass('active') - .find('> .dropdown-menu > .active') - .removeClass('active') - .end() - .find('[data-toggle="tab"]') - .attr('aria-expanded', false) - - element - .addClass('active') - .find('[data-toggle="tab"]') - .attr('aria-expanded', true) - - if (transition) { - element[0].offsetWidth // reflow for transition - element.addClass('in') - } else { - element.removeClass('fade') - } - - if (element.parent('.dropdown-menu')) { - element - .closest('li.dropdown') - .addClass('active') - .end() - .find('[data-toggle="tab"]') - .attr('aria-expanded', true) - } - - callback && callback() + var activeToggle = $(active).find(Tab._Selector.DATA_TOGGLE)[0] + if (activeToggle) { + activeToggle.setAttribute('aria-expanded', false) } + } - $active.length && transition ? - $active - .one('bsTransitionEnd', next) - .emulateTransitionEnd(Tab.TRANSITION_DURATION) : - next() + $(element).addClass(Tab._ClassName.ACTIVE) - $active.removeClass('in') + var elementToggle = $(element).find(Tab._Selector.DATA_TOGGLE)[0] + if (elementToggle) { + elementToggle.setAttribute('aria-expanded', true) } + if (isTransitioning) { + Bootstrap.reflow(element) + $(element).addClass(Tab._ClassName.IN) + } else { + $(element).removeClass(Tab._ClassName.FADE) + } - // TAB PLUGIN DEFINITION - // ===================== + if (element.parentNode && $(element.parentNode).hasClass(Tab._ClassName.DROPDOWN_MENU)) { + var dropdownElement = $(element).closest(Tab._Selector.LI_DROPDOWN)[0] + if (dropdownElement) { + $(dropdownElement).addClass(Tab._ClassName.ACTIVE) + } - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.tab') + elementToggle = $(element).find(Tab._Selector.DATA_TOGGLE)[0] + if (elementToggle) { + elementToggle.setAttribute('aria-expanded', true) + } + } - if (!data) $this.data('bs.tab', (data = new Tab(this))) - if (typeof option == 'string') data[option]() - }) + if (opt_callback) { + opt_callback() } +} - var old = $.fn.tab - $.fn.tab = Plugin - $.fn.tab.Constructor = Tab +/** + * ------------------------------------------------------------------------ + * jQuery Interface + noConflict implementaiton + * ------------------------------------------------------------------------ + */ +/** + * @const + * @type {Function} + */ +$.fn[Tab._NAME] = Tab._jQueryInterface - // TAB NO CONFLICT - // =============== - $.fn.tab.noConflict = function () { - $.fn.tab = old - return this - } +/** + * @const + * @type {Function} + */ +$.fn[Tab._NAME]['Constructor'] = Tab - // TAB DATA-API - // ============ +/** + * @const + * @type {Function} + */ +$.fn[Tab._NAME]['noConflict'] = function () { + $.fn[Tab._NAME] = Tab._JQUERY_NO_CONFLICT + return this +} - var clickHandler = function (e) { - e.preventDefault() - Plugin.call($(this), 'show') - } - $(document) - .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler) - .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) -}(jQuery); +// TAB DATA-API +// ============ + +var clickHandler = function (e) { + e.preventDefault() + Tab._jQueryInterface.call($(this), 'show') +} + +$(document) + .on('click.bs.tab.data-api', Tab._Selector.DATA_TOGGLE, clickHandler) |
