From b0431d6884d335208161be1e562d3682da168d9d Mon Sep 17 00:00:00 2001 From: christopherthielen Date: Sat, 31 Jan 2015 16:45:43 -0600 Subject: [PATCH] fix(previous): Previous state no longer tracks abstract from-states (e.g., root) Closes #123 --- src/previous.js | 10 ++++++++-- test/previousSpec.js | 16 +++++++++++++--- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/previous.js b/src/previous.js index ee368eb..5f6e88d 100644 --- a/src/previous.js +++ b/src/previous.js @@ -4,8 +4,14 @@ angular.module('ct.ui.router.extras.previous', [ 'ct.ui.router.extras.core', 'ct var previous = null, lastPrevious = null, memos = {}; $rootScope.$on("$transitionStart", function(evt, $transition$) { - lastPrevious = previous; - previous = $transition$.from; + var from = $transition$.from; + // Check if the fromState is navigable before tracking it. + // Root state doesn't get decorated with $$state(). Doh. + var fromState = from.state && from.state.$$state && from.state.$$state(); + if (fromState && fromState.navigable) { + lastPrevious = previous; + previous = $transition$.from; + } $transition$.promise.then(commit).catch(revert); function commit() { lastPrevious = null; } diff --git a/test/previousSpec.js b/test/previousSpec.js index baaea7c..5cbb366 100644 --- a/test/previousSpec.js +++ b/test/previousSpec.js @@ -53,17 +53,26 @@ describe("$previousState", function () { $previousState = $get('$previousState'); })); + // Test for #123 + it("should not capture root state (or non-navigable states)", inject(function($rootScope) { + testGo("top", { entered: 'top' }); + expect($previousState.get()).toBeNull(); + })); + + describe('.go()', function () { it("should transition back to the previous state", function () { testGo("top.people.managerlist", { entered: pathFrom('top', 'top.people.managerlist') }); - testGo("top.inv.storelist", { entered: pathFrom('top.inv', 'top.inv.storelist') , exited: pathFrom('top.people.managerlist', 'top.people') }); + testGo("top.inv.storelist", { entered: pathFrom('top.inv', 'top.inv.storelist'), exited: pathFrom('top.people.managerlist', 'top.people') }); $previousState.go(); $q.flush(); expect($state.current.name === "tabs.tabs2"); }); + }); + describe('.get()', function() { // Test for #120 - it("should go to previous state after another transition is cancelled", inject(function($rootScope) { + it("should not return current state, after a transition is cancelled", inject(function($rootScope) { testGo("top", { entered: 'top' }); testGo("top.people.managerlist", { entered: ['top.people', 'top.people.managerlist'] }); @@ -71,8 +80,9 @@ describe("$previousState", function () { $rootScope.$on("$stateChangeStart", function(evt) { if (transitionNum++ === 0) { evt.preventDefault(); } }); testGo("top.inv.storelist", undefined, { redirect: 'top.people.managerlist'}); // Cancelled, so we're still at original state + expect($previousState.get().state.name).toBe("top"); - })); + })) }); describe('.memo()', function () {