angular-gem 1.2.26 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. checksums.yaml +8 -8
  2. data/lib/angular-gem/version.rb +1 -1
  3. data/vendor/assets/javascripts/1.3.0/angular-animate.js +2112 -0
  4. data/vendor/assets/javascripts/1.3.0/angular-aria.js +250 -0
  5. data/vendor/assets/javascripts/1.3.0/angular-cookies.js +206 -0
  6. data/vendor/assets/javascripts/1.3.0/angular-loader.js +422 -0
  7. data/vendor/assets/javascripts/1.3.0/angular-messages.js +400 -0
  8. data/vendor/assets/javascripts/1.3.0/angular-mocks.js +2287 -0
  9. data/vendor/assets/javascripts/1.3.0/angular-resource.js +667 -0
  10. data/vendor/assets/javascripts/1.3.0/angular-route.js +978 -0
  11. data/vendor/assets/javascripts/1.3.0/angular-sanitize.js +647 -0
  12. data/vendor/assets/javascripts/1.3.0/angular-scenario.js +36944 -0
  13. data/vendor/assets/javascripts/1.3.0/angular-touch.js +622 -0
  14. data/vendor/assets/javascripts/1.3.0/angular.js +25584 -0
  15. data/vendor/assets/javascripts/angular-animate.js +879 -456
  16. data/vendor/assets/javascripts/angular-aria.js +250 -0
  17. data/vendor/assets/javascripts/angular-cookies.js +1 -1
  18. data/vendor/assets/javascripts/angular-loader.js +17 -10
  19. data/vendor/assets/javascripts/angular-messages.js +400 -0
  20. data/vendor/assets/javascripts/angular-mocks.js +220 -110
  21. data/vendor/assets/javascripts/angular-resource.js +287 -247
  22. data/vendor/assets/javascripts/angular-route.js +111 -54
  23. data/vendor/assets/javascripts/angular-sanitize.js +1 -1
  24. data/vendor/assets/javascripts/angular-scenario.js +11579 -8665
  25. data/vendor/assets/javascripts/angular-touch.js +49 -11
  26. data/vendor/assets/javascripts/angular.js +6660 -3106
  27. metadata +15 -1
@@ -0,0 +1,422 @@
1
+ /**
2
+ * @license AngularJS v1.3.0
3
+ * (c) 2010-2014 Google, Inc. http://angularjs.org
4
+ * License: MIT
5
+ */
6
+
7
+ (function() {'use strict';
8
+
9
+ /**
10
+ * @description
11
+ *
12
+ * This object provides a utility for producing rich Error messages within
13
+ * Angular. It can be called as follows:
14
+ *
15
+ * var exampleMinErr = minErr('example');
16
+ * throw exampleMinErr('one', 'This {0} is {1}', foo, bar);
17
+ *
18
+ * The above creates an instance of minErr in the example namespace. The
19
+ * resulting error will have a namespaced error code of example.one. The
20
+ * resulting error will replace {0} with the value of foo, and {1} with the
21
+ * value of bar. The object is not restricted in the number of arguments it can
22
+ * take.
23
+ *
24
+ * If fewer arguments are specified than necessary for interpolation, the extra
25
+ * interpolation markers will be preserved in the final string.
26
+ *
27
+ * Since data will be parsed statically during a build step, some restrictions
28
+ * are applied with respect to how minErr instances are created and called.
29
+ * Instances should have names of the form namespaceMinErr for a minErr created
30
+ * using minErr('namespace') . Error codes, namespaces and template strings
31
+ * should all be static strings, not variables or general expressions.
32
+ *
33
+ * @param {string} module The namespace to use for the new minErr instance.
34
+ * @param {function} ErrorConstructor Custom error constructor to be instantiated when returning
35
+ * error from returned function, for cases when a particular type of error is useful.
36
+ * @returns {function(code:string, template:string, ...templateArgs): Error} minErr instance
37
+ */
38
+
39
+ function minErr(module, ErrorConstructor) {
40
+ ErrorConstructor = ErrorConstructor || Error;
41
+ return function () {
42
+ var code = arguments[0],
43
+ prefix = '[' + (module ? module + ':' : '') + code + '] ',
44
+ template = arguments[1],
45
+ templateArgs = arguments,
46
+ stringify = function (obj) {
47
+ if (typeof obj === 'function') {
48
+ return obj.toString().replace(/ \{[\s\S]*$/, '');
49
+ } else if (typeof obj === 'undefined') {
50
+ return 'undefined';
51
+ } else if (typeof obj !== 'string') {
52
+ return JSON.stringify(obj);
53
+ }
54
+ return obj;
55
+ },
56
+ message, i;
57
+
58
+ message = prefix + template.replace(/\{\d+\}/g, function (match) {
59
+ var index = +match.slice(1, -1), arg;
60
+
61
+ if (index + 2 < templateArgs.length) {
62
+ arg = templateArgs[index + 2];
63
+ if (typeof arg === 'function') {
64
+ return arg.toString().replace(/ ?\{[\s\S]*$/, '');
65
+ } else if (typeof arg === 'undefined') {
66
+ return 'undefined';
67
+ } else if (typeof arg !== 'string') {
68
+ return toJson(arg);
69
+ }
70
+ return arg;
71
+ }
72
+ return match;
73
+ });
74
+
75
+ message = message + '\nhttp://errors.angularjs.org/1.3.0/' +
76
+ (module ? module + '/' : '') + code;
77
+ for (i = 2; i < arguments.length; i++) {
78
+ message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
79
+ encodeURIComponent(stringify(arguments[i]));
80
+ }
81
+ return new ErrorConstructor(message);
82
+ };
83
+ }
84
+
85
+ /**
86
+ * @ngdoc type
87
+ * @name angular.Module
88
+ * @module ng
89
+ * @description
90
+ *
91
+ * Interface for configuring angular {@link angular.module modules}.
92
+ */
93
+
94
+ function setupModuleLoader(window) {
95
+
96
+ var $injectorMinErr = minErr('$injector');
97
+ var ngMinErr = minErr('ng');
98
+
99
+ function ensure(obj, name, factory) {
100
+ return obj[name] || (obj[name] = factory());
101
+ }
102
+
103
+ var angular = ensure(window, 'angular', Object);
104
+
105
+ // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap
106
+ angular.$$minErr = angular.$$minErr || minErr;
107
+
108
+ return ensure(angular, 'module', function() {
109
+ /** @type {Object.<string, angular.Module>} */
110
+ var modules = {};
111
+
112
+ /**
113
+ * @ngdoc function
114
+ * @name angular.module
115
+ * @module ng
116
+ * @description
117
+ *
118
+ * The `angular.module` is a global place for creating, registering and retrieving Angular
119
+ * modules.
120
+ * All modules (angular core or 3rd party) that should be available to an application must be
121
+ * registered using this mechanism.
122
+ *
123
+ * When passed two or more arguments, a new module is created. If passed only one argument, an
124
+ * existing module (the name passed as the first argument to `module`) is retrieved.
125
+ *
126
+ *
127
+ * # Module
128
+ *
129
+ * A module is a collection of services, directives, controllers, filters, and configuration information.
130
+ * `angular.module` is used to configure the {@link auto.$injector $injector}.
131
+ *
132
+ * ```js
133
+ * // Create a new module
134
+ * var myModule = angular.module('myModule', []);
135
+ *
136
+ * // register a new service
137
+ * myModule.value('appName', 'MyCoolApp');
138
+ *
139
+ * // configure existing services inside initialization blocks.
140
+ * myModule.config(['$locationProvider', function($locationProvider) {
141
+ * // Configure existing providers
142
+ * $locationProvider.hashPrefix('!');
143
+ * }]);
144
+ * ```
145
+ *
146
+ * Then you can create an injector and load your modules like this:
147
+ *
148
+ * ```js
149
+ * var injector = angular.injector(['ng', 'myModule'])
150
+ * ```
151
+ *
152
+ * However it's more likely that you'll just use
153
+ * {@link ng.directive:ngApp ngApp} or
154
+ * {@link angular.bootstrap} to simplify this process for you.
155
+ *
156
+ * @param {!string} name The name of the module to create or retrieve.
157
+ * @param {!Array.<string>=} requires If specified then new module is being created. If
158
+ * unspecified then the module is being retrieved for further configuration.
159
+ * @param {Function=} configFn Optional configuration function for the module. Same as
160
+ * {@link angular.Module#config Module#config()}.
161
+ * @returns {module} new module with the {@link angular.Module} api.
162
+ */
163
+ return function module(name, requires, configFn) {
164
+ var assertNotHasOwnProperty = function(name, context) {
165
+ if (name === 'hasOwnProperty') {
166
+ throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
167
+ }
168
+ };
169
+
170
+ assertNotHasOwnProperty(name, 'module');
171
+ if (requires && modules.hasOwnProperty(name)) {
172
+ modules[name] = null;
173
+ }
174
+ return ensure(modules, name, function() {
175
+ if (!requires) {
176
+ throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " +
177
+ "the module name or forgot to load it. If registering a module ensure that you " +
178
+ "specify the dependencies as the second argument.", name);
179
+ }
180
+
181
+ /** @type {!Array.<Array.<*>>} */
182
+ var invokeQueue = [];
183
+
184
+ /** @type {!Array.<Function>} */
185
+ var configBlocks = [];
186
+
187
+ /** @type {!Array.<Function>} */
188
+ var runBlocks = [];
189
+
190
+ var config = invokeLater('$injector', 'invoke', 'push', configBlocks);
191
+
192
+ /** @type {angular.Module} */
193
+ var moduleInstance = {
194
+ // Private state
195
+ _invokeQueue: invokeQueue,
196
+ _configBlocks: configBlocks,
197
+ _runBlocks: runBlocks,
198
+
199
+ /**
200
+ * @ngdoc property
201
+ * @name angular.Module#requires
202
+ * @module ng
203
+ *
204
+ * @description
205
+ * Holds the list of modules which the injector will load before the current module is
206
+ * loaded.
207
+ */
208
+ requires: requires,
209
+
210
+ /**
211
+ * @ngdoc property
212
+ * @name angular.Module#name
213
+ * @module ng
214
+ *
215
+ * @description
216
+ * Name of the module.
217
+ */
218
+ name: name,
219
+
220
+
221
+ /**
222
+ * @ngdoc method
223
+ * @name angular.Module#provider
224
+ * @module ng
225
+ * @param {string} name service name
226
+ * @param {Function} providerType Construction function for creating new instance of the
227
+ * service.
228
+ * @description
229
+ * See {@link auto.$provide#provider $provide.provider()}.
230
+ */
231
+ provider: invokeLater('$provide', 'provider'),
232
+
233
+ /**
234
+ * @ngdoc method
235
+ * @name angular.Module#factory
236
+ * @module ng
237
+ * @param {string} name service name
238
+ * @param {Function} providerFunction Function for creating new instance of the service.
239
+ * @description
240
+ * See {@link auto.$provide#factory $provide.factory()}.
241
+ */
242
+ factory: invokeLater('$provide', 'factory'),
243
+
244
+ /**
245
+ * @ngdoc method
246
+ * @name angular.Module#service
247
+ * @module ng
248
+ * @param {string} name service name
249
+ * @param {Function} constructor A constructor function that will be instantiated.
250
+ * @description
251
+ * See {@link auto.$provide#service $provide.service()}.
252
+ */
253
+ service: invokeLater('$provide', 'service'),
254
+
255
+ /**
256
+ * @ngdoc method
257
+ * @name angular.Module#value
258
+ * @module ng
259
+ * @param {string} name service name
260
+ * @param {*} object Service instance object.
261
+ * @description
262
+ * See {@link auto.$provide#value $provide.value()}.
263
+ */
264
+ value: invokeLater('$provide', 'value'),
265
+
266
+ /**
267
+ * @ngdoc method
268
+ * @name angular.Module#constant
269
+ * @module ng
270
+ * @param {string} name constant name
271
+ * @param {*} object Constant value.
272
+ * @description
273
+ * Because the constant are fixed, they get applied before other provide methods.
274
+ * See {@link auto.$provide#constant $provide.constant()}.
275
+ */
276
+ constant: invokeLater('$provide', 'constant', 'unshift'),
277
+
278
+ /**
279
+ * @ngdoc method
280
+ * @name angular.Module#animation
281
+ * @module ng
282
+ * @param {string} name animation name
283
+ * @param {Function} animationFactory Factory function for creating new instance of an
284
+ * animation.
285
+ * @description
286
+ *
287
+ * **NOTE**: animations take effect only if the **ngAnimate** module is loaded.
288
+ *
289
+ *
290
+ * Defines an animation hook that can be later used with
291
+ * {@link ngAnimate.$animate $animate} service and directives that use this service.
292
+ *
293
+ * ```js
294
+ * module.animation('.animation-name', function($inject1, $inject2) {
295
+ * return {
296
+ * eventName : function(element, done) {
297
+ * //code to run the animation
298
+ * //once complete, then run done()
299
+ * return function cancellationFunction(element) {
300
+ * //code to cancel the animation
301
+ * }
302
+ * }
303
+ * }
304
+ * })
305
+ * ```
306
+ *
307
+ * See {@link ng.$animateProvider#register $animateProvider.register()} and
308
+ * {@link ngAnimate ngAnimate module} for more information.
309
+ */
310
+ animation: invokeLater('$animateProvider', 'register'),
311
+
312
+ /**
313
+ * @ngdoc method
314
+ * @name angular.Module#filter
315
+ * @module ng
316
+ * @param {string} name Filter name.
317
+ * @param {Function} filterFactory Factory function for creating new instance of filter.
318
+ * @description
319
+ * See {@link ng.$filterProvider#register $filterProvider.register()}.
320
+ */
321
+ filter: invokeLater('$filterProvider', 'register'),
322
+
323
+ /**
324
+ * @ngdoc method
325
+ * @name angular.Module#controller
326
+ * @module ng
327
+ * @param {string|Object} name Controller name, or an object map of controllers where the
328
+ * keys are the names and the values are the constructors.
329
+ * @param {Function} constructor Controller constructor function.
330
+ * @description
331
+ * See {@link ng.$controllerProvider#register $controllerProvider.register()}.
332
+ */
333
+ controller: invokeLater('$controllerProvider', 'register'),
334
+
335
+ /**
336
+ * @ngdoc method
337
+ * @name angular.Module#directive
338
+ * @module ng
339
+ * @param {string|Object} name Directive name, or an object map of directives where the
340
+ * keys are the names and the values are the factories.
341
+ * @param {Function} directiveFactory Factory function for creating new instance of
342
+ * directives.
343
+ * @description
344
+ * See {@link ng.$compileProvider#directive $compileProvider.directive()}.
345
+ */
346
+ directive: invokeLater('$compileProvider', 'directive'),
347
+
348
+ /**
349
+ * @ngdoc method
350
+ * @name angular.Module#config
351
+ * @module ng
352
+ * @param {Function} configFn Execute this function on module load. Useful for service
353
+ * configuration.
354
+ * @description
355
+ * Use this method to register work which needs to be performed on module loading.
356
+ * For more about how to configure services, see
357
+ * {@link providers#provider-recipe Provider Recipe}.
358
+ */
359
+ config: config,
360
+
361
+ /**
362
+ * @ngdoc method
363
+ * @name angular.Module#run
364
+ * @module ng
365
+ * @param {Function} initializationFn Execute this function after injector creation.
366
+ * Useful for application initialization.
367
+ * @description
368
+ * Use this method to register work which should be performed when the injector is done
369
+ * loading all modules.
370
+ */
371
+ run: function(block) {
372
+ runBlocks.push(block);
373
+ return this;
374
+ }
375
+ };
376
+
377
+ if (configFn) {
378
+ config(configFn);
379
+ }
380
+
381
+ return moduleInstance;
382
+
383
+ /**
384
+ * @param {string} provider
385
+ * @param {string} method
386
+ * @param {String=} insertMethod
387
+ * @returns {angular.Module}
388
+ */
389
+ function invokeLater(provider, method, insertMethod, queue) {
390
+ if (!queue) queue = invokeQueue;
391
+ return function() {
392
+ queue[insertMethod || 'push']([provider, method, arguments]);
393
+ return moduleInstance;
394
+ };
395
+ }
396
+ });
397
+ };
398
+ });
399
+
400
+ }
401
+
402
+ setupModuleLoader(window);
403
+ })(window);
404
+
405
+ /**
406
+ * Closure compiler type information
407
+ *
408
+ * @typedef { {
409
+ * requires: !Array.<string>,
410
+ * invokeQueue: !Array.<Array.<*>>,
411
+ *
412
+ * service: function(string, Function):angular.Module,
413
+ * factory: function(string, Function):angular.Module,
414
+ * value: function(string, *):angular.Module,
415
+ *
416
+ * filter: function(string, Function):angular.Module,
417
+ *
418
+ * init: function(Function):angular.Module
419
+ * } }
420
+ */
421
+ angular.Module;
422
+
@@ -0,0 +1,400 @@
1
+ /**
2
+ * @license AngularJS v1.3.0
3
+ * (c) 2010-2014 Google, Inc. http://angularjs.org
4
+ * License: MIT
5
+ */
6
+ (function(window, angular, undefined) {'use strict';
7
+
8
+ /**
9
+ * @ngdoc module
10
+ * @name ngMessages
11
+ * @description
12
+ *
13
+ * The `ngMessages` module provides enhanced support for displaying messages within templates
14
+ * (typically within forms or when rendering message objects that return key/value data).
15
+ * Instead of relying on JavaScript code and/or complex ng-if statements within your form template to
16
+ * show and hide error messages specific to the state of an input field, the `ngMessages` and
17
+ * `ngMessage` directives are designed to handle the complexity, inheritance and priority
18
+ * sequencing based on the order of how the messages are defined in the template.
19
+ *
20
+ * Currently, the ngMessages module only contains the code for the `ngMessages`
21
+ * and `ngMessage` directives.
22
+ *
23
+ * # Usage
24
+ * The `ngMessages` directive listens on a key/value collection which is set on the ngMessages attribute.
25
+ * Since the {@link ngModel ngModel} directive exposes an `$error` object, this error object can be
26
+ * used with `ngMessages` to display control error messages in an easier way than with just regular angular
27
+ * template directives.
28
+ *
29
+ * ```html
30
+ * <form name="myForm">
31
+ * <input type="text" ng-model="field" name="myField" required minlength="5" />
32
+ * <div ng-messages="myForm.myField.$error">
33
+ * <div ng-message="required">You did not enter a field</div>
34
+ * <div ng-message="minlength">The value entered is too short</div>
35
+ * </div>
36
+ * </form>
37
+ * ```
38
+ *
39
+ * Now whatever key/value entries are present within the provided object (in this case `$error`) then
40
+ * the ngMessages directive will render the inner first ngMessage directive (depending if the key values
41
+ * match the attribute value present on each ngMessage directive). In other words, if your errors
42
+ * object contains the following data:
43
+ *
44
+ * ```javascript
45
+ * <!-- keep in mind that ngModel automatically sets these error flags -->
46
+ * myField.$error = { minlength : true, required : false };
47
+ * ```
48
+ *
49
+ * Then the `required` message will be displayed first. When required is false then the `minlength` message
50
+ * will be displayed right after (since these messages are ordered this way in the template HTML code).
51
+ * The prioritization of each message is determined by what order they're present in the DOM.
52
+ * Therefore, instead of having custom JavaScript code determine the priority of what errors are
53
+ * present before others, the presentation of the errors are handled within the template.
54
+ *
55
+ * By default, ngMessages will only display one error at a time. However, if you wish to display all
56
+ * messages then the `ng-messages-multiple` attribute flag can be used on the element containing the
57
+ * ngMessages directive to make this happen.
58
+ *
59
+ * ```html
60
+ * <div ng-messages="myForm.myField.$error" ng-messages-multiple>...</div>
61
+ * ```
62
+ *
63
+ * ## Reusing and Overriding Messages
64
+ * In addition to prioritization, ngMessages also allows for including messages from a remote or an inline
65
+ * template. This allows for generic collection of messages to be reused across multiple parts of an
66
+ * application.
67
+ *
68
+ * ```html
69
+ * <script type="text/ng-template" id="error-messages">
70
+ * <div ng-message="required">This field is required</div>
71
+ * <div ng-message="minlength">This field is too short</div>
72
+ * </script>
73
+ * <div ng-messages="myForm.myField.$error" ng-messages-include="error-messages"></div>
74
+ * ```
75
+ *
76
+ * However, including generic messages may not be useful enough to match all input fields, therefore,
77
+ * `ngMessages` provides the ability to override messages defined in the remote template by redefining
78
+ * then within the directive container.
79
+ *
80
+ * ```html
81
+ * <!-- a generic template of error messages known as "my-custom-messages" -->
82
+ * <script type="text/ng-template" id="my-custom-messages">
83
+ * <div ng-message="required">This field is required</div>
84
+ * <div ng-message="minlength">This field is too short</div>
85
+ * </script>
86
+ *
87
+ * <form name="myForm">
88
+ * <input type="email"
89
+ * id="email"
90
+ * name="myEmail"
91
+ * ng-model="email"
92
+ * minlength="5"
93
+ * required />
94
+ *
95
+ * <div ng-messages="myForm.myEmail.$error" ng-messages-include="my-custom-messages">
96
+ * <!-- this required message has overridden the template message -->
97
+ * <div ng-message="required">You did not enter your email address</div>
98
+ *
99
+ * <!-- this is a brand new message and will appear last in the prioritization -->
100
+ * <div ng-message="email">Your email address is invalid</div>
101
+ * </div>
102
+ * </form>
103
+ * ```
104
+ *
105
+ * In the example HTML code above the message that is set on required will override the corresponding
106
+ * required message defined within the remote template. Therefore, with particular input fields (such
107
+ * email addresses, date fields, autocomplete inputs, etc...), specialized error messages can be applied
108
+ * while more generic messages can be used to handle other, more general input errors.
109
+ *
110
+ * ## Animations
111
+ * If the `ngAnimate` module is active within the application then both the `ngMessages` and
112
+ * `ngMessage` directives will trigger animations whenever any messages are added and removed
113
+ * from the DOM by the `ngMessages` directive.
114
+ *
115
+ * Whenever the `ngMessages` directive contains one or more visible messages then the `.ng-active` CSS
116
+ * class will be added to the element. The `.ng-inactive` CSS class will be applied when there are no
117
+ * animations present. Therefore, CSS transitions and keyframes as well as JavaScript animations can
118
+ * hook into the animations whenever these classes are added/removed.
119
+ *
120
+ * Let's say that our HTML code for our messages container looks like so:
121
+ *
122
+ * ```html
123
+ * <div ng-messages="myMessages" class="my-messages">
124
+ * <div ng-message="alert" class="some-message">...</div>
125
+ * <div ng-message="fail" class="some-message">...</div>
126
+ * </div>
127
+ * ```
128
+ *
129
+ * Then the CSS animation code for the message container looks like so:
130
+ *
131
+ * ```css
132
+ * .my-messages {
133
+ * transition:1s linear all;
134
+ * }
135
+ * .my-messages.ng-active {
136
+ * // messages are visible
137
+ * }
138
+ * .my-messages.ng-inactive {
139
+ * // messages are hidden
140
+ * }
141
+ * ```
142
+ *
143
+ * Whenever an inner message is attached (becomes visible) or removed (becomes hidden) then the enter
144
+ * and leave animation is triggered for each particular element bound to the `ngMessage` directive.
145
+ *
146
+ * Therefore, the CSS code for the inner messages looks like so:
147
+ *
148
+ * ```css
149
+ * .some-message {
150
+ * transition:1s linear all;
151
+ * }
152
+ *
153
+ * .some-message.ng-enter {}
154
+ * .some-message.ng-enter.ng-enter-active {}
155
+ *
156
+ * .some-message.ng-leave {}
157
+ * .some-message.ng-leave.ng-leave-active {}
158
+ * ```
159
+ *
160
+ * {@link ngAnimate Click here} to learn how to use JavaScript animations or to learn more about ngAnimate.
161
+ */
162
+ angular.module('ngMessages', [])
163
+
164
+ /**
165
+ * @ngdoc directive
166
+ * @module ngMessages
167
+ * @name ngMessages
168
+ * @restrict AE
169
+ *
170
+ * @description
171
+ * `ngMessages` is a directive that is designed to show and hide messages based on the state
172
+ * of a key/value object that it listens on. The directive itself compliments error message
173
+ * reporting with the `ngModel` $error object (which stores a key/value state of validation errors).
174
+ *
175
+ * `ngMessages` manages the state of internal messages within its container element. The internal
176
+ * messages use the `ngMessage` directive and will be inserted/removed from the page depending
177
+ * on if they're present within the key/value object. By default, only one message will be displayed
178
+ * at a time and this depends on the prioritization of the messages within the template. (This can
179
+ * be changed by using the ng-messages-multiple on the directive container.)
180
+ *
181
+ * A remote template can also be used to promote message reuseability and messages can also be
182
+ * overridden.
183
+ *
184
+ * {@link module:ngMessages Click here} to learn more about `ngMessages` and `ngMessage`.
185
+ *
186
+ * @usage
187
+ * ```html
188
+ * <!-- using attribute directives -->
189
+ * <ANY ng-messages="expression">
190
+ * <ANY ng-message="keyValue1">...</ANY>
191
+ * <ANY ng-message="keyValue2">...</ANY>
192
+ * <ANY ng-message="keyValue3">...</ANY>
193
+ * </ANY>
194
+ *
195
+ * <!-- or by using element directives -->
196
+ * <ng-messages for="expression">
197
+ * <ng-message when="keyValue1">...</ng-message>
198
+ * <ng-message when="keyValue2">...</ng-message>
199
+ * <ng-message when="keyValue3">...</ng-message>
200
+ * </ng-messages>
201
+ * ```
202
+ *
203
+ * @param {string} ngMessages an angular expression evaluating to a key/value object
204
+ * (this is typically the $error object on an ngModel instance).
205
+ * @param {string=} ngMessagesMultiple|multiple when set, all messages will be displayed with true
206
+ * @param {string=} ngMessagesInclude|include when set, the specified template will be included into the ng-messages container
207
+ *
208
+ * @example
209
+ * <example name="ngMessages-directive" module="ngMessagesExample"
210
+ * deps="angular-messages.js"
211
+ * animations="true" fixBase="true">
212
+ * <file name="index.html">
213
+ * <form name="myForm">
214
+ * <label>Enter your name:</label>
215
+ * <input type="text"
216
+ * name="myName"
217
+ * ng-model="name"
218
+ * ng-minlength="5"
219
+ * ng-maxlength="20"
220
+ * required />
221
+ *
222
+ * <pre>myForm.myName.$error = {{ myForm.myName.$error | json }}</pre>
223
+ *
224
+ * <div ng-messages="myForm.myName.$error" style="color:maroon">
225
+ * <div ng-message="required">You did not enter a field</div>
226
+ * <div ng-message="minlength">Your field is too short</div>
227
+ * <div ng-message="maxlength">Your field is too long</div>
228
+ * </div>
229
+ * </form>
230
+ * </file>
231
+ * <file name="script.js">
232
+ * angular.module('ngMessagesExample', ['ngMessages']);
233
+ * </file>
234
+ * </example>
235
+ */
236
+ .directive('ngMessages', ['$compile', '$animate', '$templateRequest',
237
+ function($compile, $animate, $templateRequest) {
238
+ var ACTIVE_CLASS = 'ng-active';
239
+ var INACTIVE_CLASS = 'ng-inactive';
240
+
241
+ return {
242
+ restrict: 'AE',
243
+ controller: function() {
244
+ this.$renderNgMessageClasses = angular.noop;
245
+
246
+ var messages = [];
247
+ this.registerMessage = function(index, message) {
248
+ for(var i = 0; i < messages.length; i++) {
249
+ if(messages[i].type == message.type) {
250
+ if(index != i) {
251
+ var temp = messages[index];
252
+ messages[index] = messages[i];
253
+ if(index < messages.length) {
254
+ messages[i] = temp;
255
+ } else {
256
+ messages.splice(0, i); //remove the old one (and shift left)
257
+ }
258
+ }
259
+ return;
260
+ }
261
+ }
262
+ messages.splice(index, 0, message); //add the new one (and shift right)
263
+ };
264
+
265
+ this.renderMessages = function(values, multiple) {
266
+ values = values || {};
267
+
268
+ var found;
269
+ angular.forEach(messages, function(message) {
270
+ if((!found || multiple) && truthyVal(values[message.type])) {
271
+ message.attach();
272
+ found = true;
273
+ } else {
274
+ message.detach();
275
+ }
276
+ });
277
+
278
+ this.renderElementClasses(found);
279
+
280
+ function truthyVal(value) {
281
+ return value !== null && value !== false && value;
282
+ }
283
+ };
284
+ },
285
+ require: 'ngMessages',
286
+ link: function($scope, element, $attrs, ctrl) {
287
+ ctrl.renderElementClasses = function(bool) {
288
+ bool ? $animate.setClass(element, ACTIVE_CLASS, INACTIVE_CLASS)
289
+ : $animate.setClass(element, INACTIVE_CLASS, ACTIVE_CLASS);
290
+ };
291
+
292
+ //JavaScript treats empty strings as false, but ng-message-multiple by itself is an empty string
293
+ var multiple = angular.isString($attrs.ngMessagesMultiple) ||
294
+ angular.isString($attrs.multiple);
295
+
296
+ var cachedValues, watchAttr = $attrs.ngMessages || $attrs['for']; //for is a reserved keyword
297
+ $scope.$watchCollection(watchAttr, function(values) {
298
+ cachedValues = values;
299
+ ctrl.renderMessages(values, multiple);
300
+ });
301
+
302
+ var tpl = $attrs.ngMessagesInclude || $attrs.include;
303
+ if(tpl) {
304
+ $templateRequest(tpl)
305
+ .then(function processTemplate(html) {
306
+ var after, container = angular.element('<div/>').html(html);
307
+ angular.forEach(container.children(), function(elm) {
308
+ elm = angular.element(elm);
309
+ after ? after.after(elm)
310
+ : element.prepend(elm); //start of the container
311
+ after = elm;
312
+ $compile(elm)($scope);
313
+ });
314
+ ctrl.renderMessages(cachedValues, multiple);
315
+ });
316
+ }
317
+ }
318
+ };
319
+ }])
320
+
321
+
322
+ /**
323
+ * @ngdoc directive
324
+ * @name ngMessage
325
+ * @restrict AE
326
+ * @scope
327
+ *
328
+ * @description
329
+ * `ngMessage` is a directive with the purpose to show and hide a particular message.
330
+ * For `ngMessage` to operate, a parent `ngMessages` directive on a parent DOM element
331
+ * must be situated since it determines which messages are visible based on the state
332
+ * of the provided key/value map that `ngMessages` listens on.
333
+ *
334
+ * @usage
335
+ * ```html
336
+ * <!-- using attribute directives -->
337
+ * <ANY ng-messages="expression">
338
+ * <ANY ng-message="keyValue1">...</ANY>
339
+ * <ANY ng-message="keyValue2">...</ANY>
340
+ * <ANY ng-message="keyValue3">...</ANY>
341
+ * </ANY>
342
+ *
343
+ * <!-- or by using element directives -->
344
+ * <ng-messages for="expression">
345
+ * <ng-message when="keyValue1">...</ng-message>
346
+ * <ng-message when="keyValue2">...</ng-message>
347
+ * <ng-message when="keyValue3">...</ng-message>
348
+ * </ng-messages>
349
+ * ```
350
+ *
351
+ * {@link module:ngMessages Click here} to learn more about `ngMessages` and `ngMessage`.
352
+ *
353
+ * @param {string} ngMessage a string value corresponding to the message key.
354
+ */
355
+ .directive('ngMessage', ['$animate', function($animate) {
356
+ var COMMENT_NODE = 8;
357
+ return {
358
+ require: '^ngMessages',
359
+ transclude: 'element',
360
+ terminal: true,
361
+ restrict: 'AE',
362
+ link: function($scope, $element, $attrs, ngMessages, $transclude) {
363
+ var index, element;
364
+
365
+ var commentNode = $element[0];
366
+ var parentNode = commentNode.parentNode;
367
+ for(var i = 0, j = 0; i < parentNode.childNodes.length; i++) {
368
+ var node = parentNode.childNodes[i];
369
+ if(node.nodeType == COMMENT_NODE && node.nodeValue.indexOf('ngMessage') >= 0) {
370
+ if(node === commentNode) {
371
+ index = j;
372
+ break;
373
+ }
374
+ j++;
375
+ }
376
+ }
377
+
378
+ ngMessages.registerMessage(index, {
379
+ type : $attrs.ngMessage || $attrs.when,
380
+ attach : function() {
381
+ if(!element) {
382
+ $transclude($scope, function(clone) {
383
+ $animate.enter(clone, null, $element);
384
+ element = clone;
385
+ });
386
+ }
387
+ },
388
+ detach : function(now) {
389
+ if(element) {
390
+ $animate.leave(element);
391
+ element = null;
392
+ }
393
+ }
394
+ });
395
+ }
396
+ };
397
+ }]);
398
+
399
+
400
+ })(window, window.angular);