rails-angularjs 1.3.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +22 -0
  3. data/README.md +37 -0
  4. data/lib/rails-angularjs.rb +9 -0
  5. data/lib/rails-angularjs/engine.rb +4 -0
  6. data/lib/rails-angularjs/sprockets.rb +3 -0
  7. data/lib/rails-angularjs/version.rb +4 -0
  8. data/vendor/assets/javascripts/angularjs/angular-animate.js +2137 -0
  9. data/vendor/assets/javascripts/angularjs/angular-animate.min.js +33 -0
  10. data/vendor/assets/javascripts/angularjs/angular-aria.js +339 -0
  11. data/vendor/assets/javascripts/angularjs/angular-aria.min.js +12 -0
  12. data/vendor/assets/javascripts/angularjs/angular-cookies.js +206 -0
  13. data/vendor/assets/javascripts/angularjs/angular-cookies.min.js +8 -0
  14. data/vendor/assets/javascripts/angularjs/angular-loader.js +405 -0
  15. data/vendor/assets/javascripts/angularjs/angular-loader.min.js +9 -0
  16. data/vendor/assets/javascripts/angularjs/angular-messages.js +400 -0
  17. data/vendor/assets/javascripts/angularjs/angular-messages.min.js +10 -0
  18. data/vendor/assets/javascripts/angularjs/angular-mocks.js +2396 -0
  19. data/vendor/assets/javascripts/angularjs/angular-resource.js +667 -0
  20. data/vendor/assets/javascripts/angularjs/angular-resource.min.js +13 -0
  21. data/vendor/assets/javascripts/angularjs/angular-route.js +989 -0
  22. data/vendor/assets/javascripts/angularjs/angular-route.min.js +15 -0
  23. data/vendor/assets/javascripts/angularjs/angular-sanitize.js +680 -0
  24. data/vendor/assets/javascripts/angularjs/angular-sanitize.min.js +16 -0
  25. data/vendor/assets/javascripts/angularjs/angular-scenario.js +37499 -0
  26. data/vendor/assets/javascripts/angularjs/angular-touch.js +622 -0
  27. data/vendor/assets/javascripts/angularjs/angular-touch.min.js +13 -0
  28. data/vendor/assets/javascripts/angularjs/angular.js +26130 -0
  29. data/vendor/assets/javascripts/angularjs/angular.min.js +250 -0
  30. data/vendor/assets/javascripts/angularjs/unstable/angular-animate.js +2137 -0
  31. data/vendor/assets/javascripts/angularjs/unstable/angular-animate.min.js +33 -0
  32. data/vendor/assets/javascripts/angularjs/unstable/angular-aria.js +339 -0
  33. data/vendor/assets/javascripts/angularjs/unstable/angular-aria.min.js +12 -0
  34. data/vendor/assets/javascripts/angularjs/unstable/angular-cookies.js +206 -0
  35. data/vendor/assets/javascripts/angularjs/unstable/angular-cookies.min.js +8 -0
  36. data/vendor/assets/javascripts/angularjs/unstable/angular-loader.js +410 -0
  37. data/vendor/assets/javascripts/angularjs/unstable/angular-loader.min.js +9 -0
  38. data/vendor/assets/javascripts/angularjs/unstable/angular-messages.js +400 -0
  39. data/vendor/assets/javascripts/angularjs/unstable/angular-messages.min.js +10 -0
  40. data/vendor/assets/javascripts/angularjs/unstable/angular-mocks.js +2400 -0
  41. data/vendor/assets/javascripts/angularjs/unstable/angular-resource.js +667 -0
  42. data/vendor/assets/javascripts/angularjs/unstable/angular-resource.min.js +13 -0
  43. data/vendor/assets/javascripts/angularjs/unstable/angular-route.js +989 -0
  44. data/vendor/assets/javascripts/angularjs/unstable/angular-route.min.js +15 -0
  45. data/vendor/assets/javascripts/angularjs/unstable/angular-sanitize.js +682 -0
  46. data/vendor/assets/javascripts/angularjs/unstable/angular-sanitize.min.js +16 -0
  47. data/vendor/assets/javascripts/angularjs/unstable/angular-scenario.js +38463 -0
  48. data/vendor/assets/javascripts/angularjs/unstable/angular-touch.js +622 -0
  49. data/vendor/assets/javascripts/angularjs/unstable/angular-touch.min.js +13 -0
  50. data/vendor/assets/javascripts/angularjs/unstable/angular.js +27088 -0
  51. data/vendor/assets/javascripts/angularjs/unstable/angular.min.js +281 -0
  52. metadata +140 -0
@@ -0,0 +1,8 @@
1
+ /*
2
+ AngularJS v1.4.0-beta.3
3
+ (c) 2010-2015 Google, Inc. http://angularjs.org
4
+ License: MIT
5
+ */
6
+ (function(p,f,n){'use strict';f.module("ngCookies",["ng"]).factory("$cookies",["$rootScope","$browser",function(e,b){var c={},g={},h,k=!1,l=f.copy,m=f.isUndefined;b.addPollFn(function(){var a=b.cookies();h!=a&&(h=a,l(a,g),l(a,c),k&&e.$apply())})();k=!0;e.$watch(function(){var a,d,e;for(a in g)m(c[a])&&b.cookies(a,n);for(a in c)d=c[a],f.isString(d)||(d=""+d,c[a]=d),d!==g[a]&&(b.cookies(a,d),e=!0);if(e)for(a in d=b.cookies(),c)c[a]!==d[a]&&(m(d[a])?delete c[a]:c[a]=d[a])});return c}]).factory("$cookieStore",
7
+ ["$cookies",function(e){return{get:function(b){return(b=e[b])?f.fromJson(b):b},put:function(b,c){e[b]=f.toJson(c)},remove:function(b){delete e[b]}}}])})(window,window.angular);
8
+ //# sourceMappingURL=angular-cookies.min.js.map
@@ -0,0 +1,410 @@
1
+ /**
2
+ * @license AngularJS v1.4.0-beta.3
3
+ * (c) 2010-2015 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 SKIP_INDEXES = 2;
43
+
44
+ var templateArgs = arguments,
45
+ code = templateArgs[0],
46
+ message = '[' + (module ? module + ':' : '') + code + '] ',
47
+ template = templateArgs[1],
48
+ paramPrefix, i;
49
+
50
+ message += template.replace(/\{\d+\}/g, function(match) {
51
+ var index = +match.slice(1, -1),
52
+ shiftedIndex = index + SKIP_INDEXES;
53
+
54
+ if (shiftedIndex < templateArgs.length) {
55
+ return toDebugString(templateArgs[shiftedIndex]);
56
+ }
57
+
58
+ return match;
59
+ });
60
+
61
+ message += '\nhttp://errors.angularjs.org/1.4.0-beta.3/' +
62
+ (module ? module + '/' : '') + code;
63
+
64
+ for (i = SKIP_INDEXES, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {
65
+ message += paramPrefix + 'p' + (i - SKIP_INDEXES) + '=' +
66
+ encodeURIComponent(toDebugString(templateArgs[i]));
67
+ }
68
+
69
+ return new ErrorConstructor(message);
70
+ };
71
+ }
72
+
73
+ /**
74
+ * @ngdoc type
75
+ * @name angular.Module
76
+ * @module ng
77
+ * @description
78
+ *
79
+ * Interface for configuring angular {@link angular.module modules}.
80
+ */
81
+
82
+ function setupModuleLoader(window) {
83
+
84
+ var $injectorMinErr = minErr('$injector');
85
+ var ngMinErr = minErr('ng');
86
+
87
+ function ensure(obj, name, factory) {
88
+ return obj[name] || (obj[name] = factory());
89
+ }
90
+
91
+ var angular = ensure(window, 'angular', Object);
92
+
93
+ // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap
94
+ angular.$$minErr = angular.$$minErr || minErr;
95
+
96
+ return ensure(angular, 'module', function() {
97
+ /** @type {Object.<string, angular.Module>} */
98
+ var modules = {};
99
+
100
+ /**
101
+ * @ngdoc function
102
+ * @name angular.module
103
+ * @module ng
104
+ * @description
105
+ *
106
+ * The `angular.module` is a global place for creating, registering and retrieving Angular
107
+ * modules.
108
+ * All modules (angular core or 3rd party) that should be available to an application must be
109
+ * registered using this mechanism.
110
+ *
111
+ * When passed two or more arguments, a new module is created. If passed only one argument, an
112
+ * existing module (the name passed as the first argument to `module`) is retrieved.
113
+ *
114
+ *
115
+ * # Module
116
+ *
117
+ * A module is a collection of services, directives, controllers, filters, and configuration information.
118
+ * `angular.module` is used to configure the {@link auto.$injector $injector}.
119
+ *
120
+ * ```js
121
+ * // Create a new module
122
+ * var myModule = angular.module('myModule', []);
123
+ *
124
+ * // register a new service
125
+ * myModule.value('appName', 'MyCoolApp');
126
+ *
127
+ * // configure existing services inside initialization blocks.
128
+ * myModule.config(['$locationProvider', function($locationProvider) {
129
+ * // Configure existing providers
130
+ * $locationProvider.hashPrefix('!');
131
+ * }]);
132
+ * ```
133
+ *
134
+ * Then you can create an injector and load your modules like this:
135
+ *
136
+ * ```js
137
+ * var injector = angular.injector(['ng', 'myModule'])
138
+ * ```
139
+ *
140
+ * However it's more likely that you'll just use
141
+ * {@link ng.directive:ngApp ngApp} or
142
+ * {@link angular.bootstrap} to simplify this process for you.
143
+ *
144
+ * @param {!string} name The name of the module to create or retrieve.
145
+ * @param {!Array.<string>=} requires If specified then new module is being created. If
146
+ * unspecified then the module is being retrieved for further configuration.
147
+ * @param {Function=} configFn Optional configuration function for the module. Same as
148
+ * {@link angular.Module#config Module#config()}.
149
+ * @returns {module} new module with the {@link angular.Module} api.
150
+ */
151
+ return function module(name, requires, configFn) {
152
+ var assertNotHasOwnProperty = function(name, context) {
153
+ if (name === 'hasOwnProperty') {
154
+ throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
155
+ }
156
+ };
157
+
158
+ assertNotHasOwnProperty(name, 'module');
159
+ if (requires && modules.hasOwnProperty(name)) {
160
+ modules[name] = null;
161
+ }
162
+ return ensure(modules, name, function() {
163
+ if (!requires) {
164
+ throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " +
165
+ "the module name or forgot to load it. If registering a module ensure that you " +
166
+ "specify the dependencies as the second argument.", name);
167
+ }
168
+
169
+ /** @type {!Array.<Array.<*>>} */
170
+ var invokeQueue = [];
171
+
172
+ /** @type {!Array.<Function>} */
173
+ var configBlocks = [];
174
+
175
+ /** @type {!Array.<Function>} */
176
+ var runBlocks = [];
177
+
178
+ var config = invokeLater('$injector', 'invoke', 'push', configBlocks);
179
+
180
+ /** @type {angular.Module} */
181
+ var moduleInstance = {
182
+ // Private state
183
+ _invokeQueue: invokeQueue,
184
+ _configBlocks: configBlocks,
185
+ _runBlocks: runBlocks,
186
+
187
+ /**
188
+ * @ngdoc property
189
+ * @name angular.Module#requires
190
+ * @module ng
191
+ *
192
+ * @description
193
+ * Holds the list of modules which the injector will load before the current module is
194
+ * loaded.
195
+ */
196
+ requires: requires,
197
+
198
+ /**
199
+ * @ngdoc property
200
+ * @name angular.Module#name
201
+ * @module ng
202
+ *
203
+ * @description
204
+ * Name of the module.
205
+ */
206
+ name: name,
207
+
208
+
209
+ /**
210
+ * @ngdoc method
211
+ * @name angular.Module#provider
212
+ * @module ng
213
+ * @param {string} name service name
214
+ * @param {Function} providerType Construction function for creating new instance of the
215
+ * service.
216
+ * @description
217
+ * See {@link auto.$provide#provider $provide.provider()}.
218
+ */
219
+ provider: invokeLater('$provide', 'provider'),
220
+
221
+ /**
222
+ * @ngdoc method
223
+ * @name angular.Module#factory
224
+ * @module ng
225
+ * @param {string} name service name
226
+ * @param {Function} providerFunction Function for creating new instance of the service.
227
+ * @description
228
+ * See {@link auto.$provide#factory $provide.factory()}.
229
+ */
230
+ factory: invokeLater('$provide', 'factory'),
231
+
232
+ /**
233
+ * @ngdoc method
234
+ * @name angular.Module#service
235
+ * @module ng
236
+ * @param {string} name service name
237
+ * @param {Function} constructor A constructor function that will be instantiated.
238
+ * @description
239
+ * See {@link auto.$provide#service $provide.service()}.
240
+ */
241
+ service: invokeLater('$provide', 'service'),
242
+
243
+ /**
244
+ * @ngdoc method
245
+ * @name angular.Module#value
246
+ * @module ng
247
+ * @param {string} name service name
248
+ * @param {*} object Service instance object.
249
+ * @description
250
+ * See {@link auto.$provide#value $provide.value()}.
251
+ */
252
+ value: invokeLater('$provide', 'value'),
253
+
254
+ /**
255
+ * @ngdoc method
256
+ * @name angular.Module#constant
257
+ * @module ng
258
+ * @param {string} name constant name
259
+ * @param {*} object Constant value.
260
+ * @description
261
+ * Because the constant are fixed, they get applied before other provide methods.
262
+ * See {@link auto.$provide#constant $provide.constant()}.
263
+ */
264
+ constant: invokeLater('$provide', 'constant', 'unshift'),
265
+
266
+ /**
267
+ * @ngdoc method
268
+ * @name angular.Module#animation
269
+ * @module ng
270
+ * @param {string} name animation name
271
+ * @param {Function} animationFactory Factory function for creating new instance of an
272
+ * animation.
273
+ * @description
274
+ *
275
+ * **NOTE**: animations take effect only if the **ngAnimate** module is loaded.
276
+ *
277
+ *
278
+ * Defines an animation hook that can be later used with
279
+ * {@link ngAnimate.$animate $animate} service and directives that use this service.
280
+ *
281
+ * ```js
282
+ * module.animation('.animation-name', function($inject1, $inject2) {
283
+ * return {
284
+ * eventName : function(element, done) {
285
+ * //code to run the animation
286
+ * //once complete, then run done()
287
+ * return function cancellationFunction(element) {
288
+ * //code to cancel the animation
289
+ * }
290
+ * }
291
+ * }
292
+ * })
293
+ * ```
294
+ *
295
+ * See {@link ng.$animateProvider#register $animateProvider.register()} and
296
+ * {@link ngAnimate ngAnimate module} for more information.
297
+ */
298
+ animation: invokeLater('$animateProvider', 'register'),
299
+
300
+ /**
301
+ * @ngdoc method
302
+ * @name angular.Module#filter
303
+ * @module ng
304
+ * @param {string} name Filter name.
305
+ * @param {Function} filterFactory Factory function for creating new instance of filter.
306
+ * @description
307
+ * See {@link ng.$filterProvider#register $filterProvider.register()}.
308
+ */
309
+ filter: invokeLater('$filterProvider', 'register'),
310
+
311
+ /**
312
+ * @ngdoc method
313
+ * @name angular.Module#controller
314
+ * @module ng
315
+ * @param {string|Object} name Controller name, or an object map of controllers where the
316
+ * keys are the names and the values are the constructors.
317
+ * @param {Function} constructor Controller constructor function.
318
+ * @description
319
+ * See {@link ng.$controllerProvider#register $controllerProvider.register()}.
320
+ */
321
+ controller: invokeLater('$controllerProvider', 'register'),
322
+
323
+ /**
324
+ * @ngdoc method
325
+ * @name angular.Module#directive
326
+ * @module ng
327
+ * @param {string|Object} name Directive name, or an object map of directives where the
328
+ * keys are the names and the values are the factories.
329
+ * @param {Function} directiveFactory Factory function for creating new instance of
330
+ * directives.
331
+ * @description
332
+ * See {@link ng.$compileProvider#directive $compileProvider.directive()}.
333
+ */
334
+ directive: invokeLater('$compileProvider', 'directive'),
335
+
336
+ /**
337
+ * @ngdoc method
338
+ * @name angular.Module#config
339
+ * @module ng
340
+ * @param {Function} configFn Execute this function on module load. Useful for service
341
+ * configuration.
342
+ * @description
343
+ * Use this method to register work which needs to be performed on module loading.
344
+ * For more about how to configure services, see
345
+ * {@link providers#provider-recipe Provider Recipe}.
346
+ */
347
+ config: config,
348
+
349
+ /**
350
+ * @ngdoc method
351
+ * @name angular.Module#run
352
+ * @module ng
353
+ * @param {Function} initializationFn Execute this function after injector creation.
354
+ * Useful for application initialization.
355
+ * @description
356
+ * Use this method to register work which should be performed when the injector is done
357
+ * loading all modules.
358
+ */
359
+ run: function(block) {
360
+ runBlocks.push(block);
361
+ return this;
362
+ }
363
+ };
364
+
365
+ if (configFn) {
366
+ config(configFn);
367
+ }
368
+
369
+ return moduleInstance;
370
+
371
+ /**
372
+ * @param {string} provider
373
+ * @param {string} method
374
+ * @param {String=} insertMethod
375
+ * @returns {angular.Module}
376
+ */
377
+ function invokeLater(provider, method, insertMethod, queue) {
378
+ if (!queue) queue = invokeQueue;
379
+ return function() {
380
+ queue[insertMethod || 'push']([provider, method, arguments]);
381
+ return moduleInstance;
382
+ };
383
+ }
384
+ });
385
+ };
386
+ });
387
+
388
+ }
389
+
390
+ setupModuleLoader(window);
391
+ })(window);
392
+
393
+ /**
394
+ * Closure compiler type information
395
+ *
396
+ * @typedef { {
397
+ * requires: !Array.<string>,
398
+ * invokeQueue: !Array.<Array.<*>>,
399
+ *
400
+ * service: function(string, Function):angular.Module,
401
+ * factory: function(string, Function):angular.Module,
402
+ * value: function(string, *):angular.Module,
403
+ *
404
+ * filter: function(string, Function):angular.Module,
405
+ *
406
+ * init: function(Function):angular.Module
407
+ * } }
408
+ */
409
+ angular.Module;
410
+
@@ -0,0 +1,9 @@
1
+ /*
2
+ AngularJS v1.4.0-beta.3
3
+ (c) 2010-2015 Google, Inc. http://angularjs.org
4
+ License: MIT
5
+ */
6
+ (function(){'use strict';function d(b){return function(){var c=arguments[0],e;e="["+(b?b+":":"")+c+"] http://errors.angularjs.org/1.4.0-beta.3/"+(b?b+"/":"")+c;for(c=1;c<arguments.length;c++){e=e+(1==c?"?":"&")+"p"+(c-1)+"=";var d=encodeURIComponent,a;a=arguments[c];a="function"==typeof a?a.toString().replace(/ \{[\s\S]*$/,""):"undefined"==typeof a?"undefined":"string"!=typeof a?JSON.stringify(a):a;e+=d(a)}return Error(e)}}(function(b){function c(a,c,b){return a[c]||(a[c]=b())}var e=d("$injector"),
7
+ n=d("ng");b=c(b,"angular",Object);b.$$minErr=b.$$minErr||d;return c(b,"module",function(){var a={};return function(b,d,g){if("hasOwnProperty"===b)throw n("badname","module");d&&a.hasOwnProperty(b)&&(a[b]=null);return c(a,b,function(){function a(b,d,e,f){f||(f=c);return function(){f[e||"push"]([b,d,arguments]);return h}}if(!d)throw e("nomod",b);var c=[],k=[],l=[],m=a("$injector","invoke","push",k),h={_invokeQueue:c,_configBlocks:k,_runBlocks:l,requires:d,name:b,provider:a("$provide","provider"),factory:a("$provide",
8
+ "factory"),service:a("$provide","service"),value:a("$provide","value"),constant:a("$provide","constant","unshift"),animation:a("$animateProvider","register"),filter:a("$filterProvider","register"),controller:a("$controllerProvider","register"),directive:a("$compileProvider","directive"),config:m,run:function(a){l.push(a);return this}};g&&m(g);return h})}})})(window)})(window);
9
+ //# sourceMappingURL=angular-loader.min.js.map
@@ -0,0 +1,400 @@
1
+ /**
2
+ * @license AngularJS v1.4.0-beta.3
3
+ * (c) 2010-2015 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
+ * them 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
+ * messages 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 reusability 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() {
389
+ if (element) {
390
+ $animate.leave(element);
391
+ element = null;
392
+ }
393
+ }
394
+ });
395
+ }
396
+ };
397
+ }]);
398
+
399
+
400
+ })(window, window.angular);