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/collapse.js | |
| parent | aed1cd31218113d67d2eca3296edf5d1700b19b8 (diff) | |
| download | bootstrap-834220ea20ce5b7cd31edfb624a28b4bf8b29a6a.tar.xz bootstrap-834220ea20ce5b7cd31edfb624a28b4bf8b29a6a.zip | |
bootstrap onto closure
Diffstat (limited to 'js/collapse.js')
| -rw-r--r-- | js/collapse.js | 526 |
1 files changed, 385 insertions, 141 deletions
diff --git a/js/collapse.js b/js/collapse.js index 2bc30e7ba..156163e3f 100644 --- a/js/collapse.js +++ b/js/collapse.js @@ -1,211 +1,455 @@ -/* ======================================================================== - * Bootstrap: collapse.js v3.3.2 +/** ======================================================================= + * Bootstrap: collapse.js v4.0.0 * http://getbootstrap.com/javascript/#collapse * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ + * ======================================================================== + * @fileoverview - Bootstrap's collapse plugin. Flexible support for + * collapsible components like accordions and navigation. + * + * Public Methods & Properties: + * + * + $.carousel + * + $.carousel.noConflict + * + $.carousel.Constructor + * + $.carousel.Constructor.VERSION + * + $.carousel.Constructor.Defaults + * + $.carousel.Constructor.Defaults.toggle + * + $.carousel.Constructor.Defaults.trigger + * + $.carousel.Constructor.Defaults.parent + * + $.carousel.Constructor.prototype.toggle + * + $.carousel.Constructor.prototype.show + * + $.carousel.Constructor.prototype.hide + * + * ======================================================================== + */ +'use strict'; -+function ($) { - 'use strict'; - // COLLAPSE PUBLIC CLASS DEFINITION - // ================================ +/** + * Our collapse class. + * @param {Element!} element + * @param {Object=} opt_config + * @constructor + */ +var Collapse = function (element, opt_config) { - var Collapse = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, Collapse.DEFAULTS, options) - this.$trigger = $(this.options.trigger).filter('[href="#' + element.id + '"], [data-target="#' + element.id + '"]') - this.transitioning = null + /** @private {Element} */ + this._element = element - if (this.options.parent) { - this.$parent = this.getParent() - } else { - this.addAriaAndCollapsedClass(this.$element, this.$trigger) - } + /** @private {Object} */ + this._config = $.extend({}, Collapse['Defaults'], opt_config) - if (this.options.toggle) this.toggle() - } + /** @private {Element} */ + this._trigger = typeof this._config['trigger'] == 'string' ? + $(this._config['trigger'])[0] : this._config['trigger'] - Collapse.VERSION = '3.3.2' + /** @private {boolean} */ + this._isTransitioning = false - Collapse.TRANSITION_DURATION = 350 + /** @private {?Element} */ + this._parent = this._config['parent'] ? this._getParent() : null - Collapse.DEFAULTS = { - toggle: true, - trigger: '[data-toggle="collapse"]' + if (!this._config['parent']) { + this._addAriaAndCollapsedClass(this._element, this._trigger) } - Collapse.prototype.dimension = function () { - var hasWidth = this.$element.hasClass('width') - return hasWidth ? 'width' : 'height' + if (this._config['toggle']) { + this['toggle']() } - Collapse.prototype.show = function () { - if (this.transitioning || this.$element.hasClass('in')) return - - var activesData - var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') +} + + +/** + * @const + * @type {string} + */ +Collapse['VERSION'] = '4.0.0' + + +/** + * @const + * @type {Object} + */ +Collapse['Defaults'] = { + 'toggle' : true, + 'trigger' : '[data-toggle="collapse"]', + 'parent' : null +} + + +/** + * @const + * @type {string} + * @private + */ +Collapse._NAME = 'collapse' + + +/** + * @const + * @type {string} + * @private + */ +Collapse._DATA_KEY = 'bs.collapse' + + +/** + * @const + * @type {number} + * @private + */ +Collapse._TRANSITION_DURATION = 600 + + +/** + * @const + * @type {Function} + * @private + */ +Collapse._JQUERY_NO_CONFLICT = $.fn[Collapse._NAME] + + +/** + * @const + * @enum {string} + * @private + */ +Collapse._Event = { + SHOW : 'show.bs.collapse', + SHOWN : 'shown.bs.collapse', + HIDE : 'hide.bs.collapse', + HIDDEN : 'hidden.bs.collapse' +} + + +/** + * @const + * @enum {string} + * @private + */ +Collapse._ClassName = { + IN : 'in', + COLLAPSE : 'collapse', + COLLAPSING : 'collapsing', + COLLAPSED : 'collapsed' +} + + +/** + * @const + * @enum {string} + * @private + */ +Collapse._Dimension = { + WIDTH : 'width', + HEIGHT : 'height' +} + + +/** + * @const + * @enum {string} + * @private + */ +Collapse._Selector = { + ACTIVES : '.panel > .in, .panel > .collapsing' +} + + +/** + * Provides the jQuery Interface for the alert component. + * @param {Object|string=} opt_config + * @this {jQuery} + * @return {jQuery} + * @private + */ +Collapse._jQueryInterface = function (opt_config) { + return this.each(function () { + var $this = $(this) + var data = $this.data(Collapse._DATA_KEY) + var config = $.extend({}, Collapse['Defaults'], $this.data(), typeof opt_config == 'object' && opt_config) - if (actives && actives.length) { - activesData = actives.data('bs.collapse') - if (activesData && activesData.transitioning) return + if (!data && config['toggle'] && opt_config == 'show') { + config['toggle'] = false } - var startEvent = $.Event('show.bs.collapse') - this.$element.trigger(startEvent) - if (startEvent.isDefaultPrevented()) return + if (!data) { + data = new Collapse(this, config) + $this.data(Collapse._DATA_KEY, data) + } - if (actives && actives.length) { - Plugin.call(actives, 'hide') - activesData || actives.data('bs.collapse', null) + if (typeof opt_config == 'string') { + data[opt_config]() } + }) +} + + +/** + * Function for getting target element from element + * @return {Element} + * @private + */ +Collapse._getTargetFromElement = function (element) { + var selector = Bootstrap.getSelectorFromElement(element) + + return selector ? $(selector)[0] : null +} + - var dimension = this.dimension() +/** + * Toggles the collapse element based on the presence of the 'in' class + */ +Collapse.prototype['toggle'] = function () { + if ($(this._element).hasClass(Collapse._ClassName.IN)) { + this['hide']() + } else { + this['show']() + } +} - this.$element - .removeClass('collapse') - .addClass('collapsing')[dimension](0) - .attr('aria-expanded', true) - this.$trigger - .removeClass('collapsed') - .attr('aria-expanded', true) +/** + * Show's the collapsing element + */ +Collapse.prototype['show'] = function () { + if (this._isTransitioning || $(this._element).hasClass(Collapse._ClassName.IN)) { + return + } - this.transitioning = 1 + var activesData, actives - var complete = function () { - this.$element - .removeClass('collapsing') - .addClass('collapse in')[dimension]('') - this.transitioning = 0 - this.$element - .trigger('shown.bs.collapse') + if (this._parent) { + actives = $.makeArray($(Collapse._Selector.ACTIVES)) + if (!actives.length) { + actives = null } + } - if (!$.support.transition) return complete.call(this) + if (actives) { + activesData = $(actives).data(Collapse._DATA_KEY) + if (activesData && activesData._isTransitioning) { + return + } + } - var scrollSize = $.camelCase(['scroll', dimension].join('-')) + var startEvent = $.Event(Collapse._Event.SHOW) + $(this._element).trigger(startEvent) + if (startEvent.isDefaultPrevented()) { + return + } - this.$element - .one('bsTransitionEnd', $.proxy(complete, this)) - .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) + if (actives) { + Collapse._jQueryInterface.call($(actives), 'hide') + if (!activesData) { + $(actives).data(Collapse._DATA_KEY, null) + } } - Collapse.prototype.hide = function () { - if (this.transitioning || !this.$element.hasClass('in')) return + var dimension = this._getDimension() - var startEvent = $.Event('hide.bs.collapse') - this.$element.trigger(startEvent) - if (startEvent.isDefaultPrevented()) return + $(this._element) + .removeClass(Collapse._ClassName.COLLAPSE) + .addClass(Collapse._ClassName.COLLAPSING) - var dimension = this.dimension() + this._element.style[dimension] = 0 + this._element.setAttribute('aria-expanded', true) - this.$element[dimension](this.$element[dimension]())[0].offsetHeight + if (this._trigger) { + $(this._trigger).removeClass(Collapse._ClassName.COLLAPSED) + this._trigger.setAttribute('aria-expanded', true) + } - this.$element - .addClass('collapsing') - .removeClass('collapse in') - .attr('aria-expanded', false) + this['setTransitioning'](true) - this.$trigger - .addClass('collapsed') - .attr('aria-expanded', false) + var complete = function () { + $(this._element) + .removeClass(Collapse._ClassName.COLLAPSING) + .addClass(Collapse._ClassName.COLLAPSE) + .addClass(Collapse._ClassName.IN) - this.transitioning = 1 + this._element.style[dimension] = '' - var complete = function () { - this.transitioning = 0 - this.$element - .removeClass('collapsing') - .addClass('collapse') - .trigger('hidden.bs.collapse') - } + this['setTransitioning'](false) - if (!$.support.transition) return complete.call(this) + $(this._element).trigger(Collapse._Event.SHOWN) + }.bind(this) - this.$element - [dimension](0) - .one('bsTransitionEnd', $.proxy(complete, this)) - .emulateTransitionEnd(Collapse.TRANSITION_DURATION) + if (!Bootstrap.transition) { + complete() + return } - Collapse.prototype.toggle = function () { - this[this.$element.hasClass('in') ? 'hide' : 'show']() + var scrollSize = 'scroll' + (dimension[0].toUpperCase() + dimension.slice(1)) + + $(this._element) + .one(Bootstrap.TRANSITION_END, complete) + .emulateTransitionEnd(Collapse._TRANSITION_DURATION) + + this._element.style[dimension] = this._element[scrollSize] + 'px' +} + + +/** + * Hides's the collapsing element + */ +Collapse.prototype['hide'] = function () { + if (this._isTransitioning || !$(this._element).hasClass(Collapse._ClassName.IN)) { + return } - Collapse.prototype.getParent = function () { - return $(this.options.parent) - .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') - .each($.proxy(function (i, element) { - var $element = $(element) - this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) - }, this)) - .end() + var startEvent = $.Event(Collapse._Event.HIDE) + $(this._element).trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + var dimension = this._getDimension() + var offsetDimension = dimension === Collapse._Dimension.WIDTH ? + 'offsetWidth' : 'offsetHeight' + + this._element.style[dimension] = this._element[offsetDimension] + 'px' + + Bootstrap.reflow(this._element) + + $(this._element) + .addClass(Collapse._ClassName.COLLAPSING) + .removeClass(Collapse._ClassName.COLLAPSE) + .removeClass(Collapse._ClassName.IN) + + this._element.setAttribute('aria-expanded', false) + + if (this._trigger) { + $(this._trigger).addClass(Collapse._ClassName.COLLAPSED) + this._trigger.setAttribute('aria-expanded', false) } - Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { - var isOpen = $element.hasClass('in') + this['setTransitioning'](true) + + var complete = function () { + this['setTransitioning'](false) + $(this._element) + .removeClass(Collapse._ClassName.COLLAPSING) + .addClass(Collapse._ClassName.COLLAPSE) + .trigger(Collapse._Event.HIDDEN) + + }.bind(this) - $element.attr('aria-expanded', isOpen) - $trigger - .toggleClass('collapsed', !isOpen) - .attr('aria-expanded', isOpen) + this._element.style[dimension] = 0 + + if (!Bootstrap.transition) { + return complete() } - function getTargetFromTrigger($trigger) { - var href - var target = $trigger.attr('data-target') - || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 + $(this._element) + .one(Bootstrap.TRANSITION_END, complete) + .emulateTransitionEnd(Collapse._TRANSITION_DURATION) +} + + - return $(target) +/** + * @param {boolean} isTransitioning + */ +Collapse.prototype['setTransitioning'] = function (isTransitioning) { + this._isTransitioning = isTransitioning +} + + +/** + * Returns the collapsing dimension + * @return {string} + * @private + */ +Collapse.prototype._getDimension = function () { + var hasWidth = $(this._element).hasClass(Collapse._Dimension.WIDTH) + return hasWidth ? Collapse._Dimension.WIDTH : Collapse._Dimension.HEIGHT +} + + +/** + * Returns the parent element + * @return {Element} + * @private + */ +Collapse.prototype._getParent = function () { + var selector = '[data-toggle="collapse"][data-parent="' + this._config['parent'] + '"]' + var parent = $(this._config['parent'])[0] + var elements = /** @type {Array.<Element>} */ ($.makeArray($(parent).find(selector))) + + for (var i = 0; i < elements.length; i++) { + this._addAriaAndCollapsedClass(Collapse._getTargetFromElement(elements[i]), elements[i]) } + return parent +} - // COLLAPSE PLUGIN DEFINITION - // ========================== - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.collapse') - var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) +/** + * Returns the parent element + * @param {Element} element + * @param {Element} trigger + * @private + */ +Collapse.prototype._addAriaAndCollapsedClass = function (element, trigger) { + if (element) { + var isOpen = $(element).hasClass(Collapse._ClassName.IN) + element.setAttribute('aria-expanded', isOpen) - if (!data && options.toggle && option == 'show') options.toggle = false - if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) - if (typeof option == 'string') data[option]() - }) + if (trigger) { + trigger.setAttribute('aria-expanded', isOpen) + $(trigger).toggleClass(Collapse._ClassName.COLLAPSED, !isOpen) + } } +} - var old = $.fn.collapse - $.fn.collapse = Plugin - $.fn.collapse.Constructor = Collapse +/** + * ------------------------------------------------------------------------ + * jQuery Interface + noConflict implementaiton + * ------------------------------------------------------------------------ + */ - // COLLAPSE NO CONFLICT - // ==================== +/** + * @const + * @type {Function} + */ +$.fn[Collapse._NAME] = Collapse._jQueryInterface - $.fn.collapse.noConflict = function () { - $.fn.collapse = old - return this - } +/** + * @const + * @type {Function} + */ +$.fn[Collapse._NAME]['Constructor'] = Collapse - // COLLAPSE DATA-API - // ================= - $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { - var $this = $(this) +/** + * @const + * @type {Function} + */ +$.fn[Collapse._NAME]['noConflict'] = function () { + $.fn[Collapse._NAME] = Collapse._JQUERY_NO_CONFLICT + return this +} - if (!$this.attr('data-target')) e.preventDefault() - var $target = getTargetFromTrigger($this) - var data = $target.data('bs.collapse') - var option = data ? 'toggle' : $.extend({}, $this.data(), { trigger: this }) +/** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ - Plugin.call($target, option) - }) +$(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (event) { + event.preventDefault() + + var target = Collapse._getTargetFromElement(this) + + var data = $(target).data(Collapse._DATA_KEY) + var config = data ? 'toggle' : $.extend({}, $(this).data(), { trigger: this }) -}(jQuery); + Collapse._jQueryInterface.call($(target), config) +}) |
