carousel-js
Advanced tools
Comparing version 2.1.6 to 3.0.0
@@ -7,3 +7,3 @@ { | ||
], | ||
"description": "A carousel class", | ||
"description": "Easily implement a dynamic carousel using minimal javascript. Supports Meteor, AngularJS, React, Polymer and any CSS library, e.g. Bootstrap. ", | ||
"moduleType": [ | ||
@@ -16,6 +16,9 @@ "amd", | ||
"carousel", | ||
"carousel arrows", | ||
"carousel panels", | ||
"carousels", | ||
"carousel thumbnails" | ||
"vanilla carousel", | ||
"es6 carousel", | ||
"carousel component", | ||
"carousel module", | ||
"react carousel", | ||
"angular carousel" | ||
], | ||
@@ -22,0 +25,0 @@ "license": "MIT", |
{ | ||
"name": "carousel-js", | ||
"version": "2.1.6", | ||
"description": "A carousel class", | ||
"version": "3.0.0", | ||
"description": "Easily implement a dynamic carousel using minimal javascript. Supports Meteor, AngularJS, React, Polymer and any CSS library, e.g. Bootstrap. ", | ||
"repository": { | ||
@@ -19,6 +19,9 @@ "type": "git", | ||
"carousel", | ||
"carousel arrows", | ||
"carousel panels", | ||
"carousels", | ||
"carousel thumbnails" | ||
"vanilla carousel", | ||
"es6 carousel", | ||
"carousel component", | ||
"carousel module", | ||
"react carousel", | ||
"angular carousel" | ||
], | ||
@@ -28,7 +31,7 @@ "main": "src/carousel.js", | ||
"lodash": "^4.6.1", | ||
"module-js": "^3.0.1", | ||
"module-js": "^5.4.1", | ||
"promise": "^7.1.1" | ||
}, | ||
"devDependencies": { | ||
"build-tools": "^3.0.2", | ||
"build-tools": "^3.1.0", | ||
"sinon": "^1.17.3" | ||
@@ -35,0 +38,0 @@ }, |
[![Build Status](https://travis-ci.org/mkay581/carousel-js.svg?branch=master)](https://travis-ci.org/mkay581/carousel-js) | ||
[![npm version](https://badge.fury.io/js/carousel-js.svg)](https://badge.fury.io/js/carousel-js) | ||
[![Bower version](https://badge.fury.io/bo/carousel-js.svg)](https://badge.fury.io/bo/carousel-js) | ||
@@ -6,3 +8,4 @@ # Carousel | ||
A lightweight and flexible Carousel class that allows you to build fully functional, advanced Carousels with minimal javascript and markup. | ||
This library is built using native vanilla javascript. Which means super fast performance. Supports IE10+, all major browsers and even mobile. | ||
This library is built using native vanilla javascript (for performance) and adheres to latest ECMAScript specs. | ||
Supports IE10+, all major browsers and even mobile. | ||
@@ -9,0 +12,0 @@ ## Inspiration |
'use strict'; | ||
import _ from 'lodash'; | ||
import Module from 'module-js'; | ||
@@ -19,3 +18,3 @@ /** | ||
*/ | ||
class CarouselArrows extends Module { | ||
class CarouselArrows { | ||
@@ -48,3 +47,2 @@ /** | ||
super(options); | ||
this.options = options; | ||
@@ -181,3 +179,2 @@ | ||
} | ||
super.destroy(); | ||
} | ||
@@ -184,0 +181,0 @@ } |
'use strict'; | ||
import _ from 'lodash'; | ||
import Module from 'module-js'; | ||
import Promise from 'promise'; | ||
import CarouselPanel from './carousel-panel'; | ||
@@ -18,3 +18,3 @@ /** | ||
*/ | ||
class CarouselPanels extends Module { | ||
class CarouselPanels { | ||
@@ -24,8 +24,9 @@ /** | ||
* @param {object} options - Options passed into instance | ||
* @param {HTMLCollection} options.panels - The panels in which to use for the carousel (an array of photos) | ||
* @param {string} [options.assetLoadingClass] - The CSS class that gets added to an asset when it is loading | ||
* @param {boolean} [options.autoLoadAssets] - Whether or not to automatically load assets when active | ||
* @param {HTMLCollection|NodeList} options.panels - The panels in which to use for the carousel (an array of photos) | ||
* @param {string} [options.assetLoadedClass] - The CSS class that gets added to a panel el when it is loaded | ||
* @param {string} [options.panelActiveClass] - The CSS class that gets added to an panel when it becomes active | ||
* @param {string} [options.panelBackClass] - The CSS class that gets added to all panel elements that appear before the current panel | ||
* @param {string} [options.panelForwardClass] - The CSS class that gets added to all panel elements that appear ahead of the current panel | ||
* @param {CarouselPanels~onChange} [options.onChange] - When the current panel is changed | ||
* @param {string} [options.lazyLoadAttr] - The attribute containing the url path to content that is to be lazy loaded | ||
* @param {string} [options.lazyLoadAttr] - The lazy loading attribute | ||
*/ | ||
@@ -36,15 +37,22 @@ constructor (options) { | ||
panels: [], | ||
assetLoadingClass: 'carousel-asset-loading', | ||
autoLoadAssets: true, | ||
assetLoadedClass: 'carousel-asset-loaded', | ||
panelActiveClass: 'carousel-panel-active', | ||
panelLoadedClass: 'carousel-panel-loaded', | ||
onChange: null, | ||
lazyLoadAttr: 'data-src' | ||
lazyLoadAttr: 'data-src', | ||
panelBackClass: 'carousel-panel-behind', | ||
panelForwardClass: 'carousel-panel-ahead' | ||
}, options); | ||
super(options); | ||
if (!options.panels.length) { | ||
console.error('carousel error: no panels were passed in constructor'); | ||
} else { | ||
this._panelModules = this._setupPanelModules(options); | ||
} | ||
// add forward classes initially | ||
this._panelModules.forEach((panel) => { | ||
panel.el.classList.add(options.panelForwardClass); | ||
}); | ||
this.options = options; | ||
@@ -54,5 +62,26 @@ } | ||
/** | ||
* Sets up the panel module instances. | ||
* @param {Object} options - The initialization options | ||
* @returns {Array} Returns an array of the panel instances | ||
* @private | ||
*/ | ||
_setupPanelModules (options) { | ||
let modules = []; | ||
// panels can be either an array or an HTMLCollection so we | ||
// are doing an old-school for loop to satisify both scenarios | ||
for (let i = 0; i < options.panels.length; i++) { | ||
modules[i] = new CarouselPanel(options.panels[i], { | ||
activeClass: options.panelActiveClass, | ||
lazyLoadAttr: options.lazyLoadAttr, | ||
assetLoadedClass: options.assetLoadedClass, | ||
loadedClass: options.panelLoadedClass | ||
}); | ||
} | ||
return modules; | ||
} | ||
/** | ||
* Transitions to a panel of an index. | ||
* @param {Number} index - The index number to go to | ||
* @memberOf CarouselPanels | ||
* @returns {Promise} | ||
@@ -65,3 +94,3 @@ */ | ||
errorMsg, | ||
promise = Promise.resolve(); | ||
promise; | ||
@@ -76,6 +105,4 @@ if (typeof index !== 'number' || index > maxIndex || index < minIndex) { | ||
} else { | ||
promise = this.load(index); | ||
this._updatePanels(index); | ||
if (this.options.autoLoadAssets) { | ||
promise = this.loadPanelAssets(index); | ||
} | ||
this._currentIndex = index; | ||
@@ -91,13 +118,34 @@ if (this.options.onChange) { | ||
* Makes all panels inactive except for the one at the index provided. | ||
* @param {Number} index - The new index | ||
* @memberOf CarouselPanels | ||
* @param {Number} toIndex - The new index | ||
* @private | ||
*/ | ||
_updatePanels (index) { | ||
var panels = this.options.panels, | ||
prevIndex = this.getCurrentIndex(); | ||
if (prevIndex !== undefined) { | ||
panels[prevIndex].classList.remove(this.options.panelActiveClass); | ||
_updatePanels (toIndex) { | ||
let fromIndex = this.getCurrentIndex(); | ||
let fromPanel = this._panelModules[fromIndex]; | ||
let toPanel = this._panelModules[toIndex]; | ||
let rangePanels = []; | ||
let toAdd = ''; | ||
let toRemove = ''; | ||
if (fromIndex > toIndex) { | ||
// include fromIndex but not toIndex | ||
rangePanels = this._panelModules.slice(toIndex + 1, fromIndex + 1); | ||
toAdd = this.options.panelForwardClass; | ||
toRemove = this.options.panelBackClass; | ||
} else if (fromIndex < toIndex) { | ||
rangePanels = this._panelModules.slice(fromIndex, toIndex); | ||
toAdd = this.options.panelBackClass; | ||
toRemove = this.options.panelForwardClass; | ||
} | ||
panels[index].classList.add(this.options.panelActiveClass); | ||
rangePanels.forEach((p) => { | ||
p.el.classList.add(toAdd); | ||
p.el.classList.remove(toRemove); | ||
}); | ||
if (fromPanel) { | ||
fromPanel.hide(); | ||
} | ||
toPanel.el.classList.remove(this.options.panelForwardClass, this.options.panelBackClass); | ||
toPanel.show(); | ||
} | ||
@@ -108,3 +156,2 @@ | ||
* @returns {Number} Returns the index | ||
* @memberOf CarouselPanels | ||
*/ | ||
@@ -117,56 +164,21 @@ getCurrentIndex () { | ||
* Loads assets for a given panel. | ||
* @param {Number} index - The index of the panel containing the assets to load | ||
* @memberOf CarouselPanels | ||
* @param {Number} idx - The index of the panel containing the assets to load | ||
* @returns {Promise} | ||
*/ | ||
loadPanelAssets (index) { | ||
var options = this.options, | ||
panel = options.panels[index], | ||
assets = panel.querySelectorAll('[' + options.lazyLoadAttr + ']'), | ||
loadPromises = []; | ||
// convert NodeList to real array in order to call Array methods on it | ||
assets = Array.prototype.slice.call(assets); | ||
// if panel has lazy load attribute, add to loadable assets | ||
if (panel.getAttribute(options.lazyLoadAttr)) { | ||
assets.push(panel); | ||
load (idx) { | ||
let panelModule = this._panelModules[idx]; | ||
if (panelModule.loaded) { | ||
return Promise.resolve(); | ||
} | ||
assets.forEach(function (el) { | ||
if (el.tagName.toLowerCase() === 'img') { | ||
loadPromises.push(this.loadPanelImageAsset(el)); | ||
} | ||
}, this); | ||
return Promise.all(loadPromises); | ||
return panelModule.load(); | ||
} | ||
/** | ||
* Manually lazy loads a resource using an element's data attribute. | ||
* @param {HTMLImageElement} img - The image element to load | ||
* @memberOf CarouselPanels | ||
* Loads assets for a given panel. | ||
* @deprecated since 2.1.6 | ||
* @param {Number} index - The index of the panel containing the assets to load | ||
* @returns {Promise} | ||
*/ | ||
loadPanelImageAsset (img) { | ||
var src = img.getAttribute(this.options.lazyLoadAttr), | ||
loadingClass = this.options.assetLoadingClass; | ||
img.classList.add(loadingClass); | ||
return new Promise(function (resolve) { | ||
img.onload = function () { | ||
resolve(img); | ||
}; | ||
img.onerror = function () { | ||
// IE 9-11 have an issue where it automatically triggers an error on some images, | ||
// and then will immediately trigger onload() causing intermittent errors to appear | ||
// until this is fixed or we have a workaround, we will be resolving | ||
// even if there is an error | ||
resolve(img); | ||
}; | ||
img.src = src; | ||
}).then(function() { | ||
img.classList.remove(loadingClass); | ||
}) | ||
.catch(function () { | ||
img.classList.remove(loadingClass); | ||
}); | ||
loadPanelAssets (index) { | ||
return this.load(index); | ||
} | ||
@@ -176,3 +188,2 @@ | ||
* Final cleanup of instance. | ||
* @memberOf CarouselPanels | ||
*/ | ||
@@ -186,4 +197,8 @@ destroy () { | ||
} | ||
this._currentIndex = null; | ||
super.destroy(); | ||
this._currentIndex = undefined; | ||
this._panelModules.forEach((module) => { | ||
module.el.classList.remove(options.panelForwardClass, options.panelBackClass); | ||
module.destroy(); | ||
}); | ||
} | ||
@@ -190,0 +205,0 @@ } |
'use strict'; | ||
import Module from 'module-js'; | ||
import _ from 'lodash'; | ||
@@ -17,3 +16,3 @@ | ||
*/ | ||
class CarouselThumbs extends Module { | ||
class CarouselThumbs { | ||
@@ -36,3 +35,2 @@ /** | ||
super(options); | ||
this.options = options; | ||
@@ -148,3 +146,2 @@ this._thumbnailEventListener = this.onThumbnailEvent.bind(this); | ||
} | ||
super.destroy(); | ||
} | ||
@@ -151,0 +148,0 @@ } |
@@ -6,3 +6,2 @@ 'use strict'; | ||
import _ from 'lodash'; | ||
import Module from 'module-js'; | ||
/** | ||
@@ -22,2 +21,5 @@ * A callback function that fires after a new active panel is set | ||
* @param {string} [options.panelActiveClass] - The CSS class that gets added to an panel when it becomes active | ||
* @param {string} [options.panelLoadedClass] - The CSS class that gets added to an panel when it is fully loaded | ||
* @param {string} [options.panelBackClass] - The CSS class that gets added to all panel elements that appear before the current panel | ||
* @param {string} [options.panelForwardClass] - The CSS class that gets added to all panel elements that appear ahead of the current panel | ||
* @param {Carousel~onPanelChange} [options.onPanelChange] - When the current panel is changed | ||
@@ -30,3 +32,3 @@ * @param {string} [options.lazyLoadAttr] - The attribute containing the url path to content that is to be lazy loaded | ||
class Carousel extends Module { | ||
class Carousel { | ||
@@ -55,2 +57,5 @@ /** | ||
panelActiveClass: 'carousel-panel-active', | ||
panelLoadedClass: 'carousel-panel-loaded', | ||
panelBackClass: 'carousel-panel-behind', | ||
panelForwardClass: 'carousel-panel-ahead', | ||
onPanelChange: null, | ||
@@ -70,5 +75,4 @@ lazyLoadAttr: 'data-src', | ||
super(options); | ||
this.options = options; | ||
this.subModules = {}; | ||
this._checkForInitErrors(); | ||
@@ -80,18 +84,15 @@ this.setup(); | ||
* Sets up the carousel instance and all controls. | ||
* @memberOf Carousel | ||
*/ | ||
setup () { | ||
this.subModules = this.subModules || {}; | ||
if (!this.subModules.panels) { | ||
this.subModules.panels = this.setupPanels(this.options); | ||
this.subModules.panels = this._setupPanels(this.options); | ||
} | ||
if (this.options.thumbnails.length && !this.subModules.thumbnails) { | ||
this.subModules.thumbnails = this.setupThumbs(this.options); | ||
this.subModules.thumbnails = this._setupThumbs(this.options); | ||
} | ||
if ((this.options.leftArrow || this.options.rightArrow) && !this.subModules.arrows) { | ||
this.subModules.arrows = this.setupArrows(this.options); | ||
this.subModules.arrows = this._setupArrows(this.options); | ||
} | ||
@@ -108,4 +109,5 @@ | ||
* @return {CarouselThumbs} Returns thumbnail instance | ||
* @private | ||
*/ | ||
setupThumbs (options) { | ||
_setupThumbs (options) { | ||
return new CarouselThumbs(_.extend({}, options, { | ||
@@ -120,4 +122,5 @@ onChange: this.onThumbnailChange.bind(this) | ||
* @return {CarouselPanels} Returns panels instance | ||
* @private | ||
*/ | ||
setupPanels (options) { | ||
_setupPanels (options) { | ||
if (options.panels.length) { | ||
@@ -134,4 +137,5 @@ return new CarouselPanels(_.extend({}, options, { | ||
* @return {CarouselArrows} Returns arrows instance | ||
* @private | ||
*/ | ||
setupArrows (options) { | ||
_setupArrows (options) { | ||
var internalOptions; | ||
@@ -149,3 +153,2 @@ // make clone of original options | ||
* @private | ||
* @memberOf Carousel | ||
*/ | ||
@@ -166,3 +169,2 @@ _checkForInitErrors () { | ||
* @param {Number} index - The new index | ||
* @memberOf Carousel | ||
*/ | ||
@@ -186,3 +188,2 @@ onPanelChange (index) { | ||
* @param {Number} index - The new index | ||
* @memberOf Carousel | ||
*/ | ||
@@ -218,3 +219,2 @@ onThumbnailChange (index) { | ||
* @param {Number} index - The index number to go to | ||
* @memberOf Carousel | ||
*/ | ||
@@ -249,3 +249,2 @@ goTo (index) { | ||
* @returns {Number} Returns the index | ||
* @memberOf Carousel | ||
*/ | ||
@@ -269,4 +268,15 @@ getCurrentIndex () { | ||
} | ||
/** | ||
* Destroys all sub modules. | ||
*/ | ||
destroy () { | ||
for (let key in this.subModules) { | ||
if (this.subModules.hasOwnProperty(key) && this.subModules[key]) { | ||
this.subModules[key].destroy(); | ||
} | ||
} | ||
} | ||
} | ||
module.exports = Carousel; |
@@ -0,3 +1,3 @@ | ||
'use strict'; | ||
var sinon = require('sinon'); | ||
var TestUtils = require('test-utils'); | ||
var CarouselArrows = require('../src/carousel-arrows'); | ||
@@ -108,3 +108,3 @@ var assert = require('assert'); | ||
assert.equal(rightArrowClickSpy.callCount, 0); | ||
rightArrow.dispatchEvent(TestUtils.createEvent('click')); | ||
rightArrow.click(); | ||
assert.equal(rightArrowClickSpy.callCount, 1); | ||
@@ -123,6 +123,6 @@ arrowsView.destroy(); | ||
arrowsView.destroy(); | ||
rightArrow.dispatchEvent(TestUtils.createEvent('click')); | ||
rightArrow.click(); | ||
assert.equal(rightArrowClickSpy.callCount, 0); | ||
}); | ||
it('should NOT call onRightArrowClick callback when a disabled right arrow is clicked', function () { | ||
@@ -137,7 +137,7 @@ var fixture = document.getElementById('qunit-fixture'); | ||
arrowsView.disableRightArrow(); | ||
rightArrow.dispatchEvent(TestUtils.createEvent('click')); | ||
rightArrow.click(); | ||
assert.equal(rightArrowClickSpy.callCount, 0); | ||
arrowsView.destroy(); | ||
}); | ||
it('should call onLeftArrowClick callback when left arrow is clicked', function () { | ||
@@ -152,7 +152,7 @@ var fixture = document.getElementById('qunit-fixture'); | ||
assert.equal(leftArrowClickSpy.callCount, 0); | ||
leftArrow.dispatchEvent(TestUtils.createEvent('click')); | ||
leftArrow.click(); | ||
assert.equal(leftArrowClickSpy.callCount, 1); | ||
arrowsView.destroy(); | ||
}); | ||
it('should NOT trigger onLeftArrowClick callback when left arrow is clicked after destruction', function () { | ||
@@ -167,6 +167,6 @@ var fixture = document.getElementById('qunit-fixture'); | ||
arrowsView.destroy(); | ||
leftArrow.dispatchEvent(TestUtils.createEvent('click')); | ||
leftArrow.click(); | ||
assert.equal(leftArrowClickSpy.callCount, 0); | ||
}); | ||
it('should add disabled css class on left arrow when update() is called on first panel index', function () { | ||
@@ -192,3 +192,3 @@ var fixture = document.getElementById('qunit-fixture'); | ||
}); | ||
it('should add disabled css class on right arrow when update() is called on last panel index', function () { | ||
@@ -214,3 +214,3 @@ var fixture = document.getElementById('qunit-fixture'); | ||
}); | ||
it('should NOT add disabled css class to left arrow when update() is called on last panel index when there are more panels', function () { | ||
@@ -236,3 +236,3 @@ var fixture = document.getElementById('qunit-fixture'); | ||
}); | ||
it('should NOT add disabled css class to right arrow when update() is called on first panel index when there are more panels', function () { | ||
@@ -258,3 +258,3 @@ var fixture = document.getElementById('qunit-fixture'); | ||
}); | ||
it('should add disabled css class to both left and right arrows when update() is called on the only panel that exists', function () { | ||
@@ -280,3 +280,3 @@ var fixture = document.getElementById('qunit-fixture'); | ||
}); | ||
it('should remove disabled css class from left arrow after updating to second panel', function () { | ||
@@ -306,3 +306,3 @@ var fixture = document.getElementById('qunit-fixture'); | ||
}); | ||
it('should remove disabled css class from right arrow after updating to second panel after last panel', function () { | ||
@@ -309,0 +309,0 @@ var fixture = document.getElementById('qunit-fixture'); |
@@ -0,46 +1,21 @@ | ||
"use strict"; | ||
var CarouselPanels = require('./../src/carousel-panels'); | ||
var CarouselPanel = require('./../src/carousel-panel'); | ||
var sinon = require('sinon'); | ||
var CarouselPanels = require('../src/carousel-panels'); | ||
var assert = require('assert'); | ||
var _ = require('lodash'); | ||
var Promise = require('promise'); | ||
describe('Carousel Panels', function () { | ||
it('loadPanelImageAsset() passes lazy loading attribute of the the image element passed to element kit\'s load() call', function () { | ||
var image = document.createElement('img'); | ||
var testSrc = 'blank.jpg'; | ||
image.setAttribute('data-test-src', testSrc); | ||
var panelsView = new CarouselPanels({panels: [image], lazyLoadAttr: 'data-test-src'}); | ||
panelsView.loadPanelImageAsset(image); | ||
image.onload(); // trigger onload immediately | ||
assert.ok(image.src, testSrc, 'correct src is set'); | ||
panelsView.destroy(); | ||
}); | ||
var createPanelInstance = function (el) { | ||
var panel = sinon.createStubInstance(CarouselPanel); | ||
panel.load = sinon.stub().returns(Promise.resolve()); | ||
panel.show = sinon.stub().returns(Promise.resolve()); | ||
panel.hide = sinon.stub().returns(Promise.resolve()); | ||
panel.el = el; | ||
return panel; | ||
}; | ||
it('loadPanelImageAsset() should add loading class to image element initially', function () { | ||
var image = document.createElement('img'); | ||
var imageLoadingClass = 'loading'; | ||
var panelsView = new CarouselPanels({panels: [image], assetLoadingClass: imageLoadingClass}); | ||
panelsView.loadPanelImageAsset(image); | ||
assert.ok(image.classList.contains(imageLoadingClass), 'loading class is added initially'); | ||
panelsView.destroy(); | ||
}); | ||
it('loadPanelImageAsset() should remove loading class when image is done loading', function (done) { | ||
var image = document.createElement('img'); | ||
var imageLoadingClass = 'loading'; | ||
var panelsView = new CarouselPanels({panels: [image], assetLoadingClass: imageLoadingClass}); | ||
panelsView.loadPanelImageAsset(image).then(function () { | ||
assert.ok(!image.classList.contains(imageLoadingClass), 'once image is loaded, the loading class is removed'); | ||
panelsView.destroy(); | ||
done(); | ||
}); | ||
// delay following code until the loadPanelImageAssets() | ||
// call stack has completed since it is wrapped in a Promise | ||
_.defer(function () { | ||
image.onload(); | ||
}); | ||
}); | ||
it('going to a panel that is an image should call loadPanelImageAsset() with that image element', function () { | ||
var fixture = document.getElementById('qunit-fixture'); | ||
it('should pass the same index passed to goTo to the load call', function () { | ||
var carouselEl = document.createElement('div'); | ||
@@ -55,13 +30,12 @@ var baseUrl = 'http://test/'; | ||
var images = carouselEl.getElementsByTagName('img'); | ||
var loadPanelImageAssetStub = sinon.stub(CarouselPanels.prototype, 'loadPanelImageAsset'); | ||
var panelsView = new CarouselPanels({panels: carouselEl.getElementsByTagName('img')}); | ||
panelsView.goTo(2); | ||
assert.equal(loadPanelImageAssetStub.args[0][0], images[2], 'third image element was passed to loadPanelImageAsset() method'); | ||
loadPanelImageAssetStub.restore(); | ||
var loadSpy = sinon.stub(panelsView, 'load').returns(Promise.resolve()); | ||
var testIndex = 2; | ||
panelsView.goTo(testIndex); | ||
assert.equal(loadSpy.args[0][0], testIndex); | ||
panelsView.destroy(); | ||
loadSpy.restore(); | ||
}); | ||
it('should pass all image elements inside a panel to loadPanelImageAsset() when transitioning to the panel', function () { | ||
var fixture = document.getElementById('qunit-fixture'); | ||
it('should call Carousel Panel\'s load method appropriately', function () { | ||
var carouselEl = document.createElement('div'); | ||
@@ -79,14 +53,212 @@ var baseUrl = 'http://test2/'; | ||
'</div>'; | ||
var loadPanelImageAssetStub = sinon.stub(CarouselPanels.prototype, 'loadPanelImageAsset'); | ||
var loadStub = sinon.stub(CarouselPanel.prototype, 'load').returns(Promise.resolve()); | ||
var panelsView = new CarouselPanels({ | ||
panels: carouselEl.getElementsByClassName('carousel-panel') | ||
}); | ||
var images = carouselEl.getElementsByTagName('img'); | ||
panelsView.goTo(0); | ||
assert.equal(loadPanelImageAssetStub.args[0][0], images[0], 'first panel\'s first image element was passed to loadPanelImageAsset()'); | ||
assert.equal(loadPanelImageAssetStub.args[1][0], images[1], 'first panel\'s second image element was passed to loadPanelImageAsset()'); | ||
assert.equal(loadStub.callCount, 1); | ||
panelsView.goTo(1); | ||
assert.equal(loadStub.callCount, 2); | ||
panelsView.destroy(); | ||
loadPanelImageAssetStub.restore(); | ||
loadStub.restore(); | ||
}); | ||
it('should call the show method of the Carousel Panel instance that matches the index passed to the goTo()', function () { | ||
var carouselEl = document.createElement('div'); | ||
carouselEl.innerHTML = | ||
'<div class="carousel-panel"></div>' + | ||
'<div class="carousel-panel"></div>' + | ||
'<div class="carousel-panel"></div>'; | ||
var panelEls = carouselEl.getElementsByClassName('carousel-panel'); | ||
var firstPanelInstance = createPanelInstance(panelEls[0]); | ||
var secondPanelInstance = createPanelInstance(panelEls[1]); | ||
var thirdPanelInstance = createPanelInstance(panelEls[2]); | ||
var setupPanelModulesStub = sinon.stub(CarouselPanels.prototype, '_setupPanelModules').returns([ | ||
firstPanelInstance, secondPanelInstance, thirdPanelInstance | ||
]); | ||
var panelsView = new CarouselPanels({ | ||
panels: panelEls | ||
}); | ||
return panelsView.goTo(0).then(function () { | ||
assert.equal(firstPanelInstance.show.callCount, 1); | ||
assert.equal(secondPanelInstance.show.callCount, 0); | ||
return panelsView.goTo(2).then(function () { | ||
assert.equal(thirdPanelInstance.show.callCount, 1); | ||
assert.equal(firstPanelInstance.show.callCount, 1); | ||
panelsView.destroy(); | ||
setupPanelModulesStub.restore(); | ||
}); | ||
}); | ||
}); | ||
it('should call the load method of the Carousel Panel instance before calling show method when goTo() is called', function () { | ||
var carouselEl = document.createElement('div'); | ||
carouselEl.innerHTML = | ||
'<div class="carousel-panel"></div>'; | ||
var loadStub = sinon.stub(CarouselPanel.prototype, 'load').returns(Promise.resolve()); | ||
var showStub = sinon.stub(CarouselPanel.prototype, 'show').returns(Promise.resolve()); | ||
var panelsView = new CarouselPanels({ | ||
panels: carouselEl.getElementsByClassName('carousel-panel') | ||
}); | ||
panelsView.goTo(0); | ||
assert.equal(loadStub.calledBefore(showStub), true); | ||
panelsView.destroy(); | ||
showStub.restore(); | ||
loadStub.restore(); | ||
}); | ||
it('should call the hide method of previous Carousel Panel instance when calling goTo() on a new index', function () { | ||
var carouselEl = document.createElement('div'); | ||
carouselEl.innerHTML = | ||
'<div class="carousel-panel"></div>' + | ||
'<div class="carousel-panel"></div>' + | ||
'<div class="carousel-panel"></div>'; | ||
var panelEls = carouselEl.getElementsByClassName('carousel-panel'); | ||
var firstPanelInstance = createPanelInstance(panelEls[0]); | ||
var secondPanelInstance = createPanelInstance(panelEls[1]); | ||
var thirdPanelInstance = createPanelInstance(panelEls[2]); | ||
var setupPanelModulesStub = sinon.stub(CarouselPanels.prototype, '_setupPanelModules').returns([ | ||
firstPanelInstance, secondPanelInstance, thirdPanelInstance | ||
]); | ||
var panelsView = new CarouselPanels({ | ||
panels: panelEls | ||
}); | ||
assert.equal(firstPanelInstance.hide.callCount, 0); | ||
assert.equal(secondPanelInstance.hide.callCount, 0); | ||
assert.equal(thirdPanelInstance.hide.callCount, 0); | ||
return panelsView.goTo(0).then(function () { | ||
assert.equal(firstPanelInstance.hide.callCount, 0); | ||
assert.equal(secondPanelInstance.hide.callCount, 0); | ||
assert.equal(thirdPanelInstance.hide.callCount, 0); | ||
return panelsView.goTo(2).then(function () { | ||
assert.equal(firstPanelInstance.hide.callCount, 1); | ||
assert.equal(secondPanelInstance.hide.callCount, 0); | ||
assert.equal(thirdPanelInstance.hide.callCount, 0); | ||
return panelsView.goTo(1).then(function () { | ||
assert.equal(firstPanelInstance.hide.callCount, 1); | ||
assert.equal(secondPanelInstance.hide.callCount, 0); | ||
assert.equal(thirdPanelInstance.hide.callCount, 1); | ||
panelsView.destroy(); | ||
setupPanelModulesStub.restore(); | ||
}) | ||
}); | ||
}); | ||
}); | ||
it('should add a forward css class to panel element when advancing to previous one', function () { | ||
var carouselEl = document.createElement('div'); | ||
carouselEl.innerHTML = | ||
'<div class="carousel-panel"></div>' + | ||
'<div class="carousel-panel"></div>' + | ||
'<div class="carousel-panel"></div>'; | ||
var panelEls = carouselEl.getElementsByClassName('carousel-panel'); | ||
var firstPanelInstance = createPanelInstance(panelEls[0]); | ||
var secondPanelInstance = createPanelInstance(panelEls[1]); | ||
var thirdPanelInstance = createPanelInstance(panelEls[2]); | ||
var setupPanelModulesStub = sinon.stub(CarouselPanels.prototype, '_setupPanelModules').returns([ | ||
firstPanelInstance, secondPanelInstance, thirdPanelInstance | ||
]); | ||
var forwardClass = 'panel-ahead'; | ||
var panelsView = new CarouselPanels({ | ||
panels: panelEls, | ||
panelForwardClass: forwardClass | ||
}); | ||
assert.ok(firstPanelInstance.el.classList.contains(forwardClass)); | ||
assert.ok(secondPanelInstance.el.classList.contains(forwardClass)); | ||
assert.ok(thirdPanelInstance.el.classList.contains(forwardClass)); | ||
return panelsView.goTo(0).then(function () { | ||
assert.ok(!firstPanelInstance.el.classList.contains(forwardClass)); | ||
assert.ok(secondPanelInstance.el.classList.contains(forwardClass)); | ||
assert.ok(thirdPanelInstance.el.classList.contains(forwardClass)); | ||
return panelsView.goTo(2).then(function () { | ||
assert.ok(!firstPanelInstance.el.classList.contains(forwardClass)); | ||
assert.ok(!secondPanelInstance.el.classList.contains(forwardClass)); | ||
assert.ok(!thirdPanelInstance.el.classList.contains(forwardClass)); | ||
return panelsView.goTo(1).then(function () { | ||
assert.ok(!firstPanelInstance.el.classList.contains(forwardClass)); | ||
assert.ok(!secondPanelInstance.el.classList.contains(forwardClass)); | ||
assert.ok(thirdPanelInstance.el.classList.contains(forwardClass)); | ||
return panelsView.goTo(0).then(function () { | ||
assert.ok(!firstPanelInstance.el.classList.contains(forwardClass)); | ||
assert.ok(secondPanelInstance.el.classList.contains(forwardClass)); | ||
assert.ok(thirdPanelInstance.el.classList.contains(forwardClass)); | ||
panelsView.destroy(); | ||
setupPanelModulesStub.restore(); | ||
}); | ||
}) | ||
}); | ||
}); | ||
}); | ||
it('should add a behind css class to panel element when advancing to previous one', function () { | ||
var carouselEl = document.createElement('div'); | ||
carouselEl.innerHTML = | ||
'<div class="carousel-panel"></div>' + | ||
'<div class="carousel-panel"></div>' + | ||
'<div class="carousel-panel"></div>'; | ||
var panelEls = carouselEl.getElementsByClassName('carousel-panel'); | ||
var firstPanelInstance = createPanelInstance(panelEls[0]); | ||
var secondPanelInstance = createPanelInstance(panelEls[1]); | ||
var thirdPanelInstance = createPanelInstance(panelEls[2]); | ||
var setupPanelModulesStub = sinon.stub(CarouselPanels.prototype, '_setupPanelModules').returns([ | ||
firstPanelInstance, secondPanelInstance, thirdPanelInstance | ||
]); | ||
var behindClass = 'panel-behind'; | ||
var panelsView = new CarouselPanels({ | ||
panels: panelEls, | ||
panelBackClass: behindClass | ||
}); | ||
assert.ok(!firstPanelInstance.el.classList.contains(behindClass)); | ||
assert.ok(!secondPanelInstance.el.classList.contains(behindClass)); | ||
assert.ok(!thirdPanelInstance.el.classList.contains(behindClass)); | ||
return panelsView.goTo(0).then(function () { | ||
assert.ok(!firstPanelInstance.el.classList.contains(behindClass)); | ||
assert.ok(!secondPanelInstance.el.classList.contains(behindClass)); | ||
assert.ok(!thirdPanelInstance.el.classList.contains(behindClass)); | ||
return panelsView.goTo(2).then(function () { | ||
assert.ok(firstPanelInstance.el.classList.contains(behindClass)); | ||
assert.ok(secondPanelInstance.el.classList.contains(behindClass)); | ||
assert.ok(!thirdPanelInstance.el.classList.contains(behindClass)); | ||
return panelsView.goTo(1).then(function () { | ||
assert.ok(firstPanelInstance.el.classList.contains(behindClass)); | ||
assert.ok(!secondPanelInstance.el.classList.contains(behindClass)); | ||
assert.ok(!thirdPanelInstance.el.classList.contains(behindClass)); | ||
return panelsView.goTo(0).then(function () { | ||
assert.ok(!firstPanelInstance.el.classList.contains(behindClass)); | ||
assert.ok(!secondPanelInstance.el.classList.contains(behindClass)); | ||
assert.ok(!thirdPanelInstance.el.classList.contains(behindClass)); | ||
panelsView.destroy(); | ||
setupPanelModulesStub.restore(); | ||
}); | ||
}) | ||
}); | ||
}); | ||
}); | ||
it('should NOT call show() method on panel instance again if currently showing', function () { | ||
var carouselEl = document.createElement('div'); | ||
var baseUrl = 'http://test/'; | ||
carouselEl.innerHTML = | ||
'<img class="carousel-item" src="blank.jpg" data-src="' + baseUrl + 'c1.jpg" />' + | ||
'<img class="carousel-item" src="blank.jpg" data-src="' + baseUrl + 'c2.jpg" />' + | ||
'<img class="carousel-item" src="blank.jpg" data-src="' + baseUrl + 'c3.jpg" />' + | ||
'<img class="carousel-item" src="blank.jpg" data-src="' + baseUrl + 'c4.jpg" />' + | ||
'<img class="carousel-item" src="blank.jpg" data-src="' + baseUrl + 'c5.jpg" />'; | ||
var showCallCount = 0; | ||
var showStub = sinon.stub(CarouselPanel.prototype, 'show').returns(Promise.resolve()); | ||
var panelsView = new CarouselPanels({panels: carouselEl.getElementsByTagName('img')}); | ||
var testIndex = 2; | ||
panelsView.goTo(testIndex); | ||
showCallCount++; | ||
panelsView.goTo(testIndex); | ||
assert.equal(showStub.callCount, showCallCount); | ||
panelsView.destroy(); | ||
showStub.restore(); | ||
}); | ||
}); |
@@ -0,15 +1,62 @@ | ||
'use strict'; | ||
var sinon = require('sinon'); | ||
var Carousel = require('../src/carousel'); | ||
var CarouselArrows = require('../src/carousel-arrows'); | ||
var CarouselThumbs = require('../src/carousel-thumbs'); | ||
var CarouselPanels = require('../src/carousel-panels'); | ||
var Carousel = require('../src/carousel'); | ||
var assert = require('assert'); | ||
var TestUtils = require('test-utils'); | ||
var CarouselPanels = require('../src/carousel'); | ||
describe('Carousel', function () { | ||
var fixture; | ||
it('should reflect correct index when transitioning through panels', function () { | ||
var fixture = document.getElementById('qunit-fixture'); | ||
it('should instantiate CarouselPanels with correct options when it is instantiated', function () { | ||
var carouselEl = document.createElement('div'); | ||
var panel = document.createElement('div'); | ||
carouselEl.appendChild(panel); | ||
var backClass = 'panel-transition-backwards-yo'; | ||
var forwardClass = 'panel-transition-forward-son'; | ||
var carousel = new Carousel({ | ||
panels: [panel], | ||
panelBackClass: backClass, | ||
panelForwardClass: forwardClass | ||
}); | ||
assert.equal(carousel.subModules.panels.options.panels[0], panel); | ||
assert.equal(carousel.subModules.panels.options.panels.length, 1); | ||
assert.equal(carousel.subModules.panels.options.panelBackClass, backClass); | ||
assert.equal(carousel.subModules.panels.options.panelForwardClass, forwardClass); | ||
carousel.destroy(); | ||
}); | ||
it('should call CarouselPanels destroy on destroy()', function () { | ||
var panelsDestroySpy = sinon.spy(CarouselPanels.prototype, 'destroy'); | ||
var carouselEl = document.createElement('div'); | ||
carouselEl.innerHTML = | ||
'<div class="carousel-panel"></div>' + | ||
'<div class="carousel-panel"></div>' + | ||
'<div class="carousel-panel"></div>'; | ||
var panels = carouselEl.getElementsByClassName('carousel-panel'); | ||
var carouselView = new Carousel({panels: panels}); | ||
assert.equal(panelsDestroySpy.callCount, 0); | ||
carouselView.destroy(); | ||
assert.equal(panelsDestroySpy.callCount, 1, 'CarouselPanels destroy was called'); | ||
panelsDestroySpy.restore(); | ||
}); | ||
it('should pass first parameter of goTo() to CarouselPanels.goTo()', function () { | ||
var carouselEl = document.createElement('div'); | ||
carouselEl.innerHTML = | ||
'<div class="carousel-panel"></div>' + | ||
'<div class="carousel-panel"></div>' + | ||
'<div class="carousel-panel"></div>'; | ||
var panels = carouselEl.getElementsByClassName('carousel-panel'); | ||
var carouselView = new Carousel({panels: panels}); | ||
var carouselGoToStub = sinon.stub(carouselView, 'goTo'); | ||
carouselView.goTo(2); // go to second index | ||
assert.deepEqual(carouselGoToStub.args[0], [2]); | ||
carouselGoToStub.restore(); | ||
carouselView.destroy(); | ||
}); | ||
it('should remove active class when calling goTo() with an index for any other panel but the current one', function () { | ||
var carouselEl = document.createElement('div'); | ||
var activeClass = 'carousel-panel-active'; | ||
@@ -22,22 +69,60 @@ carouselEl.innerHTML = | ||
var panels = carouselEl.getElementsByClassName('carousel-panel'); | ||
var carouselView = new Carousel({panels: panels}); | ||
carouselView.goTo(0); // go to first panel | ||
carouselView.goTo(2); // go to third panel | ||
assert.ok(!panels[0].classList.contains(activeClass)); | ||
carouselView.destroy(); | ||
}); | ||
it('should return CarouselPanel\'s getCurrentIndex() when getCurrentIndex() is called', function () { | ||
var carouselEl = document.createElement('div'); | ||
carouselEl.innerHTML = | ||
'<div class="carousel-panel"></div>' + | ||
'<div class="carousel-panel"></div>' + | ||
'<div class="carousel-panel"></div>'; | ||
var carouselPanelsGetCurrentIndexStub = sinon.stub(CarouselPanels.prototype, 'getCurrentIndex'); | ||
var panels = carouselEl.getElementsByClassName('carousel-panel'); | ||
var carouselView = new Carousel({panels: panels}); | ||
var panelReturnValue = 2500; | ||
carouselPanelsGetCurrentIndexStub.returns(panelReturnValue); | ||
assert.equal(carouselView.getCurrentIndex(), panelReturnValue); | ||
carouselView.destroy(); | ||
carouselPanelsGetCurrentIndexStub.restore(); | ||
}); | ||
it('should invoke the onPanelChange function with the index passed to goTo()', function () { | ||
var carouselEl = document.createElement('div'); | ||
carouselEl.innerHTML = | ||
'<div class="carousel-panel"></div>' + | ||
'<div class="carousel-panel"></div>' + | ||
'<div class="carousel-panel"></div>'; | ||
var panels = carouselEl.getElementsByClassName('carousel-panel'); | ||
var panelChangeSpy = sinon.spy(); | ||
var carouselView = new Carousel({ | ||
panels: panels, | ||
onPanelChange: panelChangeSpy | ||
}); | ||
assert.equal(carouselView.getCurrentIndex(), 0, 'getCurrentIndex() returns 0 on initialize'); | ||
assert.ok(panels[0].classList.contains(activeClass), 'active class has been applied to first panel'); | ||
assert.equal(panelChangeSpy.callCount, 1, 'onPanelChange callback was fired since init auto-navigates to first panel'); | ||
carouselView.goTo(2); // go to second index | ||
assert.equal(carouselView.getCurrentIndex(), 2, 'after transitioning to second panel, getCurrentIndex() returns 2'); | ||
assert.ok(panels[2].classList.contains(activeClass), 'active class has been applied to second panel'); | ||
assert.ok(!panels[0].classList.contains(activeClass), 'active class has been removed from first panel'); | ||
assert.deepEqual(panelChangeSpy.args[1], [2], 'onPanelChange callback was fired with the second index as its first argument'); | ||
var panelChangeCallCount = 0; | ||
var carouselView = new Carousel({panels: panels, onPanelChange: panelChangeSpy}); | ||
panelChangeCallCount++; | ||
// trigger false on change within CarouselPanels instance | ||
carouselView.subModules.panels.options.onChange(2); | ||
assert.deepEqual(panelChangeSpy.args[panelChangeCallCount], [2]); | ||
carouselView.destroy(); | ||
}); | ||
it('should not call goTo on initialize if initialIndex is set to false or null when instantiating', function () { | ||
var carouselEl = document.createElement('div'); | ||
var panelEl = document.createElement('div'); | ||
carouselEl.appendChild(panelEl); | ||
var panels = carouselEl.getElementsByClassName('carousel-panel'); | ||
var carouselGoToStub = sinon.stub(Carousel.prototype, 'goTo'); | ||
var carouselView = new Carousel({panels: [panelEl], initialIndex: false}); | ||
assert.equal(carouselGoToStub.callCount, 0); | ||
carouselView.destroy(); | ||
carouselView = new Carousel({panels: [panelEl], initialIndex: null}); | ||
assert.equal(carouselGoToStub.callCount, 0); | ||
carouselView.destroy(); | ||
carouselGoToStub.restore(); | ||
}); | ||
it('should call goTo() with the initialIndex option that is passed into constructor', function () { | ||
var fixture = document.getElementById('qunit-fixture'); | ||
var carouselEl = document.createElement('div'); | ||
var activeClass = 'carousel-panel-active'; | ||
carouselEl.innerHTML = | ||
@@ -60,4 +145,3 @@ '<div class="carousel-panel"></div>' + | ||
it('should not cause unexpected behavior when trying to transition to a panel that is already showing', function () { | ||
var fixture = document.getElementById('qunit-fixture'); | ||
it('should NOT invoke onPanelChange callback when calling goTo() if already on the panel index', function () { | ||
var carouselEl = document.createElement('div'); | ||
@@ -73,16 +157,8 @@ var activeClass = 'carousel-panel-active'; | ||
var panelChangeCallCount = 0; | ||
var carouselView = new Carousel({ | ||
panels: panels, | ||
onPanelChange: panelChangeSpy | ||
}); | ||
var carouselView = new Carousel({panels: panels, onPanelChange: panelChangeSpy}); | ||
panelChangeCallCount++; | ||
carouselView.goTo(2); | ||
panelChangeCallCount++; | ||
assert.deepEqual(panelChangeSpy.args[panelChangeCallCount - 1], [2], 'after transitioning to second panel, onPanelChange callback was fired with the second index as its first argument'); | ||
assert.equal(carouselView.getCurrentIndex(), 2, 'getCurrentIndex() returns 2'); | ||
assert.ok(panels[2].classList.contains(activeClass), 'active class has been applied to second panel'); | ||
carouselView.goTo(2); | ||
assert.equal(panelChangeSpy.callCount, panelChangeCallCount, 'after going to the second panel again, onPanelChange callback was NOT fired twice'); | ||
assert.equal(carouselView.getCurrentIndex(), 2, 'getCurrentIndex() still returns 2'); | ||
assert.ok(panels[2].classList.contains(activeClass), 'second panel still has active class'); | ||
assert.equal(panelChangeSpy.callCount, panelChangeCallCount); | ||
carouselView.destroy(); | ||
@@ -92,3 +168,2 @@ }); | ||
it('should not crash when showing a panel that doesn\'t exists', function () { | ||
var fixture = document.getElementById('qunit-fixture'); | ||
var carouselEl = document.createElement('div'); | ||
@@ -130,3 +205,2 @@ var activeClass = 'carousel-panel-active'; | ||
it('next() should call goTo() with correct parameters', function () { | ||
var fixture = document.getElementById('qunit-fixture'); | ||
var carouselEl = document.createElement('div'); | ||
@@ -151,4 +225,3 @@ carouselEl.innerHTML = | ||
it('should NOT instantiate CarouselArrows if no left or right arrow is declared in initialize options', function () { | ||
var fixture = document.getElementById('qunit-fixture'); | ||
var carouselArrowsInitializeStub = sinon.stub(CarouselArrows.prototype, 'initialize'); | ||
var carouselArrowsInitializeStub = sinon.stub(CarouselArrows.prototype, 'constructor'); | ||
var carouselArrowsDestroyStub = sinon.stub(CarouselArrows.prototype, 'destroy'); | ||
@@ -170,30 +243,21 @@ var carouselEl = document.createElement('div'); | ||
it('should pass arrows and panels in initialize options to CarouselArrows', function () { | ||
var fixture = document.getElementById('qunit-fixture'); | ||
var carouselArrowsInitializeSpy = sinon.spy(CarouselArrows.prototype, 'initialize'); | ||
var carouselArrowsDestroySpy = sinon.spy(CarouselArrows.prototype, 'destroy'); | ||
it('should pass arrow elements and proper options to CarouselArrows', function () { | ||
var carouselEl = document.createElement('div'); | ||
carouselEl.innerHTML = | ||
'<div class="carousel-panel"></div>' + | ||
'<div class="carousel-panel"></div>' + | ||
'<div class="carousel-panel"></div>'; | ||
var panelEl = document.createElement('div'); | ||
carouselEl.appendChild(panelEl); | ||
var leftArrow = document.createElement('div'); | ||
var rightArrow = document.createElement('div'); | ||
var panels = carouselEl.getElementsByClassName('carousel-panel'); | ||
var carouselView = new Carousel({ | ||
panels: panels, | ||
panels: [panelEl], | ||
leftArrow: leftArrow, | ||
rightArrow: rightArrow | ||
}); | ||
assert.deepEqual(carouselArrowsInitializeSpy.args[0][0].panels, panels, 'panels were passed to carousel arrows'); | ||
assert.deepEqual(carouselArrowsInitializeSpy.args[0][0].leftArrow, leftArrow, 'left arrow is passed to carousel arrows'); | ||
assert.deepEqual(carouselArrowsInitializeSpy.args[0][0].rightArrow, rightArrow, 'right arrow was passed to carousel arrows'); | ||
assert.deepEqual(carouselView.subModules.arrows.options.panels, [panelEl], 'panels were passed to carousel arrows'); | ||
assert.deepEqual(carouselView.subModules.arrows.options.leftArrow, leftArrow, 'left arrow is passed to carousel arrows'); | ||
assert.deepEqual(carouselView.subModules.arrows.options.rightArrow, rightArrow, 'right arrow was passed to carousel arrows'); | ||
carouselView.destroy(); | ||
carouselArrowsInitializeSpy.restore(); | ||
carouselArrowsDestroySpy.restore(); | ||
}); | ||
it('should call destroy on CarouselArrows when destroy() is called', function () { | ||
var fixture = document.getElementById('qunit-fixture'); | ||
var carouselArrowsInitializeSpy = sinon.spy(CarouselArrows.prototype, 'initialize'); | ||
var carouselArrowsInitializeSpy = sinon.spy(CarouselArrows.prototype, 'constructor'); | ||
var carouselArrowsDestroySpy = sinon.spy(CarouselArrows.prototype, 'destroy'); | ||
@@ -220,5 +284,2 @@ var carouselEl = document.createElement('div'); | ||
it('should call onLeftArrowClick when left arrow is clicked', function () { | ||
var fixture = document.getElementById('qunit-fixture'); | ||
var carouselArrowsInitializeSpy = sinon.spy(CarouselArrows.prototype, 'initialize'); | ||
var carouselArrowsDestroySpy = sinon.spy(CarouselArrows.prototype, 'destroy'); | ||
var carouselEl = document.createElement('div'); | ||
@@ -239,37 +300,21 @@ carouselEl.innerHTML = | ||
carouselView.goTo(1); | ||
var clickEvent = TestUtils.createEvent('click'); | ||
var clickEvent = new Event('click'); | ||
leftArrow.dispatchEvent(clickEvent); | ||
assert.equal(leftArrowClickSpy.args[0][0], clickEvent, 'click callback was called and passed click event'); | ||
carouselView.destroy(); | ||
carouselArrowsInitializeSpy.restore(); | ||
carouselArrowsDestroySpy.restore(); | ||
}); | ||
it('should NOT instantiate CarouselThumbs if null/undefined is passed as thumbnail option', function () { | ||
var fixture = document.getElementById('qunit-fixture'); | ||
var carouselThumbsInitializeStub = sinon.stub(CarouselThumbs.prototype, 'initialize'); | ||
var carouselThumbsDestroyStub = sinon.stub(CarouselThumbs.prototype, 'destroy'); | ||
var carouselView = new Carousel({ | ||
thumbnails: null | ||
}); | ||
assert.equal(carouselThumbsInitializeStub.callCount, 0); | ||
var carouselView = new Carousel({thumbnails: null}); | ||
assert.ok(!carouselView.subModules.thumbnails); | ||
carouselView.destroy(); | ||
carouselThumbsInitializeStub.restore(); | ||
carouselThumbsDestroyStub.restore(); | ||
}); | ||
it('should NOT instantiate CarouselThumbs if no thumbnail elements are passed', function () { | ||
var fixture = document.getElementById('qunit-fixture'); | ||
var carouselThumbsInitializeStub = sinon.stub(CarouselThumbs.prototype, 'initialize'); | ||
var carouselThumbsDestroyStub = sinon.stub(CarouselThumbs.prototype, 'destroy'); | ||
var carouselView = new Carousel(); | ||
assert.equal(carouselThumbsInitializeStub.callCount, 0); | ||
assert.ok(!carouselView.subModules.thumbnails); | ||
carouselView.destroy(); | ||
carouselThumbsInitializeStub.restore(); | ||
carouselThumbsDestroyStub.restore(); | ||
}); | ||
it('should pass thumbnail elements in CarouselThumbs initialize options', function () { | ||
var fixture = document.getElementById('qunit-fixture'); | ||
var carouselThumbsInitializeSpy = sinon.spy(CarouselThumbs.prototype, 'initialize'); | ||
var carouselEl = document.createElement('div'); | ||
@@ -282,9 +327,7 @@ carouselEl.innerHTML = | ||
var carouselView = new Carousel({thumbnails: thumbs}); | ||
assert.deepEqual(carouselThumbsInitializeSpy.args[0][0].thumbnails, thumbs, 'thumbnails were passed to CarouselThumbs initialize'); | ||
assert.deepEqual(carouselView.subModules.thumbnails.options.thumbnails, thumbs); | ||
carouselView.destroy(); | ||
carouselThumbsInitializeSpy.restore(); | ||
}); | ||
it('should call CarouselThumbs destroy on destroy()', function () { | ||
var fixture = document.getElementById('qunit-fixture'); | ||
var carouselThumbsDestroySpy = sinon.spy(CarouselThumbs.prototype, 'destroy'); | ||
@@ -304,21 +347,4 @@ var carouselEl = document.createElement('div'); | ||
it('should pass first parameter of goTo() to CarouselPanels.goTo()', function () { | ||
var fixture = document.getElementById('qunit-fixture'); | ||
var carouselEl = document.createElement('div'); | ||
carouselEl.innerHTML = | ||
'<div class="carousel-panel"></div>' + | ||
'<div class="carousel-panel"></div>' + | ||
'<div class="carousel-panel"></div>'; | ||
var panels = carouselEl.getElementsByClassName('carousel-panel'); | ||
var carouselView = new Carousel({panels: panels}); | ||
var carouselPanelsGoToStub = sinon.stub(CarouselPanels.prototype, 'goTo'); | ||
var textIndexNum = 2; | ||
carouselView.goTo(textIndexNum); // go to second index | ||
assert.equal(carouselPanelsGoToStub.args[0][0], textIndexNum); | ||
carouselPanelsGoToStub.restore(); | ||
carouselView.destroy(); | ||
}); | ||
it('should pass first parameter of goTo() to CarouselThumbs.goTo()', function () { | ||
var fixture = document.getElementById('qunit-fixture'); | ||
var carouselEl = document.createElement('div'); | ||
@@ -325,0 +351,0 @@ carouselEl.innerHTML = |
var sinon = require('sinon'); | ||
var TestUtils = require('test-utils'); | ||
var CarouselThumbs = require('../src/carousel-thumbs'); | ||
@@ -24,3 +23,3 @@ var assert = require('assert'); | ||
// click second thumbnail | ||
thumbEls[1].dispatchEvent(TestUtils.createEvent('click')); | ||
thumbEls[1].click(); | ||
goToCallCount++; | ||
@@ -32,3 +31,3 @@ assert.ok(thumbEls[1].classList.contains(thumbActiveClass), 'after clicking on second thumbnail, second thumbnail has active class'); | ||
// click first thumbnail | ||
thumbEls[0].dispatchEvent(TestUtils.createEvent('click')); | ||
thumbEls[0].click(); | ||
goToCallCount++; | ||
@@ -40,3 +39,3 @@ assert.ok(thumbEls[0].classList.contains(thumbActiveClass), 'after clicking on first thumbnail, first thumbnail has active class'); | ||
// click third thumbnail | ||
thumbEls[2].dispatchEvent(TestUtils.createEvent('click')); | ||
thumbEls[2].click(); | ||
goToCallCount++; | ||
@@ -48,3 +47,3 @@ assert.ok(thumbEls[2].classList.contains(thumbActiveClass), 'after clicking on third thumbnail, third thumbnail has active class'); | ||
// click on third panel AGAIN | ||
thumbEls[2].dispatchEvent(TestUtils.createEvent('click')); | ||
thumbEls[2].click(); | ||
assert.ok(thumbEls[2].classList.contains(thumbActiveClass), 'after clicking on third thumbnail AGAIN, third thumbnail still has active class'); | ||
@@ -74,9 +73,9 @@ assert.ok(!thumbEls[0].classList.contains(thumbActiveClass), 'first thumbnail does not have active class'); | ||
// click second thumbnail | ||
thumbEls[1].dispatchEvent(TestUtils.createEvent('click')); | ||
thumbEls[1].click(); | ||
assert.ok(!thumbEls[1].classList.contains(thumbActiveClass), 'second thumbnail does not have active class when clicked'); | ||
// click first thumbnail | ||
thumbEls[0].dispatchEvent(TestUtils.createEvent('click')); | ||
thumbEls[0].click(); | ||
assert.ok(!thumbEls[0].classList.contains(thumbActiveClass), 'first thumbnail does not have active class when clicked'); | ||
// click third thumbnail | ||
thumbEls[2].dispatchEvent(TestUtils.createEvent('click')); | ||
thumbEls[2].click(); | ||
assert.ok(!thumbEls[2].classList.contains(thumbActiveClass), 'third thumbnail does not have active class when clicked'); | ||
@@ -102,7 +101,7 @@ }); | ||
// click second thumbnail | ||
thumbEls[1].dispatchEvent(TestUtils.createEvent('click')); | ||
thumbEls[1].click(); | ||
// click first thumbnail | ||
thumbEls[0].dispatchEvent(TestUtils.createEvent('click')); | ||
thumbEls[0].click(); | ||
// click third thumbnail | ||
thumbEls[2].dispatchEvent(TestUtils.createEvent('click')); | ||
thumbEls[2].click(); | ||
assert.equal(goToSpy.callCount, 0); | ||
@@ -109,0 +108,0 @@ goToSpy.restore(); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Uses eval
Supply chain riskPackage uses eval() which is a dangerous function. This prevents the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 2 instances in 1 package
Uses eval
Supply chain riskPackage uses eval() which is a dangerous function. This prevents the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
1594313
21
37011
119
4
8
+ AddedJSONStream@1.3.5(transitive)
+ Addedacorn@5.7.47.4.1(transitive)
+ Addedacorn-node@1.8.2(transitive)
+ Addedacorn-walk@7.2.0(transitive)
+ Addedansi-regex@2.1.1(transitive)
+ Addedansi-styles@2.2.1(transitive)
+ Addedasn1.js@4.10.1(transitive)
+ Addedassert@1.5.1(transitive)
+ Addedbabel-code-frame@6.26.0(transitive)
+ Addedbabel-core@6.26.3(transitive)
+ Addedbabel-generator@6.26.1(transitive)
+ Addedbabel-helper-call-delegate@6.24.1(transitive)
+ Addedbabel-helper-define-map@6.26.0(transitive)
+ Addedbabel-helper-function-name@6.24.1(transitive)
+ Addedbabel-helper-get-function-arity@6.24.1(transitive)
+ Addedbabel-helper-hoist-variables@6.24.1(transitive)
+ Addedbabel-helper-optimise-call-expression@6.24.1(transitive)
+ Addedbabel-helper-regex@6.26.0(transitive)
+ Addedbabel-helper-replace-supers@6.24.1(transitive)
+ Addedbabel-helpers@6.24.1(transitive)
+ Addedbabel-messages@6.23.0(transitive)
+ Addedbabel-plugin-check-es2015-constants@6.22.0(transitive)
+ Addedbabel-plugin-transform-es2015-arrow-functions@6.22.0(transitive)
+ Addedbabel-plugin-transform-es2015-block-scoped-functions@6.22.0(transitive)
+ Addedbabel-plugin-transform-es2015-block-scoping@6.26.0(transitive)
+ Addedbabel-plugin-transform-es2015-classes@6.24.1(transitive)
+ Addedbabel-plugin-transform-es2015-computed-properties@6.24.1(transitive)
+ Addedbabel-plugin-transform-es2015-destructuring@6.23.0(transitive)
+ Addedbabel-plugin-transform-es2015-duplicate-keys@6.24.1(transitive)
+ Addedbabel-plugin-transform-es2015-for-of@6.23.0(transitive)
+ Addedbabel-plugin-transform-es2015-function-name@6.24.1(transitive)
+ Addedbabel-plugin-transform-es2015-literals@6.22.0(transitive)
+ Addedbabel-plugin-transform-es2015-modules-amd@6.24.1(transitive)
+ Addedbabel-plugin-transform-es2015-modules-commonjs@6.26.2(transitive)
+ Addedbabel-plugin-transform-es2015-modules-systemjs@6.24.1(transitive)
+ Addedbabel-plugin-transform-es2015-modules-umd@6.24.1(transitive)
+ Addedbabel-plugin-transform-es2015-object-super@6.24.1(transitive)
+ Addedbabel-plugin-transform-es2015-parameters@6.24.1(transitive)
+ Addedbabel-plugin-transform-es2015-shorthand-properties@6.24.1(transitive)
+ Addedbabel-plugin-transform-es2015-spread@6.22.0(transitive)
+ Addedbabel-plugin-transform-es2015-sticky-regex@6.24.1(transitive)
+ Addedbabel-plugin-transform-es2015-template-literals@6.22.0(transitive)
+ Addedbabel-plugin-transform-es2015-typeof-symbol@6.23.0(transitive)
+ Addedbabel-plugin-transform-es2015-unicode-regex@6.24.1(transitive)
+ Addedbabel-plugin-transform-regenerator@6.26.0(transitive)
+ Addedbabel-plugin-transform-strict-mode@6.24.1(transitive)
+ Addedbabel-preset-es2015@6.24.1(transitive)
+ Addedbabel-register@6.26.0(transitive)
+ Addedbabel-runtime@6.26.0(transitive)
+ Addedbabel-template@6.26.0(transitive)
+ Addedbabel-traverse@6.26.0(transitive)
+ Addedbabel-types@6.26.0(transitive)
+ Addedbabelify@7.3.0(transitive)
+ Addedbabylon@6.18.0(transitive)
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbase64-js@1.5.1(transitive)
+ Addedbn.js@4.12.05.2.1(transitive)
+ Addedbrace-expansion@1.1.11(transitive)
+ Addedbrorand@1.1.0(transitive)
+ Addedbrowser-pack@6.1.0(transitive)
+ Addedbrowser-resolve@1.11.3(transitive)
+ Addedbrowserify@13.3.0(transitive)
+ Addedbrowserify-aes@1.2.0(transitive)
+ Addedbrowserify-cipher@1.0.1(transitive)
+ Addedbrowserify-des@1.0.2(transitive)
+ Addedbrowserify-rsa@4.1.0(transitive)
+ Addedbrowserify-sign@4.2.3(transitive)
+ Addedbrowserify-zlib@0.1.4(transitive)
+ Addedbuffer@4.9.2(transitive)
+ Addedbuffer-from@1.1.2(transitive)
+ Addedbuffer-xor@1.0.3(transitive)
+ Addedbuiltin-status-codes@3.0.0(transitive)
+ Addedcached-path-relative@1.1.0(transitive)
+ Addedcall-bind@1.0.7(transitive)
+ Addedchalk@1.1.3(transitive)
+ Addedcipher-base@1.0.4(transitive)
+ Addedcombine-source-map@0.8.0(transitive)
+ Addedconcat-map@0.0.1(transitive)
+ Addedconcat-stream@1.5.21.6.2(transitive)
+ Addedconsole-browserify@1.2.0(transitive)
+ Addedconstants-browserify@1.0.0(transitive)
+ Addedconvert-source-map@1.1.31.9.0(transitive)
+ Addedcore-js@2.6.12(transitive)
+ Addedcore-util-is@1.0.3(transitive)
+ Addedcreate-ecdh@4.0.4(transitive)
+ Addedcreate-hash@1.2.0(transitive)
+ Addedcreate-hmac@1.1.7(transitive)
+ Addedcrypto-browserify@3.12.0(transitive)
+ Addeddash-ast@1.0.0(transitive)
+ Addeddebug@2.6.9(transitive)
+ Addeddefine-data-property@1.1.4(transitive)
+ Addeddefine-properties@1.2.1(transitive)
+ Addeddefined@1.0.1(transitive)
+ Addeddeps-sort@2.0.1(transitive)
+ Addeddes.js@1.1.0(transitive)
+ Addeddetect-indent@4.0.0(transitive)
+ Addeddetective@4.7.1(transitive)
+ Addeddiffie-hellman@5.0.3(transitive)
+ Addeddomain-browser@1.1.7(transitive)
+ Addedduplexer2@0.1.4(transitive)
+ Addedelliptic@6.5.5(transitive)
+ Addedes-define-property@1.0.0(transitive)
+ Addedes-errors@1.3.0(transitive)
+ Addedes6-promise@4.2.8(transitive)
+ Addedescape-string-regexp@1.0.5(transitive)
+ Addedesutils@2.0.3(transitive)
+ Addedevents@1.1.1(transitive)
+ Addedevp_bytestokey@1.0.3(transitive)
+ Addedfast-safe-stringify@2.1.1(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedfunction-bind@1.1.2(transitive)
+ Addedget-assigned-identifiers@1.2.0(transitive)
+ Addedget-intrinsic@1.2.4(transitive)
+ Addedglob@7.2.3(transitive)
+ Addedglobals@9.18.0(transitive)
+ Addedgopd@1.0.1(transitive)
+ Addedhandlebars@4.7.8(transitive)
+ Addedhas@1.0.4(transitive)
+ Addedhas-ansi@2.0.0(transitive)
+ Addedhas-property-descriptors@1.0.2(transitive)
+ Addedhas-proto@1.0.3(transitive)
+ Addedhas-symbols@1.0.3(transitive)
+ Addedhash-base@3.0.4(transitive)
+ Addedhash.js@1.1.7(transitive)
+ Addedhasown@2.0.2(transitive)
+ Addedhmac-drbg@1.0.1(transitive)
+ Addedhome-or-tmp@2.0.0(transitive)
+ Addedhtmlescape@1.1.1(transitive)
+ Addedhttps-browserify@0.0.1(transitive)
+ Addedieee754@1.2.1(transitive)
+ Addedindexof@0.0.1(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedinherits@2.0.32.0.4(transitive)
+ Addedinline-source-map@0.6.3(transitive)
+ Addedinsert-module-globals@7.2.1(transitive)
+ Addedinvariant@2.2.4(transitive)
+ Addedis-buffer@1.1.6(transitive)
+ Addedis-core-module@2.13.1(transitive)
+ Addedis-finite@1.1.0(transitive)
+ Addedisarray@1.0.0(transitive)
+ Addedjs-tokens@3.0.2(transitive)
+ Addedjsesc@0.5.01.3.0(transitive)
+ Addedjson-stable-stringify@0.0.1(transitive)
+ Addedjson5@0.5.1(transitive)
+ Addedjsonify@0.0.1(transitive)
+ Addedjsonparse@1.3.1(transitive)
+ Addedlabeled-stream-splicer@2.0.2(transitive)
+ Addedlodash.memoize@3.0.4(transitive)
+ Addedloose-envify@1.4.0(transitive)
+ Addedmd5.js@1.3.5(transitive)
+ Addedmiller-rabin@4.0.1(transitive)
+ Addedminimalistic-assert@1.0.1(transitive)
+ Addedminimalistic-crypto-utils@1.0.1(transitive)
+ Addedminimatch@3.1.2(transitive)
+ Addedminimist@1.2.8(transitive)
+ Addedmkdirp@0.5.6(transitive)
+ Addedmodule-deps@4.1.1(transitive)
+ Addedmodule-js@5.15.0(transitive)
+ Addedms@2.0.0(transitive)
+ Addedneo-async@2.6.2(transitive)
+ Addedobject-assign@4.1.1(transitive)
+ Addedobject-inspect@1.13.1(transitive)
+ Addedobject-keys@1.1.1(transitive)
+ Addedobject.assign@4.1.5(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedos-browserify@0.1.2(transitive)
+ Addedos-homedir@1.0.2(transitive)
+ Addedos-tmpdir@1.0.2(transitive)
+ Addedpako@0.2.9(transitive)
+ Addedparents@1.0.1(transitive)
+ Addedparse-asn1@5.1.7(transitive)
+ Addedpath-browserify@0.0.1(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedpath-parse@1.0.7(transitive)
+ Addedpath-platform@0.11.15(transitive)
+ Addedpbkdf2@3.1.2(transitive)
+ Addedprivate@0.1.8(transitive)
+ Addedprocess@0.11.10(transitive)
+ Addedprocess-nextick-args@1.0.72.0.1(transitive)
+ Addedpublic-encrypt@4.0.3(transitive)
+ Addedpunycode@1.4.1(transitive)
+ Addedqs@6.12.1(transitive)
+ Addedquerystring-es3@0.2.1(transitive)
+ Addedrandombytes@2.1.0(transitive)
+ Addedrandomfill@1.0.4(transitive)
+ Addedread-only-stream@2.0.0(transitive)
+ Addedreadable-stream@2.0.62.3.8(transitive)
+ Addedregenerate@1.4.2(transitive)
+ Addedregenerator-runtime@0.11.1(transitive)
+ Addedregenerator-transform@0.10.1(transitive)
+ Addedregexpu-core@2.0.0(transitive)
+ Addedregjsgen@0.2.0(transitive)
+ Addedregjsparser@0.1.5(transitive)
+ Addedrepeating@2.0.1(transitive)
+ Addedresolve@1.1.71.22.8(transitive)
+ Addedresource-manager-js@2.7.0(transitive)
+ Addedripemd160@2.0.2(transitive)
+ Addedsafe-buffer@5.1.25.2.1(transitive)
+ Addedset-function-length@1.2.2(transitive)
+ Addedsha.js@2.4.11(transitive)
+ Addedshasum@1.0.2(transitive)
+ Addedshasum-object@1.0.0(transitive)
+ Addedshell-quote@1.8.1(transitive)
+ Addedside-channel@1.0.6(transitive)
+ Addedsimple-concat@1.0.1(transitive)
+ Addedslash@1.0.0(transitive)
+ Addedsource-map@0.5.70.6.1(transitive)
+ Addedsource-map-support@0.4.18(transitive)
+ Addedstream-browserify@2.0.2(transitive)
+ Addedstream-combiner2@1.1.1(transitive)
+ Addedstream-http@2.8.3(transitive)
+ Addedstream-splicer@2.0.1(transitive)
+ Addedstring_decoder@0.10.311.1.1(transitive)
+ Addedstrip-ansi@3.0.1(transitive)
+ Addedsubarg@1.0.0(transitive)
+ Addedsupports-color@2.0.0(transitive)
+ Addedsupports-preserve-symlinks-flag@1.0.0(transitive)
+ Addedsyntax-error@1.4.0(transitive)
+ Addedthrough@2.3.8(transitive)
+ Addedthrough2@2.0.5(transitive)
+ Addedtimers-browserify@1.4.2(transitive)
+ Addedto-arraybuffer@1.0.1(transitive)
+ Addedto-fast-properties@1.0.3(transitive)
+ Addedtrim-right@1.0.1(transitive)
+ Addedtty-browserify@0.0.1(transitive)
+ Addedtypedarray@0.0.60.0.7(transitive)
+ Addeduglify-js@3.18.0(transitive)
+ Addedumd@3.0.3(transitive)
+ Addedundeclared-identifiers@1.1.3(transitive)
+ Addedurl@0.11.3(transitive)
+ Addedutil@0.10.4(transitive)
+ Addedutil-deprecate@1.0.2(transitive)
+ Addedvm-browserify@0.0.4(transitive)
+ Addedwhatwg-fetch@1.1.1(transitive)
+ Addedwordwrap@1.0.0(transitive)
+ Addedwrappy@1.0.2(transitive)
+ Addedxtend@4.0.2(transitive)
- Removedmodule-js@3.0.1(transitive)
- Removedunderscore@1.13.6(transitive)
Updatedmodule-js@^5.4.1