1 /*jshint globalstrict:true*/
2 /*global angular:false*/
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,
13 toJson = angular.toJson;
15 function inherit(parent, extra) {
16 return extend(new (extend(function() {}, { prototype: parent }))(), extra);
20 forEach(arguments, function(obj) {
22 forEach(obj, function(value, key) {
23 if (!dst.hasOwnProperty(key)) dst[key] = value;
31 * Finds the common ancestor path between two states.
33 * @param {Object} first The first state.
34 * @param {Object} second The second state.
35 * @return {Array} Returns an array of state names in descending order, not including the root.
37 function ancestors(first, second) {
40 for (var n in first.path) {
41 if (first.path[n] !== second.path[n]) break;
42 path.push(first.path[n]);
48 * IE8-safe wrapper for `Object.keys()`.
50 * @param {Object} object A JavaScript object.
51 * @return {Array} Returns the keys of the object as an array.
53 function objectKeys(object) {
55 return Object.keys(object);
59 forEach(object, function(val, key) {
66 * IE8-safe wrapper for `Array.prototype.indexOf()`.
68 * @param {Array} array A JavaScript array.
69 * @param {*} value A value to search the array for.
70 * @return {Number} Returns the array index value of `value`, or `-1` if not present.
72 function indexOf(array, value) {
73 if (Array.prototype.indexOf) {
74 return array.indexOf(value, Number(arguments[2]) || 0);
76 var len = array.length >>> 0, from = Number(arguments[2]) || 0;
77 from = (from < 0) ? Math.ceil(from) : Math.floor(from);
79 if (from < 0) from += len;
81 for (; from < len; from++) {
82 if (from in array && array[from] === value) return from;
88 * Merges a set of parameters with all parameters inherited between the common parents of the
89 * current state and a given destination state.
91 * @param {Object} currentParams The value of the current state parameters ($stateParams).
92 * @param {Object} newParams The set of parameters which will be composited with inherited params.
93 * @param {Object} $current Internal definition of object representing the current state.
94 * @param {Object} $to Internal definition of object representing state to transition to.
96 function inheritParams(currentParams, newParams, $current, $to) {
97 var parents = ancestors($current, $to), parentParams, inherited = {}, inheritList = [];
99 for (var i in parents) {
100 if (!parents[i] || !parents[i].params) continue;
101 parentParams = objectKeys(parents[i].params);
102 if (!parentParams.length) continue;
104 for (var j in parentParams) {
105 if (indexOf(inheritList, parentParams[j]) >= 0) continue;
106 inheritList.push(parentParams[j]);
107 inherited[parentParams[j]] = currentParams[parentParams[j]];
110 return extend({}, inherited, newParams);
114 * Performs a non-strict comparison of the subset of two objects, defined by a list of keys.
116 * @param {Object} a The first object.
117 * @param {Object} b The second object.
118 * @param {Array} keys The list of keys within each object to compare. If the list is empty or not specified,
119 * it defaults to the list of keys in `a`.
120 * @return {Boolean} Returns `true` if the keys match, otherwise `false`.
122 function equalForKeys(a, b, keys) {
125 for (var n in a) keys.push(n); // Used instead of Object.keys() for IE8 compatibility
128 for (var i=0; i<keys.length; i++) {
130 if (a[k] != b[k]) return false; // Not '===', values aren't necessarily normalized
136 * Returns the subset of an object, based on a list of keys.
138 * @param {Array} keys
139 * @param {Object} values
140 * @return {Boolean} Returns a subset of `values`.
142 function filterByKeys(keys, values) {
145 forEach(keys, function (name) {
146 filtered[name] = values[name];
152 // when you know that your index values will be unique, or you want last-one-in to win
153 function indexBy(array, propName) {
155 forEach(array, function(item) {
156 result[item[propName]] = item;
161 // extracted from underscore.js
162 // Return a copy of the object only containing the whitelisted properties.
165 var keys = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1));
166 forEach(keys, function(key) {
167 if (key in obj) copy[key] = obj[key];
172 // extracted from underscore.js
173 // Return a copy of the object omitting the blacklisted properties.
176 var keys = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1));
177 for (var key in obj) {
178 if (indexOf(keys, key) == -1) copy[key] = obj[key];
183 function pluck(collection, key) {
184 var result = isArray(collection) ? [] : {};
186 forEach(collection, function(val, i) {
187 result[i] = isFunction(key) ? key(val) : val[key];
192 function filter(collection, callback) {
193 var array = isArray(collection);
194 var result = array ? [] : {};
195 forEach(collection, function(val, i) {
196 if (callback(val, i)) {
197 result[array ? result.length : i] = val;
203 function map(collection, callback) {
204 var result = isArray(collection) ? [] : {};
206 forEach(collection, function(val, i) {
207 result[i] = callback(val, i);
214 * @name ui.router.util
217 * # ui.router.util sub-module
219 * This module is a dependency of other sub-modules. Do not include this module as a dependency
220 * in your angular app (use {@link ui.router} module instead).
223 angular.module('ui.router.util', ['ng']);
227 * @name ui.router.router
229 * @requires ui.router.util
232 * # ui.router.router sub-module
234 * This module is a dependency of other sub-modules. Do not include this module as a dependency
235 * in your angular app (use {@link ui.router} module instead).
237 angular.module('ui.router.router', ['ui.router.util']);
241 * @name ui.router.state
243 * @requires ui.router.router
244 * @requires ui.router.util
247 * # ui.router.state sub-module
249 * This module is a dependency of the main ui.router module. Do not include this module as a dependency
250 * in your angular app (use {@link ui.router} module instead).
253 angular.module('ui.router.state', ['ui.router.router', 'ui.router.util']);
259 * @requires ui.router.state
264 * ## The main module for ui.router
265 * There are several sub-modules included with the ui.router module, however only this module is needed
266 * as a dependency within your angular app. The other modules are for organization purposes.
269 * * ui.router - the main "umbrella" module
270 * * ui.router.router -
272 * *You'll need to include **only** this module as the dependency within your angular app.*
276 * <html ng-app="myApp">
278 * <script src="js/angular.js"></script>
279 * <!-- Include the ui-router script -->
280 * <script src="js/angular-ui-router.min.js"></script>
282 * // ...and add 'ui.router' as a dependency
283 * var myApp = angular.module('myApp', ['ui.router']);
291 angular.module('ui.router', ['ui.router.state']);
293 angular.module('ui.router.compat', ['ui.router']);