spud_core 0.8.28 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. data/app/assets/javascripts/spud/admin/application.js +80 -39
  2. data/app/assets/javascripts/spud/admin/editor.js +91 -0
  3. data/app/assets/libs/bootstrap/css/bootstrap-responsive.css +799 -397
  4. data/app/assets/libs/bootstrap/css/bootstrap.css +3275 -1372
  5. data/app/assets/libs/bootstrap/img/glyphicons-halflings-white.png +0 -0
  6. data/app/assets/libs/bootstrap/img/glyphicons-halflings.png +0 -0
  7. data/app/assets/libs/bootstrap/js/bootstrap.js +716 -417
  8. data/app/assets/libs/datepicker/css/datepicker.css +223 -0
  9. data/app/assets/libs/datepicker/js/bootstrap-datepicker.js +779 -0
  10. data/app/assets/libs/datepicker/less/datepicker.less +122 -0
  11. data/app/assets/libs/jquery-ui/css/flick/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  12. data/app/assets/libs/jquery-ui/css/flick/images/ui-bg_flat_0_eeeeee_40x100.png +0 -0
  13. data/app/assets/libs/jquery-ui/css/flick/images/ui-bg_flat_55_ffffff_40x100.png +0 -0
  14. data/app/assets/libs/jquery-ui/css/flick/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  15. data/app/assets/libs/jquery-ui/css/flick/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  16. data/app/assets/libs/jquery-ui/css/flick/images/ui-bg_highlight-soft_100_f6f6f6_1x100.png +0 -0
  17. data/app/assets/libs/jquery-ui/css/flick/images/ui-bg_highlight-soft_25_0073ea_1x100.png +0 -0
  18. data/app/assets/libs/jquery-ui/css/flick/images/ui-bg_highlight-soft_50_dddddd_1x100.png +0 -0
  19. data/app/assets/libs/jquery-ui/css/flick/images/ui-icons_0073ea_256x240.png +0 -0
  20. data/app/assets/libs/jquery-ui/css/flick/images/ui-icons_454545_256x240.png +0 -0
  21. data/app/assets/libs/jquery-ui/css/flick/images/ui-icons_666666_256x240.png +0 -0
  22. data/app/assets/libs/jquery-ui/css/flick/images/ui-icons_ff0084_256x240.png +0 -0
  23. data/app/assets/libs/jquery-ui/css/flick/images/ui-icons_ffffff_256x240.png +0 -0
  24. data/app/assets/libs/jquery-ui/css/flick/jquery-ui-1.9.1.custom.css +297 -0
  25. data/app/assets/libs/jquery-ui/css/flick/jquery-ui-1.9.1.custom.min.css +5 -0
  26. data/app/assets/libs/jquery-ui/js/jquery-ui-1.9.1.custom.js +4870 -0
  27. data/app/assets/libs/jquery-ui/js/jquery-ui-1.9.1.custom.min.js +6 -0
  28. data/app/assets/stylesheets/spud/admin/application.css +22 -4
  29. data/app/controllers/spud/admin/application_controller.rb +13 -4
  30. data/app/controllers/spud/admin/dashboard_controller.rb +1 -1
  31. data/app/controllers/spud/admin/users_controller.rb +4 -9
  32. data/app/controllers/spud/setup_controller.rb +3 -4
  33. data/app/models/spud_admin_permission.rb +1 -1
  34. data/app/models/spud_user.rb +4 -2
  35. data/app/views/layouts/spud/admin/application.html.erb +24 -5
  36. data/app/views/spud/admin/users/_edit.html.erb +2 -4
  37. data/app/views/spud/admin/users/_new.html.erb +3 -5
  38. data/app/views/spud/admin/users/index.html.erb +6 -5
  39. data/lib/spud_core/belongs_to_app.rb +9 -6
  40. data/lib/spud_core/configuration.rb +23 -1
  41. data/lib/spud_core/engine.rb +20 -28
  42. data/lib/spud_core/version.rb +1 -1
  43. data/spec/dummy/log/development.log +15 -37
  44. data/spec/dummy/log/test.log +72841 -25918
  45. metadata +25 -101
  46. data/app/assets/libs/bootstrap/css/bootstrap-responsive.min.css +0 -12
  47. data/app/assets/libs/bootstrap/css/bootstrap.min.css +0 -689
  48. data/app/assets/libs/bootstrap/js/bootstrap.min.js +0 -6
  49. data/app/assets/libs/tiny_mce/plugins/autosave/editor_plugin.js +0 -1
  50. data/app/assets/libs/tiny_mce/plugins/autosave/editor_plugin_src.js +0 -431
  51. data/app/assets/libs/tiny_mce/plugins/autosave/langs/en.js +0 -4
  52. data/app/assets/libs/tiny_mce/plugins/bbcode/editor_plugin.js +0 -1
  53. data/app/assets/libs/tiny_mce/plugins/bbcode/editor_plugin_src.js +0 -120
  54. data/app/assets/libs/tiny_mce/plugins/emotions/editor_plugin.js +0 -1
  55. data/app/assets/libs/tiny_mce/plugins/emotions/editor_plugin_src.js +0 -43
  56. data/app/assets/libs/tiny_mce/plugins/emotions/emotions.htm +0 -42
  57. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-cool.gif +0 -0
  58. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-cry.gif +0 -0
  59. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-embarassed.gif +0 -0
  60. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-foot-in-mouth.gif +0 -0
  61. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-frown.gif +0 -0
  62. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-innocent.gif +0 -0
  63. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-kiss.gif +0 -0
  64. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-laughing.gif +0 -0
  65. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-money-mouth.gif +0 -0
  66. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-sealed.gif +0 -0
  67. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-smile.gif +0 -0
  68. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-surprised.gif +0 -0
  69. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-tongue-out.gif +0 -0
  70. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-undecided.gif +0 -0
  71. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-wink.gif +0 -0
  72. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-yell.gif +0 -0
  73. data/app/assets/libs/tiny_mce/plugins/emotions/js/emotions.js +0 -43
  74. data/app/assets/libs/tiny_mce/plugins/emotions/langs/en_dlg.js +0 -1
  75. data/app/assets/libs/tiny_mce/plugins/fullpage/css/fullpage.css +0 -143
  76. data/app/assets/libs/tiny_mce/plugins/fullpage/editor_plugin.js +0 -1
  77. data/app/assets/libs/tiny_mce/plugins/fullpage/editor_plugin_src.js +0 -405
  78. data/app/assets/libs/tiny_mce/plugins/fullpage/fullpage.htm +0 -259
  79. data/app/assets/libs/tiny_mce/plugins/fullpage/js/fullpage.js +0 -232
  80. data/app/assets/libs/tiny_mce/plugins/fullpage/langs/en_dlg.js +0 -1
  81. data/app/assets/libs/tiny_mce/plugins/fullscreen/editor_plugin.js +0 -1
  82. data/app/assets/libs/tiny_mce/plugins/fullscreen/editor_plugin_src.js +0 -159
  83. data/app/assets/libs/tiny_mce/plugins/fullscreen/fullscreen.htm +0 -110
  84. data/app/assets/libs/tiny_mce/plugins/insertdatetime/editor_plugin.js +0 -1
  85. data/app/assets/libs/tiny_mce/plugins/insertdatetime/editor_plugin_src.js +0 -83
  86. data/app/assets/libs/tiny_mce/plugins/legacyoutput/editor_plugin.js +0 -1
  87. data/app/assets/libs/tiny_mce/plugins/legacyoutput/editor_plugin_src.js +0 -139
  88. data/app/assets/libs/tiny_mce/plugins/nonbreaking/editor_plugin.js +0 -1
  89. data/app/assets/libs/tiny_mce/plugins/nonbreaking/editor_plugin_src.js +0 -54
  90. data/app/assets/libs/tiny_mce/plugins/noneditable/editor_plugin.js +0 -1
  91. data/app/assets/libs/tiny_mce/plugins/noneditable/editor_plugin_src.js +0 -454
  92. data/app/assets/libs/tiny_mce/plugins/pagebreak/editor_plugin.js +0 -1
  93. data/app/assets/libs/tiny_mce/plugins/pagebreak/editor_plugin_src.js +0 -74
  94. data/app/assets/libs/tiny_mce/plugins/preview/editor_plugin.js +0 -1
  95. data/app/assets/libs/tiny_mce/plugins/preview/editor_plugin_src.js +0 -53
  96. data/app/assets/libs/tiny_mce/plugins/preview/example.html +0 -28
  97. data/app/assets/libs/tiny_mce/plugins/preview/jscripts/embed.js +0 -73
  98. data/app/assets/libs/tiny_mce/plugins/preview/preview.html +0 -17
  99. data/app/assets/libs/tiny_mce/plugins/print/editor_plugin.js +0 -1
  100. data/app/assets/libs/tiny_mce/plugins/print/editor_plugin_src.js +0 -34
  101. data/app/assets/libs/tiny_mce/plugins/save/editor_plugin.js +0 -1
  102. data/app/assets/libs/tiny_mce/plugins/save/editor_plugin_src.js +0 -101
  103. data/app/assets/libs/tiny_mce/plugins/searchreplace/css/searchreplace.css +0 -6
  104. data/app/assets/libs/tiny_mce/plugins/searchreplace/editor_plugin.js +0 -1
  105. data/app/assets/libs/tiny_mce/plugins/searchreplace/editor_plugin_src.js +0 -61
  106. data/app/assets/libs/tiny_mce/plugins/searchreplace/js/searchreplace.js +0 -142
  107. data/app/assets/libs/tiny_mce/plugins/searchreplace/langs/en_dlg.js +0 -1
  108. data/app/assets/libs/tiny_mce/plugins/searchreplace/searchreplace.htm +0 -100
  109. data/app/assets/libs/tiny_mce/plugins/tabfocus/editor_plugin.js +0 -1
  110. data/app/assets/libs/tiny_mce/plugins/tabfocus/editor_plugin_src.js +0 -122
  111. data/app/assets/libs/tiny_mce/plugins/template/blank.htm +0 -12
  112. data/app/assets/libs/tiny_mce/plugins/template/css/template.css +0 -23
  113. data/app/assets/libs/tiny_mce/plugins/template/editor_plugin.js +0 -1
  114. data/app/assets/libs/tiny_mce/plugins/template/editor_plugin_src.js +0 -159
  115. data/app/assets/libs/tiny_mce/plugins/template/js/template.js +0 -106
  116. data/app/assets/libs/tiny_mce/plugins/template/langs/en_dlg.js +0 -1
  117. data/app/assets/libs/tiny_mce/plugins/template/template.htm +0 -31
  118. data/app/assets/libs/tiny_mce/plugins/visualblocks/css/visualblocks.css +0 -21
  119. data/app/assets/libs/tiny_mce/plugins/visualblocks/editor_plugin.js +0 -1
  120. data/app/assets/libs/tiny_mce/plugins/visualblocks/editor_plugin_src.js +0 -63
  121. data/app/assets/libs/tiny_mce/plugins/visualchars/editor_plugin.js +0 -1
  122. data/app/assets/libs/tiny_mce/plugins/visualchars/editor_plugin_src.js +0 -83
  123. data/app/assets/libs/tiny_mce/plugins/wordcount/editor_plugin.js +0 -1
  124. data/app/assets/libs/tiny_mce/plugins/wordcount/editor_plugin_src.js +0 -122
  125. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/abbr.htm +0 -142
  126. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/acronym.htm +0 -142
  127. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/attributes.htm +0 -149
  128. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/cite.htm +0 -142
  129. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/css/attributes.css +0 -11
  130. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/css/popup.css +0 -9
  131. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/del.htm +0 -162
  132. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/editor_plugin.js +0 -1
  133. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/editor_plugin_src.js +0 -132
  134. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/ins.htm +0 -162
  135. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/js/abbr.js +0 -28
  136. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/js/acronym.js +0 -28
  137. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/js/attributes.js +0 -111
  138. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/js/cite.js +0 -28
  139. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/js/del.js +0 -53
  140. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/js/element_common.js +0 -229
  141. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/js/ins.js +0 -53
  142. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/langs/en_dlg.js +0 -1
@@ -1,5 +1,5 @@
1
1
  /* ===================================================
2
- * bootstrap-transition.js v2.0.2
2
+ * bootstrap-transition.js v2.2.1
3
3
  * http://twitter.github.com/bootstrap/javascript.html#transitions
4
4
  * ===================================================
5
5
  * Copyright 2012 Twitter, Inc.
@@ -17,39 +17,48 @@
17
17
  * limitations under the License.
18
18
  * ========================================================== */
19
19
 
20
- !function( $ ) {
21
20
 
22
- $(function () {
21
+ !function ($) {
22
+
23
+ "use strict"; // jshint ;_;
24
+
23
25
 
24
- "use strict"
26
+ /* CSS TRANSITION SUPPORT (http://www.modernizr.com/)
27
+ * ======================================================= */
25
28
 
26
- /* CSS TRANSITION SUPPORT (https://gist.github.com/373874)
27
- * ======================================================= */
29
+ $(function () {
28
30
 
29
31
  $.support.transition = (function () {
30
- var thisBody = document.body || document.documentElement
31
- , thisStyle = thisBody.style
32
- , support = thisStyle.transition !== undefined || thisStyle.WebkitTransition !== undefined || thisStyle.MozTransition !== undefined || thisStyle.MsTransition !== undefined || thisStyle.OTransition !== undefined
33
-
34
- return support && {
35
- end: (function () {
36
- var transitionEnd = "TransitionEnd"
37
- if ( $.browser.webkit ) {
38
- transitionEnd = "webkitTransitionEnd"
39
- } else if ( $.browser.mozilla ) {
40
- transitionEnd = "transitionend"
41
- } else if ( $.browser.opera ) {
42
- transitionEnd = "oTransitionEnd"
32
+
33
+ var transitionEnd = (function () {
34
+
35
+ var el = document.createElement('bootstrap')
36
+ , transEndEventNames = {
37
+ 'WebkitTransition' : 'webkitTransitionEnd'
38
+ , 'MozTransition' : 'transitionend'
39
+ , 'OTransition' : 'oTransitionEnd otransitionend'
40
+ , 'transition' : 'transitionend'
41
+ }
42
+ , name
43
+
44
+ for (name in transEndEventNames){
45
+ if (el.style[name] !== undefined) {
46
+ return transEndEventNames[name]
43
47
  }
44
- return transitionEnd
45
- }())
48
+ }
49
+
50
+ }())
51
+
52
+ return transitionEnd && {
53
+ end: transitionEnd
46
54
  }
55
+
47
56
  })()
48
57
 
49
58
  })
50
59
 
51
- }( window.jQuery );/* ==========================================================
52
- * bootstrap-alert.js v2.0.2
60
+ }(window.jQuery);/* ==========================================================
61
+ * bootstrap-alert.js v2.2.1
53
62
  * http://twitter.github.com/bootstrap/javascript.html#alerts
54
63
  * ==========================================================
55
64
  * Copyright 2012 Twitter, Inc.
@@ -68,61 +77,57 @@
68
77
  * ========================================================== */
69
78
 
70
79
 
71
- !function( $ ){
80
+ !function ($) {
81
+
82
+ "use strict"; // jshint ;_;
72
83
 
73
- "use strict"
74
84
 
75
85
  /* ALERT CLASS DEFINITION
76
86
  * ====================== */
77
87
 
78
88
  var dismiss = '[data-dismiss="alert"]'
79
- , Alert = function ( el ) {
89
+ , Alert = function (el) {
80
90
  $(el).on('click', dismiss, this.close)
81
91
  }
82
92
 
83
- Alert.prototype = {
93
+ Alert.prototype.close = function (e) {
94
+ var $this = $(this)
95
+ , selector = $this.attr('data-target')
96
+ , $parent
84
97
 
85
- constructor: Alert
98
+ if (!selector) {
99
+ selector = $this.attr('href')
100
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
101
+ }
86
102
 
87
- , close: function ( e ) {
88
- var $this = $(this)
89
- , selector = $this.attr('data-target')
90
- , $parent
103
+ $parent = $(selector)
91
104
 
92
- if (!selector) {
93
- selector = $this.attr('href')
94
- selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
95
- }
105
+ e && e.preventDefault()
96
106
 
97
- $parent = $(selector)
98
- $parent.trigger('close')
107
+ $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
99
108
 
100
- e && e.preventDefault()
109
+ $parent.trigger(e = $.Event('close'))
101
110
 
102
- $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
111
+ if (e.isDefaultPrevented()) return
103
112
 
104
- $parent
105
- .trigger('close')
106
- .removeClass('in')
113
+ $parent.removeClass('in')
107
114
 
108
- function removeElement() {
109
- $parent
110
- .trigger('closed')
111
- .remove()
112
- }
113
-
114
- $.support.transition && $parent.hasClass('fade') ?
115
- $parent.on($.support.transition.end, removeElement) :
116
- removeElement()
115
+ function removeElement() {
116
+ $parent
117
+ .trigger('closed')
118
+ .remove()
117
119
  }
118
120
 
121
+ $.support.transition && $parent.hasClass('fade') ?
122
+ $parent.on($.support.transition.end, removeElement) :
123
+ removeElement()
119
124
  }
120
125
 
121
126
 
122
127
  /* ALERT PLUGIN DEFINITION
123
128
  * ======================= */
124
129
 
125
- $.fn.alert = function ( option ) {
130
+ $.fn.alert = function (option) {
126
131
  return this.each(function () {
127
132
  var $this = $(this)
128
133
  , data = $this.data('alert')
@@ -137,12 +142,10 @@
137
142
  /* ALERT DATA-API
138
143
  * ============== */
139
144
 
140
- $(function () {
141
- $('body').on('click.alert.data-api', dismiss, Alert.prototype.close)
142
- })
145
+ $(document).on('click.alert.data-api', dismiss, Alert.prototype.close)
143
146
 
144
- }( window.jQuery );/* ============================================================
145
- * bootstrap-button.js v2.0.2
147
+ }(window.jQuery);/* ============================================================
148
+ * bootstrap-button.js v2.2.1
146
149
  * http://twitter.github.com/bootstrap/javascript.html#buttons
147
150
  * ============================================================
148
151
  * Copyright 2012 Twitter, Inc.
@@ -160,58 +163,54 @@
160
163
  * limitations under the License.
161
164
  * ============================================================ */
162
165
 
163
- !function( $ ){
164
166
 
165
- "use strict"
167
+ !function ($) {
168
+
169
+ "use strict"; // jshint ;_;
170
+
166
171
 
167
172
  /* BUTTON PUBLIC CLASS DEFINITION
168
173
  * ============================== */
169
174
 
170
- var Button = function ( element, options ) {
175
+ var Button = function (element, options) {
171
176
  this.$element = $(element)
172
177
  this.options = $.extend({}, $.fn.button.defaults, options)
173
178
  }
174
179
 
175
- Button.prototype = {
180
+ Button.prototype.setState = function (state) {
181
+ var d = 'disabled'
182
+ , $el = this.$element
183
+ , data = $el.data()
184
+ , val = $el.is('input') ? 'val' : 'html'
176
185
 
177
- constructor: Button
186
+ state = state + 'Text'
187
+ data.resetText || $el.data('resetText', $el[val]())
178
188
 
179
- , setState: function ( state ) {
180
- var d = 'disabled'
181
- , $el = this.$element
182
- , data = $el.data()
183
- , val = $el.is('input') ? 'val' : 'html'
189
+ $el[val](data[state] || this.options[state])
184
190
 
185
- state = state + 'Text'
186
- data.resetText || $el.data('resetText', $el[val]())
187
-
188
- $el[val](data[state] || this.options[state])
189
-
190
- // push to event loop to allow forms to submit
191
- setTimeout(function () {
192
- state == 'loadingText' ?
193
- $el.addClass(d).attr(d, d) :
194
- $el.removeClass(d).removeAttr(d)
195
- }, 0)
196
- }
197
-
198
- , toggle: function () {
199
- var $parent = this.$element.parent('[data-toggle="buttons-radio"]')
191
+ // push to event loop to allow forms to submit
192
+ setTimeout(function () {
193
+ state == 'loadingText' ?
194
+ $el.addClass(d).attr(d, d) :
195
+ $el.removeClass(d).removeAttr(d)
196
+ }, 0)
197
+ }
200
198
 
201
- $parent && $parent
202
- .find('.active')
203
- .removeClass('active')
199
+ Button.prototype.toggle = function () {
200
+ var $parent = this.$element.closest('[data-toggle="buttons-radio"]')
204
201
 
205
- this.$element.toggleClass('active')
206
- }
202
+ $parent && $parent
203
+ .find('.active')
204
+ .removeClass('active')
207
205
 
206
+ this.$element.toggleClass('active')
208
207
  }
209
208
 
210
209
 
211
210
  /* BUTTON PLUGIN DEFINITION
212
211
  * ======================== */
213
212
 
214
- $.fn.button = function ( option ) {
213
+ $.fn.button = function (option) {
215
214
  return this.each(function () {
216
215
  var $this = $(this)
217
216
  , data = $this.data('button')
@@ -232,16 +231,14 @@
232
231
  /* BUTTON DATA-API
233
232
  * =============== */
234
233
 
235
- $(function () {
236
- $('body').on('click.button.data-api', '[data-toggle^=button]', function ( e ) {
237
- var $btn = $(e.target)
238
- if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
239
- $btn.button('toggle')
240
- })
234
+ $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) {
235
+ var $btn = $(e.target)
236
+ if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
237
+ $btn.button('toggle')
241
238
  })
242
239
 
243
- }( window.jQuery );/* ==========================================================
244
- * bootstrap-carousel.js v2.0.2
240
+ }(window.jQuery);/* ==========================================================
241
+ * bootstrap-carousel.js v2.2.1
245
242
  * http://twitter.github.com/bootstrap/javascript.html#carousel
246
243
  * ==========================================================
247
244
  * Copyright 2012 Twitter, Inc.
@@ -260,16 +257,17 @@
260
257
  * ========================================================== */
261
258
 
262
259
 
263
- !function( $ ){
260
+ !function ($) {
261
+
262
+ "use strict"; // jshint ;_;
264
263
 
265
- "use strict"
266
264
 
267
265
  /* CAROUSEL CLASS DEFINITION
268
266
  * ========================= */
269
267
 
270
268
  var Carousel = function (element, options) {
271
269
  this.$element = $(element)
272
- this.options = $.extend({}, $.fn.carousel.defaults, options)
270
+ this.options = options
273
271
  this.options.slide && this.slide(this.options.slide)
274
272
  this.options.pause == 'hover' && this.$element
275
273
  .on('mouseenter', $.proxy(this.pause, this))
@@ -278,13 +276,16 @@
278
276
 
279
277
  Carousel.prototype = {
280
278
 
281
- cycle: function () {
282
- this.interval = setInterval($.proxy(this.next, this), this.options.interval)
279
+ cycle: function (e) {
280
+ if (!e) this.paused = false
281
+ this.options.interval
282
+ && !this.paused
283
+ && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
283
284
  return this
284
285
  }
285
286
 
286
287
  , to: function (pos) {
287
- var $active = this.$element.find('.active')
288
+ var $active = this.$element.find('.item.active')
288
289
  , children = $active.parent().children()
289
290
  , activePos = children.index($active)
290
291
  , that = this
@@ -304,7 +305,12 @@
304
305
  return this.slide(pos > activePos ? 'next' : 'prev', $(children[pos]))
305
306
  }
306
307
 
307
- , pause: function () {
308
+ , pause: function (e) {
309
+ if (!e) this.paused = true
310
+ if (this.$element.find('.next, .prev').length && $.support.transition.end) {
311
+ this.$element.trigger($.support.transition.end)
312
+ this.cycle()
313
+ }
308
314
  clearInterval(this.interval)
309
315
  this.interval = null
310
316
  return this
@@ -321,12 +327,13 @@
321
327
  }
322
328
 
323
329
  , slide: function (type, next) {
324
- var $active = this.$element.find('.active')
330
+ var $active = this.$element.find('.item.active')
325
331
  , $next = next || $active[type]()
326
332
  , isCycling = this.interval
327
333
  , direction = type == 'next' ? 'left' : 'right'
328
334
  , fallback = type == 'next' ? 'first' : 'last'
329
335
  , that = this
336
+ , e
330
337
 
331
338
  this.sliding = true
332
339
 
@@ -334,26 +341,32 @@
334
341
 
335
342
  $next = $next.length ? $next : this.$element.find('.item')[fallback]()
336
343
 
344
+ e = $.Event('slide', {
345
+ relatedTarget: $next[0]
346
+ })
347
+
337
348
  if ($next.hasClass('active')) return
338
349
 
339
- if (!$.support.transition && this.$element.hasClass('slide')) {
340
- this.$element.trigger('slide')
341
- $active.removeClass('active')
342
- $next.addClass('active')
343
- this.sliding = false
344
- this.$element.trigger('slid')
345
- } else {
350
+ if ($.support.transition && this.$element.hasClass('slide')) {
351
+ this.$element.trigger(e)
352
+ if (e.isDefaultPrevented()) return
346
353
  $next.addClass(type)
347
354
  $next[0].offsetWidth // force reflow
348
355
  $active.addClass(direction)
349
356
  $next.addClass(direction)
350
- this.$element.trigger('slide')
351
357
  this.$element.one($.support.transition.end, function () {
352
358
  $next.removeClass([type, direction].join(' ')).addClass('active')
353
359
  $active.removeClass(['active', direction].join(' '))
354
360
  that.sliding = false
355
361
  setTimeout(function () { that.$element.trigger('slid') }, 0)
356
362
  })
363
+ } else {
364
+ this.$element.trigger(e)
365
+ if (e.isDefaultPrevented()) return
366
+ $active.removeClass('active')
367
+ $next.addClass('active')
368
+ this.sliding = false
369
+ this.$element.trigger('slid')
357
370
  }
358
371
 
359
372
  isCycling && this.cycle()
@@ -367,15 +380,16 @@
367
380
  /* CAROUSEL PLUGIN DEFINITION
368
381
  * ========================== */
369
382
 
370
- $.fn.carousel = function ( option ) {
383
+ $.fn.carousel = function (option) {
371
384
  return this.each(function () {
372
385
  var $this = $(this)
373
386
  , data = $this.data('carousel')
374
- , options = typeof option == 'object' && option
387
+ , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option)
388
+ , action = typeof option == 'string' ? option : options.slide
375
389
  if (!data) $this.data('carousel', (data = new Carousel(this, options)))
376
390
  if (typeof option == 'number') data.to(option)
377
- else if (typeof option == 'string' || (option = options.slide)) data[option]()
378
- else data.cycle()
391
+ else if (action) data[action]()
392
+ else if (options.interval) data.cycle()
379
393
  })
380
394
  }
381
395
 
@@ -390,18 +404,16 @@
390
404
  /* CAROUSEL DATA-API
391
405
  * ================= */
392
406
 
393
- $(function () {
394
- $('body').on('click.carousel.data-api', '[data-slide]', function ( e ) {
395
- var $this = $(this), href
396
- , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
397
- , options = !$target.data('modal') && $.extend({}, $target.data(), $this.data())
398
- $target.carousel(options)
399
- e.preventDefault()
400
- })
407
+ $(document).on('click.carousel.data-api', '[data-slide]', function (e) {
408
+ var $this = $(this), href
409
+ , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
410
+ , options = $.extend({}, $target.data(), $this.data())
411
+ $target.carousel(options)
412
+ e.preventDefault()
401
413
  })
402
414
 
403
- }( window.jQuery );/* =============================================================
404
- * bootstrap-collapse.js v2.0.2
415
+ }(window.jQuery);/* =============================================================
416
+ * bootstrap-collapse.js v2.2.1
405
417
  * http://twitter.github.com/bootstrap/javascript.html#collapse
406
418
  * =============================================================
407
419
  * Copyright 2012 Twitter, Inc.
@@ -419,16 +431,21 @@
419
431
  * limitations under the License.
420
432
  * ============================================================ */
421
433
 
422
- !function( $ ){
423
434
 
424
- "use strict"
435
+ !function ($) {
436
+
437
+ "use strict"; // jshint ;_;
438
+
425
439
 
426
- var Collapse = function ( element, options ) {
427
- this.$element = $(element)
440
+ /* COLLAPSE PUBLIC CLASS DEFINITION
441
+ * ================================ */
442
+
443
+ var Collapse = function (element, options) {
444
+ this.$element = $(element)
428
445
  this.options = $.extend({}, $.fn.collapse.defaults, options)
429
446
 
430
- if (this.options["parent"]) {
431
- this.$parent = $(this.options["parent"])
447
+ if (this.options.parent) {
448
+ this.$parent = $(this.options.parent)
432
449
  }
433
450
 
434
451
  this.options.toggle && this.toggle()
@@ -444,31 +461,39 @@
444
461
  }
445
462
 
446
463
  , show: function () {
447
- var dimension = this.dimension()
448
- , scroll = $.camelCase(['scroll', dimension].join('-'))
449
- , actives = this.$parent && this.$parent.find('.in')
464
+ var dimension
465
+ , scroll
466
+ , actives
450
467
  , hasData
451
468
 
469
+ if (this.transitioning) return
470
+
471
+ dimension = this.dimension()
472
+ scroll = $.camelCase(['scroll', dimension].join('-'))
473
+ actives = this.$parent && this.$parent.find('> .accordion-group > .in')
474
+
452
475
  if (actives && actives.length) {
453
476
  hasData = actives.data('collapse')
477
+ if (hasData && hasData.transitioning) return
454
478
  actives.collapse('hide')
455
479
  hasData || actives.data('collapse', null)
456
480
  }
457
481
 
458
482
  this.$element[dimension](0)
459
- this.transition('addClass', 'show', 'shown')
460
- this.$element[dimension](this.$element[0][scroll])
461
-
483
+ this.transition('addClass', $.Event('show'), 'shown')
484
+ $.support.transition && this.$element[dimension](this.$element[0][scroll])
462
485
  }
463
486
 
464
487
  , hide: function () {
465
- var dimension = this.dimension()
488
+ var dimension
489
+ if (this.transitioning) return
490
+ dimension = this.dimension()
466
491
  this.reset(this.$element[dimension]())
467
- this.transition('removeClass', 'hide', 'hidden')
492
+ this.transition('removeClass', $.Event('hide'), 'hidden')
468
493
  this.$element[dimension](0)
469
494
  }
470
495
 
471
- , reset: function ( size ) {
496
+ , reset: function (size) {
472
497
  var dimension = this.dimension()
473
498
 
474
499
  this.$element
@@ -476,37 +501,43 @@
476
501
  [dimension](size || 'auto')
477
502
  [0].offsetWidth
478
503
 
479
- this.$element[size ? 'addClass' : 'removeClass']('collapse')
504
+ this.$element[size !== null ? 'addClass' : 'removeClass']('collapse')
480
505
 
481
506
  return this
482
507
  }
483
508
 
484
- , transition: function ( method, startEvent, completeEvent ) {
509
+ , transition: function (method, startEvent, completeEvent) {
485
510
  var that = this
486
511
  , complete = function () {
487
- if (startEvent == 'show') that.reset()
512
+ if (startEvent.type == 'show') that.reset()
513
+ that.transitioning = 0
488
514
  that.$element.trigger(completeEvent)
489
515
  }
490
516
 
491
- this.$element
492
- .trigger(startEvent)
493
- [method]('in')
517
+ this.$element.trigger(startEvent)
518
+
519
+ if (startEvent.isDefaultPrevented()) return
520
+
521
+ this.transitioning = 1
522
+
523
+ this.$element[method]('in')
494
524
 
495
525
  $.support.transition && this.$element.hasClass('collapse') ?
496
526
  this.$element.one($.support.transition.end, complete) :
497
527
  complete()
498
- }
528
+ }
499
529
 
500
530
  , toggle: function () {
501
531
  this[this.$element.hasClass('in') ? 'hide' : 'show']()
502
- }
532
+ }
503
533
 
504
534
  }
505
535
 
506
- /* COLLAPSIBLE PLUGIN DEFINITION
536
+
537
+ /* COLLAPSIBLE PLUGIN DEFINITION
507
538
  * ============================== */
508
539
 
509
- $.fn.collapse = function ( option ) {
540
+ $.fn.collapse = function (option) {
510
541
  return this.each(function () {
511
542
  var $this = $(this)
512
543
  , data = $this.data('collapse')
@@ -526,19 +557,18 @@
526
557
  /* COLLAPSIBLE DATA-API
527
558
  * ==================== */
528
559
 
529
- $(function () {
530
- $('body').on('click.collapse.data-api', '[data-toggle=collapse]', function ( e ) {
531
- var $this = $(this), href
532
- , target = $this.attr('data-target')
533
- || e.preventDefault()
534
- || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
535
- , option = $(target).data('collapse') ? 'toggle' : $this.data()
536
- $(target).collapse(option)
537
- })
560
+ $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) {
561
+ var $this = $(this), href
562
+ , target = $this.attr('data-target')
563
+ || e.preventDefault()
564
+ || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
565
+ , option = $(target).data('collapse') ? 'toggle' : $this.data()
566
+ $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
567
+ $(target).collapse(option)
538
568
  })
539
569
 
540
- }( window.jQuery );/* ============================================================
541
- * bootstrap-dropdown.js v2.0.2
570
+ }(window.jQuery);/* ============================================================
571
+ * bootstrap-dropdown.js v2.2.1
542
572
  * http://twitter.github.com/bootstrap/javascript.html#dropdowns
543
573
  * ============================================================
544
574
  * Copyright 2012 Twitter, Inc.
@@ -557,15 +587,16 @@
557
587
  * ============================================================ */
558
588
 
559
589
 
560
- !function( $ ){
590
+ !function ($) {
591
+
592
+ "use strict"; // jshint ;_;
561
593
 
562
- "use strict"
563
594
 
564
595
  /* DROPDOWN CLASS DEFINITION
565
596
  * ========================= */
566
597
 
567
- var toggle = '[data-toggle="dropdown"]'
568
- , Dropdown = function ( element ) {
598
+ var toggle = '[data-toggle=dropdown]'
599
+ , Dropdown = function (element) {
569
600
  var $el = $(element).on('click.dropdown.data-api', this.toggle)
570
601
  $('html').on('click.dropdown.data-api', function () {
571
602
  $el.parent().removeClass('open')
@@ -576,39 +607,93 @@
576
607
 
577
608
  constructor: Dropdown
578
609
 
579
- , toggle: function ( e ) {
610
+ , toggle: function (e) {
580
611
  var $this = $(this)
581
- , selector = $this.attr('data-target')
582
612
  , $parent
583
613
  , isActive
584
614
 
585
- if (!selector) {
586
- selector = $this.attr('href')
587
- selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
588
- }
615
+ if ($this.is('.disabled, :disabled')) return
589
616
 
590
- $parent = $(selector)
591
- $parent.length || ($parent = $this.parent())
617
+ $parent = getParent($this)
592
618
 
593
619
  isActive = $parent.hasClass('open')
594
620
 
595
621
  clearMenus()
596
- !isActive && $parent.toggleClass('open')
622
+
623
+ if (!isActive) {
624
+ $parent.toggleClass('open')
625
+ $this.focus()
626
+ }
597
627
 
598
628
  return false
599
629
  }
600
630
 
631
+ , keydown: function (e) {
632
+ var $this
633
+ , $items
634
+ , $active
635
+ , $parent
636
+ , isActive
637
+ , index
638
+
639
+ if (!/(38|40|27)/.test(e.keyCode)) return
640
+
641
+ $this = $(this)
642
+
643
+ e.preventDefault()
644
+ e.stopPropagation()
645
+
646
+ if ($this.is('.disabled, :disabled')) return
647
+
648
+ $parent = getParent($this)
649
+
650
+ isActive = $parent.hasClass('open')
651
+
652
+ if (!isActive || (isActive && e.keyCode == 27)) return $this.click()
653
+
654
+ $items = $('[role=menu] li:not(.divider) a', $parent)
655
+
656
+ if (!$items.length) return
657
+
658
+ index = $items.index($items.filter(':focus'))
659
+
660
+ if (e.keyCode == 38 && index > 0) index-- // up
661
+ if (e.keyCode == 40 && index < $items.length - 1) index++ // down
662
+ if (!~index) index = 0
663
+
664
+ $items
665
+ .eq(index)
666
+ .focus()
667
+ }
668
+
601
669
  }
602
670
 
603
671
  function clearMenus() {
604
- $(toggle).parent().removeClass('open')
672
+ $(toggle).each(function () {
673
+ getParent($(this)).removeClass('open')
674
+ })
675
+ }
676
+
677
+ function getParent($this) {
678
+ var selector = $this.attr('data-target')
679
+ , $parent
680
+
681
+ if (!selector) {
682
+ selector = $this.attr('href')
683
+ selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
684
+ }
685
+
686
+ $parent = $(selector)
687
+ $parent.length || ($parent = $this.parent())
688
+
689
+ return $parent
605
690
  }
606
691
 
607
692
 
608
693
  /* DROPDOWN PLUGIN DEFINITION
609
694
  * ========================== */
610
695
 
611
- $.fn.dropdown = function ( option ) {
696
+ $.fn.dropdown = function (option) {
612
697
  return this.each(function () {
613
698
  var $this = $(this)
614
699
  , data = $this.data('dropdown')
@@ -623,13 +708,14 @@
623
708
  /* APPLY TO STANDARD DROPDOWN ELEMENTS
624
709
  * =================================== */
625
710
 
626
- $(function () {
627
- $('html').on('click.dropdown.data-api', clearMenus)
628
- $('body').on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle)
629
- })
711
+ $(document)
712
+ .on('click.dropdown.data-api touchstart.dropdown.data-api', clearMenus)
713
+ .on('click.dropdown touchstart.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
714
+ .on('click.dropdown.data-api touchstart.dropdown.data-api' , toggle, Dropdown.prototype.toggle)
715
+ .on('keydown.dropdown.data-api touchstart.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
630
716
 
631
- }( window.jQuery );/* =========================================================
632
- * bootstrap-modal.js v2.0.2
717
+ }(window.jQuery);/* =========================================================
718
+ * bootstrap-modal.js v2.2.1
633
719
  * http://twitter.github.com/bootstrap/javascript.html#modals
634
720
  * =========================================================
635
721
  * Copyright 2012 Twitter, Inc.
@@ -648,17 +734,19 @@
648
734
  * ========================================================= */
649
735
 
650
736
 
651
- !function( $ ){
737
+ !function ($) {
738
+
739
+ "use strict"; // jshint ;_;
652
740
 
653
- "use strict"
654
741
 
655
742
  /* MODAL CLASS DEFINITION
656
743
  * ====================== */
657
744
 
658
- var Modal = function ( content, options ) {
745
+ var Modal = function (element, options) {
659
746
  this.options = options
660
- this.$element = $(content)
747
+ this.$element = $(element)
661
748
  .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
749
+ this.options.remote && this.$element.find('.modal-body').load(this.options.remote)
662
750
  }
663
751
 
664
752
  Modal.prototype = {
@@ -671,19 +759,22 @@
671
759
 
672
760
  , show: function () {
673
761
  var that = this
762
+ , e = $.Event('show')
674
763
 
675
- if (this.isShown) return
764
+ this.$element.trigger(e)
676
765
 
677
- $('body').addClass('modal-open')
766
+ if (this.isShown || e.isDefaultPrevented()) return
678
767
 
679
768
  this.isShown = true
680
- this.$element.trigger('show')
681
769
 
682
- escape.call(this)
683
- backdrop.call(this, function () {
770
+ this.escape()
771
+
772
+ this.backdrop(function () {
684
773
  var transition = $.support.transition && that.$element.hasClass('fade')
685
774
 
686
- !that.$element.parent().length && that.$element.appendTo(document.body) //don't move modals dom position
775
+ if (!that.$element.parent().length) {
776
+ that.$element.appendTo(document.body) //don't move modals dom position
777
+ }
687
778
 
688
779
  that.$element
689
780
  .show()
@@ -692,118 +783,133 @@
692
783
  that.$element[0].offsetWidth // force reflow
693
784
  }
694
785
 
695
- that.$element.addClass('in')
786
+ that.$element
787
+ .addClass('in')
788
+ .attr('aria-hidden', false)
789
+
790
+ that.enforceFocus()
696
791
 
697
792
  transition ?
698
- that.$element.one($.support.transition.end, function () { that.$element.trigger('shown') }) :
699
- that.$element.trigger('shown')
793
+ that.$element.one($.support.transition.end, function () { that.$element.focus().trigger('shown') }) :
794
+ that.$element.focus().trigger('shown')
700
795
 
701
796
  })
702
797
  }
703
798
 
704
- , hide: function ( e ) {
799
+ , hide: function (e) {
705
800
  e && e.preventDefault()
706
801
 
707
- if (!this.isShown) return
708
-
709
802
  var that = this
803
+
804
+ e = $.Event('hide')
805
+
806
+ this.$element.trigger(e)
807
+
808
+ if (!this.isShown || e.isDefaultPrevented()) return
809
+
710
810
  this.isShown = false
711
811
 
712
- $('body').removeClass('modal-open')
812
+ this.escape()
713
813
 
714
- escape.call(this)
814
+ $(document).off('focusin.modal')
715
815
 
716
816
  this.$element
717
- .trigger('hide')
718
817
  .removeClass('in')
818
+ .attr('aria-hidden', true)
719
819
 
720
820
  $.support.transition && this.$element.hasClass('fade') ?
721
- hideWithTransition.call(this) :
722
- hideModal.call(this)
821
+ this.hideWithTransition() :
822
+ this.hideModal()
723
823
  }
724
824
 
725
- }
726
-
727
-
728
- /* MODAL PRIVATE METHODS
729
- * ===================== */
825
+ , enforceFocus: function () {
826
+ var that = this
827
+ $(document).on('focusin.modal', function (e) {
828
+ if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {
829
+ that.$element.focus()
830
+ }
831
+ })
832
+ }
730
833
 
731
- function hideWithTransition() {
732
- var that = this
733
- , timeout = setTimeout(function () {
734
- that.$element.off($.support.transition.end)
735
- hideModal.call(that)
736
- }, 500)
834
+ , escape: function () {
835
+ var that = this
836
+ if (this.isShown && this.options.keyboard) {
837
+ this.$element.on('keyup.dismiss.modal', function ( e ) {
838
+ e.which == 27 && that.hide()
839
+ })
840
+ } else if (!this.isShown) {
841
+ this.$element.off('keyup.dismiss.modal')
842
+ }
843
+ }
737
844
 
738
- this.$element.one($.support.transition.end, function () {
739
- clearTimeout(timeout)
740
- hideModal.call(that)
741
- })
742
- }
845
+ , hideWithTransition: function () {
846
+ var that = this
847
+ , timeout = setTimeout(function () {
848
+ that.$element.off($.support.transition.end)
849
+ that.hideModal()
850
+ }, 500)
743
851
 
744
- function hideModal( that ) {
745
- this.$element
746
- .hide()
747
- .trigger('hidden')
852
+ this.$element.one($.support.transition.end, function () {
853
+ clearTimeout(timeout)
854
+ that.hideModal()
855
+ })
856
+ }
748
857
 
749
- backdrop.call(this)
750
- }
858
+ , hideModal: function (that) {
859
+ this.$element
860
+ .hide()
861
+ .trigger('hidden')
751
862
 
752
- function backdrop( callback ) {
753
- var that = this
754
- , animate = this.$element.hasClass('fade') ? 'fade' : ''
863
+ this.backdrop()
864
+ }
755
865
 
756
- if (this.isShown && this.options.backdrop) {
757
- var doAnimate = $.support.transition && animate
866
+ , removeBackdrop: function () {
867
+ this.$backdrop.remove()
868
+ this.$backdrop = null
869
+ }
758
870
 
759
- this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
760
- .appendTo(document.body)
871
+ , backdrop: function (callback) {
872
+ var that = this
873
+ , animate = this.$element.hasClass('fade') ? 'fade' : ''
761
874
 
762
- if (this.options.backdrop != 'static') {
763
- this.$backdrop.click($.proxy(this.hide, this))
764
- }
875
+ if (this.isShown && this.options.backdrop) {
876
+ var doAnimate = $.support.transition && animate
765
877
 
766
- if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
878
+ this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
879
+ .appendTo(document.body)
767
880
 
768
- this.$backdrop.addClass('in')
881
+ this.$backdrop.click(
882
+ this.options.backdrop == 'static' ?
883
+ $.proxy(this.$element[0].focus, this.$element[0])
884
+ : $.proxy(this.hide, this)
885
+ )
769
886
 
770
- doAnimate ?
771
- this.$backdrop.one($.support.transition.end, callback) :
772
- callback()
887
+ if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
773
888
 
774
- } else if (!this.isShown && this.$backdrop) {
775
- this.$backdrop.removeClass('in')
889
+ this.$backdrop.addClass('in')
776
890
 
777
- $.support.transition && this.$element.hasClass('fade')?
778
- this.$backdrop.one($.support.transition.end, $.proxy(removeBackdrop, this)) :
779
- removeBackdrop.call(this)
891
+ doAnimate ?
892
+ this.$backdrop.one($.support.transition.end, callback) :
893
+ callback()
780
894
 
781
- } else if (callback) {
782
- callback()
783
- }
784
- }
895
+ } else if (!this.isShown && this.$backdrop) {
896
+ this.$backdrop.removeClass('in')
785
897
 
786
- function removeBackdrop() {
787
- this.$backdrop.remove()
788
- this.$backdrop = null
789
- }
898
+ $.support.transition && this.$element.hasClass('fade')?
899
+ this.$backdrop.one($.support.transition.end, $.proxy(this.removeBackdrop, this)) :
900
+ this.removeBackdrop()
790
901
 
791
- function escape() {
792
- var that = this
793
- if (this.isShown && this.options.keyboard) {
794
- $(document).on('keyup.dismiss.modal', function ( e ) {
795
- e.which == 27 && that.hide()
796
- })
797
- } else if (!this.isShown) {
798
- $(document).off('keyup.dismiss.modal')
799
- }
902
+ } else if (callback) {
903
+ callback()
904
+ }
905
+ }
800
906
  }
801
907
 
802
908
 
803
909
  /* MODAL PLUGIN DEFINITION
804
910
  * ======================= */
805
911
 
806
- $.fn.modal = function ( option ) {
912
+ $.fn.modal = function (option) {
807
913
  return this.each(function () {
808
914
  var $this = $(this)
809
915
  , data = $this.data('modal')
@@ -826,19 +932,24 @@
826
932
  /* MODAL DATA-API
827
933
  * ============== */
828
934
 
829
- $(function () {
830
- $('body').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
831
- var $this = $(this), href
832
- , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
833
- , option = $target.data('modal') ? 'toggle' : $.extend({}, $target.data(), $this.data())
935
+ $(document).on('click.modal.data-api', '[data-toggle="modal"]', function (e) {
936
+ var $this = $(this)
937
+ , href = $this.attr('href')
938
+ , $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
939
+ , option = $target.data('modal') ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data())
834
940
 
835
- e.preventDefault()
836
- $target.modal(option)
837
- })
941
+ e.preventDefault()
942
+
943
+ $target
944
+ .modal(option)
945
+ .one('hide', function () {
946
+ $this.focus()
947
+ })
838
948
  })
839
949
 
840
- }( window.jQuery );/* ===========================================================
841
- * bootstrap-tooltip.js v2.0.2
950
+ }(window.jQuery);
951
+ /* ===========================================================
952
+ * bootstrap-tooltip.js v2.2.1
842
953
  * http://twitter.github.com/bootstrap/javascript.html#tooltips
843
954
  * Inspired by the original jQuery.tipsy by Jason Frame
844
955
  * ===========================================================
@@ -857,14 +968,16 @@
857
968
  * limitations under the License.
858
969
  * ========================================================== */
859
970
 
860
- !function( $ ) {
861
971
 
862
- "use strict"
972
+ !function ($) {
973
+
974
+ "use strict"; // jshint ;_;
975
+
863
976
 
864
977
  /* TOOLTIP PUBLIC CLASS DEFINITION
865
978
  * =============================== */
866
979
 
867
- var Tooltip = function ( element, options ) {
980
+ var Tooltip = function (element, options) {
868
981
  this.init('tooltip', element, options)
869
982
  }
870
983
 
@@ -872,7 +985,7 @@
872
985
 
873
986
  constructor: Tooltip
874
987
 
875
- , init: function ( type, element, options ) {
988
+ , init: function (type, element, options) {
876
989
  var eventIn
877
990
  , eventOut
878
991
 
@@ -881,11 +994,13 @@
881
994
  this.options = this.getOptions(options)
882
995
  this.enabled = true
883
996
 
884
- if (this.options.trigger != 'manual') {
885
- eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
997
+ if (this.options.trigger == 'click') {
998
+ this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
999
+ } else if (this.options.trigger != 'manual') {
1000
+ eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
886
1001
  eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
887
- this.$element.on(eventIn, this.options.selector, $.proxy(this.enter, this))
888
- this.$element.on(eventOut, this.options.selector, $.proxy(this.leave, this))
1002
+ this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
1003
+ this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
889
1004
  }
890
1005
 
891
1006
  this.options.selector ?
@@ -893,7 +1008,7 @@
893
1008
  this.fixTitle()
894
1009
  }
895
1010
 
896
- , getOptions: function ( options ) {
1011
+ , getOptions: function (options) {
897
1012
  options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
898
1013
 
899
1014
  if (options.delay && typeof options.delay == 'number') {
@@ -906,34 +1021,28 @@
906
1021
  return options
907
1022
  }
908
1023
 
909
- , enter: function ( e ) {
1024
+ , enter: function (e) {
910
1025
  var self = $(e.currentTarget)[this.type](this._options).data(this.type)
911
1026
 
912
- if (!self.options.delay || !self.options.delay.show) {
913
- self.show()
914
- } else {
915
- self.hoverState = 'in'
916
- setTimeout(function() {
917
- if (self.hoverState == 'in') {
918
- self.show()
919
- }
920
- }, self.options.delay.show)
921
- }
1027
+ if (!self.options.delay || !self.options.delay.show) return self.show()
1028
+
1029
+ clearTimeout(this.timeout)
1030
+ self.hoverState = 'in'
1031
+ this.timeout = setTimeout(function() {
1032
+ if (self.hoverState == 'in') self.show()
1033
+ }, self.options.delay.show)
922
1034
  }
923
1035
 
924
- , leave: function ( e ) {
1036
+ , leave: function (e) {
925
1037
  var self = $(e.currentTarget)[this.type](this._options).data(this.type)
926
1038
 
927
- if (!self.options.delay || !self.options.delay.hide) {
928
- self.hide()
929
- } else {
930
- self.hoverState = 'out'
931
- setTimeout(function() {
932
- if (self.hoverState == 'out') {
933
- self.hide()
934
- }
935
- }, self.options.delay.hide)
936
- }
1039
+ if (this.timeout) clearTimeout(this.timeout)
1040
+ if (!self.options.delay || !self.options.delay.hide) return self.hide()
1041
+
1042
+ self.hoverState = 'out'
1043
+ this.timeout = setTimeout(function() {
1044
+ if (self.hoverState == 'out') self.hide()
1045
+ }, self.options.delay.hide)
937
1046
  }
938
1047
 
939
1048
  , show: function () {
@@ -960,9 +1069,9 @@
960
1069
  inside = /in/.test(placement)
961
1070
 
962
1071
  $tip
963
- .remove()
1072
+ .detach()
964
1073
  .css({ top: 0, left: 0, display: 'block' })
965
- .appendTo(inside ? this.$element : document.body)
1074
+ .insertAfter(this.$element)
966
1075
 
967
1076
  pos = this.getPosition(inside)
968
1077
 
@@ -985,7 +1094,7 @@
985
1094
  }
986
1095
 
987
1096
  $tip
988
- .css(tp)
1097
+ .offset(tp)
989
1098
  .addClass(placement)
990
1099
  .addClass('in')
991
1100
  }
@@ -993,7 +1102,9 @@
993
1102
 
994
1103
  , setContent: function () {
995
1104
  var $tip = this.tip()
996
- $tip.find('.tooltip-inner').html(this.getTitle())
1105
+ , title = this.getTitle()
1106
+
1107
+ $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
997
1108
  $tip.removeClass('fade in top bottom left right')
998
1109
  }
999
1110
 
@@ -1005,18 +1116,20 @@
1005
1116
 
1006
1117
  function removeWithAnimation() {
1007
1118
  var timeout = setTimeout(function () {
1008
- $tip.off($.support.transition.end).remove()
1119
+ $tip.off($.support.transition.end).detach()
1009
1120
  }, 500)
1010
1121
 
1011
1122
  $tip.one($.support.transition.end, function () {
1012
1123
  clearTimeout(timeout)
1013
- $tip.remove()
1124
+ $tip.detach()
1014
1125
  })
1015
1126
  }
1016
1127
 
1017
1128
  $.support.transition && this.$tip.hasClass('fade') ?
1018
1129
  removeWithAnimation() :
1019
- $tip.remove()
1130
+ $tip.detach()
1131
+
1132
+ return this
1020
1133
  }
1021
1134
 
1022
1135
  , fixTitle: function () {
@@ -1045,8 +1158,6 @@
1045
1158
  title = $e.attr('data-original-title')
1046
1159
  || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
1047
1160
 
1048
- title = (title || '').toString().replace(/(^\s*|\s*$)/, "")
1049
-
1050
1161
  return title
1051
1162
  }
1052
1163
 
@@ -1074,8 +1185,13 @@
1074
1185
  this.enabled = !this.enabled
1075
1186
  }
1076
1187
 
1077
- , toggle: function () {
1078
- this[this.tip().hasClass('in') ? 'hide' : 'show']()
1188
+ , toggle: function (e) {
1189
+ var self = $(e.currentTarget)[this.type](this._options).data(this.type)
1190
+ self[self.tip().hasClass('in') ? 'hide' : 'show']()
1191
+ }
1192
+
1193
+ , destroy: function () {
1194
+ this.hide().$element.off('.' + this.type).removeData(this.type)
1079
1195
  }
1080
1196
 
1081
1197
  }
@@ -1098,16 +1214,17 @@
1098
1214
 
1099
1215
  $.fn.tooltip.defaults = {
1100
1216
  animation: true
1101
- , delay: 0
1102
- , selector: false
1103
1217
  , placement: 'top'
1218
+ , selector: false
1219
+ , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
1104
1220
  , trigger: 'hover'
1105
1221
  , title: ''
1106
- , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
1222
+ , delay: 0
1223
+ , html: false
1107
1224
  }
1108
1225
 
1109
- }( window.jQuery );/* ===========================================================
1110
- * bootstrap-popover.js v2.0.2
1226
+ }(window.jQuery);/* ===========================================================
1227
+ * bootstrap-popover.js v2.2.1
1111
1228
  * http://twitter.github.com/bootstrap/javascript.html#popovers
1112
1229
  * ===========================================================
1113
1230
  * Copyright 2012 Twitter, Inc.
@@ -1126,14 +1243,19 @@
1126
1243
  * =========================================================== */
1127
1244
 
1128
1245
 
1129
- !function( $ ) {
1246
+ !function ($) {
1130
1247
 
1131
- "use strict"
1248
+ "use strict"; // jshint ;_;
1132
1249
 
1133
- var Popover = function ( element, options ) {
1250
+
1251
+ /* POPOVER PUBLIC CLASS DEFINITION
1252
+ * =============================== */
1253
+
1254
+ var Popover = function (element, options) {
1134
1255
  this.init('popover', element, options)
1135
1256
  }
1136
1257
 
1258
+
1137
1259
  /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js
1138
1260
  ========================================== */
1139
1261
 
@@ -1146,8 +1268,8 @@
1146
1268
  , title = this.getTitle()
1147
1269
  , content = this.getContent()
1148
1270
 
1149
- $tip.find('.popover-title')[ $.type(title) == 'object' ? 'append' : 'html' ](title)
1150
- $tip.find('.popover-content > *')[ $.type(content) == 'object' ? 'append' : 'html' ](content)
1271
+ $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
1272
+ $tip.find('.popover-content > *')[this.options.html ? 'html' : 'text'](content)
1151
1273
 
1152
1274
  $tip.removeClass('fade top bottom left right in')
1153
1275
  }
@@ -1164,25 +1286,27 @@
1164
1286
  content = $e.attr('data-content')
1165
1287
  || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content)
1166
1288
 
1167
- content = content.toString().replace(/(^\s*|\s*$)/, "")
1168
-
1169
1289
  return content
1170
1290
  }
1171
1291
 
1172
- , tip: function() {
1292
+ , tip: function () {
1173
1293
  if (!this.$tip) {
1174
1294
  this.$tip = $(this.options.template)
1175
1295
  }
1176
1296
  return this.$tip
1177
1297
  }
1178
1298
 
1299
+ , destroy: function () {
1300
+ this.hide().$element.off('.' + this.type).removeData(this.type)
1301
+ }
1302
+
1179
1303
  })
1180
1304
 
1181
1305
 
1182
1306
  /* POPOVER PLUGIN DEFINITION
1183
1307
  * ======================= */
1184
1308
 
1185
- $.fn.popover = function ( option ) {
1309
+ $.fn.popover = function (option) {
1186
1310
  return this.each(function () {
1187
1311
  var $this = $(this)
1188
1312
  , data = $this.data('popover')
@@ -1196,12 +1320,13 @@
1196
1320
 
1197
1321
  $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
1198
1322
  placement: 'right'
1323
+ , trigger: 'click'
1199
1324
  , content: ''
1200
1325
  , 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>'
1201
1326
  })
1202
1327
 
1203
- }( window.jQuery );/* =============================================================
1204
- * bootstrap-scrollspy.js v2.0.2
1328
+ }(window.jQuery);/* =============================================================
1329
+ * bootstrap-scrollspy.js v2.2.1
1205
1330
  * http://twitter.github.com/bootstrap/javascript.html#scrollspy
1206
1331
  * =============================================================
1207
1332
  * Copyright 2012 Twitter, Inc.
@@ -1219,23 +1344,25 @@
1219
1344
  * limitations under the License.
1220
1345
  * ============================================================== */
1221
1346
 
1222
- !function ( $ ) {
1223
1347
 
1224
- "use strict"
1348
+ !function ($) {
1349
+
1350
+ "use strict"; // jshint ;_;
1225
1351
 
1226
- /* SCROLLSPY CLASS DEFINITION
1227
- * ========================== */
1228
1352
 
1229
- function ScrollSpy( element, options) {
1353
+ /* SCROLLSPY CLASS DEFINITION
1354
+ * ========================== */
1355
+
1356
+ function ScrollSpy(element, options) {
1230
1357
  var process = $.proxy(this.process, this)
1231
1358
  , $element = $(element).is('body') ? $(window) : $(element)
1232
1359
  , href
1233
1360
  this.options = $.extend({}, $.fn.scrollspy.defaults, options)
1234
- this.$scrollElement = $element.on('scroll.scroll.data-api', process)
1361
+ this.$scrollElement = $element.on('scroll.scroll-spy.data-api', process)
1235
1362
  this.selector = (this.options.target
1236
1363
  || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
1237
1364
  || '') + ' .nav li > a'
1238
- this.$body = $('body').on('click.scroll.data-api', this.selector, process)
1365
+ this.$body = $('body')
1239
1366
  this.refresh()
1240
1367
  this.process()
1241
1368
  }
@@ -1245,25 +1372,43 @@
1245
1372
  constructor: ScrollSpy
1246
1373
 
1247
1374
  , refresh: function () {
1248
- this.targets = this.$body
1375
+ var self = this
1376
+ , $targets
1377
+
1378
+ this.offsets = $([])
1379
+ this.targets = $([])
1380
+
1381
+ $targets = this.$body
1249
1382
  .find(this.selector)
1250
1383
  .map(function () {
1251
- var href = $(this).attr('href')
1252
- return /^#\w/.test(href) && $(href).length ? href : null
1384
+ var $el = $(this)
1385
+ , href = $el.data('target') || $el.attr('href')
1386
+ , $href = /^#\w/.test(href) && $(href)
1387
+ return ( $href
1388
+ && $href.length
1389
+ && [[ $href.position().top, href ]] ) || null
1390
+ })
1391
+ .sort(function (a, b) { return a[0] - b[0] })
1392
+ .each(function () {
1393
+ self.offsets.push(this[0])
1394
+ self.targets.push(this[1])
1253
1395
  })
1254
-
1255
- this.offsets = $.map(this.targets, function (id) {
1256
- return $(id).position().top
1257
- })
1258
1396
  }
1259
1397
 
1260
1398
  , process: function () {
1261
1399
  var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
1400
+ , scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
1401
+ , maxScroll = scrollHeight - this.$scrollElement.height()
1262
1402
  , offsets = this.offsets
1263
1403
  , targets = this.targets
1264
1404
  , activeTarget = this.activeTarget
1265
1405
  , i
1266
1406
 
1407
+ if (scrollTop >= maxScroll) {
1408
+ return activeTarget != (i = targets.last()[0])
1409
+ && this.activate ( i )
1410
+ }
1411
+
1267
1412
  for (i = offsets.length; i--;) {
1268
1413
  activeTarget != targets[i]
1269
1414
  && scrollTop >= offsets[i]
@@ -1274,21 +1419,27 @@
1274
1419
 
1275
1420
  , activate: function (target) {
1276
1421
  var active
1422
+ , selector
1277
1423
 
1278
1424
  this.activeTarget = target
1279
1425
 
1280
- this.$body
1281
- .find(this.selector).parent('.active')
1426
+ $(this.selector)
1427
+ .parent('.active')
1282
1428
  .removeClass('active')
1283
1429
 
1284
- active = this.$body
1285
- .find(this.selector + '[href="' + target + '"]')
1430
+ selector = this.selector
1431
+ + '[data-target="' + target + '"],'
1432
+ + this.selector + '[href="' + target + '"]'
1433
+
1434
+ active = $(selector)
1286
1435
  .parent('li')
1287
1436
  .addClass('active')
1288
1437
 
1289
- if ( active.parent('.dropdown-menu') ) {
1290
- active.closest('li.dropdown').addClass('active')
1438
+ if (active.parent('.dropdown-menu').length) {
1439
+ active = active.closest('li.dropdown').addClass('active')
1291
1440
  }
1441
+
1442
+ active.trigger('activate')
1292
1443
  }
1293
1444
 
1294
1445
  }
@@ -1297,7 +1448,7 @@
1297
1448
  /* SCROLLSPY PLUGIN DEFINITION
1298
1449
  * =========================== */
1299
1450
 
1300
- $.fn.scrollspy = function ( option ) {
1451
+ $.fn.scrollspy = function (option) {
1301
1452
  return this.each(function () {
1302
1453
  var $this = $(this)
1303
1454
  , data = $this.data('scrollspy')
@@ -1317,15 +1468,15 @@
1317
1468
  /* SCROLLSPY DATA-API
1318
1469
  * ================== */
1319
1470
 
1320
- $(function () {
1471
+ $(window).on('load', function () {
1321
1472
  $('[data-spy="scroll"]').each(function () {
1322
1473
  var $spy = $(this)
1323
1474
  $spy.scrollspy($spy.data())
1324
1475
  })
1325
1476
  })
1326
1477
 
1327
- }( window.jQuery );/* ========================================================
1328
- * bootstrap-tab.js v2.0.2
1478
+ }(window.jQuery);/* ========================================================
1479
+ * bootstrap-tab.js v2.2.1
1329
1480
  * http://twitter.github.com/bootstrap/javascript.html#tabs
1330
1481
  * ========================================================
1331
1482
  * Copyright 2012 Twitter, Inc.
@@ -1344,14 +1495,15 @@
1344
1495
  * ======================================================== */
1345
1496
 
1346
1497
 
1347
- !function( $ ){
1498
+ !function ($) {
1499
+
1500
+ "use strict"; // jshint ;_;
1348
1501
 
1349
- "use strict"
1350
1502
 
1351
1503
  /* TAB CLASS DEFINITION
1352
1504
  * ==================== */
1353
1505
 
1354
- var Tab = function ( element ) {
1506
+ var Tab = function (element) {
1355
1507
  this.element = $(element)
1356
1508
  }
1357
1509
 
@@ -1365,6 +1517,7 @@
1365
1517
  , selector = $this.attr('data-target')
1366
1518
  , previous
1367
1519
  , $target
1520
+ , e
1368
1521
 
1369
1522
  if (!selector) {
1370
1523
  selector = $this.attr('href')
@@ -1373,13 +1526,16 @@
1373
1526
 
1374
1527
  if ( $this.parent('li').hasClass('active') ) return
1375
1528
 
1376
- previous = $ul.find('.active a').last()[0]
1529
+ previous = $ul.find('.active:last a')[0]
1377
1530
 
1378
- $this.trigger({
1379
- type: 'show'
1380
- , relatedTarget: previous
1531
+ e = $.Event('show', {
1532
+ relatedTarget: previous
1381
1533
  })
1382
1534
 
1535
+ $this.trigger(e)
1536
+
1537
+ if (e.isDefaultPrevented()) return
1538
+
1383
1539
  $target = $(selector)
1384
1540
 
1385
1541
  this.activate($this.parent('li'), $ul)
@@ -1446,15 +1602,13 @@
1446
1602
  /* TAB DATA-API
1447
1603
  * ============ */
1448
1604
 
1449
- $(function () {
1450
- $('body').on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
1451
- e.preventDefault()
1452
- $(this).tab('show')
1453
- })
1605
+ $(document).on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
1606
+ e.preventDefault()
1607
+ $(this).tab('show')
1454
1608
  })
1455
1609
 
1456
- }( window.jQuery );/* =============================================================
1457
- * bootstrap-typeahead.js v2.0.2
1610
+ }(window.jQuery);/* =============================================================
1611
+ * bootstrap-typeahead.js v2.2.1
1458
1612
  * http://twitter.github.com/bootstrap/javascript.html#typeahead
1459
1613
  * =============================================================
1460
1614
  * Copyright 2012 Twitter, Inc.
@@ -1472,16 +1626,22 @@
1472
1626
  * limitations under the License.
1473
1627
  * ============================================================ */
1474
1628
 
1475
- !function( $ ){
1476
1629
 
1477
- "use strict"
1630
+ !function($){
1631
+
1632
+ "use strict"; // jshint ;_;
1478
1633
 
1479
- var Typeahead = function ( element, options ) {
1634
+
1635
+ /* TYPEAHEAD PUBLIC CLASS DEFINITION
1636
+ * ================================= */
1637
+
1638
+ var Typeahead = function (element, options) {
1480
1639
  this.$element = $(element)
1481
1640
  this.options = $.extend({}, $.fn.typeahead.defaults, options)
1482
1641
  this.matcher = this.options.matcher || this.matcher
1483
1642
  this.sorter = this.options.sorter || this.sorter
1484
1643
  this.highlighter = this.options.highlighter || this.highlighter
1644
+ this.updater = this.options.updater || this.updater
1485
1645
  this.$menu = $(this.options.menu).appendTo('body')
1486
1646
  this.source = this.options.source
1487
1647
  this.shown = false
@@ -1494,11 +1654,16 @@
1494
1654
 
1495
1655
  , select: function () {
1496
1656
  var val = this.$menu.find('.active').attr('data-value')
1497
- this.$element.val(val)
1498
- this.$element.change();
1657
+ this.$element
1658
+ .val(this.updater(val))
1659
+ .change()
1499
1660
  return this.hide()
1500
1661
  }
1501
1662
 
1663
+ , updater: function (item) {
1664
+ return item
1665
+ }
1666
+
1502
1667
  , show: function () {
1503
1668
  var pos = $.extend({}, this.$element.offset(), {
1504
1669
  height: this.$element[0].offsetHeight
@@ -1521,18 +1686,24 @@
1521
1686
  }
1522
1687
 
1523
1688
  , lookup: function (event) {
1524
- var that = this
1525
- , items
1526
- , q
1689
+ var items
1527
1690
 
1528
1691
  this.query = this.$element.val()
1529
1692
 
1530
- if (!this.query) {
1693
+ if (!this.query || this.query.length < this.options.minLength) {
1531
1694
  return this.shown ? this.hide() : this
1532
1695
  }
1533
1696
 
1534
- items = $.grep(this.source, function (item) {
1535
- if (that.matcher(item)) return item
1697
+ items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source
1698
+
1699
+ return items ? this.process(items) : this
1700
+ }
1701
+
1702
+ , process: function (items) {
1703
+ var that = this
1704
+
1705
+ items = $.grep(items, function (item) {
1706
+ return that.matcher(item)
1536
1707
  })
1537
1708
 
1538
1709
  items = this.sorter(items)
@@ -1564,7 +1735,8 @@
1564
1735
  }
1565
1736
 
1566
1737
  , highlighter: function (item) {
1567
- return item.replace(new RegExp('(' + this.query + ')', 'ig'), function ($1, match) {
1738
+ var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
1739
+ return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
1568
1740
  return '<strong>' + match + '</strong>'
1569
1741
  })
1570
1742
  }
@@ -1611,8 +1783,8 @@
1611
1783
  .on('keypress', $.proxy(this.keypress, this))
1612
1784
  .on('keyup', $.proxy(this.keyup, this))
1613
1785
 
1614
- if ($.browser.webkit || $.browser.msie) {
1615
- this.$element.on('keydown', $.proxy(this.keypress, this))
1786
+ if (this.eventSupported('keydown')) {
1787
+ this.$element.on('keydown', $.proxy(this.keydown, this))
1616
1788
  }
1617
1789
 
1618
1790
  this.$menu
@@ -1620,32 +1792,16 @@
1620
1792
  .on('mouseenter', 'li', $.proxy(this.mouseenter, this))
1621
1793
  }
1622
1794
 
1623
- , keyup: function (e) {
1624
- switch(e.keyCode) {
1625
- case 40: // down arrow
1626
- case 38: // up arrow
1627
- break
1628
-
1629
- case 9: // tab
1630
- case 13: // enter
1631
- if (!this.shown) return
1632
- this.select()
1633
- break
1634
-
1635
- case 27: // escape
1636
- if (!this.shown) return
1637
- this.hide()
1638
- break
1639
-
1640
- default:
1641
- this.lookup()
1795
+ , eventSupported: function(eventName) {
1796
+ var isSupported = eventName in this.$element
1797
+ if (!isSupported) {
1798
+ this.$element.setAttribute(eventName, 'return;')
1799
+ isSupported = typeof this.$element[eventName] === 'function'
1642
1800
  }
1801
+ return isSupported
1802
+ }
1643
1803
 
1644
- e.stopPropagation()
1645
- e.preventDefault()
1646
- }
1647
-
1648
- , keypress: function (e) {
1804
+ , move: function (e) {
1649
1805
  if (!this.shown) return
1650
1806
 
1651
1807
  switch(e.keyCode) {
@@ -1669,6 +1825,44 @@
1669
1825
  e.stopPropagation()
1670
1826
  }
1671
1827
 
1828
+ , keydown: function (e) {
1829
+ this.suppressKeyPressRepeat = !~$.inArray(e.keyCode, [40,38,9,13,27])
1830
+ this.move(e)
1831
+ }
1832
+
1833
+ , keypress: function (e) {
1834
+ if (this.suppressKeyPressRepeat) return
1835
+ this.move(e)
1836
+ }
1837
+
1838
+ , keyup: function (e) {
1839
+ switch(e.keyCode) {
1840
+ case 40: // down arrow
1841
+ case 38: // up arrow
1842
+ case 16: // shift
1843
+ case 17: // ctrl
1844
+ case 18: // alt
1845
+ break
1846
+
1847
+ case 9: // tab
1848
+ case 13: // enter
1849
+ if (!this.shown) return
1850
+ this.select()
1851
+ break
1852
+
1853
+ case 27: // escape
1854
+ if (!this.shown) return
1855
+ this.hide()
1856
+ break
1857
+
1858
+ default:
1859
+ this.lookup()
1860
+ }
1861
+
1862
+ e.stopPropagation()
1863
+ e.preventDefault()
1864
+ }
1865
+
1672
1866
  , blur: function (e) {
1673
1867
  var that = this
1674
1868
  setTimeout(function () { that.hide() }, 150)
@@ -1691,7 +1885,7 @@
1691
1885
  /* TYPEAHEAD PLUGIN DEFINITION
1692
1886
  * =========================== */
1693
1887
 
1694
- $.fn.typeahead = function ( option ) {
1888
+ $.fn.typeahead = function (option) {
1695
1889
  return this.each(function () {
1696
1890
  var $this = $(this)
1697
1891
  , data = $this.data('typeahead')
@@ -1706,21 +1900,126 @@
1706
1900
  , items: 8
1707
1901
  , menu: '<ul class="typeahead dropdown-menu"></ul>'
1708
1902
  , item: '<li><a href="#"></a></li>'
1903
+ , minLength: 1
1709
1904
  }
1710
1905
 
1711
1906
  $.fn.typeahead.Constructor = Typeahead
1712
1907
 
1713
1908
 
1714
- /* TYPEAHEAD DATA-API
1909
+ /* TYPEAHEAD DATA-API
1715
1910
  * ================== */
1716
1911
 
1717
- $(function () {
1718
- $('body').on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
1912
+ $(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
1913
+ var $this = $(this)
1914
+ if ($this.data('typeahead')) return
1915
+ e.preventDefault()
1916
+ $this.typeahead($this.data())
1917
+ })
1918
+
1919
+ }(window.jQuery);
1920
+ /* ==========================================================
1921
+ * bootstrap-affix.js v2.2.1
1922
+ * http://twitter.github.com/bootstrap/javascript.html#affix
1923
+ * ==========================================================
1924
+ * Copyright 2012 Twitter, Inc.
1925
+ *
1926
+ * Licensed under the Apache License, Version 2.0 (the "License");
1927
+ * you may not use this file except in compliance with the License.
1928
+ * You may obtain a copy of the License at
1929
+ *
1930
+ * http://www.apache.org/licenses/LICENSE-2.0
1931
+ *
1932
+ * Unless required by applicable law or agreed to in writing, software
1933
+ * distributed under the License is distributed on an "AS IS" BASIS,
1934
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1935
+ * See the License for the specific language governing permissions and
1936
+ * limitations under the License.
1937
+ * ========================================================== */
1938
+
1939
+
1940
+ !function ($) {
1941
+
1942
+ "use strict"; // jshint ;_;
1943
+
1944
+
1945
+ /* AFFIX CLASS DEFINITION
1946
+ * ====================== */
1947
+
1948
+ var Affix = function (element, options) {
1949
+ this.options = $.extend({}, $.fn.affix.defaults, options)
1950
+ this.$window = $(window)
1951
+ .on('scroll.affix.data-api', $.proxy(this.checkPosition, this))
1952
+ .on('click.affix.data-api', $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this))
1953
+ this.$element = $(element)
1954
+ this.checkPosition()
1955
+ }
1956
+
1957
+ Affix.prototype.checkPosition = function () {
1958
+ if (!this.$element.is(':visible')) return
1959
+
1960
+ var scrollHeight = $(document).height()
1961
+ , scrollTop = this.$window.scrollTop()
1962
+ , position = this.$element.offset()
1963
+ , offset = this.options.offset
1964
+ , offsetBottom = offset.bottom
1965
+ , offsetTop = offset.top
1966
+ , reset = 'affix affix-top affix-bottom'
1967
+ , affix
1968
+
1969
+ if (typeof offset != 'object') offsetBottom = offsetTop = offset
1970
+ if (typeof offsetTop == 'function') offsetTop = offset.top()
1971
+ if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()
1972
+
1973
+ affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ?
1974
+ false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ?
1975
+ 'bottom' : offsetTop != null && scrollTop <= offsetTop ?
1976
+ 'top' : false
1977
+
1978
+ if (this.affixed === affix) return
1979
+
1980
+ this.affixed = affix
1981
+ this.unpin = affix == 'bottom' ? position.top - scrollTop : null
1982
+
1983
+ this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : ''))
1984
+ }
1985
+
1986
+
1987
+ /* AFFIX PLUGIN DEFINITION
1988
+ * ======================= */
1989
+
1990
+ $.fn.affix = function (option) {
1991
+ return this.each(function () {
1719
1992
  var $this = $(this)
1720
- if ($this.data('typeahead')) return
1721
- e.preventDefault()
1722
- $this.typeahead($this.data())
1993
+ , data = $this.data('affix')
1994
+ , options = typeof option == 'object' && option
1995
+ if (!data) $this.data('affix', (data = new Affix(this, options)))
1996
+ if (typeof option == 'string') data[option]()
1997
+ })
1998
+ }
1999
+
2000
+ $.fn.affix.Constructor = Affix
2001
+
2002
+ $.fn.affix.defaults = {
2003
+ offset: 0
2004
+ }
2005
+
2006
+
2007
+ /* AFFIX DATA-API
2008
+ * ============== */
2009
+
2010
+ $(window).on('load', function () {
2011
+ $('[data-spy="affix"]').each(function () {
2012
+ var $spy = $(this)
2013
+ , data = $spy.data()
2014
+
2015
+ data.offset = data.offset || {}
2016
+
2017
+ data.offsetBottom && (data.offset.bottom = data.offsetBottom)
2018
+ data.offsetTop && (data.offset.top = data.offsetTop)
2019
+
2020
+ $spy.affix(data)
1723
2021
  })
1724
2022
  })
1725
2023
 
1726
- }( window.jQuery );
2024
+
2025
+ }(window.jQuery);