From 92245e8bc70f8d2e48036b7ba088551d07db29ca Mon Sep 17 00:00:00 2001 From: fat Date: Thu, 16 May 2013 12:50:06 -0700 Subject: [PATCH] change dropdown strategy to use an overlay - fixes mobile click anywhere + allows for firefox middle click --- docs/assets/css/bootstrap.css | 9 + docs/assets/js/bootstrap.js | 313 ++++++++++++++------------------ docs/assets/js/bootstrap.min.js | 2 +- docs/assets/js/collapse.js | 174 ++++++++---------- docs/assets/js/dropdown.js | 139 ++++++-------- docs/javascript.html | 6 +- js/dropdown.js | 139 ++++++-------- js/tests/unit/dropdown.js | 6 +- less/dropdowns.less | 12 ++ 9 files changed, 362 insertions(+), 438 deletions(-) diff --git a/docs/assets/css/bootstrap.css b/docs/assets/css/bootstrap.css index 209aed4967..b9940b55e4 100644 --- a/docs/assets/css/bootstrap.css +++ b/docs/assets/css/bootstrap.css @@ -2799,6 +2799,15 @@ input[type="button"].btn-block { outline: 0; } +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; +} + .pull-right > .dropdown-menu { right: 0; left: auto; diff --git a/docs/assets/js/bootstrap.js b/docs/assets/js/bootstrap.js index 62607d5884..77ed438b8e 100644 --- a/docs/assets/js/bootstrap.js +++ b/docs/assets/js/bootstrap.js @@ -471,132 +471,117 @@ * ============================================================ */ -!function ($) { +!function ($) { "use strict"; - "use strict"; // jshint ;_; - - - /* COLLAPSE PUBLIC CLASS DEFINITION - * ================================ */ + // COLLAPSE PUBLIC CLASS DEFINITION + // ================================ var Collapse = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, $.fn.collapse.defaults, options) + this.$element = $(element) + this.options = $.extend({}, Collapse.DEFAULTS, options) + this.transitioning = null - if (this.options.parent) { - this.$parent = $(this.options.parent) - } - - this.options.toggle && this.toggle() + if (this.options.parent) this.$parent = $(this.options.parent) + if (this.options.toggle) this.toggle() } - Collapse.prototype = { + Collapse.DEFAULTS = { + toggle: true + } - constructor: Collapse + Collapse.prototype.dimension = function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } - , dimension: function () { - var hasWidth = this.$element.hasClass('width') - return hasWidth ? 'width' : 'height' + Collapse.prototype.show = function () { + if (this.transitioning || this.$element.hasClass('in')) return + + var dimension = this.dimension() + var scroll = $.camelCase(['scroll', dimension].join('-')) + var actives = this.$parent && this.$parent.find('> .accordion-group > .in') + + if (actives && actives.length) { + var hasData = actives.data('collapse') + if (hasData && hasData.transitioning) return + actives.collapse('hide') + hasData || actives.data('collapse', null) } - , show: function () { - var dimension - , scroll - , actives - , hasData + this.$element[dimension](0) + this.transition('addClass', $.Event('show'), 'shown') - if (this.transitioning || this.$element.hasClass('in')) return + if ($.support.transition) this.$element[dimension](this.$element[0][scroll]) + } - dimension = this.dimension() - scroll = $.camelCase(['scroll', dimension].join('-')) - actives = this.$parent && this.$parent.find('> .accordion-group > .in') + Collapse.prototype.hide = function () { + if (this.transitioning || !this.$element.hasClass('in')) return + var dimension = this.dimension() + this.reset(this.$element[dimension]()) + this.transition('removeClass', $.Event('hide'), 'hidden') + this.$element[dimension](0) + } - if (actives && actives.length) { - hasData = actives.data('collapse') - if (hasData && hasData.transitioning) return - actives.collapse('hide') - hasData || actives.data('collapse', null) - } + Collapse.prototype.reset = function (size) { + var dimension = this.dimension() - this.$element[dimension](0) - this.transition('addClass', $.Event('show'), 'shown') - $.support.transition && this.$element[dimension](this.$element[0][scroll]) + this.$element + .removeClass('collapse') + [dimension](size || 'auto') + [0].offsetWidth + + this.$element[size !== null ? 'addClass' : 'removeClass']('collapse') + + return this + } + + Collapse.prototype.transition = function (method, startEvent, completeEvent) { + var that = this + var complete = function () { + if (startEvent.type == 'show') that.reset() + that.transitioning = 0 + that.$element.trigger(completeEvent) } - , hide: function () { - var dimension - if (this.transitioning || !this.$element.hasClass('in')) return - dimension = this.dimension() - this.reset(this.$element[dimension]()) - this.transition('removeClass', $.Event('hide'), 'hidden') - this.$element[dimension](0) - } + this.$element.trigger(startEvent) - , reset: function (size) { - var dimension = this.dimension() + if (startEvent.isDefaultPrevented()) return - this.$element - .removeClass('collapse') - [dimension](size || 'auto') - [0].offsetWidth + this.transitioning = 1 - this.$element[size !== null ? 'addClass' : 'removeClass']('collapse') + this.$element[method]('in') - return this - } - - , transition: function (method, startEvent, completeEvent) { - var that = this - , complete = function () { - if (startEvent.type == 'show') that.reset() - that.transitioning = 0 - that.$element.trigger(completeEvent) - } - - this.$element.trigger(startEvent) - - if (startEvent.isDefaultPrevented()) return - - this.transitioning = 1 - - this.$element[method]('in') - - $.support.transition && this.$element.hasClass('collapse') ? - this.$element.one($.support.transition.end, complete) : - complete() - } - - , toggle: function () { - this[this.$element.hasClass('in') ? 'hide' : 'show']() - } + $.support.transition && this.$element.hasClass('collapse') ? + this.$element.one($.support.transition.end, complete) : + complete() + } + Collapse.prototype.toggle = function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() } - /* COLLAPSE PLUGIN DEFINITION - * ========================== */ + // COLLAPSE PLUGIN DEFINITION + // ========================== var old = $.fn.collapse $.fn.collapse = function (option) { return this.each(function () { - var $this = $(this) - , data = $this.data('collapse') - , options = $.extend({}, $.fn.collapse.defaults, $this.data(), typeof option == 'object' && option) + var $this = $(this) + var data = $this.data('collapse') + var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) + if (!data) $this.data('collapse', (data = new Collapse(this, options))) if (typeof option == 'string') data[option]() }) } - $.fn.collapse.defaults = { - toggle: true - } - $.fn.collapse.Constructor = Collapse - /* COLLAPSE NO CONFLICT - * ==================== */ + // COLLAPSE NO CONFLICT + // ==================== $.fn.collapse.noConflict = function () { $.fn.collapse = old @@ -604,15 +589,16 @@ } - /* COLLAPSE DATA-API - * ================= */ + // COLLAPSE DATA-API + // ================= $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) { - var $this = $(this), href - , target = $this.attr('data-target') + var $this = $(this), href + var target = $this.attr('data-target') || e.preventDefault() || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 - , option = $(target).data('collapse') ? 'toggle' : $this.data() + var option = $(target).data('collapse') ? 'toggle' : $this.data() + $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed') $(target).collapse(option) }) @@ -638,123 +624,101 @@ * ============================================================ */ -!function ($) { - - "use strict"; // jshint ;_; +!function ($) { "use strict"; - /* DROPDOWN CLASS DEFINITION - * ========================= */ + // DROPDOWN CLASS DEFINITION + // ========================= - var toggle = '[data-toggle=dropdown]' - , Dropdown = function (element) { - var $el = $(element).on('click.dropdown.data-api', this.toggle) - $('html').on('click.dropdown.data-api', function () { - $el.parent().removeClass('open') - }) - } + var backdrop = '.dropdown-backdrop' + var toggle = '[data-toggle=dropdown]' + var Dropdown = function (element) { + var $el = $(element).on('click.dropdown.data-api', this.toggle) + $('html').on('click.dropdown.data-api', function () { + $el.parent().removeClass('open') + }) + } - Dropdown.prototype = { + Dropdown.prototype.toggle = function (e) { + var $this = $(this) - constructor: Dropdown + if ($this.is('.disabled, :disabled')) return - , toggle: function (e) { - var $this = $(this) - , $parent - , isActive + var $parent = getParent($this) + var isActive = $parent.hasClass('open') - if ($this.is('.disabled, :disabled')) return + clearMenus() - $parent = getParent($this) - - isActive = $parent.hasClass('open') - - clearMenus() - - if (!isActive) { - $parent.toggleClass('open') - } - - $this.focus() - - return false + if (!isActive) { + $('