publishing_platform_publishing_components 0.1.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 (259) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/README.md +2 -0
  4. data/Rakefile +41 -0
  5. data/app/assets/builds/gemkeep +0 -0
  6. data/app/assets/config/publishing_platform_publishing_components_manifest.js +2 -0
  7. data/app/assets/images/publishing_platform_publishing_components/gemkeep +0 -0
  8. data/app/assets/stylesheets/publishing_platform_publishing_components/_all_components.scss +3 -0
  9. data/app/assets/stylesheets/publishing_platform_publishing_components/components/_attachment.scss +117 -0
  10. data/app/assets/stylesheets/publishing_platform_publishing_components/components/_summary-list.scss +169 -0
  11. data/app/controllers/publishing_platform_publishing_components/application_controller.rb +4 -0
  12. data/app/helpers/publishing_platform_publishing_components/application_helper.rb +4 -0
  13. data/app/models/publishing_platform_publishing_components/component_doc.rb +90 -0
  14. data/app/models/publishing_platform_publishing_components/component_docs.rb +57 -0
  15. data/app/models/publishing_platform_publishing_components/component_example.rb +104 -0
  16. data/app/models/publishing_platform_publishing_components/shared_accessibility_criteria.rb +37 -0
  17. data/app/views/publishing_platform_publishing_components/component_doc/_component_output.html.erb +15 -0
  18. data/app/views/publishing_platform_publishing_components/components/_attachment.html.erb +91 -0
  19. data/app/views/publishing_platform_publishing_components/components/_error_summary.html.erb +38 -0
  20. data/app/views/publishing_platform_publishing_components/components/_summary_list.html.erb +135 -0
  21. data/app/views/publishing_platform_publishing_components/components/attachment/_thumbnail_document.html.erb +3 -0
  22. data/app/views/publishing_platform_publishing_components/components/attachment/_thumbnail_external.html.erb +3 -0
  23. data/app/views/publishing_platform_publishing_components/components/attachment/_thumbnail_generic.html.erb +4 -0
  24. data/app/views/publishing_platform_publishing_components/components/attachment/_thumbnail_html.html.erb +3 -0
  25. data/app/views/publishing_platform_publishing_components/components/attachment/_thumbnail_pdf.html.erb +3 -0
  26. data/app/views/publishing_platform_publishing_components/components/attachment/_thumbnail_spreadsheet.html.erb +5 -0
  27. data/app/views/publishing_platform_publishing_components/components/docs/attachment.yml +104 -0
  28. data/app/views/publishing_platform_publishing_components/components/docs/error_summary.yml +51 -0
  29. data/app/views/publishing_platform_publishing_components/components/docs/summary_list.yml +137 -0
  30. data/config/initializers/assets.rb +24 -0
  31. data/config/routes.rb +2 -0
  32. data/lib/publishing_platform_publishing_components/config.rb +25 -0
  33. data/lib/publishing_platform_publishing_components/engine.rb +5 -0
  34. data/lib/publishing_platform_publishing_components/presenters/attachment_helper.rb +176 -0
  35. data/lib/publishing_platform_publishing_components/presenters/component_wrapper_helper.rb +290 -0
  36. data/lib/publishing_platform_publishing_components/presenters/shared_helper.rb +24 -0
  37. data/lib/publishing_platform_publishing_components/version.rb +3 -0
  38. data/lib/publishing_platform_publishing_components.rb +10 -0
  39. data/lib/tasks/publishing_platform_publishing_components_tasks.rake +4 -0
  40. data/node_modules/bootstrap/LICENSE +21 -0
  41. data/node_modules/bootstrap/README.md +246 -0
  42. data/node_modules/bootstrap/dist/css/bootstrap-grid.css +4085 -0
  43. data/node_modules/bootstrap/dist/css/bootstrap-grid.css.map +1 -0
  44. data/node_modules/bootstrap/dist/css/bootstrap-grid.min.css +6 -0
  45. data/node_modules/bootstrap/dist/css/bootstrap-grid.min.css.map +1 -0
  46. data/node_modules/bootstrap/dist/css/bootstrap-grid.rtl.css +4084 -0
  47. data/node_modules/bootstrap/dist/css/bootstrap-grid.rtl.css.map +1 -0
  48. data/node_modules/bootstrap/dist/css/bootstrap-grid.rtl.min.css +6 -0
  49. data/node_modules/bootstrap/dist/css/bootstrap-grid.rtl.min.css.map +1 -0
  50. data/node_modules/bootstrap/dist/css/bootstrap-reboot.css +601 -0
  51. data/node_modules/bootstrap/dist/css/bootstrap-reboot.css.map +1 -0
  52. data/node_modules/bootstrap/dist/css/bootstrap-reboot.min.css +6 -0
  53. data/node_modules/bootstrap/dist/css/bootstrap-reboot.min.css.map +1 -0
  54. data/node_modules/bootstrap/dist/css/bootstrap-reboot.rtl.css +598 -0
  55. data/node_modules/bootstrap/dist/css/bootstrap-reboot.rtl.css.map +1 -0
  56. data/node_modules/bootstrap/dist/css/bootstrap-reboot.rtl.min.css +6 -0
  57. data/node_modules/bootstrap/dist/css/bootstrap-reboot.rtl.min.css.map +1 -0
  58. data/node_modules/bootstrap/dist/css/bootstrap-utilities.css +5406 -0
  59. data/node_modules/bootstrap/dist/css/bootstrap-utilities.css.map +1 -0
  60. data/node_modules/bootstrap/dist/css/bootstrap-utilities.min.css +6 -0
  61. data/node_modules/bootstrap/dist/css/bootstrap-utilities.min.css.map +1 -0
  62. data/node_modules/bootstrap/dist/css/bootstrap-utilities.rtl.css +5397 -0
  63. data/node_modules/bootstrap/dist/css/bootstrap-utilities.rtl.css.map +1 -0
  64. data/node_modules/bootstrap/dist/css/bootstrap-utilities.rtl.min.css +6 -0
  65. data/node_modules/bootstrap/dist/css/bootstrap-utilities.rtl.min.css.map +1 -0
  66. data/node_modules/bootstrap/dist/css/bootstrap.css +12048 -0
  67. data/node_modules/bootstrap/dist/css/bootstrap.css.map +1 -0
  68. data/node_modules/bootstrap/dist/css/bootstrap.min.css +6 -0
  69. data/node_modules/bootstrap/dist/css/bootstrap.min.css.map +1 -0
  70. data/node_modules/bootstrap/dist/css/bootstrap.rtl.css +12021 -0
  71. data/node_modules/bootstrap/dist/css/bootstrap.rtl.css.map +1 -0
  72. data/node_modules/bootstrap/dist/css/bootstrap.rtl.min.css +6 -0
  73. data/node_modules/bootstrap/dist/css/bootstrap.rtl.min.css.map +1 -0
  74. data/node_modules/bootstrap/dist/js/bootstrap.bundle.js +6312 -0
  75. data/node_modules/bootstrap/dist/js/bootstrap.bundle.js.map +1 -0
  76. data/node_modules/bootstrap/dist/js/bootstrap.bundle.min.js +7 -0
  77. data/node_modules/bootstrap/dist/js/bootstrap.bundle.min.js.map +1 -0
  78. data/node_modules/bootstrap/dist/js/bootstrap.esm.js +4447 -0
  79. data/node_modules/bootstrap/dist/js/bootstrap.esm.js.map +1 -0
  80. data/node_modules/bootstrap/dist/js/bootstrap.esm.min.js +7 -0
  81. data/node_modules/bootstrap/dist/js/bootstrap.esm.min.js.map +1 -0
  82. data/node_modules/bootstrap/dist/js/bootstrap.js +4494 -0
  83. data/node_modules/bootstrap/dist/js/bootstrap.js.map +1 -0
  84. data/node_modules/bootstrap/dist/js/bootstrap.min.js +7 -0
  85. data/node_modules/bootstrap/dist/js/bootstrap.min.js.map +1 -0
  86. data/node_modules/bootstrap/js/dist/alert.js +90 -0
  87. data/node_modules/bootstrap/js/dist/alert.js.map +1 -0
  88. data/node_modules/bootstrap/js/dist/base-component.js +86 -0
  89. data/node_modules/bootstrap/js/dist/base-component.js.map +1 -0
  90. data/node_modules/bootstrap/js/dist/button.js +79 -0
  91. data/node_modules/bootstrap/js/dist/button.js.map +1 -0
  92. data/node_modules/bootstrap/js/dist/carousel.js +388 -0
  93. data/node_modules/bootstrap/js/dist/carousel.js.map +1 -0
  94. data/node_modules/bootstrap/js/dist/collapse.js +249 -0
  95. data/node_modules/bootstrap/js/dist/collapse.js.map +1 -0
  96. data/node_modules/bootstrap/js/dist/dom/data.js +63 -0
  97. data/node_modules/bootstrap/js/dist/dom/data.js.map +1 -0
  98. data/node_modules/bootstrap/js/dist/dom/event-handler.js +237 -0
  99. data/node_modules/bootstrap/js/dist/dom/event-handler.js.map +1 -0
  100. data/node_modules/bootstrap/js/dist/dom/manipulator.js +72 -0
  101. data/node_modules/bootstrap/js/dist/dom/manipulator.js.map +1 -0
  102. data/node_modules/bootstrap/js/dist/dom/selector-engine.js +104 -0
  103. data/node_modules/bootstrap/js/dist/dom/selector-engine.js.map +1 -0
  104. data/node_modules/bootstrap/js/dist/dropdown.js +402 -0
  105. data/node_modules/bootstrap/js/dist/dropdown.js.map +1 -0
  106. data/node_modules/bootstrap/js/dist/modal.js +320 -0
  107. data/node_modules/bootstrap/js/dist/modal.js.map +1 -0
  108. data/node_modules/bootstrap/js/dist/offcanvas.js +246 -0
  109. data/node_modules/bootstrap/js/dist/offcanvas.js.map +1 -0
  110. data/node_modules/bootstrap/js/dist/popover.js +96 -0
  111. data/node_modules/bootstrap/js/dist/popover.js.map +1 -0
  112. data/node_modules/bootstrap/js/dist/scrollspy.js +275 -0
  113. data/node_modules/bootstrap/js/dist/scrollspy.js.map +1 -0
  114. data/node_modules/bootstrap/js/dist/tab.js +285 -0
  115. data/node_modules/bootstrap/js/dist/tab.js.map +1 -0
  116. data/node_modules/bootstrap/js/dist/toast.js +198 -0
  117. data/node_modules/bootstrap/js/dist/toast.js.map +1 -0
  118. data/node_modules/bootstrap/js/dist/tooltip.js +546 -0
  119. data/node_modules/bootstrap/js/dist/tooltip.js.map +1 -0
  120. data/node_modules/bootstrap/js/dist/util/backdrop.js +139 -0
  121. data/node_modules/bootstrap/js/dist/util/backdrop.js.map +1 -0
  122. data/node_modules/bootstrap/js/dist/util/component-functions.js +42 -0
  123. data/node_modules/bootstrap/js/dist/util/component-functions.js.map +1 -0
  124. data/node_modules/bootstrap/js/dist/util/config.js +68 -0
  125. data/node_modules/bootstrap/js/dist/util/config.js.map +1 -0
  126. data/node_modules/bootstrap/js/dist/util/focustrap.js +113 -0
  127. data/node_modules/bootstrap/js/dist/util/focustrap.js.map +1 -0
  128. data/node_modules/bootstrap/js/dist/util/index.js +281 -0
  129. data/node_modules/bootstrap/js/dist/util/index.js.map +1 -0
  130. data/node_modules/bootstrap/js/dist/util/sanitizer.js +113 -0
  131. data/node_modules/bootstrap/js/dist/util/sanitizer.js.map +1 -0
  132. data/node_modules/bootstrap/js/dist/util/scrollbar.js +113 -0
  133. data/node_modules/bootstrap/js/dist/util/scrollbar.js.map +1 -0
  134. data/node_modules/bootstrap/js/dist/util/swipe.js +135 -0
  135. data/node_modules/bootstrap/js/dist/util/swipe.js.map +1 -0
  136. data/node_modules/bootstrap/js/dist/util/template-factory.js +151 -0
  137. data/node_modules/bootstrap/js/dist/util/template-factory.js.map +1 -0
  138. data/node_modules/bootstrap/js/index.esm.js +19 -0
  139. data/node_modules/bootstrap/js/index.umd.js +34 -0
  140. data/node_modules/bootstrap/js/src/alert.js +87 -0
  141. data/node_modules/bootstrap/js/src/base-component.js +86 -0
  142. data/node_modules/bootstrap/js/src/button.js +72 -0
  143. data/node_modules/bootstrap/js/src/carousel.js +474 -0
  144. data/node_modules/bootstrap/js/src/collapse.js +297 -0
  145. data/node_modules/bootstrap/js/src/dom/data.js +55 -0
  146. data/node_modules/bootstrap/js/src/dom/event-handler.js +317 -0
  147. data/node_modules/bootstrap/js/src/dom/manipulator.js +71 -0
  148. data/node_modules/bootstrap/js/src/dom/selector-engine.js +126 -0
  149. data/node_modules/bootstrap/js/src/dropdown.js +455 -0
  150. data/node_modules/bootstrap/js/src/modal.js +378 -0
  151. data/node_modules/bootstrap/js/src/offcanvas.js +282 -0
  152. data/node_modules/bootstrap/js/src/popover.js +97 -0
  153. data/node_modules/bootstrap/js/src/scrollspy.js +296 -0
  154. data/node_modules/bootstrap/js/src/tab.js +315 -0
  155. data/node_modules/bootstrap/js/src/toast.js +224 -0
  156. data/node_modules/bootstrap/js/src/tooltip.js +633 -0
  157. data/node_modules/bootstrap/js/src/util/backdrop.js +151 -0
  158. data/node_modules/bootstrap/js/src/util/component-functions.js +35 -0
  159. data/node_modules/bootstrap/js/src/util/config.js +65 -0
  160. data/node_modules/bootstrap/js/src/util/focustrap.js +115 -0
  161. data/node_modules/bootstrap/js/src/util/index.js +306 -0
  162. data/node_modules/bootstrap/js/src/util/sanitizer.js +116 -0
  163. data/node_modules/bootstrap/js/src/util/scrollbar.js +114 -0
  164. data/node_modules/bootstrap/js/src/util/swipe.js +146 -0
  165. data/node_modules/bootstrap/js/src/util/template-factory.js +160 -0
  166. data/node_modules/bootstrap/package.json +210 -0
  167. data/node_modules/bootstrap/scss/_accordion.scss +153 -0
  168. data/node_modules/bootstrap/scss/_alert.scss +68 -0
  169. data/node_modules/bootstrap/scss/_badge.scss +38 -0
  170. data/node_modules/bootstrap/scss/_breadcrumb.scss +40 -0
  171. data/node_modules/bootstrap/scss/_button-group.scss +147 -0
  172. data/node_modules/bootstrap/scss/_buttons.scss +216 -0
  173. data/node_modules/bootstrap/scss/_card.scss +238 -0
  174. data/node_modules/bootstrap/scss/_carousel.scss +226 -0
  175. data/node_modules/bootstrap/scss/_close.scss +66 -0
  176. data/node_modules/bootstrap/scss/_containers.scss +41 -0
  177. data/node_modules/bootstrap/scss/_dropdown.scss +250 -0
  178. data/node_modules/bootstrap/scss/_forms.scss +9 -0
  179. data/node_modules/bootstrap/scss/_functions.scss +302 -0
  180. data/node_modules/bootstrap/scss/_grid.scss +39 -0
  181. data/node_modules/bootstrap/scss/_helpers.scss +12 -0
  182. data/node_modules/bootstrap/scss/_images.scss +42 -0
  183. data/node_modules/bootstrap/scss/_list-group.scss +199 -0
  184. data/node_modules/bootstrap/scss/_maps.scss +174 -0
  185. data/node_modules/bootstrap/scss/_mixins.scss +42 -0
  186. data/node_modules/bootstrap/scss/_modal.scss +240 -0
  187. data/node_modules/bootstrap/scss/_nav.scss +197 -0
  188. data/node_modules/bootstrap/scss/_navbar.scss +289 -0
  189. data/node_modules/bootstrap/scss/_offcanvas.scss +147 -0
  190. data/node_modules/bootstrap/scss/_pagination.scss +109 -0
  191. data/node_modules/bootstrap/scss/_placeholders.scss +51 -0
  192. data/node_modules/bootstrap/scss/_popover.scss +196 -0
  193. data/node_modules/bootstrap/scss/_progress.scss +68 -0
  194. data/node_modules/bootstrap/scss/_reboot.scss +617 -0
  195. data/node_modules/bootstrap/scss/_root.scss +187 -0
  196. data/node_modules/bootstrap/scss/_spinners.scss +86 -0
  197. data/node_modules/bootstrap/scss/_tables.scss +171 -0
  198. data/node_modules/bootstrap/scss/_toasts.scss +73 -0
  199. data/node_modules/bootstrap/scss/_tooltip.scss +119 -0
  200. data/node_modules/bootstrap/scss/_transitions.scss +27 -0
  201. data/node_modules/bootstrap/scss/_type.scss +106 -0
  202. data/node_modules/bootstrap/scss/_utilities.scss +806 -0
  203. data/node_modules/bootstrap/scss/_variables-dark.scss +102 -0
  204. data/node_modules/bootstrap/scss/_variables.scss +1753 -0
  205. data/node_modules/bootstrap/scss/bootstrap-grid.scss +62 -0
  206. data/node_modules/bootstrap/scss/bootstrap-reboot.scss +10 -0
  207. data/node_modules/bootstrap/scss/bootstrap-utilities.scss +19 -0
  208. data/node_modules/bootstrap/scss/bootstrap.scss +52 -0
  209. data/node_modules/bootstrap/scss/forms/_floating-labels.scss +97 -0
  210. data/node_modules/bootstrap/scss/forms/_form-check.scss +189 -0
  211. data/node_modules/bootstrap/scss/forms/_form-control.scss +214 -0
  212. data/node_modules/bootstrap/scss/forms/_form-range.scss +91 -0
  213. data/node_modules/bootstrap/scss/forms/_form-select.scss +80 -0
  214. data/node_modules/bootstrap/scss/forms/_form-text.scss +11 -0
  215. data/node_modules/bootstrap/scss/forms/_input-group.scss +132 -0
  216. data/node_modules/bootstrap/scss/forms/_labels.scss +36 -0
  217. data/node_modules/bootstrap/scss/forms/_validation.scss +12 -0
  218. data/node_modules/bootstrap/scss/helpers/_clearfix.scss +3 -0
  219. data/node_modules/bootstrap/scss/helpers/_color-bg.scss +7 -0
  220. data/node_modules/bootstrap/scss/helpers/_colored-links.scss +30 -0
  221. data/node_modules/bootstrap/scss/helpers/_focus-ring.scss +5 -0
  222. data/node_modules/bootstrap/scss/helpers/_icon-link.scss +25 -0
  223. data/node_modules/bootstrap/scss/helpers/_position.scss +36 -0
  224. data/node_modules/bootstrap/scss/helpers/_ratio.scss +26 -0
  225. data/node_modules/bootstrap/scss/helpers/_stacks.scss +15 -0
  226. data/node_modules/bootstrap/scss/helpers/_stretched-link.scss +15 -0
  227. data/node_modules/bootstrap/scss/helpers/_text-truncation.scss +7 -0
  228. data/node_modules/bootstrap/scss/helpers/_visually-hidden.scss +8 -0
  229. data/node_modules/bootstrap/scss/helpers/_vr.scss +8 -0
  230. data/node_modules/bootstrap/scss/mixins/_alert.scss +18 -0
  231. data/node_modules/bootstrap/scss/mixins/_backdrop.scss +14 -0
  232. data/node_modules/bootstrap/scss/mixins/_banner.scss +7 -0
  233. data/node_modules/bootstrap/scss/mixins/_border-radius.scss +78 -0
  234. data/node_modules/bootstrap/scss/mixins/_box-shadow.scss +24 -0
  235. data/node_modules/bootstrap/scss/mixins/_breakpoints.scss +127 -0
  236. data/node_modules/bootstrap/scss/mixins/_buttons.scss +70 -0
  237. data/node_modules/bootstrap/scss/mixins/_caret.scss +69 -0
  238. data/node_modules/bootstrap/scss/mixins/_clearfix.scss +9 -0
  239. data/node_modules/bootstrap/scss/mixins/_color-mode.scss +21 -0
  240. data/node_modules/bootstrap/scss/mixins/_color-scheme.scss +7 -0
  241. data/node_modules/bootstrap/scss/mixins/_container.scss +11 -0
  242. data/node_modules/bootstrap/scss/mixins/_deprecate.scss +10 -0
  243. data/node_modules/bootstrap/scss/mixins/_forms.scss +163 -0
  244. data/node_modules/bootstrap/scss/mixins/_gradients.scss +47 -0
  245. data/node_modules/bootstrap/scss/mixins/_grid.scss +151 -0
  246. data/node_modules/bootstrap/scss/mixins/_image.scss +16 -0
  247. data/node_modules/bootstrap/scss/mixins/_list-group.scss +26 -0
  248. data/node_modules/bootstrap/scss/mixins/_lists.scss +7 -0
  249. data/node_modules/bootstrap/scss/mixins/_pagination.scss +10 -0
  250. data/node_modules/bootstrap/scss/mixins/_reset-text.scss +17 -0
  251. data/node_modules/bootstrap/scss/mixins/_resize.scss +6 -0
  252. data/node_modules/bootstrap/scss/mixins/_table-variants.scss +24 -0
  253. data/node_modules/bootstrap/scss/mixins/_text-truncate.scss +8 -0
  254. data/node_modules/bootstrap/scss/mixins/_transition.scss +26 -0
  255. data/node_modules/bootstrap/scss/mixins/_utilities.scss +97 -0
  256. data/node_modules/bootstrap/scss/mixins/_visually-hidden.scss +38 -0
  257. data/node_modules/bootstrap/scss/utilities/_api.scss +47 -0
  258. data/node_modules/bootstrap/scss/vendor/_rfs.scss +348 -0
  259. metadata +448 -0
@@ -0,0 +1,633 @@
1
+ /**
2
+ * --------------------------------------------------------------------------
3
+ * Bootstrap tooltip.js
4
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5
+ * --------------------------------------------------------------------------
6
+ */
7
+
8
+ import * as Popper from '@popperjs/core'
9
+ import BaseComponent from './base-component.js'
10
+ import EventHandler from './dom/event-handler.js'
11
+ import Manipulator from './dom/manipulator.js'
12
+ import {
13
+ defineJQueryPlugin, execute, findShadowRoot, getElement, getUID, isRTL, noop
14
+ } from './util/index.js'
15
+ import { DefaultAllowlist } from './util/sanitizer.js'
16
+ import TemplateFactory from './util/template-factory.js'
17
+
18
+ /**
19
+ * Constants
20
+ */
21
+
22
+ const NAME = 'tooltip'
23
+ const DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn'])
24
+
25
+ const CLASS_NAME_FADE = 'fade'
26
+ const CLASS_NAME_MODAL = 'modal'
27
+ const CLASS_NAME_SHOW = 'show'
28
+
29
+ const SELECTOR_TOOLTIP_INNER = '.tooltip-inner'
30
+ const SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`
31
+
32
+ const EVENT_MODAL_HIDE = 'hide.bs.modal'
33
+
34
+ const TRIGGER_HOVER = 'hover'
35
+ const TRIGGER_FOCUS = 'focus'
36
+ const TRIGGER_CLICK = 'click'
37
+ const TRIGGER_MANUAL = 'manual'
38
+
39
+ const EVENT_HIDE = 'hide'
40
+ const EVENT_HIDDEN = 'hidden'
41
+ const EVENT_SHOW = 'show'
42
+ const EVENT_SHOWN = 'shown'
43
+ const EVENT_INSERTED = 'inserted'
44
+ const EVENT_CLICK = 'click'
45
+ const EVENT_FOCUSIN = 'focusin'
46
+ const EVENT_FOCUSOUT = 'focusout'
47
+ const EVENT_MOUSEENTER = 'mouseenter'
48
+ const EVENT_MOUSELEAVE = 'mouseleave'
49
+
50
+ const AttachmentMap = {
51
+ AUTO: 'auto',
52
+ TOP: 'top',
53
+ RIGHT: isRTL() ? 'left' : 'right',
54
+ BOTTOM: 'bottom',
55
+ LEFT: isRTL() ? 'right' : 'left'
56
+ }
57
+
58
+ const Default = {
59
+ allowList: DefaultAllowlist,
60
+ animation: true,
61
+ boundary: 'clippingParents',
62
+ container: false,
63
+ customClass: '',
64
+ delay: 0,
65
+ fallbackPlacements: ['top', 'right', 'bottom', 'left'],
66
+ html: false,
67
+ offset: [0, 6],
68
+ placement: 'top',
69
+ popperConfig: null,
70
+ sanitize: true,
71
+ sanitizeFn: null,
72
+ selector: false,
73
+ template: '<div class="tooltip" role="tooltip">' +
74
+ '<div class="tooltip-arrow"></div>' +
75
+ '<div class="tooltip-inner"></div>' +
76
+ '</div>',
77
+ title: '',
78
+ trigger: 'hover focus'
79
+ }
80
+
81
+ const DefaultType = {
82
+ allowList: 'object',
83
+ animation: 'boolean',
84
+ boundary: '(string|element)',
85
+ container: '(string|element|boolean)',
86
+ customClass: '(string|function)',
87
+ delay: '(number|object)',
88
+ fallbackPlacements: 'array',
89
+ html: 'boolean',
90
+ offset: '(array|string|function)',
91
+ placement: '(string|function)',
92
+ popperConfig: '(null|object|function)',
93
+ sanitize: 'boolean',
94
+ sanitizeFn: '(null|function)',
95
+ selector: '(string|boolean)',
96
+ template: 'string',
97
+ title: '(string|element|function)',
98
+ trigger: 'string'
99
+ }
100
+
101
+ /**
102
+ * Class definition
103
+ */
104
+
105
+ class Tooltip extends BaseComponent {
106
+ constructor(element, config) {
107
+ if (typeof Popper === 'undefined') {
108
+ throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org/docs/v2/)')
109
+ }
110
+
111
+ super(element, config)
112
+
113
+ // Private
114
+ this._isEnabled = true
115
+ this._timeout = 0
116
+ this._isHovered = null
117
+ this._activeTrigger = {}
118
+ this._popper = null
119
+ this._templateFactory = null
120
+ this._newContent = null
121
+
122
+ // Protected
123
+ this.tip = null
124
+
125
+ this._setListeners()
126
+
127
+ if (!this._config.selector) {
128
+ this._fixTitle()
129
+ }
130
+ }
131
+
132
+ // Getters
133
+ static get Default() {
134
+ return Default
135
+ }
136
+
137
+ static get DefaultType() {
138
+ return DefaultType
139
+ }
140
+
141
+ static get NAME() {
142
+ return NAME
143
+ }
144
+
145
+ // Public
146
+ enable() {
147
+ this._isEnabled = true
148
+ }
149
+
150
+ disable() {
151
+ this._isEnabled = false
152
+ }
153
+
154
+ toggleEnabled() {
155
+ this._isEnabled = !this._isEnabled
156
+ }
157
+
158
+ toggle() {
159
+ if (!this._isEnabled) {
160
+ return
161
+ }
162
+
163
+ if (this._isShown()) {
164
+ this._leave()
165
+ return
166
+ }
167
+
168
+ this._enter()
169
+ }
170
+
171
+ dispose() {
172
+ clearTimeout(this._timeout)
173
+
174
+ EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler)
175
+
176
+ if (this._element.getAttribute('data-bs-original-title')) {
177
+ this._element.setAttribute('title', this._element.getAttribute('data-bs-original-title'))
178
+ }
179
+
180
+ this._disposePopper()
181
+ super.dispose()
182
+ }
183
+
184
+ show() {
185
+ if (this._element.style.display === 'none') {
186
+ throw new Error('Please use show on visible elements')
187
+ }
188
+
189
+ if (!(this._isWithContent() && this._isEnabled)) {
190
+ return
191
+ }
192
+
193
+ const showEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOW))
194
+ const shadowRoot = findShadowRoot(this._element)
195
+ const isInTheDom = (shadowRoot || this._element.ownerDocument.documentElement).contains(this._element)
196
+
197
+ if (showEvent.defaultPrevented || !isInTheDom) {
198
+ return
199
+ }
200
+
201
+ // TODO: v6 remove this or make it optional
202
+ this._disposePopper()
203
+
204
+ const tip = this._getTipElement()
205
+
206
+ this._element.setAttribute('aria-describedby', tip.getAttribute('id'))
207
+
208
+ const { container } = this._config
209
+
210
+ if (!this._element.ownerDocument.documentElement.contains(this.tip)) {
211
+ container.append(tip)
212
+ EventHandler.trigger(this._element, this.constructor.eventName(EVENT_INSERTED))
213
+ }
214
+
215
+ this._popper = this._createPopper(tip)
216
+
217
+ tip.classList.add(CLASS_NAME_SHOW)
218
+
219
+ // If this is a touch-enabled device we add extra
220
+ // empty mouseover listeners to the body's immediate children;
221
+ // only needed because of broken event delegation on iOS
222
+ // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
223
+ if ('ontouchstart' in document.documentElement) {
224
+ for (const element of [].concat(...document.body.children)) {
225
+ EventHandler.on(element, 'mouseover', noop)
226
+ }
227
+ }
228
+
229
+ const complete = () => {
230
+ EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOWN))
231
+
232
+ if (this._isHovered === false) {
233
+ this._leave()
234
+ }
235
+
236
+ this._isHovered = false
237
+ }
238
+
239
+ this._queueCallback(complete, this.tip, this._isAnimated())
240
+ }
241
+
242
+ hide() {
243
+ if (!this._isShown()) {
244
+ return
245
+ }
246
+
247
+ const hideEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDE))
248
+ if (hideEvent.defaultPrevented) {
249
+ return
250
+ }
251
+
252
+ const tip = this._getTipElement()
253
+ tip.classList.remove(CLASS_NAME_SHOW)
254
+
255
+ // If this is a touch-enabled device we remove the extra
256
+ // empty mouseover listeners we added for iOS support
257
+ if ('ontouchstart' in document.documentElement) {
258
+ for (const element of [].concat(...document.body.children)) {
259
+ EventHandler.off(element, 'mouseover', noop)
260
+ }
261
+ }
262
+
263
+ this._activeTrigger[TRIGGER_CLICK] = false
264
+ this._activeTrigger[TRIGGER_FOCUS] = false
265
+ this._activeTrigger[TRIGGER_HOVER] = false
266
+ this._isHovered = null // it is a trick to support manual triggering
267
+
268
+ const complete = () => {
269
+ if (this._isWithActiveTrigger()) {
270
+ return
271
+ }
272
+
273
+ if (!this._isHovered) {
274
+ this._disposePopper()
275
+ }
276
+
277
+ this._element.removeAttribute('aria-describedby')
278
+ EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDDEN))
279
+ }
280
+
281
+ this._queueCallback(complete, this.tip, this._isAnimated())
282
+ }
283
+
284
+ update() {
285
+ if (this._popper) {
286
+ this._popper.update()
287
+ }
288
+ }
289
+
290
+ // Protected
291
+ _isWithContent() {
292
+ return Boolean(this._getTitle())
293
+ }
294
+
295
+ _getTipElement() {
296
+ if (!this.tip) {
297
+ this.tip = this._createTipElement(this._newContent || this._getContentForTemplate())
298
+ }
299
+
300
+ return this.tip
301
+ }
302
+
303
+ _createTipElement(content) {
304
+ const tip = this._getTemplateFactory(content).toHtml()
305
+
306
+ // TODO: remove this check in v6
307
+ if (!tip) {
308
+ return null
309
+ }
310
+
311
+ tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW)
312
+ // TODO: v6 the following can be achieved with CSS only
313
+ tip.classList.add(`bs-${this.constructor.NAME}-auto`)
314
+
315
+ const tipId = getUID(this.constructor.NAME).toString()
316
+
317
+ tip.setAttribute('id', tipId)
318
+
319
+ if (this._isAnimated()) {
320
+ tip.classList.add(CLASS_NAME_FADE)
321
+ }
322
+
323
+ return tip
324
+ }
325
+
326
+ setContent(content) {
327
+ this._newContent = content
328
+ if (this._isShown()) {
329
+ this._disposePopper()
330
+ this.show()
331
+ }
332
+ }
333
+
334
+ _getTemplateFactory(content) {
335
+ if (this._templateFactory) {
336
+ this._templateFactory.changeContent(content)
337
+ } else {
338
+ this._templateFactory = new TemplateFactory({
339
+ ...this._config,
340
+ // the `content` var has to be after `this._config`
341
+ // to override config.content in case of popover
342
+ content,
343
+ extraClass: this._resolvePossibleFunction(this._config.customClass)
344
+ })
345
+ }
346
+
347
+ return this._templateFactory
348
+ }
349
+
350
+ _getContentForTemplate() {
351
+ return {
352
+ [SELECTOR_TOOLTIP_INNER]: this._getTitle()
353
+ }
354
+ }
355
+
356
+ _getTitle() {
357
+ return this._resolvePossibleFunction(this._config.title) || this._element.getAttribute('data-bs-original-title')
358
+ }
359
+
360
+ // Private
361
+ _initializeOnDelegatedTarget(event) {
362
+ return this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig())
363
+ }
364
+
365
+ _isAnimated() {
366
+ return this._config.animation || (this.tip && this.tip.classList.contains(CLASS_NAME_FADE))
367
+ }
368
+
369
+ _isShown() {
370
+ return this.tip && this.tip.classList.contains(CLASS_NAME_SHOW)
371
+ }
372
+
373
+ _createPopper(tip) {
374
+ const placement = execute(this._config.placement, [this, tip, this._element])
375
+ const attachment = AttachmentMap[placement.toUpperCase()]
376
+ return Popper.createPopper(this._element, tip, this._getPopperConfig(attachment))
377
+ }
378
+
379
+ _getOffset() {
380
+ const { offset } = this._config
381
+
382
+ if (typeof offset === 'string') {
383
+ return offset.split(',').map(value => Number.parseInt(value, 10))
384
+ }
385
+
386
+ if (typeof offset === 'function') {
387
+ return popperData => offset(popperData, this._element)
388
+ }
389
+
390
+ return offset
391
+ }
392
+
393
+ _resolvePossibleFunction(arg) {
394
+ return execute(arg, [this._element, this._element])
395
+ }
396
+
397
+ _getPopperConfig(attachment) {
398
+ const defaultBsPopperConfig = {
399
+ placement: attachment,
400
+ modifiers: [
401
+ {
402
+ name: 'flip',
403
+ options: {
404
+ fallbackPlacements: this._config.fallbackPlacements
405
+ }
406
+ },
407
+ {
408
+ name: 'offset',
409
+ options: {
410
+ offset: this._getOffset()
411
+ }
412
+ },
413
+ {
414
+ name: 'preventOverflow',
415
+ options: {
416
+ boundary: this._config.boundary
417
+ }
418
+ },
419
+ {
420
+ name: 'arrow',
421
+ options: {
422
+ element: `.${this.constructor.NAME}-arrow`
423
+ }
424
+ },
425
+ {
426
+ name: 'preSetPlacement',
427
+ enabled: true,
428
+ phase: 'beforeMain',
429
+ fn: data => {
430
+ // Pre-set Popper's placement attribute in order to read the arrow sizes properly.
431
+ // Otherwise, Popper mixes up the width and height dimensions since the initial arrow style is for top placement
432
+ this._getTipElement().setAttribute('data-popper-placement', data.state.placement)
433
+ }
434
+ }
435
+ ]
436
+ }
437
+
438
+ return {
439
+ ...defaultBsPopperConfig,
440
+ ...execute(this._config.popperConfig, [undefined, defaultBsPopperConfig])
441
+ }
442
+ }
443
+
444
+ _setListeners() {
445
+ const triggers = this._config.trigger.split(' ')
446
+
447
+ for (const trigger of triggers) {
448
+ if (trigger === 'click') {
449
+ EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK), this._config.selector, event => {
450
+ const context = this._initializeOnDelegatedTarget(event)
451
+ context._activeTrigger[TRIGGER_CLICK] = !(context._isShown() && context._activeTrigger[TRIGGER_CLICK])
452
+ context.toggle()
453
+ })
454
+ } else if (trigger !== TRIGGER_MANUAL) {
455
+ const eventIn = trigger === TRIGGER_HOVER ?
456
+ this.constructor.eventName(EVENT_MOUSEENTER) :
457
+ this.constructor.eventName(EVENT_FOCUSIN)
458
+ const eventOut = trigger === TRIGGER_HOVER ?
459
+ this.constructor.eventName(EVENT_MOUSELEAVE) :
460
+ this.constructor.eventName(EVENT_FOCUSOUT)
461
+
462
+ EventHandler.on(this._element, eventIn, this._config.selector, event => {
463
+ const context = this._initializeOnDelegatedTarget(event)
464
+ context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true
465
+ context._enter()
466
+ })
467
+ EventHandler.on(this._element, eventOut, this._config.selector, event => {
468
+ const context = this._initializeOnDelegatedTarget(event)
469
+ context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] =
470
+ context._element.contains(event.relatedTarget)
471
+
472
+ context._leave()
473
+ })
474
+ }
475
+ }
476
+
477
+ this._hideModalHandler = () => {
478
+ if (this._element) {
479
+ this.hide()
480
+ }
481
+ }
482
+
483
+ EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler)
484
+ }
485
+
486
+ _fixTitle() {
487
+ const title = this._element.getAttribute('title')
488
+
489
+ if (!title) {
490
+ return
491
+ }
492
+
493
+ if (!this._element.getAttribute('aria-label') && !this._element.textContent.trim()) {
494
+ this._element.setAttribute('aria-label', title)
495
+ }
496
+
497
+ this._element.setAttribute('data-bs-original-title', title) // DO NOT USE IT. Is only for backwards compatibility
498
+ this._element.removeAttribute('title')
499
+ }
500
+
501
+ _enter() {
502
+ if (this._isShown() || this._isHovered) {
503
+ this._isHovered = true
504
+ return
505
+ }
506
+
507
+ this._isHovered = true
508
+
509
+ this._setTimeout(() => {
510
+ if (this._isHovered) {
511
+ this.show()
512
+ }
513
+ }, this._config.delay.show)
514
+ }
515
+
516
+ _leave() {
517
+ if (this._isWithActiveTrigger()) {
518
+ return
519
+ }
520
+
521
+ this._isHovered = false
522
+
523
+ this._setTimeout(() => {
524
+ if (!this._isHovered) {
525
+ this.hide()
526
+ }
527
+ }, this._config.delay.hide)
528
+ }
529
+
530
+ _setTimeout(handler, timeout) {
531
+ clearTimeout(this._timeout)
532
+ this._timeout = setTimeout(handler, timeout)
533
+ }
534
+
535
+ _isWithActiveTrigger() {
536
+ return Object.values(this._activeTrigger).includes(true)
537
+ }
538
+
539
+ _getConfig(config) {
540
+ const dataAttributes = Manipulator.getDataAttributes(this._element)
541
+
542
+ for (const dataAttribute of Object.keys(dataAttributes)) {
543
+ if (DISALLOWED_ATTRIBUTES.has(dataAttribute)) {
544
+ delete dataAttributes[dataAttribute]
545
+ }
546
+ }
547
+
548
+ config = {
549
+ ...dataAttributes,
550
+ ...(typeof config === 'object' && config ? config : {})
551
+ }
552
+ config = this._mergeConfigObj(config)
553
+ config = this._configAfterMerge(config)
554
+ this._typeCheckConfig(config)
555
+ return config
556
+ }
557
+
558
+ _configAfterMerge(config) {
559
+ config.container = config.container === false ? document.body : getElement(config.container)
560
+
561
+ if (typeof config.delay === 'number') {
562
+ config.delay = {
563
+ show: config.delay,
564
+ hide: config.delay
565
+ }
566
+ }
567
+
568
+ if (typeof config.title === 'number') {
569
+ config.title = config.title.toString()
570
+ }
571
+
572
+ if (typeof config.content === 'number') {
573
+ config.content = config.content.toString()
574
+ }
575
+
576
+ return config
577
+ }
578
+
579
+ _getDelegateConfig() {
580
+ const config = {}
581
+
582
+ for (const [key, value] of Object.entries(this._config)) {
583
+ if (this.constructor.Default[key] !== value) {
584
+ config[key] = value
585
+ }
586
+ }
587
+
588
+ config.selector = false
589
+ config.trigger = 'manual'
590
+
591
+ // In the future can be replaced with:
592
+ // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])
593
+ // `Object.fromEntries(keysWithDifferentValues)`
594
+ return config
595
+ }
596
+
597
+ _disposePopper() {
598
+ if (this._popper) {
599
+ this._popper.destroy()
600
+ this._popper = null
601
+ }
602
+
603
+ if (this.tip) {
604
+ this.tip.remove()
605
+ this.tip = null
606
+ }
607
+ }
608
+
609
+ // Static
610
+ static jQueryInterface(config) {
611
+ return this.each(function () {
612
+ const data = Tooltip.getOrCreateInstance(this, config)
613
+
614
+ if (typeof config !== 'string') {
615
+ return
616
+ }
617
+
618
+ if (typeof data[config] === 'undefined') {
619
+ throw new TypeError(`No method named "${config}"`)
620
+ }
621
+
622
+ data[config]()
623
+ })
624
+ }
625
+ }
626
+
627
+ /**
628
+ * jQuery
629
+ */
630
+
631
+ defineJQueryPlugin(Tooltip)
632
+
633
+ export default Tooltip