parsley-rails 2.0.7.0 → 2.4.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -5
  3. data/lib/parsley-rails/version.rb +1 -1
  4. data/parsley-rails.gemspec +2 -2
  5. data/update.sh +3 -4
  6. data/vendor/assets/javascripts/parsley.i18n.al.js +29 -0
  7. data/vendor/assets/javascripts/parsley.i18n.ar.js +4 -8
  8. data/vendor/assets/javascripts/parsley.i18n.bg.js +4 -8
  9. data/vendor/assets/javascripts/parsley.i18n.ca.js +29 -0
  10. data/vendor/assets/javascripts/parsley.i18n.cs.extra.js +3 -3
  11. data/vendor/assets/javascripts/parsley.i18n.cs.js +6 -10
  12. data/vendor/assets/javascripts/parsley.i18n.da.js +4 -9
  13. data/vendor/assets/javascripts/parsley.i18n.de.extra.js +3 -3
  14. data/vendor/assets/javascripts/parsley.i18n.de.js +7 -8
  15. data/vendor/assets/javascripts/parsley.i18n.el.extra.js +14 -0
  16. data/vendor/assets/javascripts/parsley.i18n.el.js +29 -0
  17. data/vendor/assets/javascripts/parsley.i18n.en.extra.js +5 -4
  18. data/vendor/assets/javascripts/parsley.i18n.en.js +5 -8
  19. data/vendor/assets/javascripts/parsley.i18n.es.js +4 -6
  20. data/vendor/assets/javascripts/parsley.i18n.eu.js +29 -0
  21. data/vendor/assets/javascripts/parsley.i18n.fa.js +9 -13
  22. data/vendor/assets/javascripts/parsley.i18n.fi.extra.js +3 -3
  23. data/vendor/assets/javascripts/parsley.i18n.fi.js +5 -9
  24. data/vendor/assets/javascripts/parsley.i18n.fr.extra.js +5 -4
  25. data/vendor/assets/javascripts/parsley.i18n.fr.js +4 -8
  26. data/vendor/assets/javascripts/parsley.i18n.he.extra.js +3 -3
  27. data/vendor/assets/javascripts/parsley.i18n.he.js +4 -8
  28. data/vendor/assets/javascripts/parsley.i18n.hr.extra.js +14 -0
  29. data/vendor/assets/javascripts/parsley.i18n.hr.js +29 -0
  30. data/vendor/assets/javascripts/parsley.i18n.hu.extra.js +14 -0
  31. data/vendor/assets/javascripts/parsley.i18n.hu.js +30 -0
  32. data/vendor/assets/javascripts/parsley.i18n.id.extra.js +3 -3
  33. data/vendor/assets/javascripts/parsley.i18n.id.js +4 -8
  34. data/vendor/assets/javascripts/parsley.i18n.it.extra.js +3 -3
  35. data/vendor/assets/javascripts/parsley.i18n.it.js +4 -8
  36. data/vendor/assets/javascripts/parsley.i18n.ja.js +4 -8
  37. data/vendor/assets/javascripts/parsley.i18n.ko.js +5 -9
  38. data/vendor/assets/javascripts/parsley.i18n.lt.js +29 -0
  39. data/vendor/assets/javascripts/parsley.i18n.lv.extra.js +14 -0
  40. data/vendor/assets/javascripts/parsley.i18n.lv.js +29 -0
  41. data/vendor/assets/javascripts/{parsley.i18n.ms_MY.extra.js → parsley.i18n.ms.extra.js} +4 -4
  42. data/vendor/assets/javascripts/{parsley.i18n.ms_MY.js → parsley.i18n.ms.js} +4 -8
  43. data/vendor/assets/javascripts/parsley.i18n.nl.extra.js +3 -3
  44. data/vendor/assets/javascripts/parsley.i18n.nl.js +4 -8
  45. data/vendor/assets/javascripts/parsley.i18n.no.js +29 -0
  46. data/vendor/assets/javascripts/parsley.i18n.pl.js +19 -23
  47. data/vendor/assets/javascripts/parsley.i18n.pt-br.js +4 -8
  48. data/vendor/assets/javascripts/parsley.i18n.pt-pt.js +29 -0
  49. data/vendor/assets/javascripts/parsley.i18n.ro.extra.js +14 -0
  50. data/vendor/assets/javascripts/parsley.i18n.ro.js +29 -0
  51. data/vendor/assets/javascripts/parsley.i18n.ru.extra.js +3 -3
  52. data/vendor/assets/javascripts/parsley.i18n.ru.js +4 -13
  53. data/vendor/assets/javascripts/parsley.i18n.sl.extra.js +14 -0
  54. data/vendor/assets/javascripts/parsley.i18n.sl.js +30 -0
  55. data/vendor/assets/javascripts/parsley.i18n.sq.js +29 -0
  56. data/vendor/assets/javascripts/parsley.i18n.sv.extra.js +3 -3
  57. data/vendor/assets/javascripts/parsley.i18n.sv.js +4 -8
  58. data/vendor/assets/javascripts/parsley.i18n.th.js +4 -8
  59. data/vendor/assets/javascripts/parsley.i18n.tr.js +22 -26
  60. data/vendor/assets/javascripts/parsley.i18n.uk.extra.js +9 -0
  61. data/vendor/assets/javascripts/parsley.i18n.uk.js +29 -0
  62. data/vendor/assets/javascripts/parsley.i18n.zh_cn.extra.js +3 -3
  63. data/vendor/assets/javascripts/parsley.i18n.zh_cn.js +4 -8
  64. data/vendor/assets/javascripts/parsley.i18n.zh_tw.js +16 -20
  65. data/vendor/assets/javascripts/parsley.js +1970 -1673
  66. data/vendor/assets/javascripts/parsley.min.js +18 -0
  67. metadata +27 -6
  68. data/vendor/assets/javascripts/parsley.remote.js +0 -2347
@@ -1,6 +1,6 @@
1
- window.ParsleyConfig = window.ParsleyConfig || {};
2
- window.ParsleyConfig.i18n = window.ParsleyConfig.i18n || {};
1
+ // Validation errors messages for Parsley
2
+ // Load this after Parsley
3
3
 
4
- window.ParsleyConfig.i18n.zh_cn = $.extend(window.ParsleyConfig.i18n.zh_cn || {}, {
4
+ Parsley.addMessages('zh-cn', {
5
5
  dateiso: "请输入正确格式的日期 (YYYY-MM-DD)."
6
6
  });
@@ -1,9 +1,7 @@
1
- // ParsleyConfig definition if not already set
2
- window.ParsleyConfig = window.ParsleyConfig || {};
3
- window.ParsleyConfig.i18n = window.ParsleyConfig.i18n || {};
1
+ // Validation errors messages for Parsley
2
+ // Load this after Parsley
4
3
 
5
- // Define then the messages
6
- window.ParsleyConfig.i18n.zh_cn = $.extend(window.ParsleyConfig.i18n.zh_cn || {}, {
4
+ Parsley.addMessages('zh-cn', {
7
5
  defaultMessage: "不正确的值",
8
6
  type: {
9
7
  email: "请输入一个有效的电子邮箱地址",
@@ -28,6 +26,4 @@ window.ParsleyConfig.i18n.zh_cn = $.extend(window.ParsleyConfig.i18n.zh_cn || {}
28
26
  equalto: "输入值不同"
29
27
  });
30
28
 
31
- // If file is loaded after Parsley main file, auto-load locale
32
- if ('undefined' !== typeof window.ParsleyValidator)
33
- window.ParsleyValidator.addCatalog('zh_cn', window.ParsleyConfig.i18n.zh_cn, true);
29
+ Parsley.setLocale('zh-cn');
@@ -1,33 +1,29 @@
1
- // ParsleyConfig definition if not already set
2
- window.ParsleyConfig = window.ParsleyConfig || {};
3
- window.ParsleyConfig.i18n = window.ParsleyConfig.i18n || {};
1
+ // Validation errors messages for Parsley
2
+ // Load this after Parsley
4
3
 
5
- // Define then the messages
6
- window.ParsleyConfig.i18n.zh_tw = $.extend(window.ParsleyConfig.i18n.zh_tw || {}, {
4
+ Parsley.addMessages('zh-tw', {
7
5
  defaultMessage: "這個值似乎是無效的。",
8
6
  type: {
9
- email: "請輸入一個有效的email。",
7
+ email: "請輸入一個正確的電子郵件地址。",
10
8
  url: "請輸入一個有效的網址。",
11
- number: "這個值應該是一個數字。",
12
- integer: "這個值應該是一個整數數字。",
13
- digits: "這個值應該是一個號碼。",
14
- alphanum: "這個值應該是字母或數字。"
9
+ number: "請輸入一個數字。",
10
+ integer: "請輸入一個整數。",
11
+ digits: "這個欄位只接受數字。",
12
+ alphanum: "這個欄位只接受英文字母或是數字。"
15
13
  },
16
- notblank: "這個值不應該為空值。",
17
- required: "這個空格必須填寫。",
14
+ notblank: "這個欄位不能為空白。",
15
+ required: "這個欄位必須填寫。",
18
16
  pattern: "這個值似乎是無效的。",
19
17
  min: "輸入的值應該大於或等於 %s",
20
18
  max: "輸入的值應該小於或等於 %s",
21
- range: "這個值應該在 %s 和 %s 之間。",
22
- minlength: "這個值至少要 %s 字元。",
23
- maxlength: "這個值最多要 %s 字元。",
24
- length: "字元長度應該在 %s 和 %s",
19
+ range: "輸入的值應該在 %s 和 %s 之間。",
20
+ minlength: "輸入的值至少要有 %s 個字元。",
21
+ maxlength: "輸入的值最多可以有 %s 個字元。",
22
+ length: "字元長度應該在 %s 和 %s 之間。",
25
23
  mincheck: "你至少要選擇 %s 個項目。",
26
24
  maxcheck: "你最多可選擇 %s 個項目。",
27
25
  check: "你必須選擇 %s 到 %s 個項目。",
28
- equalto: "輸入值不同"
26
+ equalto: "輸入值不同。"
29
27
  });
30
28
 
31
- // If file is loaded after Parsley main file, auto-load locale
32
- if ('undefined' !== typeof window.ParsleyValidator)
33
- window.ParsleyValidator.addCatalog('zh_tw', window.ParsleyConfig.i18n.zh_tw, true);
29
+ Parsley.setLocale('zh-tw');
@@ -1,2083 +1,2380 @@
1
1
  /*!
2
- * Parsleyjs
2
+ * Parsley.js
3
+ * Version 2.4.4 - built Thu, Aug 4th 2016, 9:54 pm
4
+ * http://parsleyjs.org
3
5
  * Guillaume Potier - <guillaume@wisembly.com>
4
- * Version 2.0.6 - built Sat Jan 24 2015 14:44:37
6
+ * Marc-Andre Lafortune - <petroselinum@marc-andre.ca>
5
7
  * MIT Licensed
6
- *
7
8
  */
8
- !(function (factory) {
9
- if (typeof define === 'function' && define.amd) {
10
- // AMD. Register as an anonymous module depending on jQuery.
11
- define(['jquery'], factory);
12
- } else {
13
- // No AMD. Register plugin with global jQuery object.
14
- factory(jQuery);
15
- }
16
- }(function ($) {
17
- // small hack for requirejs if jquery is loaded through map and not path
18
- // see http://requirejs.org/docs/jquery.html
19
- if ('undefined' === typeof $ && 'undefined' !== typeof window.jQuery)
20
- $ = window.jQuery;
21
- var ParsleyUtils = {
9
+
10
+ // The source code below is generated by babel as
11
+ // Parsley is written in ECMAScript 6
12
+ //
13
+ var _slice = Array.prototype.slice;
14
+
15
+ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }
16
+
17
+ (function (global, factory) {
18
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery')) : typeof define === 'function' && define.amd ? define(['jquery'], factory) : global.parsley = factory(global.jQuery);
19
+ })(this, function ($) {
20
+ 'use strict';
21
+
22
+ var globalID = 1;
23
+ var pastWarnings = {};
24
+
25
+ var ParsleyUtils__ParsleyUtils = {
22
26
  // Parsley DOM-API
23
27
  // returns object from dom attributes and values
24
- // if attr is given, returns bool if attr present in DOM or not
25
- attr: function ($element, namespace, checkAttr) {
26
- var
27
- attribute,
28
- obj = {},
29
- msie = this.msieversion(),
30
- regex = new RegExp('^' + namespace, 'i');
31
- if ('undefined' === typeof $element || 'undefined' === typeof $element[0])
32
- return {};
33
- for (var i in $element[0].attributes) {
34
- attribute = $element[0].attributes[i];
35
- if ('undefined' !== typeof attribute && null !== attribute && (!msie || msie >= 8 || attribute.specified) && regex.test(attribute.name)) {
36
- if ('undefined' !== typeof checkAttr && new RegExp(checkAttr + '$', 'i').test(attribute.name))
37
- return true;
38
- obj[this.camelize(attribute.name.replace(namespace, ''))] = this.deserializeValue(attribute.value);
28
+ attr: function attr($element, namespace, obj) {
29
+ var i;
30
+ var attribute;
31
+ var attributes;
32
+ var regex = new RegExp('^' + namespace, 'i');
33
+
34
+ if ('undefined' === typeof obj) obj = {};else {
35
+ // Clear all own properties. This won't affect prototype's values
36
+ for (i in obj) {
37
+ if (obj.hasOwnProperty(i)) delete obj[i];
39
38
  }
40
39
  }
41
- return 'undefined' === typeof checkAttr ? obj : false;
42
- },
43
- setAttr: function ($element, namespace, attr, value) {
44
- $element[0].setAttribute(this.dasherize(namespace + attr), String(value));
45
- },
46
- // Recursive object / array getter
47
- get: function (obj, path) {
48
- var
49
- i = 0,
50
- paths = (path || '').split('.');
51
- while (this.isObject(obj) || this.isArray(obj)) {
52
- obj = obj[paths[i++]];
53
- if (i === paths.length)
54
- return obj;
40
+
41
+ if ('undefined' === typeof $element || 'undefined' === typeof $element[0]) return obj;
42
+
43
+ attributes = $element[0].attributes;
44
+ for (i = attributes.length; i--;) {
45
+ attribute = attributes[i];
46
+
47
+ if (attribute && attribute.specified && regex.test(attribute.name)) {
48
+ obj[this.camelize(attribute.name.slice(namespace.length))] = this.deserializeValue(attribute.value);
49
+ }
55
50
  }
56
- return undefined;
51
+
52
+ return obj;
57
53
  },
58
- hash: function (length) {
59
- return String(Math.random()).substring(2, length ? length + 2 : 9);
54
+
55
+ checkAttr: function checkAttr($element, namespace, _checkAttr) {
56
+ return $element.is('[' + namespace + _checkAttr + ']');
60
57
  },
61
- /** Third party functions **/
62
- // Underscore isArray
63
- isArray: function (mixed) {
64
- return Object.prototype.toString.call(mixed) === '[object Array]';
58
+
59
+ setAttr: function setAttr($element, namespace, attr, value) {
60
+ $element[0].setAttribute(this.dasherize(namespace + attr), String(value));
65
61
  },
66
- // Underscore isObject
67
- isObject: function (mixed) {
68
- return mixed === Object(mixed);
62
+
63
+ generateID: function generateID() {
64
+ return '' + globalID++;
69
65
  },
66
+
67
+ /** Third party functions **/
70
68
  // Zepto deserialize function
71
- deserializeValue: function (value) {
69
+ deserializeValue: function deserializeValue(value) {
72
70
  var num;
71
+
73
72
  try {
74
- return value ?
75
- value == "true" ||
76
- (value == "false" ? false :
77
- value == "null" ? null :
78
- !isNaN(num = Number(value)) ? num :
79
- /^[\[\{]/.test(value) ? $.parseJSON(value) :
80
- value)
81
- : value;
82
- } catch (e) { return value; }
73
+ return value ? value == "true" || (value == "false" ? false : value == "null" ? null : !isNaN(num = Number(value)) ? num : /^[\[\{]/.test(value) ? $.parseJSON(value) : value) : value;
74
+ } catch (e) {
75
+ return value;
76
+ }
83
77
  },
78
+
84
79
  // Zepto camelize function
85
- camelize: function (str) {
86
- return str.replace(/-+(.)?/g, function(match, chr) {
80
+ camelize: function camelize(str) {
81
+ return str.replace(/-+(.)?/g, function (match, chr) {
87
82
  return chr ? chr.toUpperCase() : '';
88
83
  });
89
84
  },
85
+
90
86
  // Zepto dasherize function
91
- dasherize: function (str) {
92
- return str.replace(/::/g, '/')
93
- .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
94
- .replace(/([a-z\d])([A-Z])/g, '$1_$2')
95
- .replace(/_/g, '-')
96
- .toLowerCase();
97
- },
98
- // http://support.microsoft.com/kb/167820
99
- // http://stackoverflow.com/questions/19999388/jquery-check-if-user-is-using-ie
100
- msieversion: function () {
101
- var
102
- ua = window.navigator.userAgent,
103
- msie = ua.indexOf('MSIE ');
104
- if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./))
105
- return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
106
- return 0;
107
- }
87
+ dasherize: function dasherize(str) {
88
+ return str.replace(/::/g, '/').replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2').replace(/([a-z\d])([A-Z])/g, '$1_$2').replace(/_/g, '-').toLowerCase();
89
+ },
90
+
91
+ warn: function warn() {
92
+ var _window$console;
93
+
94
+ if (window.console && 'function' === typeof window.console.warn) (_window$console = window.console).warn.apply(_window$console, arguments);
95
+ },
96
+
97
+ warnOnce: function warnOnce(msg) {
98
+ if (!pastWarnings[msg]) {
99
+ pastWarnings[msg] = true;
100
+ this.warn.apply(this, arguments);
101
+ }
102
+ },
103
+
104
+ _resetWarnings: function _resetWarnings() {
105
+ pastWarnings = {};
106
+ },
107
+
108
+ trimString: function trimString(string) {
109
+ return string.replace(/^\s+|\s+$/g, '');
110
+ },
111
+
112
+ namespaceEvents: function namespaceEvents(events, namespace) {
113
+ events = this.trimString(events || '').split(/\s+/);
114
+ if (!events[0]) return '';
115
+ return $.map(events, function (evt) {
116
+ return evt + '.' + namespace;
117
+ }).join(' ');
118
+ },
119
+
120
+ difference: function difference(array, remove) {
121
+ // This is O(N^2), should be optimized
122
+ var result = [];
123
+ $.each(array, function (_, elem) {
124
+ if (remove.indexOf(elem) == -1) result.push(elem);
125
+ });
126
+ return result;
127
+ },
128
+
129
+ // Alter-ego to native Promise.all, but for jQuery
130
+ all: function all(promises) {
131
+ // jQuery treats $.when() and $.when(singlePromise) differently; let's avoid that and add spurious elements
132
+ return $.when.apply($, _toConsumableArray(promises).concat([42, 42]));
133
+ },
134
+
135
+ // Object.create polyfill, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Polyfill
136
+ objectCreate: Object.create || (function () {
137
+ var Object = function Object() {};
138
+ return function (prototype) {
139
+ if (arguments.length > 1) {
140
+ throw Error('Second argument not supported');
141
+ }
142
+ if (typeof prototype != 'object') {
143
+ throw TypeError('Argument must be an object');
144
+ }
145
+ Object.prototype = prototype;
146
+ var result = new Object();
147
+ Object.prototype = null;
148
+ return result;
149
+ };
150
+ })(),
151
+
152
+ _SubmitSelector: 'input[type="submit"], button:submit'
108
153
  };
109
- // All these options could be overriden and specified directly in DOM using
110
- // `data-parsley-` default DOM-API
111
- // eg: `inputs` can be set in DOM using `data-parsley-inputs="input, textarea"`
112
- // eg: `data-parsley-stop-on-first-failing-constraint="false"`
154
+
155
+ var ParsleyUtils__default = ParsleyUtils__ParsleyUtils;
156
+
157
+ // All these options could be overriden and specified directly in DOM using
158
+ // `data-parsley-` default DOM-API
159
+ // eg: `inputs` can be set in DOM using `data-parsley-inputs="input, textarea"`
160
+ // eg: `data-parsley-stop-on-first-failing-constraint="false"`
161
+
113
162
  var ParsleyDefaults = {
114
163
  // ### General
164
+
115
165
  // Default data-namespace for DOM API
116
166
  namespace: 'data-parsley-',
167
+
117
168
  // Supported inputs by default
118
169
  inputs: 'input, textarea, select',
170
+
119
171
  // Excluded inputs by default
120
172
  excluded: 'input[type=button], input[type=submit], input[type=reset], input[type=hidden]',
173
+
121
174
  // Stop validating field on highest priority failing constraint
122
175
  priorityEnabled: true,
176
+
177
+ // ### Field only
178
+
179
+ // identifier used to group together inputs (e.g. radio buttons...)
180
+ multiple: null,
181
+
182
+ // identifier (or array of identifiers) used to validate only a select group of inputs
183
+ group: null,
184
+
123
185
  // ### UI
124
186
  // Enable\Disable error messages
125
187
  uiEnabled: true,
188
+
126
189
  // Key events threshold before validation
127
190
  validationThreshold: 3,
128
- // Focused field on form validation error. 'fist'|'last'|'none'
191
+
192
+ // Focused field on form validation error. 'first'|'last'|'none'
129
193
  focus: 'first',
130
- // `$.Event()` that will trigger validation. eg: `keyup`, `change`...
194
+
195
+ // event(s) that will trigger validation before first failure. eg: `input`...
131
196
  trigger: false,
197
+
198
+ // event(s) that will trigger validation after first failure.
199
+ triggerAfterFailure: 'input',
200
+
132
201
  // Class that would be added on every failing validation Parsley field
133
202
  errorClass: 'parsley-error',
203
+
134
204
  // Same for success validation
135
205
  successClass: 'parsley-success',
206
+
136
207
  // Return the `$element` that will receive these above success or error classes
137
208
  // Could also be (and given directly from DOM) a valid selector like `'#div'`
138
- classHandler: function (ParsleyField) {},
209
+ classHandler: function classHandler(ParsleyField) {},
210
+
139
211
  // Return the `$element` where errors will be appended
140
212
  // Could also be (and given directly from DOM) a valid selector like `'#div'`
141
- errorsContainer: function (ParsleyField) {},
213
+ errorsContainer: function errorsContainer(ParsleyField) {},
214
+
142
215
  // ul elem that would receive errors' list
143
216
  errorsWrapper: '<ul class="parsley-errors-list"></ul>',
217
+
144
218
  // li elem that would receive error message
145
219
  errorTemplate: '<li></li>'
146
220
  };
147
221
 
148
- var ParsleyAbstract = function() {};
222
+ var ParsleyAbstract = function ParsleyAbstract() {
223
+ this.__id__ = ParsleyUtils__default.generateID();
224
+ };
225
+
149
226
  ParsleyAbstract.prototype = {
150
- asyncSupport: false,
151
- actualizeOptions: function () {
152
- this.options = this.OptionsFactory.get(this);
227
+ asyncSupport: true, // Deprecated
228
+
229
+ _pipeAccordingToValidationResult: function _pipeAccordingToValidationResult() {
230
+ var _this = this;
231
+
232
+ var pipe = function pipe() {
233
+ var r = $.Deferred();
234
+ if (true !== _this.validationResult) r.reject();
235
+ return r.resolve().promise();
236
+ };
237
+ return [pipe, pipe];
238
+ },
239
+
240
+ actualizeOptions: function actualizeOptions() {
241
+ ParsleyUtils__default.attr(this.$element, this.options.namespace, this.domOptions);
242
+ if (this.parent && this.parent.actualizeOptions) this.parent.actualizeOptions();
153
243
  return this;
154
244
  },
155
- // ParsleyValidator validate proxy function . Could be replaced by third party scripts
156
- validateThroughValidator: function (value, constraints, priority) {
157
- return window.ParsleyValidator.validate(value, constraints, priority);
245
+
246
+ _resetOptions: function _resetOptions(initOptions) {
247
+ this.domOptions = ParsleyUtils__default.objectCreate(this.parent.options);
248
+ this.options = ParsleyUtils__default.objectCreate(this.domOptions);
249
+ // Shallow copy of ownProperties of initOptions:
250
+ for (var i in initOptions) {
251
+ if (initOptions.hasOwnProperty(i)) this.options[i] = initOptions[i];
252
+ }
253
+ this.actualizeOptions();
254
+ },
255
+
256
+ _listeners: null,
257
+
258
+ // Register a callback for the given event name
259
+ // Callback is called with context as the first argument and the `this`
260
+ // The context is the current parsley instance, or window.Parsley if global
261
+ // A return value of `false` will interrupt the calls
262
+ on: function on(name, fn) {
263
+ this._listeners = this._listeners || {};
264
+ var queue = this._listeners[name] = this._listeners[name] || [];
265
+ queue.push(fn);
266
+
267
+ return this;
158
268
  },
159
- // Subscribe an event and a handler for a specific field or a specific form
160
- // If on a ParsleyForm instance, it will be attached to form instance and also
161
- // To every field instance for this form
162
- subscribe: function (name, fn) {
269
+
270
+ // Deprecated. Use `on` instead
271
+ subscribe: function subscribe(name, fn) {
163
272
  $.listenTo(this, name.toLowerCase(), fn);
273
+ },
274
+
275
+ // Unregister a callback (or all if none is given) for the given event name
276
+ off: function off(name, fn) {
277
+ var queue = this._listeners && this._listeners[name];
278
+ if (queue) {
279
+ if (!fn) {
280
+ delete this._listeners[name];
281
+ } else {
282
+ for (var i = queue.length; i--;) if (queue[i] === fn) queue.splice(i, 1);
283
+ }
284
+ }
164
285
  return this;
165
286
  },
166
- // Same as subscribe above. Unsubscribe an event for field, or form + its fields
167
- unsubscribe: function (name) {
287
+
288
+ // Deprecated. Use `off`
289
+ unsubscribe: function unsubscribe(name, fn) {
168
290
  $.unsubscribeTo(this, name.toLowerCase());
169
- return this;
170
291
  },
292
+
293
+ // Trigger an event of the given name
294
+ // A return value of `false` interrupts the callback chain
295
+ // Returns false if execution was interrupted
296
+ trigger: function trigger(name, target, extraArg) {
297
+ target = target || this;
298
+ var queue = this._listeners && this._listeners[name];
299
+ var result;
300
+ var parentResult;
301
+ if (queue) {
302
+ for (var i = queue.length; i--;) {
303
+ result = queue[i].call(target, target, extraArg);
304
+ if (result === false) return result;
305
+ }
306
+ }
307
+ if (this.parent) {
308
+ return this.parent.trigger(name, target, extraArg);
309
+ }
310
+ return true;
311
+ },
312
+
171
313
  // Reset UI
172
- reset: function () {
314
+ reset: function reset() {
173
315
  // Field case: just emit a reset event for UI
174
- if ('ParsleyForm' !== this.__class__)
175
- return $.emit('parsley:field:reset', this);
316
+ if ('ParsleyForm' !== this.__class__) {
317
+ this._resetUI();
318
+ return this._trigger('reset');
319
+ }
320
+
176
321
  // Form case: emit a reset event for each field
177
- for (var i = 0; i < this.fields.length; i++)
178
- $.emit('parsley:field:reset', this.fields[i]);
179
- $.emit('parsley:form:reset', this);
322
+ for (var i = 0; i < this.fields.length; i++) this.fields[i].reset();
323
+
324
+ this._trigger('reset');
180
325
  },
326
+
181
327
  // Destroy Parsley instance (+ UI)
182
- destroy: function () {
328
+ destroy: function destroy() {
183
329
  // Field case: emit destroy event to clean UI and then destroy stored instance
330
+ this._destroyUI();
184
331
  if ('ParsleyForm' !== this.__class__) {
185
332
  this.$element.removeData('Parsley');
186
333
  this.$element.removeData('ParsleyFieldMultiple');
187
- $.emit('parsley:field:destroy', this);
334
+ this._trigger('destroy');
335
+
188
336
  return;
189
337
  }
338
+
190
339
  // Form case: destroy all its fields and then destroy stored instance
191
- for (var i = 0; i < this.fields.length; i++)
192
- this.fields[i].destroy();
340
+ for (var i = 0; i < this.fields.length; i++) this.fields[i].destroy();
341
+
193
342
  this.$element.removeData('Parsley');
194
- $.emit('parsley:form:destroy', this);
343
+ this._trigger('destroy');
344
+ },
345
+
346
+ asyncIsValid: function asyncIsValid(group, force) {
347
+ ParsleyUtils__default.warnOnce("asyncIsValid is deprecated; please use whenValid instead");
348
+ return this.whenValid({ group: group, force: force });
349
+ },
350
+
351
+ _findRelated: function _findRelated() {
352
+ return this.options.multiple ? this.parent.$element.find('[' + this.options.namespace + 'multiple="' + this.options.multiple + '"]') : this.$element;
195
353
  }
196
354
  };
197
- /*!
198
- * validator.js
199
- * Guillaume Potier - <guillaume@wisembly.com>
200
- * Version 1.0.1 - built Mon Aug 25 2014 16:10:10
201
- * MIT Licensed
202
- *
203
- */
204
- var Validator = ( function ( ) {
205
- var exports = {};
206
- /**
207
- * Validator
208
- */
209
- var Validator = function ( options ) {
210
- this.__class__ = 'Validator';
211
- this.__version__ = '1.0.1';
212
- this.options = options || {};
213
- this.bindingKey = this.options.bindingKey || '_validatorjsConstraint';
214
- };
215
- Validator.prototype = {
216
- constructor: Validator,
217
- /*
218
- * Validate string: validate( string, Assert, string ) || validate( string, [ Assert, Assert ], [ string, string ] )
219
- * Validate object: validate( object, Constraint, string ) || validate( object, Constraint, [ string, string ] )
220
- * Validate binded object: validate( object, string ) || validate( object, [ string, string ] )
221
- */
222
- validate: function ( objectOrString, AssertsOrConstraintOrGroup, group ) {
223
- if ( 'string' !== typeof objectOrString && 'object' !== typeof objectOrString )
224
- throw new Error( 'You must validate an object or a string' );
225
- // string / array validation
226
- if ( 'string' === typeof objectOrString || _isArray(objectOrString) )
227
- return this._validateString( objectOrString, AssertsOrConstraintOrGroup, group );
228
- // binded object validation
229
- if ( this.isBinded( objectOrString ) )
230
- return this._validateBindedObject( objectOrString, AssertsOrConstraintOrGroup );
231
- // regular object validation
232
- return this._validateObject( objectOrString, AssertsOrConstraintOrGroup, group );
233
- },
234
- bind: function ( object, constraint ) {
235
- if ( 'object' !== typeof object )
236
- throw new Error( 'Must bind a Constraint to an object' );
237
- object[ this.bindingKey ] = new Constraint( constraint );
238
- return this;
355
+
356
+ var requirementConverters = {
357
+ string: function string(_string) {
358
+ return _string;
239
359
  },
240
- unbind: function ( object ) {
241
- if ( 'undefined' === typeof object._validatorjsConstraint )
242
- return this;
243
- delete object[ this.bindingKey ];
244
- return this;
360
+ integer: function integer(string) {
361
+ if (isNaN(string)) throw 'Requirement is not an integer: "' + string + '"';
362
+ return parseInt(string, 10);
245
363
  },
246
- isBinded: function ( object ) {
247
- return 'undefined' !== typeof object[ this.bindingKey ];
248
- },
249
- getBinded: function ( object ) {
250
- return this.isBinded( object ) ? object[ this.bindingKey ] : null;
251
- },
252
- _validateString: function ( string, assert, group ) {
253
- var result, failures = [];
254
- if ( !_isArray( assert ) )
255
- assert = [ assert ];
256
- for ( var i = 0; i < assert.length; i++ ) {
257
- if ( ! ( assert[ i ] instanceof Assert) )
258
- throw new Error( 'You must give an Assert or an Asserts array to validate a string' );
259
- result = assert[ i ].check( string, group );
260
- if ( result instanceof Violation )
261
- failures.push( result );
262
- }
263
- return failures.length ? failures : true;
364
+ number: function number(string) {
365
+ if (isNaN(string)) throw 'Requirement is not a number: "' + string + '"';
366
+ return parseFloat(string);
367
+ },
368
+ reference: function reference(string) {
369
+ // Unused for now
370
+ var result = $(string);
371
+ if (result.length === 0) throw 'No such reference: "' + string + '"';
372
+ return result;
264
373
  },
265
- _validateObject: function ( object, constraint, group ) {
266
- if ( 'object' !== typeof constraint )
267
- throw new Error( 'You must give a constraint to validate an object' );
268
- if ( constraint instanceof Constraint )
269
- return constraint.check( object, group );
270
- return new Constraint( constraint ).check( object, group );
374
+ boolean: function boolean(string) {
375
+ return string !== 'false';
271
376
  },
272
- _validateBindedObject: function ( object, group ) {
273
- return object[ this.bindingKey ].check( object, group );
377
+ object: function object(string) {
378
+ return ParsleyUtils__default.deserializeValue(string);
379
+ },
380
+ regexp: function regexp(_regexp) {
381
+ var flags = '';
382
+
383
+ // Test if RegExp is literal, if not, nothing to be done, otherwise, we need to isolate flags and pattern
384
+ if (/^\/.*\/(?:[gimy]*)$/.test(_regexp)) {
385
+ // Replace the regexp literal string with the first match group: ([gimy]*)
386
+ // If no flag is present, this will be a blank string
387
+ flags = _regexp.replace(/.*\/([gimy]*)$/, '$1');
388
+ // Again, replace the regexp literal string with the first match group:
389
+ // everything excluding the opening and closing slashes and the flags
390
+ _regexp = _regexp.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1');
391
+ } else {
392
+ // Anchor regexp:
393
+ _regexp = '^' + _regexp + '$';
394
+ }
395
+ return new RegExp(_regexp, flags);
274
396
  }
275
397
  };
276
- Validator.errorCode = {
277
- must_be_a_string: 'must_be_a_string',
278
- must_be_an_array: 'must_be_an_array',
279
- must_be_a_number: 'must_be_a_number',
280
- must_be_a_string_or_array: 'must_be_a_string_or_array'
398
+
399
+ var convertArrayRequirement = function convertArrayRequirement(string, length) {
400
+ var m = string.match(/^\s*\[(.*)\]\s*$/);
401
+ if (!m) throw 'Requirement is not an array: "' + string + '"';
402
+ var values = m[1].split(',').map(ParsleyUtils__default.trimString);
403
+ if (values.length !== length) throw 'Requirement has ' + values.length + ' values when ' + length + ' are needed';
404
+ return values;
281
405
  };
282
- /**
283
- * Constraint
284
- */
285
- var Constraint = function ( data, options ) {
286
- this.__class__ = 'Constraint';
287
- this.options = options || {};
288
- this.nodes = {};
289
- if ( data ) {
290
- try {
291
- this._bootstrap( data );
292
- } catch ( err ) {
293
- throw new Error( 'Should give a valid mapping object to Constraint', err, data );
406
+
407
+ var convertRequirement = function convertRequirement(requirementType, string) {
408
+ var converter = requirementConverters[requirementType || 'string'];
409
+ if (!converter) throw 'Unknown requirement specification: "' + requirementType + '"';
410
+ return converter(string);
411
+ };
412
+
413
+ var convertExtraOptionRequirement = function convertExtraOptionRequirement(requirementSpec, string, extraOptionReader) {
414
+ var main = null;
415
+ var extra = {};
416
+ for (var key in requirementSpec) {
417
+ if (key) {
418
+ var value = extraOptionReader(key);
419
+ if ('string' === typeof value) value = convertRequirement(requirementSpec[key], value);
420
+ extra[key] = value;
421
+ } else {
422
+ main = convertRequirement(requirementSpec[key], string);
294
423
  }
295
424
  }
425
+ return [main, extra];
296
426
  };
297
- Constraint.prototype = {
298
- constructor: Constraint,
299
- check: function ( object, group ) {
300
- var result, failures = {};
301
- // check all constraint nodes.
302
- for ( var property in this.nodes ) {
303
- var isRequired = false;
304
- var constraint = this.get(property);
305
- var constraints = _isArray( constraint ) ? constraint : [constraint];
306
- for (var i = constraints.length - 1; i >= 0; i--) {
307
- if ( 'Required' === constraints[i].__class__ ) {
308
- isRequired = constraints[i].requiresValidation( group );
309
- continue;
310
- }
311
- }
312
- if ( ! this.has( property, object ) && ! this.options.strict && ! isRequired ) {
313
- continue;
427
+
428
+ // A Validator needs to implement the methods `validate` and `parseRequirements`
429
+
430
+ var ParsleyValidator = function ParsleyValidator(spec) {
431
+ $.extend(true, this, spec);
432
+ };
433
+
434
+ ParsleyValidator.prototype = {
435
+ // Returns `true` iff the given `value` is valid according the given requirements.
436
+ validate: function validate(value, requirementFirstArg) {
437
+ if (this.fn) {
438
+ // Legacy style validator
439
+
440
+ if (arguments.length > 3) // If more args then value, requirement, instance...
441
+ requirementFirstArg = [].slice.call(arguments, 1, -1); // Skip first arg (value) and last (instance), combining the rest
442
+ return this.fn.call(this, value, requirementFirstArg);
443
+ }
444
+
445
+ if ($.isArray(value)) {
446
+ if (!this.validateMultiple) throw 'Validator `' + this.name + '` does not handle multiple values';
447
+ return this.validateMultiple.apply(this, arguments);
448
+ } else {
449
+ if (this.validateNumber) {
450
+ if (isNaN(value)) return false;
451
+ arguments[0] = parseFloat(arguments[0]);
452
+ return this.validateNumber.apply(this, arguments);
314
453
  }
315
- try {
316
- if (! this.has( property, this.options.strict || isRequired ? object : undefined ) ) {
317
- // we trigger here a HaveProperty Assert violation to have uniform Violation object in the end
318
- new Assert().HaveProperty( property ).validate( object );
319
- }
320
- result = this._check( property, object[ property ], group );
321
- // check returned an array of Violations or an object mapping Violations
322
- if ( ( _isArray( result ) && result.length > 0 ) || ( !_isArray( result ) && !_isEmptyObject( result ) ) ) {
323
- failures[ property ] = result;
324
- }
325
- } catch ( violation ) {
326
- failures[ property ] = violation;
454
+ if (this.validateString) {
455
+ return this.validateString.apply(this, arguments);
327
456
  }
457
+ throw 'Validator `' + this.name + '` only handles multiple values';
328
458
  }
329
- return _isEmptyObject(failures) ? true : failures;
330
459
  },
331
- add: function ( node, object ) {
332
- if ( object instanceof Assert || ( _isArray( object ) && object[ 0 ] instanceof Assert ) ) {
333
- this.nodes[ node ] = object;
334
- return this;
460
+
461
+ // Parses `requirements` into an array of arguments,
462
+ // according to `this.requirementType`
463
+ parseRequirements: function parseRequirements(requirements, extraOptionReader) {
464
+ if ('string' !== typeof requirements) {
465
+ // Assume requirement already parsed
466
+ // but make sure we return an array
467
+ return $.isArray(requirements) ? requirements : [requirements];
335
468
  }
336
- if ( 'object' === typeof object && !_isArray( object ) ) {
337
- this.nodes[ node ] = object instanceof Constraint ? object : new Constraint( object );
338
- return this;
469
+ var type = this.requirementType;
470
+ if ($.isArray(type)) {
471
+ var values = convertArrayRequirement(requirements, type.length);
472
+ for (var i = 0; i < values.length; i++) values[i] = convertRequirement(type[i], values[i]);
473
+ return values;
474
+ } else if ($.isPlainObject(type)) {
475
+ return convertExtraOptionRequirement(type, requirements, extraOptionReader);
476
+ } else {
477
+ return [convertRequirement(type, requirements)];
339
478
  }
340
- throw new Error( 'Should give an Assert, an Asserts array, a Constraint', object );
341
- },
342
- has: function ( node, nodes ) {
343
- nodes = 'undefined' !== typeof nodes ? nodes : this.nodes;
344
- return 'undefined' !== typeof nodes[ node ];
345
479
  },
346
- get: function ( node, placeholder ) {
347
- return this.has( node ) ? this.nodes[ node ] : placeholder || null;
348
- },
349
- remove: function ( node ) {
350
- var _nodes = [];
351
- for ( var i in this.nodes )
352
- if ( i !== node )
353
- _nodes[ i ] = this.nodes[ i ];
354
- this.nodes = _nodes;
355
- return this;
356
- },
357
- _bootstrap: function ( data ) {
358
- if ( data instanceof Constraint )
359
- return this.nodes = data.nodes;
360
- for ( var node in data )
361
- this.add( node, data[ node ] );
362
- },
363
- _check: function ( node, value, group ) {
364
- // Assert
365
- if ( this.nodes[ node ] instanceof Assert )
366
- return this._checkAsserts( value, [ this.nodes[ node ] ], group );
367
- // Asserts
368
- if ( _isArray( this.nodes[ node ] ) )
369
- return this._checkAsserts( value, this.nodes[ node ], group );
370
- // Constraint -> check api
371
- if ( this.nodes[ node ] instanceof Constraint )
372
- return this.nodes[ node ].check( value, group );
373
- throw new Error( 'Invalid node', this.nodes[ node ] );
374
- },
375
- _checkAsserts: function ( value, asserts, group ) {
376
- var result, failures = [];
377
- for ( var i = 0; i < asserts.length; i++ ) {
378
- result = asserts[ i ].check( value, group );
379
- if ( 'undefined' !== typeof result && true !== result )
380
- failures.push( result );
381
- // Some asserts (Collection for example) could return an object
382
- // if ( result && ! ( result instanceof Violation ) )
383
- // return result;
384
- //
385
- // // Vast assert majority return Violation
386
- // if ( result instanceof Violation )
387
- // failures.push( result );
388
- }
389
- return failures;
390
- }
480
+ // Defaults:
481
+ requirementType: 'string',
482
+
483
+ priority: 2
484
+
391
485
  };
392
- /**
393
- * Violation
394
- */
395
- var Violation = function ( assert, value, violation ) {
396
- this.__class__ = 'Violation';
397
- if ( ! ( assert instanceof Assert ) )
398
- throw new Error( 'Should give an assertion implementing the Assert interface' );
399
- this.assert = assert;
400
- this.value = value;
401
- if ( 'undefined' !== typeof violation )
402
- this.violation = violation;
486
+
487
+ var ParsleyValidatorRegistry = function ParsleyValidatorRegistry(validators, catalog) {
488
+ this.__class__ = 'ParsleyValidatorRegistry';
489
+
490
+ // Default Parsley locale is en
491
+ this.locale = 'en';
492
+
493
+ this.init(validators || {}, catalog || {});
403
494
  };
404
- Violation.prototype = {
405
- show: function () {
406
- var show = {
407
- assert: this.assert.__class__,
408
- value: this.value
409
- };
410
- if ( this.violation )
411
- show.violation = this.violation;
412
- return show;
413
- },
414
- __toString: function () {
415
- if ( 'undefined' !== typeof this.violation )
416
- this.violation = '", ' + this.getViolation().constraint + ' expected was ' + this.getViolation().expected;
417
- return this.assert.__class__ + ' assert failed for "' + this.value + this.violation || '';
418
- },
419
- getViolation: function () {
420
- var constraint, expected;
421
- for ( constraint in this.violation )
422
- expected = this.violation[ constraint ];
423
- return { constraint: constraint, expected: expected };
424
- }
495
+
496
+ var typeRegexes = {
497
+ email: /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,
498
+
499
+ // Follow https://www.w3.org/TR/html5/infrastructure.html#floating-point-numbers
500
+ number: /^-?(\d*\.)?\d+(e[-+]?\d+)?$/i,
501
+
502
+ integer: /^-?\d+$/,
503
+
504
+ digits: /^\d+$/,
505
+
506
+ alphanum: /^\w+$/i,
507
+
508
+ url: new RegExp("^" +
509
+ // protocol identifier
510
+ "(?:(?:https?|ftp)://)?" + // ** mod: make scheme optional
511
+ // user:pass authentication
512
+ "(?:\\S+(?::\\S*)?@)?" + "(?:" +
513
+ // IP address exclusion
514
+ // private & local networks
515
+ // "(?!(?:10|127)(?:\\.\\d{1,3}){3})" + // ** mod: allow local networks
516
+ // "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" + // ** mod: allow local networks
517
+ // "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" + // ** mod: allow local networks
518
+ // IP address dotted notation octets
519
+ // excludes loopback network 0.0.0.0
520
+ // excludes reserved space >= 224.0.0.0
521
+ // excludes network & broacast addresses
522
+ // (first & last IP address of each class)
523
+ "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" + "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" + "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" + "|" +
524
+ // host name
525
+ '(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)' +
526
+ // domain name
527
+ '(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*' +
528
+ // TLD identifier
529
+ '(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))' + ")" +
530
+ // port number
531
+ "(?::\\d{2,5})?" +
532
+ // resource path
533
+ "(?:/\\S*)?" + "$", 'i')
425
534
  };
426
- /**
427
- * Assert
428
- */
429
- var Assert = function ( group ) {
430
- this.__class__ = 'Assert';
431
- this.__parentClass__ = this.__class__;
432
- this.groups = [];
433
- if ( 'undefined' !== typeof group )
434
- this.addGroup( group );
535
+ typeRegexes.range = typeRegexes.number;
536
+
537
+ // See http://stackoverflow.com/a/10454560/8279
538
+ var decimalPlaces = function decimalPlaces(num) {
539
+ var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
540
+ if (!match) {
541
+ return 0;
542
+ }
543
+ return Math.max(0,
544
+ // Number of digits right of decimal point.
545
+ (match[1] ? match[1].length : 0) - (
546
+ // Adjust for scientific notation.
547
+ match[2] ? +match[2] : 0));
435
548
  };
436
- Assert.prototype = {
437
- construct: Assert,
438
- requiresValidation: function ( group ) {
439
- if ( group && !this.hasGroup( group ) )
440
- return false;
441
- if ( !group && this.hasGroups() )
442
- return false;
443
- return true;
444
- },
445
- check: function ( value, group ) {
446
- if ( !this.requiresValidation( group ) )
447
- return;
448
- try {
449
- return this.validate( value, group );
450
- } catch ( violation ) {
451
- return violation;
452
- }
453
- },
454
- hasGroup: function ( group ) {
455
- if ( _isArray( group ) )
456
- return this.hasOneOf( group );
457
- // All Asserts respond to "Any" group
458
- if ( 'Any' === group )
459
- return true;
460
- // Asserts with no group also respond to "Default" group. Else return false
461
- if ( !this.hasGroups() )
462
- return 'Default' === group;
463
- return -1 !== this.groups.indexOf( group );
464
- },
465
- hasOneOf: function ( groups ) {
466
- for ( var i = 0; i < groups.length; i++ )
467
- if ( this.hasGroup( groups[ i ] ) )
468
- return true;
469
- return false;
470
- },
471
- hasGroups: function () {
472
- return this.groups.length > 0;
473
- },
474
- addGroup: function ( group ) {
475
- if ( _isArray( group ) )
476
- return this.addGroups( group );
477
- if ( !this.hasGroup( group ) )
478
- this.groups.push( group );
479
- return this;
549
+
550
+ ParsleyValidatorRegistry.prototype = {
551
+ init: function init(validators, catalog) {
552
+ this.catalog = catalog;
553
+ // Copy prototype's validators:
554
+ this.validators = $.extend({}, this.validators);
555
+
556
+ for (var name in validators) this.addValidator(name, validators[name].fn, validators[name].priority);
557
+
558
+ window.Parsley.trigger('parsley:validator:init');
480
559
  },
481
- removeGroup: function ( group ) {
482
- var _groups = [];
483
- for ( var i = 0; i < this.groups.length; i++ )
484
- if ( group !== this.groups[ i ] )
485
- _groups.push( this.groups[ i ] );
486
- this.groups = _groups;
560
+
561
+ // Set new messages locale if we have dictionary loaded in ParsleyConfig.i18n
562
+ setLocale: function setLocale(locale) {
563
+ if ('undefined' === typeof this.catalog[locale]) throw new Error(locale + ' is not available in the catalog');
564
+
565
+ this.locale = locale;
566
+
487
567
  return this;
488
568
  },
489
- addGroups: function ( groups ) {
490
- for ( var i = 0; i < groups.length; i++ )
491
- this.addGroup( groups[ i ] );
569
+
570
+ // Add a new messages catalog for a given locale. Set locale for this catalog if set === `true`
571
+ addCatalog: function addCatalog(locale, messages, set) {
572
+ if ('object' === typeof messages) this.catalog[locale] = messages;
573
+
574
+ if (true === set) return this.setLocale(locale);
575
+
492
576
  return this;
493
577
  },
494
- /**
495
- * Asserts definitions
496
- */
497
- HaveProperty: function ( node ) {
498
- this.__class__ = 'HaveProperty';
499
- this.node = node;
500
- this.validate = function ( object ) {
501
- if ( 'undefined' === typeof object[ this.node ] )
502
- throw new Violation( this, object, { value: this.node } );
503
- return true;
504
- };
578
+
579
+ // Add a specific message for a given constraint in a given locale
580
+ addMessage: function addMessage(locale, name, message) {
581
+ if ('undefined' === typeof this.catalog[locale]) this.catalog[locale] = {};
582
+
583
+ this.catalog[locale][name] = message;
584
+
505
585
  return this;
506
586
  },
507
- Blank: function () {
508
- this.__class__ = 'Blank';
509
- this.validate = function ( value ) {
510
- if ( 'string' !== typeof value )
511
- throw new Violation( this, value, { value: Validator.errorCode.must_be_a_string } );
512
- if ( '' !== value.replace( /^\s+/g, '' ).replace( /\s+$/g, '' ) )
513
- throw new Violation( this, value );
514
- return true;
515
- };
587
+
588
+ // Add messages for a given locale
589
+ addMessages: function addMessages(locale, nameMessageObject) {
590
+ for (var name in nameMessageObject) this.addMessage(locale, name, nameMessageObject[name]);
591
+
516
592
  return this;
517
593
  },
518
- Callback: function ( fn ) {
519
- this.__class__ = 'Callback';
520
- this.arguments = Array.prototype.slice.call( arguments );
521
- if ( 1 === this.arguments.length )
522
- this.arguments = [];
523
- else
524
- this.arguments.splice( 0, 1 );
525
- if ( 'function' !== typeof fn )
526
- throw new Error( 'Callback must be instanciated with a function' );
527
- this.fn = fn;
528
- this.validate = function ( value ) {
529
- var result = this.fn.apply( this, [ value ].concat( this.arguments ) );
530
- if ( true !== result )
531
- throw new Violation( this, value, { result: result } );
532
- return true;
533
- };
534
- return this;
594
+
595
+ // Add a new validator
596
+ //
597
+ // addValidator('custom', {
598
+ // requirementType: ['integer', 'integer'],
599
+ // validateString: function(value, from, to) {},
600
+ // priority: 22,
601
+ // messages: {
602
+ // en: "Hey, that's no good",
603
+ // fr: "Aye aye, pas bon du tout",
604
+ // }
605
+ // })
606
+ //
607
+ // Old API was addValidator(name, function, priority)
608
+ //
609
+ addValidator: function addValidator(name, arg1, arg2) {
610
+ if (this.validators[name]) ParsleyUtils__default.warn('Validator "' + name + '" is already defined.');else if (ParsleyDefaults.hasOwnProperty(name)) {
611
+ ParsleyUtils__default.warn('"' + name + '" is a restricted keyword and is not a valid validator name.');
612
+ return;
613
+ }
614
+ return this._setValidator.apply(this, arguments);
535
615
  },
536
- Choice: function ( list ) {
537
- this.__class__ = 'Choice';
538
- if ( !_isArray( list ) && 'function' !== typeof list )
539
- throw new Error( 'Choice must be instanciated with an array or a function' );
540
- this.list = list;
541
- this.validate = function ( value ) {
542
- var list = 'function' === typeof this.list ? this.list() : this.list;
543
- for ( var i = 0; i < list.length; i++ )
544
- if ( value === list[ i ] )
545
- return true;
546
- throw new Violation( this, value, { choices: list } );
547
- };
548
- return this;
616
+
617
+ updateValidator: function updateValidator(name, arg1, arg2) {
618
+ if (!this.validators[name]) {
619
+ ParsleyUtils__default.warn('Validator "' + name + '" is not already defined.');
620
+ return this.addValidator.apply(this, arguments);
621
+ }
622
+ return this._setValidator.apply(this, arguments);
549
623
  },
550
- Collection: function ( assertOrConstraint ) {
551
- this.__class__ = 'Collection';
552
- this.constraint = 'undefined' !== typeof assertOrConstraint ? (assertOrConstraint instanceof Assert ? assertOrConstraint : new Constraint( assertOrConstraint )) : false;
553
- this.validate = function ( collection, group ) {
554
- var result, validator = new Validator(), count = 0, failures = {}, groups = this.groups.length ? this.groups : group;
555
- if ( !_isArray( collection ) )
556
- throw new Violation( this, collection, { value: Validator.errorCode.must_be_an_array } );
557
- for ( var i = 0; i < collection.length; i++ ) {
558
- result = this.constraint ?
559
- validator.validate( collection[ i ], this.constraint, groups ) :
560
- validator.validate( collection[ i ], groups );
561
- if ( !_isEmptyObject( result ) )
562
- failures[ count ] = result;
563
- count++;
564
- }
565
- return !_isEmptyObject( failures ) ? failures : true;
566
- };
624
+
625
+ removeValidator: function removeValidator(name) {
626
+ if (!this.validators[name]) ParsleyUtils__default.warn('Validator "' + name + '" is not defined.');
627
+
628
+ delete this.validators[name];
629
+
567
630
  return this;
568
631
  },
569
- Count: function ( count ) {
570
- this.__class__ = 'Count';
571
- this.count = count;
572
- this.validate = function ( array ) {
573
- if ( !_isArray( array ) )
574
- throw new Violation( this, array, { value: Validator.errorCode.must_be_an_array } );
575
- var count = 'function' === typeof this.count ? this.count( array ) : this.count;
576
- if ( isNaN( Number( count ) ) )
577
- throw new Error( 'Count must be a valid interger', count );
578
- if ( count !== array.length )
579
- throw new Violation( this, array, { count: count } );
580
- return true;
581
- };
632
+
633
+ _setValidator: function _setValidator(name, validator, priority) {
634
+ if ('object' !== typeof validator) {
635
+ // Old style validator, with `fn` and `priority`
636
+ validator = {
637
+ fn: validator,
638
+ priority: priority
639
+ };
640
+ }
641
+ if (!validator.validate) {
642
+ validator = new ParsleyValidator(validator);
643
+ }
644
+ this.validators[name] = validator;
645
+
646
+ for (var locale in validator.messages || {}) this.addMessage(locale, name, validator.messages[locale]);
647
+
582
648
  return this;
583
649
  },
584
- Email: function () {
585
- this.__class__ = 'Email';
586
- this.validate = function ( value ) {
587
- var regExp = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i;
588
- if ( 'string' !== typeof value )
589
- throw new Violation( this, value, { value: Validator.errorCode.must_be_a_string } );
590
- if ( !regExp.test( value ) )
591
- throw new Violation( this, value );
592
- return true;
593
- };
594
- return this;
650
+
651
+ getErrorMessage: function getErrorMessage(constraint) {
652
+ var message;
653
+
654
+ // Type constraints are a bit different, we have to match their requirements too to find right error message
655
+ if ('type' === constraint.name) {
656
+ var typeMessages = this.catalog[this.locale][constraint.name] || {};
657
+ message = typeMessages[constraint.requirements];
658
+ } else message = this.formatMessage(this.catalog[this.locale][constraint.name], constraint.requirements);
659
+
660
+ return message || this.catalog[this.locale].defaultMessage || this.catalog.en.defaultMessage;
595
661
  },
596
- EqualTo: function ( reference ) {
597
- this.__class__ = 'EqualTo';
598
- if ( 'undefined' === typeof reference )
599
- throw new Error( 'EqualTo must be instanciated with a value or a function' );
600
- this.reference = reference;
601
- this.validate = function ( value ) {
602
- var reference = 'function' === typeof this.reference ? this.reference( value ) : this.reference;
603
- if ( reference !== value )
604
- throw new Violation( this, value, { value: reference } );
605
- return true;
606
- };
607
- return this;
662
+
663
+ // Kind of light `sprintf()` implementation
664
+ formatMessage: function formatMessage(string, parameters) {
665
+ if ('object' === typeof parameters) {
666
+ for (var i in parameters) string = this.formatMessage(string, parameters[i]);
667
+
668
+ return string;
669
+ }
670
+
671
+ return 'string' === typeof string ? string.replace(/%s/i, parameters) : '';
608
672
  },
609
- GreaterThan: function ( threshold ) {
610
- this.__class__ = 'GreaterThan';
611
- if ( 'undefined' === typeof threshold )
612
- throw new Error( 'Should give a threshold value' );
613
- this.threshold = threshold;
614
- this.validate = function ( value ) {
615
- if ( '' === value || isNaN( Number( value ) ) )
616
- throw new Violation( this, value, { value: Validator.errorCode.must_be_a_number } );
617
- if ( this.threshold >= value )
618
- throw new Violation( this, value, { threshold: this.threshold } );
619
- return true;
620
- };
621
- return this;
622
- },
623
- GreaterThanOrEqual: function ( threshold ) {
624
- this.__class__ = 'GreaterThanOrEqual';
625
- if ( 'undefined' === typeof threshold )
626
- throw new Error( 'Should give a threshold value' );
627
- this.threshold = threshold;
628
- this.validate = function ( value ) {
629
- if ( '' === value || isNaN( Number( value ) ) )
630
- throw new Violation( this, value, { value: Validator.errorCode.must_be_a_number } );
631
- if ( this.threshold > value )
632
- throw new Violation( this, value, { threshold: this.threshold } );
633
- return true;
634
- };
635
- return this;
636
- },
637
- InstanceOf: function ( classRef ) {
638
- this.__class__ = 'InstanceOf';
639
- if ( 'undefined' === typeof classRef )
640
- throw new Error( 'InstanceOf must be instanciated with a value' );
641
- this.classRef = classRef;
642
- this.validate = function ( value ) {
643
- if ( true !== (value instanceof this.classRef) )
644
- throw new Violation( this, value, { classRef: this.classRef } );
645
- return true;
646
- };
647
- return this;
648
- },
649
- Length: function ( boundaries ) {
650
- this.__class__ = 'Length';
651
- if ( !boundaries.min && !boundaries.max )
652
- throw new Error( 'Lenth assert must be instanciated with a { min: x, max: y } object' );
653
- this.min = boundaries.min;
654
- this.max = boundaries.max;
655
- this.validate = function ( value ) {
656
- if ( 'string' !== typeof value && !_isArray( value ) )
657
- throw new Violation( this, value, { value: Validator.errorCode.must_be_a_string_or_array } );
658
- if ( 'undefined' !== typeof this.min && this.min === this.max && value.length !== this.min )
659
- throw new Violation( this, value, { min: this.min, max: this.max } );
660
- if ( 'undefined' !== typeof this.max && value.length > this.max )
661
- throw new Violation( this, value, { max: this.max } );
662
- if ( 'undefined' !== typeof this.min && value.length < this.min )
663
- throw new Violation( this, value, { min: this.min } );
664
- return true;
665
- };
666
- return this;
667
- },
668
- LessThan: function ( threshold ) {
669
- this.__class__ = 'LessThan';
670
- if ( 'undefined' === typeof threshold )
671
- throw new Error( 'Should give a threshold value' );
672
- this.threshold = threshold;
673
- this.validate = function ( value ) {
674
- if ( '' === value || isNaN( Number( value ) ) )
675
- throw new Violation( this, value, { value: Validator.errorCode.must_be_a_number } );
676
- if ( this.threshold <= value )
677
- throw new Violation( this, value, { threshold: this.threshold } );
678
- return true;
679
- };
680
- return this;
681
- },
682
- LessThanOrEqual: function ( threshold ) {
683
- this.__class__ = 'LessThanOrEqual';
684
- if ( 'undefined' === typeof threshold )
685
- throw new Error( 'Should give a threshold value' );
686
- this.threshold = threshold;
687
- this.validate = function ( value ) {
688
- if ( '' === value || isNaN( Number( value ) ) )
689
- throw new Violation( this, value, { value: Validator.errorCode.must_be_a_number } );
690
- if ( this.threshold < value )
691
- throw new Violation( this, value, { threshold: this.threshold } );
692
- return true;
693
- };
694
- return this;
695
- },
696
- NotNull: function () {
697
- this.__class__ = 'NotNull';
698
- this.validate = function ( value ) {
699
- if ( null === value || 'undefined' === typeof value )
700
- throw new Violation( this, value );
701
- return true;
702
- };
703
- return this;
704
- },
705
- NotBlank: function () {
706
- this.__class__ = 'NotBlank';
707
- this.validate = function ( value ) {
708
- if ( 'string' !== typeof value )
709
- throw new Violation( this, value, { value: Validator.errorCode.must_be_a_string } );
710
- if ( '' === value.replace( /^\s+/g, '' ).replace( /\s+$/g, '' ) )
711
- throw new Violation( this, value );
712
- return true;
713
- };
714
- return this;
715
- },
716
- Null: function () {
717
- this.__class__ = 'Null';
718
- this.validate = function ( value ) {
719
- if ( null !== value )
720
- throw new Violation( this, value );
721
- return true;
722
- };
723
- return this;
724
- },
725
- Range: function ( min, max ) {
726
- this.__class__ = 'Range';
727
- if ( 'undefined' === typeof min || 'undefined' === typeof max )
728
- throw new Error( 'Range assert expects min and max values' );
729
- this.min = min;
730
- this.max = max;
731
- this.validate = function ( value ) {
732
- try {
733
- // validate strings and objects with their Length
734
- if ( ( 'string' === typeof value && isNaN( Number( value ) ) ) || _isArray( value ) )
735
- new Assert().Length( { min: this.min, max: this.max } ).validate( value );
736
- // validate numbers with their value
737
- else
738
- new Assert().GreaterThanOrEqual( this.min ).validate( value ) && new Assert().LessThanOrEqual( this.max ).validate( value );
739
- return true;
740
- } catch ( violation ) {
741
- throw new Violation( this, value, violation.violation );
742
- }
743
- return true;
744
- };
745
- return this;
746
- },
747
- Regexp: function ( regexp, flag ) {
748
- this.__class__ = 'Regexp';
749
- if ( 'undefined' === typeof regexp )
750
- throw new Error( 'You must give a regexp' );
751
- this.regexp = regexp;
752
- this.flag = flag || '';
753
- this.validate = function ( value ) {
754
- if ( 'string' !== typeof value )
755
- throw new Violation( this, value, { value: Validator.errorCode.must_be_a_string } );
756
- if ( !new RegExp( this.regexp, this.flag ).test( value ) )
757
- throw new Violation( this, value, { regexp: this.regexp, flag: this.flag } );
758
- return true;
759
- };
760
- return this;
761
- },
762
- Required: function () {
763
- this.__class__ = 'Required';
764
- this.validate = function ( value ) {
765
- if ( 'undefined' === typeof value )
766
- throw new Violation( this, value );
767
- try {
768
- if ( 'string' === typeof value )
769
- new Assert().NotNull().validate( value ) && new Assert().NotBlank().validate( value );
770
- else if ( true === _isArray( value ) )
771
- new Assert().Length( { min: 1 } ).validate( value );
772
- } catch ( violation ) {
773
- throw new Violation( this, value );
774
- }
775
- return true;
776
- };
777
- return this;
778
- },
779
- // Unique() or Unique ( { key: foo } )
780
- Unique: function ( object ) {
781
- this.__class__ = 'Unique';
782
- if ( 'object' === typeof object )
783
- this.key = object.key;
784
- this.validate = function ( array ) {
785
- var value, store = [];
786
- if ( !_isArray( array ) )
787
- throw new Violation( this, array, { value: Validator.errorCode.must_be_an_array } );
788
- for ( var i = 0; i < array.length; i++ ) {
789
- value = 'object' === typeof array[ i ] ? array[ i ][ this.key ] : array[ i ];
790
- if ( 'undefined' === typeof value )
791
- continue;
792
- if ( -1 !== store.indexOf( value ) )
793
- throw new Violation( this, array, { value: value } );
794
- store.push( value );
795
- }
796
- return true;
797
- };
798
- return this;
799
- }
800
- };
801
- // expose to the world these awesome classes
802
- exports.Assert = Assert;
803
- exports.Validator = Validator;
804
- exports.Violation = Violation;
805
- exports.Constraint = Constraint;
806
- /**
807
- * Some useful object prototypes / functions here
808
- */
809
- // IE8<= compatibility
810
- // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf
811
- if (!Array.prototype.indexOf)
812
- Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
813
-
814
- if (this === null) {
815
- throw new TypeError();
816
- }
817
- var t = Object(this);
818
- var len = t.length >>> 0;
819
- if (len === 0) {
820
- return -1;
821
- }
822
- var n = 0;
823
- if (arguments.length > 1) {
824
- n = Number(arguments[1]);
825
- if (n != n) { // shortcut for verifying if it's NaN
826
- n = 0;
827
- } else if (n !== 0 && n != Infinity && n != -Infinity) {
828
- n = (n > 0 || -1) * Math.floor(Math.abs(n));
829
- }
830
- }
831
- if (n >= len) {
832
- return -1;
833
- }
834
- var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
835
- for (; k < len; k++) {
836
- if (k in t && t[k] === searchElement) {
837
- return k;
838
- }
839
- }
840
- return -1;
841
- };
842
- // Test if object is empty, useful for Constraint violations check
843
- var _isEmptyObject = function ( obj ) {
844
- for ( var property in obj )
845
- return false;
846
- return true;
847
- };
848
- var _isArray = function ( obj ) {
849
- return Object.prototype.toString.call( obj ) === '[object Array]';
850
- };
851
- // AMD export
852
- if ( typeof define === 'function' && define.amd ) {
853
- define( 'vendors/validator.js/dist/validator',[],function() {
854
- return exports;
855
- } );
856
- // commonjs export
857
- } else if ( typeof module !== 'undefined' && module.exports ) {
858
- module.exports = exports;
859
- // browser
860
- } else {
861
- window[ 'undefined' !== typeof validatorjs_ns ? validatorjs_ns : 'Validator' ] = exports;
862
- }
863
673
 
864
- return exports;
865
- } )( );
866
-
867
- // This is needed for Browserify usage that requires Validator.js through module.exports
868
- Validator = 'undefined' !== typeof Validator ? Validator : ('undefined' !== typeof module ? module.exports : null);
869
- var ParsleyValidator = function (validators, catalog) {
870
- this.__class__ = 'ParsleyValidator';
871
- this.Validator = Validator;
872
- // Default Parsley locale is en
873
- this.locale = 'en';
874
- this.init(validators || {}, catalog || {});
875
- };
876
- ParsleyValidator.prototype = {
877
- init: function (validators, catalog) {
878
- this.catalog = catalog;
879
- for (var name in validators)
880
- this.addValidator(name, validators[name].fn, validators[name].priority, validators[name].requirementsTransformer);
881
- $.emit('parsley:validator:init');
882
- },
883
- // Set new messages locale if we have dictionary loaded in ParsleyConfig.i18n
884
- setLocale: function (locale) {
885
- if ('undefined' === typeof this.catalog[locale])
886
- throw new Error(locale + ' is not available in the catalog');
887
- this.locale = locale;
888
- return this;
889
- },
890
- // Add a new messages catalog for a given locale. Set locale for this catalog if set === `true`
891
- addCatalog: function (locale, messages, set) {
892
- if ('object' === typeof messages)
893
- this.catalog[locale] = messages;
894
- if (true === set)
895
- return this.setLocale(locale);
896
- return this;
897
- },
898
- // Add a specific message for a given constraint in a given locale
899
- addMessage: function (locale, name, message) {
900
- if ('undefined' === typeof this.catalog[locale])
901
- this.catalog[locale] = {};
902
- this.catalog[locale][name.toLowerCase()] = message;
903
- return this;
904
- },
905
- validate: function (value, constraints, priority) {
906
- return new this.Validator.Validator().validate.apply(new Validator.Validator(), arguments);
907
- },
908
- // Add a new validator
909
- addValidator: function (name, fn, priority, requirementsTransformer) {
910
- this.validators[name.toLowerCase()] = function (requirements) {
911
- return $.extend(new Validator.Assert().Callback(fn, requirements), {
912
- priority: priority,
913
- requirementsTransformer: requirementsTransformer
914
- });
915
- };
916
- return this;
917
- },
918
- updateValidator: function (name, fn, priority, requirementsTransformer) {
919
- return this.addValidator(name, fn, priority, requirementsTransformer);
920
- },
921
- removeValidator: function (name) {
922
- delete this.validators[name];
923
- return this;
924
- },
925
- getErrorMessage: function (constraint) {
926
- var message;
927
- // Type constraints are a bit different, we have to match their requirements too to find right error message
928
- if ('type' === constraint.name)
929
- message = this.catalog[this.locale][constraint.name][constraint.requirements];
930
- else
931
- message = this.formatMessage(this.catalog[this.locale][constraint.name], constraint.requirements);
932
- return '' !== message ? message : this.catalog[this.locale].defaultMessage;
933
- },
934
- // Kind of light `sprintf()` implementation
935
- formatMessage: function (string, parameters) {
936
- if ('object' === typeof parameters) {
937
- for (var i in parameters)
938
- string = this.formatMessage(string, parameters[i]);
939
- return string;
940
- }
941
- return 'string' === typeof string ? string.replace(new RegExp('%s', 'i'), parameters) : '';
942
- },
943
674
  // Here is the Parsley default validators list.
944
- // This is basically Validatorjs validators, with different API for some of them
945
- // and a Parsley priority set
675
+ // A validator is an object with the following key values:
676
+ // - priority: an integer
677
+ // - requirement: 'string' (default), 'integer', 'number', 'regexp' or an Array of these
678
+ // - validateString, validateMultiple, validateNumber: functions returning `true`, `false` or a promise
679
+ // Alternatively, a validator can be a function that returns such an object
680
+ //
946
681
  validators: {
947
- notblank: function () {
948
- return $.extend(new Validator.Assert().NotBlank(), { priority: 2 });
682
+ notblank: {
683
+ validateString: function validateString(value) {
684
+ return (/\S/.test(value)
685
+ );
686
+ },
687
+ priority: 2
949
688
  },
950
- required: function () {
951
- return $.extend(new Validator.Assert().Required(), { priority: 512 });
689
+ required: {
690
+ validateMultiple: function validateMultiple(values) {
691
+ return values.length > 0;
692
+ },
693
+ validateString: function validateString(value) {
694
+ return (/\S/.test(value)
695
+ );
696
+ },
697
+ priority: 512
952
698
  },
953
- type: function (type) {
954
- var assert;
955
- switch (type) {
956
- case 'email':
957
- assert = new Validator.Assert().Email();
958
- break;
959
- // range type just ensure we have a number here
960
- case 'range':
961
- case 'number':
962
- assert = new Validator.Assert().Regexp('^-?(?:\\d+|\\d{1,3}(?:,\\d{3})+)?(?:\\.\\d+)?$');
963
- break;
964
- case 'integer':
965
- assert = new Validator.Assert().Regexp('^-?\\d+$');
966
- break;
967
- case 'digits':
968
- assert = new Validator.Assert().Regexp('^\\d+$');
969
- break;
970
- case 'alphanum':
971
- assert = new Validator.Assert().Regexp('^\\w+$', 'i');
972
- break;
973
- case 'url':
974
- assert = new Validator.Assert().Regexp('(https?:\\/\\/)?(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,24}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)', 'i');
975
- break;
976
- default:
699
+ type: {
700
+ validateString: function validateString(value, type) {
701
+ var _ref = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
702
+
703
+ var _ref$step = _ref.step;
704
+ var step = _ref$step === undefined ? '1' : _ref$step;
705
+ var _ref$base = _ref.base;
706
+ var base = _ref$base === undefined ? 0 : _ref$base;
707
+
708
+ var regex = typeRegexes[type];
709
+ if (!regex) {
977
710
  throw new Error('validator type `' + type + '` is not supported');
978
- }
979
- return $.extend(assert, { priority: 256 });
711
+ }
712
+ if (!regex.test(value)) return false;
713
+ if ('number' === type) {
714
+ if (!/^any$/i.test(step || '')) {
715
+ var nb = Number(value);
716
+ var decimals = Math.max(decimalPlaces(step), decimalPlaces(base));
717
+ if (decimalPlaces(nb) > decimals) // Value can't have too many decimals
718
+ return false;
719
+ // Be careful of rounding errors by using integers.
720
+ var toInt = function toInt(f) {
721
+ return Math.round(f * Math.pow(10, decimals));
722
+ };
723
+ if ((toInt(nb) - toInt(base)) % toInt(step) != 0) return false;
724
+ }
725
+ }
726
+ return true;
727
+ },
728
+ requirementType: {
729
+ '': 'string',
730
+ step: 'string',
731
+ base: 'number'
732
+ },
733
+ priority: 256
980
734
  },
981
- pattern: function (regexp) {
982
- var flags = '';
983
- // Test if RegExp is literal, if not, nothing to be done, otherwise, we need to isolate flags and pattern
984
- if (!!(/^\/.*\/(?:[gimy]*)$/.test(regexp))) {
985
- // Replace the regexp literal string with the first match group: ([gimy]*)
986
- // If no flag is present, this will be a blank string
987
- flags = regexp.replace(/.*\/([gimy]*)$/, '$1');
988
- // Again, replace the regexp literal string with the first match group:
989
- // everything excluding the opening and closing slashes and the flags
990
- regexp = regexp.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1');
991
- }
992
- return $.extend(new Validator.Assert().Regexp(regexp, flags), { priority: 64 });
735
+ pattern: {
736
+ validateString: function validateString(value, regexp) {
737
+ return regexp.test(value);
738
+ },
739
+ requirementType: 'regexp',
740
+ priority: 64
993
741
  },
994
- minlength: function (value) {
995
- return $.extend(new Validator.Assert().Length({ min: value }), {
996
- priority: 30,
997
- requirementsTransformer: function () {
998
- return 'string' === typeof value && !isNaN(value) ? parseInt(value, 10) : value;
999
- }
1000
- });
742
+ minlength: {
743
+ validateString: function validateString(value, requirement) {
744
+ return value.length >= requirement;
745
+ },
746
+ requirementType: 'integer',
747
+ priority: 30
1001
748
  },
1002
- maxlength: function (value) {
1003
- return $.extend(new Validator.Assert().Length({ max: value }), {
1004
- priority: 30,
1005
- requirementsTransformer: function () {
1006
- return 'string' === typeof value && !isNaN(value) ? parseInt(value, 10) : value;
1007
- }
1008
- });
749
+ maxlength: {
750
+ validateString: function validateString(value, requirement) {
751
+ return value.length <= requirement;
752
+ },
753
+ requirementType: 'integer',
754
+ priority: 30
1009
755
  },
1010
- length: function (array) {
1011
- return $.extend(new Validator.Assert().Length({ min: array[0], max: array[1] }), { priority: 32 });
756
+ length: {
757
+ validateString: function validateString(value, min, max) {
758
+ return value.length >= min && value.length <= max;
759
+ },
760
+ requirementType: ['integer', 'integer'],
761
+ priority: 30
1012
762
  },
1013
- mincheck: function (length) {
1014
- return this.minlength(length);
763
+ mincheck: {
764
+ validateMultiple: function validateMultiple(values, requirement) {
765
+ return values.length >= requirement;
766
+ },
767
+ requirementType: 'integer',
768
+ priority: 30
1015
769
  },
1016
- maxcheck: function (length) {
1017
- return this.maxlength(length);
770
+ maxcheck: {
771
+ validateMultiple: function validateMultiple(values, requirement) {
772
+ return values.length <= requirement;
773
+ },
774
+ requirementType: 'integer',
775
+ priority: 30
1018
776
  },
1019
- check: function (array) {
1020
- return this.length(array);
777
+ check: {
778
+ validateMultiple: function validateMultiple(values, min, max) {
779
+ return values.length >= min && values.length <= max;
780
+ },
781
+ requirementType: ['integer', 'integer'],
782
+ priority: 30
1021
783
  },
1022
- min: function (value) {
1023
- return $.extend(new Validator.Assert().GreaterThanOrEqual(value), {
1024
- priority: 30,
1025
- requirementsTransformer: function () {
1026
- return 'string' === typeof value && !isNaN(value) ? parseInt(value, 10) : value;
1027
- }
1028
- });
784
+ min: {
785
+ validateNumber: function validateNumber(value, requirement) {
786
+ return value >= requirement;
787
+ },
788
+ requirementType: 'number',
789
+ priority: 30
1029
790
  },
1030
- max: function (value) {
1031
- return $.extend(new Validator.Assert().LessThanOrEqual(value), {
1032
- priority: 30,
1033
- requirementsTransformer: function () {
1034
- return 'string' === typeof value && !isNaN(value) ? parseInt(value, 10) : value;
1035
- }
1036
- });
791
+ max: {
792
+ validateNumber: function validateNumber(value, requirement) {
793
+ return value <= requirement;
794
+ },
795
+ requirementType: 'number',
796
+ priority: 30
1037
797
  },
1038
- range: function (array) {
1039
- return $.extend(new Validator.Assert().Range(array[0], array[1]), {
1040
- priority: 32,
1041
- requirementsTransformer: function () {
1042
- for (var i = 0; i < array.length; i++)
1043
- array[i] = 'string' === typeof array[i] && !isNaN(array[i]) ? parseInt(array[i], 10) : array[i];
1044
- return array;
1045
- }
1046
- });
798
+ range: {
799
+ validateNumber: function validateNumber(value, min, max) {
800
+ return value >= min && value <= max;
801
+ },
802
+ requirementType: ['number', 'number'],
803
+ priority: 30
1047
804
  },
1048
- equalto: function (value) {
1049
- return $.extend(new Validator.Assert().EqualTo(value), {
1050
- priority: 256,
1051
- requirementsTransformer: function () {
1052
- return $(value).length ? $(value).val() : value;
1053
- }
1054
- });
805
+ equalto: {
806
+ validateString: function validateString(value, refOrValue) {
807
+ var $reference = $(refOrValue);
808
+ if ($reference.length) return value === $reference.val();else return value === refOrValue;
809
+ },
810
+ priority: 256
1055
811
  }
1056
812
  }
1057
813
  };
1058
814
 
1059
- var ParsleyUI = function (options) {
1060
- this.__class__ = 'ParsleyUI';
815
+ var ParsleyUI = {};
816
+
817
+ var diffResults = function diffResults(newResult, oldResult, deep) {
818
+ var added = [];
819
+ var kept = [];
820
+
821
+ for (var i = 0; i < newResult.length; i++) {
822
+ var found = false;
823
+
824
+ for (var j = 0; j < oldResult.length; j++) if (newResult[i].assert.name === oldResult[j].assert.name) {
825
+ found = true;
826
+ break;
827
+ }
828
+
829
+ if (found) kept.push(newResult[i]);else added.push(newResult[i]);
830
+ }
831
+
832
+ return {
833
+ kept: kept,
834
+ added: added,
835
+ removed: !deep ? diffResults(oldResult, newResult, true).added : []
836
+ };
1061
837
  };
1062
- ParsleyUI.prototype = {
1063
- listen: function () {
1064
- $.listen('parsley:form:init', this, this.setupForm);
1065
- $.listen('parsley:field:init', this, this.setupField);
1066
- $.listen('parsley:field:validated', this, this.reflow);
1067
- $.listen('parsley:form:validated', this, this.focus);
1068
- $.listen('parsley:field:reset', this, this.reset);
1069
- $.listen('parsley:form:destroy', this, this.destroy);
1070
- $.listen('parsley:field:destroy', this, this.destroy);
1071
- return this;
838
+
839
+ ParsleyUI.Form = {
840
+
841
+ _actualizeTriggers: function _actualizeTriggers() {
842
+ var _this2 = this;
843
+
844
+ this.$element.on('submit.Parsley', function (evt) {
845
+ _this2.onSubmitValidate(evt);
846
+ });
847
+ this.$element.on('click.Parsley', ParsleyUtils__default._SubmitSelector, function (evt) {
848
+ _this2.onSubmitButton(evt);
849
+ });
850
+
851
+ // UI could be disabled
852
+ if (false === this.options.uiEnabled) return;
853
+
854
+ this.$element.attr('novalidate', '');
1072
855
  },
1073
- reflow: function (fieldInstance) {
1074
- // If this field has not an active UI (case for multiples) don't bother doing something
1075
- if ('undefined' === typeof fieldInstance._ui || false === fieldInstance._ui.active)
1076
- return;
856
+
857
+ focus: function focus() {
858
+ this._focusedField = null;
859
+
860
+ if (true === this.validationResult || 'none' === this.options.focus) return null;
861
+
862
+ for (var i = 0; i < this.fields.length; i++) {
863
+ var field = this.fields[i];
864
+ if (true !== field.validationResult && field.validationResult.length > 0 && 'undefined' === typeof field.options.noFocus) {
865
+ this._focusedField = field.$element;
866
+ if ('first' === this.options.focus) break;
867
+ }
868
+ }
869
+
870
+ if (null === this._focusedField) return null;
871
+
872
+ return this._focusedField.focus();
873
+ },
874
+
875
+ _destroyUI: function _destroyUI() {
876
+ // Reset all event listeners
877
+ this.$element.off('.Parsley');
878
+ }
879
+
880
+ };
881
+
882
+ ParsleyUI.Field = {
883
+
884
+ _reflowUI: function _reflowUI() {
885
+ this._buildUI();
886
+
887
+ // If this field doesn't have an active UI don't bother doing something
888
+ if (!this._ui) return;
889
+
1077
890
  // Diff between two validation results
1078
- var diff = this._diff(fieldInstance.validationResult, fieldInstance._ui.lastValidationResult);
891
+ var diff = diffResults(this.validationResult, this._ui.lastValidationResult);
892
+
1079
893
  // Then store current validation result for next reflow
1080
- fieldInstance._ui.lastValidationResult = fieldInstance.validationResult;
1081
- // Field have been validated at least once if here. Useful for binded key events...
1082
- fieldInstance._ui.validatedOnce = true;
894
+ this._ui.lastValidationResult = this.validationResult;
895
+
1083
896
  // Handle valid / invalid / none field class
1084
- this.manageStatusClass(fieldInstance);
897
+ this._manageStatusClass();
898
+
1085
899
  // Add, remove, updated errors messages
1086
- this.manageErrorsMessages(fieldInstance, diff);
900
+ this._manageErrorsMessages(diff);
901
+
1087
902
  // Triggers impl
1088
- this.actualizeTriggers(fieldInstance);
903
+ this._actualizeTriggers();
904
+
1089
905
  // If field is not valid for the first time, bind keyup trigger to ease UX and quickly inform user
1090
- if ((diff.kept.length || diff.added.length) && 'undefined' === typeof fieldInstance._ui.failedOnce)
1091
- this.manageFailingFieldTrigger(fieldInstance);
906
+ if ((diff.kept.length || diff.added.length) && !this._failedOnce) {
907
+ this._failedOnce = true;
908
+ this._actualizeTriggers();
909
+ }
1092
910
  },
911
+
1093
912
  // Returns an array of field's error message(s)
1094
- getErrorsMessages: function (fieldInstance) {
913
+ getErrorsMessages: function getErrorsMessages() {
1095
914
  // No error message, field is valid
1096
- if (true === fieldInstance.validationResult)
1097
- return [];
915
+ if (true === this.validationResult) return [];
916
+
1098
917
  var messages = [];
1099
- for (var i = 0; i < fieldInstance.validationResult.length; i++)
1100
- messages.push(this._getErrorMessage(fieldInstance, fieldInstance.validationResult[i].assert));
918
+
919
+ for (var i = 0; i < this.validationResult.length; i++) messages.push(this.validationResult[i].errorMessage || this._getErrorMessage(this.validationResult[i].assert));
920
+
1101
921
  return messages;
1102
922
  },
1103
- manageStatusClass: function (fieldInstance) {
1104
- if (true === fieldInstance.validationResult)
1105
- this._successClass(fieldInstance);
1106
- else if (fieldInstance.validationResult.length > 0)
1107
- this._errorClass(fieldInstance);
1108
- else
1109
- this._resetClass(fieldInstance);
923
+
924
+ // It's a goal of Parsley that this method is no longer required [#1073]
925
+ addError: function addError(name) {
926
+ var _ref2 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
927
+
928
+ var message = _ref2.message;
929
+ var assert = _ref2.assert;
930
+ var _ref2$updateClass = _ref2.updateClass;
931
+ var updateClass = _ref2$updateClass === undefined ? true : _ref2$updateClass;
932
+
933
+ this._buildUI();
934
+ this._addError(name, { message: message, assert: assert });
935
+
936
+ if (updateClass) this._errorClass();
1110
937
  },
1111
- manageErrorsMessages: function (fieldInstance, diff) {
1112
- if ('undefined' !== typeof fieldInstance.options.errorsMessagesDisabled)
1113
- return;
938
+
939
+ // It's a goal of Parsley that this method is no longer required [#1073]
940
+ updateError: function updateError(name) {
941
+ var _ref3 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
942
+
943
+ var message = _ref3.message;
944
+ var assert = _ref3.assert;
945
+ var _ref3$updateClass = _ref3.updateClass;
946
+ var updateClass = _ref3$updateClass === undefined ? true : _ref3$updateClass;
947
+
948
+ this._buildUI();
949
+ this._updateError(name, { message: message, assert: assert });
950
+
951
+ if (updateClass) this._errorClass();
952
+ },
953
+
954
+ // It's a goal of Parsley that this method is no longer required [#1073]
955
+ removeError: function removeError(name) {
956
+ var _ref4 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
957
+
958
+ var _ref4$updateClass = _ref4.updateClass;
959
+ var updateClass = _ref4$updateClass === undefined ? true : _ref4$updateClass;
960
+
961
+ this._buildUI();
962
+ this._removeError(name);
963
+
964
+ // edge case possible here: remove a standard Parsley error that is still failing in this.validationResult
965
+ // but highly improbable cuz' manually removing a well Parsley handled error makes no sense.
966
+ if (updateClass) this._manageStatusClass();
967
+ },
968
+
969
+ _manageStatusClass: function _manageStatusClass() {
970
+ if (this.hasConstraints() && this.needsValidation() && true === this.validationResult) this._successClass();else if (this.validationResult.length > 0) this._errorClass();else this._resetClass();
971
+ },
972
+
973
+ _manageErrorsMessages: function _manageErrorsMessages(diff) {
974
+ if ('undefined' !== typeof this.options.errorsMessagesDisabled) return;
975
+
1114
976
  // Case where we have errorMessage option that configure an unique field error message, regardless failing validators
1115
- if ('undefined' !== typeof fieldInstance.options.errorMessage) {
1116
- if ((diff.added.length || diff.kept.length)) {
1117
- if (0 === fieldInstance._ui.$errorsWrapper.find('.parsley-custom-error-message').length)
1118
- fieldInstance._ui.$errorsWrapper
1119
- .append(
1120
- $(fieldInstance.options.errorTemplate)
1121
- .addClass('parsley-custom-error-message')
1122
- );
1123
- return fieldInstance._ui.$errorsWrapper
1124
- .addClass('filled')
1125
- .find('.parsley-custom-error-message')
1126
- .html(fieldInstance.options.errorMessage);
977
+ if ('undefined' !== typeof this.options.errorMessage) {
978
+ if (diff.added.length || diff.kept.length) {
979
+ this._insertErrorWrapper();
980
+
981
+ if (0 === this._ui.$errorsWrapper.find('.parsley-custom-error-message').length) this._ui.$errorsWrapper.append($(this.options.errorTemplate).addClass('parsley-custom-error-message'));
982
+
983
+ return this._ui.$errorsWrapper.addClass('filled').find('.parsley-custom-error-message').html(this.options.errorMessage);
1127
984
  }
1128
- return fieldInstance._ui.$errorsWrapper
1129
- .removeClass('filled')
1130
- .find('.parsley-custom-error-message')
1131
- .remove();
985
+
986
+ return this._ui.$errorsWrapper.removeClass('filled').find('.parsley-custom-error-message').remove();
1132
987
  }
988
+
1133
989
  // Show, hide, update failing constraints messages
1134
- for (var i = 0; i < diff.removed.length; i++)
1135
- this.removeError(fieldInstance, diff.removed[i].assert.name, true);
1136
- for (i = 0; i < diff.added.length; i++)
1137
- this.addError(fieldInstance, diff.added[i].assert.name, undefined, diff.added[i].assert, true);
1138
- for (i = 0; i < diff.kept.length; i++)
1139
- this.updateError(fieldInstance, diff.kept[i].assert.name, undefined, diff.kept[i].assert, true);
1140
- },
1141
- // TODO: strange API here, intuitive for manual usage with addError(pslyInstance, 'foo', 'bar')
1142
- // but a little bit complex for above internal usage, with forced undefined parameter...
1143
- addError: function (fieldInstance, name, message, assert, doNotUpdateClass) {
1144
- fieldInstance._ui.$errorsWrapper
1145
- .addClass('filled')
1146
- .append(
1147
- $(fieldInstance.options.errorTemplate)
1148
- .addClass('parsley-' + name)
1149
- .html(message || this._getErrorMessage(fieldInstance, assert))
1150
- );
1151
- if (true !== doNotUpdateClass)
1152
- this._errorClass(fieldInstance);
1153
- },
1154
- // Same as above
1155
- updateError: function (fieldInstance, name, message, assert, doNotUpdateClass) {
1156
- fieldInstance._ui.$errorsWrapper
1157
- .addClass('filled')
1158
- .find('.parsley-' + name)
1159
- .html(message || this._getErrorMessage(fieldInstance, assert));
1160
- if (true !== doNotUpdateClass)
1161
- this._errorClass(fieldInstance);
1162
- },
1163
- // Same as above twice
1164
- removeError: function (fieldInstance, name, doNotUpdateClass) {
1165
- fieldInstance._ui.$errorsWrapper
1166
- .removeClass('filled')
1167
- .find('.parsley-' + name)
1168
- .remove();
1169
- // edge case possible here: remove a standard Parsley error that is still failing in fieldInstance.validationResult
1170
- // but highly improbable cuz' manually removing a well Parsley handled error makes no sense.
1171
- if (true !== doNotUpdateClass)
1172
- this.manageStatusClass(fieldInstance);
1173
- },
1174
- focus: function (formInstance) {
1175
- if (true === formInstance.validationResult || 'none' === formInstance.options.focus)
1176
- return formInstance._focusedField = null;
1177
- formInstance._focusedField = null;
1178
- for (var i = 0; i < formInstance.fields.length; i++)
1179
- if (true !== formInstance.fields[i].validationResult && formInstance.fields[i].validationResult.length > 0 && 'undefined' === typeof formInstance.fields[i].options.noFocus) {
1180
- if ('first' === formInstance.options.focus) {
1181
- formInstance._focusedField = formInstance.fields[i].$element;
1182
- return formInstance._focusedField.focus();
1183
- }
1184
- formInstance._focusedField = formInstance.fields[i].$element;
1185
- }
1186
- if (null === formInstance._focusedField)
1187
- return null;
1188
- return formInstance._focusedField.focus();
990
+ for (var i = 0; i < diff.removed.length; i++) this._removeError(diff.removed[i].assert.name);
991
+
992
+ for (i = 0; i < diff.added.length; i++) this._addError(diff.added[i].assert.name, { message: diff.added[i].errorMessage, assert: diff.added[i].assert });
993
+
994
+ for (i = 0; i < diff.kept.length; i++) this._updateError(diff.kept[i].assert.name, { message: diff.kept[i].errorMessage, assert: diff.kept[i].assert });
1189
995
  },
1190
- _getErrorMessage: function (fieldInstance, constraint) {
1191
- var customConstraintErrorMessage = constraint.name + 'Message';
1192
- if ('undefined' !== typeof fieldInstance.options[customConstraintErrorMessage])
1193
- return window.ParsleyValidator.formatMessage(fieldInstance.options[customConstraintErrorMessage], constraint.requirements);
1194
- return window.ParsleyValidator.getErrorMessage(constraint);
1195
- },
1196
- _diff: function (newResult, oldResult, deep) {
1197
- var
1198
- added = [],
1199
- kept = [];
1200
- for (var i = 0; i < newResult.length; i++) {
1201
- var found = false;
1202
- for (var j = 0; j < oldResult.length; j++)
1203
- if (newResult[i].assert.name === oldResult[j].assert.name) {
1204
- found = true;
1205
- break;
1206
- }
1207
- if (found)
1208
- kept.push(newResult[i]);
1209
- else
1210
- added.push(newResult[i]);
1211
- }
1212
- return {
1213
- kept: kept,
1214
- added: added,
1215
- removed: !deep ? this._diff(oldResult, newResult, true).added : []
1216
- };
996
+
997
+ _addError: function _addError(name, _ref5) {
998
+ var message = _ref5.message;
999
+ var assert = _ref5.assert;
1000
+
1001
+ this._insertErrorWrapper();
1002
+ this._ui.$errorsWrapper.addClass('filled').append($(this.options.errorTemplate).addClass('parsley-' + name).html(message || this._getErrorMessage(assert)));
1217
1003
  },
1218
- setupForm: function (formInstance) {
1219
- formInstance.$element.on('submit.Parsley', false, $.proxy(formInstance.onSubmitValidate, formInstance));
1220
- // UI could be disabled
1221
- if (false === formInstance.options.uiEnabled)
1222
- return;
1223
- formInstance.$element.attr('novalidate', '');
1004
+
1005
+ _updateError: function _updateError(name, _ref6) {
1006
+ var message = _ref6.message;
1007
+ var assert = _ref6.assert;
1008
+
1009
+ this._ui.$errorsWrapper.addClass('filled').find('.parsley-' + name).html(message || this._getErrorMessage(assert));
1224
1010
  },
1225
- setupField: function (fieldInstance) {
1226
- var _ui = { active: false };
1227
- // UI could be disabled
1228
- if (false === fieldInstance.options.uiEnabled)
1229
- return;
1230
- _ui.active = true;
1011
+
1012
+ _removeError: function _removeError(name) {
1013
+ this._ui.$errorsWrapper.removeClass('filled').find('.parsley-' + name).remove();
1014
+ },
1015
+
1016
+ _getErrorMessage: function _getErrorMessage(constraint) {
1017
+ var customConstraintErrorMessage = constraint.name + 'Message';
1018
+
1019
+ if ('undefined' !== typeof this.options[customConstraintErrorMessage]) return window.Parsley.formatMessage(this.options[customConstraintErrorMessage], constraint.requirements);
1020
+
1021
+ return window.Parsley.getErrorMessage(constraint);
1022
+ },
1023
+
1024
+ _buildUI: function _buildUI() {
1025
+ // UI could be already built or disabled
1026
+ if (this._ui || false === this.options.uiEnabled) return;
1027
+
1028
+ var _ui = {};
1029
+
1231
1030
  // Give field its Parsley id in DOM
1232
- fieldInstance.$element.attr(fieldInstance.options.namespace + 'id', fieldInstance.__id__);
1233
- /** Generate important UI elements and store them in fieldInstance **/
1031
+ this.$element.attr(this.options.namespace + 'id', this.__id__);
1032
+
1033
+ /** Generate important UI elements and store them in this **/
1234
1034
  // $errorClassHandler is the $element that woul have parsley-error and parsley-success classes
1235
- _ui.$errorClassHandler = this._manageClassHandler(fieldInstance);
1035
+ _ui.$errorClassHandler = this._manageClassHandler();
1036
+
1236
1037
  // $errorsWrapper is a div that would contain the various field errors, it will be appended into $errorsContainer
1237
- _ui.errorsWrapperId = 'parsley-id-' + ('undefined' !== typeof fieldInstance.options.multiple ? 'multiple-' + fieldInstance.options.multiple : fieldInstance.__id__);
1238
- _ui.$errorsWrapper = $(fieldInstance.options.errorsWrapper).attr('id', _ui.errorsWrapperId);
1038
+ _ui.errorsWrapperId = 'parsley-id-' + (this.options.multiple ? 'multiple-' + this.options.multiple : this.__id__);
1039
+ _ui.$errorsWrapper = $(this.options.errorsWrapper).attr('id', _ui.errorsWrapperId);
1040
+
1239
1041
  // ValidationResult UI storage to detect what have changed bwt two validations, and update DOM accordingly
1240
1042
  _ui.lastValidationResult = [];
1241
- _ui.validatedOnce = false;
1242
1043
  _ui.validationInformationVisible = false;
1243
- // Store it in fieldInstance for later
1244
- fieldInstance._ui = _ui;
1245
- // Stops excluded inputs from getting errorContainer added
1246
- if( !fieldInstance.$element.is(fieldInstance.options.excluded) ) {
1247
- /** Mess with DOM now **/
1248
- this._insertErrorWrapper(fieldInstance);
1249
- }
1250
- // Bind triggers first time
1251
- this.actualizeTriggers(fieldInstance);
1044
+
1045
+ // Store it in this for later
1046
+ this._ui = _ui;
1252
1047
  },
1048
+
1253
1049
  // Determine which element will have `parsley-error` and `parsley-success` classes
1254
- _manageClassHandler: function (fieldInstance) {
1050
+ _manageClassHandler: function _manageClassHandler() {
1255
1051
  // An element selector could be passed through DOM with `data-parsley-class-handler=#foo`
1256
- if ('string' === typeof fieldInstance.options.classHandler && $(fieldInstance.options.classHandler).length)
1257
- return $(fieldInstance.options.classHandler);
1052
+ if ('string' === typeof this.options.classHandler && $(this.options.classHandler).length) return $(this.options.classHandler);
1053
+
1258
1054
  // Class handled could also be determined by function given in Parsley options
1259
- var $handler = fieldInstance.options.classHandler(fieldInstance);
1055
+ var $handler = this.options.classHandler.call(this, this);
1056
+
1260
1057
  // If this function returned a valid existing DOM element, go for it
1261
- if ('undefined' !== typeof $handler && $handler.length)
1262
- return $handler;
1263
- // Otherwise, if simple element (input, texatrea, select...) it will perfectly host the classes
1264
- if ('undefined' === typeof fieldInstance.options.multiple || fieldInstance.$element.is('select'))
1265
- return fieldInstance.$element;
1058
+ if ('undefined' !== typeof $handler && $handler.length) return $handler;
1059
+
1060
+ return this._inputHolder();
1061
+ },
1062
+
1063
+ _inputHolder: function _inputHolder() {
1064
+ // if simple element (input, texatrea, select...) it will perfectly host the classes and precede the error container
1065
+ if (!this.options.multiple || this.$element.is('select')) return this.$element;
1066
+
1266
1067
  // But if multiple element (radio, checkbox), that would be their parent
1267
- return fieldInstance.$element.parent();
1068
+ return this.$element.parent();
1268
1069
  },
1269
- _insertErrorWrapper: function (fieldInstance) {
1070
+
1071
+ _insertErrorWrapper: function _insertErrorWrapper() {
1270
1072
  var $errorsContainer;
1271
- if ('string' === typeof fieldInstance.options.errorsContainer) {
1272
- if ($(fieldInstance.options.errorsContainer).length)
1273
- return $(fieldInstance.options.errorsContainer).append(fieldInstance._ui.$errorsWrapper);
1274
- else if (window.console && window.console.warn)
1275
- window.console.warn('The errors container `' + fieldInstance.options.errorsContainer + '` does not exist in DOM');
1276
- }
1277
- else if ('function' === typeof fieldInstance.options.errorsContainer)
1278
- $errorsContainer = fieldInstance.options.errorsContainer(fieldInstance);
1279
- if ('undefined' !== typeof $errorsContainer && $errorsContainer.length)
1280
- return $errorsContainer.append(fieldInstance._ui.$errorsWrapper);
1281
- return 'undefined' === typeof fieldInstance.options.multiple ? fieldInstance.$element.after(fieldInstance._ui.$errorsWrapper) : fieldInstance.$element.parent().after(fieldInstance._ui.$errorsWrapper);
1282
- },
1283
- actualizeTriggers: function (fieldInstance) {
1284
- var $toBind = fieldInstance.$element;
1285
- if (fieldInstance.options.multiple)
1286
- $toBind = $('[' + fieldInstance.options.namespace + 'multiple="' + fieldInstance.options.multiple + '"]')
1287
- // Remove Parsley events already binded on this field
1073
+
1074
+ // Nothing to do if already inserted
1075
+ if (0 !== this._ui.$errorsWrapper.parent().length) return this._ui.$errorsWrapper.parent();
1076
+
1077
+ if ('string' === typeof this.options.errorsContainer) {
1078
+ if ($(this.options.errorsContainer).length) return $(this.options.errorsContainer).append(this._ui.$errorsWrapper);else ParsleyUtils__default.warn('The errors container `' + this.options.errorsContainer + '` does not exist in DOM');
1079
+ } else if ('function' === typeof this.options.errorsContainer) $errorsContainer = this.options.errorsContainer.call(this, this);
1080
+
1081
+ if ('undefined' !== typeof $errorsContainer && $errorsContainer.length) return $errorsContainer.append(this._ui.$errorsWrapper);
1082
+
1083
+ return this._inputHolder().after(this._ui.$errorsWrapper);
1084
+ },
1085
+
1086
+ _actualizeTriggers: function _actualizeTriggers() {
1087
+ var _this3 = this;
1088
+
1089
+ var $toBind = this._findRelated();
1090
+ var trigger;
1091
+
1092
+ // Remove Parsley events already bound on this field
1288
1093
  $toBind.off('.Parsley');
1289
- // If no trigger is set, all good
1290
- if (false === fieldInstance.options.trigger)
1291
- return;
1292
- var triggers = fieldInstance.options.trigger.replace(/^\s+/g , '').replace(/\s+$/g , '');
1293
- if ('' === triggers)
1294
- return;
1295
- // Bind fieldInstance.eventValidate if exists (for parsley.ajax for example), ParsleyUI.eventValidate otherwise
1296
- $toBind.on(
1297
- triggers.split(' ').join('.Parsley ') + '.Parsley',
1298
- $.proxy('function' === typeof fieldInstance.eventValidate ? fieldInstance.eventValidate : this.eventValidate, fieldInstance));
1299
- },
1300
- // Called through $.proxy with fieldInstance. `this` context is ParsleyField
1301
- eventValidate: function(event) {
1302
- // For keyup, keypress, keydown... events that could be a little bit obstrusive
1094
+ if (this._failedOnce) $toBind.on(ParsleyUtils__default.namespaceEvents(this.options.triggerAfterFailure, 'Parsley'), function () {
1095
+ _this3.validate();
1096
+ });else if (trigger = ParsleyUtils__default.namespaceEvents(this.options.trigger, 'Parsley')) {
1097
+ $toBind.on(trigger, function (event) {
1098
+ _this3._eventValidate(event);
1099
+ });
1100
+ }
1101
+ },
1102
+
1103
+ _eventValidate: function _eventValidate(event) {
1104
+ // For keyup, keypress, keydown, input... events that could be a little bit obstrusive
1303
1105
  // do not validate if val length < min threshold on first validation. Once field have been validated once and info
1304
1106
  // about success or failure have been displayed, always validate with this trigger to reflect every yalidation change.
1305
- if (new RegExp('key').test(event.type))
1306
- if (!this._ui.validationInformationVisible && this.getValue().length <= this.options.validationThreshold)
1307
- return;
1308
- this._ui.validatedOnce = true;
1107
+ if (/key|input/.test(event.type)) if (!(this._ui && this._ui.validationInformationVisible) && this.getValue().length <= this.options.validationThreshold) return;
1108
+
1309
1109
  this.validate();
1310
1110
  },
1311
- manageFailingFieldTrigger: function (fieldInstance) {
1312
- fieldInstance._ui.failedOnce = true;
1313
- // Radio and checkboxes fields must bind every field multiple
1314
- if (fieldInstance.options.multiple)
1315
- $('[' + fieldInstance.options.namespace + 'multiple="' + fieldInstance.options.multiple + '"]').each(function () {
1316
- if (!new RegExp('change', 'i').test($(this).parsley().options.trigger || ''))
1317
- return $(this).on('change.ParsleyFailedOnce', false, $.proxy(fieldInstance.validate, fieldInstance));
1318
- });
1319
- // Select case
1320
- if (fieldInstance.$element.is('select'))
1321
- if (!new RegExp('change', 'i').test(fieldInstance.options.trigger || ''))
1322
- return fieldInstance.$element.on('change.ParsleyFailedOnce', false, $.proxy(fieldInstance.validate, fieldInstance));
1323
- // All other inputs fields
1324
- if (!new RegExp('keyup', 'i').test(fieldInstance.options.trigger || ''))
1325
- return fieldInstance.$element.on('keyup.ParsleyFailedOnce', false, $.proxy(fieldInstance.validate, fieldInstance));
1326
- },
1327
- reset: function (parsleyInstance) {
1111
+
1112
+ _resetUI: function _resetUI() {
1328
1113
  // Reset all event listeners
1329
- parsleyInstance.$element.off('.Parsley');
1330
- parsleyInstance.$element.off('.ParsleyFailedOnce');
1114
+ this._failedOnce = false;
1115
+ this._actualizeTriggers();
1116
+
1331
1117
  // Nothing to do if UI never initialized for this field
1332
- if ('undefined' === typeof parsleyInstance._ui)
1333
- return;
1334
- if ('ParsleyForm' === parsleyInstance.__class__)
1335
- return;
1118
+ if ('undefined' === typeof this._ui) return;
1119
+
1336
1120
  // Reset all errors' li
1337
- parsleyInstance._ui.$errorsWrapper
1338
- .removeClass('filled')
1339
- .children()
1340
- .remove();
1121
+ this._ui.$errorsWrapper.removeClass('filled').children().remove();
1122
+
1341
1123
  // Reset validation class
1342
- this._resetClass(parsleyInstance);
1124
+ this._resetClass();
1125
+
1343
1126
  // Reset validation flags and last validation result
1344
- parsleyInstance._ui.validatedOnce = false;
1345
- parsleyInstance._ui.lastValidationResult = [];
1346
- parsleyInstance._ui.validationInformationVisible = false;
1127
+ this._ui.lastValidationResult = [];
1128
+ this._ui.validationInformationVisible = false;
1347
1129
  },
1348
- destroy: function (parsleyInstance) {
1349
- this.reset(parsleyInstance);
1350
- if ('ParsleyForm' === parsleyInstance.__class__)
1351
- return;
1352
- if ('undefined' !== typeof parsleyInstance._ui)
1353
- parsleyInstance._ui.$errorsWrapper.remove();
1354
- delete parsleyInstance._ui;
1355
- },
1356
- _successClass: function (fieldInstance) {
1357
- fieldInstance._ui.validationInformationVisible = true;
1358
- fieldInstance._ui.$errorClassHandler.removeClass(fieldInstance.options.errorClass).addClass(fieldInstance.options.successClass);
1359
- },
1360
- _errorClass: function (fieldInstance) {
1361
- fieldInstance._ui.validationInformationVisible = true;
1362
- fieldInstance._ui.$errorClassHandler.removeClass(fieldInstance.options.successClass).addClass(fieldInstance.options.errorClass);
1130
+
1131
+ _destroyUI: function _destroyUI() {
1132
+ this._resetUI();
1133
+
1134
+ if ('undefined' !== typeof this._ui) this._ui.$errorsWrapper.remove();
1135
+
1136
+ delete this._ui;
1363
1137
  },
1364
- _resetClass: function (fieldInstance) {
1365
- fieldInstance._ui.$errorClassHandler.removeClass(fieldInstance.options.successClass).removeClass(fieldInstance.options.errorClass);
1366
- }
1367
- };
1368
1138
 
1369
- var ParsleyOptionsFactory = function (defaultOptions, globalOptions, userOptions, namespace) {
1370
- this.__class__ = 'OptionsFactory';
1371
- this.__id__ = ParsleyUtils.hash(4);
1372
- this.formOptions = null;
1373
- this.fieldOptions = null;
1374
- this.staticOptions = $.extend(true, {}, defaultOptions, globalOptions, userOptions, { namespace: namespace });
1375
- };
1376
- ParsleyOptionsFactory.prototype = {
1377
- get: function (parsleyInstance) {
1378
- if ('undefined' === typeof parsleyInstance.__class__)
1379
- throw new Error('Parsley Instance expected');
1380
- switch (parsleyInstance.__class__) {
1381
- case 'Parsley':
1382
- return this.staticOptions;
1383
- case 'ParsleyForm':
1384
- return this.getFormOptions(parsleyInstance);
1385
- case 'ParsleyField':
1386
- case 'ParsleyFieldMultiple':
1387
- return this.getFieldOptions(parsleyInstance);
1388
- default:
1389
- throw new Error('Instance ' + parsleyInstance.__class__ + ' is not supported');
1390
- }
1139
+ _successClass: function _successClass() {
1140
+ this._ui.validationInformationVisible = true;
1141
+ this._ui.$errorClassHandler.removeClass(this.options.errorClass).addClass(this.options.successClass);
1142
+ },
1143
+ _errorClass: function _errorClass() {
1144
+ this._ui.validationInformationVisible = true;
1145
+ this._ui.$errorClassHandler.removeClass(this.options.successClass).addClass(this.options.errorClass);
1391
1146
  },
1392
- getFormOptions: function (formInstance) {
1393
- this.formOptions = ParsleyUtils.attr(formInstance.$element, this.staticOptions.namespace);
1394
- // not deep extend, since formOptions is a 1 level deep object
1395
- return $.extend({}, this.staticOptions, this.formOptions);
1396
- },
1397
- getFieldOptions: function (fieldInstance) {
1398
- this.fieldOptions = ParsleyUtils.attr(fieldInstance.$element, this.staticOptions.namespace);
1399
- if (null === this.formOptions && 'undefined' !== typeof fieldInstance.parent)
1400
- this.formOptions = this.getFormOptions(fieldInstance.parent);
1401
- // not deep extend, since formOptions and fieldOptions is a 1 level deep object
1402
- return $.extend({}, this.staticOptions, this.formOptions, this.fieldOptions);
1147
+ _resetClass: function _resetClass() {
1148
+ this._ui.$errorClassHandler.removeClass(this.options.successClass).removeClass(this.options.errorClass);
1403
1149
  }
1404
1150
  };
1405
1151
 
1406
- var ParsleyForm = function (element, OptionsFactory) {
1152
+ var ParsleyForm = function ParsleyForm(element, domOptions, options) {
1407
1153
  this.__class__ = 'ParsleyForm';
1408
- this.__id__ = ParsleyUtils.hash(4);
1409
- if ('OptionsFactory' !== ParsleyUtils.get(OptionsFactory, '__class__'))
1410
- throw new Error('You must give an OptionsFactory instance');
1411
- this.OptionsFactory = OptionsFactory;
1154
+
1412
1155
  this.$element = $(element);
1156
+ this.domOptions = domOptions;
1157
+ this.options = options;
1158
+ this.parent = window.Parsley;
1159
+
1160
+ this.fields = [];
1413
1161
  this.validationResult = null;
1414
- this.options = this.OptionsFactory.get(this);
1415
1162
  };
1163
+
1164
+ var ParsleyForm__statusMapping = { pending: null, resolved: true, rejected: false };
1165
+
1416
1166
  ParsleyForm.prototype = {
1417
- onSubmitValidate: function (event) {
1418
- this.validate(undefined, undefined, event);
1419
- // prevent form submission if validation fails
1420
- if (false === this.validationResult && event instanceof $.Event) {
1421
- event.stopImmediatePropagation();
1422
- event.preventDefault();
1167
+ onSubmitValidate: function onSubmitValidate(event) {
1168
+ var _this4 = this;
1169
+
1170
+ // This is a Parsley generated submit event, do not validate, do not prevent, simply exit and keep normal behavior
1171
+ if (true === event.parsley) return;
1172
+
1173
+ // If we didn't come here through a submit button, use the first one in the form
1174
+ var $submitSource = this._$submitSource || this.$element.find(ParsleyUtils__default._SubmitSelector).first();
1175
+ this._$submitSource = null;
1176
+ this.$element.find('.parsley-synthetic-submit-button').prop('disabled', true);
1177
+ if ($submitSource.is('[formnovalidate]')) return;
1178
+
1179
+ var promise = this.whenValidate({ event: event });
1180
+
1181
+ if ('resolved' === promise.state() && false !== this._trigger('submit')) {
1182
+ // All good, let event go through. We make this distinction because browsers
1183
+ // differ in their handling of `submit` being called from inside a submit event [#1047]
1184
+ } else {
1185
+ // Rejected or pending: cancel this submit
1186
+ event.stopImmediatePropagation();
1187
+ event.preventDefault();
1188
+ if ('pending' === promise.state()) promise.done(function () {
1189
+ _this4._submit($submitSource);
1190
+ });
1191
+ }
1192
+ },
1193
+
1194
+ onSubmitButton: function onSubmitButton(event) {
1195
+ this._$submitSource = $(event.currentTarget);
1196
+ },
1197
+ // internal
1198
+ // _submit submits the form, this time without going through the validations.
1199
+ // Care must be taken to "fake" the actual submit button being clicked.
1200
+ _submit: function _submit($submitSource) {
1201
+ if (false === this._trigger('submit')) return;
1202
+ // Add submit button's data
1203
+ if ($submitSource) {
1204
+ var $synthetic = this.$element.find('.parsley-synthetic-submit-button').prop('disabled', false);
1205
+ if (0 === $synthetic.length) $synthetic = $('<input class="parsley-synthetic-submit-button" type="hidden">').appendTo(this.$element);
1206
+ $synthetic.attr({
1207
+ name: $submitSource.attr('name'),
1208
+ value: $submitSource.attr('value')
1209
+ });
1423
1210
  }
1424
- return this;
1211
+
1212
+ this.$element.trigger($.extend($.Event('submit'), { parsley: true }));
1425
1213
  },
1426
- // @returns boolean
1427
- validate: function (group, force, event) {
1214
+
1215
+ // Performs validation on fields while triggering events.
1216
+ // @returns `true` if all validations succeeds, `false`
1217
+ // if a failure is immediately detected, or `null`
1218
+ // if dependant on a promise.
1219
+ // Consider using `whenValidate` instead.
1220
+ validate: function validate(options) {
1221
+ if (arguments.length >= 1 && !$.isPlainObject(options)) {
1222
+ ParsleyUtils__default.warnOnce('Calling validate on a parsley form without passing arguments as an object is deprecated.');
1223
+
1224
+ var _arguments = _slice.call(arguments);
1225
+
1226
+ var group = _arguments[0];
1227
+ var force = _arguments[1];
1228
+ var event = _arguments[2];
1229
+
1230
+ options = { group: group, force: force, event: event };
1231
+ }
1232
+ return ParsleyForm__statusMapping[this.whenValidate(options).state()];
1233
+ },
1234
+
1235
+ whenValidate: function whenValidate() {
1236
+ var _ParsleyUtils__default$all$done$fail$always,
1237
+ _this5 = this;
1238
+
1239
+ var _ref7 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
1240
+
1241
+ var group = _ref7.group;
1242
+ var force = _ref7.force;
1243
+ var event = _ref7.event;
1244
+
1428
1245
  this.submitEvent = event;
1246
+ if (event) {
1247
+ this.submitEvent = $.extend({}, event, { preventDefault: function preventDefault() {
1248
+ ParsleyUtils__default.warnOnce("Using `this.submitEvent.preventDefault()` is deprecated; instead, call `this.validationResult = false`");
1249
+ _this5.validationResult = false;
1250
+ } });
1251
+ }
1429
1252
  this.validationResult = true;
1430
- var fieldValidationResult = [];
1431
- $.emit('parsley:form:validate', this);
1253
+
1254
+ // fire validate event to eventually modify things before every validation
1255
+ this._trigger('validate');
1256
+
1432
1257
  // Refresh form DOM options and form's fields that could have changed
1433
1258
  this._refreshFields();
1434
- // loop through fields to validate them one by one
1435
- for (var i = 0; i < this.fields.length; i++) {
1436
- // do not validate a field if not the same as given validation group
1437
- if (group && !this._isFieldInGroup(this.fields[i], group))
1438
- continue;
1439
- fieldValidationResult = this.fields[i].validate(force);
1440
- if (true !== fieldValidationResult && fieldValidationResult.length > 0 && this.validationResult)
1441
- this.validationResult = false;
1442
- }
1443
- $.emit('parsley:form:' + (this.validationResult ? 'success' : 'error'), this);
1444
- $.emit('parsley:form:validated', this);
1445
- return this.validationResult;
1259
+
1260
+ var promises = this._withoutReactualizingFormOptions(function () {
1261
+ return $.map(_this5.fields, function (field) {
1262
+ return field.whenValidate({ force: force, group: group });
1263
+ });
1264
+ });
1265
+
1266
+ return (_ParsleyUtils__default$all$done$fail$always = ParsleyUtils__default.all(promises).done(function () {
1267
+ _this5._trigger('success');
1268
+ }).fail(function () {
1269
+ _this5.validationResult = false;
1270
+ _this5.focus();
1271
+ _this5._trigger('error');
1272
+ }).always(function () {
1273
+ _this5._trigger('validated');
1274
+ })).pipe.apply(_ParsleyUtils__default$all$done$fail$always, _toConsumableArray(this._pipeAccordingToValidationResult()));
1446
1275
  },
1447
- // Iterate over refreshed fields, and stop on first failure
1448
- isValid: function (group, force) {
1449
- this._refreshFields();
1450
- for (var i = 0; i < this.fields.length; i++) {
1451
- // do not validate a field if not the same as given validation group
1452
- if (group && !this._isFieldInGroup(this.fields[i], group))
1453
- continue;
1454
- if (false === this.fields[i].isValid(force))
1455
- return false;
1276
+
1277
+ // Iterate over refreshed fields, and stop on first failure.
1278
+ // Returns `true` if all fields are valid, `false` if a failure is detected
1279
+ // or `null` if the result depends on an unresolved promise.
1280
+ // Prefer using `whenValid` instead.
1281
+ isValid: function isValid(options) {
1282
+ if (arguments.length >= 1 && !$.isPlainObject(options)) {
1283
+ ParsleyUtils__default.warnOnce('Calling isValid on a parsley form without passing arguments as an object is deprecated.');
1284
+
1285
+ var _arguments2 = _slice.call(arguments);
1286
+
1287
+ var group = _arguments2[0];
1288
+ var force = _arguments2[1];
1289
+
1290
+ options = { group: group, force: force };
1456
1291
  }
1457
- return true;
1292
+ return ParsleyForm__statusMapping[this.whenValid(options).state()];
1458
1293
  },
1459
- _isFieldInGroup: function (field, group) {
1460
- if(ParsleyUtils.isArray(field.options.group))
1461
- return -1 !== $.inArray(group, field.options.group);
1462
- return field.options.group === group;
1294
+
1295
+ // Iterate over refreshed fields and validate them.
1296
+ // Returns a promise.
1297
+ // A validation that immediately fails will interrupt the validations.
1298
+ whenValid: function whenValid() {
1299
+ var _this6 = this;
1300
+
1301
+ var _ref8 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
1302
+
1303
+ var group = _ref8.group;
1304
+ var force = _ref8.force;
1305
+
1306
+ this._refreshFields();
1307
+
1308
+ var promises = this._withoutReactualizingFormOptions(function () {
1309
+ return $.map(_this6.fields, function (field) {
1310
+ return field.whenValid({ group: group, force: force });
1311
+ });
1312
+ });
1313
+ return ParsleyUtils__default.all(promises);
1463
1314
  },
1464
- _refreshFields: function () {
1315
+
1316
+ _refreshFields: function _refreshFields() {
1465
1317
  return this.actualizeOptions()._bindFields();
1466
1318
  },
1467
- _bindFields: function () {
1468
- var self = this;
1319
+
1320
+ _bindFields: function _bindFields() {
1321
+ var _this7 = this;
1322
+
1323
+ var oldFields = this.fields;
1324
+
1469
1325
  this.fields = [];
1470
1326
  this.fieldsMappedById = {};
1471
- this.$element.find(this.options.inputs).each(function () {
1472
- var fieldInstance = new window.Parsley(this, {}, self);
1473
- // Only add valid and not excluded `ParsleyField` and `ParsleyFieldMultiple` children
1474
- if (('ParsleyField' === fieldInstance.__class__ || 'ParsleyFieldMultiple' === fieldInstance.__class__) && !fieldInstance.$element.is(fieldInstance.options.excluded))
1475
- if ('undefined' === typeof self.fieldsMappedById[fieldInstance.__class__ + '-' + fieldInstance.__id__]) {
1476
- self.fieldsMappedById[fieldInstance.__class__ + '-' + fieldInstance.__id__] = fieldInstance;
1477
- self.fields.push(fieldInstance);
1327
+
1328
+ this._withoutReactualizingFormOptions(function () {
1329
+ _this7.$element.find(_this7.options.inputs).not(_this7.options.excluded).each(function (_, element) {
1330
+ var fieldInstance = new window.Parsley.Factory(element, {}, _this7);
1331
+
1332
+ // Only add valid and not excluded `ParsleyField` and `ParsleyFieldMultiple` children
1333
+ if (('ParsleyField' === fieldInstance.__class__ || 'ParsleyFieldMultiple' === fieldInstance.__class__) && true !== fieldInstance.options.excluded) if ('undefined' === typeof _this7.fieldsMappedById[fieldInstance.__class__ + '-' + fieldInstance.__id__]) {
1334
+ _this7.fieldsMappedById[fieldInstance.__class__ + '-' + fieldInstance.__id__] = fieldInstance;
1335
+ _this7.fields.push(fieldInstance);
1478
1336
  }
1337
+ });
1338
+
1339
+ $.each(ParsleyUtils__default.difference(oldFields, _this7.fields), function (_, field) {
1340
+ field._trigger('reset');
1341
+ });
1479
1342
  });
1480
1343
  return this;
1344
+ },
1345
+
1346
+ // Internal only.
1347
+ // Looping on a form's fields to do validation or similar
1348
+ // will trigger reactualizing options on all of them, which
1349
+ // in turn will reactualize the form's options.
1350
+ // To avoid calling actualizeOptions so many times on the form
1351
+ // for nothing, _withoutReactualizingFormOptions temporarily disables
1352
+ // the method actualizeOptions on this form while `fn` is called.
1353
+ _withoutReactualizingFormOptions: function _withoutReactualizingFormOptions(fn) {
1354
+ var oldActualizeOptions = this.actualizeOptions;
1355
+ this.actualizeOptions = function () {
1356
+ return this;
1357
+ };
1358
+ var result = fn();
1359
+ this.actualizeOptions = oldActualizeOptions;
1360
+ return result;
1361
+ },
1362
+
1363
+ // Internal only.
1364
+ // Shortcut to trigger an event
1365
+ // Returns true iff event is not interrupted and default not prevented.
1366
+ _trigger: function _trigger(eventName) {
1367
+ return this.trigger('form:' + eventName);
1481
1368
  }
1369
+
1482
1370
  };
1483
1371
 
1484
- var ConstraintFactory = function (parsleyField, name, requirements, priority, isDomConstraint) {
1485
- var assert = {};
1486
- if (!new RegExp('ParsleyField').test(ParsleyUtils.get(parsleyField, '__class__')))
1487
- throw new Error('ParsleyField or ParsleyFieldMultiple instance expected');
1488
- if ('function' === typeof window.ParsleyValidator.validators[name])
1489
- assert = window.ParsleyValidator.validators[name](requirements);
1490
- if ('Assert' !== assert.__parentClass__)
1491
- throw new Error('Valid validator expected');
1492
- var getPriority = function () {
1493
- if ('undefined' !== typeof parsleyField.options[name + 'Priority'])
1494
- return parsleyField.options[name + 'Priority'];
1495
- return ParsleyUtils.get(assert, 'priority') || 2;
1496
- };
1497
- priority = priority || getPriority();
1498
- // If validator have a requirementsTransformer, execute it
1499
- if ('function' === typeof assert.requirementsTransformer) {
1500
- requirements = assert.requirementsTransformer();
1501
- // rebuild assert with new requirements
1502
- assert = window.ParsleyValidator.validators[name](requirements);
1503
- }
1504
- return $.extend(assert, {
1372
+ var ConstraintFactory = function ConstraintFactory(parsleyField, name, requirements, priority, isDomConstraint) {
1373
+ if (!/ParsleyField/.test(parsleyField.__class__)) throw new Error('ParsleyField or ParsleyFieldMultiple instance expected');
1374
+
1375
+ var validatorSpec = window.Parsley._validatorRegistry.validators[name];
1376
+ var validator = new ParsleyValidator(validatorSpec);
1377
+
1378
+ $.extend(this, {
1379
+ validator: validator,
1505
1380
  name: name,
1506
1381
  requirements: requirements,
1507
- priority: priority,
1508
- groups: [priority],
1509
- isDomConstraint: isDomConstraint || ParsleyUtils.attr(parsleyField.$element, parsleyField.options.namespace, name)
1382
+ priority: priority || parsleyField.options[name + 'Priority'] || validator.priority,
1383
+ isDomConstraint: true === isDomConstraint
1510
1384
  });
1385
+ this._parseRequirements(parsleyField.options);
1386
+ };
1387
+
1388
+ var capitalize = function capitalize(str) {
1389
+ var cap = str[0].toUpperCase();
1390
+ return cap + str.slice(1);
1391
+ };
1392
+
1393
+ ConstraintFactory.prototype = {
1394
+ validate: function validate(value, instance) {
1395
+ var _validator;
1396
+
1397
+ return (_validator = this.validator).validate.apply(_validator, [value].concat(_toConsumableArray(this.requirementList), [instance]));
1398
+ },
1399
+
1400
+ _parseRequirements: function _parseRequirements(options) {
1401
+ var _this8 = this;
1402
+
1403
+ this.requirementList = this.validator.parseRequirements(this.requirements, function (key) {
1404
+ return options[_this8.name + capitalize(key)];
1405
+ });
1406
+ }
1511
1407
  };
1512
1408
 
1513
- var ParsleyField = function (field, OptionsFactory, parsleyFormInstance) {
1409
+ var ParsleyField = function ParsleyField(field, domOptions, options, parsleyFormInstance) {
1514
1410
  this.__class__ = 'ParsleyField';
1515
- this.__id__ = ParsleyUtils.hash(4);
1411
+
1516
1412
  this.$element = $(field);
1517
- // If we have a parent `ParsleyForm` instance given, use its `OptionsFactory`, and save parent
1413
+
1414
+ // Set parent if we have one
1518
1415
  if ('undefined' !== typeof parsleyFormInstance) {
1519
1416
  this.parent = parsleyFormInstance;
1520
- this.OptionsFactory = this.parent.OptionsFactory;
1521
- this.options = this.OptionsFactory.get(this);
1522
- // Else, take the `Parsley` one
1523
- } else {
1524
- this.OptionsFactory = OptionsFactory;
1525
- this.options = this.OptionsFactory.get(this);
1526
1417
  }
1418
+
1419
+ this.options = options;
1420
+ this.domOptions = domOptions;
1421
+
1527
1422
  // Initialize some properties
1528
1423
  this.constraints = [];
1529
1424
  this.constraintsByName = {};
1530
- this.validationResult = [];
1425
+ this.validationResult = true;
1426
+
1531
1427
  // Bind constraints
1532
1428
  this._bindConstraints();
1533
1429
  };
1430
+
1431
+ var parsley_field__statusMapping = { pending: null, resolved: true, rejected: false };
1432
+
1534
1433
  ParsleyField.prototype = {
1535
1434
  // # Public API
1536
- // Validate field and $.emit some events for mainly `ParsleyUI`
1537
- // @returns validationResult:
1538
- // - `true` if all constraints pass
1539
- // - `[]` if not required field and empty (not validated)
1540
- // - `[Violation, [Violation...]]` if there were validation errors
1541
- validate: function (force) {
1435
+ // Validate field and trigger some events for mainly `ParsleyUI`
1436
+ // @returns `true`, an array of the validators that failed, or
1437
+ // `null` if validation is not finished. Prefer using whenValidate
1438
+ validate: function validate(options) {
1439
+ if (arguments.length >= 1 && !$.isPlainObject(options)) {
1440
+ ParsleyUtils__default.warnOnce('Calling validate on a parsley field without passing arguments as an object is deprecated.');
1441
+ options = { options: options };
1442
+ }
1443
+ var promise = this.whenValidate(options);
1444
+ if (!promise) // If excluded with `group` option
1445
+ return true;
1446
+ switch (promise.state()) {
1447
+ case 'pending':
1448
+ return null;
1449
+ case 'resolved':
1450
+ return true;
1451
+ case 'rejected':
1452
+ return this.validationResult;
1453
+ }
1454
+ },
1455
+
1456
+ // Validate field and trigger some events for mainly `ParsleyUI`
1457
+ // @returns a promise that succeeds only when all validations do
1458
+ // or `undefined` if field is not in the given `group`.
1459
+ whenValidate: function whenValidate() {
1460
+ var _whenValid$always$done$fail$always,
1461
+ _this9 = this;
1462
+
1463
+ var _ref9 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
1464
+
1465
+ var force = _ref9.force;
1466
+ var group = _ref9.group;
1467
+
1468
+ // do not validate a field if not the same as given validation group
1469
+ this.refreshConstraints();
1470
+ if (group && !this._isInGroup(group)) return;
1471
+
1542
1472
  this.value = this.getValue();
1473
+
1543
1474
  // Field Validate event. `this.value` could be altered for custom needs
1544
- $.emit('parsley:field:validate', this);
1545
- $.emit('parsley:field:' + (this.isValid(force, this.value) ? 'success' : 'error'), this);
1546
- // Field validated event. `this.validationResult` could be altered for custom needs too
1547
- $.emit('parsley:field:validated', this);
1548
- return this.validationResult;
1549
- },
1550
- // Just validate field. Do not trigger any event
1551
- // Same @return as `validate()`
1552
- isValid: function (force, value) {
1553
- // Recompute options and rebind constraints to have latest changes
1554
- this.refreshConstraints();
1555
- // Sort priorities to validate more important first
1556
- var priorities = this._getConstraintsSortedPriorities();
1557
- if (0 === priorities.length)
1558
- return this.validationResult = [];
1559
- // Value could be passed as argument, needed to add more power to 'parsley:field:validate'
1560
- if ('undefined' === typeof value || null === value)
1561
- value = this.getValue();
1562
- // If a field is empty and not required, leave it alone, it's just fine
1475
+ this._trigger('validate');
1476
+
1477
+ return (_whenValid$always$done$fail$always = this.whenValid({ force: force, value: this.value, _refreshed: true }).always(function () {
1478
+ _this9._reflowUI();
1479
+ }).done(function () {
1480
+ _this9._trigger('success');
1481
+ }).fail(function () {
1482
+ _this9._trigger('error');
1483
+ }).always(function () {
1484
+ _this9._trigger('validated');
1485
+ })).pipe.apply(_whenValid$always$done$fail$always, _toConsumableArray(this._pipeAccordingToValidationResult()));
1486
+ },
1487
+
1488
+ hasConstraints: function hasConstraints() {
1489
+ return 0 !== this.constraints.length;
1490
+ },
1491
+
1492
+ // An empty optional field does not need validation
1493
+ needsValidation: function needsValidation(value) {
1494
+ if ('undefined' === typeof value) value = this.getValue();
1495
+
1496
+ // If a field is empty and not required, it is valid
1563
1497
  // Except if `data-parsley-validate-if-empty` explicitely added, useful for some custom validators
1564
- if (!value.length && !this._isRequired() && 'undefined' === typeof this.options.validateIfEmpty && true !== force)
1565
- return this.validationResult = [];
1566
- // If we want to validate field against all constraints, just call Validator and let it do the job
1567
- if (false === this.options.priorityEnabled)
1568
- return true === (this.validationResult = this.validateThroughValidator(value, this.constraints, 'Any'));
1569
- // Else, iterate over priorities one by one, and validate related asserts one by one
1570
- for (var i = 0; i < priorities.length; i++)
1571
- if (true !== (this.validationResult = this.validateThroughValidator(value, this.constraints, priorities[i])))
1572
- return false;
1498
+ if (!value.length && !this._isRequired() && 'undefined' === typeof this.options.validateIfEmpty) return false;
1499
+
1573
1500
  return true;
1574
1501
  },
1502
+
1503
+ _isInGroup: function _isInGroup(group) {
1504
+ if ($.isArray(this.options.group)) return -1 !== $.inArray(group, this.options.group);
1505
+ return this.options.group === group;
1506
+ },
1507
+
1508
+ // Just validate field. Do not trigger any event.
1509
+ // Returns `true` iff all constraints pass, `false` if there are failures,
1510
+ // or `null` if the result can not be determined yet (depends on a promise)
1511
+ // See also `whenValid`.
1512
+ isValid: function isValid(options) {
1513
+ if (arguments.length >= 1 && !$.isPlainObject(options)) {
1514
+ ParsleyUtils__default.warnOnce('Calling isValid on a parsley field without passing arguments as an object is deprecated.');
1515
+
1516
+ var _arguments3 = _slice.call(arguments);
1517
+
1518
+ var force = _arguments3[0];
1519
+ var value = _arguments3[1];
1520
+
1521
+ options = { force: force, value: value };
1522
+ }
1523
+ var promise = this.whenValid(options);
1524
+ if (!promise) // Excluded via `group`
1525
+ return true;
1526
+ return parsley_field__statusMapping[promise.state()];
1527
+ },
1528
+
1529
+ // Just validate field. Do not trigger any event.
1530
+ // @returns a promise that succeeds only when all validations do
1531
+ // or `undefined` if the field is not in the given `group`.
1532
+ // The argument `force` will force validation of empty fields.
1533
+ // If a `value` is given, it will be validated instead of the value of the input.
1534
+ whenValid: function whenValid() {
1535
+ var _this10 = this;
1536
+
1537
+ var _ref10 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
1538
+
1539
+ var _ref10$force = _ref10.force;
1540
+ var force = _ref10$force === undefined ? false : _ref10$force;
1541
+ var value = _ref10.value;
1542
+ var group = _ref10.group;
1543
+ var _refreshed = _ref10._refreshed;
1544
+
1545
+ // Recompute options and rebind constraints to have latest changes
1546
+ if (!_refreshed) this.refreshConstraints();
1547
+ // do not validate a field if not the same as given validation group
1548
+ if (group && !this._isInGroup(group)) return;
1549
+
1550
+ this.validationResult = true;
1551
+
1552
+ // A field without constraint is valid
1553
+ if (!this.hasConstraints()) return $.when();
1554
+
1555
+ // Value could be passed as argument, needed to add more power to 'field:validate'
1556
+ if ('undefined' === typeof value || null === value) value = this.getValue();
1557
+
1558
+ if (!this.needsValidation(value) && true !== force) return $.when();
1559
+
1560
+ var groupedConstraints = this._getGroupedConstraints();
1561
+ var promises = [];
1562
+ $.each(groupedConstraints, function (_, constraints) {
1563
+ // Process one group of constraints at a time, we validate the constraints
1564
+ // and combine the promises together.
1565
+ var promise = ParsleyUtils__default.all($.map(constraints, function (constraint) {
1566
+ return _this10._validateConstraint(value, constraint);
1567
+ }));
1568
+ promises.push(promise);
1569
+ if (promise.state() === 'rejected') return false; // Interrupt processing if a group has already failed
1570
+ });
1571
+ return ParsleyUtils__default.all(promises);
1572
+ },
1573
+
1574
+ // @returns a promise
1575
+ _validateConstraint: function _validateConstraint(value, constraint) {
1576
+ var _this11 = this;
1577
+
1578
+ var result = constraint.validate(value, this);
1579
+ // Map false to a failed promise
1580
+ if (false === result) result = $.Deferred().reject();
1581
+ // Make sure we return a promise and that we record failures
1582
+ return ParsleyUtils__default.all([result]).fail(function (errorMessage) {
1583
+ if (!(_this11.validationResult instanceof Array)) _this11.validationResult = [];
1584
+ _this11.validationResult.push({
1585
+ assert: constraint,
1586
+ errorMessage: 'string' === typeof errorMessage && errorMessage
1587
+ });
1588
+ });
1589
+ },
1590
+
1575
1591
  // @returns Parsley field computed value that could be overrided or configured in DOM
1576
- getValue: function () {
1592
+ getValue: function getValue() {
1577
1593
  var value;
1578
- // Value could be overriden in DOM
1579
- if ('undefined' !== typeof this.options.value)
1580
- value = this.options.value;
1581
- else
1582
- value = this.$element.val();
1594
+
1595
+ // Value could be overriden in DOM or with explicit options
1596
+ if ('function' === typeof this.options.value) value = this.options.value(this);else if ('undefined' !== typeof this.options.value) value = this.options.value;else value = this.$element.val();
1597
+
1583
1598
  // Handle wrong DOM or configurations
1584
- if ('undefined' === typeof value || null === value)
1585
- return '';
1586
- // Use `data-parsley-trim-value="true"` to auto trim inputs entry
1587
- if (true === this.options.trimValue)
1588
- return value.replace(/^\s+|\s+$/g, '');
1589
- return value;
1599
+ if ('undefined' === typeof value || null === value) return '';
1600
+
1601
+ return this._handleWhitespace(value);
1590
1602
  },
1603
+
1591
1604
  // Actualize options that could have change since previous validation
1592
1605
  // Re-bind accordingly constraints (could be some new, removed or updated)
1593
- refreshConstraints: function () {
1606
+ refreshConstraints: function refreshConstraints() {
1594
1607
  return this.actualizeOptions()._bindConstraints();
1595
1608
  },
1609
+
1596
1610
  /**
1597
1611
  * Add a new constraint to a field
1598
1612
  *
1599
- * @method addConstraint
1600
1613
  * @param {String} name
1601
1614
  * @param {Mixed} requirements optional
1602
1615
  * @param {Number} priority optional
1603
1616
  * @param {Boolean} isDomConstraint optional
1604
1617
  */
1605
- addConstraint: function (name, requirements, priority, isDomConstraint) {
1606
- name = name.toLowerCase();
1607
- if ('function' === typeof window.ParsleyValidator.validators[name]) {
1618
+ addConstraint: function addConstraint(name, requirements, priority, isDomConstraint) {
1619
+
1620
+ if (window.Parsley._validatorRegistry.validators[name]) {
1608
1621
  var constraint = new ConstraintFactory(this, name, requirements, priority, isDomConstraint);
1622
+
1609
1623
  // if constraint already exist, delete it and push new version
1610
- if ('undefined' !== this.constraintsByName[constraint.name])
1611
- this.removeConstraint(constraint.name);
1624
+ if ('undefined' !== this.constraintsByName[constraint.name]) this.removeConstraint(constraint.name);
1625
+
1612
1626
  this.constraints.push(constraint);
1613
1627
  this.constraintsByName[constraint.name] = constraint;
1614
1628
  }
1629
+
1615
1630
  return this;
1616
1631
  },
1632
+
1617
1633
  // Remove a constraint
1618
- removeConstraint: function (name) {
1619
- for (var i = 0; i < this.constraints.length; i++)
1620
- if (name === this.constraints[i].name) {
1621
- this.constraints.splice(i, 1);
1622
- break;
1623
- }
1634
+ removeConstraint: function removeConstraint(name) {
1635
+ for (var i = 0; i < this.constraints.length; i++) if (name === this.constraints[i].name) {
1636
+ this.constraints.splice(i, 1);
1637
+ break;
1638
+ }
1624
1639
  delete this.constraintsByName[name];
1625
1640
  return this;
1626
1641
  },
1642
+
1627
1643
  // Update a constraint (Remove + re-add)
1628
- updateConstraint: function (name, parameters, priority) {
1629
- return this.removeConstraint(name)
1630
- .addConstraint(name, parameters, priority);
1644
+ updateConstraint: function updateConstraint(name, parameters, priority) {
1645
+ return this.removeConstraint(name).addConstraint(name, parameters, priority);
1631
1646
  },
1647
+
1632
1648
  // # Internals
1649
+
1633
1650
  // Internal only.
1634
1651
  // Bind constraints from config + options + DOM
1635
- _bindConstraints: function () {
1636
- var constraints = [], constraintsByName = {};
1652
+ _bindConstraints: function _bindConstraints() {
1653
+ var constraints = [];
1654
+ var constraintsByName = {};
1655
+
1637
1656
  // clean all existing DOM constraints to only keep javascript user constraints
1638
- for (var i = 0; i < this.constraints.length; i++)
1639
- if (false === this.constraints[i].isDomConstraint) {
1640
- constraints.push(this.constraints[i]);
1641
- constraintsByName[this.constraints[i].name] = this.constraints[i];
1642
- }
1657
+ for (var i = 0; i < this.constraints.length; i++) if (false === this.constraints[i].isDomConstraint) {
1658
+ constraints.push(this.constraints[i]);
1659
+ constraintsByName[this.constraints[i].name] = this.constraints[i];
1660
+ }
1661
+
1643
1662
  this.constraints = constraints;
1644
1663
  this.constraintsByName = constraintsByName;
1664
+
1645
1665
  // then re-add Parsley DOM-API constraints
1646
- for (var name in this.options)
1647
- this.addConstraint(name, this.options[name]);
1666
+ for (var name in this.options) this.addConstraint(name, this.options[name], undefined, true);
1667
+
1648
1668
  // finally, bind special HTML5 constraints
1649
1669
  return this._bindHtml5Constraints();
1650
1670
  },
1671
+
1651
1672
  // Internal only.
1652
1673
  // Bind specific HTML5 constraints to be HTML5 compliant
1653
- _bindHtml5Constraints: function () {
1674
+ _bindHtml5Constraints: function _bindHtml5Constraints() {
1654
1675
  // html5 required
1655
- if (this.$element.hasClass('required') || this.$element.attr('required'))
1656
- this.addConstraint('required', true, undefined, true);
1676
+ if (this.$element.hasClass('required') || this.$element.attr('required')) this.addConstraint('required', true, undefined, true);
1677
+
1657
1678
  // html5 pattern
1658
- if ('string' === typeof this.$element.attr('pattern'))
1659
- this.addConstraint('pattern', this.$element.attr('pattern'), undefined, true);
1679
+ if ('string' === typeof this.$element.attr('pattern')) this.addConstraint('pattern', this.$element.attr('pattern'), undefined, true);
1680
+
1660
1681
  // range
1661
- if ('undefined' !== typeof this.$element.attr('min') && 'undefined' !== typeof this.$element.attr('max'))
1662
- this.addConstraint('range', [this.$element.attr('min'), this.$element.attr('max')], undefined, true);
1682
+ if ('undefined' !== typeof this.$element.attr('min') && 'undefined' !== typeof this.$element.attr('max')) this.addConstraint('range', [this.$element.attr('min'), this.$element.attr('max')], undefined, true);
1683
+
1663
1684
  // HTML5 min
1664
- else if ('undefined' !== typeof this.$element.attr('min'))
1665
- this.addConstraint('min', this.$element.attr('min'), undefined, true);
1666
- // HTML5 max
1667
- else if ('undefined' !== typeof this.$element.attr('max'))
1668
- this.addConstraint('max', this.$element.attr('max'), undefined, true);
1669
-
1685
+ else if ('undefined' !== typeof this.$element.attr('min')) this.addConstraint('min', this.$element.attr('min'), undefined, true);
1686
+
1687
+ // HTML5 max
1688
+ else if ('undefined' !== typeof this.$element.attr('max')) this.addConstraint('max', this.$element.attr('max'), undefined, true);
1689
+
1670
1690
  // length
1671
- if ('undefined' !== typeof this.$element.attr('minlength') && 'undefined' !== typeof this.$element.attr('maxlength'))
1672
- this.addConstraint('length', [this.$element.attr('minlength'), this.$element.attr('maxlength')], undefined, true);
1691
+ if ('undefined' !== typeof this.$element.attr('minlength') && 'undefined' !== typeof this.$element.attr('maxlength')) this.addConstraint('length', [this.$element.attr('minlength'), this.$element.attr('maxlength')], undefined, true);
1692
+
1673
1693
  // HTML5 minlength
1674
- else if ('undefined' !== typeof this.$element.attr('minlength'))
1675
- this.addConstraint('minlength', this.$element.attr('minlength'), undefined, true);
1676
- // HTML5 maxlength
1677
- else if ('undefined' !== typeof this.$element.attr('maxlength'))
1678
- this.addConstraint('maxlength', this.$element.attr('maxlength'), undefined, true);
1694
+ else if ('undefined' !== typeof this.$element.attr('minlength')) this.addConstraint('minlength', this.$element.attr('minlength'), undefined, true);
1695
+
1696
+ // HTML5 maxlength
1697
+ else if ('undefined' !== typeof this.$element.attr('maxlength')) this.addConstraint('maxlength', this.$element.attr('maxlength'), undefined, true);
1679
1698
 
1680
1699
  // html5 types
1681
1700
  var type = this.$element.attr('type');
1682
- if ('undefined' === typeof type)
1683
- return this;
1701
+
1702
+ if ('undefined' === typeof type) return this;
1703
+
1684
1704
  // Small special case here for HTML5 number: integer validator if step attribute is undefined or an integer value, number otherwise
1685
1705
  if ('number' === type) {
1686
- if (('undefined' === typeof this.$element.attr('step')) || (0 === parseFloat(this.$element.attr('step')) % 1)) {
1687
- return this.addConstraint('type', 'integer', undefined, true);
1688
- } else {
1689
- return this.addConstraint('type', 'number', undefined, true);
1706
+ return this.addConstraint('type', ['number', {
1707
+ step: this.$element.attr('step'),
1708
+ base: this.$element.attr('min') || this.$element.attr('value')
1709
+ }], undefined, true);
1710
+ // Regular other HTML5 supported types
1711
+ } else if (/^(email|url|range)$/i.test(type)) {
1712
+ return this.addConstraint('type', type, undefined, true);
1690
1713
  }
1691
- // Regular other HTML5 supported types
1692
- } else if (new RegExp(type, 'i').test('email url range')) {
1693
- return this.addConstraint('type', type, undefined, true);
1694
- }
1695
1714
  return this;
1696
1715
  },
1716
+
1697
1717
  // Internal only.
1698
1718
  // Field is required if have required constraint without `false` value
1699
- _isRequired: function () {
1700
- if ('undefined' === typeof this.constraintsByName.required)
1701
- return false;
1719
+ _isRequired: function _isRequired() {
1720
+ if ('undefined' === typeof this.constraintsByName.required) return false;
1721
+
1702
1722
  return false !== this.constraintsByName.required.requirements;
1703
1723
  },
1724
+
1725
+ // Internal only.
1726
+ // Shortcut to trigger an event
1727
+ _trigger: function _trigger(eventName) {
1728
+ return this.trigger('field:' + eventName);
1729
+ },
1730
+
1731
+ // Internal only
1732
+ // Handles whitespace in a value
1733
+ // Use `data-parsley-whitespace="squish"` to auto squish input value
1734
+ // Use `data-parsley-whitespace="trim"` to auto trim input value
1735
+ _handleWhitespace: function _handleWhitespace(value) {
1736
+ if (true === this.options.trimValue) ParsleyUtils__default.warnOnce('data-parsley-trim-value="true" is deprecated, please use data-parsley-whitespace="trim"');
1737
+
1738
+ if ('squish' === this.options.whitespace) value = value.replace(/\s{2,}/g, ' ');
1739
+
1740
+ if ('trim' === this.options.whitespace || 'squish' === this.options.whitespace || true === this.options.trimValue) value = ParsleyUtils__default.trimString(value);
1741
+
1742
+ return value;
1743
+ },
1744
+
1704
1745
  // Internal only.
1705
- // Sort constraints by priority DESC
1706
- _getConstraintsSortedPriorities: function () {
1707
- var priorities = [];
1746
+ // Returns the constraints, grouped by descending priority.
1747
+ // The result is thus an array of arrays of constraints.
1748
+ _getGroupedConstraints: function _getGroupedConstraints() {
1749
+ if (false === this.options.priorityEnabled) return [this.constraints];
1750
+
1751
+ var groupedConstraints = [];
1752
+ var index = {};
1753
+
1708
1754
  // Create array unique of priorities
1709
- for (var i = 0; i < this.constraints.length; i++)
1710
- if (-1 === priorities.indexOf(this.constraints[i].priority))
1711
- priorities.push(this.constraints[i].priority);
1755
+ for (var i = 0; i < this.constraints.length; i++) {
1756
+ var p = this.constraints[i].priority;
1757
+ if (!index[p]) groupedConstraints.push(index[p] = []);
1758
+ index[p].push(this.constraints[i]);
1759
+ }
1712
1760
  // Sort them by priority DESC
1713
- priorities.sort(function (a, b) { return b - a; });
1714
- return priorities;
1761
+ groupedConstraints.sort(function (a, b) {
1762
+ return b[0].priority - a[0].priority;
1763
+ });
1764
+
1765
+ return groupedConstraints;
1715
1766
  }
1767
+
1716
1768
  };
1717
1769
 
1718
- var ParsleyMultiple = function () {
1770
+ var parsley_field = ParsleyField;
1771
+
1772
+ var ParsleyMultiple = function ParsleyMultiple() {
1719
1773
  this.__class__ = 'ParsleyFieldMultiple';
1720
1774
  };
1775
+
1721
1776
  ParsleyMultiple.prototype = {
1722
1777
  // Add new `$element` sibling for multiple field
1723
- addElement: function ($element) {
1778
+ addElement: function addElement($element) {
1724
1779
  this.$elements.push($element);
1780
+
1725
1781
  return this;
1726
1782
  },
1783
+
1727
1784
  // See `ParsleyField.refreshConstraints()`
1728
- refreshConstraints: function () {
1785
+ refreshConstraints: function refreshConstraints() {
1729
1786
  var fieldConstraints;
1787
+
1730
1788
  this.constraints = [];
1789
+
1731
1790
  // Select multiple special treatment
1732
1791
  if (this.$element.is('select')) {
1733
1792
  this.actualizeOptions()._bindConstraints();
1793
+
1734
1794
  return this;
1735
1795
  }
1796
+
1736
1797
  // Gather all constraints for each input in the multiple group
1737
1798
  for (var i = 0; i < this.$elements.length; i++) {
1799
+
1738
1800
  // Check if element have not been dynamically removed since last binding
1739
1801
  if (!$('html').has(this.$elements[i]).length) {
1740
1802
  this.$elements.splice(i, 1);
1741
1803
  continue;
1742
1804
  }
1805
+
1743
1806
  fieldConstraints = this.$elements[i].data('ParsleyFieldMultiple').refreshConstraints().constraints;
1744
- for (var j = 0; j < fieldConstraints.length; j++)
1745
- this.addConstraint(fieldConstraints[j].name, fieldConstraints[j].requirements, fieldConstraints[j].priority, fieldConstraints[j].isDomConstraint);
1807
+
1808
+ for (var j = 0; j < fieldConstraints.length; j++) this.addConstraint(fieldConstraints[j].name, fieldConstraints[j].requirements, fieldConstraints[j].priority, fieldConstraints[j].isDomConstraint);
1746
1809
  }
1810
+
1747
1811
  return this;
1748
1812
  },
1813
+
1749
1814
  // See `ParsleyField.getValue()`
1750
- getValue: function () {
1815
+ getValue: function getValue() {
1751
1816
  // Value could be overriden in DOM
1752
- if ('undefined' !== typeof this.options.value)
1753
- return this.options.value;
1817
+ if ('function' === typeof this.options.value) return this.options.value(this);else if ('undefined' !== typeof this.options.value) return this.options.value;
1818
+
1754
1819
  // Radio input case
1755
- if (this.$element.is('input[type=radio]'))
1756
- return $('[' + this.options.namespace + 'multiple="' + this.options.multiple + '"]:checked').val() || '';
1820
+ if (this.$element.is('input[type=radio]')) return this._findRelated().filter(':checked').val() || '';
1821
+
1757
1822
  // checkbox input case
1758
1823
  if (this.$element.is('input[type=checkbox]')) {
1759
1824
  var values = [];
1760
- $('[' + this.options.namespace + 'multiple="' + this.options.multiple + '"]:checked').each(function () {
1825
+
1826
+ this._findRelated().filter(':checked').each(function () {
1761
1827
  values.push($(this).val());
1762
1828
  });
1763
- return values.length ? values : [];
1829
+
1830
+ return values;
1764
1831
  }
1832
+
1765
1833
  // Select multiple case
1766
- if (this.$element.is('select') && null === this.$element.val())
1767
- return [];
1834
+ if (this.$element.is('select') && null === this.$element.val()) return [];
1835
+
1768
1836
  // Default case that should never happen
1769
1837
  return this.$element.val();
1770
1838
  },
1771
- _init: function (multiple) {
1839
+
1840
+ _init: function _init() {
1772
1841
  this.$elements = [this.$element];
1773
- this.options.multiple = multiple;
1842
+
1774
1843
  return this;
1775
1844
  }
1776
1845
  };
1777
1846
 
1778
- var
1779
- o = $({}),
1780
- subscribed = {};
1781
- // $.listen(name, callback);
1782
- // $.listen(name, context, callback);
1783
- $.listen = function (name) {
1784
- if ('undefined' === typeof subscribed[name])
1785
- subscribed[name] = [];
1786
- if ('function' === typeof arguments[1])
1787
- return subscribed[name].push({ fn: arguments[1] });
1788
- if ('object' === typeof arguments[1] && 'function' === typeof arguments[2])
1789
- return subscribed[name].push({ fn: arguments[2], ctxt: arguments[1] });
1790
- throw new Error('Wrong parameters');
1791
- };
1792
- $.listenTo = function (instance, name, fn) {
1793
- if ('undefined' === typeof subscribed[name])
1794
- subscribed[name] = [];
1795
- if (!(instance instanceof ParsleyField) && !(instance instanceof ParsleyForm))
1796
- throw new Error('Must give Parsley instance');
1797
- if ('string' !== typeof name || 'function' !== typeof fn)
1798
- throw new Error('Wrong parameters');
1799
- subscribed[name].push({ instance: instance, fn: fn });
1800
- };
1801
- $.unsubscribe = function (name, fn) {
1802
- if ('undefined' === typeof subscribed[name])
1803
- return;
1804
- if ('string' !== typeof name || 'function' !== typeof fn)
1805
- throw new Error('Wrong arguments');
1806
- for (var i = 0; i < subscribed[name].length; i++)
1807
- if (subscribed[name][i].fn === fn)
1808
- return subscribed[name].splice(i, 1);
1809
- };
1810
- $.unsubscribeTo = function (instance, name) {
1811
- if ('undefined' === typeof subscribed[name])
1812
- return;
1813
- if (!(instance instanceof ParsleyField) && !(instance instanceof ParsleyForm))
1814
- throw new Error('Must give Parsley instance');
1815
- for (var i = 0; i < subscribed[name].length; i++)
1816
- if ('undefined' !== typeof subscribed[name][i].instance && subscribed[name][i].instance.__id__ === instance.__id__)
1817
- return subscribed[name].splice(i, 1);
1818
- };
1819
- $.unsubscribeAll = function (name) {
1820
- if ('undefined' === typeof subscribed[name])
1821
- return;
1822
- delete subscribed[name];
1823
- };
1824
- // $.emit(name [, arguments...]);
1825
- // $.emit(name, instance [, arguments...]);
1826
- $.emit = function (name, instance) {
1827
- if ('undefined' === typeof subscribed[name])
1828
- return;
1829
- // loop through registered callbacks for this event
1830
- for (var i = 0; i < subscribed[name].length; i++) {
1831
- // if instance is not registered, simple emit
1832
- if ('undefined' === typeof subscribed[name][i].instance) {
1833
- subscribed[name][i].fn.apply('undefined' !== typeof subscribed[name][i].ctxt ? subscribed[name][i].ctxt : o, Array.prototype.slice.call(arguments, 1));
1834
- continue;
1847
+ var ParsleyFactory = function ParsleyFactory(element, options, parsleyFormInstance) {
1848
+ this.$element = $(element);
1849
+
1850
+ // If the element has already been bound, returns its saved Parsley instance
1851
+ var savedparsleyFormInstance = this.$element.data('Parsley');
1852
+ if (savedparsleyFormInstance) {
1853
+
1854
+ // If the saved instance has been bound without a ParsleyForm parent and there is one given in this call, add it
1855
+ if ('undefined' !== typeof parsleyFormInstance && savedparsleyFormInstance.parent === window.Parsley) {
1856
+ savedparsleyFormInstance.parent = parsleyFormInstance;
1857
+ savedparsleyFormInstance._resetOptions(savedparsleyFormInstance.options);
1835
1858
  }
1836
- // if instance registered but no instance given for the emit, continue
1837
- if (!(instance instanceof ParsleyField) && !(instance instanceof ParsleyForm))
1838
- continue;
1839
- // if instance is registered and same id, emit
1840
- if (subscribed[name][i].instance.__id__ === instance.__id__) {
1841
- subscribed[name][i].fn.apply(o, Array.prototype.slice.call(arguments, 1));
1842
- continue;
1859
+
1860
+ if ('object' === typeof options) {
1861
+ $.extend(savedparsleyFormInstance.options, options);
1843
1862
  }
1844
- // if registered instance is a Form and fired one is a Field, loop over all its fields and emit if field found
1845
- if (subscribed[name][i].instance instanceof ParsleyForm && instance instanceof ParsleyField)
1846
- for (var j = 0; j < subscribed[name][i].instance.fields.length; j++)
1847
- if (subscribed[name][i].instance.fields[j].__id__ === instance.__id__) {
1848
- subscribed[name][i].fn.apply(o, Array.prototype.slice.call(arguments, 1));
1849
- continue;
1850
- }
1863
+
1864
+ return savedparsleyFormInstance;
1851
1865
  }
1852
- };
1853
- $.subscribed = function () { return subscribed; };
1854
-
1855
- // ParsleyConfig definition if not already set
1856
- window.ParsleyConfig = window.ParsleyConfig || {};
1857
- window.ParsleyConfig.i18n = window.ParsleyConfig.i18n || {};
1858
- // Define then the messages
1859
- window.ParsleyConfig.i18n.en = $.extend(window.ParsleyConfig.i18n.en || {}, {
1860
- defaultMessage: "This value seems to be invalid.",
1861
- type: {
1862
- email: "This value should be a valid email.",
1863
- url: "This value should be a valid url.",
1864
- number: "This value should be a valid number.",
1865
- integer: "This value should be a valid integer.",
1866
- digits: "This value should be digits.",
1867
- alphanum: "This value should be alphanumeric."
1868
- },
1869
- notblank: "This value should not be blank.",
1870
- required: "This value is required.",
1871
- pattern: "This value seems to be invalid.",
1872
- min: "This value should be greater than or equal to %s.",
1873
- max: "This value should be lower than or equal to %s.",
1874
- range: "This value should be between %s and %s.",
1875
- minlength: "This value is too short. It should have %s characters or more.",
1876
- maxlength: "This value is too long. It should have %s characters or fewer.",
1877
- length: "This value length is invalid. It should be between %s and %s characters long.",
1878
- mincheck: "You must select at least %s choices.",
1879
- maxcheck: "You must select %s choices or fewer.",
1880
- check: "You must select between %s and %s choices.",
1881
- equalto: "This value should be the same."
1882
- });
1883
- // If file is loaded after Parsley main file, auto-load locale
1884
- if ('undefined' !== typeof window.ParsleyValidator)
1885
- window.ParsleyValidator.addCatalog('en', window.ParsleyConfig.i18n.en, true);
1886
-
1887
- // Parsley.js 2.0.6
1888
- // http://parsleyjs.org
1889
- // (c) 20012-2014 Guillaume Potier, Wisembly
1890
- // Parsley may be freely distributed under the MIT license.
1891
-
1892
- // ### Parsley factory
1893
- var Parsley = function (element, options, parsleyFormInstance) {
1894
- this.__class__ = 'Parsley';
1895
- this.__version__ = '2.0.6';
1896
- this.__id__ = ParsleyUtils.hash(4);
1866
+
1897
1867
  // Parsley must be instantiated with a DOM element or jQuery $element
1898
- if ('undefined' === typeof element)
1899
- throw new Error('You must give an element');
1900
- if ('undefined' !== typeof parsleyFormInstance && 'ParsleyForm' !== parsleyFormInstance.__class__)
1901
- throw new Error('Parent instance must be a ParsleyForm instance');
1902
- return this.init($(element), options, parsleyFormInstance);
1868
+ if (!this.$element.length) throw new Error('You must bind Parsley on an existing element.');
1869
+
1870
+ if ('undefined' !== typeof parsleyFormInstance && 'ParsleyForm' !== parsleyFormInstance.__class__) throw new Error('Parent instance must be a ParsleyForm instance');
1871
+
1872
+ this.parent = parsleyFormInstance || window.Parsley;
1873
+ return this.init(options);
1903
1874
  };
1904
- Parsley.prototype = {
1905
- init: function ($element, options, parsleyFormInstance) {
1906
- if (!$element.length)
1907
- throw new Error('You must bind Parsley on an existing element.');
1908
- this.$element = $element;
1909
- // If element have already been binded, returns its saved Parsley instance
1910
- if (this.$element.data('Parsley')) {
1911
- var savedparsleyFormInstance = this.$element.data('Parsley');
1912
- // If saved instance have been binded without a ParsleyForm parent and there is one given in this call, add it
1913
- if ('undefined' !== typeof parsleyFormInstance)
1914
- savedparsleyFormInstance.parent = parsleyFormInstance;
1915
- return savedparsleyFormInstance;
1916
- }
1917
- // Handle 'static' options
1918
- this.OptionsFactory = new ParsleyOptionsFactory(ParsleyDefaults, ParsleyUtils.get(window, 'ParsleyConfig') || {}, options, this.getNamespace(options));
1919
- this.options = this.OptionsFactory.get(this);
1920
- // A ParsleyForm instance is obviously a `<form>` elem but also every node that is not an input and have `data-parsley-validate` attribute
1921
- if (this.$element.is('form') || (ParsleyUtils.attr(this.$element, this.options.namespace, 'validate') && !this.$element.is(this.options.inputs)))
1922
- return this.bind('parsleyForm');
1923
- // Every other supported element and not excluded element is binded as a `ParsleyField` or `ParsleyFieldMultiple`
1924
- else if (this.$element.is(this.options.inputs) && !this.$element.is(this.options.excluded))
1925
- return this.isMultiple() ? this.handleMultiple(parsleyFormInstance) : this.bind('parsleyField', parsleyFormInstance);
1926
- return this;
1875
+
1876
+ ParsleyFactory.prototype = {
1877
+ init: function init(options) {
1878
+ this.__class__ = 'Parsley';
1879
+ this.__version__ = '2.4.4';
1880
+ this.__id__ = ParsleyUtils__default.generateID();
1881
+
1882
+ // Pre-compute options
1883
+ this._resetOptions(options);
1884
+
1885
+ // A ParsleyForm instance is obviously a `<form>` element but also every node that is not an input and has the `data-parsley-validate` attribute
1886
+ if (this.$element.is('form') || ParsleyUtils__default.checkAttr(this.$element, this.options.namespace, 'validate') && !this.$element.is(this.options.inputs)) return this.bind('parsleyForm');
1887
+
1888
+ // Every other element is bound as a `ParsleyField` or `ParsleyFieldMultiple`
1889
+ return this.isMultiple() ? this.handleMultiple() : this.bind('parsleyField');
1927
1890
  },
1928
- isMultiple: function () {
1929
- return (this.$element.is('input[type=radio], input[type=checkbox]') && 'undefined' === typeof this.options.multiple) || (this.$element.is('select') && 'undefined' !== typeof this.$element.attr('multiple'));
1891
+
1892
+ isMultiple: function isMultiple() {
1893
+ return this.$element.is('input[type=radio], input[type=checkbox]') || this.$element.is('select') && 'undefined' !== typeof this.$element.attr('multiple');
1930
1894
  },
1895
+
1931
1896
  // Multiples fields are a real nightmare :(
1932
- // Maybe some refacto would be appreciated here...
1933
- handleMultiple: function (parsleyFormInstance) {
1934
- var
1935
- that = this,
1936
- name,
1937
- multiple,
1938
- parsleyMultipleInstance;
1939
- // Get parsleyFormInstance options if exist, mixed with element attributes
1940
- this.options = $.extend(this.options, parsleyFormInstance ? parsleyFormInstance.OptionsFactory.get(parsleyFormInstance) : {}, ParsleyUtils.attr(this.$element, this.options.namespace));
1897
+ // Maybe some refactoring would be appreciated here...
1898
+ handleMultiple: function handleMultiple() {
1899
+ var _this12 = this;
1900
+
1901
+ var name;
1902
+ var multiple;
1903
+ var parsleyMultipleInstance;
1904
+
1941
1905
  // Handle multiple name
1942
- if (this.options.multiple)
1943
- multiple = this.options.multiple;
1944
- else if ('undefined' !== typeof this.$element.attr('name') && this.$element.attr('name').length)
1945
- multiple = name = this.$element.attr('name');
1946
- else if ('undefined' !== typeof this.$element.attr('id') && this.$element.attr('id').length)
1947
- multiple = this.$element.attr('id');
1906
+ if (this.options.multiple) ; // We already have our 'multiple' identifier
1907
+ else if ('undefined' !== typeof this.$element.attr('name') && this.$element.attr('name').length) this.options.multiple = name = this.$element.attr('name');else if ('undefined' !== typeof this.$element.attr('id') && this.$element.attr('id').length) this.options.multiple = this.$element.attr('id');
1908
+
1948
1909
  // Special select multiple input
1949
1910
  if (this.$element.is('select') && 'undefined' !== typeof this.$element.attr('multiple')) {
1950
- return this.bind('parsleyFieldMultiple', parsleyFormInstance, multiple || this.__id__);
1951
- // Else for radio / checkboxes, we need a `name` or `data-parsley-multiple` to properly bind it
1952
- } else if ('undefined' === typeof multiple) {
1953
- if (window.console && window.console.warn)
1954
- window.console.warn('To be binded by Parsley, a radio, a checkbox and a multiple select input must have either a name or a multiple option.', this.$element);
1955
- return this;
1956
- }
1911
+ this.options.multiple = this.options.multiple || this.__id__;
1912
+ return this.bind('parsleyFieldMultiple');
1913
+
1914
+ // Else for radio / checkboxes, we need a `name` or `data-parsley-multiple` to properly bind it
1915
+ } else if (!this.options.multiple) {
1916
+ ParsleyUtils__default.warn('To be bound by Parsley, a radio, a checkbox and a multiple select input must have either a name or a multiple option.', this.$element);
1917
+ return this;
1918
+ }
1919
+
1957
1920
  // Remove special chars
1958
- multiple = multiple.replace(/(:|\.|\[|\]|\{|\}|\$)/g, '');
1921
+ this.options.multiple = this.options.multiple.replace(/(:|\.|\[|\]|\{|\}|\$)/g, '');
1922
+
1959
1923
  // Add proper `data-parsley-multiple` to siblings if we have a valid multiple name
1960
1924
  if ('undefined' !== typeof name) {
1961
- $('input[name="' + name + '"]').each(function () {
1962
- if ($(this).is('input[type=radio], input[type=checkbox]'))
1963
- $(this).attr(that.options.namespace + 'multiple', multiple);
1925
+ $('input[name="' + name + '"]').each(function (i, input) {
1926
+ if ($(input).is('input[type=radio], input[type=checkbox]')) $(input).attr(_this12.options.namespace + 'multiple', _this12.options.multiple);
1964
1927
  });
1965
1928
  }
1929
+
1966
1930
  // Check here if we don't already have a related multiple instance saved
1967
- if ($('[' + this.options.namespace + 'multiple=' + multiple +']').length) {
1968
- for (var i = 0; i < $('[' + this.options.namespace + 'multiple=' + multiple +']').length; i++) {
1969
- if ('undefined' !== typeof $($('[' + this.options.namespace + 'multiple=' + multiple +']').get(i)).data('Parsley')) {
1970
- parsleyMultipleInstance = $($('[' + this.options.namespace + 'multiple=' + multiple +']').get(i)).data('Parsley');
1971
- if (!this.$element.data('ParsleyFieldMultiple')) {
1972
- parsleyMultipleInstance.addElement(this.$element);
1973
- this.$element.attr(this.options.namespace + 'id', parsleyMultipleInstance.__id__);
1974
- }
1975
- break;
1931
+ var $previouslyRelated = this._findRelated();
1932
+ for (var i = 0; i < $previouslyRelated.length; i++) {
1933
+ parsleyMultipleInstance = $($previouslyRelated.get(i)).data('Parsley');
1934
+ if ('undefined' !== typeof parsleyMultipleInstance) {
1935
+
1936
+ if (!this.$element.data('ParsleyFieldMultiple')) {
1937
+ parsleyMultipleInstance.addElement(this.$element);
1976
1938
  }
1939
+
1940
+ break;
1977
1941
  }
1978
1942
  }
1979
- // Create a secret ParsleyField instance for every multiple field. It would be stored in `data('ParsleyFieldMultiple')`
1980
- // And would be useful later to access classic `ParsleyField` stuff while being in a `ParsleyFieldMultiple` instance
1981
- this.bind('parsleyField', parsleyFormInstance, multiple, true);
1982
- return parsleyMultipleInstance || this.bind('parsleyFieldMultiple', parsleyFormInstance, multiple);
1983
- },
1984
- // Retrieve namespace used for DOM-API
1985
- getNamespace: function (options) {
1986
- // `data-parsley-namespace=<namespace>`
1987
- if ('undefined' !== typeof this.$element.data('parsleyNamespace'))
1988
- return this.$element.data('parsleyNamespace');
1989
- if ('undefined' !== typeof ParsleyUtils.get(options, 'namespace'))
1990
- return options.namespace;
1991
- if ('undefined' !== typeof ParsleyUtils.get(window, 'ParsleyConfig.namespace'))
1992
- return window.ParsleyConfig.namespace;
1993
- return ParsleyDefaults.namespace;
1943
+
1944
+ // Create a secret ParsleyField instance for every multiple field. It will be stored in `data('ParsleyFieldMultiple')`
1945
+ // And will be useful later to access classic `ParsleyField` stuff while being in a `ParsleyFieldMultiple` instance
1946
+ this.bind('parsleyField', true);
1947
+
1948
+ return parsleyMultipleInstance || this.bind('parsleyFieldMultiple');
1994
1949
  },
1950
+
1995
1951
  // Return proper `ParsleyForm`, `ParsleyField` or `ParsleyFieldMultiple`
1996
- bind: function (type, parentParsleyFormInstance, multiple, doNotStore) {
1952
+ bind: function bind(type, doNotStore) {
1997
1953
  var parsleyInstance;
1954
+
1998
1955
  switch (type) {
1999
1956
  case 'parsleyForm':
2000
- parsleyInstance = $.extend(
2001
- new ParsleyForm(this.$element, this.OptionsFactory),
2002
- new ParsleyAbstract(),
2003
- window.ParsleyExtend
2004
- )._bindFields();
1957
+ parsleyInstance = $.extend(new ParsleyForm(this.$element, this.domOptions, this.options), new ParsleyAbstract(), window.ParsleyExtend)._bindFields();
2005
1958
  break;
2006
1959
  case 'parsleyField':
2007
- parsleyInstance = $.extend(
2008
- new ParsleyField(this.$element, this.OptionsFactory, parentParsleyFormInstance),
2009
- new ParsleyAbstract(),
2010
- window.ParsleyExtend
2011
- );
1960
+ parsleyInstance = $.extend(new parsley_field(this.$element, this.domOptions, this.options, this.parent), new ParsleyAbstract(), window.ParsleyExtend);
2012
1961
  break;
2013
1962
  case 'parsleyFieldMultiple':
2014
- parsleyInstance = $.extend(
2015
- new ParsleyField(this.$element, this.OptionsFactory, parentParsleyFormInstance),
2016
- new ParsleyAbstract(),
2017
- new ParsleyMultiple(),
2018
- window.ParsleyExtend
2019
- )._init(multiple);
1963
+ parsleyInstance = $.extend(new parsley_field(this.$element, this.domOptions, this.options, this.parent), new ParsleyMultiple(), new ParsleyAbstract(), window.ParsleyExtend)._init();
2020
1964
  break;
2021
1965
  default:
2022
1966
  throw new Error(type + 'is not a supported Parsley type');
2023
1967
  }
2024
- if ('undefined' !== typeof multiple)
2025
- ParsleyUtils.setAttr(this.$element, this.options.namespace, 'multiple', multiple);
1968
+
1969
+ if (this.options.multiple) ParsleyUtils__default.setAttr(this.$element, this.options.namespace, 'multiple', this.options.multiple);
1970
+
2026
1971
  if ('undefined' !== typeof doNotStore) {
2027
1972
  this.$element.data('ParsleyFieldMultiple', parsleyInstance);
1973
+
2028
1974
  return parsleyInstance;
2029
1975
  }
2030
- // Store instance if `ParsleyForm`, `ParsleyField` or `ParsleyFieldMultiple`
2031
- if (new RegExp('ParsleyF', 'i').test(parsleyInstance.__class__)) {
2032
- // Store for later access the freshly binded instance in DOM element itself using jQuery `data()`
2033
- this.$element.data('Parsley', parsleyInstance);
2034
- // Tell the world we got a new ParsleyForm or ParsleyField instance!
2035
- $.emit('parsley:' + ('parsleyForm' === type ? 'form' : 'field') + ':init', parsleyInstance);
2036
- }
1976
+
1977
+ // Store the freshly bound instance in a DOM element for later access using jQuery `data()`
1978
+ this.$element.data('Parsley', parsleyInstance);
1979
+
1980
+ // Tell the world we have a new ParsleyForm or ParsleyField instance!
1981
+ parsleyInstance._actualizeTriggers();
1982
+ parsleyInstance._trigger('init');
1983
+
2037
1984
  return parsleyInstance;
2038
1985
  }
2039
1986
  };
1987
+
1988
+ var vernums = $.fn.jquery.split('.');
1989
+ if (parseInt(vernums[0]) <= 1 && parseInt(vernums[1]) < 8) {
1990
+ throw "The loaded version of jQuery is too old. Please upgrade to 1.8.x or better.";
1991
+ }
1992
+ if (!vernums.forEach) {
1993
+ ParsleyUtils__default.warn('Parsley requires ES5 to run properly. Please include https://github.com/es-shims/es5-shim');
1994
+ }
1995
+ // Inherit `on`, `off` & `trigger` to Parsley:
1996
+ var Parsley = $.extend(new ParsleyAbstract(), {
1997
+ $element: $(document),
1998
+ actualizeOptions: null,
1999
+ _resetOptions: null,
2000
+ Factory: ParsleyFactory,
2001
+ version: '2.4.4'
2002
+ });
2003
+
2004
+ // Supplement ParsleyField and Form with ParsleyAbstract
2005
+ // This way, the constructors will have access to those methods
2006
+ $.extend(parsley_field.prototype, ParsleyUI.Field, ParsleyAbstract.prototype);
2007
+ $.extend(ParsleyForm.prototype, ParsleyUI.Form, ParsleyAbstract.prototype);
2008
+ // Inherit actualizeOptions and _resetOptions:
2009
+ $.extend(ParsleyFactory.prototype, ParsleyAbstract.prototype);
2010
+
2040
2011
  // ### jQuery API
2041
2012
  // `$('.elem').parsley(options)` or `$('.elem').psly(options)`
2042
2013
  $.fn.parsley = $.fn.psly = function (options) {
2043
2014
  if (this.length > 1) {
2044
2015
  var instances = [];
2016
+
2045
2017
  this.each(function () {
2046
2018
  instances.push($(this).parsley(options));
2047
2019
  });
2020
+
2048
2021
  return instances;
2049
2022
  }
2023
+
2050
2024
  // Return undefined if applied to non existing DOM element
2051
2025
  if (!$(this).length) {
2052
- if (window.console && window.console.warn)
2053
- window.console.warn('You must bind Parsley on an existing element.');
2026
+ ParsleyUtils__default.warn('You must bind Parsley on an existing element.');
2027
+
2054
2028
  return;
2055
2029
  }
2056
- return new Parsley(this, options);
2030
+
2031
+ return new ParsleyFactory(this, options);
2057
2032
  };
2058
- // ### ParsleyUI
2059
- // UI is a class apart that only listen to some events and them modify DOM accordingly
2060
- // Could be overriden by defining a `window.ParsleyConfig.ParsleyUI` appropriate class (with `listen()` method basically)
2061
- window.ParsleyUI = 'function' === typeof ParsleyUtils.get(window, 'ParsleyConfig.ParsleyUI') ?
2062
- new window.ParsleyConfig.ParsleyUI().listen() : new ParsleyUI().listen();
2033
+
2063
2034
  // ### ParsleyField and ParsleyForm extension
2064
- // Ensure that defined if not already the case
2065
- if ('undefined' === typeof window.ParsleyExtend)
2066
- window.ParsleyExtend = {};
2067
- // ### ParsleyConfig
2068
- // Ensure that defined if not already the case
2069
- if ('undefined' === typeof window.ParsleyConfig)
2070
- window.ParsleyConfig = {};
2035
+ // Ensure the extension is now defined if it wasn't previously
2036
+ if ('undefined' === typeof window.ParsleyExtend) window.ParsleyExtend = {};
2037
+
2038
+ // ### Parsley config
2039
+ // Inherit from ParsleyDefault, and copy over any existing values
2040
+ Parsley.options = $.extend(ParsleyUtils__default.objectCreate(ParsleyDefaults), window.ParsleyConfig);
2041
+ window.ParsleyConfig = Parsley.options; // Old way of accessing global options
2042
+
2071
2043
  // ### Globals
2072
2044
  window.Parsley = window.psly = Parsley;
2073
- window.ParsleyUtils = ParsleyUtils;
2074
- window.ParsleyValidator = new ParsleyValidator(window.ParsleyConfig.validators, window.ParsleyConfig.i18n);
2045
+ window.ParsleyUtils = ParsleyUtils__default;
2046
+
2047
+ // ### Define methods that forward to the registry, and deprecate all access except through window.Parsley
2048
+ var registry = window.Parsley._validatorRegistry = new ParsleyValidatorRegistry(window.ParsleyConfig.validators, window.ParsleyConfig.i18n);
2049
+ window.ParsleyValidator = {};
2050
+ $.each('setLocale addCatalog addMessage addMessages getErrorMessage formatMessage addValidator updateValidator removeValidator'.split(' '), function (i, method) {
2051
+ window.Parsley[method] = $.proxy(registry, method);
2052
+ window.ParsleyValidator[method] = function () {
2053
+ var _window$Parsley;
2054
+
2055
+ ParsleyUtils__default.warnOnce('Accessing the method \'' + method + '\' through ParsleyValidator is deprecated. Simply call \'window.Parsley.' + method + '(...)\'');
2056
+ return (_window$Parsley = window.Parsley)[method].apply(_window$Parsley, arguments);
2057
+ };
2058
+ });
2059
+
2060
+ // ### ParsleyUI
2061
+ // Deprecated global object
2062
+ window.Parsley.UI = ParsleyUI;
2063
+ window.ParsleyUI = {
2064
+ removeError: function removeError(instance, name, doNotUpdateClass) {
2065
+ var updateClass = true !== doNotUpdateClass;
2066
+ ParsleyUtils__default.warnOnce('Accessing ParsleyUI is deprecated. Call \'removeError\' on the instance directly. Please comment in issue 1073 as to your need to call this method.');
2067
+ return instance.removeError(name, { updateClass: updateClass });
2068
+ },
2069
+ getErrorsMessages: function getErrorsMessages(instance) {
2070
+ ParsleyUtils__default.warnOnce('Accessing ParsleyUI is deprecated. Call \'getErrorsMessages\' on the instance directly.');
2071
+ return instance.getErrorsMessages();
2072
+ }
2073
+ };
2074
+ $.each('addError updateError'.split(' '), function (i, method) {
2075
+ window.ParsleyUI[method] = function (instance, name, message, assert, doNotUpdateClass) {
2076
+ var updateClass = true !== doNotUpdateClass;
2077
+ ParsleyUtils__default.warnOnce('Accessing ParsleyUI is deprecated. Call \'' + method + '\' on the instance directly. Please comment in issue 1073 as to your need to call this method.');
2078
+ return instance[method](name, { message: message, assert: assert, updateClass: updateClass });
2079
+ };
2080
+ });
2081
+
2075
2082
  // ### PARSLEY auto-binding
2076
2083
  // Prevent it by setting `ParsleyConfig.autoBind` to `false`
2077
- if (false !== ParsleyUtils.get(window, 'ParsleyConfig.autoBind'))
2084
+ if (false !== window.ParsleyConfig.autoBind) {
2078
2085
  $(function () {
2079
2086
  // Works only on `data-parsley-validate`.
2080
- if ($('[data-parsley-validate]').length)
2081
- $('[data-parsley-validate]').parsley();
2087
+ if ($('[data-parsley-validate]').length) $('[data-parsley-validate]').parsley();
2088
+ });
2089
+ }
2090
+
2091
+ var o = $({});
2092
+ var deprecated = function deprecated() {
2093
+ ParsleyUtils__default.warnOnce("Parsley's pubsub module is deprecated; use the 'on' and 'off' methods on parsley instances or window.Parsley");
2094
+ };
2095
+
2096
+ // Returns an event handler that calls `fn` with the arguments it expects
2097
+ function adapt(fn, context) {
2098
+ // Store to allow unbinding
2099
+ if (!fn.parsleyAdaptedCallback) {
2100
+ fn.parsleyAdaptedCallback = function () {
2101
+ var args = Array.prototype.slice.call(arguments, 0);
2102
+ args.unshift(this);
2103
+ fn.apply(context || o, args);
2104
+ };
2105
+ }
2106
+ return fn.parsleyAdaptedCallback;
2107
+ }
2108
+
2109
+ var eventPrefix = 'parsley:';
2110
+ // Converts 'parsley:form:validate' into 'form:validate'
2111
+ function eventName(name) {
2112
+ if (name.lastIndexOf(eventPrefix, 0) === 0) return name.substr(eventPrefix.length);
2113
+ return name;
2114
+ }
2115
+
2116
+ // $.listen is deprecated. Use Parsley.on instead.
2117
+ $.listen = function (name, callback) {
2118
+ var context;
2119
+ deprecated();
2120
+ if ('object' === typeof arguments[1] && 'function' === typeof arguments[2]) {
2121
+ context = arguments[1];
2122
+ callback = arguments[2];
2123
+ }
2124
+
2125
+ if ('function' !== typeof callback) throw new Error('Wrong parameters');
2126
+
2127
+ window.Parsley.on(eventName(name), adapt(callback, context));
2128
+ };
2129
+
2130
+ $.listenTo = function (instance, name, fn) {
2131
+ deprecated();
2132
+ if (!(instance instanceof parsley_field) && !(instance instanceof ParsleyForm)) throw new Error('Must give Parsley instance');
2133
+
2134
+ if ('string' !== typeof name || 'function' !== typeof fn) throw new Error('Wrong parameters');
2135
+
2136
+ instance.on(eventName(name), adapt(fn));
2137
+ };
2138
+
2139
+ $.unsubscribe = function (name, fn) {
2140
+ deprecated();
2141
+ if ('string' !== typeof name || 'function' !== typeof fn) throw new Error('Wrong arguments');
2142
+ window.Parsley.off(eventName(name), fn.parsleyAdaptedCallback);
2143
+ };
2144
+
2145
+ $.unsubscribeTo = function (instance, name) {
2146
+ deprecated();
2147
+ if (!(instance instanceof parsley_field) && !(instance instanceof ParsleyForm)) throw new Error('Must give Parsley instance');
2148
+ instance.off(eventName(name));
2149
+ };
2150
+
2151
+ $.unsubscribeAll = function (name) {
2152
+ deprecated();
2153
+ window.Parsley.off(eventName(name));
2154
+ $('form,input,textarea,select').each(function () {
2155
+ var instance = $(this).data('Parsley');
2156
+ if (instance) {
2157
+ instance.off(eventName(name));
2158
+ }
2159
+ });
2160
+ };
2161
+
2162
+ // $.emit is deprecated. Use jQuery events instead.
2163
+ $.emit = function (name, instance) {
2164
+ var _instance;
2165
+
2166
+ deprecated();
2167
+ var instanceGiven = instance instanceof parsley_field || instance instanceof ParsleyForm;
2168
+ var args = Array.prototype.slice.call(arguments, instanceGiven ? 2 : 1);
2169
+ args.unshift(eventName(name));
2170
+ if (!instanceGiven) {
2171
+ instance = window.Parsley;
2172
+ }
2173
+ (_instance = instance).trigger.apply(_instance, _toConsumableArray(args));
2174
+ };
2175
+
2176
+ var pubsub = {};
2177
+
2178
+ $.extend(true, Parsley, {
2179
+ asyncValidators: {
2180
+ 'default': {
2181
+ fn: function fn(xhr) {
2182
+ // By default, only status 2xx are deemed successful.
2183
+ // Note: we use status instead of state() because responses with status 200
2184
+ // but invalid messages (e.g. an empty body for content type set to JSON) will
2185
+ // result in state() === 'rejected'.
2186
+ return xhr.status >= 200 && xhr.status < 300;
2187
+ },
2188
+ url: false
2189
+ },
2190
+ reverse: {
2191
+ fn: function fn(xhr) {
2192
+ // If reverse option is set, a failing ajax request is considered successful
2193
+ return xhr.status < 200 || xhr.status >= 300;
2194
+ },
2195
+ url: false
2196
+ }
2197
+ },
2198
+
2199
+ addAsyncValidator: function addAsyncValidator(name, fn, url, options) {
2200
+ Parsley.asyncValidators[name] = {
2201
+ fn: fn,
2202
+ url: url || false,
2203
+ options: options || {}
2204
+ };
2205
+
2206
+ return this;
2207
+ }
2208
+
2209
+ });
2210
+
2211
+ Parsley.addValidator('remote', {
2212
+ requirementType: {
2213
+ '': 'string',
2214
+ 'validator': 'string',
2215
+ 'reverse': 'boolean',
2216
+ 'options': 'object'
2217
+ },
2218
+
2219
+ validateString: function validateString(value, url, options, instance) {
2220
+ var data = {};
2221
+ var ajaxOptions;
2222
+ var csr;
2223
+ var validator = options.validator || (true === options.reverse ? 'reverse' : 'default');
2224
+
2225
+ if ('undefined' === typeof Parsley.asyncValidators[validator]) throw new Error('Calling an undefined async validator: `' + validator + '`');
2226
+
2227
+ url = Parsley.asyncValidators[validator].url || url;
2228
+
2229
+ // Fill current value
2230
+ if (url.indexOf('{value}') > -1) {
2231
+ url = url.replace('{value}', encodeURIComponent(value));
2232
+ } else {
2233
+ data[instance.$element.attr('name') || instance.$element.attr('id')] = value;
2234
+ }
2235
+
2236
+ // Merge options passed in from the function with the ones in the attribute
2237
+ var remoteOptions = $.extend(true, options.options || {}, Parsley.asyncValidators[validator].options);
2238
+
2239
+ // All `$.ajax(options)` could be overridden or extended directly from DOM in `data-parsley-remote-options`
2240
+ ajaxOptions = $.extend(true, {}, {
2241
+ url: url,
2242
+ data: data,
2243
+ type: 'GET'
2244
+ }, remoteOptions);
2245
+
2246
+ // Generate store key based on ajax options
2247
+ instance.trigger('field:ajaxoptions', instance, ajaxOptions);
2248
+
2249
+ csr = $.param(ajaxOptions);
2250
+
2251
+ // Initialise querry cache
2252
+ if ('undefined' === typeof Parsley._remoteCache) Parsley._remoteCache = {};
2253
+
2254
+ // Try to retrieve stored xhr
2255
+ var xhr = Parsley._remoteCache[csr] = Parsley._remoteCache[csr] || $.ajax(ajaxOptions);
2256
+
2257
+ var handleXhr = function handleXhr() {
2258
+ var result = Parsley.asyncValidators[validator].fn.call(instance, xhr, url, options);
2259
+ if (!result) // Map falsy results to rejected promise
2260
+ result = $.Deferred().reject();
2261
+ return $.when(result);
2262
+ };
2263
+
2264
+ return xhr.then(handleXhr, handleXhr);
2265
+ },
2266
+
2267
+ priority: -1
2268
+ });
2269
+
2270
+ Parsley.on('form:submit', function () {
2271
+ Parsley._remoteCache = {};
2272
+ });
2273
+
2274
+ window.ParsleyExtend.addAsyncValidator = function () {
2275
+ ParsleyUtils.warnOnce('Accessing the method `addAsyncValidator` through an instance is deprecated. Simply call `Parsley.addAsyncValidator(...)`');
2276
+ return Parsley.addAsyncValidator.apply(Parsley, arguments);
2277
+ };
2278
+
2279
+ // This is included with the Parsley library itself,
2280
+ // thus there is no use in adding it to your project.
2281
+ Parsley.addMessages('en', {
2282
+ defaultMessage: "This value seems to be invalid.",
2283
+ type: {
2284
+ email: "This value should be a valid email.",
2285
+ url: "This value should be a valid url.",
2286
+ number: "This value should be a valid number.",
2287
+ integer: "This value should be a valid integer.",
2288
+ digits: "This value should be digits.",
2289
+ alphanum: "This value should be alphanumeric."
2290
+ },
2291
+ notblank: "This value should not be blank.",
2292
+ required: "This value is required.",
2293
+ pattern: "This value seems to be invalid.",
2294
+ min: "This value should be greater than or equal to %s.",
2295
+ max: "This value should be lower than or equal to %s.",
2296
+ range: "This value should be between %s and %s.",
2297
+ minlength: "This value is too short. It should have %s characters or more.",
2298
+ maxlength: "This value is too long. It should have %s characters or fewer.",
2299
+ length: "This value length is invalid. It should be between %s and %s characters long.",
2300
+ mincheck: "You must select at least %s choices.",
2301
+ maxcheck: "You must select %s choices or fewer.",
2302
+ check: "You must select between %s and %s choices.",
2303
+ equalto: "This value should be the same."
2304
+ });
2305
+
2306
+ Parsley.setLocale('en');
2307
+
2308
+ /**
2309
+ * inputevent - Alleviate browser bugs for input events
2310
+ * https://github.com/marcandre/inputevent
2311
+ * @version v0.0.3 - (built Thu, Apr 14th 2016, 5:58 pm)
2312
+ * @author Marc-Andre Lafortune <github@marc-andre.ca>
2313
+ * @license MIT
2314
+ */
2315
+
2316
+ function InputEvent() {
2317
+ var _this13 = this;
2318
+
2319
+ var globals = window || global;
2320
+
2321
+ // Slightly odd way construct our object. This way methods are force bound.
2322
+ // Used to test for duplicate library.
2323
+ $.extend(this, {
2324
+
2325
+ // For browsers that do not support isTrusted, assumes event is native.
2326
+ isNativeEvent: function isNativeEvent(evt) {
2327
+ return evt.originalEvent && evt.originalEvent.isTrusted !== false;
2328
+ },
2329
+
2330
+ fakeInputEvent: function fakeInputEvent(evt) {
2331
+ if (_this13.isNativeEvent(evt)) {
2332
+ $(evt.target).trigger('input');
2333
+ }
2334
+ },
2335
+
2336
+ misbehaves: function misbehaves(evt) {
2337
+ if (_this13.isNativeEvent(evt)) {
2338
+ _this13.behavesOk(evt);
2339
+ $(document).on('change.inputevent', evt.data.selector, _this13.fakeInputEvent);
2340
+ _this13.fakeInputEvent(evt);
2341
+ }
2342
+ },
2343
+
2344
+ behavesOk: function behavesOk(evt) {
2345
+ if (_this13.isNativeEvent(evt)) {
2346
+ $(document) // Simply unbinds the testing handler
2347
+ .off('input.inputevent', evt.data.selector, _this13.behavesOk).off('change.inputevent', evt.data.selector, _this13.misbehaves);
2348
+ }
2349
+ },
2350
+
2351
+ // Bind the testing handlers
2352
+ install: function install() {
2353
+ if (globals.inputEventPatched) {
2354
+ return;
2355
+ }
2356
+ globals.inputEventPatched = '0.0.3';
2357
+ var _arr = ['select', 'input[type="checkbox"]', 'input[type="radio"]', 'input[type="file"]'];
2358
+ for (var _i = 0; _i < _arr.length; _i++) {
2359
+ var selector = _arr[_i];
2360
+ $(document).on('input.inputevent', selector, { selector: selector }, _this13.behavesOk).on('change.inputevent', selector, { selector: selector }, _this13.misbehaves);
2361
+ }
2362
+ },
2363
+
2364
+ uninstall: function uninstall() {
2365
+ delete globals.inputEventPatched;
2366
+ $(document).off('.inputevent');
2367
+ }
2368
+
2082
2369
  });
2083
- }));
2370
+ };
2371
+
2372
+ var inputevent = new InputEvent();
2373
+
2374
+ inputevent.install();
2375
+
2376
+ var parsley = Parsley;
2377
+
2378
+ return parsley;
2379
+ });
2380
+ //# sourceMappingURL=parsley.js.map