bootstrap 5.0.1 → 5.1.2

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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/assets/javascripts/bootstrap/alert.js +89 -58
  4. data/assets/javascripts/bootstrap/base-component.js +53 -39
  5. data/assets/javascripts/bootstrap/button.js +31 -25
  6. data/assets/javascripts/bootstrap/carousel.js +126 -89
  7. data/assets/javascripts/bootstrap/collapse.js +125 -133
  8. data/assets/javascripts/bootstrap/dom/data.js +5 -5
  9. data/assets/javascripts/bootstrap/dom/event-handler.js +11 -5
  10. data/assets/javascripts/bootstrap/dom/manipulator.js +6 -6
  11. data/assets/javascripts/bootstrap/dom/selector-engine.js +49 -7
  12. data/assets/javascripts/bootstrap/dropdown.js +147 -140
  13. data/assets/javascripts/bootstrap/modal.js +397 -180
  14. data/assets/javascripts/bootstrap/offcanvas.js +333 -138
  15. data/assets/javascripts/bootstrap/popover.js +36 -54
  16. data/assets/javascripts/bootstrap/scrollspy.js +58 -68
  17. data/assets/javascripts/bootstrap/tab.js +53 -26
  18. data/assets/javascripts/bootstrap/toast.js +138 -41
  19. data/assets/javascripts/bootstrap/tooltip.js +137 -120
  20. data/assets/javascripts/bootstrap-sprockets.js +8 -8
  21. data/assets/javascripts/bootstrap.js +937 -886
  22. data/assets/javascripts/bootstrap.min.js +2 -2
  23. data/assets/stylesheets/_bootstrap-grid.scss +3 -1
  24. data/assets/stylesheets/_bootstrap-reboot.scss +2 -4
  25. data/assets/stylesheets/_bootstrap.scss +2 -1
  26. data/assets/stylesheets/bootstrap/_buttons.scss +1 -0
  27. data/assets/stylesheets/bootstrap/_card.scss +7 -6
  28. data/assets/stylesheets/bootstrap/_carousel.scss +2 -2
  29. data/assets/stylesheets/bootstrap/_dropdown.scss +4 -4
  30. data/assets/stylesheets/bootstrap/_functions.scss +100 -3
  31. data/assets/stylesheets/bootstrap/_grid.scss +11 -0
  32. data/assets/stylesheets/bootstrap/_helpers.scss +2 -0
  33. data/assets/stylesheets/bootstrap/_images.scss +1 -1
  34. data/assets/stylesheets/bootstrap/_mixins.scss +1 -0
  35. data/assets/stylesheets/bootstrap/_modal.scss +5 -15
  36. data/assets/stylesheets/bootstrap/_navbar.scss +30 -1
  37. data/assets/stylesheets/bootstrap/_offcanvas.scss +8 -2
  38. data/assets/stylesheets/bootstrap/_placeholders.scss +51 -0
  39. data/assets/stylesheets/bootstrap/_popover.scss +10 -10
  40. data/assets/stylesheets/bootstrap/_reboot.scss +12 -8
  41. data/assets/stylesheets/bootstrap/_root.scss +40 -2
  42. data/assets/stylesheets/bootstrap/_tables.scss +9 -5
  43. data/assets/stylesheets/bootstrap/_toasts.scss +3 -3
  44. data/assets/stylesheets/bootstrap/_tooltip.scss +4 -4
  45. data/assets/stylesheets/bootstrap/_transitions.scss +6 -0
  46. data/assets/stylesheets/bootstrap/_utilities.scss +44 -8
  47. data/assets/stylesheets/bootstrap/_variables.scss +206 -29
  48. data/assets/stylesheets/bootstrap/bootstrap-utilities.scss +1 -1
  49. data/assets/stylesheets/bootstrap/forms/_floating-labels.scss +3 -1
  50. data/assets/stylesheets/bootstrap/forms/_form-check.scss +1 -1
  51. data/assets/stylesheets/bootstrap/forms/_form-control.scss +1 -1
  52. data/assets/stylesheets/bootstrap/forms/_form-range.scss +1 -1
  53. data/assets/stylesheets/bootstrap/forms/_form-select.scss +5 -0
  54. data/assets/stylesheets/bootstrap/helpers/_stacks.scss +15 -0
  55. data/assets/stylesheets/bootstrap/helpers/_vr.scss +8 -0
  56. data/assets/stylesheets/bootstrap/mixins/_backdrop.scss +14 -0
  57. data/assets/stylesheets/bootstrap/mixins/_buttons.scss +1 -1
  58. data/assets/stylesheets/bootstrap/mixins/_grid.scss +35 -9
  59. data/assets/stylesheets/bootstrap/mixins/_utilities.scss +27 -6
  60. data/assets/stylesheets/bootstrap/mixins/_visually-hidden.scss +1 -1
  61. data/assets/stylesheets/bootstrap/vendor/_rfs.scss +55 -13
  62. data/bootstrap.gemspec +3 -3
  63. data/lib/bootstrap/version.rb +2 -2
  64. data/tasks/updater/js.rb +6 -2
  65. metadata +12 -8
@@ -1,50 +1,47 @@
1
1
  /*!
2
- * Bootstrap tooltip.js v5.0.1 (https://getbootstrap.com/)
2
+ * Bootstrap tooltip.js v5.1.2 (https://getbootstrap.com/)
3
3
  * Copyright 2011-2021 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('@popperjs/core'), require('./dom/selector-engine.js'), require('./dom/data.js'), require('./dom/event-handler.js'), require('./dom/manipulator.js'), require('./base-component.js')) :
8
- typeof define === 'function' && define.amd ? define(['@popperjs/core', './dom/selector-engine', './dom/data', './dom/event-handler', './dom/manipulator', './base-component'], factory) :
9
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Tooltip = factory(global.Popper, global.SelectorEngine, global.Data, global.EventHandler, global.Manipulator, global.Base));
10
- }(this, (function (Popper, SelectorEngine, Data, EventHandler, Manipulator, BaseComponent) { 'use strict';
7
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@popperjs/core'), require('./dom/data.js'), require('./dom/event-handler.js'), require('./dom/manipulator.js'), require('./dom/selector-engine.js'), require('./base-component.js')) :
8
+ typeof define === 'function' && define.amd ? define(['@popperjs/core', './dom/data', './dom/event-handler', './dom/manipulator', './dom/selector-engine', './base-component'], factory) :
9
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Tooltip = factory(global.Popper, global.Data, global.EventHandler, global.Manipulator, global.SelectorEngine, global.Base));
10
+ })(this, (function (Popper, Data, EventHandler, Manipulator, SelectorEngine, BaseComponent) { 'use strict';
11
11
 
12
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
12
+ const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
13
13
 
14
14
  function _interopNamespace(e) {
15
15
  if (e && e.__esModule) return e;
16
- var n = Object.create(null);
16
+ const n = Object.create(null);
17
17
  if (e) {
18
- Object.keys(e).forEach(function (k) {
18
+ for (const k in e) {
19
19
  if (k !== 'default') {
20
- var d = Object.getOwnPropertyDescriptor(e, k);
20
+ const d = Object.getOwnPropertyDescriptor(e, k);
21
21
  Object.defineProperty(n, k, d.get ? d : {
22
22
  enumerable: true,
23
- get: function () {
24
- return e[k];
25
- }
23
+ get: () => e[k]
26
24
  });
27
25
  }
28
- });
26
+ }
29
27
  }
30
- n['default'] = e;
28
+ n.default = e;
31
29
  return Object.freeze(n);
32
30
  }
33
31
 
34
- var Popper__namespace = /*#__PURE__*/_interopNamespace(Popper);
35
- var SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
36
- var Data__default = /*#__PURE__*/_interopDefaultLegacy(Data);
37
- var EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
38
- var Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator);
39
- var BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
32
+ const Popper__namespace = /*#__PURE__*/_interopNamespace(Popper);
33
+ const Data__default = /*#__PURE__*/_interopDefaultLegacy(Data);
34
+ const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
35
+ const Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator);
36
+ const SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
37
+ const BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
40
38
 
41
39
  /**
42
40
  * --------------------------------------------------------------------------
43
- * Bootstrap (v5.0.1): util/index.js
41
+ * Bootstrap (v5.1.2): util/index.js
44
42
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
45
43
  * --------------------------------------------------------------------------
46
44
  */
47
-
48
45
  const MAX_UID = 1000000;
49
46
 
50
47
  const toType = obj => {
@@ -88,7 +85,7 @@
88
85
  }
89
86
 
90
87
  if (typeof obj === 'string' && obj.length > 0) {
91
- return SelectorEngine__default['default'].findOne(obj);
88
+ return document.querySelector(obj);
92
89
  }
93
90
 
94
91
  return null;
@@ -143,9 +140,18 @@
143
140
  return null;
144
141
  };
145
142
 
143
+ const DOMContentLoadedCallbacks = [];
144
+
146
145
  const onDOMContentLoaded = callback => {
147
146
  if (document.readyState === 'loading') {
148
- document.addEventListener('DOMContentLoaded', callback);
147
+ // add listener on the first call when the document is in loading state
148
+ if (!DOMContentLoadedCallbacks.length) {
149
+ document.addEventListener('DOMContentLoaded', () => {
150
+ DOMContentLoadedCallbacks.forEach(callback => callback());
151
+ });
152
+ }
153
+
154
+ DOMContentLoadedCallbacks.push(callback);
149
155
  } else {
150
156
  callback();
151
157
  }
@@ -174,42 +180,42 @@
174
180
 
175
181
  /**
176
182
  * --------------------------------------------------------------------------
177
- * Bootstrap (v5.0.1): util/sanitizer.js
183
+ * Bootstrap (v5.1.2): util/sanitizer.js
178
184
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
179
185
  * --------------------------------------------------------------------------
180
186
  */
181
- const uriAttrs = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']);
187
+ const uriAttributes = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']);
182
188
  const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i;
183
189
  /**
184
190
  * A pattern that recognizes a commonly useful subset of URLs that are safe.
185
191
  *
186
- * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
192
+ * Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts
187
193
  */
188
194
 
189
- const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/i;
195
+ const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i;
190
196
  /**
191
197
  * A pattern that matches safe data URLs. Only matches image, video and audio types.
192
198
  *
193
- * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
199
+ * Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts
194
200
  */
195
201
 
196
202
  const DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;
197
203
 
198
- const allowedAttribute = (attr, allowedAttributeList) => {
199
- const attrName = attr.nodeName.toLowerCase();
204
+ const allowedAttribute = (attribute, allowedAttributeList) => {
205
+ const attributeName = attribute.nodeName.toLowerCase();
200
206
 
201
- if (allowedAttributeList.includes(attrName)) {
202
- if (uriAttrs.has(attrName)) {
203
- return Boolean(SAFE_URL_PATTERN.test(attr.nodeValue) || DATA_URL_PATTERN.test(attr.nodeValue));
207
+ if (allowedAttributeList.includes(attributeName)) {
208
+ if (uriAttributes.has(attributeName)) {
209
+ return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue) || DATA_URL_PATTERN.test(attribute.nodeValue));
204
210
  }
205
211
 
206
212
  return true;
207
213
  }
208
214
 
209
- const regExp = allowedAttributeList.filter(attrRegex => attrRegex instanceof RegExp); // Check if a regular expression validates the attribute.
215
+ const regExp = allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp); // Check if a regular expression validates the attribute.
210
216
 
211
217
  for (let i = 0, len = regExp.length; i < len; i++) {
212
- if (regExp[i].test(attrName)) {
218
+ if (regExp[i].test(attributeName)) {
213
219
  return true;
214
220
  }
215
221
  }
@@ -261,23 +267,22 @@
261
267
 
262
268
  const domParser = new window.DOMParser();
263
269
  const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');
264
- const allowlistKeys = Object.keys(allowList);
265
270
  const elements = [].concat(...createdDocument.body.querySelectorAll('*'));
266
271
 
267
272
  for (let i = 0, len = elements.length; i < len; i++) {
268
- const el = elements[i];
269
- const elName = el.nodeName.toLowerCase();
273
+ const element = elements[i];
274
+ const elementName = element.nodeName.toLowerCase();
270
275
 
271
- if (!allowlistKeys.includes(elName)) {
272
- el.parentNode.removeChild(el);
276
+ if (!Object.keys(allowList).includes(elementName)) {
277
+ element.remove();
273
278
  continue;
274
279
  }
275
280
 
276
- const attributeList = [].concat(...el.attributes);
277
- const allowedAttributes = [].concat(allowList['*'] || [], allowList[elName] || []);
278
- attributeList.forEach(attr => {
279
- if (!allowedAttribute(attr, allowedAttributes)) {
280
- el.removeAttribute(attr.nodeName);
281
+ const attributeList = [].concat(...element.attributes);
282
+ const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || []);
283
+ attributeList.forEach(attribute => {
284
+ if (!allowedAttribute(attribute, allowedAttributes)) {
285
+ element.removeAttribute(attribute.nodeName);
281
286
  }
282
287
  });
283
288
  }
@@ -287,7 +292,7 @@
287
292
 
288
293
  /**
289
294
  * --------------------------------------------------------------------------
290
- * Bootstrap (v5.0.1): tooltip.js
295
+ * Bootstrap (v5.1.2): tooltip.js
291
296
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
292
297
  * --------------------------------------------------------------------------
293
298
  */
@@ -301,7 +306,6 @@
301
306
  const DATA_KEY = 'bs.tooltip';
302
307
  const EVENT_KEY = `.${DATA_KEY}`;
303
308
  const CLASS_PREFIX = 'bs-tooltip';
304
- const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g');
305
309
  const DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']);
306
310
  const DefaultType = {
307
311
  animation: 'boolean',
@@ -366,6 +370,8 @@
366
370
  const HOVER_STATE_SHOW = 'show';
367
371
  const HOVER_STATE_OUT = 'out';
368
372
  const SELECTOR_TOOLTIP_INNER = '.tooltip-inner';
373
+ const SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`;
374
+ const EVENT_MODAL_HIDE = 'hide.bs.modal';
369
375
  const TRIGGER_HOVER = 'hover';
370
376
  const TRIGGER_FOCUS = 'focus';
371
377
  const TRIGGER_CLICK = 'click';
@@ -376,7 +382,7 @@
376
382
  * ------------------------------------------------------------------------
377
383
  */
378
384
 
379
- class Tooltip extends BaseComponent__default['default'] {
385
+ class Tooltip extends BaseComponent__default.default {
380
386
  constructor(element, config) {
381
387
  if (typeof Popper__namespace === 'undefined') {
382
388
  throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org)');
@@ -454,15 +460,13 @@
454
460
 
455
461
  dispose() {
456
462
  clearTimeout(this._timeout);
457
- EventHandler__default['default'].off(this._element.closest(`.${CLASS_NAME_MODAL}`), 'hide.bs.modal', this._hideModalHandler);
463
+ EventHandler__default.default.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);
458
464
 
459
- if (this.tip && this.tip.parentNode) {
460
- this.tip.parentNode.removeChild(this.tip);
465
+ if (this.tip) {
466
+ this.tip.remove();
461
467
  }
462
468
 
463
- if (this._popper) {
464
- this._popper.destroy();
465
- }
469
+ this._disposePopper();
466
470
 
467
471
  super.dispose();
468
472
  }
@@ -476,12 +480,21 @@
476
480
  return;
477
481
  }
478
482
 
479
- const showEvent = EventHandler__default['default'].trigger(this._element, this.constructor.Event.SHOW);
483
+ const showEvent = EventHandler__default.default.trigger(this._element, this.constructor.Event.SHOW);
480
484
  const shadowRoot = findShadowRoot(this._element);
481
485
  const isInTheDom = shadowRoot === null ? this._element.ownerDocument.documentElement.contains(this._element) : shadowRoot.contains(this._element);
482
486
 
483
487
  if (showEvent.defaultPrevented || !isInTheDom) {
484
488
  return;
489
+ } // A trick to recreate a tooltip in case a new title is given by using the NOT documented `data-bs-original-title`
490
+ // This will be removed later in favor of a `setContent` method
491
+
492
+
493
+ if (this.constructor.NAME === 'tooltip' && this.tip && this.getTitle() !== this.tip.querySelector(SELECTOR_TOOLTIP_INNER).innerHTML) {
494
+ this._disposePopper();
495
+
496
+ this.tip.remove();
497
+ this.tip = null;
485
498
  }
486
499
 
487
500
  const tip = this.getTipElement();
@@ -490,8 +503,6 @@
490
503
 
491
504
  this._element.setAttribute('aria-describedby', tipId);
492
505
 
493
- this.setContent();
494
-
495
506
  if (this._config.animation) {
496
507
  tip.classList.add(CLASS_NAME_FADE);
497
508
  }
@@ -505,11 +516,11 @@
505
516
  const {
506
517
  container
507
518
  } = this._config;
508
- Data__default['default'].set(tip, this.constructor.DATA_KEY, this);
519
+ Data__default.default.set(tip, this.constructor.DATA_KEY, this);
509
520
 
510
521
  if (!this._element.ownerDocument.documentElement.contains(this.tip)) {
511
- container.appendChild(tip);
512
- EventHandler__default['default'].trigger(this._element, this.constructor.Event.INSERTED);
522
+ container.append(tip);
523
+ EventHandler__default.default.trigger(this._element, this.constructor.Event.INSERTED);
513
524
  }
514
525
 
515
526
  if (this._popper) {
@@ -519,7 +530,8 @@
519
530
  }
520
531
 
521
532
  tip.classList.add(CLASS_NAME_SHOW);
522
- const customClass = typeof this._config.customClass === 'function' ? this._config.customClass() : this._config.customClass;
533
+
534
+ const customClass = this._resolvePossibleFunction(this._config.customClass);
523
535
 
524
536
  if (customClass) {
525
537
  tip.classList.add(...customClass.split(' '));
@@ -531,14 +543,14 @@
531
543
 
532
544
  if ('ontouchstart' in document.documentElement) {
533
545
  [].concat(...document.body.children).forEach(element => {
534
- EventHandler__default['default'].on(element, 'mouseover', noop);
546
+ EventHandler__default.default.on(element, 'mouseover', noop);
535
547
  });
536
548
  }
537
549
 
538
550
  const complete = () => {
539
551
  const prevHoverState = this._hoverState;
540
552
  this._hoverState = null;
541
- EventHandler__default['default'].trigger(this._element, this.constructor.Event.SHOWN);
553
+ EventHandler__default.default.trigger(this._element, this.constructor.Event.SHOWN);
542
554
 
543
555
  if (prevHoverState === HOVER_STATE_OUT) {
544
556
  this._leave(null, this);
@@ -562,24 +574,20 @@
562
574
  return;
563
575
  }
564
576
 
565
- if (this._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {
566
- tip.parentNode.removeChild(tip);
577
+ if (this._hoverState !== HOVER_STATE_SHOW) {
578
+ tip.remove();
567
579
  }
568
580
 
569
581
  this._cleanTipClass();
570
582
 
571
583
  this._element.removeAttribute('aria-describedby');
572
584
 
573
- EventHandler__default['default'].trigger(this._element, this.constructor.Event.HIDDEN);
574
-
575
- if (this._popper) {
576
- this._popper.destroy();
585
+ EventHandler__default.default.trigger(this._element, this.constructor.Event.HIDDEN);
577
586
 
578
- this._popper = null;
579
- }
587
+ this._disposePopper();
580
588
  };
581
589
 
582
- const hideEvent = EventHandler__default['default'].trigger(this._element, this.constructor.Event.HIDE);
590
+ const hideEvent = EventHandler__default.default.trigger(this._element, this.constructor.Event.HIDE);
583
591
 
584
592
  if (hideEvent.defaultPrevented) {
585
593
  return;
@@ -589,7 +597,7 @@
589
597
  // empty mouseover listeners we added for iOS support
590
598
 
591
599
  if ('ontouchstart' in document.documentElement) {
592
- [].concat(...document.body.children).forEach(element => EventHandler__default['default'].off(element, 'mouseover', noop));
600
+ [].concat(...document.body.children).forEach(element => EventHandler__default.default.off(element, 'mouseover', noop));
593
601
  }
594
602
 
595
603
  this._activeTrigger[TRIGGER_CLICK] = false;
@@ -620,14 +628,27 @@
620
628
 
621
629
  const element = document.createElement('div');
622
630
  element.innerHTML = this._config.template;
623
- this.tip = element.children[0];
631
+ const tip = element.children[0];
632
+ this.setContent(tip);
633
+ tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW);
634
+ this.tip = tip;
624
635
  return this.tip;
625
636
  }
626
637
 
627
- setContent() {
628
- const tip = this.getTipElement();
629
- this.setElementContent(SelectorEngine__default['default'].findOne(SELECTOR_TOOLTIP_INNER, tip), this.getTitle());
630
- tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW);
638
+ setContent(tip) {
639
+ this._sanitizeAndSetContent(tip, this.getTitle(), SELECTOR_TOOLTIP_INNER);
640
+ }
641
+
642
+ _sanitizeAndSetContent(template, content, selector) {
643
+ const templateElement = SelectorEngine__default.default.findOne(selector, template);
644
+
645
+ if (!content && templateElement) {
646
+ templateElement.remove();
647
+ return;
648
+ } // we use append for html objects to maintain js events
649
+
650
+
651
+ this.setElementContent(templateElement, content);
631
652
  }
632
653
 
633
654
  setElementContent(element, content) {
@@ -641,7 +662,7 @@
641
662
  if (this._config.html) {
642
663
  if (content.parentNode !== element) {
643
664
  element.innerHTML = '';
644
- element.appendChild(content);
665
+ element.append(content);
645
666
  }
646
667
  } else {
647
668
  element.textContent = content.textContent;
@@ -662,13 +683,9 @@
662
683
  }
663
684
 
664
685
  getTitle() {
665
- let title = this._element.getAttribute('data-bs-original-title');
666
-
667
- if (!title) {
668
- title = typeof this._config.title === 'function' ? this._config.title.call(this._element) : this._config.title;
669
- }
686
+ const title = this._element.getAttribute('data-bs-original-title') || this._config.title;
670
687
 
671
- return title;
688
+ return this._resolvePossibleFunction(title);
672
689
  }
673
690
 
674
691
  updateAttachment(attachment) {
@@ -685,15 +702,7 @@
685
702
 
686
703
 
687
704
  _initializeOnDelegatedTarget(event, context) {
688
- const dataKey = this.constructor.DATA_KEY;
689
- context = context || Data__default['default'].get(event.delegateTarget, dataKey);
690
-
691
- if (!context) {
692
- context = new this.constructor(event.delegateTarget, this._getDelegateConfig());
693
- Data__default['default'].set(event.delegateTarget, dataKey, context);
694
- }
695
-
696
- return context;
705
+ return context || this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig());
697
706
  }
698
707
 
699
708
  _getOffset() {
@@ -712,6 +721,10 @@
712
721
  return offset;
713
722
  }
714
723
 
724
+ _resolvePossibleFunction(content) {
725
+ return typeof content === 'function' ? content.call(this._element) : content;
726
+ }
727
+
715
728
  _getPopperConfig(attachment) {
716
729
  const defaultBsPopperConfig = {
717
730
  placement: attachment,
@@ -753,7 +766,7 @@
753
766
  }
754
767
 
755
768
  _addAttachmentClass(attachment) {
756
- this.getTipElement().classList.add(`${CLASS_PREFIX}-${this.updateAttachment(attachment)}`);
769
+ this.getTipElement().classList.add(`${this._getBasicClassPrefix()}-${this.updateAttachment(attachment)}`);
757
770
  }
758
771
 
759
772
  _getAttachment(placement) {
@@ -765,12 +778,12 @@
765
778
 
766
779
  triggers.forEach(trigger => {
767
780
  if (trigger === 'click') {
768
- EventHandler__default['default'].on(this._element, this.constructor.Event.CLICK, this._config.selector, event => this.toggle(event));
781
+ EventHandler__default.default.on(this._element, this.constructor.Event.CLICK, this._config.selector, event => this.toggle(event));
769
782
  } else if (trigger !== TRIGGER_MANUAL) {
770
783
  const eventIn = trigger === TRIGGER_HOVER ? this.constructor.Event.MOUSEENTER : this.constructor.Event.FOCUSIN;
771
784
  const eventOut = trigger === TRIGGER_HOVER ? this.constructor.Event.MOUSELEAVE : this.constructor.Event.FOCUSOUT;
772
- EventHandler__default['default'].on(this._element, eventIn, this._config.selector, event => this._enter(event));
773
- EventHandler__default['default'].on(this._element, eventOut, this._config.selector, event => this._leave(event));
785
+ EventHandler__default.default.on(this._element, eventIn, this._config.selector, event => this._enter(event));
786
+ EventHandler__default.default.on(this._element, eventOut, this._config.selector, event => this._leave(event));
774
787
  }
775
788
  });
776
789
 
@@ -780,7 +793,7 @@
780
793
  }
781
794
  };
782
795
 
783
- EventHandler__default['default'].on(this._element.closest(`.${CLASS_NAME_MODAL}`), 'hide.bs.modal', this._hideModalHandler);
796
+ EventHandler__default.default.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);
784
797
 
785
798
  if (this._config.selector) {
786
799
  this._config = { ...this._config,
@@ -872,7 +885,7 @@
872
885
  }
873
886
 
874
887
  _getConfig(config) {
875
- const dataAttributes = Manipulator__default['default'].getDataAttributes(this._element);
888
+ const dataAttributes = Manipulator__default.default.getDataAttributes(this._element);
876
889
  Object.keys(dataAttributes).forEach(dataAttr => {
877
890
  if (DISALLOWED_ATTRIBUTES.has(dataAttr)) {
878
891
  delete dataAttributes[dataAttr];
@@ -911,26 +924,32 @@
911
924
  _getDelegateConfig() {
912
925
  const config = {};
913
926
 
914
- if (this._config) {
915
- for (const key in this._config) {
916
- if (this.constructor.Default[key] !== this._config[key]) {
917
- config[key] = this._config[key];
918
- }
927
+ for (const key in this._config) {
928
+ if (this.constructor.Default[key] !== this._config[key]) {
929
+ config[key] = this._config[key];
919
930
  }
920
- }
931
+ } // In the future can be replaced with:
932
+ // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])
933
+ // `Object.fromEntries(keysWithDifferentValues)`
934
+
921
935
 
922
936
  return config;
923
937
  }
924
938
 
925
939
  _cleanTipClass() {
926
940
  const tip = this.getTipElement();
927
- const tabClass = tip.getAttribute('class').match(BSCLS_PREFIX_REGEX);
941
+ const basicClassPrefixRegex = new RegExp(`(^|\\s)${this._getBasicClassPrefix()}\\S+`, 'g');
942
+ const tabClass = tip.getAttribute('class').match(basicClassPrefixRegex);
928
943
 
929
944
  if (tabClass !== null && tabClass.length > 0) {
930
945
  tabClass.map(token => token.trim()).forEach(tClass => tip.classList.remove(tClass));
931
946
  }
932
947
  }
933
948
 
949
+ _getBasicClassPrefix() {
950
+ return CLASS_PREFIX;
951
+ }
952
+
934
953
  _handlePopperPlacementChange(popperData) {
935
954
  const {
936
955
  state
@@ -945,22 +964,20 @@
945
964
  this._cleanTipClass();
946
965
 
947
966
  this._addAttachmentClass(this._getAttachment(state.placement));
967
+ }
968
+
969
+ _disposePopper() {
970
+ if (this._popper) {
971
+ this._popper.destroy();
972
+
973
+ this._popper = null;
974
+ }
948
975
  } // Static
949
976
 
950
977
 
951
978
  static jQueryInterface(config) {
952
979
  return this.each(function () {
953
- let data = Data__default['default'].get(this, DATA_KEY);
954
-
955
- const _config = typeof config === 'object' && config;
956
-
957
- if (!data && /dispose|hide/.test(config)) {
958
- return;
959
- }
960
-
961
- if (!data) {
962
- data = new Tooltip(this, _config);
963
- }
980
+ const data = Tooltip.getOrCreateInstance(this, config);
964
981
 
965
982
  if (typeof config === 'string') {
966
983
  if (typeof data[config] === 'undefined') {
@@ -985,4 +1002,4 @@
985
1002
 
986
1003
  return Tooltip;
987
1004
 
988
- })));
1005
+ }));
@@ -1,19 +1,19 @@
1
1
  //= require ./bootstrap-global-this-define
2
+ //= require ./bootstrap/dom/manipulator
2
3
  //= require ./bootstrap/dom/data
3
4
  //= require ./bootstrap/dom/event-handler
4
5
  //= require ./bootstrap/base-component
5
- //= require ./bootstrap/dom/manipulator
6
6
  //= require ./bootstrap/dom/selector-engine
7
- //= require ./bootstrap/dropdown
8
- //= require ./bootstrap/scrollspy
9
- //= require ./bootstrap/alert
10
- //= require ./bootstrap/collapse
11
- //= require ./bootstrap/toast
12
- //= require ./bootstrap/tooltip
13
7
  //= require ./bootstrap/offcanvas
8
+ //= require ./bootstrap/tooltip
14
9
  //= require ./bootstrap/popover
15
- //= require ./bootstrap/button
16
10
  //= require ./bootstrap/modal
11
+ //= require ./bootstrap/button
17
12
  //= require ./bootstrap/tab
13
+ //= require ./bootstrap/dropdown
14
+ //= require ./bootstrap/alert
15
+ //= require ./bootstrap/toast
18
16
  //= require ./bootstrap/carousel
17
+ //= require ./bootstrap/scrollspy
18
+ //= require ./bootstrap/collapse
19
19
  //= require ./bootstrap-global-this-undefine