angularjs-rails 1.5.8 → 1.8.0

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.
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @license AngularJS v1.5.8
3
- * (c) 2010-2016 Google, Inc. http://angularjs.org
2
+ * @license AngularJS v1.8.0
3
+ * (c) 2010-2020 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
6
6
  (function(window, angular) {'use strict';
@@ -15,30 +15,28 @@
15
15
  * attributes that convey state or semantic information about the application for users
16
16
  * of assistive technologies, such as screen readers.
17
17
  *
18
- * <div doc-module-components="ngAria"></div>
19
- *
20
18
  * ## Usage
21
19
  *
22
20
  * For ngAria to do its magic, simply include the module `ngAria` as a dependency. The following
23
21
  * directives are supported:
24
- * `ngModel`, `ngChecked`, `ngReadonly`, `ngRequired`, `ngValue`, `ngDisabled`, `ngShow`, `ngHide`, `ngClick`,
25
- * `ngDblClick`, and `ngMessages`.
22
+ * `ngModel`, `ngChecked`, `ngReadonly`, `ngRequired`, `ngValue`, `ngDisabled`, `ngShow`, `ngHide`,
23
+ * `ngClick`, `ngDblClick`, and `ngMessages`.
26
24
  *
27
25
  * Below is a more detailed breakdown of the attributes handled by ngAria:
28
26
  *
29
- * | Directive | Supported Attributes |
30
- * |---------------------------------------------|----------------------------------------------------------------------------------------|
27
+ * | Directive | Supported Attributes |
28
+ * |---------------------------------------------|-----------------------------------------------------------------------------------------------------|
31
29
  * | {@link ng.directive:ngModel ngModel} | aria-checked, aria-valuemin, aria-valuemax, aria-valuenow, aria-invalid, aria-required, input roles |
32
- * | {@link ng.directive:ngDisabled ngDisabled} | aria-disabled |
33
- * | {@link ng.directive:ngRequired ngRequired} | aria-required
34
- * | {@link ng.directive:ngChecked ngChecked} | aria-checked
35
- * | {@link ng.directive:ngReadonly ngReadonly} | aria-readonly |
36
- * | {@link ng.directive:ngValue ngValue} | aria-checked |
37
- * | {@link ng.directive:ngShow ngShow} | aria-hidden |
38
- * | {@link ng.directive:ngHide ngHide} | aria-hidden |
39
- * | {@link ng.directive:ngDblclick ngDblclick} | tabindex |
40
- * | {@link module:ngMessages ngMessages} | aria-live |
41
- * | {@link ng.directive:ngClick ngClick} | tabindex, keypress event, button role |
30
+ * | {@link ng.directive:ngDisabled ngDisabled} | aria-disabled |
31
+ * | {@link ng.directive:ngRequired ngRequired} | aria-required |
32
+ * | {@link ng.directive:ngChecked ngChecked} | aria-checked |
33
+ * | {@link ng.directive:ngReadonly ngReadonly} | aria-readonly |
34
+ * | {@link ng.directive:ngValue ngValue} | aria-checked |
35
+ * | {@link ng.directive:ngShow ngShow} | aria-hidden |
36
+ * | {@link ng.directive:ngHide ngHide} | aria-hidden |
37
+ * | {@link ng.directive:ngDblclick ngDblclick} | tabindex |
38
+ * | {@link module:ngMessages ngMessages} | aria-live |
39
+ * | {@link ng.directive:ngClick ngClick} | tabindex, keydown event, button role |
42
40
  *
43
41
  * Find out more information about each directive by reading the
44
42
  * {@link guide/accessibility ngAria Developer Guide}.
@@ -53,13 +51,19 @@
53
51
  * <md-checkbox ng-disabled="disabled" aria-disabled="true">
54
52
  * ```
55
53
  *
56
- * ## Disabling Attributes
57
- * It's possible to disable individual attributes added by ngAria with the
54
+ * ## Disabling Specific Attributes
55
+ * It is possible to disable individual attributes added by ngAria with the
58
56
  * {@link ngAria.$ariaProvider#config config} method. For more details, see the
59
57
  * {@link guide/accessibility Developer Guide}.
58
+ *
59
+ * ## Disabling `ngAria` on Specific Elements
60
+ * It is possible to make `ngAria` ignore a specific element, by adding the `ng-aria-disable`
61
+ * attribute on it. Note that only the element itself (and not its child elements) will be ignored.
60
62
  */
61
- /* global -ngAriaModule */
63
+ var ARIA_DISABLE_ATTR = 'ngAriaDisable';
64
+
62
65
  var ngAriaModule = angular.module('ngAria', ['ng']).
66
+ info({ angularVersion: '1.8.0' }).
63
67
  provider('$aria', $AriaProvider);
64
68
 
65
69
  /**
@@ -75,6 +79,7 @@ var isNodeOneOf = function(elem, nodeTypeArray) {
75
79
  /**
76
80
  * @ngdoc provider
77
81
  * @name $ariaProvider
82
+ * @this
78
83
  *
79
84
  * @description
80
85
  *
@@ -103,7 +108,7 @@ function $AriaProvider() {
103
108
  ariaInvalid: true,
104
109
  ariaValue: true,
105
110
  tabindex: true,
106
- bindKeypress: true,
111
+ bindKeydown: true,
107
112
  bindRoleForClick: true
108
113
  };
109
114
 
@@ -119,12 +124,15 @@ function $AriaProvider() {
119
124
  * - **ariaDisabled** – `{boolean}` – Enables/disables aria-disabled tags
120
125
  * - **ariaRequired** – `{boolean}` – Enables/disables aria-required tags
121
126
  * - **ariaInvalid** – `{boolean}` – Enables/disables aria-invalid tags
122
- * - **ariaValue** – `{boolean}` – Enables/disables aria-valuemin, aria-valuemax and aria-valuenow tags
127
+ * - **ariaValue** – `{boolean}` – Enables/disables aria-valuemin, aria-valuemax and
128
+ * aria-valuenow tags
123
129
  * - **tabindex** – `{boolean}` – Enables/disables tabindex tags
124
- * - **bindKeypress** – `{boolean}` – Enables/disables keypress event binding on `div` and
125
- * `li` elements with ng-click
126
- * - **bindRoleForClick** – `{boolean}` – Adds role=button to non-interactive elements like `div`
127
- * using ng-click, making them more accessible to users of assistive technologies
130
+ * - **bindKeydown** – `{boolean}` – Enables/disables keyboard event binding on non-interactive
131
+ * elements (such as `div` or `li`) using ng-click, making them more accessible to users of
132
+ * assistive technologies
133
+ * - **bindRoleForClick** `{boolean}` Adds role=button to non-interactive elements (such as
134
+ * `div` or `li`) using ng-click, making them more accessible to users of assistive
135
+ * technologies
128
136
  *
129
137
  * @description
130
138
  * Enables/disables various ARIA attributes
@@ -135,6 +143,8 @@ function $AriaProvider() {
135
143
 
136
144
  function watchExpr(attrName, ariaAttr, nodeBlackList, negate) {
137
145
  return function(scope, elem, attr) {
146
+ if (attr.hasOwnProperty(ARIA_DISABLE_ATTR)) return;
147
+
138
148
  var ariaCamelName = attr.$normalize(ariaAttr);
139
149
  if (config[ariaCamelName] && !isNodeOneOf(elem, nodeBlackList) && !attr[ariaCamelName]) {
140
150
  scope.$watch(attr[attrName], function(boolVal) {
@@ -150,7 +160,6 @@ function $AriaProvider() {
150
160
  * @name $aria
151
161
  *
152
162
  * @description
153
- * @priority 200
154
163
  *
155
164
  * The $aria service contains helper methods for applying common
156
165
  * [ARIA](http://www.w3.org/TR/wai-aria/) attributes to HTML directives.
@@ -227,14 +236,17 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
227
236
  .directive('ngModel', ['$aria', function($aria) {
228
237
 
229
238
  function shouldAttachAttr(attr, normalizedAttr, elem, allowBlacklistEls) {
230
- return $aria.config(normalizedAttr) && !elem.attr(attr) && (allowBlacklistEls || !isNodeOneOf(elem, nodeBlackList));
239
+ return $aria.config(normalizedAttr) &&
240
+ !elem.attr(attr) &&
241
+ (allowBlacklistEls || !isNodeOneOf(elem, nodeBlackList)) &&
242
+ (elem.attr('type') !== 'hidden' || elem[0].nodeName !== 'INPUT');
231
243
  }
232
244
 
233
245
  function shouldAttachRole(role, elem) {
234
246
  // if element does not have role attribute
235
247
  // AND element type is equal to role (if custom element has a type equaling shape) <-- remove?
236
- // AND element is not INPUT
237
- return !elem.attr('role') && (elem.attr('type') === role) && (elem[0].nodeName !== 'INPUT');
248
+ // AND element is not in nodeBlackList
249
+ return !elem.attr('role') && (elem.attr('type') === role) && !isNodeOneOf(elem, nodeBlackList);
238
250
  }
239
251
 
240
252
  function getShape(attr, elem) {
@@ -251,17 +263,11 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
251
263
  require: 'ngModel',
252
264
  priority: 200, //Make sure watches are fired after any other directives that affect the ngModel value
253
265
  compile: function(elem, attr) {
266
+ if (attr.hasOwnProperty(ARIA_DISABLE_ATTR)) return;
267
+
254
268
  var shape = getShape(attr, elem);
255
269
 
256
270
  return {
257
- pre: function(scope, elem, attr, ngModel) {
258
- if (shape === 'checkbox') {
259
- //Use the input[checkbox] $isEmpty implementation for elements with checkbox roles
260
- ngModel.$isEmpty = function(value) {
261
- return value === false;
262
- };
263
- }
264
- },
265
271
  post: function(scope, elem, attr, ngModel) {
266
272
  var needsTabIndex = shouldAttachAttr('tabindex', 'tabindex', elem, false);
267
273
 
@@ -270,6 +276,8 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
270
276
  }
271
277
 
272
278
  function getRadioReaction(newVal) {
279
+ // Strict comparison would cause a BC
280
+ // eslint-disable-next-line eqeqeq
273
281
  var boolVal = (attr.value == ngModel.$viewValue);
274
282
  elem.attr('aria-checked', boolVal);
275
283
  }
@@ -353,6 +361,8 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
353
361
  restrict: 'A',
354
362
  require: '?ngMessages',
355
363
  link: function(scope, elem, attr, ngMessages) {
364
+ if (attr.hasOwnProperty(ARIA_DISABLE_ATTR)) return;
365
+
356
366
  if (!elem.attr('aria-live')) {
357
367
  elem.attr('aria-live', 'assertive');
358
368
  }
@@ -363,7 +373,9 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
363
373
  return {
364
374
  restrict: 'A',
365
375
  compile: function(elem, attr) {
366
- var fn = $parse(attr.ngClick, /* interceptorFn */ null, /* expensiveChecks */ true);
376
+ if (attr.hasOwnProperty(ARIA_DISABLE_ATTR)) return;
377
+
378
+ var fn = $parse(attr.ngClick);
367
379
  return function(scope, elem, attr) {
368
380
 
369
381
  if (!isNodeOneOf(elem, nodeBlackList)) {
@@ -376,10 +388,17 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
376
388
  elem.attr('tabindex', 0);
377
389
  }
378
390
 
379
- if ($aria.config('bindKeypress') && !attr.ngKeypress) {
380
- elem.on('keypress', function(event) {
391
+ if ($aria.config('bindKeydown') && !attr.ngKeydown && !attr.ngKeypress && !attr.ngKeyup) {
392
+ elem.on('keydown', function(event) {
381
393
  var keyCode = event.which || event.keyCode;
382
- if (keyCode === 32 || keyCode === 13) {
394
+
395
+ if (keyCode === 13 || keyCode === 32) {
396
+ // If the event is triggered on a non-interactive element ...
397
+ if (nodeBlackList.indexOf(event.target.nodeName) === -1 && !event.target.isContentEditable) {
398
+ // ... prevent the default browser behavior (e.g. scrolling when pressing spacebar)
399
+ // See https://github.com/angular/angular.js/issues/16664
400
+ event.preventDefault();
401
+ }
383
402
  scope.$apply(callback);
384
403
  }
385
404
 
@@ -395,6 +414,8 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
395
414
  }])
396
415
  .directive('ngDblclick', ['$aria', function($aria) {
397
416
  return function(scope, elem, attr) {
417
+ if (attr.hasOwnProperty(ARIA_DISABLE_ATTR)) return;
418
+
398
419
  if ($aria.config('tabindex') && !elem.attr('tabindex') && !isNodeOneOf(elem, nodeBlackList)) {
399
420
  elem.attr('tabindex', 0);
400
421
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @license AngularJS v1.5.8
3
- * (c) 2010-2016 Google, Inc. http://angularjs.org
2
+ * @license AngularJS v1.8.0
3
+ * (c) 2010-2020 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
6
6
  (function(window, angular) {'use strict';
@@ -10,25 +10,21 @@
10
10
  * @name ngCookies
11
11
  * @description
12
12
  *
13
- * # ngCookies
14
- *
15
13
  * The `ngCookies` module provides a convenient wrapper for reading and writing browser cookies.
16
14
  *
17
- *
18
- * <div doc-module-components="ngCookies"></div>
19
- *
20
15
  * See {@link ngCookies.$cookies `$cookies`} for usage.
21
16
  */
22
17
 
23
18
 
24
19
  angular.module('ngCookies', ['ng']).
20
+ info({ angularVersion: '1.8.0' }).
25
21
  /**
26
22
  * @ngdoc provider
27
23
  * @name $cookiesProvider
28
24
  * @description
29
25
  * Use `$cookiesProvider` to change the default behavior of the {@link ngCookies.$cookies $cookies} service.
30
26
  * */
31
- provider('$cookies', [function $CookiesProvider() {
27
+ provider('$cookies', [/** @this */function $CookiesProvider() {
32
28
  /**
33
29
  * @ngdoc property
34
30
  * @name $cookiesProvider#defaults
@@ -47,10 +43,24 @@ angular.module('ngCookies', ['ng']).
47
43
  * or a Date object indicating the exact date/time this cookie will expire.
48
44
  * - **secure** - `{boolean}` - If `true`, then the cookie will only be available through a
49
45
  * secured connection.
46
+ * - **samesite** - `{string}` - prevents the browser from sending the cookie along with cross-site requests.
47
+ * Accepts the values `lax` and `strict`. See the [OWASP Wiki](https://www.owasp.org/index.php/SameSite)
48
+ * for more info. Note that as of May 2018, not all browsers support `SameSite`,
49
+ * so it cannot be used as a single measure against Cross-Site-Request-Forgery (CSRF) attacks.
50
50
  *
51
51
  * Note: By default, the address that appears in your `<base>` tag will be used as the path.
52
52
  * This is important so that cookies will be visible for all routes when html5mode is enabled.
53
53
  *
54
+ * @example
55
+ *
56
+ * ```js
57
+ * angular.module('cookiesProviderExample', ['ngCookies'])
58
+ * .config(['$cookiesProvider', function($cookiesProvider) {
59
+ * // Setting default options
60
+ * $cookiesProvider.defaults.domain = 'foo.com';
61
+ * $cookiesProvider.defaults.secure = true;
62
+ * }]);
63
+ * ```
54
64
  **/
55
65
  var defaults = this.defaults = {};
56
66
 
@@ -66,7 +76,7 @@ angular.module('ngCookies', ['ng']).
66
76
  * Provides read/write access to browser's cookies.
67
77
  *
68
78
  * <div class="alert alert-info">
69
- * Up until Angular 1.3, `$cookies` exposed properties that represented the
79
+ * Up until AngularJS 1.3, `$cookies` exposed properties that represented the
70
80
  * current browser cookie values. In version 1.4, this behavior has changed, and
71
81
  * `$cookies` now provides a standard api of getters, setters etc.
72
82
  * </div>
@@ -179,86 +189,6 @@ angular.module('ngCookies', ['ng']).
179
189
  }];
180
190
  }]);
181
191
 
182
- angular.module('ngCookies').
183
- /**
184
- * @ngdoc service
185
- * @name $cookieStore
186
- * @deprecated
187
- * @requires $cookies
188
- *
189
- * @description
190
- * Provides a key-value (string-object) storage, that is backed by session cookies.
191
- * Objects put or retrieved from this storage are automatically serialized or
192
- * deserialized by angular's toJson/fromJson.
193
- *
194
- * Requires the {@link ngCookies `ngCookies`} module to be installed.
195
- *
196
- * <div class="alert alert-danger">
197
- * **Note:** The $cookieStore service is **deprecated**.
198
- * Please use the {@link ngCookies.$cookies `$cookies`} service instead.
199
- * </div>
200
- *
201
- * @example
202
- *
203
- * ```js
204
- * angular.module('cookieStoreExample', ['ngCookies'])
205
- * .controller('ExampleController', ['$cookieStore', function($cookieStore) {
206
- * // Put cookie
207
- * $cookieStore.put('myFavorite','oatmeal');
208
- * // Get cookie
209
- * var favoriteCookie = $cookieStore.get('myFavorite');
210
- * // Removing a cookie
211
- * $cookieStore.remove('myFavorite');
212
- * }]);
213
- * ```
214
- */
215
- factory('$cookieStore', ['$cookies', function($cookies) {
216
-
217
- return {
218
- /**
219
- * @ngdoc method
220
- * @name $cookieStore#get
221
- *
222
- * @description
223
- * Returns the value of given cookie key
224
- *
225
- * @param {string} key Id to use for lookup.
226
- * @returns {Object} Deserialized cookie value, undefined if the cookie does not exist.
227
- */
228
- get: function(key) {
229
- return $cookies.getObject(key);
230
- },
231
-
232
- /**
233
- * @ngdoc method
234
- * @name $cookieStore#put
235
- *
236
- * @description
237
- * Sets a value for given cookie key
238
- *
239
- * @param {string} key Id for the `value`.
240
- * @param {Object} value Value to be stored.
241
- */
242
- put: function(key, value) {
243
- $cookies.putObject(key, value);
244
- },
245
-
246
- /**
247
- * @ngdoc method
248
- * @name $cookieStore#remove
249
- *
250
- * @description
251
- * Remove given cookie
252
- *
253
- * @param {string} key Id of the key-value pair to delete.
254
- */
255
- remove: function(key) {
256
- $cookies.remove(key);
257
- }
258
- };
259
-
260
- }]);
261
-
262
192
  /**
263
193
  * @name $$cookieWriter
264
194
  * @requires $document
@@ -292,6 +222,7 @@ function $$CookieWriter($document, $log, $browser) {
292
222
  str += options.domain ? ';domain=' + options.domain : '';
293
223
  str += expires ? ';expires=' + expires.toUTCString() : '';
294
224
  str += options.secure ? ';secure' : '';
225
+ str += options.samesite ? ';samesite=' + options.samesite : '';
295
226
 
296
227
  // per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum:
297
228
  // - 300 cookies
@@ -299,9 +230,9 @@ function $$CookieWriter($document, $log, $browser) {
299
230
  // - 4096 bytes per cookie
300
231
  var cookieLength = str.length + 1;
301
232
  if (cookieLength > 4096) {
302
- $log.warn("Cookie '" + name +
303
- "' possibly not set or overflowed because it was too large (" +
304
- cookieLength + " > 4096 bytes)!");
233
+ $log.warn('Cookie \'' + name +
234
+ '\' possibly not set or overflowed because it was too large (' +
235
+ cookieLength + ' > 4096 bytes)!');
305
236
  }
306
237
 
307
238
  return str;
@@ -314,7 +245,7 @@ function $$CookieWriter($document, $log, $browser) {
314
245
 
315
246
  $$CookieWriter.$inject = ['$document', '$log', '$browser'];
316
247
 
317
- angular.module('ngCookies').provider('$$cookieWriter', function $$CookieWriterProvider() {
248
+ angular.module('ngCookies').provider('$$cookieWriter', /** @this */ function $$CookieWriterProvider() {
318
249
  this.$get = $$CookieWriter;
319
250
  });
320
251
 
@@ -1,17 +1,51 @@
1
1
  /**
2
- * @license AngularJS v1.5.8
3
- * (c) 2010-2016 Google, Inc. http://angularjs.org
2
+ * @license AngularJS v1.8.0
3
+ * (c) 2010-2020 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
6
6
 
7
7
  (function() {'use strict';
8
- function isFunction(value) {return typeof value === 'function';};
8
+ // NOTE:
9
+ // These functions are copied here from `src/Angular.js`, because they are needed inside the
10
+ // `angular-loader.js` closure and need to be available before the main `angular.js` script has
11
+ // been loaded.
12
+ function isFunction(value) {return typeof value === 'function';}
13
+ function isDefined(value) {return typeof value !== 'undefined';}
14
+ function isNumber(value) {return typeof value === 'number';}
15
+ function isObject(value) {return value !== null && typeof value === 'object';}
16
+ function isScope(obj) {return obj && obj.$evalAsync && obj.$watch;}
17
+ function isUndefined(value) {return typeof value === 'undefined';}
18
+ function isWindow(obj) {return obj && obj.window === obj;}
19
+ function sliceArgs(args, startIndex) {return Array.prototype.slice.call(args, startIndex || 0);}
20
+ function toJsonReplacer(key, value) {
21
+ var val = value;
22
+
23
+ if (typeof key === 'string' && key.charAt(0) === '$' && key.charAt(1) === '$') {
24
+ val = undefined;
25
+ } else if (isWindow(value)) {
26
+ val = '$WINDOW';
27
+ } else if (value && window.document === value) {
28
+ val = '$DOCUMENT';
29
+ } else if (isScope(value)) {
30
+ val = '$SCOPE';
31
+ }
32
+
33
+ return val;
34
+ }
9
35
 
10
- /* global toDebugString: true */
36
+ /* exported toDebugString */
11
37
 
12
- function serializeObject(obj) {
38
+ function serializeObject(obj, maxDepth) {
13
39
  var seen = [];
14
40
 
41
+ // There is no direct way to stringify object until reaching a specific depth
42
+ // and a very deep object can cause a performance issue, so we copy the object
43
+ // based on this specific depth and then stringify it.
44
+ if (isValidObjectMaxDepth(maxDepth)) {
45
+ // This file is also included in `angular-loader`, so `copy()` might not always be available in
46
+ // the closure. Therefore, it is lazily retrieved as `angular.copy()` when needed.
47
+ obj = angular.copy(obj, null, maxDepth);
48
+ }
15
49
  return JSON.stringify(obj, function(key, val) {
16
50
  val = toJsonReplacer(key, val);
17
51
  if (isObject(val)) {
@@ -24,22 +58,83 @@ function serializeObject(obj) {
24
58
  });
25
59
  }
26
60
 
27
- function toDebugString(obj) {
61
+ function toDebugString(obj, maxDepth) {
28
62
  if (typeof obj === 'function') {
29
63
  return obj.toString().replace(/ \{[\s\S]*$/, '');
30
64
  } else if (isUndefined(obj)) {
31
65
  return 'undefined';
32
66
  } else if (typeof obj !== 'string') {
33
- return serializeObject(obj);
67
+ return serializeObject(obj, maxDepth);
34
68
  }
35
69
  return obj;
36
70
  }
37
71
 
72
+ /* exported
73
+ minErrConfig,
74
+ errorHandlingConfig,
75
+ isValidObjectMaxDepth
76
+ */
77
+
78
+ var minErrConfig = {
79
+ objectMaxDepth: 5,
80
+ urlErrorParamsEnabled: true
81
+ };
82
+
83
+ /**
84
+ * @ngdoc function
85
+ * @name angular.errorHandlingConfig
86
+ * @module ng
87
+ * @kind function
88
+ *
89
+ * @description
90
+ * Configure several aspects of error handling in AngularJS if used as a setter or return the
91
+ * current configuration if used as a getter. The following options are supported:
92
+ *
93
+ * - **objectMaxDepth**: The maximum depth to which objects are traversed when stringified for error messages.
94
+ *
95
+ * Omitted or undefined options will leave the corresponding configuration values unchanged.
96
+ *
97
+ * @param {Object=} config - The configuration object. May only contain the options that need to be
98
+ * updated. Supported keys:
99
+ *
100
+ * * `objectMaxDepth` **{Number}** - The max depth for stringifying objects. Setting to a
101
+ * non-positive or non-numeric value, removes the max depth limit.
102
+ * Default: 5
103
+ *
104
+ * * `urlErrorParamsEnabled` **{Boolean}** - Specifies whether the generated error url will
105
+ * contain the parameters of the thrown error. Disabling the parameters can be useful if the
106
+ * generated error url is very long.
107
+ *
108
+ * Default: true. When used without argument, it returns the current value.
109
+ */
110
+ function errorHandlingConfig(config) {
111
+ if (isObject(config)) {
112
+ if (isDefined(config.objectMaxDepth)) {
113
+ minErrConfig.objectMaxDepth = isValidObjectMaxDepth(config.objectMaxDepth) ? config.objectMaxDepth : NaN;
114
+ }
115
+ if (isDefined(config.urlErrorParamsEnabled) && isBoolean(config.urlErrorParamsEnabled)) {
116
+ minErrConfig.urlErrorParamsEnabled = config.urlErrorParamsEnabled;
117
+ }
118
+ } else {
119
+ return minErrConfig;
120
+ }
121
+ }
122
+
123
+ /**
124
+ * @private
125
+ * @param {Number} maxDepth
126
+ * @return {boolean}
127
+ */
128
+ function isValidObjectMaxDepth(maxDepth) {
129
+ return isNumber(maxDepth) && maxDepth > 0;
130
+ }
131
+
132
+
38
133
  /**
39
134
  * @description
40
135
  *
41
136
  * This object provides a utility for producing rich Error messages within
42
- * Angular. It can be called as follows:
137
+ * AngularJS. It can be called as follows:
43
138
  *
44
139
  * var exampleMinErr = minErr('example');
45
140
  * throw exampleMinErr('one', 'This {0} is {1}', foo, bar);
@@ -56,7 +151,7 @@ function toDebugString(obj) {
56
151
  * Since data will be parsed statically during a build step, some restrictions
57
152
  * are applied with respect to how minErr instances are created and called.
58
153
  * Instances should have names of the form namespaceMinErr for a minErr created
59
- * using minErr('namespace') . Error codes, namespaces and template strings
154
+ * using minErr('namespace'). Error codes, namespaces and template strings
60
155
  * should all be static strings, not variables or general expressions.
61
156
  *
62
157
  * @param {string} module The namespace to use for the new minErr instance.
@@ -67,32 +162,41 @@ function toDebugString(obj) {
67
162
 
68
163
  function minErr(module, ErrorConstructor) {
69
164
  ErrorConstructor = ErrorConstructor || Error;
70
- return function() {
71
- var SKIP_INDEXES = 2;
72
165
 
73
- var templateArgs = arguments,
74
- code = templateArgs[0],
166
+ var url = 'https://errors.angularjs.org/1.8.0/';
167
+ var regex = url.replace('.', '\\.') + '[\\s\\S]*';
168
+ var errRegExp = new RegExp(regex, 'g');
169
+
170
+ return function() {
171
+ var code = arguments[0],
172
+ template = arguments[1],
75
173
  message = '[' + (module ? module + ':' : '') + code + '] ',
76
- template = templateArgs[1],
174
+ templateArgs = sliceArgs(arguments, 2).map(function(arg) {
175
+ return toDebugString(arg, minErrConfig.objectMaxDepth);
176
+ }),
77
177
  paramPrefix, i;
78
178
 
179
+ // A minErr message has two parts: the message itself and the url that contains the
180
+ // encoded message.
181
+ // The message's parameters can contain other error messages which also include error urls.
182
+ // To prevent the messages from getting too long, we strip the error urls from the parameters.
183
+
79
184
  message += template.replace(/\{\d+\}/g, function(match) {
80
- var index = +match.slice(1, -1),
81
- shiftedIndex = index + SKIP_INDEXES;
185
+ var index = +match.slice(1, -1);
82
186
 
83
- if (shiftedIndex < templateArgs.length) {
84
- return toDebugString(templateArgs[shiftedIndex]);
187
+ if (index < templateArgs.length) {
188
+ return templateArgs[index].replace(errRegExp, '');
85
189
  }
86
190
 
87
191
  return match;
88
192
  });
89
193
 
90
- message += '\nhttp://errors.angularjs.org/1.5.8/' +
91
- (module ? module + '/' : '') + code;
194
+ message += '\n' + url + (module ? module + '/' : '') + code;
92
195
 
93
- for (i = SKIP_INDEXES, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {
94
- message += paramPrefix + 'p' + (i - SKIP_INDEXES) + '=' +
95
- encodeURIComponent(toDebugString(templateArgs[i]));
196
+ if (minErrConfig.urlErrorParamsEnabled) {
197
+ for (i = 0, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {
198
+ message += paramPrefix + 'p' + i + '=' + encodeURIComponent(templateArgs[i]);
199
+ }
96
200
  }
97
201
 
98
202
  return new ErrorConstructor(message);
@@ -105,7 +209,7 @@ function minErr(module, ErrorConstructor) {
105
209
  * @module ng
106
210
  * @description
107
211
  *
108
- * Interface for configuring angular {@link angular.module modules}.
212
+ * Interface for configuring AngularJS {@link angular.module modules}.
109
213
  */
110
214
 
111
215
  function setupModuleLoader(window) {
@@ -132,9 +236,9 @@ function setupModuleLoader(window) {
132
236
  * @module ng
133
237
  * @description
134
238
  *
135
- * The `angular.module` is a global place for creating, registering and retrieving Angular
239
+ * The `angular.module` is a global place for creating, registering and retrieving AngularJS
136
240
  * modules.
137
- * All modules (angular core or 3rd party) that should be available to an application must be
241
+ * All modules (AngularJS core or 3rd party) that should be available to an application must be
138
242
  * registered using this mechanism.
139
243
  *
140
244
  * Passing one argument retrieves an existing {@link angular.Module},
@@ -178,6 +282,9 @@ function setupModuleLoader(window) {
178
282
  * @returns {angular.Module} new module with the {@link angular.Module} api.
179
283
  */
180
284
  return function module(name, requires, configFn) {
285
+
286
+ var info = {};
287
+
181
288
  var assertNotHasOwnProperty = function(name, context) {
182
289
  if (name === 'hasOwnProperty') {
183
290
  throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
@@ -190,9 +297,9 @@ function setupModuleLoader(window) {
190
297
  }
191
298
  return ensure(modules, name, function() {
192
299
  if (!requires) {
193
- throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " +
194
- "the module name or forgot to load it. If registering a module ensure that you " +
195
- "specify the dependencies as the second argument.", name);
300
+ throw $injectorMinErr('nomod', 'Module \'{0}\' is not available! You either misspelled ' +
301
+ 'the module name or forgot to load it. If registering a module ensure that you ' +
302
+ 'specify the dependencies as the second argument.', name);
196
303
  }
197
304
 
198
305
  /** @type {!Array.<Array.<*>>} */
@@ -213,6 +320,45 @@ function setupModuleLoader(window) {
213
320
  _configBlocks: configBlocks,
214
321
  _runBlocks: runBlocks,
215
322
 
323
+ /**
324
+ * @ngdoc method
325
+ * @name angular.Module#info
326
+ * @module ng
327
+ *
328
+ * @param {Object=} info Information about the module
329
+ * @returns {Object|Module} The current info object for this module if called as a getter,
330
+ * or `this` if called as a setter.
331
+ *
332
+ * @description
333
+ * Read and write custom information about this module.
334
+ * For example you could put the version of the module in here.
335
+ *
336
+ * ```js
337
+ * angular.module('myModule', []).info({ version: '1.0.0' });
338
+ * ```
339
+ *
340
+ * The version could then be read back out by accessing the module elsewhere:
341
+ *
342
+ * ```
343
+ * var version = angular.module('myModule').info().version;
344
+ * ```
345
+ *
346
+ * You can also retrieve this information during runtime via the
347
+ * {@link $injector#modules `$injector.modules`} property:
348
+ *
349
+ * ```js
350
+ * var version = $injector.modules['myModule'].info().version;
351
+ * ```
352
+ */
353
+ info: function(value) {
354
+ if (isDefined(value)) {
355
+ if (!isObject(value)) throw ngMinErr('aobj', 'Argument \'{0}\' must be an object', 'value');
356
+ info = value;
357
+ return this;
358
+ }
359
+ return info;
360
+ },
361
+
216
362
  /**
217
363
  * @ngdoc property
218
364
  * @name angular.Module#requires
@@ -302,7 +448,7 @@ function setupModuleLoader(window) {
302
448
  * @description
303
449
  * See {@link auto.$provide#decorator $provide.decorator()}.
304
450
  */
305
- decorator: invokeLaterAndSetModuleName('$provide', 'decorator'),
451
+ decorator: invokeLaterAndSetModuleName('$provide', 'decorator', configBlocks),
306
452
 
307
453
  /**
308
454
  * @ngdoc method
@@ -342,13 +488,13 @@ function setupModuleLoader(window) {
342
488
  * @ngdoc method
343
489
  * @name angular.Module#filter
344
490
  * @module ng
345
- * @param {string} name Filter name - this must be a valid angular expression identifier
491
+ * @param {string} name Filter name - this must be a valid AngularJS expression identifier
346
492
  * @param {Function} filterFactory Factory function for creating new instance of filter.
347
493
  * @description
348
494
  * See {@link ng.$filterProvider#register $filterProvider.register()}.
349
495
  *
350
496
  * <div class="alert alert-warning">
351
- * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`.
497
+ * **Note:** Filter names must be valid AngularJS {@link expression} identifiers, such as `uppercase` or `orderBy`.
352
498
  * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace
353
499
  * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores
354
500
  * (`myapp_subsection_filterx`).
@@ -385,7 +531,8 @@ function setupModuleLoader(window) {
385
531
  * @ngdoc method
386
532
  * @name angular.Module#component
387
533
  * @module ng
388
- * @param {string} name Name of the component in camel-case (i.e. myComp which will match as my-comp)
534
+ * @param {string|Object} name Name of the component in camelCase (i.e. `myComp` which will match `<my-comp>`),
535
+ * or an object map of components where the keys are the names and the values are the component definition objects.
389
536
  * @param {Object} options Component definition object (a simplified
390
537
  * {@link ng.$compile#directive-definition-object directive definition object})
391
538
  *
@@ -401,7 +548,13 @@ function setupModuleLoader(window) {
401
548
  * @param {Function} configFn Execute this function on module load. Useful for service
402
549
  * configuration.
403
550
  * @description
404
- * Use this method to register work which needs to be performed on module loading.
551
+ * Use this method to configure services by injecting their
552
+ * {@link angular.Module#provider `providers`}, e.g. for adding routes to the
553
+ * {@link ngRoute.$routeProvider $routeProvider}.
554
+ *
555
+ * Note that you can only inject {@link angular.Module#provider `providers`} and
556
+ * {@link angular.Module#constant `constants`} into this function.
557
+ *
405
558
  * For more about how to configure services, see
406
559
  * {@link providers#provider-recipe Provider Recipe}.
407
560
  */
@@ -448,10 +601,11 @@ function setupModuleLoader(window) {
448
601
  * @param {string} method
449
602
  * @returns {angular.Module}
450
603
  */
451
- function invokeLaterAndSetModuleName(provider, method) {
604
+ function invokeLaterAndSetModuleName(provider, method, queue) {
605
+ if (!queue) queue = invokeQueue;
452
606
  return function(recipeName, factoryFunction) {
453
607
  if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name;
454
- invokeQueue.push([provider, method, arguments]);
608
+ queue.push([provider, method, arguments]);
455
609
  return moduleInstance;
456
610
  };
457
611
  }