From 80085a12f6936bef11aa72631392e3e9b2646f17 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Wed, 14 Apr 2021 23:28:50 +0300 Subject: Decouple BackDrop from modal (#32439) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Create backdrop.js util * revert breaking changes remove PromiseTimout usage revert class name * one more test | change bundlewatch.config * add config obj to backdrop helper | tests for rootElement | use transitionend helper * Minor tweaks — Renaming Co-authored-by: Rohit Sharma --- js/src/util/backdrop.js | 123 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 js/src/util/backdrop.js (limited to 'js/src/util/backdrop.js') diff --git a/js/src/util/backdrop.js b/js/src/util/backdrop.js new file mode 100644 index 000000000..ab14c23fe --- /dev/null +++ b/js/src/util/backdrop.js @@ -0,0 +1,123 @@ +/** + * -------------------------------------------------------------------------- + * Bootstrap (v5.0.0-beta3): util/backdrop.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +import EventHandler from '../dom/event-handler' +import { emulateTransitionEnd, execute, getTransitionDurationFromElement, reflow, typeCheckConfig } from './index' + +const Default = { + isVisible: true, // if false, we use the backdrop helper without adding any element to the dom + isAnimated: false, + rootElement: document.body // give the choice to place backdrop under different elements +} + +const DefaultType = { + isVisible: 'boolean', + isAnimated: 'boolean', + rootElement: 'element' +} +const NAME = 'backdrop' +const CLASS_NAME_BACKDROP = 'modal-backdrop' +const CLASS_NAME_FADE = 'fade' +const CLASS_NAME_SHOW = 'show' + +class Backdrop { + constructor(config) { + this._config = this._getConfig(config) + this._isAppended = false + this._element = null + } + + show(callback) { + if (!this._config.isVisible) { + execute(callback) + return + } + + this._append() + + if (this._config.isAnimated) { + reflow(this._getElement()) + } + + this._getElement().classList.add(CLASS_NAME_SHOW) + + this._emulateAnimation(() => { + execute(callback) + }) + } + + hide(callback) { + if (!this._config.isVisible) { + execute(callback) + return + } + + this._getElement().classList.remove(CLASS_NAME_SHOW) + + this._emulateAnimation(() => { + this.dispose() + execute(callback) + }) + } + + // Private + + _getElement() { + if (!this._element) { + const backdrop = document.createElement('div') + backdrop.className = CLASS_NAME_BACKDROP + if (this._config.isAnimated) { + backdrop.classList.add(CLASS_NAME_FADE) + } + + this._element = backdrop + } + + return this._element + } + + _getConfig(config) { + config = { + ...Default, + ...(typeof config === 'object' ? config : {}) + } + typeCheckConfig(NAME, config, DefaultType) + return config + } + + _append() { + if (this._isAppended) { + return + } + + this._config.rootElement.appendChild(this._getElement()) + + this._isAppended = true + } + + dispose() { + if (!this._isAppended) { + return + } + + this._getElement().parentNode.removeChild(this._element) + this._isAppended = false + } + + _emulateAnimation(callback) { + if (!this._config.isAnimated) { + execute(callback) + return + } + + const backdropTransitionDuration = getTransitionDurationFromElement(this._getElement()) + EventHandler.one(this._getElement(), 'transitionend', () => execute(callback)) + emulateTransitionEnd(this._getElement(), backdropTransitionDuration) + } +} + +export default Backdrop -- cgit v1.2.3 From a9d7a62658c5d93dcba5ed5fc47d84f3ddd3e0a3 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Mon, 19 Apr 2021 08:20:25 +0300 Subject: Use the backdrop util in offcanvas, enforcing consistency (#33545) * respect /share modal's backdrop functionality, keeping consistency * listen click events over backdrop (only) and trigger `hide()` without add/remove event tricks * achieve to hide foreign open offcanvas instances without glitches `if (allReadyOpen && allReadyOpen !== target)`, in case another is going to be open, when user clicks on trigger button --- js/src/util/backdrop.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'js/src/util/backdrop.js') diff --git a/js/src/util/backdrop.js b/js/src/util/backdrop.js index ab14c23fe..a9d28bd10 100644 --- a/js/src/util/backdrop.js +++ b/js/src/util/backdrop.js @@ -11,19 +11,23 @@ import { emulateTransitionEnd, execute, getTransitionDurationFromElement, reflow const Default = { isVisible: true, // if false, we use the backdrop helper without adding any element to the dom isAnimated: false, - rootElement: document.body // give the choice to place backdrop under different elements + rootElement: document.body, // give the choice to place backdrop under different elements + clickCallback: null } const DefaultType = { isVisible: 'boolean', isAnimated: 'boolean', - rootElement: 'element' + rootElement: 'element', + clickCallback: '(function|null)' } const NAME = 'backdrop' const CLASS_NAME_BACKDROP = 'modal-backdrop' const CLASS_NAME_FADE = 'fade' const CLASS_NAME_SHOW = 'show' +const EVENT_MOUSEDOWN = `mousedown.bs.${NAME}` + class Backdrop { constructor(config) { this._config = this._getConfig(config) @@ -96,6 +100,10 @@ class Backdrop { this._config.rootElement.appendChild(this._getElement()) + EventHandler.on(this._getElement(), EVENT_MOUSEDOWN, () => { + execute(this._config.clickCallback) + }) + this._isAppended = true } @@ -104,6 +112,8 @@ class Backdrop { return } + EventHandler.off(this._element, EVENT_MOUSEDOWN) + this._getElement().parentNode.removeChild(this._element) this._isAppended = false } -- cgit v1.2.3 From bf0936748602c8109fd916c64b4560799fa1c3f8 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Wed, 5 May 2021 22:32:12 +0300 Subject: Release v5.0.0 (#33647) * Bump version to 5.0.0 * Fix npm tag * Dist --- js/src/util/backdrop.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/util/backdrop.js') diff --git a/js/src/util/backdrop.js b/js/src/util/backdrop.js index a9d28bd10..775c09ec0 100644 --- a/js/src/util/backdrop.js +++ b/js/src/util/backdrop.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v5.0.0-beta3): util/backdrop.js + * Bootstrap (v5.0.0): util/backdrop.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ -- cgit v1.2.3 From 741fa589d027c2d16bff844e45a08c842f5f7e04 Mon Sep 17 00:00:00 2001 From: Nagarjun Bodduna Date: Mon, 10 May 2021 23:47:53 +0530 Subject: Fix backdrop `rootElement` not initialized in Modal (#33853) * Initialize default value of rootElement before using * Remove redundant test | put rootElement tests together Co-authored-by: GeoSot --- js/src/util/backdrop.js | 2 ++ 1 file changed, 2 insertions(+) (limited to 'js/src/util/backdrop.js') diff --git a/js/src/util/backdrop.js b/js/src/util/backdrop.js index 775c09ec0..ad9fcb92f 100644 --- a/js/src/util/backdrop.js +++ b/js/src/util/backdrop.js @@ -89,6 +89,8 @@ class Backdrop { ...Default, ...(typeof config === 'object' ? config : {}) } + + config.rootElement = config.rootElement || document.body typeCheckConfig(NAME, config, DefaultType) return config } -- cgit v1.2.3 From 58b1be927f43c779377e478df2d119f2ddf956ca Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Thu, 13 May 2021 19:22:20 +0300 Subject: Release v5.0.1 (#33972) * Bump version to 5.0.1. * Dist --- js/src/util/backdrop.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/util/backdrop.js') diff --git a/js/src/util/backdrop.js b/js/src/util/backdrop.js index ad9fcb92f..4c18e99c0 100644 --- a/js/src/util/backdrop.js +++ b/js/src/util/backdrop.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v5.0.0): util/backdrop.js + * Bootstrap (v5.0.1): util/backdrop.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ -- cgit v1.2.3 From a2b5901efc6de12bb828f8dda118ddccbcd545cf Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Fri, 21 May 2021 18:16:05 -0400 Subject: Fix bug where backdrop calls method on null if it is already removed from the body (#34014) Co-authored-by: Rohit Sharma --- js/src/util/backdrop.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'js/src/util/backdrop.js') diff --git a/js/src/util/backdrop.js b/js/src/util/backdrop.js index 4c18e99c0..c05c221dd 100644 --- a/js/src/util/backdrop.js +++ b/js/src/util/backdrop.js @@ -116,7 +116,11 @@ class Backdrop { EventHandler.off(this._element, EVENT_MOUSEDOWN) - this._getElement().parentNode.removeChild(this._element) + const { parentNode } = this._getElement() + if (parentNode) { + parentNode.removeChild(this._element) + } + this._isAppended = false } -- cgit v1.2.3 From 544d9ac3cf5b7a501524c1bab9570f4b46b8e7e4 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Tue, 25 May 2021 18:30:38 +0300 Subject: Change `element.parentNode.removeChild(element)` to `element.remove()` (#34071) --- js/src/util/backdrop.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'js/src/util/backdrop.js') diff --git a/js/src/util/backdrop.js b/js/src/util/backdrop.js index c05c221dd..f7990f701 100644 --- a/js/src/util/backdrop.js +++ b/js/src/util/backdrop.js @@ -116,11 +116,7 @@ class Backdrop { EventHandler.off(this._element, EVENT_MOUSEDOWN) - const { parentNode } = this._getElement() - if (parentNode) { - parentNode.removeChild(this._element) - } - + this._element.remove() this._isAppended = false } -- cgit v1.2.3 From 0cb70e214ffd24070fa9e312746953faa0b8a305 Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Mon, 31 May 2021 05:35:59 -0400 Subject: Changing Backdrop rootElement to default to a string (#34092) The current config can cause the "body" to become stale. Specifically, if the entire body element is swapped out for a new body element, then the backdrop will continue to append itself to the original body element, since it's stored in memory as a reference on this object. This also no longer allows an explicit null to be passed to Backdrop's rootElement This still accomplishes the laziness of "not finding the rootElement until the Backdrop is created" to avoid problems of the JavaScript being included inside (so, before body is available). --- js/src/util/backdrop.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'js/src/util/backdrop.js') diff --git a/js/src/util/backdrop.js b/js/src/util/backdrop.js index f7990f701..07ad20fab 100644 --- a/js/src/util/backdrop.js +++ b/js/src/util/backdrop.js @@ -6,19 +6,19 @@ */ import EventHandler from '../dom/event-handler' -import { emulateTransitionEnd, execute, getTransitionDurationFromElement, reflow, typeCheckConfig } from './index' +import { emulateTransitionEnd, execute, getElement, getTransitionDurationFromElement, reflow, typeCheckConfig } from './index' const Default = { isVisible: true, // if false, we use the backdrop helper without adding any element to the dom isAnimated: false, - rootElement: document.body, // give the choice to place backdrop under different elements + rootElement: 'body', // give the choice to place backdrop under different elements clickCallback: null } const DefaultType = { isVisible: 'boolean', isAnimated: 'boolean', - rootElement: 'element', + rootElement: '(element|string)', clickCallback: '(function|null)' } const NAME = 'backdrop' @@ -90,7 +90,8 @@ class Backdrop { ...(typeof config === 'object' ? config : {}) } - config.rootElement = config.rootElement || document.body + // use getElement() with the default "body" to get a fresh Element on each instantiation + config.rootElement = getElement(config.rootElement) typeCheckConfig(NAME, config, DefaultType) return config } -- cgit v1.2.3 From 4a5029ea29ac75243dfec68153051292fc70f5cf Mon Sep 17 00:00:00 2001 From: alpadev <2838324+alpadev@users.noreply.github.com> Date: Thu, 3 Jun 2021 13:44:16 +0200 Subject: Fix handling of transitionend events dispatched by nested elements(#33845) Fix handling of transitionend events dispatched by nested elements Properly handle events from nested elements Change `emulateTransitionEnd` to `executeAfterTransition` && --- js/src/util/backdrop.js | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'js/src/util/backdrop.js') diff --git a/js/src/util/backdrop.js b/js/src/util/backdrop.js index 07ad20fab..028325d11 100644 --- a/js/src/util/backdrop.js +++ b/js/src/util/backdrop.js @@ -6,7 +6,7 @@ */ import EventHandler from '../dom/event-handler' -import { emulateTransitionEnd, execute, getElement, getTransitionDurationFromElement, reflow, typeCheckConfig } from './index' +import { execute, executeAfterTransition, getElement, reflow, typeCheckConfig } from './index' const Default = { isVisible: true, // if false, we use the backdrop helper without adding any element to the dom @@ -122,14 +122,7 @@ class Backdrop { } _emulateAnimation(callback) { - if (!this._config.isAnimated) { - execute(callback) - return - } - - const backdropTransitionDuration = getTransitionDurationFromElement(this._getElement()) - EventHandler.one(this._getElement(), 'transitionend', () => execute(callback)) - emulateTransitionEnd(this._getElement(), backdropTransitionDuration) + executeAfterTransition(callback, this._getElement(), this._config.isAnimated) } } -- cgit v1.2.3 From 688bce4fa695cc360a0d084e34f029b0c192b223 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Tue, 22 Jun 2021 21:29:16 +0300 Subject: Release v5.0.2 (#34276) * Bump version to v5.0.2. * Dist --- js/src/util/backdrop.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/util/backdrop.js') diff --git a/js/src/util/backdrop.js b/js/src/util/backdrop.js index 028325d11..7ba7b4c43 100644 --- a/js/src/util/backdrop.js +++ b/js/src/util/backdrop.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v5.0.1): util/backdrop.js + * Bootstrap (v5.0.2): util/backdrop.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ -- cgit v1.2.3 From 45d26de72817b295c5f94c8426354fd5b7d0a1f9 Mon Sep 17 00:00:00 2001 From: Mark Otto Date: Fri, 25 Jun 2021 13:41:15 -0700 Subject: Variablize backdrop for modal and offcanvas --- js/src/util/backdrop.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'js/src/util/backdrop.js') diff --git a/js/src/util/backdrop.js b/js/src/util/backdrop.js index 7ba7b4c43..fbe32445e 100644 --- a/js/src/util/backdrop.js +++ b/js/src/util/backdrop.js @@ -9,6 +9,7 @@ import EventHandler from '../dom/event-handler' import { execute, executeAfterTransition, getElement, reflow, typeCheckConfig } from './index' const Default = { + className: 'modal-backdrop', isVisible: true, // if false, we use the backdrop helper without adding any element to the dom isAnimated: false, rootElement: 'body', // give the choice to place backdrop under different elements @@ -16,13 +17,13 @@ const Default = { } const DefaultType = { + className: 'string', isVisible: 'boolean', isAnimated: 'boolean', rootElement: '(element|string)', clickCallback: '(function|null)' } const NAME = 'backdrop' -const CLASS_NAME_BACKDROP = 'modal-backdrop' const CLASS_NAME_FADE = 'fade' const CLASS_NAME_SHOW = 'show' @@ -73,7 +74,7 @@ class Backdrop { _getElement() { if (!this._element) { const backdrop = document.createElement('div') - backdrop.className = CLASS_NAME_BACKDROP + backdrop.className = this._config.className if (this._config.isAnimated) { backdrop.classList.add(CLASS_NAME_FADE) } -- cgit v1.2.3 From 6d707f4801750f1454351d6afe93a80ce4516d1a Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Fri, 30 Jul 2021 01:23:00 +0300 Subject: Enable a few eslint-config-xo rules (#34620) * unicorn/prefer-dom-node-append * unicorn/prefer-dom-node-remove --- js/src/util/backdrop.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/util/backdrop.js') diff --git a/js/src/util/backdrop.js b/js/src/util/backdrop.js index fbe32445e..30a3686f8 100644 --- a/js/src/util/backdrop.js +++ b/js/src/util/backdrop.js @@ -102,7 +102,7 @@ class Backdrop { return } - this._config.rootElement.appendChild(this._getElement()) + this._config.rootElement.append(this._getElement()) EventHandler.on(this._getElement(), EVENT_MOUSEDOWN, () => { execute(this._config.clickCallback) -- cgit v1.2.3 From f20fece3a8cdd0e76a42c2737524b7652bf54d26 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Wed, 4 Aug 2021 18:41:51 +0300 Subject: Prepare v5.1.0. (#34674) --- js/src/util/backdrop.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/util/backdrop.js') diff --git a/js/src/util/backdrop.js b/js/src/util/backdrop.js index 30a3686f8..0f515b3d3 100644 --- a/js/src/util/backdrop.js +++ b/js/src/util/backdrop.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v5.0.2): util/backdrop.js + * Bootstrap (v5.1.0): util/backdrop.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ -- cgit v1.2.3