@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.
- package/dist/angular-ts.esm.js +1 -1
- package/dist/angular-ts.umd.js +1 -1
- package/package.json +4 -1
- package/src/exts/messages.md +30 -30
- package/src/index.js +1 -0
- package/src/public.js +2 -0
- package/src/router/adapter/directives/stateDirectives.js +695 -0
- package/src/router/adapter/directives/viewDirective.js +514 -0
- package/src/router/adapter/injectables.js +314 -0
- package/src/router/adapter/interface.js +1 -0
- package/src/router/adapter/locationServices.js +84 -0
- package/src/router/adapter/services.js +126 -0
- package/src/router/adapter/stateFilters.js +43 -0
- package/src/router/adapter/stateProvider.js +137 -0
- package/src/router/adapter/statebuilders/onEnterExitRetain.js +30 -0
- package/src/router/adapter/statebuilders/views.js +146 -0
- package/src/router/adapter/templateFactory.js +218 -0
- package/src/router/adapter/viewScroll.js +31 -0
- package/src/router/core/common/common.js +496 -0
- package/src/router/core/common/coreservices.js +15 -0
- package/src/router/core/common/glob.js +75 -0
- package/src/router/core/common/hof.js +194 -0
- package/src/router/core/common/predicates.js +44 -0
- package/src/router/core/common/queue.js +41 -0
- package/src/router/core/common/safeConsole.js +38 -0
- package/src/router/core/common/strings.js +141 -0
- package/src/router/core/common/trace.js +232 -0
- package/src/router/core/globals.js +29 -0
- package/src/router/core/hooks/coreResolvables.js +33 -0
- package/src/router/core/hooks/ignoredTransition.js +25 -0
- package/src/router/core/hooks/invalidTransition.js +14 -0
- package/src/router/core/hooks/lazyLoad.js +102 -0
- package/src/router/core/hooks/onEnterExitRetain.js +55 -0
- package/src/router/core/hooks/redirectTo.js +36 -0
- package/src/router/core/hooks/resolve.js +57 -0
- package/src/router/core/hooks/updateGlobals.js +30 -0
- package/src/router/core/hooks/url.js +25 -0
- package/src/router/core/hooks/views.js +39 -0
- package/src/router/core/interface.js +3 -0
- package/src/router/core/params/README.md +8 -0
- package/src/router/core/params/param.js +232 -0
- package/src/router/core/params/paramType.js +139 -0
- package/src/router/core/params/paramTypes.js +163 -0
- package/src/router/core/params/stateParams.js +35 -0
- package/src/router/core/path/pathNode.js +77 -0
- package/src/router/core/path/pathUtils.js +199 -0
- package/src/router/core/resolve/interface.js +10 -0
- package/src/router/core/resolve/resolvable.js +124 -0
- package/src/router/core/resolve/resolveContext.js +211 -0
- package/src/router/core/router.js +203 -0
- package/src/router/core/state/README.md +21 -0
- package/src/router/core/state/stateBuilder.js +332 -0
- package/src/router/core/state/stateMatcher.js +65 -0
- package/src/router/core/state/stateObject.js +117 -0
- package/src/router/core/state/stateQueueManager.js +89 -0
- package/src/router/core/state/stateRegistry.js +175 -0
- package/src/router/core/state/stateService.js +592 -0
- package/src/router/core/state/targetState.js +159 -0
- package/src/router/core/transition/hookBuilder.js +127 -0
- package/src/router/core/transition/hookRegistry.js +175 -0
- package/src/router/core/transition/interface.js +14 -0
- package/src/router/core/transition/rejectFactory.js +122 -0
- package/src/router/core/transition/transition.js +739 -0
- package/src/router/core/transition/transitionEventType.js +27 -0
- package/src/router/core/transition/transitionHook.js +199 -0
- package/src/router/core/transition/transitionService.js +311 -0
- package/src/router/core/url/interface.js +1 -0
- package/src/router/core/url/urlConfig.js +165 -0
- package/src/router/core/url/urlMatcher.js +548 -0
- package/src/router/core/url/urlMatcherFactory.js +123 -0
- package/src/router/core/url/urlRouter.js +115 -0
- package/src/router/core/url/urlRule.js +202 -0
- package/src/router/core/url/urlRules.js +348 -0
- package/src/router/core/url/urlService.js +268 -0
- package/src/router/core/view/interface.js +1 -0
- package/src/router/core/view/view.js +312 -0
- package/src/router/router.js +58 -0
- package/test/module-test.html +6 -2
- 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
|
+
}
|