From 886b940796b3595a03b44230ca8b78197c5ee1c5 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Fri, 10 Dec 2021 18:18:18 +0200 Subject: Extract Component config functionality to a separate class (#33872) Co-authored-by: XhmikosR --- js/src/carousel.js | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 3589f2206..e50894aa8 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -12,8 +12,7 @@ import { isRTL, isVisible, reflow, - triggerTransitionEnd, - typeCheckConfig + triggerTransitionEnd } from './util/index' import EventHandler from './dom/event-handler' import Manipulator from './dom/manipulator' @@ -95,7 +94,7 @@ const DefaultType = { class Carousel extends BaseComponent { constructor(element, config) { - super(element) + super(element, config) this._items = null this._interval = null @@ -105,7 +104,6 @@ class Carousel extends BaseComponent { this.touchTimeout = null this._swipeHelper = null - this._config = this._getConfig(config) this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element) this._addEventListeners() } @@ -115,6 +113,10 @@ class Carousel extends BaseComponent { return Default } + static get DefaultType() { + return DefaultType + } + static get NAME() { return NAME } @@ -205,16 +207,6 @@ class Carousel extends BaseComponent { } // Private - _getConfig(config) { - config = { - ...Default, - ...Manipulator.getDataAttributes(this._element), - ...(typeof config === 'object' ? config : {}) - } - typeCheckConfig(NAME, config, DefaultType) - return config - } - _addEventListeners() { if (this._config.keyboard) { EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event)) -- cgit v1.2.3 From d60f146507c94bd889f7049d77a4b3725a6fa0a9 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Thu, 8 Jul 2021 01:29:25 +0300 Subject: Carousel: add a helper to get the active element --- js/src/carousel.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index e50894aa8..14a0bd40b 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -173,7 +173,7 @@ class Carousel extends BaseComponent { } to(index) { - this._activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element) + this._activeElement = this._getActive() const activeIndex = this._getItemIndex(this._activeElement) if (index > this._items.length - 1 || index < 0) { @@ -282,7 +282,7 @@ class Carousel extends BaseComponent { _triggerSlideEvent(relatedTarget, eventDirectionName) { const targetIndex = this._getItemIndex(relatedTarget) - const fromIndex = this._getItemIndex(SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element)) + const fromIndex = this._getItemIndex(this._getActive()) return EventHandler.trigger(this._element, EVENT_SLIDE, { relatedTarget, @@ -312,7 +312,7 @@ class Carousel extends BaseComponent { } _updateInterval() { - const element = this._activeElement || SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element) + const element = this._activeElement || this._getActive() if (!element) { return @@ -330,7 +330,7 @@ class Carousel extends BaseComponent { _slide(directionOrOrder, element) { const order = this._directionToOrder(directionOrOrder) - const activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element) + const activeElement = this._getActive() const activeElementIndex = this._getItemIndex(activeElement) const nextElement = element || this._getItemByOrder(order, activeElement) @@ -412,6 +412,10 @@ class Carousel extends BaseComponent { } } + _getActive() { + return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element) + } + _directionToOrder(direction) { if (![DIRECTION_RIGHT, DIRECTION_LEFT].includes(direction)) { return direction -- cgit v1.2.3 From 6f79721c82ecef5a4a25482e915ffa157965702c Mon Sep 17 00:00:00 2001 From: GeoSot Date: Fri, 10 Sep 2021 02:02:44 +0300 Subject: Carousel: return early and drop a loop. We can achieve the same thing by querying the specific selector directly --- js/src/carousel.js | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 14a0bd40b..856d70dac 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -61,7 +61,6 @@ const SELECTOR_ITEM = '.carousel-item' const SELECTOR_ITEM_IMG = '.carousel-item img' const SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev' const SELECTOR_INDICATORS = '.carousel-indicators' -const SELECTOR_INDICATOR = '[data-bs-target]' const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]' const SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]' @@ -293,21 +292,20 @@ class Carousel extends BaseComponent { } _setActiveIndicatorElement(element) { - if (this._indicatorsElement) { - const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement) + if (!this._indicatorsElement) { + return + } - activeIndicator.classList.remove(CLASS_NAME_ACTIVE) - activeIndicator.removeAttribute('aria-current') + const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement) - const indicators = SelectorEngine.find(SELECTOR_INDICATOR, this._indicatorsElement) + activeIndicator.classList.remove(CLASS_NAME_ACTIVE) + activeIndicator.removeAttribute('aria-current') - for (const indicator of indicators) { - if (Number.parseInt(indicator.getAttribute('data-bs-slide-to'), 10) === this._getItemIndex(element)) { - indicator.classList.add(CLASS_NAME_ACTIVE) - indicator.setAttribute('aria-current', 'true') - break - } - } + const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to="${this._getItemIndex(element)}"]`, this._indicatorsElement) + + if (newActiveIndicator) { + newActiveIndicator.classList.add(CLASS_NAME_ACTIVE) + newActiveIndicator.setAttribute('aria-current', 'true') } } -- cgit v1.2.3 From ff4bf4a458d1bfab6a3cb8803e762fdb0de8bc3e Mon Sep 17 00:00:00 2001 From: GeoSot Date: Fri, 10 Sep 2021 02:11:14 +0300 Subject: Carousel: move carousel default interval to `_getConfig()` and simplify it --- js/src/carousel.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 856d70dac..336bcd261 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -161,7 +161,7 @@ class Carousel extends BaseComponent { this._interval = null } - if (this._config && this._config.interval && !this._isPaused) { + if (this._config.interval && !this._isPaused) { this._updateInterval() this._interval = setInterval( @@ -206,6 +206,11 @@ class Carousel extends BaseComponent { } // Private + _configAfterMerge(config) { + config.defaultInterval = config.interval + return config + } + _addEventListeners() { if (this._config.keyboard) { EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event)) @@ -318,12 +323,7 @@ class Carousel extends BaseComponent { const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10) - if (elementInterval) { - this._config.defaultInterval = this._config.defaultInterval || this._config.interval - this._config.interval = elementInterval - } else { - this._config.interval = this._config.defaultInterval || this._config.interval - } + this._config.interval = elementInterval || this._config.defaultInterval } _slide(directionOrOrder, element) { -- cgit v1.2.3 From b8ee68cfa0f3516dc55aec5da6d7e43e2705f402 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Fri, 10 Sep 2021 02:13:58 +0300 Subject: Carousel: remove always true `visibilityState` check According to https://developer.mozilla.org/en-US/docs/Web/API/Document/visibilityState `visibilityState` is always a string, so the check was always true --- js/src/carousel.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 336bcd261..e91ba376c 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -126,6 +126,7 @@ class Carousel extends BaseComponent { } nextWhenVisible() { + // FIXME TODO use `document.visibilityState` // Don't call next when the page isn't visible // or the carousel or its parent isn't visible if (!document.hidden && isVisible(this._element)) { @@ -164,10 +165,7 @@ class Carousel extends BaseComponent { if (this._config.interval && !this._isPaused) { this._updateInterval() - this._interval = setInterval( - (document.visibilityState ? this.nextWhenVisible : this.next).bind(this), - this._config.interval - ) + this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval) } } -- cgit v1.2.3 From 0d4213bde39bb4f2e2bc5a0df699dad82780efa3 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Fri, 10 Sep 2021 02:17:28 +0300 Subject: Carousel: move repeated code to a method --- js/src/carousel.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index e91ba376c..51c5dded8 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -148,8 +148,7 @@ class Carousel extends BaseComponent { this.cycle(true) } - clearInterval(this._interval) - this._interval = null + this._clearInterval() } cycle(event) { @@ -157,11 +156,7 @@ class Carousel extends BaseComponent { this._isPaused = false } - if (this._interval) { - clearInterval(this._interval) - this._interval = null - } - + this._clearInterval() if (this._config.interval && !this._isPaused) { this._updateInterval() @@ -412,6 +407,13 @@ class Carousel extends BaseComponent { return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element) } + _clearInterval() { + if (this._interval) { + clearInterval(this._interval) + this._interval = null + } + } + _directionToOrder(direction) { if (![DIRECTION_RIGHT, DIRECTION_LEFT].includes(direction)) { return direction -- cgit v1.2.3 From 62d86c07f81dfae632742dbf62633e767bac8edd Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Fri, 29 Oct 2021 10:38:35 +0300 Subject: Rename variables --- js/src/carousel.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 51c5dded8..fe3ccf94e 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -220,8 +220,8 @@ class Carousel extends BaseComponent { } _addTouchEventListeners() { - for (const itemImg of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) { - EventHandler.on(itemImg, EVENT_DRAG_START, event => event.preventDefault()) + for (const img of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) { + EventHandler.on(img, EVENT_DRAG_START, event => event.preventDefault()) } const endCallBack = () => { -- cgit v1.2.3 From 558002f3dccb9fcb1ba408abfbe55d201af4e152 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Tue, 9 Nov 2021 15:44:14 +0200 Subject: Return early in more places --- js/src/carousel.js | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index fe3ccf94e..5a0cbc208 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -225,22 +225,24 @@ class Carousel extends BaseComponent { } const endCallBack = () => { - if (this._config.pause === 'hover') { - // If it's a touch-enabled device, mouseenter/leave are fired as - // part of the mouse compatibility events on first tap - the carousel - // would stop cycling until user tapped out of it; - // here, we listen for touchend, explicitly pause the carousel - // (as if it's the second time we tap on it, mouseenter compat event - // is NOT fired) and after a timeout (to allow for mouse compatibility - // events to fire) we explicitly restart cycling - - this.pause() - if (this.touchTimeout) { - clearTimeout(this.touchTimeout) - } - - this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval) + if (this._config.pause !== 'hover') { + return } + + // If it's a touch-enabled device, mouseenter/leave are fired as + // part of the mouse compatibility events on first tap - the carousel + // would stop cycling until user tapped out of it; + // here, we listen for touchend, explicitly pause the carousel + // (as if it's the second time we tap on it, mouseenter compat event + // is NOT fired) and after a timeout (to allow for mouse compatibility + // events to fire) we explicitly restart cycling + + this.pause() + if (this.touchTimeout) { + clearTimeout(this.touchTimeout) + } + + this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval) } const swipeConfig = { -- cgit v1.2.3 From ccba6a3589ba33e25ab2919cb844b5bc870e2fef Mon Sep 17 00:00:00 2001 From: GeoSot Date: Fri, 10 Sep 2021 02:55:28 +0300 Subject: Carousel: remove redundant config merge on `dataApiClickHandler`, as it is done by default in the `constructor` --- js/src/carousel.js | 1 - 1 file changed, 1 deletion(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 5a0cbc208..38e33cbee 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -482,7 +482,6 @@ class Carousel extends BaseComponent { } const config = { - ...Manipulator.getDataAttributes(target), ...Manipulator.getDataAttributes(this) } const slideIndex = this.getAttribute('data-bs-slide-to') -- cgit v1.2.3 From a247fe9b27ec57152f07aaa5dfc79f633d2b6d10 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Fri, 10 Sep 2021 03:41:03 +0300 Subject: Carousel: simplify initialization on document load, using `getOrCreateInstance` --- js/src/carousel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 38e33cbee..4cb03d51f 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -510,7 +510,7 @@ EventHandler.on(window, EVENT_LOAD_DATA_API, () => { const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE) for (const carousel of carousels) { - Carousel.carouselInterface(carousel, Carousel.getInstance(carousel)) + Carousel.getOrCreateInstance(carousel) } }) -- cgit v1.2.3 From d97125475b3a5cbbafe3100d5981fd456c92c722 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Mon, 31 Jan 2022 00:22:33 +0200 Subject: Carousel: merge slide functionality, regardless of whether it is animated or not --- js/src/carousel.js | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 4cb03d51f..00d930495 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -372,39 +372,35 @@ class Carousel extends BaseComponent { }) } - if (this._element.classList.contains(CLASS_NAME_SLIDE)) { - nextElement.classList.add(orderClassName) + nextElement.classList.add(orderClassName) - reflow(nextElement) + reflow(nextElement) - activeElement.classList.add(directionalClassName) - nextElement.classList.add(directionalClassName) + activeElement.classList.add(directionalClassName) + nextElement.classList.add(directionalClassName) - const completeCallBack = () => { - nextElement.classList.remove(directionalClassName, orderClassName) - nextElement.classList.add(CLASS_NAME_ACTIVE) - - activeElement.classList.remove(CLASS_NAME_ACTIVE, orderClassName, directionalClassName) - - this._isSliding = false - - setTimeout(triggerSlidEvent, 0) - } - - this._queueCallback(completeCallBack, activeElement, true) - } else { - activeElement.classList.remove(CLASS_NAME_ACTIVE) + const completeCallBack = () => { + nextElement.classList.remove(directionalClassName, orderClassName) nextElement.classList.add(CLASS_NAME_ACTIVE) + activeElement.classList.remove(CLASS_NAME_ACTIVE, orderClassName, directionalClassName) + this._isSliding = false - triggerSlidEvent() + + setTimeout(triggerSlidEvent, 0) } + this._queueCallback(completeCallBack, activeElement, this._isAnimated()) + if (isCycling) { this.cycle() } } + _isAnimated() { + return this._element.classList.contains(CLASS_NAME_SLIDE) + } + _getActive() { return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element) } -- cgit v1.2.3 From 928bdcadc56cef30b4483616c4b2eee7cfa34bd2 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Mon, 31 Jan 2022 00:31:07 +0200 Subject: Carousel: make direct triggering of slid event, instead of using a callback --- js/src/carousel.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 00d930495..b8d921e42 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -363,15 +363,6 @@ class Carousel extends BaseComponent { this._setActiveIndicatorElement(nextElement) this._activeElement = nextElement - const triggerSlidEvent = () => { - EventHandler.trigger(this._element, EVENT_SLID, { - relatedTarget: nextElement, - direction: eventDirectionName, - from: activeElementIndex, - to: nextElementIndex - }) - } - nextElement.classList.add(orderClassName) reflow(nextElement) @@ -387,7 +378,12 @@ class Carousel extends BaseComponent { this._isSliding = false - setTimeout(triggerSlidEvent, 0) + EventHandler.trigger(this._element, EVENT_SLID, { + relatedTarget: nextElement, + direction: eventDirectionName, + from: activeElementIndex, + to: nextElementIndex + }) } this._queueCallback(completeCallBack, activeElement, this._isAnimated()) -- cgit v1.2.3 From d52f6c9de144ac2bc3eba002d3db538183c52465 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Fri, 10 Sep 2021 12:00:28 +0300 Subject: Carousel: change argument to `_setActiveIndicatorElement`, from element to index --- js/src/carousel.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index b8d921e42..e3c836048 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -291,7 +291,7 @@ class Carousel extends BaseComponent { }) } - _setActiveIndicatorElement(element) { + _setActiveIndicatorElement(index) { if (!this._indicatorsElement) { return } @@ -301,7 +301,7 @@ class Carousel extends BaseComponent { activeIndicator.classList.remove(CLASS_NAME_ACTIVE) activeIndicator.removeAttribute('aria-current') - const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to="${this._getItemIndex(element)}"]`, this._indicatorsElement) + const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to="${index}"]`, this._indicatorsElement) if (newActiveIndicator) { newActiveIndicator.classList.add(CLASS_NAME_ACTIVE) @@ -360,7 +360,7 @@ class Carousel extends BaseComponent { this.pause() } - this._setActiveIndicatorElement(nextElement) + this._setActiveIndicatorElement(nextElementIndex) this._activeElement = nextElement nextElement.classList.add(orderClassName) -- cgit v1.2.3 From 642d756eeaf107bed2baac931933c9350c33f5c1 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Fri, 10 Sep 2021 12:54:20 +0300 Subject: Carousel: remove one more call to ActiveIndex --- js/src/carousel.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index e3c836048..7b22e9cbf 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -279,9 +279,8 @@ class Carousel extends BaseComponent { return getNextActiveElement(this._items, activeElement, isNext, this._config.wrap) } - _triggerSlideEvent(relatedTarget, eventDirectionName) { + _triggerSlideEvent(relatedTarget, fromIndex, eventDirectionName) { const targetIndex = this._getItemIndex(relatedTarget) - const fromIndex = this._getItemIndex(this._getActive()) return EventHandler.trigger(this._element, EVENT_SLIDE, { relatedTarget, @@ -344,7 +343,7 @@ class Carousel extends BaseComponent { return } - const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName) + const slideEvent = this._triggerSlideEvent(nextElement, activeElementIndex, eventDirectionName) if (slideEvent.defaultPrevented) { return } -- cgit v1.2.3 From 631cec4f70fa74b066c9d949aa5b8bf8cf06b46d Mon Sep 17 00:00:00 2001 From: GeoSot Date: Fri, 10 Sep 2021 03:33:14 +0300 Subject: Carousel: refactor dataApiKeyHandler to avoid use of `carouselInterface` --- js/src/carousel.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 7b22e9cbf..a5fe2597b 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -472,22 +472,22 @@ class Carousel extends BaseComponent { return } - const config = { - ...Manipulator.getDataAttributes(this) - } + event.preventDefault() + + const carousel = Carousel.getOrCreateInstance(target) const slideIndex = this.getAttribute('data-bs-slide-to') if (slideIndex) { - config.interval = false + carousel.to(slideIndex) + return } - Carousel.carouselInterface(target, config) - - if (slideIndex) { - Carousel.getInstance(target).to(slideIndex) + if (Manipulator.getDataAttribute(this, 'slide') === 'next') { + carousel.next() + return } - event.preventDefault() + carousel.prev() } } -- cgit v1.2.3 From 13042d25cae2a8f5d43e24cd143cb1303aaed41e Mon Sep 17 00:00:00 2001 From: GeoSot Date: Sat, 19 Feb 2022 19:02:51 +0200 Subject: Carousel: move logic of `dataApiClickHandler` --- js/src/carousel.js | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index a5fe2597b..12102f224 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -464,38 +464,36 @@ class Carousel extends BaseComponent { Carousel.carouselInterface(this, config) }) } +} - static dataApiClickHandler(event) { - const target = getElementFromSelector(this) - - if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) { - return - } +/** + * Data API implementation + */ - event.preventDefault() +EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, function (event) { + const target = getElementFromSelector(this) - const carousel = Carousel.getOrCreateInstance(target) - const slideIndex = this.getAttribute('data-bs-slide-to') + if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) { + return + } - if (slideIndex) { - carousel.to(slideIndex) - return - } + event.preventDefault() - if (Manipulator.getDataAttribute(this, 'slide') === 'next') { - carousel.next() - return - } + const carousel = Carousel.getOrCreateInstance(target) + const slideIndex = this.getAttribute('data-bs-slide-to') - carousel.prev() + if (slideIndex) { + carousel.to(slideIndex) + return } -} -/** - * Data API implementation - */ + if (Manipulator.getDataAttribute(this, 'slide') === 'next') { + carousel.next() + return + } -EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, Carousel.dataApiClickHandler) + carousel.prev() +}) EventHandler.on(window, EVENT_LOAD_DATA_API, () => { const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE) -- cgit v1.2.3 From eb8d5b43cedc76d88331f4d2f6ed3bca10e573ff Mon Sep 17 00:00:00 2001 From: GeoSot Date: Sat, 19 Feb 2022 19:04:50 +0200 Subject: Carousel: move `carouselInterface` inside `jqueryInterface` --- js/src/carousel.js | 48 ++++++++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 26 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 12102f224..4262d60df 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -432,36 +432,32 @@ class Carousel extends BaseComponent { } // Static - static carouselInterface(element, config) { - const data = Carousel.getOrCreateInstance(element, config) - - let { _config } = data - if (typeof config === 'object') { - _config = { - ..._config, - ...config + static jQueryInterface(config) { + return this.each(function () { + const data = Carousel.getOrCreateInstance(this, config) + + let { _config } = data + if (typeof config === 'object') { + _config = { + ..._config, + ...config + } } - } - const action = typeof config === 'string' ? config : _config.slide - - if (typeof config === 'number') { - data.to(config) - } else if (typeof action === 'string') { - if (typeof data[action] === 'undefined') { - throw new TypeError(`No method named "${action}"`) - } + const action = typeof config === 'string' ? config : _config.slide - data[action]() - } else if (_config.interval && _config.ride) { - data.pause() - data.cycle() - } - } + if (typeof config === 'number') { + data.to(config) + } else if (typeof action === 'string') { + if (typeof data[action] === 'undefined') { + throw new TypeError(`No method named "${action}"`) + } - static jQueryInterface(config) { - return this.each(function () { - Carousel.carouselInterface(this, config) + data[action]() + } else if (_config.interval && _config.ride) { + data.pause() + data.cycle() + } }) } } -- cgit v1.2.3 From c644f09d88a93445b415faa796f1d246ca34e2e7 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Fri, 10 Sep 2021 11:57:58 +0300 Subject: Carousel: simplify carousel items selection We already know that carousel's parent is the carousel element, so we can use it explicitly --- js/src/carousel.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 4262d60df..ea258527d 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -267,9 +267,7 @@ class Carousel extends BaseComponent { } _getItemIndex(element) { - this._items = element && element.parentNode ? - SelectorEngine.find(SELECTOR_ITEM, element.parentNode) : - [] + this._items = SelectorEngine.find(SELECTOR_ITEM, this._element) return this._items.indexOf(element) } -- cgit v1.2.3 From e77ae50311366b07225d15b19e330a3871123437 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Wed, 2 Mar 2022 00:57:28 +0200 Subject: Carousel: cleanup jQueryInterface Drop chained else ifs and unused variable. Since we were checking for `typeof config === 'string'` in both places, action was never `_config.slide`. --- js/src/carousel.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index ea258527d..afe02f5b7 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -442,17 +442,21 @@ class Carousel extends BaseComponent { } } - const action = typeof config === 'string' ? config : _config.slide - if (typeof config === 'number') { data.to(config) - } else if (typeof action === 'string') { - if (typeof data[action] === 'undefined') { - throw new TypeError(`No method named "${action}"`) + return + } + + if (typeof config === 'string') { + if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { + throw new TypeError(`No method named "${config}"`) } - data[action]() - } else if (_config.interval && _config.ride) { + data[config]() + return + } + + if (_config.interval && _config.ride) { data.pause() data.cycle() } -- cgit v1.2.3 From a8142497c79f33bebd13a8b00d8104b324ce5cf7 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Wed, 2 Mar 2022 01:16:25 +0200 Subject: Carousel: reorder variables and refactor method to use it inline --- js/src/carousel.js | 44 +++++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 25 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index afe02f5b7..bc89a404f 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -277,17 +277,6 @@ class Carousel extends BaseComponent { return getNextActiveElement(this._items, activeElement, isNext, this._config.wrap) } - _triggerSlideEvent(relatedTarget, fromIndex, eventDirectionName) { - const targetIndex = this._getItemIndex(relatedTarget) - - return EventHandler.trigger(this._element, EVENT_SLIDE, { - relatedTarget, - direction: eventDirectionName, - from: fromIndex, - to: targetIndex - }) - } - _setActiveIndicatorElement(index) { if (!this._indicatorsElement) { return @@ -320,17 +309,12 @@ class Carousel extends BaseComponent { _slide(directionOrOrder, element) { const order = this._directionToOrder(directionOrOrder) + const activeElement = this._getActive() const activeElementIndex = this._getItemIndex(activeElement) - const nextElement = element || this._getItemByOrder(order, activeElement) + const nextElement = element || this._getItemByOrder(order, activeElement) const nextElementIndex = this._getItemIndex(nextElement) - const isCycling = Boolean(this._interval) - - const isNext = order === ORDER_NEXT - const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END - const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV - const eventDirectionName = this._orderToDirection(order) if (nextElement && nextElement.classList.contains(CLASS_NAME_ACTIVE)) { this._isSliding = false @@ -341,7 +325,17 @@ class Carousel extends BaseComponent { return } - const slideEvent = this._triggerSlideEvent(nextElement, activeElementIndex, eventDirectionName) + const triggerEvent = eventName => { + return EventHandler.trigger(this._element, eventName, { + relatedTarget: nextElement, + direction: this._orderToDirection(order), + from: activeElementIndex, + to: nextElementIndex + }) + } + + const slideEvent = triggerEvent(EVENT_SLIDE) + if (slideEvent.defaultPrevented) { return } @@ -353,6 +347,7 @@ class Carousel extends BaseComponent { this._isSliding = true + const isCycling = Boolean(this._interval) if (isCycling) { this.pause() } @@ -360,6 +355,10 @@ class Carousel extends BaseComponent { this._setActiveIndicatorElement(nextElementIndex) this._activeElement = nextElement + const isNext = order === ORDER_NEXT + const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END + const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV + nextElement.classList.add(orderClassName) reflow(nextElement) @@ -375,12 +374,7 @@ class Carousel extends BaseComponent { this._isSliding = false - EventHandler.trigger(this._element, EVENT_SLID, { - relatedTarget: nextElement, - direction: eventDirectionName, - from: activeElementIndex, - to: nextElementIndex - }) + triggerEvent(EVENT_SLID) } this._queueCallback(completeCallBack, activeElement, this._isAnimated()) -- cgit v1.2.3 From b7cce49dbc7d9dd6be1dd49e6764dd6f23f6d758 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Wed, 2 Mar 2022 01:34:38 +0200 Subject: Carousel: use combined selector and drop variable used once --- js/src/carousel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index bc89a404f..f8ca1d638 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -56,8 +56,8 @@ const CLASS_NAME_NEXT = 'carousel-item-next' const CLASS_NAME_PREV = 'carousel-item-prev' const SELECTOR_ACTIVE = '.active' -const SELECTOR_ACTIVE_ITEM = '.active.carousel-item' const SELECTOR_ITEM = '.carousel-item' +const SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM const SELECTOR_ITEM_IMG = '.carousel-item img' const SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev' const SELECTOR_INDICATORS = '.carousel-indicators' -- cgit v1.2.3 From fcc2c809767525a32357fc4877a6dbbac6ba1370 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Wed, 2 Mar 2022 02:04:03 +0200 Subject: Carousel: add a `getItems` helper --- js/src/carousel.js | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index f8ca1d638..fdc6736ad 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -95,7 +95,6 @@ class Carousel extends BaseComponent { constructor(element, config) { super(element, config) - this._items = null this._interval = null this._activeElement = null this._isPaused = false @@ -165,10 +164,8 @@ class Carousel extends BaseComponent { } to(index) { - this._activeElement = this._getActive() - const activeIndex = this._getItemIndex(this._activeElement) - - if (index > this._items.length - 1 || index < 0) { + const items = this._getItems() + if (index > items.length - 1 || index < 0) { return } @@ -177,17 +174,16 @@ class Carousel extends BaseComponent { return } + const activeIndex = this._getItemIndex(this._getActive()) if (activeIndex === index) { this.pause() this.cycle() return } - const order = index > activeIndex ? - ORDER_NEXT : - ORDER_PREV + const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV - this._slide(order, this._items[index]) + this._slide(order, items[index]) } dispose() { @@ -267,14 +263,12 @@ class Carousel extends BaseComponent { } _getItemIndex(element) { - this._items = SelectorEngine.find(SELECTOR_ITEM, this._element) - - return this._items.indexOf(element) + return this._getItems().indexOf(element) } _getItemByOrder(order, activeElement) { const isNext = order === ORDER_NEXT - return getNextActiveElement(this._items, activeElement, isNext, this._config.wrap) + return getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap) } _setActiveIndicatorElement(index) { @@ -392,6 +386,10 @@ class Carousel extends BaseComponent { return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element) } + _getItems() { + return SelectorEngine.find(SELECTOR_ITEM, this._element) + } + _clearInterval() { if (this._interval) { clearInterval(this._interval) -- cgit v1.2.3 From 699402bee5d02659acaab69208549f26f9b3313d Mon Sep 17 00:00:00 2001 From: GeoSot Date: Wed, 2 Mar 2022 02:07:36 +0200 Subject: Carousel: refactor `_slide` method te accept only order as first argument --- js/src/carousel.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index fdc6736ad..3a692657a 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -242,8 +242,8 @@ class Carousel extends BaseComponent { } const swipeConfig = { - leftCallback: () => this._slide(DIRECTION_LEFT), - rightCallback: () => this._slide(DIRECTION_RIGHT), + leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT)), + rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT)), endCallback: endCallBack } @@ -258,7 +258,7 @@ class Carousel extends BaseComponent { const direction = KEY_TO_DIRECTION[event.key] if (direction) { event.preventDefault() - this._slide(direction) + this._slide(this._directionToOrder(direction)) } } @@ -301,9 +301,7 @@ class Carousel extends BaseComponent { this._config.interval = elementInterval || this._config.defaultInterval } - _slide(directionOrOrder, element) { - const order = this._directionToOrder(directionOrOrder) - + _slide(order, element = null) { const activeElement = this._getActive() const activeElementIndex = this._getItemIndex(activeElement) -- cgit v1.2.3 From dd93551914424e577176a6377e1614742aa1018c Mon Sep 17 00:00:00 2001 From: GeoSot Date: Wed, 2 Mar 2022 02:11:14 +0200 Subject: Carousel: refactor using inline function and move variables to the proper place --- js/src/carousel.js | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 3a692657a..086062251 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -266,11 +266,6 @@ class Carousel extends BaseComponent { return this._getItems().indexOf(element) } - _getItemByOrder(order, activeElement) { - const isNext = order === ORDER_NEXT - return getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap) - } - _setActiveIndicatorElement(index) { if (!this._indicatorsElement) { return @@ -303,10 +298,8 @@ class Carousel extends BaseComponent { _slide(order, element = null) { const activeElement = this._getActive() - const activeElementIndex = this._getItemIndex(activeElement) - - const nextElement = element || this._getItemByOrder(order, activeElement) - const nextElementIndex = this._getItemIndex(nextElement) + const isNext = order === ORDER_NEXT + const nextElement = element || getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap) if (nextElement && nextElement.classList.contains(CLASS_NAME_ACTIVE)) { this._isSliding = false @@ -317,11 +310,13 @@ class Carousel extends BaseComponent { return } + const nextElementIndex = this._getItemIndex(nextElement) + const triggerEvent = eventName => { return EventHandler.trigger(this._element, eventName, { relatedTarget: nextElement, direction: this._orderToDirection(order), - from: activeElementIndex, + from: this._getItemIndex(activeElement), to: nextElementIndex }) } @@ -347,7 +342,6 @@ class Carousel extends BaseComponent { this._setActiveIndicatorElement(nextElementIndex) this._activeElement = nextElement - const isNext = order === ORDER_NEXT const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV -- cgit v1.2.3 From d4e87d28cdc1b5d053b4c08da737321ab4de2ff7 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Wed, 2 Mar 2022 02:16:51 +0200 Subject: Carousel: small refactoring, remove unnecessary checks --- js/src/carousel.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 086062251..f37ded7c2 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -301,8 +301,7 @@ class Carousel extends BaseComponent { const isNext = order === ORDER_NEXT const nextElement = element || getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap) - if (nextElement && nextElement.classList.contains(CLASS_NAME_ACTIVE)) { - this._isSliding = false + if (nextElement === activeElement) { return } -- cgit v1.2.3 From 7e5a8016ba557641ee93b38aed4482a1360b64af Mon Sep 17 00:00:00 2001 From: GeoSot Date: Wed, 2 Mar 2022 02:18:55 +0200 Subject: Carousel: return early in `_slide` method --- js/src/carousel.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index f37ded7c2..f5917eb7f 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -297,6 +297,10 @@ class Carousel extends BaseComponent { } _slide(order, element = null) { + if (this._isSliding) { + return + } + const activeElement = this._getActive() const isNext = order === ORDER_NEXT const nextElement = element || getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap) @@ -305,10 +309,6 @@ class Carousel extends BaseComponent { return } - if (this._isSliding) { - return - } - const nextElementIndex = this._getItemIndex(nextElement) const triggerEvent = eventName => { -- cgit v1.2.3 From 28f150d7204788114e2b36555f5e07eb8bdfdbab Mon Sep 17 00:00:00 2001 From: GeoSot Date: Thu, 10 Mar 2022 00:01:55 +0200 Subject: Carousel: omit config merging in jQueryInterface after we create the instance This is already done inside `getOrCreateInstance` method --- js/src/carousel.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index f5917eb7f..37ebde3fc 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -417,14 +417,6 @@ class Carousel extends BaseComponent { return this.each(function () { const data = Carousel.getOrCreateInstance(this, config) - let { _config } = data - if (typeof config === 'object') { - _config = { - ..._config, - ...config - } - } - if (typeof config === 'number') { data.to(config) return @@ -439,7 +431,7 @@ class Carousel extends BaseComponent { return } - if (_config.interval && _config.ride) { + if (data._config.interval && data._config.ride) { data.pause() data.cycle() } -- cgit v1.2.3 From 88da704eedc5149b70dcec7845453456a6e26761 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Thu, 10 Mar 2022 00:38:17 +0200 Subject: Carousel: omit redundant checks as we are always transforming the right values --- js/src/carousel.js | 8 -------- 1 file changed, 8 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 37ebde3fc..70c5fd286 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -389,10 +389,6 @@ class Carousel extends BaseComponent { } _directionToOrder(direction) { - if (![DIRECTION_RIGHT, DIRECTION_LEFT].includes(direction)) { - return direction - } - if (isRTL()) { return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT } @@ -401,10 +397,6 @@ class Carousel extends BaseComponent { } _orderToDirection(order) { - if (![ORDER_NEXT, ORDER_PREV].includes(order)) { - return order - } - if (isRTL()) { return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT } -- cgit v1.2.3 From ec0e1c220e2f9b1f4591b4c7f12a622822f14014 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Thu, 10 Mar 2022 01:00:33 +0200 Subject: Carousel: add comment for future fixes --- js/src/carousel.js | 1 + 1 file changed, 1 insertion(+) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 70c5fd286..edaec08f2 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -328,6 +328,7 @@ class Carousel extends BaseComponent { if (!activeElement || !nextElement) { // Some weirdness is happening, so we bail + // todo: change tests that use empty divs to avoid this check return } -- cgit v1.2.3 From 3673933fe74b4323267b0b0a7871a393ce2ff5cb Mon Sep 17 00:00:00 2001 From: GeoSot Date: Thu, 10 Mar 2022 02:07:01 +0200 Subject: Carousel: rename private property --- js/src/carousel.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index edaec08f2..5a9b2dc84 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -97,7 +97,7 @@ class Carousel extends BaseComponent { this._interval = null this._activeElement = null - this._isPaused = false + this._stayPaused = false this._isSliding = false this.touchTimeout = null this._swipeHelper = null @@ -139,7 +139,7 @@ class Carousel extends BaseComponent { pause(event) { if (!event) { - this._isPaused = true + this._stayPaused = true } if (SelectorEngine.findOne(SELECTOR_NEXT_PREV, this._element)) { @@ -152,11 +152,11 @@ class Carousel extends BaseComponent { cycle(event) { if (!event) { - this._isPaused = false + this._stayPaused = false } this._clearInterval() - if (this._config.interval && !this._isPaused) { + if (this._config.interval && !this._stayPaused) { this._updateInterval() this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval) -- cgit v1.2.3 From 6e904341c9a4a07ea0232850a2dcd4ddc7dfa00a Mon Sep 17 00:00:00 2001 From: GeoSot Date: Thu, 10 Mar 2022 02:12:19 +0200 Subject: Carousel: change class check as it can only exist if carousel is sliding Also, fix the corresponding test --- js/src/carousel.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 5a9b2dc84..7a30beb10 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -59,7 +59,6 @@ const SELECTOR_ACTIVE = '.active' const SELECTOR_ITEM = '.carousel-item' const SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM const SELECTOR_ITEM_IMG = '.carousel-item img' -const SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev' const SELECTOR_INDICATORS = '.carousel-indicators' const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]' const SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]' @@ -142,7 +141,7 @@ class Carousel extends BaseComponent { this._stayPaused = true } - if (SelectorEngine.findOne(SELECTOR_NEXT_PREV, this._element)) { + if (this._isSliding) { triggerTransitionEnd(this._element) this.cycle(true) } -- cgit v1.2.3 From 554736834dd929263ab307593f4d4d3f28f61479 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Thu, 21 Apr 2022 22:42:17 +0300 Subject: Carousel: Fix not used option (`ride`), simplify `cycle` method (#35983) * Fix not used option (`ride`) (according to docs), continuing of #35753 a247fe9 * separate concept of `programmatical cycle` vs `maybe cycle after click` functionality --- js/src/carousel.js | 72 ++++++++++++++++++++++++++---------------------------- 1 file changed, 35 insertions(+), 37 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 7a30beb10..64f38d7e6 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -71,19 +71,19 @@ const KEY_TO_DIRECTION = { const Default = { interval: 5000, keyboard: true, - slide: false, pause: 'hover', - wrap: true, - touch: true + ride: false, + touch: true, + wrap: true } const DefaultType = { interval: '(number|boolean)', keyboard: 'boolean', - slide: '(boolean|string)', + ride: '(boolean|string)', pause: '(string|boolean)', - wrap: 'boolean', - touch: 'boolean' + touch: 'boolean', + wrap: 'boolean' } /** @@ -96,13 +96,16 @@ class Carousel extends BaseComponent { this._interval = null this._activeElement = null - this._stayPaused = false this._isSliding = false this.touchTimeout = null this._swipeHelper = null this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element) this._addEventListeners() + + if (this._config.ride === CLASS_NAME_CAROUSEL) { + this.cycle() + } } // Getters @@ -136,30 +139,32 @@ class Carousel extends BaseComponent { this._slide(ORDER_PREV) } - pause(event) { - if (!event) { - this._stayPaused = true - } - + pause() { if (this._isSliding) { triggerTransitionEnd(this._element) - this.cycle(true) } this._clearInterval() } - cycle(event) { - if (!event) { - this._stayPaused = false - } - + cycle() { this._clearInterval() - if (this._config.interval && !this._stayPaused) { - this._updateInterval() + this._updateInterval() - this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval) + this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval) + } + + _maybeEnableCycle() { + if (!this._config.ride) { + return + } + + if (this._isSliding) { + EventHandler.one(this._element, EVENT_SLID, () => this.cycle()) + return } + + this.cycle() } to(index) { @@ -175,8 +180,6 @@ class Carousel extends BaseComponent { const activeIndex = this._getItemIndex(this._getActive()) if (activeIndex === index) { - this.pause() - this.cycle() return } @@ -205,8 +208,8 @@ class Carousel extends BaseComponent { } if (this._config.pause === 'hover') { - EventHandler.on(this._element, EVENT_MOUSEENTER, event => this.pause(event)) - EventHandler.on(this._element, EVENT_MOUSELEAVE, event => this.cycle(event)) + EventHandler.on(this._element, EVENT_MOUSEENTER, () => this.pause()) + EventHandler.on(this._element, EVENT_MOUSELEAVE, () => this._maybeEnableCycle()) } if (this._config.touch && Swipe.isSupported()) { @@ -237,7 +240,7 @@ class Carousel extends BaseComponent { clearTimeout(this.touchTimeout) } - this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval) + this.touchTimeout = setTimeout(() => this._maybeEnableCycle(), TOUCHEVENT_COMPAT_WAIT + this._config.interval) } const swipeConfig = { @@ -331,12 +334,10 @@ class Carousel extends BaseComponent { return } - this._isSliding = true - const isCycling = Boolean(this._interval) - if (isCycling) { - this.pause() - } + this.pause() + + this._isSliding = true this._setActiveIndicatorElement(nextElementIndex) this._activeElement = nextElement @@ -420,12 +421,6 @@ class Carousel extends BaseComponent { } data[config]() - return - } - - if (data._config.interval && data._config.ride) { - data.pause() - data.cycle() } }) } @@ -449,15 +444,18 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, function (e if (slideIndex) { carousel.to(slideIndex) + carousel._maybeEnableCycle() return } if (Manipulator.getDataAttribute(this, 'slide') === 'next') { carousel.next() + carousel._maybeEnableCycle() return } carousel.prev() + carousel._maybeEnableCycle() }) EventHandler.on(window, EVENT_LOAD_DATA_API, () => { -- cgit v1.2.3 From f7e8ca91e03165abb82d4c82555dc4ef96340cc9 Mon Sep 17 00:00:00 2001 From: Mark Otto Date: Fri, 6 May 2022 23:57:58 +0300 Subject: Prepare v5.2.0-beta1 --- js/src/carousel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 64f38d7e6..b68f32e7c 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v5.1.3): carousel.js + * Bootstrap (v5.2.0-beta1): carousel.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ -- cgit v1.2.3 From c137d11aa2df111e2a42bc42295576fdd366fd68 Mon Sep 17 00:00:00 2001 From: "louismaxime.piton" Date: Thu, 19 May 2022 15:35:44 +0200 Subject: Re-ordering js default objects --- js/src/carousel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index b68f32e7c..b23a85b96 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -80,8 +80,8 @@ const Default = { const DefaultType = { interval: '(number|boolean)', keyboard: 'boolean', - ride: '(boolean|string)', pause: '(string|boolean)', + ride: '(boolean|string)', touch: 'boolean', wrap: 'boolean' } -- cgit v1.2.3 From fc24f8788fbfadf72d627ade9b967f8502e7199a Mon Sep 17 00:00:00 2001 From: GeoSot Date: Tue, 14 Jun 2022 16:17:28 +0300 Subject: Carousel: Remove redundant reference to `interval=false` from docs (#36545) * docs: remove redundant reference to `interval=false` * docs: remove redundant reference to `interval=false` from tests Co-authored-by: XhmikosR --- js/src/carousel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index b23a85b96..5f2f6342e 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -78,7 +78,7 @@ const Default = { } const DefaultType = { - interval: '(number|boolean)', + interval: '(number|boolean)', // TODO:v6 remove boolean support keyboard: 'boolean', pause: '(string|boolean)', ride: '(boolean|string)', -- cgit v1.2.3 From edf9c40956d19e6ab3f9151bfe0dfac6be06fa21 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Tue, 19 Jul 2022 18:43:58 +0300 Subject: Release v5.2.0 (#36768) * Bump version to 5.2.0 * Dist * Update masthead.html --- js/src/carousel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 5f2f6342e..e6e175a21 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v5.2.0-beta1): carousel.js + * Bootstrap (v5.2.0): carousel.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ -- cgit v1.2.3 From 23e50829f958ea1d741d63e2781716be037e4644 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Wed, 7 Sep 2022 18:31:39 +0300 Subject: Release v5.2.1 (#37098) * Bump version to v5.2.1. * Dist --- js/src/carousel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index e6e175a21..025472aae 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v5.2.0): carousel.js + * Bootstrap (v5.2.1): carousel.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ -- cgit v1.2.3 From 961d5ff9844372a4e294980c667bbe7e0651cdeb Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Mon, 3 Oct 2022 10:44:02 +0300 Subject: Release v5.2.2 (#37236) * Bump version to v5.2.2 * Dist --- js/src/carousel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 025472aae..7e89e1614 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v5.2.1): carousel.js + * Bootstrap (v5.2.2): carousel.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ -- cgit v1.2.3 From aa9d32dd153ed16943ad8be5e8795afaad24d0cf Mon Sep 17 00:00:00 2001 From: GeoSot Date: Wed, 26 Oct 2022 08:26:51 +0300 Subject: Use explicit imports in our javascript source files (#36854) --- js/src/carousel.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 7e89e1614..e25395628 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -13,12 +13,12 @@ import { isVisible, reflow, triggerTransitionEnd -} from './util/index' -import EventHandler from './dom/event-handler' -import Manipulator from './dom/manipulator' -import SelectorEngine from './dom/selector-engine' -import Swipe from './util/swipe' -import BaseComponent from './base-component' +} from './util/index.js' +import EventHandler from './dom/event-handler.js' +import Manipulator from './dom/manipulator.js' +import SelectorEngine from './dom/selector-engine.js' +import Swipe from './util/swipe.js' +import BaseComponent from './base-component.js' /** * Constants -- cgit v1.2.3 From e81e7cda90026cdb2a05fcdadd2d66f48f0bbdc4 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Sun, 6 Nov 2022 20:31:43 +0200 Subject: Move `getElementFromSelector` & `getSelectorFromElement` to SelectorEngine (#36027) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Move `getElementFromSelector` & getSelectorFromElement` inside selector-engine.js, in order to use SelectorEngine methods, avoiding raw querySelector usage * add `getMultipleElementsFromSelector` helper Co-authored-by: Julien Déramond --- js/src/carousel.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index e25395628..8ba9f351a 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -7,7 +7,6 @@ import { defineJQueryPlugin, - getElementFromSelector, getNextActiveElement, isRTL, isVisible, @@ -431,7 +430,7 @@ class Carousel extends BaseComponent { */ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, function (event) { - const target = getElementFromSelector(this) + const target = SelectorEngine.getElementFromSelector(this) if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) { return -- cgit v1.2.3 From 39589472f709ddf7d614ffd4f0ab1a50e542ac91 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Mon, 21 Nov 2022 20:15:33 +0200 Subject: Bump version to 5.2.3 --- js/src/carousel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 7e89e1614..24bbe392a 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v5.2.2): carousel.js + * Bootstrap (v5.2.3): carousel.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ -- cgit v1.2.3 From cf9454caa00872899215603e5e036d9a824b1b11 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Sat, 24 Dec 2022 18:37:22 +0200 Subject: Release v5.3.0-alpha1 (#37661) * Bump version to 5.3.0-alpha1 * Dist * Add docs versions updates * Update note in homepage hero Co-authored-by: Mark Otto --- js/src/carousel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index d190075eb..72c77dc4a 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): carousel.js + * Bootstrap (v5.3.0-alpha1): carousel.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ -- cgit v1.2.3 From ab049cd4a02650ca95d490217f93bd628f9295a6 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Wed, 22 Mar 2023 09:12:33 +0200 Subject: Remove version comment from JavaScript src files (#38294) --- js/src/carousel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 72c77dc4a..4d15d7fde 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v5.3.0-alpha1): carousel.js + * Bootstrap carousel.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ -- cgit v1.2.3 From ae43f0c48bf7acede8a325b24197001fe2b2f416 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Wed, 29 Mar 2023 20:49:30 +0300 Subject: Tweak and re-organize ESLint config (#38369) * Tweak and re-organize ESLint config * merge individual configs to the root config * enable more eslint-plugin-import rules * lint markdown files * Lint --- js/src/carousel.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'js/src/carousel.js') diff --git a/js/src/carousel.js b/js/src/carousel.js index 4d15d7fde..68d11a32f 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -5,6 +5,10 @@ * -------------------------------------------------------------------------- */ +import BaseComponent from './base-component.js' +import EventHandler from './dom/event-handler.js' +import Manipulator from './dom/manipulator.js' +import SelectorEngine from './dom/selector-engine.js' import { defineJQueryPlugin, getNextActiveElement, @@ -13,11 +17,7 @@ import { reflow, triggerTransitionEnd } from './util/index.js' -import EventHandler from './dom/event-handler.js' -import Manipulator from './dom/manipulator.js' -import SelectorEngine from './dom/selector-engine.js' import Swipe from './util/swipe.js' -import BaseComponent from './base-component.js' /** * Constants @@ -329,7 +329,7 @@ class Carousel extends BaseComponent { if (!activeElement || !nextElement) { // Some weirdness is happening, so we bail - // todo: change tests that use empty divs to avoid this check + // TODO: change tests that use empty divs to avoid this check return } -- cgit v1.2.3