PageSourceSearch

https://www.giuliopassamilolio.it/assets/js/bootstrap-typeahead.js

js giuliopassamilolio.it collected 2026-10-07 13:38:49 UTC 7,484 bytes, 300 lines download raw bytes

vendor: 7,234 bytes, lines 1-291
1/* =============================================================
2 * bootstrap-typeahead.js v2.1.1
3 * http://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 * http://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.$menu = $(this.options.menu).appendTo('body')
37    this.source = this.options.source
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.offset(), {
60        height: this.$element[0].offsetHeight
61      })
62
63      this.$menu.css({
64        top: pos.top + pos.height
65      , left: pos.left
66      })
67
68      this.$menu.show()
69      this.shown = true
70      return this
71    }
72
73  , hide: function () {
74      this.$menu.hide()
75      this.shown = false
76      return this
77    }
78
79  , lookup: function (event) {
80      var items
81
82      this.query = this.$element.val()
83
84      if (!this.query || this.query.length < this.options.minLength) {
85        return this.shown ? this.hide() : this
86      }
87
88      items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source
89
90      return items ? this.process(items) : this
91    }
92
93  , process: function (items) {
94      var that = this
95
96      items = $.grep(items, function (item) {
97        return that.matcher(item)
98      })
99
100      items = this.sorter(items)
101
102      if (!items.length) {
103        return this.shown ? this.hide() : this
104      }
105
106      return this.render(items.slice(0, this.options.items)).show()
107    }
108
109  , matcher: function (item) {
110      return ~item.toLowerCase().indexOf(this.query.toLowerCase())
111    }
112
113  , sorter: function (items) {
114      var beginswith = []
115        , caseSensitive = []
116        , caseInsensitive = []
117        , item
118
119      while (item = items.shift()) {
120        if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
121        else if (~item.indexOf(this.query)) caseSensitive.push(item)
122        else caseInsensitive.push(item)
123      }
124
125      return beginswith.concat(caseSensitive, caseInsensitive)
126    }
127
128  , highlighter: function (item) {
129      var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
130      return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
131        return '<strong>' + match + '</strong>'
132      })
133    }
134
135  , render: function (items) {
136      var that = this
137
138      items = $(items).map(function (i, item) {
139        i = $(that.options.item).attr('data-value', item)
140        i.find('a').html(that.highlighter(item))
141        return i[0]
142      })
143
144      items.first().addClass('active')
145      this.$menu.html(items)
146      return this
147    }
148
149  , next: function (event) {
150      var active = this.$menu.find('.active').removeClass('active')
151        , next = active.next()
152
153      if (!next.length) {
154        next = $(this.$menu.find('li')[0])
155      }
156
157      next.addClass('active')
158    }
159
160  , prev: function (event) {
161      var active = this.$menu.find('.active').removeClass('active')
162        , prev = active.prev()
163
164      if (!prev.length) {
165        prev = this.$menu.find('li').last()
166      }
167
168      prev.addClass('active')
169    }
170
171  , listen: function () {
172      this.$element
173        .on('blur',     $.proxy(this.blur, this))
174        .on('keypress', $.proxy(this.keypress, this))
175        .on('keyup',    $.proxy(this.keyup, this))
176
177      if ($.browser.chrome || $.browser.webkit || $.browser.msie) {
178        this.$element.on('keydown', $.proxy(this.keydown, this))
179      }
180
181      this.$menu
182        .on('click', $.proxy(this.click, this))
183        .on('mouseenter', 'li', $.proxy(this.mouseenter, this))
184    }
185
186  , move: function (e) {
187      if (!this.shown) return
188
189      switch(e.keyCode) {
190        case 9: // tab
191        case 13: // enter
192        case 27: // escape
193          e.preventDefault()
194          break
195
196        case 38: // up arrow
197          e.preventDefault()
198          this.prev()
199          break
200
201        case 40: // down arrow
202          e.preventDefault()
203          this.next()
204          break
205      }
206
207      e.stopPropagation()
208    }
209
210  , keydown: function (e) {
211      this.suppressKeyPressRepeat = !~$.inArray(e.keyCode, [40,38,9,13,27])
212      this.move(e)
213    }
214
215  , keypress: function (e) {
216      if (this.suppressKeyPressRepeat) return
217      this.move(e)
218    }
219
220  , keyup: function (e) {
221      switch(e.keyCode) {
222        case 40: // down arrow
223        case 38: // up arrow
224          break
225
226        case 9: // tab
227        case 13: // enter
228          if (!this.shown) return
229          this.select()
230          break
231
232        case 27: // escape
233          if (!this.shown) return
234          this.hide()
235          break
236
237        default:
238          this.lookup()
239      }
240
241      e.stopPropagation()
242      e.preventDefault()
243  }
244
245  , blur: function (e) {
246      var that = this
247      setTimeout(function () { that.hide() }, 150)
248    }
249
250  , click: function (e) {
251      e.stopPropagation()
252      e.preventDefault()
253      this.select()
254    }
255
256  , mouseenter: function (e) {
257      this.$menu.find('.active').removeClass('active')
258      $(e.currentTarget).addClass('active')
259    }
260
261  }
262
263
264  /* TYPEAHEAD PLUGIN DEFINITION
265   * =========================== */
266
267  $.fn.typeahead = function (option) {
268    return this.each(function () {
269      var $this = $(this)
270        , data = $this.data('typeahead')
271        , options = typeof option == 'object' && option
272      if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))
273      if (typeof option == 'string') data[option]()
274    })
275  }
276
277  $.fn.typeahead.defaults = {
278    source: []
279  , items: 8
280  , menu: '<ul class="typeahead dropdown-menu"></ul>'
281  , item: '<li><a href="#"></a></li>'
282  , minLength: 1
283  }
284
285  $.fn.typeahead.Constructor = Typeahead
286
287
288 /*   TYPEAHEAD DATA-API
289  * ================== */
290
291  $(function () {
292    $('body').on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
293      var $this = $(this)
294      if ($this.data('typeahead')) return
295      e.preventDefault()
296      $this.typeahead($this.data())
297    })
298  })
299
300}(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.