feat($ionicScrollDelegate): rememberScrollPosition, scrollToRememberedPosition

/**
 * @ngdoc method
 * @name $ionicScrollDelegate#rememberScrollPosition
 * @description
 *
 * When this scroll area is destroyed, its last scroll position will be
 * saved using the given id.
 *
 * @param {string} id The identifier for this saved scroll position.
 */

/**
 * @ngdoc method
 * @name $ionicScrollDelegate#scrollToRememberedPosition
 * @description
 *
 * If a scroll position was remembered using the given id, loads the
 * remembered scroll position and scrolls there.
 *
 * @param {string} id The identifier for this saved scroll position.
 * @param {boolean=} shouldAnimate Whether to animate the scroll.
 */
This commit is contained in:
Andy Joslin
2014-03-17 08:39:23 -06:00
parent cc0a4ef775
commit 5a0efecef6
8 changed files with 159 additions and 98 deletions

View File

@@ -63,6 +63,27 @@ describe('$ionicScroll Controller', function() {
expect(ctrl.scrollView.resize).toHaveBeenCalled();
});
it('should remember scroll position on $viewContentLoaded event', function() {
var historyData = { rememberedScrollValues: { left: 1, top: 2 } };
setup();
spyOn(ctrl.scrollView, 'scrollTo');
scope.$broadcast('$viewContentLoaded', historyData);
timeout.flush();
expect(ctrl.scrollView.scrollTo).toHaveBeenCalledWith(1, 2);
spyOn(ctrl.scrollView, 'getValues').andCallFake(function() {
return {
left: 33,
top: 44
};
});
scope.$broadcast('$destroy');
expect(historyData.rememberedScrollValues).toEqual({
left: 33,
top: 44
});
});
it('should unbind window event listener on scope destroy', function() {
spyOn(window, 'removeEventListener');
spyOn(window, 'addEventListener');

View File

@@ -81,63 +81,6 @@ describe('Ionic Content directive', function() {
expect(vals.top).toBe(300);
});
describe('save scroll', function() {
function compileWithParent() {
var parent = angular.element('<div>');
//Make a phony element that tells the world it's a navView when in reality it's just a div
parent.data('$navViewController', true);
parent.append('<ion-content><br/><div>hello</div><br/></ion-content>');
compile(parent)(scope);
scope.$apply();
/* Mock setting and getting scroll because we don't have time for the dom to load */
var scrollValues = {};
spyOn(scope.scrollView, 'scrollTo').andCallFake(function(left, top, a, zoom) {
scrollValues = {
left: left || 0,
top: top || 0,
zoom: zoom || 1
};
});
spyOn(scope.scrollView, 'getValues').andCallFake(function() {
return scrollValues;
});
}
it('should set x and y with historyData.scrollValues passed in through $viewContentLoaded', function() {
compileWithParent();
var scrollValues = { top: 40, left: -20, zoom: 3 };
scope.$broadcast('$viewContentLoaded', {
scrollValues: scrollValues
});
timeout.flush();
expect(scope.scrollView.scrollTo.mostRecentCall.args).toEqual([-20, 40]);
});
it('should set null with historyData.scrollValues not valid', function() {
compileWithParent();
var scrollValues = { left: 'bar', top: 'foo' };
scope.$broadcast('$viewContentLoaded', { scrollValues: scrollValues });
timeout.flush();
expect(scope.scrollView.scrollTo.mostRecentCall.args).toEqual([null, null]);
});
it('should save scroll on the historyData passed in on $destroy', function() {
compileWithParent();
var historyData = {};
scope.$broadcast('$viewContentLoaded', historyData);
timeout.flush();
scope.scrollView.scrollTo(null, 9, false);
expect(historyData.scrollValues).toBeUndefined(); //sanity test
scope.$destroy();
expect(historyData.scrollValues).toEqual({
left: 0,
top: 9,
zoom: 1
});
});
});
});
/* Tests #555 */
describe('Ionic Content Directive scoping', function() {

View File

@@ -11,6 +11,13 @@ describe('Ionic ScrollDelegate Service', function() {
compile = $compile;
}));
it('should just return rootScope if no scrollCtrl', inject(function($rootScope) {
expect(function() {
$ionicScrollDelegate($rootScope);
}).not.toThrow();
expect($ionicScrollDelegate($rootScope).getScrollView()).toBeFalsy();
}));
it('Should get scroll view', function() {
var scope = rootScope.$new();
var el = compile('<ion-content></ion-content>')(scope);
@@ -137,6 +144,50 @@ describe('Ionic ScrollDelegate Service', function() {
expect(sv.resize).toHaveBeenCalled();
expect(sv.scrollTo.mostRecentCall.args).toEqual([2, 3, animate]);
});
it('should throw error on rememberScroll if no id', function() {
var scope = rootScope.$new();
var el = compile('<ion-content></ion-content>');
var del = $ionicScrollDelegate(scope);
expect(del.rememberScrollPosition).toThrow();
});
it('scrollToRememberedPosition should scroll if exists', function() {
var scope = rootScope.$new();
var el = compile('<ion-content></ion-content>')(scope);
var del = $ionicScrollDelegate(scope);
var sv = del.getScrollView();
scope.$apply();
$ionicScrollDelegate._rememberedScrollValues['1'] = {
left: 3,
top: 4
};
del.scrollToRememberedPosition('1', animate);
spyOn(sv, 'scrollTo');
timeout.flush();
expect(sv.scrollTo).toHaveBeenCalledWith(3, 4, animate);
});
it('should save on destroy for rememberScrollPosition', function() {
var scope = rootScope.$new();
var el = compile('<ion-content></ion-content>')(scope);
var del = $ionicScrollDelegate(scope);
var sv = del.getScrollView();
scope.$apply();
$ionicScrollDelegate._rememberedScrollValues['1'] = {
left: -1,
top: -1
};
del.rememberScrollPosition('1', animate);
spyOn(sv, 'getValues').andCallFake(function() {
return { foo: 'bar' };
});
scope.$destroy();
expect(sv.getValues).toHaveBeenCalled();
expect($ionicScrollDelegate._rememberedScrollValues['1']).toEqual({
foo: 'bar'
});
});
});
}
});

View File

@@ -141,7 +141,7 @@ describe('Ionic View Service', function() {
registerData = viewService.register({});
currentView = viewService.getCurrentView();
//Set test value for remembered scroll
currentView.scrollValues = 'foo';
currentView.rememberedScrollValues = 'foo';
backView = viewService.getBackView();
forwardView = viewService.getForwardView();
expect(backView.stateName).toEqual('about');
@@ -159,7 +159,7 @@ describe('Ionic View Service', function() {
currentView = viewService.getCurrentView();
backView = viewService.getBackView();
forwardView = viewService.getForwardView();
expect(forwardView.scrollValues).toEqual({});
expect(forwardView.rememberedScrollValues).toEqual({});
expect(currentView.stateName).toEqual('about');
expect(currentView.backViewId).toEqual(backView.viewId);
expect(currentView.forwardViewId).toEqual(forwardView.viewId);