bootstrap 4.0.0.alpha6 → 4.0.0.beta

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

Potentially problematic release.


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

Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/Gemfile +2 -4
  4. data/README.md +20 -22
  5. data/assets/javascripts/bootstrap.js +657 -361
  6. data/assets/javascripts/bootstrap.min.js +2 -3
  7. data/assets/javascripts/bootstrap/alert.js +8 -8
  8. data/assets/javascripts/bootstrap/button.js +16 -9
  9. data/assets/javascripts/bootstrap/carousel.js +48 -21
  10. data/assets/javascripts/bootstrap/collapse.js +42 -33
  11. data/assets/javascripts/bootstrap/dropdown.js +196 -52
  12. data/assets/javascripts/bootstrap/modal.js +71 -29
  13. data/assets/javascripts/bootstrap/popover.js +25 -13
  14. data/assets/javascripts/bootstrap/scrollspy.js +23 -21
  15. data/assets/javascripts/bootstrap/tab.js +14 -18
  16. data/assets/javascripts/bootstrap/tooltip.js +139 -83
  17. data/assets/javascripts/bootstrap/util.js +10 -8
  18. data/assets/stylesheets/_bootstrap-grid.scss +2 -8
  19. data/assets/stylesheets/_bootstrap-reboot.scss +1 -2
  20. data/assets/stylesheets/_bootstrap.scss +2 -15
  21. data/assets/stylesheets/bootstrap/_alert.scss +4 -11
  22. data/assets/stylesheets/bootstrap/_badge.scss +4 -33
  23. data/assets/stylesheets/bootstrap/_breadcrumb.scss +1 -1
  24. data/assets/stylesheets/bootstrap/_button-group.scss +11 -15
  25. data/assets/stylesheets/bootstrap/_buttons.scss +13 -42
  26. data/assets/stylesheets/bootstrap/_card.scss +27 -80
  27. data/assets/stylesheets/bootstrap/_carousel.scss +24 -17
  28. data/assets/stylesheets/bootstrap/_close.scss +0 -2
  29. data/assets/stylesheets/bootstrap/_custom-forms.scss +27 -36
  30. data/assets/stylesheets/bootstrap/_dropdown.scss +15 -48
  31. data/assets/stylesheets/bootstrap/_forms.scss +70 -68
  32. data/assets/stylesheets/bootstrap/_functions.scss +90 -0
  33. data/assets/stylesheets/bootstrap/_grid.scss +3 -2
  34. data/assets/stylesheets/bootstrap/_images.scss +1 -1
  35. data/assets/stylesheets/bootstrap/_input-group.scss +6 -8
  36. data/assets/stylesheets/bootstrap/_jumbotron.scss +0 -4
  37. data/assets/stylesheets/bootstrap/_list-group.scss +9 -36
  38. data/assets/stylesheets/bootstrap/_mixins.scss +2 -18
  39. data/assets/stylesheets/bootstrap/_modal.scss +3 -3
  40. data/assets/stylesheets/bootstrap/_nav.scss +15 -16
  41. data/assets/stylesheets/bootstrap/_navbar.scss +70 -54
  42. data/assets/stylesheets/bootstrap/_pagination.scss +3 -4
  43. data/assets/stylesheets/bootstrap/_popover.scss +96 -72
  44. data/assets/stylesheets/bootstrap/_print.scss +1 -9
  45. data/assets/stylesheets/bootstrap/_progress.scss +4 -4
  46. data/assets/stylesheets/bootstrap/_reboot.scss +187 -95
  47. data/assets/stylesheets/bootstrap/_tables.scss +34 -19
  48. data/assets/stylesheets/bootstrap/_tooltip.scss +52 -35
  49. data/assets/stylesheets/bootstrap/_type.scss +8 -28
  50. data/assets/stylesheets/bootstrap/_utilities.scss +1 -0
  51. data/assets/stylesheets/bootstrap/_variables.scss +286 -410
  52. data/assets/stylesheets/bootstrap/mixins/_alert.scss +4 -5
  53. data/assets/stylesheets/bootstrap/mixins/_badge.scss +6 -5
  54. data/assets/stylesheets/bootstrap/mixins/_border-radius.scss +3 -3
  55. data/assets/stylesheets/bootstrap/mixins/_box-shadow.scss +5 -0
  56. data/assets/stylesheets/bootstrap/mixins/_breakpoints.scss +23 -13
  57. data/assets/stylesheets/bootstrap/mixins/_buttons.scss +11 -14
  58. data/assets/stylesheets/bootstrap/mixins/_clearfix.scss +1 -1
  59. data/assets/stylesheets/bootstrap/mixins/_forms.scss +57 -55
  60. data/assets/stylesheets/bootstrap/mixins/_gradients.scss +1 -1
  61. data/assets/stylesheets/bootstrap/mixins/_grid-framework.scss +9 -18
  62. data/assets/stylesheets/bootstrap/mixins/_grid.scss +12 -65
  63. data/assets/stylesheets/bootstrap/mixins/_hover.scss +6 -6
  64. data/assets/stylesheets/bootstrap/mixins/_list-group.scss +2 -4
  65. data/assets/stylesheets/bootstrap/mixins/_nav-divider.scss +3 -3
  66. data/assets/stylesheets/bootstrap/mixins/_pagination.scss +1 -0
  67. data/assets/stylesheets/bootstrap/mixins/_reset-text.scss +4 -3
  68. data/assets/stylesheets/bootstrap/mixins/_resize.scss +1 -1
  69. data/assets/stylesheets/bootstrap/mixins/_screen-reader.scss +5 -2
  70. data/assets/stylesheets/bootstrap/mixins/_text-truncate.scss +1 -1
  71. data/assets/stylesheets/bootstrap/mixins/_transition.scss +9 -0
  72. data/assets/stylesheets/bootstrap/mixins/_visibility.scss +2 -2
  73. data/assets/stylesheets/bootstrap/utilities/_background.scss +4 -17
  74. data/assets/stylesheets/bootstrap/utilities/_borders.scss +20 -5
  75. data/assets/stylesheets/bootstrap/utilities/_display.scss +36 -1
  76. data/assets/stylesheets/bootstrap/{_responsive-embed.scss → utilities/_embed.scss} +0 -0
  77. data/assets/stylesheets/bootstrap/utilities/_flex.scss +0 -4
  78. data/assets/stylesheets/bootstrap/utilities/_position.scss +5 -3
  79. data/assets/stylesheets/bootstrap/utilities/_spacing.scss +10 -12
  80. data/assets/stylesheets/bootstrap/utilities/_text.scss +5 -17
  81. data/assets/stylesheets/bootstrap/utilities/_visibility.scss +4 -48
  82. data/bootstrap.gemspec +2 -0
  83. data/lib/bootstrap.rb +2 -0
  84. data/lib/bootstrap/version.rb +2 -2
  85. data/tasks/updater/js.rb +7 -9
  86. data/tasks/updater/scss.rb +1 -4
  87. data/templates/project/_bootstrap-variables.scss +289 -396
  88. data/test/dummy_rails/app/assets/javascripts/application.js +1 -1
  89. data/test/dummy_rails/config/application.rb +0 -1
  90. data/test/gemfiles/rails_4_2.gemfile +0 -4
  91. data/test/gemfiles/rails_5_0.gemfile +0 -4
  92. data/test/gemfiles/rails_5_1.gemfile +8 -0
  93. metadata +23 -8
  94. data/assets/stylesheets/bootstrap/_custom.scss +0 -4
  95. data/assets/stylesheets/bootstrap/_normalize.scss +0 -461
  96. data/assets/stylesheets/bootstrap/mixins/_cards.scss +0 -47
  97. data/assets/stylesheets/bootstrap/mixins/_transforms.scss +0 -14
@@ -10,7 +10,7 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
10
10
 
11
11
  /**
12
12
  * --------------------------------------------------------------------------
13
- * Bootstrap (v4.0.0-alpha.6): popover.js
13
+ * Bootstrap (v4.0.0-beta): popover.js
14
14
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
15
15
  * --------------------------------------------------------------------------
16
16
  */
@@ -24,16 +24,18 @@ var Popover = function ($) {
24
24
  */
25
25
 
26
26
  var NAME = 'popover';
27
- var VERSION = '4.0.0-alpha.6';
27
+ var VERSION = '4.0.0-beta';
28
28
  var DATA_KEY = 'bs.popover';
29
29
  var EVENT_KEY = '.' + DATA_KEY;
30
30
  var JQUERY_NO_CONFLICT = $.fn[NAME];
31
+ var CLASS_PREFIX = 'bs-popover';
32
+ var BSCLS_PREFIX_REGEX = new RegExp('(^|\\s)' + CLASS_PREFIX + '\\S+', 'g');
31
33
 
32
34
  var Default = $.extend({}, Tooltip.Default, {
33
35
  placement: 'right',
34
36
  trigger: 'click',
35
37
  content: '',
36
- template: '<div class="popover" role="tooltip">' + '<h3 class="popover-title"></h3>' + '<div class="popover-content"></div></div>'
38
+ template: '<div class="popover" role="tooltip">' + '<div class="arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div></div>'
37
39
  });
38
40
 
39
41
  var DefaultType = $.extend({}, Tooltip.DefaultType, {
@@ -46,8 +48,8 @@ var Popover = function ($) {
46
48
  };
47
49
 
48
50
  var Selector = {
49
- TITLE: '.popover-title',
50
- CONTENT: '.popover-content'
51
+ TITLE: '.popover-header',
52
+ CONTENT: '.popover-body'
51
53
  };
52
54
 
53
55
  var Event = {
@@ -61,14 +63,14 @@ var Popover = function ($) {
61
63
  FOCUSOUT: 'focusout' + EVENT_KEY,
62
64
  MOUSEENTER: 'mouseenter' + EVENT_KEY,
63
65
  MOUSELEAVE: 'mouseleave' + EVENT_KEY
64
- };
65
66
 
66
- /**
67
- * ------------------------------------------------------------------------
68
- * Class Definition
69
- * ------------------------------------------------------------------------
70
- */
67
+ /**
68
+ * ------------------------------------------------------------------------
69
+ * Class Definition
70
+ * ------------------------------------------------------------------------
71
+ */
71
72
 
73
+ };
72
74
  var Popover = function (_Tooltip) {
73
75
  _inherits(Popover, _Tooltip);
74
76
 
@@ -84,6 +86,10 @@ var Popover = function ($) {
84
86
  return this.getTitle() || this._getContent();
85
87
  };
86
88
 
89
+ Popover.prototype.addAttachmentClass = function addAttachmentClass(attachment) {
90
+ $(this.getTipElement()).addClass(CLASS_PREFIX + '-' + attachment);
91
+ };
92
+
87
93
  Popover.prototype.getTipElement = function getTipElement() {
88
94
  return this.tip = this.tip || $(this.config.template)[0];
89
95
  };
@@ -96,8 +102,6 @@ var Popover = function ($) {
96
102
  this.setElementContent($tip.find(Selector.CONTENT), this._getContent());
97
103
 
98
104
  $tip.removeClass(ClassName.FADE + ' ' + ClassName.SHOW);
99
-
100
- this.cleanupTether();
101
105
  };
102
106
 
103
107
  // private
@@ -106,6 +110,14 @@ var Popover = function ($) {
106
110
  return this.element.getAttribute('data-content') || (typeof this.config.content === 'function' ? this.config.content.call(this.element) : this.config.content);
107
111
  };
108
112
 
113
+ Popover.prototype._cleanTipClass = function _cleanTipClass() {
114
+ var $tip = $(this.getTipElement());
115
+ var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX);
116
+ if (tabClass !== null && tabClass.length > 0) {
117
+ $tip.removeClass(tabClass.join(''));
118
+ }
119
+ };
120
+
109
121
  // static
110
122
 
111
123
  Popover._jQueryInterface = function _jQueryInterface(config) {
@@ -6,7 +6,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
6
6
 
7
7
  /**
8
8
  * --------------------------------------------------------------------------
9
- * Bootstrap (v4.0.0-alpha.6): scrollspy.js
9
+ * Bootstrap (v4.0.0-beta): scrollspy.js
10
10
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11
11
  * --------------------------------------------------------------------------
12
12
  */
@@ -20,7 +20,7 @@ var ScrollSpy = function ($) {
20
20
  */
21
21
 
22
22
  var NAME = 'scrollspy';
23
- var VERSION = '4.0.0-alpha.6';
23
+ var VERSION = '4.0.0-beta';
24
24
  var DATA_KEY = 'bs.scrollspy';
25
25
  var EVENT_KEY = '.' + DATA_KEY;
26
26
  var DATA_API_KEY = '.data-api';
@@ -47,18 +47,15 @@ var ScrollSpy = function ($) {
47
47
  var ClassName = {
48
48
  DROPDOWN_ITEM: 'dropdown-item',
49
49
  DROPDOWN_MENU: 'dropdown-menu',
50
- NAV_LINK: 'nav-link',
51
- NAV: 'nav',
52
50
  ACTIVE: 'active'
53
51
  };
54
52
 
55
53
  var Selector = {
56
54
  DATA_SPY: '[data-spy="scroll"]',
57
55
  ACTIVE: '.active',
58
- LIST_ITEM: '.list-item',
59
- LI: 'li',
60
- LI_DROPDOWN: 'li.dropdown',
56
+ NAV_LIST_GROUP: '.nav, .list-group',
61
57
  NAV_LINKS: '.nav-link',
58
+ LIST_ITEMS: '.list-group-item',
62
59
  DROPDOWN: '.dropdown',
63
60
  DROPDOWN_ITEMS: '.dropdown-item',
64
61
  DROPDOWN_TOGGLE: '.dropdown-toggle'
@@ -67,14 +64,14 @@ var ScrollSpy = function ($) {
67
64
  var OffsetMethod = {
68
65
  OFFSET: 'offset',
69
66
  POSITION: 'position'
70
- };
71
67
 
72
- /**
73
- * ------------------------------------------------------------------------
74
- * Class Definition
75
- * ------------------------------------------------------------------------
76
- */
68
+ /**
69
+ * ------------------------------------------------------------------------
70
+ * Class Definition
71
+ * ------------------------------------------------------------------------
72
+ */
77
73
 
74
+ };
78
75
  var ScrollSpy = function () {
79
76
  function ScrollSpy(element, config) {
80
77
  var _this = this;
@@ -84,7 +81,7 @@ var ScrollSpy = function ($) {
84
81
  this._element = element;
85
82
  this._scrollElement = element.tagName === 'BODY' ? window : element;
86
83
  this._config = this._getConfig(config);
87
- this._selector = this._config.target + ' ' + Selector.NAV_LINKS + ',' + (this._config.target + ' ' + Selector.DROPDOWN_ITEMS);
84
+ this._selector = this._config.target + ' ' + Selector.NAV_LINKS + ',' + (this._config.target + ' ' + Selector.LIST_ITEMS + ',') + (this._config.target + ' ' + Selector.DROPDOWN_ITEMS);
88
85
  this._offsets = [];
89
86
  this._targets = [];
90
87
  this._activeTarget = null;
@@ -126,9 +123,12 @@ var ScrollSpy = function ($) {
126
123
  target = $(targetSelector)[0];
127
124
  }
128
125
 
129
- if (target && (target.offsetWidth || target.offsetHeight)) {
130
- // todo (fat): remove sketch reliance on jQuery position/offset
131
- return [$(target)[offsetMethod]().top + offsetBase, targetSelector];
126
+ if (target) {
127
+ var targetBCR = target.getBoundingClientRect();
128
+ if (targetBCR.width || targetBCR.height) {
129
+ // todo (fat): remove sketch reliance on jQuery position/offset
130
+ return [$(target)[offsetMethod]().top + offsetBase, targetSelector];
131
+ }
132
132
  }
133
133
  return null;
134
134
  }).filter(function (item) {
@@ -183,7 +183,7 @@ var ScrollSpy = function ($) {
183
183
  };
184
184
 
185
185
  ScrollSpy.prototype._getOffsetHeight = function _getOffsetHeight() {
186
- return this._scrollElement === window ? window.innerHeight : this._scrollElement.offsetHeight;
186
+ return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height;
187
187
  };
188
188
 
189
189
  ScrollSpy.prototype._process = function _process() {
@@ -235,9 +235,11 @@ var ScrollSpy = function ($) {
235
235
  $link.closest(Selector.DROPDOWN).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE);
236
236
  $link.addClass(ClassName.ACTIVE);
237
237
  } else {
238
- // todo (fat) this is kinda sus...
239
- // recursively add actives to tested nav-links
240
- $link.parents(Selector.LI).find('> ' + Selector.NAV_LINKS).addClass(ClassName.ACTIVE);
238
+ // Set triggered link as active
239
+ $link.addClass(ClassName.ACTIVE);
240
+ // Set triggered links parents as active
241
+ // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
242
+ $link.parents(Selector.NAV_LIST_GROUP).prev(Selector.NAV_LINKS + ', ' + Selector.LIST_ITEMS).addClass(ClassName.ACTIVE);
241
243
  }
242
244
 
243
245
  $(this._scrollElement).trigger(Event.ACTIVATE, {
@@ -4,7 +4,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
4
4
 
5
5
  /**
6
6
  * --------------------------------------------------------------------------
7
- * Bootstrap (v4.0.0-alpha.6): tab.js
7
+ * Bootstrap (v4.0.0-beta): tab.js
8
8
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
9
9
  * --------------------------------------------------------------------------
10
10
  */
@@ -18,7 +18,7 @@ var Tab = function ($) {
18
18
  */
19
19
 
20
20
  var NAME = 'tab';
21
- var VERSION = '4.0.0-alpha.6';
21
+ var VERSION = '4.0.0-beta';
22
22
  var DATA_KEY = 'bs.tab';
23
23
  var EVENT_KEY = '.' + DATA_KEY;
24
24
  var DATA_API_KEY = '.data-api';
@@ -42,24 +42,20 @@ var Tab = function ($) {
42
42
  };
43
43
 
44
44
  var Selector = {
45
- A: 'a',
46
- LI: 'li',
47
45
  DROPDOWN: '.dropdown',
48
- LIST: 'ul:not(.dropdown-menu), ol:not(.dropdown-menu), nav:not(.dropdown-menu)',
49
- FADE_CHILD: '> .nav-item .fade, > .fade',
46
+ NAV_LIST_GROUP: '.nav, .list-group',
50
47
  ACTIVE: '.active',
51
- ACTIVE_CHILD: '> .nav-item > .active, > .active',
52
- DATA_TOGGLE: '[data-toggle="tab"], [data-toggle="pill"]',
48
+ DATA_TOGGLE: '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',
53
49
  DROPDOWN_TOGGLE: '.dropdown-toggle',
54
50
  DROPDOWN_ACTIVE_CHILD: '> .dropdown-menu .active'
55
- };
56
51
 
57
- /**
58
- * ------------------------------------------------------------------------
59
- * Class Definition
60
- * ------------------------------------------------------------------------
61
- */
52
+ /**
53
+ * ------------------------------------------------------------------------
54
+ * Class Definition
55
+ * ------------------------------------------------------------------------
56
+ */
62
57
 
58
+ };
63
59
  var Tab = function () {
64
60
  function Tab(element) {
65
61
  _classCallCheck(this, Tab);
@@ -80,7 +76,7 @@ var Tab = function ($) {
80
76
 
81
77
  var target = void 0;
82
78
  var previous = void 0;
83
- var listElement = $(this._element).closest(Selector.LIST)[0];
79
+ var listElement = $(this._element).closest(Selector.NAV_LIST_GROUP)[0];
84
80
  var selector = Util.getSelectorFromElement(this._element);
85
81
 
86
82
  if (listElement) {
@@ -133,7 +129,7 @@ var Tab = function ($) {
133
129
  };
134
130
 
135
131
  Tab.prototype.dispose = function dispose() {
136
- $.removeClass(this._element, DATA_KEY);
132
+ $.removeData(this._element, DATA_KEY);
137
133
  this._element = null;
138
134
  };
139
135
 
@@ -142,8 +138,8 @@ var Tab = function ($) {
142
138
  Tab.prototype._activate = function _activate(element, container, callback) {
143
139
  var _this2 = this;
144
140
 
145
- var active = $(container).find(Selector.ACTIVE_CHILD)[0];
146
- var isTransitioning = callback && Util.supportsTransitionEnd() && (active && $(active).hasClass(ClassName.FADE) || Boolean($(container).find(Selector.FADE_CHILD)[0]));
141
+ var active = $(container).find(Selector.ACTIVE)[0];
142
+ var isTransitioning = callback && Util.supportsTransitionEnd() && active && $(active).hasClass(ClassName.FADE);
147
143
 
148
144
  var complete = function complete() {
149
145
  return _this2._transitionComplete(element, active, isTransitioning, callback);
@@ -6,7 +6,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
6
6
 
7
7
  /**
8
8
  * --------------------------------------------------------------------------
9
- * Bootstrap (v4.0.0-alpha.6): tooltip.js
9
+ * Bootstrap (v4.0.0-beta): tooltip.js
10
10
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11
11
  * --------------------------------------------------------------------------
12
12
  */
@@ -14,11 +14,11 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
14
14
  var Tooltip = function ($) {
15
15
 
16
16
  /**
17
- * Check for Tether dependency
18
- * Tether - http://tether.io/
17
+ * Check for Popper dependency
18
+ * Popper - https://popper.js.org
19
19
  */
20
- if (typeof Tether === 'undefined') {
21
- throw new Error('Bootstrap tooltips require Tether (http://tether.io/)');
20
+ if (typeof Popper === 'undefined') {
21
+ throw new Error('Bootstrap tooltips require Popper.js (https://popper.js.org)');
22
22
  }
23
23
 
24
24
  /**
@@ -28,26 +28,13 @@ var Tooltip = function ($) {
28
28
  */
29
29
 
30
30
  var NAME = 'tooltip';
31
- var VERSION = '4.0.0-alpha.6';
31
+ var VERSION = '4.0.0-beta';
32
32
  var DATA_KEY = 'bs.tooltip';
33
33
  var EVENT_KEY = '.' + DATA_KEY;
34
34
  var JQUERY_NO_CONFLICT = $.fn[NAME];
35
35
  var TRANSITION_DURATION = 150;
36
- var CLASS_PREFIX = 'bs-tether';
37
-
38
- var Default = {
39
- animation: true,
40
- template: '<div class="tooltip" role="tooltip">' + '<div class="tooltip-inner"></div></div>',
41
- trigger: 'hover focus',
42
- title: '',
43
- delay: 0,
44
- html: false,
45
- selector: false,
46
- placement: 'top',
47
- offset: '0 0',
48
- constraints: [],
49
- container: false
50
- };
36
+ var CLASS_PREFIX = 'bs-tooltip';
37
+ var BSCLS_PREFIX_REGEX = new RegExp('(^|\\s)' + CLASS_PREFIX + '\\S+', 'g');
51
38
 
52
39
  var DefaultType = {
53
40
  animation: 'boolean',
@@ -58,16 +45,31 @@ var Tooltip = function ($) {
58
45
  html: 'boolean',
59
46
  selector: '(string|boolean)',
60
47
  placement: '(string|function)',
61
- offset: 'string',
62
- constraints: 'array',
63
- container: '(string|element|boolean)'
48
+ offset: '(number|string)',
49
+ container: '(string|element|boolean)',
50
+ fallbackPlacement: '(string|array)'
64
51
  };
65
52
 
66
53
  var AttachmentMap = {
67
- TOP: 'bottom center',
68
- RIGHT: 'middle left',
69
- BOTTOM: 'top center',
70
- LEFT: 'middle right'
54
+ AUTO: 'auto',
55
+ TOP: 'top',
56
+ RIGHT: 'right',
57
+ BOTTOM: 'bottom',
58
+ LEFT: 'left'
59
+ };
60
+
61
+ var Default = {
62
+ animation: true,
63
+ template: '<div class="tooltip" role="tooltip">' + '<div class="arrow"></div>' + '<div class="tooltip-inner"></div></div>',
64
+ trigger: 'hover focus',
65
+ title: '',
66
+ delay: 0,
67
+ html: false,
68
+ selector: false,
69
+ placement: 'top',
70
+ offset: 0,
71
+ container: false,
72
+ fallbackPlacement: 'flip'
71
73
  };
72
74
 
73
75
  var HoverState = {
@@ -95,12 +97,8 @@ var Tooltip = function ($) {
95
97
 
96
98
  var Selector = {
97
99
  TOOLTIP: '.tooltip',
98
- TOOLTIP_INNER: '.tooltip-inner'
99
- };
100
-
101
- var TetherClass = {
102
- element: false,
103
- enabled: false
100
+ TOOLTIP_INNER: '.tooltip-inner',
101
+ ARROW: '.arrow'
104
102
  };
105
103
 
106
104
  var Trigger = {
@@ -108,14 +106,14 @@ var Tooltip = function ($) {
108
106
  FOCUS: 'focus',
109
107
  CLICK: 'click',
110
108
  MANUAL: 'manual'
111
- };
112
109
 
113
- /**
114
- * ------------------------------------------------------------------------
115
- * Class Definition
116
- * ------------------------------------------------------------------------
117
- */
110
+ /**
111
+ * ------------------------------------------------------------------------
112
+ * Class Definition
113
+ * ------------------------------------------------------------------------
114
+ */
118
115
 
116
+ };
119
117
  var Tooltip = function () {
120
118
  function Tooltip(element, config) {
121
119
  _classCallCheck(this, Tooltip);
@@ -125,8 +123,7 @@ var Tooltip = function ($) {
125
123
  this._timeout = 0;
126
124
  this._hoverState = '';
127
125
  this._activeTrigger = {};
128
- this._isTransitioning = false;
129
- this._tether = null;
126
+ this._popper = null;
130
127
 
131
128
  // protected
132
129
  this.element = element;
@@ -183,8 +180,6 @@ var Tooltip = function ($) {
183
180
  Tooltip.prototype.dispose = function dispose() {
184
181
  clearTimeout(this._timeout);
185
182
 
186
- this.cleanupTether();
187
-
188
183
  $.removeData(this.element, this.constructor.DATA_KEY);
189
184
 
190
185
  $(this.element).off(this.constructor.EVENT_KEY);
@@ -198,7 +193,10 @@ var Tooltip = function ($) {
198
193
  this._timeout = null;
199
194
  this._hoverState = null;
200
195
  this._activeTrigger = null;
201
- this._tether = null;
196
+ if (this._popper !== null) {
197
+ this._popper.destroy();
198
+ }
199
+ this._popper = null;
202
200
 
203
201
  this.element = null;
204
202
  this.config = null;
@@ -214,9 +212,6 @@ var Tooltip = function ($) {
214
212
 
215
213
  var showEvent = $.Event(this.constructor.Event.SHOW);
216
214
  if (this.isWithContent() && this._isEnabled) {
217
- if (this._isTransitioning) {
218
- throw new Error('Tooltip is transitioning');
219
- }
220
215
  $(this.element).trigger(showEvent);
221
216
 
222
217
  var isInTheDom = $.contains(this.element.ownerDocument.documentElement, this.element);
@@ -240,33 +235,57 @@ var Tooltip = function ($) {
240
235
  var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement;
241
236
 
242
237
  var attachment = this._getAttachment(placement);
238
+ this.addAttachmentClass(attachment);
243
239
 
244
240
  var container = this.config.container === false ? document.body : $(this.config.container);
245
241
 
246
- $(tip).data(this.constructor.DATA_KEY, this).appendTo(container);
242
+ $(tip).data(this.constructor.DATA_KEY, this);
243
+
244
+ if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {
245
+ $(tip).appendTo(container);
246
+ }
247
247
 
248
248
  $(this.element).trigger(this.constructor.Event.INSERTED);
249
249
 
250
- this._tether = new Tether({
251
- attachment: attachment,
252
- element: tip,
253
- target: this.element,
254
- classes: TetherClass,
255
- classPrefix: CLASS_PREFIX,
256
- offset: this.config.offset,
257
- constraints: this.config.constraints,
258
- addTargetClasses: false
250
+ this._popper = new Popper(this.element, tip, {
251
+ placement: attachment,
252
+ modifiers: {
253
+ offset: {
254
+ offset: this.config.offset
255
+ },
256
+ flip: {
257
+ behavior: this.config.fallbackPlacement
258
+ },
259
+ arrow: {
260
+ element: Selector.ARROW
261
+ }
262
+ },
263
+ onCreate: function onCreate(data) {
264
+ if (data.originalPlacement !== data.placement) {
265
+ _this._handlePopperPlacementChange(data);
266
+ }
267
+ },
268
+ onUpdate: function onUpdate(data) {
269
+ _this._handlePopperPlacementChange(data);
270
+ }
259
271
  });
260
272
 
261
- Util.reflow(tip);
262
- this._tether.position();
263
-
264
273
  $(tip).addClass(ClassName.SHOW);
265
274
 
275
+ // if this is a touch-enabled device we add extra
276
+ // empty mouseover listeners to the body's immediate children;
277
+ // only needed because of broken event delegation on iOS
278
+ // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
279
+ if ('ontouchstart' in document.documentElement) {
280
+ $('body').children().on('mouseover', null, $.noop);
281
+ }
282
+
266
283
  var complete = function complete() {
284
+ if (_this.config.animation) {
285
+ _this._fixTransition();
286
+ }
267
287
  var prevHoverState = _this._hoverState;
268
288
  _this._hoverState = null;
269
- _this._isTransitioning = false;
270
289
 
271
290
  $(_this.element).trigger(_this.constructor.Event.SHOWN);
272
291
 
@@ -276,12 +295,10 @@ var Tooltip = function ($) {
276
295
  };
277
296
 
278
297
  if (Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE)) {
279
- this._isTransitioning = true;
280
298
  $(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(Tooltip._TRANSITION_DURATION);
281
- return;
299
+ } else {
300
+ complete();
282
301
  }
283
-
284
- complete();
285
302
  }
286
303
  };
287
304
 
@@ -290,18 +307,17 @@ var Tooltip = function ($) {
290
307
 
291
308
  var tip = this.getTipElement();
292
309
  var hideEvent = $.Event(this.constructor.Event.HIDE);
293
- if (this._isTransitioning) {
294
- throw new Error('Tooltip is transitioning');
295
- }
296
310
  var complete = function complete() {
297
311
  if (_this2._hoverState !== HoverState.SHOW && tip.parentNode) {
298
312
  tip.parentNode.removeChild(tip);
299
313
  }
300
314
 
315
+ _this2._cleanTipClass();
301
316
  _this2.element.removeAttribute('aria-describedby');
302
317
  $(_this2.element).trigger(_this2.constructor.Event.HIDDEN);
303
- _this2._isTransitioning = false;
304
- _this2.cleanupTether();
318
+ if (_this2._popper !== null) {
319
+ _this2._popper.destroy();
320
+ }
305
321
 
306
322
  if (callback) {
307
323
  callback();
@@ -316,12 +332,18 @@ var Tooltip = function ($) {
316
332
 
317
333
  $(tip).removeClass(ClassName.SHOW);
318
334
 
335
+ // if this is a touch-enabled device we remove the extra
336
+ // empty mouseover listeners we added for iOS support
337
+ if ('ontouchstart' in document.documentElement) {
338
+ $('body').children().off('mouseover', null, $.noop);
339
+ }
340
+
319
341
  this._activeTrigger[Trigger.CLICK] = false;
320
342
  this._activeTrigger[Trigger.FOCUS] = false;
321
343
  this._activeTrigger[Trigger.HOVER] = false;
322
344
 
323
345
  if (Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE)) {
324
- this._isTransitioning = true;
346
+
325
347
  $(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
326
348
  } else {
327
349
  complete();
@@ -330,24 +352,30 @@ var Tooltip = function ($) {
330
352
  this._hoverState = '';
331
353
  };
332
354
 
355
+ Tooltip.prototype.update = function update() {
356
+ if (this._popper !== null) {
357
+ this._popper.scheduleUpdate();
358
+ }
359
+ };
360
+
333
361
  // protected
334
362
 
335
363
  Tooltip.prototype.isWithContent = function isWithContent() {
336
364
  return Boolean(this.getTitle());
337
365
  };
338
366
 
367
+ Tooltip.prototype.addAttachmentClass = function addAttachmentClass(attachment) {
368
+ $(this.getTipElement()).addClass(CLASS_PREFIX + '-' + attachment);
369
+ };
370
+
339
371
  Tooltip.prototype.getTipElement = function getTipElement() {
340
372
  return this.tip = this.tip || $(this.config.template)[0];
341
373
  };
342
374
 
343
375
  Tooltip.prototype.setContent = function setContent() {
344
376
  var $tip = $(this.getTipElement());
345
-
346
377
  this.setElementContent($tip.find(Selector.TOOLTIP_INNER), this.getTitle());
347
-
348
378
  $tip.removeClass(ClassName.FADE + ' ' + ClassName.SHOW);
349
-
350
- this.cleanupTether();
351
379
  };
352
380
 
353
381
  Tooltip.prototype.setElementContent = function setElementContent($element, content) {
@@ -376,12 +404,6 @@ var Tooltip = function ($) {
376
404
  return title;
377
405
  };
378
406
 
379
- Tooltip.prototype.cleanupTether = function cleanupTether() {
380
- if (this._tether) {
381
- this._tether.destroy();
382
- }
383
- };
384
-
385
407
  // private
386
408
 
387
409
  Tooltip.prototype._getAttachment = function _getAttachment(placement) {
@@ -521,6 +543,14 @@ var Tooltip = function ($) {
521
543
  };
522
544
  }
523
545
 
546
+ if (config.title && typeof config.title === 'number') {
547
+ config.title = config.title.toString();
548
+ }
549
+
550
+ if (config.content && typeof config.content === 'number') {
551
+ config.content = config.content.toString();
552
+ }
553
+
524
554
  Util.typeCheckConfig(NAME, config, this.constructor.DefaultType);
525
555
 
526
556
  return config;
@@ -540,6 +570,32 @@ var Tooltip = function ($) {
540
570
  return config;
541
571
  };
542
572
 
573
+ Tooltip.prototype._cleanTipClass = function _cleanTipClass() {
574
+ var $tip = $(this.getTipElement());
575
+ var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX);
576
+ if (tabClass !== null && tabClass.length > 0) {
577
+ $tip.removeClass(tabClass.join(''));
578
+ }
579
+ };
580
+
581
+ Tooltip.prototype._handlePopperPlacementChange = function _handlePopperPlacementChange(data) {
582
+ this._cleanTipClass();
583
+ this.addAttachmentClass(this._getAttachment(data.placement));
584
+ };
585
+
586
+ Tooltip.prototype._fixTransition = function _fixTransition() {
587
+ var tip = this.getTipElement();
588
+ var initConfigAnimation = this.config.animation;
589
+ if (tip.getAttribute('x-placement') !== null) {
590
+ return;
591
+ }
592
+ $(tip).removeClass(ClassName.FADE);
593
+ this.config.animation = false;
594
+ this.hide();
595
+ this.show();
596
+ this.config.animation = initConfigAnimation;
597
+ };
598
+
543
599
  // static
544
600
 
545
601
  Tooltip._jQueryInterface = function _jQueryInterface(config) {
@@ -619,4 +675,4 @@ var Tooltip = function ($) {
619
675
  };
620
676
 
621
677
  return Tooltip;
622
- }(jQuery); /* global Tether */
678
+ }(jQuery); /* global Popper */