Skip to content

Commit

Permalink
release 0.2.15
Browse files Browse the repository at this point in the history
  • Loading branch information
christopherthielen committed May 19, 2015
1 parent b4a2d27 commit 805e69b
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 39 deletions.
105 changes: 68 additions & 37 deletions release/angular-ui-router.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* State-based routing for AngularJS
* @version v0.2.14
* @version v0.2.15
* @link http://angular-ui.github.com/
* @license MIT License, http://www.opensource.org/licenses/MIT
*/
Expand Down Expand Up @@ -1241,15 +1241,14 @@ function $UrlMatcherFactory() {

function valToString(val) { return val != null ? val.toString().replace(/\//g, "%2F") : val; }
function valFromString(val) { return val != null ? val.toString().replace(/%2F/g, "/") : val; }
// TODO: in 1.0, make string .is() return false if value is undefined by default.
// function regexpMatches(val) { /*jshint validthis:true */ return isDefined(val) && this.pattern.test(val); }
function regexpMatches(val) { /*jshint validthis:true */ return this.pattern.test(val); }

var $types = {}, enqueue = true, typeQueue = [], injector, defaultTypes = {
string: {
encode: valToString,
decode: valFromString,
is: function(val) { return typeof val === "string"; },
// TODO: in 1.0, make string .is() return false if value is undefined/null by default.
// In 0.2.x, string params are optional by default for backwards compat
is: function(val) { return val == null || !isDefined(val) || typeof val === "string"; },
pattern: /[^/]*/
},
int: {
Expand Down Expand Up @@ -1293,7 +1292,6 @@ function $UrlMatcherFactory() {
any: { // does not encode/decode
encode: angular.identity,
decode: angular.identity,
is: angular.identity,
equals: angular.equals,
pattern: /.*/
}
Expand Down Expand Up @@ -2002,7 +2000,8 @@ function $UrlRouterProvider( $locationProvider, $urlMatcherFactory) {
if (evt && evt.defaultPrevented) return;
var ignoreUpdate = lastPushedUrl && $location.url() === lastPushedUrl;
lastPushedUrl = undefined;
if (ignoreUpdate) return true;
// TODO: Re-implement this in 1.0 for https://github.com/angular-ui/ui-router/issues/1573
//if (ignoreUpdate) return true;

function check(rule) {
var handled = rule($injector, $location);
Expand Down Expand Up @@ -3104,7 +3103,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
* have not changed, aka a reload of the same state. It differs from reloadOnSearch because you'd
* use this when you want to force a reload when *everything* is the same, including search params.
* if String, then will reload the state with the name given in reload, and any children.
* if Object, then a stateObj is expected, will reload the state found in stateObj, and any chhildren.
* if Object, then a stateObj is expected, will reload the state found in stateObj, and any children.
*
* @returns {promise} A promise representing the state of the new transition. See
* {@link ui.router.state.$state#methods_go $state.go}.
Expand Down Expand Up @@ -3152,7 +3151,6 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {

// Starting from the root of the path, keep all levels that haven't changed
var keep = 0, state = toPath[keep], locals = root.locals, toLocals = [];
var skipTriggerReloadCheck = false;

if (!options.reload) {
while (state && state === fromPath[keep] && state.ownParams.$$equals(toParams, fromParams)) {
Expand All @@ -3170,8 +3168,6 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
throw new Error("No such reload state '" + (isString(options.reload) ? options.reload : options.reload.name) + "'");
}

skipTriggerReloadCheck = true;

while (state && state === fromPath[keep] && state !== reloadState) {
locals = toLocals[keep] = state.locals;
keep++;
Expand All @@ -3184,8 +3180,16 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
// TODO: We may not want to bump 'transition' if we're called from a location change
// that we've initiated ourselves, because we might accidentally abort a legitimate
// transition initiated from code?
if (!skipTriggerReloadCheck && shouldTriggerReload(to, from, locals, options)) {
if (to.self.reloadOnSearch !== false) $urlRouter.update();
if (shouldSkipReload(to, toParams, from, fromParams, locals, options)) {
if (hash) toParams['#'] = hash;
$state.params = toParams;
copy($state.params, $stateParams);
if (options.location && to.navigable && to.navigable.url) {
$urlRouter.push(to.navigable.url, toParams, {
$$avoidResync: true, replace: options.location === 'replace'
});
$urlRouter.update(true);
}
$state.transition = null;
return $q.when($state.current);
}
Expand Down Expand Up @@ -3540,39 +3544,66 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
})];
if (inherited) promises.push(inherited);

// Resolve template and dependencies for all views.
forEach(state.views, function (view, name) {
var injectables = (view.resolve && view.resolve !== state.resolve ? view.resolve : {});
injectables.$template = [ function () {
return $view.load(name, { view: view, locals: locals, params: $stateParams, notify: options.notify }) || '';
}];

promises.push($resolve.resolve(injectables, locals, dst.resolve, state).then(function (result) {
// References to the controller (only instantiated at link time)
if (isFunction(view.controllerProvider) || isArray(view.controllerProvider)) {
var injectLocals = angular.extend({}, injectables, locals, result);
result.$$controller = $injector.invoke(view.controllerProvider, null, injectLocals);
} else {
result.$$controller = view.controller;
}
// Provide access to the state itself for internal use
result.$$state = state;
result.$$controllerAs = view.controllerAs;
dst[name] = result;
}));
});
function resolveViews() {
var viewsPromises = [];

// Resolve template and dependencies for all views.
forEach(state.views, function (view, name) {
var injectables = (view.resolve && view.resolve !== state.resolve ? view.resolve : {});
injectables.$template = [ function () {
return $view.load(name, { view: view, locals: dst.globals, params: $stateParams, notify: options.notify }) || '';
}];

viewsPromises.push($resolve.resolve(injectables, dst.globals, dst.resolve, state).then(function (result) {
// References to the controller (only instantiated at link time)
if (isFunction(view.controllerProvider) || isArray(view.controllerProvider)) {
var injectLocals = angular.extend({}, injectables, dst.globals);
result.$$controller = $injector.invoke(view.controllerProvider, null, injectLocals);
} else {
result.$$controller = view.controller;
}
// Provide access to the state itself for internal use
result.$$state = state;
result.$$controllerAs = view.controllerAs;
dst[name] = result;
}));
});

return $q.all(viewsPromises).then(function(){
return dst.globals;
});
}

// Wait for all the promises and then return the activation object
return $q.all(promises).then(function (values) {
return $q.all(promises).then(resolveViews).then(function (values) {
return dst;
});
}

return $state;
}

function shouldTriggerReload(to, from, locals, options) {
if (to === from && ((locals === from.locals && !options.reload) || (to.self.reloadOnSearch === false))) {
function shouldSkipReload(to, toParams, from, fromParams, locals, options) {
// Return true if there are no differences in non-search (path/object) params, false if there are differences
function nonSearchParamsEqual(fromAndToState, fromParams, toParams) {
// Identify whether all the parameters that differ between `fromParams` and `toParams` were search params.
function notSearchParam(key) {
return fromAndToState.params[key].location != "search";
}
var nonQueryParamKeys = fromAndToState.params.$$keys().filter(notSearchParam);
var nonQueryParams = pick.apply({}, [fromAndToState.params].concat(nonQueryParamKeys));
var nonQueryParamSet = new $$UMFP.ParamSet(nonQueryParams);
return nonQueryParamSet.$$equals(fromParams, toParams);
}

// If reload was not explicitly requested
// and we're transitioning to the same state we're already in
// and the locals didn't change
// or they changed in a way that doesn't merit reloading
// (reloadOnParams:false, or reloadOnSearch.false and only search params changed)
// Then return true.
if (!options.reload && to === from &&
(locals === from.locals || (to.self.reloadOnSearch === false && nonSearchParamsEqual(from, fromParams, toParams)))) {
return true;
}
}
Expand Down
Loading

0 comments on commit 805e69b

Please sign in to comment.