refactor(ionSlideBox): use live nodeList to preserve ordering

This commit is contained in:
Andrew
2014-11-05 13:51:56 -07:00
parent debccaeaaa
commit 8b1bef3ea1
13 changed files with 237 additions and 348 deletions

View File

@@ -10,7 +10,12 @@ IonicModule
*/
function(scope, element, $$ionicAttachDrag, $interval) {
var self = this;
var slideList = ionic.Utils.list([]);
// This is a live nodeList that is updated whenever child ion-slides
// are added or removed.
var slideNodes = element[0].getElementsByTagName('ion-slide');
var slideList = ionic.Utils.list(slideNodes);
var slidesParent = angular.element(element[0].querySelector('.slider-slides'));
// Successful slide requires velocity to be greater than this amount
@@ -27,29 +32,37 @@ function(scope, element, $$ionicAttachDrag, $interval) {
self.isRelevant = isRelevant;
self.previous = previous;
self.next = next;
self.onSlidesChanged = ionic.animationFrameThrottle(onSlidesChanged);
// Methods calling straight back to Utils.list
self.at = slideList.at;
self.at = at;
self.count = slideList.count;
self.indexOf = slideList.indexOf;
self.indexOf = indexOf;
self.isInRange = slideList.isInRange;
self.loop = slideList.loop;
self.delta = slideList.delta;
self.update = update;
self.enableSlide = enableSlide;
self.autoPlay = autoPlay;
self.add = add;
self.remove = remove;
self.move = move;
self.selected = selected;
self.select = select;
self.onDragStart = onDragStart;
self.onDrag = onDrag;
self.onDragEnd = onDragEnd;
scope.$watchCollection(function() { return slideNodes; }, self.onSlidesChanged);
// ***
// Public Methods
// ***
function at(index) {
return jqLite( slideList.at(index) ).controller('ionSlide');
}
function indexOf(slide) {
return slide && slideList.indexOf(slide.node) || -1;
}
// Gets whether the given index is relevant to selected
// That is, whether the given index is previous, selected, or next
@@ -74,18 +87,6 @@ function(scope, element, $$ionicAttachDrag, $interval) {
return slideList.next(index);
}
function update() {
var selectedIndex = scope.selectedIndex;
for (var i = self.count() - 1; i >= 0; i--) {
slideList.remove(i);
}
var slideNodes = element[0].querySelectorAll('ion-slide');
for (var j = 0, jj = slideNodes.length; j < jj; j++) {
slideList.add(jqLite(slideNodes[j]).controller('ionSlide'));
}
self.select(selectedIndex);
}
function enableSlide(isEnabled) {
if (arguments.length) {
self.dragDisabled = !isEnabled;
@@ -103,51 +104,6 @@ function(scope, element, $$ionicAttachDrag, $interval) {
}
}
/*
* Add/remove/move slides
*/
function add(slide, index) {
var newIndex = slideList.add(slide, index);
slide.onAdded();
// If we are waiting for a certain scope.selectedIndex and this is it,
// select the slide
if (scope.selectedIndex === index) {
self.select(newIndex);
// If we don't have a selectedIndex yet, select the first one available
} else if (!isNumber(scope.selectedIndex) || scope.selectedIndex === -1) {
self.select(newIndex);
} else if (newIndex === self.previous() || newIndex === self.next()) {
// if the new slide is adjacent to selected, refresh the selection
enqueueRefresh();
}
}
function remove(slide) {
var index = self.indexOf(slide);
if (index === -1) return;
var isSelected = self.selected() === index;
slideList.remove(index);
slide.onRemoved();
if (isSelected) {
self.select( self.isInRange(scope.selectedIndex) ? scope.selectedIndex : scope.selectedIndex - 1 );
}
}
function move(slide, targetIndex) {
var index = self.indexOf(slide);
if (index === -1) return;
// If the slide is current, next, or previous, save so we can re-select after moving.
var isRelevant = self.selected() === index || self.isRelevant(targetIndex);
slideList.remove(index);
slideList.add(slide, targetIndex);
if (isRelevant) {
self.select(targetIndex);
}
}
function selected() {
return self.isInRange(scope.selectedIndex) ? scope.selectedIndex : -1;
}
@@ -187,11 +143,13 @@ function(scope, element, $$ionicAttachDrag, $interval) {
}
}
function onDragStart() {
if (self.dragDisabled) return false;
}
// percent is negative 0-1 for backward slide
// positive 0-1 for forward slide
function onDrag(percent) {
if (self.dragDisabled) return;
var target = self.at(percent > 0 ? self.next() : self.previous());
var current = self.at(self.selected());
@@ -222,6 +180,49 @@ function(scope, element, $$ionicAttachDrag, $interval) {
// Private Methods
// ***
var oldNodes = [];
function onSlidesChanged() {
var newSelected = slideNodes[scope.selectedIndex];
var oldSelected = oldNodes[scope.selectedIndex];
if (!newSelected && !oldSelected) {
if (slideNodes[scope.selectedIndex]) {
// If we don't have a selected slide and are waiting for a certain selectedIndex,
// then select it now.
self.select(scope.selectedIndex);
} else if (slideNodes.length) {
// If we don't have a selectedIndex yet, go ahead and select the first available
self.select(0);
}
} else {
if (newSelected !== oldSelected) {
// If the item at newList[selectedIndex] isn't the same as the item at
// oldList[selectedIndex], that means the selected slide was either moved
// in the list or was removed.
var newIndex = slideList.indexOf(oldSelected);
if (newIndex === -1) {
// If the selected slide was removed, try to select the nearest available slide
self.select(scope.selectedIndex > 0 ? scope.selectedIndex - 1 : scope.selectedIndex);
} else {
// If the selected slide moved, select the selected slide's new index
self.select(newIndex);
}
} else {
// Figure out the next and previous index based upon the old list.
// That way, if the old list had a previous item that's out of range
// in the new list, our check below will catch that the next/previous
// have changed.
var oldNextIndex = ionic.Utils.list.next(oldNodes, slideList.loop(), scope.selectedIndex);
var oldPrevIndex = ionic.Utils.list.previous(oldNodes, slideList.loop(), scope.selectedIndex);
if (slideNodes[self.next()] !== oldNodes[oldNextIndex] ||
slideNodes[self.previous()] !== oldNodes[oldPrevIndex]) {
//If the next or previous slides have changed, just refresh selection of the current slide.
self.select(scope.selectedIndex);
}
}
}
oldNodes = Array.prototype.slice.call(slideNodes);
}
var oldSlides;
function arrangeSlides(newShownIndex) {
var newSlides = {
@@ -265,18 +266,4 @@ function(scope, element, $$ionicAttachDrag, $interval) {
oldSlides = newSlides;
}
// When adding/moving slides, we sometimes need to refresh
// the currently selected slides to reflect new data.
// We don't want to refresh more than once per digest cycle,
// so we do this.
function enqueueRefresh() {
if (!enqueueRefresh.queued) {
enqueueRefresh.queued = true;
scope.$$postDigest(function() {
self.select(scope.selectedIndex);
enqueueRefresh.queued = false;
});
}
}
}]);

View File

@@ -6,34 +6,22 @@ IonicModule
function(scope, element, $q) {
var self = this;
scope.$on('$destroy', function() {
// Re-attach the element so it can be properly removed
attachSlide();
});
element.on(ionic.CSS.TRANSITIONEND, onTransitionEnd);
self.element = element;
self.onAdded = onAdded;
self.onRemoved = onRemoved;
self.node = element[0];
self.transform = transform;
self.state = '';
self.setState = setState;
self.setState('detached');
// ***
// Public Methods
// ***
function onAdded() {
// Set default state
self.setState('detached');
}
function onRemoved() {
self.setState('detached');
}
var isTransforming;
// percent is negative 0-1 for dragging left
// percent is positive 0-1 for dragging right
@@ -83,20 +71,10 @@ function(scope, element, $q) {
// ***
function attachSlide() {
// if (!self.element[0].parentNode) {
// self.parentElement.append(self.element);
// ionic.Utils.reconnectScope(scope);
// }
ionic.Utils.reconnectScope(scope);
}
function detachSlide() {
// Don't use self.element.remove(), that will destroy the element's data
// var parent = self.element[0].parentNode;
// if (parent) {
// parent.removeChild(self.element[0]);
// ionic.Utils.disconnectScope(scope);
// }
ionic.Utils.disconnectScope(scope);
}

View File

@@ -18,25 +18,21 @@
* ```
*/
IonicModule
.directive('ionSlide', [function() {
.directive('ionSlide', ['$timeout', function($timeout) {
return {
restrict: 'E',
controller: '$ionSlide',
require: '^ionSlideBox',
scope: true,
require: ['^ionSlideBox', 'ionSlide'],
link: postLink
};
function postLink(scope, element, attr, ctrls) {
var slideBoxCtrl = ctrls[0];
var slideCtrl = ctrls[1];
function postLink(scope, element, attr, slideBoxCtrl) {
element.addClass('slider-slide');
slideBoxCtrl.add(slideCtrl);
$timeout(angular.noop);
element.on('$destroy', function() {
slideBoxCtrl.remove(slideCtrl);
$timeout(angular.noop);
});
}
}]);

View File

@@ -63,7 +63,6 @@ function($ionicSlideBoxDelegate, $window) {
element.addClass('slider');
var deregister = $ionicSlideBoxDelegate._registerInstance(slideBoxCtrl, attr.delegateHandle);
scope.$on('$destroy', deregister);
watchSelected();
isDefined(attr.loop) && watchLoop();
@@ -74,6 +73,7 @@ function($ionicSlideBoxDelegate, $window) {
angular.element($window).on('resize', throttledReposition);
scope.$on('$destroy', function() {
deregister();
angular.element($window).off('resize', throttledReposition);
});

View File

@@ -32,12 +32,13 @@ IonicModule
var dragState;
function handleDragStart(ev) {
if (dragState) return;
dragState = {
startX: ev.gesture.center.pageX,
startY: ev.gesture.center.pageY,
distance: opts.getDistance()
};
opts.onDragStart();
if (opts.onDragStart() !== false) {
dragState = {
startX: ev.gesture.center.pageX,
startY: ev.gesture.center.pageY,
distance: opts.getDistance()
};
}
}
function handleDrag(ev) {
if (!dragState) return;

View File

@@ -89,16 +89,6 @@ IonicModule
* @returns `number` The number of slides there are currently.
*/
'count',
/**
* @ngdoc method
* @name $ionicSlideBoxDelegate#update
* @description Causes the slidebox to re-scan all of the child slide
* elements and reorganize itself again. This will rarely be needed.
* You only need to call update if you are moving slides around in the DOM
* (for example, ng-repeat moving an element from the middle to the end of
* the list).
*/
'update',
/**
* @ngdoc method
* @name $ionicSlideBoxDelegate#$getByHandle

View File

@@ -2,29 +2,97 @@
function trueFn() { return true; }
ionic.Utils.list = list;
ionic.Utils.list = wrapList;
function list(initialArray) {
// Expose previous and next publicly so we can use them
// without having to instantiate a whole list wrapper.
ionic.Utils.list.next = listNext;
ionic.Utils.list.previous = listPrevious;
var array = angular.isArray(initialArray) ? initialArray : [];
// Get the index after the given index.
// Takes looping and the given filterFn into account.
function listNext(list, isLooping, index, filterFn) {
filterFn = filterFn || trueFn;
if (index < 0 || index >= list.length) return -1;
// Keep adding 1 to index, trying to find an index that passes filterFn.
// If we loop through *everything* and get back to our original index, return -1.
// We don't use recursion here because Javascript sucks at recursion.
var nextIndex = index + 1;
while ( nextIndex !== index ) {
if (nextIndex === list.length) {
if (isLooping) nextIndex -= list.length;
else break;
} else {
if (filterFn(list[nextIndex], nextIndex)) {
return nextIndex;
}
nextIndex++;
}
}
return -1;
}
// Get the index before the given index.
// Takes looping and the given filterFn into account.
function listPrevious(list, isLooping, index, filterFn) {
filterFn = filterFn || trueFn;
if (index < 0 || index >= list.length) return -1;
// Keep subtracting 1 from index, trying to find an index that passes filterFn.
// If we loop through *everything* and get back to our original index, return -1.
// We don't use recursion here because Javascript sucks at recursion.
var prevIndex = index - 1;
while ( prevIndex !== index ) {
if (prevIndex === -1) {
if (isLooping) prevIndex += list.length;
else break;
} else {
if (filterFn(list[prevIndex], prevIndex)) {
return prevIndex;
}
prevIndex--;
}
}
return -1;
}
// initialList may be a nodeList or an list,
// so we don't expect it to have any list methods
function wrapList(initialList) {
var list = initialList || [];
var self = {};
var isLooping = false;
// The Basics
self.items = items;
self.add = add;
self.remove = remove;
// add and remove are array-ONLY, if we're given a nodeList
// it's immutable
if (angular.isArray(list)) {
self.add = add;
self.remove = remove;
}
self.at = at;
self.count = count;
self.indexOf = angular.bind(array, array.indexOf);
self.indexOf = indexOf;
self.isInRange = isInRange;
self.loop = loop;
// The Crazy Ones
self.delta = delta;
self.isRelevant = isRelevant;
self.previous = previous;
self.next = next;
self.previous = function(index, filterFn) {
return listPrevious(list, isLooping, index, filterFn);
};
self.next = function(index, filterFn) {
return listNext(list, isLooping, index, filterFn);
};
return self;
@@ -32,29 +100,37 @@ function list(initialArray) {
// Public methods
// ***************
function items() {
return array;
return list;
}
function add(item, index) {
if (!self.isInRange(index)) index = array.length;
array.splice(index, 0, item);
if (!self.isInRange(index)) index = list.length;
list.splice(index, 0, item);
return index;
}
function remove(index) {
if (!self.isInRange(index)) return;
array.splice(index, 1);
list.splice(index, 1);
}
function at(index) {
return array[index];
return list[index];
}
function count() {
return array.length;
return list.length;
}
function indexOf(item) {
for (var i = 0, ii = list.length; i < ii; i++) {
if (list[i] === item) return i;
}
return -1;
}
function isInRange(index) {
return index > -1 && index < array.length;
return index > -1 && index < list.length;
}
function loop(newIsLooping) {
@@ -95,56 +171,6 @@ function list(initialArray) {
);
}
// Get the index after the given index.
// Takes looping and the given filterFn into account.
function next(index, filterFn) {
filterFn = filterFn || trueFn;
if (!self.isInRange(index)) return -1;
// Keep adding 1 to index, trying to find an index that passes filterFn.
// If we loop through *everything* and get back to our original index, return -1.
// We don't use recursion here because Javascript sucks at recursion.
var nextIndex = index + 1;
while ( nextIndex !== index ) {
if (nextIndex === array.length) {
if (isLooping) nextIndex -= array.length;
else break;
} else {
if (filterFn(array[nextIndex], nextIndex)) {
return nextIndex;
}
nextIndex++;
}
}
return -1;
}
// Get the index before the given index.
// Takes looping and the given filterFn into account.
function previous(index, filterFn) {
filterFn = filterFn || trueFn;
if (!self.isInRange(index)) return -1;
// Keep subtracting 1 from index, trying to find an index that passes filterFn.
// If we loop through *everything* and get back to our original index, return -1.
// We don't use recursion here because Javascript sucks at recursion.
var prevIndex = index - 1;
while ( prevIndex !== index ) {
if (prevIndex === -1) {
if (isLooping) prevIndex += array.length;
else break;
} else {
if (filterFn(array[prevIndex], prevIndex)) {
return prevIndex;
}
prevIndex--;
}
}
return -1;
}
}
})();

View File

@@ -41,49 +41,31 @@
}
</style>
</head>
<body ng-init="$root.selectedIndex = 0">
<body ng-init="$root.selectedIndex = 4">
<div ng-controller="SlideCtrl" ng-init="$root.hasBox = true">
<ion-header-bar class="bar-positive">
<button class="button" ng-click="$root.items.shift()">
shift
</button>
<button class="button" ng-click="$root.items.unshift($root.random())">
unshift
</button>
<h1 class="title">Hi</h1>
<div class="right-buttons">
<button class="button" ng-click="$root.items.pop()">
pop
</button>
<button class="button" ng-click="$root.items.push($root.random())">
push
</button>
</div>
</ion-header-bar>
<ion-content>
<ion-slide-box selected="$root.selectedIndex" loop="true" ng-if="$root.hasBox">
<ion-slide ng-controller="FirstSlideCtrl">
<h3>Thank you for choosing the Awesome App!</h3>
<div id="logo">
<img src="app_icon.png">
</div>
<p>
We've worked super hard to make you happy.
</p>
<p>
But if you are angry, too bad.
</p>
<p>
<button class="button button-dark" ng-click="toLast()">Skip to last</button>
</p>
<p>
<button class="button button-dark" ng-click="clickTest()">Click Test</button>
</p>
</ion-slide>
<ion-slide>
<h3>Using Awesome</h3>
<div id="list">
<h5>Just three steps:</h5>
<ol>
<li>Be awesome</li>
<li>Stay awesome</li>
<li>There is no step 3</li>
</ol>
</div>
</ion-slide>
<ion-slide>
<ion-content class="has-header">
<div style="width: 300px; height: 2000px; background: url('tree_bark.png') repeat"></div>
</ion-content>
</ion-slide>
<ion-slide ng-repeat="i in items">
<h3>item {{i}}</h3>
<img ng-src="http://placekitten.com/{{200 + (i%50)}}/{{200 + (i%50)}}">
<h3>item {{$index}} / {{items.length - 1}}</h3>
<img ng-src="http://placekitten.com/{{200 + (i%50)}}/{{200 + (i%50)}}">
</ion-slide>
</ion-slide-box>
@@ -93,13 +75,15 @@
angular.module('slideBoxTest', ['ionic'])
.controller('SlideCtrl', function($scope, $timeout) {
$scope.items = [];
$scope.items = $scope.$root.items = [];
for (var i = 0; i < 10; i++) {
$scope.items.push(i);
}
$scope.$root.random = Math.random.bind(Math);
setTimeout(function() {
window.box = angular.element(document.querySelector('ion-slide-box')).controller('ionSlideBox');
window.els = document.querySelector('ion-slide-box').getElementsByTagName('ion-slide');
});
})

View File

@@ -1,14 +1,23 @@
describe('$ionSlideBox controller', function() {
beforeEach(module('ionic'));
beforeEach(function() {
ionic.animationFrameThrottle = function(cb) {
return function() {
cb.apply(this, arguments);
};
};
});
function mockSlide() {
return {
onAdded: jasmine.createSpy('onAdded'),
onRemoved: jasmine.createSpy('onRemoved'),
function mockSlide(slideBoxCtrl) {
var slideCtrl = {
setState: jasmine.createSpy('setState'),
transform: jasmine.createSpy('transform')
};
var slide = angular.element('<ion-slide>');
slide.data('$ionSlideController', slideCtrl);
slideBoxCtrl.element.append(slide);
return slideCtrl;
}
function makeCtrl(locals) {
var ctrl;
@@ -21,62 +30,11 @@ describe('$ionSlideBox controller', function() {
return ctrl;
}
it('#add()', inject(function($rootScope, $timeout) {
var ctrl = makeCtrl();
var slide1 = mockSlide();
var slide2 = mockSlide();
expect(ctrl.selected()).toBe(-1);
ctrl.add(slide1);
expect(ctrl.selected()).toBe(0);
expect(ctrl.count()).toBe(1);
$timeout.flush();
expect(slide1.setState).toHaveBeenCalledWith('selected');
ctrl.add(slide2);
$rootScope.$apply();
expect(ctrl.selected()).toBe(0);
expect(ctrl.count()).toBe(2);
$timeout.flush();
expect(slide2.setState).toHaveBeenCalledWith('next');
}));
it('#remove()', function() {
var ctrl = makeCtrl();
var slide0, slide1, slide2;
ctrl.add(slide0 = mockSlide());
ctrl.add(slide1 = mockSlide());
ctrl.add(slide2 = mockSlide());
ctrl.select(1);
expect(ctrl.selected()).toBe(1);
ctrl.remove(slide1);
expect(ctrl.selected()).toBe(1);
expect(ctrl.at(1)).toBe(slide2);
ctrl.remove(slide2);
expect(ctrl.selected()).toBe(0);
});
it('#move()', function() {
var ctrl = makeCtrl();
var slide0, slide1;
ctrl.add(slide0 = mockSlide());
ctrl.add(slide1 = mockSlide());
expect(ctrl.at(1)).toBe(slide1);
ctrl.move(slide1, 0);
expect(ctrl.at(0)).toBe(slide1);
expect(ctrl.at(1)).toBe(slide0);
});
it('#onDrag()', function() {
var ctrl = makeCtrl();
var slide0, slide1, slide2;
ctrl.add(slide0 = mockSlide());
ctrl.add(slide1 = mockSlide());
ctrl.add(slide2 = mockSlide());
var slide0 = mockSlide(ctrl);
var slide1 = mockSlide(ctrl);
var slide2 = mockSlide(ctrl);
ctrl.select(1);
// Transforming forward should move current and next
@@ -98,10 +56,9 @@ describe('$ionSlideBox controller', function() {
it('#onDragEnd()', function() {
var ctrl = makeCtrl();
var slide0, slide1, slide2;
ctrl.add(slide0 = mockSlide());
ctrl.add(slide1 = mockSlide());
ctrl.add(slide2 = mockSlide());
var slide0 = mockSlide(ctrl);
var slide1 = mockSlide(ctrl);
var slide2 = mockSlide(ctrl);
ctrl.select(1);
// Greater than 0.5 should change slide
@@ -116,11 +73,9 @@ describe('$ionSlideBox controller', function() {
it('#isRelevant()', function() {
var ctrl = makeCtrl();
ctrl.add(mockSlide());
ctrl.add(mockSlide());
ctrl.add(mockSlide());
ctrl.add(mockSlide());
ctrl.add(mockSlide());
for (var i = 0; i < 5; i++) {
mockSlide(ctrl);
}
ctrl.loop(false);
ctrl.select(0);
@@ -139,9 +94,9 @@ describe('$ionSlideBox controller', function() {
it('#previous()', function() {
var ctrl = makeCtrl();
ctrl.add(mockSlide());
ctrl.add(mockSlide());
ctrl.add(mockSlide());
for (var i = 0; i < 3; i++) {
mockSlide(ctrl);
}
ctrl.loop(false);
ctrl.select(0);
@@ -158,9 +113,9 @@ describe('$ionSlideBox controller', function() {
it('#next()', function() {
var ctrl = makeCtrl();
ctrl.add(mockSlide());
ctrl.add(mockSlide());
ctrl.add(mockSlide());
for (var i = 0; i < 3; i++) {
mockSlide(ctrl);
}
ctrl.loop(false);
ctrl.select(2);

View File

@@ -12,23 +12,8 @@ describe('$ionSlide controller', function() {
return ctrl;
}
it('#onAdded()', function() {
var ctrl = makeCtrl();
expect(ctrl.state).toBeFalsy();
ctrl.onAdded(parent);
expect(ctrl.state).toBe('detached');
});
it('#onRemoved()', function() {
var ctrl = makeCtrl();
expect(ctrl.state).toBeFalsy();
ctrl.onRemoved();
expect(ctrl.state).toBe('detached');
});
it('#setState()', function() {
var ctrl = makeCtrl();
ctrl.onAdded();
ctrl.setState('selected');
expect(ctrl.element.attr('slide-state')).toBe('selected');

View File

@@ -1,7 +1,7 @@
describe('ionSlide directive', function() {
beforeEach(module('ionic'));
it('should add and remove itself from parent ctrl', inject(function($compile, $rootScope) {
it('should add and remove itself from parent ctrl', inject(function($compile, $rootScope, $timeout) {
var parent = $compile('<ion-scroll><ion-slide-box>' +
'<ion-slide>Hello</ion-slide>' +
'</ion-slide-box></ion-scroll>')($rootScope.$new());
@@ -15,7 +15,8 @@ describe('ionSlide directive', function() {
expect(slideBoxCtrl.count()).toBe(1);
expect(slideBoxCtrl.at(0)).toBe(slideCtrl);
slide.triggerHandler('$destroy');
slide.remove();
$timeout.flush();
expect(slideBoxCtrl.count()).toBe(0);
}));

View File

@@ -41,25 +41,6 @@ describe('ionSlideBox directive', function() {
expect(slideBoxCtrl.selected()).toBe(-1);
}));
it('should bind to selected attr to slide', inject(function($rootScope, $timeout) {
$rootScope.currentIndex = 2;
var slideBox = makeSlideBox('<ion-slide-box selected="$root.currentIndex">' +
'<ion-slide>A</ion-slide>' +
'<ion-slide>B</ion-slide>' +
'<ion-slide>C</ion-slide>' +
'</ion-slide-box>');
var slideBoxCtrl = slideBox.controller('ionSlideBox');
expect(slideBoxCtrl.selected()).toBe(2);
expect($rootScope.currentIndex).toBe(2);
$timeout.flush();
slideBoxCtrl.select(1);
$timeout.flush();
expect($rootScope.currentIndex).toBe(1);
}));
it('should loop depending on attr.loop', inject(function($rootScope) {
var slideBox = makeSlideBox('<ion-slide-box loop="shouldLoop">' +
'<ion-slide>A</ion-slide>' +

View File

@@ -1,5 +1,10 @@
describe('<ion-slide-pager> directive', function() {
beforeEach(module('ionic'));
beforeEach(function() {
ionic.animationFrameThrottle = function(cb) {
return function() { cb.apply(this, arguments); };
};
});
it('should create pager elements', inject(function($compile, $rootScope, $timeout) {
var el = $compile('<ion-slide-box>' +
@@ -19,7 +24,7 @@ describe('<ion-slide-pager> directive', function() {
$rootScope.$apply('showThird = false');
$timeout.flush();
expect(pager.find('.slider-pager-page').length).toBe(2);
}));
it('should by default select on click', inject(function($compile, $rootScope, $timeout) {
@@ -39,7 +44,7 @@ describe('<ion-slide-pager> directive', function() {
pagers.eq(2).click();
expect(slideBoxCtrl.selected()).toBe(2);
}));
it('should allow custom click action which overrides default', inject(function($compile, $rootScope, $timeout) {
@@ -62,7 +67,7 @@ describe('<ion-slide-pager> directive', function() {
pagers.eq(2).click();
expect(slideBoxCtrl.selected()).toBe(0);
expect($rootScope.click).toHaveBeenCalledWith(2);
}));
});