@angular-wave/angular.ts 0.0.11 → 0.0.12
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/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 +86 -0
- package/src/router/adapter/services.js +132 -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/urlRouterProvider.js +196 -0
- package/src/router/adapter/viewScroll.js +31 -0
- package/src/router/core/common/common.js +506 -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 +200 -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 +201 -0
- package/src/router/core/state/README.md +21 -0
- package/src/router/core/state/stateBuilder.js +333 -0
- package/src/router/core/state/stateMatcher.js +66 -0
- package/src/router/core/state/stateObject.js +116 -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 +182 -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/vanilla/baseLocationService.js +31 -0
- package/src/router/core/vanilla/browserLocationConfig.js +42 -0
- package/src/router/core/vanilla/hashLocationService.js +19 -0
- package/src/router/core/vanilla/injector.js +98 -0
- package/src/router/core/vanilla/interface.js +1 -0
- package/src/router/core/vanilla/memoryLocationConfig.js +20 -0
- package/src/router/core/vanilla/memoryLocationService.js +13 -0
- package/src/router/core/vanilla/plugins.js +35 -0
- package/src/router/core/vanilla/pushStateLocationService.js +69 -0
- package/src/router/core/vanilla/q.js +54 -0
- package/src/router/core/vanilla/utils.js +63 -0
- package/src/router/core/view/interface.js +1 -0
- package/src/router/core/view/view.js +312 -0
- package/src/router/router.js +52 -0
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Random utility functions used in the UI-Router code
|
|
3
|
+
*
|
|
4
|
+
* These functions are exported, but are subject to change without notice.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
* @preferred
|
|
8
|
+
*/
|
|
9
|
+
import { isFunction, isString, isArray, isRegExp, isDate } from "./predicates";
|
|
10
|
+
import { all, any, prop, curry, not } from "./hof";
|
|
11
|
+
import { services } from "./coreservices";
|
|
12
|
+
export const root =
|
|
13
|
+
(typeof self === "object" && self.self === self && self) ||
|
|
14
|
+
(typeof global === "object" && global.global === global && global) ||
|
|
15
|
+
this;
|
|
16
|
+
const angular = root.angular || {};
|
|
17
|
+
export const fromJson = angular.fromJson || JSON.parse.bind(JSON);
|
|
18
|
+
export const toJson = angular.toJson || JSON.stringify.bind(JSON);
|
|
19
|
+
export const forEach = angular.forEach || _forEach;
|
|
20
|
+
export const extend = Object.assign || _extend;
|
|
21
|
+
export const equals = angular.equals || _equals;
|
|
22
|
+
export function identity(x) {
|
|
23
|
+
return x;
|
|
24
|
+
}
|
|
25
|
+
export function noop() {}
|
|
26
|
+
/**
|
|
27
|
+
* Builds proxy functions on the `to` object which pass through to the `from` object.
|
|
28
|
+
*
|
|
29
|
+
* For each key in `fnNames`, creates a proxy function on the `to` object.
|
|
30
|
+
* The proxy function calls the real function on the `from` object.
|
|
31
|
+
*
|
|
32
|
+
*
|
|
33
|
+
* #### Example:
|
|
34
|
+
* This example creates an new class instance whose functions are prebound to the new'd object.
|
|
35
|
+
* ```js
|
|
36
|
+
* class Foo {
|
|
37
|
+
* constructor(data) {
|
|
38
|
+
* // Binds all functions from Foo.prototype to 'this',
|
|
39
|
+
* // then copies them to 'this'
|
|
40
|
+
* bindFunctions(Foo.prototype, this, this);
|
|
41
|
+
* this.data = data;
|
|
42
|
+
* }
|
|
43
|
+
*
|
|
44
|
+
* log() {
|
|
45
|
+
* console.log(this.data);
|
|
46
|
+
* }
|
|
47
|
+
* }
|
|
48
|
+
*
|
|
49
|
+
* let myFoo = new Foo([1,2,3]);
|
|
50
|
+
* var logit = myFoo.log;
|
|
51
|
+
* logit(); // logs [1, 2, 3] from the myFoo 'this' instance
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* #### Example:
|
|
55
|
+
* This example creates a bound version of a service function, and copies it to another object
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* var SomeService = {
|
|
59
|
+
* this.data = [3, 4, 5];
|
|
60
|
+
* this.log = function() {
|
|
61
|
+
* console.log(this.data);
|
|
62
|
+
* }
|
|
63
|
+
* }
|
|
64
|
+
*
|
|
65
|
+
* // Constructor fn
|
|
66
|
+
* function OtherThing() {
|
|
67
|
+
* // Binds all functions from SomeService to SomeService,
|
|
68
|
+
* // then copies them to 'this'
|
|
69
|
+
* bindFunctions(SomeService, this, SomeService);
|
|
70
|
+
* }
|
|
71
|
+
*
|
|
72
|
+
* let myOtherThing = new OtherThing();
|
|
73
|
+
* myOtherThing.log(); // logs [3, 4, 5] from SomeService's 'this'
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* @param source A function that returns the source object which contains the original functions to be bound
|
|
77
|
+
* @param target A function that returns the target object which will receive the bound functions
|
|
78
|
+
* @param bind A function that returns the object which the functions will be bound to
|
|
79
|
+
* @param fnNames The function names which will be bound (Defaults to all the functions found on the 'from' object)
|
|
80
|
+
* @param latebind If true, the binding of the function is delayed until the first time it's invoked
|
|
81
|
+
*/
|
|
82
|
+
export function createProxyFunctions(
|
|
83
|
+
source,
|
|
84
|
+
target,
|
|
85
|
+
bind,
|
|
86
|
+
fnNames,
|
|
87
|
+
latebind = false,
|
|
88
|
+
) {
|
|
89
|
+
const bindFunction = (fnName) => source()[fnName].bind(bind());
|
|
90
|
+
const makeLateRebindFn = (fnName) =>
|
|
91
|
+
function lateRebindFunction() {
|
|
92
|
+
target[fnName] = bindFunction(fnName);
|
|
93
|
+
return target[fnName].apply(null, arguments);
|
|
94
|
+
};
|
|
95
|
+
fnNames = fnNames || Object.keys(source());
|
|
96
|
+
return fnNames.reduce((acc, name) => {
|
|
97
|
+
acc[name] = latebind ? makeLateRebindFn(name) : bindFunction(name);
|
|
98
|
+
return acc;
|
|
99
|
+
}, target);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* prototypal inheritance helper.
|
|
103
|
+
* Creates a new object which has `parent` object as its prototype, and then copies the properties from `extra` onto it
|
|
104
|
+
*/
|
|
105
|
+
export const inherit = (parent, extra) => extend(Object.create(parent), extra);
|
|
106
|
+
/** Given an array, returns true if the object is found in the array, (using indexOf) */
|
|
107
|
+
export const inArray = curry(_inArray);
|
|
108
|
+
export function _inArray(array, obj) {
|
|
109
|
+
return array.indexOf(obj) !== -1;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Given an array, and an item, if the item is found in the array, it removes it (in-place).
|
|
113
|
+
* The same array is returned
|
|
114
|
+
*/
|
|
115
|
+
export const removeFrom = curry(_removeFrom);
|
|
116
|
+
export function _removeFrom(array, obj) {
|
|
117
|
+
const idx = array.indexOf(obj);
|
|
118
|
+
if (idx >= 0) array.splice(idx, 1);
|
|
119
|
+
return array;
|
|
120
|
+
}
|
|
121
|
+
/** pushes a values to an array and returns the value */
|
|
122
|
+
export const pushTo = curry(_pushTo);
|
|
123
|
+
export function _pushTo(arr, val) {
|
|
124
|
+
return arr.push(val), val;
|
|
125
|
+
}
|
|
126
|
+
/** Given an array of (deregistration) functions, calls all functions and removes each one from the source array */
|
|
127
|
+
export const deregAll = (functions) =>
|
|
128
|
+
functions.slice().forEach((fn) => {
|
|
129
|
+
typeof fn === "function" && fn();
|
|
130
|
+
removeFrom(functions, fn);
|
|
131
|
+
});
|
|
132
|
+
/**
|
|
133
|
+
* Applies a set of defaults to an options object. The options object is filtered
|
|
134
|
+
* to only those properties of the objects in the defaultsList.
|
|
135
|
+
* Earlier objects in the defaultsList take precedence when applying defaults.
|
|
136
|
+
*/
|
|
137
|
+
export function defaults(opts, ...defaultsList) {
|
|
138
|
+
const defaultVals = extend({}, ...defaultsList.reverse());
|
|
139
|
+
return extend(defaultVals, pick(opts || {}, Object.keys(defaultVals)));
|
|
140
|
+
}
|
|
141
|
+
/** Reduce function that merges each element of the list into a single object, using extend */
|
|
142
|
+
export const mergeR = (memo, item) => extend(memo, item);
|
|
143
|
+
/**
|
|
144
|
+
* Finds the common ancestor path between two states.
|
|
145
|
+
*
|
|
146
|
+
* @param {Object} first The first state.
|
|
147
|
+
* @param {Object} second The second state.
|
|
148
|
+
* @return {Array} Returns an array of state names in descending order, not including the root.
|
|
149
|
+
*/
|
|
150
|
+
export function ancestors(first, second) {
|
|
151
|
+
const path = [];
|
|
152
|
+
// tslint:disable-next-line:forin
|
|
153
|
+
for (const n in first.path) {
|
|
154
|
+
if (first.path[n] !== second.path[n]) break;
|
|
155
|
+
path.push(first.path[n]);
|
|
156
|
+
}
|
|
157
|
+
return path;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Return a copy of the object only containing the whitelisted properties.
|
|
161
|
+
*
|
|
162
|
+
* #### Example:
|
|
163
|
+
* ```
|
|
164
|
+
* var foo = { a: 1, b: 2, c: 3 };
|
|
165
|
+
* var ab = pick(foo, ['a', 'b']); // { a: 1, b: 2 }
|
|
166
|
+
* ```
|
|
167
|
+
* @param obj the source object
|
|
168
|
+
* @param propNames an Array of strings, which are the whitelisted property names
|
|
169
|
+
*/
|
|
170
|
+
export function pick(obj, propNames) {
|
|
171
|
+
const objCopy = {};
|
|
172
|
+
for (const _prop in obj) {
|
|
173
|
+
if (propNames.indexOf(_prop) !== -1) {
|
|
174
|
+
objCopy[_prop] = obj[_prop];
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return objCopy;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Return a copy of the object omitting the blacklisted properties.
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```
|
|
184
|
+
*
|
|
185
|
+
* var foo = { a: 1, b: 2, c: 3 };
|
|
186
|
+
* var ab = omit(foo, ['a', 'b']); // { c: 3 }
|
|
187
|
+
* ```
|
|
188
|
+
* @param obj the source object
|
|
189
|
+
* @param propNames an Array of strings, which are the blacklisted property names
|
|
190
|
+
*/
|
|
191
|
+
export function omit(obj, propNames) {
|
|
192
|
+
return Object.keys(obj)
|
|
193
|
+
.filter(not(inArray(propNames)))
|
|
194
|
+
.reduce((acc, key) => ((acc[key] = obj[key]), acc), {});
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Maps an array, or object to a property (by name)
|
|
198
|
+
*/
|
|
199
|
+
export function pluck(collection, propName) {
|
|
200
|
+
return map(collection, prop(propName));
|
|
201
|
+
}
|
|
202
|
+
/** Filters an Array or an Object's properties based on a predicate */
|
|
203
|
+
export function filter(collection, callback) {
|
|
204
|
+
const arr = isArray(collection),
|
|
205
|
+
result = arr ? [] : {};
|
|
206
|
+
const accept = arr ? (x) => result.push(x) : (x, key) => (result[key] = x);
|
|
207
|
+
forEach(collection, function (item, i) {
|
|
208
|
+
if (callback(item, i)) accept(item, i);
|
|
209
|
+
});
|
|
210
|
+
return result;
|
|
211
|
+
}
|
|
212
|
+
/** Finds an object from an array, or a property of an object, that matches a predicate */
|
|
213
|
+
export function find(collection, callback) {
|
|
214
|
+
let result;
|
|
215
|
+
forEach(collection, function (item, i) {
|
|
216
|
+
if (result) return;
|
|
217
|
+
if (callback(item, i)) result = item;
|
|
218
|
+
});
|
|
219
|
+
return result;
|
|
220
|
+
}
|
|
221
|
+
/** Given an object, returns a new object, where each property is transformed by the callback function */
|
|
222
|
+
export let mapObj = map;
|
|
223
|
+
/** Maps an array or object properties using a callback function */
|
|
224
|
+
export function map(collection, callback, target) {
|
|
225
|
+
target = target || (isArray(collection) ? [] : {});
|
|
226
|
+
forEach(collection, (item, i) => (target[i] = callback(item, i)));
|
|
227
|
+
return target;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Given an object, return its enumerable property values
|
|
231
|
+
*
|
|
232
|
+
* @example
|
|
233
|
+
* ```
|
|
234
|
+
*
|
|
235
|
+
* let foo = { a: 1, b: 2, c: 3 }
|
|
236
|
+
* let vals = values(foo); // [ 1, 2, 3 ]
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
export const values = (obj) => Object.keys(obj).map((key) => obj[key]);
|
|
240
|
+
/**
|
|
241
|
+
* Reduce function that returns true if all of the values are truthy.
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* ```
|
|
245
|
+
*
|
|
246
|
+
* let vals = [ 1, true, {}, "hello world"];
|
|
247
|
+
* vals.reduce(allTrueR, true); // true
|
|
248
|
+
*
|
|
249
|
+
* vals.push(0);
|
|
250
|
+
* vals.reduce(allTrueR, true); // false
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
export const allTrueR = (memo, elem) => memo && elem;
|
|
254
|
+
/**
|
|
255
|
+
* Reduce function that returns true if any of the values are truthy.
|
|
256
|
+
*
|
|
257
|
+
* * @example
|
|
258
|
+
* ```
|
|
259
|
+
*
|
|
260
|
+
* let vals = [ 0, null, undefined ];
|
|
261
|
+
* vals.reduce(anyTrueR, true); // false
|
|
262
|
+
*
|
|
263
|
+
* vals.push("hello world");
|
|
264
|
+
* vals.reduce(anyTrueR, true); // true
|
|
265
|
+
* ```
|
|
266
|
+
*/
|
|
267
|
+
export const anyTrueR = (memo, elem) => memo || elem;
|
|
268
|
+
/**
|
|
269
|
+
* Reduce function which un-nests a single level of arrays
|
|
270
|
+
* @example
|
|
271
|
+
* ```
|
|
272
|
+
*
|
|
273
|
+
* let input = [ [ "a", "b" ], [ "c", "d" ], [ [ "double", "nested" ] ] ];
|
|
274
|
+
* input.reduce(unnestR, []) // [ "a", "b", "c", "d", [ "double, "nested" ] ]
|
|
275
|
+
* ```
|
|
276
|
+
*/
|
|
277
|
+
export const unnestR = (memo, elem) => memo.concat(elem);
|
|
278
|
+
/**
|
|
279
|
+
* Reduce function which recursively un-nests all arrays
|
|
280
|
+
*
|
|
281
|
+
* @example
|
|
282
|
+
* ```
|
|
283
|
+
*
|
|
284
|
+
* let input = [ [ "a", "b" ], [ "c", "d" ], [ [ "double", "nested" ] ] ];
|
|
285
|
+
* input.reduce(unnestR, []) // [ "a", "b", "c", "d", "double, "nested" ]
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
288
|
+
export const flattenR = (memo, elem) =>
|
|
289
|
+
isArray(elem) ? memo.concat(elem.reduce(flattenR, [])) : pushR(memo, elem);
|
|
290
|
+
/**
|
|
291
|
+
* Reduce function that pushes an object to an array, then returns the array.
|
|
292
|
+
* Mostly just for [[flattenR]] and [[uniqR]]
|
|
293
|
+
*/
|
|
294
|
+
export function pushR(arr, obj) {
|
|
295
|
+
arr.push(obj);
|
|
296
|
+
return arr;
|
|
297
|
+
}
|
|
298
|
+
/** Reduce function that filters out duplicates */
|
|
299
|
+
export const uniqR = (acc, token) =>
|
|
300
|
+
inArray(acc, token) ? acc : pushR(acc, token);
|
|
301
|
+
/**
|
|
302
|
+
* Return a new array with a single level of arrays unnested.
|
|
303
|
+
*
|
|
304
|
+
* @example
|
|
305
|
+
* ```
|
|
306
|
+
*
|
|
307
|
+
* let input = [ [ "a", "b" ], [ "c", "d" ], [ [ "double", "nested" ] ] ];
|
|
308
|
+
* unnest(input) // [ "a", "b", "c", "d", [ "double, "nested" ] ]
|
|
309
|
+
* ```
|
|
310
|
+
*/
|
|
311
|
+
export const unnest = (arr) => arr.reduce(unnestR, []);
|
|
312
|
+
/**
|
|
313
|
+
* Return a completely flattened version of an array.
|
|
314
|
+
*
|
|
315
|
+
* @example
|
|
316
|
+
* ```
|
|
317
|
+
*
|
|
318
|
+
* let input = [ [ "a", "b" ], [ "c", "d" ], [ [ "double", "nested" ] ] ];
|
|
319
|
+
* flatten(input) // [ "a", "b", "c", "d", "double, "nested" ]
|
|
320
|
+
* ```
|
|
321
|
+
*/
|
|
322
|
+
export const flatten = (arr) => arr.reduce(flattenR, []);
|
|
323
|
+
/**
|
|
324
|
+
* Given a .filter Predicate, builds a .filter Predicate which throws an error if any elements do not pass.
|
|
325
|
+
* @example
|
|
326
|
+
* ```
|
|
327
|
+
*
|
|
328
|
+
* let isNumber = (obj) => typeof(obj) === 'number';
|
|
329
|
+
* let allNumbers = [ 1, 2, 3, 4, 5 ];
|
|
330
|
+
* allNumbers.filter(assertPredicate(isNumber)); //OK
|
|
331
|
+
*
|
|
332
|
+
* let oneString = [ 1, 2, 3, 4, "5" ];
|
|
333
|
+
* oneString.filter(assertPredicate(isNumber, "Not all numbers")); // throws Error(""Not all numbers"");
|
|
334
|
+
* ```
|
|
335
|
+
*/
|
|
336
|
+
export const assertPredicate = assertFn;
|
|
337
|
+
/**
|
|
338
|
+
* Given a .map function, builds a .map function which throws an error if any mapped elements do not pass a truthyness test.
|
|
339
|
+
* @example
|
|
340
|
+
* ```
|
|
341
|
+
*
|
|
342
|
+
* var data = { foo: 1, bar: 2 };
|
|
343
|
+
*
|
|
344
|
+
* let keys = [ 'foo', 'bar' ]
|
|
345
|
+
* let values = keys.map(assertMap(key => data[key], "Key not found"));
|
|
346
|
+
* // values is [1, 2]
|
|
347
|
+
*
|
|
348
|
+
* let keys = [ 'foo', 'bar', 'baz' ]
|
|
349
|
+
* let values = keys.map(assertMap(key => data[key], "Key not found"));
|
|
350
|
+
* // throws Error("Key not found")
|
|
351
|
+
* ```
|
|
352
|
+
*/
|
|
353
|
+
export const assertMap = assertFn;
|
|
354
|
+
export function assertFn(predicateOrMap, errMsg = "assert failure") {
|
|
355
|
+
return (obj) => {
|
|
356
|
+
const result = predicateOrMap(obj);
|
|
357
|
+
if (!result) {
|
|
358
|
+
throw new Error(isFunction(errMsg) ? errMsg(obj) : errMsg);
|
|
359
|
+
}
|
|
360
|
+
return result;
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Like _.pairs: Given an object, returns an array of key/value pairs
|
|
365
|
+
*
|
|
366
|
+
* @example
|
|
367
|
+
* ```
|
|
368
|
+
*
|
|
369
|
+
* pairs({ foo: "FOO", bar: "BAR }) // [ [ "foo", "FOO" ], [ "bar": "BAR" ] ]
|
|
370
|
+
* ```
|
|
371
|
+
*/
|
|
372
|
+
export const pairs = (obj) => Object.keys(obj).map((key) => [key, obj[key]]);
|
|
373
|
+
/**
|
|
374
|
+
* Given two or more parallel arrays, returns an array of tuples where
|
|
375
|
+
* each tuple is composed of [ a[i], b[i], ... z[i] ]
|
|
376
|
+
*
|
|
377
|
+
* @example
|
|
378
|
+
* ```
|
|
379
|
+
*
|
|
380
|
+
* let foo = [ 0, 2, 4, 6 ];
|
|
381
|
+
* let bar = [ 1, 3, 5, 7 ];
|
|
382
|
+
* let baz = [ 10, 30, 50, 70 ];
|
|
383
|
+
* arrayTuples(foo, bar); // [ [0, 1], [2, 3], [4, 5], [6, 7] ]
|
|
384
|
+
* arrayTuples(foo, bar, baz); // [ [0, 1, 10], [2, 3, 30], [4, 5, 50], [6, 7, 70] ]
|
|
385
|
+
* ```
|
|
386
|
+
*/
|
|
387
|
+
export function arrayTuples(...args) {
|
|
388
|
+
if (args.length === 0) return [];
|
|
389
|
+
const maxArrayLen = args.reduce(
|
|
390
|
+
(min, arr) => Math.min(arr.length, min),
|
|
391
|
+
9007199254740991,
|
|
392
|
+
); // aka 2^53 − 1 aka Number.MAX_SAFE_INTEGER
|
|
393
|
+
const result = [];
|
|
394
|
+
for (let i = 0; i < maxArrayLen; i++) {
|
|
395
|
+
// This is a hot function
|
|
396
|
+
// Unroll when there are 1-4 arguments
|
|
397
|
+
switch (args.length) {
|
|
398
|
+
case 1:
|
|
399
|
+
result.push([args[0][i]]);
|
|
400
|
+
break;
|
|
401
|
+
case 2:
|
|
402
|
+
result.push([args[0][i], args[1][i]]);
|
|
403
|
+
break;
|
|
404
|
+
case 3:
|
|
405
|
+
result.push([args[0][i], args[1][i], args[2][i]]);
|
|
406
|
+
break;
|
|
407
|
+
case 4:
|
|
408
|
+
result.push([args[0][i], args[1][i], args[2][i], args[3][i]]);
|
|
409
|
+
break;
|
|
410
|
+
default:
|
|
411
|
+
result.push(args.map((array) => array[i]));
|
|
412
|
+
break;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
return result;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Reduce function which builds an object from an array of [key, value] pairs.
|
|
419
|
+
*
|
|
420
|
+
* Each iteration sets the key/val pair on the memo object, then returns the memo for the next iteration.
|
|
421
|
+
*
|
|
422
|
+
* Each keyValueTuple should be an array with values [ key: string, value: any ]
|
|
423
|
+
*
|
|
424
|
+
* @example
|
|
425
|
+
* ```
|
|
426
|
+
*
|
|
427
|
+
* var pairs = [ ["fookey", "fooval"], ["barkey", "barval"] ]
|
|
428
|
+
*
|
|
429
|
+
* var pairsToObj = pairs.reduce((memo, pair) => applyPairs(memo, pair), {})
|
|
430
|
+
* // pairsToObj == { fookey: "fooval", barkey: "barval" }
|
|
431
|
+
*
|
|
432
|
+
* // Or, more simply:
|
|
433
|
+
* var pairsToObj = pairs.reduce(applyPairs, {})
|
|
434
|
+
* // pairsToObj == { fookey: "fooval", barkey: "barval" }
|
|
435
|
+
* ```
|
|
436
|
+
*/
|
|
437
|
+
export function applyPairs(memo, keyValTuple) {
|
|
438
|
+
let key, value;
|
|
439
|
+
if (isArray(keyValTuple)) [key, value] = keyValTuple;
|
|
440
|
+
if (!isString(key)) throw new Error("invalid parameters to applyPairs");
|
|
441
|
+
memo[key] = value;
|
|
442
|
+
return memo;
|
|
443
|
+
}
|
|
444
|
+
/** Get the last element of an array */
|
|
445
|
+
export function tail(arr) {
|
|
446
|
+
return (arr.length && arr[arr.length - 1]) || undefined;
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* shallow copy from src to dest
|
|
450
|
+
*/
|
|
451
|
+
export function copy(src, dest) {
|
|
452
|
+
if (dest) Object.keys(dest).forEach((key) => delete dest[key]);
|
|
453
|
+
if (!dest) dest = {};
|
|
454
|
+
return extend(dest, src);
|
|
455
|
+
}
|
|
456
|
+
/** Naive forEach implementation works with Objects or Arrays */
|
|
457
|
+
function _forEach(obj, cb, _this) {
|
|
458
|
+
if (isArray(obj)) return obj.forEach(cb, _this);
|
|
459
|
+
Object.keys(obj).forEach((key) => cb(obj[key], key));
|
|
460
|
+
}
|
|
461
|
+
export function _extend(toObj) {
|
|
462
|
+
for (let i = 1; i < arguments.length; i++) {
|
|
463
|
+
const obj = arguments[i];
|
|
464
|
+
if (!obj) continue;
|
|
465
|
+
const keys = Object.keys(obj);
|
|
466
|
+
for (let j = 0; j < keys.length; j++) {
|
|
467
|
+
toObj[keys[j]] = obj[keys[j]];
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
return toObj;
|
|
471
|
+
}
|
|
472
|
+
function _equals(o1, o2) {
|
|
473
|
+
if (o1 === o2) return true;
|
|
474
|
+
if (o1 === null || o2 === null) return false;
|
|
475
|
+
if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN
|
|
476
|
+
const t1 = typeof o1,
|
|
477
|
+
t2 = typeof o2;
|
|
478
|
+
if (t1 !== t2 || t1 !== "object") return false;
|
|
479
|
+
const tup = [o1, o2];
|
|
480
|
+
if (all(isArray)(tup)) return _arraysEq(o1, o2);
|
|
481
|
+
if (all(isDate)(tup)) return o1.getTime() === o2.getTime();
|
|
482
|
+
if (all(isRegExp)(tup)) return o1.toString() === o2.toString();
|
|
483
|
+
if (all(isFunction)(tup)) return true; // meh
|
|
484
|
+
const predicates = [isFunction, isArray, isDate, isRegExp];
|
|
485
|
+
if (predicates.map(any).reduce((b, fn) => b || !!fn(tup), false))
|
|
486
|
+
return false;
|
|
487
|
+
const keys = {};
|
|
488
|
+
// tslint:disable-next-line:forin
|
|
489
|
+
for (const key in o1) {
|
|
490
|
+
if (!_equals(o1[key], o2[key])) return false;
|
|
491
|
+
keys[key] = true;
|
|
492
|
+
}
|
|
493
|
+
for (const key in o2) {
|
|
494
|
+
if (!keys[key]) return false;
|
|
495
|
+
}
|
|
496
|
+
return true;
|
|
497
|
+
}
|
|
498
|
+
function _arraysEq(a1, a2) {
|
|
499
|
+
if (a1.length !== a2.length) return false;
|
|
500
|
+
return arrayTuples(a1, a2).reduce((b, t) => b && _equals(t[0], t[1]), true);
|
|
501
|
+
}
|
|
502
|
+
// issue #2676
|
|
503
|
+
export const silenceUncaughtInPromise = (promise) =>
|
|
504
|
+
promise.catch((e) => 0) && promise;
|
|
505
|
+
export const silentRejection = (error) =>
|
|
506
|
+
silenceUncaughtInPromise(services.$q.reject(error));
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const noImpl = (fnname) => () => {
|
|
2
|
+
throw new Error(
|
|
3
|
+
`No implementation for ${fnname}. The framework specific code did not implement this method.`,
|
|
4
|
+
);
|
|
5
|
+
};
|
|
6
|
+
export const makeStub = (service, methods) =>
|
|
7
|
+
methods.reduce(
|
|
8
|
+
(acc, key) => ((acc[key] = noImpl(`${service}.${key}()`)), acc),
|
|
9
|
+
{},
|
|
10
|
+
);
|
|
11
|
+
const services = {
|
|
12
|
+
$q: undefined,
|
|
13
|
+
$injector: undefined,
|
|
14
|
+
};
|
|
15
|
+
export { services };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Matches state names using glob-like pattern strings.
|
|
3
|
+
*
|
|
4
|
+
* Globs can be used in specific APIs including:
|
|
5
|
+
*
|
|
6
|
+
* - [[StateService.is]]
|
|
7
|
+
* - [[StateService.includes]]
|
|
8
|
+
* - The first argument to Hook Registration functions like [[TransitionService.onStart]]
|
|
9
|
+
* - [[HookMatchCriteria]] and [[HookMatchCriterion]]
|
|
10
|
+
*
|
|
11
|
+
* A `Glob` string is a pattern which matches state names.
|
|
12
|
+
* Nested state names are split into segments (separated by a dot) when processing.
|
|
13
|
+
* The state named `foo.bar.baz` is split into three segments ['foo', 'bar', 'baz']
|
|
14
|
+
*
|
|
15
|
+
* Globs work according to the following rules:
|
|
16
|
+
*
|
|
17
|
+
* ### Exact match:
|
|
18
|
+
*
|
|
19
|
+
* The glob `'A.B'` matches the state named exactly `'A.B'`.
|
|
20
|
+
*
|
|
21
|
+
* | Glob |Matches states named|Does not match state named|
|
|
22
|
+
* |:------------|:--------------------|:---------------------|
|
|
23
|
+
* | `'A'` | `'A'` | `'B'` , `'A.C'` |
|
|
24
|
+
* | `'A.B'` | `'A.B'` | `'A'` , `'A.B.C'` |
|
|
25
|
+
* | `'foo'` | `'foo'` | `'FOO'` , `'foo.bar'`|
|
|
26
|
+
*
|
|
27
|
+
* ### Single star (`*`)
|
|
28
|
+
*
|
|
29
|
+
* A single star (`*`) is a wildcard that matches exactly one segment.
|
|
30
|
+
*
|
|
31
|
+
* | Glob |Matches states named |Does not match state named |
|
|
32
|
+
* |:------------|:---------------------|:--------------------------|
|
|
33
|
+
* | `'*'` | `'A'` , `'Z'` | `'A.B'` , `'Z.Y.X'` |
|
|
34
|
+
* | `'A.*'` | `'A.B'` , `'A.C'` | `'A'` , `'A.B.C'` |
|
|
35
|
+
* | `'A.*.*'` | `'A.B.C'` , `'A.X.Y'`| `'A'`, `'A.B'` , `'Z.Y.X'`|
|
|
36
|
+
*
|
|
37
|
+
* ### Double star (`**`)
|
|
38
|
+
*
|
|
39
|
+
* A double star (`'**'`) is a wildcard that matches *zero or more segments*
|
|
40
|
+
*
|
|
41
|
+
* | Glob |Matches states named |Does not match state named |
|
|
42
|
+
* |:------------|:----------------------------------------------|:----------------------------------|
|
|
43
|
+
* | `'**'` | `'A'` , `'A.B'`, `'Z.Y.X'` | (matches all states) |
|
|
44
|
+
* | `'A.**'` | `'A'` , `'A.B'` , `'A.C.X'` | `'Z.Y.X'` |
|
|
45
|
+
* | `'**.X'` | `'X'` , `'A.X'` , `'Z.Y.X'` | `'A'` , `'A.login.Z'` |
|
|
46
|
+
* | `'A.**.X'` | `'A.X'` , `'A.B.X'` , `'A.B.C.X'` | `'A'` , `'A.B.C'` |
|
|
47
|
+
*
|
|
48
|
+
* @packageDocumentation
|
|
49
|
+
*/
|
|
50
|
+
export class Glob {
|
|
51
|
+
/** Returns true if the string has glob-like characters in it */
|
|
52
|
+
static is(text) {
|
|
53
|
+
return !!/[!,*]+/.exec(text);
|
|
54
|
+
}
|
|
55
|
+
/** Returns a glob from the string, or null if the string isn't Glob-like */
|
|
56
|
+
static fromString(text) {
|
|
57
|
+
return Glob.is(text) ? new Glob(text) : null;
|
|
58
|
+
}
|
|
59
|
+
constructor(text) {
|
|
60
|
+
this.text = text;
|
|
61
|
+
this.glob = text.split(".");
|
|
62
|
+
const regexpString = this.text
|
|
63
|
+
.split(".")
|
|
64
|
+
.map((seg) => {
|
|
65
|
+
if (seg === "**") return "(?:|(?:\\.[^.]*)*)";
|
|
66
|
+
if (seg === "*") return "\\.[^.]*";
|
|
67
|
+
return "\\." + seg;
|
|
68
|
+
})
|
|
69
|
+
.join("");
|
|
70
|
+
this.regexp = new RegExp("^" + regexpString + "$");
|
|
71
|
+
}
|
|
72
|
+
matches(name) {
|
|
73
|
+
return this.regexp.test("." + name);
|
|
74
|
+
}
|
|
75
|
+
}
|