From c348ad4a941cf309de9073d5db02814453469369 Mon Sep 17 00:00:00 2001 From: Rohit Sharma Date: Wed, 25 Nov 2020 12:46:22 +0530 Subject: [PATCH 01/17] Ability to add custom class in tooltip/popover (#32217) Porting of #31834 to main. Co-authored-by: XhmikosR --- .bundlewatch.config.json | 2 +- js/src/tooltip.js | 7 +++ js/tests/unit/popover.spec.js | 16 ++++++ js/tests/unit/tooltip.spec.js | 55 ++++++++++++++++++++ site/content/docs/5.0/components/popovers.md | 9 ++++ site/content/docs/5.0/components/tooltips.md | 9 ++++ 6 files changed, 97 insertions(+), 1 deletion(-) diff --git a/.bundlewatch.config.json b/.bundlewatch.config.json index 4bfffbab4..525d29f6a 100644 --- a/.bundlewatch.config.json +++ b/.bundlewatch.config.json @@ -38,7 +38,7 @@ }, { "path": "./dist/js/bootstrap.bundle.min.js", - "maxSize": "22 kB" + "maxSize": "22.25 kB" }, { "path": "./dist/js/bootstrap.esm.js", diff --git a/js/src/tooltip.js b/js/src/tooltip.js index b2495a3e1..368e04b30 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -54,6 +54,7 @@ const DefaultType = { container: '(string|element|boolean)', fallbackPlacement: '(string|array)', boundary: '(string|element)', + customClass: '(string|function)', sanitize: 'boolean', sanitizeFn: '(null|function)', allowList: 'object', @@ -83,6 +84,7 @@ const Default = { container: false, fallbackPlacement: 'flip', boundary: 'scrollParent', + customClass: '', sanitize: true, sanitizeFn: null, allowList: DefaultAllowlist, @@ -296,6 +298,11 @@ class Tooltip { tip.classList.add(CLASS_NAME_SHOW) + const customClass = typeof this.config.customClass === 'function' ? this.config.customClass() : this.config.customClass + if (customClass) { + tip.classList.add(...customClass.split(' ')) + } + // 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 diff --git a/js/tests/unit/popover.spec.js b/js/tests/unit/popover.spec.js index df4830595..e87ed1214 100644 --- a/js/tests/unit/popover.spec.js +++ b/js/tests/unit/popover.spec.js @@ -116,6 +116,22 @@ describe('Popover', () => { popover.show() }) + + it('should show a popover with provided custom class', done => { + fixtureEl.innerHTML = 'BS twitter' + + const popoverEl = fixtureEl.querySelector('a') + const popover = new Popover(popoverEl) + + popoverEl.addEventListener('shown.bs.popover', () => { + const tip = document.querySelector('.popover') + expect(tip).toBeDefined() + expect(tip.classList.contains('custom-class')).toBeTrue() + done() + }) + + popover.show() + }) }) describe('hide', () => { diff --git a/js/tests/unit/tooltip.spec.js b/js/tests/unit/tooltip.spec.js index c781f587a..da2abba31 100644 --- a/js/tests/unit/tooltip.spec.js +++ b/js/tests/unit/tooltip.spec.js @@ -632,6 +632,61 @@ describe('Tooltip', () => { tooltipEl.dispatchEvent(createEvent('mouseover')) }) + + it('should show a tooltip with custom class provided in data attributes', done => { + fixtureEl.innerHTML = '' + + const tooltipEl = fixtureEl.querySelector('a') + const tooltip = new Tooltip(tooltipEl) + + tooltipEl.addEventListener('shown.bs.tooltip', () => { + const tip = document.querySelector('.tooltip') + expect(tip).toBeDefined() + expect(tip.classList.contains('custom-class')).toBeTrue() + done() + }) + + tooltip.show() + }) + + it('should show a tooltip with custom class provided as a string in config', done => { + fixtureEl.innerHTML = '' + + const tooltipEl = fixtureEl.querySelector('a') + const tooltip = new Tooltip(tooltipEl, { + customClass: 'custom-class custom-class-2' + }) + + tooltipEl.addEventListener('shown.bs.tooltip', () => { + const tip = document.querySelector('.tooltip') + expect(tip).toBeDefined() + expect(tip.classList.contains('custom-class')).toBeTrue() + expect(tip.classList.contains('custom-class-2')).toBeTrue() + done() + }) + + tooltip.show() + }) + + it('should show a tooltip with custom class provided as a function in config', done => { + fixtureEl.innerHTML = '' + + const spy = jasmine.createSpy('customClass').and.returnValue('custom-class') + const tooltipEl = fixtureEl.querySelector('a') + const tooltip = new Tooltip(tooltipEl, { + customClass: spy + }) + + tooltipEl.addEventListener('shown.bs.tooltip', () => { + const tip = document.querySelector('.tooltip') + expect(tip).toBeDefined() + expect(spy).toHaveBeenCalled() + expect(tip.classList.contains('custom-class')).toBeTrue() + done() + }) + + tooltip.show() + }) }) describe('hide', () => { diff --git a/site/content/docs/5.0/components/popovers.md b/site/content/docs/5.0/components/popovers.md index c1e1f9017..86efe909e 100644 --- a/site/content/docs/5.0/components/popovers.md +++ b/site/content/docs/5.0/components/popovers.md @@ -262,6 +262,15 @@ Note that for security reasons the `sanitize`, `sanitizeFn`, and `allowList` opt 'scrollParent' Overflow constraint boundary of the popover. Accepts the values of 'viewport', 'window', 'scrollParent', or an HTMLElement reference (JavaScript only). For more information refer to Popper's preventOverflow docs. + + customClass + string | function + '' + +

Add classes to the popover when it is shown. Note that these classes will be added in addition to any classes specified in the template. To add multiple classes, separate them with spaces: 'class-1 class-2'.

+

You can also pass a function that should return a single string containing additional class names.

+ + sanitize boolean diff --git a/site/content/docs/5.0/components/tooltips.md b/site/content/docs/5.0/components/tooltips.md index 58c1bf9db..a4e76bc06 100644 --- a/site/content/docs/5.0/components/tooltips.md +++ b/site/content/docs/5.0/components/tooltips.md @@ -271,6 +271,15 @@ Note that for security reasons the `sanitize`, `sanitizeFn`, and `allowList` opt 'scrollParent' Overflow constraint boundary of the tooltip. Accepts the values of 'viewport', 'window', 'scrollParent', or an HTMLElement reference (JavaScript only). For more information refer to Popper's preventOverflow docs. + + customClass + string | function + '' + +

Add classes to the tooltip when it is shown. Note that these classes will be added in addition to any classes specified in the template. To add multiple classes, separate them with spaces: 'class-1 class-2'.

+

You can also pass a function that should return a single string containing additional class names.

+ + sanitize boolean From 81ac002a02430869035e68a35aa722cf69cbb885 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Wed, 25 Nov 2020 09:29:16 +0200 Subject: [PATCH 02/17] npm scripts: run integration tests in parallel (#32232) --- package.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 7ef514d1c..b4545406c 100644 --- a/package.json +++ b/package.json @@ -40,10 +40,11 @@ "js-minify-standalone": "terser --compress --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.js.map,includeSources,url=bootstrap.min.js.map\" --output dist/js/bootstrap.min.js dist/js/bootstrap.js", "js-minify-standalone-esm": "terser --compress --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.esm.js.map,includeSources,url=bootstrap.esm.min.js.map\" --output dist/js/bootstrap.esm.min.js dist/js/bootstrap.esm.js", "js-minify-bundle": "terser --compress --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.bundle.js.map,includeSources,url=bootstrap.bundle.min.js.map\" --output dist/js/bootstrap.bundle.min.js dist/js/bootstrap.bundle.js", - "js-test": "npm-run-all --parallel js-test-karma js-test-jquery js-test-integration", + "js-test": "npm-run-all --parallel js-test-karma js-test-jquery js-test-integration-*", "js-debug": "cross-env DEBUG=true npm run js-test-karma", "js-test-karma": "karma start js/tests/karma.conf.js", - "js-test-integration": "rollup --config js/tests/integration/rollup.bundle.js && rollup --config js/tests/integration/rollup.bundle-modularity.js", + "js-test-integration-bundle": "rollup --config js/tests/integration/rollup.bundle.js", + "js-test-integration-modularity": "rollup --config js/tests/integration/rollup.bundle-modularity.js", "js-test-cloud": "cross-env BROWSER=true npm run js-test-karma", "js-test-jquery": "cross-env JQUERY=true npm run js-test-karma", "lint": "npm-run-all --parallel js-lint css-lint lockfile-lint", From c63aebc86ba05f0ebb420add653b80804c6a0cff Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Wed, 25 Nov 2020 18:31:34 +0200 Subject: [PATCH 03/17] homepage: fix wrong `alt` attribute (#32258) --- site/layouts/partials/home/masthead-followup.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/layouts/partials/home/masthead-followup.html b/site/layouts/partials/home/masthead-followup.html index d14febd4e..a2dbdc76b 100644 --- a/site/layouts/partials/home/masthead-followup.html +++ b/site/layouts/partials/home/masthead-followup.html @@ -81,7 +81,7 @@ Bootstrap Icons + alt="Bootstrap Themes" width="700" height="500" loading="lazy"> From 9f6b342dc710e4334b37ded90136efa1127a47cd Mon Sep 17 00:00:00 2001 From: Johann-S Date: Wed, 4 Sep 2019 17:58:29 +0300 Subject: [PATCH 04/17] create a base component --- js/src/alert.js | 19 +++------ js/src/base-component.js | 31 ++++++++++++++ js/src/button.js | 16 +++----- js/src/carousel.js | 14 ++++--- js/src/collapse.js | 14 ++++--- js/src/dropdown.js | 14 ++++--- js/src/modal.js | 14 ++++--- js/src/popover.js | 8 +--- js/src/scrollspy.js | 13 +++--- js/src/tab.js | 17 +++----- js/src/toast.js | 14 ++++--- js/src/tooltip.js | 72 ++++++++++++++++----------------- js/tests/unit/alert.spec.js | 20 +++++++++ js/tests/unit/button.spec.js | 20 +++++++++ js/tests/unit/carousel.spec.js | 20 +++++++++ js/tests/unit/collapse.spec.js | 1 + js/tests/unit/dropdown.spec.js | 1 + js/tests/unit/modal.spec.js | 1 + js/tests/unit/popover.spec.js | 1 + js/tests/unit/scrollspy.spec.js | 10 +++++ js/tests/unit/tab.spec.js | 1 + js/tests/unit/toast.spec.js | 1 + js/tests/unit/tooltip.spec.js | 20 +++++++++ 23 files changed, 229 insertions(+), 113 deletions(-) create mode 100644 js/src/base-component.js diff --git a/js/src/alert.js b/js/src/alert.js index 724cda017..6f4c0be8d 100644 --- a/js/src/alert.js +++ b/js/src/alert.js @@ -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 index 000000000..a6c7f36bd --- /dev/null +++ b/js/src/base-component.js @@ -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 diff --git a/js/src/button.js b/js/src/button.js index 42376943d..2694e7b78 100644 --- a/js/src/button.js +++ b/js/src/button.js @@ -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) - } } /** diff --git a/js/src/carousel.js b/js/src/carousel.js index c663efbea..6a035c9ab 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -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) - } } /** diff --git a/js/src/collapse.js b/js/src/collapse.js index 2ddcb0c04..c76426c7c 100644 --- a/js/src/collapse.js +++ b/js/src/collapse.js @@ -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) - } } /** diff --git a/js/src/dropdown.js b/js/src/dropdown.js index b9f5a4cd3..16d35b911 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -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) - } } /** diff --git a/js/src/modal.js b/js/src/modal.js index 4309cbd9a..1e7ce0346 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -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) - } } /** diff --git a/js/src/popover.js b/js/src/popover.js index 46b693e69..bae5537aa 100644 --- a/js/src/popover.js +++ b/js/src/popover.js @@ -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) - } } /** diff --git a/js/src/scrollspy.js b/js/src/scrollspy.js index de456e080..6eb66f3b4 100644 --- a/js/src/scrollspy.js +++ b/js/src/scrollspy.js @@ -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) - } } /** diff --git a/js/src/tab.js b/js/src/tab.js index 56269e2fa..523810a39 100644 --- a/js/src/tab.js +++ b/js/src/tab.js @@ -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) - } } /** diff --git a/js/src/toast.js b/js/src/toast.js index 1e50b0669..c351139be 100644 --- a/js/src/toast.js +++ b/js/src/toast.js @@ -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) - } } /** diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 368e04b30..99f910efc 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -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) - } } /** diff --git a/js/tests/unit/alert.spec.js b/js/tests/unit/alert.spec.js index a746d8501..52643e575 100644 --- a/js/tests/unit/alert.spec.js +++ b/js/tests/unit/alert.spec.js @@ -170,4 +170,24 @@ describe('Alert', () => { expect(fixtureEl.querySelector('.alert')).not.toBeNull() }) }) + + describe('getInstance', () => { + it('should return alert instance', () => { + fixtureEl.innerHTML = '
' + + 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 = '
' + + const div = fixtureEl.querySelector('div') + + expect(Alert.getInstance(div)).toEqual(null) + }) + }) }) diff --git a/js/tests/unit/button.spec.js b/js/tests/unit/button.spec.js index 44d7b54b1..e7f6566ea 100644 --- a/js/tests/unit/button.spec.js +++ b/js/tests/unit/button.spec.js @@ -128,4 +128,24 @@ describe('Button', () => { expect(btnEl.classList.contains('active')).toEqual(false) }) }) + + describe('getInstance', () => { + it('should return button instance', () => { + fixtureEl.innerHTML = '
' + + 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 = '
' + + const div = fixtureEl.querySelector('div') + + expect(Button.getInstance(div)).toEqual(null) + }) + }) }) diff --git a/js/tests/unit/carousel.spec.js b/js/tests/unit/carousel.spec.js index 8c928c429..a21003dc5 100644 --- a/js/tests/unit/carousel.spec.js +++ b/js/tests/unit/carousel.spec.js @@ -1062,6 +1062,26 @@ describe('Carousel', () => { }) }) + describe('getInstance', () => { + it('should return carousel instance', () => { + fixtureEl.innerHTML = '
' + + 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 = '
' + + const div = fixtureEl.querySelector('div') + + expect(Carousel.getInstance(div)).toEqual(null) + }) + }) + describe('jQueryInterface', () => { it('should create a carousel', () => { fixtureEl.innerHTML = '
' diff --git a/js/tests/unit/collapse.spec.js b/js/tests/unit/collapse.spec.js index c1ead859a..e5c8c53b5 100644 --- a/js/tests/unit/collapse.spec.js +++ b/js/tests/unit/collapse.spec.js @@ -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', () => { diff --git a/js/tests/unit/dropdown.spec.js b/js/tests/unit/dropdown.spec.js index f5f41636c..96f677c02 100644 --- a/js/tests/unit/dropdown.spec.js +++ b/js/tests/unit/dropdown.spec.js @@ -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', () => { diff --git a/js/tests/unit/modal.spec.js b/js/tests/unit/modal.spec.js index 084f78ad1..8e8d4f0ff 100644 --- a/js/tests/unit/modal.spec.js +++ b/js/tests/unit/modal.spec.js @@ -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', () => { diff --git a/js/tests/unit/popover.spec.js b/js/tests/unit/popover.spec.js index e87ed1214..3a8342a80 100644 --- a/js/tests/unit/popover.spec.js +++ b/js/tests/unit/popover.spec.js @@ -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', () => { diff --git a/js/tests/unit/scrollspy.spec.js b/js/tests/unit/scrollspy.spec.js index 33298300c..303a336f4 100644 --- a/js/tests/unit/scrollspy.spec.js +++ b/js/tests/unit/scrollspy.spec.js @@ -634,6 +634,16 @@ describe('ScrollSpy', () => { }) describe('getInstance', () => { + it('should return scrollspy instance', () => { + fixtureEl.innerHTML = '
' + + 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) }) diff --git a/js/tests/unit/tab.spec.js b/js/tests/unit/tab.spec.js index 324c4a09b..7112dda18 100644 --- a/js/tests/unit/tab.spec.js +++ b/js/tests/unit/tab.spec.js @@ -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) }) }) diff --git a/js/tests/unit/toast.spec.js b/js/tests/unit/toast.spec.js index c4cb69a7f..60c7d9177 100644 --- a/js/tests/unit/toast.spec.js +++ b/js/tests/unit/toast.spec.js @@ -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', () => { diff --git a/js/tests/unit/tooltip.spec.js b/js/tests/unit/tooltip.spec.js index da2abba31..36316b42f 100644 --- a/js/tests/unit/tooltip.spec.js +++ b/js/tests/unit/tooltip.spec.js @@ -1030,6 +1030,26 @@ describe('Tooltip', () => { }) }) + describe('getInstance', () => { + it('should return tooltip instance', () => { + fixtureEl.innerHTML = '
' + + 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 = '
' + + const div = fixtureEl.querySelector('div') + + expect(Tooltip.getInstance(div)).toEqual(null) + }) + }) + describe('jQueryInterface', () => { it('should create a tooltip', () => { fixtureEl.innerHTML = '
' From 51a208f119522f8618801a6e61ff8d47cf89d4cf Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Mon, 16 Nov 2020 17:23:09 +0200 Subject: [PATCH 05/17] Switch to Jasmine's `toBeInstanceOf` matcher --- js/tests/unit/alert.spec.js | 2 +- js/tests/unit/button.spec.js | 2 +- js/tests/unit/carousel.spec.js | 2 +- js/tests/unit/collapse.spec.js | 2 +- js/tests/unit/dropdown.spec.js | 2 +- js/tests/unit/modal.spec.js | 2 +- js/tests/unit/popover.spec.js | 2 +- js/tests/unit/scrollspy.spec.js | 2 +- js/tests/unit/tab.spec.js | 2 +- js/tests/unit/toast.spec.js | 2 +- js/tests/unit/tooltip.spec.js | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/js/tests/unit/alert.spec.js b/js/tests/unit/alert.spec.js index 52643e575..a1322f1c7 100644 --- a/js/tests/unit/alert.spec.js +++ b/js/tests/unit/alert.spec.js @@ -179,7 +179,7 @@ describe('Alert', () => { const alert = new Alert(div) expect(Alert.getInstance(div)).toEqual(alert) - expect(Alert.getInstance(div) instanceof Alert).toEqual(true) + expect(Alert.getInstance(div)).toBeInstanceOf(Alert) }) it('should return null when there is no alert instance', () => { diff --git a/js/tests/unit/button.spec.js b/js/tests/unit/button.spec.js index e7f6566ea..51aa73774 100644 --- a/js/tests/unit/button.spec.js +++ b/js/tests/unit/button.spec.js @@ -137,7 +137,7 @@ describe('Button', () => { const button = new Button(div) expect(Button.getInstance(div)).toEqual(button) - expect(Button.getInstance(div) instanceof Button).toEqual(true) + expect(Button.getInstance(div)).toBeInstanceOf(Button) }) it('should return null when there is no button instance', () => { diff --git a/js/tests/unit/carousel.spec.js b/js/tests/unit/carousel.spec.js index a21003dc5..07b8fc311 100644 --- a/js/tests/unit/carousel.spec.js +++ b/js/tests/unit/carousel.spec.js @@ -1070,7 +1070,7 @@ describe('Carousel', () => { const carousel = new Carousel(div) expect(Carousel.getInstance(div)).toEqual(carousel) - expect(Carousel.getInstance(div) instanceof Carousel).toEqual(true) + expect(Carousel.getInstance(div)).toBeInstanceOf(Carousel) }) it('should return null when there is no carousel instance', () => { diff --git a/js/tests/unit/collapse.spec.js b/js/tests/unit/collapse.spec.js index e5c8c53b5..d53ab5964 100644 --- a/js/tests/unit/collapse.spec.js +++ b/js/tests/unit/collapse.spec.js @@ -812,7 +812,7 @@ describe('Collapse', () => { const collapse = new Collapse(div) expect(Collapse.getInstance(div)).toEqual(collapse) - expect(Collapse.getInstance(div) instanceof Collapse).toEqual(true) + expect(Collapse.getInstance(div)).toBeInstanceOf(Collapse) }) it('should return null when there is no collapse instance', () => { diff --git a/js/tests/unit/dropdown.spec.js b/js/tests/unit/dropdown.spec.js index 96f677c02..145763d20 100644 --- a/js/tests/unit/dropdown.spec.js +++ b/js/tests/unit/dropdown.spec.js @@ -1612,7 +1612,7 @@ describe('Dropdown', () => { const dropdown = new Dropdown(div) expect(Dropdown.getInstance(div)).toEqual(dropdown) - expect(Dropdown.getInstance(div) instanceof Dropdown).toEqual(true) + expect(Dropdown.getInstance(div)).toBeInstanceOf(Dropdown) }) it('should return null when there is no dropdown instance', () => { diff --git a/js/tests/unit/modal.spec.js b/js/tests/unit/modal.spec.js index 8e8d4f0ff..f645e9892 100644 --- a/js/tests/unit/modal.spec.js +++ b/js/tests/unit/modal.spec.js @@ -1108,7 +1108,7 @@ describe('Modal', () => { const modal = new Modal(div) expect(Modal.getInstance(div)).toEqual(modal) - expect(Modal.getInstance(div) instanceof Modal).toEqual(true) + expect(Modal.getInstance(div)).toBeInstanceOf(Modal) }) it('should return null when there is no modal instance', () => { diff --git a/js/tests/unit/popover.spec.js b/js/tests/unit/popover.spec.js index 3a8342a80..3c04e7ac1 100644 --- a/js/tests/unit/popover.spec.js +++ b/js/tests/unit/popover.spec.js @@ -253,7 +253,7 @@ describe('Popover', () => { const popover = new Popover(popoverEl) expect(Popover.getInstance(popoverEl)).toEqual(popover) - expect(Popover.getInstance(popoverEl) instanceof Popover).toEqual(true) + expect(Popover.getInstance(popoverEl)).toBeInstanceOf(Popover) }) it('should return null when there is no popover instance', () => { diff --git a/js/tests/unit/scrollspy.spec.js b/js/tests/unit/scrollspy.spec.js index 303a336f4..45de56fbe 100644 --- a/js/tests/unit/scrollspy.spec.js +++ b/js/tests/unit/scrollspy.spec.js @@ -641,7 +641,7 @@ describe('ScrollSpy', () => { const scrollSpy = new ScrollSpy(div) expect(ScrollSpy.getInstance(div)).toEqual(scrollSpy) - expect(ScrollSpy.getInstance(div) instanceof ScrollSpy).toEqual(true) + expect(ScrollSpy.getInstance(div)).toBeInstanceOf(ScrollSpy) }) it('should return null if there is no instance', () => { diff --git a/js/tests/unit/tab.spec.js b/js/tests/unit/tab.spec.js index 7112dda18..67a85b2e4 100644 --- a/js/tests/unit/tab.spec.js +++ b/js/tests/unit/tab.spec.js @@ -417,7 +417,7 @@ describe('Tab', () => { const tab = new Tab(divEl) expect(Tab.getInstance(divEl)).toEqual(tab) - expect(Tab.getInstance(divEl) instanceof Tab).toEqual(true) + expect(Tab.getInstance(divEl)).toBeInstanceOf(Tab) }) }) diff --git a/js/tests/unit/toast.spec.js b/js/tests/unit/toast.spec.js index 60c7d9177..a4ab4f76c 100644 --- a/js/tests/unit/toast.spec.js +++ b/js/tests/unit/toast.spec.js @@ -384,7 +384,7 @@ describe('Toast', () => { const toast = new Toast(div) expect(Toast.getInstance(div)).toEqual(toast) - expect(Toast.getInstance(div) instanceof Toast).toEqual(true) + expect(Toast.getInstance(div)).toBeInstanceOf(Toast) }) it('should return null when there is no toast instance', () => { diff --git a/js/tests/unit/tooltip.spec.js b/js/tests/unit/tooltip.spec.js index 36316b42f..e8572b300 100644 --- a/js/tests/unit/tooltip.spec.js +++ b/js/tests/unit/tooltip.spec.js @@ -1038,7 +1038,7 @@ describe('Tooltip', () => { const alert = new Tooltip(div) expect(Tooltip.getInstance(div)).toEqual(alert) - expect(Tooltip.getInstance(div) instanceof Tooltip).toEqual(true) + expect(Tooltip.getInstance(div)).toBeInstanceOf(Tooltip) }) it('should return null when there is no tooltip instance', () => { From 9eb9d02084dc914e614e8844e3ffdee4d0a25126 Mon Sep 17 00:00:00 2001 From: Johann-S Date: Fri, 20 Nov 2020 11:13:11 +0100 Subject: [PATCH 06/17] add dispose in base component --- js/src/alert.js | 5 ----- js/src/base-component.js | 5 +++++ js/src/button.js | 5 ----- js/src/carousel.js | 3 +-- js/src/collapse.js | 4 +--- js/src/dropdown.js | 3 +-- js/src/modal.js | 5 ++--- js/src/scrollspy.js | 3 +-- js/src/tab.js | 5 ----- js/src/toast.js | 3 +-- js/src/tooltip.js | 4 +--- 11 files changed, 13 insertions(+), 32 deletions(-) diff --git a/js/src/alert.js b/js/src/alert.js index 6f4c0be8d..41cff54db 100644 --- a/js/src/alert.js +++ b/js/src/alert.js @@ -69,11 +69,6 @@ class Alert extends BaseComponent { this._removeElement(rootElement) } - dispose() { - Data.removeData(this._element, DATA_KEY) - this._element = null - } - // Private _getRootElement(element) { diff --git a/js/src/base-component.js b/js/src/base-component.js index a6c7f36bd..b1b85a4ee 100644 --- a/js/src/base-component.js +++ b/js/src/base-component.js @@ -17,6 +17,11 @@ class BaseComponent { Data.setData(element, this.constructor.DATA_KEY, this) } + dispose() { + Data.removeData(this._element, this.constructor.DATA_KEY) + this._element = null + } + /** Static */ static getInstance(element) { diff --git a/js/src/button.js b/js/src/button.js index 2694e7b78..8b7c6c953 100644 --- a/js/src/button.js +++ b/js/src/button.js @@ -52,11 +52,6 @@ class Button extends BaseComponent { this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE)) } - dispose() { - Data.removeData(this._element, DATA_KEY) - this._element = null - } - // Static static jQueryInterface(config) { diff --git a/js/src/carousel.js b/js/src/carousel.js index 6a035c9ab..35a1848f8 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -224,12 +224,11 @@ class Carousel extends BaseComponent { } dispose() { + super.dispose() EventHandler.off(this._element, EVENT_KEY) - Data.removeData(this._element, DATA_KEY) this._items = null this._config = null - this._element = null this._interval = null this._isPaused = null this._isSliding = null diff --git a/js/src/collapse.js b/js/src/collapse.js index c76426c7c..9fb4d5ede 100644 --- a/js/src/collapse.js +++ b/js/src/collapse.js @@ -272,11 +272,9 @@ class Collapse extends BaseComponent { } dispose() { - Data.removeData(this._element, DATA_KEY) - + super.dispose() this._config = null this._parent = null - this._element = null this._triggerArray = null this._isTransitioning = null } diff --git a/js/src/dropdown.js b/js/src/dropdown.js index 16d35b911..3641d9f9d 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -235,9 +235,8 @@ class Dropdown extends BaseComponent { } dispose() { - Data.removeData(this._element, DATA_KEY) + super.dispose() EventHandler.off(this._element, EVENT_KEY) - this._element = null this._menu = null if (this._popper) { this._popper.destroy() diff --git a/js/src/modal.js b/js/src/modal.js index 1e7ce0346..449721caf 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -207,6 +207,8 @@ class Modal extends BaseComponent { [window, this._element, this._dialog] .forEach(htmlElement => EventHandler.off(htmlElement, EVENT_KEY)) + super.dispose() + /** * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API` * Do not move `document` in `htmlElements` array @@ -214,10 +216,7 @@ class Modal extends BaseComponent { */ EventHandler.off(document, EVENT_FOCUSIN) - Data.removeData(this._element, DATA_KEY) - this._config = null - this._element = null this._dialog = null this._backdrop = null this._isShown = null diff --git a/js/src/scrollspy.js b/js/src/scrollspy.js index 6eb66f3b4..0df00e8f7 100644 --- a/js/src/scrollspy.js +++ b/js/src/scrollspy.js @@ -146,10 +146,9 @@ class ScrollSpy extends BaseComponent { } dispose() { - Data.removeData(this._element, DATA_KEY) + super.dispose() EventHandler.off(this._scrollElement, EVENT_KEY) - this._element = null this._scrollElement = null this._config = null this._selector = null diff --git a/js/src/tab.js b/js/src/tab.js index 523810a39..a57d1b12d 100644 --- a/js/src/tab.js +++ b/js/src/tab.js @@ -126,11 +126,6 @@ class Tab extends BaseComponent { } } - dispose() { - Data.removeData(this._element, DATA_KEY) - this._element = null - } - // Private _activate(element, container, callback) { diff --git a/js/src/toast.js b/js/src/toast.js index c351139be..04917869d 100644 --- a/js/src/toast.js +++ b/js/src/toast.js @@ -165,9 +165,8 @@ class Toast extends BaseComponent { } EventHandler.off(this._element, EVENT_CLICK_DISMISS) - Data.removeData(this._element, DATA_KEY) - this._element = null + super.dispose() this._config = null } diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 99f910efc..b84432065 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -229,8 +229,6 @@ class Tooltip extends BaseComponent { dispose() { clearTimeout(this._timeout) - 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) @@ -247,9 +245,9 @@ class Tooltip extends BaseComponent { } this._popper = null - this._element = null this.config = null this.tip = null + super.dispose() } show() { From f6a87337416f900773268db9fc4307538c7daf88 Mon Sep 17 00:00:00 2001 From: Rohit Sharma Date: Wed, 25 Nov 2020 12:43:33 +0530 Subject: [PATCH 07/17] Move `VERSION` to BaseComponent (#32254) --- js/src/alert.js | 5 ----- js/src/base-component.js | 12 ++++++++++++ js/src/button.js | 5 ----- js/src/carousel.js | 5 ----- js/src/collapse.js | 5 ----- js/src/dropdown.js | 5 ----- js/src/modal.js | 5 ----- js/src/popover.js | 5 ----- js/src/scrollspy.js | 5 ----- js/src/tab.js | 5 ----- js/src/toast.js | 5 ----- js/src/tooltip.js | 5 ----- 12 files changed, 12 insertions(+), 55 deletions(-) diff --git a/js/src/alert.js b/js/src/alert.js index 41cff54db..f1f612232 100644 --- a/js/src/alert.js +++ b/js/src/alert.js @@ -24,7 +24,6 @@ import BaseComponent from './base-component' */ const NAME = 'alert' -const VERSION = '5.0.0-alpha3' const DATA_KEY = 'bs.alert' const EVENT_KEY = `.${DATA_KEY}` const DATA_API_KEY = '.data-api' @@ -48,10 +47,6 @@ const CLASSNAME_SHOW = 'show' class Alert extends BaseComponent { // Getters - static get VERSION() { - return VERSION - } - static get DATA_KEY() { return DATA_KEY } diff --git a/js/src/base-component.js b/js/src/base-component.js index b1b85a4ee..e9b4de669 100644 --- a/js/src/base-component.js +++ b/js/src/base-component.js @@ -7,6 +7,14 @@ import Data from './dom/data' +/** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + +const VERSION = '5.0.0-alpha3' + class BaseComponent { constructor(element) { if (!element) { @@ -28,6 +36,10 @@ class BaseComponent { return Data.getData(element, this.DATA_KEY) } + static get VERSION() { + return VERSION + } + static get DATA_KEY() { return null } diff --git a/js/src/button.js b/js/src/button.js index 8b7c6c953..240995564 100644 --- a/js/src/button.js +++ b/js/src/button.js @@ -17,7 +17,6 @@ import BaseComponent from './base-component' */ const NAME = 'button' -const VERSION = '5.0.0-alpha3' const DATA_KEY = 'bs.button' const EVENT_KEY = `.${DATA_KEY}` const DATA_API_KEY = '.data-api' @@ -37,10 +36,6 @@ const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` class Button extends BaseComponent { // Getters - static get VERSION() { - return VERSION - } - static get DATA_KEY() { return DATA_KEY } diff --git a/js/src/carousel.js b/js/src/carousel.js index 35a1848f8..7d2b4dc50 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -30,7 +30,6 @@ import BaseComponent from './base-component' */ const NAME = 'carousel' -const VERSION = '5.0.0-alpha3' const DATA_KEY = 'bs.carousel' const EVENT_KEY = `.${DATA_KEY}` const DATA_API_KEY = '.data-api' @@ -129,10 +128,6 @@ class Carousel extends BaseComponent { // Getters - static get VERSION() { - return VERSION - } - static get Default() { return Default } diff --git a/js/src/collapse.js b/js/src/collapse.js index 9fb4d5ede..da3e504d1 100644 --- a/js/src/collapse.js +++ b/js/src/collapse.js @@ -30,7 +30,6 @@ import BaseComponent from './base-component' */ const NAME = 'collapse' -const VERSION = '5.0.0-alpha3' const DATA_KEY = 'bs.collapse' const EVENT_KEY = `.${DATA_KEY}` const DATA_API_KEY = '.data-api' @@ -108,10 +107,6 @@ class Collapse extends BaseComponent { // Getters - static get VERSION() { - return VERSION - } - static get Default() { return Default } diff --git a/js/src/dropdown.js b/js/src/dropdown.js index 3641d9f9d..f9c945c33 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -28,7 +28,6 @@ import BaseComponent from './base-component' */ const NAME = 'dropdown' -const VERSION = '5.0.0-alpha3' const DATA_KEY = 'bs.dropdown' const EVENT_KEY = `.${DATA_KEY}` const DATA_API_KEY = '.data-api' @@ -112,10 +111,6 @@ class Dropdown extends BaseComponent { // Getters - static get VERSION() { - return VERSION - } - static get Default() { return Default } diff --git a/js/src/modal.js b/js/src/modal.js index 449721caf..e3fe487a8 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -29,7 +29,6 @@ import BaseComponent from './base-component' */ const NAME = 'modal' -const VERSION = '5.0.0-alpha3' const DATA_KEY = 'bs.modal' const EVENT_KEY = `.${DATA_KEY}` const DATA_API_KEY = '.data-api' @@ -99,10 +98,6 @@ class Modal extends BaseComponent { // Getters - static get VERSION() { - return VERSION - } - static get Default() { return Default } diff --git a/js/src/popover.js b/js/src/popover.js index bae5537aa..97db9a3f7 100644 --- a/js/src/popover.js +++ b/js/src/popover.js @@ -17,7 +17,6 @@ import Tooltip from './tooltip' */ const NAME = 'popover' -const VERSION = '5.0.0-alpha3' const DATA_KEY = 'bs.popover' const EVENT_KEY = `.${DATA_KEY}` const CLASS_PREFIX = 'bs-popover' @@ -67,10 +66,6 @@ const SELECTOR_CONTENT = '.popover-body' class Popover extends Tooltip { // Getters - static get VERSION() { - return VERSION - } - static get Default() { return Default } diff --git a/js/src/scrollspy.js b/js/src/scrollspy.js index 0df00e8f7..4e88a2321 100644 --- a/js/src/scrollspy.js +++ b/js/src/scrollspy.js @@ -26,7 +26,6 @@ import BaseComponent from './base-component' */ const NAME = 'scrollspy' -const VERSION = '5.0.0-alpha3' const DATA_KEY = 'bs.scrollspy' const EVENT_KEY = `.${DATA_KEY}` const DATA_API_KEY = '.data-api' @@ -88,10 +87,6 @@ class ScrollSpy extends BaseComponent { // Getters - static get VERSION() { - return VERSION - } - static get Default() { return Default } diff --git a/js/src/tab.js b/js/src/tab.js index a57d1b12d..0e9755ea0 100644 --- a/js/src/tab.js +++ b/js/src/tab.js @@ -26,7 +26,6 @@ import BaseComponent from './base-component' */ const NAME = 'tab' -const VERSION = '5.0.0-alpha3' const DATA_KEY = 'bs.tab' const EVENT_KEY = `.${DATA_KEY}` const DATA_API_KEY = '.data-api' @@ -60,10 +59,6 @@ const SELECTOR_DROPDOWN_ACTIVE_CHILD = ':scope > .dropdown-menu .active' class Tab extends BaseComponent { // Getters - static get VERSION() { - return VERSION - } - static get DATA_KEY() { return DATA_KEY } diff --git a/js/src/toast.js b/js/src/toast.js index 04917869d..065c6c753 100644 --- a/js/src/toast.js +++ b/js/src/toast.js @@ -26,7 +26,6 @@ import BaseComponent from './base-component' */ const NAME = 'toast' -const VERSION = '5.0.0-alpha3' const DATA_KEY = 'bs.toast' const EVENT_KEY = `.${DATA_KEY}` @@ -73,10 +72,6 @@ class Toast extends BaseComponent { // Getters - static get VERSION() { - return VERSION - } - static get DefaultType() { return DefaultType } diff --git a/js/src/tooltip.js b/js/src/tooltip.js index b84432065..fae606322 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -35,7 +35,6 @@ import BaseComponent from './base-component' */ const NAME = 'tooltip' -const VERSION = '5.0.0-alpha3' const DATA_KEY = 'bs.tooltip' const EVENT_KEY = `.${DATA_KEY}` const CLASS_PREFIX = 'bs-tooltip' @@ -150,10 +149,6 @@ class Tooltip extends BaseComponent { // Getters - static get VERSION() { - return VERSION - } - static get Default() { return Default } From 4999c3dbbc87e125c4b2bde405e4ecdccc5d0b18 Mon Sep 17 00:00:00 2001 From: Johann-S Date: Wed, 25 Nov 2020 08:25:27 +0100 Subject: [PATCH 08/17] remove data key in base component --- js/src/base-component.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/js/src/base-component.js b/js/src/base-component.js index e9b4de669..776a0052b 100644 --- a/js/src/base-component.js +++ b/js/src/base-component.js @@ -39,10 +39,6 @@ class BaseComponent { static get VERSION() { return VERSION } - - static get DATA_KEY() { - return null - } } export default BaseComponent From 04674f88b0a2f7ad21bbe36a8d18b08357c8eafa Mon Sep 17 00:00:00 2001 From: Rohit Sharma Date: Sun, 29 Nov 2020 23:18:00 +0530 Subject: [PATCH 09/17] Remove setData from construtors (#32264) --- js/src/carousel.js | 1 - js/src/collapse.js | 2 -- js/src/dropdown.js | 1 - js/src/modal.js | 1 - js/src/scrollspy.js | 2 -- js/src/toast.js | 1 - js/src/tooltip.js | 1 - 7 files changed, 9 deletions(-) diff --git a/js/src/carousel.js b/js/src/carousel.js index 7d2b4dc50..6443ef094 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -123,7 +123,6 @@ class Carousel extends BaseComponent { this._pointerEvent = Boolean(window.PointerEvent) this._addEventListeners() - Data.setData(element, DATA_KEY, this) } // Getters diff --git a/js/src/collapse.js b/js/src/collapse.js index da3e504d1..feff6c917 100644 --- a/js/src/collapse.js +++ b/js/src/collapse.js @@ -101,8 +101,6 @@ class Collapse extends BaseComponent { if (this._config.toggle) { this.toggle() } - - Data.setData(element, DATA_KEY, this) } // Getters diff --git a/js/src/dropdown.js b/js/src/dropdown.js index f9c945c33..5b8ae0645 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -106,7 +106,6 @@ class Dropdown extends BaseComponent { this._inNavbar = this._detectNavbar() this._addEventListeners() - Data.setData(element, DATA_KEY, this) } // Getters diff --git a/js/src/modal.js b/js/src/modal.js index e3fe487a8..db8345fac 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -93,7 +93,6 @@ class Modal extends BaseComponent { this._ignoreBackdropClick = false this._isTransitioning = false this._scrollbarWidth = 0 - Data.setData(element, DATA_KEY, this) } // Getters diff --git a/js/src/scrollspy.js b/js/src/scrollspy.js index 4e88a2321..e3e5e76b9 100644 --- a/js/src/scrollspy.js +++ b/js/src/scrollspy.js @@ -81,8 +81,6 @@ class ScrollSpy extends BaseComponent { this.refresh() this._process() - - Data.setData(element, DATA_KEY, this) } // Getters diff --git a/js/src/toast.js b/js/src/toast.js index 065c6c753..30df4606a 100644 --- a/js/src/toast.js +++ b/js/src/toast.js @@ -67,7 +67,6 @@ class Toast extends BaseComponent { this._config = this._getConfig(config) this._timeout = null this._setListeners() - Data.setData(element, DATA_KEY, this) } // Getters diff --git a/js/src/tooltip.js b/js/src/tooltip.js index fae606322..797afb134 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -144,7 +144,6 @@ class Tooltip extends BaseComponent { this.tip = null this._setListeners() - Data.setData(element, this.constructor.DATA_KEY, this) } // Getters From 948f8343474d8fea4bf8fa01ad2d71e9428d53d8 Mon Sep 17 00:00:00 2001 From: "Patrick H. Lauke" Date: Mon, 30 Nov 2020 05:02:03 +0000 Subject: [PATCH 10/17] Add mention of link underline change to migration and typography (#32281) x-ref https://github.com/twbs/bootstrap/discussions/32276#discussioncomment-141850 Co-authored-by: XhmikosR --- site/content/docs/5.0/content/typography.md | 2 +- site/content/docs/5.0/migration.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/site/content/docs/5.0/content/typography.md b/site/content/docs/5.0/content/typography.md index b8e4f558a..d93702eea 100644 --- a/site/content/docs/5.0/content/typography.md +++ b/site/content/docs/5.0/content/typography.md @@ -13,7 +13,7 @@ Bootstrap sets basic global display, typography, and link styles. When more cont - Use a [native font stack]({{< docsref "/content/reboot#native-font-stack" >}}) that selects the best `font-family` for each OS and device. - For a more inclusive and accessible type scale, we use the browser's default root `font-size` (typically 16px) so visitors can customize their browser defaults as needed. - Use the `$font-family-base`, `$font-size-base`, and `$line-height-base` attributes as our typographic base applied to the ``. -- Set the global link color via `$link-color` and apply link underlines only on `:hover`. +- Set the global link color via `$link-color`. - Use `$body-bg` to set a `background-color` on the `` (`#fff` by default). These styles can be found within `_reboot.scss`, and the global variables are defined in `_variables.scss`. Make sure to set `$font-size-base` in `rem`. diff --git a/site/content/docs/5.0/migration.md b/site/content/docs/5.0/migration.md index dab1bd7df..296bdd427 100644 --- a/site/content/docs/5.0/migration.md +++ b/site/content/docs/5.0/migration.md @@ -267,6 +267,7 @@ Changes to Reboot, typography, tables, and more. - Removed individual `$display-*-weight` variables for a single `$display-font-weight`. - Added two new `.display-*` heading styles, `.display-5` and `.display-6`. - Resized existing display headings for a slightly more consistent set of `font-size`s. +- Links are underlined by default (not just on hover), unless they're part of specific components. ### Forms From ff25a7532062caf8b922ff8909a7e2db848242f5 Mon Sep 17 00:00:00 2001 From: Martijn Cuppens Date: Mon, 30 Nov 2020 09:51:32 +0100 Subject: [PATCH 11/17] Remove default linear gradient (#32277) Remove the default invisible gradient causing the performance issue in #32266. By removing the custom property, the linear gradient will become invalid, thus not appear by default. There can still be a performance issue with striped tables though. Co-authored-by: XhmikosR --- scss/_tables.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/scss/_tables.scss b/scss/_tables.scss index 1b2db3008..506c60be0 100644 --- a/scss/_tables.scss +++ b/scss/_tables.scss @@ -4,7 +4,6 @@ .table { --#{$variable-prefix}table-bg: #{$table-bg}; - --#{$variable-prefix}table-accent-bg: transparent; --#{$variable-prefix}table-striped-color: #{$table-striped-color}; --#{$variable-prefix}table-striped-bg: #{$table-striped-bg}; --#{$variable-prefix}table-active-color: #{$table-active-color}; From af5744440583e0a13ad637bc41e8e7a4074086fb Mon Sep 17 00:00:00 2001 From: Rohit Sharma Date: Mon, 30 Nov 2020 14:39:55 +0530 Subject: [PATCH 12/17] Keep rounded corners for the first .btn in vertical button group (#31303) Co-authored-by: XhmikosR --- scss/_button-group.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scss/_button-group.scss b/scss/_button-group.scss index 1571d1ea9..abb363a84 100644 --- a/scss/_button-group.scss +++ b/scss/_button-group.scss @@ -132,7 +132,7 @@ @include border-bottom-radius(0); } - > .btn:not(:first-child), + > .btn ~ .btn, > .btn-group:not(:first-child) > .btn { @include border-top-radius(0); } From b0372bb6588ab12c398e5dbf39950dfd3269575e Mon Sep 17 00:00:00 2001 From: Matty Williams Date: Wed, 29 May 2019 21:48:59 +0300 Subject: [PATCH 13/17] Accessibility update for tooltip.js Update to the tooltip.js to add an aria-label attribute that contains the original title of the element, but only if the element doesn't have an existing aria-label attribute. This is to address cases where screen readers are not capturing the aria-describedby attribute that is added when the tooltip is triggered. This should also avoid a race condition between the screen reader and the appearance of the tooltip. --- js/src/tooltip.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 797afb134..936a2a66f 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -584,6 +584,10 @@ class Tooltip extends BaseComponent { if (title || originalTitleType !== 'string') { this._element.setAttribute('data-bs-original-title', title || '') + if (!this._element.getAttribute('aria-label') && !this._element.textContent) { + this._element.setAttribute('aria-label', this._element.getAttribute('title') || '') + } + this._element.setAttribute('title', '') } } From adc857f617bfebe05d8f2ec294b1b2e37fac6cd8 Mon Sep 17 00:00:00 2001 From: "Patrick H. Lauke" Date: Tue, 10 Nov 2020 00:44:24 +0200 Subject: [PATCH 14/17] Extra check for existence of any `aria-label` before overwriting it... --- js/src/tooltip.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 936a2a66f..a04739b7f 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -584,8 +584,8 @@ class Tooltip extends BaseComponent { if (title || originalTitleType !== 'string') { this._element.setAttribute('data-bs-original-title', title || '') - if (!this._element.getAttribute('aria-label') && !this._element.textContent) { - this._element.setAttribute('aria-label', this._element.getAttribute('title') || '') + if (this._element.getAttribute('title') && !this._element.getAttribute('aria-label') && !this._element.textContent) { + this._element.setAttribute('aria-label', this._element.getAttribute('title')) } this._element.setAttribute('title', '') From dd992c722625a48d534a3a1e8c6edee38e91685d Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Tue, 10 Nov 2020 16:04:33 +0200 Subject: [PATCH 15/17] Add tests --- js/tests/unit/tooltip.spec.js | 53 +++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/js/tests/unit/tooltip.spec.js b/js/tests/unit/tooltip.spec.js index e8572b300..b11980751 100644 --- a/js/tests/unit/tooltip.spec.js +++ b/js/tests/unit/tooltip.spec.js @@ -1050,6 +1050,59 @@ describe('Tooltip', () => { }) }) + describe('aria-label', () => { + it('should add the aria-label attribute for referencing original title', done => { + fixtureEl.innerHTML = '' + + const tooltipEl = fixtureEl.querySelector('a') + const tooltip = new Tooltip(tooltipEl) + + tooltipEl.addEventListener('shown.bs.tooltip', () => { + const tooltipShown = document.querySelector('.tooltip') + + expect(tooltipShown).toBeDefined() + expect(tooltipEl.getAttribute('aria-label')).toEqual('Another tooltip') + done() + }) + + tooltip.show() + }) + + it('should not add the aria-label attribute if the attribute already exists', done => { + fixtureEl.innerHTML = '' + + const tooltipEl = fixtureEl.querySelector('a') + const tooltip = new Tooltip(tooltipEl) + + tooltipEl.addEventListener('shown.bs.tooltip', () => { + const tooltipShown = document.querySelector('.tooltip') + + expect(tooltipShown).toBeDefined() + expect(tooltipEl.getAttribute('aria-label')).toEqual('Different label') + done() + }) + + tooltip.show() + }) + + it('should not add the aria-label attribute if the element has text content', done => { + fixtureEl.innerHTML = 'text content' + + const tooltipEl = fixtureEl.querySelector('a') + const tooltip = new Tooltip(tooltipEl) + + tooltipEl.addEventListener('shown.bs.tooltip', () => { + const tooltipShown = document.querySelector('.tooltip') + + expect(tooltipShown).toBeDefined() + expect(tooltipEl.getAttribute('aria-label')).toBeNull() + done() + }) + + tooltip.show() + }) + }) + describe('jQueryInterface', () => { it('should create a tooltip', () => { fixtureEl.innerHTML = '
' From 03ed3e0b3b0ed3449e24bf9694d3868cbde19c80 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Wed, 25 Nov 2020 09:45:36 +0200 Subject: [PATCH 16/17] tooltip.js: reuse existent variable --- js/src/tooltip.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/src/tooltip.js b/js/src/tooltip.js index a04739b7f..62b338839 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -584,8 +584,8 @@ class Tooltip extends BaseComponent { if (title || originalTitleType !== 'string') { this._element.setAttribute('data-bs-original-title', title || '') - if (this._element.getAttribute('title') && !this._element.getAttribute('aria-label') && !this._element.textContent) { - this._element.setAttribute('aria-label', this._element.getAttribute('title')) + if (title && !this._element.getAttribute('aria-label') && !this._element.textContent) { + this._element.setAttribute('aria-label', title) } this._element.setAttribute('title', '') From c3689ac07335c1c76a9d16efc5363ed32ea6c1f3 Mon Sep 17 00:00:00 2001 From: Rohit Sharma Date: Mon, 30 Nov 2020 15:42:40 +0530 Subject: [PATCH 17/17] Remove the `show` property from the modal plugin (#32279) Drop the support of show property from the modal plugin. When creating the new modal instance in v5, the `show` property does not work anymore, so instead of fixing the behavior just removing it permanently to keep the consistency between all the plugins. (All other plugins require the `show()` method to be called on the instances to be shown) Co-authored-by: XhmikosR --- js/src/modal.js | 8 ++------ site/content/docs/5.0/components/modal.md | 6 ------ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/js/src/modal.js b/js/src/modal.js index db8345fac..fdca48213 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -37,15 +37,13 @@ const ESCAPE_KEY = 'Escape' const Default = { backdrop: true, keyboard: true, - focus: true, - show: true + focus: true } const DefaultType = { backdrop: '(boolean|string)', keyboard: 'boolean', - focus: 'boolean', - show: 'boolean' + focus: 'boolean' } const EVENT_HIDE = `hide${EVENT_KEY}` @@ -557,8 +555,6 @@ class Modal extends BaseComponent { } data[config](relatedTarget) - } else if (_config.show) { - data.show(relatedTarget) } }) } diff --git a/site/content/docs/5.0/components/modal.md b/site/content/docs/5.0/components/modal.md index 5bd116c8e..36dc3b548 100644 --- a/site/content/docs/5.0/components/modal.md +++ b/site/content/docs/5.0/components/modal.md @@ -877,12 +877,6 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap true Puts the focus on the modal when initialized. - - show - boolean - true - Shows the modal when initialized. -