1 | /**
|
2 | * # Legacy state events
|
3 | *
|
4 | * Polyfill implementation of the UI-Router 0.2.x state events.
|
5 | *
|
6 | * The 0.2.x state events are deprecated. We recommend moving to Transition Hooks instead, as they
|
7 | * provide much more flexibility, support async, and provide the context (the Transition, etc) necessary
|
8 | * to implement meaningful application behaviors.
|
9 | *
|
10 | * To enable these state events, include the `stateEvents.js` file in your project, e.g.,
|
11 | * ```
|
12 | * <script src="stateEvents.js"></script>
|
13 | * ```
|
14 | * and also make sure you depend on the `ui.router.state.events` angular module, e.g.,
|
15 | * ```
|
16 | * angular.module("myApplication", ['ui.router', 'ui.router.state.events']
|
17 | * ```
|
18 | *
|
19 | * @publicapi @module ng1_state_events
|
20 | */ /** */
|
21 | import { ng as angular } from '../angular';
|
22 | /**
|
23 | * An event broadcast on `$rootScope` when the state transition **begins**.
|
24 | *
|
25 | * ### Deprecation warning: use [[TransitionService.onStart]] instead
|
26 | *
|
27 | * You can use `event.preventDefault()`
|
28 | * to prevent the transition from happening and then the transition promise will be
|
29 | * rejected with a `'transition prevented'` value.
|
30 | *
|
31 | * Additional arguments to the event handler are provided:
|
32 | * - `toState`: the Transition Target state
|
33 | * - `toParams`: the Transition Target Params
|
34 | * - `fromState`: the state the transition is coming from
|
35 | * - `fromParams`: the parameters from the state the transition is coming from
|
36 | * - `options`: any Transition Options
|
37 | * - `$transition$`: the [[Transition]]
|
38 | *
|
39 | * #### Example:
|
40 | * ```js
|
41 | * $rootScope.$on('$stateChangeStart', function(event, transition) {
|
42 | * event.preventDefault();
|
43 | * // transitionTo() promise will be rejected with
|
44 | * // a 'transition prevented' error
|
45 | * })
|
46 | * ```
|
47 | *
|
48 | * @event $stateChangeStart
|
49 | * @deprecated
|
50 | */
|
51 | export var $stateChangeStart;
|
52 | /**
|
53 | * An event broadcast on `$rootScope` if a transition is **cancelled**.
|
54 | *
|
55 | * ### Deprecation warning: use [[TransitionService.onStart]] instead
|
56 | *
|
57 | * Additional arguments to the event handler are provided:
|
58 | * - `toState`: the Transition Target state
|
59 | * - `toParams`: the Transition Target Params
|
60 | * - `fromState`: the state the transition is coming from
|
61 | * - `fromParams`: the parameters from the state the transition is coming from
|
62 | * - `options`: any Transition Options
|
63 | * - `$transition$`: the [[Transition]] that was cancelled
|
64 | *
|
65 | * @event $stateChangeCancel
|
66 | * @deprecated
|
67 | */
|
68 | export var $stateChangeCancel;
|
69 | /**
|
70 | * An event broadcast on `$rootScope` once the state transition is **complete**.
|
71 | *
|
72 | * ### Deprecation warning: use [[TransitionService.onStart]] and [[Transition.promise]], or [[Transition.onSuccess]]
|
73 | *
|
74 | * Additional arguments to the event handler are provided:
|
75 | * - `toState`: the Transition Target state
|
76 | * - `toParams`: the Transition Target Params
|
77 | * - `fromState`: the state the transition is coming from
|
78 | * - `fromParams`: the parameters from the state the transition is coming from
|
79 | * - `options`: any Transition Options
|
80 | * - `$transition$`: the [[Transition]] that just succeeded
|
81 | *
|
82 | * @event $stateChangeSuccess
|
83 | * @deprecated
|
84 | */
|
85 | export var $stateChangeSuccess;
|
86 | /**
|
87 | * An event broadcast on `$rootScope` when an **error occurs** during transition.
|
88 | *
|
89 | * ### Deprecation warning: use [[TransitionService.onStart]] and [[Transition.promise]], or [[Transition.onError]]
|
90 | *
|
91 | * It's important to note that if you
|
92 | * have any errors in your resolve functions (javascript errors, non-existent services, etc)
|
93 | * they will not throw traditionally. You must listen for this $stateChangeError event to
|
94 | * catch **ALL** errors.
|
95 | *
|
96 | * Additional arguments to the event handler are provided:
|
97 | * - `toState`: the Transition Target state
|
98 | * - `toParams`: the Transition Target Params
|
99 | * - `fromState`: the state the transition is coming from
|
100 | * - `fromParams`: the parameters from the state the transition is coming from
|
101 | * - `error`: The reason the transition errored.
|
102 | * - `options`: any Transition Options
|
103 | * - `$transition$`: the [[Transition]] that errored
|
104 | *
|
105 | * @event $stateChangeError
|
106 | * @deprecated
|
107 | */
|
108 | export var $stateChangeError;
|
109 | /**
|
110 | * An event broadcast on `$rootScope` when a requested state **cannot be found** using the provided state name.
|
111 | *
|
112 | * ### Deprecation warning: use [[StateService.onInvalid]] instead
|
113 | *
|
114 | * The event is broadcast allowing any handlers a single chance to deal with the error (usually by
|
115 | * lazy-loading the unfound state). A `TargetState` object is passed to the listener handler,
|
116 | * you can see its properties in the example. You can use `event.preventDefault()` to abort the
|
117 | * transition and the promise returned from `transitionTo()` will be rejected with a
|
118 | * `'transition aborted'` error.
|
119 | *
|
120 | * Additional arguments to the event handler are provided:
|
121 | * - `unfoundState` Unfound State information. Contains: `to, toParams, options` properties.
|
122 | * - `fromState`: the state the transition is coming from
|
123 | * - `fromParams`: the parameters from the state the transition is coming from
|
124 | * - `options`: any Transition Options
|
125 | *
|
126 | * #### Example:
|
127 | * ```js
|
128 | * // somewhere, assume lazy.state has not been defined
|
129 | * $state.go("lazy.state", { a: 1, b: 2 }, { inherit: false });
|
130 | *
|
131 | * // somewhere else
|
132 | * $scope.$on('$stateNotFound', function(event, transition) {
|
133 | * function(event, unfoundState, fromState, fromParams){
|
134 | * console.log(unfoundState.to); // "lazy.state"
|
135 | * console.log(unfoundState.toParams); // {a:1, b:2}
|
136 | * console.log(unfoundState.options); // {inherit:false} + default options
|
137 | * });
|
138 | * ```
|
139 | *
|
140 | * @event $stateNotFound
|
141 | * @deprecated
|
142 | */
|
143 | export var $stateNotFound;
|
144 | (function () {
|
145 | var isFunction = angular.isFunction, isString = angular.isString;
|
146 | function applyPairs(memo, keyValTuple) {
|
147 | var key, value;
|
148 | if (Array.isArray(keyValTuple))
|
149 | key = keyValTuple[0], value = keyValTuple[1];
|
150 | if (!isString(key))
|
151 | throw new Error('invalid parameters to applyPairs');
|
152 | memo[key] = value;
|
153 | return memo;
|
154 | }
|
155 | function stateChangeStartHandler($transition$) {
|
156 | if (!$transition$.options().notify || !$transition$.valid() || $transition$.ignored())
|
157 | return;
|
158 | var $injector = $transition$.injector();
|
159 | var $stateEvents = $injector.get('$stateEvents');
|
160 | var $rootScope = $injector.get('$rootScope');
|
161 | var $state = $injector.get('$state');
|
162 | var $urlRouter = $injector.get('$urlRouter');
|
163 | var enabledEvents = $stateEvents.provider.enabled();
|
164 | var toParams = $transition$.params('to');
|
165 | var fromParams = $transition$.params('from');
|
166 | if (enabledEvents.$stateChangeSuccess) {
|
167 | var startEvent = $rootScope.$broadcast('$stateChangeStart', $transition$.to(), toParams, $transition$.from(), fromParams, $transition$.options(), $transition$);
|
168 | if (startEvent.defaultPrevented) {
|
169 | if (enabledEvents.$stateChangeCancel) {
|
170 | $rootScope.$broadcast('$stateChangeCancel', $transition$.to(), toParams, $transition$.from(), fromParams, $transition$.options(), $transition$);
|
171 | }
|
172 | // Don't update and resync url if there's been a new transition started. see issue #2238, #600
|
173 | if ($state.transition == null)
|
174 | $urlRouter.update();
|
175 | return false;
|
176 | }
|
177 | // right after global state is updated
|
178 | var successOpts = { priority: 9999 };
|
179 | $transition$.onSuccess({}, function () {
|
180 | $rootScope.$broadcast('$stateChangeSuccess', $transition$.to(), toParams, $transition$.from(), fromParams, $transition$.options(), $transition$);
|
181 | }, successOpts);
|
182 | }
|
183 | if (enabledEvents.$stateChangeError) {
|
184 | $transition$.promise['catch'](function (error) {
|
185 | if (error && (error.type === 2 /* RejectType.SUPERSEDED */ || error.type === 3) /* RejectType.ABORTED */)
|
186 | return;
|
187 | var evt = $rootScope.$broadcast('$stateChangeError', $transition$.to(), toParams, $transition$.from(), fromParams, error, $transition$.options(), $transition$);
|
188 | if (!evt.defaultPrevented) {
|
189 | $urlRouter.update();
|
190 | }
|
191 | });
|
192 | }
|
193 | }
|
194 | stateNotFoundHandler.$inject = ['$to$', '$from$', '$state', '$rootScope', '$urlRouter'];
|
195 | function stateNotFoundHandler($to$, $from$, injector) {
|
196 | var $state = injector.get('$state');
|
197 | var $rootScope = injector.get('$rootScope');
|
198 | var $urlRouter = injector.get('$urlRouter');
|
199 | var redirect = { to: $to$.identifier(), toParams: $to$.params(), options: $to$.options() };
|
200 | var e = $rootScope.$broadcast('$stateNotFound', redirect, $from$.state(), $from$.params());
|
201 | if (e.defaultPrevented || e.retry)
|
202 | $urlRouter.update();
|
203 | function redirectFn() {
|
204 | return $state.target(redirect.to, redirect.toParams, redirect.options);
|
205 | }
|
206 | if (e.defaultPrevented) {
|
207 | return false;
|
208 | }
|
209 | else if (e.retry || !!$state.get(redirect.to)) {
|
210 | return e.retry && isFunction(e.retry.then) ? e.retry.then(redirectFn) : redirectFn();
|
211 | }
|
212 | }
|
213 | $StateEventsProvider.$inject = ['$stateProvider'];
|
214 | function $StateEventsProvider($stateProvider) {
|
215 | $StateEventsProvider.prototype.instance = this;
|
216 | var runtime = false;
|
217 | var allEvents = ['$stateChangeStart', '$stateNotFound', '$stateChangeSuccess', '$stateChangeError'];
|
218 | var enabledStateEvents = allEvents.map(function (e) { return [e, true]; }).reduce(applyPairs, {});
|
219 | function assertNotRuntime() {
|
220 | if (runtime)
|
221 | throw new Error('Cannot enable events at runtime (use $stateEventsProvider');
|
222 | }
|
223 | /**
|
224 | * Enables the deprecated UI-Router 0.2.x State Events
|
225 | * [ '$stateChangeStart', '$stateNotFound', '$stateChangeSuccess', '$stateChangeError' ]
|
226 | */
|
227 | this.enable = function () {
|
228 | var events = [];
|
229 | for (var _i = 0; _i < arguments.length; _i++) {
|
230 | events[_i] = arguments[_i];
|
231 | }
|
232 | assertNotRuntime();
|
233 | if (!events || !events.length)
|
234 | events = allEvents;
|
235 | events.forEach(function (event) { return (enabledStateEvents[event] = true); });
|
236 | };
|
237 | /**
|
238 | * Disables the deprecated UI-Router 0.2.x State Events
|
239 | * [ '$stateChangeStart', '$stateNotFound', '$stateChangeSuccess', '$stateChangeError' ]
|
240 | */
|
241 | this.disable = function () {
|
242 | var events = [];
|
243 | for (var _i = 0; _i < arguments.length; _i++) {
|
244 | events[_i] = arguments[_i];
|
245 | }
|
246 | assertNotRuntime();
|
247 | if (!events || !events.length)
|
248 | events = allEvents;
|
249 | events.forEach(function (event) { return delete enabledStateEvents[event]; });
|
250 | };
|
251 | this.enabled = function () { return enabledStateEvents; };
|
252 | this.$get = $get;
|
253 | $get.$inject = ['$transitions'];
|
254 | function $get($transitions) {
|
255 | runtime = true;
|
256 | if (enabledStateEvents['$stateNotFound'])
|
257 | $stateProvider.onInvalid(stateNotFoundHandler);
|
258 | if (enabledStateEvents.$stateChangeStart)
|
259 | $transitions.onBefore({}, stateChangeStartHandler, { priority: 1000 });
|
260 | return {
|
261 | provider: $StateEventsProvider.prototype.instance,
|
262 | };
|
263 | }
|
264 | }
|
265 | angular
|
266 | .module('ui.router.state.events', ['ui.router.state'])
|
267 | .provider('$stateEvents', $StateEventsProvider)
|
268 | .run([
|
269 | '$stateEvents',
|
270 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
271 | function ($stateEvents) {
|
272 | /* Invokes $get() */
|
273 | },
|
274 | ]);
|
275 | })();
|
276 | //# sourceMappingURL=stateEvents.js.map |
\ | No newline at end of file |