From 8b1bef3ea195a95a1f1bdf6f86d71f81871825bf Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 5 Nov 2014 13:51:56 -0700 Subject: [PATCH] refactor(ionSlideBox): use live nodeList to preserve ordering --- js/angular/controller/slideBoxController.js | 147 ++++++++--------- js/angular/controller/slideController.js | 28 +--- js/angular/directive/slide.js | 14 +- js/angular/directive/slideBox.js | 2 +- js/angular/service/attachDrag.js | 13 +- js/angular/service/slideBoxDelegate.js | 10 -- js/utils/list.js | 156 ++++++++++-------- test/html/slideBox.html | 64 +++---- .../controller/slideBoxController.unit.js | 101 ++++-------- .../controller/slideController.unit.js | 15 -- test/unit/angular/directive/slide.unit.js | 5 +- test/unit/angular/directive/slideBox.unit.js | 19 --- .../unit/angular/directive/slidePager.unit.js | 11 +- 13 files changed, 237 insertions(+), 348 deletions(-) diff --git a/js/angular/controller/slideBoxController.js b/js/angular/controller/slideBoxController.js index 187a55f0ea..26e2342558 100644 --- a/js/angular/controller/slideBoxController.js +++ b/js/angular/controller/slideBoxController.js @@ -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; - }); - } - } }]); diff --git a/js/angular/controller/slideController.js b/js/angular/controller/slideController.js index 8754c27d5a..d7930c840d 100644 --- a/js/angular/controller/slideController.js +++ b/js/angular/controller/slideController.js @@ -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); } diff --git a/js/angular/directive/slide.js b/js/angular/directive/slide.js index 61e34a8144..f1fc620029 100644 --- a/js/angular/directive/slide.js +++ b/js/angular/directive/slide.js @@ -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); }); - } }]); diff --git a/js/angular/directive/slideBox.js b/js/angular/directive/slideBox.js index 7e014bfee4..00561a5f29 100644 --- a/js/angular/directive/slideBox.js +++ b/js/angular/directive/slideBox.js @@ -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); }); diff --git a/js/angular/service/attachDrag.js b/js/angular/service/attachDrag.js index 8de1853697..187c91d296 100644 --- a/js/angular/service/attachDrag.js +++ b/js/angular/service/attachDrag.js @@ -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; diff --git a/js/angular/service/slideBoxDelegate.js b/js/angular/service/slideBoxDelegate.js index 5869f33942..1878c77a80 100644 --- a/js/angular/service/slideBoxDelegate.js +++ b/js/angular/service/slideBoxDelegate.js @@ -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 diff --git a/js/utils/list.js b/js/utils/list.js index 47091037ec..9a5e907463 100644 --- a/js/utils/list.js +++ b/js/utils/list.js @@ -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; - } - } })(); diff --git a/test/html/slideBox.html b/test/html/slideBox.html index 784e8d661e..0f6a383b66 100644 --- a/test/html/slideBox.html +++ b/test/html/slideBox.html @@ -41,49 +41,31 @@ } - +
+ + + +

Hi

+
+ + +
+
- -

Thank you for choosing the Awesome App!

- -

- We've worked super hard to make you happy. -

-

- But if you are angry, too bad. -

-

- -

-

- -

-
- -

Using Awesome

- -
-
Just three steps:
-
    -
  1. Be awesome
  2. -
  3. Stay awesome
  4. -
  5. There is no step 3
  6. -
-
-
- - -
-
-
-

item {{i}}

- +

item {{$index}} / {{items.length - 1}}

+
@@ -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'); }); }) diff --git a/test/unit/angular/controller/slideBoxController.unit.js b/test/unit/angular/controller/slideBoxController.unit.js index ee4c613566..4c64a4b986 100644 --- a/test/unit/angular/controller/slideBoxController.unit.js +++ b/test/unit/angular/controller/slideBoxController.unit.js @@ -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(''); + 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); diff --git a/test/unit/angular/controller/slideController.unit.js b/test/unit/angular/controller/slideController.unit.js index 0aa6e0d6ed..66dee8ecdb 100644 --- a/test/unit/angular/controller/slideController.unit.js +++ b/test/unit/angular/controller/slideController.unit.js @@ -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'); diff --git a/test/unit/angular/directive/slide.unit.js b/test/unit/angular/directive/slide.unit.js index a768f17649..f8a74b7275 100644 --- a/test/unit/angular/directive/slide.unit.js +++ b/test/unit/angular/directive/slide.unit.js @@ -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('' + 'Hello' + '')($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); })); diff --git a/test/unit/angular/directive/slideBox.unit.js b/test/unit/angular/directive/slideBox.unit.js index 7b73c7711e..244093ec0a 100644 --- a/test/unit/angular/directive/slideBox.unit.js +++ b/test/unit/angular/directive/slideBox.unit.js @@ -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('' + - 'A' + - 'B' + - 'C' + - ''); - - 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('' + 'A' + diff --git a/test/unit/angular/directive/slidePager.unit.js b/test/unit/angular/directive/slidePager.unit.js index 372cf783e5..7dcde0038b 100644 --- a/test/unit/angular/directive/slidePager.unit.js +++ b/test/unit/angular/directive/slidePager.unit.js @@ -1,5 +1,10 @@ describe(' 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('' + @@ -19,7 +24,7 @@ describe(' 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(' 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(' directive', function() { pagers.eq(2).click(); expect(slideBoxCtrl.selected()).toBe(0); expect($rootScope.click).toHaveBeenCalledWith(2); - + })); });