vendor: 8,018 bytes, lines 1-321
1/* ============================================================= 2 * bootstrap-typeahead.js v2.2.2 3 * https://twitter.github.com/bootstrap/javascript.html#typeahead 4 * ============================================================= 5 * Copyright 2012 Twitter, Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * https://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * ============================================================ */ 19 20 21!function($){ 22 23 "use strict"; // jshint ;_; 24 25 26 /* TYPEAHEAD PUBLIC CLASS DEFINITION 27 * ================================= */ 28 29 var Typeahead = function (element, options) { 30 this.$element = $(element) 31 this.options = $.extend({}, $.fn.typeahead.defaults, options) 32 this.matcher = this.options.matcher || this.matcher 33 this.sorter = this.options.sorter || this.sorter 34 this.highlighter = this.options.highlighter || this.highlighter 35 this.updater = this.options.updater || this.updater 36 this.source = this.options.source 37 this.$menu = $(this.options.menu) 38 this.shown = false 39 this.listen() 40 } 41 42 Typeahead.prototype = { 43 44 constructor: Typeahead 45 46 , select: function () { 47 var val = this.$menu.find('.active').attr('data-value') 48 this.$element 49 .val(this.updater(val)) 50 .change() 51 return this.hide() 52 } 53 54 , updater: function (item) { 55 return item 56 } 57 58 , show: function () { 59 var pos = $.extend({}, this.$element.position(), { 60 height: this.$element[0].offsetHeight 61 }) 62 63 this.$menu 64 .insertAfter(this.$element) 65 .css({ 66 top: pos.top + pos.height 67 , left: pos.left 68 }) 69 .show() 70 71 this.shown = true 72 return this 73 } 74 75 , hide: function () { 76 this.$menu.hide() 77 this.shown = false 78 return this 79 } 80 81 , lookup: function (event) { 82 var items 83 84 this.query = this.$element.val() 85 86 if (!this.query || this.query.length < this.options.minLength) { 87 return this.shown ? this.hide() : this 88 } 89 90 items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source 91 92 return items ? this.process(items) : this 93 } 94 95 , process: function (items) { 96 var that = this 97 98 items = $.grep(items, function (item) { 99 return that.matcher(item) 100 }) 101 102 items = this.sorter(items) 103 104 if (!items.length) { 105 return this.shown ? this.hide() : this 106 } 107 108 return this.render(items.slice(0, this.options.items)).show() 109 } 110 111 , matcher: function (item) { 112 return ~item.toLowerCase().indexOf(this.query.toLowerCase()) 113 } 114 115 , sorter: function (items) { 116 var beginswith = [] 117 , caseSensitive = [] 118 , caseInsensitive = [] 119 , item 120 121 while (item = items.shift()) { 122 if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item) 123 else if (~item.indexOf(this.query)) caseSensitive.push(item) 124 else caseInsensitive.push(item) 125 } 126 127 return beginswith.concat(caseSensitive, caseInsensitive) 128 } 129 130 , highlighter: function (item) { 131 var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&') 132 return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) { 133 return '<strong>' + match + '</strong>' 134 }) 135 } 136 137 , render: function (items) { 138 var that = this 139 140 items = $(items).map(function (i, item) { 141 i = $(that.options.item).attr('data-value', item) 142 i.find('a').html(that.highlighter(item)) 143 return i[0] 144 }) 145 146 items.first().addClass('active') 147 this.$menu.html(items) 148 return this 149 } 150 151 , next: function (event) { 152 var active = this.$menu.find('.active').removeClass('active') 153 , next = active.next() 154 155 if (!next.length) { 156 next = $(this.$menu.find('li')[0]) 157 } 158 159 next.addClass('active') 160 } 161 162 , prev: function (event) { 163 var active = this.$menu.find('.active').removeClass('active') 164 , prev = active.prev() 165 166 if (!prev.length) { 167 prev = this.$menu.find('li').last() 168 } 169 170 prev.addClass('active') 171 } 172 173 , listen: function () { 174 this.$element 175 .on('blur', $.proxy(this.blur, this)) 176 .on('keypress', $.proxy(this.keypress, this)) 177 .on('keyup', $.proxy(this.keyup, this)) 178 179 if (this.eventSupported('keydown')) { 180 this.$element.on('keydown', $.proxy(this.keydown, this)) 181 } 182 183 this.$menu 184 .on('click', $.proxy(this.click, this)) 185 .on('mouseenter', 'li', $.proxy(this.mouseenter, this)) 186 .on('mouseleave', 'li', $.proxy(this.mouseleave, this)) 187 } 188 189 , eventSupported: function(eventName) { 190 var isSupported = eventName in this.$element 191 if (!isSupported) { 192 this.$element.setAttribute(eventName, 'return;') 193 isSupported = typeof this.$element[eventName] === 'function' 194 } 195 return isSupported 196 } 197 198 , move: function (e) { 199 if (!this.shown) return 200 201 switch(e.keyCode) { 202 case 9: // tab 203 case 13: // enter 204 case 27: // escape 205 e.preventDefault() 206 break 207 208 case 38: // up arrow 209 e.preventDefault() 210 this.prev() 211 break 212 213 case 40: // down arrow 214 e.preventDefault() 215 this.next() 216 break 217 } 218 219 e.stopPropagation() 220 } 221 222 , keydown: function (e) { 223 this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27]) 224 this.move(e) 225 } 226 227 , keypress: function (e) { 228 if (this.suppressKeyPressRepeat) return 229 this.move(e) 230 } 231 232 , keyup: function (e) { 233 switch(e.keyCode) { 234 case 40: // down arrow 235 case 38: // up arrow 236 case 16: // shift 237 case 17: // ctrl 238 case 18: // alt 239 break 240 241 case 9: // tab 242 case 13: // enter 243 if (!this.shown) return 244 this.select() 245 break 246 247 case 27: // escape 248 if (!this.shown) return 249 this.hide() 250 break 251 252 default: 253 this.lookup() 254 } 255 256 e.stopPropagation() 257 e.preventDefault() 258 } 259 260 , blur: function (e) { 261 var that = this 262 setTimeout(function () { that.hide() }, 150) 263 } 264 265 , click: function (e) { 266 e.stopPropagation() 267 e.preventDefault() 268 this.select() 269 } 270 271 , mouseenter: function (e) { 272 this.$menu.find('.active').removeClass('active') 273 $(e.currentTarget).addClass('active') 274 } 275 276 , mouseleave: function (e) { 277 this.$menu.find('.active').removeClass('active') 278 $(e.currentTarget).addClass('active') 279 } 280 281 } 282 283 284 /* TYPEAHEAD PLUGIN DEFINITION 285 * =========================== */ 286 287 var old = $.fn.typeahead 288 289 $.fn.typeahead = function (option) { 290 return this.each(function () { 291 var $this = $(this) 292 , data = $this.data('typeahead') 293 , options = typeof option == 'object' && option 294 if (!data) $this.data('typeahead', (data = new Typeahead(this, options))) 295 if (typeof option == 'string') data[option]() 296 }) 297 } 298 299 $.fn.typeahead.defaults = { 300 source: [] 301 , items: 20 302 , menu: '<ul class="typeahead dropdown-menu" aria-labelledby="navbarDropdownMenuLink"></ul>' 303 , item: '<li><a class="dropdown-item" href="#"></a></li>' 304 , minLength: 1 305 } 306 307 $.fn.typeahead.Constructor = Typeahead 308 309 310 /* TYPEAHEAD NO CONFLICT 311 * =================== */ 312 313 $.fn.typeahead.noConflict = function () { 314 $.fn.typeahead = old 315 return this 316 } 317 318 319 /* TYPEAHEAD DATA-API 320 * ================== */ 321
322 $(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) { 323 var $this = $(this) 324 if ($this.data('typeahead')) return 325 e.preventDefault() 326 $this.typeahead($this.data()) 327 }) 328 329}(window.jQuery);
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.