tooltip.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857
  1. /*!
  2. * Bootstrap tooltip.js v4.5.2 (https://getbootstrap.com/)
  3. * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
  4. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
  5. */
  6. (function (global, factory) {
  7. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('popper.js'), require('./util.js')) :
  8. typeof define === 'function' && define.amd ? define(['jquery', 'popper.js', './util.js'], factory) :
  9. (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Tooltip = factory(global.jQuery, global.Popper, global.Util));
  10. }(this, (function ($, Popper, Util) { 'use strict';
  11. $ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $;
  12. Popper = Popper && Object.prototype.hasOwnProperty.call(Popper, 'default') ? Popper['default'] : Popper;
  13. Util = Util && Object.prototype.hasOwnProperty.call(Util, 'default') ? Util['default'] : Util;
  14. /**
  15. * --------------------------------------------------------------------------
  16. * Bootstrap (v4.5.2): tools/sanitizer.js
  17. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
  18. * --------------------------------------------------------------------------
  19. */
  20. var uriAttrs = ['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href'];
  21. var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i;
  22. var DefaultWhitelist = {
  23. // Global attributes allowed on any supplied element below.
  24. '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
  25. a: ['target', 'href', 'title', 'rel'],
  26. area: [],
  27. b: [],
  28. br: [],
  29. col: [],
  30. code: [],
  31. div: [],
  32. em: [],
  33. hr: [],
  34. h1: [],
  35. h2: [],
  36. h3: [],
  37. h4: [],
  38. h5: [],
  39. h6: [],
  40. i: [],
  41. img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],
  42. li: [],
  43. ol: [],
  44. p: [],
  45. pre: [],
  46. s: [],
  47. small: [],
  48. span: [],
  49. sub: [],
  50. sup: [],
  51. strong: [],
  52. u: [],
  53. ul: []
  54. };
  55. /**
  56. * A pattern that recognizes a commonly useful subset of URLs that are safe.
  57. *
  58. * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
  59. */
  60. var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi;
  61. /**
  62. * A pattern that matches safe data URLs. Only matches image, video and audio types.
  63. *
  64. * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
  65. */
  66. var 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;
  67. function allowedAttribute(attr, allowedAttributeList) {
  68. var attrName = attr.nodeName.toLowerCase();
  69. if (allowedAttributeList.indexOf(attrName) !== -1) {
  70. if (uriAttrs.indexOf(attrName) !== -1) {
  71. return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN));
  72. }
  73. return true;
  74. }
  75. var regExp = allowedAttributeList.filter(function (attrRegex) {
  76. return attrRegex instanceof RegExp;
  77. }); // Check if a regular expression validates the attribute.
  78. for (var i = 0, len = regExp.length; i < len; i++) {
  79. if (attrName.match(regExp[i])) {
  80. return true;
  81. }
  82. }
  83. return false;
  84. }
  85. function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {
  86. if (unsafeHtml.length === 0) {
  87. return unsafeHtml;
  88. }
  89. if (sanitizeFn && typeof sanitizeFn === 'function') {
  90. return sanitizeFn(unsafeHtml);
  91. }
  92. var domParser = new window.DOMParser();
  93. var createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');
  94. var whitelistKeys = Object.keys(whiteList);
  95. var elements = [].slice.call(createdDocument.body.querySelectorAll('*'));
  96. var _loop = function _loop(i, len) {
  97. var el = elements[i];
  98. var elName = el.nodeName.toLowerCase();
  99. if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) {
  100. el.parentNode.removeChild(el);
  101. return "continue";
  102. }
  103. var attributeList = [].slice.call(el.attributes);
  104. var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []);
  105. attributeList.forEach(function (attr) {
  106. if (!allowedAttribute(attr, whitelistedAttributes)) {
  107. el.removeAttribute(attr.nodeName);
  108. }
  109. });
  110. };
  111. for (var i = 0, len = elements.length; i < len; i++) {
  112. var _ret = _loop(i);
  113. if (_ret === "continue") continue;
  114. }
  115. return createdDocument.body.innerHTML;
  116. }
  117. function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
  118. function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  119. function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
  120. /**
  121. * ------------------------------------------------------------------------
  122. * Constants
  123. * ------------------------------------------------------------------------
  124. */
  125. var NAME = 'tooltip';
  126. var VERSION = '4.5.2';
  127. var DATA_KEY = 'bs.tooltip';
  128. var EVENT_KEY = "." + DATA_KEY;
  129. var JQUERY_NO_CONFLICT = $.fn[NAME];
  130. var CLASS_PREFIX = 'bs-tooltip';
  131. var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g');
  132. var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn'];
  133. var DefaultType = {
  134. animation: 'boolean',
  135. template: 'string',
  136. title: '(string|element|function)',
  137. trigger: 'string',
  138. delay: '(number|object)',
  139. html: 'boolean',
  140. selector: '(string|boolean)',
  141. placement: '(string|function)',
  142. offset: '(number|string|function)',
  143. container: '(string|element|boolean)',
  144. fallbackPlacement: '(string|array)',
  145. boundary: '(string|element)',
  146. sanitize: 'boolean',
  147. sanitizeFn: '(null|function)',
  148. whiteList: 'object',
  149. popperConfig: '(null|object)'
  150. };
  151. var AttachmentMap = {
  152. AUTO: 'auto',
  153. TOP: 'top',
  154. RIGHT: 'right',
  155. BOTTOM: 'bottom',
  156. LEFT: 'left'
  157. };
  158. var Default = {
  159. animation: true,
  160. template: '<div class="tooltip" role="tooltip">' + '<div class="arrow"></div>' + '<div class="tooltip-inner"></div></div>',
  161. trigger: 'hover focus',
  162. title: '',
  163. delay: 0,
  164. html: false,
  165. selector: false,
  166. placement: 'top',
  167. offset: 0,
  168. container: false,
  169. fallbackPlacement: 'flip',
  170. boundary: 'scrollParent',
  171. sanitize: true,
  172. sanitizeFn: null,
  173. whiteList: DefaultWhitelist,
  174. popperConfig: null
  175. };
  176. var HOVER_STATE_SHOW = 'show';
  177. var HOVER_STATE_OUT = 'out';
  178. var Event = {
  179. HIDE: "hide" + EVENT_KEY,
  180. HIDDEN: "hidden" + EVENT_KEY,
  181. SHOW: "show" + EVENT_KEY,
  182. SHOWN: "shown" + EVENT_KEY,
  183. INSERTED: "inserted" + EVENT_KEY,
  184. CLICK: "click" + EVENT_KEY,
  185. FOCUSIN: "focusin" + EVENT_KEY,
  186. FOCUSOUT: "focusout" + EVENT_KEY,
  187. MOUSEENTER: "mouseenter" + EVENT_KEY,
  188. MOUSELEAVE: "mouseleave" + EVENT_KEY
  189. };
  190. var CLASS_NAME_FADE = 'fade';
  191. var CLASS_NAME_SHOW = 'show';
  192. var SELECTOR_TOOLTIP_INNER = '.tooltip-inner';
  193. var SELECTOR_ARROW = '.arrow';
  194. var TRIGGER_HOVER = 'hover';
  195. var TRIGGER_FOCUS = 'focus';
  196. var TRIGGER_CLICK = 'click';
  197. var TRIGGER_MANUAL = 'manual';
  198. /**
  199. * ------------------------------------------------------------------------
  200. * Class Definition
  201. * ------------------------------------------------------------------------
  202. */
  203. var Tooltip = /*#__PURE__*/function () {
  204. function Tooltip(element, config) {
  205. if (typeof Popper === 'undefined') {
  206. throw new TypeError('Bootstrap\'s tooltips require Popper.js (https://popper.js.org/)');
  207. } // private
  208. this._isEnabled = true;
  209. this._timeout = 0;
  210. this._hoverState = '';
  211. this._activeTrigger = {};
  212. this._popper = null; // Protected
  213. this.element = element;
  214. this.config = this._getConfig(config);
  215. this.tip = null;
  216. this._setListeners();
  217. } // Getters
  218. var _proto = Tooltip.prototype;
  219. // Public
  220. _proto.enable = function enable() {
  221. this._isEnabled = true;
  222. };
  223. _proto.disable = function disable() {
  224. this._isEnabled = false;
  225. };
  226. _proto.toggleEnabled = function toggleEnabled() {
  227. this._isEnabled = !this._isEnabled;
  228. };
  229. _proto.toggle = function toggle(event) {
  230. if (!this._isEnabled) {
  231. return;
  232. }
  233. if (event) {
  234. var dataKey = this.constructor.DATA_KEY;
  235. var context = $(event.currentTarget).data(dataKey);
  236. if (!context) {
  237. context = new this.constructor(event.currentTarget, this._getDelegateConfig());
  238. $(event.currentTarget).data(dataKey, context);
  239. }
  240. context._activeTrigger.click = !context._activeTrigger.click;
  241. if (context._isWithActiveTrigger()) {
  242. context._enter(null, context);
  243. } else {
  244. context._leave(null, context);
  245. }
  246. } else {
  247. if ($(this.getTipElement()).hasClass(CLASS_NAME_SHOW)) {
  248. this._leave(null, this);
  249. return;
  250. }
  251. this._enter(null, this);
  252. }
  253. };
  254. _proto.dispose = function dispose() {
  255. clearTimeout(this._timeout);
  256. $.removeData(this.element, this.constructor.DATA_KEY);
  257. $(this.element).off(this.constructor.EVENT_KEY);
  258. $(this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler);
  259. if (this.tip) {
  260. $(this.tip).remove();
  261. }
  262. this._isEnabled = null;
  263. this._timeout = null;
  264. this._hoverState = null;
  265. this._activeTrigger = null;
  266. if (this._popper) {
  267. this._popper.destroy();
  268. }
  269. this._popper = null;
  270. this.element = null;
  271. this.config = null;
  272. this.tip = null;
  273. };
  274. _proto.show = function show() {
  275. var _this = this;
  276. if ($(this.element).css('display') === 'none') {
  277. throw new Error('Please use show on visible elements');
  278. }
  279. var showEvent = $.Event(this.constructor.Event.SHOW);
  280. if (this.isWithContent() && this._isEnabled) {
  281. $(this.element).trigger(showEvent);
  282. var shadowRoot = Util.findShadowRoot(this.element);
  283. var isInTheDom = $.contains(shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement, this.element);
  284. if (showEvent.isDefaultPrevented() || !isInTheDom) {
  285. return;
  286. }
  287. var tip = this.getTipElement();
  288. var tipId = Util.getUID(this.constructor.NAME);
  289. tip.setAttribute('id', tipId);
  290. this.element.setAttribute('aria-describedby', tipId);
  291. this.setContent();
  292. if (this.config.animation) {
  293. $(tip).addClass(CLASS_NAME_FADE);
  294. }
  295. var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement;
  296. var attachment = this._getAttachment(placement);
  297. this.addAttachmentClass(attachment);
  298. var container = this._getContainer();
  299. $(tip).data(this.constructor.DATA_KEY, this);
  300. if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {
  301. $(tip).appendTo(container);
  302. }
  303. $(this.element).trigger(this.constructor.Event.INSERTED);
  304. this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment));
  305. $(tip).addClass(CLASS_NAME_SHOW); // If this is a touch-enabled device we add extra
  306. // empty mouseover listeners to the body's immediate children;
  307. // only needed because of broken event delegation on iOS
  308. // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
  309. if ('ontouchstart' in document.documentElement) {
  310. $(document.body).children().on('mouseover', null, $.noop);
  311. }
  312. var complete = function complete() {
  313. if (_this.config.animation) {
  314. _this._fixTransition();
  315. }
  316. var prevHoverState = _this._hoverState;
  317. _this._hoverState = null;
  318. $(_this.element).trigger(_this.constructor.Event.SHOWN);
  319. if (prevHoverState === HOVER_STATE_OUT) {
  320. _this._leave(null, _this);
  321. }
  322. };
  323. if ($(this.tip).hasClass(CLASS_NAME_FADE)) {
  324. var transitionDuration = Util.getTransitionDurationFromElement(this.tip);
  325. $(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
  326. } else {
  327. complete();
  328. }
  329. }
  330. };
  331. _proto.hide = function hide(callback) {
  332. var _this2 = this;
  333. var tip = this.getTipElement();
  334. var hideEvent = $.Event(this.constructor.Event.HIDE);
  335. var complete = function complete() {
  336. if (_this2._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {
  337. tip.parentNode.removeChild(tip);
  338. }
  339. _this2._cleanTipClass();
  340. _this2.element.removeAttribute('aria-describedby');
  341. $(_this2.element).trigger(_this2.constructor.Event.HIDDEN);
  342. if (_this2._popper !== null) {
  343. _this2._popper.destroy();
  344. }
  345. if (callback) {
  346. callback();
  347. }
  348. };
  349. $(this.element).trigger(hideEvent);
  350. if (hideEvent.isDefaultPrevented()) {
  351. return;
  352. }
  353. $(tip).removeClass(CLASS_NAME_SHOW); // If this is a touch-enabled device we remove the extra
  354. // empty mouseover listeners we added for iOS support
  355. if ('ontouchstart' in document.documentElement) {
  356. $(document.body).children().off('mouseover', null, $.noop);
  357. }
  358. this._activeTrigger[TRIGGER_CLICK] = false;
  359. this._activeTrigger[TRIGGER_FOCUS] = false;
  360. this._activeTrigger[TRIGGER_HOVER] = false;
  361. if ($(this.tip).hasClass(CLASS_NAME_FADE)) {
  362. var transitionDuration = Util.getTransitionDurationFromElement(tip);
  363. $(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
  364. } else {
  365. complete();
  366. }
  367. this._hoverState = '';
  368. };
  369. _proto.update = function update() {
  370. if (this._popper !== null) {
  371. this._popper.scheduleUpdate();
  372. }
  373. } // Protected
  374. ;
  375. _proto.isWithContent = function isWithContent() {
  376. return Boolean(this.getTitle());
  377. };
  378. _proto.addAttachmentClass = function addAttachmentClass(attachment) {
  379. $(this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment);
  380. };
  381. _proto.getTipElement = function getTipElement() {
  382. this.tip = this.tip || $(this.config.template)[0];
  383. return this.tip;
  384. };
  385. _proto.setContent = function setContent() {
  386. var tip = this.getTipElement();
  387. this.setElementContent($(tip.querySelectorAll(SELECTOR_TOOLTIP_INNER)), this.getTitle());
  388. $(tip).removeClass(CLASS_NAME_FADE + " " + CLASS_NAME_SHOW);
  389. };
  390. _proto.setElementContent = function setElementContent($element, content) {
  391. if (typeof content === 'object' && (content.nodeType || content.jquery)) {
  392. // Content is a DOM node or a jQuery
  393. if (this.config.html) {
  394. if (!$(content).parent().is($element)) {
  395. $element.empty().append(content);
  396. }
  397. } else {
  398. $element.text($(content).text());
  399. }
  400. return;
  401. }
  402. if (this.config.html) {
  403. if (this.config.sanitize) {
  404. content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn);
  405. }
  406. $element.html(content);
  407. } else {
  408. $element.text(content);
  409. }
  410. };
  411. _proto.getTitle = function getTitle() {
  412. var title = this.element.getAttribute('data-original-title');
  413. if (!title) {
  414. title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title;
  415. }
  416. return title;
  417. } // Private
  418. ;
  419. _proto._getPopperConfig = function _getPopperConfig(attachment) {
  420. var _this3 = this;
  421. var defaultBsConfig = {
  422. placement: attachment,
  423. modifiers: {
  424. offset: this._getOffset(),
  425. flip: {
  426. behavior: this.config.fallbackPlacement
  427. },
  428. arrow: {
  429. element: SELECTOR_ARROW
  430. },
  431. preventOverflow: {
  432. boundariesElement: this.config.boundary
  433. }
  434. },
  435. onCreate: function onCreate(data) {
  436. if (data.originalPlacement !== data.placement) {
  437. _this3._handlePopperPlacementChange(data);
  438. }
  439. },
  440. onUpdate: function onUpdate(data) {
  441. return _this3._handlePopperPlacementChange(data);
  442. }
  443. };
  444. return _extends({}, defaultBsConfig, this.config.popperConfig);
  445. };
  446. _proto._getOffset = function _getOffset() {
  447. var _this4 = this;
  448. var offset = {};
  449. if (typeof this.config.offset === 'function') {
  450. offset.fn = function (data) {
  451. data.offsets = _extends({}, data.offsets, _this4.config.offset(data.offsets, _this4.element) || {});
  452. return data;
  453. };
  454. } else {
  455. offset.offset = this.config.offset;
  456. }
  457. return offset;
  458. };
  459. _proto._getContainer = function _getContainer() {
  460. if (this.config.container === false) {
  461. return document.body;
  462. }
  463. if (Util.isElement(this.config.container)) {
  464. return $(this.config.container);
  465. }
  466. return $(document).find(this.config.container);
  467. };
  468. _proto._getAttachment = function _getAttachment(placement) {
  469. return AttachmentMap[placement.toUpperCase()];
  470. };
  471. _proto._setListeners = function _setListeners() {
  472. var _this5 = this;
  473. var triggers = this.config.trigger.split(' ');
  474. triggers.forEach(function (trigger) {
  475. if (trigger === 'click') {
  476. $(_this5.element).on(_this5.constructor.Event.CLICK, _this5.config.selector, function (event) {
  477. return _this5.toggle(event);
  478. });
  479. } else if (trigger !== TRIGGER_MANUAL) {
  480. var eventIn = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSEENTER : _this5.constructor.Event.FOCUSIN;
  481. var eventOut = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSELEAVE : _this5.constructor.Event.FOCUSOUT;
  482. $(_this5.element).on(eventIn, _this5.config.selector, function (event) {
  483. return _this5._enter(event);
  484. }).on(eventOut, _this5.config.selector, function (event) {
  485. return _this5._leave(event);
  486. });
  487. }
  488. });
  489. this._hideModalHandler = function () {
  490. if (_this5.element) {
  491. _this5.hide();
  492. }
  493. };
  494. $(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler);
  495. if (this.config.selector) {
  496. this.config = _extends({}, this.config, {
  497. trigger: 'manual',
  498. selector: ''
  499. });
  500. } else {
  501. this._fixTitle();
  502. }
  503. };
  504. _proto._fixTitle = function _fixTitle() {
  505. var titleType = typeof this.element.getAttribute('data-original-title');
  506. if (this.element.getAttribute('title') || titleType !== 'string') {
  507. this.element.setAttribute('data-original-title', this.element.getAttribute('title') || '');
  508. this.element.setAttribute('title', '');
  509. }
  510. };
  511. _proto._enter = function _enter(event, context) {
  512. var dataKey = this.constructor.DATA_KEY;
  513. context = context || $(event.currentTarget).data(dataKey);
  514. if (!context) {
  515. context = new this.constructor(event.currentTarget, this._getDelegateConfig());
  516. $(event.currentTarget).data(dataKey, context);
  517. }
  518. if (event) {
  519. context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true;
  520. }
  521. if ($(context.getTipElement()).hasClass(CLASS_NAME_SHOW) || context._hoverState === HOVER_STATE_SHOW) {
  522. context._hoverState = HOVER_STATE_SHOW;
  523. return;
  524. }
  525. clearTimeout(context._timeout);
  526. context._hoverState = HOVER_STATE_SHOW;
  527. if (!context.config.delay || !context.config.delay.show) {
  528. context.show();
  529. return;
  530. }
  531. context._timeout = setTimeout(function () {
  532. if (context._hoverState === HOVER_STATE_SHOW) {
  533. context.show();
  534. }
  535. }, context.config.delay.show);
  536. };
  537. _proto._leave = function _leave(event, context) {
  538. var dataKey = this.constructor.DATA_KEY;
  539. context = context || $(event.currentTarget).data(dataKey);
  540. if (!context) {
  541. context = new this.constructor(event.currentTarget, this._getDelegateConfig());
  542. $(event.currentTarget).data(dataKey, context);
  543. }
  544. if (event) {
  545. context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = false;
  546. }
  547. if (context._isWithActiveTrigger()) {
  548. return;
  549. }
  550. clearTimeout(context._timeout);
  551. context._hoverState = HOVER_STATE_OUT;
  552. if (!context.config.delay || !context.config.delay.hide) {
  553. context.hide();
  554. return;
  555. }
  556. context._timeout = setTimeout(function () {
  557. if (context._hoverState === HOVER_STATE_OUT) {
  558. context.hide();
  559. }
  560. }, context.config.delay.hide);
  561. };
  562. _proto._isWithActiveTrigger = function _isWithActiveTrigger() {
  563. for (var trigger in this._activeTrigger) {
  564. if (this._activeTrigger[trigger]) {
  565. return true;
  566. }
  567. }
  568. return false;
  569. };
  570. _proto._getConfig = function _getConfig(config) {
  571. var dataAttributes = $(this.element).data();
  572. Object.keys(dataAttributes).forEach(function (dataAttr) {
  573. if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) {
  574. delete dataAttributes[dataAttr];
  575. }
  576. });
  577. config = _extends({}, this.constructor.Default, dataAttributes, typeof config === 'object' && config ? config : {});
  578. if (typeof config.delay === 'number') {
  579. config.delay = {
  580. show: config.delay,
  581. hide: config.delay
  582. };
  583. }
  584. if (typeof config.title === 'number') {
  585. config.title = config.title.toString();
  586. }
  587. if (typeof config.content === 'number') {
  588. config.content = config.content.toString();
  589. }
  590. Util.typeCheckConfig(NAME, config, this.constructor.DefaultType);
  591. if (config.sanitize) {
  592. config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn);
  593. }
  594. return config;
  595. };
  596. _proto._getDelegateConfig = function _getDelegateConfig() {
  597. var config = {};
  598. if (this.config) {
  599. for (var key in this.config) {
  600. if (this.constructor.Default[key] !== this.config[key]) {
  601. config[key] = this.config[key];
  602. }
  603. }
  604. }
  605. return config;
  606. };
  607. _proto._cleanTipClass = function _cleanTipClass() {
  608. var $tip = $(this.getTipElement());
  609. var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX);
  610. if (tabClass !== null && tabClass.length) {
  611. $tip.removeClass(tabClass.join(''));
  612. }
  613. };
  614. _proto._handlePopperPlacementChange = function _handlePopperPlacementChange(popperData) {
  615. this.tip = popperData.instance.popper;
  616. this._cleanTipClass();
  617. this.addAttachmentClass(this._getAttachment(popperData.placement));
  618. };
  619. _proto._fixTransition = function _fixTransition() {
  620. var tip = this.getTipElement();
  621. var initConfigAnimation = this.config.animation;
  622. if (tip.getAttribute('x-placement') !== null) {
  623. return;
  624. }
  625. $(tip).removeClass(CLASS_NAME_FADE);
  626. this.config.animation = false;
  627. this.hide();
  628. this.show();
  629. this.config.animation = initConfigAnimation;
  630. } // Static
  631. ;
  632. Tooltip._jQueryInterface = function _jQueryInterface(config) {
  633. return this.each(function () {
  634. var data = $(this).data(DATA_KEY);
  635. var _config = typeof config === 'object' && config;
  636. if (!data && /dispose|hide/.test(config)) {
  637. return;
  638. }
  639. if (!data) {
  640. data = new Tooltip(this, _config);
  641. $(this).data(DATA_KEY, data);
  642. }
  643. if (typeof config === 'string') {
  644. if (typeof data[config] === 'undefined') {
  645. throw new TypeError("No method named \"" + config + "\"");
  646. }
  647. data[config]();
  648. }
  649. });
  650. };
  651. _createClass(Tooltip, null, [{
  652. key: "VERSION",
  653. get: function get() {
  654. return VERSION;
  655. }
  656. }, {
  657. key: "Default",
  658. get: function get() {
  659. return Default;
  660. }
  661. }, {
  662. key: "NAME",
  663. get: function get() {
  664. return NAME;
  665. }
  666. }, {
  667. key: "DATA_KEY",
  668. get: function get() {
  669. return DATA_KEY;
  670. }
  671. }, {
  672. key: "Event",
  673. get: function get() {
  674. return Event;
  675. }
  676. }, {
  677. key: "EVENT_KEY",
  678. get: function get() {
  679. return EVENT_KEY;
  680. }
  681. }, {
  682. key: "DefaultType",
  683. get: function get() {
  684. return DefaultType;
  685. }
  686. }]);
  687. return Tooltip;
  688. }();
  689. /**
  690. * ------------------------------------------------------------------------
  691. * jQuery
  692. * ------------------------------------------------------------------------
  693. */
  694. $.fn[NAME] = Tooltip._jQueryInterface;
  695. $.fn[NAME].Constructor = Tooltip;
  696. $.fn[NAME].noConflict = function () {
  697. $.fn[NAME] = JQUERY_NO_CONFLICT;
  698. return Tooltip._jQueryInterface;
  699. };
  700. return Tooltip;
  701. })));
  702. //# sourceMappingURL=tooltip.js.map