angularjs-rails 1.5.8 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  }