Skip to content

Commit ac2a708

Browse files
authored
fix(carousel): setInterval memory leak when no slides provided (#2399)
1 parent f46258f commit ac2a708

File tree

3 files changed

+39
-5
lines changed

3 files changed

+39
-5
lines changed

Diff for: src/components/carousel/carousel.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,7 @@ export default {
213213
attributeFilter: [ 'id' ]
214214
})
215215
},
216-
/* istanbul ignore next: dificult to test */
217-
beforeDestroy () {
216+
beforeDestroy () /* istanbul ignore next: dificult to test */ {
218217
clearInterval(this.intervalId)
219218
clearTimeout(this._animationTimeout)
220219
this.intervalId = null
@@ -224,6 +223,7 @@ export default {
224223
// Set slide
225224
setSlide (slide) {
226225
// Don't animate when page is not visible
226+
/* istanbul ignore if: dificult to test */
227227
if (typeof document !== 'undefined' && document.visibilityState && document.hidden) {
228228
return
229229
}
@@ -266,8 +266,8 @@ export default {
266266
},
267267
// Start auto rotate slides
268268
start () {
269-
// Don't start if no interval, or if we are already running
270-
if (!this.interval || this.isCycling) {
269+
// Don't start if no interval, no slides, or if we are already running
270+
if (!this.interval || this.isCycling || this.intervalId || this.slides.length === 0) {
271271
return
272272
}
273273
this.slides.forEach(slide => {
@@ -279,6 +279,7 @@ export default {
279279
},
280280
// Re-Start auto rotate slides when focus/hover leaves the carousel
281281
restart (evt) {
282+
/* istanbul ignore if: dificult to test */
282283
if (!this.$el.contains(document.activeElement)) {
283284
this.start()
284285
}

Diff for: src/components/carousel/carousel.spec.js

+25
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,29 @@ describe('carousel', async () => {
7070
expect(carousel.isSliding).toBe(false)
7171
})
7272
})
73+
74+
it('Should scroll to specified slide', async () => {
75+
const { app } = window
76+
const carousel = app.$refs.carousel
77+
78+
const spyBegin = jest.fn()
79+
const spyEnd = jest.fn()
80+
81+
carousel.$on('sliding-start', spyBegin)
82+
carousel.$on('sliding-end', spyEnd)
83+
84+
app.slide = 2
85+
86+
app.$nextTick(() => {
87+
expect(spyBegin).toHaveBeenCalled()
88+
expect(carousel.isSliding).toBe(true)
89+
})
90+
91+
jest.runAllTimers()
92+
93+
app.$nextTick(() => {
94+
expect(spyEnd).toHaveBeenCalledWith(app.slide)
95+
expect(carousel.isSliding).toBe(false)
96+
})
97+
})
7398
})

Diff for: src/components/carousel/fixtures/carousel.html

+9-1
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,16 @@ <h1>Hello world!</h1>
3030

3131
</b-carousel>
3232

33-
<p class="mt-4">
33+
<p class="mt-4 mb-4">
3434
Slide #: {{ slide }}<br>
3535
Is Sliding: {{ sliding }}
3636
</p>
37+
38+
<!-- empty carousel -->
39+
<b-carousel id="carousel2"
40+
ref="carousel2"
41+
controls
42+
indicators
43+
background="grey">
44+
</b-carousel>
3745
</div>

0 commit comments

Comments
 (0)