@angular-wave/angular.ts 0.0.11 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/dist/angular-ts.esm.js +1 -1
  2. package/dist/angular-ts.umd.js +1 -1
  3. package/package.json +4 -1
  4. package/src/exts/messages.md +30 -30
  5. package/src/index.js +1 -0
  6. package/src/public.js +2 -0
  7. package/src/router/adapter/directives/stateDirectives.js +695 -0
  8. package/src/router/adapter/directives/viewDirective.js +514 -0
  9. package/src/router/adapter/injectables.js +314 -0
  10. package/src/router/adapter/interface.js +1 -0
  11. package/src/router/adapter/locationServices.js +84 -0
  12. package/src/router/adapter/services.js +126 -0
  13. package/src/router/adapter/stateFilters.js +43 -0
  14. package/src/router/adapter/stateProvider.js +137 -0
  15. package/src/router/adapter/statebuilders/onEnterExitRetain.js +30 -0
  16. package/src/router/adapter/statebuilders/views.js +146 -0
  17. package/src/router/adapter/templateFactory.js +218 -0
  18. package/src/router/adapter/viewScroll.js +31 -0
  19. package/src/router/core/common/common.js +496 -0
  20. package/src/router/core/common/coreservices.js +15 -0
  21. package/src/router/core/common/glob.js +75 -0
  22. package/src/router/core/common/hof.js +194 -0
  23. package/src/router/core/common/predicates.js +44 -0
  24. package/src/router/core/common/queue.js +41 -0
  25. package/src/router/core/common/safeConsole.js +38 -0
  26. package/src/router/core/common/strings.js +141 -0
  27. package/src/router/core/common/trace.js +232 -0
  28. package/src/router/core/globals.js +29 -0
  29. package/src/router/core/hooks/coreResolvables.js +33 -0
  30. package/src/router/core/hooks/ignoredTransition.js +25 -0
  31. package/src/router/core/hooks/invalidTransition.js +14 -0
  32. package/src/router/core/hooks/lazyLoad.js +102 -0
  33. package/src/router/core/hooks/onEnterExitRetain.js +55 -0
  34. package/src/router/core/hooks/redirectTo.js +36 -0
  35. package/src/router/core/hooks/resolve.js +57 -0
  36. package/src/router/core/hooks/updateGlobals.js +30 -0
  37. package/src/router/core/hooks/url.js +25 -0
  38. package/src/router/core/hooks/views.js +39 -0
  39. package/src/router/core/interface.js +3 -0
  40. package/src/router/core/params/README.md +8 -0
  41. package/src/router/core/params/param.js +232 -0
  42. package/src/router/core/params/paramType.js +139 -0
  43. package/src/router/core/params/paramTypes.js +163 -0
  44. package/src/router/core/params/stateParams.js +35 -0
  45. package/src/router/core/path/pathNode.js +77 -0
  46. package/src/router/core/path/pathUtils.js +199 -0
  47. package/src/router/core/resolve/interface.js +10 -0
  48. package/src/router/core/resolve/resolvable.js +124 -0
  49. package/src/router/core/resolve/resolveContext.js +211 -0
  50. package/src/router/core/router.js +203 -0
  51. package/src/router/core/state/README.md +21 -0
  52. package/src/router/core/state/stateBuilder.js +332 -0
  53. package/src/router/core/state/stateMatcher.js +65 -0
  54. package/src/router/core/state/stateObject.js +117 -0
  55. package/src/router/core/state/stateQueueManager.js +89 -0
  56. package/src/router/core/state/stateRegistry.js +175 -0
  57. package/src/router/core/state/stateService.js +592 -0
  58. package/src/router/core/state/targetState.js +159 -0
  59. package/src/router/core/transition/hookBuilder.js +127 -0
  60. package/src/router/core/transition/hookRegistry.js +175 -0
  61. package/src/router/core/transition/interface.js +14 -0
  62. package/src/router/core/transition/rejectFactory.js +122 -0
  63. package/src/router/core/transition/transition.js +739 -0
  64. package/src/router/core/transition/transitionEventType.js +27 -0
  65. package/src/router/core/transition/transitionHook.js +199 -0
  66. package/src/router/core/transition/transitionService.js +311 -0
  67. package/src/router/core/url/interface.js +1 -0
  68. package/src/router/core/url/urlConfig.js +165 -0
  69. package/src/router/core/url/urlMatcher.js +548 -0
  70. package/src/router/core/url/urlMatcherFactory.js +123 -0
  71. package/src/router/core/url/urlRouter.js +115 -0
  72. package/src/router/core/url/urlRule.js +202 -0
  73. package/src/router/core/url/urlRules.js +348 -0
  74. package/src/router/core/url/urlService.js +268 -0
  75. package/src/router/core/view/interface.js +1 -0
  76. package/src/router/core/view/view.js +312 -0
  77. package/src/router/router.js +58 -0
  78. package/test/module-test.html +6 -2
  79. package/test/module-test.js +0 -0
@@ -0,0 +1,27 @@
1
+ import { TransitionHook } from "./transitionHook";
2
+ /**
3
+ * This class defines a type of hook, such as `onBefore` or `onEnter`.
4
+ * Plugins can define custom hook types, such as sticky states does for `onInactive`.
5
+ */
6
+ export class TransitionEventType {
7
+ /* tslint:disable:no-inferrable-types */
8
+ constructor(
9
+ name,
10
+ hookPhase,
11
+ hookOrder,
12
+ criteriaMatchPath,
13
+ reverseSort = false,
14
+ getResultHandler = TransitionHook.HANDLE_RESULT,
15
+ getErrorHandler = TransitionHook.REJECT_ERROR,
16
+ synchronous = false,
17
+ ) {
18
+ this.name = name;
19
+ this.hookPhase = hookPhase;
20
+ this.hookOrder = hookOrder;
21
+ this.criteriaMatchPath = criteriaMatchPath;
22
+ this.reverseSort = reverseSort;
23
+ this.getResultHandler = getResultHandler;
24
+ this.getErrorHandler = getErrorHandler;
25
+ this.synchronous = synchronous;
26
+ }
27
+ }
@@ -0,0 +1,199 @@
1
+ import { TransitionHookPhase } from "./interface";
2
+ import { defaults, noop, silentRejection } from "../common/common";
3
+ import { fnToString, maxLength } from "../common/strings";
4
+ import { isPromise } from "../common/predicates";
5
+ import { is, parse } from "../common/hof";
6
+ import { trace } from "../common/trace";
7
+ import { services } from "../common/coreservices";
8
+ import { Rejection } from "./rejectFactory";
9
+ import { TargetState } from "../state/targetState";
10
+ const defaultOptions = {
11
+ current: noop,
12
+ transition: null,
13
+ traceData: {},
14
+ bind: null,
15
+ };
16
+ export class TransitionHook {
17
+ /**
18
+ * Chains together an array of TransitionHooks.
19
+ *
20
+ * Given a list of [[TransitionHook]] objects, chains them together.
21
+ * Each hook is invoked after the previous one completes.
22
+ *
23
+ * #### Example:
24
+ * ```js
25
+ * var hooks: TransitionHook[] = getHooks();
26
+ * let promise: Promise<any> = TransitionHook.chain(hooks);
27
+ *
28
+ * promise.then(handleSuccess, handleError);
29
+ * ```
30
+ *
31
+ * @param hooks the list of hooks to chain together
32
+ * @param waitFor if provided, the chain is `.then()`'ed off this promise
33
+ * @returns a `Promise` for sequentially invoking the hooks (in order)
34
+ */
35
+ static chain(hooks, waitFor) {
36
+ // Chain the next hook off the previous
37
+ const createHookChainR = (prev, nextHook) =>
38
+ prev.then(() => nextHook.invokeHook());
39
+ return hooks.reduce(createHookChainR, waitFor || services.$q.when());
40
+ }
41
+ /**
42
+ * Invokes all the provided TransitionHooks, in order.
43
+ * Each hook's return value is checked.
44
+ * If any hook returns a promise, then the rest of the hooks are chained off that promise, and the promise is returned.
45
+ * If no hook returns a promise, then all hooks are processed synchronously.
46
+ *
47
+ * @param hooks the list of TransitionHooks to invoke
48
+ * @param doneCallback a callback that is invoked after all the hooks have successfully completed
49
+ *
50
+ * @returns a promise for the async result, or the result of the callback
51
+ */
52
+ static invokeHooks(hooks, doneCallback) {
53
+ for (let idx = 0; idx < hooks.length; idx++) {
54
+ const hookResult = hooks[idx].invokeHook();
55
+ if (isPromise(hookResult)) {
56
+ const remainingHooks = hooks.slice(idx + 1);
57
+ return TransitionHook.chain(remainingHooks, hookResult).then(
58
+ doneCallback,
59
+ );
60
+ }
61
+ }
62
+ return doneCallback();
63
+ }
64
+ /**
65
+ * Run all TransitionHooks, ignoring their return value.
66
+ */
67
+ static runAllHooks(hooks) {
68
+ hooks.forEach((hook) => hook.invokeHook());
69
+ }
70
+ constructor(transition, stateContext, registeredHook, options) {
71
+ this.transition = transition;
72
+ this.stateContext = stateContext;
73
+ this.registeredHook = registeredHook;
74
+ this.options = options;
75
+ this.isSuperseded = () =>
76
+ this.type.hookPhase === TransitionHookPhase.RUN &&
77
+ !this.options.transition.isActive();
78
+ this.options = defaults(options, defaultOptions);
79
+ this.type = registeredHook.eventType;
80
+ }
81
+ logError(err) {
82
+ this.transition.router.stateService.defaultErrorHandler()(err);
83
+ }
84
+ invokeHook() {
85
+ const hook = this.registeredHook;
86
+ if (hook._deregistered) return;
87
+ const notCurrent = this.getNotCurrentRejection();
88
+ if (notCurrent) return notCurrent;
89
+ const options = this.options;
90
+ trace.traceHookInvocation(this, this.transition, options);
91
+ const invokeCallback = () =>
92
+ hook.callback.call(options.bind, this.transition, this.stateContext);
93
+ const normalizeErr = (err) => Rejection.normalize(err).toPromise();
94
+ const handleError = (err) => hook.eventType.getErrorHandler(this)(err);
95
+ const handleResult = (result) =>
96
+ hook.eventType.getResultHandler(this)(result);
97
+ try {
98
+ const result = invokeCallback();
99
+ if (!this.type.synchronous && isPromise(result)) {
100
+ return result.catch(normalizeErr).then(handleResult, handleError);
101
+ } else {
102
+ return handleResult(result);
103
+ }
104
+ } catch (err) {
105
+ // If callback throws (synchronously)
106
+ return handleError(Rejection.normalize(err));
107
+ } finally {
108
+ if (hook.invokeLimit && ++hook.invokeCount >= hook.invokeLimit) {
109
+ hook.deregister();
110
+ }
111
+ }
112
+ }
113
+ /**
114
+ * This method handles the return value of a Transition Hook.
115
+ *
116
+ * A hook can return false (cancel), a TargetState (redirect),
117
+ * or a promise (which may later resolve to false or a redirect)
118
+ *
119
+ * This also handles "transition superseded" -- when a new transition
120
+ * was started while the hook was still running
121
+ */
122
+ handleHookResult(result) {
123
+ const notCurrent = this.getNotCurrentRejection();
124
+ if (notCurrent) return notCurrent;
125
+ // Hook returned a promise
126
+ if (isPromise(result)) {
127
+ // Wait for the promise, then reprocess with the resulting value
128
+ return result.then((val) => this.handleHookResult(val));
129
+ }
130
+ trace.traceHookResult(result, this.transition, this.options);
131
+ // Hook returned false
132
+ if (result === false) {
133
+ // Abort this Transition
134
+ return Rejection.aborted("Hook aborted transition").toPromise();
135
+ }
136
+ const isTargetState = is(TargetState);
137
+ // hook returned a TargetState
138
+ if (isTargetState(result)) {
139
+ // Halt the current Transition and redirect (a new Transition) to the TargetState.
140
+ return Rejection.redirected(result).toPromise();
141
+ }
142
+ }
143
+ /**
144
+ * Return a Rejection promise if the transition is no longer current due
145
+ * to a stopped router (disposed), or a new transition has started and superseded this one.
146
+ */
147
+ getNotCurrentRejection() {
148
+ const router = this.transition.router;
149
+ // The router is stopped
150
+ if (router._disposed) {
151
+ return Rejection.aborted(
152
+ `UIRouter instance #${router.$id} has been stopped (disposed)`,
153
+ ).toPromise();
154
+ }
155
+ if (this.transition._aborted) {
156
+ return Rejection.aborted().toPromise();
157
+ }
158
+ // This transition is no longer current.
159
+ // Another transition started while this hook was still running.
160
+ if (this.isSuperseded()) {
161
+ // Abort this transition
162
+ return Rejection.superseded(this.options.current()).toPromise();
163
+ }
164
+ }
165
+ toString() {
166
+ const { options, registeredHook } = this;
167
+ const event = parse("traceData.hookType")(options) || "internal",
168
+ context =
169
+ parse("traceData.context.state.name")(options) ||
170
+ parse("traceData.context")(options) ||
171
+ "unknown",
172
+ name = fnToString(registeredHook.callback);
173
+ return `${event} context: ${context}, ${maxLength(200, name)}`;
174
+ }
175
+ }
176
+ /**
177
+ * These GetResultHandler(s) are used by [[invokeHook]] below
178
+ * Each HookType chooses a GetResultHandler (See: [[TransitionService._defineCoreEvents]])
179
+ */
180
+ TransitionHook.HANDLE_RESULT = (hook) => (result) =>
181
+ hook.handleHookResult(result);
182
+ /**
183
+ * If the result is a promise rejection, log it.
184
+ * Otherwise, ignore the result.
185
+ */
186
+ TransitionHook.LOG_REJECTED_RESULT = (hook) => (result) => {
187
+ isPromise(result) &&
188
+ result.catch((err) => hook.logError(Rejection.normalize(err)));
189
+ return undefined;
190
+ };
191
+ /**
192
+ * These GetErrorHandler(s) are used by [[invokeHook]] below
193
+ * Each HookType chooses a GetErrorHandler (See: [[TransitionService._defineCoreEvents]])
194
+ */
195
+ TransitionHook.LOG_ERROR = (hook) => (error) => hook.logError(error);
196
+ TransitionHook.REJECT_ERROR = (hook) => (error) => silentRejection(error);
197
+ TransitionHook.THROW_ERROR = (hook) => (error) => {
198
+ throw error;
199
+ };
@@ -0,0 +1,311 @@
1
+ import { TransitionHookScope, TransitionHookPhase } from "./interface";
2
+ import { Transition } from "./transition";
3
+ import { makeEvent } from "./hookRegistry";
4
+ import {
5
+ registerAddCoreResolvables,
6
+ treeChangesCleanup,
7
+ } from "../hooks/coreResolvables";
8
+ import { registerRedirectToHook } from "../hooks/redirectTo";
9
+ import {
10
+ registerOnExitHook,
11
+ registerOnRetainHook,
12
+ registerOnEnterHook,
13
+ } from "../hooks/onEnterExitRetain";
14
+ import {
15
+ registerEagerResolvePath,
16
+ registerLazyResolveState,
17
+ registerResolveRemaining,
18
+ } from "../hooks/resolve";
19
+ import {
20
+ registerLoadEnteringViews,
21
+ registerActivateViews,
22
+ } from "../hooks/views";
23
+ import { registerUpdateGlobalState } from "../hooks/updateGlobals";
24
+ import { registerUpdateUrl } from "../hooks/url";
25
+ import { registerLazyLoadHook } from "../hooks/lazyLoad";
26
+ import { TransitionEventType } from "./transitionEventType";
27
+ import { TransitionHook } from "./transitionHook";
28
+ import { isDefined } from "../common/predicates";
29
+ import { removeFrom, createProxyFunctions } from "../common/common";
30
+ import { val } from "../common/hof";
31
+ import { registerIgnoredTransitionHook } from "../hooks/ignoredTransition";
32
+ import { registerInvalidTransitionHook } from "../hooks/invalidTransition";
33
+ /**
34
+ * The default [[Transition]] options.
35
+ *
36
+ * Include this object when applying custom defaults:
37
+ * let reloadOpts = { reload: true, notify: true }
38
+ * let options = defaults(theirOpts, customDefaults, defaultOptions);
39
+ */
40
+ export let defaultTransOpts = {
41
+ location: true,
42
+ relative: null,
43
+ inherit: false,
44
+ notify: true,
45
+ reload: false,
46
+ supercede: true,
47
+ custom: {},
48
+ current: () => null,
49
+ source: "unknown",
50
+ };
51
+ /**
52
+ * This class provides services related to Transitions.
53
+ *
54
+ * - Most importantly, it allows global Transition Hooks to be registered.
55
+ * - It allows the default transition error handler to be set.
56
+ * - It also has a factory function for creating new [[Transition]] objects, (used internally by the [[StateService]]).
57
+ *
58
+ * At bootstrap, [[UIRouter]] creates a single instance (singleton) of this class.
59
+ *
60
+ * This API is located at `router.transitionService` ([[UIRouter.transitionService]])
61
+ */
62
+ export class TransitionService {
63
+ /** @internal */
64
+ constructor(_router) {
65
+ /** @internal */
66
+ this._transitionCount = 0;
67
+ /** The transition hook types, such as `onEnter`, `onStart`, etc */
68
+ this._eventTypes = [];
69
+ /** @internal The registered transition hooks */
70
+ this._registeredHooks = {};
71
+ /** The paths on a criteria object */
72
+ this._criteriaPaths = {};
73
+ this._router = _router;
74
+ this.$view = _router.viewService;
75
+ this._deregisterHookFns = {};
76
+ this._pluginapi = createProxyFunctions(val(this), {}, val(this), [
77
+ "_definePathType",
78
+ "_defineEvent",
79
+ "_getPathTypes",
80
+ "_getEvents",
81
+ "getHooks",
82
+ ]);
83
+ this._defineCorePaths();
84
+ this._defineCoreEvents();
85
+ this._registerCoreTransitionHooks();
86
+ _router.globals.successfulTransitions.onEvict(treeChangesCleanup);
87
+ }
88
+ /**
89
+ * Registers a [[TransitionHookFn]], called *while a transition is being constructed*.
90
+ *
91
+ * Registers a transition lifecycle hook, which is invoked during transition construction.
92
+ *
93
+ * This low level hook should only be used by plugins.
94
+ * This can be a useful time for plugins to add resolves or mutate the transition as needed.
95
+ * The Sticky States plugin uses this hook to modify the treechanges.
96
+ *
97
+ * ### Lifecycle
98
+ *
99
+ * `onCreate` hooks are invoked *while a transition is being constructed*.
100
+ *
101
+ * ### Return value
102
+ *
103
+ * The hook's return value is ignored
104
+ *
105
+ * @internal
106
+ * @param criteria defines which Transitions the Hook should be invoked for.
107
+ * @param callback the hook function which will be invoked.
108
+ * @param options the registration options
109
+ * @returns a function which deregisters the hook.
110
+ */
111
+ onCreate(criteria, callback, options) {
112
+ return;
113
+ }
114
+ /** @inheritdoc */
115
+ onBefore(criteria, callback, options) {
116
+ return;
117
+ }
118
+ /** @inheritdoc */
119
+ onStart(criteria, callback, options) {
120
+ return;
121
+ }
122
+ /** @inheritdoc */
123
+ onExit(criteria, callback, options) {
124
+ return;
125
+ }
126
+ /** @inheritdoc */
127
+ onRetain(criteria, callback, options) {
128
+ return;
129
+ }
130
+ /** @inheritdoc */
131
+ onEnter(criteria, callback, options) {
132
+ return;
133
+ }
134
+ /** @inheritdoc */
135
+ onFinish(criteria, callback, options) {
136
+ return;
137
+ }
138
+ /** @inheritdoc */
139
+ onSuccess(criteria, callback, options) {
140
+ return;
141
+ }
142
+ /** @inheritdoc */
143
+ onError(criteria, callback, options) {
144
+ return;
145
+ }
146
+ /**
147
+ * dispose
148
+ * @internal
149
+ */
150
+ dispose(router) {
151
+ Object.values(this._registeredHooks).forEach((hooksArray) =>
152
+ hooksArray.forEach((hook) => {
153
+ hook._deregistered = true;
154
+ removeFrom(hooksArray, hook);
155
+ }),
156
+ );
157
+ }
158
+ /**
159
+ * Creates a new [[Transition]] object
160
+ *
161
+ * This is a factory function for creating new Transition objects.
162
+ * It is used internally by the [[StateService]] and should generally not be called by application code.
163
+ *
164
+ * @internal
165
+ * @param fromPath the path to the current state (the from state)
166
+ * @param targetState the target state (destination)
167
+ * @returns a Transition
168
+ */
169
+ create(fromPath, targetState) {
170
+ return new Transition(fromPath, targetState, this._router);
171
+ }
172
+ /** @internal */
173
+ _defineCoreEvents() {
174
+ const Phase = TransitionHookPhase;
175
+ const TH = TransitionHook;
176
+ const paths = this._criteriaPaths;
177
+ const NORMAL_SORT = false,
178
+ REVERSE_SORT = true;
179
+ const SYNCHRONOUS = true;
180
+ this._defineEvent(
181
+ "onCreate",
182
+ Phase.CREATE,
183
+ 0,
184
+ paths.to,
185
+ NORMAL_SORT,
186
+ TH.LOG_REJECTED_RESULT,
187
+ TH.THROW_ERROR,
188
+ SYNCHRONOUS,
189
+ );
190
+ this._defineEvent("onBefore", Phase.BEFORE, 0, paths.to);
191
+ this._defineEvent("onStart", Phase.RUN, 0, paths.to);
192
+ this._defineEvent("onExit", Phase.RUN, 100, paths.exiting, REVERSE_SORT);
193
+ this._defineEvent("onRetain", Phase.RUN, 200, paths.retained);
194
+ this._defineEvent("onEnter", Phase.RUN, 300, paths.entering);
195
+ this._defineEvent("onFinish", Phase.RUN, 400, paths.to);
196
+ this._defineEvent(
197
+ "onSuccess",
198
+ Phase.SUCCESS,
199
+ 0,
200
+ paths.to,
201
+ NORMAL_SORT,
202
+ TH.LOG_REJECTED_RESULT,
203
+ TH.LOG_ERROR,
204
+ SYNCHRONOUS,
205
+ );
206
+ this._defineEvent(
207
+ "onError",
208
+ Phase.ERROR,
209
+ 0,
210
+ paths.to,
211
+ NORMAL_SORT,
212
+ TH.LOG_REJECTED_RESULT,
213
+ TH.LOG_ERROR,
214
+ SYNCHRONOUS,
215
+ );
216
+ }
217
+ /** @internal */
218
+ _defineCorePaths() {
219
+ const { STATE, TRANSITION } = TransitionHookScope;
220
+ this._definePathType("to", TRANSITION);
221
+ this._definePathType("from", TRANSITION);
222
+ this._definePathType("exiting", STATE);
223
+ this._definePathType("retained", STATE);
224
+ this._definePathType("entering", STATE);
225
+ }
226
+ /** @internal */
227
+ _defineEvent(
228
+ name,
229
+ hookPhase,
230
+ hookOrder,
231
+ criteriaMatchPath,
232
+ reverseSort = false,
233
+ getResultHandler = TransitionHook.HANDLE_RESULT,
234
+ getErrorHandler = TransitionHook.REJECT_ERROR,
235
+ synchronous = false,
236
+ ) {
237
+ const eventType = new TransitionEventType(
238
+ name,
239
+ hookPhase,
240
+ hookOrder,
241
+ criteriaMatchPath,
242
+ reverseSort,
243
+ getResultHandler,
244
+ getErrorHandler,
245
+ synchronous,
246
+ );
247
+ this._eventTypes.push(eventType);
248
+ makeEvent(this, this, eventType);
249
+ }
250
+ /** @internal */
251
+ _getEvents(phase) {
252
+ const transitionHookTypes = isDefined(phase)
253
+ ? this._eventTypes.filter((type) => type.hookPhase === phase)
254
+ : this._eventTypes.slice();
255
+ return transitionHookTypes.sort((l, r) => {
256
+ const cmpByPhase = l.hookPhase - r.hookPhase;
257
+ return cmpByPhase === 0 ? l.hookOrder - r.hookOrder : cmpByPhase;
258
+ });
259
+ }
260
+ /**
261
+ * Adds a Path to be used as a criterion against a TreeChanges path
262
+ *
263
+ * For example: the `exiting` path in [[HookMatchCriteria]] is a STATE scoped path.
264
+ * It was defined by calling `defineTreeChangesCriterion('exiting', TransitionHookScope.STATE)`
265
+ * Each state in the exiting path is checked against the criteria and returned as part of the match.
266
+ *
267
+ * Another example: the `to` path in [[HookMatchCriteria]] is a TRANSITION scoped path.
268
+ * It was defined by calling `defineTreeChangesCriterion('to', TransitionHookScope.TRANSITION)`
269
+ * Only the tail of the `to` path is checked against the criteria and returned as part of the match.
270
+ *
271
+ * @internal
272
+ */
273
+ _definePathType(name, hookScope) {
274
+ this._criteriaPaths[name] = { name, scope: hookScope };
275
+ }
276
+ /** @internal */
277
+ // tslint:disable-next-line
278
+ _getPathTypes() {
279
+ return this._criteriaPaths;
280
+ }
281
+ /** @internal */
282
+ getHooks(hookName) {
283
+ return this._registeredHooks[hookName];
284
+ }
285
+ /** @internal */
286
+ _registerCoreTransitionHooks() {
287
+ const fns = this._deregisterHookFns;
288
+ fns.addCoreResolves = registerAddCoreResolvables(this);
289
+ fns.ignored = registerIgnoredTransitionHook(this);
290
+ fns.invalid = registerInvalidTransitionHook(this);
291
+ // Wire up redirectTo hook
292
+ fns.redirectTo = registerRedirectToHook(this);
293
+ // Wire up onExit/Retain/Enter state hooks
294
+ fns.onExit = registerOnExitHook(this);
295
+ fns.onRetain = registerOnRetainHook(this);
296
+ fns.onEnter = registerOnEnterHook(this);
297
+ // Wire up Resolve hooks
298
+ fns.eagerResolve = registerEagerResolvePath(this);
299
+ fns.lazyResolve = registerLazyResolveState(this);
300
+ fns.resolveAll = registerResolveRemaining(this);
301
+ // Wire up the View management hooks
302
+ fns.loadViews = registerLoadEnteringViews(this);
303
+ fns.activateViews = registerActivateViews(this);
304
+ // Updates global state after a transition
305
+ fns.updateGlobals = registerUpdateGlobalState(this);
306
+ // After globals.current is updated at priority: 10000
307
+ fns.updateUrl = registerUpdateUrl(this);
308
+ // Lazy load state trees
309
+ fns.lazyLoad = registerLazyLoadHook(this);
310
+ }
311
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,165 @@
1
+ import { ParamTypes } from "../../core/params/paramTypes";
2
+ import { isDefined, isString } from "../../../core/utils";
3
+ /**
4
+ * An API to customize the URL behavior and retrieve URL configuration
5
+ *
6
+ * This API is used to customize the behavior of the URL.
7
+ * This includes optional trailing slashes ([[strictMode]]), case sensitivity ([[caseInsensitive]]),
8
+ * and custom parameter encoding (custom [[type]]).
9
+ *
10
+ * It also has information about the location (url) configuration such as [[port]] and [[baseHref]].
11
+ * This information can be used to build absolute URLs, such as
12
+ * `https://example.com:443/basepath/state/substate?param1=a#hashvalue`;
13
+ *
14
+ * This API is found at `router.urlService.config` (see: [[UIRouter.urlService]], [[URLService.config]])
15
+ */
16
+ export class UrlConfig {
17
+ /** @internal */ constructor(/** @internal */ router) {
18
+ this.router = router;
19
+ /** @internal */ this.paramTypes = new ParamTypes();
20
+ /** @internal */ this._decodeParams = true;
21
+ /** @internal */ this._isCaseInsensitive = false;
22
+ /** @internal */ this._isStrictMode = true;
23
+ /** @internal */ this._defaultSquashPolicy = false;
24
+ /** @internal */ this.dispose = () => this.paramTypes.dispose();
25
+ // Delegate these calls to the current LocationConfig implementation
26
+ /**
27
+ * Gets the base Href, e.g., `http://localhost/approot/`
28
+ *
29
+ * @return the application's base href
30
+ */
31
+ this.baseHref = () => this.router.locationConfig.baseHref();
32
+ /**
33
+ * Gets or sets the hashPrefix
34
+ *
35
+ * This only applies when not running in [[html5Mode]] (pushstate mode)
36
+ *
37
+ * If the current url is `http://localhost/app#!/uirouter/path/#anchor`, it returns `!` which is the prefix for the "hashbang" portion.
38
+ *
39
+ * @return the hash prefix
40
+ */
41
+ this.hashPrefix = (newprefix) =>
42
+ this.router.locationConfig.hashPrefix(newprefix);
43
+ /**
44
+ * Gets the host, e.g., `localhost`
45
+ *
46
+ * @return the protocol
47
+ */
48
+ this.host = () => this.router.locationConfig.host();
49
+ /**
50
+ * Returns true when running in pushstate mode
51
+ *
52
+ * @return true when running in html5 mode (pushstate mode).
53
+ */
54
+ this.html5Mode = () => this.router.locationConfig.html5Mode();
55
+ /**
56
+ * Gets the port, e.g., `80`
57
+ *
58
+ * @return the port number
59
+ */
60
+ this.port = () => this.router.locationConfig.port();
61
+ /**
62
+ * Gets the protocol, e.g., `http`
63
+ *
64
+ * @return the protocol
65
+ */
66
+ this.protocol = () => this.router.locationConfig.protocol();
67
+ }
68
+ /**
69
+ * Defines whether URL matching should be case sensitive (the default behavior), or not.
70
+ *
71
+ * #### Example:
72
+ * ```js
73
+ * // Allow case insensitive url matches
74
+ * urlService.config.caseInsensitive(true);
75
+ * ```
76
+ *
77
+ * @param value `false` to match URL in a case sensitive manner; otherwise `true`;
78
+ * @returns the current value of caseInsensitive
79
+ */
80
+ caseInsensitive(value) {
81
+ return (this._isCaseInsensitive = isDefined(value)
82
+ ? value
83
+ : this._isCaseInsensitive);
84
+ }
85
+ /**
86
+ * Sets the default behavior when generating or matching URLs with default parameter values.
87
+ *
88
+ * #### Example:
89
+ * ```js
90
+ * // Remove default parameter values from the url
91
+ * urlService.config.defaultSquashPolicy(true);
92
+ * ```
93
+ *
94
+ * @param value A string that defines the default parameter URL squashing behavior.
95
+ * - `nosquash`: When generating an href with a default parameter value, do not squash the parameter value from the URL
96
+ * - `slash`: When generating an href with a default parameter value, squash (remove) the parameter value, and, if the
97
+ * parameter is surrounded by slashes, squash (remove) one slash from the URL
98
+ * - any other string, e.g. "~": When generating an href with a default parameter value, squash (remove)
99
+ * the parameter value from the URL and replace it with this string.
100
+ * @returns the current value of defaultSquashPolicy
101
+ */
102
+ defaultSquashPolicy(value) {
103
+ if (
104
+ isDefined(value) &&
105
+ value !== true &&
106
+ value !== false &&
107
+ !isString(value)
108
+ )
109
+ throw new Error(
110
+ `Invalid squash policy: ${value}. Valid policies: false, true, arbitrary-string`,
111
+ );
112
+ return (this._defaultSquashPolicy = isDefined(value)
113
+ ? value
114
+ : this._defaultSquashPolicy);
115
+ }
116
+ /**
117
+ * Defines whether URLs should match trailing slashes, or not (the default behavior).
118
+ *
119
+ * #### Example:
120
+ * ```js
121
+ * // Allow optional trailing slashes
122
+ * urlService.config.strictMode(false);
123
+ * ```
124
+ *
125
+ * @param value `false` to match trailing slashes in URLs, otherwise `true`.
126
+ * @returns the current value of strictMode
127
+ */
128
+ strictMode(value) {
129
+ return (this._isStrictMode = isDefined(value) ? value : this._isStrictMode);
130
+ }
131
+ /**
132
+ * Creates and registers a custom [[ParamType]] object
133
+ *
134
+ * A custom parameter type can be used to generate URLs with typed parameters or custom encoding/decoding.
135
+ *
136
+ * #### Note: Register custom types *before using them* in a state definition.
137
+ *
138
+ * #### Example:
139
+ * ```js
140
+ * // Encode object parameter as JSON string
141
+ * urlService.config.type('myjson', {
142
+ * encode: (obj) => JSON.stringify(obj),
143
+ * decode: (str) => JSON.parse(str),
144
+ * is: (val) => typeof(val) === 'object',
145
+ * pattern: /[^/]+/,
146
+ * equals: (a, b) => _.isEqual(a, b),
147
+ * });
148
+ * ```
149
+ *
150
+ * See [[ParamTypeDefinition]] for more examples
151
+ *
152
+ * @param name The type name.
153
+ * @param definition The type definition. See [[ParamTypeDefinition]] for information on the values accepted.
154
+ * @param definitionFn A function that is injected before the app runtime starts.
155
+ * The result of this function should be a [[ParamTypeDefinition]].
156
+ * The result is merged into the existing `definition`.
157
+ * See [[ParamType]] for information on the values accepted.
158
+ *
159
+ * @returns if only the `name` parameter was specified: the currently registered [[ParamType]] object, or undefined
160
+ */
161
+ type(name, definition, definitionFn) {
162
+ const type = this.paramTypes.type(name, definition, definitionFn);
163
+ return !isDefined(definition) ? type : this;
164
+ }
165
+ }