Skip to content

Commit

Permalink
fix(history): tabs lose history after switching tabs
Browse files Browse the repository at this point in the history
It was possible that when switching between tabs, and creating a
navigation history in one of the tabs, then switching tabs again, it
could clear out the individual tab stacks under certain scenarios.
Closes #1978
  • Loading branch information
adamdbradley committed Sep 16, 2014
1 parent 1c62ed7 commit 68de8ed
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 4 deletions.
16 changes: 13 additions & 3 deletions js/angular/service/viewService.js
Expand Up @@ -210,9 +210,18 @@ function($rootScope, $state, $location, $window, $injector, $animate, $ionicNavV
hist.cursor > -1 && hist.stack.length > 0 && hist.cursor < hist.stack.length &&
hist.stack[hist.cursor].stateId === currentStateId) {
// they just changed to a different history and the history already has views in it
rsp.viewId = hist.stack[hist.cursor].viewId;
var switchToView = hist.stack[hist.cursor];
rsp.viewId = switchToView.viewId;
rsp.navAction = 'moveBack';

// if switching to a different history, and the history of the view we're switching
// to has an existing back view from a different history than itself, then
// it's back view would be better represented using the current view as its back view
var switchToViewBackView = this._getViewById(switchToView.backViewId);
if(switchToViewBackView && switchToView.historyId !== switchToViewBackView.historyId) {
hist.stack[hist.cursor].backViewId = currentView.viewId;
}

} else {

// set a new unique viewId
Expand All @@ -228,8 +237,9 @@ function($rootScope, $state, $location, $window, $injector, $animate, $ionicNavV
}
rsp.navAction = 'newView';

// check if there is a new forward view
if(forwardView && currentView.stateId !== forwardView.stateId) {
// check if there is a new forward view within the same history
if(forwardView && currentView.stateId !== forwardView.stateId &&
currentView.historyId === forwardView.historyId) {
// they navigated to a new view but the stack already has a forward view
// since its a new view remove any forwards that existed
var forwardsHistory = this._getHistoryById(forwardView.historyId);
Expand Down
73 changes: 72 additions & 1 deletion test/unit/angular/service/viewService.unit.js
Expand Up @@ -586,6 +586,7 @@ describe('Ionic View Service', function() {
rootScope.$apply();
expect(viewService.getCurrentStateName()).toEqual('tabs.tab1view1');
registerData = viewService.register(tab1view1Scope);
var tab1view1ViewId = registerData.viewId;
expect(registerData.navAction).toEqual('moveBack');
expect(registerData.navDirection).toEqual(null);

Expand Down Expand Up @@ -613,6 +614,7 @@ describe('Ionic View Service', function() {
expect(rootScope.$viewHistory.histories[tab1Scope.$historyId].cursor).toEqual(1);
expect(registerData.navAction).toEqual('newView');
expect(registerData.navDirection).toEqual('forward');
expect(rootScope.$viewHistory.views[tab1view2ViewId].backViewId).toEqual(tab1view1ViewId);

// go to view 1 in tab 2
tab2view1Scope = { $parent: tab2Scope };
Expand All @@ -621,7 +623,7 @@ describe('Ionic View Service', function() {
registerData = viewService.register(tab2view1Scope);
expect(viewService.getCurrentStateName()).toEqual('tabs.tab2view1');
expect(rootScope.$viewHistory.histories[tab2Scope.$historyId].cursor).toEqual(0);
expect(registerData.navAction).toEqual('newView');
expect(registerData.navAction).toEqual('moveBack');
expect(registerData.navDirection).toEqual(null);
currentView = viewService.getCurrentView();
expect(currentView.backViewId).toEqual(tab1view2ViewId);
Expand Down Expand Up @@ -688,6 +690,75 @@ describe('Ionic View Service', function() {
expect(currentView.viewId).toEqual(currentViewId);
}));

it('should go one level in tab1, visit tab2, go to tab2 page2, visit, tab1, tab3, history still page 2 tab2', inject(function($location, $state) {
var tab1Container = {};
var tab2Container = {};
var tab3Container = {};
viewService.registerHistory(tab1Container);
viewService.registerHistory(tab2Container);
viewService.registerHistory(tab3Container);

// register tab1, view1
$state.go('tabs.tab1view1');
rootScope.$apply();
var tab1view1Reg = viewService.register(tab1Container);
expect(tab1view1Reg.navAction).toEqual('initialView');
expect(rootScope.$viewHistory.histories[tab1Container.$historyId].cursor).toEqual(0);

// register tab2, view1
$state.go('tabs.tab2view1');
rootScope.$apply();
var tab2view1Reg = viewService.register(tab2Container);
expect(tab2view1Reg.navAction).toEqual('newView');
expect(rootScope.$viewHistory.histories[tab1Container.$historyId].stack[0].forwardViewId).toEqual(tab2view1Reg.viewId);
expect(rootScope.$viewHistory.histories[tab2Container.$historyId].cursor).toEqual(0);

// register tab2, view2
$state.go('tabs.tab2view2');
rootScope.$apply();
var tab2view2Reg = viewService.register(tab2Container);
expect(tab2view2Reg.navAction).toEqual('newView');
expect(rootScope.$viewHistory.histories[tab2Container.$historyId].cursor).toEqual(1);
expect(rootScope.$viewHistory.histories[tab2Container.$historyId].stack.length).toEqual(2);

// register tab1, view1
$state.go('tabs.tab1view1');
rootScope.$apply();
tab1view1Reg = viewService.register(tab1Container);
expect(tab1view1Reg.navAction).toEqual('moveBack');
expect(tab1view1Reg.navDirection).toEqual(null);
expect(rootScope.$viewHistory.histories[tab2Container.$historyId].cursor).toEqual(1);
expect(rootScope.$viewHistory.histories[tab2Container.$historyId].stack.length).toEqual(2);

// register tab3, view1
$state.go('tabs.tab3view1');
rootScope.$apply();
var tab3view1Reg = viewService.register(tab3Container);
expect(tab3view1Reg.navAction).toEqual('newView');
expect(tab3view1Reg.navDirection).toEqual(null);

expect(rootScope.$viewHistory.histories[tab2Container.$historyId].cursor).toEqual(1);
expect(rootScope.$viewHistory.histories[tab2Container.$historyId].stack.length).toEqual(2);


var tab2Hist = viewService._getHistory(tab2Container);
var currentStateId = viewService.getCurrentStateId()
currentView = viewService.getCurrentView();
expect(currentView).toBeDefined();
expect(currentView.historyId).not.toEqual(tab2Hist.historyId);
expect(tab2Hist.cursor).toEqual(1);
expect(tab2Hist.stack.length).toEqual(2);
expect(tab2Hist.cursor).toBeLessThan(tab2Hist.stack.length);

// register tab2, view2
$state.go('tabs.tab2view2');
rootScope.$apply();
var tab2view2RegAgain = viewService.register(tab2Container);
expect(tab2view2RegAgain.historyId).toEqual(tab2view2Reg.historyId);
expect(rootScope.$viewHistory.histories[tab2Container.$historyId].cursor).toEqual(1);
expect(rootScope.$viewHistory.histories[tab2Container.$historyId].stack.length).toEqual(2);
}));

it('should init root viewHistory data', inject(function() {
expect(rootScope.$viewHistory.backView).toEqual(null);
expect(rootScope.$viewHistory.currentView).toEqual(null);
Expand Down

0 comments on commit 68de8ed

Please sign in to comment.