Logging in no longer causes page refresh.
This patch updates the LastLocation service to store data from the UI-Router state, rather than the url, which allows us to navigate to a state directly using UI-Router. It also updates the SearchParamProvider to grab its data in the config phase, before the UI-Router is initialized. This permits us to forcefully remove any query parameters passed to our application in the URL - as happens during the OAuth exchange - before the router is aware of them, and thus circumvents an infinite digest loop. The end result is that StoryBoard no longer has to reload itself after a user is successfully authorized. Note: The URL class used is not supported by PhantomJS. As such, PhantomJS has been removed from our karma.conf. Change-Id: Iae113544ad35708f63c5636189f0c88990eab203
This commit is contained in:
parent
4b9dbd1d99
commit
a3abee9058
@ -29,7 +29,6 @@ module.exports = function (config) {
|
||||
'karma-coverage',
|
||||
'karma-jasmine',
|
||||
'karma-html-reporter',
|
||||
'karma-phantomjs-launcher',
|
||||
'karma-chrome-launcher',
|
||||
'karma-firefox-launcher'
|
||||
],
|
||||
@ -52,7 +51,7 @@ module.exports = function (config) {
|
||||
|
||||
colors: false,
|
||||
|
||||
browsers: [ 'PhantomJS', 'Firefox' ],
|
||||
browsers: [ 'Firefox' ],
|
||||
|
||||
preprocessors: {
|
||||
'./dist/js/storyboard.js': ['coverage']
|
||||
|
@ -22,8 +22,7 @@
|
||||
*/
|
||||
|
||||
angular.module('sb.auth').controller('AuthAuthorizeController',
|
||||
function ($stateParams, $state, $log, OpenId, $window, LastLocation,
|
||||
localStorageService) {
|
||||
function ($stateParams, $state, $log, OpenId) {
|
||||
'use strict';
|
||||
|
||||
// First, check for the edge case where the API returns an error code
|
||||
@ -36,9 +35,6 @@ angular.module('sb.auth').controller('AuthAuthorizeController',
|
||||
return;
|
||||
}
|
||||
|
||||
// Store the last path...
|
||||
localStorageService.set('lastPath', LastLocation.get());
|
||||
|
||||
// We're not an error, let's fire the authorization.
|
||||
OpenId.authorize();
|
||||
});
|
||||
|
@ -36,21 +36,6 @@ angular.module('sb.auth').controller('AuthTokenController',
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate any previously stored redirect path
|
||||
function buildNextPath() {
|
||||
|
||||
// First, do we have a stored last location?
|
||||
var location = LastLocation.get();
|
||||
|
||||
// Sanity check on the location, we don't want to bounce straight
|
||||
// back into auth.
|
||||
if (location.indexOf('/auth') > -1) {
|
||||
location = '/';
|
||||
}
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
// Looks like there's no error, so let's see if we can resolve a token.
|
||||
// TODO: Finish implementing.
|
||||
OpenId.token($searchParams)
|
||||
@ -58,9 +43,7 @@ angular.module('sb.auth').controller('AuthTokenController',
|
||||
function (token) {
|
||||
Session.updateSession(token)
|
||||
.then(function () {
|
||||
var nextPath = buildNextPath();
|
||||
$window.location.href =
|
||||
UrlUtil.buildApplicationUrl(nextPath);
|
||||
LastLocation.go('sb.page.about', {});
|
||||
});
|
||||
},
|
||||
function (error) {
|
||||
|
@ -18,18 +18,46 @@
|
||||
* Utility injector, injects the query parameters from the NON-hashbang URL as
|
||||
* $searchParams.
|
||||
*/
|
||||
angular.module('sb.util').factory('$searchParams',
|
||||
function ($window, UrlUtil) {
|
||||
angular.module('sb.util').provider('$searchParams',
|
||||
function ($windowProvider) {
|
||||
'use strict';
|
||||
|
||||
var params = {};
|
||||
var search = $window.location.search;
|
||||
if (!!search) {
|
||||
var pageParams = {};
|
||||
|
||||
this.extractSearchParameters = function () {
|
||||
var window = $windowProvider.$get();
|
||||
var search = window.location.search;
|
||||
if (search.charAt(0) === '?') {
|
||||
search = search.substr(1);
|
||||
}
|
||||
var queryComponents = search.split('&');
|
||||
for (var i = 0; i < queryComponents.length; i++) {
|
||||
var parts = queryComponents[i].split('=');
|
||||
var key = decodeURIComponent(parts[0]) || null;
|
||||
var value = decodeURIComponent(parts[1]) || null;
|
||||
|
||||
return UrlUtil.deserializeParameters(search);
|
||||
if (!!key && !!value) {
|
||||
pageParams[key] = value;
|
||||
}
|
||||
}
|
||||
};
|
||||
this.$get = function () {
|
||||
return angular.copy(pageParams);
|
||||
};
|
||||
})
|
||||
.config(function ($searchParamsProvider, $windowProvider) {
|
||||
'use strict';
|
||||
|
||||
// Make sure we save the search parameters so they can be used later.
|
||||
$searchParamsProvider.extractSearchParameters();
|
||||
|
||||
// Overwrite the URL's current state.
|
||||
var window = $windowProvider.$get();
|
||||
var url = new URL(window.location.toString());
|
||||
url.search = '';
|
||||
if (window.location.toString() !== url.toString()) {
|
||||
window.history.replaceState({},
|
||||
window.document.title,
|
||||
url.toString());
|
||||
}
|
||||
return params;
|
||||
});
|
||||
|
@ -17,49 +17,53 @@
|
||||
/**
|
||||
* A service that keeps track of the last page we visited.
|
||||
*/
|
||||
angular.module('sb.util')
|
||||
.factory('LastLocation',
|
||||
function ($rootScope, localStorageService, $location) {
|
||||
angular.module('sb.util').factory('LastLocation',
|
||||
function ($rootScope, localStorageService, $state) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* The last detected length of the history
|
||||
* onStateChange handler. Stores the next destination state, and its
|
||||
* parameters, so we can keep revisit the history after bouncing out
|
||||
* for authentication.
|
||||
*
|
||||
* @param event The state change event.
|
||||
* @param toState The destination state.
|
||||
* @param toParams The parameters for that destination state.
|
||||
*/
|
||||
|
||||
// When the location changes, store the new one. Since the $location
|
||||
// object changes too quickly, we instead extract the hash manually.
|
||||
function onLocationChange() {
|
||||
var path = $location.path();
|
||||
if (!!path && path.indexOf('/auth') === -1) {
|
||||
localStorageService.set('lastLocation', path);
|
||||
function onStateChange(event, toState, toParams) {
|
||||
if (toState.name.indexOf('sb.auth') === -1) {
|
||||
var data = {
|
||||
'name': toState.name,
|
||||
'params': toParams
|
||||
};
|
||||
localStorageService.set('lastLocation',
|
||||
angular.toJson(data));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// Add the listener to the application, remove it when the scope is
|
||||
// destroyed.
|
||||
$rootScope.$on('$destroy',
|
||||
$rootScope.$on('$stateChangeStart', onStateChange)
|
||||
);
|
||||
|
||||
// The published API.
|
||||
return {
|
||||
|
||||
/**
|
||||
* Get the recorded history path at the provided index.
|
||||
* Navigate to the last recorded state.
|
||||
*
|
||||
* @param defaultStateName A fallback state.
|
||||
* @param defaultStateParams Default state parameters.
|
||||
*/
|
||||
get: function () {
|
||||
return localStorageService.get('lastLocation');
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize this service.
|
||||
*/
|
||||
initialize: function () {
|
||||
// Register (and disconnect) our listener.
|
||||
$rootScope.$on('$destroy',
|
||||
$rootScope.$on('$locationChangeStart', onLocationChange)
|
||||
);
|
||||
go: function (defaultStateName, defaultStateParams) {
|
||||
var last = localStorageService.get('lastLocation');
|
||||
if (!last) {
|
||||
$state.go(defaultStateName, defaultStateParams);
|
||||
} else {
|
||||
last = angular.fromJson(last);
|
||||
$state.go(last.name, last.params);
|
||||
}
|
||||
}
|
||||
};
|
||||
})
|
||||
.run(function (LastLocation) {
|
||||
'use strict';
|
||||
|
||||
// Initialize this service.
|
||||
LastLocation.initialize();
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user