twitter-bootstrap-rails 2.1.1 → 2.1.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of twitter-bootstrap-rails might be problematic. Click here for more details.

Files changed (71) hide show
  1. data/README.md +14 -3
  2. data/app/helpers/bootstrap_flash_helper.rb +12 -0
  3. data/lib/generators/bootstrap/layout/templates/layout.html.erb +1 -0
  4. data/lib/generators/bootstrap/layout/templates/layout.html.haml +1 -0
  5. data/lib/generators/bootstrap/layout/templates/layout.html.slim +1 -0
  6. data/lib/generators/bootstrap/partial/partial_generator.rb +20 -0
  7. data/lib/generators/bootstrap/partial/templates/_login.html.erb +29 -0
  8. data/lib/generators/bootstrap/partial/templates/_navbar.html.erb +13 -0
  9. data/lib/generators/bootstrap/themed/templates/index.html.erb +1 -1
  10. data/lib/generators/bootstrap/themed/templates/index.html.haml +1 -1
  11. data/lib/generators/bootstrap/themed/templates/index.html.slim +1 -1
  12. data/lib/generators/bootstrap/themed/templates/show.html.erb +1 -1
  13. data/lib/generators/bootstrap/themed/templates/show.html.haml +1 -1
  14. data/lib/generators/bootstrap/themed/templates/show.html.slim +1 -1
  15. data/lib/twitter/bootstrap/rails/version.rb +1 -1
  16. data/vendor/assets/javascripts/twitter/bootstrap.js +1 -0
  17. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-affix.js +104 -0
  18. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-alert.js +1 -1
  19. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-button.js +1 -1
  20. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-carousel.js +12 -5
  21. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-collapse.js +4 -3
  22. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-dropdown.js +66 -16
  23. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-modal.js +95 -74
  24. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-popover.js +9 -4
  25. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-scrollspy.js +9 -9
  26. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-tab.js +2 -2
  27. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-tooltip.js +15 -15
  28. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-transition.js +2 -3
  29. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-typeahead.js +51 -40
  30. data/vendor/toolkit/fontawesome.less +5 -5
  31. data/vendor/toolkit/twitter/bootstrap/accordion.less +3 -2
  32. data/vendor/toolkit/twitter/bootstrap/alerts.less +16 -9
  33. data/vendor/toolkit/twitter/bootstrap/bootstrap.less +1 -1
  34. data/vendor/toolkit/twitter/bootstrap/breadcrumbs.less +10 -10
  35. data/vendor/toolkit/twitter/bootstrap/button-groups.less +76 -23
  36. data/vendor/toolkit/twitter/bootstrap/buttons.less +85 -65
  37. data/vendor/toolkit/twitter/bootstrap/carousel.less +13 -3
  38. data/vendor/toolkit/twitter/bootstrap/close.less +4 -2
  39. data/vendor/toolkit/twitter/bootstrap/code.less +6 -5
  40. data/vendor/toolkit/twitter/bootstrap/component-animations.less +5 -2
  41. data/vendor/toolkit/twitter/bootstrap/dropdowns.less +81 -14
  42. data/vendor/toolkit/twitter/bootstrap/forms.less +100 -48
  43. data/vendor/toolkit/twitter/bootstrap/grid.less +17 -1
  44. data/vendor/toolkit/twitter/bootstrap/hero-unit.less +4 -2
  45. data/vendor/toolkit/twitter/bootstrap/labels-badges.less +19 -2
  46. data/vendor/toolkit/twitter/bootstrap/layouts.less +1 -2
  47. data/vendor/toolkit/twitter/bootstrap/mixins.less +98 -73
  48. data/vendor/toolkit/twitter/bootstrap/modals.less +9 -2
  49. data/vendor/toolkit/twitter/bootstrap/navbar.less +238 -127
  50. data/vendor/toolkit/twitter/bootstrap/navs.less +38 -17
  51. data/vendor/toolkit/twitter/bootstrap/pager.less +5 -4
  52. data/vendor/toolkit/twitter/bootstrap/pagination.less +16 -8
  53. data/vendor/toolkit/twitter/bootstrap/popovers.less +101 -33
  54. data/vendor/toolkit/twitter/bootstrap/progress-bars.less +18 -13
  55. data/vendor/toolkit/twitter/bootstrap/reset.less +6 -3
  56. data/vendor/toolkit/twitter/bootstrap/responsive-1200px-min.less +9 -7
  57. data/vendor/toolkit/twitter/bootstrap/responsive-767px-max.less +86 -68
  58. data/vendor/toolkit/twitter/bootstrap/responsive-768px-979px.less +7 -5
  59. data/vendor/toolkit/twitter/bootstrap/responsive-navbar.less +18 -5
  60. data/vendor/toolkit/twitter/bootstrap/responsive-utilities.less +17 -15
  61. data/vendor/toolkit/twitter/bootstrap/responsive.less +5 -5
  62. data/vendor/toolkit/twitter/bootstrap/scaffolding.less +26 -4
  63. data/vendor/toolkit/twitter/bootstrap/sprites.less +15 -19
  64. data/vendor/toolkit/twitter/bootstrap/tables.less +60 -11
  65. data/vendor/toolkit/twitter/bootstrap/thumbnails.less +9 -4
  66. data/vendor/toolkit/twitter/bootstrap/tooltip.less +47 -12
  67. data/vendor/toolkit/twitter/bootstrap/type.less +57 -92
  68. data/vendor/toolkit/twitter/bootstrap/utilities.less +9 -2
  69. data/vendor/toolkit/twitter/bootstrap/variables.less +100 -29
  70. data/vendor/toolkit/twitter/bootstrap/wells.less +7 -5
  71. metadata +16 -22
@@ -1,5 +1,5 @@
1
1
  /* =========================================================
2
- * bootstrap-modal.js v2.0.4
2
+ * bootstrap-modal.js v2.1.0
3
3
  * http://twitter.github.com/bootstrap/javascript.html#modals
4
4
  * =========================================================
5
5
  * Copyright 2012 Twitter, Inc.
@@ -26,10 +26,11 @@
26
26
  /* MODAL CLASS DEFINITION
27
27
  * ====================== */
28
28
 
29
- var Modal = function (content, options) {
29
+ var Modal = function (element, options) {
30
30
  this.options = options
31
- this.$element = $(content)
31
+ this.$element = $(element)
32
32
  .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
33
+ this.options.remote && this.$element.find('.modal-body').load(this.options.remote)
33
34
  }
34
35
 
35
36
  Modal.prototype = {
@@ -52,8 +53,9 @@
52
53
 
53
54
  this.isShown = true
54
55
 
55
- escape.call(this)
56
- backdrop.call(this, function () {
56
+ this.escape()
57
+
58
+ this.backdrop(function () {
57
59
  var transition = $.support.transition && that.$element.hasClass('fade')
58
60
 
59
61
  if (!that.$element.parent().length) {
@@ -67,7 +69,12 @@
67
69
  that.$element[0].offsetWidth // force reflow
68
70
  }
69
71
 
70
- that.$element.addClass('in')
72
+ that.$element
73
+ .addClass('in')
74
+ .attr('aria-hidden', false)
75
+ .focus()
76
+
77
+ that.enforceFocus()
71
78
 
72
79
  transition ?
73
80
  that.$element.one($.support.transition.end, function () { that.$element.trigger('shown') }) :
@@ -91,90 +98,98 @@
91
98
 
92
99
  $('body').removeClass('modal-open')
93
100
 
94
- escape.call(this)
101
+ this.escape()
102
+
103
+ $(document).off('focusin.modal')
95
104
 
96
- this.$element.removeClass('in')
105
+ this.$element
106
+ .removeClass('in')
107
+ .attr('aria-hidden', true)
97
108
 
98
109
  $.support.transition && this.$element.hasClass('fade') ?
99
- hideWithTransition.call(this) :
100
- hideModal.call(this)
110
+ this.hideWithTransition() :
111
+ this.hideModal()
101
112
  }
102
113
 
103
- }
104
-
105
-
106
- /* MODAL PRIVATE METHODS
107
- * ===================== */
108
-
109
- function hideWithTransition() {
110
- var that = this
111
- , timeout = setTimeout(function () {
112
- that.$element.off($.support.transition.end)
113
- hideModal.call(that)
114
- }, 500)
114
+ , enforceFocus: function () {
115
+ var that = this
116
+ $(document).on('focusin.modal', function (e) {
117
+ if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {
118
+ that.$element.focus()
119
+ }
120
+ })
121
+ }
115
122
 
116
- this.$element.one($.support.transition.end, function () {
117
- clearTimeout(timeout)
118
- hideModal.call(that)
119
- })
120
- }
123
+ , escape: function () {
124
+ var that = this
125
+ if (this.isShown && this.options.keyboard) {
126
+ this.$element.on('keyup.dismiss.modal', function ( e ) {
127
+ e.which == 27 && that.hide()
128
+ })
129
+ } else if (!this.isShown) {
130
+ this.$element.off('keyup.dismiss.modal')
131
+ }
132
+ }
121
133
 
122
- function hideModal(that) {
123
- this.$element
124
- .hide()
125
- .trigger('hidden')
134
+ , hideWithTransition: function () {
135
+ var that = this
136
+ , timeout = setTimeout(function () {
137
+ that.$element.off($.support.transition.end)
138
+ that.hideModal()
139
+ }, 500)
140
+
141
+ this.$element.one($.support.transition.end, function () {
142
+ clearTimeout(timeout)
143
+ that.hideModal()
144
+ })
145
+ }
126
146
 
127
- backdrop.call(this)
128
- }
147
+ , hideModal: function (that) {
148
+ this.$element
149
+ .hide()
150
+ .trigger('hidden')
129
151
 
130
- function backdrop(callback) {
131
- var that = this
132
- , animate = this.$element.hasClass('fade') ? 'fade' : ''
152
+ this.backdrop()
153
+ }
133
154
 
134
- if (this.isShown && this.options.backdrop) {
135
- var doAnimate = $.support.transition && animate
155
+ , removeBackdrop: function () {
156
+ this.$backdrop.remove()
157
+ this.$backdrop = null
158
+ }
136
159
 
137
- this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
138
- .appendTo(document.body)
160
+ , backdrop: function (callback) {
161
+ var that = this
162
+ , animate = this.$element.hasClass('fade') ? 'fade' : ''
139
163
 
140
- if (this.options.backdrop != 'static') {
141
- this.$backdrop.click($.proxy(this.hide, this))
142
- }
164
+ if (this.isShown && this.options.backdrop) {
165
+ var doAnimate = $.support.transition && animate
143
166
 
144
- if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
167
+ this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
168
+ .appendTo(document.body)
145
169
 
146
- this.$backdrop.addClass('in')
170
+ if (this.options.backdrop != 'static') {
171
+ this.$backdrop.click($.proxy(this.hide, this))
172
+ }
147
173
 
148
- doAnimate ?
149
- this.$backdrop.one($.support.transition.end, callback) :
150
- callback()
174
+ if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
151
175
 
152
- } else if (!this.isShown && this.$backdrop) {
153
- this.$backdrop.removeClass('in')
176
+ this.$backdrop.addClass('in')
154
177
 
155
- $.support.transition && this.$element.hasClass('fade')?
156
- this.$backdrop.one($.support.transition.end, $.proxy(removeBackdrop, this)) :
157
- removeBackdrop.call(this)
178
+ doAnimate ?
179
+ this.$backdrop.one($.support.transition.end, callback) :
180
+ callback()
158
181
 
159
- } else if (callback) {
160
- callback()
161
- }
162
- }
182
+ } else if (!this.isShown && this.$backdrop) {
183
+ this.$backdrop.removeClass('in')
163
184
 
164
- function removeBackdrop() {
165
- this.$backdrop.remove()
166
- this.$backdrop = null
167
- }
185
+ $.support.transition && this.$element.hasClass('fade')?
186
+ this.$backdrop.one($.support.transition.end, $.proxy(this.removeBackdrop, this)) :
187
+ this.removeBackdrop()
168
188
 
169
- function escape() {
170
- var that = this
171
- if (this.isShown && this.options.keyboard) {
172
- $(document).on('keyup.dismiss.modal', function ( e ) {
173
- e.which == 27 && that.hide()
174
- })
175
- } else if (!this.isShown) {
176
- $(document).off('keyup.dismiss.modal')
177
- }
189
+ } else if (callback) {
190
+ callback()
191
+ }
192
+ }
178
193
  }
179
194
 
180
195
 
@@ -206,12 +221,18 @@
206
221
 
207
222
  $(function () {
208
223
  $('body').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
209
- var $this = $(this), href
210
- , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
211
- , option = $target.data('modal') ? 'toggle' : $.extend({}, $target.data(), $this.data())
224
+ var $this = $(this)
225
+ , href = $this.attr('href')
226
+ , $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
227
+ , option = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
212
228
 
213
229
  e.preventDefault()
214
- $target.modal(option)
230
+
231
+ $target
232
+ .modal(option)
233
+ .one('hide', function () {
234
+ $this.focus()
235
+ })
215
236
  })
216
237
  })
217
238
 
@@ -1,5 +1,5 @@
1
1
  /* ===========================================================
2
- * bootstrap-popover.js v2.0.4
2
+ * bootstrap-popover.js v2.1.0
3
3
  * http://twitter.github.com/bootstrap/javascript.html#popovers
4
4
  * ===========================================================
5
5
  * Copyright 2012 Twitter, Inc.
@@ -26,7 +26,7 @@
26
26
  /* POPOVER PUBLIC CLASS DEFINITION
27
27
  * =============================== */
28
28
 
29
- var Popover = function ( element, options ) {
29
+ var Popover = function (element, options) {
30
30
  this.init('popover', element, options)
31
31
  }
32
32
 
@@ -43,8 +43,8 @@
43
43
  , title = this.getTitle()
44
44
  , content = this.getContent()
45
45
 
46
- $tip.find('.popover-title')[this.isHTML(title) ? 'html' : 'text'](title)
47
- $tip.find('.popover-content > *')[this.isHTML(content) ? 'html' : 'text'](content)
46
+ $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
47
+ $tip.find('.popover-content > *')[this.options.html ? 'html' : 'text'](content)
48
48
 
49
49
  $tip.removeClass('fade top bottom left right in')
50
50
  }
@@ -71,6 +71,10 @@
71
71
  return this.$tip
72
72
  }
73
73
 
74
+ , destroy: function () {
75
+ this.hide().$element.off('.' + this.type).removeData(this.type)
76
+ }
77
+
74
78
  })
75
79
 
76
80
 
@@ -91,6 +95,7 @@
91
95
 
92
96
  $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
93
97
  placement: 'right'
98
+ , trigger: 'click'
94
99
  , content: ''
95
100
  , template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
96
101
  })
@@ -1,5 +1,5 @@
1
1
  /* =============================================================
2
- * bootstrap-scrollspy.js v2.0.4
2
+ * bootstrap-scrollspy.js v2.1.0
3
3
  * http://twitter.github.com/bootstrap/javascript.html#scrollspy
4
4
  * =============================================================
5
5
  * Copyright 2012 Twitter, Inc.
@@ -23,15 +23,15 @@
23
23
  "use strict"; // jshint ;_;
24
24
 
25
25
 
26
- /* SCROLLSPY CLASS DEFINITION
27
- * ========================== */
26
+ /* SCROLLSPY CLASS DEFINITION
27
+ * ========================== */
28
28
 
29
- function ScrollSpy( element, options) {
29
+ function ScrollSpy(element, options) {
30
30
  var process = $.proxy(this.process, this)
31
31
  , $element = $(element).is('body') ? $(window) : $(element)
32
32
  , href
33
33
  this.options = $.extend({}, $.fn.scrollspy.defaults, options)
34
- this.$scrollElement = $element.on('scroll.scroll.data-api', process)
34
+ this.$scrollElement = $element.on('scroll.scroll-spy.data-api', process)
35
35
  this.selector = (this.options.target
36
36
  || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
37
37
  || '') + ' .nav li > a'
@@ -58,7 +58,7 @@
58
58
  , href = $el.data('target') || $el.attr('href')
59
59
  , $href = /^#\w/.test(href) && $(href)
60
60
  return ( $href
61
- && href.length
61
+ && $href.length
62
62
  && [[ $href.position().top, href ]] ) || null
63
63
  })
64
64
  .sort(function (a, b) { return a[0] - b[0] })
@@ -108,7 +108,7 @@
108
108
  .parent('li')
109
109
  .addClass('active')
110
110
 
111
- if (active.parent('.dropdown-menu')) {
111
+ if (active.parent('.dropdown-menu').length) {
112
112
  active = active.closest('li.dropdown').addClass('active')
113
113
  }
114
114
 
@@ -121,7 +121,7 @@
121
121
  /* SCROLLSPY PLUGIN DEFINITION
122
122
  * =========================== */
123
123
 
124
- $.fn.scrollspy = function ( option ) {
124
+ $.fn.scrollspy = function (option) {
125
125
  return this.each(function () {
126
126
  var $this = $(this)
127
127
  , data = $this.data('scrollspy')
@@ -141,7 +141,7 @@
141
141
  /* SCROLLSPY DATA-API
142
142
  * ================== */
143
143
 
144
- $(function () {
144
+ $(window).on('load', function () {
145
145
  $('[data-spy="scroll"]').each(function () {
146
146
  var $spy = $(this)
147
147
  $spy.scrollspy($spy.data())
@@ -1,5 +1,5 @@
1
1
  /* ========================================================
2
- * bootstrap-tab.js v2.0.4
2
+ * bootstrap-tab.js v2.1.0
3
3
  * http://twitter.github.com/bootstrap/javascript.html#tabs
4
4
  * ========================================================
5
5
  * Copyright 2012 Twitter, Inc.
@@ -26,7 +26,7 @@
26
26
  /* TAB CLASS DEFINITION
27
27
  * ==================== */
28
28
 
29
- var Tab = function ( element ) {
29
+ var Tab = function (element) {
30
30
  this.element = $(element)
31
31
  }
32
32
 
@@ -1,5 +1,5 @@
1
1
  /* ===========================================================
2
- * bootstrap-tooltip.js v2.0.4
2
+ * bootstrap-tooltip.js v2.1.0
3
3
  * http://twitter.github.com/bootstrap/javascript.html#tooltips
4
4
  * Inspired by the original jQuery.tipsy by Jason Frame
5
5
  * ===========================================================
@@ -44,11 +44,13 @@
44
44
  this.options = this.getOptions(options)
45
45
  this.enabled = true
46
46
 
47
- if (this.options.trigger != 'manual') {
48
- eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
47
+ if (this.options.trigger == 'click') {
48
+ this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
49
+ } else if (this.options.trigger != 'manual') {
50
+ eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
49
51
  eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
50
- this.$element.on(eventIn, this.options.selector, $.proxy(this.enter, this))
51
- this.$element.on(eventOut, this.options.selector, $.proxy(this.leave, this))
52
+ this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
53
+ this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
52
54
  }
53
55
 
54
56
  this.options.selector ?
@@ -148,20 +150,11 @@
148
150
  }
149
151
  }
150
152
 
151
- , isHTML: function(text) {
152
- // html string detection logic adapted from jQuery
153
- return typeof text != 'string'
154
- || ( text.charAt(0) === "<"
155
- && text.charAt( text.length - 1 ) === ">"
156
- && text.length >= 3
157
- ) || /^(?:[^<]*<[\w\W]+>[^>]*$)/.exec(text)
158
- }
159
-
160
153
  , setContent: function () {
161
154
  var $tip = this.tip()
162
155
  , title = this.getTitle()
163
156
 
164
- $tip.find('.tooltip-inner')[this.isHTML(title) ? 'html' : 'text'](title)
157
+ $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
165
158
  $tip.removeClass('fade in top bottom left right')
166
159
  }
167
160
 
@@ -185,6 +178,8 @@
185
178
  $.support.transition && this.$tip.hasClass('fade') ?
186
179
  removeWithAnimation() :
187
180
  $tip.remove()
181
+
182
+ return this
188
183
  }
189
184
 
190
185
  , fixTitle: function () {
@@ -244,6 +239,10 @@
244
239
  this[this.tip().hasClass('in') ? 'hide' : 'show']()
245
240
  }
246
241
 
242
+ , destroy: function () {
243
+ this.hide().$element.off('.' + this.type).removeData(this.type)
244
+ }
245
+
247
246
  }
248
247
 
249
248
 
@@ -270,6 +269,7 @@
270
269
  , trigger: 'hover'
271
270
  , title: ''
272
271
  , delay: 0
272
+ , html: true
273
273
  }
274
274
 
275
275
  }(window.jQuery);
@@ -1,5 +1,5 @@
1
1
  /* ===================================================
2
- * bootstrap-transition.js v2.0.4
2
+ * bootstrap-transition.js v2.1.0
3
3
  * http://twitter.github.com/bootstrap/javascript.html#transitions
4
4
  * ===================================================
5
5
  * Copyright 2012 Twitter, Inc.
@@ -36,8 +36,7 @@
36
36
  , transEndEventNames = {
37
37
  'WebkitTransition' : 'webkitTransitionEnd'
38
38
  , 'MozTransition' : 'transitionend'
39
- , 'OTransition' : 'oTransitionEnd'
40
- , 'msTransition' : 'MSTransitionEnd'
39
+ , 'OTransition' : 'oTransitionEnd otransitionend'
41
40
  , 'transition' : 'transitionend'
42
41
  }
43
42
  , name
@@ -1,5 +1,5 @@
1
1
  /* =============================================================
2
- * bootstrap-typeahead.js v2.0.4
2
+ * bootstrap-typeahead.js v2.1.0
3
3
  * http://twitter.github.com/bootstrap/javascript.html#typeahead
4
4
  * =============================================================
5
5
  * Copyright 2012 Twitter, Inc.
@@ -77,17 +77,23 @@
77
77
  }
78
78
 
79
79
  , lookup: function (event) {
80
- var that = this
81
- , items
82
- , q
80
+ var items
83
81
 
84
82
  this.query = this.$element.val()
85
83
 
86
- if (!this.query) {
84
+ if (!this.query || this.query.length < this.options.minLength) {
87
85
  return this.shown ? this.hide() : this
88
86
  }
89
87
 
90
- items = $.grep(this.source, function (item) {
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) {
91
97
  return that.matcher(item)
92
98
  })
93
99
 
@@ -169,7 +175,7 @@
169
175
  .on('keyup', $.proxy(this.keyup, this))
170
176
 
171
177
  if ($.browser.webkit || $.browser.msie) {
172
- this.$element.on('keydown', $.proxy(this.keypress, this))
178
+ this.$element.on('keydown', $.proxy(this.keydown, this))
173
179
  }
174
180
 
175
181
  this.$menu
@@ -177,6 +183,40 @@
177
183
  .on('mouseenter', 'li', $.proxy(this.mouseenter, this))
178
184
  }
179
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
+
180
220
  , keyup: function (e) {
181
221
  switch(e.keyCode) {
182
222
  case 40: // down arrow
@@ -202,39 +242,9 @@
202
242
  e.preventDefault()
203
243
  }
204
244
 
205
- , keypress: function (e) {
206
- if (!this.shown) return
207
-
208
- switch(e.keyCode) {
209
- case 9: // tab
210
- case 13: // enter
211
- case 27: // escape
212
- e.preventDefault()
213
- break
214
-
215
- case 38: // up arrow
216
- if (e.type != 'keydown') break
217
- e.preventDefault()
218
- this.prev()
219
- break
220
-
221
- case 40: // down arrow
222
- if (e.type != 'keydown') break
223
- e.preventDefault()
224
- this.next()
225
- break
226
- }
227
-
228
- e.stopPropagation()
229
- }
230
-
231
245
  , blur: function (e) {
232
246
  var that = this
233
- setTimeout(function () {
234
- if (!that.$menu.is(':hover')) {
235
- that.hide();
236
- }
237
- }, 150)
247
+ setTimeout(function () { that.hide() }, 150)
238
248
  }
239
249
 
240
250
  , click: function (e) {
@@ -269,12 +279,13 @@
269
279
  , items: 8
270
280
  , menu: '<ul class="typeahead dropdown-menu"></ul>'
271
281
  , item: '<li><a href="#"></a></li>'
282
+ , minLength: 1
272
283
  }
273
284
 
274
285
  $.fn.typeahead.Constructor = Typeahead
275
286
 
276
287
 
277
- /* TYPEAHEAD DATA-API
288
+ /* TYPEAHEAD DATA-API
278
289
  * ================== */
279
290
 
280
291
  $(function () {
@@ -286,4 +297,4 @@
286
297
  })
287
298
  })
288
299
 
289
- }(window.jQuery);
300
+ }(window.jQuery);