carousel.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. $(function () {
  2. 'use strict';
  3. QUnit.module('carousel plugin')
  4. QUnit.test('should be defined on jQuery object', function (assert) {
  5. assert.expect(1)
  6. assert.ok($(document.body).carousel, 'carousel method is defined')
  7. })
  8. QUnit.module('carousel', {
  9. beforeEach: function () {
  10. // Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode
  11. $.fn.bootstrapCarousel = $.fn.carousel.noConflict()
  12. },
  13. afterEach: function () {
  14. $.fn.carousel = $.fn.bootstrapCarousel
  15. delete $.fn.bootstrapCarousel
  16. }
  17. })
  18. QUnit.test('should provide no conflict', function (assert) {
  19. assert.expect(1)
  20. assert.strictEqual($.fn.carousel, undefined, 'carousel was set back to undefined (orig value)')
  21. })
  22. QUnit.test('should return jquery collection containing the element', function (assert) {
  23. assert.expect(2)
  24. var $el = $('<div/>')
  25. var $carousel = $el.bootstrapCarousel()
  26. assert.ok($carousel instanceof $, 'returns jquery collection')
  27. assert.strictEqual($carousel[0], $el[0], 'collection contains element')
  28. })
  29. QUnit.test('should not fire slid when slide is prevented', function (assert) {
  30. assert.expect(1)
  31. var done = assert.async()
  32. $('<div class="carousel"/>')
  33. .on('slide.bs.carousel', function (e) {
  34. e.preventDefault()
  35. assert.ok(true, 'slide event fired')
  36. done()
  37. })
  38. .on('slid.bs.carousel', function () {
  39. assert.ok(false, 'slid event fired')
  40. })
  41. .bootstrapCarousel('next')
  42. })
  43. QUnit.test('should reset when slide is prevented', function (assert) {
  44. assert.expect(6)
  45. var carouselHTML = '<div id="carousel-example-generic" class="carousel slide">'
  46. + '<ol class="carousel-indicators">'
  47. + '<li data-target="#carousel-example-generic" data-slide-to="0" class="active"/>'
  48. + '<li data-target="#carousel-example-generic" data-slide-to="1"/>'
  49. + '<li data-target="#carousel-example-generic" data-slide-to="2"/>'
  50. + '</ol>'
  51. + '<div class="carousel-inner">'
  52. + '<div class="item active">'
  53. + '<div class="carousel-caption"/>'
  54. + '</div>'
  55. + '<div class="item">'
  56. + '<div class="carousel-caption"/>'
  57. + '</div>'
  58. + '<div class="item">'
  59. + '<div class="carousel-caption"/>'
  60. + '</div>'
  61. + '</div>'
  62. + '<a class="left carousel-control" href="#carousel-example-generic" data-slide="prev"/>'
  63. + '<a class="right carousel-control" href="#carousel-example-generic" data-slide="next"/>'
  64. + '</div>'
  65. var $carousel = $(carouselHTML)
  66. var done = assert.async()
  67. $carousel
  68. .one('slide.bs.carousel', function (e) {
  69. e.preventDefault()
  70. setTimeout(function () {
  71. assert.ok($carousel.find('.item:eq(0)').is('.active'), 'first item still active')
  72. assert.ok($carousel.find('.carousel-indicators li:eq(0)').is('.active'), 'first indicator still active')
  73. $carousel.bootstrapCarousel('next')
  74. }, 0)
  75. })
  76. .one('slid.bs.carousel', function () {
  77. setTimeout(function () {
  78. assert.ok(!$carousel.find('.item:eq(0)').is('.active'), 'first item still active')
  79. assert.ok(!$carousel.find('.carousel-indicators li:eq(0)').is('.active'), 'first indicator still active')
  80. assert.ok($carousel.find('.item:eq(1)').is('.active'), 'second item active')
  81. assert.ok($carousel.find('.carousel-indicators li:eq(1)').is('.active'), 'second indicator active')
  82. done()
  83. }, 0)
  84. })
  85. .bootstrapCarousel('next')
  86. })
  87. QUnit.test('should fire slide event with direction', function (assert) {
  88. assert.expect(4)
  89. var carouselHTML = '<div id="myCarousel" class="carousel slide">'
  90. + '<div class="carousel-inner">'
  91. + '<div class="item active">'
  92. + '<img alt="">'
  93. + '<div class="carousel-caption">'
  94. + '<h4>First Thumbnail label</h4>'
  95. + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
  96. + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
  97. + 'ultricies vehicula ut id elit.</p>'
  98. + '</div>'
  99. + '</div>'
  100. + '<div class="item">'
  101. + '<img alt="">'
  102. + '<div class="carousel-caption">'
  103. + '<h4>Second Thumbnail label</h4>'
  104. + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
  105. + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
  106. + 'ultricies vehicula ut id elit.</p>'
  107. + '</div>'
  108. + '</div>'
  109. + '<div class="item">'
  110. + '<img alt="">'
  111. + '<div class="carousel-caption">'
  112. + '<h4>Third Thumbnail label</h4>'
  113. + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
  114. + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
  115. + 'ultricies vehicula ut id elit.</p>'
  116. + '</div>'
  117. + '</div>'
  118. + '</div>'
  119. + '<a class="left carousel-control" href="#myCarousel" data-slide="prev">&lsaquo;</a>'
  120. + '<a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</a>'
  121. + '</div>'
  122. var $carousel = $(carouselHTML)
  123. var done = assert.async()
  124. $carousel
  125. .one('slide.bs.carousel', function (e) {
  126. assert.ok(e.direction, 'direction present on next')
  127. assert.strictEqual(e.direction, 'left', 'direction is left on next')
  128. $carousel
  129. .one('slide.bs.carousel', function (e) {
  130. assert.ok(e.direction, 'direction present on prev')
  131. assert.strictEqual(e.direction, 'right', 'direction is right on prev')
  132. done()
  133. })
  134. .bootstrapCarousel('prev')
  135. })
  136. .bootstrapCarousel('next')
  137. })
  138. QUnit.test('should fire slid event with direction', function (assert) {
  139. assert.expect(4)
  140. var carouselHTML = '<div id="myCarousel" class="carousel slide">'
  141. + '<div class="carousel-inner">'
  142. + '<div class="item active">'
  143. + '<img alt="">'
  144. + '<div class="carousel-caption">'
  145. + '<h4>First Thumbnail label</h4>'
  146. + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
  147. + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
  148. + 'ultricies vehicula ut id elit.</p>'
  149. + '</div>'
  150. + '</div>'
  151. + '<div class="item">'
  152. + '<img alt="">'
  153. + '<div class="carousel-caption">'
  154. + '<h4>Second Thumbnail label</h4>'
  155. + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
  156. + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
  157. + 'ultricies vehicula ut id elit.</p>'
  158. + '</div>'
  159. + '</div>'
  160. + '<div class="item">'
  161. + '<img alt="">'
  162. + '<div class="carousel-caption">'
  163. + '<h4>Third Thumbnail label</h4>'
  164. + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
  165. + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
  166. + 'ultricies vehicula ut id elit.</p>'
  167. + '</div>'
  168. + '</div>'
  169. + '</div>'
  170. + '<a class="left carousel-control" href="#myCarousel" data-slide="prev">&lsaquo;</a>'
  171. + '<a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</a>'
  172. + '</div>'
  173. var $carousel = $(carouselHTML)
  174. var done = assert.async()
  175. $carousel
  176. .one('slid.bs.carousel', function (e) {
  177. assert.ok(e.direction, 'direction present on next')
  178. assert.strictEqual(e.direction, 'left', 'direction is left on next')
  179. $carousel
  180. .one('slid.bs.carousel', function (e) {
  181. assert.ok(e.direction, 'direction present on prev')
  182. assert.strictEqual(e.direction, 'right', 'direction is right on prev')
  183. done()
  184. })
  185. .bootstrapCarousel('prev')
  186. })
  187. .bootstrapCarousel('next')
  188. })
  189. QUnit.test('should fire slide event with relatedTarget', function (assert) {
  190. assert.expect(2)
  191. var template = '<div id="myCarousel" class="carousel slide">'
  192. + '<div class="carousel-inner">'
  193. + '<div class="item active">'
  194. + '<img alt="">'
  195. + '<div class="carousel-caption">'
  196. + '<h4>First Thumbnail label</h4>'
  197. + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
  198. + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
  199. + 'ultricies vehicula ut id elit.</p>'
  200. + '</div>'
  201. + '</div>'
  202. + '<div class="item">'
  203. + '<img alt="">'
  204. + '<div class="carousel-caption">'
  205. + '<h4>Second Thumbnail label</h4>'
  206. + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
  207. + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
  208. + 'ultricies vehicula ut id elit.</p>'
  209. + '</div>'
  210. + '</div>'
  211. + '<div class="item">'
  212. + '<img alt="">'
  213. + '<div class="carousel-caption">'
  214. + '<h4>Third Thumbnail label</h4>'
  215. + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
  216. + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
  217. + 'ultricies vehicula ut id elit.</p>'
  218. + '</div>'
  219. + '</div>'
  220. + '</div>'
  221. + '<a class="left carousel-control" href="#myCarousel" data-slide="prev">&lsaquo;</a>'
  222. + '<a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</a>'
  223. + '</div>'
  224. var done = assert.async()
  225. $(template)
  226. .on('slide.bs.carousel', function (e) {
  227. assert.ok(e.relatedTarget, 'relatedTarget present')
  228. assert.ok($(e.relatedTarget).hasClass('item'), 'relatedTarget has class "item"')
  229. done()
  230. })
  231. .bootstrapCarousel('next')
  232. })
  233. QUnit.test('should fire slid event with relatedTarget', function (assert) {
  234. assert.expect(2)
  235. var template = '<div id="myCarousel" class="carousel slide">'
  236. + '<div class="carousel-inner">'
  237. + '<div class="item active">'
  238. + '<img alt="">'
  239. + '<div class="carousel-caption">'
  240. + '<h4>First Thumbnail label</h4>'
  241. + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
  242. + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
  243. + 'ultricies vehicula ut id elit.</p>'
  244. + '</div>'
  245. + '</div>'
  246. + '<div class="item">'
  247. + '<img alt="">'
  248. + '<div class="carousel-caption">'
  249. + '<h4>Second Thumbnail label</h4>'
  250. + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
  251. + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
  252. + 'ultricies vehicula ut id elit.</p>'
  253. + '</div>'
  254. + '</div>'
  255. + '<div class="item">'
  256. + '<img alt="">'
  257. + '<div class="carousel-caption">'
  258. + '<h4>Third Thumbnail label</h4>'
  259. + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
  260. + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
  261. + 'ultricies vehicula ut id elit.</p>'
  262. + '</div>'
  263. + '</div>'
  264. + '</div>'
  265. + '<a class="left carousel-control" href="#myCarousel" data-slide="prev">&lsaquo;</a>'
  266. + '<a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</a>'
  267. + '</div>'
  268. var done = assert.async()
  269. $(template)
  270. .on('slid.bs.carousel', function (e) {
  271. assert.ok(e.relatedTarget, 'relatedTarget present')
  272. assert.ok($(e.relatedTarget).hasClass('item'), 'relatedTarget has class "item"')
  273. done()
  274. })
  275. .bootstrapCarousel('next')
  276. })
  277. QUnit.test('should set interval from data attribute', function (assert) {
  278. assert.expect(4)
  279. var templateHTML = '<div id="myCarousel" class="carousel slide">'
  280. + '<div class="carousel-inner">'
  281. + '<div class="item active">'
  282. + '<img alt="">'
  283. + '<div class="carousel-caption">'
  284. + '<h4>First Thumbnail label</h4>'
  285. + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
  286. + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
  287. + 'ultricies vehicula ut id elit.</p>'
  288. + '</div>'
  289. + '</div>'
  290. + '<div class="item">'
  291. + '<img alt="">'
  292. + '<div class="carousel-caption">'
  293. + '<h4>Second Thumbnail label</h4>'
  294. + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
  295. + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
  296. + 'ultricies vehicula ut id elit.</p>'
  297. + '</div>'
  298. + '</div>'
  299. + '<div class="item">'
  300. + '<img alt="">'
  301. + '<div class="carousel-caption">'
  302. + '<h4>Third Thumbnail label</h4>'
  303. + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
  304. + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
  305. + 'ultricies vehicula ut id elit.</p>'
  306. + '</div>'
  307. + '</div>'
  308. + '</div>'
  309. + '<a class="left carousel-control" href="#myCarousel" data-slide="prev">&lsaquo;</a>'
  310. + '<a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</a>'
  311. + '</div>'
  312. var $carousel = $(templateHTML)
  313. $carousel.attr('data-interval', 1814)
  314. $carousel.appendTo('body')
  315. $('[data-slide]').first().trigger('click')
  316. assert.strictEqual($carousel.data('bs.carousel').options.interval, 1814)
  317. $carousel.remove()
  318. $carousel.appendTo('body').attr('data-modal', 'foobar')
  319. $('[data-slide]').first().trigger('click')
  320. assert.strictEqual($carousel.data('bs.carousel').options.interval, 1814, 'even if there is an data-modal attribute set')
  321. $carousel.remove()
  322. $carousel.appendTo('body')
  323. $('[data-slide]').first().trigger('click')
  324. $carousel.attr('data-interval', 1860)
  325. $('[data-slide]').first().trigger('click')
  326. assert.strictEqual($carousel.data('bs.carousel').options.interval, 1814, 'attributes should be read only on initialization')
  327. $carousel.remove()
  328. $carousel.attr('data-interval', false)
  329. $carousel.appendTo('body')
  330. $carousel.bootstrapCarousel(1)
  331. assert.strictEqual($carousel.data('bs.carousel').options.interval, false, 'data attribute has higher priority than default options')
  332. $carousel.remove()
  333. })
  334. QUnit.test('should skip over non-items when using item indices', function (assert) {
  335. assert.expect(2)
  336. var templateHTML = '<div id="myCarousel" class="carousel" data-interval="1814">'
  337. + '<div class="carousel-inner">'
  338. + '<div class="item active">'
  339. + '<img alt="">'
  340. + '</div>'
  341. + '<script type="text/x-metamorph" id="thingy"/>'
  342. + '<div class="item">'
  343. + '<img alt="">'
  344. + '</div>'
  345. + '<div class="item">'
  346. + '</div>'
  347. + '</div>'
  348. + '</div>'
  349. var $template = $(templateHTML)
  350. $template.bootstrapCarousel()
  351. assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item active')
  352. $template.bootstrapCarousel(1)
  353. assert.strictEqual($template.find('.item')[1], $template.find('.active')[0], 'second item active')
  354. })
  355. QUnit.test('should skip over non-items when using next/prev methods', function (assert) {
  356. assert.expect(2)
  357. var templateHTML = '<div id="myCarousel" class="carousel" data-interval="1814">'
  358. + '<div class="carousel-inner">'
  359. + '<div class="item active">'
  360. + '<img alt="">'
  361. + '</div>'
  362. + '<script type="text/x-metamorph" id="thingy"/>'
  363. + '<div class="item">'
  364. + '<img alt="">'
  365. + '</div>'
  366. + '<div class="item">'
  367. + '</div>'
  368. + '</div>'
  369. + '</div>'
  370. var $template = $(templateHTML)
  371. $template.bootstrapCarousel()
  372. assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item active')
  373. $template.bootstrapCarousel('next')
  374. assert.strictEqual($template.find('.item')[1], $template.find('.active')[0], 'second item active')
  375. })
  376. QUnit.test('should go to previous item if left arrow key is pressed', function (assert) {
  377. assert.expect(2)
  378. var templateHTML = '<div id="myCarousel" class="carousel" data-interval="false">'
  379. + '<div class="carousel-inner">'
  380. + '<div id="first" class="item">'
  381. + '<img alt="">'
  382. + '</div>'
  383. + '<div id="second" class="item active">'
  384. + '<img alt="">'
  385. + '</div>'
  386. + '<div id="third" class="item">'
  387. + '<img alt="">'
  388. + '</div>'
  389. + '</div>'
  390. + '</div>'
  391. var $template = $(templateHTML)
  392. $template.bootstrapCarousel()
  393. assert.strictEqual($template.find('.item')[1], $template.find('.active')[0], 'second item active')
  394. $template.trigger($.Event('keydown', { which: 37 }))
  395. assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item active')
  396. })
  397. QUnit.test('should go to next item if right arrow key is pressed', function (assert) {
  398. assert.expect(2)
  399. var templateHTML = '<div id="myCarousel" class="carousel" data-interval="false">'
  400. + '<div class="carousel-inner">'
  401. + '<div id="first" class="item active">'
  402. + '<img alt="">'
  403. + '</div>'
  404. + '<div id="second" class="item">'
  405. + '<img alt="">'
  406. + '</div>'
  407. + '<div id="third" class="item">'
  408. + '<img alt="">'
  409. + '</div>'
  410. + '</div>'
  411. + '</div>'
  412. var $template = $(templateHTML)
  413. $template.bootstrapCarousel()
  414. assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item active')
  415. $template.trigger($.Event('keydown', { which: 39 }))
  416. assert.strictEqual($template.find('.item')[1], $template.find('.active')[0], 'second item active')
  417. })
  418. QUnit.test('should support disabling the keyboard navigation', function (assert) {
  419. assert.expect(3)
  420. var templateHTML = '<div id="myCarousel" class="carousel" data-interval="false" data-keyboard="false">'
  421. + '<div class="carousel-inner">'
  422. + '<div id="first" class="item active">'
  423. + '<img alt="">'
  424. + '</div>'
  425. + '<div id="second" class="item">'
  426. + '<img alt="">'
  427. + '</div>'
  428. + '<div id="third" class="item">'
  429. + '<img alt="">'
  430. + '</div>'
  431. + '</div>'
  432. + '</div>'
  433. var $template = $(templateHTML)
  434. $template.bootstrapCarousel()
  435. assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item active')
  436. $template.trigger($.Event('keydown', { which: 39 }))
  437. assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item still active after right arrow press')
  438. $template.trigger($.Event('keydown', { which: 37 }))
  439. assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item still active after left arrow press')
  440. })
  441. QUnit.test('should ignore keyboard events within <input>s and <textarea>s', function (assert) {
  442. assert.expect(7)
  443. var templateHTML = '<div id="myCarousel" class="carousel" data-interval="false">'
  444. + '<div class="carousel-inner">'
  445. + '<div id="first" class="item active">'
  446. + '<img alt="">'
  447. + '<input type="text" id="in-put">'
  448. + '<textarea id="text-area"></textarea>'
  449. + '</div>'
  450. + '<div id="second" class="item">'
  451. + '<img alt="">'
  452. + '</div>'
  453. + '<div id="third" class="item">'
  454. + '<img alt="">'
  455. + '</div>'
  456. + '</div>'
  457. + '</div>'
  458. var $template = $(templateHTML)
  459. var $input = $template.find('#in-put')
  460. var $textarea = $template.find('#text-area')
  461. assert.strictEqual($input.length, 1, 'found <input>')
  462. assert.strictEqual($textarea.length, 1, 'found <textarea>')
  463. $template.bootstrapCarousel()
  464. assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item active')
  465. $input.trigger($.Event('keydown', { which: 39 }))
  466. assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item still active after right arrow press in <input>')
  467. $input.trigger($.Event('keydown', { which: 37 }))
  468. assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item still active after left arrow press in <input>')
  469. $textarea.trigger($.Event('keydown', { which: 39 }))
  470. assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item still active after right arrow press in <textarea>')
  471. $textarea.trigger($.Event('keydown', { which: 37 }))
  472. assert.strictEqual($template.find('.item')[0], $template.find('.active')[0], 'first item still active after left arrow press in <textarea>')
  473. })
  474. QUnit.test('should only add mouseenter and mouseleave listeners when not on mobile', function (assert) {
  475. assert.expect(2)
  476. var isMobile = 'ontouchstart' in document.documentElement
  477. var templateHTML = '<div id="myCarousel" class="carousel" data-interval="false" data-pause="hover">'
  478. + '<div class="carousel-inner">'
  479. + '<div id="first" class="item active">'
  480. + '<img alt="">'
  481. + '</div>'
  482. + '<div id="second" class="item">'
  483. + '<img alt="">'
  484. + '</div>'
  485. + '<div id="third" class="item">'
  486. + '<img alt="">'
  487. + '</div>'
  488. + '</div>'
  489. + '</div>'
  490. var $template = $(templateHTML).bootstrapCarousel()
  491. $.each(['mouseover', 'mouseout'], function (i, type) {
  492. assert.strictEqual(type in $._data($template[0], 'events'), !isMobile, 'does' + (isMobile ? ' not' : '') + ' listen for ' + type + ' events')
  493. })
  494. })
  495. QUnit.test('should wrap around from end to start when wrap option is true', function (assert) {
  496. assert.expect(3)
  497. var carouselHTML = '<div id="carousel-example-generic" class="carousel slide" data-wrap="true">'
  498. + '<ol class="carousel-indicators">'
  499. + '<li data-target="#carousel-example-generic" data-slide-to="0" class="active"/>'
  500. + '<li data-target="#carousel-example-generic" data-slide-to="1"/>'
  501. + '<li data-target="#carousel-example-generic" data-slide-to="2"/>'
  502. + '</ol>'
  503. + '<div class="carousel-inner">'
  504. + '<div class="item active" id="one">'
  505. + '<div class="carousel-caption"/>'
  506. + '</div>'
  507. + '<div class="item" id="two">'
  508. + '<div class="carousel-caption"/>'
  509. + '</div>'
  510. + '<div class="item" id="three">'
  511. + '<div class="carousel-caption"/>'
  512. + '</div>'
  513. + '</div>'
  514. + '<a class="left carousel-control" href="#carousel-example-generic" data-slide="prev"/>'
  515. + '<a class="right carousel-control" href="#carousel-example-generic" data-slide="next"/>'
  516. + '</div>'
  517. var $carousel = $(carouselHTML)
  518. var getActiveId = function () { return $carousel.find('.item.active').attr('id') }
  519. var done = assert.async()
  520. $carousel
  521. .one('slid.bs.carousel', function () {
  522. assert.strictEqual(getActiveId(), 'two', 'carousel slid from 1st to 2nd slide')
  523. $carousel
  524. .one('slid.bs.carousel', function () {
  525. assert.strictEqual(getActiveId(), 'three', 'carousel slid from 2nd to 3rd slide')
  526. $carousel
  527. .one('slid.bs.carousel', function () {
  528. assert.strictEqual(getActiveId(), 'one', 'carousel wrapped around and slid from 3rd to 1st slide')
  529. done()
  530. })
  531. .bootstrapCarousel('next')
  532. })
  533. .bootstrapCarousel('next')
  534. })
  535. .bootstrapCarousel('next')
  536. })
  537. QUnit.test('should wrap around from start to end when wrap option is true', function (assert) {
  538. assert.expect(1)
  539. var carouselHTML = '<div id="carousel-example-generic" class="carousel slide" data-wrap="true">'
  540. + '<ol class="carousel-indicators">'
  541. + '<li data-target="#carousel-example-generic" data-slide-to="0" class="active"/>'
  542. + '<li data-target="#carousel-example-generic" data-slide-to="1"/>'
  543. + '<li data-target="#carousel-example-generic" data-slide-to="2"/>'
  544. + '</ol>'
  545. + '<div class="carousel-inner">'
  546. + '<div class="item active" id="one">'
  547. + '<div class="carousel-caption"/>'
  548. + '</div>'
  549. + '<div class="item" id="two">'
  550. + '<div class="carousel-caption"/>'
  551. + '</div>'
  552. + '<div class="item" id="three">'
  553. + '<div class="carousel-caption"/>'
  554. + '</div>'
  555. + '</div>'
  556. + '<a class="left carousel-control" href="#carousel-example-generic" data-slide="prev"/>'
  557. + '<a class="right carousel-control" href="#carousel-example-generic" data-slide="next"/>'
  558. + '</div>'
  559. var $carousel = $(carouselHTML)
  560. var done = assert.async()
  561. $carousel
  562. .on('slid.bs.carousel', function () {
  563. assert.strictEqual($carousel.find('.item.active').attr('id'), 'three', 'carousel wrapped around and slid from 1st to 3rd slide')
  564. done()
  565. })
  566. .bootstrapCarousel('prev')
  567. })
  568. QUnit.test('should stay at the end when the next method is called and wrap is false', function (assert) {
  569. assert.expect(3)
  570. var carouselHTML = '<div id="carousel-example-generic" class="carousel slide" data-wrap="false">'
  571. + '<ol class="carousel-indicators">'
  572. + '<li data-target="#carousel-example-generic" data-slide-to="0" class="active"/>'
  573. + '<li data-target="#carousel-example-generic" data-slide-to="1"/>'
  574. + '<li data-target="#carousel-example-generic" data-slide-to="2"/>'
  575. + '</ol>'
  576. + '<div class="carousel-inner">'
  577. + '<div class="item active" id="one">'
  578. + '<div class="carousel-caption"/>'
  579. + '</div>'
  580. + '<div class="item" id="two">'
  581. + '<div class="carousel-caption"/>'
  582. + '</div>'
  583. + '<div class="item" id="three">'
  584. + '<div class="carousel-caption"/>'
  585. + '</div>'
  586. + '</div>'
  587. + '<a class="left carousel-control" href="#carousel-example-generic" data-slide="prev"/>'
  588. + '<a class="right carousel-control" href="#carousel-example-generic" data-slide="next"/>'
  589. + '</div>'
  590. var $carousel = $(carouselHTML)
  591. var getActiveId = function () { return $carousel.find('.item.active').attr('id') }
  592. var done = assert.async()
  593. $carousel
  594. .one('slid.bs.carousel', function () {
  595. assert.strictEqual(getActiveId(), 'two', 'carousel slid from 1st to 2nd slide')
  596. $carousel
  597. .one('slid.bs.carousel', function () {
  598. assert.strictEqual(getActiveId(), 'three', 'carousel slid from 2nd to 3rd slide')
  599. $carousel
  600. .one('slid.bs.carousel', function () {
  601. assert.ok(false, 'carousel slid when it should not have slid')
  602. })
  603. .bootstrapCarousel('next')
  604. assert.strictEqual(getActiveId(), 'three', 'carousel did not wrap around and stayed on 3rd slide')
  605. done()
  606. })
  607. .bootstrapCarousel('next')
  608. })
  609. .bootstrapCarousel('next')
  610. })
  611. QUnit.test('should stay at the start when the prev method is called and wrap is false', function (assert) {
  612. assert.expect(1)
  613. var carouselHTML = '<div id="carousel-example-generic" class="carousel slide" data-wrap="false">'
  614. + '<ol class="carousel-indicators">'
  615. + '<li data-target="#carousel-example-generic" data-slide-to="0" class="active"/>'
  616. + '<li data-target="#carousel-example-generic" data-slide-to="1"/>'
  617. + '<li data-target="#carousel-example-generic" data-slide-to="2"/>'
  618. + '</ol>'
  619. + '<div class="carousel-inner">'
  620. + '<div class="item active" id="one">'
  621. + '<div class="carousel-caption"/>'
  622. + '</div>'
  623. + '<div class="item" id="two">'
  624. + '<div class="carousel-caption"/>'
  625. + '</div>'
  626. + '<div class="item" id="three">'
  627. + '<div class="carousel-caption"/>'
  628. + '</div>'
  629. + '</div>'
  630. + '<a class="left carousel-control" href="#carousel-example-generic" data-slide="prev"/>'
  631. + '<a class="right carousel-control" href="#carousel-example-generic" data-slide="next"/>'
  632. + '</div>'
  633. var $carousel = $(carouselHTML)
  634. $carousel
  635. .on('slid.bs.carousel', function () {
  636. assert.ok(false, 'carousel slid when it should not have slid')
  637. })
  638. .bootstrapCarousel('prev')
  639. assert.strictEqual($carousel.find('.item.active').attr('id'), 'one', 'carousel did not wrap around and stayed on 1st slide')
  640. })
  641. })