From 527fb87dadd1e677f132ca3db0b02825d5bd57e5 Mon Sep 17 00:00:00 2001 From: Jacob Thornton Date: Sat, 17 Mar 2012 21:29:56 -0700 Subject: add /head --- js/tests/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js') diff --git a/js/tests/index.html b/js/tests/index.html index 8c710de36..2d59ab032 100644 --- a/js/tests/index.html +++ b/js/tests/index.html @@ -36,7 +36,7 @@ - +

Bootstrap Plugin Test Suite

-- cgit v1.2.3 From 5a2c7eb50abae8d07cebb6b0e984f7e63843cf75 Mon Sep 17 00:00:00 2001 From: Jacob Thornton Date: Mon, 19 Mar 2012 15:18:00 -0700 Subject: select last item in scrollspy if you've reached the bottom of the document or element --- js/bootstrap-scrollspy.js | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'js') diff --git a/js/bootstrap-scrollspy.js b/js/bootstrap-scrollspy.js index ea29f2f86..47b485785 100644 --- a/js/bootstrap-scrollspy.js +++ b/js/bootstrap-scrollspy.js @@ -57,11 +57,18 @@ , process: function () { var scrollTop = this.$scrollElement.scrollTop() + this.options.offset + , scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight + , maxScroll = scrollHeight - this.$scrollElement.height() , offsets = this.offsets , targets = this.targets , activeTarget = this.activeTarget , i + if (scrollTop >= maxScroll) { + return activeTarget != (i = targets.last()[0]) + && this.activate ( i ); + } + for (i = offsets.length; i--;) { activeTarget != targets[i] && scrollTop >= offsets[i] -- cgit v1.2.3 From bf59220b87a3b5960381f500dbc6a310a8aef60b Mon Sep 17 00:00:00 2001 From: Jacob Thornton Date: Mon, 19 Mar 2012 15:19:01 -0700 Subject: ;) --- js/bootstrap-scrollspy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js') diff --git a/js/bootstrap-scrollspy.js b/js/bootstrap-scrollspy.js index 47b485785..b7ff907f7 100644 --- a/js/bootstrap-scrollspy.js +++ b/js/bootstrap-scrollspy.js @@ -66,7 +66,7 @@ if (scrollTop >= maxScroll) { return activeTarget != (i = targets.last()[0]) - && this.activate ( i ); + && this.activate ( i ) } for (i = offsets.length; i--;) { -- cgit v1.2.3 From 83a7a698939b5b4cba3c04a86befc12b9005df3d Mon Sep 17 00:00:00 2001 From: Jacob Thornton Date: Mon, 19 Mar 2012 15:33:28 -0700 Subject: typeahead should escape regexp special chars --- js/bootstrap-typeahead.js | 3 ++- js/tests/unit/bootstrap-typeahead.js | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'js') diff --git a/js/bootstrap-typeahead.js b/js/bootstrap-typeahead.js index dc2f88221..804e60dc4 100644 --- a/js/bootstrap-typeahead.js +++ b/js/bootstrap-typeahead.js @@ -109,7 +109,8 @@ } , highlighter: function (item) { - return item.replace(new RegExp('(' + this.query + ')', 'ig'), function ($1, match) { + var query = this.query.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') + return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) { return '' + match + '' }) } diff --git a/js/tests/unit/bootstrap-typeahead.js b/js/tests/unit/bootstrap-typeahead.js index 96ea7c45f..25d313c85 100644 --- a/js/tests/unit/bootstrap-typeahead.js +++ b/js/tests/unit/bootstrap-typeahead.js @@ -52,6 +52,22 @@ $(function () { typeahead.$menu.remove() }) + test("should not explode when regex chars are entered", function () { + var $input = $('').typeahead({ + source: ['aa', 'ab', 'ac', 'mdo*', 'fat+'] + }) + , typeahead = $input.data('typeahead') + + $input.val('+') + typeahead.lookup() + + ok(typeahead.$menu.is(":visible"), 'typeahead is visible') + equals(typeahead.$menu.find('li').length, 1, 'has 1 item in menu') + equals(typeahead.$menu.find('.active').length, 1, 'one item is active') + + typeahead.$menu.remove() + }) + test("should hide menu when query entered", function () { stop() var $input = $('').typeahead({ -- cgit v1.2.3 From 67f199678c6f764f2812260f42b553b22ec740f8 Mon Sep 17 00:00:00 2001 From: Jacob Thornton Date: Mon, 19 Mar 2012 15:48:57 -0700 Subject: if interval is false, do not autocycle the carousel --- js/bootstrap-carousel.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'js') diff --git a/js/bootstrap-carousel.js b/js/bootstrap-carousel.js index 8c0723d28..287519900 100644 --- a/js/bootstrap-carousel.js +++ b/js/bootstrap-carousel.js @@ -27,7 +27,7 @@ var Carousel = function (element, options) { this.$element = $(element) - this.options = $.extend({}, $.fn.carousel.defaults, options) + this.options = options this.options.slide && this.slide(this.options.slide) this.options.pause == 'hover' && this.$element .on('mouseenter', $.proxy(this.pause, this)) @@ -37,7 +37,8 @@ Carousel.prototype = { cycle: function () { - this.interval = setInterval($.proxy(this.next, this), this.options.interval) + this.options.interval + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) return this } @@ -129,11 +130,11 @@ return this.each(function () { var $this = $(this) , data = $this.data('carousel') - , options = typeof option == 'object' && option + , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option) if (!data) $this.data('carousel', (data = new Carousel(this, options))) if (typeof option == 'number') data.to(option) else if (typeof option == 'string' || (option = options.slide)) data[option]() - else data.cycle() + else if (options.interval) data.cycle() }) } -- cgit v1.2.3 From 05e0d5f3d931e84f3bc86a5c1153e710237cb53a Mon Sep 17 00:00:00 2001 From: Jacob Thornton Date: Mon, 19 Mar 2012 16:09:08 -0700 Subject: fire active event on active --- js/bootstrap-scrollspy.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'js') diff --git a/js/bootstrap-scrollspy.js b/js/bootstrap-scrollspy.js index b7ff907f7..dea6e95f0 100644 --- a/js/bootstrap-scrollspy.js +++ b/js/bootstrap-scrollspy.js @@ -92,8 +92,10 @@ .addClass('active') if ( active.parent('.dropdown-menu') ) { - active.closest('li.dropdown').addClass('active') + active = active.closest('li.dropdown').addClass('active') } + + active.trigger('active') } } -- cgit v1.2.3 From 384a082e8d220115d0eb94b0c57d837b625ad2ab Mon Sep 17 00:00:00 2001 From: Jacob Thornton Date: Mon, 19 Mar 2012 20:24:46 -0700 Subject: active - onActivate --- js/bootstrap-scrollspy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js') diff --git a/js/bootstrap-scrollspy.js b/js/bootstrap-scrollspy.js index dea6e95f0..e0c74539e 100644 --- a/js/bootstrap-scrollspy.js +++ b/js/bootstrap-scrollspy.js @@ -95,7 +95,7 @@ active = active.closest('li.dropdown').addClass('active') } - active.trigger('active') + active.trigger('activate') } } -- cgit v1.2.3 From 630ff4ff7dca4d51474b8b4168e48e60fc858e0c Mon Sep 17 00:00:00 2001 From: Jacob Thornton Date: Mon, 19 Mar 2012 20:51:20 -0700 Subject: fix collapse bug in ie7+ for initial collapse in --- js/bootstrap-collapse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js') diff --git a/js/bootstrap-collapse.js b/js/bootstrap-collapse.js index 9a364468b..228d2a182 100644 --- a/js/bootstrap-collapse.js +++ b/js/bootstrap-collapse.js @@ -74,7 +74,7 @@ [dimension](size || 'auto') [0].offsetWidth - this.$element[size ? 'addClass' : 'removeClass']('collapse') + this.$element[size != null ? 'addClass' : 'removeClass']('collapse') return this } -- cgit v1.2.3 From bce33bbb091e66a58418395188ea50be151f3f8e Mon Sep 17 00:00:00 2001 From: Jacob Thornton Date: Mon, 19 Mar 2012 21:10:55 -0700 Subject: if parent in collapse, only grab children --- js/bootstrap-collapse.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'js') diff --git a/js/bootstrap-collapse.js b/js/bootstrap-collapse.js index 228d2a182..2dbf7a761 100644 --- a/js/bootstrap-collapse.js +++ b/js/bootstrap-collapse.js @@ -44,7 +44,7 @@ , show: function () { var dimension = this.dimension() , scroll = $.camelCase(['scroll', dimension].join('-')) - , actives = this.$parent && this.$parent.find('.in') + , actives = this.$parent && this.$parent.find('> .accordion-group > .in') , hasData if (actives && actives.length) { @@ -56,7 +56,6 @@ this.$element[dimension](0) this.transition('addClass', 'show', 'shown') this.$element[dimension](this.$element[0][scroll]) - } , hide: function () { -- cgit v1.2.3 From 63bd7cb478500463ac7339667d89792f7108f3c0 Mon Sep 17 00:00:00 2001 From: Jacob Thornton Date: Mon, 19 Mar 2012 21:39:39 -0700 Subject: fix slide logic for ie+ in carousel --- js/bootstrap-carousel.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'js') diff --git a/js/bootstrap-carousel.js b/js/bootstrap-carousel.js index 287519900..7db5bea33 100644 --- a/js/bootstrap-carousel.js +++ b/js/bootstrap-carousel.js @@ -95,13 +95,7 @@ if ($next.hasClass('active')) return - if (!$.support.transition && this.$element.hasClass('slide')) { - this.$element.trigger('slide') - $active.removeClass('active') - $next.addClass('active') - this.sliding = false - this.$element.trigger('slid') - } else { + if ($.support.transition && this.$element.hasClass('slide')) { $next.addClass(type) $next[0].offsetWidth // force reflow $active.addClass(direction) @@ -113,6 +107,12 @@ that.sliding = false setTimeout(function () { that.$element.trigger('slid') }, 0) }) + } else { + this.$element.trigger('slide') + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger('slid') } isCycling && this.cycle() -- cgit v1.2.3 From 663e41d74f6369812da29a1dd66b0b1fcfd22827 Mon Sep 17 00:00:00 2001 From: Jacob Thornton Date: Mon, 19 Mar 2012 23:13:55 -0700 Subject: prevent dropdowns from closing when clicking inside form element inside dropdown --- js/bootstrap-dropdown.js | 4 +++- js/bootstrap-typeahead.js | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'js') diff --git a/js/bootstrap-dropdown.js b/js/bootstrap-dropdown.js index 54b61c5e9..f26b83f41 100644 --- a/js/bootstrap-dropdown.js +++ b/js/bootstrap-dropdown.js @@ -86,7 +86,9 @@ $(function () { $('html').on('click.dropdown.data-api', clearMenus) - $('body').on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle) + $('body') + .on('click.dropdown', '.dropdown form', function (e) { e.stopPropagation() }) + .on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle) }) }( window.jQuery ); \ No newline at end of file diff --git a/js/bootstrap-typeahead.js b/js/bootstrap-typeahead.js index 804e60dc4..f4d26186c 100644 --- a/js/bootstrap-typeahead.js +++ b/js/bootstrap-typeahead.js @@ -39,8 +39,9 @@ , select: function () { var val = this.$menu.find('.active').attr('data-value') - this.$element.val(val) - this.$element.change(); + this.$element + .val(val) + .change() return this.hide() } -- cgit v1.2.3 From cb8dcfcebfbbd8f2ea26b786b44992f00d35ac30 Mon Sep 17 00:00:00 2001 From: Jacob Thornton Date: Tue, 20 Mar 2012 22:43:27 -0700 Subject: if transitioning collapse, don't start new transition --- js/bootstrap-collapse.js | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'js') diff --git a/js/bootstrap-collapse.js b/js/bootstrap-collapse.js index 2dbf7a761..16b91eb24 100644 --- a/js/bootstrap-collapse.js +++ b/js/bootstrap-collapse.js @@ -42,11 +42,18 @@ } , show: function () { - var dimension = this.dimension() - , scroll = $.camelCase(['scroll', dimension].join('-')) - , actives = this.$parent && this.$parent.find('> .accordion-group > .in') + var dimension + , scroll + , actives , hasData + if (this.transitioning) return + + dimension = this.dimension() + scroll = $.camelCase(['scroll', dimension].join('-')) + actives = this.$parent && this.$parent.find('> .accordion-group > .in') + hasData + if (actives && actives.length) { hasData = actives.data('collapse') actives.collapse('hide') @@ -59,7 +66,9 @@ } , hide: function () { - var dimension = this.dimension() + var dimension + if (this.transitioning) return + dimension = this.dimension() this.reset(this.$element[dimension]()) this.transition('removeClass', 'hide', 'hidden') this.$element[dimension](0) @@ -82,9 +91,12 @@ var that = this , complete = function () { if (startEvent == 'show') that.reset() + that.transitioning = 0 that.$element.trigger(completeEvent) } + this.transitioning = 1 + this.$element .trigger(startEvent) [method]('in') -- cgit v1.2.3 From d5fb653914617d63739142f6ecef00afd4d3c796 Mon Sep 17 00:00:00 2001 From: Jacob Thornton Date: Wed, 21 Mar 2012 21:35:02 -0700 Subject: top stripping leading and trailing whitespace + always use .html method --- js/bootstrap-popover.js | 6 ++---- js/bootstrap-tooltip.js | 2 -- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'js') diff --git a/js/bootstrap-popover.js b/js/bootstrap-popover.js index e1aa5ac39..6f389785c 100644 --- a/js/bootstrap-popover.js +++ b/js/bootstrap-popover.js @@ -38,8 +38,8 @@ , title = this.getTitle() , content = this.getContent() - $tip.find('.popover-title')[ $.type(title) == 'object' ? 'append' : 'html' ](title) - $tip.find('.popover-content > *')[ $.type(content) == 'object' ? 'append' : 'html' ](content) + $tip.find('.popover-title').html(title) + $tip.find('.popover-content > *').html(content) $tip.removeClass('fade top bottom left right in') } @@ -56,8 +56,6 @@ content = $e.attr('data-content') || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content) - content = content.toString().replace(/(^\s*|\s*$)/, "") - return content } diff --git a/js/bootstrap-tooltip.js b/js/bootstrap-tooltip.js index 49b5f7286..2b5f146b1 100644 --- a/js/bootstrap-tooltip.js +++ b/js/bootstrap-tooltip.js @@ -206,8 +206,6 @@ title = $e.attr('data-original-title') || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) - title = (title || '').toString().replace(/(^\s*|\s*$)/, "") - return title } -- cgit v1.2.3 From 94b24aaa473755093677cb4eb80faf3daee53357 Mon Sep 17 00:00:00 2001 From: Jacob Thornton Date: Wed, 21 Mar 2012 21:57:06 -0700 Subject: clear timeout to reset delays for tooltip/popover --- js/bootstrap-tooltip.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'js') diff --git a/js/bootstrap-tooltip.js b/js/bootstrap-tooltip.js index 2b5f146b1..7d58a6c8d 100644 --- a/js/bootstrap-tooltip.js +++ b/js/bootstrap-tooltip.js @@ -73,8 +73,9 @@ if (!self.options.delay || !self.options.delay.show) { self.show() } else { + clearTimeout(this.timeout) self.hoverState = 'in' - setTimeout(function() { + this.timeout = setTimeout(function() { if (self.hoverState == 'in') { self.show() } @@ -88,8 +89,9 @@ if (!self.options.delay || !self.options.delay.hide) { self.hide() } else { + clearTimeout(this.timeout) self.hoverState = 'out' - setTimeout(function() { + this.timeout = setTimeout(function() { if (self.hoverState == 'out') { self.hide() } -- cgit v1.2.3 From 706ee46b73b58059230b24589160da784778aad2 Mon Sep 17 00:00:00 2001 From: Jacob Thornton Date: Wed, 21 Mar 2012 23:45:58 -0700 Subject: sort scrollspy to prevent flicker for unordered nav --- js/bootstrap-scrollspy.js | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'js') diff --git a/js/bootstrap-scrollspy.js b/js/bootstrap-scrollspy.js index e0c74539e..5008b0fe9 100644 --- a/js/bootstrap-scrollspy.js +++ b/js/bootstrap-scrollspy.js @@ -43,16 +43,25 @@ constructor: ScrollSpy , refresh: function () { - this.targets = this.$body + var self = this + , $targets + + this.offsets = [] + this.targets = [] + + $targets = this.$body .find(this.selector) .map(function () { var href = $(this).attr('href') - return /^#\w/.test(href) && $(href).length ? href : null + return /^#\w/.test(href) + && $(href).length + && [[ $(href).position().top, href ]] + }) + .sort(function (a, b) { return a[0] - b[0] }) + .each(function () { + self.offsets.push(this[0]) + self.targets.push(this[1]) }) - - this.offsets = $.map(this.targets, function (id) { - return $(id).position().top - }) } , process: function () { -- cgit v1.2.3 From 20e085723b3f55fdc1db7f1687d535af7d127319 Mon Sep 17 00:00:00 2001 From: Jacob Thornton Date: Wed, 21 Mar 2012 23:51:32 -0700 Subject: cache $(href) lookup --- js/bootstrap-scrollspy.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'js') diff --git a/js/bootstrap-scrollspy.js b/js/bootstrap-scrollspy.js index 5008b0fe9..487e6818b 100644 --- a/js/bootstrap-scrollspy.js +++ b/js/bootstrap-scrollspy.js @@ -53,9 +53,10 @@ .find(this.selector) .map(function () { var href = $(this).attr('href') - return /^#\w/.test(href) - && $(href).length - && [[ $(href).position().top, href ]] + , $href = /^#\w/.test(href) && $(href) + return $href + && href.length + && [[ $href.position().top, href ]] }) .sort(function (a, b) { return a[0] - b[0] }) .each(function () { -- cgit v1.2.3 From b3bf223617754e658eb62ef0f068732e719a2c82 Mon Sep 17 00:00:00 2001 From: Jacob Thornton Date: Wed, 21 Mar 2012 23:59:27 -0700 Subject: filter out non matches in map --- js/bootstrap-scrollspy.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'js') diff --git a/js/bootstrap-scrollspy.js b/js/bootstrap-scrollspy.js index 487e6818b..bd3f10604 100644 --- a/js/bootstrap-scrollspy.js +++ b/js/bootstrap-scrollspy.js @@ -54,9 +54,9 @@ .map(function () { var href = $(this).attr('href') , $href = /^#\w/.test(href) && $(href) - return $href + return ( $href && href.length - && [[ $href.position().top, href ]] + && [[ $href.position().top, href ]] ) || null }) .sort(function (a, b) { return a[0] - b[0] }) .each(function () { -- cgit v1.2.3 From ef5ac02b698ffab3a42d21f20859b70df85543c0 Mon Sep 17 00:00:00 2001 From: Jacob Thornton Date: Sat, 24 Mar 2012 17:50:21 -0700 Subject: allow prevent default for show and hide event in modal --- js/bootstrap-modal.js | 19 ++++++++++++------- js/tests/unit/bootstrap-modal.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 7 deletions(-) (limited to 'js') diff --git a/js/bootstrap-modal.js b/js/bootstrap-modal.js index e92970627..3e0fb1481 100644 --- a/js/bootstrap-modal.js +++ b/js/bootstrap-modal.js @@ -41,13 +41,15 @@ , show: function () { var that = this + , e = $.Event('show') - if (this.isShown) return + this.$element.trigger(e) + + if (this.isShown || e.isDefaultPrevented()) return $('body').addClass('modal-open') this.isShown = true - this.$element.trigger('show') escape.call(this) backdrop.call(this, function () { @@ -74,18 +76,21 @@ , hide: function ( e ) { e && e.preventDefault() - if (!this.isShown) return - var that = this + + e = $.Event('hide') + + this.$element.trigger(e) + + if (!this.isShown || e.isDefaultPrevented()) return + this.isShown = false $('body').removeClass('modal-open') escape.call(this) - this.$element - .trigger('hide') - .removeClass('in') + this.$element.removeClass('in') $.support.transition && this.$element.hasClass('fade') ? hideWithTransition.call(this) : diff --git a/js/tests/unit/bootstrap-modal.js b/js/tests/unit/bootstrap-modal.js index 22f5781ea..0851f64a7 100644 --- a/js/tests/unit/bootstrap-modal.js +++ b/js/tests/unit/bootstrap-modal.js @@ -29,6 +29,35 @@ $(function () { .modal("show") }) + test("should fire show event", function () { + stop() + $.support.transition = false + $("") + .bind("show", function () { + ok(true, "show was called") + }) + .bind("shown", function () { + $(this).remove() + start() + }) + .modal("show") + }) + + test("should not fire shown when default prevented", function () { + stop() + $.support.transition = false + $("") + .bind("show", function (e) { + e.preventDefault() + ok(true, "show was called") + start() + }) + .bind("shown", function () { + ok(false, "shown was called") + }) + .modal("show") + }) + test("should hide modal when hide is called", function () { stop() $.support.transition = false -- cgit v1.2.3 From bccc2cb7191eb54a4d67563625a748d7ecd381d4 Mon Sep 17 00:00:00 2001 From: Jacob Thornton Date: Sat, 24 Mar 2012 18:20:09 -0700 Subject: add preventDefault support for all inital event types (show, close, hide, etc.) + fix small bug with scrollspy.last --- js/bootstrap-alert.js | 9 +++++---- js/bootstrap-carousel.js | 7 +++++-- js/bootstrap-collapse.js | 12 +++++++----- js/bootstrap-scrollspy.js | 4 ++-- js/bootstrap-tab.js | 10 +++++++--- js/tests/index.html | 2 ++ js/tests/unit/bootstrap-alert.js | 15 +++++++++++++++ js/tests/unit/bootstrap-carousel.js | 28 ++++++++++++++++++++++++++++ js/tests/unit/bootstrap-collapse.js | 15 +++++++++++++++ js/tests/unit/bootstrap-tab.js | 16 ++++++++++++++++ 10 files changed, 102 insertions(+), 16 deletions(-) create mode 100644 js/tests/unit/bootstrap-carousel.js (limited to 'js') diff --git a/js/bootstrap-alert.js b/js/bootstrap-alert.js index d17f44e15..7a1607da1 100644 --- a/js/bootstrap-alert.js +++ b/js/bootstrap-alert.js @@ -45,15 +45,16 @@ } $parent = $(selector) - $parent.trigger('close') e && e.preventDefault() $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent()) - $parent - .trigger('close') - .removeClass('in') + $parent.trigger(e = $.Event('close')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') function removeElement() { $parent diff --git a/js/bootstrap-carousel.js b/js/bootstrap-carousel.js index 7db5bea33..8ce7418d2 100644 --- a/js/bootstrap-carousel.js +++ b/js/bootstrap-carousel.js @@ -86,6 +86,7 @@ , direction = type == 'next' ? 'left' : 'right' , fallback = type == 'next' ? 'first' : 'last' , that = this + , e = $.Event('slide') this.sliding = true @@ -96,11 +97,12 @@ if ($next.hasClass('active')) return if ($.support.transition && this.$element.hasClass('slide')) { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return $next.addClass(type) $next[0].offsetWidth // force reflow $active.addClass(direction) $next.addClass(direction) - this.$element.trigger('slide') this.$element.one($.support.transition.end, function () { $next.removeClass([type, direction].join(' ')).addClass('active') $active.removeClass(['active', direction].join(' ')) @@ -108,7 +110,8 @@ setTimeout(function () { that.$element.trigger('slid') }, 0) }) } else { - this.$element.trigger('slide') + this.$element.trigger(e) + if (e.isDefaultPrevented()) return $active.removeClass('active') $next.addClass('active') this.sliding = false diff --git a/js/bootstrap-collapse.js b/js/bootstrap-collapse.js index 16b91eb24..478eea391 100644 --- a/js/bootstrap-collapse.js +++ b/js/bootstrap-collapse.js @@ -61,7 +61,7 @@ } this.$element[dimension](0) - this.transition('addClass', 'show', 'shown') + this.transition('addClass', $.Event('show'), 'shown') this.$element[dimension](this.$element[0][scroll]) } @@ -70,7 +70,7 @@ if (this.transitioning) return dimension = this.dimension() this.reset(this.$element[dimension]()) - this.transition('removeClass', 'hide', 'hidden') + this.transition('removeClass', $.Event('hide'), 'hidden') this.$element[dimension](0) } @@ -95,11 +95,13 @@ that.$element.trigger(completeEvent) } + this.$element.trigger(startEvent) + + if (startEvent.isDefaultPrevented()) return + this.transitioning = 1 - this.$element - .trigger(startEvent) - [method]('in') + this.$element[method]('in') $.support.transition && this.$element.hasClass('collapse') ? this.$element.one($.support.transition.end, complete) : diff --git a/js/bootstrap-scrollspy.js b/js/bootstrap-scrollspy.js index bd3f10604..c02e263b0 100644 --- a/js/bootstrap-scrollspy.js +++ b/js/bootstrap-scrollspy.js @@ -46,8 +46,8 @@ var self = this , $targets - this.offsets = [] - this.targets = [] + this.offsets = $([]) + this.targets = $([]) $targets = this.$body .find(this.selector) diff --git a/js/bootstrap-tab.js b/js/bootstrap-tab.js index b3938f671..974cc0aca 100644 --- a/js/bootstrap-tab.js +++ b/js/bootstrap-tab.js @@ -39,6 +39,7 @@ , selector = $this.attr('data-target') , previous , $target + , e if (!selector) { selector = $this.attr('href') @@ -49,11 +50,14 @@ previous = $ul.find('.active a').last()[0] - $this.trigger({ - type: 'show' - , relatedTarget: previous + e = $.Event('show', { + relatedTarget: previous }) + $this.trigger(e) + + if (e.isDefaultPrevented()) return + $target = $(selector) this.activate($this.parent('li'), $ul) diff --git a/js/tests/index.html b/js/tests/index.html index 2d59ab032..3e6cb9777 100644 --- a/js/tests/index.html +++ b/js/tests/index.html @@ -15,6 +15,7 @@ + @@ -28,6 +29,7 @@ + diff --git a/js/tests/unit/bootstrap-alert.js b/js/tests/unit/bootstrap-alert.js index e607f4340..7f24e0e6b 100644 --- a/js/tests/unit/bootstrap-alert.js +++ b/js/tests/unit/bootstrap-alert.js @@ -38,4 +38,19 @@ $(function () { ok(!$('#qunit-fixture').find('.alert-message').length, 'element removed from dom') }) + test("should not fire closed when close is prevented", function () { + $.support.transition = false + stop(); + $('
') + .bind('close', function (e) { + e.preventDefault(); + ok(true); + start(); + }) + .bind('closed', function () { + ok(false); + }) + .alert('close') + }) + }) \ No newline at end of file diff --git a/js/tests/unit/bootstrap-carousel.js b/js/tests/unit/bootstrap-carousel.js new file mode 100644 index 000000000..92c23e227 --- /dev/null +++ b/js/tests/unit/bootstrap-carousel.js @@ -0,0 +1,28 @@ +$(function () { + + module("bootstrap-carousel") + + test("should be defined on jquery object", function () { + ok($(document.body).carousel, 'carousel method is defined') + }) + + test("should return element", function () { + ok($(document.body).carousel()[0] == document.body, 'document.body returned') + }) + + test("should not fire sliden when slide is prevented", function () { + $.support.transition = false + stop(); + $('