aboutsummaryrefslogtreecommitdiff
path: root/js/tab.js
diff options
context:
space:
mode:
authorfat <[email protected]>2015-01-03 13:58:44 -0800
committerfat <[email protected]>2015-02-11 11:29:43 -0800
commit834220ea20ce5b7cd31edfb624a28b4bf8b29a6a (patch)
tree19bfdadb0c140df437e7b7034e5e1f5ce58343cc /js/tab.js
parentaed1cd31218113d67d2eca3296edf5d1700b19b8 (diff)
downloadbootstrap-834220ea20ce5b7cd31edfb624a28b4bf8b29a6a.tar.xz
bootstrap-834220ea20ce5b7cd31edfb624a28b4bf8b29a6a.zip
bootstrap onto closure
Diffstat (limited to 'js/tab.js')
-rw-r--r--js/tab.js395
1 files changed, 283 insertions, 112 deletions
diff --git a/js/tab.js b/js/tab.js
index ddb7fc9c4..07897294a 100644
--- a/js/tab.js
+++ b/js/tab.js
@@ -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)