diff --git a/.gitignore b/.gitignore
index 8a325f0..cedd4ec 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,3 @@
.DS_Store
-test/spec-1-api.js
-test/spec-2-shell.js
-test/spec-3-tests.js
\ No newline at end of file
+.sass-cache/
+progress/
\ No newline at end of file
diff --git a/pitchdeck.core.js b/pitchdeck.core.js
index 09915f3..53b71f0 100644
--- a/pitchdeck.core.js
+++ b/pitchdeck.core.js
@@ -69,18 +69,44 @@
function updateStates() {
var oc = options.classes,
$container = $(options.selectors.container),
- old = $container.data('onSlide');
+ old = $container.data('onSlide'),
+ $all = $();
+ // Container state
$container.removeClass(oc.onPrefix + old)
.addClass(oc.onPrefix + current)
.data('onSlide', current);
- $.each(slides, function(i, $e) {
- $e.toggleClass(oc.before, i < current - 1)
- .toggleClass(oc.previous, i === current - 1)
- .toggleClass(oc.current, i === current)
- .toggleClass(oc.next, i === current + 1)
- .toggleClass(oc.after, i > current + 1);
+
+ // Remove previous states
+ $.each(slides, function(i, el) {
+ $all = $all.add(el);
});
+ $all.removeClass([
+ oc.before,
+ oc.previous,
+ oc.current,
+ oc.next,
+ oc.after
+ ].join(" "));
+
+ // Add new states back in
+ slides[current].addClass(oc.current);
+ if (current > 0) {
+ slides[current-1].addClass(oc.previous);
+ }
+ if (current + 1 < slides.length) {
+ slides[current+1].addClass(oc.next);
+ }
+ if (current > 1) {
+ $.each(slides.slice(0, current - 1), function(i, el) {
+ el.addClass(oc.before);
+ });
+ }
+ if (current + 2 < slides.length) {
+ $.each(slides.slice(current+2), function(i, el) {
+ el.addClass(oc.after);
+ })
+ }
}
$[pd] = function(method, arg) {
diff --git a/test/fixtures/complex.html b/test/fixtures/complex.html
new file mode 100644
index 0000000..d9a2956
--- /dev/null
+++ b/test/fixtures/complex.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/index.html b/test/index.html
index 962ca1e..7501fcc 100644
--- a/test/index.html
+++ b/test/index.html
@@ -6,7 +6,7 @@
-
+
diff --git a/test/spec.core.js b/test/spec.core.js
index f9d7561..20585b8 100755
--- a/test/spec.core.js
+++ b/test/spec.core.js
@@ -4,247 +4,308 @@ var defaults = $.pitchdeck.defaults;
// Go tests, go
describe('PitchDeck', function() {
- beforeEach(function() {
- loadFixtures('standard.html');
- });
-
- describe('init(selector)', function() {
- it('should create slides', function() {
- $.pitchdeck('.slide');
- expect($.pitchdeck('getSlides').length).toEqual($('.slide').length);
+ describe('standard html structure', function() {
+ beforeEach(function() {
+ loadFixtures('standard.html');
+ });
+
+ describe('init(selector)', function() {
+ it('should create slides', function() {
+ $.pitchdeck('.slide');
+ expect($.pitchdeck('getSlides').length).toEqual($('.slide').length);
+ });
+ });
+
+ describe('init([selectors])', function() {
+ it('should create slides', function() {
+ $.pitchdeck([
+ '.slide1',
+ '.slide2',
+ '.slide3',
+ '.slide4',
+ '.slide5'
+ ]);
+ expect($.pitchdeck('getSlides').length).toEqual($('.slide').length);
+ });
+ });
+
+ describe('navigation functions', function() {
+ beforeEach(function() {
+ $.pitchdeck('.slide');
+ });
+
+ describe('go(i)', function() {
+ it('should go to the i slide (0 based index)', function() {
+ $.pitchdeck('go', 3);
+ expect($.pitchdeck('getSlide')).toHaveClass('slide4');
+ });
+
+ it('should go nowhere if i is NaN', function() {
+ $.pitchdeck('go', 'foobar');
+ expect($.pitchdeck('getSlide')).toHaveClass('slide1');
+ });
+
+ it('should go nowhere if i is out of bounds', function() {
+ $.pitchdeck('go', 5);
+ expect($.pitchdeck('getSlide')).toHaveClass('slide1');
+ });
+ });
+
+ describe('next()', function() {
+ it('should go to the next slide', function() {
+ $.pitchdeck('next');
+ expect($.pitchdeck('getSlide')).toHaveClass('slide2');
+ });
+
+ it('should go nowhere if on the last slide', function() {
+ $.pitchdeck('go', 4);
+ $.pitchdeck('next');
+ expect($.pitchdeck('getSlide')).toHaveClass('slide5');
+ });
+ });
+
+ describe('prev()', function() {
+ it('should go to the previous slide', function() {
+ $.pitchdeck('go', 2);
+ $.pitchdeck('prev');
+ expect($.pitchdeck('getSlide')).toHaveClass('slide2');
+ });
+
+ it('should go nowhere if on the first slide', function() {
+ $.pitchdeck('prev');
+ expect($.pitchdeck('getSlide')).toHaveClass('slide1');
+ });
+ });
+ });
+
+ describe('getters', function() {
+ beforeEach(function() {
+ $.pitchdeck('.slide');
+ });
+
+ describe('getSlide()', function() {
+ it('should get the current slide', function() {
+ expect($.pitchdeck('getSlide')).toHaveClass('slide1');
+ $.pitchdeck('go', 2);
+ expect($.pitchdeck('getSlide')).toHaveClass('slide3');
+ });
+ });
+
+ describe('getSlide(i)', function() {
+ it('should get slide number i (0 based index)', function() {
+ expect($.pitchdeck('getSlide', 1)).toHaveClass('slide2');
+ expect($.pitchdeck('getSlide', 3)).toHaveClass('slide4');
+ });
+
+ it('should return null if i is NaN', function() {
+ expect($.pitchdeck('getSlide', 'barfoo')).toBeNull();
+ });
+
+ it('should return null if i is out of bounds', function() {
+ expect($.pitchdeck('getSlide', 6)).toBeNull();
+ });
+ });
+
+ describe('getSlides()', function() {
+ it('should return an array of jQuery objects for each slide', function() {
+ var expectation = [];
+ $('.slide').each(function() {
+ expectation.push($(this));
+ });
+ slides = $.pitchdeck('getSlides');
+ expect(slides).toEqual(expectation);
+ });
+ });
+ });
+
+ describe('container states', function() {
+ beforeEach(function() {
+ $.pitchdeck('.slide');
+ });
+
+ it('should start at state 0', function() {
+ expect($(defaults.selectors.container)).toHaveClass(defaults.classes.onPrefix + '0');
+ });
+
+ it('should change states with the slide number', function() {
+ $.pitchdeck('next');
+ expect($(defaults.selectors.container)).toHaveClass(defaults.classes.onPrefix + '1');
+ $.pitchdeck('go', 3);
+ expect($(defaults.selectors.container)).toHaveClass(defaults.classes.onPrefix + '3');
+ $.pitchdeck('prev');
+ expect($(defaults.selectors.container)).toHaveClass(defaults.classes.onPrefix + '2');
+ });
+ });
+
+ describe('options object', function() {
+ var $d = $(document);
+
+ beforeEach(function() {
+ $d.unbind('keydown');
+ $.pitchdeck('.alt-slide', {
+ classes: {
+ after: 'alt-after',
+ before: 'alt-before',
+ current: 'alt-current',
+ onPrefix: 'alt-on-',
+ next: 'alt-next',
+ previous: 'alt-prev'
+ },
+
+ selectors: {
+ container: '.alt-container'
+ },
+
+ keys: {
+ next: 87,
+ previous: 69
+ }
+ });
+ });
+
+ describe('classes', function() {
+ it('should use the specified after class', function() {
+ expect($('.alt-slide3, .alt-slide4, .alt-slide5')).toHaveClass('alt-after');
+ });
+
+ it('should use the specified before class', function() {
+ $.pitchdeck('go', 4);
+ expect($('.alt-slide1, .alt-slide2, .alt-slide3')).toHaveClass('alt-before');
+ });
+
+ it('should use the specified container class', function() {
+ $.pitchdeck('go', 2);
+ expect($('.alt-container')).toHaveClass('alt-on-2');
+ });
+
+ it('should use the specified current class', function() {
+ expect($.pitchdeck('getSlide')).toHaveClass('alt-current');
+ });
+
+ it('should use the specified next class', function() {
+ expect($('.alt-slide2')).toHaveClass('alt-next');
+ });
+
+ it('should use the specified previous class', function() {
+ $.pitchdeck('next');
+ expect($('.alt-slide1')).toHaveClass('alt-prev');
+ });
+ });
+
+ describe('key bindings', function() {
+ var e;
+
+ beforeEach(function() {
+ e = jQuery.Event('keydown');
+ });
+
+ it('should go to the next slide using the specified key', function() {
+ e.which = 87; // 'w'
+ $d.trigger(e);
+ expect($.pitchdeck('getSlide')).toHaveClass('alt-slide2');
+ });
+
+ it('should go to the previous slide using the specified key', function() {
+ $.pitchdeck('next');
+ e.which = 69; // 'e'
+ $d.trigger(e);
+ expect($.pitchdeck('getSlide')).toHaveClass('alt-slide1');
+ });
+ });
+ });
+
+ describe('events', function() {
+ var $d = $(document);
+
+ beforeEach(function() {
+ $.pitchdeck('.slide');
+ $.pitchdeck('go', 1);
+ spyOnEvent($d, 'pitchdeck.change');
+ });
+
+ describe('pitchdeck.change', function() {
+ it('should fire on go(i)', function() {
+ $.pitchdeck('go', 3);
+ expect('pitchdeck.change').toHaveBeenTriggeredOn($d);
+ });
+
+ it('should fire on next()', function() {
+ $.pitchdeck('next');
+ expect('pitchdeck.change').toHaveBeenTriggeredOn($d);
+ });
+
+ it('should fire on prev()', function() {
+ $.pitchdeck('prev');
+ expect('pitchdeck.change').toHaveBeenTriggeredOn($d);
+ });
+
+ it('should pass parameters with from and to indices', function() {
+ $d.bind('pitchdeck.change', function(e, from, to) {
+ expect(from).toEqual(1);
+ expect(to).toEqual(3);
+ });
+ $.pitchdeck('go', 3);
+ $d.unbind('pitchdeck.change');
+ });
+ });
});
});
- describe('init([selectors])', function() {
- it('should create slides', function() {
+ describe('complex html structure', function() {
+ beforeEach(function() {
+ loadFixtures('complex.html');
$.pitchdeck([
'.slide1',
'.slide2',
'.slide3',
'.slide4',
- '.slide5'
+ '.slide5',
+ '.slide6',
+ '.slide7',
+ '.slide8',
+ '.slide9',
+ '.slide10',
]);
- expect($.pitchdeck('getSlides').length).toEqual($('.slide').length);
- });
- });
-
- describe('navigation functions', function() {
- beforeEach(function() {
- $.pitchdeck('.slide');
+ $.pitchdeck('go', 2);
});
- describe('go(i)', function() {
- it('should go to the i slide (0 based index)', function() {
- $.pitchdeck('go', 3);
- expect($.pitchdeck('getSlide')).toHaveClass('slide4');
- });
-
- it('should go nowhere if i is NaN', function() {
- $.pitchdeck('go', 'foobar');
- expect($.pitchdeck('getSlide')).toHaveClass('slide1');
- });
-
- it('should go nowhere if i is out of bounds', function() {
- $.pitchdeck('go', 5);
- expect($.pitchdeck('getSlide')).toHaveClass('slide1');
- });
- });
-
- describe('next()', function() {
- it('should go to the next slide', function() {
- $.pitchdeck('next');
- expect($.pitchdeck('getSlide')).toHaveClass('slide2');
- });
-
- it('should go nowhere if on the last slide', function() {
- $.pitchdeck('go', 4);
- $.pitchdeck('next');
- expect($.pitchdeck('getSlide')).toHaveClass('slide5');
- });
- });
-
- describe('prev()', function() {
- it('should go to the previous slide', function() {
- $.pitchdeck('go', 2);
- $.pitchdeck('prev');
- expect($.pitchdeck('getSlide')).toHaveClass('slide2');
- });
-
- it('should go nowhere if on the first slide', function() {
- $.pitchdeck('prev');
- expect($.pitchdeck('getSlide')).toHaveClass('slide1');
- });
- });
- });
-
- describe('getters', function() {
- beforeEach(function() {
- $.pitchdeck('.slide');
- });
-
- describe('getSlide()', function() {
- it('should get the current slide', function() {
- expect($.pitchdeck('getSlide')).toHaveClass('slide1');
- $.pitchdeck('go', 2);
- expect($.pitchdeck('getSlide')).toHaveClass('slide3');
- });
- });
-
- describe('getSlide(i)', function() {
- it('should get slide number i (0 based index)', function() {
- expect($.pitchdeck('getSlide', 1)).toHaveClass('slide2');
- expect($.pitchdeck('getSlide', 3)).toHaveClass('slide4');
- });
-
- it('should return null if i is NaN', function() {
- expect($.pitchdeck('getSlide', 'barfoo')).toBeNull();
- });
-
- it('should return null if i is out of bounds', function() {
- expect($.pitchdeck('getSlide', 6)).toBeNull();
- });
- });
-
- describe('getSlides()', function() {
- it('should return an array of jQuery objects for each slide', function() {
- var expectation = [];
- $('.slide').each(function() {
- expectation.push($(this));
+ describe('compound state classes', function() {
+ it('should apply current class', function() {
+ $('.slide3').each(function(i, el) {
+ expect($(el)).toHaveClass(defaults.classes.current);
});
- slides = $.pitchdeck('getSlides');
- expect(slides).toEqual(expectation);
- });
- });
- });
-
- describe('container states', function() {
- beforeEach(function() {
- $.pitchdeck('.slide');
- });
-
- it('should start at state 0', function() {
- expect($(defaults.selectors.container)).toHaveClass(defaults.classes.onPrefix + '0');
- });
-
- it('should change states with the slide number', function() {
- $.pitchdeck('next');
- expect($(defaults.selectors.container)).toHaveClass(defaults.classes.onPrefix + '1');
- $.pitchdeck('go', 3);
- expect($(defaults.selectors.container)).toHaveClass(defaults.classes.onPrefix + '3');
- $.pitchdeck('prev');
- expect($(defaults.selectors.container)).toHaveClass(defaults.classes.onPrefix + '2');
- });
- });
-
- describe('options object', function() {
- var $d = $(document);
-
- beforeEach(function() {
- $d.unbind('keydown');
- $.pitchdeck('.alt-slide', {
- classes: {
- after: 'alt-after',
- before: 'alt-before',
- current: 'alt-current',
- onPrefix: 'alt-on-',
- next: 'alt-next',
- previous: 'alt-prev'
- },
-
- selectors: {
- container: '.alt-container'
- },
-
- keys: {
- next: 87,
- previous: 69
- }
- });
- });
-
- describe('classes', function() {
- it('should use the specified after class', function() {
- expect($('.alt-slide3, .alt-slide4, .alt-slide5')).toHaveClass('alt-after');
});
- it('should use the specified before class', function() {
- $.pitchdeck('go', 4);
- expect($('.alt-slide1, .alt-slide2, .alt-slide3')).toHaveClass('alt-before');
- });
-
- it('should use the specified container class', function() {
- $.pitchdeck('go', 2);
- expect($('.alt-container')).toHaveClass('alt-on-2');
- });
-
- it('should use the specified current class', function() {
- expect($.pitchdeck('getSlide')).toHaveClass('alt-current');
- });
-
- it('should use the specified next class', function() {
- expect($('.alt-slide2')).toHaveClass('alt-next');
- });
-
- it('should use the specified previous class', function() {
- $.pitchdeck('next');
- expect($('.alt-slide1')).toHaveClass('alt-prev');
- });
- });
-
- describe('key bindings', function() {
- var e;
-
- beforeEach(function() {
- e = jQuery.Event('keydown');
- });
-
- it('should go to the next slide using the specified key', function() {
- e.which = 87; // 'w'
- $d.trigger(e);
- expect($.pitchdeck('getSlide')).toHaveClass('alt-slide2');
- });
-
- it('should go to the previous slide using the specified key', function() {
- $.pitchdeck('next');
- e.which = 69; // 'e'
- $d.trigger(e);
- expect($.pitchdeck('getSlide')).toHaveClass('alt-slide1');
- });
- });
- });
-
- describe('events', function() {
- var $d = $(document);
-
- beforeEach(function() {
- $.pitchdeck('.slide');
- $.pitchdeck('go', 1);
- spyOnEvent($d, 'pitchdeck.change');
- });
-
- describe('pitchdeck.change', function() {
- it('should fire on go(i)', function() {
- $.pitchdeck('go', 3);
- expect('pitchdeck.change').toHaveBeenTriggeredOn($d);
- });
-
- it('should fire on next()', function() {
- $.pitchdeck('next');
- expect('pitchdeck.change').toHaveBeenTriggeredOn($d);
- });
-
- it('should fire on prev()', function() {
- $.pitchdeck('prev');
- expect('pitchdeck.change').toHaveBeenTriggeredOn($d);
- });
-
- it('should pass parameters with from and to indices', function() {
- $d.bind('pitchdeck.change', function(e, from, to) {
- expect(from).toEqual(1);
- expect(to).toEqual(3);
+ it('should apply previous class', function() {
+ $('.slide2').each(function(i, el) {
+ expect($(el)).toHaveClass(defaults.classes.previous);
});
- $.pitchdeck('go', 3);
});
+
+ it('should apply next class', function() {
+ $('.slide4').each(function(i, el) {
+ expect($(el)).toHaveClass(defaults.classes.next);
+ });
+ });
+
+ it('should apply before class', function() {
+ $('.slide1').each(function(i, el) {
+ expect($(el)).toHaveClass(defaults.classes.before);
+ });
+ });
+
+ it('should apply after class', function() {
+ $('.slide5, .slide6, .slide7, .slide8, .slide9, .slide10').each(function(i, el) {
+ expect($(el)).toHaveClass(defaults.classes.after);
+ });
+ });
+ });
+
+ it('should remove old state classes', function() {
+ $.pitchdeck('go', 4);
+ expect($('.slide3').not('.slide5')).not.toHaveClass(defaults.classes.current);
+ expect($('.slide2').not('.slide4')).not.toHaveClass(defaults.classes.previous);
+ expect($('.slide4').not('.slide6')).not.toHaveClass(defaults.classes.next);
});
});
});
\ No newline at end of file