ember-validations-rails-ja 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,779 @@
1
+ // ==========================================================================
2
+ // Project: Ember Validations
3
+ // Copyright: Copyright 2013 DockYard, LLC. and contributors.
4
+ // License: Licensed under MIT license (see license.js)
5
+ // ==========================================================================
6
+
7
+
8
+ // Version: 1.0.0
9
+
10
+ (function() {
11
+ Ember.Validations = Ember.Namespace.create({
12
+ VERSION: '1.0.0'
13
+ });
14
+
15
+ })();
16
+
17
+
18
+
19
+ (function() {
20
+ Ember.Validations.messages = {
21
+ render: function(attribute, context) {
22
+ if (Ember.I18n) {
23
+ return Ember.I18n.t('errors.' + attribute, context);
24
+ } else {
25
+ var regex = new RegExp("{{(.*?)}}"),
26
+ attributeName = "";
27
+ if (regex.test(this.defaults[attribute])) {
28
+ attributeName = regex.exec(this.defaults[attribute])[1];
29
+ }
30
+ return this.defaults[attribute].replace(regex, context[attributeName]);
31
+ }
32
+ },
33
+ defaults: {
34
+ inclusion: "is not included in the list",
35
+ exclusion: "is reserved",
36
+ invalid: "is invalid",
37
+ confirmation: "doesn't match {{attribute}}",
38
+ accepted: "must be accepted",
39
+ empty: "can't be empty",
40
+ blank: "can't be blank",
41
+ present: "must be blank",
42
+ tooLong: "is too long (maximum is {{count}} characters)",
43
+ tooShort: "is too short (minimum is {{count}} characters)",
44
+ wrongLength: "is the wrong length (should be {{count}} characters)",
45
+ notANumber: "is not a number",
46
+ notAnInteger: "must be an integer",
47
+ greaterThan: "must be greater than {{count}}",
48
+ greaterThanOrEqualTo: "must be greater than or equal to {{count}}",
49
+ equalTo: "must be equal to {{count}}",
50
+ lessThan: "must be less than {{count}}",
51
+ lessThanOrEqualTo: "must be less than or equal to {{count}}",
52
+ otherThan: "must be other than {{count}}",
53
+ odd: "must be odd",
54
+ even: "must be even",
55
+ url: "is not a valid URL"
56
+ }
57
+ };
58
+
59
+ })();
60
+
61
+
62
+
63
+ (function() {
64
+ Ember.Validations.Errors = Ember.Object.extend({
65
+ unknownProperty: function(property) {
66
+ this.set(property, Ember.makeArray());
67
+ return this.get(property);
68
+ }
69
+ });
70
+
71
+ })();
72
+
73
+
74
+
75
+ (function() {
76
+ var setValidityMixin = Ember.Mixin.create({
77
+ isValid: function() {
78
+ return this.get('validators').compact().filterBy('isValid', false).get('length') === 0;
79
+ }.property('validators.@each.isValid'),
80
+ isInvalid: Ember.computed.not('isValid')
81
+ });
82
+
83
+ var pushValidatableObject = function(model, property) {
84
+ var content = model.get(property);
85
+
86
+ model.removeObserver(property, pushValidatableObject);
87
+ if (Ember.isArray(content)) {
88
+ model.validators.pushObject(ArrayValidatorProxy.create({model: model, property: property, contentBinding: 'model.' + property}));
89
+ } else {
90
+ model.validators.pushObject(content);
91
+ }
92
+ };
93
+
94
+ var findValidator = function(validator) {
95
+ var klass = validator.classify();
96
+ return Ember.Validations.validators.local[klass] || Ember.Validations.validators.remote[klass];
97
+ };
98
+
99
+ var ArrayValidatorProxy = Ember.ArrayProxy.extend(setValidityMixin, {
100
+ validate: function() {
101
+ return this._validate();
102
+ },
103
+ _validate: function() {
104
+ var promises = this.get('content').invoke('_validate').without(undefined);
105
+ return Ember.RSVP.all(promises);
106
+ }.on('init'),
107
+ validators: Ember.computed.alias('content')
108
+ });
109
+
110
+ Ember.Validations.Mixin = Ember.Mixin.create(setValidityMixin, {
111
+ init: function() {
112
+ this._super();
113
+ this.errors = Ember.Validations.Errors.create();
114
+ this._dependentValidationKeys = {};
115
+ this.validators = Ember.makeArray();
116
+ if (this.get('validations') === undefined) {
117
+ this.validations = {};
118
+ }
119
+ this.buildValidators();
120
+ this.validators.forEach(function(validator) {
121
+ validator.addObserver('errors.[]', this, function(sender, key, value, context, rev) {
122
+ var errors = Ember.makeArray();
123
+ this.validators.forEach(function(validator) {
124
+ if (validator.property === sender.property) {
125
+ errors = errors.concat(validator.errors);
126
+ }
127
+ }, this);
128
+ this.set('errors.' + sender.property, errors);
129
+ });
130
+ }, this);
131
+ },
132
+ buildValidators: function() {
133
+ var property, validator;
134
+
135
+ for (property in this.validations) {
136
+ if (this.validations[property].constructor === Object) {
137
+ this.buildRuleValidator(property);
138
+ } else {
139
+ this.buildObjectValidator(property);
140
+ }
141
+ }
142
+ },
143
+ buildRuleValidator: function(property) {
144
+ var validator;
145
+ for (validator in this.validations[property]) {
146
+ if (this.validations[property].hasOwnProperty(validator)) {
147
+ this.validators.pushObject(findValidator(validator).create({model: this, property: property, options: this.validations[property][validator]}));
148
+ }
149
+ }
150
+ },
151
+ buildObjectValidator: function(property) {
152
+ if (Ember.isNone(this.get(property))) {
153
+ this.addObserver(property, this, pushValidatableObject);
154
+ } else {
155
+ pushValidatableObject(this, property);
156
+ }
157
+ },
158
+ validate: function() {
159
+ var self = this;
160
+ return this._validate().then(function(vals) {
161
+ var errors = self.get('errors');
162
+ if (vals.contains(false)) {
163
+ return Ember.RSVP.reject(errors);
164
+ }
165
+ return errors;
166
+ });
167
+ },
168
+ _validate: function() {
169
+ var promises = this.validators.invoke('_validate').without(undefined);
170
+ return Ember.RSVP.all(promises);
171
+ }.on('init')
172
+ });
173
+
174
+ })();
175
+
176
+
177
+
178
+ (function() {
179
+ Ember.Validations.patterns = Ember.Namespace.create({
180
+ numericality: /^(-|\+)?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d*)?$/,
181
+ blank: /^\s*$/
182
+ });
183
+
184
+ })();
185
+
186
+
187
+
188
+ (function() {
189
+ Ember.Validations.validators = Ember.Namespace.create();
190
+ Ember.Validations.validators.local = Ember.Namespace.create();
191
+ Ember.Validations.validators.remote = Ember.Namespace.create();
192
+
193
+ })();
194
+
195
+
196
+
197
+ (function() {
198
+ Ember.Validations.validators.Base = Ember.Object.extend({
199
+ init: function() {
200
+ this.set('errors', Ember.makeArray());
201
+ this._dependentValidationKeys = Ember.makeArray();
202
+ this.conditionals = {
203
+ 'if': this.get('options.if'),
204
+ unless: this.get('options.unless')
205
+ };
206
+ this.model.addObserver(this.property, this, this._validate);
207
+ },
208
+ addObserversForDependentValidationKeys: function() {
209
+ this._dependentValidationKeys.forEach(function(key) {
210
+ this.model.addObserver(key, this, this._validate);
211
+ }, this);
212
+ }.on('init'),
213
+ pushDependentValidationKeyToModel: function() {
214
+ var model = this.get('model');
215
+ if (model._dependentValidationKeys[this.property] === undefined) {
216
+ model._dependentValidationKeys[this.property] = Ember.makeArray();
217
+ }
218
+ model._dependentValidationKeys[this.property].addObjects(this._dependentValidationKeys);
219
+ }.on('init'),
220
+ call: function () {
221
+ throw 'Not implemented!';
222
+ },
223
+ unknownProperty: function(key) {
224
+ var model = this.get('model');
225
+ if (model) {
226
+ return model.get(key);
227
+ }
228
+ },
229
+ isValid: Ember.computed.empty('errors.[]'),
230
+ validate: function() {
231
+ var self = this;
232
+ return this._validate().then(function(success) {
233
+ // Convert validation failures to rejects.
234
+ var errors = self.get('model.errors');
235
+ if (success) {
236
+ return errors;
237
+ } else {
238
+ return Ember.RSVP.reject(errors);
239
+ }
240
+ });
241
+ },
242
+ _validate: function() {
243
+ this.errors.clear();
244
+ if (this.canValidate()) {
245
+ this.call();
246
+ }
247
+ if (this.get('isValid')) {
248
+ return Ember.RSVP.resolve(true);
249
+ } else {
250
+ return Ember.RSVP.resolve(false);
251
+ }
252
+ }.on('init'),
253
+ canValidate: function() {
254
+ if (typeof(this.conditionals) === 'object') {
255
+ if (this.conditionals['if']) {
256
+ if (typeof(this.conditionals['if']) === 'function') {
257
+ return this.conditionals['if'](this.model, this.property);
258
+ } else if (typeof(this.conditionals['if']) === 'string') {
259
+ if (typeof(this.model[this.conditionals['if']]) === 'function') {
260
+ return this.model[this.conditionals['if']]();
261
+ } else {
262
+ return this.model.get(this.conditionals['if']);
263
+ }
264
+ }
265
+ } else if (this.conditionals.unless) {
266
+ if (typeof(this.conditionals.unless) === 'function') {
267
+ return !this.conditionals.unless(this.model, this.property);
268
+ } else if (typeof(this.conditionals.unless) === 'string') {
269
+ if (typeof(this.model[this.conditionals.unless]) === 'function') {
270
+ return !this.model[this.conditionals.unless]();
271
+ } else {
272
+ return !this.model.get(this.conditionals.unless);
273
+ }
274
+ }
275
+ } else {
276
+ return true;
277
+ }
278
+ } else {
279
+ return true;
280
+ }
281
+ }
282
+ });
283
+
284
+ })();
285
+
286
+
287
+
288
+ (function() {
289
+ Ember.Validations.validators.local.Absence = Ember.Validations.validators.Base.extend({
290
+ init: function() {
291
+ this._super();
292
+ /*jshint expr:true*/
293
+ if (this.options === true) {
294
+ this.set('options', {});
295
+ }
296
+
297
+ if (this.options.message === undefined) {
298
+ this.set('options.message', Ember.Validations.messages.render('present', this.options));
299
+ }
300
+ },
301
+ call: function() {
302
+ if (!Ember.isEmpty(this.model.get(this.property))) {
303
+ this.errors.pushObject(this.options.message);
304
+ }
305
+ }
306
+ });
307
+
308
+ })();
309
+
310
+
311
+
312
+ (function() {
313
+ Ember.Validations.validators.local.Acceptance = Ember.Validations.validators.Base.extend({
314
+ init: function() {
315
+ this._super();
316
+ /*jshint expr:true*/
317
+ if (this.options === true) {
318
+ this.set('options', {});
319
+ }
320
+
321
+ if (this.options.message === undefined) {
322
+ this.set('options.message', Ember.Validations.messages.render('accepted', this.options));
323
+ }
324
+ },
325
+ call: function() {
326
+ if (this.options.accept) {
327
+ if (this.model.get(this.property) !== this.options.accept) {
328
+ this.errors.pushObject(this.options.message);
329
+ }
330
+ } else if (this.model.get(this.property) !== '1' && this.model.get(this.property) !== 1 && this.model.get(this.property) !== true) {
331
+ this.errors.pushObject(this.options.message);
332
+ }
333
+ }
334
+ });
335
+
336
+ })();
337
+
338
+
339
+
340
+ (function() {
341
+ Ember.Validations.validators.local.Confirmation = Ember.Validations.validators.Base.extend({
342
+ init: function() {
343
+ this.originalProperty = this.property;
344
+ this.property = this.property + 'Confirmation';
345
+ this._super();
346
+ this._dependentValidationKeys.pushObject(this.originalProperty);
347
+ /*jshint expr:true*/
348
+ if (this.options === true) {
349
+ this.set('options', { attribute: this.originalProperty });
350
+ this.set('options', { message: Ember.Validations.messages.render('confirmation', this.options) });
351
+ }
352
+ },
353
+ call: function() {
354
+ if (this.model.get(this.originalProperty) !== this.model.get(this.property)) {
355
+ this.errors.pushObject(this.options.message);
356
+ }
357
+ }
358
+ });
359
+
360
+ })();
361
+
362
+
363
+
364
+ (function() {
365
+ Ember.Validations.validators.local.Exclusion = Ember.Validations.validators.Base.extend({
366
+ init: function() {
367
+ this._super();
368
+ if (this.options.constructor === Array) {
369
+ this.set('options', { 'in': this.options });
370
+ }
371
+
372
+ if (this.options.message === undefined) {
373
+ this.set('options.message', Ember.Validations.messages.render('exclusion', this.options));
374
+ }
375
+ },
376
+ call: function() {
377
+ /*jshint expr:true*/
378
+ var message, lower, upper;
379
+
380
+ if (Ember.isEmpty(this.model.get(this.property))) {
381
+ if (this.options.allowBlank === undefined) {
382
+ this.errors.pushObject(this.options.message);
383
+ }
384
+ } else if (this.options['in']) {
385
+ if (Ember.$.inArray(this.model.get(this.property), this.options['in']) !== -1) {
386
+ this.errors.pushObject(this.options.message);
387
+ }
388
+ } else if (this.options.range) {
389
+ lower = this.options.range[0];
390
+ upper = this.options.range[1];
391
+
392
+ if (this.model.get(this.property) >= lower && this.model.get(this.property) <= upper) {
393
+ this.errors.pushObject(this.options.message);
394
+ }
395
+ }
396
+ }
397
+ });
398
+
399
+ })();
400
+
401
+
402
+
403
+ (function() {
404
+ Ember.Validations.validators.local.Format = Ember.Validations.validators.Base.extend({
405
+ init: function() {
406
+ this._super();
407
+ if (this.options.constructor === RegExp) {
408
+ this.set('options', { 'with': this.options });
409
+ }
410
+
411
+ if (this.options.message === undefined) {
412
+ this.set('options.message', Ember.Validations.messages.render('invalid', this.options));
413
+ }
414
+ },
415
+ call: function() {
416
+ if (Ember.isEmpty(this.model.get(this.property))) {
417
+ if (this.options.allowBlank === undefined) {
418
+ this.errors.pushObject(this.options.message);
419
+ }
420
+ } else if (this.options['with'] && !this.options['with'].test(this.model.get(this.property))) {
421
+ this.errors.pushObject(this.options.message);
422
+ } else if (this.options.without && this.options.without.test(this.model.get(this.property))) {
423
+ this.errors.pushObject(this.options.message);
424
+ }
425
+ }
426
+ });
427
+
428
+ })();
429
+
430
+
431
+
432
+ (function() {
433
+ Ember.Validations.validators.local.Inclusion = Ember.Validations.validators.Base.extend({
434
+ init: function() {
435
+ this._super();
436
+ if (this.options.constructor === Array) {
437
+ this.set('options', { 'in': this.options });
438
+ }
439
+
440
+ if (this.options.message === undefined) {
441
+ this.set('options.message', Ember.Validations.messages.render('inclusion', this.options));
442
+ }
443
+ },
444
+ call: function() {
445
+ var message, lower, upper;
446
+ if (Ember.isEmpty(this.model.get(this.property))) {
447
+ if (this.options.allowBlank === undefined) {
448
+ this.errors.pushObject(this.options.message);
449
+ }
450
+ } else if (this.options['in']) {
451
+ if (Ember.$.inArray(this.model.get(this.property), this.options['in']) === -1) {
452
+ this.errors.pushObject(this.options.message);
453
+ }
454
+ } else if (this.options.range) {
455
+ lower = this.options.range[0];
456
+ upper = this.options.range[1];
457
+
458
+ if (this.model.get(this.property) < lower || this.model.get(this.property) > upper) {
459
+ this.errors.pushObject(this.options.message);
460
+ }
461
+ }
462
+ }
463
+ });
464
+
465
+ })();
466
+
467
+
468
+
469
+ (function() {
470
+ Ember.Validations.validators.local.Length = Ember.Validations.validators.Base.extend({
471
+ init: function() {
472
+ var index, key;
473
+ this._super();
474
+ /*jshint expr:true*/
475
+ if (typeof(this.options) === 'number') {
476
+ this.set('options', { 'is': this.options });
477
+ }
478
+
479
+ if (this.options.messages === undefined) {
480
+ this.set('options.messages', {});
481
+ }
482
+
483
+ for (index = 0; index < this.messageKeys().length; index++) {
484
+ key = this.messageKeys()[index];
485
+ if (this.options[key] !== undefined && this.options[key].constructor === String) {
486
+ this.model.addObserver(this.options[key], this, this._validate);
487
+ }
488
+ }
489
+
490
+ this.options.tokenizer = this.options.tokenizer || function(value) { return value.split(''); };
491
+ // if (typeof(this.options.tokenizer) === 'function') {
492
+ // debugger;
493
+ // // this.tokenizedLength = new Function('value', 'return '
494
+ // } else {
495
+ // this.tokenizedLength = new Function('value', 'return (value || "").' + (this.options.tokenizer || 'split("")') + '.length');
496
+ // }
497
+ },
498
+ CHECKS: {
499
+ 'is' : '==',
500
+ 'minimum' : '>=',
501
+ 'maximum' : '<='
502
+ },
503
+ MESSAGES: {
504
+ 'is' : 'wrongLength',
505
+ 'minimum' : 'tooShort',
506
+ 'maximum' : 'tooLong'
507
+ },
508
+ getValue: function(key) {
509
+ if (this.options[key].constructor === String) {
510
+ return this.model.get(this.options[key]) || 0;
511
+ } else {
512
+ return this.options[key];
513
+ }
514
+ },
515
+ messageKeys: function() {
516
+ return Ember.keys(this.MESSAGES);
517
+ },
518
+ checkKeys: function() {
519
+ return Ember.keys(this.CHECKS);
520
+ },
521
+ renderMessageFor: function(key) {
522
+ var options = {count: this.getValue(key)}, _key;
523
+ for (_key in this.options) {
524
+ options[_key] = this.options[_key];
525
+ }
526
+
527
+ return this.options.messages[this.MESSAGES[key]] || Ember.Validations.messages.render(this.MESSAGES[key], options);
528
+ },
529
+ renderBlankMessage: function() {
530
+ if (this.options.is) {
531
+ return this.renderMessageFor('is');
532
+ } else if (this.options.minimum) {
533
+ return this.renderMessageFor('minimum');
534
+ }
535
+ },
536
+ call: function() {
537
+ var check, fn, message, operator, key;
538
+
539
+ if (Ember.isEmpty(this.model.get(this.property))) {
540
+ if (this.options.allowBlank === undefined && (this.options.is || this.options.minimum)) {
541
+ this.errors.pushObject(this.renderBlankMessage());
542
+ }
543
+ } else {
544
+ for (key in this.CHECKS) {
545
+ operator = this.CHECKS[key];
546
+ if (!this.options[key]) {
547
+ continue;
548
+ }
549
+
550
+ fn = new Function('return ' + this.options.tokenizer(this.model.get(this.property)).length + ' ' + operator + ' ' + this.getValue(key));
551
+ if (!fn()) {
552
+ this.errors.pushObject(this.renderMessageFor(key));
553
+ }
554
+ }
555
+ }
556
+ }
557
+ });
558
+
559
+ })();
560
+
561
+
562
+
563
+ (function() {
564
+ Ember.Validations.validators.local.Numericality = Ember.Validations.validators.Base.extend({
565
+ init: function() {
566
+ /*jshint expr:true*/
567
+ var index, keys, key;
568
+ this._super();
569
+
570
+ if (this.options === true) {
571
+ this.options = {};
572
+ } else if (this.options.constructor === String) {
573
+ key = this.options;
574
+ this.options = {};
575
+ this.options[key] = true;
576
+ }
577
+
578
+ if (this.options.messages === undefined || this.options.messages.numericality === undefined) {
579
+ this.options.messages = this.options.messages || {};
580
+ this.options.messages = { numericality: Ember.Validations.messages.render('notANumber', this.options) };
581
+ }
582
+
583
+ if (this.options.onlyInteger !== undefined && this.options.messages.onlyInteger === undefined) {
584
+ this.options.messages.onlyInteger = Ember.Validations.messages.render('notAnInteger', this.options);
585
+ }
586
+
587
+ keys = Ember.keys(this.CHECKS).concat(['odd', 'even']);
588
+ for(index = 0; index < keys.length; index++) {
589
+ key = keys[index];
590
+
591
+ var prop = this.options[key];
592
+ if (key in this.options && isNaN(prop)) {
593
+ this.model.addObserver(prop, this, this._validate);
594
+ }
595
+
596
+ if (prop !== undefined && this.options.messages[key] === undefined) {
597
+ if (Ember.$.inArray(key, Ember.keys(this.CHECKS)) !== -1) {
598
+ this.options.count = prop;
599
+ }
600
+ this.options.messages[key] = Ember.Validations.messages.render(key, this.options);
601
+ if (this.options.count !== undefined) {
602
+ delete this.options.count;
603
+ }
604
+ }
605
+ }
606
+ },
607
+ CHECKS: {
608
+ equalTo :'===',
609
+ greaterThan : '>',
610
+ greaterThanOrEqualTo : '>=',
611
+ lessThan : '<',
612
+ lessThanOrEqualTo : '<='
613
+ },
614
+ call: function() {
615
+ var check, checkValue, fn, form, operator, val;
616
+
617
+ if (Ember.isEmpty(this.model.get(this.property))) {
618
+ if (this.options.allowBlank === undefined) {
619
+ this.errors.pushObject(this.options.messages.numericality);
620
+ }
621
+ } else if (!Ember.Validations.patterns.numericality.test(this.model.get(this.property))) {
622
+ this.errors.pushObject(this.options.messages.numericality);
623
+ } else if (this.options.onlyInteger === true && !(/^[+\-]?\d+$/.test(this.model.get(this.property)))) {
624
+ this.errors.pushObject(this.options.messages.onlyInteger);
625
+ } else if (this.options.odd && parseInt(this.model.get(this.property), 10) % 2 === 0) {
626
+ this.errors.pushObject(this.options.messages.odd);
627
+ } else if (this.options.even && parseInt(this.model.get(this.property), 10) % 2 !== 0) {
628
+ this.errors.pushObject(this.options.messages.even);
629
+ } else {
630
+ for (check in this.CHECKS) {
631
+ operator = this.CHECKS[check];
632
+
633
+ if (this.options[check] === undefined) {
634
+ continue;
635
+ }
636
+
637
+ if (!isNaN(parseFloat(this.options[check])) && isFinite(this.options[check])) {
638
+ checkValue = this.options[check];
639
+ } else if (this.model.get(this.options[check]) !== undefined) {
640
+ checkValue = this.model.get(this.options[check]);
641
+ }
642
+
643
+ fn = new Function('return ' + this.model.get(this.property) + ' ' + operator + ' ' + checkValue);
644
+
645
+ if (!fn()) {
646
+ this.errors.pushObject(this.options.messages[check]);
647
+ }
648
+ }
649
+ }
650
+ }
651
+ });
652
+
653
+ })();
654
+
655
+
656
+
657
+ (function() {
658
+ Ember.Validations.validators.local.Presence = Ember.Validations.validators.Base.extend({
659
+ init: function() {
660
+ this._super();
661
+ /*jshint expr:true*/
662
+ if (this.options === true) {
663
+ this.options = {};
664
+ }
665
+
666
+ if (this.options.message === undefined) {
667
+ this.options.message = Ember.Validations.messages.render('blank', this.options);
668
+ }
669
+ },
670
+ call: function() {
671
+ if (Ember.isEmpty(this.model.get(this.property))) {
672
+ this.errors.pushObject(this.options.message);
673
+ }
674
+ }
675
+ });
676
+
677
+ })();
678
+
679
+
680
+
681
+ (function() {
682
+ Ember.Validations.validators.local.Url = Ember.Validations.validators.Base.extend({
683
+ regexp: null,
684
+ regexp_ip: null,
685
+
686
+ init: function() {
687
+ this._super();
688
+
689
+ if (this.get('options.message') === undefined) {
690
+ this.set('options.message', Ember.Validations.messages.render('url', this.options));
691
+ }
692
+
693
+ if (this.get('options.protocols') === undefined) {
694
+ this.set('options.protocols', ['http', 'https']);
695
+ }
696
+
697
+ // Regular Expression Parts
698
+ var dec_octet = '(25[0-5]|2[0-4][0-9]|[0-1][0-9][0-9]|[1-9][0-9]|[0-9])'; // 0-255
699
+ var ipaddress = '(' + dec_octet + '(\\.' + dec_octet + '){3})';
700
+ var hostname = '([a-zA-Z0-9\\-]+\\.)+([a-zA-Z]{2,})';
701
+ var encoded = '%[0-9a-fA-F]{2}';
702
+ var characters = 'a-zA-Z0-9$\\-_.+!*\'(),;:@&=';
703
+ var segment = '([' + characters + ']|' + encoded + ')*';
704
+
705
+ // Build Regular Expression
706
+ var regex_str = '^';
707
+
708
+ if (this.get('options.domainOnly') === true) {
709
+ regex_str += hostname;
710
+ } else {
711
+ regex_str += '(' + this.get('options.protocols').join('|') + '):\\/\\/'; // Protocol
712
+
713
+ // Username and password
714
+ if (this.get('options.allowUserPass') === true) {
715
+ regex_str += '(([a-zA-Z0-9$\\-_.+!*\'(),;:&=]|' + encoded + ')+@)?'; // Username & passwords
716
+ }
717
+
718
+ // IP Addresses?
719
+ if (this.get('options.allowIp') === true) {
720
+ regex_str += '(' + hostname + '|' + ipaddress + ')'; // Hostname OR IP
721
+ } else {
722
+ regex_str += '(' + hostname + ')'; // Hostname only
723
+ }
724
+
725
+ // Ports
726
+ if (this.get('options.allowPort') === true) {
727
+ regex_str += '(:[0-9]+)?'; // Port
728
+ }
729
+
730
+ regex_str += '(\\/';
731
+ regex_str += '(' + segment + '(\\/' + segment + ')*)?'; // Path
732
+ regex_str += '(\\?' + '([' + characters + '/?]|' + encoded + ')*)?'; // Query
733
+ regex_str += '(\\#' + '([' + characters + '/?]|' + encoded + ')*)?'; // Anchor
734
+ regex_str += ')?';
735
+ }
736
+
737
+ regex_str += '$';
738
+
739
+ // RegExp
740
+ this.regexp = new RegExp(regex_str);
741
+ this.regexp_ip = new RegExp(ipaddress);
742
+ },
743
+ call: function() {
744
+ var url = this.model.get(this.property);
745
+
746
+ if (Ember.isEmpty(url)) {
747
+ if (this.get('options.allowBlank') !== true) {
748
+ this.errors.pushObject(this.get('options.message'));
749
+ }
750
+ } else {
751
+ if (this.get('options.allowIp') !== true) {
752
+ if (this.regexp_ip.test(url)) {
753
+ this.errors.pushObject(this.get('options.message'));
754
+ return;
755
+ }
756
+ }
757
+
758
+ if (!this.regexp.test(url)) {
759
+ this.errors.pushObject(this.get('options.message'));
760
+ }
761
+ }
762
+ }
763
+ });
764
+
765
+
766
+ })();
767
+
768
+
769
+
770
+ (function() {
771
+
772
+ })();
773
+
774
+
775
+
776
+ (function() {
777
+
778
+ })();
779
+