anjlab-bootstrap-rails 3.0.0.0.alpha1 → 3.0.0.rc1

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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -27
  3. data/Rakefile +11 -35
  4. data/{vendor → app}/assets/javascripts/twitter/bootstrap.js +6 -6
  5. data/{vendor → app}/assets/javascripts/twitter/bootstrap/affix.js +9 -3
  6. data/{vendor → app}/assets/javascripts/twitter/bootstrap/alert.js +4 -2
  7. data/{vendor → app}/assets/javascripts/twitter/bootstrap/button.js +6 -4
  8. data/{vendor → app}/assets/javascripts/twitter/bootstrap/carousel.js +22 -12
  9. data/{vendor → app}/assets/javascripts/twitter/bootstrap/collapse.js +69 -43
  10. data/{vendor → app}/assets/javascripts/twitter/bootstrap/dropdown.js +22 -13
  11. data/{vendor → app}/assets/javascripts/twitter/bootstrap/modal.js +37 -38
  12. data/{vendor → app}/assets/javascripts/twitter/bootstrap/popover.js +11 -5
  13. data/{vendor → app}/assets/javascripts/twitter/bootstrap/scrollspy.js +6 -4
  14. data/{vendor → app}/assets/javascripts/twitter/bootstrap/tab.js +4 -2
  15. data/{vendor → app}/assets/javascripts/twitter/bootstrap/tooltip.js +49 -38
  16. data/{vendor → app}/assets/javascripts/twitter/bootstrap/transition.js +10 -1
  17. data/{vendor → app}/assets/stylesheets/twitter/bootstrap.scss +0 -0
  18. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_accordion.scss +7 -10
  19. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_alerts.scss +11 -34
  20. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_badges.scss +8 -15
  21. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_bootstrap.scss +0 -1
  22. data/app/assets/stylesheets/twitter/bootstrap/_breadcrumbs.scss +23 -0
  23. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_button-groups.scss +23 -22
  24. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_buttons.scss +21 -24
  25. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_carousel.scss +46 -32
  26. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_close.scss +3 -3
  27. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_code.scss +6 -12
  28. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_component-animations.scss +10 -4
  29. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_dropdowns.scss +46 -101
  30. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_forms.scss +139 -179
  31. data/app/assets/stylesheets/twitter/bootstrap/_grid.scss +155 -0
  32. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_jumbotron.scss +1 -4
  33. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_labels.scss +7 -31
  34. data/app/assets/stylesheets/twitter/bootstrap/_list-group.scss +89 -0
  35. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_media.scss +8 -6
  36. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_mixins.scss +152 -131
  37. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_modals.scss +11 -12
  38. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_navbar.scss +90 -66
  39. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_navs.scss +56 -68
  40. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_normalize.scss +0 -0
  41. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_pager.scss +4 -3
  42. data/app/assets/stylesheets/twitter/bootstrap/_pagination.scss +108 -0
  43. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_panels.scss +8 -2
  44. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_popovers.scss +22 -20
  45. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_print.scss +26 -0
  46. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_progress-bars.scss +5 -18
  47. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_responsive-utilities.scss +25 -25
  48. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_scaffolding.scss +24 -8
  49. data/app/assets/stylesheets/twitter/bootstrap/_tables.scss +211 -0
  50. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_thumbnails.scss +2 -3
  51. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_tooltip.scss +26 -2
  52. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_type.scss +31 -49
  53. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_utilities.scss +0 -0
  54. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_variables.scss +201 -54
  55. data/{vendor → app}/assets/stylesheets/twitter/bootstrap/_wells.scss +0 -0
  56. data/bootstrap-rails.gemspec +0 -1
  57. data/lib/bootstrap-rails/version.rb +1 -1
  58. metadata +54 -60
  59. data/vendor/assets/fonts/twitter/glyphiconshalflings-regular.eot +0 -0
  60. data/vendor/assets/fonts/twitter/glyphiconshalflings-regular.otf +0 -0
  61. data/vendor/assets/fonts/twitter/glyphiconshalflings-regular.svg +0 -175
  62. data/vendor/assets/fonts/twitter/glyphiconshalflings-regular.ttf +0 -0
  63. data/vendor/assets/fonts/twitter/glyphiconshalflings-regular.woff +0 -0
  64. data/vendor/assets/stylesheets/twitter/bootstrap/_breadcrumbs.scss +0 -28
  65. data/vendor/assets/stylesheets/twitter/bootstrap/_glyphicons.scss +0 -200
  66. data/vendor/assets/stylesheets/twitter/bootstrap/_grid.scss +0 -65
  67. data/vendor/assets/stylesheets/twitter/bootstrap/_list-group.scss +0 -96
  68. data/vendor/assets/stylesheets/twitter/bootstrap/_pagination.scss +0 -87
  69. data/vendor/assets/stylesheets/twitter/bootstrap/_tables.scss +0 -242
@@ -1,6 +1,6 @@
1
1
  /* ========================================================================
2
2
  * Bootstrap: dropdown.js v3.0.0
3
- * http://twitter.github.com/bootstrap/javascript.html#dropdowns
3
+ * http://twbs.github.com/bootstrap/javascript.html#dropdowns
4
4
  * ========================================================================
5
5
  * Copyright 2012 Twitter, Inc.
6
6
  *
@@ -26,10 +26,7 @@
26
26
  var backdrop = '.dropdown-backdrop'
27
27
  var toggle = '[data-toggle=dropdown]'
28
28
  var Dropdown = function (element) {
29
- var $el = $(element).on('click.dropdown.data-api', this.toggle)
30
- $('html').on('click.dropdown.data-api', function () {
31
- $el.parent().removeClass('open')
32
- })
29
+ var $el = $(element).on('click.bs.dropdown', this.toggle)
33
30
  }
34
31
 
35
32
  Dropdown.prototype.toggle = function (e) {
@@ -45,9 +42,16 @@
45
42
  if (!isActive) {
46
43
  if ('ontouchstart' in document.documentElement) {
47
44
  // if mobile we we use a backdrop because click events don't delegate
48
- $('<div class="dropdown-backdrop"/>').insertBefore($(this)).on('click', clearMenus)
45
+ $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
49
46
  }
50
- $parent.toggleClass('open')
47
+
48
+ $parent.trigger(e = $.Event('show.bs.dropdown'))
49
+
50
+ if (e.isDefaultPrevented()) return
51
+
52
+ $parent
53
+ .toggleClass('open')
54
+ .trigger('shown.bs.dropdown')
51
55
  }
52
56
 
53
57
  $this.focus()
@@ -88,7 +92,13 @@
88
92
 
89
93
  function clearMenus() {
90
94
  $(backdrop).remove()
91
- $(toggle).each(function () { getParent($(this)).removeClass('open') })
95
+ $(toggle).each(function (e) {
96
+ var $parent = getParent($(this))
97
+ if (!$parent.hasClass('open')) return
98
+ $parent.trigger(e = $.Event('hide.bs.dropdown'))
99
+ if (e.isDefaultPrevented()) return
100
+ $parent.removeClass('open').trigger('hidden.bs.dropdown')
101
+ })
92
102
  }
93
103
 
94
104
  function getParent($this) {
@@ -135,11 +145,10 @@
135
145
  // APPLY TO STANDARD DROPDOWN ELEMENTS
136
146
  // ===================================
137
147
 
138
-
139
148
  $(document)
140
- .on('click.dropdown.data-api', clearMenus)
141
- .on('click.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
142
- .on('click.dropdown.data-api' , toggle, Dropdown.prototype.toggle)
143
- .on('keydown.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
149
+ .on('click.bs.dropdown.data-api', clearMenus)
150
+ .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
151
+ .on('click.bs.dropdown.data-api' , toggle, Dropdown.prototype.toggle)
152
+ .on('keydown.bs.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
144
153
 
145
154
  }(window.jQuery);
@@ -1,6 +1,6 @@
1
1
  /* ========================================================================
2
2
  * Bootstrap: modal.js v3.0.0
3
- * http://twitter.github.com/bootstrap/javascript.html#modals
3
+ * http://twbs.github.com/bootstrap/javascript.html#modals
4
4
  * ========================================================================
5
5
  * Copyright 2012 Twitter, Inc.
6
6
  *
@@ -25,7 +25,7 @@
25
25
 
26
26
  var Modal = function (element, options) {
27
27
  this.options = options
28
- this.$element = $(element).delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
28
+ this.$element = $(element).on('click.dismiss.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
29
29
  this.$backdrop =
30
30
  this.isShown = null
31
31
 
@@ -58,7 +58,7 @@
58
58
  var transition = $.support.transition && that.$element.hasClass('fade')
59
59
 
60
60
  if (!that.$element.parent().length) {
61
- that.$element.appendTo(document.body) //don't move modals dom position
61
+ that.$element.appendTo(document.body) // don't move modals dom position
62
62
  }
63
63
 
64
64
  that.$element.show()
@@ -74,9 +74,12 @@
74
74
  that.enforceFocus()
75
75
 
76
76
  transition ?
77
- that.$element.one($.support.transition.end, function () { that.$element.focus().trigger('shown.bs.modal') }) :
77
+ that.$element
78
+ .one($.support.transition.end, function () {
79
+ that.$element.focus().trigger('shown.bs.modal')
80
+ })
81
+ .emulateTransitionEnd(300) :
78
82
  that.$element.focus().trigger('shown.bs.modal')
79
-
80
83
  })
81
84
  }
82
85
 
@@ -100,41 +103,32 @@
100
103
  .attr('aria-hidden', true)
101
104
 
102
105
  $.support.transition && this.$element.hasClass('fade') ?
103
- this.hideWithTransition() :
106
+ this.$element
107
+ .one($.support.transition.end, $.proxy(this.hideModal, this))
108
+ .emulateTransitionEnd(300) :
104
109
  this.hideModal()
105
110
  }
106
111
 
107
112
  Modal.prototype.enforceFocus = function () {
108
- $(document).on('focusin.bs.modal', function (e) {
109
- if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
110
- this.$element.focus()
111
- }
112
- }, this)
113
+ $(document)
114
+ .off('focusin.bs.modal') // guard against infinite focus loop
115
+ .on('focusin.bs.modal', $.proxy(function (e) {
116
+ if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
117
+ this.$element.focus()
118
+ }
119
+ }, this))
113
120
  }
114
121
 
115
122
  Modal.prototype.escape = function () {
116
123
  if (this.isShown && this.options.keyboard) {
117
- this.$element.on('keyup.dismiss.bs.modal', function ( e ) {
124
+ this.$element.on('keyup.dismiss.bs.modal', $.proxy(function (e) {
118
125
  e.which == 27 && this.hide()
119
- }, this)
126
+ }, this))
120
127
  } else if (!this.isShown) {
121
128
  this.$element.off('keyup.dismiss.bs.modal')
122
129
  }
123
130
  }
124
131
 
125
- Modal.prototype.hideWithTransition = function () {
126
- var that = this
127
- var timeout = setTimeout(function () {
128
- that.$element.off($.support.transition.end)
129
- that.hideModal()
130
- }, 500)
131
-
132
- this.$element.one($.support.transition.end, function () {
133
- clearTimeout(timeout)
134
- that.hideModal()
135
- })
136
- }
137
-
138
132
  Modal.prototype.hideModal = function () {
139
133
  var that = this
140
134
  this.$element.hide()
@@ -159,11 +153,12 @@
159
153
  this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
160
154
  .appendTo(document.body)
161
155
 
162
- this.$backdrop.click(
163
- this.options.backdrop == 'static' ?
164
- $.proxy(this.$element[0].focus, this.$element[0])
165
- : $.proxy(this.hide, this)
166
- )
156
+ this.$element.on('click', $.proxy(function (e) {
157
+ if (e.target !== e.currentTarget) return
158
+ this.options.backdrop == 'static'
159
+ ? this.$element[0].focus.call(this.$element[0])
160
+ : this.hide.call(this)
161
+ }, this))
167
162
 
168
163
  if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
169
164
 
@@ -172,14 +167,18 @@
172
167
  if (!callback) return
173
168
 
174
169
  doAnimate ?
175
- this.$backdrop.one($.support.transition.end, callback) :
170
+ this.$backdrop
171
+ .one($.support.transition.end, callback)
172
+ .emulateTransitionEnd(150) :
176
173
  callback()
177
174
 
178
175
  } else if (!this.isShown && this.$backdrop) {
179
176
  this.$backdrop.removeClass('in')
180
177
 
181
178
  $.support.transition && this.$element.hasClass('fade')?
182
- this.$backdrop.one($.support.transition.end, callback) :
179
+ this.$backdrop
180
+ .one($.support.transition.end, callback)
181
+ .emulateTransitionEnd(150) :
183
182
  callback()
184
183
 
185
184
  } else if (callback) {
@@ -231,12 +230,12 @@
231
230
  $target
232
231
  .modal(option)
233
232
  .one('hide', function () {
234
- $this.focus()
233
+ $this.is(':visible') && $this.focus()
235
234
  })
236
- })
235
+ })
237
236
 
238
- var $body = $(document.body)
239
- .on('bs.modal.shown', '.modal', function () { $body.addClass('modal-open') })
240
- .on('bs.modal.hidden', '.modal', function () { $body.removeClass('modal-open') })
237
+ var $body = $(document.body)
238
+ .on('shown.bs.modal', '.modal', function () { $body.addClass('modal-open') })
239
+ .on('hidden.bs.modal', '.modal', function () { $body.removeClass('modal-open') })
241
240
 
242
241
  }(window.jQuery);
@@ -1,6 +1,6 @@
1
1
  /* ========================================================================
2
2
  * Bootstrap: popover.js v3.0.0
3
- * http://twitter.github.com/bootstrap/javascript.html#popovers
3
+ * http://twbs.github.com/bootstrap/javascript.html#popovers
4
4
  * ========================================================================
5
5
  * Copyright 2012 Twitter, Inc.
6
6
  *
@@ -27,6 +27,8 @@
27
27
  this.init('popover', element, options)
28
28
  }
29
29
 
30
+ if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
31
+
30
32
  Popover.DEFAULTS = $.extend({} , $.fn.tooltip.Constructor.DEFAULTS, {
31
33
  placement: 'right'
32
34
  , trigger: 'click'
@@ -55,6 +57,8 @@
55
57
  $tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)
56
58
 
57
59
  $tip.removeClass('fade top bottom left right in')
60
+
61
+ $tip.find('.popover-title:empty').hide()
58
62
  }
59
63
 
60
64
  Popover.prototype.hasContent = function () {
@@ -62,11 +66,13 @@
62
66
  }
63
67
 
64
68
  Popover.prototype.getContent = function () {
65
- var content = typeof this.options.content == 'function' ?
66
- this.options.content.call(this.$element[0]) :
67
- this.options.content
69
+ var $e = this.$element
70
+ var o = this.options
68
71
 
69
- return content || this.$element.attr('data-content')
72
+ return $e.attr('data-content')
73
+ || (typeof o.content == 'function' ?
74
+ o.content.call($e[0]) :
75
+ o.content)
70
76
  }
71
77
 
72
78
  Popover.prototype.tip = function () {
@@ -1,6 +1,6 @@
1
1
  /* ========================================================================
2
2
  * Bootstrap: scrollspy.js v3.0.0
3
- * http://twitter.github.com/bootstrap/javascript.html#scrollspy
3
+ * http://twbs.github.com/bootstrap/javascript.html#scrollspy
4
4
  * ========================================================================
5
5
  * Copyright 2012 Twitter, Inc.
6
6
  *
@@ -26,10 +26,10 @@
26
26
  function ScrollSpy(element, options) {
27
27
  var href
28
28
  var process = $.proxy(this.process, this)
29
- var $element = $(element).is('body') ? $(window) : $(element)
30
29
 
30
+ this.$element = $(element).is('body') ? $(window) : $(element)
31
31
  this.$body = $('body')
32
- this.$scrollElement = $element.on('scroll.scroll-spy.data-api', process)
32
+ this.$scrollElement = this.$element.on('scroll.bs.scroll-spy.data-api', process)
33
33
  this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
34
34
  this.selector = (this.options.target
35
35
  || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
@@ -47,6 +47,8 @@
47
47
  }
48
48
 
49
49
  ScrollSpy.prototype.refresh = function () {
50
+ var offsetMethod = this.$element[0] == window ? 'offset' : 'position'
51
+
50
52
  this.offsets = $([])
51
53
  this.targets = $([])
52
54
 
@@ -60,7 +62,7 @@
60
62
 
61
63
  return ($href
62
64
  && $href.length
63
- && [[ $href.position().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]]) || null
65
+ && [[ $href[offsetMethod]().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]]) || null
64
66
  })
65
67
  .sort(function (a, b) { return a[0] - b[0] })
66
68
  .each(function () {
@@ -1,6 +1,6 @@
1
1
  /* ========================================================================
2
2
  * Bootstrap: tab.js v3.0.0
3
- * http://twitter.github.com/bootstrap/javascript.html#tabs
3
+ * http://twbs.github.com/bootstrap/javascript.html#tabs
4
4
  * ========================================================================
5
5
  * Copyright 2012 Twitter, Inc.
6
6
  *
@@ -88,7 +88,9 @@
88
88
  }
89
89
 
90
90
  transition ?
91
- $active.one($.support.transition.end, next) :
91
+ $active
92
+ .one($.support.transition.end, next)
93
+ .emulateTransitionEnd(150) :
92
94
  next()
93
95
 
94
96
  $active.removeClass('in')
@@ -1,6 +1,6 @@
1
1
  /* ========================================================================
2
2
  * Bootstrap: tooltip.js v3.0.0
3
- * http://twitter.github.com/bootstrap/javascript.html#affix
3
+ * http://twbs.github.com/bootstrap/javascript.html#affix
4
4
  * Inspired by the original jQuery.tipsy by Jason Frame
5
5
  * ========================================================================
6
6
  * Copyright 2012 Twitter, Inc.
@@ -91,7 +91,7 @@
91
91
  return options
92
92
  }
93
93
 
94
- Tooltip.prototype.enter = function (e) {
94
+ Tooltip.prototype.enter = function (obj) {
95
95
  var defaults = this.getDefaults()
96
96
  var options = {}
97
97
 
@@ -99,26 +99,29 @@
99
99
  if (defaults[key] != value) options[key] = value
100
100
  })
101
101
 
102
- var self = $(e.currentTarget)[this.type](options).data('bs.' + this.type)
102
+ var self = obj instanceof this.constructor ?
103
+ obj : $(obj.currentTarget)[this.type](options).data('bs.' + this.type)
103
104
 
104
- if (!self.options.delay || !self.options.delay.show) return self.show()
105
+ clearTimeout(self.timeout)
105
106
 
106
- clearTimeout(this.timeout)
107
+ if (!self.options.delay || !self.options.delay.show) return self.show()
107
108
 
108
109
  self.hoverState = 'in'
109
- this.timeout = setTimeout(function() {
110
+ self.timeout = setTimeout(function () {
110
111
  if (self.hoverState == 'in') self.show()
111
112
  }, self.options.delay.show)
112
113
  }
113
114
 
114
- Tooltip.prototype.leave = function (e) {
115
- var self = $(e.currentTarget)[this.type](this._options).data('bs.' + this.type)
115
+ Tooltip.prototype.leave = function (obj) {
116
+ var self = obj instanceof this.constructor ?
117
+ obj : $(obj.currentTarget)[this.type](this._options).data('bs.' + this.type)
118
+
119
+ clearTimeout(self.timeout)
116
120
 
117
- if (this.timeout) clearTimeout(this.timeout)
118
121
  if (!self.options.delay || !self.options.delay.hide) return self.hide()
119
122
 
120
123
  self.hoverState = 'out'
121
- this.timeout = setTimeout(function() {
124
+ self.timeout = setTimeout(function () {
122
125
  if (self.hoverState == 'out') self.hide()
123
126
  }, self.options.delay.hide)
124
127
  }
@@ -141,32 +144,46 @@
141
144
  this.options.placement.call(this, $tip[0], this.$element[0]) :
142
145
  this.options.placement
143
146
 
147
+ var autoToken = /\s?auto?\s?/i
148
+ var autoPlace = autoToken.test(placement)
149
+ if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
150
+
144
151
  $tip
145
152
  .detach()
146
153
  .css({ top: 0, left: 0, display: 'block' })
154
+ .addClass(placement)
147
155
 
148
156
  this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
149
157
 
150
- var tp
151
158
  var pos = this.getPosition()
152
159
  var actualWidth = $tip[0].offsetWidth
153
160
  var actualHeight = $tip[0].offsetHeight
154
161
 
155
- switch (placement) {
156
- case 'bottom':
157
- tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
158
- break
159
- case 'top':
160
- tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
161
- break
162
- case 'left':
163
- tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
164
- break
165
- case 'right':
166
- tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
167
- break
162
+ if (autoPlace) {
163
+ var $parent = this.$element.parent()
164
+
165
+ var orgPlacement = placement
166
+ var docScroll = document.documentElement.scrollTop || document.body.scrollTop
167
+ var parentWidth = this.options.container == 'body' ? window.innerWidth : $parent.outerWidth()
168
+ var parentHeight = this.options.container == 'body' ? window.innerHeight : $parent.outerHeight()
169
+ var parentLeft = this.options.container == 'body' ? 0 : $parent.offset().left
170
+
171
+ placement = placement == 'bottom' && pos.top + pos.height + actualHeight - docScroll > parentHeight ? 'top' :
172
+ placement == 'top' && pos.top - docScroll - actualHeight < 0 ? 'bottom' :
173
+ placement == 'right' && pos.right + actualWidth > parentWidth ? 'left' :
174
+ placement == 'left' && pos.left - actualWidth < parentLeft ? 'right' :
175
+ placement
176
+
177
+ $tip
178
+ .removeClass(orgPlacement)
179
+ .addClass(placement)
168
180
  }
169
181
 
182
+ var tp = placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
183
+ placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
184
+ placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
185
+ /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
186
+
170
187
  this.applyPlacement(tp, placement)
171
188
  this.$element.trigger('shown.bs.' + this.type)
172
189
  }
@@ -178,9 +195,12 @@
178
195
  var width = $tip[0].offsetWidth
179
196
  var height = $tip[0].offsetHeight
180
197
 
198
+ // manually read margins because getBoundingClientRect includes difference
199
+ offset.top = offset.top + parseInt($tip.css('margin-top'), 10)
200
+ offset.left = offset.left + parseInt($tip.css('margin-left'), 10)
201
+
181
202
  $tip
182
203
  .offset(offset)
183
- .addClass(placement)
184
204
  .addClass('in')
185
205
 
186
206
  var actualWidth = $tip[0].offsetWidth
@@ -235,19 +255,10 @@
235
255
 
236
256
  $tip.removeClass('in')
237
257
 
238
- function removeWithAnimation() {
239
- var timeout = setTimeout(function () {
240
- $tip.off($.support.transition.end).detach()
241
- }, 500)
242
-
243
- $tip.one($.support.transition.end, function () {
244
- clearTimeout(timeout)
245
- $tip.detach()
246
- })
247
- }
248
-
249
258
  $.support.transition && this.$tip.hasClass('fade') ?
250
- removeWithAnimation() :
259
+ $tip
260
+ .one($.support.transition.end, $tip.detach)
261
+ .emulateTransitionEnd(150) :
251
262
  $tip.detach()
252
263
 
253
264
  this.$element.trigger('hidden.bs.' + this.type)
@@ -315,7 +326,7 @@
315
326
 
316
327
  Tooltip.prototype.toggle = function (e) {
317
328
  var self = e ? $(e.currentTarget)[this.type](this._options).data('bs.' + this.type) : this
318
- self.tip().hasClass('in') ? self.hide() : self.show()
329
+ self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
319
330
  }
320
331
 
321
332
  Tooltip.prototype.destroy = function () {