From 36691bbaebf51ae5252e5673d3392e3e6c724eb9 Mon Sep 17 00:00:00 2001 From: Andy Joslin Date: Tue, 11 Feb 2014 09:16:29 -0500 Subject: [PATCH] feat($ionicScrollDelegate): allow anchorScroll to animate with param Addresses #508 --- .../service/delegates/ionicScrollDelegate.js | 10 +- .../delegates/ionicScrollDelegate.unit.js | 109 ++++++++---------- 2 files changed, 55 insertions(+), 64 deletions(-) diff --git a/js/ext/angular/src/service/delegates/ionicScrollDelegate.js b/js/ext/angular/src/service/delegates/ionicScrollDelegate.js index 51c5dbb0c0e..d43555217bd 100644 --- a/js/ext/angular/src/service/delegates/ionicScrollDelegate.js +++ b/js/ext/angular/src/service/delegates/ionicScrollDelegate.js @@ -17,8 +17,8 @@ angular.module('ionic.ui.service.scrollDelegate', []) resize: function() { $rootScope.$broadcast('scroll.resize'); }, - anchorScroll: function() { - $rootScope.$broadcast('scroll.anchorScroll'); + anchorScroll: function(animate) { + $rootScope.$broadcast('scroll.anchorScroll', animate); }, tapScrollToTop: function(element) { var _this = this; @@ -80,14 +80,14 @@ angular.module('ionic.ui.service.scrollDelegate', []) scrollView.finishPullToRefresh(); }); - $scope.$parent.$on('scroll.anchorScroll', function() { + $scope.$parent.$on('scroll.anchorScroll', function(e, animate) { var hash = $location.hash(); var elm; if (hash && (elm = document.getElementById(hash)) ) { var scroll = ionic.DomUtil.getPositionInParent(elm, scrollEl); - scrollView.scrollTo(scroll.left, scroll.top); + scrollView.scrollTo(scroll.left, scroll.top, !!animate); } else { - scrollView.scrollTo(0,0); + scrollView.scrollTo(0,0, !!animate); } }); diff --git a/js/ext/angular/test/service/delegates/ionicScrollDelegate.unit.js b/js/ext/angular/test/service/delegates/ionicScrollDelegate.unit.js index c65b119bc9f..397264a2365 100644 --- a/js/ext/angular/test/service/delegates/ionicScrollDelegate.unit.js +++ b/js/ext/angular/test/service/delegates/ionicScrollDelegate.unit.js @@ -92,66 +92,57 @@ describe('anchorScroll', function() { beforeEach(module('ionic')); - var contentEl, scope, del; - beforeEach(inject(function($rootScope, $compile, $timeout, $document, $ionicScrollDelegate) { - scope = $rootScope.$new(); - contentEl = $compile('')(scope); - - document.body.appendChild(contentEl[0]); - del = $ionicScrollDelegate; - })); - - it('should anchorScroll to an element with id', function() { - var anchorMe = angular.element('
'); - var sv = del.getScrollView(scope); - spyOn(sv, 'scrollTo'); - - setLocationHash('anchorMe'); - contentEl.append(anchorMe); - - var pos = ionic.DomUtil.getPositionInParent(anchorMe[0], contentEl[0]); - del.anchorScroll(); - expect(sv.scrollTo).toHaveBeenCalledWith(pos.left, pos.top); - }); - - it('should anchorScroll to top if !$location.hash()', function() { - var sv = del.getScrollView(scope); - spyOn(sv, 'scrollTo'); - del.anchorScroll(); - expect(sv.scrollTo).toHaveBeenCalledWith(0, 0); - }); - - it('should anchorScroll to top if element with hash id doesnt exist', function() { - var sv = del.getScrollView(scope); - spyOn(sv, 'scrollTo'); - - setLocationHash('doesnotexist'); - del.anchorScroll(); - - expect(sv.scrollTo).toHaveBeenCalledWith(0, 0); - }); - - it('should anchorScroll to first element with id if multiple exist', function() { - var foo1 = angular.element('
hello
'); - var foo2 = angular.element('
hola
'); - var sv = del.getScrollView(scope); - - contentEl.append(foo1).append(foo2); - - //Fake the top/left because dom doesn't have time to load in a test - spyOn(ionic.DomUtil, 'getPositionInParent').andCallFake(function(el) { - return el === foo1[0] ? {left: 20, top: 40} : {left: 30, top: 50}; + testWithAnimate(true); + testWithAnimate(false); + + function testWithAnimate(animate) { + describe('with animate=' + animate, function() { + var contentEl, scope, del; + beforeEach(inject(function($rootScope, $compile, $timeout, $document, $ionicScrollDelegate) { + scope = $rootScope.$new(); + contentEl = $compile('')(scope); + + document.body.appendChild(contentEl[0]); + del = $ionicScrollDelegate; + })); + + it('should anchorScroll to an element with id', function() { + var anchorMe = angular.element('
'); + var sv = del.getScrollView(scope); + spyOn(sv, 'scrollTo'); + spyOn(ionic.DomUtil, 'getPositionInParent').andCallFake(function() { + return { left: 2, top: 1 }; + }); + + setLocationHash('anchorMe'); + contentEl.append(anchorMe); + + del.anchorScroll(animate); + expect(sv.scrollTo).toHaveBeenCalledWith(2, 1, animate); + }); + + it('should anchorScroll to top if !$location.hash()', function() { + var sv = del.getScrollView(scope); + spyOn(sv, 'scrollTo'); + spyOn(ionic.DomUtil, 'getPositionInParent'); + del.anchorScroll(animate); + expect(sv.scrollTo).toHaveBeenCalledWith(0, 0, animate); + expect(ionic.DomUtil.getPositionInParent).not.toHaveBeenCalled(); + }); + + it('should anchorScroll to top if element with hash id doesnt exist', function() { + var sv = del.getScrollView(scope); + spyOn(sv, 'scrollTo'); + spyOn(ionic.DomUtil, 'getPositionInParent'); + + setLocationHash('doesnotexist'); + del.anchorScroll(animate); + + expect(sv.scrollTo).toHaveBeenCalledWith(0, 0, animate); + expect(ionic.DomUtil.getPositionInParent).not.toHaveBeenCalled(); + }); }); - var pos1 = ionic.DomUtil.getPositionInParent(foo1[0], contentEl[0]); - var pos2 = ionic.DomUtil.getPositionInParent(foo2[0], contentEl[0]); - - spyOn(sv, 'scrollTo'); - setLocationHash('foo'); - del.anchorScroll(); - expect(sv.scrollTo.callCount).toBe(1); - expect(sv.scrollTo).toHaveBeenCalledWith(pos1.left, pos1.top); - expect(sv.scrollTo).not.toHaveBeenCalledWith(pos2.left, pos2.top); - }); + } });