diff options
author | alpadev <2838324+alpadev@users.noreply.github.com> | 2021-03-02 17:55:44 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-02 17:55:44 +0300 |
commit | 48a95f7280735d6f8962fe8b17975b03e351710c (patch) | |
tree | ce88821218c34186f610929525b34015885ba23c /js/src | |
parent | 6d93a1371a7edb823f7d625c6f4489f37c06aac1 (diff) |
refactor: use a Map instead of an Object in dom/data (#32180)
Co-authored-by: XhmikosR <xhmikosr@gmail.com>
Co-authored-by: Rohit Sharma <rohit2sharma95@gmail.com>
Diffstat (limited to 'js/src')
-rw-r--r-- | js/src/alert.js | 2 | ||||
-rw-r--r-- | js/src/base-component.js | 6 | ||||
-rw-r--r-- | js/src/button.js | 4 | ||||
-rw-r--r-- | js/src/carousel.js | 6 | ||||
-rw-r--r-- | js/src/collapse.js | 8 | ||||
-rw-r--r-- | js/src/dom/data.js | 80 | ||||
-rw-r--r-- | js/src/dropdown.js | 4 | ||||
-rw-r--r-- | js/src/modal.js | 4 | ||||
-rw-r--r-- | js/src/popover.js | 4 | ||||
-rw-r--r-- | js/src/scrollspy.js | 2 | ||||
-rw-r--r-- | js/src/tab.js | 4 | ||||
-rw-r--r-- | js/src/toast.js | 2 | ||||
-rw-r--r-- | js/src/tooltip.js | 8 |
13 files changed, 62 insertions, 72 deletions
diff --git a/js/src/alert.js b/js/src/alert.js index 8fc3f12a8d..d10e6c8da3 100644 --- a/js/src/alert.js +++ b/js/src/alert.js @@ -98,7 +98,7 @@ class Alert extends BaseComponent { static jQueryInterface(config) { return this.each(function () { - let data = Data.getData(this, DATA_KEY) + let data = Data.get(this, DATA_KEY) if (!data) { data = new Alert(this) diff --git a/js/src/base-component.js b/js/src/base-component.js index 989a641561..2a9e29c2aa 100644 --- a/js/src/base-component.js +++ b/js/src/base-component.js @@ -24,18 +24,18 @@ class BaseComponent { } this._element = element - Data.setData(this._element, this.constructor.DATA_KEY, this) + Data.set(this._element, this.constructor.DATA_KEY, this) } dispose() { - Data.removeData(this._element, this.constructor.DATA_KEY) + Data.remove(this._element, this.constructor.DATA_KEY) this._element = null } /** Static */ static getInstance(element) { - return Data.getData(element, this.DATA_KEY) + return Data.get(element, this.DATA_KEY) } static get VERSION() { diff --git a/js/src/button.js b/js/src/button.js index 4ec48ca083..7a9449f075 100644 --- a/js/src/button.js +++ b/js/src/button.js @@ -51,7 +51,7 @@ class Button extends BaseComponent { static jQueryInterface(config) { return this.each(function () { - let data = Data.getData(this, DATA_KEY) + let data = Data.get(this, DATA_KEY) if (!data) { data = new Button(this) @@ -75,7 +75,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, event => { const button = event.target.closest(SELECTOR_DATA_TOGGLE) - let data = Data.getData(button, DATA_KEY) + let data = Data.get(button, DATA_KEY) if (!data) { data = new Button(button) } diff --git a/js/src/carousel.js b/js/src/carousel.js index 75f8a4da79..a825aaef48 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -527,7 +527,7 @@ class Carousel extends BaseComponent { // Static static carouselInterface(element, config) { - let data = Data.getData(element, DATA_KEY) + let data = Data.get(element, DATA_KEY) let _config = { ...Default, ...Manipulator.getDataAttributes(element) @@ -586,7 +586,7 @@ class Carousel extends BaseComponent { Carousel.carouselInterface(target, config) if (slideIndex) { - Data.getData(target, DATA_KEY).to(slideIndex) + Data.get(target, DATA_KEY).to(slideIndex) } event.preventDefault() @@ -605,7 +605,7 @@ EventHandler.on(window, EVENT_LOAD_DATA_API, () => { const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE) for (let i = 0, len = carousels.length; i < len; i++) { - Carousel.carouselInterface(carousels[i], Data.getData(carousels[i], DATA_KEY)) + Carousel.carouselInterface(carousels[i], Data.get(carousels[i], DATA_KEY)) } }) diff --git a/js/src/collapse.js b/js/src/collapse.js index f861667659..036ffcf248 100644 --- a/js/src/collapse.js +++ b/js/src/collapse.js @@ -147,7 +147,7 @@ class Collapse extends BaseComponent { const container = SelectorEngine.findOne(this._selector) if (actives) { const tempActiveData = actives.find(elem => container !== elem) - activesData = tempActiveData ? Data.getData(tempActiveData, DATA_KEY) : null + activesData = tempActiveData ? Data.get(tempActiveData, DATA_KEY) : null if (activesData && activesData._isTransitioning) { return @@ -166,7 +166,7 @@ class Collapse extends BaseComponent { } if (!activesData) { - Data.setData(elemActive, DATA_KEY, null) + Data.set(elemActive, DATA_KEY, null) } }) } @@ -332,7 +332,7 @@ class Collapse extends BaseComponent { // Static static collapseInterface(element, config) { - let data = Data.getData(element, DATA_KEY) + let data = Data.get(element, DATA_KEY) const _config = { ...Default, ...Manipulator.getDataAttributes(element), @@ -380,7 +380,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function ( const selectorElements = SelectorEngine.find(selector) selectorElements.forEach(element => { - const data = Data.getData(element, DATA_KEY) + const data = Data.get(element, DATA_KEY) let config if (data) { // update parent attribute diff --git a/js/src/dom/data.js b/js/src/dom/data.js index c93a8dc7c5..1d283d68b8 100644 --- a/js/src/dom/data.js +++ b/js/src/dom/data.js @@ -11,57 +11,47 @@ * ------------------------------------------------------------------------ */ -const mapData = (() => { - const storeData = {} - let id = 1 - return { - set(element, key, data) { - if (typeof element.bsKey === 'undefined') { - element.bsKey = { - key, - id - } - id++ - } +const elementMap = new Map() - storeData[element.bsKey.id] = data - }, - get(element, key) { - if (!element || typeof element.bsKey === 'undefined') { - return null - } - - const keyProperties = element.bsKey - if (keyProperties.key === key) { - return storeData[keyProperties.id] - } +export default { + set(element, key, instance) { + if (!elementMap.has(element)) { + elementMap.set(element, new Map()) + } - return null - }, - delete(element, key) { - if (typeof element.bsKey === 'undefined') { - return - } + const instanceMap = elementMap.get(element) - const keyProperties = element.bsKey - if (keyProperties.key === key) { - delete storeData[keyProperties.id] - delete element.bsKey - } + // make it clear we only want one instance per element + // can be removed later when multiple key/instances are fine to be used + if (!instanceMap.has(key) && instanceMap.size !== 0) { + // eslint-disable-next-line no-console + console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`) + return } - } -})() -const Data = { - setData(instance, key, data) { - mapData.set(instance, key, data) + instanceMap.set(key, instance) }, - getData(instance, key) { - return mapData.get(instance, key) + + get(element, key) { + if (elementMap.has(element)) { + return elementMap.get(element).get(key) || null + } + + return null }, - removeData(instance, key) { - mapData.delete(instance, key) + + remove(element, key) { + if (!elementMap.has(element)) { + return + } + + const instanceMap = elementMap.get(element) + + instanceMap.delete(key) + + // free up element references if there are no instances left for an element + if (instanceMap.size === 0) { + elementMap.delete(element) + } } } - -export default Data diff --git a/js/src/dropdown.js b/js/src/dropdown.js index 590c748012..fea0b1919b 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -357,7 +357,7 @@ class Dropdown extends BaseComponent { // Static static dropdownInterface(element, config) { - let data = Data.getData(element, DATA_KEY) + let data = Data.get(element, DATA_KEY) const _config = typeof config === 'object' ? config : null if (!data) { @@ -387,7 +387,7 @@ class Dropdown extends BaseComponent { const toggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE) for (let i = 0, len = toggles.length; i < len; i++) { - const context = Data.getData(toggles[i], DATA_KEY) + const context = Data.get(toggles[i], DATA_KEY) const relatedTarget = { relatedTarget: toggles[i] } diff --git a/js/src/modal.js b/js/src/modal.js index 5afb9791b4..332d636d0f 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -508,7 +508,7 @@ class Modal extends BaseComponent { static jQueryInterface(config, relatedTarget) { return this.each(function () { - let data = Data.getData(this, DATA_KEY) + let data = Data.get(this, DATA_KEY) const _config = { ...Default, ...Manipulator.getDataAttributes(this), @@ -556,7 +556,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function ( }) }) - let data = Data.getData(target, DATA_KEY) + let data = Data.get(target, DATA_KEY) if (!data) { const config = { ...Manipulator.getDataAttributes(target), diff --git a/js/src/popover.js b/js/src/popover.js index 0677dafa09..5535447547 100644 --- a/js/src/popover.js +++ b/js/src/popover.js @@ -136,7 +136,7 @@ class Popover extends Tooltip { static jQueryInterface(config) { return this.each(function () { - let data = Data.getData(this, DATA_KEY) + let data = Data.get(this, DATA_KEY) const _config = typeof config === 'object' ? config : null if (!data && /dispose|hide/.test(config)) { @@ -145,7 +145,7 @@ class Popover extends Tooltip { if (!data) { data = new Popover(this, _config) - Data.setData(this, DATA_KEY, data) + Data.set(this, DATA_KEY, data) } if (typeof config === 'string') { diff --git a/js/src/scrollspy.js b/js/src/scrollspy.js index 0c51eab0fe..c7472439be 100644 --- a/js/src/scrollspy.js +++ b/js/src/scrollspy.js @@ -278,7 +278,7 @@ class ScrollSpy extends BaseComponent { static jQueryInterface(config) { return this.each(function () { - let data = Data.getData(this, DATA_KEY) + let data = Data.get(this, DATA_KEY) const _config = typeof config === 'object' && config if (!data) { diff --git a/js/src/tab.js b/js/src/tab.js index e60ecddb56..95968f4f8b 100644 --- a/js/src/tab.js +++ b/js/src/tab.js @@ -182,7 +182,7 @@ class Tab extends BaseComponent { static jQueryInterface(config) { return this.each(function () { - const data = Data.getData(this, DATA_KEY) || new Tab(this) + const data = Data.get(this, DATA_KEY) || new Tab(this) if (typeof config === 'string') { if (typeof data[config] === 'undefined') { @@ -204,7 +204,7 @@ class Tab extends BaseComponent { EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { event.preventDefault() - const data = Data.getData(this, DATA_KEY) || new Tab(this) + const data = Data.get(this, DATA_KEY) || new Tab(this) data.show() }) diff --git a/js/src/toast.js b/js/src/toast.js index 2f451aab76..ea91163d84 100644 --- a/js/src/toast.js +++ b/js/src/toast.js @@ -189,7 +189,7 @@ class Toast extends BaseComponent { static jQueryInterface(config) { return this.each(function () { - let data = Data.getData(this, DATA_KEY) + let data = Data.get(this, DATA_KEY) const _config = typeof config === 'object' && config if (!data) { diff --git a/js/src/tooltip.js b/js/src/tooltip.js index d35b5e0ab1..6f33245f8e 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -275,7 +275,7 @@ class Tooltip extends BaseComponent { this._addAttachmentClass(attachment) const container = this._getContainer() - Data.setData(tip, this.constructor.DATA_KEY, this) + Data.set(tip, this.constructor.DATA_KEY, this) if (!this._element.ownerDocument.documentElement.contains(this.tip)) { container.appendChild(tip) @@ -465,11 +465,11 @@ class Tooltip extends BaseComponent { _initializeOnDelegatedTarget(event, context) { const dataKey = this.constructor.DATA_KEY - context = context || Data.getData(event.delegateTarget, dataKey) + context = context || Data.get(event.delegateTarget, dataKey) if (!context) { context = new this.constructor(event.delegateTarget, this._getDelegateConfig()) - Data.setData(event.delegateTarget, dataKey, context) + Data.set(event.delegateTarget, dataKey, context) } return context @@ -761,7 +761,7 @@ class Tooltip extends BaseComponent { static jQueryInterface(config) { return this.each(function () { - let data = Data.getData(this, DATA_KEY) + let data = Data.get(this, DATA_KEY) const _config = typeof config === 'object' && config if (!data && /dispose|hide/.test(config)) { |