From ed3a65f08456571f5d9939d428379760d34741dc Mon Sep 17 00:00:00 2001 From: Heinrich Fenkart Date: Thu, 25 Sep 2014 23:04:11 +0200 Subject: [PATCH] Handle `collapsed` class on triggers even when manually invoked Fixes #13636. --- js/collapse.js | 65 ++++++++++++++++++++++++++--------- js/tests/unit/collapse.js | 72 +++++++++++++++++++++++++++------------ 2 files changed, 99 insertions(+), 38 deletions(-) diff --git a/js/collapse.js b/js/collapse.js index abbf25f2a6..5d0f932ffb 100644 --- a/js/collapse.js +++ b/js/collapse.js @@ -16,9 +16,15 @@ var Collapse = function (element, options) { this.$element = $(element) this.options = $.extend({}, Collapse.DEFAULTS, options) + this.$trigger = $(this.options.trigger).filter('[href="#' + element.id + '"], [data-target="#' + element.id + '"]') this.transitioning = null - if (this.options.parent) this.$parent = $(this.options.parent) + if (this.options.parent) { + this.$parent = this.getParent() + } else { + this.addAriaAndCollapsedClass(this.$element, this.$trigger) + } + if (this.options.toggle) this.toggle() } @@ -27,7 +33,8 @@ Collapse.TRANSITION_DURATION = 350 Collapse.DEFAULTS = { - toggle: true + toggle: true, + trigger: '[data-toggle="collapse"]' } Collapse.prototype.dimension = function () { @@ -62,6 +69,10 @@ .addClass('collapsing')[dimension](0) .attr('aria-expanded', true) + this.$trigger + .removeClass('collapsed') + .attr('aria-expanded', true) + this.transitioning = 1 var complete = function () { @@ -98,6 +109,10 @@ .removeClass('collapse in') .attr('aria-expanded', false) + this.$trigger + .addClass('collapsed') + .attr('aria-expanded', false) + this.transitioning = 1 var complete = function () { @@ -120,6 +135,33 @@ this[this.$element.hasClass('in') ? 'hide' : 'show']() } + Collapse.prototype.getParent = function () { + return $(this.options.parent) + .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') + .each($.proxy(function (i, element) { + var $element = $(element) + this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) + }, this)) + .end() + } + + Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { + var isOpen = $element.hasClass('in') + + $element.attr('aria-expanded', isOpen) + $trigger + .toggleClass('collapsed', !isOpen) + .attr('aria-expanded', isOpen) + } + + function getTargetFromTrigger($trigger) { + var href + var target = $trigger.attr('data-target') + || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 + + return $(target) + } + // COLLAPSE PLUGIN DEFINITION // ========================== @@ -155,22 +197,13 @@ // ================= $(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').attr('aria-expanded', false) - var isCollapsed = $target.hasClass('in') - $this.toggleClass('collapsed', isCollapsed).attr('aria-expanded', !isCollapsed) - } + if (!$this.attr('data-target')) e.preventDefault() + + var $target = getTargetFromTrigger($this) + var data = $target.data('bs.collapse') + var option = data ? 'toggle' : $.extend({}, $this.data(), { trigger: this }) Plugin.call($target, option) }) diff --git a/js/tests/unit/collapse.js b/js/tests/unit/collapse.js index c1d78575c6..30d00e4135 100644 --- a/js/tests/unit/collapse.js +++ b/js/tests/unit/collapse.js @@ -79,7 +79,7 @@ $(function () { $('
') .appendTo('#qunit-fixture') - .on('show.bs.collapse', function () { + .on('shown.bs.collapse', function () { ok(!$target.hasClass('collapsed')) start() }) @@ -94,7 +94,7 @@ $(function () { $('
') .appendTo('#qunit-fixture') - .on('hide.bs.collapse', function () { + .on('hidden.bs.collapse', function () { ok($target.hasClass('collapsed')) start() }) @@ -137,12 +137,12 @@ $(function () { test('should remove "collapsed" class from active accordion target', function () { stop() - var accordionHTML = '
' - + '
' - + '
' - + '
' + var accordionHTML = '
' + + '
' + + '
' + + '
' + '
' - var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.accordion-group') + var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.panel') var $target1 = $('').appendTo($groups.eq(0)) @@ -156,7 +156,7 @@ $(function () { $('
') .appendTo($groups.eq(2)) - .on('show.bs.collapse', function () { + .on('shown.bs.collapse', function () { 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"') @@ -170,12 +170,12 @@ $(function () { test('should allow dots in data-parent', function () { stop() - var accordionHTML = '
' - + '
' - + '
' - + '
' + var accordionHTML = '
' + + '
' + + '
' + + '
' + '
' - var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.accordion-group') + var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.panel') var $target1 = $('').appendTo($groups.eq(0)) @@ -189,7 +189,7 @@ $(function () { $('
') .appendTo($groups.eq(2)) - .on('show.bs.collapse', function () { + .on('shown.bs.collapse', function () { 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"') @@ -207,7 +207,7 @@ $(function () { $('
') .appendTo('#qunit-fixture') - .on('show.bs.collapse', function () { + .on('shown.bs.collapse', function () { equal($target.attr('aria-expanded'), 'true', 'aria-expanded on target is "true"') start() }) @@ -222,7 +222,7 @@ $(function () { $('
') .appendTo('#qunit-fixture') - .on('hide.bs.collapse', function () { + .on('hidden.bs.collapse', function () { equal($target.attr('aria-expanded'), 'false', 'aria-expanded on target is "false"') start() }) @@ -233,12 +233,12 @@ $(function () { test('should change aria-expanded from active accordion target to "false" and set the newly active one to "true"', function () { stop() - var accordionHTML = '