Skip to content

Releases: ui-router/core

5.0.4

19 Jun 03:22
Compare
Choose a tag to compare

@uirouter/core changes

5.0.4 (2017-06-06)

Bug Fixes

  • future: Allow future states to specify a parent: (de68fe1)
  • view: only sync views which are of the same name and type (49b5594)

Features

  • invalidTransition: Better error messaging when param values are invalid (fd45f44)
  • trace: Trace view synchronization. Allow trace.enable(...string) (29503a0)

5.0.3

19 Jun 03:21
Compare
Choose a tag to compare

@uirouter/core changes

5.0.3 (2017-05-07)

Bug Fixes

  • common: Re-fix implementation of 'pick' using for .. in (f2da7f4)

5.0.2

19 Jun 03:21
Compare
Choose a tag to compare

@uirouter/core changes

5.0.2 (2017-05-06)

Bug Fixes

  • common: Fix implementation of 'pick' -- use hasOwnProperty (09848a4)

Features

  • build: Build and distribute UMD bundles (0a8da85)

5.0.1

19 Jun 03:21
Compare
Choose a tag to compare

@uirouter/core changes

5.0.1 (2017-05-03)

Bug Fixes

  • transition: Do not ignore transitions which have states being entered or exited (175717e)

5.0.0

19 Jun 03:20
Compare
Choose a tag to compare

@uirouter/core changes

5.0.0 (2017-04-21)

Bug Fixes

  • BrowserLocationConfig: fixed protocol + port value (#38) (5559382)
  • lazyLoad: Wait for future state to be replaced before registering lazy children (4bdce47)
  • noImplicitAny: Fix noimplicitany compliance (1a6cdfc)
  • redirect: Do not update URL after redirect with { location: false } (652a760)
  • tfs: Rename $q.ts and $injector.ts files, removing leading dollar signs (cb653ee)
  • trace: Re-add transitionStart trace (b019036)
  • transitionHook: Do not process transition hooks after router has been disposed. (666c6d7)
  • TransitionHook: Transition hooks no longer expose the internal StateObject (2b0e48b)
  • typings: Allow strictNullChecks for HookMatchCriteria (d92d4d5)
  • ui-sref: Improve performance of generating hrefs (c3967bd)
  • view: Do not throw when uiView doesn't have a state context (f76ee2a)
  • view: Update views in order of ui-view depth and also by state depth (46dea2b)

Features

  • abort: Add API to manually abort/cancel a transition (39f8a53)
  • common: Perf improvements in hot functions: (4193244)
  • core: Switch to @uirouter/core npm module (e3f389f)
  • decorators: Add state, resolve and resolve data decorators (642df0b)
  • defaultErrorHandler: Do not invoke default error handler for ABORTED transitions (b07a24b)
  • Globals: implement Disposable and delete global transition data (a794018)
  • onBefore: Run onBefore hooks asynchronously. (30b82aa)
  • onEnter/Exit/Retain: Use onExit/onEnter/onRetain from 56955state(), not state.self (bc1f554)
  • Rejection: Add $id to ease debugging of transition rejections (d456d54)
  • State: Support registration of ES6 state classes (as opposed to object literals) (3a5d055)
  • State: Switch Internal State Object to prototypally inherit from the State Declaration (027c995), closes #34
  • StateObject: Rename internal State object to StateObject (feceaf9)
  • StateRegistry: improve perf for: .register() and StateMatcher.find() misses (fdb3ab9)
  • transition: Ignore duplicate transitions (double clicks) (bd1bd0b)
  • transition: Improve supersede logic: Do not supersede if the new trans is aborted before onStart (3141a8f)
  • transition: Run hooks synchronously in current stack, when possible (953e618)
  • Transition: deprecate Transition.is() which was never implemented (1edff4b)
  • Transition: Normalize all transition errors to a Rejection. (a7464bb)
  • UrlService: (UrlRouter) improve perf of registering Url Rules and sorting Url Rules (64fbfff)
  • UrlService: Add rules.initial("/home") to config initial state (like otherwise) (bbe4209)

BREAKING CHANGES

TransitionHook: Transition hooks no longer expose the internal State object (now named StateObject)

Before:

import { State } from "@uirouter/core";
const match = { to: (state: State) => state.data.auth };
transitionsvc.onEnter(match, (trans: Transition, state: State) => {
  // state is the internal State object
  if (state.includes["foo"]) { // internal ui-router API
    return false;
  }
}

Now:

import { StateDeclaration } from "@uirouter/core";
const match = { to: (state: StateDeclaration) => state.data.auth };
transitionsvc.onEnter(match, (trans: Transition, state: StateDeclaration) => {
  // state === the state object you registered
  // Access internal ui-router API using $$state()
  if (state.$$state().includes["foo"]) {
    return false;
  }
}

Motivation:

The State object (now named StateObject) is an internal API and should not be exposed via any public APIs.
If you depend on the internal APIs, you can still access the internal object by calling state.$$state().

BC Likelihood

How likely is this BC to affect me?

Medium: You will likely be affected you 1) have transition hooks, 2) are using typescript and/or 3) use the internal ui-router State API.

BC Severity

How severe is this BC?

Low: Access to the internal api is still available using $$state().

StateObject: Renamed internal API State object to StateObject

Before:

import {State} from "@uirouter/core";

Now:

import {StateObject} from "@uirouter/core";

Motivation:

We'd like to use the State name/symbol as a public API. It will be an
ES7/TS decorator for ES6/TS state definition classes, i.e:

@State("foo")
export class FooState implements StateDeclaration {
  url = "/foo";
  component = FooComponent;

  @Resolve({ deps: [FooService] })
  fooData(fooService) {
    return fooService.getFoos();
  }
}

BC Likelihood

How likely is this to affect me?

Low: This only affects code that imports the internal API symbol State.
You will likely be affected you 1) import that symbol, 2) are using typescript and 3) explicitly
typed a variable such as let internalStateObject = state.$$state();

BC Severity

How severe is this change?

Low: Find all places where State is imported and rename to StateObject

Transition: All Transition errors are now wrapped in a Rejection object.

Before:

Previously, if a transition hook returned a rejected promise:

.onStart({}, () => Promise.reject('reject transition'));

In onError or transtion.promise.catch(), the raw rejection was returned:

.onError({}, (trans, err) => err === 'reject transition')

Now:

Now, the error is wrapped in a Rejection object.

  • The detail (thrown error or rejected value) is still available as .detail.
.onError({}, (trans, err) =>
    err instanceof Rejection && err.detail === 'reject transition')
  • The Rejection object indicates the .type of transition rejection (ABORTED, ERROR, SUPERSEDED and/or redirection).
.onError({}, (trans, err) => {
  err.type === RejectType.ABORTED === 3
});

Motivation:

Errors thrown from a hook and rejection values returned from a hook can now be processed in the same way.

BC Likelihood

How likely is this to affect me?

Medium: apps which have onError handlers for rejected values

BC Severity

How severe is this change?

Low: Find all error handlers (or .catch/.then chains) that do not understand Rejection. Add err.detail processing.

onBefore: onBefore hooks are now run asynchronously like all the other hooks.

Old behavior

Previously, the onBefore hooks were run in the same stackframe as transitionTo.
If they threw an error, it could be caught using try/catch.

transitionService.onBefore({ to: 'foo' }), () => { throw new Error('doh'); });
try {
  stateService.go('foo');
} catch (error) {
  // handle error
}

New behavior

Now, onBefore hooks are processed asynchronously.
To handle errors, use any of the async error handling paradigms:

  • Chain off the promise
    transitionService.onBefore({ to: 'foo' }), () => { throw new Error('doh'); });
    stateService.go('foo').catch(error => { //handle error });
  • Define an error handler
    transitionService.onBefore({ to: 'foo' }), () => { throw new Error('doh'); });
    transitionService.onError({ to: 'foo' }), () => { // handle error });
    stateService.go('foo');
  • Use the global defaultErrorHandler
    transitionService.onBefore({ to: 'foo' }), () => { throw new Error('doh'); });
    stateService.go('foo');
    stateService.defaultErrorHandler(error => { // global error handler });

Motivation

Why introduce a BC?

  • No subtle behavior differences by hook type
  • Simpler code and mental model
  • Fewer edge cases to account for

BC Liklihood

How likely is this to affect my app?

Very Low: Apps that registered onBefore hooks and depend on
synchronous execution are affected.

BC Severity

How severe is this BC?

Low: Switch to asynchronous handling, such as chaining off the
tr...

Read more

for-ng1-to-ng2-2.0

22 Mar 20:48
Compare
Choose a tag to compare
5.0.0-pre.1

chore(*): pushing pre tag

4.0.0

29 Jan 23:18
Compare
Choose a tag to compare

ui-router-core changes

4.0.0 (2017-01-22)

Bug Fixes

  • resolve: Allow hook and resolve's state context to be injected as $state$ (a06948b)

Features

  • core: Export all vanilla.* code from ui-router-core (f3392d1)
  • globals: Removed UIRouterGlobals interface. Renamed Globals class to UIRouterGlobals (8719334)

BREAKING CHANGES

  • BREAKING CHANGE:

This change will likely only affect a small subset of typescript users and probably only those using ui-router-ng2.
If you're injecting the Globals class somewhere, e.g.:

@Injectable()
class MyService {
  _globals: UIRouterGlobals;
  constructor(globals: Globals) {
    this._globals = <UIRouterGlobals> globals;
  }
}

you should now inject UIRouterGlobals, e.g.:

@Injectable()
class MyService {
  constructor(public globals: UIRouterGlobals) { }
}

Likewise, if you were casting the UIRouter.globals object as a UIRouterGlobals, it is no longer necessary:

function myHook(trans: Transition) {
  let globals: UIRouterGlobals = trans.router.globals; // cast is no longer necessary
}

Closes #31

3.1.1

29 Jan 23:19
Compare
Choose a tag to compare

ui-router-core changes

3.1.1 (2017-01-16)

Bug Fixes

  • lazyLoad: Allow lazyLoad stateBuilder: Get lazyLoad fn from internal State object, not StateDeclaration (9313880)
  • lazyLoad: Fix State.lazyLoad type def (9313880)
  • pushStateLocation: call listeners in url() (#24) (7c90911), closes #23

Features

  • UIRouter: Add trace global to the UIRouter object (48c5af6)
  • View: Allow targeting views on own state using viewname@. (normalizeUIViewTarget) (7078216), closes #25

3.1.0

29 Jan 23:20
Compare
Choose a tag to compare

ui-router-core changes

3.1.0 (2017-01-09)

Bug Fixes

  • UrlRouter: Use { location: 'replace' } whenever a url redirect happens (6cf9b8f)

3.0.0

08 Jan 19:49
Compare
Choose a tag to compare

ui-router-core changes

3.0.0 (2017-01-08)

Bug Fixes

  • lazyLoad: Use UrlService.match() to retry url sync after successful lazy load triggered by url (8c2461d), closes #19
  • Params: params: { foo: { raw: true } } overrides ParamType.raw (aefeabf)
  • Params: Mark all query parameters as optional (7334d98)
  • Params: Check for null in int param type is() check (aa551e4), closes #3197
  • Transition: Use { location: replace } when redirecting a transtition in response to a URL sync (23e2b78)
  • UrlService: Wire urlMatcherFactory and urlRouter functions (a7b58d6)
  • vanilla: vanilla locations: do not parse "empty string" query key parameter (f949480)

Features

  • (CoreServices) Move location and locationConfig from services to UIRouter.locationService and UIRouter.locationConfig. (029fb00)
  • Built-in string parameter type no longer encodes slashes as ~2F nor tildes as ~~ (72bb2d8)
  • Move html5Mode and hashPrefix from LocationServices to LocationConfig interface (9d316a7)
  • Order URL Matching Rules by priority, not registration order (eb2f5d7)
  • Path/Query parameters no longer default to string param type (72bb2d8)
  • Remove getResolveValue and getResolvable methods from Transition in favor of injector().get() and injector().getAsync() (111d259)
  • Replace LocationServices.setUrl with LocationServices.url (4c39dcb)
  • Replace UrlRouterProvider/UrlRouter with just UrlRouter (fddd1e2)
  • hash: Change the hash parameter type ('#') to inherit: false so it is cleared out when another transition occurs. (849f84f), closes #3245 #3218 #3017
  • LocationServices: Add a parts() method which returns the URL parts as an object (32e64f0)
  • Params: Add path and query param types (72bb2d8)
  • Params: add option to use generic type for Transition.params (#17) (eb12ec8), closes #16
  • Params: Allow inherit: false specified per parameter or type (849f84f)
  • Resolve: implement NOWAIT policy: Do not wait for resolves before completing a transition. (05d4c73), closes #3243 #2691
  • Transition: Add Transition.originalTransition() to return the initial transition in a chain of redirects (4fe39e3)
  • Transition: Allow injector() to retrieve resolves for the exiting states/path (df502e8)
  • Transition: Allow a plain object ResolvableLiteral in Transition.addResolvable (ad9ae81)
  • Transition: Make Transition.params() immutable to avoid confusion about mutability (0162212)
  • UrlMatcher: Add comparison function by UrlMatcher specificity (eb2f5d7)
  • UrlRouter: sort url rules by specificity, not by registration order. (eb2f5d7)
  • UrlService: allow eager or lazy binding of location objects during construction (7e0a8af)
  • UrlService: Add match(): given a URL, return the best matching Url Rule (32e64f0)

BREAKING CHANGES

BREAKING CHANGE: Remove getResolveValue and getResolvable methods from Transition in favor of injector().get() and injector().getAsync()

In beta.3, the Transition APIs: injector(), getResolvable, and getResolveValue duplicated functionality.

Instead of:

trans.getResolveValue('myResolve');

use:

trans.injector().get('myResolve')

BREAKING CHANGE: Order URL Matching Rules by priority, not registration order

URL Rules can come from registered states' .urls, calling .when(), or calling .rule().
It's possible that two or more URL Rules could match the URL.

Previously

Previously, url rules were matched in the order in which they were registered.
The rule which was registered first would handle the URL change.

Now

Now, the URL rules are sorted according to a sort function.
More specific rules are preferred over less specific rules

Why

It's possible to have multiple url rules that match a given URL.
Consider the following states:

  • { name: 'books', url: '/books/index' }''
  • { name: 'book', url: '/books/:bookId' }''

Both states match when the url is /books/index.
Additionally, you might have some custom url rewrite rules such as:

.when('/books/list', '/books/index').

The book state also matches when the rewrite rule is matched.

Previously, we simply used the first rule that matched. However, now that lazy loading is officially supported, it can be difficult for developers to ensure the rules are registered in the right order.

Instead, we now prioritize url rules by how specific they are. More specific rules are matched earlier than less specific rules.
We split the path on /. A static segment (such as index in the example) is more specific than a parameter (such as:bookId).

More Details

The built-in rule sorting function (see UrlRouter.defaultRuleSortFn) sorts rules in this order:

  • Explicit priority: .when('/foo', '/bar', { priority: 1 }) (default priority is 0)
  • Rule Type:
    • UrlMatchers first (registered states and .when(string, ...))
    • then regular Expressions (.when(regexp, ...))
    • finally, everything else (.rule())
  • UrlMatcher specificity: static path segments are more specific than variables (see UrlMatcher.compare)
  • Registration order (except for UrlMatcher based rules)

For complete control, a custom sort function can be registered with UrlService.rules.sort(sortFn)

Query params

Because query parameters are optional, they are not considered during sorting.
For example, both these rules will match when the url is '/foo/bar':

.when('/foo/bar', doSomething);
.when('/foo/bar?queryparam', doSomethingElse);

To choose the most specific rule, we match both rules, then choose the rule with the "best ratio" of matched optional parameters (see UrlRuleFactory.fromUrlMatcher)

This allows child states to be defined with only query params for a URL.
The state only activates when the query parameter is present.

.state('parent', { url: '/parent' });
.state('parent.child', { url: '?queryParam' });

Restoring the previous behavior

For backwards compatibility, register a sort function which sorts by the registration order:

myApp.config(function ($urlServiceProvider) {

  function sortByRegistrationOrder(a, b) {
   return a.$id - b.$id;
  }

  $urlServiceProvider.rules.sort(sortByRegistrationOrder);

});

BREAKING CHANGE: Replace LocationServices.setUrl with LocationServices.url

This makes url() a getter/setter. It also adds the optional state parameter to pass through to the browser history when using pushstate.
End users should not notice this change, but plugin authors may.

BREAKING CHANGE: Replace UrlRouterProvider/UrlRouter with just UrlRouter

The configuration functions from the provider object have been integrated into the normal UrlRouter object.
The UIRouter object no longer has a uriRouterProvider, but the equivalent functions can be found on uiRouter

One difference between the old functions on urlRouterProvider and the new ones on uriRouter is that new functions do not accept injectable functions.

BREAKING CHANGE: Built-in string parameter type no longer encodes slashes as ~2F nor tildes as ~~

Previously, the string parameter type pre-encoded tilde chars (~) as two tilde chars (~~) and slashes (/) as ~2F.

Now, the string parameter type does not pre-encode slashes nor tildes.
If you rely on the previous encoding, create a custom parameter type that implements the behavior:

urlMatcherFactory.type('tildes', {
  encode: (val: any) =>
      val != null ? val.toString().replace(/(~|\/)/g, m => ({ '~': '~~', '/': '~2F' }[m])) : val;
  decode: (val: string) =>
      val != null ? val.toString().replace(/(~~|~2F)/g, m => ({ '~~': '~', '~2F': '/' }[m])) : val;
  pattern: /[^/]*/
});

BREAKING CHANGE: Path/Query parameters no longer default to string param type

Previously, if a url parameter's type was not specified (in either the path or query), it defaulted to the string type.

Now, path parame...

Read more