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