angularjs-rails 1.2.16 → 1.2.18

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.3.0-beta.5
2
+ * @license AngularJS v1.3.0-beta.13
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -35,6 +35,8 @@
35
35
  * | {@link ng.directive:ngClass#usage_animations ngClass} | add and remove (the CSS class(es) present) |
36
36
  * | {@link ng.directive:ngShow#usage_animations ngShow} & {@link ng.directive:ngHide#usage_animations ngHide} | add and remove (the ng-hide class value) |
37
37
  * | {@link ng.directive:form#usage_animations form} & {@link ng.directive:ngModel#usage_animations ngModel} | add and remove (dirty, pristine, valid, invalid & all other validations) |
38
+ * | {@link ngMessages.directive:ngMessage#usage_animations ngMessages} | add and remove (ng-active & ng-inactive) |
39
+ * | {@link ngMessages.directive:ngMessage#usage_animations ngMessage} | enter and leave |
38
40
  *
39
41
  * You can find out more information about animations upon visiting each directive page.
40
42
  *
@@ -358,6 +360,10 @@ angular.module('ngAnimate', ['ng'])
358
360
  }
359
361
  }
360
362
 
363
+ function prepareElement(element) {
364
+ return element && angular.element(element);
365
+ }
366
+
361
367
  function stripCommentsFromElement(element) {
362
368
  return angular.element(extractElementNode(element));
363
369
  }
@@ -566,7 +572,7 @@ angular.module('ngAnimate', ['ng'])
566
572
  /**
567
573
  * @ngdoc service
568
574
  * @name $animate
569
- * @function
575
+ * @kind function
570
576
  *
571
577
  * @description
572
578
  * The `$animate` service provides animation detection support while performing DOM operations (enter, leave and move) as well as during addClass and removeClass operations.
@@ -586,7 +592,7 @@ angular.module('ngAnimate', ['ng'])
586
592
  /**
587
593
  * @ngdoc method
588
594
  * @name $animate#enter
589
- * @function
595
+ * @kind function
590
596
  *
591
597
  * @description
592
598
  * Appends the element to the parentElement element that resides in the document and then runs the enter animation. Once
@@ -616,6 +622,10 @@ angular.module('ngAnimate', ['ng'])
616
622
  * @param {function()=} doneCallback the callback function that will be called once the animation is complete
617
623
  */
618
624
  enter : function(element, parentElement, afterElement, doneCallback) {
625
+ element = angular.element(element);
626
+ parentElement = prepareElement(parentElement);
627
+ afterElement = prepareElement(afterElement);
628
+
619
629
  this.enabled(false, element);
620
630
  $delegate.enter(element, parentElement, afterElement);
621
631
  $rootScope.$$postDigest(function() {
@@ -627,7 +637,7 @@ angular.module('ngAnimate', ['ng'])
627
637
  /**
628
638
  * @ngdoc method
629
639
  * @name $animate#leave
630
- * @function
640
+ * @kind function
631
641
  *
632
642
  * @description
633
643
  * Runs the leave animation operation and, upon completion, removes the element from the DOM. Once
@@ -655,6 +665,7 @@ angular.module('ngAnimate', ['ng'])
655
665
  * @param {function()=} doneCallback the callback function that will be called once the animation is complete
656
666
  */
657
667
  leave : function(element, doneCallback) {
668
+ element = angular.element(element);
658
669
  cancelChildAnimations(element);
659
670
  this.enabled(false, element);
660
671
  $rootScope.$$postDigest(function() {
@@ -667,7 +678,7 @@ angular.module('ngAnimate', ['ng'])
667
678
  /**
668
679
  * @ngdoc method
669
680
  * @name $animate#move
670
- * @function
681
+ * @kind function
671
682
  *
672
683
  * @description
673
684
  * Fires the move DOM operation. Just before the animation starts, the animate service will either append it into the parentElement container or
@@ -698,6 +709,10 @@ angular.module('ngAnimate', ['ng'])
698
709
  * @param {function()=} doneCallback the callback function that will be called once the animation is complete
699
710
  */
700
711
  move : function(element, parentElement, afterElement, doneCallback) {
712
+ element = angular.element(element);
713
+ parentElement = prepareElement(parentElement);
714
+ afterElement = prepareElement(afterElement);
715
+
701
716
  cancelChildAnimations(element);
702
717
  this.enabled(false, element);
703
718
  $delegate.move(element, parentElement, afterElement);
@@ -737,6 +752,7 @@ angular.module('ngAnimate', ['ng'])
737
752
  * @param {function()=} doneCallback the callback function that will be called once the animation is complete
738
753
  */
739
754
  addClass : function(element, className, doneCallback) {
755
+ element = angular.element(element);
740
756
  element = stripCommentsFromElement(element);
741
757
  performAnimation('addClass', className, element, null, null, function() {
742
758
  $delegate.addClass(element, className);
@@ -773,6 +789,7 @@ angular.module('ngAnimate', ['ng'])
773
789
  * @param {function()=} doneCallback the callback function that will be called once the animation is complete
774
790
  */
775
791
  removeClass : function(element, className, doneCallback) {
792
+ element = angular.element(element);
776
793
  element = stripCommentsFromElement(element);
777
794
  performAnimation('removeClass', className, element, null, null, function() {
778
795
  $delegate.removeClass(element, className);
@@ -799,7 +816,7 @@ angular.module('ngAnimate', ['ng'])
799
816
  * | 8. The animation ends and all generated CSS classes are removed from the element | class="my-animation" |
800
817
  * | 9. The doneCallback() callback is fired (if provided) | class="my-animation" |
801
818
  *
802
- * @param {DOMElement} element the element which will it's CSS classes changed
819
+ * @param {DOMElement} element the element which will have its CSS classes changed
803
820
  * removed from it
804
821
  * @param {string} add the CSS classes which will be added to the element
805
822
  * @param {string} remove the CSS class which will be removed from the element
@@ -807,6 +824,7 @@ angular.module('ngAnimate', ['ng'])
807
824
  * CSS classes have been set on the element
808
825
  */
809
826
  setClass : function(element, add, remove, doneCallback) {
827
+ element = angular.element(element);
810
828
  element = stripCommentsFromElement(element);
811
829
  performAnimation('setClass', [add, remove], element, null, null, function() {
812
830
  $delegate.setClass(element, add, remove);
@@ -816,7 +834,7 @@ angular.module('ngAnimate', ['ng'])
816
834
  /**
817
835
  * @ngdoc method
818
836
  * @name $animate#enabled
819
- * @function
837
+ * @kind function
820
838
  *
821
839
  * @param {boolean=} value If provided then set the animation on or off.
822
840
  * @param {DOMElement=} element If provided then the element will be used to represent the enable/disable operation
@@ -940,6 +958,7 @@ angular.module('ngAnimate', ['ng'])
940
958
  }
941
959
 
942
960
  if(skipAnimation) {
961
+ fireDOMOperation();
943
962
  fireBeforeCallbackAsync();
944
963
  fireAfterCallbackAsync();
945
964
  fireDoneCallbackAsync();
@@ -1389,7 +1408,7 @@ angular.module('ngAnimate', ['ng'])
1389
1408
  });
1390
1409
 
1391
1410
  element.addClass(activeClassName);
1392
- var eventCacheKey = elementData.eventCacheKey + ' ' + activeClassName;
1411
+ var eventCacheKey = elementData.cacheKey + ' ' + activeClassName;
1393
1412
  var timings = getElementAnimationDetails(element, eventCacheKey);
1394
1413
 
1395
1414
  var maxDuration = Math.max(timings.transitionDuration, timings.animationDuration);
@@ -1436,7 +1455,7 @@ angular.module('ngAnimate', ['ng'])
1436
1455
  //the jqLite object, so we're safe to use a single variable to house
1437
1456
  //the styles since there is always only one element being animated
1438
1457
  var oldStyle = node.getAttribute('style') || '';
1439
- node.setAttribute('style', oldStyle + ' ' + style);
1458
+ node.setAttribute('style', oldStyle + '; ' + style);
1440
1459
  }
1441
1460
 
1442
1461
  var startTime = Date.now();
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.3.0-beta.5
2
+ * @license AngularJS v1.3.0-beta.13
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -37,18 +37,15 @@ angular.module('ngCookies', ['ng']).
37
37
  * Requires the {@link ngCookies `ngCookies`} module to be installed.
38
38
  *
39
39
  * @example
40
- <example>
41
- <file name="index.html">
42
- <script>
43
- function ExampleController($cookies) {
44
- // Retrieving a cookie
45
- var favoriteCookie = $cookies.myFavorite;
46
- // Setting a cookie
47
- $cookies.myFavorite = 'oatmeal';
48
- }
49
- </script>
50
- </file>
51
- </example>
40
+ *
41
+ * ```js
42
+ * function ExampleController($cookies) {
43
+ * // Retrieving a cookie
44
+ * var favoriteCookie = $cookies.myFavorite;
45
+ * // Setting a cookie
46
+ * $cookies.myFavorite = 'oatmeal';
47
+ * }
48
+ * ```
52
49
  */
53
50
  factory('$cookies', ['$rootScope', '$browser', function ($rootScope, $browser) {
54
51
  var cookies = {},
@@ -143,6 +140,17 @@ angular.module('ngCookies', ['ng']).
143
140
  * Requires the {@link ngCookies `ngCookies`} module to be installed.
144
141
  *
145
142
  * @example
143
+ *
144
+ * ```js
145
+ * function ExampleController($cookieStore) {
146
+ * // Put cookie
147
+ * $cookieStore.put('myFavorite','oatmeal');
148
+ * // Get cookie
149
+ * var favoriteCookie = $cookieStore.get('myFavorite');
150
+ * // Removing a cookie
151
+ * $cookieStore.remove('myFavorite');
152
+ * }
153
+ * ```
146
154
  */
147
155
  factory('$cookieStore', ['$cookies', function($cookies) {
148
156
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.3.0-beta.5
2
+ * @license AngularJS v1.3.0-beta.13
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -69,7 +69,7 @@ function minErr(module) {
69
69
  return match;
70
70
  });
71
71
 
72
- message = message + '\nhttp://errors.angularjs.org/1.3.0-beta.5/' +
72
+ message = message + '\nhttp://errors.angularjs.org/1.3.0-beta.13/' +
73
73
  (module ? module + '/' : '') + code;
74
74
  for (i = 2; i < arguments.length; i++) {
75
75
  message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
@@ -124,7 +124,7 @@ function setupModuleLoader(window) {
124
124
  *
125
125
  * # Module
126
126
  *
127
- * A module is a collection of services, directives, filters, and configuration information.
127
+ * A module is a collection of services, directives, controllers, filters, and configuration information.
128
128
  * `angular.module` is used to configure the {@link auto.$injector $injector}.
129
129
  *
130
130
  * ```js
@@ -179,15 +179,19 @@ function setupModuleLoader(window) {
179
179
  /** @type {!Array.<Array.<*>>} */
180
180
  var invokeQueue = [];
181
181
 
182
+ /** @type {!Array.<Function>} */
183
+ var configBlocks = [];
184
+
182
185
  /** @type {!Array.<Function>} */
183
186
  var runBlocks = [];
184
187
 
185
- var config = invokeLater('$injector', 'invoke');
188
+ var config = invokeLater('$injector', 'invoke', 'push', configBlocks);
186
189
 
187
190
  /** @type {angular.Module} */
188
191
  var moduleInstance = {
189
192
  // Private state
190
193
  _invokeQueue: invokeQueue,
194
+ _configBlocks: configBlocks,
191
195
  _runBlocks: runBlocks,
192
196
 
193
197
  /**
@@ -346,6 +350,8 @@ function setupModuleLoader(window) {
346
350
  * configuration.
347
351
  * @description
348
352
  * Use this method to register work which needs to be performed on module loading.
353
+ * For more about how to configure services, see
354
+ * {@link providers#providers_provider-recipe Provider Recipe}.
349
355
  */
350
356
  config: config,
351
357
 
@@ -377,9 +383,10 @@ function setupModuleLoader(window) {
377
383
  * @param {String=} insertMethod
378
384
  * @returns {angular.Module}
379
385
  */
380
- function invokeLater(provider, method, insertMethod) {
386
+ function invokeLater(provider, method, insertMethod, queue) {
387
+ if (!queue) queue = invokeQueue;
381
388
  return function() {
382
- invokeQueue[insertMethod || 'push']([provider, method, arguments]);
389
+ queue[insertMethod || 'push']([provider, method, arguments]);
383
390
  return moduleInstance;
384
391
  };
385
392
  }
@@ -0,0 +1,400 @@
1
+ /**
2
+ * @license AngularJS v1.3.0-beta.13
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 is 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', '$http', '$templateCache',
237
+ function($compile, $animate, $http, $templateCache) {
238
+ var ACTIVE_CLASS = 'ng-active';
239
+ var INACTIVE_CLASS = 'ng-inactive';
240
+
241
+ return {
242
+ restrict: 'AE',
243
+ controller: ['$scope', function($scope) {
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
+ $http.get(tpl, { cache: $templateCache })
305
+ .success(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);