JAVASCRIPT   12

tooltip

Guest on 6th July 2022 01:04:21 AM

  1. /**
  2.  * --------------------------------------------------------------------------
  3.  * Bootstrap (v4.3.1): tooltip.js
  4.  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  5.  * --------------------------------------------------------------------------
  6.  */
  7.  
  8. import {
  9.   DefaultWhitelist,
  10.   sanitizeHtml
  11. } from './tools/sanitizer'
  12. import $ from 'jquery'
  13. import Popper from 'popper.js'
  14. import Util from './util'
  15.  
  16. /**
  17.  * ------------------------------------------------------------------------
  18.  * Constants
  19.  * ------------------------------------------------------------------------
  20.  */
  21.  
  22. const NAME                  = 'tooltip'
  23. const VERSION               = '4.3.1'
  24. const DATA_KEY              = 'bs.tooltip'
  25. const EVENT_KEY             = `.${DATA_KEY}`
  26. const JQUERY_NO_CONFLICT    = $.fn[NAME]
  27. const CLASS_PREFIX          = 'bs-tooltip'
  28. const BSCLS_PREFIX_REGEX    = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g')
  29. const DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']
  30.  
  31. const DefaultType = {
  32.   animation         : 'boolean',
  33.   template          : 'string',
  34.   title             : '(string|element|function)',
  35.   trigger           : 'string',
  36.   delay             : '(number|object)',
  37.   html              : 'boolean',
  38.   selector          : '(string|boolean)',
  39.   placement         : '(string|function)',
  40.   offset            : '(number|string|function)',
  41.   container         : '(string|element|boolean)',
  42.   fallbackPlacement : '(string|array)',
  43.   boundary          : '(string|element)',
  44.   sanitize          : 'boolean',
  45.   sanitizeFn        : '(null|function)',
  46.   whiteList         : 'object'
  47. }
  48.  
  49. const AttachmentMap = {
  50.   AUTO   : 'auto',
  51.   TOP    : 'top',
  52.   RIGHT  : 'right',
  53.   BOTTOM : 'bottom',
  54.   LEFT   : 'left'
  55. }
  56.  
  57. const Default = {
  58.   animation         : true,
  59.   template          : '<div class="tooltip" role="tooltip">' +
  60.                     '<div class="arrow"></div>' +
  61.                     '<div class="tooltip-inner"></div></div>',
  62.   trigger           : 'hover focus',
  63.   title             : '',
  64.   delay             : 0,
  65.   html              : false,
  66.   selector          : false,
  67.   placement         : 'top',
  68.   offset            : 0,
  69.   container         : false,
  70.   fallbackPlacement : 'flip',
  71.   boundary          : 'scrollParent',
  72.   sanitize          : true,
  73.   sanitizeFn        : null,
  74.   whiteList         : DefaultWhitelist
  75. }
  76.  
  77. const HoverState = {
  78.   SHOW : 'show',
  79.   OUT  : 'out'
  80. }
  81.  
  82. const Event = {
  83.   HIDE       : `hide${EVENT_KEY}`,
  84.   HIDDEN     : `hidden${EVENT_KEY}`,
  85.   SHOW       : `show${EVENT_KEY}`,
  86.   SHOWN      : `shown${EVENT_KEY}`,
  87.   INSERTED   : `inserted${EVENT_KEY}`,
  88.   CLICK      : `click${EVENT_KEY}`,
  89.   FOCUSIN    : `focusin${EVENT_KEY}`,
  90.   FOCUSOUT   : `focusout${EVENT_KEY}`,
  91.   MOUSEENTER : `mouseenter${EVENT_KEY}`,
  92.   MOUSELEAVE : `mouseleave${EVENT_KEY}`
  93. }
  94.  
  95. const ClassName = {
  96.   FADE : 'fade',
  97.   SHOW : 'show'
  98. }
  99.  
  100. const Selector = {
  101.   TOOLTIP       : '.tooltip',
  102.   TOOLTIP_INNER : '.tooltip-inner',
  103.   ARROW         : '.arrow'
  104. }
  105.  
  106. const Trigger = {
  107.   HOVER  : 'hover',
  108.   FOCUS  : 'focus',
  109.   CLICK  : 'click',
  110.   MANUAL : 'manual'
  111. }
  112.  
  113.  
  114. /**
  115.  * ------------------------------------------------------------------------
  116.  * Class Definition
  117.  * ------------------------------------------------------------------------
  118.  */
  119.  
  120. class Tooltip {
  121.   constructor(element, config) {
  122.     /**
  123.      * Check for Popper dependency
  124.      * Popper - https://popper.js.org
  125.      */
  126.     if (typeof Popper === 'undefined') {
  127.       throw new TypeError('Bootstrap\'s tooltips require Popper.js (https://popper.js.org/)')
  128.     }
  129.  
  130.     // private
  131.     this._isEnabled     = true
  132.     this._timeout       = 0
  133.     this._hoverState    = ''
  134.     this._activeTrigger = {}
  135.     this._popper        = null
  136.  
  137.     // Protected
  138.     this.element = element
  139.     this.config  = this._getConfig(config)
  140.     this.tip     = null
  141.  
  142.     this._setListeners()
  143.   }
  144.  
  145.   // Getters
  146.  
  147.   static get VERSION() {
  148.     return VERSION
  149.   }
  150.  
  151.   static get Default() {
  152.     return Default
  153.   }
  154.  
  155.   static get NAME() {
  156.     return NAME
  157.   }
  158.  
  159.   static get DATA_KEY() {
  160.     return DATA_KEY
  161.   }
  162.  
  163.   static get Event() {
  164.     return Event
  165.   }
  166.  
  167.   static get EVENT_KEY() {
  168.     return EVENT_KEY
  169.   }
  170.  
  171.   static get DefaultType() {
  172.     return DefaultType
  173.   }
  174.  
  175.   // Public
  176.  
  177.   enable() {
  178.     this._isEnabled = true
  179.   }
  180.  
  181.   disable() {
  182.     this._isEnabled = false
  183.   }
  184.  
  185.   toggleEnabled() {
  186.     this._isEnabled = !this._isEnabled
  187.   }
  188.  
  189.   toggle(event) {
  190.     if (!this._isEnabled) {
  191.       return
  192.     }
  193.  
  194.     if (event) {
  195.       const dataKey = this.constructor.DATA_KEY
  196.       let context = $(event.currentTarget).data(dataKey)
  197.  
  198.       if (!context) {
  199.         context = new this.constructor(
  200.           event.currentTarget,
  201.           this._getDelegateConfig()
  202.         )
  203.         $(event.currentTarget).data(dataKey, context)
  204.       }
  205.  
  206.       context._activeTrigger.click = !context._activeTrigger.click
  207.  
  208.       if (context._isWithActiveTrigger()) {
  209.         context._enter(null, context)
  210.       } else {
  211.         context._leave(null, context)
  212.       }
  213.     } else {
  214.       if ($(this.getTipElement()).hasClass(ClassName.SHOW)) {
  215.         this._leave(null, this)
  216.         return
  217.       }
  218.  
  219.       this._enter(null, this)
  220.     }
  221.   }
  222.  
  223.   dispose() {
  224.     clearTimeout(this._timeout)
  225.  
  226.     $.removeData(this.element, this.constructor.DATA_KEY)
  227.  
  228.     $(this.element).off(this.constructor.EVENT_KEY)
  229.     $(this.element).closest('.modal').off('hide.bs.modal')
  230.  
  231.     if (this.tip) {
  232.       $(this.tip).remove()
  233.     }
  234.  
  235.     this._isEnabled     = null
  236.     this._timeout       = null
  237.     this._hoverState    = null
  238.     this._activeTrigger = null
  239.     if (this._popper !== null) {
  240.       this._popper.destroy()
  241.     }
  242.  
  243.     this._popper = null
  244.     this.element = null
  245.     this.config  = null
  246.     this.tip     = null
  247.   }
  248.  
  249.   show() {
  250.     if ($(this.element).css('display') === 'none') {
  251.       throw new Error('Please use show on visible elements')
  252.     }
  253.  
  254.     const showEvent = $.Event(this.constructor.Event.SHOW)
  255.     if (this.isWithContent() && this._isEnabled) {
  256.       $(this.element).trigger(showEvent)
  257.  
  258.       const shadowRoot = Util.findShadowRoot(this.element)
  259.       const isInTheDom = $.contains(
  260.         shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement,
  261.         this.element
  262.       )
  263.  
  264.       if (showEvent.isDefaultPrevented() || !isInTheDom) {
  265.         return
  266.       }
  267.  
  268.       const tip   = this.getTipElement()
  269.       const tipId = Util.getUID(this.constructor.NAME)
  270.  
  271.       tip.setAttribute('id', tipId)
  272.       this.element.setAttribute('aria-describedby', tipId)
  273.  
  274.       this.setContent()
  275.  
  276.       if (this.config.animation) {
  277.         $(tip).addClass(ClassName.FADE)
  278.       }
  279.  
  280.       const placement  = typeof this.config.placement === 'function'
  281.         ? this.config.placement.call(this, tip, this.element)
  282.         : this.config.placement
  283.  
  284.       const attachment = this._getAttachment(placement)
  285.       this.addAttachmentClass(attachment)
  286.  
  287.       const container = this._getContainer()
  288.       $(tip).data(this.constructor.DATA_KEY, this)
  289.  
  290.       if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {
  291.         $(tip).appendTo(container)
  292.       }
  293.  
  294.       $(this.element).trigger(this.constructor.Event.INSERTED)
  295.  
  296.       this._popper = new Popper(this.element, tip, {
  297.         placement: attachment,
  298.         modifiers: {
  299.           offset: this._getOffset(),
  300.           flip: {
  301.             behavior: this.config.fallbackPlacement
  302.           },
  303.           arrow: {
  304.             element: Selector.ARROW
  305.           },
  306.           preventOverflow: {
  307.             boundariesElement: this.config.boundary
  308.           }
  309.         },
  310.         onCreate: (data) => {
  311.           if (data.originalPlacement !== data.placement) {
  312.             this._handlePopperPlacementChange(data)
  313.           }
  314.         },
  315.         onUpdate: (data) => this._handlePopperPlacementChange(data)
  316.       })
  317.  
  318.       $(tip).addClass(ClassName.SHOW)
  319.  
  320.       // If this is a touch-enabled device we add extra
  321.       // empty mouseover listeners to the body's immediate children;
  322.       // only needed because of broken event delegation on iOS
  323.       // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
  324.       if ('ontouchstart' in document.documentElement) {
  325.         $(document.body).children().on('mouseover', null, $.noop)
  326.       }
  327.  
  328.       const complete = () => {
  329.         if (this.config.animation) {
  330.           this._fixTransition()
  331.         }
  332.         const prevHoverState = this._hoverState
  333.         this._hoverState     = null
  334.  
  335.         $(this.element).trigger(this.constructor.Event.SHOWN)
  336.  
  337.         if (prevHoverState === HoverState.OUT) {
  338.           this._leave(null, this)
  339.         }
  340.       }
  341.  
  342.       if ($(this.tip).hasClass(ClassName.FADE)) {
  343.         const transitionDuration = Util.getTransitionDurationFromElement(this.tip)
  344.  
  345.         $(this.tip)
  346.           .one(Util.TRANSITION_END, complete)
  347.           .emulateTransitionEnd(transitionDuration)
  348.       } else {
  349.         complete()
  350.       }
  351.     }
  352.   }
  353.  
  354.   hide(callback) {
  355.     const tip       = this.getTipElement()
  356.     const hideEvent = $.Event(this.constructor.Event.HIDE)
  357.     const complete = () => {
  358.       if (this._hoverState !== HoverState.SHOW && tip.parentNode) {
  359.         tip.parentNode.removeChild(tip)
  360.       }
  361.  
  362.       this._cleanTipClass()
  363.       this.element.removeAttribute('aria-describedby')
  364.       $(this.element).trigger(this.constructor.Event.HIDDEN)
  365.       if (this._popper !== null) {
  366.         this._popper.destroy()
  367.       }
  368.  
  369.       if (callback) {
  370.         callback()
  371.       }
  372.     }
  373.  
  374.     $(this.element).trigger(hideEvent)
  375.  
  376.     if (hideEvent.isDefaultPrevented()) {
  377.       return
  378.     }
  379.  
  380.     $(tip).removeClass(ClassName.SHOW)
  381.  
  382.     // If this is a touch-enabled device we remove the extra
  383.     // empty mouseover listeners we added for iOS support
  384.     if ('ontouchstart' in document.documentElement) {
  385.       $(document.body).children().off('mouseover', null, $.noop)
  386.     }
  387.  
  388.     this._activeTrigger[Trigger.CLICK] = false
  389.     this._activeTrigger[Trigger.FOCUS] = false
  390.     this._activeTrigger[Trigger.HOVER] = false
  391.  
  392.     if ($(this.tip).hasClass(ClassName.FADE)) {
  393.       const transitionDuration = Util.getTransitionDurationFromElement(tip)
  394.  
  395.       $(tip)
  396.         .one(Util.TRANSITION_END, complete)
  397.         .emulateTransitionEnd(transitionDuration)
  398.     } else {
  399.       complete()
  400.     }
  401.  
  402.     this._hoverState = ''
  403.   }
  404.  
  405.   update() {
  406.     if (this._popper !== null) {
  407.       this._popper.scheduleUpdate()
  408.     }
  409.   }
  410.  
  411.   // Protected
  412.  
  413.   isWithContent() {
  414.     return Boolean(this.getTitle())
  415.   }
  416.  
  417.   addAttachmentClass(attachment) {
  418.     $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)
  419.   }
  420.  
  421.   getTipElement() {
  422.     this.tip = this.tip || $(this.config.template)[0]
  423.     return this.tip
  424.   }
  425.  
  426.   setContent() {
  427.     const tip = this.getTipElement()
  428.     this.setElementContent($(tip.querySelectorAll(Selector.TOOLTIP_INNER)), this.getTitle())
  429.     $(tip).removeClass(`${ClassName.FADE} ${ClassName.SHOW}`)
  430.   }
  431.  
  432.   setElementContent($element, content) {
  433.     if (typeof content === 'object' && (content.nodeType || content.jquery)) {
  434.       // Content is a DOM node or a jQuery
  435.       if (this.config.html) {
  436.         if (!$(content).parent().is($element)) {
  437.           $element.empty().append(content)
  438.         }
  439.       } else {
  440.         $element.text($(content).text())
  441.       }
  442.  
  443.       return
  444.     }
  445.  
  446.     if (this.config.html) {
  447.       if (this.config.sanitize) {
  448.         content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn)
  449.       }
  450.  
  451.       $element.html(content)
  452.     } else {
  453.       $element.text(content)
  454.     }
  455.   }
  456.  
  457.   getTitle() {
  458.     let title = this.element.getAttribute('data-original-title')
  459.  
  460.     if (!title) {
  461.       title = typeof this.config.title === 'function'
  462.         ? this.config.title.call(this.element)
  463.         : this.config.title
  464.     }
  465.  
  466.     return title
  467.   }
  468.  
  469.   // Private
  470.  
  471.   _getOffset() {
  472.     const offset = {}
  473.  
  474.     if (typeof this.config.offset === 'function') {
  475.       offset.fn = (data) => {
  476.         data.offsets = {
  477.           ...data.offsets,
  478.           ...this.config.offset(data.offsets, this.element) || {}
  479.         }
  480.  
  481.         return data
  482.       }
  483.     } else {
  484.       offset.offset = this.config.offset
  485.     }
  486.  
  487.     return offset
  488.   }
  489.  
  490.   _getContainer() {
  491.     if (this.config.container === false) {
  492.       return document.body
  493.     }
  494.  
  495.     if (Util.isElement(this.config.container)) {
  496.       return $(this.config.container)
  497.     }
  498.  
  499.     return $(document).find(this.config.container)
  500.   }
  501.  
  502.   _getAttachment(placement) {
  503.     return AttachmentMap[placement.toUpperCase()]
  504.   }
  505.  
  506.   _setListeners() {
  507.     const triggers = this.config.trigger.split(' ')
  508.  
  509.     triggers.forEach((trigger) => {
  510.       if (trigger === 'click') {
  511.         $(this.element).on(
  512.           this.constructor.Event.CLICK,
  513.           this.config.selector,
  514.           (event) => this.toggle(event)
  515.         )
  516.       } else if (trigger !== Trigger.MANUAL) {
  517.         const eventIn = trigger === Trigger.HOVER
  518.           ? this.constructor.Event.MOUSEENTER
  519.           : this.constructor.Event.FOCUSIN
  520.         const eventOut = trigger === Trigger.HOVER
  521.           ? this.constructor.Event.MOUSELEAVE
  522.           : this.constructor.Event.FOCUSOUT
  523.  
  524.         $(this.element)
  525.           .on(
  526.             eventIn,
  527.             this.config.selector,
  528.             (event) => this._enter(event)
  529.           )
  530.           .on(
  531.             eventOut,
  532.             this.config.selector,
  533.             (event) => this._leave(event)
  534.           )
  535.       }
  536.     })
  537.  
  538.     $(this.element).closest('.modal').on(
  539.       'hide.bs.modal',
  540.       () => {
  541.         if (this.element) {
  542.           this.hide()
  543.         }
  544.       }
  545.     )
  546.  
  547.     if (this.config.selector) {
  548.       this.config = {
  549.         ...this.config,
  550.         trigger: 'manual',
  551.         selector: ''
  552.       }
  553.     } else {
  554.       this._fixTitle()
  555.     }
  556.   }
  557.  
  558.   _fixTitle() {
  559.     const titleType = typeof this.element.getAttribute('data-original-title')
  560.  
  561.     if (this.element.getAttribute('title') || titleType !== 'string') {
  562.       this.element.setAttribute(
  563.         'data-original-title',
  564.         this.element.getAttribute('title') || ''
  565.       )
  566.  
  567.       this.element.setAttribute('title', '')
  568.     }
  569.   }
  570.  
  571.   _enter(event, context) {
  572.     const dataKey = this.constructor.DATA_KEY
  573.     context = context || $(event.currentTarget).data(dataKey)
  574.  
  575.     if (!context) {
  576.       context = new this.constructor(
  577.         event.currentTarget,
  578.         this._getDelegateConfig()
  579.       )
  580.       $(event.currentTarget).data(dataKey, context)
  581.     }
  582.  
  583.     if (event) {
  584.       context._activeTrigger[
  585.         event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER
  586.       ] = true
  587.     }
  588.  
  589.     if ($(context.getTipElement()).hasClass(ClassName.SHOW) || context._hoverState === HoverState.SHOW) {
  590.       context._hoverState = HoverState.SHOW
  591.       return
  592.     }
  593.  
  594.     clearTimeout(context._timeout)
  595.  
  596.     context._hoverState = HoverState.SHOW
  597.  
  598.     if (!context.config.delay || !context.config.delay.show) {
  599.       context.show()
  600.       return
  601.     }
  602.  
  603.     context._timeout = setTimeout(() => {
  604.       if (context._hoverState === HoverState.SHOW) {
  605.         context.show()
  606.       }
  607.     }, context.config.delay.show)
  608.   }
  609.  
  610.   _leave(event, context) {
  611.     const dataKey = this.constructor.DATA_KEY
  612.     context = context || $(event.currentTarget).data(dataKey)
  613.  
  614.     if (!context) {
  615.       context = new this.constructor(
  616.         event.currentTarget,
  617.         this._getDelegateConfig()
  618.       )
  619.       $(event.currentTarget).data(dataKey, context)
  620.     }
  621.  
  622.     if (event) {
  623.       context._activeTrigger[
  624.         event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER
  625.       ] = false
  626.     }
  627.  
  628.     if (context._isWithActiveTrigger()) {
  629.       return
  630.     }
  631.  
  632.     clearTimeout(context._timeout)
  633.  
  634.     context._hoverState = HoverState.OUT
  635.  
  636.     if (!context.config.delay || !context.config.delay.hide) {
  637.       context.hide()
  638.       return
  639.     }
  640.  
  641.     context._timeout = setTimeout(() => {
  642.       if (context._hoverState === HoverState.OUT) {
  643.         context.hide()
  644.       }
  645.     }, context.config.delay.hide)
  646.   }
  647.  
  648.   _isWithActiveTrigger() {
  649.     for (const trigger in this._activeTrigger) {
  650.       if (this._activeTrigger[trigger]) {
  651.         return true
  652.       }
  653.     }
  654.  
  655.     return false
  656.   }
  657.  
  658.   _getConfig(config) {
  659.     const dataAttributes = $(this.element).data()
  660.  
  661.     Object.keys(dataAttributes)
  662.       .forEach((dataAttr) => {
  663.         if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) {
  664.           delete dataAttributes[dataAttr]
  665.         }
  666.       })
  667.  
  668.     config = {
  669.       ...this.constructor.Default,
  670.       ...dataAttributes,
  671.       ...typeof config === 'object' && config ? config : {}
  672.     }
  673.  
  674.     if (typeof config.delay === 'number') {
  675.       config.delay = {
  676.         show: config.delay,
  677.         hide: config.delay
  678.       }
  679.     }
  680.  
  681.     if (typeof config.title === 'number') {
  682.       config.title = config.title.toString()
  683.     }
  684.  
  685.     if (typeof config.content === 'number') {
  686.       config.content = config.content.toString()
  687.     }
  688.  
  689.     Util.typeCheckConfig(
  690.       NAME,
  691.       config,
  692.       this.constructor.DefaultType
  693.     )
  694.  
  695.     if (config.sanitize) {
  696.       config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn)
  697.     }
  698.  
  699.     return config
  700.   }
  701.  
  702.   _getDelegateConfig() {
  703.     const config = {}
  704.  
  705.     if (this.config) {
  706.       for (const key in this.config) {
  707.         if (this.constructor.Default[key] !== this.config[key]) {
  708.           config[key] = this.config[key]
  709.         }
  710.       }
  711.     }
  712.  
  713.     return config
  714.   }
  715.  
  716.   _cleanTipClass() {
  717.     const $tip = $(this.getTipElement())
  718.     const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)
  719.     if (tabClass !== null && tabClass.length) {
  720.       $tip.removeClass(tabClass.join(''))
  721.     }
  722.   }
  723.  
  724.   _handlePopperPlacementChange(popperData) {
  725.     const popperInstance = popperData.instance
  726.     this.tip = popperInstance.popper
  727.     this._cleanTipClass()
  728.     this.addAttachmentClass(this._getAttachment(popperData.placement))
  729.   }
  730.  
  731.   _fixTransition() {
  732.     const tip = this.getTipElement()
  733.     const initConfigAnimation = this.config.animation
  734.  
  735.     if (tip.getAttribute('x-placement') !== null) {
  736.       return
  737.     }
  738.  
  739.     $(tip).removeClass(ClassName.FADE)
  740.     this.config.animation = false
  741.     this.hide()
  742.     this.show()
  743.     this.config.animation = initConfigAnimation
  744.   }
  745.  
  746.   // Static
  747.  
  748.   static _jQueryInterface(config) {
  749.     return this.each(function () {
  750.       let data = $(this).data(DATA_KEY)
  751.       const _config = typeof config === 'object' && config
  752.  
  753.       if (!data && /dispose|hide/.test(config)) {
  754.         return
  755.       }
  756.  
  757.       if (!data) {
  758.         data = new Tooltip(this, _config)
  759.         $(this).data(DATA_KEY, data)
  760.       }
  761.  
  762.       if (typeof config === 'string') {
  763.         if (typeof data[config] === 'undefined') {
  764.           throw new TypeError(`No method named "${config}"`)
  765.         }
  766.         data[config]()
  767.       }
  768.     })
  769.   }
  770. }
  771.  
  772. /**
  773.  * ------------------------------------------------------------------------
  774.  * jQuery
  775.  * ------------------------------------------------------------------------
  776.  */
  777.  
  778. $.fn[NAME] = Tooltip._jQueryInterface
  779. $.fn[NAME].Constructor = Tooltip
  780. $.fn[NAME].noConflict = () => {
  781.   $.fn[NAME] = JQUERY_NO_CONFLICT
  782.   return Tooltip._jQueryInterface
  783. }
  784.  
  785. export default Tooltip

Raw Paste


Login or Register to edit or fork this paste. It's free.