bootstrap 5.1.3 → 5.2.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 (94) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/assets/javascripts/bootstrap/alert.js +11 -146
  4. data/assets/javascripts/bootstrap/base-component.js +37 -120
  5. data/assets/javascripts/bootstrap/button.js +10 -74
  6. data/assets/javascripts/bootstrap/carousel.js +213 -485
  7. data/assets/javascripts/bootstrap/collapse.js +65 -249
  8. data/assets/javascripts/bootstrap/dom/data.js +3 -5
  9. data/assets/javascripts/bootstrap/dom/event-handler.js +94 -132
  10. data/assets/javascripts/bootstrap/dom/manipulator.js +23 -27
  11. data/assets/javascripts/bootstrap/dom/selector-engine.js +16 -58
  12. data/assets/javascripts/bootstrap/dropdown.js +101 -317
  13. data/assets/javascripts/bootstrap/modal.js +107 -752
  14. data/assets/javascripts/bootstrap/offcanvas.js +90 -659
  15. data/assets/javascripts/bootstrap/popover.js +36 -118
  16. data/assets/javascripts/bootstrap/scrollspy.js +179 -262
  17. data/assets/javascripts/bootstrap/tab.js +215 -214
  18. data/assets/javascripts/bootstrap/toast.js +28 -214
  19. data/assets/javascripts/bootstrap/tooltip.js +268 -611
  20. data/assets/javascripts/bootstrap/util/backdrop.js +165 -0
  21. data/assets/javascripts/bootstrap/util/component-functions.js +46 -0
  22. data/assets/javascripts/bootstrap/util/config.js +79 -0
  23. data/assets/javascripts/bootstrap/util/focustrap.js +129 -0
  24. data/assets/javascripts/bootstrap/util/index.js +350 -0
  25. data/assets/javascripts/bootstrap/util/sanitizer.js +122 -0
  26. data/assets/javascripts/bootstrap/util/scrollbar.js +138 -0
  27. data/assets/javascripts/bootstrap/util/swipe.js +155 -0
  28. data/assets/javascripts/bootstrap/util/template-factory.js +177 -0
  29. data/assets/javascripts/bootstrap-global-this-define.js +1 -1
  30. data/assets/javascripts/bootstrap-sprockets.js +10 -1
  31. data/assets/javascripts/bootstrap.js +2065 -1860
  32. data/assets/javascripts/bootstrap.min.js +3 -3
  33. data/assets/stylesheets/_bootstrap-grid.scss +3 -6
  34. data/assets/stylesheets/_bootstrap-reboot.scss +3 -7
  35. data/assets/stylesheets/_bootstrap.scss +4 -6
  36. data/assets/stylesheets/bootstrap/_accordion.scss +52 -24
  37. data/assets/stylesheets/bootstrap/_alert.scss +18 -4
  38. data/assets/stylesheets/bootstrap/_badge.scss +14 -5
  39. data/assets/stylesheets/bootstrap/_breadcrumb.scss +22 -10
  40. data/assets/stylesheets/bootstrap/_button-group.scss +3 -0
  41. data/assets/stylesheets/bootstrap/_buttons.scss +97 -22
  42. data/assets/stylesheets/bootstrap/_card.scss +55 -37
  43. data/assets/stylesheets/bootstrap/_close.scss +1 -1
  44. data/assets/stylesheets/bootstrap/_containers.scss +1 -1
  45. data/assets/stylesheets/bootstrap/_dropdown.scss +83 -75
  46. data/assets/stylesheets/bootstrap/_functions.scss +7 -7
  47. data/assets/stylesheets/bootstrap/_grid.scss +3 -3
  48. data/assets/stylesheets/bootstrap/_helpers.scss +1 -0
  49. data/assets/stylesheets/bootstrap/_list-group.scss +44 -27
  50. data/assets/stylesheets/bootstrap/_maps.scss +54 -0
  51. data/assets/stylesheets/bootstrap/_modal.scss +71 -43
  52. data/assets/stylesheets/bootstrap/_nav.scss +53 -20
  53. data/assets/stylesheets/bootstrap/_navbar.scss +91 -150
  54. data/assets/stylesheets/bootstrap/_offcanvas.scss +119 -59
  55. data/assets/stylesheets/bootstrap/_pagination.scss +66 -21
  56. data/assets/stylesheets/bootstrap/_placeholders.scss +1 -1
  57. data/assets/stylesheets/bootstrap/_popover.scss +90 -52
  58. data/assets/stylesheets/bootstrap/_progress.scss +20 -9
  59. data/assets/stylesheets/bootstrap/_reboot.scss +25 -40
  60. data/assets/stylesheets/bootstrap/_root.scss +40 -21
  61. data/assets/stylesheets/bootstrap/_spinners.scss +38 -22
  62. data/assets/stylesheets/bootstrap/_tables.scss +32 -23
  63. data/assets/stylesheets/bootstrap/_toasts.scss +35 -16
  64. data/assets/stylesheets/bootstrap/_tooltip.scss +61 -56
  65. data/assets/stylesheets/bootstrap/_type.scss +2 -0
  66. data/assets/stylesheets/bootstrap/_utilities.scss +43 -26
  67. data/assets/stylesheets/bootstrap/_variables.scss +113 -121
  68. data/assets/stylesheets/bootstrap/bootstrap-utilities.scss +3 -6
  69. data/assets/stylesheets/bootstrap/forms/_floating-labels.scss +14 -3
  70. data/assets/stylesheets/bootstrap/forms/_form-check.scss +28 -5
  71. data/assets/stylesheets/bootstrap/forms/_form-control.scss +12 -37
  72. data/assets/stylesheets/bootstrap/forms/_form-select.scss +0 -1
  73. data/assets/stylesheets/bootstrap/forms/_input-group.scss +15 -7
  74. data/assets/stylesheets/bootstrap/helpers/_color-bg.scss +10 -0
  75. data/assets/stylesheets/bootstrap/helpers/_colored-links.scss +2 -2
  76. data/assets/stylesheets/bootstrap/helpers/_position.scss +7 -1
  77. data/assets/stylesheets/bootstrap/helpers/_ratio.scss +2 -2
  78. data/assets/stylesheets/bootstrap/helpers/_vr.scss +1 -1
  79. data/assets/stylesheets/bootstrap/mixins/_alert.scss +7 -3
  80. data/assets/stylesheets/bootstrap/mixins/_banner.scss +9 -0
  81. data/assets/stylesheets/bootstrap/mixins/_breakpoints.scss +8 -8
  82. data/assets/stylesheets/bootstrap/mixins/_buttons.scss +32 -95
  83. data/assets/stylesheets/bootstrap/mixins/_container.scss +4 -2
  84. data/assets/stylesheets/bootstrap/mixins/_forms.scss +8 -0
  85. data/assets/stylesheets/bootstrap/mixins/_gradients.scss +1 -1
  86. data/assets/stylesheets/bootstrap/mixins/_grid.scss +12 -12
  87. data/assets/stylesheets/bootstrap/mixins/_pagination.scss +4 -25
  88. data/assets/stylesheets/bootstrap/mixins/_reset-text.scss +1 -1
  89. data/assets/stylesheets/bootstrap/mixins/_table-variants.scss +12 -9
  90. data/assets/stylesheets/bootstrap/mixins/_utilities.scss +12 -4
  91. data/bootstrap.gemspec +1 -1
  92. data/lib/bootstrap/version.rb +2 -2
  93. data/tasks/updater/js.rb +9 -4
  94. metadata +16 -4
@@ -1,19 +1,19 @@
1
1
  /*!
2
- * Bootstrap tooltip.js v5.1.3 (https://getbootstrap.com/)
3
- * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
2
+ * Bootstrap tooltip.js v5.2.0 (https://getbootstrap.com/)
3
+ * Copyright 2011-2022 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/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';
7
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@popperjs/core'), require('./util/index'), require('./util/sanitizer'), require('./dom/event-handler'), require('./dom/manipulator'), require('./base-component'), require('./util/template-factory')) :
8
+ typeof define === 'function' && define.amd ? define(['@popperjs/core', './util/index', './util/sanitizer', './dom/event-handler', './dom/manipulator', './base-component', './util/template-factory'], factory) :
9
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Tooltip = factory(global["@popperjs/core"], global.Index, global.Sanitizer, global.EventHandler, global.Manipulator, global.BaseComponent, global.TemplateFactory));
10
+ })(this, (function (Popper, index, sanitizer, EventHandler, Manipulator, BaseComponent, TemplateFactory) { 'use strict';
11
11
 
12
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
- const n = Object.create(null);
16
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
17
17
  if (e) {
18
18
  for (const k in e) {
19
19
  if (k !== 'default') {
@@ -30,356 +30,90 @@
30
30
  }
31
31
 
32
32
  const Popper__namespace = /*#__PURE__*/_interopNamespace(Popper);
33
- const Data__default = /*#__PURE__*/_interopDefaultLegacy(Data);
34
33
  const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
35
34
  const Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator);
36
- const SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
37
35
  const BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
36
+ const TemplateFactory__default = /*#__PURE__*/_interopDefaultLegacy(TemplateFactory);
38
37
 
39
38
  /**
40
39
  * --------------------------------------------------------------------------
41
- * Bootstrap (v5.1.3): util/index.js
40
+ * Bootstrap (v5.2.0): tooltip.js
42
41
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
43
42
  * --------------------------------------------------------------------------
44
43
  */
45
- const MAX_UID = 1000000;
46
-
47
- const toType = obj => {
48
- if (obj === null || obj === undefined) {
49
- return `${obj}`;
50
- }
51
-
52
- return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();
53
- };
54
- /**
55
- * --------------------------------------------------------------------------
56
- * Public Util Api
57
- * --------------------------------------------------------------------------
58
- */
59
-
60
-
61
- const getUID = prefix => {
62
- do {
63
- prefix += Math.floor(Math.random() * MAX_UID);
64
- } while (document.getElementById(prefix));
65
-
66
- return prefix;
67
- };
68
-
69
- const isElement = obj => {
70
- if (!obj || typeof obj !== 'object') {
71
- return false;
72
- }
73
-
74
- if (typeof obj.jquery !== 'undefined') {
75
- obj = obj[0];
76
- }
77
-
78
- return typeof obj.nodeType !== 'undefined';
79
- };
80
-
81
- const getElement = obj => {
82
- if (isElement(obj)) {
83
- // it's a jQuery object or a node element
84
- return obj.jquery ? obj[0] : obj;
85
- }
86
-
87
- if (typeof obj === 'string' && obj.length > 0) {
88
- return document.querySelector(obj);
89
- }
90
-
91
- return null;
92
- };
93
-
94
- const typeCheckConfig = (componentName, config, configTypes) => {
95
- Object.keys(configTypes).forEach(property => {
96
- const expectedTypes = configTypes[property];
97
- const value = config[property];
98
- const valueType = value && isElement(value) ? 'element' : toType(value);
99
-
100
- if (!new RegExp(expectedTypes).test(valueType)) {
101
- throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);
102
- }
103
- });
104
- };
105
-
106
- const findShadowRoot = element => {
107
- if (!document.documentElement.attachShadow) {
108
- return null;
109
- } // Can find the shadow root otherwise it'll return the document
110
-
111
-
112
- if (typeof element.getRootNode === 'function') {
113
- const root = element.getRootNode();
114
- return root instanceof ShadowRoot ? root : null;
115
- }
116
-
117
- if (element instanceof ShadowRoot) {
118
- return element;
119
- } // when we don't find a shadow root
120
-
121
-
122
- if (!element.parentNode) {
123
- return null;
124
- }
125
-
126
- return findShadowRoot(element.parentNode);
127
- };
128
-
129
- const noop = () => {};
130
-
131
- const getjQuery = () => {
132
- const {
133
- jQuery
134
- } = window;
135
-
136
- if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
137
- return jQuery;
138
- }
139
-
140
- return null;
141
- };
142
-
143
- const DOMContentLoadedCallbacks = [];
144
-
145
- const onDOMContentLoaded = callback => {
146
- if (document.readyState === 'loading') {
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);
155
- } else {
156
- callback();
157
- }
158
- };
159
-
160
- const isRTL = () => document.documentElement.dir === 'rtl';
161
-
162
- const defineJQueryPlugin = plugin => {
163
- onDOMContentLoaded(() => {
164
- const $ = getjQuery();
165
- /* istanbul ignore if */
166
-
167
- if ($) {
168
- const name = plugin.NAME;
169
- const JQUERY_NO_CONFLICT = $.fn[name];
170
- $.fn[name] = plugin.jQueryInterface;
171
- $.fn[name].Constructor = plugin;
172
-
173
- $.fn[name].noConflict = () => {
174
- $.fn[name] = JQUERY_NO_CONFLICT;
175
- return plugin.jQueryInterface;
176
- };
177
- }
178
- });
179
- };
180
-
181
44
  /**
182
- * --------------------------------------------------------------------------
183
- * Bootstrap (v5.1.3): util/sanitizer.js
184
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
185
- * --------------------------------------------------------------------------
186
- */
187
- const uriAttributes = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']);
188
- const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i;
189
- /**
190
- * A pattern that recognizes a commonly useful subset of URLs that are safe.
191
- *
192
- * Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts
193
- */
194
-
195
- const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i;
196
- /**
197
- * A pattern that matches safe data URLs. Only matches image, video and audio types.
198
- *
199
- * Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts
200
- */
201
-
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;
203
-
204
- const allowedAttribute = (attribute, allowedAttributeList) => {
205
- const attributeName = attribute.nodeName.toLowerCase();
206
-
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));
210
- }
211
-
212
- return true;
213
- }
214
-
215
- const regExp = allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp); // Check if a regular expression validates the attribute.
216
-
217
- for (let i = 0, len = regExp.length; i < len; i++) {
218
- if (regExp[i].test(attributeName)) {
219
- return true;
220
- }
221
- }
222
-
223
- return false;
224
- };
225
-
226
- const DefaultAllowlist = {
227
- // Global attributes allowed on any supplied element below.
228
- '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
229
- a: ['target', 'href', 'title', 'rel'],
230
- area: [],
231
- b: [],
232
- br: [],
233
- col: [],
234
- code: [],
235
- div: [],
236
- em: [],
237
- hr: [],
238
- h1: [],
239
- h2: [],
240
- h3: [],
241
- h4: [],
242
- h5: [],
243
- h6: [],
244
- i: [],
245
- img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],
246
- li: [],
247
- ol: [],
248
- p: [],
249
- pre: [],
250
- s: [],
251
- small: [],
252
- span: [],
253
- sub: [],
254
- sup: [],
255
- strong: [],
256
- u: [],
257
- ul: []
258
- };
259
- function sanitizeHtml(unsafeHtml, allowList, sanitizeFn) {
260
- if (!unsafeHtml.length) {
261
- return unsafeHtml;
262
- }
263
-
264
- if (sanitizeFn && typeof sanitizeFn === 'function') {
265
- return sanitizeFn(unsafeHtml);
266
- }
267
-
268
- const domParser = new window.DOMParser();
269
- const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');
270
- const elements = [].concat(...createdDocument.body.querySelectorAll('*'));
271
-
272
- for (let i = 0, len = elements.length; i < len; i++) {
273
- const element = elements[i];
274
- const elementName = element.nodeName.toLowerCase();
275
-
276
- if (!Object.keys(allowList).includes(elementName)) {
277
- element.remove();
278
- continue;
279
- }
280
-
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);
286
- }
287
- });
288
- }
289
-
290
- return createdDocument.body.innerHTML;
291
- }
292
-
293
- /**
294
- * --------------------------------------------------------------------------
295
- * Bootstrap (v5.1.3): tooltip.js
296
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
297
- * --------------------------------------------------------------------------
298
- */
299
- /**
300
- * ------------------------------------------------------------------------
301
45
  * Constants
302
- * ------------------------------------------------------------------------
303
46
  */
304
47
 
305
48
  const NAME = 'tooltip';
306
- const DATA_KEY = 'bs.tooltip';
307
- const EVENT_KEY = `.${DATA_KEY}`;
308
- const CLASS_PREFIX = 'bs-tooltip';
309
49
  const DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']);
310
- const DefaultType = {
311
- animation: 'boolean',
312
- template: 'string',
313
- title: '(string|element|function)',
314
- trigger: 'string',
315
- delay: '(number|object)',
316
- html: 'boolean',
317
- selector: '(string|boolean)',
318
- placement: '(string|function)',
319
- offset: '(array|string|function)',
320
- container: '(string|element|boolean)',
321
- fallbackPlacements: 'array',
322
- boundary: '(string|element)',
323
- customClass: '(string|function)',
324
- sanitize: 'boolean',
325
- sanitizeFn: '(null|function)',
326
- allowList: 'object',
327
- popperConfig: '(null|object|function)'
328
- };
50
+ const CLASS_NAME_FADE = 'fade';
51
+ const CLASS_NAME_MODAL = 'modal';
52
+ const CLASS_NAME_SHOW = 'show';
53
+ const SELECTOR_TOOLTIP_INNER = '.tooltip-inner';
54
+ const SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`;
55
+ const EVENT_MODAL_HIDE = 'hide.bs.modal';
56
+ const TRIGGER_HOVER = 'hover';
57
+ const TRIGGER_FOCUS = 'focus';
58
+ const TRIGGER_CLICK = 'click';
59
+ const TRIGGER_MANUAL = 'manual';
60
+ const EVENT_HIDE = 'hide';
61
+ const EVENT_HIDDEN = 'hidden';
62
+ const EVENT_SHOW = 'show';
63
+ const EVENT_SHOWN = 'shown';
64
+ const EVENT_INSERTED = 'inserted';
65
+ const EVENT_CLICK = 'click';
66
+ const EVENT_FOCUSIN = 'focusin';
67
+ const EVENT_FOCUSOUT = 'focusout';
68
+ const EVENT_MOUSEENTER = 'mouseenter';
69
+ const EVENT_MOUSELEAVE = 'mouseleave';
329
70
  const AttachmentMap = {
330
71
  AUTO: 'auto',
331
72
  TOP: 'top',
332
- RIGHT: isRTL() ? 'left' : 'right',
73
+ RIGHT: index.isRTL() ? 'left' : 'right',
333
74
  BOTTOM: 'bottom',
334
- LEFT: isRTL() ? 'right' : 'left'
75
+ LEFT: index.isRTL() ? 'right' : 'left'
335
76
  };
336
77
  const Default = {
78
+ allowList: sanitizer.DefaultAllowlist,
337
79
  animation: true,
338
- template: '<div class="tooltip" role="tooltip">' + '<div class="tooltip-arrow"></div>' + '<div class="tooltip-inner"></div>' + '</div>',
339
- trigger: 'hover focus',
340
- title: '',
80
+ boundary: 'clippingParents',
81
+ container: false,
82
+ customClass: '',
341
83
  delay: 0,
84
+ fallbackPlacements: ['top', 'right', 'bottom', 'left'],
342
85
  html: false,
343
- selector: false,
344
- placement: 'top',
345
86
  offset: [0, 0],
346
- container: false,
347
- fallbackPlacements: ['top', 'right', 'bottom', 'left'],
348
- boundary: 'clippingParents',
349
- customClass: '',
87
+ placement: 'top',
88
+ popperConfig: null,
350
89
  sanitize: true,
351
90
  sanitizeFn: null,
352
- allowList: DefaultAllowlist,
353
- popperConfig: null
91
+ selector: false,
92
+ template: '<div class="tooltip" role="tooltip">' + '<div class="tooltip-arrow"></div>' + '<div class="tooltip-inner"></div>' + '</div>',
93
+ title: '',
94
+ trigger: 'hover focus'
354
95
  };
355
- const Event = {
356
- HIDE: `hide${EVENT_KEY}`,
357
- HIDDEN: `hidden${EVENT_KEY}`,
358
- SHOW: `show${EVENT_KEY}`,
359
- SHOWN: `shown${EVENT_KEY}`,
360
- INSERTED: `inserted${EVENT_KEY}`,
361
- CLICK: `click${EVENT_KEY}`,
362
- FOCUSIN: `focusin${EVENT_KEY}`,
363
- FOCUSOUT: `focusout${EVENT_KEY}`,
364
- MOUSEENTER: `mouseenter${EVENT_KEY}`,
365
- MOUSELEAVE: `mouseleave${EVENT_KEY}`
96
+ const DefaultType = {
97
+ allowList: 'object',
98
+ animation: 'boolean',
99
+ boundary: '(string|element)',
100
+ container: '(string|element|boolean)',
101
+ customClass: '(string|function)',
102
+ delay: '(number|object)',
103
+ fallbackPlacements: 'array',
104
+ html: 'boolean',
105
+ offset: '(array|string|function)',
106
+ placement: '(string|function)',
107
+ popperConfig: '(null|object|function)',
108
+ sanitize: 'boolean',
109
+ sanitizeFn: '(null|function)',
110
+ selector: '(string|boolean)',
111
+ template: 'string',
112
+ title: '(string|element|function)',
113
+ trigger: 'string'
366
114
  };
367
- const CLASS_NAME_FADE = 'fade';
368
- const CLASS_NAME_MODAL = 'modal';
369
- const CLASS_NAME_SHOW = 'show';
370
- const HOVER_STATE_SHOW = 'show';
371
- const HOVER_STATE_OUT = 'out';
372
- const SELECTOR_TOOLTIP_INNER = '.tooltip-inner';
373
- const SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`;
374
- const EVENT_MODAL_HIDE = 'hide.bs.modal';
375
- const TRIGGER_HOVER = 'hover';
376
- const TRIGGER_FOCUS = 'focus';
377
- const TRIGGER_CLICK = 'click';
378
- const TRIGGER_MANUAL = 'manual';
379
115
  /**
380
- * ------------------------------------------------------------------------
381
- * Class Definition
382
- * ------------------------------------------------------------------------
116
+ * Class definition
383
117
  */
384
118
 
385
119
  class Tooltip extends BaseComponent__default.default {
@@ -388,15 +122,16 @@
388
122
  throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org)');
389
123
  }
390
124
 
391
- super(element); // private
125
+ super(element, config); // Private
392
126
 
393
127
  this._isEnabled = true;
394
128
  this._timeout = 0;
395
- this._hoverState = '';
129
+ this._isHovered = false;
396
130
  this._activeTrigger = {};
397
- this._popper = null; // Protected
131
+ this._popper = null;
132
+ this._templateFactory = null;
133
+ this._newContent = null; // Protected
398
134
 
399
- this._config = this._getConfig(config);
400
135
  this.tip = null;
401
136
 
402
137
  this._setListeners();
@@ -407,16 +142,12 @@
407
142
  return Default;
408
143
  }
409
144
 
410
- static get NAME() {
411
- return NAME;
412
- }
413
-
414
- static get Event() {
415
- return Event;
416
- }
417
-
418
145
  static get DefaultType() {
419
146
  return DefaultType;
147
+ }
148
+
149
+ static get NAME() {
150
+ return NAME;
420
151
  } // Public
421
152
 
422
153
 
@@ -443,19 +174,21 @@
443
174
  context._activeTrigger.click = !context._activeTrigger.click;
444
175
 
445
176
  if (context._isWithActiveTrigger()) {
446
- context._enter(null, context);
177
+ context._enter();
447
178
  } else {
448
- context._leave(null, context);
179
+ context._leave();
449
180
  }
450
- } else {
451
- if (this.getTipElement().classList.contains(CLASS_NAME_SHOW)) {
452
- this._leave(null, this);
453
181
 
454
- return;
455
- }
182
+ return;
183
+ }
184
+
185
+ if (this._isShown()) {
186
+ this._leave();
456
187
 
457
- this._enter(null, this);
188
+ return;
458
189
  }
190
+
191
+ this._enter();
459
192
  }
460
193
 
461
194
  dispose() {
@@ -476,233 +209,206 @@
476
209
  throw new Error('Please use show on visible elements');
477
210
  }
478
211
 
479
- if (!(this.isWithContent() && this._isEnabled)) {
212
+ if (!(this._isWithContent() && this._isEnabled)) {
480
213
  return;
481
214
  }
482
215
 
483
- const showEvent = EventHandler__default.default.trigger(this._element, this.constructor.Event.SHOW);
484
- const shadowRoot = findShadowRoot(this._element);
485
- const isInTheDom = shadowRoot === null ? this._element.ownerDocument.documentElement.contains(this._element) : shadowRoot.contains(this._element);
216
+ const showEvent = EventHandler__default.default.trigger(this._element, this.constructor.eventName(EVENT_SHOW));
217
+ const shadowRoot = index.findShadowRoot(this._element);
218
+
219
+ const isInTheDom = (shadowRoot || this._element.ownerDocument.documentElement).contains(this._element);
486
220
 
487
221
  if (showEvent.defaultPrevented || !isInTheDom) {
488
222
  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
223
+ } // todo v6 remove this OR make it optional
491
224
 
492
225
 
493
- if (this.constructor.NAME === 'tooltip' && this.tip && this.getTitle() !== this.tip.querySelector(SELECTOR_TOOLTIP_INNER).innerHTML) {
494
- this._disposePopper();
495
-
226
+ if (this.tip) {
496
227
  this.tip.remove();
497
228
  this.tip = null;
498
229
  }
499
230
 
500
- const tip = this.getTipElement();
501
- const tipId = getUID(this.constructor.NAME);
502
- tip.setAttribute('id', tipId);
503
-
504
- this._element.setAttribute('aria-describedby', tipId);
505
-
506
- if (this._config.animation) {
507
- tip.classList.add(CLASS_NAME_FADE);
508
- }
231
+ const tip = this._getTipElement();
509
232
 
510
- const placement = typeof this._config.placement === 'function' ? this._config.placement.call(this, tip, this._element) : this._config.placement;
511
-
512
- const attachment = this._getAttachment(placement);
513
-
514
- this._addAttachmentClass(attachment);
233
+ this._element.setAttribute('aria-describedby', tip.getAttribute('id'));
515
234
 
516
235
  const {
517
236
  container
518
237
  } = this._config;
519
- Data__default.default.set(tip, this.constructor.DATA_KEY, this);
520
238
 
521
239
  if (!this._element.ownerDocument.documentElement.contains(this.tip)) {
522
240
  container.append(tip);
523
- EventHandler__default.default.trigger(this._element, this.constructor.Event.INSERTED);
241
+ EventHandler__default.default.trigger(this._element, this.constructor.eventName(EVENT_INSERTED));
524
242
  }
525
243
 
526
244
  if (this._popper) {
527
245
  this._popper.update();
528
246
  } else {
529
- this._popper = Popper__namespace.createPopper(this._element, tip, this._getPopperConfig(attachment));
247
+ this._popper = this._createPopper(tip);
530
248
  }
531
249
 
532
- tip.classList.add(CLASS_NAME_SHOW);
533
-
534
- const customClass = this._resolvePossibleFunction(this._config.customClass);
535
-
536
- if (customClass) {
537
- tip.classList.add(...customClass.split(' '));
538
- } // If this is a touch-enabled device we add extra
250
+ tip.classList.add(CLASS_NAME_SHOW); // If this is a touch-enabled device we add extra
539
251
  // empty mouseover listeners to the body's immediate children;
540
252
  // only needed because of broken event delegation on iOS
541
253
  // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
542
254
 
543
-
544
255
  if ('ontouchstart' in document.documentElement) {
545
- [].concat(...document.body.children).forEach(element => {
546
- EventHandler__default.default.on(element, 'mouseover', noop);
547
- });
256
+ for (const element of [].concat(...document.body.children)) {
257
+ EventHandler__default.default.on(element, 'mouseover', index.noop);
258
+ }
548
259
  }
549
260
 
550
261
  const complete = () => {
551
- const prevHoverState = this._hoverState;
552
- this._hoverState = null;
553
- EventHandler__default.default.trigger(this._element, this.constructor.Event.SHOWN);
262
+ const previousHoverState = this._isHovered;
263
+ this._isHovered = false;
264
+ EventHandler__default.default.trigger(this._element, this.constructor.eventName(EVENT_SHOWN));
554
265
 
555
- if (prevHoverState === HOVER_STATE_OUT) {
556
- this._leave(null, this);
266
+ if (previousHoverState) {
267
+ this._leave();
557
268
  }
558
269
  };
559
270
 
560
- const isAnimated = this.tip.classList.contains(CLASS_NAME_FADE);
561
-
562
- this._queueCallback(complete, this.tip, isAnimated);
271
+ this._queueCallback(complete, this.tip, this._isAnimated());
563
272
  }
564
273
 
565
274
  hide() {
566
- if (!this._popper) {
275
+ if (!this._isShown()) {
567
276
  return;
568
277
  }
569
278
 
570
- const tip = this.getTipElement();
571
-
572
- const complete = () => {
573
- if (this._isWithActiveTrigger()) {
574
- return;
575
- }
576
-
577
- if (this._hoverState !== HOVER_STATE_SHOW) {
578
- tip.remove();
579
- }
580
-
581
- this._cleanTipClass();
582
-
583
- this._element.removeAttribute('aria-describedby');
584
-
585
- EventHandler__default.default.trigger(this._element, this.constructor.Event.HIDDEN);
586
-
587
- this._disposePopper();
588
- };
589
-
590
- const hideEvent = EventHandler__default.default.trigger(this._element, this.constructor.Event.HIDE);
279
+ const hideEvent = EventHandler__default.default.trigger(this._element, this.constructor.eventName(EVENT_HIDE));
591
280
 
592
281
  if (hideEvent.defaultPrevented) {
593
282
  return;
594
283
  }
595
284
 
285
+ const tip = this._getTipElement();
286
+
596
287
  tip.classList.remove(CLASS_NAME_SHOW); // If this is a touch-enabled device we remove the extra
597
288
  // empty mouseover listeners we added for iOS support
598
289
 
599
290
  if ('ontouchstart' in document.documentElement) {
600
- [].concat(...document.body.children).forEach(element => EventHandler__default.default.off(element, 'mouseover', noop));
291
+ for (const element of [].concat(...document.body.children)) {
292
+ EventHandler__default.default.off(element, 'mouseover', index.noop);
293
+ }
601
294
  }
602
295
 
603
296
  this._activeTrigger[TRIGGER_CLICK] = false;
604
297
  this._activeTrigger[TRIGGER_FOCUS] = false;
605
298
  this._activeTrigger[TRIGGER_HOVER] = false;
606
- const isAnimated = this.tip.classList.contains(CLASS_NAME_FADE);
299
+ this._isHovered = false;
607
300
 
608
- this._queueCallback(complete, this.tip, isAnimated);
301
+ const complete = () => {
302
+ if (this._isWithActiveTrigger()) {
303
+ return;
304
+ }
609
305
 
610
- this._hoverState = '';
306
+ if (!this._isHovered) {
307
+ tip.remove();
308
+ }
309
+
310
+ this._element.removeAttribute('aria-describedby');
311
+
312
+ EventHandler__default.default.trigger(this._element, this.constructor.eventName(EVENT_HIDDEN));
313
+
314
+ this._disposePopper();
315
+ };
316
+
317
+ this._queueCallback(complete, this.tip, this._isAnimated());
611
318
  }
612
319
 
613
320
  update() {
614
- if (this._popper !== null) {
321
+ if (this._popper) {
615
322
  this._popper.update();
616
323
  }
617
324
  } // Protected
618
325
 
619
326
 
620
- isWithContent() {
621
- return Boolean(this.getTitle());
327
+ _isWithContent() {
328
+ return Boolean(this._getTitle());
622
329
  }
623
330
 
624
- getTipElement() {
625
- if (this.tip) {
626
- return this.tip;
331
+ _getTipElement() {
332
+ if (!this.tip) {
333
+ this.tip = this._createTipElement(this._newContent || this._getContentForTemplate());
627
334
  }
628
335
 
629
- const element = document.createElement('div');
630
- element.innerHTML = this._config.template;
631
- const tip = element.children[0];
632
- this.setContent(tip);
633
- tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW);
634
- this.tip = tip;
635
336
  return this.tip;
636
337
  }
637
338
 
638
- setContent(tip) {
639
- this._sanitizeAndSetContent(tip, this.getTitle(), SELECTOR_TOOLTIP_INNER);
640
- }
339
+ _createTipElement(content) {
340
+ const tip = this._getTemplateFactory(content).toHtml(); // todo: remove this check on v6
641
341
 
642
- _sanitizeAndSetContent(template, content, selector) {
643
- const templateElement = SelectorEngine__default.default.findOne(selector, template);
644
342
 
645
- if (!content && templateElement) {
646
- templateElement.remove();
647
- return;
648
- } // we use append for html objects to maintain js events
343
+ if (!tip) {
344
+ return null;
345
+ }
649
346
 
347
+ tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW); // todo: on v6 the following can be achieved with CSS only
650
348
 
651
- this.setElementContent(templateElement, content);
652
- }
349
+ tip.classList.add(`bs-${this.constructor.NAME}-auto`);
350
+ const tipId = index.getUID(this.constructor.NAME).toString();
351
+ tip.setAttribute('id', tipId);
653
352
 
654
- setElementContent(element, content) {
655
- if (element === null) {
656
- return;
353
+ if (this._isAnimated()) {
354
+ tip.classList.add(CLASS_NAME_FADE);
657
355
  }
658
356
 
659
- if (isElement(content)) {
660
- content = getElement(content); // content is a DOM node or a jQuery
357
+ return tip;
358
+ }
661
359
 
662
- if (this._config.html) {
663
- if (content.parentNode !== element) {
664
- element.innerHTML = '';
665
- element.append(content);
666
- }
667
- } else {
668
- element.textContent = content.textContent;
669
- }
360
+ setContent(content) {
361
+ this._newContent = content;
670
362
 
671
- return;
672
- }
363
+ if (this._isShown()) {
364
+ this._disposePopper();
673
365
 
674
- if (this._config.html) {
675
- if (this._config.sanitize) {
676
- content = sanitizeHtml(content, this._config.allowList, this._config.sanitizeFn);
677
- }
366
+ this.show();
367
+ }
368
+ }
678
369
 
679
- element.innerHTML = content;
370
+ _getTemplateFactory(content) {
371
+ if (this._templateFactory) {
372
+ this._templateFactory.changeContent(content);
680
373
  } else {
681
- element.textContent = content;
374
+ this._templateFactory = new TemplateFactory__default.default({ ...this._config,
375
+ // the `content` var has to be after `this._config`
376
+ // to override config.content in case of popover
377
+ content,
378
+ extraClass: this._resolvePossibleFunction(this._config.customClass)
379
+ });
682
380
  }
683
- }
684
381
 
685
- getTitle() {
686
- const title = this._element.getAttribute('data-bs-original-title') || this._config.title;
382
+ return this._templateFactory;
383
+ }
687
384
 
688
- return this._resolvePossibleFunction(title);
385
+ _getContentForTemplate() {
386
+ return {
387
+ [SELECTOR_TOOLTIP_INNER]: this._getTitle()
388
+ };
689
389
  }
690
390
 
691
- updateAttachment(attachment) {
692
- if (attachment === 'right') {
693
- return 'end';
694
- }
391
+ _getTitle() {
392
+ return this._resolvePossibleFunction(this._config.title) || this._config.originalTitle;
393
+ } // Private
695
394
 
696
- if (attachment === 'left') {
697
- return 'start';
698
- }
699
395
 
700
- return attachment;
701
- } // Private
396
+ _initializeOnDelegatedTarget(event) {
397
+ return this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig());
398
+ }
399
+
400
+ _isAnimated() {
401
+ return this._config.animation || this.tip && this.tip.classList.contains(CLASS_NAME_FADE);
402
+ }
702
403
 
404
+ _isShown() {
405
+ return this.tip && this.tip.classList.contains(CLASS_NAME_SHOW);
406
+ }
703
407
 
704
- _initializeOnDelegatedTarget(event, context) {
705
- return context || this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig());
408
+ _createPopper(tip) {
409
+ const placement = typeof this._config.placement === 'function' ? this._config.placement.call(this, tip, this._element) : this._config.placement;
410
+ const attachment = AttachmentMap[placement.toUpperCase()];
411
+ return Popper__namespace.createPopper(this._element, tip, this._getPopperConfig(attachment));
706
412
  }
707
413
 
708
414
  _getOffset() {
@@ -711,7 +417,7 @@
711
417
  } = this._config;
712
418
 
713
419
  if (typeof offset === 'string') {
714
- return offset.split(',').map(val => Number.parseInt(val, 10));
420
+ return offset.split(',').map(value => Number.parseInt(value, 10));
715
421
  }
716
422
 
717
423
  if (typeof offset === 'function') {
@@ -721,8 +427,8 @@
721
427
  return offset;
722
428
  }
723
429
 
724
- _resolvePossibleFunction(content) {
725
- return typeof content === 'function' ? content.call(this._element) : content;
430
+ _resolvePossibleFunction(arg) {
431
+ return typeof arg === 'function' ? arg.call(this._element) : arg;
726
432
  }
727
433
 
728
434
  _getPopperConfig(attachment) {
@@ -749,43 +455,46 @@
749
455
  element: `.${this.constructor.NAME}-arrow`
750
456
  }
751
457
  }, {
752
- name: 'onChange',
458
+ name: 'preSetPlacement',
753
459
  enabled: true,
754
- phase: 'afterWrite',
755
- fn: data => this._handlePopperPlacementChange(data)
756
- }],
757
- onFirstUpdate: data => {
758
- if (data.options.placement !== data.placement) {
759
- this._handlePopperPlacementChange(data);
460
+ phase: 'beforeMain',
461
+ fn: data => {
462
+ // Pre-set Popper's placement attribute in order to read the arrow sizes properly.
463
+ // Otherwise, Popper mixes up the width and height dimensions since the initial arrow style is for top placement
464
+ this._getTipElement().setAttribute('data-popper-placement', data.state.placement);
760
465
  }
761
- }
466
+ }]
762
467
  };
763
468
  return { ...defaultBsPopperConfig,
764
469
  ...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig)
765
470
  };
766
471
  }
767
472
 
768
- _addAttachmentClass(attachment) {
769
- this.getTipElement().classList.add(`${this._getBasicClassPrefix()}-${this.updateAttachment(attachment)}`);
770
- }
771
-
772
- _getAttachment(placement) {
773
- return AttachmentMap[placement.toUpperCase()];
774
- }
775
-
776
473
  _setListeners() {
777
474
  const triggers = this._config.trigger.split(' ');
778
475
 
779
- triggers.forEach(trigger => {
476
+ for (const trigger of triggers) {
780
477
  if (trigger === 'click') {
781
- EventHandler__default.default.on(this._element, this.constructor.Event.CLICK, this._config.selector, event => this.toggle(event));
478
+ EventHandler__default.default.on(this._element, this.constructor.eventName(EVENT_CLICK), this._config.selector, event => this.toggle(event));
782
479
  } else if (trigger !== TRIGGER_MANUAL) {
783
- const eventIn = trigger === TRIGGER_HOVER ? this.constructor.Event.MOUSEENTER : this.constructor.Event.FOCUSIN;
784
- const eventOut = trigger === TRIGGER_HOVER ? this.constructor.Event.MOUSELEAVE : this.constructor.Event.FOCUSOUT;
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));
480
+ const eventIn = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSEENTER) : this.constructor.eventName(EVENT_FOCUSIN);
481
+ const eventOut = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSELEAVE) : this.constructor.eventName(EVENT_FOCUSOUT);
482
+ EventHandler__default.default.on(this._element, eventIn, this._config.selector, event => {
483
+ const context = this._initializeOnDelegatedTarget(event);
484
+
485
+ context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true;
486
+
487
+ context._enter();
488
+ });
489
+ EventHandler__default.default.on(this._element, eventOut, this._config.selector, event => {
490
+ const context = this._initializeOnDelegatedTarget(event);
491
+
492
+ context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = context._element.contains(event.relatedTarget);
493
+
494
+ context._leave();
495
+ });
787
496
  }
788
- });
497
+ }
789
498
 
790
499
  this._hideModalHandler = () => {
791
500
  if (this._element) {
@@ -806,96 +515,79 @@
806
515
  }
807
516
 
808
517
  _fixTitle() {
809
- const title = this._element.getAttribute('title');
810
-
811
- const originalTitleType = typeof this._element.getAttribute('data-bs-original-title');
812
-
813
- if (title || originalTitleType !== 'string') {
814
- this._element.setAttribute('data-bs-original-title', title || '');
815
-
816
- if (title && !this._element.getAttribute('aria-label') && !this._element.textContent) {
817
- this._element.setAttribute('aria-label', title);
818
- }
819
-
820
- this._element.setAttribute('title', '');
821
- }
822
- }
518
+ const title = this._config.originalTitle;
823
519
 
824
- _enter(event, context) {
825
- context = this._initializeOnDelegatedTarget(event, context);
826
-
827
- if (event) {
828
- context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true;
520
+ if (!title) {
521
+ return;
829
522
  }
830
523
 
831
- if (context.getTipElement().classList.contains(CLASS_NAME_SHOW) || context._hoverState === HOVER_STATE_SHOW) {
832
- context._hoverState = HOVER_STATE_SHOW;
833
- return;
524
+ if (!this._element.getAttribute('aria-label') && !this._element.textContent.trim()) {
525
+ this._element.setAttribute('aria-label', title);
834
526
  }
835
527
 
836
- clearTimeout(context._timeout);
837
- context._hoverState = HOVER_STATE_SHOW;
528
+ this._element.removeAttribute('title');
529
+ }
838
530
 
839
- if (!context._config.delay || !context._config.delay.show) {
840
- context.show();
531
+ _enter() {
532
+ if (this._isShown() || this._isHovered) {
533
+ this._isHovered = true;
841
534
  return;
842
535
  }
843
536
 
844
- context._timeout = setTimeout(() => {
845
- if (context._hoverState === HOVER_STATE_SHOW) {
846
- context.show();
537
+ this._isHovered = true;
538
+
539
+ this._setTimeout(() => {
540
+ if (this._isHovered) {
541
+ this.show();
847
542
  }
848
- }, context._config.delay.show);
543
+ }, this._config.delay.show);
849
544
  }
850
545
 
851
- _leave(event, context) {
852
- context = this._initializeOnDelegatedTarget(event, context);
853
-
854
- if (event) {
855
- context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = context._element.contains(event.relatedTarget);
856
- }
857
-
858
- if (context._isWithActiveTrigger()) {
546
+ _leave() {
547
+ if (this._isWithActiveTrigger()) {
859
548
  return;
860
549
  }
861
550
 
862
- clearTimeout(context._timeout);
863
- context._hoverState = HOVER_STATE_OUT;
551
+ this._isHovered = false;
864
552
 
865
- if (!context._config.delay || !context._config.delay.hide) {
866
- context.hide();
867
- return;
868
- }
869
-
870
- context._timeout = setTimeout(() => {
871
- if (context._hoverState === HOVER_STATE_OUT) {
872
- context.hide();
553
+ this._setTimeout(() => {
554
+ if (!this._isHovered) {
555
+ this.hide();
873
556
  }
874
- }, context._config.delay.hide);
557
+ }, this._config.delay.hide);
875
558
  }
876
559
 
877
- _isWithActiveTrigger() {
878
- for (const trigger in this._activeTrigger) {
879
- if (this._activeTrigger[trigger]) {
880
- return true;
881
- }
882
- }
560
+ _setTimeout(handler, timeout) {
561
+ clearTimeout(this._timeout);
562
+ this._timeout = setTimeout(handler, timeout);
563
+ }
883
564
 
884
- return false;
565
+ _isWithActiveTrigger() {
566
+ return Object.values(this._activeTrigger).includes(true);
885
567
  }
886
568
 
887
569
  _getConfig(config) {
888
570
  const dataAttributes = Manipulator__default.default.getDataAttributes(this._element);
889
- Object.keys(dataAttributes).forEach(dataAttr => {
890
- if (DISALLOWED_ATTRIBUTES.has(dataAttr)) {
891
- delete dataAttributes[dataAttr];
571
+
572
+ for (const dataAttribute of Object.keys(dataAttributes)) {
573
+ if (DISALLOWED_ATTRIBUTES.has(dataAttribute)) {
574
+ delete dataAttributes[dataAttribute];
892
575
  }
893
- });
894
- config = { ...this.constructor.Default,
895
- ...dataAttributes,
576
+ }
577
+
578
+ config = { ...dataAttributes,
896
579
  ...(typeof config === 'object' && config ? config : {})
897
580
  };
898
- config.container = config.container === false ? document.body : getElement(config.container);
581
+ config = this._mergeConfigObj(config);
582
+ config = this._configAfterMerge(config);
583
+
584
+ this._typeCheckConfig(config);
585
+
586
+ return config;
587
+ }
588
+
589
+ _configAfterMerge(config) {
590
+ config.container = config.container === false ? document.body : index.getElement(config.container);
899
591
 
900
592
  if (typeof config.delay === 'number') {
901
593
  config.delay = {
@@ -904,6 +596,8 @@
904
596
  };
905
597
  }
906
598
 
599
+ config.originalTitle = this._element.getAttribute('title') || '';
600
+
907
601
  if (typeof config.title === 'number') {
908
602
  config.title = config.title.toString();
909
603
  }
@@ -912,12 +606,6 @@
912
606
  config.content = config.content.toString();
913
607
  }
914
608
 
915
- typeCheckConfig(NAME, config, this.constructor.DefaultType);
916
-
917
- if (config.sanitize) {
918
- config.template = sanitizeHtml(config.template, config.allowList, config.sanitizeFn);
919
- }
920
-
921
609
  return config;
922
610
  }
923
611
 
@@ -936,36 +624,6 @@
936
624
  return config;
937
625
  }
938
626
 
939
- _cleanTipClass() {
940
- const tip = this.getTipElement();
941
- const basicClassPrefixRegex = new RegExp(`(^|\\s)${this._getBasicClassPrefix()}\\S+`, 'g');
942
- const tabClass = tip.getAttribute('class').match(basicClassPrefixRegex);
943
-
944
- if (tabClass !== null && tabClass.length > 0) {
945
- tabClass.map(token => token.trim()).forEach(tClass => tip.classList.remove(tClass));
946
- }
947
- }
948
-
949
- _getBasicClassPrefix() {
950
- return CLASS_PREFIX;
951
- }
952
-
953
- _handlePopperPlacementChange(popperData) {
954
- const {
955
- state
956
- } = popperData;
957
-
958
- if (!state) {
959
- return;
960
- }
961
-
962
- this.tip = state.elements.popper;
963
-
964
- this._cleanTipClass();
965
-
966
- this._addAttachmentClass(this._getAttachment(state.placement));
967
- }
968
-
969
627
  _disposePopper() {
970
628
  if (this._popper) {
971
629
  this._popper.destroy();
@@ -979,26 +637,25 @@
979
637
  return this.each(function () {
980
638
  const data = Tooltip.getOrCreateInstance(this, config);
981
639
 
982
- if (typeof config === 'string') {
983
- if (typeof data[config] === 'undefined') {
984
- throw new TypeError(`No method named "${config}"`);
985
- }
640
+ if (typeof config !== 'string') {
641
+ return;
642
+ }
986
643
 
987
- data[config]();
644
+ if (typeof data[config] === 'undefined') {
645
+ throw new TypeError(`No method named "${config}"`);
988
646
  }
647
+
648
+ data[config]();
989
649
  });
990
650
  }
991
651
 
992
652
  }
993
653
  /**
994
- * ------------------------------------------------------------------------
995
654
  * jQuery
996
- * ------------------------------------------------------------------------
997
- * add .Tooltip to jQuery only if jQuery is present
998
655
  */
999
656
 
1000
657
 
1001
- defineJQueryPlugin(Tooltip);
658
+ index.defineJQueryPlugin(Tooltip);
1002
659
 
1003
660
  return Tooltip;
1004
661