@angular-wave/angular.ts 0.0.27 → 0.0.28
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/README.md +1 -2
- package/dist/angular-ts.esm.js +1 -1
- package/dist/angular-ts.umd.js +1 -1
- package/e2e/unit.spec.ts +2 -1
- package/index.html +8 -9
- package/package.json +1 -1
- package/src/core/pubsub.js +329 -0
- package/src/router/hooks/core-resolvables.js +12 -11
- package/src/router/hooks/ignored-transition.js +1 -1
- package/src/router/hooks/lazy-load.js +40 -41
- package/src/router/hooks/redirect-to.js +32 -29
- package/src/router/hooks/update-globals.js +1 -1
- package/src/router/hooks/url.js +33 -24
- package/src/router/hooks/views.js +21 -20
- package/src/router/params/param-factory.js +17 -0
- package/src/router/router.js +74 -10
- package/src/router/state/state-queue-manager.js +5 -4
- package/src/router/state/state-registry.js +8 -5
- package/src/router/state/state-service.js +34 -29
- package/src/router/transition/hook-builder.js +2 -2
- package/src/router/transition/transition-hook.js +2 -1
- package/src/router/transition/transition-service.js +12 -18
- package/src/router/transition/transition.js +28 -25
- package/src/router/url/url-config.js +1 -49
- package/src/router/url/url-matcher-factory.js +10 -51
- package/src/router/url/url-router.js +27 -17
- package/src/router/url/url-rule.js +9 -13
- package/src/router/url/url-rules.js +3 -3
- package/src/router/url/url-service.js +22 -18
- package/src/router/view/view.js +3 -3
- package/src/shared/hof.js +1 -1
- package/test/angular.spec.js +1 -0
- package/test/aria/aria.spec.js +2 -1
- package/test/core/pubsub.spec.js +314 -0
- package/test/directive/bind.spec.js +2 -1
- package/test/directive/boolean.spec.js +4 -2
- package/test/directive/change.spec.js +1 -1
- package/test/directive/class.spec.js +1 -0
- package/test/directive/click.spec.js +2 -1
- package/test/directive/cloak.spec.js +1 -2
- package/test/directive/{constoller.spec.js → controller.spec.js} +1 -0
- package/test/directive/element-style.spec.js +1 -0
- package/test/directive/event.spec.js +1 -1
- package/test/directive/href.spec.js +2 -1
- package/test/directive/init.spec.js +1 -0
- package/test/directive/input.spec.js +200 -285
- package/test/directive/list.spec.js +2 -1
- package/test/directive/model.spec.js +1 -0
- package/test/directive/non-bindable.spec.js +2 -1
- package/test/directive/script.spec.js +1 -0
- package/test/directive/scrset.spec.js +2 -1
- package/test/directive/show-hide.spec.js +1 -0
- package/test/directive/src.spec.js +2 -1
- package/test/directive/style.spec.js +1 -0
- package/test/directive/switch.spec.js +2 -1
- package/test/directive/validators.spec.js +1 -1
- package/test/router/view-hook.spec.js +2 -2
- package/test/router/view-scroll.spec.js +1 -1
- package/test/router/view.spec.js +1 -1
- package/types/router/core/common/coreservices.d.ts +2 -3
- package/types/router/core/globals.d.ts +1 -4
- package/types/router/core/interface.d.ts +2 -8
- package/types/router/core/params/paramTypes.d.ts +0 -1
- package/types/router/core/router.d.ts +2 -3
- package/types/router/core/state/stateQueueManager.d.ts +1 -3
- package/types/router/core/state/stateRegistry.d.ts +0 -2
- package/types/router/core/state/stateService.d.ts +1 -2
- package/types/router/core/transition/interface.d.ts +3 -3
- package/types/router/core/transition/transitionService.d.ts +1 -2
- package/types/router/core/url/urlConfig.d.ts +1 -2
- package/types/router/core/url/urlRules.d.ts +1 -2
- package/types/router/core/url/urlService.d.ts +1 -2
- package/types/router/locationServices.d.ts +0 -1
package/e2e/unit.spec.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { test, expect } from '@playwright/test';
|
|
2
2
|
|
|
3
3
|
test('unit tests contain no errors', async ({ page }) => {
|
|
4
|
-
await page.goto('
|
|
4
|
+
await page.goto('/');
|
|
5
5
|
|
|
6
6
|
await page.content();
|
|
7
7
|
// on average 15-17 seconds
|
|
8
|
+
// TODO break these up
|
|
8
9
|
await page.waitForTimeout(20000);
|
|
9
10
|
//await page.screenshot({ path: 'errors-view.png' , fullPage: true });
|
|
10
11
|
// Expect a jasmine bar to contain 0 failures
|
package/index.html
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
<!-- <script src="dist/angular-ts.umd.js"></script> -->
|
|
18
18
|
<!-- include spec files here... -->
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
<script type="module" src="test/directive/boolean.spec.js"></script>
|
|
21
21
|
<script type="module" src="test/directive/form.spec.js"></script>
|
|
22
22
|
<script type="module" src="test/directive/input.spec.js"></script>
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
<script type="module" src="test/directive/class.spec.js"></script>
|
|
26
26
|
<script type="module" src="test/directive/click.spec.js"></script>
|
|
27
27
|
<script type="module" src="test/directive/cloak.spec.js"></script>
|
|
28
|
-
<script type="module" src="test/directive/
|
|
29
|
-
<script type="module" src="test/directive/event.spec.js"></script>
|
|
28
|
+
<script type="module" src="test/directive/controller.spec.js"></script>
|
|
29
|
+
<!-- <script type="module" src="test/directive/event.spec.js"></script>
|
|
30
30
|
<script type="module" src="test/directive/href.spec.js"></script>
|
|
31
31
|
<script type="module" src="test/directive/if.spec.js"></script>
|
|
32
32
|
<script type="module" src="test/directive/include.spec.js"></script>
|
|
@@ -95,9 +95,8 @@
|
|
|
95
95
|
<script type="module" src="test/shared/common.spec.js"></script>
|
|
96
96
|
<script type="module" src="test/shared/hof.spec.js"></script>
|
|
97
97
|
<script type="module" src="test/shared/strings.spec.js"></script>
|
|
98
|
-
<script type="module" src="test/shared/utils.spec.js"></script
|
|
99
|
-
|
|
100
|
-
<!-- Router specs-->
|
|
98
|
+
<script type="module" src="test/shared/utils.spec.js"></script>-->
|
|
99
|
+
<!-- <script type="module" src="test/core/pubsub.spec.js"></script>
|
|
101
100
|
<script type="module" src="test/router/glob.spec.js"></script>
|
|
102
101
|
<script type="module" src="test/router/services.spec.js"></script>
|
|
103
102
|
<script type="module" src="test/router/state-directives.spec.js"></script>
|
|
@@ -108,11 +107,11 @@
|
|
|
108
107
|
<script type="module" src="test/router/view-directive.spec.js"></script>
|
|
109
108
|
<script type="module" src="test/router/view-hook.spec.js"></script>
|
|
110
109
|
<script type="module" src="test/router/view-scroll.spec.js"></script>
|
|
111
|
-
<script type="module" src="test/router/view.spec.js"></script>
|
|
110
|
+
<script type="module" src="test/router/view.spec.js"></script> -->
|
|
112
111
|
|
|
113
|
-
|
|
112
|
+
|
|
114
113
|
<!-- <script type="module" src="test/core/interval.spec.js"></script>
|
|
115
|
-
<script type="module" src="test/core/timeout.spec.js"></script>
|
|
114
|
+
<script type="module" src="test/core/timeout.spec.js"></script> -->
|
|
116
115
|
</head>
|
|
117
116
|
<body>
|
|
118
117
|
<div id="dummy"></div>
|
package/package.json
CHANGED
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
export class PubSub {
|
|
2
|
+
/**
|
|
3
|
+
* Topic-based publish/subscribe channel. Maintains a map of topics to
|
|
4
|
+
* subscriptions. When a message is published to a topic, all functions
|
|
5
|
+
* subscribed to that topic are invoked in the order they were added.
|
|
6
|
+
* Uncaught errors abort publishing.
|
|
7
|
+
*
|
|
8
|
+
* Topics may be identified by any nonempty string, <strong>except</strong>
|
|
9
|
+
* strings corresponding to native Object properties, e.g. "constructor",
|
|
10
|
+
* "toString", "hasOwnProperty", etc.
|
|
11
|
+
*
|
|
12
|
+
* @param {boolean=} opt_async Enable asynchronous behavior. Recommended for
|
|
13
|
+
* new code. See notes on the publish() method.
|
|
14
|
+
*/
|
|
15
|
+
constructor(opt_async = false) {
|
|
16
|
+
this.disposed = false;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The next available subscription key. Internally, this is an index into the
|
|
20
|
+
* sparse array of subscriptions.
|
|
21
|
+
*
|
|
22
|
+
* @private {number}
|
|
23
|
+
*/
|
|
24
|
+
this.key = 1;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Array of subscription keys pending removal once publishing is done.
|
|
28
|
+
*
|
|
29
|
+
* @private {!Array<number>}
|
|
30
|
+
* @const
|
|
31
|
+
*/
|
|
32
|
+
this.pendingKeys = [];
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Lock to prevent the removal of subscriptions during publishing. Incremented
|
|
36
|
+
* at the beginning of {@link #publish}, and decremented at the end.
|
|
37
|
+
*
|
|
38
|
+
* @private {number}
|
|
39
|
+
*/
|
|
40
|
+
this.publishDepth = 0;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Sparse array of subscriptions. Each subscription is represented by a tuple
|
|
44
|
+
* comprising a topic identifier, a function, and an optional context object.
|
|
45
|
+
* Each tuple occupies three consecutive positions in the array, with the
|
|
46
|
+
* topic identifier at index n, the function at index (n + 1), the context
|
|
47
|
+
* object at index (n + 2), the next topic at index (n + 3), etc. (This
|
|
48
|
+
* representation minimizes the number of object allocations and has been
|
|
49
|
+
* shown to be faster than an array of objects with three key-value pairs or
|
|
50
|
+
* three parallel arrays, especially on IE.) Once a subscription is removed
|
|
51
|
+
* via {@link #unsubscribe} or {@link #unsubscribeByKey}, the three
|
|
52
|
+
* corresponding array elements are deleted, and never reused. This means the
|
|
53
|
+
* total number of subscriptions during the lifetime of the pubsub channel is
|
|
54
|
+
* limited by the maximum length of a JavaScript array to (2^32 - 1) / 3 =
|
|
55
|
+
* 1,431,655,765 subscriptions, which should suffice for most applications.
|
|
56
|
+
*
|
|
57
|
+
* @private {!Array<?>}
|
|
58
|
+
* @const
|
|
59
|
+
*/
|
|
60
|
+
this.subscriptions = [];
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Map of topics to arrays of subscription keys.
|
|
64
|
+
*
|
|
65
|
+
* @private {!Object<!Array<number>>}
|
|
66
|
+
*/
|
|
67
|
+
this.topics = {};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @private @const {boolean}
|
|
71
|
+
*/
|
|
72
|
+
this.async_ = Boolean(opt_async);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Subscribes a function to a topic. The function is invoked as a method on
|
|
77
|
+
* the given `opt_context` object, or in the global scope if no context
|
|
78
|
+
* is specified. Subscribing the same function to the same topic multiple
|
|
79
|
+
* times will result in multiple function invocations while publishing.
|
|
80
|
+
* Returns a subscription key that can be used to unsubscribe the function from
|
|
81
|
+
* the topic via {@link #unsubscribeByKey}.
|
|
82
|
+
*
|
|
83
|
+
* @param {string} topic Topic to subscribe to.
|
|
84
|
+
* @param {Function} fn Function to be invoked when a message is published to
|
|
85
|
+
* the given topic.
|
|
86
|
+
* @param {Object=} opt_context Object in whose context the function is to be
|
|
87
|
+
* called (the global scope if none).
|
|
88
|
+
* @return {number} Subscription key.
|
|
89
|
+
*/
|
|
90
|
+
subscribe(topic, fn, opt_context = null) {
|
|
91
|
+
let keys = this.topics[topic];
|
|
92
|
+
if (!keys) {
|
|
93
|
+
// First subscription to this topic; initialize subscription key array.
|
|
94
|
+
keys = this.topics[topic] = [];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Push the tuple representing the subscription onto the subscription array.
|
|
98
|
+
const key = this.key;
|
|
99
|
+
this.subscriptions[key] = topic;
|
|
100
|
+
this.subscriptions[key + 1] = fn;
|
|
101
|
+
this.subscriptions[key + 2] = opt_context;
|
|
102
|
+
this.key = key + 3;
|
|
103
|
+
|
|
104
|
+
// Push the subscription key onto the list of subscriptions for the topic.
|
|
105
|
+
keys.push(key);
|
|
106
|
+
|
|
107
|
+
// Return the subscription key.
|
|
108
|
+
return key;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Subscribes a single-use function to a topic. The function is invoked as a
|
|
113
|
+
* method on the given `opt_context` object, or in the global scope if
|
|
114
|
+
* no context is specified, and is then unsubscribed. Returns a subscription
|
|
115
|
+
* key that can be used to unsubscribe the function from the topic via
|
|
116
|
+
* {@link #unsubscribeByKey}.
|
|
117
|
+
*
|
|
118
|
+
* @param {string} topic Topic to subscribe to.
|
|
119
|
+
* @param {Function} fn Function to be invoked once and then unsubscribed when
|
|
120
|
+
* a message is published to the given topic.
|
|
121
|
+
* @param {Object=} opt_context Object in whose context the function is to be
|
|
122
|
+
* called (the global scope if none).
|
|
123
|
+
* @return {number} Subscription key.
|
|
124
|
+
*/
|
|
125
|
+
subscribeOnce(topic, fn, opt_context = null) {
|
|
126
|
+
let called = false;
|
|
127
|
+
|
|
128
|
+
// Behold the power of lexical closures!
|
|
129
|
+
const key = this.subscribe(
|
|
130
|
+
topic,
|
|
131
|
+
(...args) => {
|
|
132
|
+
if (!called) {
|
|
133
|
+
called = true;
|
|
134
|
+
|
|
135
|
+
// Unsubscribe before calling function so the function is unsubscribed
|
|
136
|
+
// even if it throws an exception.
|
|
137
|
+
this.unsubscribeByKey(key);
|
|
138
|
+
|
|
139
|
+
fn.apply(opt_context, args);
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
this,
|
|
143
|
+
);
|
|
144
|
+
return key;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Runs a function asynchronously.
|
|
149
|
+
*
|
|
150
|
+
* @private
|
|
151
|
+
* @param {Function} fn Function to run.
|
|
152
|
+
* @param {Object} context Context in which to run the function.
|
|
153
|
+
* @param {Array} args Arguments to pass to the function.
|
|
154
|
+
*/
|
|
155
|
+
static runAsync_(fn, context, args) {
|
|
156
|
+
setTimeout(() => {
|
|
157
|
+
fn.apply(context, args);
|
|
158
|
+
}, 0);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Unsubscribes a function from a topic. Only deletes the first match found.
|
|
163
|
+
* Returns a Boolean indicating whether a subscription was removed.
|
|
164
|
+
*
|
|
165
|
+
* @param {string} topic Topic to unsubscribe from.
|
|
166
|
+
* @param {Function} fn Function to unsubscribe.
|
|
167
|
+
* @param {Object=} opt_context Object in whose context the function was to be
|
|
168
|
+
* called (the global scope if none).
|
|
169
|
+
* @return {boolean} Whether a matching subscription was removed.
|
|
170
|
+
*/
|
|
171
|
+
unsubscribe(topic, fn, opt_context = null) {
|
|
172
|
+
const keys = this.topics[topic];
|
|
173
|
+
if (keys) {
|
|
174
|
+
const subscriptions = this.subscriptions;
|
|
175
|
+
const key = keys.find(
|
|
176
|
+
(k) =>
|
|
177
|
+
subscriptions[k + 1] === fn && subscriptions[k + 2] === opt_context,
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
if (key !== undefined) {
|
|
181
|
+
return this.unsubscribeByKey(key);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Removes a subscription based on the key returned by {@link #subscribe}.
|
|
190
|
+
* No-op if no matching subscription is found. Returns a Boolean indicating
|
|
191
|
+
* whether a subscription was removed.
|
|
192
|
+
*
|
|
193
|
+
* @param {number} key Subscription key.
|
|
194
|
+
* @return {boolean} Whether a matching subscription was removed.
|
|
195
|
+
*/
|
|
196
|
+
unsubscribeByKey(key) {
|
|
197
|
+
const topic = this.subscriptions[key];
|
|
198
|
+
if (topic) {
|
|
199
|
+
let keys = this.topics[topic];
|
|
200
|
+
|
|
201
|
+
if (this.publishDepth !== 0) {
|
|
202
|
+
// Defer removal until after publishing is complete, but replace the
|
|
203
|
+
// function with a no-op so it isn't called.
|
|
204
|
+
this.pendingKeys.push(key);
|
|
205
|
+
this.subscriptions[key + 1] = () => {};
|
|
206
|
+
} else {
|
|
207
|
+
if (keys) {
|
|
208
|
+
this.topics[topic] = keys.filter((k) => k !== key);
|
|
209
|
+
}
|
|
210
|
+
delete this.subscriptions[key];
|
|
211
|
+
delete this.subscriptions[key + 1];
|
|
212
|
+
delete this.subscriptions[key + 2];
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return !!topic;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Publishes a message to a topic. Calls functions subscribed to the topic in
|
|
221
|
+
* the order in which they were added, passing all arguments along.
|
|
222
|
+
*
|
|
223
|
+
* If this object was created with async=true, subscribed functions are called
|
|
224
|
+
* via setTimeout(). Otherwise, the functions are called directly, and if
|
|
225
|
+
* any of them throw an uncaught error, publishing is aborted.
|
|
226
|
+
*
|
|
227
|
+
* @param {string} topic Topic to publish to.
|
|
228
|
+
* @param {...*} var_args Arguments that are applied to each subscription
|
|
229
|
+
* function.
|
|
230
|
+
* @return {boolean} Whether any subscriptions were called.
|
|
231
|
+
*/
|
|
232
|
+
publish(topic, ...var_args) {
|
|
233
|
+
const keys = this.topics[topic];
|
|
234
|
+
if (keys) {
|
|
235
|
+
const args = var_args;
|
|
236
|
+
|
|
237
|
+
if (this.async_) {
|
|
238
|
+
// For each key in the list of subscription keys for the topic, schedule
|
|
239
|
+
// the function to be applied to the arguments in the appropriate context.
|
|
240
|
+
for (let i = 0; i < keys.length; i++) {
|
|
241
|
+
const key = keys[i];
|
|
242
|
+
PubSub.runAsync_(
|
|
243
|
+
this.subscriptions[key + 1],
|
|
244
|
+
this.subscriptions[key + 2],
|
|
245
|
+
args,
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
} else {
|
|
249
|
+
this.publishDepth++;
|
|
250
|
+
|
|
251
|
+
try {
|
|
252
|
+
for (
|
|
253
|
+
let i = 0, len = keys.length;
|
|
254
|
+
i < len && !this.isDisposed();
|
|
255
|
+
i++
|
|
256
|
+
) {
|
|
257
|
+
const key = keys[i];
|
|
258
|
+
this.subscriptions[key + 1].apply(
|
|
259
|
+
this.subscriptions[key + 2],
|
|
260
|
+
args,
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
} finally {
|
|
264
|
+
this.publishDepth--;
|
|
265
|
+
|
|
266
|
+
if (this.pendingKeys.length > 0 && this.publishDepth === 0) {
|
|
267
|
+
let pendingKey;
|
|
268
|
+
while ((pendingKey = this.pendingKeys.pop())) {
|
|
269
|
+
this.unsubscribeByKey(pendingKey);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return true;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Clears the subscription list for a topic, or all topics if unspecified.
|
|
283
|
+
* @param {string=} opt_topic Topic to clear (all topics if unspecified).
|
|
284
|
+
*/
|
|
285
|
+
clear(opt_topic) {
|
|
286
|
+
if (opt_topic) {
|
|
287
|
+
const keys = this.topics[opt_topic];
|
|
288
|
+
if (keys) {
|
|
289
|
+
keys.forEach(this.unsubscribeByKey, this);
|
|
290
|
+
delete this.topics[opt_topic];
|
|
291
|
+
}
|
|
292
|
+
} else {
|
|
293
|
+
this.subscriptions.length = 0;
|
|
294
|
+
this.topics = {};
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Returns the number of subscriptions to the given topic (or all topics if
|
|
300
|
+
* unspecified). This number will not change while publishing any messages.
|
|
301
|
+
* @param {string=} opt_topic The topic (all topics if unspecified).
|
|
302
|
+
* @return {number} Number of subscriptions to the topic.
|
|
303
|
+
*/
|
|
304
|
+
getCount(opt_topic) {
|
|
305
|
+
if (opt_topic) {
|
|
306
|
+
const keys = this.topics[opt_topic];
|
|
307
|
+
return keys ? keys.length : 0;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
let count = 0;
|
|
311
|
+
for (const topic in this.topics) {
|
|
312
|
+
count += this.getCount(topic);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
return count;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
isDisposed() {
|
|
319
|
+
return this.disposed;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
dispose() {
|
|
323
|
+
this.clear();
|
|
324
|
+
this.pendingKeys.length = 0;
|
|
325
|
+
this.disposed = true;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
export const EventBus = new PubSub(true);
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { Transition } from "../transition/transition";
|
|
2
|
-
import { UIRouter } from "../router";
|
|
3
2
|
import { Resolvable } from "../resolve/resolvable";
|
|
4
3
|
import { inArray, uniqR, unnestR } from "../../shared/common";
|
|
5
|
-
|
|
6
|
-
trans.addResolvable(Resolvable.fromData(UIRouter, trans.router), "");
|
|
7
|
-
trans.addResolvable(Resolvable.fromData(Transition, trans), "");
|
|
8
|
-
trans.addResolvable(Resolvable.fromData("$transition$", trans), "");
|
|
9
|
-
trans.addResolvable(Resolvable.fromData("$stateParams", trans.params()), "");
|
|
10
|
-
trans.entering().forEach((state) => {
|
|
11
|
-
trans.addResolvable(Resolvable.fromData("$state$", state), state);
|
|
12
|
-
});
|
|
13
|
-
}
|
|
4
|
+
|
|
14
5
|
export function registerAddCoreResolvables(transitionService) {
|
|
15
|
-
transitionService.onCreate({}, addCoreResolvables)
|
|
6
|
+
transitionService.onCreate({}, function addCoreResolvables(trans) {
|
|
7
|
+
trans.addResolvable(Resolvable.fromData(Transition, trans), "");
|
|
8
|
+
trans.addResolvable(Resolvable.fromData("$transition$", trans), "");
|
|
9
|
+
trans.addResolvable(
|
|
10
|
+
Resolvable.fromData("$stateParams", trans.params()),
|
|
11
|
+
"",
|
|
12
|
+
);
|
|
13
|
+
trans.entering().forEach((state) => {
|
|
14
|
+
trans.addResolvable(Resolvable.fromData("$state$", state), state);
|
|
15
|
+
});
|
|
16
|
+
});
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
const TRANSITION_TOKENS = ["$transition$", Transition];
|
|
@@ -12,7 +12,7 @@ function ignoredHook(trans) {
|
|
|
12
12
|
const ignoredReason = trans._ignoredReason();
|
|
13
13
|
if (!ignoredReason) return;
|
|
14
14
|
trace.traceTransitionIgnored(trans);
|
|
15
|
-
const pending = trans.
|
|
15
|
+
const pending = trans.globals.transition;
|
|
16
16
|
// The user clicked a link going back to the *current state* ('A')
|
|
17
17
|
// However, there is also a pending transition in flight (to 'B')
|
|
18
18
|
// Abort the transition to 'B' because the user now wants to be back at 'A'.
|
|
@@ -23,45 +23,46 @@ import { services } from "../common/coreservices";
|
|
|
23
23
|
*
|
|
24
24
|
* See [[StateDeclaration.lazyLoad]]
|
|
25
25
|
*/
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const orig = transition.targetState();
|
|
33
|
-
return router.stateService.target(
|
|
34
|
-
orig.identifier(),
|
|
35
|
-
orig.params(),
|
|
36
|
-
orig.options(),
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
// The original transition was triggered via url sync
|
|
40
|
-
// Run the URL rules and find the best match
|
|
41
|
-
const $url = router.urlService;
|
|
42
|
-
const result = $url.match($url.parts());
|
|
43
|
-
const rule = result && result.rule;
|
|
44
|
-
// If the best match is a state, redirect the transition (instead
|
|
45
|
-
// of calling sync() which supersedes the current transition)
|
|
46
|
-
if (rule && rule.type === "STATE") {
|
|
47
|
-
const state = rule.state;
|
|
48
|
-
const params = result.match;
|
|
49
|
-
return router.stateService.target(state, params, transition.options());
|
|
50
|
-
}
|
|
51
|
-
// No matching state found, so let .sync() choose the best non-state match/otherwise
|
|
52
|
-
router.urlService.sync();
|
|
53
|
-
}
|
|
54
|
-
const promises = transition
|
|
55
|
-
.entering()
|
|
56
|
-
.filter((state) => !!state.$$state().lazyLoad)
|
|
57
|
-
.map((state) => lazyLoadState(transition, state));
|
|
58
|
-
return services.$q.all(promises).then(retryTransition);
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
export function registerLazyLoadHook(transitionService) {
|
|
26
|
+
export function registerLazyLoadHook(
|
|
27
|
+
transitionService,
|
|
28
|
+
stateService,
|
|
29
|
+
urlService,
|
|
30
|
+
stateRegistry,
|
|
31
|
+
) {
|
|
62
32
|
return transitionService.onBefore(
|
|
63
33
|
{ entering: (state) => !!state.lazyLoad },
|
|
64
|
-
|
|
34
|
+
(transition) => {
|
|
35
|
+
function retryTransition() {
|
|
36
|
+
if (transition.originalTransition().options().source !== "url") {
|
|
37
|
+
// The original transition was not triggered via url sync
|
|
38
|
+
// The lazy state should be loaded now, so re-try the original transition
|
|
39
|
+
const orig = transition.targetState();
|
|
40
|
+
return stateService.target(
|
|
41
|
+
orig.identifier(),
|
|
42
|
+
orig.params(),
|
|
43
|
+
orig.options(),
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
// The original transition was triggered via url sync
|
|
47
|
+
// Run the URL rules and find the best match
|
|
48
|
+
const result = urlService.match(urlService.parts());
|
|
49
|
+
const rule = result && result.rule;
|
|
50
|
+
// If the best match is a state, redirect the transition (instead
|
|
51
|
+
// of calling sync() which supersedes the current transition)
|
|
52
|
+
if (rule && rule.type === "STATE") {
|
|
53
|
+
const state = rule.state;
|
|
54
|
+
const params = result.match;
|
|
55
|
+
return stateService.target(state, params, transition.options());
|
|
56
|
+
}
|
|
57
|
+
// No matching state found, so let .sync() choose the best non-state match/otherwise
|
|
58
|
+
urlService.sync();
|
|
59
|
+
}
|
|
60
|
+
const promises = transition
|
|
61
|
+
.entering()
|
|
62
|
+
.filter((state) => !!state.$$state().lazyLoad)
|
|
63
|
+
.map((state) => lazyLoadState(transition, state, stateRegistry));
|
|
64
|
+
return services.$q.all(promises).then(retryTransition);
|
|
65
|
+
},
|
|
65
66
|
);
|
|
66
67
|
}
|
|
67
68
|
|
|
@@ -72,7 +73,7 @@ export function registerLazyLoadHook(transitionService) {
|
|
|
72
73
|
* @param state the state to lazy load
|
|
73
74
|
* @returns A promise for the lazy load result
|
|
74
75
|
*/
|
|
75
|
-
export function lazyLoadState(transition, state) {
|
|
76
|
+
export function lazyLoadState(transition, state, stateRegistry) {
|
|
76
77
|
const lazyLoadFn = state.$$state().lazyLoad;
|
|
77
78
|
// Store/get the lazy load promise on/from the hookfn so it doesn't get re-invoked
|
|
78
79
|
let promise = lazyLoadFn["_promise"];
|
|
@@ -95,9 +96,7 @@ export function lazyLoadState(transition, state) {
|
|
|
95
96
|
/** Register any lazy loaded state definitions */
|
|
96
97
|
function updateStateRegistry(result) {
|
|
97
98
|
if (result && Array.isArray(result.states)) {
|
|
98
|
-
result.states.forEach((_state) =>
|
|
99
|
-
transition.router.stateRegistry.register(_state),
|
|
100
|
-
);
|
|
99
|
+
result.states.forEach((_state) => stateRegistry.register(_state));
|
|
101
100
|
}
|
|
102
101
|
return result;
|
|
103
102
|
}
|
|
@@ -1,36 +1,39 @@
|
|
|
1
1
|
import { isString, isFunction } from "../../shared/utils";
|
|
2
2
|
import { services } from "../common/coreservices";
|
|
3
3
|
import { TargetState } from "../state/target-state";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
4
|
+
|
|
5
|
+
export const registerRedirectToHook = (transitionService, stateService) => {
|
|
6
|
+
/**
|
|
7
|
+
* A [[TransitionHookFn]] that redirects to a different state or params
|
|
8
|
+
*
|
|
9
|
+
* Registered using `transitionService.onStart({ to: (state) => !!state.redirectTo }, redirectHook);`
|
|
10
|
+
*
|
|
11
|
+
* See [[StateDeclaration.redirectTo]]
|
|
12
|
+
*/
|
|
13
|
+
const redirectToHook = (trans) => {
|
|
14
|
+
const redirect = trans.to().redirectTo;
|
|
15
|
+
if (!redirect) return;
|
|
16
|
+
const $state = stateService;
|
|
17
|
+
function handleResult(result) {
|
|
18
|
+
if (!result) return;
|
|
19
|
+
if (result instanceof TargetState) return result;
|
|
20
|
+
if (isString(result))
|
|
21
|
+
return $state.target(result, trans.params(), trans.options());
|
|
22
|
+
if (result["state"] || result["params"])
|
|
23
|
+
return $state.target(
|
|
24
|
+
result["state"] || trans.to(),
|
|
25
|
+
result["params"] || trans.params(),
|
|
26
|
+
trans.options(),
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
if (isFunction(redirect)) {
|
|
30
|
+
return services.$q.when(redirect(trans)).then(handleResult);
|
|
31
|
+
}
|
|
32
|
+
return handleResult(redirect);
|
|
33
|
+
};
|
|
34
|
+
|
|
33
35
|
transitionService.onStart(
|
|
34
36
|
{ to: (state) => !!state.redirectTo },
|
|
35
37
|
redirectToHook,
|
|
36
38
|
);
|
|
39
|
+
};
|
|
@@ -12,7 +12,7 @@ import { copy } from "../../shared/common";
|
|
|
12
12
|
* [[StateService.transition]], [[StateService.current]], [[StateService.params]]
|
|
13
13
|
*/
|
|
14
14
|
const updateGlobalState = (trans) => {
|
|
15
|
-
const globals = trans.
|
|
15
|
+
const globals = trans.globals;
|
|
16
16
|
const transitionSuccessful = () => {
|
|
17
17
|
globals.successfulTransitions.enqueue(trans);
|
|
18
18
|
globals.$current = trans.$to();
|