]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
create a base component
authorJohann-S <johann.servoire@gmail.com>
Wed, 4 Sep 2019 14:58:29 +0000 (17:58 +0300)
committerXhmikosR <xhmikosr@gmail.com>
Sun, 29 Nov 2020 18:58:26 +0000 (20:58 +0200)
23 files changed:
js/src/alert.js
js/src/base-component.js [new file with mode: 0644]
js/src/button.js
js/src/carousel.js
js/src/collapse.js
js/src/dropdown.js
js/src/modal.js
js/src/popover.js
js/src/scrollspy.js
js/src/tab.js
js/src/toast.js
js/src/tooltip.js
js/tests/unit/alert.spec.js
js/tests/unit/button.spec.js
js/tests/unit/carousel.spec.js
js/tests/unit/collapse.spec.js
js/tests/unit/dropdown.spec.js
js/tests/unit/modal.spec.js
js/tests/unit/popover.spec.js
js/tests/unit/scrollspy.spec.js
js/tests/unit/tab.spec.js
js/tests/unit/toast.spec.js
js/tests/unit/tooltip.spec.js

index 724cda0173b2e4108a33aabb9f7b254b86829c8c..6f4c0be8dee9f3f004c7d9029a61e85ff0ffd31e 100644 (file)
@@ -15,6 +15,7 @@ import {
 } from './util/index'
 import Data from './dom/data'
 import EventHandler from './dom/event-handler'
+import BaseComponent from './base-component'
 
 /**
  * ------------------------------------------------------------------------
@@ -44,21 +45,17 @@ const CLASSNAME_SHOW = 'show'
  * ------------------------------------------------------------------------
  */
 
-class Alert {
-  constructor(element) {
-    this._element = element
-
-    if (this._element) {
-      Data.setData(element, DATA_KEY, this)
-    }
-  }
-
+class Alert extends BaseComponent {
   // Getters
 
   static get VERSION() {
     return VERSION
   }
 
+  static get DATA_KEY() {
+    return DATA_KEY
+  }
+
   // Public
 
   close(element) {
@@ -134,10 +131,6 @@ class Alert {
       alertInstance.close(this)
     }
   }
-
-  static getInstance(element) {
-    return Data.getData(element, DATA_KEY)
-  }
 }
 
 /**
diff --git a/js/src/base-component.js b/js/src/base-component.js
new file mode 100644 (file)
index 0000000..a6c7f36
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.0.0-alpha3): base-component.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+import Data from './dom/data'
+
+class BaseComponent {
+  constructor(element) {
+    if (!element) {
+      return
+    }
+
+    this._element = element
+    Data.setData(element, this.constructor.DATA_KEY, this)
+  }
+
+  /** Static */
+
+  static getInstance(element) {
+    return Data.getData(element, this.DATA_KEY)
+  }
+
+  static get DATA_KEY() {
+    return null
+  }
+}
+
+export default BaseComponent
index 42376943debd04376541c4dc82818bd0f300a77e..2694e7b786c7d00929591c145151a2e0f420bdb9 100644 (file)
@@ -8,6 +8,7 @@
 import { getjQuery, onDOMContentLoaded } from './util/index'
 import Data from './dom/data'
 import EventHandler from './dom/event-handler'
+import BaseComponent from './base-component'
 
 /**
  * ------------------------------------------------------------------------
@@ -33,18 +34,17 @@ const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
  * ------------------------------------------------------------------------
  */
 
-class Button {
-  constructor(element) {
-    this._element = element
-    Data.setData(element, DATA_KEY, this)
-  }
-
+class Button extends BaseComponent {
   // Getters
 
   static get VERSION() {
     return VERSION
   }
 
+  static get DATA_KEY() {
+    return DATA_KEY
+  }
+
   // Public
 
   toggle() {
@@ -72,10 +72,6 @@ class Button {
       }
     })
   }
-
-  static getInstance(element) {
-    return Data.getData(element, DATA_KEY)
-  }
 }
 
 /**
index c663efbeacdc1a4b4198c6f2f9208e5e5eb60ed9..6a035c9abda5def2dace645fc4017b4c511ecba7 100644 (file)
@@ -21,6 +21,7 @@ import Data from './dom/data'
 import EventHandler from './dom/event-handler'
 import Manipulator from './dom/manipulator'
 import SelectorEngine from './dom/selector-engine'
+import BaseComponent from './base-component'
 
 /**
  * ------------------------------------------------------------------------
@@ -104,8 +105,10 @@ const PointerType = {
  * Class Definition
  * ------------------------------------------------------------------------
  */
-class Carousel {
+class Carousel extends BaseComponent {
   constructor(element, config) {
+    super(element)
+
     this._items = null
     this._interval = null
     this._activeElement = null
@@ -116,7 +119,6 @@ class Carousel {
     this.touchDeltaX = 0
 
     this._config = this._getConfig(config)
-    this._element = element
     this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element)
     this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0
     this._pointerEvent = Boolean(window.PointerEvent)
@@ -135,6 +137,10 @@ class Carousel {
     return Default
   }
 
+  static get DATA_KEY() {
+    return DATA_KEY
+  }
+
   // Public
 
   next() {
@@ -590,10 +596,6 @@ class Carousel {
 
     event.preventDefault()
   }
-
-  static getInstance(element) {
-    return Data.getData(element, DATA_KEY)
-  }
 }
 
 /**
index 2ddcb0c047a0887125c0963b1d6f5b8f640b9a1d..c76426c7c44132dd22bbdc4b3ce58a3777ea0261 100644 (file)
@@ -21,6 +21,7 @@ import Data from './dom/data'
 import EventHandler from './dom/event-handler'
 import Manipulator from './dom/manipulator'
 import SelectorEngine from './dom/selector-engine'
+import BaseComponent from './base-component'
 
 /**
  * ------------------------------------------------------------------------
@@ -67,10 +68,11 @@ const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="collapse"]'
  * ------------------------------------------------------------------------
  */
 
-class Collapse {
+class Collapse extends BaseComponent {
   constructor(element, config) {
+    super(element)
+
     this._isTransitioning = false
-    this._element = element
     this._config = this._getConfig(config)
     this._triggerArray = SelectorEngine.find(
       `${SELECTOR_DATA_TOGGLE}[href="#${element.id}"],` +
@@ -114,6 +116,10 @@ class Collapse {
     return Default
   }
 
+  static get DATA_KEY() {
+    return DATA_KEY
+  }
+
   // Public
 
   toggle() {
@@ -368,10 +374,6 @@ class Collapse {
       Collapse.collapseInterface(this, config)
     })
   }
-
-  static getInstance(element) {
-    return Data.getData(element, DATA_KEY)
-  }
 }
 
 /**
index b9f5a4cd39cd1e1604ee12f06c6748d72cf6927b..16d35b911d069022394017a67203397ff90dc648 100644 (file)
@@ -19,6 +19,7 @@ import EventHandler from './dom/event-handler'
 import Manipulator from './dom/manipulator'
 import Popper from 'popper.js'
 import SelectorEngine from './dom/selector-engine'
+import BaseComponent from './base-component'
 
 /**
  * ------------------------------------------------------------------------
@@ -96,9 +97,10 @@ const DefaultType = {
  * ------------------------------------------------------------------------
  */
 
-class Dropdown {
+class Dropdown extends BaseComponent {
   constructor(element, config) {
-    this._element = element
+    super(element)
+
     this._popper = null
     this._config = this._getConfig(config)
     this._menu = this._getMenuElement()
@@ -122,6 +124,10 @@ class Dropdown {
     return DefaultType
   }
 
+  static get DATA_KEY() {
+    return DATA_KEY
+  }
+
   // Public
 
   toggle() {
@@ -489,10 +495,6 @@ class Dropdown {
 
     items[index].focus()
   }
-
-  static getInstance(element) {
-    return Data.getData(element, DATA_KEY)
-  }
 }
 
 /**
index 4309cbd9a23eedce83b04fb8c75cc7718c8a5ad6..1e7ce034692fce22c04eeff48da45ce0074e0d43 100644 (file)
@@ -20,6 +20,7 @@ import Data from './dom/data'
 import EventHandler from './dom/event-handler'
 import Manipulator from './dom/manipulator'
 import SelectorEngine from './dom/selector-engine'
+import BaseComponent from './base-component'
 
 /**
  * ------------------------------------------------------------------------
@@ -81,10 +82,11 @@ const SELECTOR_STICKY_CONTENT = '.sticky-top'
  * ------------------------------------------------------------------------
  */
 
-class Modal {
+class Modal extends BaseComponent {
   constructor(element, config) {
+    super(element)
+
     this._config = this._getConfig(config)
-    this._element = element
     this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, element)
     this._backdrop = null
     this._isShown = false
@@ -105,6 +107,10 @@ class Modal {
     return Default
   }
 
+  static get DATA_KEY() {
+    return DATA_KEY
+  }
+
   // Public
 
   toggle(relatedTarget) {
@@ -563,10 +569,6 @@ class Modal {
       }
     })
   }
-
-  static getInstance(element) {
-    return Data.getData(element, DATA_KEY)
-  }
 }
 
 /**
index 46b693e6963b9536c474c065140ec3fa81e79783..bae5537aa20a4dd8eb267f33d5b495727a4c00bd 100644 (file)
@@ -108,7 +108,7 @@ class Popover extends Tooltip {
     this.setElementContent(SelectorEngine.findOne(SELECTOR_TITLE, tip), this.getTitle())
     let content = this._getContent()
     if (typeof content === 'function') {
-      content = content.call(this.element)
+      content = content.call(this._element)
     }
 
     this.setElementContent(SelectorEngine.findOne(SELECTOR_CONTENT, tip), content)
@@ -123,7 +123,7 @@ class Popover extends Tooltip {
   }
 
   _getContent() {
-    return this.element.getAttribute('data-bs-content') ||
+    return this._element.getAttribute('data-bs-content') ||
       this.config.content
   }
 
@@ -161,10 +161,6 @@ class Popover extends Tooltip {
       }
     })
   }
-
-  static getInstance(element) {
-    return Data.getData(element, DATA_KEY)
-  }
 }
 
 /**
index de456e0805ced136cab16d999e4f1aabbfba1a89..6eb66f3b4a32fc43ea18edfb51c2e845e2aab460 100644 (file)
@@ -17,6 +17,7 @@ import Data from './dom/data'
 import EventHandler from './dom/event-handler'
 import Manipulator from './dom/manipulator'
 import SelectorEngine from './dom/selector-engine'
+import BaseComponent from './base-component'
 
 /**
  * ------------------------------------------------------------------------
@@ -66,9 +67,9 @@ const METHOD_POSITION = 'position'
  * ------------------------------------------------------------------------
  */
 
-class ScrollSpy {
+class ScrollSpy extends BaseComponent {
   constructor(element, config) {
-    this._element = element
+    super(element)
     this._scrollElement = element.tagName === 'BODY' ? window : element
     this._config = this._getConfig(config)
     this._selector = `${this._config.target} ${SELECTOR_NAV_LINKS}, ${this._config.target} ${SELECTOR_LIST_ITEMS}, ${this._config.target} .${CLASS_NAME_DROPDOWN_ITEM}`
@@ -95,6 +96,10 @@ class ScrollSpy {
     return Default
   }
 
+  static get DATA_KEY() {
+    return DATA_KEY
+  }
+
   // Public
 
   refresh() {
@@ -301,10 +306,6 @@ class ScrollSpy {
       }
     })
   }
-
-  static getInstance(element) {
-    return Data.getData(element, DATA_KEY)
-  }
 }
 
 /**
index 56269e2facba3b60563e4507347b6f20ef3a73fa..523810a392c7f4462dbaa4be7a56ed57e7816f47 100644 (file)
@@ -17,6 +17,7 @@ import {
 import Data from './dom/data'
 import EventHandler from './dom/event-handler'
 import SelectorEngine from './dom/selector-engine'
+import BaseComponent from './base-component'
 
 /**
  * ------------------------------------------------------------------------
@@ -56,19 +57,17 @@ const SELECTOR_DROPDOWN_ACTIVE_CHILD = ':scope > .dropdown-menu .active'
  * ------------------------------------------------------------------------
  */
 
-class Tab {
-  constructor(element) {
-    this._element = element
-
-    Data.setData(this._element, DATA_KEY, this)
-  }
-
+class Tab extends BaseComponent {
   // Getters
 
   static get VERSION() {
     return VERSION
   }
 
+  static get DATA_KEY() {
+    return DATA_KEY
+  }
+
   // Public
 
   show() {
@@ -217,10 +216,6 @@ class Tab {
       }
     })
   }
-
-  static getInstance(element) {
-    return Data.getData(element, DATA_KEY)
-  }
 }
 
 /**
index 1e50b06693479fd49f594f93f902076c4e37ab2c..c351139be0c7798a9bf726a5cc4e1b8ba017428d 100644 (file)
@@ -17,6 +17,7 @@ import {
 import Data from './dom/data'
 import EventHandler from './dom/event-handler'
 import Manipulator from './dom/manipulator'
+import BaseComponent from './base-component'
 
 /**
  * ------------------------------------------------------------------------
@@ -60,9 +61,10 @@ const SELECTOR_DATA_DISMISS = '[data-bs-dismiss="toast"]'
  * ------------------------------------------------------------------------
  */
 
-class Toast {
+class Toast extends BaseComponent {
   constructor(element, config) {
-    this._element = element
+    super(element)
+
     this._config = this._getConfig(config)
     this._timeout = null
     this._setListeners()
@@ -83,6 +85,10 @@ class Toast {
     return Default
   }
 
+  static get DATA_KEY() {
+    return DATA_KEY
+  }
+
   // Public
 
   show() {
@@ -208,10 +214,6 @@ class Toast {
       }
     })
   }
-
-  static getInstance(element) {
-    return Data.getData(element, DATA_KEY)
-  }
 }
 
 /**
index 368e04b30cc30d5a5c731b53849ad949e8ba388d..99f910efc782194780eaff8710927868c0a3cb63 100644 (file)
@@ -26,6 +26,7 @@ import EventHandler from './dom/event-handler'
 import Manipulator from './dom/manipulator'
 import Popper from 'popper.js'
 import SelectorEngine from './dom/selector-engine'
+import BaseComponent from './base-component'
 
 /**
  * ------------------------------------------------------------------------
@@ -124,12 +125,14 @@ const TRIGGER_MANUAL = 'manual'
  * ------------------------------------------------------------------------
  */
 
-class Tooltip {
+class Tooltip extends BaseComponent {
   constructor(element, config) {
     if (typeof Popper === 'undefined') {
       throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org)')
     }
 
+    super(element)
+
     // private
     this._isEnabled = true
     this._timeout = 0
@@ -138,7 +141,6 @@ class Tooltip {
     this._popper = null
 
     // Protected
-    this.element = element
     this.config = this._getConfig(config)
     this.tip = null
 
@@ -227,10 +229,10 @@ class Tooltip {
   dispose() {
     clearTimeout(this._timeout)
 
-    Data.removeData(this.element, this.constructor.DATA_KEY)
+    Data.removeData(this._element, this.constructor.DATA_KEY)
 
-    EventHandler.off(this.element, this.constructor.EVENT_KEY)
-    EventHandler.off(this.element.closest(`.${CLASS_NAME_MODAL}`), 'hide.bs.modal', this._hideModalHandler)
+    EventHandler.off(this._element, this.constructor.EVENT_KEY)
+    EventHandler.off(this._element.closest(`.${CLASS_NAME_MODAL}`), 'hide.bs.modal', this._hideModalHandler)
 
     if (this.tip) {
       this.tip.parentNode.removeChild(this.tip)
@@ -245,22 +247,22 @@ class Tooltip {
     }
 
     this._popper = null
-    this.element = null
+    this._element = null
     this.config = null
     this.tip = null
   }
 
   show() {
-    if (this.element.style.display === 'none') {
+    if (this._element.style.display === 'none') {
       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 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)
+        this._element.ownerDocument.documentElement.contains(this._element) :
+        shadowRoot.contains(this._element)
 
       if (showEvent.defaultPrevented || !isInTheDom) {
         return
@@ -270,7 +272,7 @@ class Tooltip {
       const tipId = getUID(this.constructor.NAME)
 
       tip.setAttribute('id', tipId)
-      this.element.setAttribute('aria-describedby', tipId)
+      this._element.setAttribute('aria-describedby', tipId)
 
       this.setContent()
 
@@ -279,7 +281,7 @@ class Tooltip {
       }
 
       const placement = typeof this.config.placement === 'function' ?
-        this.config.placement.call(this, tip, this.element) :
+        this.config.placement.call(this, tip, this._element) :
         this.config.placement
 
       const attachment = this._getAttachment(placement)
@@ -288,13 +290,13 @@ class Tooltip {
       const container = this._getContainer()
       Data.setData(tip, this.constructor.DATA_KEY, this)
 
-      if (!this.element.ownerDocument.documentElement.contains(this.tip)) {
+      if (!this._element.ownerDocument.documentElement.contains(this.tip)) {
         container.appendChild(tip)
       }
 
-      EventHandler.trigger(this.element, this.constructor.Event.INSERTED)
+      EventHandler.trigger(this._element, this.constructor.Event.INSERTED)
 
-      this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment))
+      this._popper = new Popper(this._element, tip, this._getPopperConfig(attachment))
 
       tip.classList.add(CLASS_NAME_SHOW)
 
@@ -321,7 +323,7 @@ class Tooltip {
         const prevHoverState = this._hoverState
         this._hoverState = null
 
-        EventHandler.trigger(this.element, this.constructor.Event.SHOWN)
+        EventHandler.trigger(this._element, this.constructor.Event.SHOWN)
 
         if (prevHoverState === HOVER_STATE_OUT) {
           this._leave(null, this)
@@ -350,12 +352,12 @@ class Tooltip {
       }
 
       this._cleanTipClass()
-      this.element.removeAttribute('aria-describedby')
-      EventHandler.trigger(this.element, this.constructor.Event.HIDDEN)
+      this._element.removeAttribute('aria-describedby')
+      EventHandler.trigger(this._element, this.constructor.Event.HIDDEN)
       this._popper.destroy()
     }
 
-    const hideEvent = EventHandler.trigger(this.element, this.constructor.Event.HIDE)
+    const hideEvent = EventHandler.trigger(this._element, this.constructor.Event.HIDE)
     if (hideEvent.defaultPrevented) {
       return
     }
@@ -450,11 +452,11 @@ class Tooltip {
   }
 
   getTitle() {
-    let title = this.element.getAttribute('data-bs-original-title')
+    let title = this._element.getAttribute('data-bs-original-title')
 
     if (!title) {
       title = typeof this.config.title === 'function' ?
-        this.config.title.call(this.element) :
+        this.config.title.call(this._element) :
         this.config.title
     }
 
@@ -503,7 +505,7 @@ class Tooltip {
       offset.fn = data => {
         data.offsets = {
           ...data.offsets,
-          ...(this.config.offset(data.offsets, this.element) || {})
+          ...(this.config.offset(data.offsets, this._element) || {})
         }
 
         return data
@@ -536,7 +538,7 @@ class Tooltip {
 
     triggers.forEach(trigger => {
       if (trigger === 'click') {
-        EventHandler.on(this.element,
+        EventHandler.on(this._element,
           this.constructor.Event.CLICK,
           this.config.selector,
           event => this.toggle(event)
@@ -549,12 +551,12 @@ class Tooltip {
           this.constructor.Event.MOUSELEAVE :
           this.constructor.Event.FOCUSOUT
 
-        EventHandler.on(this.element,
+        EventHandler.on(this._element,
           eventIn,
           this.config.selector,
           event => this._enter(event)
         )
-        EventHandler.on(this.element,
+        EventHandler.on(this._element,
           eventOut,
           this.config.selector,
           event => this._leave(event)
@@ -563,12 +565,12 @@ class Tooltip {
     })
 
     this._hideModalHandler = () => {
-      if (this.element) {
+      if (this._element) {
         this.hide()
       }
     }
 
-    EventHandler.on(this.element.closest(`.${CLASS_NAME_MODAL}`),
+    EventHandler.on(this._element.closest(`.${CLASS_NAME_MODAL}`),
       'hide.bs.modal',
       this._hideModalHandler
     )
@@ -585,12 +587,12 @@ class Tooltip {
   }
 
   _fixTitle() {
-    const title = this.element.getAttribute('title')
-    const originalTitleType = typeof this.element.getAttribute('data-bs-original-title')
+    const title = this._element.getAttribute('title')
+    const originalTitleType = typeof this._element.getAttribute('data-bs-original-title')
 
     if (title || originalTitleType !== 'string') {
-      this.element.setAttribute('data-bs-original-title', title || '')
-      this.element.setAttribute('title', '')
+      this._element.setAttribute('data-bs-original-title', title || '')
+      this._element.setAttribute('title', '')
     }
   }
 
@@ -683,7 +685,7 @@ class Tooltip {
   }
 
   _getConfig(config) {
-    const dataAttributes = Manipulator.getDataAttributes(this.element)
+    const dataAttributes = Manipulator.getDataAttributes(this._element)
 
     Object.keys(dataAttributes).forEach(dataAttr => {
       if (DISALLOWED_ATTRIBUTES.has(dataAttr)) {
@@ -792,10 +794,6 @@ class Tooltip {
       }
     })
   }
-
-  static getInstance(element) {
-    return Data.getData(element, DATA_KEY)
-  }
 }
 
 /**
index a746d85011efdb129524b887b52731340f213c7c..52643e575d73428822c5f1b4e703c76a52c82213 100644 (file)
@@ -170,4 +170,24 @@ describe('Alert', () => {
       expect(fixtureEl.querySelector('.alert')).not.toBeNull()
     })
   })
+
+  describe('getInstance', () => {
+    it('should return alert instance', () => {
+      fixtureEl.innerHTML = '<div></div>'
+
+      const div = fixtureEl.querySelector('div')
+      const alert = new Alert(div)
+
+      expect(Alert.getInstance(div)).toEqual(alert)
+      expect(Alert.getInstance(div) instanceof Alert).toEqual(true)
+    })
+
+    it('should return null when there is no alert instance', () => {
+      fixtureEl.innerHTML = '<div></div>'
+
+      const div = fixtureEl.querySelector('div')
+
+      expect(Alert.getInstance(div)).toEqual(null)
+    })
+  })
 })
index 44d7b54b18155d25ddca6878a8875b347a2668d4..e7f6566ea3ff2b0e1e16f6046163114899bcfdb8 100644 (file)
@@ -128,4 +128,24 @@ describe('Button', () => {
       expect(btnEl.classList.contains('active')).toEqual(false)
     })
   })
+
+  describe('getInstance', () => {
+    it('should return button instance', () => {
+      fixtureEl.innerHTML = '<div></div>'
+
+      const div = fixtureEl.querySelector('div')
+      const button = new Button(div)
+
+      expect(Button.getInstance(div)).toEqual(button)
+      expect(Button.getInstance(div) instanceof Button).toEqual(true)
+    })
+
+    it('should return null when there is no button instance', () => {
+      fixtureEl.innerHTML = '<div></div>'
+
+      const div = fixtureEl.querySelector('div')
+
+      expect(Button.getInstance(div)).toEqual(null)
+    })
+  })
 })
index 8c928c429dcad9dd13eee503ac0fd4d9bd783f95..a21003dc5e13e2945fa9c09285cd477486d0a053 100644 (file)
@@ -1062,6 +1062,26 @@ describe('Carousel', () => {
     })
   })
 
+  describe('getInstance', () => {
+    it('should return carousel instance', () => {
+      fixtureEl.innerHTML = '<div></div>'
+
+      const div = fixtureEl.querySelector('div')
+      const carousel = new Carousel(div)
+
+      expect(Carousel.getInstance(div)).toEqual(carousel)
+      expect(Carousel.getInstance(div) instanceof Carousel).toEqual(true)
+    })
+
+    it('should return null when there is no carousel instance', () => {
+      fixtureEl.innerHTML = '<div></div>'
+
+      const div = fixtureEl.querySelector('div')
+
+      expect(Carousel.getInstance(div)).toEqual(null)
+    })
+  })
+
   describe('jQueryInterface', () => {
     it('should create a carousel', () => {
       fixtureEl.innerHTML = '<div></div>'
index c1ead859a9fee2afa3cbf44f9617ace5427f45e2..e5c8c53b5b751c6393b9fcbad06700c3431ce6db 100644 (file)
@@ -812,6 +812,7 @@ describe('Collapse', () => {
       const collapse = new Collapse(div)
 
       expect(Collapse.getInstance(div)).toEqual(collapse)
+      expect(Collapse.getInstance(div) instanceof Collapse).toEqual(true)
     })
 
     it('should return null when there is no collapse instance', () => {
index f5f41636cd9c5d55bb1be3013b6da8cb1e228962..96f677c02ccf34410fe442d729a0688172b760bd 100644 (file)
@@ -1612,6 +1612,7 @@ describe('Dropdown', () => {
       const dropdown = new Dropdown(div)
 
       expect(Dropdown.getInstance(div)).toEqual(dropdown)
+      expect(Dropdown.getInstance(div) instanceof Dropdown).toEqual(true)
     })
 
     it('should return null when there is no dropdown instance', () => {
index 084f78ad14a5fa4fbb1474e0692f77851f9613f4..8e8d4f0ff66c9b405498f8a3b2e9d60687afbef2 100644 (file)
@@ -1108,6 +1108,7 @@ describe('Modal', () => {
       const modal = new Modal(div)
 
       expect(Modal.getInstance(div)).toEqual(modal)
+      expect(Modal.getInstance(div) instanceof Modal).toEqual(true)
     })
 
     it('should return null when there is no modal instance', () => {
index e87ed12144594780b35ae49e11649af91a1da6de..3a8342a80fad7d7614d6b14902b5b62d8580dfb1 100644 (file)
@@ -253,6 +253,7 @@ describe('Popover', () => {
       const popover = new Popover(popoverEl)
 
       expect(Popover.getInstance(popoverEl)).toEqual(popover)
+      expect(Popover.getInstance(popoverEl) instanceof Popover).toEqual(true)
     })
 
     it('should return null when there is no popover instance', () => {
index 33298300cf5331b83a6b37c84c7b3358529251d6..303a336f442e4e247f53bb10201a890c89333ba1 100644 (file)
@@ -634,6 +634,16 @@ describe('ScrollSpy', () => {
   })
 
   describe('getInstance', () => {
+    it('should return scrollspy instance', () => {
+      fixtureEl.innerHTML = '<div></div>'
+
+      const div = fixtureEl.querySelector('div')
+      const scrollSpy = new ScrollSpy(div)
+
+      expect(ScrollSpy.getInstance(div)).toEqual(scrollSpy)
+      expect(ScrollSpy.getInstance(div) instanceof ScrollSpy).toEqual(true)
+    })
+
     it('should return null if there is no instance', () => {
       expect(ScrollSpy.getInstance(fixtureEl)).toEqual(null)
     })
index 324c4a09ba0a0c0644d0872bfaf445a479014809..7112dda181d01ecd407fd4e204dde534be6cb6db 100644 (file)
@@ -417,6 +417,7 @@ describe('Tab', () => {
       const tab = new Tab(divEl)
 
       expect(Tab.getInstance(divEl)).toEqual(tab)
+      expect(Tab.getInstance(divEl) instanceof Tab).toEqual(true)
     })
   })
 
index c4cb69a7f148dd6e856193eac5f1e7ca9fe360c6..60c7d9177bbe90dd158c6942e3c3f79d460a6a88 100644 (file)
@@ -384,6 +384,7 @@ describe('Toast', () => {
       const toast = new Toast(div)
 
       expect(Toast.getInstance(div)).toEqual(toast)
+      expect(Toast.getInstance(div) instanceof Toast).toEqual(true)
     })
 
     it('should return null when there is no toast instance', () => {
index da2abba3143d31892923bed9f871dfe63ef33601..36316b42f9cbb749e3197de32d3adf2eb8735710 100644 (file)
@@ -1030,6 +1030,26 @@ describe('Tooltip', () => {
     })
   })
 
+  describe('getInstance', () => {
+    it('should return tooltip instance', () => {
+      fixtureEl.innerHTML = '<div></div>'
+
+      const div = fixtureEl.querySelector('div')
+      const alert = new Tooltip(div)
+
+      expect(Tooltip.getInstance(div)).toEqual(alert)
+      expect(Tooltip.getInstance(div) instanceof Tooltip).toEqual(true)
+    })
+
+    it('should return null when there is no tooltip instance', () => {
+      fixtureEl.innerHTML = '<div></div>'
+
+      const div = fixtureEl.querySelector('div')
+
+      expect(Tooltip.getInstance(div)).toEqual(null)
+    })
+  })
+
   describe('jQueryInterface', () => {
     it('should create a tooltip', () => {
       fixtureEl.innerHTML = '<div></div>'