Skip to content

Commit

Permalink
fixup! fix($state.transitionTo): trigger $stateChangeCancel appropria…
Browse files Browse the repository at this point in the history
…tely
  • Loading branch information
zeusdeux committed Sep 26, 2016
1 parent ca7dba4 commit 6dc93a2
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 60 deletions.
110 changes: 55 additions & 55 deletions src/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
if (path) {
if (!base) throw new Error("No reference point given for path '" + name + "'");
base = findState(base);

var rel = name.split("."), i = 0, pathLength = rel.length, current = base;

for (; i < pathLength; i++) {
Expand Down Expand Up @@ -259,9 +259,9 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
* @methodOf ui.router.state.$stateProvider
*
* @description
* Allows you to extend (carefully) or override (at your own peril) the
* `stateBuilder` object used internally by `$stateProvider`. This can be used
* to add custom functionality to ui-router, for example inferring templateUrl
* Allows you to extend (carefully) or override (at your own peril) the
* `stateBuilder` object used internally by `$stateProvider`. This can be used
* to add custom functionality to ui-router, for example inferring templateUrl
* based on the state name.
*
* When passing only a name, it returns the current (original or decorated) builder
Expand All @@ -270,14 +270,14 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
* The builder functions that can be decorated are listed below. Though not all
* necessarily have a good use case for decoration, that is up to you to decide.
*
* In addition, users can attach custom decorators, which will generate new
* properties within the state's internal definition. There is currently no clear
* use-case for this beyond accessing internal states (i.e. $state.$current),
* however, expect this to become increasingly relevant as we introduce additional
* In addition, users can attach custom decorators, which will generate new
* properties within the state's internal definition. There is currently no clear
* use-case for this beyond accessing internal states (i.e. $state.$current),
* however, expect this to become increasingly relevant as we introduce additional
* meta-programming features.
*
* **Warning**: Decorators should not be interdependent because the order of
* execution of the builder functions in non-deterministic. Builder functions
* **Warning**: Decorators should not be interdependent because the order of
* execution of the builder functions in non-deterministic. Builder functions
* should only be dependent on the state definition object and super function.
*
*
Expand All @@ -288,21 +288,21 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
* overridden by own values (if any).
* - **url** `{object}` - returns a {@link ui.router.util.type:UrlMatcher UrlMatcher}
* or `null`.
* - **navigable** `{object}` - returns closest ancestor state that has a URL (aka is
* - **navigable** `{object}` - returns closest ancestor state that has a URL (aka is
* navigable).
* - **params** `{object}` - returns an array of state params that are ensured to
* - **params** `{object}` - returns an array of state params that are ensured to
* be a super-set of parent's params.
* - **views** `{object}` - returns a views object where each key is an absolute view
* name (i.e. "viewName@stateName") and each value is the config object
* (template, controller) for the view. Even when you don't use the views object
* - **views** `{object}` - returns a views object where each key is an absolute view
* name (i.e. "viewName@stateName") and each value is the config object
* (template, controller) for the view. Even when you don't use the views object
* explicitly on a state config, one is still created for you internally.
* So by decorating this builder function you have access to decorating template
* So by decorating this builder function you have access to decorating template
* and controller properties.
* - **ownParams** `{object}` - returns an array of params that belong to the state,
* - **ownParams** `{object}` - returns an array of params that belong to the state,
* not including any params defined by ancestor states.
* - **path** `{string}` - returns the full path from the root down to this state.
* - **path** `{string}` - returns the full path from the root down to this state.
* Needed for state activation.
* - **includes** `{object}` - returns an object that includes every state that
* - **includes** `{object}` - returns an object that includes every state that
* would pass a `$state.includes()` test.
*
* @example
Expand Down Expand Up @@ -335,8 +335,8 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
* // and /partials/home/contact/item.html, respectively.
* </pre>
*
* @param {string} name The name of the builder function to decorate.
* @param {object} func A function that is responsible for decorating the original
* @param {string} name The name of the builder function to decorate.
* @param {object} func A function that is responsible for decorating the original
* builder function. The function receives two parameters:
*
* - `{object}` - state - The state config object.
Expand Down Expand Up @@ -375,9 +375,9 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
* @param {string|function=} stateConfig.template
* <a id='template'></a>
* html template as a string or a function that returns
* an html template as a string which should be used by the uiView directives. This property
* an html template as a string which should be used by the uiView directives. This property
* takes precedence over templateUrl.
*
*
* If `template` is a function, it will be called with the following parameters:
*
* - {array.&lt;object&gt;} - state parameters extracted from the current $location.path() by
Expand All @@ -395,10 +395,10 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
*
* path or function that returns a path to an html
* template that should be used by uiView.
*
*
* If `templateUrl` is a function, it will be called with the following parameters:
*
* - {array.&lt;object&gt;} - state parameters extracted from the current $location.path() by
* - {array.&lt;object&gt;} - state parameters extracted from the current $location.path() by
* applying the current state
*
* <pre>templateUrl: "home.html"</pre>
Expand Down Expand Up @@ -442,7 +442,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
*
* @param {string=} stateConfig.controllerAs
* <a id='controllerAs'></a>
*
*
* A controller alias name. If present the controller will be
* published to scope under the controllerAs name.
* <pre>controllerAs: "myCtrl"</pre>
Expand All @@ -458,17 +458,17 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
* <a id='resolve'></a>
*
* An optional map&lt;string, function&gt; of dependencies which
* should be injected into the controller. If any of these dependencies are promises,
* should be injected into the controller. If any of these dependencies are promises,
* the router will wait for them all to be resolved before the controller is instantiated.
* If all the promises are resolved successfully, the $stateChangeSuccess event is fired
* and the values of the resolved promises are injected into any controllers that reference them.
* If any of the promises are rejected the $stateChangeError event is fired.
*
* The map object is:
*
*
* - key - {string}: name of dependency to be injected into controller
* - factory - {string|function}: If string then it is alias for service. Otherwise if function,
* it is injected and return value it treated as dependency. If result is a promise, it is
* - factory - {string|function}: If string then it is alias for service. Otherwise if function,
* it is injected and return value it treated as dependency. If result is a promise, it is
* resolved before its value is injected into controller.
*
* <pre>resolve: {
Expand All @@ -482,7 +482,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
* <a id='url'></a>
*
* A url fragment with optional parameters. When a state is navigated or
* transitioned to, the `$stateParams` service will be populated with any
* transitioned to, the `$stateParams` service will be populated with any
* parameters that were passed.
*
* (See {@link ui.router.util.type:UrlMatcher UrlMatcher} `UrlMatcher`} for
Expand Down Expand Up @@ -565,7 +565,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
* <a id='reloadOnSearch'></a>
*
* If `false`, will not retrigger the same state
* just because a search/query parameter has changed (via $location.search() or $location.hash()).
* just because a search/query parameter has changed (via $location.search() or $location.hash()).
* Useful for when you'd like to modify $location.search() without triggering a reload.
* <pre>reloadOnSearch: false</pre>
*
Expand Down Expand Up @@ -700,11 +700,11 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
* @requires ui.router.state.$stateParams
* @requires ui.router.router.$urlRouter
*
* @property {object} params A param object, e.g. {sectionId: section.id)}, that
* @property {object} params A param object, e.g. {sectionId: section.id)}, that
* you'd like to test against the current active state.
* @property {object} current A reference to the state's config object. However
* @property {object} current A reference to the state's config object. However
* you passed it in. Useful for accessing custom data.
* @property {object} transition Currently pending transition. A promise that'll
* @property {object} transition Currently pending transition. A promise that'll
* resolve or reject.
*
* @description
Expand Down Expand Up @@ -822,15 +822,15 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
*
* `reload()` is just an alias for:
* <pre>
* $state.transitionTo($state.current, $stateParams, {
* $state.transitionTo($state.current, $stateParams, {
* reload: true, inherit: false, notify: true
* });
* </pre>
*
* @param {string=|object=} state - A state name or a state object, which is the root of the resolves to be re-resolved.
* @example
* <pre>
* //assuming app application consists of 3 states: 'contacts', 'contacts.detail', 'contacts.detail.item'
* //assuming app application consists of 3 states: 'contacts', 'contacts.detail', 'contacts.detail.item'
* //and current state is 'contacts.detail.item'
* var app angular.module('app', ['ui.router']);
*
Expand All @@ -844,7 +844,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
*
* `reload()` is just an alias for:
* <pre>
* $state.transitionTo($state.current, $stateParams, {
* $state.transitionTo($state.current, $stateParams, {
* reload: true, inherit: false, notify: true
* });
* </pre>
Expand All @@ -862,11 +862,11 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
* @methodOf ui.router.state.$state
*
* @description
* Convenience method for transitioning to a new state. `$state.go` calls
* `$state.transitionTo` internally but automatically sets options to
* `{ location: true, inherit: true, relative: $state.$current, notify: true }`.
* This allows you to easily use an absolute or relative to path and specify
* only the parameters you'd like to update (while letting unspecified parameters
* Convenience method for transitioning to a new state. `$state.go` calls
* `$state.transitionTo` internally but automatically sets options to
* `{ location: true, inherit: true, relative: $state.$current, notify: true }`.
* This allows you to easily use an absolute or relative to path and specify
* only the parameters you'd like to update (while letting unspecified parameters
* inherit from the currently active ancestor states).
*
* @example
Expand All @@ -888,9 +888,9 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
* - `$state.go('^.sibling')` - will go to a sibling state
* - `$state.go('.child.grandchild')` - will go to grandchild state
*
* @param {object=} params A map of the parameters that will be sent to the state,
* will populate $stateParams. Any parameters that are not specified will be inherited from currently
* defined parameters. Only parameters specified in the state definition can be overridden, new
* @param {object=} params A map of the parameters that will be sent to the state,
* will populate $stateParams. Any parameters that are not specified will be inherited from currently
* defined parameters. Only parameters specified in the state definition can be overridden, new
* parameters will be ignored. This allows, for example, going to a sibling state that shares parameters
* specified in a parent state. Parameter inheritance only works between common ancestor states, I.e.
* transitioning to a sibling will get you the parameters for all parents, transitioning to a child
Expand All @@ -900,7 +900,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
* - **`location`** - {boolean=true|string=} - If `true` will update the url in the location bar, if `false`
* will not. If string, must be `"replace"`, which will update url and also replace last history record.
* - **`inherit`** - {boolean=true}, If `true` will inherit url parameters from current url.
* - **`relative`** - {object=$state.$current}, When transitioning with relative path (e.g '^'),
* - **`relative`** - {object=$state.$current}, When transitioning with relative path (e.g '^'),
* defines which state to be relative from.
* - **`notify`** - {boolean=true}, If `true` will broadcast $stateChangeStart and $stateChangeSuccess events.
* - **`reload`** (v0.2.5) - {boolean=false|string|object}, If `true` will force transition even if no state or params
Expand Down Expand Up @@ -956,10 +956,10 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
* - **`location`** - {boolean=true|string=} - If `true` will update the url in the location bar, if `false`
* will not. If string, must be `"replace"`, which will update url and also replace last history record.
* - **`inherit`** - {boolean=false}, If `true` will inherit url parameters from current url.
* - **`relative`** - {object=}, When transitioning with relative path (e.g '^'),
* - **`relative`** - {object=}, When transitioning with relative path (e.g '^'),
* defines which state to be relative from.
* - **`notify`** - {boolean=true}, If `true` will broadcast $stateChangeStart and $stateChangeSuccess events.
* - **`reload`** (v0.2.5) - {boolean=false|string=|object=}, If `true` will force transition even if the state or params
* - **`reload`** (v0.2.5) - {boolean=false|string=|object=}, If `true` will force transition even if the state or params
* 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.
Expand Down Expand Up @@ -1022,7 +1022,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
if (isObject(options.reload) && !options.reload.name) {
throw new Error('Invalid reload state object');
}

var reloadState = options.reload === true ? fromPath[0] : findState(options.reload);
if (options.reload && !reloadState) {
throw new Error("No such reload state '" + (isString(options.reload) ? options.reload : options.reload.name) + "'");
Expand Down Expand Up @@ -1057,10 +1057,10 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {

// Filter parameters before we pass them to event handlers etc.
toParams = filterByKeys(to.params.$$keys(), toParams || {});

// Re-add the saved hash before we start returning things or broadcasting $stateChangeStart
if (hash) toParams['#'] = hash;

// Broadcast start event and cancel the transition if requested
if (options.notify) {
/**
Expand Down Expand Up @@ -1353,10 +1353,10 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
* first parameter, then the constructed href url will be built from the first navigable ancestor (aka
* ancestor with a valid url).
* - **`inherit`** - {boolean=true}, If `true` will inherit url parameters from current url.
* - **`relative`** - {object=$state.$current}, When transitioning with relative path (e.g '^'),
* - **`relative`** - {object=$state.$current}, When transitioning with relative path (e.g '^'),
* defines which state to be relative from.
* - **`absolute`** - {boolean=false}, If true will generate an absolute url, e.g. "http://www.example.com/fullurl".
*
*
* @returns {string} compiled state url
*/
$state.href = function href(stateOrName, params, options) {
Expand All @@ -1371,7 +1371,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {

if (!isDefined(state)) return null;
if (options.inherit) params = inheritParams($stateParams, params || {}, $state.$current, state);

var nav = (state && options.lossy) ? state.navigable : state;

if (!nav || nav.url === undefined || nav.url === null) {
Expand Down
10 changes: 5 additions & 5 deletions test/stateSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -598,16 +598,16 @@ describe('state', function () {
expect($location.url()).toBe('/front/world#frag');
expect($location.hash()).toBe('frag');
}));

it('has access to the #fragment in $stateChangeStart hook', inject(function ($state, $q, $location, $rootScope) {
var hash_accessible = false;
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
hash_accessible = toParams['#'] === 'frag';
});

$state.transitionTo('home.item', {id: 'world', '#': 'frag'});
$q.flush();

expect(hash_accessible).toBe(true);
}));
});
Expand Down Expand Up @@ -809,7 +809,7 @@ describe('state', function () {

it('should work for relative states', inject(function ($state, $q) {
var options = { relative: $state.get('about') };

$state.transitionTo('about.person'); $q.flush();
expect($state.is('.person', undefined, options)).toBe(true);

Expand Down Expand Up @@ -964,7 +964,7 @@ describe('state', function () {
expect($state.href("root", {}, {inherit:false})).toEqual("#/root");
expect($state.href("root", {}, {inherit:true})).toEqual("#/root?param1=1");
}));

it('generates absolute url when absolute is true', inject(function ($state) {
expect($state.href("about.sidebar", null, { absolute: true })).toEqual("http://server/#/about");
locationProvider.html5Mode(true);
Expand Down

0 comments on commit 6dc93a2

Please sign in to comment.