bootstrap 4.3.1 → 5.3.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 (179) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +55 -0
  3. data/CHANGELOG.md +2 -14
  4. data/README.md +28 -5
  5. data/assets/javascripts/bootstrap/alert.js +54 -163
  6. data/assets/javascripts/bootstrap/base-component.js +83 -0
  7. data/assets/javascripts/bootstrap/button.js +44 -152
  8. data/assets/javascripts/bootstrap/carousel.js +289 -569
  9. data/assets/javascripts/bootstrap/collapse.js +170 -349
  10. data/assets/javascripts/bootstrap/dom/data.js +62 -0
  11. data/assets/javascripts/bootstrap/dom/event-handler.js +236 -0
  12. data/assets/javascripts/bootstrap/dom/manipulator.js +71 -0
  13. data/assets/javascripts/bootstrap/dom/selector-engine.js +103 -0
  14. data/assets/javascripts/bootstrap/dropdown.js +303 -496
  15. data/assets/javascripts/bootstrap/modal.js +229 -559
  16. data/assets/javascripts/bootstrap/offcanvas.js +245 -0
  17. data/assets/javascripts/bootstrap/popover.js +61 -226
  18. data/assets/javascripts/bootstrap/scrollspy.js +217 -317
  19. data/assets/javascripts/bootstrap/tab.js +220 -212
  20. data/assets/javascripts/bootstrap/toast.js +145 -229
  21. data/assets/javascripts/bootstrap/tooltip.js +421 -782
  22. data/assets/javascripts/bootstrap/util/backdrop.js +139 -0
  23. data/assets/javascripts/bootstrap/util/component-functions.js +41 -0
  24. data/assets/javascripts/bootstrap/util/config.js +67 -0
  25. data/assets/javascripts/bootstrap/util/focustrap.js +113 -0
  26. data/assets/javascripts/bootstrap/util/index.js +281 -0
  27. data/assets/javascripts/bootstrap/util/sanitizer.js +110 -0
  28. data/assets/javascripts/bootstrap/util/scrollbar.js +112 -0
  29. data/assets/javascripts/bootstrap/util/swipe.js +134 -0
  30. data/assets/javascripts/bootstrap/util/template-factory.js +150 -0
  31. data/assets/javascripts/bootstrap-global-this-define.js +6 -0
  32. data/assets/javascripts/bootstrap-global-this-undefine.js +2 -0
  33. data/assets/javascripts/bootstrap-sprockets.js +23 -7
  34. data/assets/javascripts/bootstrap.js +3690 -3639
  35. data/assets/javascripts/bootstrap.min.js +4 -4
  36. data/assets/stylesheets/_bootstrap-grid.scss +53 -20
  37. data/assets/stylesheets/_bootstrap-reboot.scss +5 -7
  38. data/assets/stylesheets/_bootstrap.scss +21 -13
  39. data/assets/stylesheets/bootstrap/_accordion.scss +158 -0
  40. data/assets/stylesheets/bootstrap/_alert.scss +32 -15
  41. data/assets/stylesheets/bootstrap/_badge.scss +15 -31
  42. data/assets/stylesheets/bootstrap/_breadcrumb.scss +23 -24
  43. data/assets/stylesheets/bootstrap/_button-group.scss +27 -48
  44. data/assets/stylesheets/bootstrap/_buttons.scss +139 -69
  45. data/assets/stylesheets/bootstrap/_card.scss +91 -141
  46. data/assets/stylesheets/bootstrap/_carousel.scss +86 -39
  47. data/assets/stylesheets/bootstrap/_close.scss +51 -29
  48. data/assets/stylesheets/bootstrap/_containers.scss +41 -0
  49. data/assets/stylesheets/bootstrap/_dropdown.scss +131 -72
  50. data/assets/stylesheets/bootstrap/_forms.scss +9 -330
  51. data/assets/stylesheets/bootstrap/_functions.scss +244 -28
  52. data/assets/stylesheets/bootstrap/_grid.scss +18 -31
  53. data/assets/stylesheets/bootstrap/_helpers.scss +12 -0
  54. data/assets/stylesheets/bootstrap/_images.scss +3 -3
  55. data/assets/stylesheets/bootstrap/_list-group.scss +101 -53
  56. data/assets/stylesheets/bootstrap/_maps.scss +174 -0
  57. data/assets/stylesheets/bootstrap/_mixins.scss +13 -18
  58. data/assets/stylesheets/bootstrap/_modal.scss +120 -112
  59. data/assets/stylesheets/bootstrap/_nav.scss +113 -24
  60. data/assets/stylesheets/bootstrap/_navbar.scss +145 -150
  61. data/assets/stylesheets/bootstrap/_offcanvas.scss +146 -0
  62. data/assets/stylesheets/bootstrap/_pagination.scss +74 -38
  63. data/assets/stylesheets/bootstrap/_placeholders.scss +51 -0
  64. data/assets/stylesheets/bootstrap/_popover.scss +99 -74
  65. data/assets/stylesheets/bootstrap/_progress.scss +40 -15
  66. data/assets/stylesheets/bootstrap/_reboot.scss +342 -215
  67. data/assets/stylesheets/bootstrap/_root.scss +174 -9
  68. data/assets/stylesheets/bootstrap/_spinners.scss +52 -22
  69. data/assets/stylesheets/bootstrap/_tables.scss +101 -115
  70. data/assets/stylesheets/bootstrap/_toasts.scss +54 -25
  71. data/assets/stylesheets/bootstrap/_tooltip.scss +67 -63
  72. data/assets/stylesheets/bootstrap/_transitions.scss +8 -1
  73. data/assets/stylesheets/bootstrap/_type.scss +42 -61
  74. data/assets/stylesheets/bootstrap/_utilities.scss +806 -17
  75. data/assets/stylesheets/bootstrap/_variables-dark.scss +85 -0
  76. data/assets/stylesheets/bootstrap/_variables.scss +1235 -615
  77. data/assets/stylesheets/bootstrap/bootstrap-utilities.scss +19 -0
  78. data/assets/stylesheets/bootstrap/forms/_floating-labels.scss +94 -0
  79. data/assets/stylesheets/bootstrap/forms/_form-check.scss +188 -0
  80. data/assets/stylesheets/bootstrap/forms/_form-control.scss +214 -0
  81. data/assets/stylesheets/bootstrap/forms/_form-range.scss +91 -0
  82. data/assets/stylesheets/bootstrap/forms/_form-select.scss +80 -0
  83. data/assets/stylesheets/bootstrap/forms/_form-text.scss +11 -0
  84. data/assets/stylesheets/bootstrap/forms/_input-group.scss +132 -0
  85. data/assets/stylesheets/bootstrap/forms/_labels.scss +36 -0
  86. data/assets/stylesheets/bootstrap/forms/_validation.scss +12 -0
  87. data/assets/stylesheets/bootstrap/helpers/_color-bg.scss +8 -0
  88. data/assets/stylesheets/bootstrap/helpers/_colored-links.scss +30 -0
  89. data/assets/stylesheets/bootstrap/helpers/_focus-ring.scss +5 -0
  90. data/assets/stylesheets/bootstrap/helpers/_icon-link.scss +25 -0
  91. data/assets/stylesheets/bootstrap/helpers/_position.scss +36 -0
  92. data/assets/stylesheets/bootstrap/helpers/_ratio.scss +26 -0
  93. data/assets/stylesheets/bootstrap/helpers/_stacks.scss +15 -0
  94. data/assets/stylesheets/bootstrap/helpers/_stretched-link.scss +15 -0
  95. data/assets/stylesheets/bootstrap/helpers/_text-truncation.scss +7 -0
  96. data/assets/stylesheets/bootstrap/helpers/_visually-hidden.scss +8 -0
  97. data/assets/stylesheets/bootstrap/helpers/_vr.scss +8 -0
  98. data/assets/stylesheets/bootstrap/mixins/_alert.scss +11 -6
  99. data/assets/stylesheets/bootstrap/mixins/_backdrop.scss +14 -0
  100. data/assets/stylesheets/bootstrap/mixins/_banner.scss +7 -0
  101. data/assets/stylesheets/bootstrap/mixins/_border-radius.scss +37 -22
  102. data/assets/stylesheets/bootstrap/mixins/_box-shadow.scss +7 -9
  103. data/assets/stylesheets/bootstrap/mixins/_breakpoints.scss +20 -16
  104. data/assets/stylesheets/bootstrap/mixins/_buttons.scss +60 -97
  105. data/assets/stylesheets/bootstrap/mixins/_caret.scss +34 -27
  106. data/assets/stylesheets/bootstrap/mixins/_clearfix.scss +2 -0
  107. data/assets/stylesheets/bootstrap/mixins/_color-mode.scss +21 -0
  108. data/assets/stylesheets/bootstrap/mixins/_color-scheme.scss +7 -0
  109. data/assets/stylesheets/bootstrap/mixins/_container.scss +11 -0
  110. data/assets/stylesheets/bootstrap/mixins/_forms.scss +77 -116
  111. data/assets/stylesheets/bootstrap/mixins/_gradients.scss +13 -11
  112. data/assets/stylesheets/bootstrap/mixins/_grid.scss +133 -33
  113. data/assets/stylesheets/bootstrap/mixins/_image.scss +0 -20
  114. data/assets/stylesheets/bootstrap/mixins/_list-group.scss +7 -2
  115. data/assets/stylesheets/bootstrap/mixins/_pagination.scss +7 -19
  116. data/assets/stylesheets/bootstrap/mixins/_reset-text.scss +2 -2
  117. data/assets/stylesheets/bootstrap/mixins/_table-variants.scss +24 -0
  118. data/assets/stylesheets/bootstrap/mixins/_transition.scss +18 -8
  119. data/assets/stylesheets/bootstrap/mixins/_utilities.scss +97 -0
  120. data/assets/stylesheets/bootstrap/mixins/_visually-hidden.scss +33 -0
  121. data/assets/stylesheets/bootstrap/utilities/_api.scss +47 -0
  122. data/assets/stylesheets/bootstrap/vendor/_rfs.scss +276 -132
  123. data/bootstrap.gemspec +4 -6
  124. data/lib/bootstrap/version.rb +2 -2
  125. data/tasks/updater/js.rb +31 -7
  126. data/tasks/updater/network.rb +10 -4
  127. data/tasks/updater/scss.rb +1 -1
  128. data/tasks/updater.rb +2 -2
  129. data/test/dummy_rails/app/assets/config/manifest.js +3 -0
  130. data/test/dummy_rails/app/assets/javascripts/application.js +4 -3
  131. data/test/dummy_rails/app/assets/stylesheets/.browserslistrc +1 -0
  132. data/test/dummy_rails/app/views/layouts/application.html.erb +3 -1
  133. data/test/dummy_rails/app/views/pages/root.html +89 -0
  134. data/test/dummy_rails/config/application.rb +0 -3
  135. data/test/gemfiles/rails_5_2.gemfile +8 -0
  136. data/test/gemfiles/rails_6_0.gemfile +7 -0
  137. data/test/gemfiles/rails_6_1.gemfile +7 -0
  138. data/test/gemfiles/rails_7_0.gemfile +7 -0
  139. data/test/support/dummy_rails_integration.rb +3 -1
  140. data/test/test_helper.rb +18 -12
  141. metadata +86 -84
  142. data/.travis.yml +0 -17
  143. data/assets/javascripts/bootstrap/util.js +0 -171
  144. data/assets/stylesheets/bootstrap/_code.scss +0 -48
  145. data/assets/stylesheets/bootstrap/_custom-forms.scss +0 -507
  146. data/assets/stylesheets/bootstrap/_input-group.scss +0 -193
  147. data/assets/stylesheets/bootstrap/_jumbotron.scss +0 -17
  148. data/assets/stylesheets/bootstrap/_media.scss +0 -8
  149. data/assets/stylesheets/bootstrap/_print.scss +0 -141
  150. data/assets/stylesheets/bootstrap/mixins/_background-variant.scss +0 -21
  151. data/assets/stylesheets/bootstrap/mixins/_badge.scss +0 -17
  152. data/assets/stylesheets/bootstrap/mixins/_float.scss +0 -14
  153. data/assets/stylesheets/bootstrap/mixins/_grid-framework.scss +0 -66
  154. data/assets/stylesheets/bootstrap/mixins/_hover.scss +0 -37
  155. data/assets/stylesheets/bootstrap/mixins/_nav-divider.scss +0 -10
  156. data/assets/stylesheets/bootstrap/mixins/_screen-reader.scss +0 -33
  157. data/assets/stylesheets/bootstrap/mixins/_size.scss +0 -7
  158. data/assets/stylesheets/bootstrap/mixins/_table-row.scss +0 -39
  159. data/assets/stylesheets/bootstrap/mixins/_text-emphasis.scss +0 -16
  160. data/assets/stylesheets/bootstrap/mixins/_text-hide.scss +0 -11
  161. data/assets/stylesheets/bootstrap/mixins/_visibility.scss +0 -8
  162. data/assets/stylesheets/bootstrap/utilities/_align.scss +0 -8
  163. data/assets/stylesheets/bootstrap/utilities/_background.scss +0 -19
  164. data/assets/stylesheets/bootstrap/utilities/_borders.scss +0 -75
  165. data/assets/stylesheets/bootstrap/utilities/_display.scss +0 -26
  166. data/assets/stylesheets/bootstrap/utilities/_embed.scss +0 -39
  167. data/assets/stylesheets/bootstrap/utilities/_flex.scss +0 -51
  168. data/assets/stylesheets/bootstrap/utilities/_float.scss +0 -11
  169. data/assets/stylesheets/bootstrap/utilities/_overflow.scss +0 -5
  170. data/assets/stylesheets/bootstrap/utilities/_position.scss +0 -32
  171. data/assets/stylesheets/bootstrap/utilities/_screenreaders.scss +0 -11
  172. data/assets/stylesheets/bootstrap/utilities/_shadows.scss +0 -6
  173. data/assets/stylesheets/bootstrap/utilities/_sizing.scss +0 -20
  174. data/assets/stylesheets/bootstrap/utilities/_spacing.scss +0 -73
  175. data/assets/stylesheets/bootstrap/utilities/_stretched-link.scss +0 -19
  176. data/assets/stylesheets/bootstrap/utilities/_text.scss +0 -72
  177. data/assets/stylesheets/bootstrap/utilities/_visibility.scss +0 -13
  178. data/test/dummy_rails/app/views/pages/root.html.slim +0 -58
  179. /data/assets/stylesheets/bootstrap/{utilities → helpers}/_clearfix.scss +0 -0
@@ -1,267 +1,275 @@
1
1
  /*!
2
- * Bootstrap tab.js v4.3.1 (https://getbootstrap.com/)
3
- * Copyright 2011-2019 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
4
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
2
+ * Bootstrap tab.js v5.3.0 (https://getbootstrap.com/)
3
+ * Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
4
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5
5
  */
6
6
  (function (global, factory) {
7
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('./util.js')) :
8
- typeof define === 'function' && define.amd ? define(['jquery', './util.js'], factory) :
9
- (global = global || self, global.Tab = factory(global.jQuery, global.Util));
10
- }(this, function ($, Util) { 'use strict';
7
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./base-component.js'), require('./dom/event-handler.js'), require('./dom/selector-engine.js'), require('./util/index.js')) :
8
+ typeof define === 'function' && define.amd ? define(['./base-component', './dom/event-handler', './dom/selector-engine', './util/index'], factory) :
9
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Tab = factory(global.BaseComponent, global.EventHandler, global.SelectorEngine, global.Index));
10
+ })(this, (function (BaseComponent, EventHandler, SelectorEngine, index_js) { 'use strict';
11
11
 
12
- $ = $ && $.hasOwnProperty('default') ? $['default'] : $;
13
- Util = Util && Util.hasOwnProperty('default') ? Util['default'] : Util;
14
-
15
- function _defineProperties(target, props) {
16
- for (var i = 0; i < props.length; i++) {
17
- var descriptor = props[i];
18
- descriptor.enumerable = descriptor.enumerable || false;
19
- descriptor.configurable = true;
20
- if ("value" in descriptor) descriptor.writable = true;
21
- Object.defineProperty(target, descriptor.key, descriptor);
22
- }
23
- }
12
+ /**
13
+ * --------------------------------------------------------------------------
14
+ * Bootstrap tab.js
15
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
16
+ * --------------------------------------------------------------------------
17
+ */
24
18
 
25
- function _createClass(Constructor, protoProps, staticProps) {
26
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
27
- if (staticProps) _defineProperties(Constructor, staticProps);
28
- return Constructor;
29
- }
30
19
 
31
20
  /**
32
- * ------------------------------------------------------------------------
33
21
  * Constants
34
- * ------------------------------------------------------------------------
35
22
  */
36
23
 
37
- var NAME = 'tab';
38
- var VERSION = '4.3.1';
39
- var DATA_KEY = 'bs.tab';
40
- var EVENT_KEY = "." + DATA_KEY;
41
- var DATA_API_KEY = '.data-api';
42
- var JQUERY_NO_CONFLICT = $.fn[NAME];
43
- var Event = {
44
- HIDE: "hide" + EVENT_KEY,
45
- HIDDEN: "hidden" + EVENT_KEY,
46
- SHOW: "show" + EVENT_KEY,
47
- SHOWN: "shown" + EVENT_KEY,
48
- CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY
49
- };
50
- var ClassName = {
51
- DROPDOWN_MENU: 'dropdown-menu',
52
- ACTIVE: 'active',
53
- DISABLED: 'disabled',
54
- FADE: 'fade',
55
- SHOW: 'show'
56
- };
57
- var Selector = {
58
- DROPDOWN: '.dropdown',
59
- NAV_LIST_GROUP: '.nav, .list-group',
60
- ACTIVE: '.active',
61
- ACTIVE_UL: '> li > .active',
62
- DATA_TOGGLE: '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',
63
- DROPDOWN_TOGGLE: '.dropdown-toggle',
64
- DROPDOWN_ACTIVE_CHILD: '> .dropdown-menu .active'
65
- /**
66
- * ------------------------------------------------------------------------
67
- * Class Definition
68
- * ------------------------------------------------------------------------
69
- */
24
+ const NAME = 'tab';
25
+ const DATA_KEY = 'bs.tab';
26
+ const EVENT_KEY = `.${DATA_KEY}`;
27
+ const EVENT_HIDE = `hide${EVENT_KEY}`;
28
+ const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
29
+ const EVENT_SHOW = `show${EVENT_KEY}`;
30
+ const EVENT_SHOWN = `shown${EVENT_KEY}`;
31
+ const EVENT_CLICK_DATA_API = `click${EVENT_KEY}`;
32
+ const EVENT_KEYDOWN = `keydown${EVENT_KEY}`;
33
+ const EVENT_LOAD_DATA_API = `load${EVENT_KEY}`;
34
+ const ARROW_LEFT_KEY = 'ArrowLeft';
35
+ const ARROW_RIGHT_KEY = 'ArrowRight';
36
+ const ARROW_UP_KEY = 'ArrowUp';
37
+ const ARROW_DOWN_KEY = 'ArrowDown';
38
+ const CLASS_NAME_ACTIVE = 'active';
39
+ const CLASS_NAME_FADE = 'fade';
40
+ const CLASS_NAME_SHOW = 'show';
41
+ const CLASS_DROPDOWN = 'dropdown';
42
+ const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';
43
+ const SELECTOR_DROPDOWN_MENU = '.dropdown-menu';
44
+ const NOT_SELECTOR_DROPDOWN_TOGGLE = ':not(.dropdown-toggle)';
45
+ const SELECTOR_TAB_PANEL = '.list-group, .nav, [role="tablist"]';
46
+ const SELECTOR_OUTER = '.nav-item, .list-group-item';
47
+ const SELECTOR_INNER = `.nav-link${NOT_SELECTOR_DROPDOWN_TOGGLE}, .list-group-item${NOT_SELECTOR_DROPDOWN_TOGGLE}, [role="tab"]${NOT_SELECTOR_DROPDOWN_TOGGLE}`;
48
+ const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]'; // TODO: could only be `tab` in v6
49
+ const SELECTOR_INNER_ELEM = `${SELECTOR_INNER}, ${SELECTOR_DATA_TOGGLE}`;
50
+ const SELECTOR_DATA_TOGGLE_ACTIVE = `.${CLASS_NAME_ACTIVE}[data-bs-toggle="tab"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="pill"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="list"]`;
70
51
 
71
- };
52
+ /**
53
+ * Class definition
54
+ */
72
55
 
73
- var Tab =
74
- /*#__PURE__*/
75
- function () {
76
- function Tab(element) {
77
- this._element = element;
78
- } // Getters
56
+ class Tab extends BaseComponent {
57
+ constructor(element) {
58
+ super(element);
59
+ this._parent = this._element.closest(SELECTOR_TAB_PANEL);
60
+ if (!this._parent) {
61
+ return;
62
+ // TODO: should throw exception in v6
63
+ // throw new TypeError(`${element.outerHTML} has not a valid parent ${SELECTOR_INNER_ELEM}`)
64
+ }
79
65
 
66
+ // Set up initial aria attributes
67
+ this._setInitialAttributes(this._parent, this._getChildren());
68
+ EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event));
69
+ }
80
70
 
81
- var _proto = Tab.prototype;
71
+ // Getters
72
+ static get NAME() {
73
+ return NAME;
74
+ }
82
75
 
83
76
  // Public
84
- _proto.show = function show() {
85
- var _this = this;
86
-
87
- if (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && $(this._element).hasClass(ClassName.ACTIVE) || $(this._element).hasClass(ClassName.DISABLED)) {
77
+ show() {
78
+ // Shows this elem and deactivate the active sibling if exists
79
+ const innerElem = this._element;
80
+ if (this._elemIsActive(innerElem)) {
88
81
  return;
89
82
  }
90
83
 
91
- var target;
92
- var previous;
93
- var listElement = $(this._element).closest(Selector.NAV_LIST_GROUP)[0];
94
- var selector = Util.getSelectorFromElement(this._element);
95
-
96
- if (listElement) {
97
- var itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? Selector.ACTIVE_UL : Selector.ACTIVE;
98
- previous = $.makeArray($(listElement).find(itemSelector));
99
- previous = previous[previous.length - 1];
100
- }
101
-
102
- var hideEvent = $.Event(Event.HIDE, {
103
- relatedTarget: this._element
104
- });
105
- var showEvent = $.Event(Event.SHOW, {
106
- relatedTarget: previous
84
+ // Search for active tab on same parent to deactivate it
85
+ const active = this._getActiveElem();
86
+ const hideEvent = active ? EventHandler.trigger(active, EVENT_HIDE, {
87
+ relatedTarget: innerElem
88
+ }) : null;
89
+ const showEvent = EventHandler.trigger(innerElem, EVENT_SHOW, {
90
+ relatedTarget: active
107
91
  });
108
-
109
- if (previous) {
110
- $(previous).trigger(hideEvent);
111
- }
112
-
113
- $(this._element).trigger(showEvent);
114
-
115
- if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) {
92
+ if (showEvent.defaultPrevented || hideEvent && hideEvent.defaultPrevented) {
116
93
  return;
117
94
  }
95
+ this._deactivate(active, innerElem);
96
+ this._activate(innerElem, active);
97
+ }
118
98
 
119
- if (selector) {
120
- target = document.querySelector(selector);
99
+ // Private
100
+ _activate(element, relatedElem) {
101
+ if (!element) {
102
+ return;
121
103
  }
104
+ element.classList.add(CLASS_NAME_ACTIVE);
105
+ this._activate(SelectorEngine.getElementFromSelector(element)); // Search and activate/show the proper section
122
106
 
123
- this._activate(this._element, listElement);
124
-
125
- var complete = function complete() {
126
- var hiddenEvent = $.Event(Event.HIDDEN, {
127
- relatedTarget: _this._element
128
- });
129
- var shownEvent = $.Event(Event.SHOWN, {
130
- relatedTarget: previous
107
+ const complete = () => {
108
+ if (element.getAttribute('role') !== 'tab') {
109
+ element.classList.add(CLASS_NAME_SHOW);
110
+ return;
111
+ }
112
+ element.removeAttribute('tabindex');
113
+ element.setAttribute('aria-selected', true);
114
+ this._toggleDropDown(element, true);
115
+ EventHandler.trigger(element, EVENT_SHOWN, {
116
+ relatedTarget: relatedElem
131
117
  });
132
- $(previous).trigger(hiddenEvent);
133
- $(_this._element).trigger(shownEvent);
134
118
  };
135
-
136
- if (target) {
137
- this._activate(target, target.parentNode, complete);
138
- } else {
139
- complete();
119
+ this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE));
120
+ }
121
+ _deactivate(element, relatedElem) {
122
+ if (!element) {
123
+ return;
140
124
  }
141
- };
142
-
143
- _proto.dispose = function dispose() {
144
- $.removeData(this._element, DATA_KEY);
145
- this._element = null;
146
- } // Private
147
- ;
148
-
149
- _proto._activate = function _activate(element, container, callback) {
150
- var _this2 = this;
151
-
152
- var activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ? $(container).find(Selector.ACTIVE_UL) : $(container).children(Selector.ACTIVE);
153
- var active = activeElements[0];
154
- var isTransitioning = callback && active && $(active).hasClass(ClassName.FADE);
155
-
156
- var complete = function complete() {
157
- return _this2._transitionComplete(element, active, callback);
125
+ element.classList.remove(CLASS_NAME_ACTIVE);
126
+ element.blur();
127
+ this._deactivate(SelectorEngine.getElementFromSelector(element)); // Search and deactivate the shown section too
128
+
129
+ const complete = () => {
130
+ if (element.getAttribute('role') !== 'tab') {
131
+ element.classList.remove(CLASS_NAME_SHOW);
132
+ return;
133
+ }
134
+ element.setAttribute('aria-selected', false);
135
+ element.setAttribute('tabindex', '-1');
136
+ this._toggleDropDown(element, false);
137
+ EventHandler.trigger(element, EVENT_HIDDEN, {
138
+ relatedTarget: relatedElem
139
+ });
158
140
  };
159
-
160
- if (active && isTransitioning) {
161
- var transitionDuration = Util.getTransitionDurationFromElement(active);
162
- $(active).removeClass(ClassName.SHOW).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
163
- } else {
164
- complete();
141
+ this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE));
142
+ }
143
+ _keydown(event) {
144
+ if (![ARROW_LEFT_KEY, ARROW_RIGHT_KEY, ARROW_UP_KEY, ARROW_DOWN_KEY].includes(event.key)) {
145
+ return;
165
146
  }
166
- };
167
-
168
- _proto._transitionComplete = function _transitionComplete(element, active, callback) {
169
- if (active) {
170
- $(active).removeClass(ClassName.ACTIVE);
171
- var dropdownChild = $(active.parentNode).find(Selector.DROPDOWN_ACTIVE_CHILD)[0];
172
-
173
- if (dropdownChild) {
174
- $(dropdownChild).removeClass(ClassName.ACTIVE);
175
- }
176
-
177
- if (active.getAttribute('role') === 'tab') {
178
- active.setAttribute('aria-selected', false);
179
- }
147
+ event.stopPropagation(); // stopPropagation/preventDefault both added to support up/down keys without scrolling the page
148
+ event.preventDefault();
149
+ const isNext = [ARROW_RIGHT_KEY, ARROW_DOWN_KEY].includes(event.key);
150
+ const nextActiveElement = index_js.getNextActiveElement(this._getChildren().filter(element => !index_js.isDisabled(element)), event.target, isNext, true);
151
+ if (nextActiveElement) {
152
+ nextActiveElement.focus({
153
+ preventScroll: true
154
+ });
155
+ Tab.getOrCreateInstance(nextActiveElement).show();
180
156
  }
181
-
182
- $(element).addClass(ClassName.ACTIVE);
183
-
184
- if (element.getAttribute('role') === 'tab') {
185
- element.setAttribute('aria-selected', true);
157
+ }
158
+ _getChildren() {
159
+ // collection of inner elements
160
+ return SelectorEngine.find(SELECTOR_INNER_ELEM, this._parent);
161
+ }
162
+ _getActiveElem() {
163
+ return this._getChildren().find(child => this._elemIsActive(child)) || null;
164
+ }
165
+ _setInitialAttributes(parent, children) {
166
+ this._setAttributeIfNotExists(parent, 'role', 'tablist');
167
+ for (const child of children) {
168
+ this._setInitialAttributesOnChild(child);
186
169
  }
187
-
188
- Util.reflow(element);
189
-
190
- if (element.classList.contains(ClassName.FADE)) {
191
- element.classList.add(ClassName.SHOW);
170
+ }
171
+ _setInitialAttributesOnChild(child) {
172
+ child = this._getInnerElement(child);
173
+ const isActive = this._elemIsActive(child);
174
+ const outerElem = this._getOuterElement(child);
175
+ child.setAttribute('aria-selected', isActive);
176
+ if (outerElem !== child) {
177
+ this._setAttributeIfNotExists(outerElem, 'role', 'presentation');
192
178
  }
179
+ if (!isActive) {
180
+ child.setAttribute('tabindex', '-1');
181
+ }
182
+ this._setAttributeIfNotExists(child, 'role', 'tab');
193
183
 
194
- if (element.parentNode && $(element.parentNode).hasClass(ClassName.DROPDOWN_MENU)) {
195
- var dropdownElement = $(element).closest(Selector.DROPDOWN)[0];
196
-
197
- if (dropdownElement) {
198
- var dropdownToggleList = [].slice.call(dropdownElement.querySelectorAll(Selector.DROPDOWN_TOGGLE));
199
- $(dropdownToggleList).addClass(ClassName.ACTIVE);
184
+ // set attributes to the related panel too
185
+ this._setInitialAttributesOnTargetPanel(child);
186
+ }
187
+ _setInitialAttributesOnTargetPanel(child) {
188
+ const target = SelectorEngine.getElementFromSelector(child);
189
+ if (!target) {
190
+ return;
191
+ }
192
+ this._setAttributeIfNotExists(target, 'role', 'tabpanel');
193
+ if (child.id) {
194
+ this._setAttributeIfNotExists(target, 'aria-labelledby', `${child.id}`);
195
+ }
196
+ }
197
+ _toggleDropDown(element, open) {
198
+ const outerElem = this._getOuterElement(element);
199
+ if (!outerElem.classList.contains(CLASS_DROPDOWN)) {
200
+ return;
201
+ }
202
+ const toggle = (selector, className) => {
203
+ const element = SelectorEngine.findOne(selector, outerElem);
204
+ if (element) {
205
+ element.classList.toggle(className, open);
200
206
  }
201
-
202
- element.setAttribute('aria-expanded', true);
207
+ };
208
+ toggle(SELECTOR_DROPDOWN_TOGGLE, CLASS_NAME_ACTIVE);
209
+ toggle(SELECTOR_DROPDOWN_MENU, CLASS_NAME_SHOW);
210
+ outerElem.setAttribute('aria-expanded', open);
211
+ }
212
+ _setAttributeIfNotExists(element, attribute, value) {
213
+ if (!element.hasAttribute(attribute)) {
214
+ element.setAttribute(attribute, value);
203
215
  }
216
+ }
217
+ _elemIsActive(elem) {
218
+ return elem.classList.contains(CLASS_NAME_ACTIVE);
219
+ }
204
220
 
205
- if (callback) {
206
- callback();
207
- }
208
- } // Static
209
- ;
221
+ // Try to get the inner element (usually the .nav-link)
222
+ _getInnerElement(elem) {
223
+ return elem.matches(SELECTOR_INNER_ELEM) ? elem : SelectorEngine.findOne(SELECTOR_INNER_ELEM, elem);
224
+ }
210
225
 
211
- Tab._jQueryInterface = function _jQueryInterface(config) {
212
- return this.each(function () {
213
- var $this = $(this);
214
- var data = $this.data(DATA_KEY);
226
+ // Try to get the outer element (usually the .nav-item)
227
+ _getOuterElement(elem) {
228
+ return elem.closest(SELECTOR_OUTER) || elem;
229
+ }
215
230
 
216
- if (!data) {
217
- data = new Tab(this);
218
- $this.data(DATA_KEY, data);
231
+ // Static
232
+ static jQueryInterface(config) {
233
+ return this.each(function () {
234
+ const data = Tab.getOrCreateInstance(this);
235
+ if (typeof config !== 'string') {
236
+ return;
219
237
  }
220
-
221
- if (typeof config === 'string') {
222
- if (typeof data[config] === 'undefined') {
223
- throw new TypeError("No method named \"" + config + "\"");
224
- }
225
-
226
- data[config]();
238
+ if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
239
+ throw new TypeError(`No method named "${config}"`);
227
240
  }
241
+ data[config]();
228
242
  });
229
- };
230
-
231
- _createClass(Tab, null, [{
232
- key: "VERSION",
233
- get: function get() {
234
- return VERSION;
235
- }
236
- }]);
243
+ }
244
+ }
237
245
 
238
- return Tab;
239
- }();
240
246
  /**
241
- * ------------------------------------------------------------------------
242
- * Data Api implementation
243
- * ------------------------------------------------------------------------
247
+ * Data API implementation
244
248
  */
245
249
 
250
+ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
251
+ if (['A', 'AREA'].includes(this.tagName)) {
252
+ event.preventDefault();
253
+ }
254
+ if (index_js.isDisabled(this)) {
255
+ return;
256
+ }
257
+ Tab.getOrCreateInstance(this).show();
258
+ });
246
259
 
247
- $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
248
- event.preventDefault();
249
-
250
- Tab._jQueryInterface.call($(this), 'show');
260
+ /**
261
+ * Initialize on focus
262
+ */
263
+ EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
264
+ for (const element of SelectorEngine.find(SELECTOR_DATA_TOGGLE_ACTIVE)) {
265
+ Tab.getOrCreateInstance(element);
266
+ }
251
267
  });
252
268
  /**
253
- * ------------------------------------------------------------------------
254
269
  * jQuery
255
- * ------------------------------------------------------------------------
256
270
  */
257
271
 
258
- $.fn[NAME] = Tab._jQueryInterface;
259
- $.fn[NAME].Constructor = Tab;
260
-
261
- $.fn[NAME].noConflict = function () {
262
- $.fn[NAME] = JQUERY_NO_CONFLICT;
263
- return Tab._jQueryInterface;
264
- };
272
+ index_js.defineJQueryPlugin(Tab);
265
273
 
266
274
  return Tab;
267
275