Built motion from commit 3000230.|0.0.51
[motion.git] / public / bower_components / angular-validator / angular-validator.js
1 (function() {
2   var $;
3
4   $ = angular.element;
5
6   angular.module('validator.directive', ['validator.provider']).directive('validator', [
7     '$injector', function($injector) {
8       return {
9         restrict: 'A',
10         require: 'ngModel',
11         link: function(scope, element, attrs, ctrl) {
12           var $parse, $validator, isAcceptTheBroadcast, model, observerRequired, onBlur, registerRequired, removeRule, rules, validate;
13           $validator = $injector.get('$validator');
14           $parse = $injector.get('$parse');
15           model = $parse(attrs.ngModel);
16           rules = [];
17           validate = function(from, args) {
18             var errorCount, increaseSuccessCount, rule, successCount, _fn, _i, _len;
19             if (args == null) {
20               args = {};
21             }
22
23             /*
24             Validate this element with all rules.
25             @param from: 'watch', 'blur' or 'broadcast'
26             @param args:
27                 success(): success callback (this callback will return success count)
28                 error(): error callback (this callback will return error count)
29                 oldValue: the old value of $watch
30              */
31             successCount = 0;
32             errorCount = 0;
33             increaseSuccessCount = function() {
34               var rule, _i, _len;
35               if (++successCount >= rules.length) {
36                 ctrl.$setValidity(attrs.ngModel, true);
37                 for (_i = 0, _len = rules.length; _i < _len; _i++) {
38                   rule = rules[_i];
39                   rule.success(model(scope), scope, element, attrs, $injector);
40                 }
41                 if (typeof args.success === "function") {
42                   args.success();
43                 }
44               }
45             };
46             if (rules.length === 0) {
47               return increaseSuccessCount();
48             }
49             _fn = function(rule) {
50               return rule.validator(model(scope), scope, element, attrs, {
51                 success: function() {
52                   return increaseSuccessCount();
53                 },
54                 error: function() {
55                   if (rule.enableError && ++errorCount === 1) {
56                     ctrl.$setValidity(attrs.ngModel, false);
57                     rule.error(model(scope), scope, element, attrs, $injector);
58                   }
59                   if ((typeof args.error === "function" ? args.error() : void 0) === 1) {
60                     try {
61                       element[0].scrollIntoViewIfNeeded();
62                     } catch (_error) {}
63                     return element[0].select();
64                   }
65                 }
66               });
67             };
68             for (_i = 0, _len = rules.length; _i < _len; _i++) {
69               rule = rules[_i];
70               switch (from) {
71                 case 'blur':
72                   if (rule.invoke !== 'blur') {
73                     continue;
74                   }
75                   rule.enableError = true;
76                   break;
77                 case 'watch':
78                   if (rule.invoke !== 'watch' && !rule.enableError) {
79                     increaseSuccessCount();
80                     continue;
81                   }
82                   break;
83                 case 'broadcast':
84                   rule.enableError = true;
85                   break;
86               }
87               _fn(rule);
88             }
89           };
90           registerRequired = function() {
91             var rule;
92             rule = $validator.getRule('required');
93             if (rule == null) {
94               rule = $validator.convertRule('required', {
95                 validator: /^.+$/,
96                 invoke: 'watch'
97               });
98             }
99             return rules.push(rule);
100           };
101           removeRule = function(name) {
102
103             /*
104             Remove the rule in rules by the name.
105              */
106             var index, _i, _ref, _ref1, _results;
107             _results = [];
108             for (index = _i = 0, _ref = rules.length; _i < _ref; index = _i += 1) {
109               if (!(((_ref1 = rules[index]) != null ? _ref1.name : void 0) === name)) {
110                 continue;
111               }
112               rules[index].success(model(scope), scope, element, attrs, $injector);
113               rules.splice(index, 1);
114               _results.push(index--);
115             }
116             return _results;
117           };
118           attrs.$observe('validator', function(value) {
119             var match, name, rule, ruleNames, _i, _len, _results;
120             rules.length = 0;
121             if (observerRequired.validatorRequired || observerRequired.required) {
122               registerRequired();
123             }
124             match = value.match(/^\/(.*)\/$/);
125             if (match) {
126               rule = $validator.convertRule('dynamic', {
127                 validator: RegExp(match[1]),
128                 invoke: attrs.validatorInvoke,
129                 error: attrs.validatorError
130               });
131               rules.push(rule);
132               return;
133             }
134             match = value.match(/^\[(.+)\]$/);
135             if (match) {
136               ruleNames = match[1].split(',');
137               _results = [];
138               for (_i = 0, _len = ruleNames.length; _i < _len; _i++) {
139                 name = ruleNames[_i];
140                 rule = $validator.getRule(name.replace(/^\s+|\s+$/g, ''));
141                 if (typeof rule.init === "function") {
142                   rule.init(scope, element, attrs, $injector);
143                 }
144                 if (rule) {
145                   _results.push(rules.push(rule));
146                 } else {
147                   _results.push(void 0);
148                 }
149               }
150               return _results;
151             }
152           });
153           attrs.$observe('validatorError', function(value) {
154             var match, rule;
155             match = attrs.validator.match(/^\/(.*)\/$/);
156             if (match) {
157               removeRule('dynamic');
158               rule = $validator.convertRule('dynamic', {
159                 validator: RegExp(match[1]),
160                 invoke: attrs.validatorInvoke,
161                 error: value
162               });
163               return rules.push(rule);
164             }
165           });
166           observerRequired = {
167             validatorRequired: false,
168             required: false
169           };
170           attrs.$observe('validatorRequired', function(value) {
171             if (value && value !== 'false') {
172               registerRequired();
173               return observerRequired.validatorRequired = true;
174             } else if (observerRequired.validatorRequired) {
175               removeRule('required');
176               return observerRequired.validatorRequired = false;
177             }
178           });
179           attrs.$observe('required', function(value) {
180             if (value && value !== 'false') {
181               registerRequired();
182               return observerRequired.required = true;
183             } else if (observerRequired.required) {
184               removeRule('required');
185               return observerRequired.required = false;
186             }
187           });
188           isAcceptTheBroadcast = function(broadcast, modelName) {
189             var anyHashKey, dotIndex, itemExpression, itemModel;
190             if (modelName) {
191               if (attrs.validatorGroup === modelName) {
192                 return true;
193               }
194               if (broadcast.targetScope === scope) {
195                 return attrs.ngModel.indexOf(modelName) === 0;
196               } else {
197                 anyHashKey = function(targetModel, hashKey) {
198                   var key, x;
199                   for (key in targetModel) {
200                     x = targetModel[key];
201                     switch (typeof x) {
202                       case 'string':
203                         if (key === '$$hashKey' && x === hashKey) {
204                           return true;
205                         }
206                         break;
207                       case 'object':
208                         if (anyHashKey(x, hashKey)) {
209                           return true;
210                         }
211                         break;
212                     }
213                   }
214                   return false;
215                 };
216                 dotIndex = attrs.ngModel.indexOf('.');
217                 itemExpression = dotIndex >= 0 ? attrs.ngModel.substr(0, dotIndex) : attrs.ngModel;
218                 itemModel = $parse(itemExpression)(scope);
219                 return anyHashKey($parse(modelName)(broadcast.targetScope), itemModel.$$hashKey);
220               }
221             }
222             return true;
223           };
224           scope.$on($validator.broadcastChannel.prepare, function(self, object) {
225             if (!isAcceptTheBroadcast(self, object.model)) {
226               return;
227             }
228             return object.accept();
229           });
230           scope.$on($validator.broadcastChannel.start, function(self, object) {
231             if (!isAcceptTheBroadcast(self, object.model)) {
232               return;
233             }
234             return validate('broadcast', {
235               success: object.success,
236               error: object.error
237             });
238           });
239           scope.$on($validator.broadcastChannel.reset, function(self, object) {
240             var rule, _i, _len;
241             if (!isAcceptTheBroadcast(self, object.model)) {
242               return;
243             }
244             for (_i = 0, _len = rules.length; _i < _len; _i++) {
245               rule = rules[_i];
246               rule.success(model(scope), scope, element, attrs, $injector);
247               if (rule.invoke !== 'watch') {
248                 rule.enableError = false;
249               }
250             }
251             return ctrl.$setValidity(attrs.ngModel, true);
252           });
253           scope.$watch(attrs.ngModel, function(newValue, oldValue) {
254             if (newValue === oldValue) {
255               return;
256             }
257             return validate('watch', {
258               oldValue: oldValue
259             });
260           });
261           onBlur = function() {
262             if (scope.$root.$$phase) {
263               return validate('blur');
264             } else {
265               return scope.$apply(function() {
266                 return validate('blur');
267               });
268             }
269           };
270           $(element).bind('blur', onBlur);
271           return scope.$on('$destroy', function() {
272             return $(element).unbind('blur', onBlur);
273           });
274         }
275       };
276     }
277   ]);
278
279 }).call(this);
280
281 (function() {
282   angular.module('validator', ['validator.directive']);
283
284 }).call(this);
285
286 (function() {
287   var $;
288
289   $ = angular.element;
290
291   angular.module('validator.provider', []).provider('$validator', function() {
292     var $injector, $q, $timeout;
293     $injector = null;
294     $q = null;
295     $timeout = null;
296     this.rules = {};
297     this.broadcastChannel = {
298       prepare: '$validatePrepare',
299       start: '$validateStart',
300       reset: '$validateReset'
301     };
302     this.setupProviders = function(injector) {
303       $injector = injector;
304       $q = $injector.get('$q');
305       return $timeout = $injector.get('$timeout');
306     };
307     this.convertError = function(error) {
308
309       /*
310       Convert rule.error.
311       @param error: error messate (string) or function(value, scope, element, attrs, $injector)
312       @return: function(value, scope, element, attrs, $injector)
313        */
314       var errorMessage;
315       if (typeof error === 'function') {
316         return error;
317       }
318       errorMessage = error.constructor === String ? error : '';
319       return function(value, scope, element, attrs) {
320         var $label, label, parent, _i, _len, _ref, _results;
321         parent = $(element).parent();
322         _results = [];
323         while (parent.length !== 0) {
324           if (parent.hasClass('form-group')) {
325             parent.addClass('has-error');
326             _ref = parent.find('label');
327             for (_i = 0, _len = _ref.length; _i < _len; _i++) {
328               label = _ref[_i];
329               if ($(label).hasClass('error')) {
330                 $(label).remove();
331               }
332             }
333             $label = $("<label class='control-label error'>" + errorMessage + "</label>");
334             if (attrs.id) {
335               $label.attr('for', attrs.id);
336             }
337             if ($(element).parent().hasClass('input-group')) {
338               $(element).parent().parent().append($label);
339             } else {
340               $(element).parent().append($label);
341             }
342             break;
343           }
344           _results.push(parent = parent.parent());
345         }
346         return _results;
347       };
348     };
349     this.convertSuccess = function(success) {
350
351       /*
352       Convert rule.success.
353       @param success: function(value, scope, element, attrs, $injector)
354       @return: function(value, scope, element, attrs, $injector)
355        */
356       if (typeof success === 'function') {
357         return success;
358       }
359       return function(value, scope, element) {
360         var label, parent, _i, _len, _ref, _results;
361         parent = $(element).parent();
362         _results = [];
363         while (parent.length !== 0) {
364           if (parent.hasClass('has-error')) {
365             parent.removeClass('has-error');
366             _ref = parent.find('label');
367             for (_i = 0, _len = _ref.length; _i < _len; _i++) {
368               label = _ref[_i];
369               if ($(label).hasClass('error')) {
370                 $(label).remove();
371               }
372             }
373             break;
374           }
375           _results.push(parent = parent.parent());
376         }
377         return _results;
378       };
379     };
380     this.convertValidator = function(validator) {
381
382       /*
383       Convert rule.validator.
384       @param validator: RegExp() or function(value, scope, element, attrs, $injector)
385                                                   { return true / false }
386       @return: function(value, scope, element, attrs, funcs{success, error})
387           (funcs is callback functions)
388        */
389       var func, regex, result;
390       result = function() {};
391       if (validator.constructor === RegExp) {
392         regex = validator;
393         result = function(value, scope, element, attrs, funcs) {
394           if (value == null) {
395             value = '';
396           }
397           if (regex.test(value)) {
398             return typeof funcs.success === "function" ? funcs.success() : void 0;
399           } else {
400             return typeof funcs.error === "function" ? funcs.error() : void 0;
401           }
402         };
403       } else if (typeof validator === 'function') {
404         func = validator;
405         result = function(value, scope, element, attrs, funcs) {
406           return $q.all([func(value, scope, element, attrs, $injector)]).then(function(objects) {
407             if (objects && objects.length > 0 && objects[0]) {
408               return typeof funcs.success === "function" ? funcs.success() : void 0;
409             } else {
410               return typeof funcs.error === "function" ? funcs.error() : void 0;
411             }
412           }, function() {
413             return typeof funcs.error === "function" ? funcs.error() : void 0;
414           });
415         };
416       }
417       return result;
418     };
419     this.convertRule = (function(_this) {
420       return function(name, object) {
421         var result, _ref, _ref1;
422         if (object == null) {
423           object = {};
424         }
425
426         /*
427         Convert the rule object.
428          */
429         result = {
430           name: name,
431           enableError: object.invoke === 'watch',
432           invoke: object.invoke,
433           init: object.init,
434           validator: (_ref = object.validator) != null ? _ref : function() {
435             return true;
436           },
437           error: (_ref1 = object.error) != null ? _ref1 : '',
438           success: object.success
439         };
440         result.error = _this.convertError(result.error);
441         result.success = _this.convertSuccess(result.success);
442         result.validator = _this.convertValidator(result.validator);
443         return result;
444       };
445     })(this);
446     this.register = function(name, object) {
447       if (object == null) {
448         object = {};
449       }
450
451       /*
452       Register the rule.
453       @params name: The rule name.
454       @params object:
455           invoke: 'watch' or 'blur' or undefined(validate by yourself)
456           init: function(scope, element, attrs, $injector)
457           validator: RegExp() or function(value, scope, element, attrs, $injector)
458           error: string or function(scope, element, attrs)
459           success: function(scope, element, attrs)
460        */
461       return this.rules[name] = this.convertRule(name, object);
462     };
463     this.getRule = function(name) {
464
465       /*
466       Get the rule form $validator.rules by the name.
467       @return rule / null
468        */
469       if (this.rules[name]) {
470         return angular.copy(this.rules[name]);
471       } else {
472         return null;
473       }
474     };
475     this.validate = (function(_this) {
476       return function(scope, model) {
477
478         /*
479         Validate the model.
480         @param scope: The scope.
481         @param model: The model name of the scope or validator-group.
482         @return:
483             @promise success(): The success function.
484             @promise error(): The error function.
485          */
486         var broadcastObject, count, deferred, func, promise;
487         deferred = $q.defer();
488         promise = deferred.promise;
489         count = {
490           total: 0,
491           success: 0,
492           error: 0
493         };
494         func = {
495           promises: {
496             success: [],
497             error: [],
498             then: []
499           },
500           accept: function() {
501             return count.total++;
502           },
503           validatedSuccess: function() {
504             var x, _i, _j, _len, _len1, _ref, _ref1;
505             if (++count.success === count.total) {
506               _ref = func.promises.success;
507               for (_i = 0, _len = _ref.length; _i < _len; _i++) {
508                 x = _ref[_i];
509                 x();
510               }
511               _ref1 = func.promises.then;
512               for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
513                 x = _ref1[_j];
514                 x();
515               }
516             }
517             return count.success;
518           },
519           validatedError: function() {
520             var x, _i, _j, _len, _len1, _ref, _ref1;
521             if (count.error++ === 0) {
522               _ref = func.promises.error;
523               for (_i = 0, _len = _ref.length; _i < _len; _i++) {
524                 x = _ref[_i];
525                 x();
526               }
527               _ref1 = func.promises.then;
528               for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
529                 x = _ref1[_j];
530                 x();
531               }
532             }
533             return count.error;
534           }
535         };
536         promise.success = function(fn) {
537           func.promises.success.push(fn);
538           return promise;
539         };
540         promise.error = function(fn) {
541           func.promises.error.push(fn);
542           return promise;
543         };
544         promise.then = function(fn) {
545           func.promises.then.push(fn);
546           return promise;
547         };
548         broadcastObject = {
549           model: model,
550           accept: func.accept,
551           success: func.validatedSuccess,
552           error: func.validatedError
553         };
554         scope.$broadcast(_this.broadcastChannel.prepare, broadcastObject);
555         $timeout(function() {
556           var $validator, x, _i, _len, _ref;
557           if (count.total === 0) {
558             _ref = func.promises.success;
559             for (_i = 0, _len = _ref.length; _i < _len; _i++) {
560               x = _ref[_i];
561               x();
562             }
563             return;
564           }
565           $validator = $injector.get('$validator');
566           return scope.$broadcast($validator.broadcastChannel.start, broadcastObject);
567         });
568         return promise;
569       };
570     })(this);
571     this.reset = (function(_this) {
572       return function(scope, model) {
573
574         /*
575         Reset validated error messages of the model.
576         @param scope: The scope.
577         @param model: The model name of the scope or validator-group.
578          */
579         return scope.$broadcast(_this.broadcastChannel.reset, {
580           model: model
581         });
582       };
583     })(this);
584     this.get = function($injector) {
585       this.setupProviders($injector);
586       return {
587         rules: this.rules,
588         broadcastChannel: this.broadcastChannel,
589         register: this.register,
590         convertRule: this.convertRule,
591         getRule: this.getRule,
592         validate: this.validate,
593         reset: this.reset
594       };
595     };
596     this.get.$inject = ['$injector'];
597     this.$get = this.get;
598   });
599
600 }).call(this);