]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
Tooltip refactoring (#32523)
authorGeoSot <geo.sotis@gmail.com>
Wed, 27 Jan 2021 17:01:24 +0000 (19:01 +0200)
committerGitHub <noreply@github.com>
Wed, 27 Jan 2021 17:01:24 +0000 (19:01 +0200)
* tooltip: move common code to a reusable function

* tooltip: return early in `show()`

Co-authored-by: Rohit Sharma <rohit2sharma95@gmail.com>
Co-authored-by: XhmikosR <xhmikosr@gmail.com>
js/src/tooltip.js

index 63a30cf2fbd2e120e9fa3a29d94dbd2c5caa6c7f..909cb0f8a7d53b2bdcd9397b322d8da7a8011514 100644 (file)
@@ -191,13 +191,7 @@ class Tooltip extends BaseComponent {
     }
 
     if (event) {
-      const dataKey = this.constructor.DATA_KEY
-      let context = Data.getData(event.delegateTarget, dataKey)
-
-      if (!context) {
-        context = new this.constructor(event.delegateTarget, this._getDelegateConfig())
-        Data.setData(event.delegateTarget, dataKey, context)
-      }
+      const context = this._initializeOnDelegatedTarget(event)
 
       context._activeTrigger.click = !context._activeTrigger.click
 
@@ -245,83 +239,85 @@ class Tooltip extends BaseComponent {
       throw new Error('Please use show on visible elements')
     }
 
-    if (this.isWithContent() && this._isEnabled) {
-      const showEvent = EventHandler.trigger(this._element, this.constructor.Event.SHOW)
-      const shadowRoot = findShadowRoot(this._element)
-      const isInTheDom = shadowRoot === null ?
-        this._element.ownerDocument.documentElement.contains(this._element) :
-        shadowRoot.contains(this._element)
+    if (!(this.isWithContent() && this._isEnabled)) {
+      return
+    }
 
-      if (showEvent.defaultPrevented || !isInTheDom) {
-        return
-      }
+    const showEvent = EventHandler.trigger(this._element, this.constructor.Event.SHOW)
+    const shadowRoot = findShadowRoot(this._element)
+    const isInTheDom = shadowRoot === null ?
+      this._element.ownerDocument.documentElement.contains(this._element) :
+      shadowRoot.contains(this._element)
 
-      const tip = this.getTipElement()
-      const tipId = getUID(this.constructor.NAME)
+    if (showEvent.defaultPrevented || !isInTheDom) {
+      return
+    }
 
-      tip.setAttribute('id', tipId)
-      this._element.setAttribute('aria-describedby', tipId)
+    const tip = this.getTipElement()
+    const tipId = getUID(this.constructor.NAME)
 
-      this.setContent()
+    tip.setAttribute('id', tipId)
+    this._element.setAttribute('aria-describedby', tipId)
 
-      if (this.config.animation) {
-        tip.classList.add(CLASS_NAME_FADE)
-      }
+    this.setContent()
 
-      const placement = typeof this.config.placement === 'function' ?
-        this.config.placement.call(this, tip, this._element) :
-        this.config.placement
+    if (this.config.animation) {
+      tip.classList.add(CLASS_NAME_FADE)
+    }
 
-      const attachment = this._getAttachment(placement)
-      this._addAttachmentClass(attachment)
+    const placement = typeof this.config.placement === 'function' ?
+      this.config.placement.call(this, tip, this._element) :
+      this.config.placement
 
-      const container = this._getContainer()
-      Data.setData(tip, this.constructor.DATA_KEY, this)
+    const attachment = this._getAttachment(placement)
+    this._addAttachmentClass(attachment)
 
-      if (!this._element.ownerDocument.documentElement.contains(this.tip)) {
-        container.appendChild(tip)
-      }
+    const container = this._getContainer()
+    Data.setData(tip, this.constructor.DATA_KEY, this)
 
-      EventHandler.trigger(this._element, this.constructor.Event.INSERTED)
+    if (!this._element.ownerDocument.documentElement.contains(this.tip)) {
+      container.appendChild(tip)
+    }
 
-      this._popper = Popper.createPopper(this._element, tip, this._getPopperConfig(attachment))
+    EventHandler.trigger(this._element, this.constructor.Event.INSERTED)
 
-      tip.classList.add(CLASS_NAME_SHOW)
+    this._popper = Popper.createPopper(this._element, tip, this._getPopperConfig(attachment))
 
-      const customClass = typeof this.config.customClass === 'function' ? this.config.customClass() : this.config.customClass
-      if (customClass) {
-        tip.classList.add(...customClass.split(' '))
-      }
+    tip.classList.add(CLASS_NAME_SHOW)
 
-      // If this is a touch-enabled device we add extra
-      // empty mouseover listeners to the body's immediate children;
-      // only needed because of broken event delegation on iOS
-      // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
-      if ('ontouchstart' in document.documentElement) {
-        [].concat(...document.body.children).forEach(element => {
-          EventHandler.on(element, 'mouseover', noop())
-        })
-      }
+    const customClass = typeof this.config.customClass === 'function' ? this.config.customClass() : this.config.customClass
+    if (customClass) {
+      tip.classList.add(...customClass.split(' '))
+    }
 
-      const complete = () => {
-        const prevHoverState = this._hoverState
+    // If this is a touch-enabled device we add extra
+    // empty mouseover listeners to the body's immediate children;
+    // only needed because of broken event delegation on iOS
+    // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
+    if ('ontouchstart' in document.documentElement) {
+      [].concat(...document.body.children).forEach(element => {
+        EventHandler.on(element, 'mouseover', noop())
+      })
+    }
 
-        this._hoverState = null
-        EventHandler.trigger(this._element, this.constructor.Event.SHOWN)
+    const complete = () => {
+      const prevHoverState = this._hoverState
 
-        if (prevHoverState === HOVER_STATE_OUT) {
-          this._leave(null, this)
-        }
-      }
+      this._hoverState = null
+      EventHandler.trigger(this._element, this.constructor.Event.SHOWN)
 
-      if (this.tip.classList.contains(CLASS_NAME_FADE)) {
-        const transitionDuration = getTransitionDurationFromElement(this.tip)
-        EventHandler.one(this.tip, 'transitionend', complete)
-        emulateTransitionEnd(this.tip, transitionDuration)
-      } else {
-        complete()
+      if (prevHoverState === HOVER_STATE_OUT) {
+        this._leave(null, this)
       }
     }
+
+    if (this.tip.classList.contains(CLASS_NAME_FADE)) {
+      const transitionDuration = getTransitionDurationFromElement(this.tip)
+      EventHandler.one(this.tip, 'transitionend', complete)
+      emulateTransitionEnd(this.tip, transitionDuration)
+    } else {
+      complete()
+    }
   }
 
   hide() {
@@ -465,6 +461,18 @@ class Tooltip extends BaseComponent {
 
   // Private
 
+  _initializeOnDelegatedTarget(event, context) {
+    const dataKey = this.constructor.DATA_KEY
+    context = context || Data.getData(event.delegateTarget, dataKey)
+
+    if (!context) {
+      context = new this.constructor(event.delegateTarget, this._getDelegateConfig())
+      Data.setData(event.delegateTarget, dataKey, context)
+    }
+
+    return context
+  }
+
   _getPopperConfig(attachment) {
     const defaultBsConfig = {
       placement: attachment,
@@ -582,16 +590,7 @@ class Tooltip extends BaseComponent {
   }
 
   _enter(event, context) {
-    const dataKey = this.constructor.DATA_KEY
-    context = context || Data.getData(event.delegateTarget, dataKey)
-
-    if (!context) {
-      context = new this.constructor(
-        event.delegateTarget,
-        this._getDelegateConfig()
-      )
-      Data.setData(event.delegateTarget, dataKey, context)
-    }
+    context = this._initializeOnDelegatedTarget(event, context)
 
     if (event) {
       context._activeTrigger[
@@ -621,16 +620,7 @@ class Tooltip extends BaseComponent {
   }
 
   _leave(event, context) {
-    const dataKey = this.constructor.DATA_KEY
-    context = context || Data.getData(event.delegateTarget, dataKey)
-
-    if (!context) {
-      context = new this.constructor(
-        event.delegateTarget,
-        this._getDelegateConfig()
-      )
-      Data.setData(event.delegateTarget, dataKey, context)
-    }
+    context = this._initializeOnDelegatedTarget(event, context)
 
     if (event) {
       context._activeTrigger[