1/** 2 * $.inArray: friends with IE8. Use Array.prototype.indexOf in future. 3 * $.proxy: friends with IE8. Use Function.prototype.bind in future. 4 */ 5 6'use strict'; 7 8(function(factory) { 9 if (typeof define == 'function' && define.amd) { 10 // AMD. Register as an anonymous module 11 define(['jquery'], factory); 12 } 13 else if (typeof exports == 'object') { 14 // Node/CommonJS 15 module.exports = factory(require('jquery')); 16 } 17 else { 18 // Browser globals 19 factory(jQuery); 20 } 21})(function($) { 22 function Item(element) { 23 this.$element = $(element); 24 this.$menu = this.$element.closest('.dropdown-menu'); 25 this.$main = this.$menu.parent(); 26 this.$items = this.$menu.children('.dropdown-submenu'); 27 28 this.init(); 29 } 30 31 Item.prototype = { 32 init: function() { 33 this.$element.on('keydown', $.proxy(this, 'keydown')); 34 }, 35 close: function() { 36 this.$main.removeClass('open'); 37 this.$items.trigger('hide.bs.submenu'); 38 }, 39 keydown: function(event) { 40 // 27: Esc 41 42 if (event.keyCode == 27) { 43 event.stopPropagation(); 44 45 this.close(); 46 this.$main.children('a, button').trigger('focus'); 47 } 48 } 49 }; 50 51 function SubmenuItem(element) { 52 this.$element = $(element); 53 this.$main = this.$element.parent(); 54 this.$menu = this.$main.children('.dropdown-menu'); 55 this.$subs = this.$main.siblings('.dropdown-submenu'); 56 this.$items = this.$menu.children('.dropdown-submenu'); 57 58 this.init(); 59 } 60 61 $.extend(SubmenuItem.prototype, Item.prototype, { 62 init: function() { 63 this.$element.on({ 64 click: $.proxy(this, 'click'), 65 keydown: $.proxy(this, 'keydown') 66 }); 67 68 this.$main.on('hide.bs.submenu', $.proxy(this, 'hide')); 69 }, 70 click: function(event) { 71 // Fix a[href="#"]. For community 72 event.preventDefault(); 73 74 event.stopPropagation(); 75 76 this.toggle(); 77 }, 78 hide: function(event) { 79 // Stop event bubbling 80 event.stopPropagation(); 81 82 this.close(); 83 }, 84 open: function() { 85 this.$main.addClass('open'); 86 this.$subs.trigger('hide.bs.submenu'); 87 }, 88 toggle: function() { 89 if (this.$main.hasClass('open')) { 90 this.close(); 91 } 92 else { 93 this.open(); 94 } 95 }, 96 keydown: function(event) { 97 // 13: Return, 32: Spacebar 98 99 if (event.keyCode == 32) { 100 // Off vertical scrolling 101 event.preventDefault(); 102 } 103 104 if ($.inArray(event.keyCode, [13, 32]) != -1) { 105 this.toggle(); 106 } 107 } 108 }); 109 110 function Submenupicker(element) { 111 this.$element = $(element); 112 this.$main = this.$element.parent(); 113 this.$menu = this.$main.children('.dropdown-menu'); 114 this.$items = this.$menu.children('.dropdown-submenu'); 115 116 this.init(); 117 } 118 119 Submenupicker.prototype = { 120 init: function() { 121 this.$menu.off('keydown.bs.dropdown.data-api'); 122 this.$menu.on('keydown', $.proxy(this, 'itemKeydown')); 123 124 this.$menu.find('li > a').each(function() { 125 new Item(this); 126 }); 127 128 this.$menu.find('.dropdown-submenu > a').each(function() { 129 new SubmenuItem(this); 130 }); 131 132 this.$main.on('hidden.bs.dropdown', $.proxy(this, 'hidden')); 133 }, 134 hidden: function() { 135 this.$items.trigger('hide.bs.submenu'); 136 }, 137 itemKeydown: function(event) { 138 // 38: Arrow up, 40: Arrow down 139 140 if ($.inArray(event.keyCode, [38, 40]) != -1) { 141 // Off vertical scrolling 142 event.preventDefault(); 143 144 event.stopPropagation(); 145 146 var $items = this.$menu.find('li:not(.disabled):visible > a'); 147 var index = $items.index(event.target); 148 149 if (event.keyCode == 38 && index !== 0) { 150 index--; 151 } 152 else if (event.keyCode == 40 && index !== $items.length - 1) { 153 index++; 154 } 155 else { 156 return; 157 } 158 159 $items.eq(index).trigger('focus'); 160 } 161 } 162 }; 163 164 var old = $.fn.submenupicker; 165 166 // For AMD/Node/CommonJS used elements (optional) 167 // http://learn.jquery.com/jquery-ui/environments/amd/ 168 $.fn.submenupicker = function(elements) { 169 var $elements = this instanceof $ ? this : $(elements); 170 171 return $elements.each(function() { 172 var data = $.data(this, 'bs.submenu'); 173 174 if (!data) { 175 data = new Submenupicker(this); 176 177 $.data(this, 'bs.submenu', data); 178 } 179 }); 180 }; 181 182 $.fn.submenupicker.Constructor = Submenupicker; 183 $.fn.submenupicker.noConflict = function() { 184 $.fn.submenupicker = old; 185 return this; 186 }; 187 188 return $.fn.submenupicker; 189});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.