Нет описания

stateEvents.js 12KB

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