aboutsummaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
authorJames Friend <[email protected]>2014-08-28 09:32:08 +0800
committerJames Friend <[email protected]>2014-08-28 09:32:08 +0800
commit9aeaf19b1dca68ee71e916ae415a0c270a47d301 (patch)
treebc8385acb8ec7a46bba03ff2ef7e4283cd9f1146 /js
parente7991a9a1e2f474c8f1d8a2e0ed113816f1c5e82 (diff)
parent35f09315ed543a0479719afa2143240952c215db (diff)
downloadbootstrap-9aeaf19b1dca68ee71e916ae415a0c270a47d301.tar.xz
bootstrap-9aeaf19b1dca68ee71e916ae415a0c270a47d301.zip
Merge remote-tracking branch 'upstream/master' into node-requirable
Conflicts: Gruntfile.js
Diffstat (limited to 'js')
-rw-r--r--js/.jscsrc10
-rw-r--r--js/.jshintrc3
-rw-r--r--js/affix.js190
-rw-r--r--js/alert.js120
-rw-r--r--js/button.js154
-rw-r--r--js/carousel.js348
-rw-r--r--js/collapse.js243
-rw-r--r--js/dropdown.js210
-rw-r--r--js/modal.js413
-rw-r--r--js/popover.js158
-rw-r--r--js/scrollspy.js258
-rw-r--r--js/tab.js184
-rw-r--r--js/tests/index.html29
-rw-r--r--js/tests/unit/affix.js31
-rw-r--r--js/tests/unit/alert.js46
-rw-r--r--js/tests/unit/button.js168
-rw-r--r--js/tests/unit/carousel.js409
-rw-r--r--js/tests/unit/collapse.js169
-rw-r--r--js/tests/unit/dropdown.js317
-rw-r--r--js/tests/unit/modal.js189
-rw-r--r--js/tests/unit/phantom.js64
-rw-r--r--js/tests/unit/popover.js140
-rw-r--r--js/tests/unit/scrollspy.js184
-rw-r--r--js/tests/unit/tab.js80
-rw-r--r--js/tests/unit/tooltip.js917
-rw-r--r--js/tests/visual/affix.html68
-rw-r--r--js/tests/visual/dropdown.html2
-rw-r--r--js/tests/visual/scrollspy.html2
-rw-r--r--js/tests/visual/tab.html109
-rw-r--r--js/tooltip.js689
-rw-r--r--js/transition.js88
31 files changed, 3327 insertions, 2665 deletions
diff --git a/js/.jscsrc b/js/.jscsrc
index e6eb84560..9612c1683 100644
--- a/js/.jscsrc
+++ b/js/.jscsrc
@@ -1,29 +1,29 @@
{
"disallowEmptyBlocks": true,
"disallowKeywords": ["with"],
- "disallowLeftStickedOperators": ["?", "/", "*", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="],
"disallowMixedSpacesAndTabs": true,
"disallowMultipleLineStrings": true,
"disallowMultipleVarDecl": true,
"disallowQuotedKeysInObjects": "allButReserved",
- "disallowRightStickedOperators": ["?", "/", "*", ":", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="],
"disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"],
+ "disallowSpaceBeforeBinaryOperators": [","],
"disallowSpaceBeforePostfixUnaryOperators": ["++", "--"],
"disallowSpacesInNamedFunctionExpression": { "beforeOpeningRoundBrace": true },
"disallowSpacesInsideArrayBrackets": true,
- "disallowTrailingComma": true,
"disallowSpacesInsideParentheses": true,
+ "disallowTrailingComma": true,
"disallowTrailingWhitespace": true,
+ "requireCamelCaseOrUpperCaseIdentifiers": true,
"requireCapitalizedConstructors": true,
"requireCommaBeforeLineBreak": true,
"requireDotNotation": true,
- "requireLeftStickedOperators": [","],
"requireLineFeedAtFileEnd": true,
- "requireRightStickedOperators": ["!"],
"requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", "<", ">=", "<="],
"requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"],
+ "requireSpaceAfterLineComment": true,
"requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", "<", ">=", "<="],
"requireSpacesInAnonymousFunctionExpression": { "beforeOpeningCurlyBrace": true, "beforeOpeningRoundBrace": true },
+ "requireSpacesInConditionalExpression": true,
"requireSpacesInFunctionDeclaration": { "beforeOpeningCurlyBrace": true },
"requireSpacesInFunctionExpression": { "beforeOpeningCurlyBrace": true },
"requireSpacesInNamedFunctionExpression": { "beforeOpeningCurlyBrace": true },
diff --git a/js/.jshintrc b/js/.jshintrc
index 8a9391fdd..a59e1d00a 100644
--- a/js/.jshintrc
+++ b/js/.jshintrc
@@ -11,6 +11,5 @@
"nonbsp" : true,
"strict" : true,
"undef" : true,
- "unused" : true,
- "predef" : [ "define", "require" ]
+ "unused" : true
}
diff --git a/js/affix.js b/js/affix.js
index ab215bb81..bd48fc2ca 100644
--- a/js/affix.js
+++ b/js/affix.js
@@ -1,5 +1,5 @@
/* ========================================================================
- * Bootstrap: affix.js v3.1.1
+ * Bootstrap: affix.js v3.2.0
* http://getbootstrap.com/javascript/#affix
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
@@ -7,71 +7,86 @@
* ======================================================================== */
-+function () { 'use strict';
++function ($) {
+ 'use strict';
- (function (o_o) {
- typeof define == 'function' && define.amd ? define(['jquery'], o_o) :
- typeof exports == 'object' ? o_o(require('jquery')) : o_o(jQuery)
- })(function ($) {
+ // AFFIX CLASS DEFINITION
+ // ======================
- // AFFIX CLASS DEFINITION
- // ======================
+ var Affix = function (element, options) {
+ this.options = $.extend({}, Affix.DEFAULTS, options)
- var Affix = function (element, options) {
- this.options = $.extend({}, Affix.DEFAULTS, options)
+ this.$target = $(this.options.target)
+ .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
+ .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
- this.$target = $(this.options.target)
- .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
- .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
+ this.$element = $(element)
+ this.affixed =
+ this.unpin =
+ this.pinnedOffset = null
- this.$element = $(element)
- this.affixed =
- this.unpin =
- this.pinnedOffset = null
+ this.checkPosition()
+ }
- this.checkPosition()
- }
+ Affix.VERSION = '3.2.0'
- Affix.VERSION = '3.1.1'
+ Affix.RESET = 'affix affix-top affix-bottom'
- Affix.RESET = 'affix affix-top affix-bottom'
+ Affix.DEFAULTS = {
+ offset: 0,
+ target: window
+ }
- Affix.DEFAULTS = {
- offset: 0,
- target: window
- }
+ Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
+ var scrollTop = this.$target.scrollTop()
+ var position = this.$element.offset()
+ var targetHeight = this.$target.height()
- Affix.prototype.getPinnedOffset = function () {
- if (this.pinnedOffset) return this.pinnedOffset
- this.$element.removeClass(Affix.RESET).addClass('affix')
- var scrollTop = this.$target.scrollTop()
- var position = this.$element.offset()
- return (this.pinnedOffset = position.top - scrollTop)
- }
+ if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
- Affix.prototype.checkPositionWithEventLoop = function () {
- setTimeout($.proxy(this.checkPosition, this), 1)
+ if (this.affixed == 'bottom') {
+ if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
+ return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
}
- Affix.prototype.checkPosition = function () {
- if (!this.$element.is(':visible')) return
+ var initializing = this.affixed == null
+ var colliderTop = initializing ? scrollTop : position.top
+ var colliderHeight = initializing ? targetHeight : height
+
+ if (offsetTop != null && colliderTop <= offsetTop) return 'top'
+ if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
+
+ return false
+ }
+
+ Affix.prototype.getPinnedOffset = function () {
+ if (this.pinnedOffset) return this.pinnedOffset
+ this.$element.removeClass(Affix.RESET).addClass('affix')
+ var scrollTop = this.$target.scrollTop()
+ var position = this.$element.offset()
+ return (this.pinnedOffset = position.top - scrollTop)
+ }
+
+ Affix.prototype.checkPositionWithEventLoop = function () {
+ setTimeout($.proxy(this.checkPosition, this), 1)
+ }
+
+ Affix.prototype.checkPosition = function () {
+ if (!this.$element.is(':visible')) return
- var scrollHeight = $(document).height()
- var scrollTop = this.$target.scrollTop()
- var position = this.$element.offset()
- var offset = this.options.offset
- var offsetTop = offset.top
- var offsetBottom = offset.bottom
+ var height = this.$element.height()
+ var offset = this.options.offset
+ var offsetTop = offset.top
+ var offsetBottom = offset.bottom
+ var scrollHeight = $('body').height()
- if (typeof offset != 'object') offsetBottom = offsetTop = offset
- if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
- if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
+ if (typeof offset != 'object') offsetBottom = offsetTop = offset
+ if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
+ if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
- var affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? false :
- offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' :
- offsetTop != null && (scrollTop <= offsetTop) ? 'top' : false
+ var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
- if (this.affixed === affix) return
+ if (this.affixed != affix) {
if (this.unpin != null) this.$element.css('top', '')
var affixType = 'affix' + (affix ? '-' + affix : '')
@@ -87,62 +102,61 @@
this.$element
.removeClass(Affix.RESET)
.addClass(affixType)
- .trigger($.Event(affixType.replace('affix', 'affixed')))
+ .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
+ }
- if (affix == 'bottom') {
- this.$element.offset({
- top: scrollHeight - this.$element.height() - offsetBottom
- })
- }
+ if (affix == 'bottom') {
+ this.$element.offset({
+ top: scrollHeight - height - offsetBottom
+ })
}
+ }
- // AFFIX PLUGIN DEFINITION
- // =======================
+ // AFFIX PLUGIN DEFINITION
+ // =======================
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.affix')
- var options = typeof option == 'object' && option
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.affix')
+ var options = typeof option == 'object' && option
- if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
+ if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
- var old = $.fn.affix
+ var old = $.fn.affix
- $.fn.affix = Plugin
- $.fn.affix.Constructor = Affix
+ $.fn.affix = Plugin
+ $.fn.affix.Constructor = Affix
- // AFFIX NO CONFLICT
- // =================
+ // AFFIX NO CONFLICT
+ // =================
- $.fn.affix.noConflict = function () {
- $.fn.affix = old
- return this
- }
+ $.fn.affix.noConflict = function () {
+ $.fn.affix = old
+ return this
+ }
- // AFFIX DATA-API
- // ==============
+ // AFFIX DATA-API
+ // ==============
- $(window).on('load', function () {
- $('[data-spy="affix"]').each(function () {
- var $spy = $(this)
- var data = $spy.data()
+ $(window).on('load', function () {
+ $('[data-spy="affix"]').each(function () {
+ var $spy = $(this)
+ var data = $spy.data()
- data.offset = data.offset || {}
+ data.offset = data.offset || {}
- if (data.offsetBottom) data.offset.bottom = data.offsetBottom
- if (data.offsetTop) data.offset.top = data.offsetTop
+ if (data.offsetBottom) data.offset.bottom = data.offsetBottom
+ if (data.offsetTop) data.offset.top = data.offsetTop
- Plugin.call($spy, data)
- })
+ Plugin.call($spy, data)
})
-
})
-}();
+}(jQuery);
diff --git a/js/alert.js b/js/alert.js
index f34f84a28..10483899d 100644
--- a/js/alert.js
+++ b/js/alert.js
@@ -1,5 +1,5 @@
/* ========================================================================
- * Bootstrap: alert.js v3.1.1
+ * Bootstrap: alert.js v3.2.0
* http://getbootstrap.com/javascript/#alerts
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
@@ -7,92 +7,88 @@
* ======================================================================== */
-+function () { 'use strict';
++function ($) {
+ 'use strict';
- (function (o_o) {
- typeof define == 'function' && define.amd ? define(['jquery'], o_o) :
- typeof exports == 'object' ? o_o(require('jquery')) : o_o(jQuery)
- })(function ($) {
+ // ALERT CLASS DEFINITION
+ // ======================
- // ALERT CLASS DEFINITION
- // ======================
+ var dismiss = '[data-dismiss="alert"]'
+ var Alert = function (el) {
+ $(el).on('click', dismiss, this.close)
+ }
- var dismiss = '[data-dismiss="alert"]'
- var Alert = function (el) {
- $(el).on('click', dismiss, this.close)
- }
-
- Alert.VERSION = '3.1.1'
+ Alert.VERSION = '3.2.0'
- Alert.prototype.close = function (e) {
- var $this = $(this)
- var selector = $this.attr('data-target')
+ Alert.TRANSITION_DURATION = 150
- if (!selector) {
- selector = $this.attr('href')
- selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
- }
+ Alert.prototype.close = function (e) {
+ var $this = $(this)
+ var selector = $this.attr('data-target')
- var $parent = $(selector)
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
+ }
- if (e) e.preventDefault()
+ var $parent = $(selector)
- if (!$parent.length) {
- $parent = $this.hasClass('alert') ? $this : $this.parent()
- }
+ if (e) e.preventDefault()
- $parent.trigger(e = $.Event('close.bs.alert'))
+ if (!$parent.length) {
+ $parent = $this.closest('.alert')
+ }
- if (e.isDefaultPrevented()) return
+ $parent.trigger(e = $.Event('close.bs.alert'))
- $parent.removeClass('in')
+ if (e.isDefaultPrevented()) return
- function removeElement() {
- // detach from parent, fire event then clean up data
- $parent.detach().trigger('closed.bs.alert').remove()
- }
+ $parent.removeClass('in')
- $.support.transition && $parent.hasClass('fade') ?
- $parent
- .one('bsTransitionEnd', removeElement)
- .emulateTransitionEnd(150) :
- removeElement()
+ function removeElement() {
+ // detach from parent, fire event then clean up data
+ $parent.detach().trigger('closed.bs.alert').remove()
}
+ $.support.transition && $parent.hasClass('fade') ?
+ $parent
+ .one('bsTransitionEnd', removeElement)
+ .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
+ removeElement()
+ }
- // ALERT PLUGIN DEFINITION
- // =======================
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.alert')
+ // ALERT PLUGIN DEFINITION
+ // =======================
- if (!data) $this.data('bs.alert', (data = new Alert(this)))
- if (typeof option == 'string') data[option].call($this)
- })
- }
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.alert')
- var old = $.fn.alert
+ if (!data) $this.data('bs.alert', (data = new Alert(this)))
+ if (typeof option == 'string') data[option].call($this)
+ })
+ }
- $.fn.alert = Plugin
- $.fn.alert.Constructor = Alert
+ var old = $.fn.alert
+ $.fn.alert = Plugin
+ $.fn.alert.Constructor = Alert
- // ALERT NO CONFLICT
- // =================
- $.fn.alert.noConflict = function () {
- $.fn.alert = old
- return this
- }
+ // ALERT NO CONFLICT
+ // =================
+ $.fn.alert.noConflict = function () {
+ $.fn.alert = old
+ return this
+ }
- // ALERT DATA-API
- // ==============
- $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
+ // ALERT DATA-API
+ // ==============
- })
+ $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
-}();
+}(jQuery);
diff --git a/js/button.js b/js/button.js
index e96788c05..b3e944c59 100644
--- a/js/button.js
+++ b/js/button.js
@@ -1,5 +1,5 @@
/* ========================================================================
- * Bootstrap: button.js v3.1.1
+ * Bootstrap: button.js v3.2.0
* http://getbootstrap.com/javascript/#buttons
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
@@ -7,110 +7,108 @@
* ======================================================================== */
-+function () { 'use strict';
++function ($) {
+ 'use strict';
- (function (o_o) {
- typeof define == 'function' && define.amd ? define(['jquery'], o_o) :
- typeof exports == 'object' ? o_o(require('jquery')) : o_o(jQuery)
- })(function ($) {
+ // BUTTON PUBLIC CLASS DEFINITION
+ // ==============================
- // BUTTON PUBLIC CLASS DEFINITION
- // ==============================
+ var Button = function (element, options) {
+ this.$element = $(element)
+ this.options = $.extend({}, Button.DEFAULTS, options)
+ this.isLoading = false
+ }
- var Button = function (element, options) {
- this.$element = $(element)
- this.options = $.extend({}, Button.DEFAULTS, options)
- this.isLoading = false
- }
-
- Button.VERSION = '3.1.1'
+ Button.VERSION = '3.2.0'
- Button.DEFAULTS = {
- loadingText: 'loading...'
- }
+ Button.DEFAULTS = {
+ loadingText: 'loading...'
+ }
- Button.prototype.setState = function (state) {
- var d = 'disabled'
- var $el = this.$element
- var val = $el.is('input') ? 'val' : 'html'
- var data = $el.data()
+ Button.prototype.setState = function (state) {
+ var d = 'disabled'
+ var $el = this.$element
+ var val = $el.is('input') ? 'val' : 'html'
+ var data = $el.data()
- state = state + 'Text'
+ state = state + 'Text'
- if (data.resetText == null) $el.data('resetText', $el[val]())
+ if (data.resetText == null) $el.data('resetText', $el[val]())
- $el[val](data[state] == null ? this.options[state] : data[state])
+ $el[val](data[state] == null ? this.options[state] : data[state])
- // push to event loop to allow forms to submit
- setTimeout($.proxy(function () {
- if (state == 'loadingText') {
- this.isLoading = true
- $el.addClass(d).attr(d, d)
- } else if (this.isLoading) {
- this.isLoading = false
- $el.removeClass(d).removeAttr(d)
- }
- }, this), 0)
- }
-
- Button.prototype.toggle = function () {
- var changed = true
- var $parent = this.$element.closest('[data-toggle="buttons"]')
-
- if ($parent.length) {
- var $input = this.$element.find('input')
- if ($input.prop('type') == 'radio') {
- if ($input.prop('checked') && this.$element.hasClass('active')) changed = false
- else $parent.find('.active').removeClass('active')
- }
- if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
+ // push to event loop to allow forms to submit
+ setTimeout($.proxy(function () {
+ if (state == 'loadingText') {
+ this.isLoading = true
+ $el.addClass(d).attr(d, d)
+ } else if (this.isLoading) {
+ this.isLoading = false
+ $el.removeClass(d).removeAttr(d)
}
-
- if (changed) this.$element.toggleClass('active')
+ }, this), 0)
+ }
+
+ Button.prototype.toggle = function () {
+ var changed = true
+ var $parent = this.$element.closest('[data-toggle="buttons"]')
+
+ if ($parent.length) {
+ var $input = this.$element.find('input')
+ if ($input.prop('type') == 'radio') {
+ if ($input.prop('checked') && this.$element.hasClass('active')) changed = false
+ else $parent.find('.active').removeClass('active')
+ }
+ if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
}
+ if (changed) this.$element.toggleClass('active')
+ }
- // BUTTON PLUGIN DEFINITION
- // ========================
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.button')
- var options = typeof option == 'object' && option
+ // BUTTON PLUGIN DEFINITION
+ // ========================
- if (!data) $this.data('bs.button', (data = new Button(this, options)))
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.button')
+ var options = typeof option == 'object' && option
- if (option == 'toggle') data.toggle()
- else if (option) data.setState(option)
- })
- }
+ if (!data) $this.data('bs.button', (data = new Button(this, options)))
- var old = $.fn.button
+ if (option == 'toggle') data.toggle()
+ else if (option) data.setState(option)
+ })
+ }
- $.fn.button = Plugin
- $.fn.button.Constructor = Button
+ var old = $.fn.button
+ $.fn.button = Plugin
+ $.fn.button.Constructor = Button
- // BUTTON NO CONFLICT
- // ==================
- $.fn.button.noConflict = function () {
- $.fn.button = old
- return this
- }
+ // BUTTON NO CONFLICT
+ // ==================
+ $.fn.button.noConflict = function () {
+ $.fn.button = old
+ return this
+ }
- // BUTTON DATA-API
- // ===============
- $(document).on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
+ // BUTTON DATA-API
+ // ===============
+
+ $(document)
+ .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
var $btn = $(e.target)
if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
Plugin.call($btn, 'toggle')
e.preventDefault()
})
+ .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
+ $(e.target).closest('.btn').toggleClass('focus', e.type == 'focus')
+ })
- })
-
-}();
+}(jQuery);
diff --git a/js/carousel.js b/js/carousel.js
index 05631f7a3..65cc7b912 100644
--- a/js/carousel.js
+++ b/js/carousel.js
@@ -1,5 +1,5 @@
/* ========================================================================
- * Bootstrap: carousel.js v3.1.1
+ * Bootstrap: carousel.js v3.2.0
* http://getbootstrap.com/javascript/#carousel
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
@@ -7,222 +7,226 @@
* ======================================================================== */
-+function () { 'use strict';
++function ($) {
+ 'use strict';
- (function (o_o) {
- typeof define == 'function' && define.amd ? define(['jquery'], o_o) :
- typeof exports == 'object' ? o_o(require('jquery')) : o_o(jQuery)
- })(function ($) {
+ // CAROUSEL CLASS DEFINITION
+ // =========================
- // CAROUSEL CLASS DEFINITION
- // =========================
+ var Carousel = function (element, options) {
+ this.$element = $(element).on('keydown.bs.carousel', $.proxy(this.keydown, this))
+ this.$indicators = this.$element.find('.carousel-indicators')
+ this.options = options
+ this.paused =
+ this.sliding =
+ this.interval =
+ this.$active =
+ this.$items = null
- var Carousel = function (element, options) {
- this.$element = $(element).on('keydown.bs.carousel', $.proxy(this.keydown, this))
- this.$indicators = this.$element.find('.carousel-indicators')
- this.options = options
- this.paused =
- this.sliding =
- this.interval =
- this.$active =
- this.$items = null
+ this.options.pause == 'hover' && this.$element
+ .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
+ .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
+ }
- this.options.pause == 'hover' && this.$element
- .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
- .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
- }
+ Carousel.VERSION = '3.2.0'
+
+ Carousel.TRANSITION_DURATION = 600
- Carousel.VERSION = '3.1.1'
+ Carousel.DEFAULTS = {
+ interval: 5000,
+ pause: 'hover',
+ wrap: true
+ }
- Carousel.DEFAULTS = {
- interval: 5000,
- pause: 'hover',
- wrap: true
+ Carousel.prototype.keydown = function (e) {
+ switch (e.which) {
+ case 37: this.prev(); break
+ case 39: this.next(); break
+ default: return
}
- Carousel.prototype.keydown = function (e) {
- switch (e.which) {
- case 37: this.prev(); break
- case 39: this.next(); break
- default: return
- }
+ e.preventDefault()
+ }
- e.preventDefault()
- }
+ Carousel.prototype.cycle = function (e) {
+ e || (this.paused = false)
- Carousel.prototype.cycle = function (e) {
- e || (this.paused = false)
+ this.interval && clearInterval(this.interval)
- this.interval && clearInterval(this.interval)
+ this.options.interval
+ && !this.paused
+ && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
- this.options.interval
- && !this.paused
- && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
+ return this
+ }
- return this
- }
+ Carousel.prototype.getItemIndex = function (item) {
+ this.$items = item.parent().children('.item')
+ return this.$items.index(item || this.$active)
+ }
- Carousel.prototype.getItemIndex = function (item) {
- this.$items = item.parent().children('.item')
- return this.$items.index(item || this.$active)
- }
+ Carousel.prototype.getItemForDirection = function (direction, active) {
+ var delta = direction == 'prev' ? -1 : 1
+ var activeIndex = this.getItemIndex(active)
+ var itemIndex = (activeIndex + delta) % this.$items.length
+ return this.$items.eq(itemIndex)
+ }
+
+ Carousel.prototype.to = function (pos) {
+ var that = this
+ var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
- Carousel.prototype.to = function (pos) {
- var that = this
- var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
+ if (pos > (this.$items.length - 1) || pos < 0) return
- if (pos > (this.$items.length - 1) || pos < 0) return
+ if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
+ if (activeIndex == pos) return this.pause().cycle()
- if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
- if (activeIndex == pos) return this.pause().cycle()
+ return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
+ }
- return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
+ Carousel.prototype.pause = function (e) {
+ e || (this.paused = true)
+
+ if (this.$element.find('.next, .prev').length && $.support.transition) {
+ this.$element.trigger($.support.transition.end)
+ this.cycle(true)
}
- Carousel.prototype.pause = function (e) {
- e || (this.paused = true)
+ this.interval = clearInterval(this.interval)
- if (this.$element.find('.next, .prev').length && $.support.transition) {
- this.$element.trigger($.support.transition.end)
- this.cycle(true)
- }
+ return this
+ }
- this.interval = clearInterval(this.interval)
+ Carousel.prototype.next = function () {
+ if (this.sliding) return
+ return this.slide('next')
+ }
- return this
- }
+ Carousel.prototype.prev = function () {
+ if (this.sliding) return
+ return this.slide('prev')
+ }
+
+ Carousel.prototype.slide = function (type, next) {
+ var $active = this.$element.find('.item.active')
+ var $next = next || this.getItemForDirection(type, $active)
+ var isCycling = this.interval
+ var direction = type == 'next' ? 'left' : 'right'
+ var fallback = type == 'next' ? 'first' : 'last'
+ var that = this
- Carousel.prototype.next = function () {
- if (this.sliding) return
- return this.slide('next')
+ if (!$next.length) {
+ if (!this.options.wrap) return
+ $next = this.$element.find('.item')[fallback]()
}
- Carousel.prototype.prev = function () {
- if (this.sliding) return
- return this.slide('prev')
+ if ($next.hasClass('active')) return (this.sliding = false)
+
+ var relatedTarget = $next[0]
+ var slideEvent = $.Event('slide.bs.carousel', {
+ relatedTarget: relatedTarget,
+ direction: direction
+ })
+ this.$element.trigger(slideEvent)
+ if (slideEvent.isDefaultPrevented()) return
+
+ this.sliding = true
+
+ isCycling && this.pause()
+
+ if (this.$indicators.length) {
+ this.$indicators.find('.active').removeClass('active')
+ var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
+ $nextIndicator && $nextIndicator.addClass('active')
}
- Carousel.prototype.slide = function (type, next) {
- var $active = this.$element.find('.item.active')
- var $next = next || $active[type]()
- var isCycling = this.interval
- var direction = type == 'next' ? 'left' : 'right'
- var fallback = type == 'next' ? 'first' : 'last'
- var that = this
-
- if (!$next.length) {
- if (!this.options.wrap) return
- $next = this.$element.find('.item')[fallback]()
- }
-
- if ($next.hasClass('active')) return (this.sliding = false)
-
- var relatedTarget = $next[0]
- var slideEvent = $.Event('slide.bs.carousel', {
- relatedTarget: relatedTarget,
- direction: direction
- })
- this.$element.trigger(slideEvent)
- if (slideEvent.isDefaultPrevented()) return
-
- this.sliding = true
-
- isCycling && this.pause()
-
- if (this.$indicators.length) {
- this.$indicators.find('.active').removeClass('active')
- var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
- $nextIndicator && $nextIndicator.addClass('active')
- }
-
- var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
- if ($.support.transition && this.$element.hasClass('slide')) {
- $next.addClass(type)
- $next[0].offsetWidth // force reflow
- $active.addClass(direction)
- $next.addClass(direction)
- $active
- .one('bsTransitionEnd', function () {
- $next.removeClass([type, direction].join(' ')).addClass('active')
- $active.removeClass(['active', direction].join(' '))
- that.sliding = false
- setTimeout(function () {
- that.$element.trigger(slidEvent)
- }, 0)
- })
- .emulateTransitionEnd($active.css('transition-duration').slice(0, -1) * 1000)
- } else {
- $active.removeClass('active')
- $next.addClass('active')
- this.sliding = false
- this.$element.trigger(slidEvent)
- }
-
- isCycling && this.cycle()
-
- return this
+ var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
+ if ($.support.transition && this.$element.hasClass('slide')) {
+ $next.addClass(type)
+ $next[0].offsetWidth // force reflow
+ $active.addClass(direction)
+ $next.addClass(direction)
+ $active
+ .one('bsTransitionEnd', function () {
+ $next.removeClass([type, direction].join(' ')).addClass('active')
+ $active.removeClass(['active', direction].join(' '))
+ that.sliding = false
+ setTimeout(function () {
+ that.$element.trigger(slidEvent)
+ }, 0)
+ })
+ .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
+ } else {
+ $active.removeClass('active')
+ $next.addClass('active')
+ this.sliding = false
+ this.$element.trigger(slidEvent)
}
+ isCycling && this.cycle()
- // CAROUSEL PLUGIN DEFINITION
- // ==========================
+ return this
+ }
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.carousel')
- var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
- var action = typeof option == 'string' ? option : options.slide
- if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
- if (typeof option == 'number') data.to(option)
- else if (action) data[action]()
- else if (options.interval) data.pause().cycle()
- })
- }
+ // CAROUSEL PLUGIN DEFINITION
+ // ==========================
- var old = $.fn.carousel
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.carousel')
+ var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
+ var action = typeof option == 'string' ? option : options.slide
+
+ if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
+ if (typeof option == 'number') data.to(option)
+ else if (action) data[action]()
+ else if (options.interval) data.pause().cycle()
+ })
+ }
- $.fn.carousel = Plugin
- $.fn.carousel.Constructor = Carousel
+ var old = $.fn.carousel
+ $.fn.carousel = Plugin
+ $.fn.carousel.Constructor = Carousel
- // CAROUSEL NO CONFLICT
- // ====================
- $.fn.carousel.noConflict = function () {
- $.fn.carousel = old
- return this
- }
+ // CAROUSEL NO CONFLICT
+ // ====================
+ $.fn.carousel.noConflict = function () {
+ $.fn.carousel = old
+ return this
+ }
- // CAROUSEL DATA-API
- // =================
- $(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
- var href
- var $this = $(this)
- var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
- var options = $.extend({}, $target.data(), $this.data())
- var slideIndex = $this.attr('data-slide-to')
- if (slideIndex) options.interval = false
+ // CAROUSEL DATA-API
+ // =================
- Plugin.call($target, options)
+ $(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
+ var href
+ var $this = $(this)
+ var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
+ if (!$target.hasClass('carousel')) return
+ var options = $.extend({}, $target.data(), $this.data())
+ var slideIndex = $this.attr('data-slide-to')
+ if (slideIndex) options.interval = false
- if (slideIndex) {
- $target.data('bs.carousel').to(slideIndex)
- }
+ Plugin.call($target, options)
- e.preventDefault()
- })
+ if (slideIndex) {
+ $target.data('bs.carousel').to(slideIndex)
+ }
- $(window).on('load', function () {
- $('[data-ride="carousel"]').each(function () {
- var $carousel = $(this)
- Plugin.call($carousel, $carousel.data())
- })
- })
+ e.preventDefault()
+ })
+ $(window).on('load', function () {
+ $('[data-ride="carousel"]').each(function () {
+ var $carousel = $(this)
+ Plugin.call($carousel, $carousel.data())
+ })
})
-}();
+}(jQuery);
diff --git a/js/collapse.js b/js/collapse.js
index d37b8898c..db89804cb 100644
--- a/js/collapse.js
+++ b/js/collapse.js
@@ -1,5 +1,5 @@
/* ========================================================================
- * Bootstrap: collapse.js v3.1.1
+ * Bootstrap: collapse.js v3.2.0
* http://getbootstrap.com/javascript/#collapse
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
@@ -7,170 +7,165 @@
* ======================================================================== */
-+function () { 'use strict';
++function ($) {
+ 'use strict';
- (function (o_o) {
- typeof define == 'function' && define.amd ? define(['jquery'], o_o) :
- typeof exports == 'object' ? o_o(require('jquery')) : o_o(jQuery)
- })(function ($) {
+ // COLLAPSE PUBLIC CLASS DEFINITION
+ // ================================
- // COLLAPSE PUBLIC CLASS DEFINITION
- // ================================
+ var Collapse = function (element, options) {
+ this.$element = $(element)
+ this.options = $.extend({}, Collapse.DEFAULTS, options)
+ this.transitioning = null
- var Collapse = function (element, options) {
- this.$element = $(element)
- this.options = $.extend({}, Collapse.DEFAULTS, options)
- this.transitioning = null
+ if (this.options.parent) this.$parent = $(this.options.parent)
+ if (this.options.toggle) this.toggle()
+ }
- if (this.options.parent) this.$parent = $(this.options.parent)
- if (this.options.toggle) this.toggle()
- }
-
- Collapse.VERSION = '3.1.1'
-
- Collapse.DEFAULTS = {
- toggle: true
- }
+ Collapse.VERSION = '3.2.0'
- Collapse.prototype.dimension = function () {
- var hasWidth = this.$element.hasClass('width')
- return hasWidth ? 'width' : 'height'
- }
+ Collapse.TRANSITION_DURATION = 350
- Collapse.prototype.show = function () {
- if (this.transitioning || this.$element.hasClass('in')) return
+ Collapse.DEFAULTS = {
+ toggle: true
+ }
- var startEvent = $.Event('show.bs.collapse')
- this.$element.trigger(startEvent)
- if (startEvent.isDefaultPrevented()) return
+ Collapse.prototype.dimension = function () {
+ var hasWidth = this.$element.hasClass('width')
+ return hasWidth ? 'width' : 'height'
+ }
- var actives = this.$parent && this.$parent.find('> .panel > .in')
+ Collapse.prototype.show = function () {
+ if (this.transitioning || this.$element.hasClass('in')) return
- if (actives && actives.length) {
- var hasData = actives.data('bs.collapse')
- if (hasData && hasData.transitioning) return
- Plugin.call(actives, 'hide')
- hasData || actives.data('bs.collapse', null)
- }
+ var startEvent = $.Event('show.bs.collapse')
+ this.$element.trigger(startEvent)
+ if (startEvent.isDefaultPrevented()) return
- var dimension = this.dimension()
+ var actives = this.$parent && this.$parent.find('> .panel > .in')
- this.$element
- .removeClass('collapse')
- .addClass('collapsing')[dimension](0)
-
- this.transitioning = 1
+ if (actives && actives.length) {
+ var hasData = actives.data('bs.collapse')
+ if (hasData && hasData.transitioning) return
+ Plugin.call(actives, 'hide')
+ hasData || actives.data('bs.collapse', null)
+ }
- var complete = function () {
- this.$element
- .removeClass('collapsing')
- .addClass('collapse in')[dimension]('')
- this.transitioning = 0
- this.$element
- .trigger('shown.bs.collapse')
- }
+ var dimension = this.dimension()
- if (!$.support.transition) return complete.call(this)
+ this.$element
+ .removeClass('collapse')
+ .addClass('collapsing')[dimension](0)
- var scrollSize = $.camelCase(['scroll', dimension].join('-'))
+ this.transitioning = 1
+ var complete = function () {
+ this.$element
+ .removeClass('collapsing')
+ .addClass('collapse in')[dimension]('')
+ this.transitioning = 0
this.$element
- .one('bsTransitionEnd', $.proxy(complete, this))
- .emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize])
+ .trigger('shown.bs.collapse')
}
- Collapse.prototype.hide = function () {
- if (this.transitioning || !this.$element.hasClass('in')) return
+ if (!$.support.transition) return complete.call(this)
- var startEvent = $.Event('hide.bs.collapse')
- this.$element.trigger(startEvent)
- if (startEvent.isDefaultPrevented()) return
+ var scrollSize = $.camelCase(['scroll', dimension].join('-'))
- var dimension = this.dimension()
+ this.$element
+ .one('bsTransitionEnd', $.proxy(complete, this))
+ .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
+ }
- this.$element[dimension](this.$element[dimension]())[0].offsetHeight
+ Collapse.prototype.hide = function () {
+ if (this.transitioning || !this.$element.hasClass('in')) return
- this.$element
- .addClass('collapsing')
- .removeClass('collapse')
- .removeClass('in')
+ var startEvent = $.Event('hide.bs.collapse')
+ this.$element.trigger(startEvent)
+ if (startEvent.isDefaultPrevented()) return
+
+ var dimension = this.dimension()
- this.transitioning = 1
+ this.$element[dimension](this.$element[dimension]())[0].offsetHeight
- var complete = function () {
- this.transitioning = 0
- this.$element
- .trigger('hidden.bs.collapse')
- .removeClass('collapsing')
- .addClass('collapse')
- }
+ this.$element
+ .addClass('collapsing')
+ .removeClass('collapse in')
- if (!$.support.transition) return complete.call(this)
+ this.transitioning = 1
+ var complete = function () {
+ this.transitioning = 0
this.$element
- [dimension](0)
- .one('bsTransitionEnd', $.proxy(complete, this))
- .emulateTransitionEnd(350)
+ .trigger('hidden.bs.collapse')
+ .removeClass('collapsing')
+ .addClass('collapse')
}
- Collapse.prototype.toggle = function () {
- this[this.$element.hasClass('in') ? 'hide' : 'show']()
- }
+ if (!$.support.transition) return complete.call(this)
+ this.$element
+ [dimension](0)
+ .one('bsTransitionEnd', $.proxy(complete, this))
+ .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
+ }
- // COLLAPSE PLUGIN DEFINITION
- // ==========================
+ Collapse.prototype.toggle = function () {
+ this[this.$element.hasClass('in') ? 'hide' : 'show']()
+ }
- 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)
- if (!data && options.toggle && option == 'show') option = !option
- if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
+ // COLLAPSE PLUGIN DEFINITION
+ // ==========================
- var old = $.fn.collapse
+ 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)
- $.fn.collapse = Plugin
- $.fn.collapse.Constructor = Collapse
+ 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]()
+ })
+ }
+ var old = $.fn.collapse
- // COLLAPSE NO CONFLICT
- // ====================
+ $.fn.collapse = Plugin
+ $.fn.collapse.Constructor = Collapse
- $.fn.collapse.noConflict = function () {
- $.fn.collapse = old
- return this
- }
+ // COLLAPSE NO CONFLICT
+ // ====================
- // COLLAPSE DATA-API
- // =================
+ $.fn.collapse.noConflict = function () {
+ $.fn.collapse = old
+ return this
+ }
- $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
- var href
- var $this = $(this)
- var target = $this.attr('data-target')
- || e.preventDefault()
- || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
- var $target = $(target)
- var data = $target.data('bs.collapse')
- var option = data ? 'toggle' : $this.data()
- var parent = $this.attr('data-parent')
- var $parent = parent && $(parent)
-
- if (!data || !data.transitioning) {
- if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed')
- $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
- }
-
- Plugin.call($target, option)
- })
+ // COLLAPSE DATA-API
+ // =================
+
+ $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
+ var href
+ var $this = $(this)
+ var target = $this.attr('data-target')
+ || e.preventDefault()
+ || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
+ var $target = $(target)
+ var data = $target.data('bs.collapse')
+ var option = data ? 'toggle' : $this.data()
+ var parent = $this.attr('data-parent')
+ var $parent = parent && $(parent)
+
+ if (!data || !data.transitioning) {
+ if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed')
+ $this.toggleClass('collapsed', $target.hasClass('in'))
+ }
+
+ Plugin.call($target, option)
})
-}();
+}(jQuery);
diff --git a/js/dropdown.js b/js/dropdown.js
index f4f6358cd..756fc21f5 100644
--- a/js/dropdown.js
+++ b/js/dropdown.js
@@ -1,5 +1,5 @@
/* ========================================================================
- * Bootstrap: dropdown.js v3.1.1
+ * Bootstrap: dropdown.js v3.2.0
* http://getbootstrap.com/javascript/#dropdowns
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
@@ -7,151 +7,153 @@
* ======================================================================== */
-+function () { 'use strict';
++function ($) {
+ 'use strict';
- (function (o_o) {
- typeof define == 'function' && define.amd ? define(['jquery'], o_o) :
- typeof exports == 'object' ? o_o(require('jquery')) : o_o(jQuery)
- })(function ($) {
+ // DROPDOWN CLASS DEFINITION
+ // =========================
- // DROPDOWN CLASS DEFINITION
- // =========================
+ var backdrop = '.dropdown-backdrop'
+ var toggle = '[data-toggle="dropdown"]'
+ var Dropdown = function (element) {
+ $(element).on('click.bs.dropdown', this.toggle)
+ }
- var backdrop = '.dropdown-backdrop'
- var toggle = '[data-toggle="dropdown"]'
- var Dropdown = function (element) {
- $(element).on('click.bs.dropdown', this.toggle)
- }
+ Dropdown.VERSION = '3.2.0'
- Dropdown.VERSION = '3.1.1'
+ Dropdown.prototype.toggle = function (e) {
+ var $this = $(this)
- Dropdown.prototype.toggle = function (e) {
- var $this = $(this)
+ if ($this.is('.disabled, :disabled')) return
- if ($this.is('.disabled, :disabled')) return
+ var $parent = getParent($this)
+ var isActive = $parent.hasClass('open')
- var $parent = getParent($this)
- var isActive = $parent.hasClass('open')
+ clearMenus()
- clearMenus()
+ if (!isActive) {
+ if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
+ // if mobile we use a backdrop because click events don't delegate
+ $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
+ }
- if (!isActive) {
- if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
- // if mobile we use a backdrop because click events don't delegate
- $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
- }
+ var relatedTarget = { relatedTarget: this }
+ $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
- var relatedTarget = { relatedTarget: this }
- $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
+ if (e.isDefaultPrevented()) return
- if (e.isDefaultPrevented()) return
+ $this
+ .trigger('focus')
+ .attr('aria-expanded', 'true')
- $this.trigger('focus')
+ $parent
+ .toggleClass('open')
+ .trigger('shown.bs.dropdown', relatedTarget)
+ }
- $parent
- .toggleClass('open')
- .trigger('shown.bs.dropdown', relatedTarget)
- }
+ return false
+ }
- return false
- }
+ Dropdown.prototype.keydown = function (e) {
+ if (!/(38|40|27)/.test(e.keyCode)) return
- Dropdown.prototype.keydown = function (e) {
- if (!/(38|40|27)/.test(e.keyCode)) return
+ var $this = $(this)
- var $this = $(this)
+ e.preventDefault()
+ e.stopPropagation()
- e.preventDefault()
- e.stopPropagation()
+ if ($this.is('.disabled, :disabled')) return
- if ($this.is('.disabled, :disabled')) return
+ var $parent = getParent($this)
+ var isActive = $parent.hasClass('open')
- var $parent = getParent($this)
- var isActive = $parent.hasClass('open')
+ if (!isActive || (isActive && e.keyCode == 27)) {
+ if (e.which == 27) $parent.find(toggle).trigger('focus')
+ return $this.trigger('click')
+ }
- if (!isActive || (isActive && e.keyCode == 27)) {
- if (e.which == 27) $parent.find(toggle).trigger('focus')
- return $this.trigger('click')
- }
+ var desc = ' li:not(.divider):visible a'
+ var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)
- var desc = ' li:not(.divider):visible a'
- var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)
+ if (!$items.length) return
- if (!$items.length) return
+ var index = $items.index($items.filter(':focus'))
- var index = $items.index($items.filter(':focus'))
+ if (e.keyCode == 38 && index > 0) index-- // up
+ if (e.keyCode == 40 && index < $items.length - 1) index++ // down
+ if (!~index) index = 0
- if (e.keyCode == 38 && index > 0) index-- // up
- if (e.keyCode == 40 && index < $items.length - 1) index++ // down
- if (!~index) index = 0
+ $items.eq(index).trigger('focus')
+ }
- $items.eq(index).trigger('focus')
- }
+ function clearMenus(e) {
+ if (e && e.which === 3) return
+ $(backdrop).remove()
+ $(toggle).each(function () {
+ var $this = $(this)
+ var $parent = getParent($this)
+ var relatedTarget = { relatedTarget: this }
- function clearMenus(e) {
- if (e && e.which === 3) return
- $(backdrop).remove()
- $(toggle).each(function () {
- var $parent = getParent($(this))
- var relatedTarget = { relatedTarget: this }
- if (!$parent.hasClass('open')) return
- $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
- if (e.isDefaultPrevented()) return
- $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
- })
- }
+ if (!$parent.hasClass('open')) return
- function getParent($this) {
- var selector = $this.attr('data-target')
+ $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
- if (!selector) {
- selector = $this.attr('href')
- selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
- }
+ if (e.isDefaultPrevented()) return
+
+ $this.attr('aria-expanded', 'false')
+ $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
+ })
+ }
- var $parent = selector && $(selector)
+ function getParent($this) {
+ var selector = $this.attr('data-target')
- return $parent && $parent.length ? $parent : $this.parent()
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
}
+ var $parent = selector && $(selector)
- // DROPDOWN PLUGIN DEFINITION
- // ==========================
+ return $parent && $parent.length ? $parent : $this.parent()
+ }
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.dropdown')
- if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
- if (typeof option == 'string') data[option].call($this)
- })
- }
+ // DROPDOWN PLUGIN DEFINITION
+ // ==========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.dropdown')
- var old = $.fn.dropdown
+ if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
+ if (typeof option == 'string') data[option].call($this)
+ })
+ }
- $.fn.dropdown = Plugin
- $.fn.dropdown.Constructor = Dropdown
+ var old = $.fn.dropdown
+ $.fn.dropdown = Plugin
+ $.fn.dropdown.Constructor = Dropdown
- // DROPDOWN NO CONFLICT
- // ====================
- $.fn.dropdown.noConflict = function () {
- $.fn.dropdown = old
- return this
- }
+ // DROPDOWN NO CONFLICT
+ // ====================
+ $.fn.dropdown.noConflict = function () {
+ $.fn.dropdown = old
+ return this
+ }
- // APPLY TO STANDARD DROPDOWN ELEMENTS
- // ===================================
- $(document)
- .on('click.bs.dropdown.data-api', clearMenus)
- .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
- .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
- .on('keydown.bs.dropdown.data-api', toggle + ', [role="menu"], [role="listbox"]', Dropdown.prototype.keydown)
+ // APPLY TO STANDARD DROPDOWN ELEMENTS
+ // ===================================
- })
+ $(document)
+ .on('click.bs.dropdown.data-api', clearMenus)
+ .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
+ .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
+ .on('keydown.bs.dropdown.data-api', toggle + ', [role="menu"], [role="listbox"]', Dropdown.prototype.keydown)
-}();
+}(jQuery);
diff --git a/js/modal.js b/js/modal.js
index 2241e7b1e..f8d53e251 100644
--- a/js/modal.js
+++ b/js/modal.js
@@ -1,5 +1,5 @@
/* ========================================================================
- * Bootstrap: modal.js v3.1.1
+ * Bootstrap: modal.js v3.2.0
* http://getbootstrap.com/javascript/#modals
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
@@ -7,280 +7,277 @@
* ======================================================================== */
-+function () { 'use strict';
++function ($) {
+ 'use strict';
- (function (o_o) {
- typeof define == 'function' && define.amd ? define(['jquery'], o_o) :
- typeof exports == 'object' ? o_o(require('jquery')) : o_o(jQuery)
- })(function ($) {
+ // MODAL CLASS DEFINITION
+ // ======================
- // MODAL CLASS DEFINITION
- // ======================
+ var Modal = function (element, options) {
+ this.options = options
+ this.$body = $(document.body)
+ this.$element = $(element)
+ this.$backdrop =
+ this.isShown = null
+ this.scrollbarWidth = 0
- var Modal = function (element, options) {
- this.options = options
- this.$body = $(document.body)
- this.$element = $(element)
- this.$backdrop =
- this.isShown = null
- this.scrollbarWidth = 0
-
- if (this.options.remote) {
- this.$element
- .find('.modal-content')
- .load(this.options.remote, $.proxy(function () {
- this.$element.trigger('loaded.bs.modal')
- }, this))
- }
+ if (this.options.remote) {
+ this.$element
+ .find('.modal-content')
+ .load(this.options.remote, $.proxy(function () {
+ this.$element.trigger('loaded.bs.modal')
+ }, this))
}
+ }
- Modal.VERSION = '3.1.1'
+ Modal.VERSION = '3.2.0'
- Modal.DEFAULTS = {
- backdrop: true,
- keyboard: true,
- show: true
- }
+ Modal.TRANSITION_DURATION = 300
+ Modal.BACKDROP_TRANSITION_DURATION = 150
- Modal.prototype.toggle = function (_relatedTarget) {
- return this.isShown ? this.hide() : this.show(_relatedTarget)
- }
+ Modal.DEFAULTS = {
+ backdrop: true,
+ keyboard: true,
+ show: true
+ }
- Modal.prototype.show = function (_relatedTarget) {
- var that = this
- var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
+ Modal.prototype.toggle = function (_relatedTarget) {
+ return this.isShown ? this.hide() : this.show(_relatedTarget)
+ }
- this.$element.trigger(e)
+ Modal.prototype.show = function (_relatedTarget) {
+ var that = this
+ var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
- if (this.isShown || e.isDefaultPrevented()) return
+ this.$element.trigger(e)
- this.isShown = true
+ if (this.isShown || e.isDefaultPrevented()) return
- this.checkScrollbar()
- this.$body.addClass('modal-open')
+ this.isShown = true
- this.setScrollbar()
- this.escape()
+ this.checkScrollbar()
+ this.$body.addClass('modal-open')
- this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
+ this.setScrollbar()
+ this.escape()
- this.backdrop(function () {
- var transition = $.support.transition && that.$element.hasClass('fade')
+ this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
- if (!that.$element.parent().length) {
- that.$element.appendTo(that.$body) // don't move modals dom position
- }
+ this.backdrop(function () {
+ var transition = $.support.transition && that.$element.hasClass('fade')
- that.$element
- .show()
- .scrollTop(0)
+ if (!that.$element.parent().length) {
+ that.$element.appendTo(that.$body) // don't move modals dom position
+ }
- if (transition) {
- that.$element[0].offsetWidth // force reflow
- }
+ that.$element
+ .show()
+ .scrollTop(0)
- that.$element
- .addClass('in')
- .attr('aria-hidden', false)
+ if (transition) {
+ that.$element[0].offsetWidth // force reflow
+ }
- that.enforceFocus()
+ that.$element
+ .addClass('in')
+ .attr('aria-hidden', false)
- var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
+ that.enforceFocus()
- transition ?
- that.$element.find('.modal-dialog') // wait for modal to slide in
- .one('bsTransitionEnd', function () {
- that.$element.trigger('focus').trigger(e)
- })
- .emulateTransitionEnd(300) :
- that.$element.trigger('focus').trigger(e)
- })
- }
+ var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
- Modal.prototype.hide = function (e) {
- if (e) e.preventDefault()
-
- e = $.Event('hide.bs.modal')
+ transition ?
+ that.$element.find('.modal-dialog') // wait for modal to slide in
+ .one('bsTransitionEnd', function () {
+ that.$element.trigger('focus').trigger(e)
+ })
+ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
+ that.$element.trigger('focus').trigger(e)
+ })
+ }
- this.$element.trigger(e)
+ Modal.prototype.hide = function (e) {
+ if (e) e.preventDefault()
- if (!this.isShown || e.isDefaultPrevented()) return
+ e = $.Event('hide.bs.modal')
- this.isShown = false
+ this.$element.trigger(e)
- this.$body.removeClass('modal-open')
+ if (!this.isShown || e.isDefaultPrevented()) return
- this.resetScrollbar()
- this.escape()
+ this.isShown = false
- $(document).off('focusin.bs.modal')
+ this.$body.removeClass('modal-open')
- this.$element
- .removeClass('in')
- .attr('aria-hidden', true)
- .off('click.dismiss.bs.modal')
+ this.resetScrollbar()
+ this.escape()
- $.support.transition && this.$element.hasClass('fade') ?
- this.$element
- .one('bsTransitionEnd', $.proxy(this.hideModal, this))
- .emulateTransitionEnd(300) :
- this.hideModal()
- }
+ $(document).off('focusin.bs.modal')
- Modal.prototype.enforceFocus = function () {
- $(document)
- .off('focusin.bs.modal') // guard against infinite focus loop
- .on('focusin.bs.modal', $.proxy(function (e) {
- if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
- this.$element.trigger('focus')
- }
- }, this))
- }
-
- Modal.prototype.escape = function () {
- if (this.isShown && this.options.keyboard) {
- this.$element.on('keyup.dismiss.bs.modal', $.proxy(function (e) {
- e.which == 27 && this.hide()
- }, this))
- } else if (!this.isShown) {
- this.$element.off('keyup.dismiss.bs.modal')
- }
- }
+ this.$element
+ .removeClass('in')
+ .attr('aria-hidden', true)
+ .off('click.dismiss.bs.modal')
- Modal.prototype.hideModal = function () {
- var that = this
- this.$element.hide()
- this.backdrop(function () {
- that.$element.trigger('hidden.bs.modal')
- })
+ $.support.transition && this.$element.hasClass('fade') ?
+ this.$element
+ .one('bsTransitionEnd', $.proxy(this.hideModal, this))
+ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
+ this.hideModal()
+ }
+
+ Modal.prototype.enforceFocus = function () {
+ $(document)
+ .off('focusin.bs.modal') // guard against infinite focus loop
+ .on('focusin.bs.modal', $.proxy(function (e) {
+ if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
+ this.$element.trigger('focus')
+ }
+ }, this))
+ }
+
+ Modal.prototype.escape = function () {
+ if (this.isShown && this.options.keyboard) {
+ this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
+ e.which == 27 && this.hide()
+ }, this))
+ } else if (!this.isShown) {
+ this.$element.off('keydown.dismiss.bs.modal')
}
+ }
- Modal.prototype.removeBackdrop = function () {
- this.$backdrop && this.$backdrop.remove()
- this.$backdrop = null
- }
+ Modal.prototype.hideModal = function () {
+ var that = this
+ this.$element.hide()
+ this.backdrop(function () {
+ that.$element.trigger('hidden.bs.modal')
+ })
+ }
- Modal.prototype.backdrop = function (callback) {
- var that = this
- var animate = this.$element.hasClass('fade') ? 'fade' : ''
+ Modal.prototype.removeBackdrop = function () {
+ this.$backdrop && this.$backdrop.remove()
+ this.$backdrop = null
+ }
- if (this.isShown && this.options.backdrop) {
- var doAnimate = $.support.transition && animate
+ Modal.prototype.backdrop = function (callback) {
+ var that = this
+ var animate = this.$element.hasClass('fade') ? 'fade' : ''
- this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
- .appendTo(this.$body)
+ if (this.isShown && this.options.backdrop) {
+ var doAnimate = $.support.transition && animate
- this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
- if (e.target !== e.currentTarget) return
- this.options.backdrop == 'static'
- ? this.$element[0].focus.call(this.$element[0])
- : this.hide.call(this)
- }, this))
+ this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
+ .appendTo(this.$body)
- if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
+ this.$element.on('mousedown.dismiss.bs.modal', $.proxy(function (e) {
+ if (e.target !== e.currentTarget) return
+ this.options.backdrop == 'static'
+ ? this.$element[0].focus.call(this.$element[0])
+ : this.hide.call(this)
+ }, this))
- this.$backdrop.addClass('in')
+ if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
- if (!callback) return
+ this.$backdrop.addClass('in')
- doAnimate ?
- this.$backdrop
- .one('bsTransitionEnd', callback)
- .emulateTransitionEnd(150) :
- callback()
+ if (!callback) return
- } else if (!this.isShown && this.$backdrop) {
- this.$backdrop.removeClass('in')
+ doAnimate ?
+ this.$backdrop
+ .one('bsTransitionEnd', callback)
+ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
+ callback()
- var callbackRemove = function () {
- that.removeBackdrop()
- callback && callback()
- }
- $.support.transition && this.$element.hasClass('fade') ?
- this.$backdrop
- .one('bsTransitionEnd', callbackRemove)
- .emulateTransitionEnd(150) :
- callbackRemove()
+ } else if (!this.isShown && this.$backdrop) {
+ this.$backdrop.removeClass('in')
- } else if (callback) {
- callback()
+ var callbackRemove = function () {
+ that.removeBackdrop()
+ callback && callback()
}
- }
+ $.support.transition && this.$element.hasClass('fade') ?
+ this.$backdrop
+ .one('bsTransitionEnd', callbackRemove)
+ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
+ callbackRemove()
- Modal.prototype.checkScrollbar = function () {
- if (document.body.clientWidth >= window.innerWidth) return
- this.scrollbarWidth = this.scrollbarWidth || this.measureScrollbar()
+ } else if (callback) {
+ callback()
}
+ }
- Modal.prototype.setScrollbar = function () {
- var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
- if (this.scrollbarWidth) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
- }
+ Modal.prototype.checkScrollbar = function () {
+ if (document.body.clientWidth >= window.innerWidth) return
+ this.scrollbarWidth = this.scrollbarWidth || this.measureScrollbar()
+ }
- Modal.prototype.resetScrollbar = function () {
- this.$body.css('padding-right', '')
- }
+ Modal.prototype.setScrollbar = function () {
+ var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
+ if (this.scrollbarWidth) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
+ }
- Modal.prototype.measureScrollbar = function () { // thx walsh
- var scrollDiv = document.createElement('div')
- scrollDiv.className = 'modal-scrollbar-measure'
- this.$body.append(scrollDiv)
- var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
- this.$body[0].removeChild(scrollDiv)
- return scrollbarWidth
- }
+ Modal.prototype.resetScrollbar = function () {
+ this.$body.css('padding-right', '')
+ }
+ Modal.prototype.measureScrollbar = function () { // thx walsh
+ var scrollDiv = document.createElement('div')
+ scrollDiv.className = 'modal-scrollbar-measure'
+ this.$body.append(scrollDiv)
+ var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
+ this.$body[0].removeChild(scrollDiv)
+ return scrollbarWidth
+ }
- // MODAL PLUGIN DEFINITION
- // =======================
- function Plugin(option, _relatedTarget) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.modal')
- var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
+ // MODAL PLUGIN DEFINITION
+ // =======================
- if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
- if (typeof option == 'string') data[option](_relatedTarget)
- else if (options.show) data.show(_relatedTarget)
- })
- }
+ function Plugin(option, _relatedTarget) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.modal')
+ var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
- var old = $.fn.modal
+ if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
+ if (typeof option == 'string') data[option](_relatedTarget)
+ else if (options.show) data.show(_relatedTarget)
+ })
+ }
- $.fn.modal = Plugin
- $.fn.modal.Constructor = Modal
+ var old = $.fn.modal
+ $.fn.modal = Plugin
+ $.fn.modal.Constructor = Modal
- // MODAL NO CONFLICT
- // =================
- $.fn.modal.noConflict = function () {
- $.fn.modal = old
- return this
- }
+ // MODAL NO CONFLICT
+ // =================
+ $.fn.modal.noConflict = function () {
+ $.fn.modal = old
+ return this
+ }
- // MODAL DATA-API
- // ==============
- $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
- var $this = $(this)
- var href = $this.attr('href')
- var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
- var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
+ // MODAL DATA-API
+ // ==============
- if ($this.is('a')) e.preventDefault()
+ $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
+ var $this = $(this)
+ var href = $this.attr('href')
+ var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
+ var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
- $target.one('show.bs.modal', function (showEvent) {
- if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
- $target.one('hidden.bs.modal', function () {
- $this.is(':visible') && $this.trigger('focus')
- })
+ if ($this.is('a')) e.preventDefault()
+
+ $target.one('show.bs.modal', function (showEvent) {
+ if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
+ $target.one('hidden.bs.modal', function () {
+ $this.is(':visible') && $this.trigger('focus')
})
- Plugin.call($target, option, this)
})
-
+ Plugin.call($target, option, this)
})
-}();
+}(jQuery);
diff --git a/js/popover.js b/js/popover.js
index 919e9dc87..87b8d12de 100644
--- a/js/popover.js
+++ b/js/popover.js
@@ -1,5 +1,5 @@
/* ========================================================================
- * Bootstrap: popover.js v3.1.1
+ * Bootstrap: popover.js v3.2.0
* http://getbootstrap.com/javascript/#popovers
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
@@ -7,113 +7,107 @@
* ======================================================================== */
-+function () { 'use strict';
++function ($) {
+ 'use strict';
- (function (o_o) {
- typeof define == 'function' && define.amd ? define(['jquery'], o_o) :
- typeof exports == 'object' ? o_o(require('jquery')) : o_o(jQuery)
- })(function ($) {
+ // POPOVER PUBLIC CLASS DEFINITION
+ // ===============================
- // POPOVER PUBLIC CLASS DEFINITION
- // ===============================
+ var Popover = function (element, options) {
+ this.init('popover', element, options)
+ }
- var Popover = function (element, options) {
- this.init('popover', element, options)
- }
+ if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
- if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
-
- Popover.VERSION = '3.1.1'
-
- Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
- placement: 'right',
- trigger: 'click',
- content: '',
- template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
- })
+ Popover.VERSION = '3.2.0'
+ Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
+ placement: 'right',
+ trigger: 'click',
+ content: '',
+ template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
+ })
- // NOTE: POPOVER EXTENDS tooltip.js
- // ================================
- Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
+ // NOTE: POPOVER EXTENDS tooltip.js
+ // ================================
- Popover.prototype.constructor = Popover
+ Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
- Popover.prototype.getDefaults = function () {
- return Popover.DEFAULTS
- }
+ Popover.prototype.constructor = Popover
- Popover.prototype.setContent = function () {
- var $tip = this.tip()
- var title = this.getTitle()
- var content = this.getContent()
+ Popover.prototype.getDefaults = function () {
+ return Popover.DEFAULTS
+ }
- $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
- $tip.find('.popover-content').empty()[ // we use append for html objects to maintain js events
- this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
- ](content)
+ Popover.prototype.setContent = function () {
+ var $tip = this.tip()
+ var title = this.getTitle()
+ var content = this.getContent()
- $tip.removeClass('fade top bottom left right in')
+ $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
+ $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
+ this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
+ ](content)
- // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
- // this manually by checking the contents.
- if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
- }
+ $tip.removeClass('fade top bottom left right in')
- Popover.prototype.hasContent = function () {
- return this.getTitle() || this.getContent()
- }
+ // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
+ // this manually by checking the contents.
+ if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
+ }
- Popover.prototype.getContent = function () {
- var $e = this.$element
- var o = this.options
+ Popover.prototype.hasContent = function () {
+ return this.getTitle() || this.getContent()
+ }
- return $e.attr('data-content')
- || (typeof o.content == 'function' ?
- o.content.call($e[0]) :
- o.content)
- }
+ Popover.prototype.getContent = function () {
+ var $e = this.$element
+ var o = this.options
- Popover.prototype.arrow = function () {
- return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
- }
+ return $e.attr('data-content')
+ || (typeof o.content == 'function' ?
+ o.content.call($e[0]) :
+ o.content)
+ }
- Popover.prototype.tip = function () {
- if (!this.$tip) this.$tip = $(this.options.template)
- return this.$tip
- }
+ Popover.prototype.arrow = function () {
+ return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
+ }
+ Popover.prototype.tip = function () {
+ if (!this.$tip) this.$tip = $(this.options.template)
+ return this.$tip
+ }
- // POPOVER PLUGIN DEFINITION
- // =========================
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.popover')
- var options = typeof option == 'object' && option
+ // POPOVER PLUGIN DEFINITION
+ // =========================
- if (!data && option == 'destroy') return
- if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.popover')
+ var options = typeof option == 'object' && option
- var old = $.fn.popover
+ if (!data && option == 'destroy') return
+ if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
- $.fn.popover = Plugin
- $.fn.popover.Constructor = Popover
+ var old = $.fn.popover
+ $.fn.popover = Plugin
+ $.fn.popover.Constructor = Popover
- // POPOVER NO CONFLICT
- // ===================
- $.fn.popover.noConflict = function () {
- $.fn.popover = old
- return this
- }
+ // POPOVER NO CONFLICT
+ // ===================
- })
+ $.fn.popover.noConflict = function () {
+ $.fn.popover = old
+ return this
+ }
-}();
+}(jQuery);
diff --git a/js/scrollspy.js b/js/scrollspy.js
index ac0244391..db2378787 100644
--- a/js/scrollspy.js
+++ b/js/scrollspy.js
@@ -1,5 +1,5 @@
/* ========================================================================
- * Bootstrap: scrollspy.js v3.1.1
+ * Bootstrap: scrollspy.js v3.2.0
* http://getbootstrap.com/javascript/#scrollspy
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
@@ -7,170 +7,164 @@
* ======================================================================== */
-+function () { 'use strict';
++function ($) {
+ 'use strict';
- (function (o_o) {
- typeof define == 'function' && define.amd ? define(['jquery'], o_o) :
- typeof exports == 'object' ? o_o(require('jquery')) : o_o(jQuery)
- })(function ($) {
+ // SCROLLSPY CLASS DEFINITION
+ // ==========================
- // SCROLLSPY CLASS DEFINITION
- // ==========================
+ function ScrollSpy(element, options) {
+ var process = $.proxy(this.process, this)
- function ScrollSpy(element, options) {
- var process = $.proxy(this.process, this)
+ this.$body = $('body')
+ this.$scrollElement = $(element).is('body') ? $(window) : $(element)
+ this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
+ this.selector = (this.options.target || '') + ' .nav li > a'
+ this.offsets = []
+ this.targets = []
+ this.activeTarget = null
+ this.scrollHeight = 0
- this.$body = $('body')
- this.$scrollElement = $(element).is('body') ? $(window) : $(element)
- this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
- this.selector = (this.options.target || '') + ' .nav li > a'
- this.offsets = []
- this.targets = []
- this.activeTarget = null
- this.scrollHeight = 0
+ this.$scrollElement.on('scroll.bs.scrollspy', process)
+ this.refresh()
+ this.process()
+ }
- this.$scrollElement.on('scroll.bs.scrollspy', process)
- this.refresh()
- this.process()
- }
+ ScrollSpy.VERSION = '3.2.0'
+
+ ScrollSpy.DEFAULTS = {
+ offset: 10
+ }
- ScrollSpy.VERSION = '3.1.1'
+ ScrollSpy.prototype.getScrollHeight = function () {
+ return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
+ }
- ScrollSpy.DEFAULTS = {
- offset: 10
+ ScrollSpy.prototype.refresh = function () {
+ var offsetMethod = 'offset'
+ var offsetBase = 0
+
+ if (!$.isWindow(this.$scrollElement[0])) {
+ offsetMethod = 'position'
+ offsetBase = this.$scrollElement.scrollTop()
}
- ScrollSpy.prototype.getScrollHeight = function () {
- return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
+ this.offsets = []
+ this.targets = []
+ this.scrollHeight = this.getScrollHeight()
+
+ var self = this
+
+ this.$body
+ .find(this.selector)
+ .map(function () {
+ var $el = $(this)
+ var href = $el.data('target') || $el.attr('href')
+ var $href = /^#./.test(href) && $(href)
+
+ return ($href
+ && $href.length
+ && $href.is(':visible')
+ && [[$href[offsetMethod]().top + offsetBase, href]]) || null
+ })
+ .sort(function (a, b) { return a[0] - b[0] })
+ .each(function () {
+ self.offsets.push(this[0])
+ self.targets.push(this[1])
+ })
+ }
+
+ ScrollSpy.prototype.process = function () {
+ var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
+ var scrollHeight = this.getScrollHeight()
+ var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
+ var offsets = this.offsets
+ var targets = this.targets
+ var activeTarget = this.activeTarget
+ var i
+
+ if (this.scrollHeight != scrollHeight) {
+ this.refresh()
}
- ScrollSpy.prototype.refresh = function () {
- var offsetMethod = 'offset'
- var offsetBase = 0
-
- if (!$.isWindow(this.$scrollElement[0])) {
- offsetMethod = 'position'
- offsetBase = this.$scrollElement.scrollTop()
- }
-
- this.offsets = []
- this.targets = []
- this.scrollHeight = this.getScrollHeight()
-
- var self = this
-
- this.$body
- .find(this.selector)
- .map(function () {
- var $el = $(this)
- var href = $el.data('target') || $el.attr('href')
- var $href = /^#./.test(href) && $(href)
-
- return ($href
- && $href.length
- && $href.is(':visible')
- && [[$href[offsetMethod]().top + offsetBase, href]]) || null
- })
- .sort(function (a, b) { return a[0] - b[0] })
- .each(function () {
- self.offsets.push(this[0])
- self.targets.push(this[1])
- })
+ if (scrollTop >= maxScroll) {
+ return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
}
- ScrollSpy.prototype.process = function () {
- var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
- var scrollHeight = this.getScrollHeight()
- var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
- var offsets = this.offsets
- var targets = this.targets
- var activeTarget = this.activeTarget
- var i
-
- if (this.scrollHeight != scrollHeight) {
- this.refresh()
- }
-
- if (scrollTop >= maxScroll) {
- return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
- }
-
- if (activeTarget && scrollTop <= offsets[0]) {
- return activeTarget != (i = targets[0]) && this.activate(i)
- }
-
- for (i = offsets.length; i--;) {
- activeTarget != targets[i]
- && scrollTop >= offsets[i]
- && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
- && this.activate(targets[i])
- }
+ if (activeTarget && scrollTop <= offsets[0]) {
+ return activeTarget != (i = targets[0]) && this.activate(i)
}
- ScrollSpy.prototype.activate = function (target) {
- this.activeTarget = target
+ for (i = offsets.length; i--;) {
+ activeTarget != targets[i]
+ && scrollTop >= offsets[i]
+ && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
+ && this.activate(targets[i])
+ }
+ }
- $(this.selector)
- .parentsUntil(this.options.target, '.active')
- .removeClass('active')
+ ScrollSpy.prototype.activate = function (target) {
+ this.activeTarget = target
- var selector = this.selector +
- '[data-target="' + target + '"],' +
- this.selector + '[href="' + target + '"]'
+ $(this.selector)
+ .parentsUntil(this.options.target, '.active')
+ .removeClass('active')
- var active = $(selector)
- .parents('li')
- .addClass('active')
+ var selector = this.selector +
+ '[data-target="' + target + '"],' +
+ this.selector + '[href="' + target + '"]'
- if (active.parent('.dropdown-menu').length) {
- active = active
- .closest('li.dropdown')
- .addClass('active')
- }
+ var active = $(selector)
+ .parents('li')
+ .addClass('active')
- active.trigger('activate.bs.scrollspy')
+ if (active.parent('.dropdown-menu').length) {
+ active = active
+ .closest('li.dropdown')
+ .addClass('active')
}
+ active.trigger('activate.bs.scrollspy')
+ }
- // SCROLLSPY PLUGIN DEFINITION
- // ===========================
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.scrollspy')
- var options = typeof option == 'object' && option
+ // SCROLLSPY PLUGIN DEFINITION
+ // ===========================
- if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.scrollspy')
+ var options = typeof option == 'object' && option
- var old = $.fn.scrollspy
+ if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
- $.fn.scrollspy = Plugin
- $.fn.scrollspy.Constructor = ScrollSpy
+ var old = $.fn.scrollspy
+ $.fn.scrollspy = Plugin
+ $.fn.scrollspy.Constructor = ScrollSpy
- // SCROLLSPY NO CONFLICT
- // =====================
- $.fn.scrollspy.noConflict = function () {
- $.fn.scrollspy = old
- return this
- }
+ // SCROLLSPY NO CONFLICT
+ // =====================
+ $.fn.scrollspy.noConflict = function () {
+ $.fn.scrollspy = old
+ return this
+ }
- // SCROLLSPY DATA-API
- // ==================
- $(window).on('load.bs.scrollspy.data-api', function () {
- $('[data-spy="scroll"]').each(function () {
- var $spy = $(this)
- Plugin.call($spy, $spy.data())
- })
- })
+ // SCROLLSPY DATA-API
+ // ==================
+ $(window).on('load.bs.scrollspy.data-api', function () {
+ $('[data-spy="scroll"]').each(function () {
+ var $spy = $(this)
+ Plugin.call($spy, $spy.data())
+ })
})
-}();
+}(jQuery);
diff --git a/js/tab.js b/js/tab.js
index c8122157f..d7023c817 100644
--- a/js/tab.js
+++ b/js/tab.js
@@ -1,5 +1,5 @@
/* ========================================================================
- * Bootstrap: tab.js v3.1.1
+ * Bootstrap: tab.js v3.2.0
* http://getbootstrap.com/javascript/#tabs
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
@@ -7,128 +7,124 @@
* ======================================================================== */
-+function () { 'use strict';
++function ($) {
+ 'use strict';
- (function (o_o) {
- typeof define == 'function' && define.amd ? define(['jquery'], o_o) :
- typeof exports == 'object' ? o_o(require('jquery')) : o_o(jQuery)
- })(function ($) {
+ // TAB CLASS DEFINITION
+ // ====================
- // TAB CLASS DEFINITION
- // ====================
+ var Tab = function (element) {
+ this.element = $(element)
+ }
- var Tab = function (element) {
- this.element = $(element)
- }
-
- Tab.VERSION = '3.1.1'
-
- Tab.prototype.show = function () {
- var $this = this.element
- var $ul = $this.closest('ul:not(.dropdown-menu)')
- var selector = $this.data('target')
+ Tab.VERSION = '3.2.0'
- if (!selector) {
- selector = $this.attr('href')
- selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
- }
+ Tab.TRANSITION_DURATION = 150
- if ($this.parent('li').hasClass('active')) return
+ Tab.prototype.show = function () {
+ var $this = this.element
+ var $ul = $this.closest('ul:not(.dropdown-menu)')
+ var selector = $this.data('target')
- var previous = $ul.find('.active:last a')[0]
- var e = $.Event('show.bs.tab', {
- relatedTarget: previous
- })
-
- $this.trigger(e)
-
- if (e.isDefaultPrevented()) return
-
- var $target = $(selector)
-
- this.activate($this.closest('li'), $ul)
- this.activate($target, $target.parent(), function () {
- $this.trigger({
- type: 'shown.bs.tab',
- relatedTarget: previous
- })
- })
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
}
- Tab.prototype.activate = function (element, container, callback) {
- var $active = container.find('> .active')
- var transition = callback
- && $.support.transition
- && $active.hasClass('fade')
+ if ($this.parent('li').hasClass('active')) return
- function next() {
- $active
- .removeClass('active')
- .find('> .dropdown-menu > .active')
- .removeClass('active')
+ var previous = $ul.find('.active:last a')[0]
+ var e = $.Event('show.bs.tab', {
+ relatedTarget: previous
+ })
- element.addClass('active')
+ $this.trigger(e)
- if (transition) {
- element[0].offsetWidth // reflow for transition
- element.addClass('in')
- } else {
- element.removeClass('fade')
- }
+ if (e.isDefaultPrevented()) return
- if (element.parent('.dropdown-menu')) {
- element.closest('li.dropdown').addClass('active')
- }
+ var $target = $(selector)
- callback && callback()
+ this.activate($this.closest('li'), $ul)
+ this.activate($target, $target.parent(), function () {
+ $this.trigger({
+ type: 'shown.bs.tab',
+ relatedTarget: previous
+ })
+ })
+ }
+
+ 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')
+
+ element.addClass('active')
+
+ if (transition) {
+ element[0].offsetWidth // reflow for transition
+ element.addClass('in')
+ } else {
+ element.removeClass('fade')
}
- transition ?
- $active
- .one('bsTransitionEnd', next)
- .emulateTransitionEnd(150) :
- next()
+ if (element.parent('.dropdown-menu')) {
+ element.closest('li.dropdown').addClass('active')
+ }
- $active.removeClass('in')
+ callback && callback()
}
+ $active.length && transition ?
+ $active
+ .one('bsTransitionEnd', next)
+ .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
+ next()
- // TAB PLUGIN DEFINITION
- // =====================
+ $active.removeClass('in')
+ }
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.tab')
- if (!data) $this.data('bs.tab', (data = new Tab(this)))
- if (typeof option == 'string') data[option]()
- })
- }
+ // TAB PLUGIN DEFINITION
+ // =====================
- var old = $.fn.tab
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.tab')
- $.fn.tab = Plugin
- $.fn.tab.Constructor = Tab
+ if (!data) $this.data('bs.tab', (data = new Tab(this)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+ var old = $.fn.tab
- // TAB NO CONFLICT
- // ===============
+ $.fn.tab = Plugin
+ $.fn.tab.Constructor = Tab
- $.fn.tab.noConflict = function () {
- $.fn.tab = old
- return this
- }
+ // TAB NO CONFLICT
+ // ===============
- // TAB DATA-API
- // ============
+ $.fn.tab.noConflict = function () {
+ $.fn.tab = old
+ return this
+ }
- $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
- e.preventDefault()
- Plugin.call($(this), 'show')
- })
+ // TAB DATA-API
+ // ============
+
+ $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
+ e.preventDefault()
+ Plugin.call($(this), 'show')
})
-}();
+}(jQuery);
diff --git a/js/tests/index.html b/js/tests/index.html
index 363ebe599..1c025cf76 100644
--- a/js/tests/index.html
+++ b/js/tests/index.html
@@ -13,23 +13,22 @@
<script>
// See https://github.com/axemclion/grunt-saucelabs#test-result-details-with-qunit
var log = []
- QUnit.done = function (test_results) {
- var tests = log.map(function (details) {
- return {
+ QUnit.done(function (testResults) {
+ var tests = []
+ for (var i = 0, len = log.length; i < len; i++) {
+ var details = log[i]
+ tests.push({
name: details.name,
result: details.result,
expected: details.expected,
actual: details.actual,
source: details.source
- }
- })
- test_results.tests = tests
+ })
+ }
+ testResults.tests = tests
- // Delaying results a bit because in real-world scenario you won't get them immediately
- setTimeout(function () {
- window.global_test_results = test_results
- }, 2000)
- }
+ window.global_test_results = testResults
+ })
QUnit.testStart(function (testDetails) {
QUnit.log = function (details) {
@@ -39,6 +38,12 @@
}
}
})
+
+ // Cleanup
+ QUnit.testDone(function () {
+ $('#qunit-fixture').empty()
+ $('#modal-test, .modal-backdrop').remove()
+ })
</script>
<!-- Plugin sources -->
@@ -70,7 +75,7 @@
</head>
<body>
- <div>
+ <div id="qunit-container">
<div id="qunit"></div>
<div id="qunit-fixture"></div>
</div>
diff --git a/js/tests/unit/affix.js b/js/tests/unit/affix.js
index 1cdfc7f90..ef6ef74b9 100644
--- a/js/tests/unit/affix.js
+++ b/js/tests/unit/affix.js
@@ -19,15 +19,18 @@ $(function () {
})
test('should provide no conflict', function () {
- ok(!$.fn.affix, 'affix was set back to undefined (org value)')
+ strictEqual($.fn.affix, undefined, 'affix was set back to undefined (org value)')
})
- test('should return element', function () {
- ok($(document.body).bootstrapAffix()[0] == document.body, 'document.body returned')
+ test('should return jquery collection containing the element', function () {
+ var $el = $('<div/>')
+ var $affix = $el.bootstrapAffix()
+ ok($affix instanceof $, 'returns jquery collection')
+ strictEqual($affix[0], $el[0], 'collection contains element')
})
test('should exit early if element is not visible', function () {
- var $affix = $('<div style="display: none"></div>').bootstrapAffix()
+ var $affix = $('<div style="display: none"/>').bootstrapAffix()
$affix.data('bs.affix').checkPosition()
ok(!$affix.hasClass('affix'), 'affix class was not added')
})
@@ -35,8 +38,14 @@ $(function () {
test('should trigger affixed event after affix', function () {
stop()
- var template = $('<div id="affixTarget"><ul><li>Please affix</li><li>And unaffix</li></ul></div><div id="affixAfter" style="height: 20000px; display:block;"></div>')
- template.appendTo('body')
+ var templateHTML = '<div id="affixTarget">'
+ + '<ul>'
+ + '<li>Please affix</li>'
+ + '<li>And unaffix</li>'
+ + '</ul>'
+ + '</div>'
+ + '<div id="affixAfter" style="height: 20000px; display: block;"/>'
+ $(templateHTML).appendTo(document.body)
$('#affixTarget').bootstrapAffix({
offset: $('#affixTarget ul').position()
@@ -44,19 +53,19 @@ $(function () {
$('#affixTarget')
.on('affix.bs.affix', function () {
- ok(true, 'affix event triggered')
+ ok(true, 'affix event fired')
}).on('affixed.bs.affix', function () {
- ok(true, 'affixed event triggered')
- $('#affixTarget').remove()
- $('#affixAfter').remove()
+ ok(true, 'affixed event fired')
+ $('#affixTarget, #affixAfter').remove()
start()
})
setTimeout(function () {
window.scrollTo(0, document.body.scrollHeight)
+
setTimeout(function () {
window.scroll(0, 0)
- }, 0)
+ }, 16) // for testing in a browser
}, 0)
})
})
diff --git a/js/tests/unit/alert.js b/js/tests/unit/alert.js
index 31116cce2..bc4eed676 100644
--- a/js/tests/unit/alert.js
+++ b/js/tests/unit/alert.js
@@ -19,52 +19,52 @@ $(function () {
})
test('should provide no conflict', function () {
- ok(!$.fn.alert, 'alert was set back to undefined (org value)')
+ strictEqual($.fn.alert, undefined, 'alert was set back to undefined (org value)')
})
- test('should return element', function () {
- ok($(document.body).bootstrapAlert()[0] == document.body, 'document.body returned')
+ test('should return jquery collection containing the element', function () {
+ var $el = $('<div/>')
+ var $alert = $el.bootstrapAlert()
+ ok($alert instanceof $, 'returns jquery collection')
+ strictEqual($alert[0], $el[0], 'collection contains element')
})
test('should fade element out on clicking .close', function () {
- var alertHTML = '<div class="alert-message warning fade in">' +
- '<a class="close" href="#" data-dismiss="alert">×</a>' +
- '<p><strong>Holy guacamole!</strong> Best check yo self, you\'re not looking too good.</p>' +
- '</div>'
- var alert = $(alertHTML).bootstrapAlert()
+ var alertHTML = '<div class="alert alert-danger fade in">'
+ + '<a class="close" href="#" data-dismiss="alert">×</a>'
+ + '<p><strong>Holy guacamole!</strong> Best check yo self, you\'re not looking too good.</p>'
+ + '</div>'
+ var $alert = $(alertHTML).bootstrapAlert()
- alert.find('.close').click()
+ $alert.find('.close').click()
- ok(!alert.hasClass('in'), 'remove .in class on .close click')
+ equal($alert.hasClass('in'), false, 'remove .in class on .close click')
})
test('should remove element when clicking .close', function () {
- $.support.transition = false
+ var alertHTML = '<div class="alert alert-danger fade in">'
+ + '<a class="close" href="#" data-dismiss="alert">×</a>'
+ + '<p><strong>Holy guacamole!</strong> Best check yo self, you\'re not looking too good.</p>'
+ + '</div>'
+ var $alert = $(alertHTML).appendTo('#qunit-fixture').bootstrapAlert()
- var alertHTML = '<div class="alert-message warning fade in">' +
- '<a class="close" href="#" data-dismiss="alert">×</a>' +
- '<p><strong>Holy guacamole!</strong> Best check yo self, you\'re not looking too good.</p>' +
- '</div>'
- var alert = $(alertHTML).appendTo('#qunit-fixture').bootstrapAlert()
+ notEqual($('#qunit-fixture').find('.alert').length, 0, 'element added to dom')
- ok($('#qunit-fixture').find('.alert-message').length, 'element added to dom')
+ $alert.find('.close').click()
- alert.find('.close').click()
-
- ok(!$('#qunit-fixture').find('.alert-message').length, 'element removed from dom')
+ equal($('#qunit-fixture').find('.alert').length, 0, 'element removed from dom')
})
test('should not fire closed when close is prevented', function () {
- $.support.transition = false
stop()
$('<div class="alert"/>')
.on('close.bs.alert', function (e) {
e.preventDefault()
- ok(true)
+ ok(true, 'close event fired')
start()
})
.on('closed.bs.alert', function () {
- ok(false)
+ ok(false, 'closed event fired')
})
.bootstrapAlert('close')
})
diff --git a/js/tests/unit/button.js b/js/tests/unit/button.js
index 671a93891..bd431d546 100644
--- a/js/tests/unit/button.js
+++ b/js/tests/unit/button.js
@@ -19,133 +19,133 @@ $(function () {
})
test('should provide no conflict', function () {
- ok(!$.fn.button, 'button was set back to undefined (org value)')
+ strictEqual($.fn.button, undefined, 'button was set back to undefined (org value)')
})
- test('should return element', function () {
- ok($(document.body).bootstrapButton()[0] == document.body, 'document.body returned')
+ test('should return jquery collection containing the element', function () {
+ var $el = $('<div/>')
+ var $button = $el.bootstrapButton()
+ ok($button instanceof $, 'returns jquery collection')
+ strictEqual($button[0], $el[0], 'collection contains element')
})
test('should return set state to loading', function () {
- var btn = $('<button class="btn" data-loading-text="fat">mdo</button>')
- equal(btn.html(), 'mdo', 'btn text equals mdo')
- btn.bootstrapButton('loading')
- equal(btn.html(), 'fat', 'btn text equals fat')
+ var $btn = $('<button class="btn" data-loading-text="fat">mdo</button>')
+ equal($btn.html(), 'mdo', 'btn text equals mdo')
+ $btn.bootstrapButton('loading')
+ equal($btn.html(), 'fat', 'btn text equals fat')
stop()
setTimeout(function () {
- ok(btn.attr('disabled'), 'btn is disabled')
- ok(btn.hasClass('disabled'), 'btn has disabled class')
+ ok($btn[0].hasAttribute('disabled'), 'btn is disabled')
+ ok($btn.hasClass('disabled'), 'btn has disabled class')
start()
}, 0)
})
test('should return reset state', function () {
- var btn = $('<button class="btn" data-loading-text="fat">mdo</button>')
- equal(btn.html(), 'mdo', 'btn text equals mdo')
- btn.bootstrapButton('loading')
- equal(btn.html(), 'fat', 'btn text equals fat')
+ var $btn = $('<button class="btn" data-loading-text="fat">mdo</button>')
+ equal($btn.html(), 'mdo', 'btn text equals mdo')
+ $btn.bootstrapButton('loading')
+ equal($btn.html(), 'fat', 'btn text equals fat')
stop()
setTimeout(function () {
- ok(btn.attr('disabled'), 'btn is disabled')
- ok(btn.hasClass('disabled'), 'btn has disabled class')
+ ok($btn[0].hasAttribute('disabled'), 'btn is disabled')
+ ok($btn.hasClass('disabled'), 'btn has disabled class')
start()
stop()
- btn.bootstrapButton('reset')
- equal(btn.html(), 'mdo', 'btn text equals mdo')
+ $btn.bootstrapButton('reset')
+ equal($btn.html(), 'mdo', 'btn text equals mdo')
setTimeout(function () {
- ok(!btn.attr('disabled'), 'btn is not disabled')
- ok(!btn.hasClass('disabled'), 'btn does not have disabled class')
+ ok(!$btn[0].hasAttribute('disabled'), 'btn is not disabled')
+ ok(!$btn.hasClass('disabled'), 'btn does not have disabled class')
start()
}, 0)
}, 0)
})
test('should work with an empty string as reset state', function () {
- var btn = $('<button class="btn" data-loading-text="fat"></button>')
- equal(btn.html(), '', 'btn text equals ""')
- btn.bootstrapButton('loading')
- equal(btn.html(), 'fat', 'btn text equals fat')
+ var $btn = $('<button class="btn" data-loading-text="fat"/>')
+ equal($btn.html(), '', 'btn text equals ""')
+ $btn.bootstrapButton('loading')
+ equal($btn.html(), 'fat', 'btn text equals fat')
stop()
setTimeout(function () {
- ok(btn.attr('disabled'), 'btn is disabled')
- ok(btn.hasClass('disabled'), 'btn has disabled class')
+ ok($btn[0].hasAttribute('disabled'), 'btn is disabled')
+ ok($btn.hasClass('disabled'), 'btn has disabled class')
start()
stop()
- btn.bootstrapButton('reset')
- equal(btn.html(), '', 'btn text equals ""')
+ $btn.bootstrapButton('reset')
+ equal($btn.html(), '', 'btn text equals ""')
setTimeout(function () {
- ok(!btn.attr('disabled'), 'btn is not disabled')
- ok(!btn.hasClass('disabled'), 'btn does not have disabled class')
+ ok(!$btn[0].hasAttribute('disabled'), 'btn is not disabled')
+ ok(!$btn.hasClass('disabled'), 'btn does not have disabled class')
start()
}, 0)
}, 0)
})
test('should toggle active', function () {
- var btn = $('<button class="btn">mdo</button>')
- ok(!btn.hasClass('active'), 'btn does not have active class')
- btn.bootstrapButton('toggle')
- ok(btn.hasClass('active'), 'btn has class active')
+ var $btn = $('<button class="btn">mdo</button>')
+ ok(!$btn.hasClass('active'), 'btn does not have active class')
+ $btn.bootstrapButton('toggle')
+ ok($btn.hasClass('active'), 'btn has class active')
})
test('should toggle active when btn children are clicked', function () {
- var btn = $('<button class="btn" data-toggle="button">mdo</button>')
- var inner = $('<i></i>')
- btn
- .append(inner)
- .appendTo($('#qunit-fixture'))
- ok(!btn.hasClass('active'), 'btn does not have active class')
- inner.click()
- ok(btn.hasClass('active'), 'btn has class active')
+ var $btn = $('<button class="btn" data-toggle="button">mdo</button>')
+ var $inner = $('<i/>')
+ $btn
+ .append($inner)
+ .appendTo('#qunit-fixture')
+ ok(!$btn.hasClass('active'), 'btn does not have active class')
+ $inner.click()
+ ok($btn.hasClass('active'), 'btn has class active')
})
test('should toggle active when btn children are clicked within btn-group', function () {
- var btngroup = $('<div class="btn-group" data-toggle="buttons"></div>')
- var btn = $('<button class="btn">fat</button>')
- var inner = $('<i></i>')
- btngroup
- .append(btn.append(inner))
- .appendTo($('#qunit-fixture'))
- ok(!btn.hasClass('active'), 'btn does not have active class')
- inner.click()
- ok(btn.hasClass('active'), 'btn has class active')
+ var $btngroup = $('<div class="btn-group" data-toggle="buttons"/>')
+ var $btn = $('<button class="btn">fat</button>')
+ var $inner = $('<i/>')
+ $btngroup
+ .append($btn.append($inner))
+ .appendTo('#qunit-fixture')
+ ok(!$btn.hasClass('active'), 'btn does not have active class')
+ $inner.click()
+ ok($btn.hasClass('active'), 'btn has class active')
})
test('should check for closest matching toggle', function () {
- var group = '<div class="btn-group" data-toggle="buttons">' +
- '<label class="btn btn-primary active">' +
- '<input type="radio" name="options" id="option1" checked="true"> Option 1' +
- '</label>' +
- '<label class="btn btn-primary">' +
- '<input type="radio" name="options" id="option2"> Option 2' +
- '</label>' +
- '<label class="btn btn-primary">' +
- '<input type="radio" name="options" id="option3"> Option 3' +
- '</label>' +
- '</div>'
-
- group = $(group)
-
- var btn1 = $(group.children()[0])
- var btn2 = $(group.children()[1])
-
- group.appendTo($('#qunit-fixture'))
-
- ok(btn1.hasClass('active'), 'btn1 has active class')
- ok(btn1.find('input').prop('checked'), 'btn1 is checked')
- ok(!btn2.hasClass('active'), 'btn2 does not have active class')
- ok(!btn2.find('input').prop('checked'), 'btn2 is not checked')
- btn2.find('input').click()
- ok(!btn1.hasClass('active'), 'btn1 does not have active class')
- ok(!btn1.find('input').prop('checked'), 'btn1 is checked')
- ok(btn2.hasClass('active'), 'btn2 has active class')
- ok(btn2.find('input').prop('checked'), 'btn2 is checked')
-
- btn2.find('input').click() /* clicking an already checked radio should not un-check it */
- ok(!btn1.hasClass('active'), 'btn1 does not have active class')
- ok(!btn1.find('input').prop('checked'), 'btn1 is checked')
- ok(btn2.hasClass('active'), 'btn2 has active class')
- ok(btn2.find('input').prop('checked'), 'btn2 is checked')
+ var groupHTML = '<div class="btn-group" data-toggle="buttons">'
+ + '<label class="btn btn-primary active">'
+ + '<input type="radio" name="options" id="option1" checked="true"> Option 1'
+ + '</label>'
+ + '<label class="btn btn-primary">'
+ + '<input type="radio" name="options" id="option2"> Option 2'
+ + '</label>'
+ + '<label class="btn btn-primary">'
+ + '<input type="radio" name="options" id="option3"> Option 3'
+ + '</label>'
+ + '</div>'
+ var $group = $(groupHTML).appendTo('#qunit-fixture')
+
+ var $btn1 = $group.children().eq(0)
+ var $btn2 = $group.children().eq(1)
+
+ ok($btn1.hasClass('active'), 'btn1 has active class')
+ ok($btn1.find('input').prop('checked'), 'btn1 is checked')
+ ok(!$btn2.hasClass('active'), 'btn2 does not have active class')
+ ok(!$btn2.find('input').prop('checked'), 'btn2 is not checked')
+ $btn2.find('input').click()
+ ok(!$btn1.hasClass('active'), 'btn1 does not have active class')
+ ok(!$btn1.find('input').prop('checked'), 'btn1 is checked')
+ ok($btn2.hasClass('active'), 'btn2 has active class')
+ ok($btn2.find('input').prop('checked'), 'btn2 is checked')
+
+ $btn2.find('input').click() // clicking an already checked radio should not un-check it
+ ok(!$btn1.hasClass('active'), 'btn1 does not have active class')
+ ok(!$btn1.find('input').prop('checked'), 'btn1 is checked')
+ ok($btn2.hasClass('active'), 'btn2 has active class')
+ ok($btn2.find('input').prop('checked'), 'btn2 is checked')
})
})
diff --git a/js/tests/unit/carousel.js b/js/tests/unit/carousel.js
index 474cfb40c..3f9e61a34 100644
--- a/js/tests/unit/carousel.js
+++ b/js/tests/unit/carousel.js
@@ -19,156 +19,383 @@ $(function () {
})
test('should provide no conflict', function () {
- ok(!$.fn.carousel, 'carousel was set back to undefined (orig value)')
+ strictEqual($.fn.carousel, undefined, 'carousel was set back to undefined (orig value)')
})
- test('should return element', function () {
- ok($(document.body).bootstrapCarousel()[0] == document.body, 'document.body returned')
+ test('should return jquery collection containing the element', function () {
+ var $el = $('<div/>')
+ var $carousel = $el.bootstrapCarousel()
+ ok($carousel instanceof $, 'returns jquery collection')
+ strictEqual($carousel[0], $el[0], 'collection contains element')
})
- test('should not fire slide when slide is prevented', function () {
- $.support.transition = false
+ test('should not fire slid when slide is prevented', function () {
stop()
$('<div class="carousel"/>')
.on('slide.bs.carousel', function (e) {
e.preventDefault()
- ok(true)
+ ok(true, 'slide event fired')
start()
})
.on('slid.bs.carousel', function () {
- ok(false)
+ ok(false, 'slid event fired')
})
.bootstrapCarousel('next')
})
test('should reset when slide is prevented', function () {
- var template = '<div id="carousel-example-generic" class="carousel slide"><ol class="carousel-indicators"><li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li><li data-target="#carousel-example-generic" data-slide-to="1"></li><li data-target="#carousel-example-generic" data-slide-to="2"></li></ol><div class="carousel-inner"><div class="item active"><div class="carousel-caption"></div></div><div class="item"><div class="carousel-caption"></div></div><div class="item"><div class="carousel-caption"></div></div></div><a class="left carousel-control" href="#carousel-example-generic" data-slide="prev"></a><a class="right carousel-control" href="#carousel-example-generic" data-slide="next"></a></div>'
- var $carousel = $(template)
- $.support.transition = false
+ var carouselHTML = '<div id="carousel-example-generic" class="carousel slide">'
+ + '<ol class="carousel-indicators">'
+ + '<li data-target="#carousel-example-generic" data-slide-to="0" class="active"/>'
+ + '<li data-target="#carousel-example-generic" data-slide-to="1"/>'
+ + '<li data-target="#carousel-example-generic" data-slide-to="2"/>'
+ + '</ol>'
+ + '<div class="carousel-inner">'
+ + '<div class="item active">'
+ + '<div class="carousel-caption"/>'
+ + '</div>'
+ + '<div class="item">'
+ + '<div class="carousel-caption"/>'
+ + '</div>'
+ + '<div class="item">'
+ + '<div class="carousel-caption"/>'
+ + '</div>'
+ + '</div>'
+ + '<a class="left carousel-control" href="#carousel-example-generic" data-slide="prev"/>'
+ + '<a class="right carousel-control" href="#carousel-example-generic" data-slide="next"/>'
+ + '</div>'
+ var $carousel = $(carouselHTML)
+
stop()
- $carousel.one('slide.bs.carousel', function (e) {
- e.preventDefault()
- setTimeout(function () {
- ok($carousel.find('.item:eq(0)').is('.active'))
- ok($carousel.find('.carousel-indicators li:eq(0)').is('.active'))
- $carousel.bootstrapCarousel('next')
- }, 1)
- })
- $carousel.one('slid.bs.carousel', function () {
- setTimeout(function () {
- ok($carousel.find('.item:eq(1)').is('.active'))
- ok($carousel.find('.carousel-indicators li:eq(1)').is('.active'))
- start()
- }, 1)
- })
- $carousel.bootstrapCarousel('next')
+ $carousel
+ .one('slide.bs.carousel', function (e) {
+ e.preventDefault()
+ setTimeout(function () {
+ ok($carousel.find('.item:eq(0)').is('.active'), 'first item still active')
+ ok($carousel.find('.carousel-indicators li:eq(0)').is('.active'), 'first indicator still active')
+ $carousel.bootstrapCarousel('next')
+ }, 0)
+ })
+ .one('slid.bs.carousel', function () {
+ setTimeout(function () {
+ ok(!$carousel.find('.item:eq(0)').is('.active'), 'first item still active')
+ ok(!$carousel.find('.carousel-indicators li:eq(0)').is('.active'), 'first indicator still active')
+ ok($carousel.find('.item:eq(1)').is('.active'), 'second item active')
+ ok($carousel.find('.carousel-indicators li:eq(1)').is('.active'), 'second indicator active')
+ start()
+ }, 0)
+ })
+ .bootstrapCarousel('next')
})
test('should fire slide event with direction', function () {
- var template = '<div id="myCarousel" class="carousel slide"><div class="carousel-inner"><div class="item active"><img alt=""><div class="carousel-caption"><h4>{{_i}}First Thumbnail label{{/i}}</h4><p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p></div></div><div class="item"><img alt=""><div class="carousel-caption"><h4>{{_i}}Second Thumbnail label{{/i}}</h4><p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p></div></div><div class="item"><img alt=""><div class="carousel-caption"><h4>{{_i}}Third Thumbnail label{{/i}}</h4><p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p></div></div></div><a class="left carousel-control" href="#myCarousel" data-slide="prev">&lsaquo;</a><a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</a></div>'
- $.support.transition = false
+ var carouselHTML = '<div id="myCarousel" class="carousel slide">'
+ + '<div class="carousel-inner">'
+ + '<div class="item active">'
+ + '<img alt="">'
+ + '<div class="carousel-caption">'
+ + '<h4>First Thumbnail label</h4>'
+ + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
+ + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
+ + 'ultricies vehicula ut id elit.</p>'
+ + '</div>'
+ + '</div>'
+ + '<div class="item">'
+ + '<img alt="">'
+ + '<div class="carousel-caption">'
+ + '<h4>Second Thumbnail label</h4>'
+ + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
+ + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
+ + 'ultricies vehicula ut id elit.</p>'
+ + '</div>'
+ + '</div>'
+ + '<div class="item">'
+ + '<img alt="">'
+ + '<div class="carousel-caption">'
+ + '<h4>Third Thumbnail label</h4>'
+ + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
+ + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
+ + 'ultricies vehicula ut id elit.</p>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
+ + '<a class="left carousel-control" href="#myCarousel" data-slide="prev">&lsaquo;</a>'
+ + '<a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</a>'
+ + '</div>'
+ var $carousel = $(carouselHTML)
+
stop()
- $(template).on('slide.bs.carousel', function (e) {
- e.preventDefault()
- ok(e.direction)
- ok(e.direction === 'right' || e.direction === 'left')
- start()
- }).bootstrapCarousel('next')
+
+ $carousel
+ .one('slide.bs.carousel', function (e) {
+ ok(e.direction, 'direction present on next')
+ strictEqual(e.direction, 'left', 'direction is left on next')
+
+ $carousel
+ .one('slide.bs.carousel', function (e) {
+ ok(e.direction, 'direction present on prev')
+ strictEqual(e.direction, 'right', 'direction is right on prev')
+ start()
+ })
+ .bootstrapCarousel('prev')
+ })
+ .bootstrapCarousel('next')
})
test('should fire slid event with direction', function () {
- var template = '<div id="myCarousel" class="carousel slide"><div class="carousel-inner"><div class="item active"><img alt=""><div class="carousel-caption"><h4>{{_i}}First Thumbnail label{{/i}}</h4><p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p></div></div><div class="item"><img alt=""><div class="carousel-caption"><h4>{{_i}}Second Thumbnail label{{/i}}</h4><p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p></div></div><div class="item"><img alt=""><div class="carousel-caption"><h4>{{_i}}Third Thumbnail label{{/i}}</h4><p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p></div></div></div><a class="left carousel-control" href="#myCarousel" data-slide="prev">&lsaquo;</a><a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</a></div>'
- $.support.transition = false
+ var carouselHTML = '<div id="myCarousel" class="carousel slide">'
+ + '<div class="carousel-inner">'
+ + '<div class="item active">'
+ + '<img alt="">'
+ + '<div class="carousel-caption">'
+ + '<h4>First Thumbnail label</h4>'
+ + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
+ + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
+ + 'ultricies vehicula ut id elit.</p>'
+ + '</div>'
+ + '</div>'
+ + '<div class="item">'
+ + '<img alt="">'
+ + '<div class="carousel-caption">'
+ + '<h4>Second Thumbnail label</h4>'
+ + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
+ + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
+ + 'ultricies vehicula ut id elit.</p>'
+ + '</div>'
+ + '</div>'
+ + '<div class="item">'
+ + '<img alt="">'
+ + '<div class="carousel-caption">'
+ + '<h4>Third Thumbnail label</h4>'
+ + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
+ + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
+ + 'ultricies vehicula ut id elit.</p>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
+ + '<a class="left carousel-control" href="#myCarousel" data-slide="prev">&lsaquo;</a>'
+ + '<a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</a>'
+ + '</div>'
+ var $carousel = $(carouselHTML)
+
stop()
- $(template).on('slid.bs.carousel', function (e) {
- e.preventDefault()
- ok(e.direction)
- ok(e.direction === 'right' || e.direction === 'left')
- start()
- }).bootstrapCarousel('next')
+
+ $carousel
+ .one('slid.bs.carousel', function (e) {
+ ok(e.direction, 'direction present on next')
+ strictEqual(e.direction, 'left', 'direction is left on next')
+
+ $carousel
+ .one('slid.bs.carousel', function (e) {
+ ok(e.direction, 'direction present on prev')
+ strictEqual(e.direction, 'right', 'direction is right on prev')
+ start()
+ })
+ .bootstrapCarousel('prev')
+ })
+ .bootstrapCarousel('next')
})
test('should fire slide event with relatedTarget', function () {
- var template = '<div id="myCarousel" class="carousel slide"><div class="carousel-inner"><div class="item active"><img alt=""><div class="carousel-caption"><h4>{{_i}}First Thumbnail label{{/i}}</h4><p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p></div></div><div class="item"><img alt=""><div class="carousel-caption"><h4>{{_i}}Second Thumbnail label{{/i}}</h4><p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p></div></div><div class="item"><img alt=""><div class="carousel-caption"><h4>{{_i}}Third Thumbnail label{{/i}}</h4><p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p></div></div></div><a class="left carousel-control" href="#myCarousel" data-slide="prev">&lsaquo;</a><a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</a></div>'
- $.support.transition = false
+ var template = '<div id="myCarousel" class="carousel slide">'
+ + '<div class="carousel-inner">'
+ + '<div class="item active">'
+ + '<img alt="">'
+ + '<div class="carousel-caption">'
+ + '<h4>First Thumbnail label</h4>'
+ + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
+ + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
+ + 'ultricies vehicula ut id elit.</p>'
+ + '</div>'
+ + '</div>'
+ + '<div class="item">'
+ + '<img alt="">'
+ + '<div class="carousel-caption">'
+ + '<h4>Second Thumbnail label</h4>'
+ + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
+ + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
+ + 'ultricies vehicula ut id elit.</p>'
+ + '</div>'
+ + '</div>'
+ + '<div class="item">'
+ + '<img alt="">'
+ + '<div class="carousel-caption">'
+ + '<h4>Third Thumbnail label</h4>'
+ + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
+ + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
+ + 'ultricies vehicula ut id elit.</p>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
+ + '<a class="left carousel-control" href="#myCarousel" data-slide="prev">&lsaquo;</a>'
+ + '<a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</a>'
+ + '</div>'
+
stop()
+
$(template)
.on('slide.bs.carousel', function (e) {
- e.preventDefault()
- ok(e.relatedTarget)
- ok($(e.relatedTarget).hasClass('item'))
+ ok(e.relatedTarget, 'relatedTarget present')
+ ok($(e.relatedTarget).hasClass('item'), 'relatedTarget has class "item"')
start()
})
.bootstrapCarousel('next')
})
test('should fire slid event with relatedTarget', function () {
- var template = '<div id="myCarousel" class="carousel slide"><div class="carousel-inner"><div class="item active"><img alt=""><div class="carousel-caption"><h4>{{_i}}First Thumbnail label{{/i}}</h4><p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p></div></div><div class="item"><img alt=""><div class="carousel-caption"><h4>{{_i}}Second Thumbnail label{{/i}}</h4><p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p></div></div><div class="item"><img alt=""><div class="carousel-caption"><h4>{{_i}}Third Thumbnail label{{/i}}</h4><p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p></div></div></div><a class="left carousel-control" href="#myCarousel" data-slide="prev">&lsaquo;</a><a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</a></div>'
- $.support.transition = false
+ var template = '<div id="myCarousel" class="carousel slide">'
+ + '<div class="carousel-inner">'
+ + '<div class="item active">'
+ + '<img alt="">'
+ + '<div class="carousel-caption">'
+ + '<h4>First Thumbnail label</h4>'
+ + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
+ + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
+ + 'ultricies vehicula ut id elit.</p>'
+ + '</div>'
+ + '</div>'
+ + '<div class="item">'
+ + '<img alt="">'
+ + '<div class="carousel-caption">'
+ + '<h4>Second Thumbnail label</h4>'
+ + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
+ + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
+ + 'ultricies vehicula ut id elit.</p>'
+ + '</div>'
+ + '</div>'
+ + '<div class="item">'
+ + '<img alt="">'
+ + '<div class="carousel-caption">'
+ + '<h4>Third Thumbnail label</h4>'
+ + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
+ + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
+ + 'ultricies vehicula ut id elit.</p>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
+ + '<a class="left carousel-control" href="#myCarousel" data-slide="prev">&lsaquo;</a>'
+ + '<a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</a>'
+ + '</div>'
+
stop()
+
$(template)
.on('slid.bs.carousel', function (e) {
- e.preventDefault()
- ok(e.relatedTarget)
- ok($(e.relatedTarget).hasClass('item'))
+ ok(e.relatedTarget, 'relatedTarget present')
+ ok($(e.relatedTarget).hasClass('item'), 'relatedTarget has class "item"')
start()
})
.bootstrapCarousel('next')
})
- test('should set interval from data attribute', 4, function () {
- var template = $('<div id="myCarousel" class="carousel slide"> <div class="carousel-inner"> <div class="item active"> <img alt=""> <div class="carousel-caption"> <h4>{{_i}}First Thumbnail label{{/i}}</h4> <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p> </div> </div> <div class="item"> <img alt=""> <div class="carousel-caption"> <h4>{{_i}}Second Thumbnail label{{/i}}</h4> <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p> </div> </div> <div class="item"> <img alt=""> <div class="carousel-caption"> <h4>{{_i}}Third Thumbnail label{{/i}}</h4> <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p> </div> </div> </div> <a class="left carousel-control" href="#myCarousel" data-slide="prev">&lsaquo;</a> <a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</a> </div>')
- template.attr('data-interval', 1814)
+ test('should set interval from data attribute', function () {
+ var templateHTML = '<div id="myCarousel" class="carousel slide">'
+ + '<div class="carousel-inner">'
+ + '<div class="item active">'
+ + '<img alt="">'
+ + '<div class="carousel-caption">'
+ + '<h4>First Thumbnail label</h4>'
+ + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
+ + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
+ + 'ultricies vehicula ut id elit.</p>'
+ + '</div>'
+ + '</div>'
+ + '<div class="item">'
+ + '<img alt="">'
+ + '<div class="carousel-caption">'
+ + '<h4>Second Thumbnail label</h4>'
+ + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
+ + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
+ + 'ultricies vehicula ut id elit.</p>'
+ + '</div>'
+ + '</div>'
+ + '<div class="item">'
+ + '<img alt="">'
+ + '<div class="carousel-caption">'
+ + '<h4>Third Thumbnail label</h4>'
+ + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
+ + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
+ + 'ultricies vehicula ut id elit.</p>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
+ + '<a class="left carousel-control" href="#myCarousel" data-slide="prev">&lsaquo;</a>'
+ + '<a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</a>'
+ + '</div>'
+ var $carousel = $(templateHTML)
+ $carousel.attr('data-interval', 1814)
- template.appendTo('body')
+ $carousel.appendTo('body')
$('[data-slide]').first().click()
- ok($('#myCarousel').data('bs.carousel').options.interval == 1814)
- $('#myCarousel').remove()
+ equal($carousel.data('bs.carousel').options.interval, 1814)
+ $carousel.remove()
- template.appendTo('body').attr('data-modal', 'foobar')
+ $carousel.appendTo('body').attr('data-modal', 'foobar')
$('[data-slide]').first().click()
- ok($('#myCarousel').data('bs.carousel').options.interval == 1814, 'even if there is an data-modal attribute set')
- $('#myCarousel').remove()
+ equal($carousel.data('bs.carousel').options.interval, 1814, 'even if there is an data-modal attribute set')
+ $carousel.remove()
- template.appendTo('body')
+ $carousel.appendTo('body')
$('[data-slide]').first().click()
- $('#myCarousel').attr('data-interval', 1860)
+ $carousel.attr('data-interval', 1860)
$('[data-slide]').first().click()
- ok($('#myCarousel').data('bs.carousel').options.interval == 1814, 'attributes should be read only on initialization')
- $('#myCarousel').remove()
-
- template.attr('data-interval', false)
- template.appendTo('body')
- $('#myCarousel').bootstrapCarousel(1)
- ok($('#myCarousel').data('bs.carousel').options.interval === false, 'data attribute has higher priority than default options')
- $('#myCarousel').remove()
+ equal($carousel.data('bs.carousel').options.interval, 1814, 'attributes should be read only on initialization')
+ $carousel.remove()
+
+ $carousel.attr('data-interval', false)
+ $carousel.appendTo('body')
+ $carousel.bootstrapCarousel(1)
+ strictEqual($carousel.data('bs.carousel').options.interval, false, 'data attribute has higher priority than default options')
+ $carousel.remove()
})
- test('should skip over non-items', function () {
- $.support.transition = false
-
- var $template = $(
- '<div id="myCarousel" class="carousel" data-interval="1814">'
- + '<div class="carousel-inner">'
- + '<div class="item active">'
- + '<img alt="">'
- + '</div>'
- + '<script type="text/x-metamorph" id="thingy"></script>'
- + '<div class="item">'
- + '<img alt="">'
- + '</div>'
- + '<div class="item">'
- + '</div>'
- + '</div>'
- + '</div>'
- )
+ test('should skip over non-items when using item indices', function () {
+ var templateHTML = '<div id="myCarousel" class="carousel" data-interval="1814">'
+ + '<div class="carousel-inner">'
+ + '<div class="item active">'
+ + '<img alt="">'
+ + '</div>'
+ + '<script type="text/x-metamorph" id="thingy"/>'
+ + '<div class="item">'
+ + '<img alt="">'
+ + '</div>'
+ + '<div class="item">'
+ + '</div>'
+ + '</div>'
+ + '</div>'
+ var $template = $(templateHTML)
$template.bootstrapCarousel()
- equal($template.find('.item')[0], $template.find('.active')[0], 'the first carousel item should be active')
+ strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item active')
$template.bootstrapCarousel(1)
- equal($template.find('.item')[1], $template.find('.active')[0], 'the second carousel item should be active')
+ strictEqual($template.find('.item')[1], $template.find('.active')[0], 'second item active')
+ })
+
+ test('should skip over non-items when using next/prev methods', function () {
+ var templateHTML = '<div id="myCarousel" class="carousel" data-interval="1814">'
+ + '<div class="carousel-inner">'
+ + '<div class="item active">'
+ + '<img alt="">'
+ + '</div>'
+ + '<script type="text/x-metamorph" id="thingy"/>'
+ + '<div class="item">'
+ + '<img alt="">'
+ + '</div>'
+ + '<div class="item">'
+ + '</div>'
+ + '</div>'
+ + '</div>'
+ var $template = $(templateHTML)
+
+ $template.bootstrapCarousel()
+
+ strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item active')
+
+ $template.bootstrapCarousel('next')
+
+ strictEqual($template.find('.item')[1], $template.find('.active')[0], 'second item active')
})
})
diff --git a/js/tests/unit/collapse.js b/js/tests/unit/collapse.js
index 4a0cf2b2e..ffa8f7e6d 100644
--- a/js/tests/unit/collapse.js
+++ b/js/tests/unit/collapse.js
@@ -19,156 +19,185 @@ $(function () {
})
test('should provide no conflict', function () {
- ok(!$.fn.collapse, 'collapse was set back to undefined (org value)')
+ strictEqual($.fn.collapse, undefined, 'collapse was set back to undefined (org value)')
})
- test('should return element', function () {
- ok($(document.body).bootstrapCollapse()[0] == document.body, 'document.body returned')
+ test('should return jquery collection containing the element', function () {
+ var $el = $('<div/>')
+ var $collapse = $el.bootstrapCollapse()
+ ok($collapse instanceof $, 'returns jquery collection')
+ strictEqual($collapse[0], $el[0], 'collection contains element')
})
test('should show a collapsed element', function () {
- var el = $('<div class="collapse"></div>').bootstrapCollapse('show')
- ok(el.hasClass('in'), 'has class in')
- ok(!/height/.test(el.attr('style')), 'has height reset')
+ var $el = $('<div class="collapse"/>').bootstrapCollapse('show')
+
+ ok($el.hasClass('in'), 'has class "in"')
+ ok(!/height/i.test($el.attr('style')), 'has height reset')
})
test('should hide a collapsed element', function () {
- var el = $('<div class="collapse"></div>').bootstrapCollapse('hide')
- ok(!el.hasClass('in'), 'does not have class in')
- ok(/height/.test(el.attr('style')), 'has height set')
+ var $el = $('<div class="collapse"/>').bootstrapCollapse('hide')
+
+ ok(!$el.hasClass('in'), 'does not have class "in"')
+ ok(/height/i.test($el.attr('style')), 'has height set')
})
test('should not fire shown when show is prevented', function () {
- $.support.transition = false
stop()
+
$('<div class="collapse"/>')
.on('show.bs.collapse', function (e) {
e.preventDefault()
- ok(true)
+ ok(true, 'show event fired')
start()
})
.on('shown.bs.collapse', function () {
- ok(false)
+ ok(false, 'shown event fired')
})
.bootstrapCollapse('show')
})
test('should reset style to auto after finishing opening collapse', function () {
- $.support.transition = false
stop()
+
$('<div class="collapse" style="height: 0px"/>')
.on('show.bs.collapse', function () {
- ok(this.style.height == '0px')
+ equal(this.style.height, '0px', 'height is 0px')
})
.on('shown.bs.collapse', function () {
- ok(this.style.height === '')
+ strictEqual(this.style.height, '', 'height is auto')
start()
})
.bootstrapCollapse('show')
})
- test('should add active class to target when collapse shown', function () {
- $.support.transition = false
+ test('should remove "collapsed" class from target when collapse is shown', function () {
stop()
- var target = $('<a data-toggle="collapse" href="#test1"></a>')
- .appendTo($('#qunit-fixture'))
+ var $target = $('<a data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
- $('<div id="test1"></div>')
- .appendTo($('#qunit-fixture'))
+ $('<div id="test1"/>')
+ .appendTo('#qunit-fixture')
.on('show.bs.collapse', function () {
- ok(!target.hasClass('collapsed'))
+ ok(!$target.hasClass('collapsed'))
start()
})
- target.click()
+ $target.click()
})
- test('should remove active class to target when collapse hidden', function () {
- $.support.transition = false
+ test('should add "collapsed" class to target when collapse is hidden', function () {
stop()
- var target = $('<a data-toggle="collapse" href="#test1"></a>')
- .appendTo($('#qunit-fixture'))
+ var $target = $('<a data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
- $('<div id="test1" class="in"></div>')
- .appendTo($('#qunit-fixture'))
+ $('<div id="test1" class="in"/>')
+ .appendTo('#qunit-fixture')
.on('hide.bs.collapse', function () {
- ok(target.hasClass('collapsed'))
+ ok($target.hasClass('collapsed'))
start()
})
- target.click()
+ $target.click()
+ })
+
+ test('should not close a collapse when initialized with "show" if already shown', function () {
+ stop()
+
+ expect(0)
+
+ var $test = $('<div id="test1" class="in"/>')
+ .appendTo('#qunit-fixture')
+ .on('hide.bs.collapse', function () {
+ ok(false)
+ })
+
+ $test.bootstrapCollapse('show')
+
+ setTimeout(start, 0)
+ })
+
+ test('should open a collapse when initialized with "show" if not already shown', function () {
+ stop()
+
+ expect(1)
+
+ var $test = $('<div id="test1" />')
+ .appendTo('#qunit-fixture')
+ .on('show.bs.collapse', function () {
+ ok(true)
+ })
+
+ $test.bootstrapCollapse('show')
+
+ setTimeout(start, 0)
})
- test('should remove active class from inactive accordion targets', function () {
- $.support.transition = false
+ test('should remove "collapsed" class from active accordion target', function () {
stop()
- var accordion = $('<div id="accordion"><div class="accordion-group"></div><div class="accordion-group"></div><div class="accordion-group"></div></div>')
- .appendTo($('#qunit-fixture'))
+ var accordionHTML = '<div id="accordion">'
+ + '<div class="accordion-group"/>'
+ + '<div class="accordion-group"/>'
+ + '<div class="accordion-group"/>'
+ + '</div>'
+ var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.accordion-group')
- var target1 = $('<a data-toggle="collapse" href="#body1" data-parent="#accordion"></a>')
- .appendTo(accordion.find('.accordion-group').eq(0))
+ var $target1 = $('<a data-toggle="collapse" href="#body1" data-parent="#accordion"/>').appendTo($groups.eq(0))
- $('<div id="body1" class="in"></div>')
- .appendTo(accordion.find('.accordion-group').eq(0))
+ $('<div id="body1" class="in"/>').appendTo($groups.eq(0))
- var target2 = $('<a class="collapsed" data-toggle="collapse" href="#body2" data-parent="#accordion"></a>')
- .appendTo(accordion.find('.accordion-group').eq(1))
+ var $target2 = $('<a class="collapsed" data-toggle="collapse" href="#body2" data-parent="#accordion"/>').appendTo($groups.eq(1))
- $('<div id="body2"></div>')
- .appendTo(accordion.find('.accordion-group').eq(1))
+ $('<div id="body2"/>').appendTo($groups.eq(1))
- var target3 = $('<a class="collapsed" data-toggle="collapse" href="#body3" data-parent="#accordion"></a>')
- .appendTo(accordion.find('.accordion-group').eq(2))
+ var $target3 = $('<a class="collapsed" data-toggle="collapse" href="#body3" data-parent="#accordion"/>').appendTo($groups.eq(2))
- $('<div id="body3"></div>')
- .appendTo(accordion.find('.accordion-group').eq(2))
+ $('<div id="body3"/>')
+ .appendTo($groups.eq(2))
.on('show.bs.collapse', function () {
- ok(target1.hasClass('collapsed'))
- ok(target2.hasClass('collapsed'))
- ok(!target3.hasClass('collapsed'))
+ ok($target1.hasClass('collapsed'), 'inactive target 1 does have class "collapsed"')
+ ok($target2.hasClass('collapsed'), 'inactive target 2 does have class "collapsed"')
+ ok(!$target3.hasClass('collapsed'), 'active target 3 does not have class "collapsed"')
start()
})
- target3.click()
+ $target3.click()
})
test('should allow dots in data-parent', function () {
- $.support.transition = false
stop()
- var accordion = $('<div class="accordion"><div class="accordion-group"></div><div class="accordion-group"></div><div class="accordion-group"></div></div>')
- .appendTo($('#qunit-fixture'))
+ var accordionHTML = '<div class="accordion">'
+ + '<div class="accordion-group"/>'
+ + '<div class="accordion-group"/>'
+ + '<div class="accordion-group"/>'
+ + '</div>'
+ var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.accordion-group')
- var target1 = $('<a data-toggle="collapse" href="#body1" data-parent=".accordion"></a>')
- .appendTo(accordion.find('.accordion-group').eq(0))
+ var $target1 = $('<a data-toggle="collapse" href="#body1" data-parent=".accordion"/>').appendTo($groups.eq(0))
- $('<div id="body1" class="in"></div>')
- .appendTo(accordion.find('.accordion-group').eq(0))
+ $('<div id="body1" class="in"/>').appendTo($groups.eq(0))
- var target2 = $('<a class="collapsed" data-toggle="collapse" href="#body2" data-parent=".accordion"></a>')
- .appendTo(accordion.find('.accordion-group').eq(1))
+ var $target2 = $('<a class="collapsed" data-toggle="collapse" href="#body2" data-parent=".accordion"/>').appendTo($groups.eq(1))
- $('<div id="body2"></div>')
- .appendTo(accordion.find('.accordion-group').eq(1))
+ $('<div id="body2"/>').appendTo($groups.eq(1))
- var target3 = $('<a class="collapsed" data-toggle="collapse" href="#body3" data-parent=".accordion"></a>')
- .appendTo(accordion.find('.accordion-group').eq(2))
+ var $target3 = $('<a class="collapsed" data-toggle="collapse" href="#body3" data-parent=".accordion"/>').appendTo($groups.eq(2))
- $('<div id="body3"></div>')
- .appendTo(accordion.find('.accordion-group').eq(2))
+ $('<div id="body3"/>')
+ .appendTo($groups.eq(2))
.on('show.bs.collapse', function () {
- ok(target1.hasClass('collapsed'))
- ok(target2.hasClass('collapsed'))
- ok(!target3.hasClass('collapsed'))
+ ok($target1.hasClass('collapsed'), 'inactive target 1 does have class "collapsed"')
+ ok($target2.hasClass('collapsed'), 'inactive target 2 does have class "collapsed"')
+ ok(!$target3.hasClass('collapsed'), 'active target 3 does not have class "collapsed"')
start()
})
- target3.click()
+ $target3.click()
})
})
diff --git a/js/tests/unit/dropdown.js b/js/tests/unit/dropdown.js
index f21aa98fc..335795fde 100644
--- a/js/tests/unit/dropdown.js
+++ b/js/tests/unit/dropdown.js
@@ -19,209 +19,208 @@ $(function () {
})
test('should provide no conflict', function () {
- ok(!$.fn.dropdown, 'dropdown was set back to undefined (org value)')
+ strictEqual($.fn.dropdown, undefined, 'dropdown was set back to undefined (org value)')
})
- test('should return element', function () {
- var el = $('<div />')
- ok(el.bootstrapDropdown()[0] === el[0], 'same element returned')
+ test('should return jquery collection containing the element', function () {
+ var $el = $('<div/>')
+ var $dropdown = $el.bootstrapDropdown()
+ ok($dropdown instanceof $, 'returns jquery collection')
+ strictEqual($dropdown[0], $el[0], 'collection contains element')
})
- test('should not open dropdown if target is disabled', function () {
- var dropdownHTML = '<ul class="tabs">' +
- '<li class="dropdown">' +
- '<button disabled href="#" class="btn dropdown-toggle" data-toggle="dropdown">Dropdown</button>' +
- '<ul class="dropdown-menu">' +
- '<li><a href="#">Secondary link</a></li>' +
- '<li><a href="#">Something else here</a></li>' +
- '<li class="divider"></li>' +
- '<li><a href="#">Another link</a></li>' +
- '</ul>' +
- '</li>' +
- '</ul>'
- var dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().click()
-
- ok(!dropdown.parent('.dropdown').hasClass('open'), 'open class added on click')
+ test('should not open dropdown if target is disabled via attribute', function () {
+ var dropdownHTML = '<ul class="tabs">'
+ + '<li class="dropdown">'
+ + '<button disabled href="#" class="btn dropdown-toggle" data-toggle="dropdown">Dropdown</button>'
+ + '<ul class="dropdown-menu">'
+ + '<li><a href="#">Secondary link</a></li>'
+ + '<li><a href="#">Something else here</a></li>'
+ + '<li class="divider"/>'
+ + '<li><a href="#">Another link</a></li>'
+ + '</ul>'
+ + '</li>'
+ + '</ul>'
+ var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().click()
+
+ ok(!$dropdown.parent('.dropdown').hasClass('open'), '"open" class added on click')
})
- test('should not open dropdown if target is disabled', function () {
- var dropdownHTML = '<ul class="tabs">' +
- '<li class="dropdown">' +
- '<button href="#" class="btn dropdown-toggle disabled" data-toggle="dropdown">Dropdown</button>' +
- '<ul class="dropdown-menu">' +
- '<li><a href="#">Secondary link</a></li>' +
- '<li><a href="#">Something else here</a></li>' +
- '<li class="divider"></li>' +
- '<li><a href="#">Another link</a></li>' +
- '</ul>' +
- '</li>' +
- '</ul>'
- var dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().click()
-
- ok(!dropdown.parent('.dropdown').hasClass('open'), 'open class added on click')
+ test('should not open dropdown if target is disabled via class', function () {
+ var dropdownHTML = '<ul class="tabs">'
+ + '<li class="dropdown">'
+ + '<button href="#" class="btn dropdown-toggle disabled" data-toggle="dropdown">Dropdown</button>'
+ + '<ul class="dropdown-menu">'
+ + '<li><a href="#">Secondary link</a></li>'
+ + '<li><a href="#">Something else here</a></li>'
+ + '<li class="divider"/>'
+ + '<li><a href="#">Another link</a></li>'
+ + '</ul>'
+ + '</li>'
+ + '</ul>'
+ var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().click()
+
+ ok(!$dropdown.parent('.dropdown').hasClass('open'), '"open" class added on click')
})
test('should add class open to menu if clicked', function () {
- var dropdownHTML = '<ul class="tabs">' +
- '<li class="dropdown">' +
- '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>' +
- '<ul class="dropdown-menu">' +
- '<li><a href="#">Secondary link</a></li>' +
- '<li><a href="#">Something else here</a></li>' +
- '<li class="divider"></li>' +
- '<li><a href="#">Another link</a></li>' +
- '</ul>' +
- '</li>' +
- '</ul>'
- var dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().click()
-
- ok(dropdown.parent('.dropdown').hasClass('open'), 'open class added on click')
+ var dropdownHTML = '<ul class="tabs">'
+ + '<li class="dropdown">'
+ + '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
+ + '<ul class="dropdown-menu">'
+ + '<li><a href="#">Secondary link</a></li>'
+ + '<li><a href="#">Something else here</a></li>'
+ + '<li class="divider"/>'
+ + '<li><a href="#">Another link</a></li>'
+ + '</ul>'
+ + '</li>'
+ + '</ul>'
+ var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().click()
+
+ ok($dropdown.parent('.dropdown').hasClass('open'), '"open" class added on click')
})
test('should test if element has a # before assuming it\'s a selector', function () {
- var dropdownHTML = '<ul class="tabs">' +
- '<li class="dropdown">' +
- '<a href="/foo/" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>' +
- '<ul class="dropdown-menu">' +
- '<li><a href="#">Secondary link</a></li>' +
- '<li><a href="#">Something else here</a></li>' +
- '<li class="divider"></li>' +
- '<li><a href="#">Another link</a></li>' +
- '</ul>' +
- '</li>' +
- '</ul>'
- var dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().click()
-
- ok(dropdown.parent('.dropdown').hasClass('open'), 'open class added on click')
+ var dropdownHTML = '<ul class="tabs">'
+ + '<li class="dropdown">'
+ + '<a href="/foo/" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
+ + '<ul class="dropdown-menu">'
+ + '<li><a href="#">Secondary link</a></li>'
+ + '<li><a href="#">Something else here</a></li>'
+ + '<li class="divider"/>'
+ + '<li><a href="#">Another link</a></li>'
+ + '</ul>'
+ + '</li>'
+ + '</ul>'
+ var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().click()
+
+ ok($dropdown.parent('.dropdown').hasClass('open'), '"open" class added on click')
})
- test('should remove open class if body clicked', function () {
- var dropdownHTML = '<ul class="tabs">' +
- '<li class="dropdown">' +
- '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>' +
- '<ul class="dropdown-menu">' +
- '<li><a href="#">Secondary link</a></li>' +
- '<li><a href="#">Something else here</a></li>' +
- '<li class="divider"></li>' +
- '<li><a href="#">Another link</a></li>' +
- '</ul>' +
- '</li>' +
- '</ul>'
- var dropdown = $(dropdownHTML)
- .appendTo('#qunit-fixture')
- .find('[data-toggle="dropdown"]')
- .bootstrapDropdown()
- .click()
-
- ok(dropdown.parent('.dropdown').hasClass('open'), 'open class added on click')
- $('body').click()
- ok(!dropdown.parent('.dropdown').hasClass('open'), 'open class removed')
- dropdown.remove()
+ test('should remove "open" class if body is clicked', function () {
+ var dropdownHTML = '<ul class="tabs">'
+ + '<li class="dropdown">'
+ + '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
+ + '<ul class="dropdown-menu">'
+ + '<li><a href="#">Secondary link</a></li>'
+ + '<li><a href="#">Something else here</a></li>'
+ + '<li class="divider"/>'
+ + '<li><a href="#">Another link</a></li>'
+ + '</ul>'
+ + '</li>'
+ + '</ul>'
+ var $dropdown = $(dropdownHTML)
+ .appendTo('#qunit-fixture')
+ .find('[data-toggle="dropdown"]')
+ .bootstrapDropdown()
+ .click()
+
+ ok($dropdown.parent('.dropdown').hasClass('open'), '"open" class added on click')
+ $(document.body).click()
+ ok(!$dropdown.parent('.dropdown').hasClass('open'), '"open" class removed')
})
- test('should remove open class if body clicked, with multiple drop downs', function () {
- var dropdownHTML = '<ul class="nav">' +
- ' <li><a href="#menu1">Menu 1</a></li>' +
- ' <li class="dropdown" id="testmenu">' +
- ' <a class="dropdown-toggle" data-toggle="dropdown" href="#testmenu">Test menu <b class="caret"></b></a>' +
- ' <ul class="dropdown-menu" role="menu">' +
- ' <li><a href="#sub1">Submenu 1</a></li>' +
- ' </ul>' +
- ' </li>' +
- '</ul>' +
- '<div class="btn-group">' +
- ' <button class="btn">Actions</button>' +
- ' <button class="btn dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>' +
- ' <ul class="dropdown-menu">' +
- ' <li><a href="#">Action 1</a></li>' +
- ' </ul>' +
- '</div>'
- var dropdowns = $(dropdownHTML).appendTo('#qunit-fixture').find('[data-toggle="dropdown"]')
- var first = dropdowns.first()
- var last = dropdowns.last()
-
- ok(dropdowns.length == 2, 'Should be two dropdowns')
-
- first.click()
- ok(first.parents('.open').length == 1, 'open class added on click')
- ok($('#qunit-fixture .open').length == 1, 'only one object is open')
- $('body').click()
- ok($('#qunit-fixture .open').length === 0, 'open class removed')
-
- last.click()
- ok(last.parent('.open').length == 1, 'open class added on click')
- ok($('#qunit-fixture .open').length == 1, 'only one object is open')
- $('body').click()
- ok($('#qunit-fixture .open').length === 0, 'open class removed')
-
- $('#qunit-fixture').html('')
+ test('should remove "open" class if body is clicked, with multiple dropdowns', function () {
+ var dropdownHTML = '<ul class="nav">'
+ + '<li><a href="#menu1">Menu 1</a></li>'
+ + '<li class="dropdown" id="testmenu">'
+ + '<a class="dropdown-toggle" data-toggle="dropdown" href="#testmenu">Test menu <span class="caret"/></a>'
+ + '<ul class="dropdown-menu" role="menu">'
+ + '<li><a href="#sub1">Submenu 1</a></li>'
+ + '</ul>'
+ + '</li>'
+ + '</ul>'
+ + '<div class="btn-group">'
+ + '<button class="btn">Actions</button>'
+ + '<button class="btn dropdown-toggle" data-toggle="dropdown"><span class="caret"/></button>'
+ + '<ul class="dropdown-menu">'
+ + '<li><a href="#">Action 1</a></li>'
+ + '</ul>'
+ + '</div>'
+ var $dropdowns = $(dropdownHTML).appendTo('#qunit-fixture').find('[data-toggle="dropdown"]')
+ var $first = $dropdowns.first()
+ var $last = $dropdowns.last()
+
+ strictEqual($dropdowns.length, 2, 'two dropdowns')
+
+ $first.click()
+ strictEqual($first.parents('.open').length, 1, '"open" class added on click')
+ strictEqual($('#qunit-fixture .open').length, 1, 'only one dropdown is open')
+ $(document.body).click()
+ strictEqual($('#qunit-fixture .open').length, 0, '"open" class removed')
+
+ $last.click()
+ strictEqual($last.parent('.open').length, 1, '"open" class added on click')
+ strictEqual($('#qunit-fixture .open').length, 1, 'only one dropdown is open')
+ $(document.body).click()
+ strictEqual($('#qunit-fixture .open').length, 0, '"open" class removed')
})
test('should fire show and hide event', function () {
- var dropdownHTML = '<ul class="tabs">' +
- '<li class="dropdown">' +
- '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>' +
- '<ul class="dropdown-menu">' +
- '<li><a href="#">Secondary link</a></li>' +
- '<li><a href="#">Something else here</a></li>' +
- '<li class="divider"></li>' +
- '<li><a href="#">Another link</a></li>' +
- '</ul>' +
- '</li>' +
- '</ul>'
- var dropdown = $(dropdownHTML)
- .appendTo('#qunit-fixture')
- .find('[data-toggle="dropdown"]')
- .bootstrapDropdown()
+ var dropdownHTML = '<ul class="tabs">'
+ + '<li class="dropdown">'
+ + '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
+ + '<ul class="dropdown-menu">'
+ + '<li><a href="#">Secondary link</a></li>'
+ + '<li><a href="#">Something else here</a></li>'
+ + '<li class="divider"/>'
+ + '<li><a href="#">Another link</a></li>'
+ + '</ul>'
+ + '</li>'
+ + '</ul>'
+ var $dropdown = $(dropdownHTML)
+ .appendTo('#qunit-fixture')
+ .find('[data-toggle="dropdown"]')
+ .bootstrapDropdown()
stop()
- dropdown
+ $dropdown
.parent('.dropdown')
.on('show.bs.dropdown', function () {
- ok(true, 'show was called')
+ ok(true, 'show was fired')
})
.on('hide.bs.dropdown', function () {
- ok(true, 'hide was called')
+ ok(true, 'hide was fired')
start()
})
- dropdown.click()
+ $dropdown.click()
$(document.body).click()
})
- test('should fire shown and hiden event', function () {
- var dropdownHTML = '<ul class="tabs">' +
- '<li class="dropdown">' +
- '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>' +
- '<ul class="dropdown-menu">' +
- '<li><a href="#">Secondary link</a></li>' +
- '<li><a href="#">Something else here</a></li>' +
- '<li class="divider"></li>' +
- '<li><a href="#">Another link</a></li>' +
- '</ul>' +
- '</li>' +
- '</ul>'
- var dropdown = $(dropdownHTML)
- .appendTo('#qunit-fixture')
- .find('[data-toggle="dropdown"]')
- .bootstrapDropdown()
+ test('should fire shown and hidden event', function () {
+ var dropdownHTML = '<ul class="tabs">'
+ + '<li class="dropdown">'
+ + '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
+ + '<ul class="dropdown-menu">'
+ + '<li><a href="#">Secondary link</a></li>'
+ + '<li><a href="#">Something else here</a></li>'
+ + '<li class="divider"/>'
+ + '<li><a href="#">Another link</a></li>'
+ + '</ul>'
+ + '</li>'
+ + '</ul>'
+ var $dropdown = $(dropdownHTML)
+ .appendTo('#qunit-fixture')
+ .find('[data-toggle="dropdown"]')
+ .bootstrapDropdown()
stop()
- dropdown
+ $dropdown
.parent('.dropdown')
.on('shown.bs.dropdown', function () {
- ok(true, 'show was called')
+ ok(true, 'shown was fired')
})
.on('hidden.bs.dropdown', function () {
- ok(true, 'hide was called')
+ ok(true, 'hidden was fired')
start()
})
- dropdown.click()
+ $dropdown.click()
$(document.body).click()
})
diff --git a/js/tests/unit/modal.js b/js/tests/unit/modal.js
index a415129aa..6c48ed44b 100644
--- a/js/tests/unit/modal.js
+++ b/js/tests/unit/modal.js
@@ -4,8 +4,7 @@ $(function () {
module('modal plugin')
test('should be defined on jquery object', function () {
- var div = $('<div id="modal-test"></div>')
- ok(div.modal, 'modal method is defined')
+ ok($(document.body).modal, 'modal method is defined')
})
module('modal', {
@@ -20,13 +19,14 @@ $(function () {
})
test('should provide no conflict', function () {
- ok(!$.fn.modal, 'modal was set back to undefined (orig value)')
+ strictEqual($.fn.modal, undefined, 'modal was set back to undefined (orig value)')
})
- test('should return element', function () {
- var div = $('<div id="modal-test"></div>')
- ok(div.bootstrapModal() == div, 'document.body returned')
- $('#modal-test').remove()
+ test('should return jquery collection containing the element', function () {
+ var $el = $('<div id="modal-test"/>')
+ var $modal = $el.bootstrapModal()
+ ok($modal instanceof $, 'returns jquery collection')
+ strictEqual($modal[0], $el[0], 'collection contains element')
})
test('should expose defaults var for settings', function () {
@@ -35,11 +35,10 @@ $(function () {
test('should insert into dom when show method is called', function () {
stop()
- $.support.transition = false
- $('<div id="modal-test"></div>')
+
+ $('<div id="modal-test"/>')
.on('shown.bs.modal', function () {
- ok($('#modal-test').length, 'modal inserted into dom')
- $(this).remove()
+ notEqual($('#modal-test').length, 0, 'modal inserted into dom')
start()
})
.bootstrapModal('show')
@@ -47,46 +46,41 @@ $(function () {
test('should fire show event', function () {
stop()
- $.support.transition = false
- $('<div id="modal-test"></div>')
+
+ $('<div id="modal-test"/>')
.on('show.bs.modal', function () {
- ok(true, 'show was called')
- })
- .on('shown.bs.modal', function () {
- $(this).remove()
+ ok(true, 'show event fired')
start()
})
.bootstrapModal('show')
})
- test('should not fire shown when default prevented', function () {
+ test('should not fire shown when show was prevented', function () {
stop()
- $.support.transition = false
- $('<div id="modal-test"></div>')
+
+ $('<div id="modal-test"/>')
.on('show.bs.modal', function (e) {
e.preventDefault()
- ok(true, 'show was called')
+ ok(true, 'show event fired')
start()
})
.on('shown.bs.modal', function () {
- ok(false, 'shown was called')
+ ok(false, 'shown event fired')
})
.bootstrapModal('show')
})
test('should hide modal when hide is called', function () {
stop()
- $.support.transition = false
- $('<div id="modal-test"></div>')
+ $('<div id="modal-test"/>')
.on('shown.bs.modal', function () {
ok($('#modal-test').is(':visible'), 'modal visible')
- ok($('#modal-test').length, 'modal inserted into dom')
+ notEqual($('#modal-test').length, 0, 'modal inserted into dom')
$(this).bootstrapModal('hide')
})
.on('hidden.bs.modal', function () {
ok(!$('#modal-test').is(':visible'), 'modal hidden')
- $('#modal-test').remove()
start()
})
.bootstrapModal('show')
@@ -94,17 +88,15 @@ $(function () {
test('should toggle when toggle is called', function () {
stop()
- $.support.transition = false
- var div = $('<div id="modal-test"></div>')
- div
+
+ $('<div id="modal-test"/>')
.on('shown.bs.modal', function () {
ok($('#modal-test').is(':visible'), 'modal visible')
- ok($('#modal-test').length, 'modal inserted into dom')
- div.bootstrapModal('toggle')
+ notEqual($('#modal-test').length, 0, 'modal inserted into dom')
+ $(this).bootstrapModal('toggle')
})
.on('hidden.bs.modal', function () {
ok(!$('#modal-test').is(':visible'), 'modal hidden')
- div.remove()
start()
})
.bootstrapModal('toggle')
@@ -112,17 +104,15 @@ $(function () {
test('should remove from dom when click [data-dismiss="modal"]', function () {
stop()
- $.support.transition = false
- var div = $('<div id="modal-test"><span class="close" data-dismiss="modal"></span></div>')
- div
+
+ $('<div id="modal-test"><span class="close" data-dismiss="modal"/></div>')
.on('shown.bs.modal', function () {
ok($('#modal-test').is(':visible'), 'modal visible')
- ok($('#modal-test').length, 'modal inserted into dom')
- div.find('.close').click()
+ notEqual($('#modal-test').length, 0, 'modal inserted into dom')
+ $(this).find('.close').click()
})
.on('hidden.bs.modal', function () {
ok(!$('#modal-test').is(':visible'), 'modal hidden')
- div.remove()
start()
})
.bootstrapModal('toggle')
@@ -130,16 +120,14 @@ $(function () {
test('should allow modal close with "backdrop:false"', function () {
stop()
- $.support.transition = false
- var div = $('<div>', { id: 'modal-test', 'data-backdrop': false })
- div
+
+ $('<div id="modal-test" data-backdrop="false"/>')
.on('shown.bs.modal', function () {
ok($('#modal-test').is(':visible'), 'modal visible')
- div.bootstrapModal('hide')
+ $(this).bootstrapModal('hide')
})
.on('hidden.bs.modal', function () {
ok(!$('#modal-test').is(':visible'), 'modal hidden')
- div.remove()
start()
})
.bootstrapModal('show')
@@ -147,38 +135,72 @@ $(function () {
test('should close modal when clicking outside of modal-content', function () {
stop()
- $.support.transition = false
- var div = $('<div id="modal-test"><div class="contents"></div></div>')
- div
+
+ $('<div id="modal-test"><div class="contents"/></div>')
.on('shown.bs.modal', function () {
- ok($('#modal-test').length, 'modal insterted into dom')
+ notEqual($('#modal-test').length, 0, 'modal insterted into dom')
$('.contents').click()
ok($('#modal-test').is(':visible'), 'modal visible')
- $('#modal-test').click()
+ $('#modal-test').mousedown()
})
.on('hidden.bs.modal', function () {
ok(!$('#modal-test').is(':visible'), 'modal hidden')
- div.remove()
start()
})
.bootstrapModal('show')
})
+ test('should close modal when escape key is pressed via keydown', function () {
+ stop()
+
+ var div = $('<div id="modal-test"/>')
+ div
+ .on('shown.bs.modal', function () {
+ ok($('#modal-test').length, 'modal insterted into dom')
+ ok($('#modal-test').is(':visible'), 'modal visible')
+ div.trigger($.Event('keydown', { which: 27 }))
+
+ setTimeout(function () {
+ ok(!$('#modal-test').is(':visible'), 'modal hidden')
+ div.remove()
+ start()
+ }, 0)
+ })
+ .bootstrapModal('show')
+ })
+
+ test('should not close modal when escape key is pressed via keyup', function () {
+ stop()
+
+ var div = $('<div id="modal-test"/>')
+ div
+ .on('shown.bs.modal', function () {
+ ok($('#modal-test').length, 'modal insterted into dom')
+ ok($('#modal-test').is(':visible'), 'modal visible')
+ div.trigger($.Event('keyup', { which: 27 }))
+
+ setTimeout(function () {
+ ok($('#modal-test').is(':visible'), 'modal still visible')
+ div.remove()
+ start()
+ }, 0)
+ })
+ .bootstrapModal('show')
+ })
+
test('should trigger hide event once when clicking outside of modal-content', function () {
stop()
- $.support.transition = false
var triggered
- var div = $('<div id="modal-test"><div class="contents"></div></div>')
- div
+ $('<div id="modal-test"><div class="contents"/></div>')
.on('shown.bs.modal', function () {
triggered = 0
- $('#modal-test').click()
+ $('#modal-test').mousedown()
})
.on('hide.bs.modal', function () {
triggered += 1
- ok(triggered === 1, 'modal hide triggered once')
+ strictEqual(triggered, 1, 'modal hide triggered once')
start()
})
.bootstrapModal('show')
@@ -186,34 +208,31 @@ $(function () {
test('should close reopened modal with [data-dismiss="modal"] click', function () {
stop()
- $.support.transition = false
- var div = $('<div id="modal-test"><div class="contents"><div id="close" data-dismiss="modal"></div></div></div>')
- div
+
+ $('<div id="modal-test"><div class="contents"><div id="close" data-dismiss="modal"/></div></div>')
.on('shown.bs.modal', function () {
$('#close').click()
ok(!$('#modal-test').is(':visible'), 'modal hidden')
})
.one('hidden.bs.modal', function () {
- div.one('hidden.bs.modal', function () {
- start()
- }).bootstrapModal('show')
+ $(this)
+ .one('hidden.bs.modal', function () {
+ start()
+ })
+ .bootstrapModal('show')
})
.bootstrapModal('show')
-
- div.remove()
})
test('should restore focus to toggling element when modal is hidden after having been opened via data-api', function () {
stop()
- $.support.transition = false
- var toggleBtn = $('<button data-toggle="modal" data-target="#modal-test">Launch modal</button>').appendTo('#qunit-fixture')
- var div = $('<div id="modal-test"><div class="contents"><div id="close" data-dismiss="modal"></div></div></div>')
- div
+
+ var $toggleBtn = $('<button data-toggle="modal" data-target="#modal-test"/>').appendTo('#qunit-fixture')
+
+ $('<div id="modal-test"><div class="contents"><div id="close" data-dismiss="modal"/></div></div>')
.on('hidden.bs.modal', function () {
- window.setTimeout(function () { // give the focus restoration callback a chance to run
- equal(document.activeElement, toggleBtn[0], 'toggling element is once again focused')
- div.remove()
- toggleBtn.remove()
+ setTimeout(function () {
+ ok($(document.activeElement).is($toggleBtn), 'toggling element is once again focused')
start()
}, 0)
})
@@ -221,29 +240,26 @@ $(function () {
$('#close').click()
})
.appendTo('#qunit-fixture')
- toggleBtn.click()
+
+ $toggleBtn.click()
})
test('should not restore focus to toggling element if the associated show event gets prevented', function () {
stop()
- $.support.transition = false
- var toggleBtn = $('<button data-toggle="modal" data-target="#modal-test">Launch modal</button>').appendTo('#qunit-fixture')
- var otherBtn = $('<button id="other-btn">Golden boy</button>').appendTo('#qunit-fixture')
- var div = $('<div id="modal-test"><div class="contents"><div id="close" data-dismiss="modal"></div></div></div>')
- div
+ var $toggleBtn = $('<button data-toggle="modal" data-target="#modal-test"/>').appendTo('#qunit-fixture')
+ var $otherBtn = $('<button id="other-btn"/>').appendTo('#qunit-fixture')
+
+ $('<div id="modal-test"><div class="contents"><div id="close" data-dismiss="modal"/></div>')
.one('show.bs.modal', function (e) {
e.preventDefault()
- otherBtn.focus()
- window.setTimeout(function () { // give the focus event from the previous line a chance to run
- div.bootstrapModal('show')
- }, 0)
+ $otherBtn.focus()
+ setTimeout($.proxy(function () {
+ $(this).bootstrapModal('show')
+ }, this), 0)
})
.on('hidden.bs.modal', function () {
- window.setTimeout(function () { // give the focus restoration callback a chance to run (except it shouldn't run in this case)
- equal(document.activeElement, otherBtn[0], 'show was prevented, so focus should not have been restored to toggling element')
- div.remove()
- toggleBtn.remove()
- otherBtn.remove()
+ setTimeout(function () {
+ ok($(document.activeElement).is($otherBtn), 'focus returned to toggling element')
start()
}, 0)
})
@@ -251,6 +267,7 @@ $(function () {
$('#close').click()
})
.appendTo('#qunit-fixture')
- toggleBtn.click()
+
+ $toggleBtn.click()
})
})
diff --git a/js/tests/unit/phantom.js b/js/tests/unit/phantom.js
index b5f0c67a6..ea7455cfc 100644
--- a/js/tests/unit/phantom.js
+++ b/js/tests/unit/phantom.js
@@ -2,7 +2,7 @@
* grunt-contrib-qunit
* http://gruntjs.com/
*
- * Copyright (c) 2013 "Cowboy" Ben Alman, contributors
+ * Copyright (c) 2014 "Cowboy" Ben Alman, contributors
* Licensed under the MIT license.
*/
@@ -21,48 +21,52 @@
}
// These methods connect QUnit to PhantomJS.
- QUnit.log = function (obj) {
+ QUnit.log(function (obj) {
// What is this I don’t even
if (obj.message === '[object Object], undefined:undefined') { return }
+
// Parse some stuff before sending it.
- var actual = QUnit.jsDump.parse(obj.actual)
- var expected = QUnit.jsDump.parse(obj.expected)
+ var actual
+ var expected
+ if (!obj.result) {
+ // Dumping large objects can be very slow, and the dump isn't used for
+ // passing tests, so only dump if the test failed.
+ actual = QUnit.jsDump.parse(obj.actual)
+ expected = QUnit.jsDump.parse(obj.expected)
+ }
// Send it.
sendMessage('qunit.log', obj.result, actual, expected, obj.message, obj.source)
- }
+ })
- QUnit.testStart = function (obj) {
+ QUnit.testStart(function (obj) {
sendMessage('qunit.testStart', obj.name)
- }
+ })
- QUnit.testDone = function (obj) {
- sendMessage('qunit.testDone', obj.name, obj.failed, obj.passed, obj.total)
- }
+ QUnit.testDone(function (obj) {
+ sendMessage('qunit.testDone', obj.name, obj.failed, obj.passed, obj.total, obj.duration)
+ })
- QUnit.moduleStart = function (obj) {
+ QUnit.moduleStart(function (obj) {
sendMessage('qunit.moduleStart', obj.name)
- }
+ })
- QUnit.begin = function () {
- sendMessage('qunit.begin')
- console.log('Starting test suite')
- console.log('================================================\n')
- }
-
- QUnit.moduleDone = function (opts) {
- if (opts.failed === 0) {
- console.log('\r\u2714 All tests passed in "' + opts.name + '" module')
+ QUnit.moduleDone(function (obj) {
+ if (obj.failed === 0) {
+ console.log('\r\u2714 All tests passed in "' + obj.name + '" module')
} else {
- console.log('\u2716 ' + opts.failed + ' tests failed in "' + opts.name + '" module')
+ console.log('\u2716 ' + obj.failed + ' tests failed in "' + obj.name + '" module')
}
- sendMessage('qunit.moduleDone', opts.name, opts.failed, opts.passed, opts.total)
- }
+ sendMessage('qunit.moduleDone', obj.name, obj.failed, obj.passed, obj.total)
+ })
- QUnit.done = function (opts) {
- console.log('\n================================================')
- console.log('Tests completed in ' + opts.runtime + ' milliseconds')
- console.log(opts.passed + ' tests of ' + opts.total + ' passed, ' + opts.failed + ' failed.')
- sendMessage('qunit.done', opts.failed, opts.passed, opts.total, opts.runtime)
- }
+ QUnit.begin(function () {
+ sendMessage('qunit.begin')
+ console.log('\n\nStarting test suite')
+ console.log('================================================\n')
+ })
+
+ QUnit.done(function (obj) {
+ sendMessage('qunit.done', obj.failed, obj.passed, obj.total, obj.runtime)
+ })
}())
diff --git a/js/tests/unit/popover.js b/js/tests/unit/popover.js
index 16f94e143..5cb4cafdd 100644
--- a/js/tests/unit/popover.js
+++ b/js/tests/unit/popover.js
@@ -4,8 +4,7 @@ $(function () {
module('popover plugin')
test('should be defined on jquery object', function () {
- var div = $('<div></div>')
- ok(div.popover, 'popover method is defined')
+ ok($(document.body).popover, 'popover method is defined')
})
module('popover', {
@@ -20,46 +19,44 @@ $(function () {
})
test('should provide no conflict', function () {
- ok(!$.fn.popover, 'popover was set back to undefined (org value)')
+ strictEqual($.fn.popover, undefined, 'popover was set back to undefined (org value)')
})
- test('should return element', function () {
- var div = $('<div></div>')
- ok(div.bootstrapPopover() == div, 'document.body returned')
+ test('should return jquery collection containing the element', function () {
+ var $el = $('<div/>')
+ var $popover = $el.bootstrapPopover()
+ ok($popover instanceof $, 'returns jquery collection')
+ strictEqual($popover[0], $el[0], 'collection contains element')
})
test('should render popover element', function () {
- $.support.transition = false
- var popover = $('<a href="#" title="mdo" data-content="http://twitter.com/mdo">@mdo</a>')
+ var $popover = $('<a href="#" title="mdo" data-content="http://twitter.com/mdo">@mdo</a>')
.appendTo('#qunit-fixture')
.bootstrapPopover('show')
- ok($('.popover').length, 'popover was inserted')
- popover.bootstrapPopover('hide')
- ok(!$('.popover').length, 'popover removed')
+ notEqual($('.popover').length, 0, 'popover was inserted')
+ $popover.bootstrapPopover('hide')
+ equal($('.popover').length, 0, 'popover removed')
})
test('should store popover instance in popover data object', function () {
- $.support.transition = false
- var popover = $('<a href="#" title="mdo" data-content="http://twitter.com/mdo">@mdo</a>')
- .bootstrapPopover()
+ var $popover = $('<a href="#" title="mdo" data-content="http://twitter.com/mdo">@mdo</a>').bootstrapPopover()
- ok(!!popover.data('bs.popover'), 'popover instance exists')
+ ok($popover.data('bs.popover'), 'popover instance exists')
})
test('should store popover trigger in popover instance data object', function () {
- $.support.transition = false
- var popover = $('<a href="#" title="ResentedHook">@ResentedHook</a>')
+ var $popover = $('<a href="#" title="ResentedHook">@ResentedHook</a>')
.appendTo('#qunit-fixture')
.bootstrapPopover()
- popover.bootstrapPopover('show')
- ok(!!$('.popover').data('bs.popover'), 'popover trigger stored in instance data')
- $('#qunit-fixture').empty()
+
+ $popover.bootstrapPopover('show')
+
+ ok($('.popover').data('bs.popover'), 'popover trigger stored in instance data')
})
test('should get title and content from options', function () {
- $.support.transition = false
- var popover = $('<a href="#">@fat</a>')
+ var $popover = $('<a href="#">@fat</a>')
.appendTo('#qunit-fixture')
.bootstrapPopover({
title: function () {
@@ -70,23 +67,20 @@ $(function () {
}
})
- popover.bootstrapPopover('show')
+ $popover.bootstrapPopover('show')
- ok($('.popover').length, 'popover was inserted')
+ notEqual($('.popover').length, 0, 'popover was inserted')
equal($('.popover .popover-title').text(), '@fat', 'title correctly inserted')
equal($('.popover .popover-content').text(), 'loves writing tests (╯°□°)╯︵ ┻━┻', 'content correctly inserted')
- popover.bootstrapPopover('hide')
- ok(!$('.popover').length, 'popover was removed')
- $('#qunit-fixture').empty()
+ $popover.bootstrapPopover('hide')
+ equal($('.popover').length, 0, 'popover was removed')
})
test('should not duplicate HTML object', function () {
- $.support.transition = false
+ var $div = $('<div/>').html('loves writing tests (╯°□°)╯︵ ┻━┻')
- var $div = $('<div>').html('loves writing tests (╯°□°)╯︵ ┻━┻')
-
- var popover = $('<a href="#">@fat</a>')
+ var $popover = $('<a href="#">@fat</a>')
.appendTo('#qunit-fixture')
.bootstrapPopover({
content: function () {
@@ -94,42 +88,38 @@ $(function () {
}
})
- popover.bootstrapPopover('show')
- ok($('.popover').length, 'popover was inserted')
+ $popover.bootstrapPopover('show')
+ notEqual($('.popover').length, 0, 'popover was inserted')
equal($('.popover .popover-content').html(), $div, 'content correctly inserted')
- popover.bootstrapPopover('hide')
- ok(!$('.popover').length, 'popover was removed')
+ $popover.bootstrapPopover('hide')
+ equal($('.popover').length, 0, 'popover was removed')
- popover.bootstrapPopover('show')
- ok($('.popover').length, 'popover was inserted')
+ $popover.bootstrapPopover('show')
+ notEqual($('.popover').length, 0, 'popover was inserted')
equal($('.popover .popover-content').html(), $div, 'content correctly inserted')
- popover.bootstrapPopover('hide')
- ok(!$('.popover').length, 'popover was removed')
- $('#qunit-fixture').empty()
+ $popover.bootstrapPopover('hide')
+ equal($('.popover').length, 0, 'popover was removed')
})
test('should get title and content from attributes', function () {
- $.support.transition = false
- var popover = $('<a href="#" title="@mdo" data-content="loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻" >@mdo</a>')
+ var $popover = $('<a href="#" title="@mdo" data-content="loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻" >@mdo</a>')
.appendTo('#qunit-fixture')
.bootstrapPopover()
.bootstrapPopover('show')
- ok($('.popover').length, 'popover was inserted')
+ notEqual($('.popover').length, 0, 'popover was inserted')
equal($('.popover .popover-title').text(), '@mdo', 'title correctly inserted')
equal($('.popover .popover-content').text(), 'loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻', 'content correctly inserted')
- popover.bootstrapPopover('hide')
- ok(!$('.popover').length, 'popover was removed')
- $('#qunit-fixture').empty()
+ $popover.bootstrapPopover('hide')
+ equal($('.popover').length, 0, 'popover was removed')
})
- test('should get title and content from attributes #2', function () {
- $.support.transition = false
- var popover = $('<a href="#" title="@mdo" data-content="loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻" >@mdo</a>')
+ test('should get title and content from attributes ignoring options passed via js', function () {
+ var $popover = $('<a href="#" title="@mdo" data-content="loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻" >@mdo</a>')
.appendTo('#qunit-fixture')
.bootstrapPopover({
title: 'ignored title option',
@@ -137,48 +127,50 @@ $(function () {
})
.bootstrapPopover('show')
- ok($('.popover').length, 'popover was inserted')
+ notEqual($('.popover').length, 0, 'popover was inserted')
equal($('.popover .popover-title').text(), '@mdo', 'title correctly inserted')
equal($('.popover .popover-content').text(), 'loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻', 'content correctly inserted')
- popover.bootstrapPopover('hide')
- ok(!$('.popover').length, 'popover was removed')
- $('#qunit-fixture').empty()
+ $popover.bootstrapPopover('hide')
+ equal($('.popover').length, 0, 'popover was removed')
})
- test('should respect custom classes', function () {
- $.support.transition = false
- var popover = $('<a href="#">@fat</a>')
+ test('should respect custom template', function () {
+ var $popover = $('<a href="#">@fat</a>')
.appendTo('#qunit-fixture')
.bootstrapPopover({
title: 'Test',
content: 'Test',
- template: '<div class="popover foobar"><div class="arrow"></div><div class="inner"><h3 class="title"></h3><div class="content"><p></p></div></div></div>'
+ template: '<div class="popover foobar"><div class="arrow"></div><div class="inner"><h3 class="title"/><div class="content"><p/></div></div></div>'
})
- popover.bootstrapPopover('show')
+ $popover.bootstrapPopover('show')
- ok($('.popover').length, 'popover was inserted')
+ notEqual($('.popover').length, 0, 'popover was inserted')
ok($('.popover').hasClass('foobar'), 'custom class is present')
- popover.bootstrapPopover('hide')
- ok(!$('.popover').length, 'popover was removed')
- $('#qunit-fixture').empty()
+ $popover.bootstrapPopover('hide')
+ equal($('.popover').length, 0, 'popover was removed')
})
test('should destroy popover', function () {
- var popover = $('<div/>').bootstrapPopover({
- trigger: 'hover'
- }).on('click.foo', function () {})
- ok(popover.data('bs.popover'), 'popover has data')
- ok($._data(popover[0], 'events').mouseover && $._data(popover[0], 'events').mouseout, 'popover has hover event')
- ok($._data(popover[0], 'events').click[0].namespace == 'foo', 'popover has extra click.foo event')
- popover.bootstrapPopover('show')
- popover.bootstrapPopover('destroy')
- ok(!popover.hasClass('in'), 'popover is hidden')
- ok(!popover.data('popover'), 'popover does not have data')
- ok($._data(popover[0], 'events').click[0].namespace == 'foo', 'popover still has click.foo')
- ok(!$._data(popover[0], 'events').mouseover && !$._data(popover[0], 'events').mouseout, 'popover does not have any events')
+ var $popover = $('<div/>')
+ .bootstrapPopover({
+ trigger: 'hover'
+ })
+ .on('click.foo', $.noop)
+
+ ok($popover.data('bs.popover'), 'popover has data')
+ ok($._data($popover[0], 'events').mouseover && $._data($popover[0], 'events').mouseout, 'popover has hover event')
+ equal($._data($popover[0], 'events').click[0].namespace, 'foo', 'popover has extra click.foo event')
+
+ $popover.bootstrapPopover('show')
+ $popover.bootstrapPopover('destroy')
+
+ ok(!$popover.hasClass('in'), 'popover is hidden')
+ ok(!$popover.data('popover'), 'popover does not have data')
+ equal($._data($popover[0], 'events').click[0].namespace, 'foo', 'popover still has click.foo')
+ ok(!$._data($popover[0], 'events').mouseover && !$._data($popover[0], 'events').mouseout, 'popover does not have any events')
})
})
diff --git a/js/tests/unit/scrollspy.js b/js/tests/unit/scrollspy.js
index 2ec51fc24..c071d0f65 100644
--- a/js/tests/unit/scrollspy.js
+++ b/js/tests/unit/scrollspy.js
@@ -19,99 +19,143 @@ $(function () {
})
test('should provide no conflict', function () {
- ok(!$.fn.scrollspy, 'scrollspy was set back to undefined (org value)')
+ strictEqual($.fn.scrollspy, undefined, 'scrollspy was set back to undefined (org value)')
})
- test('should return element', function () {
- ok($(document.body).bootstrapScrollspy()[0] == document.body, 'document.body returned')
+ test('should return jquery collection containing the element', function () {
+ var $el = $('<div/>')
+ var $scrollspy = $el.bootstrapScrollspy()
+ ok($scrollspy instanceof $, 'returns jquery collection')
+ strictEqual($scrollspy[0], $el[0], 'collection contains element')
})
- test('should switch active class on scroll', function () {
- var sectionHTML = '<div id="masthead"></div>'
- $(sectionHTML).append('#qunit-fixture')
- var topbarHTML = '<div class="topbar">' +
- '<div class="topbar-inner">' +
- '<div class="container">' +
- '<h3><a href="#">Bootstrap</a></h3>' +
- '<li><a href="#masthead">Overview</a></li>' +
- '</ul>' +
- '</div>' +
- '</div>' +
- '</div>'
+ // Does not work properly ATM, #13500 will fix this
+ test('should switch "active" class on scroll', function () {
+ var topbarHTML = '<div class="topbar">'
+ + '<div class="topbar-inner">'
+ + '<div class="container">'
+ + '<h3><a href="#">Bootstrap</a></h3>'
+ + '<li><a href="#masthead">Overview</a></li>'
+ + '</ul>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
var $topbar = $(topbarHTML).bootstrapScrollspy()
- $(sectionHTML).append('#qunit-fixture')
ok($topbar.find('.active', true))
})
- asyncTest('should only switch active class on current target', function () {
- expect(1);
- var sectionHTML = '<div id="root" class="active">' +
- '<div class="topbar">' +
- '<div class="topbar-inner">' +
- '<div class="container" id="ss-target">' +
- '<ul class="nav">' +
- '<li><a href="#masthead">Overview</a></li>' +
- '<li><a href="#detail">Detail</a></li>' +
- '</ul>' +
- '</div>' +
- '</div>' +
- '</div>' +
- '<div id="scrollspy-example" style="height: 100px; overflow: auto;">' +
- '<div style="height: 200px;">' +
- '<h4 id="masthead">Overview</h4>' +
- '<p style="height: 200px">' +
- 'Ad leggings keytar, brunch id art party dolor labore.' +
- '</p>' +
- '</div>' +
- '<div style="height: 200px;">' +
- '<h4 id="detail">Detail</h4>' +
- '<p style="height: 200px">' +
- 'Veniam marfa mustache skateboard, adipisicing fugiat velit pitchfork beard.' +
- '</p>' +
- '</div>' +
- '</div>' +
- '</div>'
+ test('should only switch "active" class on current target', function () {
+ stop()
+
+ var sectionHTML = '<div id="root" class="active">'
+ + '<div class="topbar">'
+ + '<div class="topbar-inner">'
+ + '<div class="container" id="ss-target">'
+ + '<ul class="nav">'
+ + '<li><a href="#masthead">Overview</a></li>'
+ + '<li><a href="#detail">Detail</a></li>'
+ + '</ul>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
+ + '<div id="scrollspy-example" style="height: 100px; overflow: auto;">'
+ + '<div style="height: 200px;">'
+ + '<h4 id="masthead">Overview</h4>'
+ + '<p style="height: 200px">'
+ + 'Ad leggings keytar, brunch id art party dolor labore.'
+ + '</p>'
+ + '</div>'
+ + '<div style="height: 200px;">'
+ + '<h4 id="detail">Detail</h4>'
+ + '<p style="height: 200px">'
+ + 'Veniam marfa mustache skateboard, adipisicing fugiat velit pitchfork beard.'
+ + '</p>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
var $section = $(sectionHTML).appendTo('#qunit-fixture')
- var $scrollSpy = $section
+
+ var $scrollspy = $section
.show()
.find('#scrollspy-example')
.bootstrapScrollspy({ target: '#ss-target' })
- $scrollSpy.on('scroll.bs.scrollspy', function () {
- ok($section.hasClass('active'), 'Active class still on root node')
+ $scrollspy.on('scroll.bs.scrollspy', function () {
+ ok($section.hasClass('active'), '"active" class still on root node')
start()
})
- $scrollSpy.scrollTop(350);
+
+ $scrollspy.scrollTop(350)
})
- asyncTest('middle navigation option correctly selected when large offset is used', function () {
- expect(3);
- var sectionHTML = '<div id="header" style="height: 500px;"></div>' +
- '<nav id="navigation" class="navbar">' +
- '<ul class="nav navbar-nav">' +
- '<li class="active"><a id="one-link" href="#one">One</a></li>' +
- '<li><a id="two-link" href="#two">Two</a></li>' +
- '<li><a id="three-link" href="#three">Three</a></li>' +
- '</ul>' +
- '</nav>' +
- '<div id="content" style="height: 200px; overflow-y: auto;">' +
- '<div id="one" style="height: 500px;"></div>' +
- '<div id="two" style="height: 300px;"></div>' +
- '<div id="three" style="height: 10px;"></div>' +
- '</div>'
+ test('middle navigation option correctly selected when large offset is used', function () {
+ stop()
+
+ var sectionHTML = '<div id="header" style="height: 500px;"></div>'
+ + '<nav id="navigation" class="navbar">'
+ + '<ul class="nav navbar-nav">'
+ + '<li class="active"><a id="one-link" href="#one">One</a></li>'
+ + '<li><a id="two-link" href="#two">Two</a></li>'
+ + '<li><a id="three-link" href="#three">Three</a></li>'
+ + '</ul>'
+ + '</nav>'
+ + '<div id="content" style="height: 200px; overflow-y: auto;">'
+ + '<div id="one" style="height: 500px;"></div>'
+ + '<div id="two" style="height: 300px;"></div>'
+ + '<div id="three" style="height: 10px;"></div>'
+ + '</div>'
var $section = $(sectionHTML).appendTo('#qunit-fixture')
- var $scrollSpy = $section
+ var $scrollspy = $section
.show()
.filter('#content')
- $scrollSpy.bootstrapScrollspy({ target: '#navigation', offset: $scrollSpy.position().top })
- $scrollSpy.on('scroll.bs.scrollspy', function () {
- ok(!$section.find('#one-link').parent().hasClass('active'), 'Active class removed from first section')
- ok($section.find('#two-link').parent().hasClass('active'), 'Active class on middle section')
- ok(!$section.find('#three-link').parent().hasClass('active'), 'Active class not on last section')
+ $scrollspy.bootstrapScrollspy({ target: '#navigation', offset: $scrollspy.position().top })
+
+ $scrollspy.on('scroll.bs.scrollspy', function () {
+ ok(!$section.find('#one-link').parent().hasClass('active'), '"active" class removed from first section')
+ ok($section.find('#two-link').parent().hasClass('active'), '"active" class on middle section')
+ ok(!$section.find('#three-link').parent().hasClass('active'), '"active" class not on last section')
start()
})
- $scrollSpy.scrollTop(550);
+
+ $scrollspy.scrollTop(550)
})
+
+ test('should add the active class to the correct element', function () {
+ var navbarHtml =
+ '<nav class="navbar">'
+ + '<ul class="nav">'
+ + '<li id="li-1"><a href="#div-1">div 1</a></li>'
+ + '<li id="li-2"><a href="#div-2">div 2</a></li>'
+ + '</ul>'
+ + '</nav>'
+ var contentHtml =
+ '<div class="content" style="overflow: auto; height: 50px">'
+ + '<div id="div-1" style="height: 100px; padding: 0; margin: 0">div 1</div>'
+ + '<div id="div-2" style="height: 200px; padding: 0; margin: 0">div 2</div>'
+ + '</div>'
+
+ $(navbarHtml).appendTo('#qunit-fixture')
+ var $content = $(contentHtml)
+ .appendTo('#qunit-fixture')
+ .bootstrapScrollspy({ offset: 0, target: '.navbar' })
+
+ var testElementIsActiveAfterScroll = function (element, target) {
+ var deferred = $.Deferred()
+ var scrollHeight = Math.ceil($content.scrollTop() + $(target).position().top)
+ stop()
+ $content.one('scroll', function () {
+ ok($(element).hasClass('active'), 'target:' + target + ', element' + element)
+ start()
+ deferred.resolve()
+ })
+ $content.scrollTop(scrollHeight)
+ return deferred.promise()
+ }
+
+ $.when(testElementIsActiveAfterScroll('#li-1', '#div-1'))
+ .then(function () { return testElementIsActiveAfterScroll('#li-2', '#div-2') })
+ })
+
})
diff --git a/js/tests/unit/tab.js b/js/tests/unit/tab.js
index 0c49feeaf..8e50614ec 100644
--- a/js/tests/unit/tab.js
+++ b/js/tests/unit/tab.js
@@ -19,20 +19,23 @@ $(function () {
})
test('should provide no conflict', function () {
- ok(!$.fn.tab, 'tab was set back to undefined (org value)')
+ strictEqual($.fn.tab, undefined, 'tab was set back to undefined (org value)')
})
- test('should return element', function () {
- ok($(document.body).bootstrapTab()[0] == document.body, 'document.body returned')
+ test('should return jquery collection containing the element', function () {
+ var $el = $('<div/>')
+ var $tab = $el.bootstrapTab()
+ ok($tab instanceof $, 'returns jquery collection')
+ strictEqual($tab[0], $el[0], 'collection contains element')
})
test('should activate element by tab id', function () {
- var tabsHTML = '<ul class="tabs">' +
- '<li><a href="#home">Home</a></li>' +
- '<li><a href="#profile">Profile</a></li>' +
- '</ul>'
+ var tabsHTML = '<ul class="tabs">'
+ + '<li><a href="#home">Home</a></li>'
+ + '<li><a href="#profile">Profile</a></li>'
+ + '</ul>'
- $('<ul><li id="home"></li><li id="profile"></li></ul>').appendTo('#qunit-fixture')
+ $('<ul><li id="home"/><li id="profile"/></ul>').appendTo('#qunit-fixture')
$(tabsHTML).find('li:last a').bootstrapTab('show')
equal($('#qunit-fixture').find('.active').attr('id'), 'profile')
@@ -42,12 +45,12 @@ $(function () {
})
test('should activate element by tab id', function () {
- var pillsHTML = '<ul class="pills">' +
- '<li><a href="#home">Home</a></li>' +
- '<li><a href="#profile">Profile</a></li>' +
- '</ul>'
+ var pillsHTML = '<ul class="pills">'
+ + '<li><a href="#home">Home</a></li>'
+ + '<li><a href="#profile">Profile</a></li>'
+ + '</ul>'
- $('<ul><li id="home"></li><li id="profile"></li></ul>').appendTo('#qunit-fixture')
+ $('<ul><li id="home"/><li id="profile"/></ul>').appendTo('#qunit-fixture')
$(pillsHTML).find('li:last a').bootstrapTab('show')
equal($('#qunit-fixture').find('.active').attr('id'), 'profile')
@@ -56,41 +59,46 @@ $(function () {
equal($('#qunit-fixture').find('.active').attr('id'), 'home')
})
-
- test('should not fire closed when close is prevented', function () {
- $.support.transition = false
+ test('should not fire shown when show is prevented', function () {
stop()
+
$('<div class="tab"/>')
.on('show.bs.tab', function (e) {
e.preventDefault()
- ok(true)
+ ok(true, 'show event fired')
start()
})
.on('shown.bs.tab', function () {
- ok(false)
+ ok(false, 'shown event fired')
})
.bootstrapTab('show')
})
test('show and shown events should reference correct relatedTarget', function () {
- var dropHTML = '<ul class="drop">' +
- '<li class="dropdown"><a data-toggle="dropdown" href="#">1</a>' +
- '<ul class="dropdown-menu">' +
- '<li><a href="#1-1" data-toggle="tab">1-1</a></li>' +
- '<li><a href="#1-2" data-toggle="tab">1-2</a></li>' +
- '</ul>' +
- '</li>' +
- '</ul>'
-
- $(dropHTML).find('ul>li:first a').bootstrapTab('show').end()
- .find('ul>li:last a')
- .on('show.bs.tab', function (event) {
- equal(event.relatedTarget.hash, '#1-1')
- })
- .on('show.bs.tab', function (event) {
- equal(event.relatedTarget.hash, '#1-1')
- })
- .bootstrapTab('show')
+ stop()
+
+ var dropHTML = '<ul class="drop">'
+ + '<li class="dropdown"><a data-toggle="dropdown" href="#">1</a>'
+ + '<ul class="dropdown-menu">'
+ + '<li><a href="#1-1" data-toggle="tab">1-1</a></li>'
+ + '<li><a href="#1-2" data-toggle="tab">1-2</a></li>'
+ + '</ul>'
+ + '</li>'
+ + '</ul>'
+
+ $(dropHTML)
+ .find('ul > li:first a')
+ .bootstrapTab('show')
+ .end()
+ .find('ul > li:last a')
+ .on('show.bs.tab', function (e) {
+ equal(e.relatedTarget.hash, '#1-1', 'references correct element as relatedTarget')
+ start()
+ })
+ .on('shown.bs.tab', function (e) {
+ equal(e.relatedTarget.hash, '#1-1', 'references correct element as relatedTarget')
+ })
+ .bootstrapTab('show')
})
})
diff --git a/js/tests/unit/tooltip.js b/js/tests/unit/tooltip.js
index f4c840d84..7896c2c96 100644
--- a/js/tests/unit/tooltip.js
+++ b/js/tests/unit/tooltip.js
@@ -4,8 +4,7 @@ $(function () {
module('tooltip plugin')
test('should be defined on jquery object', function () {
- var div = $('<div></div>')
- ok(div.tooltip, 'popover method is defined')
+ ok($(document.body).tooltip, 'popover method is defined')
})
module('tooltip', {
@@ -20,97 +19,108 @@ $(function () {
})
test('should provide no conflict', function () {
- ok(!$.fn.tooltip, 'tooltip was set back to undefined (org value)')
+ strictEqual($.fn.tooltip, undefined, 'tooltip was set back to undefined (org value)')
})
- test('should return element', function () {
- var div = $('<div></div>')
- ok(div.bootstrapTooltip() == div, 'document.body returned')
+ test('should return jquery collection containing the element', function () {
+ var $el = $('<div/>')
+ var $tooltip = $el.bootstrapTooltip()
+ ok($tooltip instanceof $, 'returns jquery collection')
+ strictEqual($tooltip[0], $el[0], 'collection contains element')
})
test('should expose default settings', function () {
- ok(!!$.fn.bootstrapTooltip.Constructor.DEFAULTS, 'defaults is defined')
+ ok($.fn.bootstrapTooltip.Constructor.DEFAULTS, 'defaults is defined')
})
test('should empty title attribute', function () {
- var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>').bootstrapTooltip()
- ok(tooltip.attr('title') === '', 'title attribute was emptied')
+ var $trigger = $('<a href="#" rel="tooltip" title="Another tooltip"/>').bootstrapTooltip()
+ strictEqual($trigger.attr('title'), '', 'title attribute was emptied')
})
test('should add data attribute for referencing original title', function () {
- var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>').bootstrapTooltip()
- equal(tooltip.attr('data-original-title'), 'Another tooltip', 'original title preserved in data attribute')
+ var $trigger = $('<a href="#" rel="tooltip" title="Another tooltip"/>').bootstrapTooltip()
+ strictEqual($trigger.attr('data-original-title'), 'Another tooltip', 'original title preserved in data attribute')
})
- test('should add set set aria describedby to the element called on show', function () {
- var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>').bootstrapTooltip()
+ test('should add aria-describedby to the trigger on show', function () {
+ var $trigger = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
+ .bootstrapTooltip()
.appendTo('#qunit-fixture')
.bootstrapTooltip('show')
- ok(tooltip.attr('aria-describedby'), 'has the right attributes')
+
var id = $('.tooltip').attr('id')
- ok($('#' + id).length == 1, 'has a unique id')
- ok($('.tooltip').attr('aria-describedby') === tooltip.attr('id'), 'they match!')
- ok(tooltip.attr('aria-describedby') !== undefined, 'has the right attributes')
+ strictEqual($('#' + id).length, 1, 'has a unique id')
+ strictEqual($('.tooltip').attr('aria-describedby'), $trigger.attr('id'), 'tooltip id and aria-describedby on trigger match')
+ ok($trigger[0].hasAttribute('aria-describedby'), 'trigger has aria-describedby')
})
- test('should remove the aria-describedby attributes on hide', function () {
- var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>').bootstrapTooltip()
+ test('should remove aria-describedby from trigger on hide', function () {
+ var $trigger = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
+ .bootstrapTooltip()
.appendTo('#qunit-fixture')
- .bootstrapTooltip('show')
- ok(tooltip.attr('aria-describedby'), 'has the right attributes')
- tooltip.bootstrapTooltip('hide')
- ok(!tooltip.attr('aria-describedby'), 'removed the attributes on hide')
+
+ $trigger.bootstrapTooltip('show')
+ ok($trigger[0].hasAttribute('aria-describedby'), 'trigger has aria-describedby')
+
+ $trigger.bootstrapTooltip('hide')
+ ok(!$trigger[0].hasAttribute('aria-describedby'), 'trigger does not have aria-describedby')
})
test('should assign a unique id tooltip element', function () {
- $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
+ $('<a href="#" rel="tooltip" title="Another tooltip"/>')
.appendTo('#qunit-fixture')
.bootstrapTooltip('show')
+
var id = $('.tooltip').attr('id')
- ok($('#' + id).length == 1 && id.indexOf('tooltip') === 0, 'generated prefixed and unique tooltip id')
+ strictEqual($('#' + id).length, 1, 'tooltip has unique id')
+ strictEqual(id.indexOf('tooltip'), 0, 'tooltip id has prefix')
})
test('should place tooltips relative to placement option', function () {
- $.support.transition = false
- var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
+ var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
.appendTo('#qunit-fixture')
.bootstrapTooltip({ placement: 'bottom' })
- .bootstrapTooltip('show')
+ $tooltip.bootstrapTooltip('show')
ok($('.tooltip').is('.fade.bottom.in'), 'has correct classes applied')
- tooltip.bootstrapTooltip('hide')
+
+ $tooltip.bootstrapTooltip('hide')
+ equal($('.tooltip').length, 0, 'tooltip removed')
})
test('should allow html entities', function () {
- $.support.transition = false
- var tooltip = $('<a href="#" rel="tooltip" title="<b>@fat</b>"></a>')
+ var $tooltip = $('<a href="#" rel="tooltip" title="&lt;b&gt;@fat&lt;/b&gt;"/>')
.appendTo('#qunit-fixture')
.bootstrapTooltip({ html: true })
- .bootstrapTooltip('show')
- ok($('.tooltip b').length, 'b tag was inserted')
- tooltip.bootstrapTooltip('hide')
- ok(!$('.tooltip').length, 'tooltip removed')
+ $tooltip.bootstrapTooltip('show')
+ notEqual($('.tooltip b').length, 0, 'b tag was inserted')
+
+ $tooltip.bootstrapTooltip('hide')
+ equal($('.tooltip').length, 0, 'tooltip removed')
})
test('should respect custom classes', function () {
- var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
+ var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
.appendTo('#qunit-fixture')
.bootstrapTooltip({ template: '<div class="tooltip some-class"><div class="tooltip-arrow"/><div class="tooltip-inner"/></div>' })
- .bootstrapTooltip('show')
+ $tooltip.bootstrapTooltip('show')
ok($('.tooltip').hasClass('some-class'), 'custom class is present')
- tooltip.bootstrapTooltip('hide')
- ok(!$('.tooltip').length, 'tooltip removed')
+
+ $tooltip.bootstrapTooltip('hide')
+ equal($('.tooltip').length, 0, 'tooltip removed')
})
test('should fire show event', function () {
stop()
- $('<div title="tooltip title"></div>')
+
+ $('<div title="tooltip title"/>')
.on('show.bs.tooltip', function () {
- ok(true, 'show was called')
+ ok(true, 'show event fired')
start()
})
.bootstrapTooltip('show')
@@ -118,40 +128,41 @@ $(function () {
test('should fire shown event', function () {
stop()
- var tooltip = $('<div title="tooltip title"></div>').appendTo('#qunit-fixture')
- tooltip
+
+ $('<div title="tooltip title"></div>')
+ .appendTo('#qunit-fixture')
.on('shown.bs.tooltip', function () {
ok(true, 'shown was called')
- tooltip.remove()
start()
})
.bootstrapTooltip('show')
})
- test('should not fire shown event when default prevented', function () {
+ test('should not fire shown event when show was prevented', function () {
stop()
- $('<div title="tooltip title"></div>')
+
+ $('<div title="tooltip title"/>')
.on('show.bs.tooltip', function (e) {
e.preventDefault()
- ok(true, 'show was called')
+ ok(true, 'show event fired')
start()
})
.on('shown.bs.tooltip', function () {
- ok(false, 'shown was called')
+ ok(false, 'shown event fired')
})
.bootstrapTooltip('show')
})
test('should fire hide event', function () {
stop()
- var tooltip = $('<div title="tooltip title"></div>').appendTo('#qunit-fixture')
- tooltip
+
+ $('<div title="tooltip title"/>')
+ .appendTo('#qunit-fixture')
.on('shown.bs.tooltip', function () {
$(this).bootstrapTooltip('hide')
})
.on('hide.bs.tooltip', function () {
- ok(true, 'hide was called')
- tooltip.remove()
+ ok(true, 'hide event fired')
start()
})
.bootstrapTooltip('show')
@@ -159,437 +170,609 @@ $(function () {
test('should fire hidden event', function () {
stop()
- var tooltip = $('<div title="tooltip title"></div>').appendTo('#qunit-fixture')
- tooltip
+
+ $('<div title="tooltip title"/>')
+ .appendTo('#qunit-fixture')
.on('shown.bs.tooltip', function () {
$(this).bootstrapTooltip('hide')
})
.on('hidden.bs.tooltip', function () {
- ok(true, 'hidden was called')
- tooltip.remove()
+ ok(true, 'hidden event fired')
start()
})
.bootstrapTooltip('show')
})
- test('should not fire hidden event when default prevented', function () {
+ test('should not fire hidden event when hide was prevented', function () {
stop()
- var tooltip = $('<div title="tooltip title"></div>').appendTo('#qunit-fixture')
- tooltip
+
+ $('<div title="tooltip title"/>')
+ .appendTo('#qunit-fixture')
.on('shown.bs.tooltip', function () {
$(this).bootstrapTooltip('hide')
})
.on('hide.bs.tooltip', function (e) {
e.preventDefault()
- ok(true, 'hide was called')
- tooltip.remove()
+ ok(true, 'hide event fired')
start()
})
.on('hidden.bs.tooltip', function () {
- ok(false, 'hidden was called')
+ ok(false, 'hidden event fired')
})
.bootstrapTooltip('show')
})
- test('should not show tooltip if leave event occurs before delay expires', function () {
- var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
- .appendTo('#qunit-fixture')
- .bootstrapTooltip({ delay: 200 })
-
- stop()
-
- tooltip.trigger('mouseenter')
-
- setTimeout(function () {
- ok(!$('.tooltip').is('.fade.in'), 'tooltip is not faded in')
- tooltip.trigger('mouseout')
- setTimeout(function () {
- ok(!$('.tooltip').is('.fade.in'), 'tooltip is not faded in')
- start()
- }, 200)
- }, 100)
- })
-
- test('should not show tooltip if leave event occurs before delay expires, even if hide delay is 0', function () {
- var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
- .appendTo('#qunit-fixture')
- .bootstrapTooltip({ delay: { show: 200, hide: 0 }})
-
- stop()
-
- tooltip.trigger('mouseenter')
-
- setTimeout(function () {
- ok(!$('.tooltip').is('.fade.in'), 'tooltip is not faded in')
- tooltip.trigger('mouseout')
- setTimeout(function () {
- ok(!$('.tooltip').is('.fade.in'), 'tooltip is not faded in')
- start()
- }, 200)
- }, 100)
- })
-
- test('should wait 200 ms before hiding the tooltip', 3, function () {
- var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
- .appendTo('#qunit-fixture')
- .bootstrapTooltip({ delay: { show: 0, hide: 200 }})
-
- stop()
-
- tooltip.trigger('mouseenter')
-
- setTimeout(function () {
- ok($('.tooltip').is('.fade.in'), 'tooltip is faded in')
- tooltip.trigger('mouseout')
- setTimeout(function () {
- ok($('.tooltip').is('.fade.in'), '100ms:tooltip is still faded in')
- setTimeout(function () {
- ok(!$('.tooltip').is('.in'), 'tooltip removed')
- start()
- }, 150)
- }, 100)
- }, 1)
- })
-
- test('should not hide tooltip if leave event occurs, then tooltip is show immediately again', function () {
- var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
- .appendTo('#qunit-fixture')
- .bootstrapTooltip({ delay: { show: 0, hide: 200 }})
+ test('should destroy tooltip', function () {
+ var $tooltip = $('<div/>')
+ .bootstrapTooltip()
+ .on('click.foo', function () {})
- stop()
+ ok($tooltip.data('bs.tooltip'), 'tooltip has data')
+ ok($._data($tooltip[0], 'events').mouseover && $._data($tooltip[0], 'events').mouseout, 'tooltip has hover events')
+ equal($._data($tooltip[0], 'events').click[0].namespace, 'foo', 'tooltip has extra click.foo event')
- tooltip.trigger('mouseenter')
+ $tooltip.bootstrapTooltip('show')
+ $tooltip.bootstrapTooltip('destroy')
- setTimeout(function () {
- ok($('.tooltip').is('.fade.in'), 'tooltip is faded in')
- tooltip.trigger('mouseout')
- setTimeout(function () {
- ok($('.tooltip').is('.fade.in'), '100ms:tooltip is still faded in')
- tooltip.trigger('mouseenter')
- setTimeout(function () {
- ok($('.tooltip').is('.in'), 'tooltip removed')
- start()
- }, 150)
- }, 100)
- }, 1)
- })
-
- test('should not show tooltip if leave event occurs before delay expires', function () {
- var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
- .appendTo('#qunit-fixture')
- .bootstrapTooltip({ delay: 100 })
- stop()
- tooltip.trigger('mouseenter')
- setTimeout(function () {
- ok(!$('.tooltip').is('.fade.in'), 'tooltip is not faded in')
- tooltip.trigger('mouseout')
- setTimeout(function () {
- ok(!$('.tooltip').is('.fade.in'), 'tooltip is not faded in')
- start()
- }, 100)
- }, 50)
+ ok(!$tooltip.hasClass('in'), 'tooltip is hidden')
+ ok(!$._data($tooltip[0], 'bs.tooltip'), 'tooltip does not have data')
+ equal($._data($tooltip[0], 'events').click[0].namespace, 'foo', 'tooltip still has click.foo')
+ ok(!$._data($tooltip[0], 'events').mouseover && !$._data($tooltip[0], 'events').mouseout, 'tooltip does not have hover events')
})
- test('should show tooltip if leave event hasn\'t occured before delay expires', function () {
- var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
+ test('should show tooltip with delegate selector on click', function () {
+ var $div = $('<div><a href="#" rel="tooltip" title="Another tooltip"/></div>')
.appendTo('#qunit-fixture')
- .bootstrapTooltip({ delay: 150 })
- stop()
- tooltip.trigger('mouseenter')
- setTimeout(function () {
- ok(!$('.tooltip').is('.fade.in'), 'tooltip is not faded in')
- }, 100)
- setTimeout(function () {
- ok($('.tooltip').is('.fade.in'), 'tooltip has faded in')
- start()
- }, 200)
- })
-
- test('should destroy tooltip', function () {
- var tooltip = $('<div/>').bootstrapTooltip().on('click.foo', function () {})
- ok(tooltip.data('bs.tooltip'), 'tooltip has data')
- ok($._data(tooltip[0], 'events').mouseover && $._data(tooltip[0], 'events').mouseout, 'tooltip has hover event')
- ok($._data(tooltip[0], 'events').click[0].namespace == 'foo', 'tooltip has extra click.foo event')
- tooltip.bootstrapTooltip('show')
- tooltip.bootstrapTooltip('destroy')
- ok(!tooltip.hasClass('in'), 'tooltip is hidden')
- ok(!$._data(tooltip[0], 'bs.tooltip'), 'tooltip does not have data')
- ok($._data(tooltip[0], 'events').click[0].namespace == 'foo', 'tooltip still has click.foo')
- ok(!$._data(tooltip[0], 'events').mouseover && !$._data(tooltip[0], 'events').mouseout, 'tooltip does not have any events')
- })
+ .bootstrapTooltip({
+ selector: 'a[rel="tooltip"]',
+ trigger: 'click'
+ })
- test('should show tooltip with delegate selector on click', function () {
- var div = $('<div><a href="#" rel="tooltip" title="Another tooltip"></a></div>')
- div.appendTo('#qunit-fixture').bootstrapTooltip({
- selector: 'a[rel="tooltip"]', trigger: 'click'
- })
- div.find('a').trigger('click')
+ $div.find('a').click()
ok($('.tooltip').is('.fade.in'), 'tooltip is faded in')
+
+ $div.find('a').click()
+ equal($('.tooltip').length, 0, 'tooltip was removed from dom')
})
test('should show tooltip when toggle is called', function () {
- $('<a href="#" rel="tooltip" title="tooltip on toggle"></a>')
+ $('<a href="#" rel="tooltip" title="tooltip on toggle"/>')
.appendTo('#qunit-fixture')
.bootstrapTooltip({ trigger: 'manual' })
.bootstrapTooltip('toggle')
- ok($('.tooltip').is('.fade.in'), 'tooltip should be toggled in')
+
+ ok($('.tooltip').is('.fade.in'), 'tooltip is faded in')
})
- test('should hide shown tooltip when toggle is called on tooltip', function () {
- var tooltip = $('<a href="#" rel="tooltip" title="tooltip on toggle">@ResentedHook</a>')
+ test('should hide previously shown tooltip when toggle is called on tooltip', function () {
+ $('<a href="#" rel="tooltip" title="tooltip on toggle">@ResentedHook</a>')
.appendTo('#qunit-fixture')
.bootstrapTooltip({ trigger: 'manual' })
- .bootstrapTooltip('toggle')
- $('.tooltip', '#qunit-fixture').bootstrapTooltip('toggle')
- ok($('.tooltip').not('.fade.in'), 'tooltip should be toggled out')
- tooltip.bootstrapTooltip('hide')
- $('#qunit-fixture').empty()
+ .bootstrapTooltip('show')
+
+ $('.tooltip').bootstrapTooltip('toggle')
+ ok($('.tooltip').not('.fade.in'), 'tooltip was faded out')
})
- test('should place tooltips inside the body', function () {
- var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
+ test('should place tooltips inside body when container is body', function () {
+ var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
.appendTo('#qunit-fixture')
.bootstrapTooltip({ container: 'body' })
.bootstrapTooltip('show')
- ok($('body > .tooltip').length, 'inside the body')
- ok(!$('#qunit-fixture > .tooltip').length, 'not found in parent')
- tooltip.bootstrapTooltip('hide')
- })
-
- test('should place tooltip inside window', function () {
- var container = $('<div />').appendTo('body')
- .css({ position: 'absolute', width: 200, height: 200, bottom: 0, left: 0 })
- $('<a href="#" title="Very very very very very very very very long tooltip">Hover me</a>')
- .css({ position: 'absolute', top: 0, left: 0 })
- .appendTo(container)
- .bootstrapTooltip({ placement: 'top', animate: false })
- .bootstrapTooltip('show')
-
- stop()
-
- setTimeout(function () {
- ok($('.tooltip').offset().left >= 0)
-
- start()
- container.remove()
- }, 100)
- })
-
- test('should place tooltip on top of element', function () {
- var container = $('<div />').appendTo('body')
- .css({ position: 'absolute', bottom: 0, left: 0, textAlign: 'right', width: 300, height: 300 })
- var p = $('<p style="margin-top:200px" />').appendTo(container)
- var tooltiped = $('<a href="#" title="very very very very very very very long tooltip">Hover me</a>')
- .css({ marginTop: 200 })
- .appendTo(p)
- .bootstrapTooltip({ placement: 'top', animate: false })
- .bootstrapTooltip('show')
-
- stop()
- setTimeout(function () {
- var tooltip = container.find('.tooltip')
+ notEqual($('body > .tooltip').length, 0, 'tooltip is direct descendant of body')
+ equal($('#qunit-fixture > .tooltip').length, 0, 'tooltip is not in parent')
- start()
- ok(Math.round(tooltip.offset().top + tooltip.outerHeight()) <= Math.round(tooltiped.offset().top))
- container.remove()
- }, 100)
+ $tooltip.bootstrapTooltip('hide')
+ equal($('body > .tooltip').length, 0, 'tooltip was removed from dom')
})
test('should add position class before positioning so that position-specific styles are taken into account', function () {
- $('head').append('<style id="test"> .tooltip.right { white-space: nowrap; } .tooltip.right .tooltip-inner { max-width: none; } </style>')
-
- var container = $('<div />').appendTo('body')
- var target = $('<a href="#" rel="tooltip" title="very very very very very very very very long tooltip in one line"></a>')
- .appendTo(container)
- .bootstrapTooltip({ placement: 'right', viewport: null })
- .bootstrapTooltip('show')
- var tooltip = container.find('.tooltip')
+ var styles = '<style>'
+ + '.tooltip.right { white-space: nowrap; }'
+ + '.tooltip.right .tooltip-inner { max-width: none; }'
+ + '</style>'
+ var $styles = $(styles).appendTo('head')
+
+ var $container = $('<div/>').appendTo('#qunit-fixture')
+ var $target = $('<a href="#" rel="tooltip" title="very very very very very very very very long tooltip in one line"/>')
+ .appendTo($container)
+ .bootstrapTooltip({
+ placement: 'right',
+ viewport: null
+ })
+ .bootstrapTooltip('show')
+ var $tooltip = $container.find('.tooltip')
// this is some dumb hack shit because sub pixels in firefox
- var top = Math.round(target.offset().top + (target[0].offsetHeight / 2) - (tooltip[0].offsetHeight / 2))
- var top2 = Math.round(tooltip.offset().top)
+ var top = Math.round($target.offset().top + ($target[0].offsetHeight / 2) - ($tooltip[0].offsetHeight / 2))
+ var top2 = Math.round($tooltip.offset().top)
var topDiff = top - top2
ok(topDiff <= 1 && topDiff >= -1)
- target.bootstrapTooltip('hide')
- $('head #test').remove()
+ $target.bootstrapTooltip('hide')
+
+ $container.remove()
+ $styles.remove()
})
- test('tooltip title test #1', function () {
- var tooltip = $('<a href="#" rel="tooltip" title="Simple tooltip" style="display: inline-block; position: absolute; top: 0; left: 0;"></a>')
+ test('should use title attribute for tooltip text', function () {
+ var $tooltip = $('<a href="#" rel="tooltip" title="Simple tooltip"/>')
.appendTo('#qunit-fixture')
- .bootstrapTooltip({})
- .bootstrapTooltip('show')
+ .bootstrapTooltip()
+
+ $tooltip.bootstrapTooltip('show')
equal($('.tooltip').children('.tooltip-inner').text(), 'Simple tooltip', 'title from title attribute is set')
- tooltip.bootstrapTooltip('hide')
- ok(!$('.tooltip').length, 'tooltip removed')
+
+ $tooltip.bootstrapTooltip('hide')
+ equal($('.tooltip').length, 0, 'tooltip removed from dom')
})
- test('tooltip title test #2', function () {
- var tooltip = $('<a href="#" rel="tooltip" title="Simple tooltip" style="display: inline-block; position: absolute; top: 0; left: 0;"></a>')
+ test('should prefer title attribute over title option', function () {
+ var $tooltip = $('<a href="#" rel="tooltip" title="Simple tooltip"/>')
.appendTo('#qunit-fixture')
.bootstrapTooltip({
title: 'This is a tooltip with some content'
})
- .bootstrapTooltip('show')
- equal($('.tooltip').children('.tooltip-inner').text(), 'Simple tooltip', 'title is set from title attribute while prefered over title option')
- tooltip.bootstrapTooltip('hide')
- ok(!$('.tooltip').length, 'tooltip removed')
+
+ $tooltip.bootstrapTooltip('show')
+ equal($('.tooltip').children('.tooltip-inner').text(), 'Simple tooltip', 'title is set from title attribute while preferred over title option')
+
+ $tooltip.bootstrapTooltip('hide')
+ equal($('.tooltip').length, 0, 'tooltip removed from dom')
})
- test('tooltip title test #3', function () {
- var tooltip = $('<a href="#" rel="tooltip" style="display: inline-block; position: absolute; top: 0; left: 0;"></a>')
+ test('should use title option', function () {
+ var $tooltip = $('<a href="#" rel="tooltip"/>')
.appendTo('#qunit-fixture')
.bootstrapTooltip({
title: 'This is a tooltip with some content'
})
- .bootstrapTooltip('show')
+
+ $tooltip.bootstrapTooltip('show')
equal($('.tooltip').children('.tooltip-inner').text(), 'This is a tooltip with some content', 'title from title option is set')
- tooltip.bootstrapTooltip('hide')
- ok(!$('.tooltip').length, 'tooltip removed')
- })
-
- test('tooltips should be placed dynamically, with the dynamic placement option', function () {
- $.support.transition = false
- var ttContainer = $('<div id="dynamic-tt-test"/>').css({
- height: 400,
- overflow: 'hidden',
- position: 'absolute',
- top: 0,
- left: 0,
- width: 600
- })
- .appendTo('body')
-
- var topTooltip = $('<div style="display: inline-block; position: absolute; left: 0; top: 0;" rel="tooltip" title="Top tooltip">Top Dynamic Tooltip</div>')
- .appendTo('#dynamic-tt-test')
+
+ $tooltip.bootstrapTooltip('hide')
+ equal($('.tooltip').length, 0, 'tooltip removed from dom')
+ })
+
+ test('should be placed dynamically with the dynamic placement option', function () {
+ var $style = $('<style> a[rel="tooltip"] { display: inline-block; position: absolute; } </style>')
+ var $container = $('<div/>')
+ .css({
+ position: 'absolute',
+ overflow: 'hidden',
+ width: 600,
+ height: 400,
+ top: 0,
+ left: 0
+ })
+ .appendTo(document.body)
+
+ var $topTooltip = $('<div style="left: 0; top: 0;" rel="tooltip" title="Top tooltip">Top Dynamic Tooltip</div>')
+ .appendTo($container)
.bootstrapTooltip({ placement: 'auto' })
- .bootstrapTooltip('show')
- ok($('.tooltip').is('.bottom'), 'top positioned tooltip is dynamically positioned bottom')
+ $topTooltip.bootstrapTooltip('show')
+ ok($('.tooltip').is('.bottom'), 'top positioned tooltip is dynamically positioned to bottom')
- topTooltip.bootstrapTooltip('hide')
+ $topTooltip.bootstrapTooltip('hide')
+ equal($('.tooltip').length, 0, 'top positioned tooltip removed from dom')
- var rightTooltip = $('<div style="display: inline-block; position: absolute; right: 0;" rel="tooltip" title="Right tooltip">Right Dynamic Tooltip</div>')
- .appendTo('#dynamic-tt-test')
+ var $rightTooltip = $('<div style="right: 0;" rel="tooltip" title="Right tooltip">Right Dynamic Tooltip</div>')
+ .appendTo($container)
.bootstrapTooltip({ placement: 'right auto' })
- .bootstrapTooltip('show')
+ $rightTooltip.bootstrapTooltip('show')
ok($('.tooltip').is('.left'), 'right positioned tooltip is dynamically positioned left')
- rightTooltip.bootstrapTooltip('hide')
- var leftTooltip = $('<div style="display: inline-block; position: absolute; left: 0;" rel="tooltip" title="Left tooltip">Left Dynamic Tooltip</div>')
- .appendTo('#dynamic-tt-test')
+ $rightTooltip.bootstrapTooltip('hide')
+ equal($('.tooltip').length, 0, 'right positioned tooltip removed from dom')
+
+ var $leftTooltip = $('<div style="left: 0;" rel="tooltip" title="Left tooltip">Left Dynamic Tooltip</div>')
+ .appendTo($container)
.bootstrapTooltip({ placement: 'auto left' })
- .bootstrapTooltip('show')
+ $leftTooltip.bootstrapTooltip('show')
ok($('.tooltip').is('.right'), 'left positioned tooltip is dynamically positioned right')
- leftTooltip.bootstrapTooltip('hide')
- ttContainer.remove()
+ $leftTooltip.bootstrapTooltip('hide')
+ equal($('.tooltip').length, 0, 'left positioned tooltip removed from dom')
+
+ $container.remove()
+ $style.remove()
})
- test('should adjust the tip\'s top when up against the top of the viewport', function () {
- $('head').append('<style id="test"> .tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; } </style>')
+ test('should adjust the tip\'s top position when up against the top of the viewport', function () {
+ var styles = '<style>'
+ + '.tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; }'
+ + 'a[rel="tooltip"] { position: fixed; }'
+ + '</style>'
+ var $styles = $(styles).appendTo('head')
- var container = $('<div />').appendTo('body')
- var target = $('<a href="#" rel="tooltip" title="tip" style="position: fixed; top: 0px; left: 0px;"></a>')
- .appendTo(container)
- .bootstrapTooltip({ placement: 'right', viewport: { selector: 'body', padding: 12 }})
- .bootstrapTooltip('show')
- var tooltip = container.find('.tooltip')
+ var $container = $('<div/>').appendTo('#qunit-fixture')
+ var $target = $('<a href="#" rel="tooltip" title="tip" style="top: 0px; left: 0px;"/>')
+ .appendTo($container)
+ .bootstrapTooltip({
+ placement: 'right',
+ viewport: {
+ selector: 'body',
+ padding: 12
+ }
+ })
+
+ $target.bootstrapTooltip('show')
+ equal(Math.round($container.find('.tooltip').offset().top), 12)
+
+ $target.bootstrapTooltip('hide')
+ equal($('.tooltip').length, 0, 'tooltip removed from dom')
- ok(Math.round(tooltip.offset().top) === 12)
- target.bootstrapTooltip('hide')
- $('head #test').remove()
+ $styles.remove()
})
- test('should adjust the tip\'s top when up against the bottom of the viewport', function () {
- $('head').append('<style id="test"> .tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; } </style>')
+ test('should adjust the tip\'s top position when up against the bottom of the viewport', function () {
+ var styles = '<style>'
+ + '.tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; }'
+ + 'a[rel="tooltip"] { position: fixed; }'
+ + '</style>'
+ var $styles = $(styles).appendTo('head')
+
+ var $container = $('<div/>').appendTo('#qunit-fixture')
+ var $target = $('<a href="#" rel="tooltip" title="tip" style="bottom: 0px; left: 0px;"/>')
+ .appendTo($container)
+ .bootstrapTooltip({
+ placement: 'right',
+ viewport: {
+ selector: 'body',
+ padding: 12
+ }
+ })
+
+ $target.bootstrapTooltip('show')
+ var $tooltip = $container.find('.tooltip')
+ strictEqual(Math.round($tooltip.offset().top), Math.round($(window).height() - 12 - $tooltip[0].offsetHeight))
- var container = $('<div />').appendTo('body')
- var target = $('<a href="#" rel="tooltip" title="tip" style="position: fixed; bottom: 0px; left: 0px;"></a>')
- .appendTo(container)
- .bootstrapTooltip({ placement: 'right', viewport: { selector: 'body', padding: 12 }})
- .bootstrapTooltip('show')
- var tooltip = container.find('.tooltip')
+ $target.bootstrapTooltip('hide')
+ equal($('.tooltip').length, 0, 'tooltip removed from dom')
- ok(Math.round(tooltip.offset().top) === Math.round($(window).height() - 12 - tooltip[0].offsetHeight))
- target.bootstrapTooltip('hide')
- $('head #test').remove()
+ $container.remove()
+ $styles.remove()
})
- test('should adjust the tip\'s left when up against the left of the viewport', function () {
- $('head').append('<style id="test"> .tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; } </style>')
+ test('should adjust the tip\'s left position when up against the left of the viewport', function () {
+ var styles = '<style>'
+ + '.tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; }'
+ + 'a[rel="tooltip"] { position: fixed; }'
+ + '</style>'
+ var $styles = $(styles).appendTo('head')
- var container = $('<div />').appendTo('body')
- var target = $('<a href="#" rel="tooltip" title="tip" style="position: fixed; top: 0px; left: 0px;"></a>')
- .appendTo(container)
- .bootstrapTooltip({ placement: 'bottom', viewport: { selector: 'body', padding: 12 }})
- .bootstrapTooltip('show')
- var tooltip = container.find('.tooltip')
+ var $container = $('<div/>').appendTo('#qunit-fixture')
+ var $target = $('<a href="#" rel="tooltip" title="tip" style="top: 0px; left: 0px;"/>')
+ .appendTo($container)
+ .bootstrapTooltip({
+ placement: 'bottom',
+ viewport: {
+ selector: 'body',
+ padding: 12
+ }
+ })
+
+ $target.bootstrapTooltip('show')
+ strictEqual(Math.round($container.find('.tooltip').offset().left), 12)
- ok(Math.round(tooltip.offset().left) === 12)
- target.bootstrapTooltip('hide')
- $('head #test').remove()
+ $target.bootstrapTooltip('hide')
+ equal($('.tooltip').length, 0, 'tooltip removed from dom')
+
+ $container.remove()
+ $styles.remove()
})
- test('should adjust the tip\'s left when up against the right of the viewport', function () {
- $('head').append('<style id="test"> .tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; } </style>')
+ test('should adjust the tip\'s left position when up against the right of the viewport', function () {
+ var styles = '<style>'
+ + '.tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; }'
+ + 'a[rel="tooltip"] { position: fixed; }'
+ + '</style>'
+ var $styles = $(styles).appendTo('head')
- var container = $('<div />').appendTo('body')
- var target = $('<a href="#" rel="tooltip" title="tip" style="position: fixed; top: 0px; right: 0px;"></a>')
- .appendTo(container)
- .bootstrapTooltip({ placement: 'bottom', viewport: { selector: 'body', padding: 12 }})
- .bootstrapTooltip('show')
- var tooltip = container.find('.tooltip')
+ var $container = $('<div/>').appendTo('body')
+ var $target = $('<a href="#" rel="tooltip" title="tip" style="top: 0px; right: 0px;"/>')
+ .appendTo($container)
+ .bootstrapTooltip({
+ placement: 'bottom',
+ viewport: {
+ selector: 'body',
+ padding: 12
+ }
+ })
+
+ $target.bootstrapTooltip('show')
+ var $tooltip = $container.find('.tooltip')
+ strictEqual(Math.round($tooltip.offset().left), Math.round($(window).width() - 12 - $tooltip[0].offsetWidth))
- ok(Math.round(tooltip.offset().left) === Math.round($(window).width() - 12 - tooltip[0].offsetWidth))
- target.bootstrapTooltip('hide')
- $('head #test').remove()
+ $target.bootstrapTooltip('hide')
+ equal($('.tooltip').length, 0, 'tooltip removed from dom')
+
+ $container.remove()
+ $styles.remove()
})
test('should adjust the tip when up against the right of an arbitrary viewport', function () {
- $('head').append('<style id="test"> .tooltip, .tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; } </style>')
- $('head').append('<style id="viewport-style"> .container-viewport { position: absolute; top: 50px; left: 60px; width: 300px; height: 300px; } </style>')
+ var styles = '<style>'
+ + '.tooltip, .tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; }'
+ + '.container-viewport { position: absolute; top: 50px; left: 60px; width: 300px; height: 300px; }'
+ + 'a[rel="tooltip"] { position: fixed; }'
+ + '</style>'
+ var $styles = $(styles).appendTo('head')
+
+ var $container = $('<div class="container-viewport"/>').appendTo(document.body)
+ var $target = $('<a href="#" rel="tooltip" title="tip" style="top: 50px; left: 350px;"/>')
+ .appendTo($container)
+ .bootstrapTooltip({
+ placement: 'bottom',
+ viewport: '.container-viewport'
+ })
+
+ $target.bootstrapTooltip('show')
+ var $tooltip = $container.find('.tooltip')
+ strictEqual(Math.round($tooltip.offset().left), Math.round(60 + $container.width() - $tooltip[0].offsetWidth))
- var container = $('<div />', { 'class': 'container-viewport' }).appendTo('body')
- var target = $('<a href="#" rel="tooltip" title="tip" style="position: fixed; top: 50px; left: 350px;"></a>')
- .appendTo(container)
- .bootstrapTooltip({ placement: 'bottom', viewport: '.container-viewport' })
- .bootstrapTooltip('show')
- var tooltip = container.find('.tooltip')
+ $target.bootstrapTooltip('hide')
+ equal($('.tooltip').length, 0, 'tooltip removed from dom')
- ok(Math.round(tooltip.offset().left) === Math.round(60 + container.width() - tooltip[0].offsetWidth))
- target.bootstrapTooltip('hide')
- $('head #test').remove()
- $('head #viewport-style').remove()
+ $container.remove()
+ $styles.remove()
})
test('should not error when trying to show an auto-placed tooltip that has been removed from the dom', function () {
- var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>').appendTo('#qunit-fixture')
-
- tooltip
+ var passed = true
+ var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
+ .appendTo('#qunit-fixture')
.one('show.bs.tooltip', function () {
- tooltip.remove()
+ $(this).remove()
})
.bootstrapTooltip({ placement: 'auto' })
- var passed = true
try {
- tooltip.bootstrapTooltip('show')
- }
- catch (err) {
+ $tooltip.bootstrapTooltip('show')
+ } catch (err) {
passed = false
console.log(err)
}
- ok(passed, '.tooltip(\'show\') should not throw an error in this case')
- try {
- tooltip.remove()
- }
- catch (err) {
- // tooltip may have already been removed
+ ok(passed, '.tooltip(\'show\') should not throw an error if element no longer is in dom')
+ })
+
+ test('should place tooltip on top of element', function () {
+ stop()
+
+ var containerHTML = '<div>'
+ + '<p style="margin-top: 200px">'
+ + '<a href="#" title="very very very very very very very long tooltip">Hover me</a>'
+ + '</p>'
+ + '</div>'
+
+ var $container = $(containerHTML)
+ .css({
+ position: 'absolute',
+ bottom: 0,
+ left: 0,
+ textAlign: 'right',
+ width: 300,
+ height: 300
+ })
+ .appendTo('#qunit-fixture')
+
+ var $trigger = $container
+ .find('a')
+ .css('margin-top', 200)
+ .bootstrapTooltip({
+ placement: 'top',
+ animate: false
+ })
+ .bootstrapTooltip('show')
+
+ var $tooltip = $container.find('.tooltip')
+
+ setTimeout(function () {
+ ok(Math.round($tooltip.offset().top + $tooltip.outerHeight()) <= Math.round($trigger.offset().top))
+ start()
+ }, 0)
+ })
+
+ test('should place tooltip inside viewport', function () {
+ stop()
+
+ var $container = $('<div/>')
+ .css({
+ position: 'absolute',
+ width: 200,
+ height: 200,
+ bottom: 0,
+ left: 0
+ })
+ .appendTo('#qunit-fixture')
+
+ $('<a href="#" title="Very very very very very very very very long tooltip">Hover me</a>')
+ .css({
+ position: 'absolute',
+ top: 0,
+ left: 0
+ })
+ .appendTo($container)
+ .bootstrapTooltip({
+ placement: 'top'
+ })
+ .bootstrapTooltip('show')
+
+ setTimeout(function () {
+ ok($('.tooltip').offset().left >= 0)
+ start()
+ }, 0)
+ })
+
+ test('should show tooltip if leave event hasn\'t occured before delay expires', function () {
+ stop()
+
+ var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
+ .appendTo('#qunit-fixture')
+ .bootstrapTooltip({ delay: 15 })
+
+ setTimeout(function () {
+ ok(!$('.tooltip').is('.fade.in'), '10ms: tooltip is not faded in')
+ }, 10)
+
+ setTimeout(function () {
+ ok($('.tooltip').is('.fade.in'), '20ms: tooltip is faded in')
+ start()
+ }, 20)
+
+ $tooltip.trigger('mouseenter')
+ })
+
+ test('should not show tooltip if leave event occurs before delay expires', function () {
+ stop()
+
+ var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
+ .appendTo('#qunit-fixture')
+ .bootstrapTooltip({ delay: 15 })
+
+ setTimeout(function () {
+ ok(!$('.tooltip').is('.fade.in'), '10ms: tooltip not faded in')
+ $tooltip.trigger('mouseout')
+ }, 10)
+
+ setTimeout(function () {
+ ok(!$('.tooltip').is('.fade.in'), '20ms: tooltip not faded in')
+ start()
+ }, 20)
+
+ $tooltip.trigger('mouseenter')
+ })
+
+ test('should not hide tooltip if leave event occurs and enter event occurs within the hide delay', function () {
+ stop()
+
+ var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
+ .appendTo('#qunit-fixture')
+ .bootstrapTooltip({ delay: { show: 0, hide: 15 }})
+
+ setTimeout(function () {
+ ok($('.tooltip').is('.fade.in'), '1ms: tooltip faded in')
+ $tooltip.trigger('mouseout')
+
+ setTimeout(function () {
+ ok($('.tooltip').is('.fade.in'), '10ms: tooltip still faded in')
+ $tooltip.trigger('mouseenter')
+ }, 10)
+
+ setTimeout(function () {
+ ok($('.tooltip').is('.fade.in'), '20ms: tooltip still faded in')
+ start()
+ }, 20)
+ }, 0)
+
+ $tooltip.trigger('mouseenter')
+ })
+
+ test('should not show tooltip if leave event occurs before delay expires', function () {
+ stop()
+
+ var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
+ .appendTo('#qunit-fixture')
+ .bootstrapTooltip({ delay: 15 })
+
+ setTimeout(function () {
+ ok(!$('.tooltip').is('.fade.in'), '10ms: tooltip not faded in')
+ $tooltip.trigger('mouseout')
+ }, 10)
+
+ setTimeout(function () {
+ ok(!$('.tooltip').is('.fade.in'), '20ms: tooltip not faded in')
+ start()
+ }, 20)
+
+ $tooltip.trigger('mouseenter')
+ })
+
+ test('should not show tooltip if leave event occurs before delay expires, even if hide delay is 0', function () {
+ stop()
+
+ var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
+ .appendTo('#qunit-fixture')
+ .bootstrapTooltip({ delay: { show: 15, hide: 0 }})
+
+ setTimeout(function () {
+ ok(!$('.tooltip').is('.fade.in'), '10ms: tooltip not faded in')
+ $tooltip.trigger('mouseout')
+ }, 10)
+
+ setTimeout(function () {
+ ok(!$('.tooltip').is('.fade.in'), '25ms: tooltip not faded in')
+ start()
+ }, 25)
+
+ $tooltip.trigger('mouseenter')
+ })
+
+ test('should wait 20ms before hiding the tooltip', function () {
+ stop()
+
+ var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
+ .appendTo('#qunit-fixture')
+ .bootstrapTooltip({ delay: { show: 0, hide: 15 }})
+
+ setTimeout(function () {
+ ok($tooltip.data('bs.tooltip').$tip.is('.fade.in'), '1ms: tooltip faded in')
+
+ $tooltip.trigger('mouseout')
+
+ setTimeout(function () {
+ ok($tooltip.data('bs.tooltip').$tip.is('.fade.in'), '10ms: tooltip still faded in')
+ }, 10)
+
+ setTimeout(function () {
+ ok(!$tooltip.data('bs.tooltip').$tip.is('.in'), '20ms: tooltip removed')
+ start()
+ }, 20)
+
+ }, 0)
+
+ $tooltip.trigger('mouseenter')
+ })
+
+ test('should correctly position tooltips on SVG elements', function () {
+ if (!window.SVGElement) {
+ // Skip IE8 since it doesn't support SVG
+ expect(0)
+ return
}
+
+ stop()
+
+ var styles = '<style>'
+ + '.tooltip, .tooltip *, .tooltip *:before, .tooltip *:after { box-sizing: border-box; }'
+ + '.tooltip { position: absolute; }'
+ + '.tooltip .tooltip-inner { width: 24px; height: 24px; font-family: Helvetica; }'
+ + '</style>'
+ var $styles = $(styles).appendTo('head')
+
+ $('#qunit-fixture').append(
+ '<div style="position: fixed; top: 0; left: 0;">'
+ + ' <svg width="200" height="200">'
+ + ' <circle cx="100" cy="100" r="10" title="m" id="theCircle" />'
+ + ' </svg>'
+ + '</div>')
+ var $circle = $('#theCircle')
+
+ $circle
+ .on('shown.bs.tooltip', function () {
+ var offset = $('.tooltip').offset()
+ $styles.remove()
+ ok(Math.abs(offset.left - 88) <= 1, 'tooltip has correct horizontal location')
+ start()
+ })
+ .bootstrapTooltip({ container: 'body', placement: 'top', trigger: 'manual' })
+
+ $circle.bootstrapTooltip('show')
})
+
})
diff --git a/js/tests/visual/affix.html b/js/tests/visual/affix.html
index 5e677eb57..40a55ab51 100644
--- a/js/tests/visual/affix.html
+++ b/js/tests/visual/affix.html
@@ -6,12 +6,36 @@
<style>
/* Test Styles */
- .affix {
+ .affixed-element-top.affix {
top: 10px;
}
- .affix-bottom {
+ .affixed-element-top.affix-bottom {
position: absolute;
}
+ .affixed-element-bottom {
+ margin-bottom: 0;
+ }
+ .affixed-element-bottom.affix {
+ bottom: 10px;
+ }
+ .affixed-element-bottom.affix-bottom {
+ position: relative;
+ }
+ .grow-btn, .shrink-btn {
+ color: #FFF;
+ }
+ .grow-btn {
+ background-color: #2ECC40;
+ }
+ .grow-btn:hover {
+ background-color: #3D9970;
+ }
+ .shrink-btn {
+ background-color: #FF4136;
+ }
+ .shrink-btn:hover {
+ background-color: #85144B;
+ }
</style>
</head>
<body>
@@ -23,7 +47,7 @@
</div>
<div class="col-md-3">
- <ul class="list-group js-affixed-element">
+ <ul class="list-group affixed-element-top js-affixed-element-top">
<li class="list-group-item">Cras justo odio</li>
<li class="list-group-item">Dapibus ac facilisis in</li>
<li class="list-group-item">Morbi leo risus</li>
@@ -43,7 +67,7 @@
</ul>
</div>
- <div class="col-md-9">
+ <div class="col-md-6 js-content">
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
@@ -199,6 +223,27 @@
</div>
+ <div class="col-md-3">
+ <ul class="list-group affixed-element-bottom js-affixed-element-bottom">
+ <li class="list-group-item">Sit necessitatibus aspernatur.</li>
+ <li class="list-group-item">Adipisicing alias dolor!</li>
+ <li class="list-group-item">Ipsum molestiae impedit.</li>
+ <li class="list-group-item">Amet quis iste?</li>
+ <li class="list-group-item">Ipsum quaerat porro.</li>
+ <li class="list-group-item">Elit lorem libero.</li>
+ <li class="list-group-item">Ipsum dolore facilis.</li>
+ <li class="list-group-item">Elit ad atque.</li>
+ <li class="list-group-item">Dolor amet sequi!</li>
+ <li class="list-group-item">Consectetur voluptatum facilis!</li>
+ <li class="list-group-item">Sit neque eligendi?</li>
+ <li class="list-group-item">Amet fuga consectetur!</li>
+ <li class="list-group-item">Amet molestias repellat!</li>
+ <li class="list-group-item">Consectetur minima repellendus.</li>
+ <li class="list-group-item grow-btn js-grow-btn">Grow content</li>
+ <li class="list-group-item shrink-btn js-shrink-btn">Shrink content</li>
+ </ul>
+ </div>
+
<div class="col-md-12 js-footer">
<hr>
@@ -222,7 +267,7 @@
<!-- JavaScript Test -->
<script>
$(function () {
- $('.js-affixed-element').affix({
+ $('.js-affixed-element-top').affix({
offset: {
top: $('.js-page-header').outerHeight(true) - 10
, bottom: $('.js-footer').outerHeight(true) + 10
@@ -232,6 +277,19 @@ $(function () {
.on('affix.bs.affix', function (e) {
$(e.target).width(e.target.offsetWidth)
})
+
+ $('.js-affixed-element-bottom').affix({
+ offset: {
+ bottom: $('.js-footer').outerHeight(true) + 10
+ }
+ })
+
+ $('.js-grow-btn').on('click', function() {
+ $('.js-content').append('<p>Ipsum corrupti ipsam est temporibus.</p>')
+ })
+ $('.js-shrink-btn').on('click', function() {
+ $('.js-content p').last().remove()
+ })
})
</script>
</body>
diff --git a/js/tests/visual/dropdown.html b/js/tests/visual/dropdown.html
index c6b2f7aab..455a4f571 100644
--- a/js/tests/visual/dropdown.html
+++ b/js/tests/visual/dropdown.html
@@ -15,7 +15,7 @@
<nav id="navbar-example" class="navbar navbar-default navbar-static" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
- <button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".bs-example-js-navbar-collapse">
+ <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target=".bs-example-js-navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
diff --git a/js/tests/visual/scrollspy.html b/js/tests/visual/scrollspy.html
index 9d581e331..2611337f5 100644
--- a/js/tests/visual/scrollspy.html
+++ b/js/tests/visual/scrollspy.html
@@ -14,7 +14,7 @@
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
- <button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".js-navbar-scrollspy">
+ <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target=".js-navbar-scrollspy">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
diff --git a/js/tests/visual/tab.html b/js/tests/visual/tab.html
index 37921afec..28757df6e 100644
--- a/js/tests/visual/tab.html
+++ b/js/tests/visual/tab.html
@@ -4,6 +4,9 @@
<title>Tab</title>
<link rel="stylesheet" type="text/css" href="../../../dist/css/bootstrap.min.css">
<style type="text/css">
+ h4 {
+ margin: 40px 0 10px;
+ }
.nav-tabs {
margin-bottom: 15px;
}
@@ -17,6 +20,8 @@
<h1>Tab <small>Bootstrap Visual Test</small></h1>
</div>
+ <h4>Tabs without fade</h4>
+
<ul id="myTab" class="nav nav-tabs">
<li class="active"><a href="#home" data-toggle="tab">Home</a></li>
<li><a href="#profile" data-toggle="tab">Profile</a></li>
@@ -29,19 +34,115 @@
</li>
</ul>
<div id="myTabContent" class="tab-content">
- <div class="tab-pane fade in active" id="home">
+ <div class="tab-pane active" id="home">
+ <p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
+ <p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
+ </div>
+ <div class="tab-pane" id="profile">
+ <p>Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park.</p>
+ <p>Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park.</p>
+ </div>
+ <div class="tab-pane" id="dropdown1">
+ <p>Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.</p>
+ <p>Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.</p>
+ </div>
+ <div class="tab-pane" id="dropdown2">
+ <p>Trust fund seitan letterpress, keytar raw denim keffiyeh etsy art party before they sold out master cleanse gluten-free squid scenester freegan cosby sweater. Fanny pack portland seitan DIY, art party locavore wolf cliche high life echo park Austin. Cred vinyl keffiyeh DIY salvia PBR, banh mi before they sold out farm-to-table VHS viral locavore cosby sweater. Lomo wolf viral, mustache readymade thundercats keffiyeh craft beer marfa ethical. Wolf salvia freegan, sartorial keffiyeh echo park vegan.</p>
+ <p>Trust fund seitan letterpress, keytar raw denim keffiyeh etsy art party before they sold out master cleanse gluten-free squid scenester freegan cosby sweater. Fanny pack portland seitan DIY, art party locavore wolf cliche high life echo park Austin. Cred vinyl keffiyeh DIY salvia PBR, banh mi before they sold out farm-to-table VHS viral locavore cosby sweater. Lomo wolf viral, mustache readymade thundercats keffiyeh craft beer marfa ethical. Wolf salvia freegan, sartorial keffiyeh echo park vegan.</p>
+ </div>
+ </div>
+
+ <h4>Tabs with fade</h4>
+
+ <ul id="myTab1" class="nav nav-tabs">
+ <li class="active"><a href="#home1" data-toggle="tab">Home</a></li>
+ <li><a href="#profile1" data-toggle="tab">Profile</a></li>
+ <li class="dropdown">
+ <a href="#" id="myTabDrop2" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
+ <ul class="dropdown-menu" role="menu" aria-labelledby="myTabDrop2">
+ <li><a href="#dropdown1-1" tabindex="-1" data-toggle="tab">@fat</a></li>
+ <li><a href="#dropdown1-2" tabindex="-1" data-toggle="tab">@mdo</a></li>
+ </ul>
+ </li>
+ </ul>
+ <div id="myTabContent1" class="tab-content">
+ <div class="tab-pane fade in active" id="home1">
+ <p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
+ <p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
+ </div>
+ <div class="tab-pane fade" id="profile1">
+ <p>Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park.</p>
+ <p>Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park.</p>
+ </div>
+ <div class="tab-pane fade" id="dropdown1-1">
+ <p>Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.</p>
+ <p>Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.</p>
+ </div>
+ <div class="tab-pane fade" id="dropdown1-2">
+ <p>Trust fund seitan letterpress, keytar raw denim keffiyeh etsy art party before they sold out master cleanse gluten-free squid scenester freegan cosby sweater. Fanny pack portland seitan DIY, art party locavore wolf cliche high life echo park Austin. Cred vinyl keffiyeh DIY salvia PBR, banh mi before they sold out farm-to-table VHS viral locavore cosby sweater. Lomo wolf viral, mustache readymade thundercats keffiyeh craft beer marfa ethical. Wolf salvia freegan, sartorial keffiyeh echo park vegan.</p>
+ <p>Trust fund seitan letterpress, keytar raw denim keffiyeh etsy art party before they sold out master cleanse gluten-free squid scenester freegan cosby sweater. Fanny pack portland seitan DIY, art party locavore wolf cliche high life echo park Austin. Cred vinyl keffiyeh DIY salvia PBR, banh mi before they sold out farm-to-table VHS viral locavore cosby sweater. Lomo wolf viral, mustache readymade thundercats keffiyeh craft beer marfa ethical. Wolf salvia freegan, sartorial keffiyeh echo park vegan.</p>
+ </div>
+ </div>
+
+ <h4>Tabs without fade (no initially active pane)</h4>
+
+ <ul id="myTab2" class="nav nav-tabs">
+ <li><a href="#home2" data-toggle="tab">Home</a></li>
+ <li><a href="#profile2" data-toggle="tab">Profile</a></li>
+ <li class="dropdown">
+ <a href="#" id="myTabDrop3" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
+ <ul class="dropdown-menu" role="menu" aria-labelledby="myTabDrop3">
+ <li><a href="#dropdown2-1" tabindex="-1" data-toggle="tab">@fat</a></li>
+ <li><a href="#dropdown2-2" tabindex="-1" data-toggle="tab">@mdo</a></li>
+ </ul>
+ </li>
+ </ul>
+ <div id="myTabContent2" class="tab-content">
+ <div class="tab-pane" id="home2">
+ <p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
+ <p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
+ </div>
+ <div class="tab-pane" id="profile2">
+ <p>Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park.</p>
+ <p>Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park.</p>
+ </div>
+ <div class="tab-pane" id="dropdown2-1">
+ <p>Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.</p>
+ <p>Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.</p>
+ </div>
+ <div class="tab-pane" id="dropdown2-2">
+ <p>Trust fund seitan letterpress, keytar raw denim keffiyeh etsy art party before they sold out master cleanse gluten-free squid scenester freegan cosby sweater. Fanny pack portland seitan DIY, art party locavore wolf cliche high life echo park Austin. Cred vinyl keffiyeh DIY salvia PBR, banh mi before they sold out farm-to-table VHS viral locavore cosby sweater. Lomo wolf viral, mustache readymade thundercats keffiyeh craft beer marfa ethical. Wolf salvia freegan, sartorial keffiyeh echo park vegan.</p>
+ <p>Trust fund seitan letterpress, keytar raw denim keffiyeh etsy art party before they sold out master cleanse gluten-free squid scenester freegan cosby sweater. Fanny pack portland seitan DIY, art party locavore wolf cliche high life echo park Austin. Cred vinyl keffiyeh DIY salvia PBR, banh mi before they sold out farm-to-table VHS viral locavore cosby sweater. Lomo wolf viral, mustache readymade thundercats keffiyeh craft beer marfa ethical. Wolf salvia freegan, sartorial keffiyeh echo park vegan.</p>
+ </div>
+ </div>
+
+ <h4>Tabs with fade (no initially active pane)</h4>
+
+ <ul id="myTab3" class="nav nav-tabs">
+ <li><a href="#home3" data-toggle="tab">Home</a></li>
+ <li><a href="#profile3" data-toggle="tab">Profile</a></li>
+ <li class="dropdown">
+ <a href="#" id="myTabDrop4" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
+ <ul class="dropdown-menu" role="menu" aria-labelledby="myTabDrop4">
+ <li><a href="#dropdown3-1" tabindex="-1" data-toggle="tab">@fat</a></li>
+ <li><a href="#dropdown3-2" tabindex="-1" data-toggle="tab">@mdo</a></li>
+ </ul>
+ </li>
+ </ul>
+ <div id="myTabContent3" class="tab-content">
+ <div class="tab-pane fade" id="home3">
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
</div>
- <div class="tab-pane fade" id="profile">
+ <div class="tab-pane fade" id="profile3">
<p>Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park.</p>
<p>Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park.</p>
</div>
- <div class="tab-pane fade" id="dropdown1">
+ <div class="tab-pane fade" id="dropdown3-1">
<p>Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.</p>
<p>Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.</p>
</div>
- <div class="tab-pane fade" id="dropdown2">
+ <div class="tab-pane fade" id="dropdown3-2">
<p>Trust fund seitan letterpress, keytar raw denim keffiyeh etsy art party before they sold out master cleanse gluten-free squid scenester freegan cosby sweater. Fanny pack portland seitan DIY, art party locavore wolf cliche high life echo park Austin. Cred vinyl keffiyeh DIY salvia PBR, banh mi before they sold out farm-to-table VHS viral locavore cosby sweater. Lomo wolf viral, mustache readymade thundercats keffiyeh craft beer marfa ethical. Wolf salvia freegan, sartorial keffiyeh echo park vegan.</p>
<p>Trust fund seitan letterpress, keytar raw denim keffiyeh etsy art party before they sold out master cleanse gluten-free squid scenester freegan cosby sweater. Fanny pack portland seitan DIY, art party locavore wolf cliche high life echo park Austin. Cred vinyl keffiyeh DIY salvia PBR, banh mi before they sold out farm-to-table VHS viral locavore cosby sweater. Lomo wolf viral, mustache readymade thundercats keffiyeh craft beer marfa ethical. Wolf salvia freegan, sartorial keffiyeh echo park vegan.</p>
</div>
diff --git a/js/tooltip.js b/js/tooltip.js
index 38940a384..e730db6e9 100644
--- a/js/tooltip.js
+++ b/js/tooltip.js
@@ -1,5 +1,5 @@
/* ========================================================================
- * Bootstrap: tooltip.js v3.1.1
+ * Bootstrap: tooltip.js v3.2.0
* http://getbootstrap.com/javascript/#tooltip
* Inspired by the original jQuery.tipsy by Jason Frame
* ========================================================================
@@ -8,456 +8,459 @@
* ======================================================================== */
-+function () { 'use strict';
++function ($) {
+ 'use strict';
+
+ // TOOLTIP PUBLIC CLASS DEFINITION
+ // ===============================
+
+ var Tooltip = function (element, options) {
+ this.type =
+ this.options =
+ this.enabled =
+ this.timeout =
+ this.hoverState =
+ this.$element = null
+
+ this.init('tooltip', element, options)
+ }
+
+ Tooltip.VERSION = '3.2.0'
+
+ Tooltip.TRANSITION_DURATION = 150
+
+ Tooltip.DEFAULTS = {
+ animation: true,
+ placement: 'top',
+ selector: false,
+ template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
+ trigger: 'hover focus',
+ title: '',
+ delay: 0,
+ html: false,
+ container: false,
+ viewport: {
+ selector: 'body',
+ padding: 0
+ }
+ }
- (function (o_o) {
- typeof define == 'function' && define.amd ? define(['jquery'], o_o) :
- typeof exports == 'object' ? o_o(require('jquery')) : o_o(jQuery)
- })(function ($) {
+ Tooltip.prototype.init = function (type, element, options) {
+ this.enabled = true
+ this.type = type
+ this.$element = $(element)
+ this.options = this.getOptions(options)
+ this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
- // TOOLTIP PUBLIC CLASS DEFINITION
- // ===============================
+ var triggers = this.options.trigger.split(' ')
- var Tooltip = function (element, options) {
- this.type =
- this.options =
- this.enabled =
- this.timeout =
- this.hoverState =
- this.$element = null
+ for (var i = triggers.length; i--;) {
+ var trigger = triggers[i]
- this.init('tooltip', element, options)
- }
+ if (trigger == 'click') {
+ this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
+ } else if (trigger != 'manual') {
+ var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
+ var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
- Tooltip.VERSION = '3.1.1'
-
- Tooltip.DEFAULTS = {
- animation: true,
- placement: 'top',
- selector: false,
- template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
- trigger: 'hover focus',
- title: '',
- delay: 0,
- html: false,
- container: false,
- viewport: {
- selector: 'body',
- padding: 0
+ this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
+ this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
}
}
- Tooltip.prototype.init = function (type, element, options) {
- this.enabled = true
- this.type = type
- this.$element = $(element)
- this.options = this.getOptions(options)
- this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
-
- var triggers = this.options.trigger.split(' ')
+ this.options.selector ?
+ (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
+ this.fixTitle()
+ }
- for (var i = triggers.length; i--;) {
- var trigger = triggers[i]
+ Tooltip.prototype.getDefaults = function () {
+ return Tooltip.DEFAULTS
+ }
- if (trigger == 'click') {
- this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
- } else if (trigger != 'manual') {
- var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
- var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
+ Tooltip.prototype.getOptions = function (options) {
+ options = $.extend({}, this.getDefaults(), this.$element.data(), options)
- this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
- this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
- }
+ if (options.delay && typeof options.delay == 'number') {
+ options.delay = {
+ show: options.delay,
+ hide: options.delay
}
-
- this.options.selector ?
- (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
- this.fixTitle()
}
- Tooltip.prototype.getDefaults = function () {
- return Tooltip.DEFAULTS
- }
+ return options
+ }
- Tooltip.prototype.getOptions = function (options) {
- options = $.extend({}, this.getDefaults(), this.$element.data(), options)
+ Tooltip.prototype.getDelegateOptions = function () {
+ var options = {}
+ var defaults = this.getDefaults()
- if (options.delay && typeof options.delay == 'number') {
- options.delay = {
- show: options.delay,
- hide: options.delay
- }
- }
-
- return options
- }
+ this._options && $.each(this._options, function (key, value) {
+ if (defaults[key] != value) options[key] = value
+ })
- Tooltip.prototype.getDelegateOptions = function () {
- var options = {}
- var defaults = this.getDefaults()
+ return options
+ }
- this._options && $.each(this._options, function (key, value) {
- if (defaults[key] != value) options[key] = value
- })
+ Tooltip.prototype.enter = function (obj) {
+ var self = obj instanceof this.constructor ?
+ obj : $(obj.currentTarget).data('bs.' + this.type)
- return options
+ if (!self) {
+ self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
+ $(obj.currentTarget).data('bs.' + this.type, self)
}
- Tooltip.prototype.enter = function (obj) {
- var self = obj instanceof this.constructor ?
- obj : $(obj.currentTarget).data('bs.' + this.type)
+ clearTimeout(self.timeout)
- if (!self) {
- self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
- $(obj.currentTarget).data('bs.' + this.type, self)
- }
+ self.hoverState = 'in'
- clearTimeout(self.timeout)
+ if (!self.options.delay || !self.options.delay.show) return self.show()
- self.hoverState = 'in'
+ self.timeout = setTimeout(function () {
+ if (self.hoverState == 'in') self.show()
+ }, self.options.delay.show)
+ }
- if (!self.options.delay || !self.options.delay.show) return self.show()
+ Tooltip.prototype.leave = function (obj) {
+ var self = obj instanceof this.constructor ?
+ obj : $(obj.currentTarget).data('bs.' + this.type)
- self.timeout = setTimeout(function () {
- if (self.hoverState == 'in') self.show()
- }, self.options.delay.show)
+ if (!self) {
+ self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
+ $(obj.currentTarget).data('bs.' + this.type, self)
}
- Tooltip.prototype.leave = function (obj) {
- var self = obj instanceof this.constructor ?
- obj : $(obj.currentTarget).data('bs.' + this.type)
-
- if (!self) {
- self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
- $(obj.currentTarget).data('bs.' + this.type, self)
- }
-
- clearTimeout(self.timeout)
-
- self.hoverState = 'out'
+ clearTimeout(self.timeout)
- if (!self.options.delay || !self.options.delay.hide) return self.hide()
+ self.hoverState = 'out'
- self.timeout = setTimeout(function () {
- if (self.hoverState == 'out') self.hide()
- }, self.options.delay.hide)
- }
+ if (!self.options.delay || !self.options.delay.hide) return self.hide()
- Tooltip.prototype.show = function () {
- var e = $.Event('show.bs.' + this.type)
+ self.timeout = setTimeout(function () {
+ if (self.hoverState == 'out') self.hide()
+ }, self.options.delay.hide)
+ }
- if (this.hasContent() && this.enabled) {
- this.$element.trigger(e)
+ Tooltip.prototype.show = function () {
+ var e = $.Event('show.bs.' + this.type)
- var inDom = $.contains(document.documentElement, this.$element[0])
- if (e.isDefaultPrevented() || !inDom) return
- var that = this
+ if (this.hasContent() && this.enabled) {
+ this.$element.trigger(e)
- var $tip = this.tip()
+ var inDom = $.contains(document.documentElement, this.$element[0])
+ if (e.isDefaultPrevented() || !inDom) return
+ var that = this
- var tipId = this.getUID(this.type)
+ var $tip = this.tip()
- this.setContent()
- $tip.attr('id', tipId)
- this.$element.attr('aria-describedby', tipId)
+ var tipId = this.getUID(this.type)
- if (this.options.animation) $tip.addClass('fade')
+ this.setContent()
+ $tip.attr('id', tipId)
+ this.$element.attr('aria-describedby', tipId)
- var placement = typeof this.options.placement == 'function' ?
- this.options.placement.call(this, $tip[0], this.$element[0]) :
- this.options.placement
+ if (this.options.animation) $tip.addClass('fade')
- var autoToken = /\s?auto?\s?/i
- var autoPlace = autoToken.test(placement)
- if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
+ var placement = typeof this.options.placement == 'function' ?
+ this.options.placement.call(this, $tip[0], this.$element[0]) :
+ this.options.placement
- $tip
- .detach()
- .css({ top: 0, left: 0, display: 'block' })
- .addClass(placement)
- .data('bs.' + this.type, this)
+ var autoToken = /\s?auto?\s?/i
+ var autoPlace = autoToken.test(placement)
+ if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
- this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
+ $tip
+ .detach()
+ .css({ top: 0, left: 0, display: 'block' })
+ .addClass(placement)
+ .data('bs.' + this.type, this)
- var pos = this.getPosition()
- var actualWidth = $tip[0].offsetWidth
- var actualHeight = $tip[0].offsetHeight
+ this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
- if (autoPlace) {
- var orgPlacement = placement
- var $parent = this.$element.parent()
- var parentDim = this.getPosition($parent)
+ var pos = this.getPosition()
+ var actualWidth = $tip[0].offsetWidth
+ var actualHeight = $tip[0].offsetHeight
- placement = placement == 'bottom' && pos.top + pos.height + actualHeight - parentDim.scroll > parentDim.height ? 'top' :
- placement == 'top' && pos.top - parentDim.scroll - actualHeight < 0 ? 'bottom' :
- placement == 'right' && pos.right + actualWidth > parentDim.width ? 'left' :
- placement == 'left' && pos.left - actualWidth < parentDim.left ? 'right' :
- placement
+ if (autoPlace) {
+ var orgPlacement = placement
+ var $parent = this.$element.parent()
+ var parentDim = this.getPosition($parent)
- $tip
- .removeClass(orgPlacement)
- .addClass(placement)
- }
+ placement = placement == 'bottom' && pos.top + pos.height + actualHeight - parentDim.scroll > parentDim.height ? 'top' :
+ placement == 'top' && pos.top - parentDim.scroll - actualHeight < 0 ? 'bottom' :
+ placement == 'right' && pos.right + actualWidth > parentDim.width ? 'left' :
+ placement == 'left' && pos.left - actualWidth < parentDim.left ? 'right' :
+ placement
- var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
+ $tip
+ .removeClass(orgPlacement)
+ .addClass(placement)
+ }
- this.applyPlacement(calculatedOffset, placement)
- this.hoverState = null
+ var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
- var complete = function () {
- that.$element.trigger('shown.bs.' + that.type)
- }
+ this.applyPlacement(calculatedOffset, placement)
- $.support.transition && this.$tip.hasClass('fade') ?
- $tip
- .one('bsTransitionEnd', complete)
- .emulateTransitionEnd(150) :
- complete()
+ var complete = function () {
+ that.$element.trigger('shown.bs.' + that.type)
+ that.hoverState = null
}
+
+ $.support.transition && this.$tip.hasClass('fade') ?
+ $tip
+ .one('bsTransitionEnd', complete)
+ .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
+ complete()
}
+ }
+
+ Tooltip.prototype.applyPlacement = function (offset, placement) {
+ var $tip = this.tip()
+ var width = $tip[0].offsetWidth
+ var height = $tip[0].offsetHeight
+
+ // manually read margins because getBoundingClientRect includes difference
+ var marginTop = parseInt($tip.css('margin-top'), 10)
+ var marginLeft = parseInt($tip.css('margin-left'), 10)
+
+ // we must check for NaN for ie 8/9
+ if (isNaN(marginTop)) marginTop = 0
+ if (isNaN(marginLeft)) marginLeft = 0
+
+ offset.top = offset.top + marginTop
+ offset.left = offset.left + marginLeft
+
+ // $.fn.offset doesn't round pixel values
+ // so we use setOffset directly with our own function B-0
+ $.offset.setOffset($tip[0], $.extend({
+ using: function (props) {
+ $tip.css({
+ top: Math.round(props.top),
+ left: Math.round(props.left)
+ })
+ }
+ }, offset), 0)
- Tooltip.prototype.applyPlacement = function (offset, placement) {
- var $tip = this.tip()
- var width = $tip[0].offsetWidth
- var height = $tip[0].offsetHeight
+ $tip.addClass('in')
- // manually read margins because getBoundingClientRect includes difference
- var marginTop = parseInt($tip.css('margin-top'), 10)
- var marginLeft = parseInt($tip.css('margin-left'), 10)
+ // check to see if placing tip in new offset caused the tip to resize itself
+ var actualWidth = $tip[0].offsetWidth
+ var actualHeight = $tip[0].offsetHeight
- // we must check for NaN for ie 8/9
- if (isNaN(marginTop)) marginTop = 0
- if (isNaN(marginLeft)) marginLeft = 0
+ if (placement == 'top' && actualHeight != height) {
+ offset.top = offset.top + height - actualHeight
+ }
- offset.top = offset.top + marginTop
- offset.left = offset.left + marginLeft
+ var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
- // $.fn.offset doesn't round pixel values
- // so we use setOffset directly with our own function B-0
- $.offset.setOffset($tip[0], $.extend({
- using: function (props) {
- $tip.css({
- top: Math.round(props.top),
- left: Math.round(props.left)
- })
- }
- }, offset), 0)
+ if (delta.left) offset.left += delta.left
+ else offset.top += delta.top
- $tip.addClass('in')
+ var arrowDelta = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
+ var arrowPosition = delta.left ? 'left' : 'top'
+ var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight'
- // check to see if placing tip in new offset caused the tip to resize itself
- var actualWidth = $tip[0].offsetWidth
- var actualHeight = $tip[0].offsetHeight
+ $tip.offset(offset)
+ this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition)
+ }
- if (placement == 'top' && actualHeight != height) {
- offset.top = offset.top + height - actualHeight
- }
+ Tooltip.prototype.replaceArrow = function (delta, dimension, position) {
+ this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '')
+ }
- var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
+ Tooltip.prototype.setContent = function () {
+ var $tip = this.tip()
+ var title = this.getTitle()
- if (delta.left) offset.left += delta.left
- else offset.top += delta.top
+ $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
+ $tip.removeClass('fade in top bottom left right')
+ }
- var arrowDelta = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
- var arrowPosition = delta.left ? 'left' : 'top'
- var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight'
+ Tooltip.prototype.hide = function () {
+ var that = this
+ var $tip = this.tip()
+ var e = $.Event('hide.bs.' + this.type)
- $tip.offset(offset)
- this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition)
- }
+ this.$element.removeAttr('aria-describedby')
- Tooltip.prototype.replaceArrow = function (delta, dimension, position) {
- this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '')
+ function complete() {
+ if (that.hoverState != 'in') $tip.detach()
+ that.$element.trigger('hidden.bs.' + that.type)
}
- Tooltip.prototype.setContent = function () {
- var $tip = this.tip()
- var title = this.getTitle()
+ this.$element.trigger(e)
- $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
- $tip.removeClass('fade in top bottom left right')
- }
+ if (e.isDefaultPrevented()) return
- Tooltip.prototype.hide = function () {
- var that = this
- var $tip = this.tip()
- var e = $.Event('hide.bs.' + this.type)
+ $tip.removeClass('in')
- this.$element.removeAttr('aria-describedby')
+ $.support.transition && this.$tip.hasClass('fade') ?
+ $tip
+ .one('bsTransitionEnd', complete)
+ .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
+ complete()
- function complete() {
- if (that.hoverState != 'in') $tip.detach()
- that.$element.trigger('hidden.bs.' + that.type)
- }
+ this.hoverState = null
- this.$element.trigger(e)
+ return this
+ }
- if (e.isDefaultPrevented()) return
+ Tooltip.prototype.fixTitle = function () {
+ var $e = this.$element
+ if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') {
+ $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
+ }
+ }
- $tip.removeClass('in')
+ Tooltip.prototype.hasContent = function () {
+ return this.getTitle()
+ }
- $.support.transition && this.$tip.hasClass('fade') ?
- $tip
- .one('bsTransitionEnd', complete)
- .emulateTransitionEnd(150) :
- complete()
+ Tooltip.prototype.getPosition = function ($element) {
+ $element = $element || this.$element
- this.hoverState = null
+ var el = $element[0]
+ var isBody = el.tagName == 'BODY'
+ var isSvg = window.SVGElement && el instanceof window.SVGElement
- return this
+ var elRect = el.getBoundingClientRect()
+ var elOffset = isBody ? { top: 0, left: 0 } : $element.offset()
+ var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
+ var outerDims = isSvg ? {} : {
+ width: isBody ? $(window).width() : $element.outerWidth(),
+ height: isBody ? $(window).height() : $element.outerHeight()
}
- Tooltip.prototype.fixTitle = function () {
- var $e = this.$element
- if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') {
- $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
- }
- }
+ return $.extend({}, elRect, scroll, outerDims, elOffset)
+ }
- Tooltip.prototype.hasContent = function () {
- return this.getTitle()
- }
+ Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
+ return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
+ placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
+ placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
+ /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
- Tooltip.prototype.getPosition = function ($element) {
- $element = $element || this.$element
- var el = $element[0]
- var isBody = el.tagName == 'BODY'
- return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, {
- scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(),
- width: isBody ? $(window).width() : $element.outerWidth(),
- height: isBody ? $(window).height() : $element.outerHeight()
- }, isBody ? { top: 0, left: 0 } : $element.offset())
- }
+ }
- Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
- return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
- placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
- placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
- /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
+ Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
+ var delta = { top: 0, left: 0 }
+ if (!this.$viewport) return delta
- }
+ var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
+ var viewportDimensions = this.getPosition(this.$viewport)
- Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
- var delta = { top: 0, left: 0 }
- if (!this.$viewport) return delta
-
- var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
- var viewportDimensions = this.getPosition(this.$viewport)
-
- if (/right|left/.test(placement)) {
- var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
- var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
- if (topEdgeOffset < viewportDimensions.top) { // top overflow
- delta.top = viewportDimensions.top - topEdgeOffset
- } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
- delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
- }
- } else {
- var leftEdgeOffset = pos.left - viewportPadding
- var rightEdgeOffset = pos.left + viewportPadding + actualWidth
- if (leftEdgeOffset < viewportDimensions.left) { // left overflow
- delta.left = viewportDimensions.left - leftEdgeOffset
- } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow
- delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
- }
+ if (/right|left/.test(placement)) {
+ var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
+ var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
+ if (topEdgeOffset < viewportDimensions.top) { // top overflow
+ delta.top = viewportDimensions.top - topEdgeOffset
+ } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
+ delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
+ }
+ } else {
+ var leftEdgeOffset = pos.left - viewportPadding
+ var rightEdgeOffset = pos.left + viewportPadding + actualWidth
+ if (leftEdgeOffset < viewportDimensions.left) { // left overflow
+ delta.left = viewportDimensions.left - leftEdgeOffset
+ } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow
+ delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
}
-
- return delta
}
- Tooltip.prototype.getTitle = function () {
- var title
- var $e = this.$element
- var o = this.options
+ return delta
+ }
- title = $e.attr('data-original-title')
- || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
+ Tooltip.prototype.getTitle = function () {
+ var title
+ var $e = this.$element
+ var o = this.options
- return title
- }
+ title = $e.attr('data-original-title')
+ || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
- Tooltip.prototype.getUID = function (prefix) {
- do prefix += ~~(Math.random() * 1000000)
- while (document.getElementById(prefix))
- return prefix
- }
+ return title
+ }
- Tooltip.prototype.tip = function () {
- return (this.$tip = this.$tip || $(this.options.template))
- }
+ Tooltip.prototype.getUID = function (prefix) {
+ do prefix += ~~(Math.random() * 1000000)
+ while (document.getElementById(prefix))
+ return prefix
+ }
- Tooltip.prototype.arrow = function () {
- return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
- }
+ Tooltip.prototype.tip = function () {
+ return (this.$tip = this.$tip || $(this.options.template))
+ }
- Tooltip.prototype.validate = function () {
- if (!this.$element[0].parentNode) {
- this.hide()
- this.$element = null
- this.options = null
- }
- }
+ Tooltip.prototype.arrow = function () {
+ return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
+ }
- Tooltip.prototype.enable = function () {
- this.enabled = true
+ Tooltip.prototype.validate = function () {
+ if (!this.$element[0].parentNode) {
+ this.hide()
+ this.$element = null
+ this.options = null
}
+ }
- Tooltip.prototype.disable = function () {
- this.enabled = false
- }
+ Tooltip.prototype.enable = function () {
+ this.enabled = true
+ }
- Tooltip.prototype.toggleEnabled = function () {
- this.enabled = !this.enabled
- }
+ Tooltip.prototype.disable = function () {
+ this.enabled = false
+ }
- Tooltip.prototype.toggle = function (e) {
- var self = this
- if (e) {
- self = $(e.currentTarget).data('bs.' + this.type)
- if (!self) {
- self = new this.constructor(e.currentTarget, this.getDelegateOptions())
- $(e.currentTarget).data('bs.' + this.type, self)
- }
- }
+ Tooltip.prototype.toggleEnabled = function () {
+ this.enabled = !this.enabled
+ }
- self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
+ Tooltip.prototype.toggle = function (e) {
+ var self = this
+ if (e) {
+ self = $(e.currentTarget).data('bs.' + this.type)
+ if (!self) {
+ self = new this.constructor(e.currentTarget, this.getDelegateOptions())
+ $(e.currentTarget).data('bs.' + this.type, self)
+ }
}
- Tooltip.prototype.destroy = function () {
- clearTimeout(this.timeout)
- this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)
- }
+ self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
+ }
+ Tooltip.prototype.destroy = function () {
+ clearTimeout(this.timeout)
+ this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)
+ }
- // TOOLTIP PLUGIN DEFINITION
- // =========================
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.tooltip')
- var options = typeof option == 'object' && option
+ // TOOLTIP PLUGIN DEFINITION
+ // =========================
- if (!data && option == 'destroy') return
- if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.tooltip')
+ var options = typeof option == 'object' && option
- var old = $.fn.tooltip
+ if (!data && option == 'destroy') return
+ if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
- $.fn.tooltip = Plugin
- $.fn.tooltip.Constructor = Tooltip
+ var old = $.fn.tooltip
+ $.fn.tooltip = Plugin
+ $.fn.tooltip.Constructor = Tooltip
- // TOOLTIP NO CONFLICT
- // ===================
- $.fn.tooltip.noConflict = function () {
- $.fn.tooltip = old
- return this
- }
+ // TOOLTIP NO CONFLICT
+ // ===================
- })
+ $.fn.tooltip.noConflict = function () {
+ $.fn.tooltip = old
+ return this
+ }
-}();
+}(jQuery);
diff --git a/js/transition.js b/js/transition.js
index a747dc2fd..83f85bf45 100644
--- a/js/transition.js
+++ b/js/transition.js
@@ -1,5 +1,5 @@
/* ========================================================================
- * Bootstrap: transition.js v3.1.1
+ * Bootstrap: transition.js v3.2.0
* http://getbootstrap.com/javascript/#transitions
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
@@ -7,59 +7,53 @@
* ======================================================================== */
-+function () { 'use strict';
++function ($) {
+ 'use strict';
- (function (o_o) {
- typeof define == 'function' && define.amd ? define(['jquery'], o_o) :
- typeof exports == 'object' ? o_o(require('jquery')) : o_o(jQuery)
- })(function ($) {
+ // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
+ // ============================================================
- // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
- // ============================================================
+ function transitionEnd() {
+ var el = document.createElement('bootstrap')
- function transitionEnd() {
- var el = document.createElement('bootstrap')
-
- var transEndEventNames = {
- WebkitTransition : 'webkitTransitionEnd',
- MozTransition : 'transitionend',
- OTransition : 'oTransitionEnd otransitionend',
- transition : 'transitionend'
- }
-
- for (var name in transEndEventNames) {
- if (el.style[name] !== undefined) {
- return { end: transEndEventNames[name] }
- }
- }
-
- return false // explicit for ie8 ( ._.)
+ var transEndEventNames = {
+ WebkitTransition : 'webkitTransitionEnd',
+ MozTransition : 'transitionend',
+ OTransition : 'oTransitionEnd otransitionend',
+ transition : 'transitionend'
}
- // http://blog.alexmaccaw.com/css-transitions
- $.fn.emulateTransitionEnd = function (duration) {
- var called = false
- var $el = this
- $(this).one('bsTransitionEnd', function () { called = true })
- var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
- setTimeout(callback, duration)
- return this
+ for (var name in transEndEventNames) {
+ if (el.style[name] !== undefined) {
+ return { end: transEndEventNames[name] }
+ }
}
- $(function () {
- $.support.transition = transitionEnd()
-
- if (!$.support.transition) return
-
- $.event.special.bsTransitionEnd = {
- bindType: $.support.transition.end,
- delegateType: $.support.transition.end,
- handle: function (e) {
- if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
- }
+ return false // explicit for ie8 ( ._.)
+ }
+
+ // http://blog.alexmaccaw.com/css-transitions
+ $.fn.emulateTransitionEnd = function (duration) {
+ var called = false
+ var $el = this
+ $(this).one('bsTransitionEnd', function () { called = true })
+ var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
+ setTimeout(callback, duration)
+ return this
+ }
+
+ $(function () {
+ $.support.transition = transitionEnd()
+
+ if (!$.support.transition) return
+
+ $.event.special.bsTransitionEnd = {
+ bindType: $.support.transition.end,
+ delegateType: $.support.transition.end,
+ handle: function (e) {
+ if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
}
- })
-
+ }
})
-}();
+}(jQuery);