bootstrap 5.1.3 → 5.3.5
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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +61 -0
- data/CHANGELOG.md +9 -0
- data/Gemfile +1 -0
- data/README.md +35 -14
- data/Rakefile +16 -5
- data/assets/javascripts/bootstrap/alert.js +22 -167
- data/assets/javascripts/bootstrap/base-component.js +34 -133
- data/assets/javascripts/bootstrap/button.js +19 -86
- data/assets/javascripts/bootstrap/carousel.js +209 -564
- data/assets/javascripts/bootstrap/collapse.js +78 -324
- data/assets/javascripts/bootstrap/dom/data.js +8 -14
- data/assets/javascripts/bootstrap/dom/event-handler.js +89 -174
- data/assets/javascripts/bootstrap/dom/manipulator.js +22 -39
- data/assets/javascripts/bootstrap/dom/selector-engine.js +47 -71
- data/assets/javascripts/bootstrap/dropdown.js +135 -420
- data/assets/javascripts/bootstrap/modal.js +115 -837
- data/assets/javascripts/bootstrap/offcanvas.js +93 -714
- data/assets/javascripts/bootstrap/popover.js +42 -130
- data/assets/javascripts/bootstrap/scrollspy.js +180 -296
- data/assets/javascripts/bootstrap/tab.js +197 -245
- data/assets/javascripts/bootstrap/toast.js +52 -276
- data/assets/javascripts/bootstrap/tooltip.js +283 -744
- data/assets/javascripts/bootstrap/util/backdrop.js +138 -0
- data/assets/javascripts/bootstrap/util/component-functions.js +41 -0
- data/assets/javascripts/bootstrap/util/config.js +67 -0
- data/assets/javascripts/bootstrap/util/focustrap.js +112 -0
- data/assets/javascripts/bootstrap/util/index.js +280 -0
- data/assets/javascripts/bootstrap/util/sanitizer.js +113 -0
- data/assets/javascripts/bootstrap/util/scrollbar.js +112 -0
- data/assets/javascripts/bootstrap/util/swipe.js +134 -0
- data/assets/javascripts/bootstrap/util/template-factory.js +150 -0
- data/assets/javascripts/bootstrap-global-this-define.js +1 -1
- data/assets/javascripts/bootstrap-sprockets.js +15 -6
- data/assets/javascripts/bootstrap.js +2278 -2831
- data/assets/javascripts/bootstrap.min.js +3 -3
- data/assets/stylesheets/_bootstrap-grid.scss +4 -9
- data/assets/stylesheets/_bootstrap-reboot.scss +4 -7
- data/assets/stylesheets/_bootstrap-utilities.scss +19 -0
- data/assets/stylesheets/_bootstrap.scss +5 -6
- data/assets/stylesheets/bootstrap/_accordion.scss +68 -33
- data/assets/stylesheets/bootstrap/_alert.scss +25 -14
- data/assets/stylesheets/bootstrap/_badge.scss +14 -5
- data/assets/stylesheets/bootstrap/_breadcrumb.scss +22 -10
- data/assets/stylesheets/bootstrap/_button-group.scss +12 -4
- data/assets/stylesheets/bootstrap/_buttons.scss +133 -28
- data/assets/stylesheets/bootstrap/_card.scss +61 -39
- data/assets/stylesheets/bootstrap/_carousel.scss +22 -25
- data/assets/stylesheets/bootstrap/_close.scss +36 -10
- data/assets/stylesheets/bootstrap/_containers.scss +1 -1
- data/assets/stylesheets/bootstrap/_dropdown.scss +86 -76
- data/assets/stylesheets/bootstrap/_functions.scss +10 -10
- data/assets/stylesheets/bootstrap/_grid.scss +9 -3
- data/assets/stylesheets/bootstrap/_helpers.scss +3 -0
- data/assets/stylesheets/bootstrap/_list-group.scss +81 -56
- data/assets/stylesheets/bootstrap/_maps.scss +174 -0
- data/assets/stylesheets/bootstrap/_mixins.scss +1 -2
- data/assets/stylesheets/bootstrap/_modal.scss +76 -45
- data/assets/stylesheets/bootstrap/_nav.scss +87 -29
- data/assets/stylesheets/bootstrap/_navbar.scss +102 -148
- data/assets/stylesheets/bootstrap/_offcanvas.scss +125 -61
- data/assets/stylesheets/bootstrap/_pagination.scss +66 -21
- data/assets/stylesheets/bootstrap/_placeholders.scss +1 -1
- data/assets/stylesheets/bootstrap/_popover.scss +90 -52
- data/assets/stylesheets/bootstrap/_progress.scss +31 -11
- data/assets/stylesheets/bootstrap/_reboot.scss +32 -46
- data/assets/stylesheets/bootstrap/_root.scss +155 -22
- data/assets/stylesheets/bootstrap/_spinners.scss +38 -22
- data/assets/stylesheets/bootstrap/_tables.scss +40 -24
- data/assets/stylesheets/bootstrap/_toasts.scss +38 -16
- data/assets/stylesheets/bootstrap/_tooltip.scss +60 -56
- data/assets/stylesheets/bootstrap/_type.scss +3 -1
- data/assets/stylesheets/bootstrap/_utilities.scss +209 -33
- data/assets/stylesheets/bootstrap/_variables-dark.scss +102 -0
- data/assets/stylesheets/bootstrap/_variables.scss +415 -303
- data/assets/stylesheets/bootstrap/forms/_floating-labels.scss +39 -5
- data/assets/stylesheets/bootstrap/forms/_form-check.scss +51 -14
- data/assets/stylesheets/bootstrap/forms/_form-control.scss +36 -41
- data/assets/stylesheets/bootstrap/forms/_form-range.scss +3 -3
- data/assets/stylesheets/bootstrap/forms/_form-select.scss +12 -4
- data/assets/stylesheets/bootstrap/forms/_input-group.scss +20 -9
- data/assets/stylesheets/bootstrap/helpers/_color-bg.scss +7 -0
- data/assets/stylesheets/bootstrap/helpers/_colored-links.scss +20 -2
- data/assets/stylesheets/bootstrap/helpers/_focus-ring.scss +5 -0
- data/assets/stylesheets/bootstrap/helpers/_icon-link.scss +25 -0
- data/assets/stylesheets/bootstrap/helpers/_position.scss +7 -1
- data/assets/stylesheets/bootstrap/helpers/_ratio.scss +2 -2
- data/assets/stylesheets/bootstrap/helpers/_vr.scss +2 -2
- data/assets/stylesheets/bootstrap/mixins/_alert.scss +11 -4
- data/assets/stylesheets/bootstrap/mixins/_banner.scss +7 -0
- data/assets/stylesheets/bootstrap/mixins/_breakpoints.scss +8 -8
- data/assets/stylesheets/bootstrap/mixins/_buttons.scss +32 -95
- data/assets/stylesheets/bootstrap/mixins/_caret.scss +30 -25
- data/assets/stylesheets/bootstrap/mixins/_color-mode.scss +21 -0
- data/assets/stylesheets/bootstrap/mixins/_container.scss +4 -2
- data/assets/stylesheets/bootstrap/mixins/_forms.scss +38 -19
- data/assets/stylesheets/bootstrap/mixins/_gradients.scss +1 -1
- data/assets/stylesheets/bootstrap/mixins/_grid.scss +15 -15
- data/assets/stylesheets/bootstrap/mixins/_list-group.scss +2 -0
- data/assets/stylesheets/bootstrap/mixins/_pagination.scss +4 -25
- data/assets/stylesheets/bootstrap/mixins/_reset-text.scss +1 -1
- data/assets/stylesheets/bootstrap/mixins/_table-variants.scss +12 -9
- data/assets/stylesheets/bootstrap/mixins/_utilities.scss +14 -6
- data/assets/stylesheets/bootstrap/mixins/_visually-hidden.scss +6 -2
- data/assets/stylesheets/bootstrap/vendor/_rfs.scss +23 -29
- data/bootstrap.gemspec +3 -3
- data/lib/bootstrap/engine.rb +17 -2
- data/lib/bootstrap/version.rb +2 -2
- data/tasks/updater/js.rb +10 -5
- data/tasks/updater/network.rb +2 -2
- data/tasks/updater/scss.rb +2 -2
- data/tasks/updater.rb +2 -2
- data/test/dummy_rails/config/application.rb +0 -2
- data/test/dummy_rails/public/favicon.ico +0 -0
- data/test/gemfiles/rails_4_2.gemfile +2 -1
- data/test/gemfiles/rails_5_0.gemfile +1 -2
- data/test/gemfiles/rails_5_1.gemfile +1 -2
- data/test/gemfiles/rails_5_2.gemfile +7 -0
- data/test/gemfiles/rails_6_0.gemfile +1 -1
- data/test/gemfiles/rails_6_1.gemfile +1 -1
- data/test/gemfiles/rails_7_0_dartsass.gemfile +7 -0
- data/test/gemfiles/rails_7_0_sassc.gemfile +7 -0
- data/test/rails_test.rb +0 -5
- data/test/test_helper.rb +3 -2
- metadata +49 -29
- data/.travis.yml +0 -32
- data/assets/stylesheets/bootstrap/bootstrap-utilities.scss +0 -18
|
@@ -1,331 +1,283 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Bootstrap tab.js v5.
|
|
3
|
-
* Copyright 2011-
|
|
2
|
+
* Bootstrap tab.js v5.3.5 (https://getbootstrap.com/)
|
|
3
|
+
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
|
4
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('./dom/event-handler.js'), require('./dom/selector-engine.js'), require('./
|
|
8
|
-
typeof define === 'function' && define.amd ? define(['./dom/event-handler', './dom/selector-engine', './
|
|
9
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Tab = factory(global.EventHandler, global.SelectorEngine, global.
|
|
10
|
-
})(this, (function (EventHandler, SelectorEngine,
|
|
11
|
-
|
|
12
|
-
const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
|
|
13
|
-
|
|
14
|
-
const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
|
|
15
|
-
const SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
|
|
16
|
-
const BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
|
|
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';
|
|
17
11
|
|
|
18
12
|
/**
|
|
19
13
|
* --------------------------------------------------------------------------
|
|
20
|
-
* Bootstrap
|
|
14
|
+
* Bootstrap tab.js
|
|
21
15
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
22
16
|
* --------------------------------------------------------------------------
|
|
23
17
|
*/
|
|
24
18
|
|
|
25
|
-
const getSelector = element => {
|
|
26
|
-
let selector = element.getAttribute('data-bs-target');
|
|
27
|
-
|
|
28
|
-
if (!selector || selector === '#') {
|
|
29
|
-
let hrefAttr = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,
|
|
30
|
-
// so everything starting with `#` or `.`. If a "real" URL is used as the selector,
|
|
31
|
-
// `document.querySelector` will rightfully complain it is invalid.
|
|
32
|
-
// See https://github.com/twbs/bootstrap/issues/32273
|
|
33
|
-
|
|
34
|
-
if (!hrefAttr || !hrefAttr.includes('#') && !hrefAttr.startsWith('.')) {
|
|
35
|
-
return null;
|
|
36
|
-
} // Just in case some CMS puts out a full URL with the anchor appended
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
|
|
40
|
-
hrefAttr = `#${hrefAttr.split('#')[1]}`;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return selector;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const getElementFromSelector = element => {
|
|
50
|
-
const selector = getSelector(element);
|
|
51
|
-
return selector ? document.querySelector(selector) : null;
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const isDisabled = element => {
|
|
55
|
-
if (!element || element.nodeType !== Node.ELEMENT_NODE) {
|
|
56
|
-
return true;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (element.classList.contains('disabled')) {
|
|
60
|
-
return true;
|
|
61
|
-
}
|
|
62
19
|
|
|
63
|
-
if (typeof element.disabled !== 'undefined') {
|
|
64
|
-
return element.disabled;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
|
|
68
|
-
};
|
|
69
20
|
/**
|
|
70
|
-
* Trick to restart an element's animation
|
|
71
|
-
*
|
|
72
|
-
* @param {HTMLElement} element
|
|
73
|
-
* @return void
|
|
74
|
-
*
|
|
75
|
-
* @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
|
|
76
|
-
*/
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const reflow = element => {
|
|
80
|
-
// eslint-disable-next-line no-unused-expressions
|
|
81
|
-
element.offsetHeight;
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
const getjQuery = () => {
|
|
85
|
-
const {
|
|
86
|
-
jQuery
|
|
87
|
-
} = window;
|
|
88
|
-
|
|
89
|
-
if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
|
|
90
|
-
return jQuery;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return null;
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
const DOMContentLoadedCallbacks = [];
|
|
97
|
-
|
|
98
|
-
const onDOMContentLoaded = callback => {
|
|
99
|
-
if (document.readyState === 'loading') {
|
|
100
|
-
// add listener on the first call when the document is in loading state
|
|
101
|
-
if (!DOMContentLoadedCallbacks.length) {
|
|
102
|
-
document.addEventListener('DOMContentLoaded', () => {
|
|
103
|
-
DOMContentLoadedCallbacks.forEach(callback => callback());
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
DOMContentLoadedCallbacks.push(callback);
|
|
108
|
-
} else {
|
|
109
|
-
callback();
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
const defineJQueryPlugin = plugin => {
|
|
114
|
-
onDOMContentLoaded(() => {
|
|
115
|
-
const $ = getjQuery();
|
|
116
|
-
/* istanbul ignore if */
|
|
117
|
-
|
|
118
|
-
if ($) {
|
|
119
|
-
const name = plugin.NAME;
|
|
120
|
-
const JQUERY_NO_CONFLICT = $.fn[name];
|
|
121
|
-
$.fn[name] = plugin.jQueryInterface;
|
|
122
|
-
$.fn[name].Constructor = plugin;
|
|
123
|
-
|
|
124
|
-
$.fn[name].noConflict = () => {
|
|
125
|
-
$.fn[name] = JQUERY_NO_CONFLICT;
|
|
126
|
-
return plugin.jQueryInterface;
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* --------------------------------------------------------------------------
|
|
134
|
-
* Bootstrap (v5.1.3): tab.js
|
|
135
|
-
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
136
|
-
* --------------------------------------------------------------------------
|
|
137
|
-
*/
|
|
138
|
-
/**
|
|
139
|
-
* ------------------------------------------------------------------------
|
|
140
21
|
* Constants
|
|
141
|
-
* ------------------------------------------------------------------------
|
|
142
22
|
*/
|
|
143
23
|
|
|
144
24
|
const NAME = 'tab';
|
|
145
25
|
const DATA_KEY = 'bs.tab';
|
|
146
26
|
const EVENT_KEY = `.${DATA_KEY}`;
|
|
147
|
-
const DATA_API_KEY = '.data-api';
|
|
148
27
|
const EVENT_HIDE = `hide${EVENT_KEY}`;
|
|
149
28
|
const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
|
|
150
29
|
const EVENT_SHOW = `show${EVENT_KEY}`;
|
|
151
30
|
const EVENT_SHOWN = `shown${EVENT_KEY}`;
|
|
152
|
-
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}
|
|
153
|
-
const
|
|
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 HOME_KEY = 'Home';
|
|
39
|
+
const END_KEY = 'End';
|
|
154
40
|
const CLASS_NAME_ACTIVE = 'active';
|
|
155
41
|
const CLASS_NAME_FADE = 'fade';
|
|
156
42
|
const CLASS_NAME_SHOW = 'show';
|
|
157
|
-
const
|
|
158
|
-
const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';
|
|
159
|
-
const SELECTOR_ACTIVE = '.active';
|
|
160
|
-
const SELECTOR_ACTIVE_UL = ':scope > li > .active';
|
|
161
|
-
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]';
|
|
43
|
+
const CLASS_DROPDOWN = 'dropdown';
|
|
162
44
|
const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';
|
|
163
|
-
const
|
|
45
|
+
const SELECTOR_DROPDOWN_MENU = '.dropdown-menu';
|
|
46
|
+
const NOT_SELECTOR_DROPDOWN_TOGGLE = `:not(${SELECTOR_DROPDOWN_TOGGLE})`;
|
|
47
|
+
const SELECTOR_TAB_PANEL = '.list-group, .nav, [role="tablist"]';
|
|
48
|
+
const SELECTOR_OUTER = '.nav-item, .list-group-item';
|
|
49
|
+
const SELECTOR_INNER = `.nav-link${NOT_SELECTOR_DROPDOWN_TOGGLE}, .list-group-item${NOT_SELECTOR_DROPDOWN_TOGGLE}, [role="tab"]${NOT_SELECTOR_DROPDOWN_TOGGLE}`;
|
|
50
|
+
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]'; // TODO: could only be `tab` in v6
|
|
51
|
+
const SELECTOR_INNER_ELEM = `${SELECTOR_INNER}, ${SELECTOR_DATA_TOGGLE}`;
|
|
52
|
+
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"]`;
|
|
53
|
+
|
|
164
54
|
/**
|
|
165
|
-
*
|
|
166
|
-
* Class Definition
|
|
167
|
-
* ------------------------------------------------------------------------
|
|
55
|
+
* Class definition
|
|
168
56
|
*/
|
|
169
57
|
|
|
170
|
-
class Tab extends
|
|
58
|
+
class Tab extends BaseComponent {
|
|
59
|
+
constructor(element) {
|
|
60
|
+
super(element);
|
|
61
|
+
this._parent = this._element.closest(SELECTOR_TAB_PANEL);
|
|
62
|
+
if (!this._parent) {
|
|
63
|
+
return;
|
|
64
|
+
// TODO: should throw exception in v6
|
|
65
|
+
// throw new TypeError(`${element.outerHTML} has not a valid parent ${SELECTOR_INNER_ELEM}`)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Set up initial aria attributes
|
|
69
|
+
this._setInitialAttributes(this._parent, this._getChildren());
|
|
70
|
+
EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event));
|
|
71
|
+
}
|
|
72
|
+
|
|
171
73
|
// Getters
|
|
172
74
|
static get NAME() {
|
|
173
75
|
return NAME;
|
|
174
|
-
}
|
|
175
|
-
|
|
76
|
+
}
|
|
176
77
|
|
|
78
|
+
// Public
|
|
177
79
|
show() {
|
|
178
|
-
|
|
80
|
+
// Shows this elem and deactivate the active sibling if exists
|
|
81
|
+
const innerElem = this._element;
|
|
82
|
+
if (this._elemIsActive(innerElem)) {
|
|
179
83
|
return;
|
|
180
84
|
}
|
|
181
85
|
|
|
182
|
-
|
|
183
|
-
const
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
if (listElement) {
|
|
188
|
-
const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE;
|
|
189
|
-
previous = SelectorEngine__default.default.find(itemSelector, listElement);
|
|
190
|
-
previous = previous[previous.length - 1];
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
const hideEvent = previous ? EventHandler__default.default.trigger(previous, EVENT_HIDE, {
|
|
194
|
-
relatedTarget: this._element
|
|
86
|
+
// Search for active tab on same parent to deactivate it
|
|
87
|
+
const active = this._getActiveElem();
|
|
88
|
+
const hideEvent = active ? EventHandler.trigger(active, EVENT_HIDE, {
|
|
89
|
+
relatedTarget: innerElem
|
|
195
90
|
}) : null;
|
|
196
|
-
const showEvent =
|
|
197
|
-
relatedTarget:
|
|
91
|
+
const showEvent = EventHandler.trigger(innerElem, EVENT_SHOW, {
|
|
92
|
+
relatedTarget: active
|
|
198
93
|
});
|
|
199
|
-
|
|
200
|
-
if (showEvent.defaultPrevented || hideEvent !== null && hideEvent.defaultPrevented) {
|
|
94
|
+
if (showEvent.defaultPrevented || hideEvent && hideEvent.defaultPrevented) {
|
|
201
95
|
return;
|
|
202
96
|
}
|
|
97
|
+
this._deactivate(active, innerElem);
|
|
98
|
+
this._activate(innerElem, active);
|
|
99
|
+
}
|
|
203
100
|
|
|
204
|
-
|
|
101
|
+
// Private
|
|
102
|
+
_activate(element, relatedElem) {
|
|
103
|
+
if (!element) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
element.classList.add(CLASS_NAME_ACTIVE);
|
|
107
|
+
this._activate(SelectorEngine.getElementFromSelector(element)); // Search and activate/show the proper section
|
|
205
108
|
|
|
206
109
|
const complete = () => {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
110
|
+
if (element.getAttribute('role') !== 'tab') {
|
|
111
|
+
element.classList.add(CLASS_NAME_SHOW);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
element.removeAttribute('tabindex');
|
|
115
|
+
element.setAttribute('aria-selected', true);
|
|
116
|
+
this._toggleDropDown(element, true);
|
|
117
|
+
EventHandler.trigger(element, EVENT_SHOWN, {
|
|
118
|
+
relatedTarget: relatedElem
|
|
212
119
|
});
|
|
213
120
|
};
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
121
|
+
this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE));
|
|
122
|
+
}
|
|
123
|
+
_deactivate(element, relatedElem) {
|
|
124
|
+
if (!element) {
|
|
125
|
+
return;
|
|
219
126
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
_activate(element, container, callback) {
|
|
224
|
-
const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ? SelectorEngine__default.default.find(SELECTOR_ACTIVE_UL, container) : SelectorEngine__default.default.children(container, SELECTOR_ACTIVE);
|
|
225
|
-
const active = activeElements[0];
|
|
226
|
-
const isTransitioning = callback && active && active.classList.contains(CLASS_NAME_FADE);
|
|
227
|
-
|
|
228
|
-
const complete = () => this._transitionComplete(element, active, callback);
|
|
229
|
-
|
|
230
|
-
if (active && isTransitioning) {
|
|
231
|
-
active.classList.remove(CLASS_NAME_SHOW);
|
|
127
|
+
element.classList.remove(CLASS_NAME_ACTIVE);
|
|
128
|
+
element.blur();
|
|
129
|
+
this._deactivate(SelectorEngine.getElementFromSelector(element)); // Search and deactivate the shown section too
|
|
232
130
|
|
|
233
|
-
|
|
131
|
+
const complete = () => {
|
|
132
|
+
if (element.getAttribute('role') !== 'tab') {
|
|
133
|
+
element.classList.remove(CLASS_NAME_SHOW);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
element.setAttribute('aria-selected', false);
|
|
137
|
+
element.setAttribute('tabindex', '-1');
|
|
138
|
+
this._toggleDropDown(element, false);
|
|
139
|
+
EventHandler.trigger(element, EVENT_HIDDEN, {
|
|
140
|
+
relatedTarget: relatedElem
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE));
|
|
144
|
+
}
|
|
145
|
+
_keydown(event) {
|
|
146
|
+
if (![ARROW_LEFT_KEY, ARROW_RIGHT_KEY, ARROW_UP_KEY, ARROW_DOWN_KEY, HOME_KEY, END_KEY].includes(event.key)) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
event.stopPropagation(); // stopPropagation/preventDefault both added to support up/down keys without scrolling the page
|
|
150
|
+
event.preventDefault();
|
|
151
|
+
const children = this._getChildren().filter(element => !index_js.isDisabled(element));
|
|
152
|
+
let nextActiveElement;
|
|
153
|
+
if ([HOME_KEY, END_KEY].includes(event.key)) {
|
|
154
|
+
nextActiveElement = children[event.key === HOME_KEY ? 0 : children.length - 1];
|
|
234
155
|
} else {
|
|
235
|
-
|
|
156
|
+
const isNext = [ARROW_RIGHT_KEY, ARROW_DOWN_KEY].includes(event.key);
|
|
157
|
+
nextActiveElement = index_js.getNextActiveElement(children, event.target, isNext, true);
|
|
158
|
+
}
|
|
159
|
+
if (nextActiveElement) {
|
|
160
|
+
nextActiveElement.focus({
|
|
161
|
+
preventScroll: true
|
|
162
|
+
});
|
|
163
|
+
Tab.getOrCreateInstance(nextActiveElement).show();
|
|
236
164
|
}
|
|
237
165
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
active.setAttribute('aria-selected', false);
|
|
250
|
-
}
|
|
166
|
+
_getChildren() {
|
|
167
|
+
// collection of inner elements
|
|
168
|
+
return SelectorEngine.find(SELECTOR_INNER_ELEM, this._parent);
|
|
169
|
+
}
|
|
170
|
+
_getActiveElem() {
|
|
171
|
+
return this._getChildren().find(child => this._elemIsActive(child)) || null;
|
|
172
|
+
}
|
|
173
|
+
_setInitialAttributes(parent, children) {
|
|
174
|
+
this._setAttributeIfNotExists(parent, 'role', 'tablist');
|
|
175
|
+
for (const child of children) {
|
|
176
|
+
this._setInitialAttributesOnChild(child);
|
|
251
177
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
178
|
+
}
|
|
179
|
+
_setInitialAttributesOnChild(child) {
|
|
180
|
+
child = this._getInnerElement(child);
|
|
181
|
+
const isActive = this._elemIsActive(child);
|
|
182
|
+
const outerElem = this._getOuterElement(child);
|
|
183
|
+
child.setAttribute('aria-selected', isActive);
|
|
184
|
+
if (outerElem !== child) {
|
|
185
|
+
this._setAttributeIfNotExists(outerElem, 'role', 'presentation');
|
|
257
186
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
if (element.classList.contains(CLASS_NAME_FADE)) {
|
|
262
|
-
element.classList.add(CLASS_NAME_SHOW);
|
|
187
|
+
if (!isActive) {
|
|
188
|
+
child.setAttribute('tabindex', '-1');
|
|
263
189
|
}
|
|
190
|
+
this._setAttributeIfNotExists(child, 'role', 'tab');
|
|
264
191
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
192
|
+
// set attributes to the related panel too
|
|
193
|
+
this._setInitialAttributesOnTargetPanel(child);
|
|
194
|
+
}
|
|
195
|
+
_setInitialAttributesOnTargetPanel(child) {
|
|
196
|
+
const target = SelectorEngine.getElementFromSelector(child);
|
|
197
|
+
if (!target) {
|
|
198
|
+
return;
|
|
269
199
|
}
|
|
270
|
-
|
|
271
|
-
if (
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
200
|
+
this._setAttributeIfNotExists(target, 'role', 'tabpanel');
|
|
201
|
+
if (child.id) {
|
|
202
|
+
this._setAttributeIfNotExists(target, 'aria-labelledby', `${child.id}`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
_toggleDropDown(element, open) {
|
|
206
|
+
const outerElem = this._getOuterElement(element);
|
|
207
|
+
if (!outerElem.classList.contains(CLASS_DROPDOWN)) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const toggle = (selector, className) => {
|
|
211
|
+
const element = SelectorEngine.findOne(selector, outerElem);
|
|
212
|
+
if (element) {
|
|
213
|
+
element.classList.toggle(className, open);
|
|
276
214
|
}
|
|
277
|
-
|
|
278
|
-
|
|
215
|
+
};
|
|
216
|
+
toggle(SELECTOR_DROPDOWN_TOGGLE, CLASS_NAME_ACTIVE);
|
|
217
|
+
toggle(SELECTOR_DROPDOWN_MENU, CLASS_NAME_SHOW);
|
|
218
|
+
outerElem.setAttribute('aria-expanded', open);
|
|
219
|
+
}
|
|
220
|
+
_setAttributeIfNotExists(element, attribute, value) {
|
|
221
|
+
if (!element.hasAttribute(attribute)) {
|
|
222
|
+
element.setAttribute(attribute, value);
|
|
279
223
|
}
|
|
224
|
+
}
|
|
225
|
+
_elemIsActive(elem) {
|
|
226
|
+
return elem.classList.contains(CLASS_NAME_ACTIVE);
|
|
227
|
+
}
|
|
280
228
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
}
|
|
229
|
+
// Try to get the inner element (usually the .nav-link)
|
|
230
|
+
_getInnerElement(elem) {
|
|
231
|
+
return elem.matches(SELECTOR_INNER_ELEM) ? elem : SelectorEngine.findOne(SELECTOR_INNER_ELEM, elem);
|
|
232
|
+
}
|
|
285
233
|
|
|
234
|
+
// Try to get the outer element (usually the .nav-item)
|
|
235
|
+
_getOuterElement(elem) {
|
|
236
|
+
return elem.closest(SELECTOR_OUTER) || elem;
|
|
237
|
+
}
|
|
286
238
|
|
|
239
|
+
// Static
|
|
287
240
|
static jQueryInterface(config) {
|
|
288
241
|
return this.each(function () {
|
|
289
242
|
const data = Tab.getOrCreateInstance(this);
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
if (typeof data[config] === 'undefined') {
|
|
293
|
-
throw new TypeError(`No method named "${config}"`);
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
data[config]();
|
|
243
|
+
if (typeof config !== 'string') {
|
|
244
|
+
return;
|
|
297
245
|
}
|
|
246
|
+
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
|
247
|
+
throw new TypeError(`No method named "${config}"`);
|
|
248
|
+
}
|
|
249
|
+
data[config]();
|
|
298
250
|
});
|
|
299
251
|
}
|
|
300
|
-
|
|
301
252
|
}
|
|
253
|
+
|
|
302
254
|
/**
|
|
303
|
-
*
|
|
304
|
-
* Data Api implementation
|
|
305
|
-
* ------------------------------------------------------------------------
|
|
255
|
+
* Data API implementation
|
|
306
256
|
*/
|
|
307
257
|
|
|
308
|
-
|
|
309
|
-
EventHandler__default.default.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
|
|
258
|
+
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
|
|
310
259
|
if (['A', 'AREA'].includes(this.tagName)) {
|
|
311
260
|
event.preventDefault();
|
|
312
261
|
}
|
|
313
|
-
|
|
314
|
-
if (isDisabled(this)) {
|
|
262
|
+
if (index_js.isDisabled(this)) {
|
|
315
263
|
return;
|
|
316
264
|
}
|
|
265
|
+
Tab.getOrCreateInstance(this).show();
|
|
266
|
+
});
|
|
317
267
|
|
|
318
|
-
|
|
319
|
-
|
|
268
|
+
/**
|
|
269
|
+
* Initialize on focus
|
|
270
|
+
*/
|
|
271
|
+
EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
|
|
272
|
+
for (const element of SelectorEngine.find(SELECTOR_DATA_TOGGLE_ACTIVE)) {
|
|
273
|
+
Tab.getOrCreateInstance(element);
|
|
274
|
+
}
|
|
320
275
|
});
|
|
321
276
|
/**
|
|
322
|
-
* ------------------------------------------------------------------------
|
|
323
277
|
* jQuery
|
|
324
|
-
* ------------------------------------------------------------------------
|
|
325
|
-
* add .Tab to jQuery only if jQuery is present
|
|
326
278
|
*/
|
|
327
279
|
|
|
328
|
-
defineJQueryPlugin(Tab);
|
|
280
|
+
index_js.defineJQueryPlugin(Tab);
|
|
329
281
|
|
|
330
282
|
return Tab;
|
|
331
283
|
|