]> git.openstreetmap.org Git - rails.git/blob - vendor/assets/bootstrap/bootstrap.dropdown.js
200e1c67b4ffbbc005e7f7319dab3bb2e77e3851
[rails.git] / vendor / assets / bootstrap / bootstrap.dropdown.js
1 /* ========================================================================
2  * Bootstrap: dropdown.js v3.3.2
3  * http://getbootstrap.com/javascript/#dropdowns
4  * ========================================================================
5  * Copyright 2011-2015 Twitter, Inc.
6  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
7  * ======================================================================== */
8
9
10 +function ($) {
11   'use strict';
12
13   // DROPDOWN CLASS DEFINITION
14   // =========================
15
16   var backdrop = '.dropdown-backdrop'
17   var toggle   = '[data-toggle="dropdown"]'
18   var Dropdown = function (element) {
19     $(element).on('click.bs.dropdown', this.toggle)
20   }
21
22   Dropdown.VERSION = '3.3.2'
23
24   Dropdown.prototype.toggle = function (e) {
25     var $this = $(this)
26
27     if ($this.is('.disabled, :disabled')) return
28
29     var $parent  = getParent($this)
30     var isActive = $parent.hasClass('open')
31
32     clearMenus()
33
34     if (!isActive) {
35       if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
36         // if mobile we use a backdrop because click events don't delegate
37         $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
38       }
39
40       var relatedTarget = { relatedTarget: this }
41       $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
42
43       if (e.isDefaultPrevented()) return
44
45       $this
46         .trigger('focus')
47         .attr('aria-expanded', 'true')
48
49       $parent
50         .toggleClass('open')
51         .trigger('shown.bs.dropdown', relatedTarget)
52     }
53
54     return false
55   }
56
57   Dropdown.prototype.keydown = function (e) {
58     if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
59
60     var $this = $(this)
61
62     e.preventDefault()
63     e.stopPropagation()
64
65     if ($this.is('.disabled, :disabled')) return
66
67     var $parent  = getParent($this)
68     var isActive = $parent.hasClass('open')
69
70     if ((!isActive && e.which != 27) || (isActive && e.which == 27)) {
71       if (e.which == 27) $parent.find(toggle).trigger('focus')
72       return $this.trigger('click')
73     }
74
75     var desc = ' li:not(.divider):visible a'
76     var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)
77
78     if (!$items.length) return
79
80     var index = $items.index(e.target)
81
82     if (e.which == 38 && index > 0)                 index--                        // up
83     if (e.which == 40 && index < $items.length - 1) index++                        // down
84     if (!~index)                                      index = 0
85
86     $items.eq(index).trigger('focus')
87   }
88
89   function clearMenus(e) {
90     if (e && e.which === 3) return
91     $(backdrop).remove()
92     $(toggle).each(function () {
93       var $this         = $(this)
94       var $parent       = getParent($this)
95       var relatedTarget = { relatedTarget: this }
96
97       if (!$parent.hasClass('open')) return
98
99       $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
100
101       if (e.isDefaultPrevented()) return
102
103       $this.attr('aria-expanded', 'false')
104       $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
105     })
106   }
107
108   function getParent($this) {
109     var selector = $this.attr('data-target')
110
111     if (!selector) {
112       selector = $this.attr('href')
113       selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
114     }
115
116     var $parent = selector && $(selector)
117
118     return $parent && $parent.length ? $parent : $this.parent()
119   }
120
121
122   // DROPDOWN PLUGIN DEFINITION
123   // ==========================
124
125   function Plugin(option) {
126     return this.each(function () {
127       var $this = $(this)
128       var data  = $this.data('bs.dropdown')
129
130       if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
131       if (typeof option == 'string') data[option].call($this)
132     })
133   }
134
135   var old = $.fn.dropdown
136
137   $.fn.dropdown             = Plugin
138   $.fn.dropdown.Constructor = Dropdown
139
140
141   // DROPDOWN NO CONFLICT
142   // ====================
143
144   $.fn.dropdown.noConflict = function () {
145     $.fn.dropdown = old
146     return this
147   }
148
149
150   // APPLY TO STANDARD DROPDOWN ELEMENTS
151   // ===================================
152
153   $(document)
154     .on('click.bs.dropdown.data-api', clearMenus)
155     .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
156     .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
157     .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
158     .on('keydown.bs.dropdown.data-api', '[role="menu"]', Dropdown.prototype.keydown)
159     .on('keydown.bs.dropdown.data-api', '[role="listbox"]', Dropdown.prototype.keydown)
160
161 }(jQuery);