twbs_sass_rails 0.9.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/README.md +1 -1
  4. data/app/assets/fonts/glyphicons-halflings-regular.svg +1 -1
  5. data/lib/twbs_sass_rails/version.rb +1 -1
  6. data/twbs_sass_rails.gemspec +6 -6
  7. data/vendor/assets/javascripts/twbs/bootstrap/affix.js +43 -23
  8. data/vendor/assets/javascripts/twbs/bootstrap/alert.js +6 -4
  9. data/vendor/assets/javascripts/twbs/bootstrap/button.js +16 -10
  10. data/vendor/assets/javascripts/twbs/bootstrap/carousel.js +26 -10
  11. data/vendor/assets/javascripts/twbs/bootstrap/collapse.js +69 -28
  12. data/vendor/assets/javascripts/twbs/bootstrap/dropdown.js +20 -10
  13. data/vendor/assets/javascripts/twbs/bootstrap/modal.js +22 -21
  14. data/vendor/assets/javascripts/twbs/bootstrap/popover.js +13 -7
  15. data/vendor/assets/javascripts/twbs/bootstrap/scrollspy.js +12 -7
  16. data/vendor/assets/javascripts/twbs/bootstrap/tab.js +41 -16
  17. data/vendor/assets/javascripts/twbs/bootstrap/tooltip.js +60 -39
  18. data/vendor/assets/javascripts/twbs/bootstrap/transition.js +1 -1
  19. data/vendor/assets/stylesheets/twbs/bootstrap/_button-groups.scss +18 -11
  20. data/vendor/assets/stylesheets/twbs/bootstrap/_buttons.scss +8 -5
  21. data/vendor/assets/stylesheets/twbs/bootstrap/_carousel.scss +25 -1
  22. data/vendor/assets/stylesheets/twbs/bootstrap/_code.scss +1 -0
  23. data/vendor/assets/stylesheets/twbs/bootstrap/_component-animations.scss +5 -2
  24. data/vendor/assets/stylesheets/twbs/bootstrap/_dropdowns.scss +4 -6
  25. data/vendor/assets/stylesheets/twbs/bootstrap/_forms.scss +51 -28
  26. data/vendor/assets/stylesheets/twbs/bootstrap/_glyphicons.scss +2 -1
  27. data/vendor/assets/stylesheets/twbs/bootstrap/_grid.scss +4 -4
  28. data/vendor/assets/stylesheets/twbs/bootstrap/_jumbotron.scss +4 -4
  29. data/vendor/assets/stylesheets/twbs/bootstrap/_list-group.scss +1 -0
  30. data/vendor/assets/stylesheets/twbs/bootstrap/_media.scss +27 -36
  31. data/vendor/assets/stylesheets/twbs/bootstrap/_modals.scss +3 -4
  32. data/vendor/assets/stylesheets/twbs/bootstrap/_navbar.scss +35 -33
  33. data/vendor/assets/stylesheets/twbs/bootstrap/_navs.scss +5 -3
  34. data/vendor/assets/stylesheets/twbs/bootstrap/_normalize.scss +5 -3
  35. data/vendor/assets/stylesheets/twbs/bootstrap/_pager.scss +2 -3
  36. data/vendor/assets/stylesheets/twbs/bootstrap/_pagination.scss +1 -1
  37. data/vendor/assets/stylesheets/twbs/bootstrap/_panels.scss +22 -4
  38. data/vendor/assets/stylesheets/twbs/bootstrap/_popovers.scss +5 -4
  39. data/vendor/assets/stylesheets/twbs/bootstrap/_print.scss +102 -96
  40. data/vendor/assets/stylesheets/twbs/bootstrap/_progress-bars.scss +2 -20
  41. data/vendor/assets/stylesheets/twbs/bootstrap/_responsive-embed.scss +2 -1
  42. data/vendor/assets/stylesheets/twbs/bootstrap/_scaffolding.scss +3 -3
  43. data/vendor/assets/stylesheets/twbs/bootstrap/_tables.scss +11 -10
  44. data/vendor/assets/stylesheets/twbs/bootstrap/_theme.scss +16 -14
  45. data/vendor/assets/stylesheets/twbs/bootstrap/_thumbnails.scss +2 -2
  46. data/vendor/assets/stylesheets/twbs/bootstrap/_type.scss +10 -16
  47. data/vendor/assets/stylesheets/twbs/bootstrap/_utilities.scss +3 -4
  48. data/vendor/assets/stylesheets/twbs/bootstrap/_variables.scss +29 -19
  49. data/vendor/assets/stylesheets/twbs/bootstrap/mixins/_buttons.scss +2 -0
  50. data/vendor/assets/stylesheets/twbs/bootstrap/mixins/_forms.scss +5 -1
  51. data/vendor/assets/stylesheets/twbs/bootstrap/mixins/_grid.scss +2 -2
  52. data/vendor/assets/stylesheets/twbs/bootstrap/mixins/_hide-text.scss +1 -1
  53. data/vendor/assets/stylesheets/twbs/bootstrap/mixins/_image.scss +0 -1
  54. data/vendor/assets/stylesheets/twbs/bootstrap/mixins/_labels.scss +1 -1
  55. data/vendor/assets/stylesheets/twbs/bootstrap/mixins/_progress-bar.scss +1 -1
  56. data/vendor/assets/stylesheets/twbs/bootstrap/mixins/_vendor-prefixes.scss +6 -3
  57. metadata +24 -30
@@ -1,5 +1,5 @@
1
1
  /* ========================================================================
2
- * Bootstrap: modal.js v3.2.0
2
+ * Bootstrap: modal.js v3.3.0
3
3
  * http://getbootstrap.com/javascript/#modals
4
4
  * ========================================================================
5
5
  * Copyright 2011-2014 Twitter, Inc.
@@ -30,7 +30,10 @@
30
30
  }
31
31
  }
32
32
 
33
- Modal.VERSION = '3.2.0'
33
+ Modal.VERSION = '3.3.0'
34
+
35
+ Modal.TRANSITION_DURATION = 300
36
+ Modal.BACKDROP_TRANSITION_DURATION = 150
34
37
 
35
38
  Modal.DEFAULTS = {
36
39
  backdrop: true,
@@ -88,7 +91,7 @@
88
91
  .one('bsTransitionEnd', function () {
89
92
  that.$element.trigger('focus').trigger(e)
90
93
  })
91
- .emulateTransitionEnd(300) :
94
+ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
92
95
  that.$element.trigger('focus').trigger(e)
93
96
  })
94
97
  }
@@ -104,9 +107,6 @@
104
107
 
105
108
  this.isShown = false
106
109
 
107
- this.$body.removeClass('modal-open')
108
-
109
- this.resetScrollbar()
110
110
  this.escape()
111
111
 
112
112
  $(document).off('focusin.bs.modal')
@@ -119,7 +119,7 @@
119
119
  $.support.transition && this.$element.hasClass('fade') ?
120
120
  this.$element
121
121
  .one('bsTransitionEnd', $.proxy(this.hideModal, this))
122
- .emulateTransitionEnd(300) :
122
+ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
123
123
  this.hideModal()
124
124
  }
125
125
 
@@ -135,11 +135,11 @@
135
135
 
136
136
  Modal.prototype.escape = function () {
137
137
  if (this.isShown && this.options.keyboard) {
138
- this.$element.on('keyup.dismiss.bs.modal', $.proxy(function (e) {
138
+ this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
139
139
  e.which == 27 && this.hide()
140
140
  }, this))
141
141
  } else if (!this.isShown) {
142
- this.$element.off('keyup.dismiss.bs.modal')
142
+ this.$element.off('keydown.dismiss.bs.modal')
143
143
  }
144
144
  }
145
145
 
@@ -147,6 +147,8 @@
147
147
  var that = this
148
148
  this.$element.hide()
149
149
  this.backdrop(function () {
150
+ that.$body.removeClass('modal-open')
151
+ that.resetScrollbar()
150
152
  that.$element.trigger('hidden.bs.modal')
151
153
  })
152
154
  }
@@ -164,14 +166,13 @@
164
166
  var doAnimate = $.support.transition && animate
165
167
 
166
168
  this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
167
- .appendTo(this.$body)
168
-
169
- this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
170
- if (e.target !== e.currentTarget) return
171
- this.options.backdrop == 'static'
172
- ? this.$element[0].focus.call(this.$element[0])
173
- : this.hide.call(this)
174
- }, this))
169
+ .prependTo(this.$element)
170
+ .on('click.dismiss.bs.modal', $.proxy(function (e) {
171
+ if (e.target !== e.currentTarget) return
172
+ this.options.backdrop == 'static'
173
+ ? this.$element[0].focus.call(this.$element[0])
174
+ : this.hide.call(this)
175
+ }, this))
175
176
 
176
177
  if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
177
178
 
@@ -182,7 +183,7 @@
182
183
  doAnimate ?
183
184
  this.$backdrop
184
185
  .one('bsTransitionEnd', callback)
185
- .emulateTransitionEnd(150) :
186
+ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
186
187
  callback()
187
188
 
188
189
  } else if (!this.isShown && this.$backdrop) {
@@ -195,7 +196,7 @@
195
196
  $.support.transition && this.$element.hasClass('fade') ?
196
197
  this.$backdrop
197
198
  .one('bsTransitionEnd', callbackRemove)
198
- .emulateTransitionEnd(150) :
199
+ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
199
200
  callbackRemove()
200
201
 
201
202
  } else if (callback) {
@@ -204,8 +205,7 @@
204
205
  }
205
206
 
206
207
  Modal.prototype.checkScrollbar = function () {
207
- if (document.body.clientWidth >= window.innerWidth) return
208
- this.scrollbarWidth = this.scrollbarWidth || this.measureScrollbar()
208
+ this.scrollbarWidth = this.measureScrollbar()
209
209
  }
210
210
 
211
211
  Modal.prototype.setScrollbar = function () {
@@ -218,6 +218,7 @@
218
218
  }
219
219
 
220
220
  Modal.prototype.measureScrollbar = function () { // thx walsh
221
+ if (document.body.clientWidth >= window.innerWidth) return 0
221
222
  var scrollDiv = document.createElement('div')
222
223
  scrollDiv.className = 'modal-scrollbar-measure'
223
224
  this.$body.append(scrollDiv)
@@ -1,5 +1,5 @@
1
1
  /* ========================================================================
2
- * Bootstrap: popover.js v3.2.0
2
+ * Bootstrap: popover.js v3.3.0
3
3
  * http://getbootstrap.com/javascript/#popovers
4
4
  * ========================================================================
5
5
  * Copyright 2011-2014 Twitter, Inc.
@@ -19,7 +19,7 @@
19
19
 
20
20
  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
21
21
 
22
- Popover.VERSION = '3.2.0'
22
+ Popover.VERSION = '3.3.0'
23
23
 
24
24
  Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
25
25
  placement: 'right',
@@ -46,7 +46,7 @@
46
46
  var content = this.getContent()
47
47
 
48
48
  $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
49
- $tip.find('.popover-content').empty()[ // we use append for html objects to maintain js events
49
+ $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
50
50
  this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
51
51
  ](content)
52
52
 
@@ -86,12 +86,18 @@
86
86
 
87
87
  function Plugin(option) {
88
88
  return this.each(function () {
89
- var $this = $(this)
90
- var data = $this.data('bs.popover')
91
- var options = typeof option == 'object' && option
89
+ var $this = $(this)
90
+ var data = $this.data('bs.popover')
91
+ var options = typeof option == 'object' && option
92
+ var selector = options && options.selector
92
93
 
93
94
  if (!data && option == 'destroy') return
94
- if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
95
+ if (selector) {
96
+ if (!data) $this.data('bs.popover', (data = {}))
97
+ if (!data[selector]) data[selector] = new Popover(this, options)
98
+ } else {
99
+ if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
100
+ }
95
101
  if (typeof option == 'string') data[option]()
96
102
  })
97
103
  }
@@ -1,5 +1,5 @@
1
1
  /* ========================================================================
2
- * Bootstrap: scrollspy.js v3.2.0
2
+ * Bootstrap: scrollspy.js v3.3.0
3
3
  * http://getbootstrap.com/javascript/#scrollspy
4
4
  * ========================================================================
5
5
  * Copyright 2011-2014 Twitter, Inc.
@@ -30,7 +30,7 @@
30
30
  this.process()
31
31
  }
32
32
 
33
- ScrollSpy.VERSION = '3.2.0'
33
+ ScrollSpy.VERSION = '3.3.0'
34
34
 
35
35
  ScrollSpy.DEFAULTS = {
36
36
  offset: 10
@@ -91,8 +91,9 @@
91
91
  return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
92
92
  }
93
93
 
94
- if (activeTarget && scrollTop <= offsets[0]) {
95
- return activeTarget != (i = targets[0]) && this.activate(i)
94
+ if (activeTarget && scrollTop < offsets[0]) {
95
+ this.activeTarget = null
96
+ return this.clear()
96
97
  }
97
98
 
98
99
  for (i = offsets.length; i--;) {
@@ -106,9 +107,7 @@
106
107
  ScrollSpy.prototype.activate = function (target) {
107
108
  this.activeTarget = target
108
109
 
109
- $(this.selector)
110
- .parentsUntil(this.options.target, '.active')
111
- .removeClass('active')
110
+ this.clear()
112
111
 
113
112
  var selector = this.selector +
114
113
  '[data-target="' + target + '"],' +
@@ -127,6 +126,12 @@
127
126
  active.trigger('activate.bs.scrollspy')
128
127
  }
129
128
 
129
+ ScrollSpy.prototype.clear = function () {
130
+ $(this.selector)
131
+ .parentsUntil(this.options.target, '.active')
132
+ .removeClass('active')
133
+ }
134
+
130
135
 
131
136
  // SCROLLSPY PLUGIN DEFINITION
132
137
  // ===========================
@@ -1,5 +1,5 @@
1
1
  /* ========================================================================
2
- * Bootstrap: tab.js v3.2.0
2
+ * Bootstrap: tab.js v3.3.0
3
3
  * http://getbootstrap.com/javascript/#tabs
4
4
  * ========================================================================
5
5
  * Copyright 2011-2014 Twitter, Inc.
@@ -17,7 +17,9 @@
17
17
  this.element = $(element)
18
18
  }
19
19
 
20
- Tab.VERSION = '3.2.0'
20
+ Tab.VERSION = '3.3.0'
21
+
22
+ Tab.TRANSITION_DURATION = 150
21
23
 
22
24
  Tab.prototype.show = function () {
23
25
  var $this = this.element
@@ -31,22 +33,30 @@
31
33
 
32
34
  if ($this.parent('li').hasClass('active')) return
33
35
 
34
- var previous = $ul.find('.active:last a')[0]
35
- var e = $.Event('show.bs.tab', {
36
- relatedTarget: previous
36
+ var $previous = $ul.find('.active:last a')
37
+ var hideEvent = $.Event('hide.bs.tab', {
38
+ relatedTarget: $this[0]
39
+ })
40
+ var showEvent = $.Event('show.bs.tab', {
41
+ relatedTarget: $previous[0]
37
42
  })
38
43
 
39
- $this.trigger(e)
44
+ $previous.trigger(hideEvent)
45
+ $this.trigger(showEvent)
40
46
 
41
- if (e.isDefaultPrevented()) return
47
+ if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
42
48
 
43
49
  var $target = $(selector)
44
50
 
45
51
  this.activate($this.closest('li'), $ul)
46
52
  this.activate($target, $target.parent(), function () {
53
+ $previous.trigger({
54
+ type: 'hidden.bs.tab',
55
+ relatedTarget: $this[0]
56
+ })
47
57
  $this.trigger({
48
58
  type: 'shown.bs.tab',
49
- relatedTarget: previous
59
+ relatedTarget: $previous[0]
50
60
  })
51
61
  })
52
62
  }
@@ -55,15 +65,21 @@
55
65
  var $active = container.find('> .active')
56
66
  var transition = callback
57
67
  && $.support.transition
58
- && $active.hasClass('fade')
68
+ && (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length)
59
69
 
60
70
  function next() {
61
71
  $active
62
72
  .removeClass('active')
63
73
  .find('> .dropdown-menu > .active')
64
- .removeClass('active')
74
+ .removeClass('active')
75
+ .end()
76
+ .find('[data-toggle="tab"]')
77
+ .attr('aria-expanded', false)
65
78
 
66
- element.addClass('active')
79
+ element
80
+ .addClass('active')
81
+ .find('[data-toggle="tab"]')
82
+ .attr('aria-expanded', true)
67
83
 
68
84
  if (transition) {
69
85
  element[0].offsetWidth // reflow for transition
@@ -73,16 +89,21 @@
73
89
  }
74
90
 
75
91
  if (element.parent('.dropdown-menu')) {
76
- element.closest('li.dropdown').addClass('active')
92
+ element
93
+ .closest('li.dropdown')
94
+ .addClass('active')
95
+ .end()
96
+ .find('[data-toggle="tab"]')
97
+ .attr('aria-expanded', true)
77
98
  }
78
99
 
79
100
  callback && callback()
80
101
  }
81
102
 
82
- transition ?
103
+ $active.length && transition ?
83
104
  $active
84
105
  .one('bsTransitionEnd', next)
85
- .emulateTransitionEnd(150) :
106
+ .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
86
107
  next()
87
108
 
88
109
  $active.removeClass('in')
@@ -120,9 +141,13 @@
120
141
  // TAB DATA-API
121
142
  // ============
122
143
 
123
- $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
144
+ var clickHandler = function (e) {
124
145
  e.preventDefault()
125
146
  Plugin.call($(this), 'show')
126
- })
147
+ }
148
+
149
+ $(document)
150
+ .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
151
+ .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
127
152
 
128
153
  }(jQuery);
@@ -1,5 +1,5 @@
1
1
  /* ========================================================================
2
- * Bootstrap: tooltip.js v3.2.0
2
+ * Bootstrap: tooltip.js v3.3.0
3
3
  * http://getbootstrap.com/javascript/#tooltip
4
4
  * Inspired by the original jQuery.tipsy by Jason Frame
5
5
  * ========================================================================
@@ -25,7 +25,9 @@
25
25
  this.init('tooltip', element, options)
26
26
  }
27
27
 
28
- Tooltip.VERSION = '3.2.0'
28
+ Tooltip.VERSION = '3.3.0'
29
+
30
+ Tooltip.TRANSITION_DURATION = 150
29
31
 
30
32
  Tooltip.DEFAULTS = {
31
33
  animation: true,
@@ -103,6 +105,11 @@
103
105
  var self = obj instanceof this.constructor ?
104
106
  obj : $(obj.currentTarget).data('bs.' + this.type)
105
107
 
108
+ if (self && self.$tip && self.$tip.is(':visible')) {
109
+ self.hoverState = 'in'
110
+ return
111
+ }
112
+
106
113
  if (!self) {
107
114
  self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
108
115
  $(obj.currentTarget).data('bs.' + this.type, self)
@@ -145,7 +152,7 @@
145
152
  if (this.hasContent() && this.enabled) {
146
153
  this.$element.trigger(e)
147
154
 
148
- var inDom = $.contains(document.documentElement, this.$element[0])
155
+ var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
149
156
  if (e.isDefaultPrevented() || !inDom) return
150
157
  var that = this
151
158
 
@@ -181,13 +188,13 @@
181
188
 
182
189
  if (autoPlace) {
183
190
  var orgPlacement = placement
184
- var $parent = this.$element.parent()
185
- var parentDim = this.getPosition($parent)
191
+ var $container = this.options.container ? $(this.options.container) : this.$element.parent()
192
+ var containerDim = this.getPosition($container)
186
193
 
187
- placement = placement == 'bottom' && pos.top + pos.height + actualHeight - parentDim.scroll > parentDim.height ? 'top' :
188
- placement == 'top' && pos.top - parentDim.scroll - actualHeight < 0 ? 'bottom' :
189
- placement == 'right' && pos.right + actualWidth > parentDim.width ? 'left' :
190
- placement == 'left' && pos.left - actualWidth < parentDim.left ? 'right' :
194
+ placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top' :
195
+ placement == 'top' && pos.top - actualHeight < containerDim.top ? 'bottom' :
196
+ placement == 'right' && pos.right + actualWidth > containerDim.width ? 'left' :
197
+ placement == 'left' && pos.left - actualWidth < containerDim.left ? 'right' :
191
198
  placement
192
199
 
193
200
  $tip
@@ -200,14 +207,17 @@
200
207
  this.applyPlacement(calculatedOffset, placement)
201
208
 
202
209
  var complete = function () {
210
+ var prevHoverState = that.hoverState
203
211
  that.$element.trigger('shown.bs.' + that.type)
204
212
  that.hoverState = null
213
+
214
+ if (prevHoverState == 'out') that.leave(that)
205
215
  }
206
216
 
207
217
  $.support.transition && this.$tip.hasClass('fade') ?
208
218
  $tip
209
219
  .one('bsTransitionEnd', complete)
210
- .emulateTransitionEnd(150) :
220
+ .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
211
221
  complete()
212
222
  }
213
223
  }
@@ -254,16 +264,18 @@
254
264
  if (delta.left) offset.left += delta.left
255
265
  else offset.top += delta.top
256
266
 
257
- var arrowDelta = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
258
- var arrowPosition = delta.left ? 'left' : 'top'
259
- var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight'
267
+ var isVertical = /top|bottom/.test(placement)
268
+ var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
269
+ var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
260
270
 
261
271
  $tip.offset(offset)
262
- this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition)
272
+ this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
263
273
  }
264
274
 
265
- Tooltip.prototype.replaceArrow = function (delta, dimension, position) {
266
- this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '')
275
+ Tooltip.prototype.replaceArrow = function (delta, dimension, isHorizontal) {
276
+ this.arrow()
277
+ .css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
278
+ .css(isHorizontal ? 'top' : 'left', '')
267
279
  }
268
280
 
269
281
  Tooltip.prototype.setContent = function () {
@@ -274,16 +286,17 @@
274
286
  $tip.removeClass('fade in top bottom left right')
275
287
  }
276
288
 
277
- Tooltip.prototype.hide = function () {
289
+ Tooltip.prototype.hide = function (callback) {
278
290
  var that = this
279
291
  var $tip = this.tip()
280
292
  var e = $.Event('hide.bs.' + this.type)
281
293
 
282
- this.$element.removeAttr('aria-describedby')
283
-
284
294
  function complete() {
285
295
  if (that.hoverState != 'in') $tip.detach()
286
- that.$element.trigger('hidden.bs.' + that.type)
296
+ that.$element
297
+ .removeAttr('aria-describedby')
298
+ .trigger('hidden.bs.' + that.type)
299
+ callback && callback()
287
300
  }
288
301
 
289
302
  this.$element.trigger(e)
@@ -295,7 +308,7 @@
295
308
  $.support.transition && this.$tip.hasClass('fade') ?
296
309
  $tip
297
310
  .one('bsTransitionEnd', complete)
298
- .emulateTransitionEnd(150) :
311
+ .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
299
312
  complete()
300
313
 
301
314
  this.hoverState = null
@@ -316,13 +329,20 @@
316
329
 
317
330
  Tooltip.prototype.getPosition = function ($element) {
318
331
  $element = $element || this.$element
332
+
319
333
  var el = $element[0]
320
334
  var isBody = el.tagName == 'BODY'
321
- return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, {
322
- scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(),
323
- width: isBody ? $(window).width() : $element.outerWidth(),
324
- height: isBody ? $(window).height() : $element.outerHeight()
325
- }, isBody ? { top: 0, left: 0 } : $element.offset())
335
+
336
+ var elRect = el.getBoundingClientRect()
337
+ if (elRect.width == null) {
338
+ // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
339
+ elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
340
+ }
341
+ var elOffset = isBody ? { top: 0, left: 0 } : $element.offset()
342
+ var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
343
+ var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
344
+
345
+ return $.extend({}, elRect, scroll, outerDims, elOffset)
326
346
  }
327
347
 
328
348
  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
@@ -386,14 +406,6 @@
386
406
  return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
387
407
  }
388
408
 
389
- Tooltip.prototype.validate = function () {
390
- if (!this.$element[0].parentNode) {
391
- this.hide()
392
- this.$element = null
393
- this.options = null
394
- }
395
- }
396
-
397
409
  Tooltip.prototype.enable = function () {
398
410
  this.enabled = true
399
411
  }
@@ -420,8 +432,11 @@
420
432
  }
421
433
 
422
434
  Tooltip.prototype.destroy = function () {
435
+ var that = this
423
436
  clearTimeout(this.timeout)
424
- this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)
437
+ this.hide(function () {
438
+ that.$element.off('.' + that.type).removeData('bs.' + that.type)
439
+ })
425
440
  }
426
441
 
427
442
 
@@ -430,12 +445,18 @@
430
445
 
431
446
  function Plugin(option) {
432
447
  return this.each(function () {
433
- var $this = $(this)
434
- var data = $this.data('bs.tooltip')
435
- var options = typeof option == 'object' && option
448
+ var $this = $(this)
449
+ var data = $this.data('bs.tooltip')
450
+ var options = typeof option == 'object' && option
451
+ var selector = options && options.selector
436
452
 
437
453
  if (!data && option == 'destroy') return
438
- if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
454
+ if (selector) {
455
+ if (!data) $this.data('bs.tooltip', (data = {}))
456
+ if (!data[selector]) data[selector] = new Tooltip(this, options)
457
+ } else {
458
+ if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
459
+ }
439
460
  if (typeof option == 'string') data[option]()
440
461
  })
441
462
  }
@@ -1,5 +1,5 @@
1
1
  /* ========================================================================
2
- * Bootstrap: transition.js v3.2.0
2
+ * Bootstrap: transition.js v3.3.0
3
3
  * http://getbootstrap.com/javascript/#transitions
4
4
  * ========================================================================
5
5
  * Copyright 2011-2014 Twitter, Inc.
@@ -38,7 +38,7 @@
38
38
  // Optional: Group multiple button groups together for a toolbar
39
39
  .btn-toolbar {
40
40
  margin-left: -5px; // Offset the first child's margin
41
- @include clearfix();
41
+ @include clearfix;
42
42
 
43
43
  .btn-group,
44
44
  .input-group {
@@ -156,7 +156,7 @@
156
156
 
157
157
  // Clear floats so dropdown menus can be properly placed
158
158
  > .btn-group {
159
- @include clearfix();
159
+ @include clearfix;
160
160
  > .btn {
161
161
  float: none;
162
162
  }
@@ -198,7 +198,6 @@
198
198
  }
199
199
 
200
200
 
201
-
202
201
  // Justified button groups
203
202
  // ----------------------
204
203
 
@@ -226,15 +225,23 @@
226
225
  // Checkbox and radio options
227
226
  //
228
227
  // In order to support the browser's form validation feedback, powered by the
229
- // `required` attribute, we have to "hide" the inputs via `opacity`. We cannot
230
- // use `display: none;` or `visibility: hidden;` as that also hides the popover.
228
+ // `required` attribute, we have to "hide" the inputs via `clip`. We cannot use
229
+ // `display: none;` or `visibility: hidden;` as that also hides the popover.
230
+ // Simply visually hiding the inputs via `opacity` would leave them clickable in
231
+ // certain cases which is prevented by using `clip` and `pointer-events`.
231
232
  // This way, we ensure a DOM element is visible to position the popover from.
232
233
  //
233
- // See https://github.com/twbs/bootstrap/pull/12794 for more.
234
+ // See https://github.com/twbs/bootstrap/pull/12794 and
235
+ // https://github.com/twbs/bootstrap/pull/14559 for more information.
234
236
 
235
- [data-toggle="buttons"] > .btn > input[type="radio"],
236
- [data-toggle="buttons"] > .btn > input[type="checkbox"] {
237
- position: absolute;
238
- z-index: -1;
239
- @include opacity(0);
237
+ [data-toggle="buttons"] {
238
+ > .btn,
239
+ > .btn-group > .btn {
240
+ input[type="radio"],
241
+ input[type="checkbox"] {
242
+ position: absolute;
243
+ clip: rect(0,0,0,0);
244
+ pointer-events: none;
245
+ }
246
+ }
240
247
  }
@@ -12,6 +12,7 @@
12
12
  font-weight: $btn-font-weight;
13
13
  text-align: center;
14
14
  vertical-align: middle;
15
+ touch-action: manipulation;
15
16
  cursor: pointer;
16
17
  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
17
18
  border: 1px solid transparent;
@@ -22,13 +23,15 @@
22
23
  &,
23
24
  &:active,
24
25
  &.active {
25
- &:focus {
26
- @include tab-focus();
26
+ &:focus,
27
+ &.focus {
28
+ @include tab-focus;
27
29
  }
28
30
  }
29
31
 
30
32
  &:hover,
31
- &:focus {
33
+ &:focus,
34
+ &.focus {
32
35
  color: $btn-default-color;
33
36
  text-decoration: none;
34
37
  }
@@ -43,7 +46,7 @@
43
46
  &.disabled,
44
47
  &[disabled],
45
48
  fieldset[disabled] & {
46
- cursor: not-allowed;
49
+ cursor: $cursor-disabled;
47
50
  pointer-events: none; // Future-proof disabling of clicks
48
51
  @include opacity(.65);
49
52
  @include box-shadow(none);
@@ -85,11 +88,11 @@
85
88
  .btn-link {
86
89
  color: $link-color;
87
90
  font-weight: normal;
88
- cursor: pointer;
89
91
  border-radius: 0;
90
92
 
91
93
  &,
92
94
  &:active,
95
+ &.active,
93
96
  &[disabled],
94
97
  fieldset[disabled] & {
95
98
  background-color: transparent;