1
0
mirror of https://github.com/twbs/bootstrap.git synced 2025-08-11 08:04:59 +02:00

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
This commit is contained in:
GeoSot
2022-04-21 22:42:17 +03:00
committed by GitHub
parent 584600bda3
commit 554736834d
3 changed files with 143 additions and 146 deletions

View File

@@ -63,6 +63,20 @@ describe('Carousel', () => {
expect(carouselByElement._element).toEqual(carouselEl)
})
it('should start cycling if `ride`===`carousel`', () => {
fixtureEl.innerHTML = '<div id="myCarousel" class="carousel slide" data-bs-ride="carousel"></div>'
const carousel = new Carousel('#myCarousel')
expect(carousel._interval).not.toBeNull()
})
it('should not start cycling if `ride`!==`carousel`', () => {
fixtureEl.innerHTML = '<div id="myCarousel" class="carousel slide" data-bs-ride="true"></div>'
const carousel = new Carousel('#myCarousel')
expect(carousel._interval).toBeNull()
})
it('should go to next item if right arrow key is pressed', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = [
@@ -95,6 +109,40 @@ describe('Carousel', () => {
})
})
it('should ignore keyboard events if data-bs-keyboard=false', () => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide" data-bs-keyboard="false">',
' <div class="carousel-inner">',
' <div class="carousel-item active">item 1</div>',
' <div id="item2" class="carousel-item">item 2</div>',
' </div>',
'</div>'
].join('')
spyOn(EventHandler, 'trigger').and.callThrough()
const carouselEl = fixtureEl.querySelector('#myCarousel')
// eslint-disable-next-line no-new
new Carousel('#myCarousel')
expect(EventHandler.trigger).not.toHaveBeenCalledWith(carouselEl, 'keydown.bs.carousel', jasmine.any(Function))
})
it('should ignore mouse events if data-bs-pause=false', () => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide" data-bs-pause="false">',
' <div class="carousel-inner">',
' <div class="carousel-item active">item 1</div>',
' <div id="item2" class="carousel-item">item 2</div>',
' </div>',
'</div>'
].join('')
spyOn(EventHandler, 'trigger').and.callThrough()
const carouselEl = fixtureEl.querySelector('#myCarousel')
// eslint-disable-next-line no-new
new Carousel('#myCarousel')
expect(EventHandler.trigger).not.toHaveBeenCalledWith(carouselEl, 'hover.bs.carousel', jasmine.any(Function))
})
it('should go to previous item if left arrow key is pressed', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = [
@@ -612,19 +660,21 @@ describe('Carousel', () => {
})
})
it('should call cycle on mouse out with pause equal to hover', () => {
it('should call `maybeCycle` on mouse out with pause equal to hover', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<div class="carousel"></div>'
fixtureEl.innerHTML = '<div class="carousel" data-bs-ride="true"></div>'
const carouselEl = fixtureEl.querySelector('.carousel')
const carousel = new Carousel(carouselEl)
spyOn(carousel, '_maybeEnableCycle').and.callThrough()
spyOn(carousel, 'cycle')
const mouseOutEvent = createEvent('mouseout')
carouselEl.dispatchEvent(mouseOutEvent)
setTimeout(() => {
expect(carousel._maybeEnableCycle).toHaveBeenCalled()
expect(carousel.cycle).toHaveBeenCalled()
resolve()
}, 10)
@@ -769,6 +819,28 @@ describe('Carousel', () => {
expect(carousel._activeElement).toEqual(secondItemEl)
})
it('should continue cycling if it was already', () => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
' <div class="carousel-item active">item 1</div>',
' <div class="carousel-item">item 2</div>',
' </div>',
'</div>'
].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')
const carousel = new Carousel(carouselEl)
spyOn(carousel, 'cycle')
carousel.next()
expect(carousel.cycle).not.toHaveBeenCalled()
carousel.cycle()
carousel.next()
expect(carousel.cycle).toHaveBeenCalled()
})
it('should update indicators if present', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = [
@@ -823,12 +895,14 @@ describe('Carousel', () => {
const carousel = new Carousel(carouselEl)
const nextSpy = spyOn(carousel, 'next')
const prevSpy = spyOn(carousel, 'prev')
spyOn(carousel, '_maybeEnableCycle')
nextBtnEl.click()
prevBtnEl.click()
expect(nextSpy).toHaveBeenCalled()
expect(prevSpy).toHaveBeenCalled()
expect(carousel._maybeEnableCycle).toHaveBeenCalled()
})
})
@@ -868,82 +942,32 @@ describe('Carousel', () => {
})
describe('pause', () => {
it('should call cycle if the carousel have carousel-item-next or carousel-item-prev class, cause is sliding', () => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
' <div class="carousel-item active">item 1</div>',
' <div class="carousel-item carousel-item-next">item 2</div>',
' <div class="carousel-item">item 3</div>',
' </div>',
' <div class="carousel-control-prev"></div>',
' <div class="carousel-control-next"></div>',
'</div>'
].join('')
it('should trigger transitionend if the carousel have carousel-item-next or carousel-item-prev class, cause is sliding', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
' <div class="carousel-item active">item 1</div>',
' <div class="carousel-item carousel-item-next">item 2</div>',
' <div class="carousel-item">item 3</div>',
' </div>',
' <div class="carousel-control-prev"></div>',
' <div class="carousel-control-next"></div>',
'</div>'
].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')
const carousel = new Carousel(carouselEl)
const carouselEl = fixtureEl.querySelector('#myCarousel')
const carousel = new Carousel(carouselEl)
spyOn(carousel, 'cycle')
spyOn(carousel, '_clearInterval')
carouselEl.addEventListener('transitionend', () => {
expect(carousel._clearInterval).toHaveBeenCalled()
resolve()
})
carousel._slide('next')
carousel.pause()
expect(carousel.cycle).toHaveBeenCalledWith(true)
expect(carousel._clearInterval).toHaveBeenCalled()
expect(carousel._stayPaused).toBeTrue()
})
it('should not call cycle if nothing is in transition', () => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
' <div class="carousel-item active">item 1</div>',
' <div class="carousel-item">item 2</div>',
' <div class="carousel-item">item 3</div>',
' </div>',
' <div class="carousel-control-prev"></div>',
' <div class="carousel-control-next"></div>',
'</div>'
].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')
const carousel = new Carousel(carouselEl)
spyOn(carousel, 'cycle')
spyOn(carousel, '_clearInterval')
carousel.pause()
expect(carousel.cycle).not.toHaveBeenCalled()
expect(carousel._clearInterval).toHaveBeenCalled()
expect(carousel._stayPaused).toBeTrue()
})
it('should not set is paused at true if an event is passed', () => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
' <div class="carousel-item active">item 1</div>',
' <div class="carousel-item">item 2</div>',
' <div class="carousel-item">item 3</div>',
' </div>',
' <div class="carousel-control-prev"></div>',
' <div class="carousel-control-next"></div>',
'</div>'
].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')
const carousel = new Carousel(carouselEl)
const event = createEvent('mouseenter')
spyOn(carousel, '_clearInterval')
carousel.pause(event)
expect(carousel._clearInterval).toHaveBeenCalled()
expect(carousel._stayPaused).toBeFalse()
spyOn(carousel, '_clearInterval')
carousel._slide('next')
carousel.pause()
})
})
})
@@ -971,30 +995,6 @@ describe('Carousel', () => {
expect(window.setInterval).toHaveBeenCalled()
})
it('should not set interval if the carousel is paused', () => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
' <div class="carousel-item active">item 1</div>',
' <div class="carousel-item">item 2</div>',
' <div class="carousel-item">item 3</div>',
' </div>',
' <div class="carousel-control-prev"></div>',
' <div class="carousel-control-next"></div>',
'</div>'
].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')
const carousel = new Carousel(carouselEl)
spyOn(window, 'setInterval').and.callThrough()
carousel._stayPaused = true
carousel.cycle(true)
expect(window.setInterval).not.toHaveBeenCalled()
})
it('should clear interval if there is one', () => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
@@ -1132,7 +1132,7 @@ describe('Carousel', () => {
expect(spy).not.toHaveBeenCalled()
})
it('should call pause and cycle is the provided is the same compare to the current one', () => {
it('should not continue if the provided is the same compare to the current one', () => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
@@ -1153,8 +1153,6 @@ describe('Carousel', () => {
carousel.to(0)
expect(carousel._slide).not.toHaveBeenCalled()
expect(carousel.pause).toHaveBeenCalled()
expect(carousel.cycle).toHaveBeenCalled()
})
it('should wait before performing to if a slide is sliding', () => {
@@ -1449,8 +1447,8 @@ describe('Carousel', () => {
const loadEvent = createEvent('load')
window.dispatchEvent(loadEvent)
expect(Carousel.getInstance(carouselEl)).not.toBeNull()
const carousel = Carousel.getInstance(carouselEl)
expect(carousel._interval).not.toBeNull()
})
it('should create carousel and go to the next slide on click (with real button controls)', () => {
@@ -1508,7 +1506,7 @@ describe('Carousel', () => {
it('should create carousel and go to the next slide on click with data-bs-slide-to', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
'<div id="myCarousel" class="carousel slide" data-bs-ride="true">',
' <div class="carousel-inner">',
' <div class="carousel-item active">item 1</div>',
' <div id="item2" class="carousel-item">item 2</div>',
@@ -1525,6 +1523,7 @@ describe('Carousel', () => {
setTimeout(() => {
expect(item2).toHaveClass('active')
expect(Carousel.getInstance('#myCarousel')._interval).not.toBeNull()
resolve()
}, 10)
})