Merge "add web portal framework for TestAPI"
[releng.git] / utils / test / testapi / 3rd_party / static / testapi-ui / assets / lib / angular-ui-router / src / common.js
1 /*jshint globalstrict:true*/
2 /*global angular:false*/
3 'use strict';
4
5 var isDefined = angular.isDefined,
6     isFunction = angular.isFunction,
7     isString = angular.isString,
8     isObject = angular.isObject,
9     isArray = angular.isArray,
10     forEach = angular.forEach,
11     extend = angular.extend,
12     copy = angular.copy;
13
14 function inherit(parent, extra) {
15   return extend(new (extend(function() {}, { prototype: parent }))(), extra);
16 }
17
18 function merge(dst) {
19   forEach(arguments, function(obj) {
20     if (obj !== dst) {
21       forEach(obj, function(value, key) {
22         if (!dst.hasOwnProperty(key)) dst[key] = value;
23       });
24     }
25   });
26   return dst;
27 }
28
29 /**
30  * Finds the common ancestor path between two states.
31  *
32  * @param {Object} first The first state.
33  * @param {Object} second The second state.
34  * @return {Array} Returns an array of state names in descending order, not including the root.
35  */
36 function ancestors(first, second) {
37   var path = [];
38
39   for (var n in first.path) {
40     if (first.path[n] !== second.path[n]) break;
41     path.push(first.path[n]);
42   }
43   return path;
44 }
45
46 /**
47  * IE8-safe wrapper for `Object.keys()`.
48  *
49  * @param {Object} object A JavaScript object.
50  * @return {Array} Returns the keys of the object as an array.
51  */
52 function objectKeys(object) {
53   if (Object.keys) {
54     return Object.keys(object);
55   }
56   var result = [];
57
58   angular.forEach(object, function(val, key) {
59     result.push(key);
60   });
61   return result;
62 }
63
64 /**
65  * IE8-safe wrapper for `Array.prototype.indexOf()`.
66  *
67  * @param {Array} array A JavaScript array.
68  * @param {*} value A value to search the array for.
69  * @return {Number} Returns the array index value of `value`, or `-1` if not present.
70  */
71 function indexOf(array, value) {
72   if (Array.prototype.indexOf) {
73     return array.indexOf(value, Number(arguments[2]) || 0);
74   }
75   var len = array.length >>> 0, from = Number(arguments[2]) || 0;
76   from = (from < 0) ? Math.ceil(from) : Math.floor(from);
77
78   if (from < 0) from += len;
79
80   for (; from < len; from++) {
81     if (from in array && array[from] === value) return from;
82   }
83   return -1;
84 }
85
86 /**
87  * Merges a set of parameters with all parameters inherited between the common parents of the
88  * current state and a given destination state.
89  *
90  * @param {Object} currentParams The value of the current state parameters ($stateParams).
91  * @param {Object} newParams The set of parameters which will be composited with inherited params.
92  * @param {Object} $current Internal definition of object representing the current state.
93  * @param {Object} $to Internal definition of object representing state to transition to.
94  */
95 function inheritParams(currentParams, newParams, $current, $to) {
96   var parents = ancestors($current, $to), parentParams, inherited = {}, inheritList = [];
97
98   for (var i in parents) {
99     if (!parents[i].params) continue;
100     parentParams = objectKeys(parents[i].params);
101     if (!parentParams.length) continue;
102
103     for (var j in parentParams) {
104       if (indexOf(inheritList, parentParams[j]) >= 0) continue;
105       inheritList.push(parentParams[j]);
106       inherited[parentParams[j]] = currentParams[parentParams[j]];
107     }
108   }
109   return extend({}, inherited, newParams);
110 }
111
112 /**
113  * Performs a non-strict comparison of the subset of two objects, defined by a list of keys.
114  *
115  * @param {Object} a The first object.
116  * @param {Object} b The second object.
117  * @param {Array} keys The list of keys within each object to compare. If the list is empty or not specified,
118  *                     it defaults to the list of keys in `a`.
119  * @return {Boolean} Returns `true` if the keys match, otherwise `false`.
120  */
121 function equalForKeys(a, b, keys) {
122   if (!keys) {
123     keys = [];
124     for (var n in a) keys.push(n); // Used instead of Object.keys() for IE8 compatibility
125   }
126
127   for (var i=0; i<keys.length; i++) {
128     var k = keys[i];
129     if (a[k] != b[k]) return false; // Not '===', values aren't necessarily normalized
130   }
131   return true;
132 }
133
134 /**
135  * Returns the subset of an object, based on a list of keys.
136  *
137  * @param {Array} keys
138  * @param {Object} values
139  * @return {Boolean} Returns a subset of `values`.
140  */
141 function filterByKeys(keys, values) {
142   var filtered = {};
143
144   forEach(keys, function (name) {
145     filtered[name] = values[name];
146   });
147   return filtered;
148 }
149
150 // like _.indexBy
151 // when you know that your index values will be unique, or you want last-one-in to win
152 function indexBy(array, propName) {
153   var result = {};
154   forEach(array, function(item) {
155     result[item[propName]] = item;
156   });
157   return result;
158 }
159
160 // extracted from underscore.js
161 // Return a copy of the object only containing the whitelisted properties.
162 function pick(obj) {
163   var copy = {};
164   var keys = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1));
165   forEach(keys, function(key) {
166     if (key in obj) copy[key] = obj[key];
167   });
168   return copy;
169 }
170
171 // extracted from underscore.js
172 // Return a copy of the object omitting the blacklisted properties.
173 function omit(obj) {
174   var copy = {};
175   var keys = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1));
176   for (var key in obj) {
177     if (indexOf(keys, key) == -1) copy[key] = obj[key];
178   }
179   return copy;
180 }
181
182 function pluck(collection, key) {
183   var result = isArray(collection) ? [] : {};
184
185   forEach(collection, function(val, i) {
186     result[i] = isFunction(key) ? key(val) : val[key];
187   });
188   return result;
189 }
190
191 function filter(collection, callback) {
192   var array = isArray(collection);
193   var result = array ? [] : {};
194   forEach(collection, function(val, i) {
195     if (callback(val, i)) {
196       result[array ? result.length : i] = val;
197     }
198   });
199   return result;
200 }
201
202 function map(collection, callback) {
203   var result = isArray(collection) ? [] : {};
204
205   forEach(collection, function(val, i) {
206     result[i] = callback(val, i);
207   });
208   return result;
209 }
210
211 /**
212  * @ngdoc overview
213  * @name ui.router.util
214  *
215  * @description
216  * # ui.router.util sub-module
217  *
218  * This module is a dependency of other sub-modules. Do not include this module as a dependency
219  * in your angular app (use {@link ui.router} module instead).
220  *
221  */
222 angular.module('ui.router.util', ['ng']);
223
224 /**
225  * @ngdoc overview
226  * @name ui.router.router
227  * 
228  * @requires ui.router.util
229  *
230  * @description
231  * # ui.router.router sub-module
232  *
233  * This module is a dependency of other sub-modules. Do not include this module as a dependency
234  * in your angular app (use {@link ui.router} module instead).
235  */
236 angular.module('ui.router.router', ['ui.router.util']);
237
238 /**
239  * @ngdoc overview
240  * @name ui.router.state
241  * 
242  * @requires ui.router.router
243  * @requires ui.router.util
244  *
245  * @description
246  * # ui.router.state sub-module
247  *
248  * This module is a dependency of the main ui.router module. Do not include this module as a dependency
249  * in your angular app (use {@link ui.router} module instead).
250  * 
251  */
252 angular.module('ui.router.state', ['ui.router.router', 'ui.router.util']);
253
254 /**
255  * @ngdoc overview
256  * @name ui.router
257  *
258  * @requires ui.router.state
259  *
260  * @description
261  * # ui.router
262  * 
263  * ## The main module for ui.router 
264  * There are several sub-modules included with the ui.router module, however only this module is needed
265  * as a dependency within your angular app. The other modules are for organization purposes. 
266  *
267  * The modules are:
268  * * ui.router - the main "umbrella" module
269  * * ui.router.router - 
270  * 
271  * *You'll need to include **only** this module as the dependency within your angular app.*
272  * 
273  * <pre>
274  * <!doctype html>
275  * <html ng-app="myApp">
276  * <head>
277  *   <script src="js/angular.js"></script>
278  *   <!-- Include the ui-router script -->
279  *   <script src="js/angular-ui-router.min.js"></script>
280  *   <script>
281  *     // ...and add 'ui.router' as a dependency
282  *     var myApp = angular.module('myApp', ['ui.router']);
283  *   </script>
284  * </head>
285  * <body>
286  * </body>
287  * </html>
288  * </pre>
289  */
290 angular.module('ui.router', ['ui.router.state']);
291
292 angular.module('ui.router.compat', ['ui.router']);