Skip to content

Commit 68de8ed

Browse files
committed
fix(history): tabs lose history after switching tabs
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
1 parent 1c62ed7 commit 68de8ed

File tree

2 files changed

+85
-4
lines changed

2 files changed

+85
-4
lines changed

Diff for: js/angular/service/viewService.js

+13-3
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,18 @@ function($rootScope, $state, $location, $window, $injector, $animate, $ionicNavV
210210
hist.cursor > -1 && hist.stack.length > 0 && hist.cursor < hist.stack.length &&
211211
hist.stack[hist.cursor].stateId === currentStateId) {
212212
// they just changed to a different history and the history already has views in it
213-
rsp.viewId = hist.stack[hist.cursor].viewId;
213+
var switchToView = hist.stack[hist.cursor];
214+
rsp.viewId = switchToView.viewId;
214215
rsp.navAction = 'moveBack';
215216

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

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

231-
// check if there is a new forward view
232-
if(forwardView && currentView.stateId !== forwardView.stateId) {
240+
// check if there is a new forward view within the same history
241+
if(forwardView && currentView.stateId !== forwardView.stateId &&
242+
currentView.historyId === forwardView.historyId) {
233243
// they navigated to a new view but the stack already has a forward view
234244
// since its a new view remove any forwards that existed
235245
var forwardsHistory = this._getHistoryById(forwardView.historyId);

Diff for: test/unit/angular/service/viewService.unit.js

+72-1
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,7 @@ describe('Ionic View Service', function() {
586586
rootScope.$apply();
587587
expect(viewService.getCurrentStateName()).toEqual('tabs.tab1view1');
588588
registerData = viewService.register(tab1view1Scope);
589+
var tab1view1ViewId = registerData.viewId;
589590
expect(registerData.navAction).toEqual('moveBack');
590591
expect(registerData.navDirection).toEqual(null);
591592

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

617619
// go to view 1 in tab 2
618620
tab2view1Scope = { $parent: tab2Scope };
@@ -621,7 +623,7 @@ describe('Ionic View Service', function() {
621623
registerData = viewService.register(tab2view1Scope);
622624
expect(viewService.getCurrentStateName()).toEqual('tabs.tab2view1');
623625
expect(rootScope.$viewHistory.histories[tab2Scope.$historyId].cursor).toEqual(0);
624-
expect(registerData.navAction).toEqual('newView');
626+
expect(registerData.navAction).toEqual('moveBack');
625627
expect(registerData.navDirection).toEqual(null);
626628
currentView = viewService.getCurrentView();
627629
expect(currentView.backViewId).toEqual(tab1view2ViewId);
@@ -688,6 +690,75 @@ describe('Ionic View Service', function() {
688690
expect(currentView.viewId).toEqual(currentViewId);
689691
}));
690692

693+
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) {
694+
var tab1Container = {};
695+
var tab2Container = {};
696+
var tab3Container = {};
697+
viewService.registerHistory(tab1Container);
698+
viewService.registerHistory(tab2Container);
699+
viewService.registerHistory(tab3Container);
700+
701+
// register tab1, view1
702+
$state.go('tabs.tab1view1');
703+
rootScope.$apply();
704+
var tab1view1Reg = viewService.register(tab1Container);
705+
expect(tab1view1Reg.navAction).toEqual('initialView');
706+
expect(rootScope.$viewHistory.histories[tab1Container.$historyId].cursor).toEqual(0);
707+
708+
// register tab2, view1
709+
$state.go('tabs.tab2view1');
710+
rootScope.$apply();
711+
var tab2view1Reg = viewService.register(tab2Container);
712+
expect(tab2view1Reg.navAction).toEqual('newView');
713+
expect(rootScope.$viewHistory.histories[tab1Container.$historyId].stack[0].forwardViewId).toEqual(tab2view1Reg.viewId);
714+
expect(rootScope.$viewHistory.histories[tab2Container.$historyId].cursor).toEqual(0);
715+
716+
// register tab2, view2
717+
$state.go('tabs.tab2view2');
718+
rootScope.$apply();
719+
var tab2view2Reg = viewService.register(tab2Container);
720+
expect(tab2view2Reg.navAction).toEqual('newView');
721+
expect(rootScope.$viewHistory.histories[tab2Container.$historyId].cursor).toEqual(1);
722+
expect(rootScope.$viewHistory.histories[tab2Container.$historyId].stack.length).toEqual(2);
723+
724+
// register tab1, view1
725+
$state.go('tabs.tab1view1');
726+
rootScope.$apply();
727+
tab1view1Reg = viewService.register(tab1Container);
728+
expect(tab1view1Reg.navAction).toEqual('moveBack');
729+
expect(tab1view1Reg.navDirection).toEqual(null);
730+
expect(rootScope.$viewHistory.histories[tab2Container.$historyId].cursor).toEqual(1);
731+
expect(rootScope.$viewHistory.histories[tab2Container.$historyId].stack.length).toEqual(2);
732+
733+
// register tab3, view1
734+
$state.go('tabs.tab3view1');
735+
rootScope.$apply();
736+
var tab3view1Reg = viewService.register(tab3Container);
737+
expect(tab3view1Reg.navAction).toEqual('newView');
738+
expect(tab3view1Reg.navDirection).toEqual(null);
739+
740+
expect(rootScope.$viewHistory.histories[tab2Container.$historyId].cursor).toEqual(1);
741+
expect(rootScope.$viewHistory.histories[tab2Container.$historyId].stack.length).toEqual(2);
742+
743+
744+
var tab2Hist = viewService._getHistory(tab2Container);
745+
var currentStateId = viewService.getCurrentStateId()
746+
currentView = viewService.getCurrentView();
747+
expect(currentView).toBeDefined();
748+
expect(currentView.historyId).not.toEqual(tab2Hist.historyId);
749+
expect(tab2Hist.cursor).toEqual(1);
750+
expect(tab2Hist.stack.length).toEqual(2);
751+
expect(tab2Hist.cursor).toBeLessThan(tab2Hist.stack.length);
752+
753+
// register tab2, view2
754+
$state.go('tabs.tab2view2');
755+
rootScope.$apply();
756+
var tab2view2RegAgain = viewService.register(tab2Container);
757+
expect(tab2view2RegAgain.historyId).toEqual(tab2view2Reg.historyId);
758+
expect(rootScope.$viewHistory.histories[tab2Container.$historyId].cursor).toEqual(1);
759+
expect(rootScope.$viewHistory.histories[tab2Container.$historyId].stack.length).toEqual(2);
760+
}));
761+
691762
it('should init root viewHistory data', inject(function() {
692763
expect(rootScope.$viewHistory.backView).toEqual(null);
693764
expect(rootScope.$viewHistory.currentView).toEqual(null);

0 commit comments

Comments
 (0)