camaleon_cms 2.1.1 → 2.1.1.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of camaleon_cms might be problematic. Click here for more details.

Files changed (180) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +35 -1
  3. data/app/apps/plugins/attack/config/locales/translation.yml +20 -1
  4. data/app/apps/plugins/contact_form/config/locales/translation.yml +106 -1
  5. data/app/apps/plugins/contact_form/contact_form_helper.rb +44 -27
  6. data/app/apps/plugins/front_cache/config/locales/translation.yml +21 -1
  7. data/app/apps/plugins/front_cache/front_cache_helper.rb +1 -1
  8. data/app/apps/plugins/visibility_post/assets/js/form.js +1 -3
  9. data/app/apps/plugins/visibility_post/visibility_post_helper.rb +2 -4
  10. data/app/assets/images/camaleon_cms/language/de.png +0 -0
  11. data/app/assets/images/camaleon_cms/language/en.png +0 -0
  12. data/app/assets/images/camaleon_cms/language/es.png +0 -0
  13. data/app/assets/images/camaleon_cms/language/fr.png +0 -0
  14. data/app/assets/images/camaleon_cms/language/it.png +0 -0
  15. data/app/assets/images/camaleon_cms/language/nl.png +0 -0
  16. data/app/assets/images/camaleon_cms/language/pl.png +0 -0
  17. data/app/assets/images/camaleon_cms/language/pt.png +0 -0
  18. data/app/assets/images/camaleon_cms/language/pt_br.png +0 -0
  19. data/app/assets/images/camaleon_cms/language/ru.png +0 -0
  20. data/app/assets/images/camaleon_cms/language/zh.png +0 -0
  21. data/app/assets/javascripts/camaleon_cms/admin/_custom_fields.js +3 -11
  22. data/app/assets/javascripts/camaleon_cms/admin/_data.js +2 -6
  23. data/app/assets/javascripts/camaleon_cms/admin/_libraries.js +11 -229
  24. data/app/assets/javascripts/camaleon_cms/admin/_modal.js +11 -37
  25. data/app/assets/javascripts/camaleon_cms/admin/_post.js +27 -22
  26. data/app/assets/javascripts/camaleon_cms/admin/_translator.js +2 -1
  27. data/app/assets/javascripts/camaleon_cms/admin/admin-manifest.js +6 -2
  28. data/app/assets/javascripts/camaleon_cms/admin/bootstrap-datepicker.js +2557 -1689
  29. data/app/assets/javascripts/camaleon_cms/admin/jquery.validate.js +119 -1361
  30. data/app/assets/javascripts/camaleon_cms/admin/jquery_validate/nl.js +33 -0
  31. data/app/assets/javascripts/camaleon_cms/admin/momentjs/_moment.js +3606 -0
  32. data/app/assets/javascripts/camaleon_cms/admin/momentjs/ar.js +136 -0
  33. data/app/assets/javascripts/camaleon_cms/admin/momentjs/ca.js +79 -0
  34. data/app/assets/javascripts/camaleon_cms/admin/momentjs/de.js +76 -0
  35. data/app/assets/javascripts/camaleon_cms/admin/momentjs/es.js +79 -0
  36. data/app/assets/javascripts/camaleon_cms/admin/momentjs/fr.js +62 -0
  37. data/app/assets/javascripts/camaleon_cms/admin/momentjs/it.js +70 -0
  38. data/app/assets/javascripts/camaleon_cms/admin/momentjs/ja.js +65 -0
  39. data/app/assets/javascripts/camaleon_cms/admin/momentjs/nl.js +71 -0
  40. data/app/assets/javascripts/camaleon_cms/admin/momentjs/pl.js +105 -0
  41. data/app/assets/javascripts/camaleon_cms/admin/momentjs/pt.js +64 -0
  42. data/app/assets/javascripts/camaleon_cms/admin/momentjs/pt_br.js +60 -0
  43. data/app/assets/javascripts/camaleon_cms/admin/momentjs/ru.js +166 -0
  44. data/app/assets/javascripts/camaleon_cms/admin/momentjs/zh.js +127 -0
  45. data/app/assets/javascripts/camaleon_cms/admin/nav-menu.js +15 -25
  46. data/app/assets/javascripts/camaleon_cms/admin/tinymce/langs/nl.js +219 -0
  47. data/app/assets/javascripts/camaleon_cms/admin/uploader/_media_manager.js.coffee +82 -19
  48. data/app/assets/javascripts/camaleon_cms/admin/user_profile.js +8 -8
  49. data/app/assets/stylesheets/camaleon_cms/admin/_custom_admin.css.scss +19 -2
  50. data/app/assets/stylesheets/camaleon_cms/admin/admin-manifest.css +0 -4
  51. data/app/assets/stylesheets/camaleon_cms/admin/bootstrap-datepicker.css.scss +315 -414
  52. data/app/assets/stylesheets/camaleon_cms/admin/uploader/_uploadfile.css.scss +7 -3
  53. data/app/controllers/camaleon_cms/admin/appearances/nav_menus_controller.rb +9 -5
  54. data/app/controllers/camaleon_cms/admin/categories_controller.rb +5 -0
  55. data/app/controllers/camaleon_cms/admin/media_controller.rb +27 -10
  56. data/app/controllers/camaleon_cms/admin/posts_controller.rb +9 -19
  57. data/app/controllers/camaleon_cms/admin/sessions_controller.rb +3 -10
  58. data/app/controllers/camaleon_cms/admin/settings/custom_fields_controller.rb +0 -1
  59. data/app/controllers/camaleon_cms/admin/settings/sites_controller.rb +6 -1
  60. data/app/controllers/camaleon_cms/admin/users_controller.rb +1 -8
  61. data/app/controllers/camaleon_cms/admin_controller.rb +5 -4
  62. data/app/controllers/camaleon_cms/apps/plugins_front_controller.rb +0 -8
  63. data/app/controllers/camaleon_cms/camaleon_controller.rb +6 -1
  64. data/app/controllers/camaleon_cms/frontend_controller.rb +11 -8
  65. data/app/decorators/camaleon_cms/category_decorator.rb +2 -1
  66. data/app/decorators/camaleon_cms/post_decorator.rb +28 -1
  67. data/app/decorators/camaleon_cms/post_tag_decorator.rb +1 -0
  68. data/app/decorators/camaleon_cms/post_type_decorator.rb +17 -0
  69. data/app/decorators/camaleon_cms/site_decorator.rb +22 -7
  70. data/app/decorators/camaleon_cms/user_decorator.rb +1 -0
  71. data/app/helpers/camaleon_cms/admin/application_helper.rb +3 -2
  72. data/app/helpers/camaleon_cms/admin/custom_fields_helper.rb +13 -25
  73. data/app/helpers/camaleon_cms/admin/post_type_helper.rb +27 -2
  74. data/app/helpers/camaleon_cms/camaleon_helper.rb +0 -16
  75. data/app/helpers/camaleon_cms/captcha_helper.rb +9 -3
  76. data/app/helpers/camaleon_cms/email_helper.rb +27 -8
  77. data/app/helpers/camaleon_cms/frontend/nav_menu_helper.rb +21 -17
  78. data/app/helpers/camaleon_cms/frontend/seo_helper.rb +5 -3
  79. data/app/helpers/camaleon_cms/html_helper.rb +2 -2
  80. data/app/helpers/camaleon_cms/site_helper.rb +10 -14
  81. data/app/helpers/camaleon_cms/uploader_helper.rb +119 -31
  82. data/app/mailers/camaleon_cms/html_mailer.rb +26 -20
  83. data/app/models/camaleon_cms/custom_field.rb +1 -0
  84. data/app/models/camaleon_cms/custom_field_group.rb +2 -1
  85. data/app/models/camaleon_cms/nav_menu.rb +6 -7
  86. data/app/models/camaleon_cms/nav_menu_item.rb +2 -1
  87. data/app/models/camaleon_cms/post.rb +29 -2
  88. data/app/models/camaleon_cms/post_type.rb +20 -1
  89. data/app/models/camaleon_cms/site.rb +19 -19
  90. data/app/models/camaleon_cms/term_taxonomy.rb +1 -1
  91. data/app/models/concerns/camaleon_cms/custom_fields_read.rb +6 -4
  92. data/app/models/concerns/camaleon_cms/metas.rb +5 -4
  93. data/app/views/camaleon_cms/admin/appearances/nav_menus/_custom_fields.html.erb +4 -2
  94. data/app/views/camaleon_cms/admin/appearances/nav_menus/_external_menu.html.erb +1 -1
  95. data/app/views/camaleon_cms/admin/appearances/nav_menus/index.html.erb +3 -6
  96. data/app/views/camaleon_cms/admin/categories/index.html.erb +1 -0
  97. data/app/views/camaleon_cms/admin/media/_files_list.html.erb +3 -3
  98. data/app/views/camaleon_cms/admin/media/_render_file_item.html.erb +3 -2
  99. data/app/views/camaleon_cms/admin/media/index.html.erb +31 -4
  100. data/app/views/camaleon_cms/admin/posts/_sidebar.html.erb +10 -1
  101. data/app/views/camaleon_cms/admin/posts/form.html.erb +6 -2
  102. data/app/views/camaleon_cms/admin/posts/index.html.erb +4 -4
  103. data/app/views/camaleon_cms/admin/search.html.erb +5 -3
  104. data/app/views/camaleon_cms/admin/settings/_file_system_settings.html.erb +5 -5
  105. data/app/views/camaleon_cms/admin/settings/custom_fields/_get_items.html.erb +2 -1
  106. data/app/views/camaleon_cms/admin/settings/custom_fields/_render.html.erb +1 -1
  107. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_date.html.erb +3 -4
  108. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_image.html.erb +1 -1
  109. data/app/views/camaleon_cms/admin/settings/custom_fields/form.html.erb +2 -2
  110. data/app/views/camaleon_cms/admin/settings/post_types/_form.html.erb +11 -1
  111. data/app/views/camaleon_cms/admin/settings/post_types/index.html.erb +1 -0
  112. data/app/views/camaleon_cms/admin/users/form.html.erb +30 -55
  113. data/app/views/camaleon_cms/html_mailer/mailer.html.erb +1 -1
  114. data/app/views/camaleon_cms/html_mailer/password_reset.html.erb +3 -0
  115. data/app/views/layouts/camaleon_cms/admin.html.erb +4 -1
  116. data/app/views/layouts/camaleon_cms/admin/_ajax.html.erb +3 -1
  117. data/app/views/layouts/camaleon_cms/admin/_footer.html.erb +1 -1
  118. data/app/views/layouts/camaleon_cms/admin/_header.html.erb +1 -1
  119. data/config/initializers/assets.rb +4 -2
  120. data/config/initializers/model_alias.rb +11 -0
  121. data/config/locales/camaleon_cms/admin/en.yml +2 -0
  122. data/config/locales/camaleon_cms/admin/es.yml +2 -1
  123. data/config/locales/camaleon_cms/admin/it.yml +1 -0
  124. data/config/locales/camaleon_cms/admin/js.yml +42 -1
  125. data/config/locales/camaleon_cms/admin/nl.yml +659 -0
  126. data/config/locales/camaleon_cms/admin/pt_br.yml +1 -0
  127. data/config/locales/camaleon_cms/admin/ru.yml +659 -0
  128. data/config/locales/camaleon_cms/common.yml +127 -0
  129. data/config/locales/camaleon_cms/languages.yml +16 -0
  130. data/config/locales/camaleon_cms/routes.yml +8 -0
  131. data/config/locales/nl.yml +209 -0
  132. data/config/routes.rb +1 -1
  133. data/config/routes/admin.rb +5 -4
  134. data/config/routes/frontend.rb +16 -3
  135. data/config/system.json +2 -3
  136. data/lib/camaleon_cms/engine.rb +5 -1
  137. data/lib/camaleon_cms/version.rb +1 -1
  138. data/lib/ext/array.rb +5 -0
  139. data/lib/generators/camaleon_cms/gem_plugin_generator.rb +1 -1
  140. data/lib/generators/camaleon_cms/gem_plugin_template/app/models/plugins/my_plugin/my_plugin.rb +1 -2
  141. data/lib/generators/camaleon_cms/gem_plugin_template/config/{custom_models.rb → initializers/custom_models.rb} +0 -0
  142. data/lib/plugin_routes.rb +38 -63
  143. data/lib/tasks/camaleon_cms/camaleon_tasks.rake +18 -0
  144. data/lib/tasks/camaleon_cms/rspec_test.rake +7 -4
  145. metadata +43 -54
  146. data/app/assets/javascripts/camaleon_cms/admin/bootstrap-datetimepicker.min.js +0 -26
  147. data/app/assets/javascripts/camaleon_cms/admin/plugins.js +0 -637
  148. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-cool.gif +0 -0
  149. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-cry.gif +0 -0
  150. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-embarassed.gif +0 -0
  151. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif +0 -0
  152. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-frown.gif +0 -0
  153. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-innocent.gif +0 -0
  154. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-kiss.gif +0 -0
  155. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-laughing.gif +0 -0
  156. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-money-mouth.gif +0 -0
  157. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-sealed.gif +0 -0
  158. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-smile.gif +0 -0
  159. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-surprised.gif +0 -0
  160. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-tongue-out.gif +0 -0
  161. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-undecided.gif +0 -0
  162. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-wink.gif +0 -0
  163. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/emoticons/img/smiley-yell.gif +0 -0
  164. data/app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/visualblocks/css/visualblocks.css +0 -135
  165. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/content.min.css.scss +0 -4
  166. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/fonts/tinymce-small.eot +0 -0
  167. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/fonts/tinymce-small.svg +0 -62
  168. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/fonts/tinymce-small.ttf +0 -0
  169. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/fonts/tinymce-small.woff +0 -0
  170. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/fonts/tinymce.eot +0 -0
  171. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/fonts/tinymce.svg +0 -83
  172. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/fonts/tinymce.ttf +0 -0
  173. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/fonts/tinymce.woff +0 -0
  174. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/img/anchor.gif +0 -0
  175. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/img/loader.gif +0 -0
  176. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/img/object.gif +0 -0
  177. data/app/assets/javascripts/camaleon_cms/admin/tinymce/skins/lightgray/img/trans.gif +0 -0
  178. data/app/assets/javascripts/camaleon_cms/admin/tinymce/themes/modern/theme.min.js +0 -1
  179. data/app/assets/javascripts/camaleon_cms/admin/tinymce/tinymce.min.js +0 -11
  180. data/app/assets/stylesheets/camaleon_cms/admin/bootstrap-datetimepicker.css.scss +0 -339
@@ -1,1363 +1,121 @@
1
- /*!
2
- * jQuery Validation Plugin v1.13.0
3
- *
1
+ /*! jQuery Validation Plugin - v1.15.0 - 2/24/2016
4
2
  * http://jqueryvalidation.org/
5
- *
6
- * Copyright (c) 2014 Jörn Zaefferer
7
- * Released under the MIT license
8
- */
9
- (function( factory ) {
10
- if ( typeof define === "function" && define.amd ) {
11
- define( ["jquery"], factory );
12
- } else {
13
- factory( jQuery );
14
- }
15
- }(function( $ ) {
16
-
17
- $.extend($.fn, {
18
- // http://jqueryvalidation.org/validate/
19
- validate: function( options ) {
20
-
21
- // if nothing is selected, return nothing; can't chain anyway
22
- if ( !this.length ) {
23
- if ( options && options.debug && window.console ) {
24
- console.warn( "Nothing selected, can't validate, returning nothing." );
25
- }
26
- return;
27
- }
28
-
29
- // check if a validator for this form was already created
30
- var validator = $.data( this[ 0 ], "validator" );
31
- if ( validator ) {
32
- return validator;
33
- }
34
-
35
- // Add novalidate tag if HTML5.
36
- this.attr( "novalidate", "novalidate" );
37
-
38
- validator = new $.validator( options, this[ 0 ] );
39
- $.data( this[ 0 ], "validator", validator );
40
-
41
- if ( validator.settings.onsubmit ) {
42
-
43
- this.validateDelegate( ":submit", "click", function( event ) {
44
- if ( validator.settings.submitHandler ) {
45
- validator.submitButton = event.target;
46
- }
47
- // allow suppressing validation by adding a cancel class to the submit button
48
- if ( $( event.target ).hasClass( "cancel" ) ) {
49
- validator.cancelSubmit = true;
50
- }
51
-
52
- // allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
53
- if ( $( event.target ).attr( "formnovalidate" ) !== undefined ) {
54
- validator.cancelSubmit = true;
55
- }
56
- });
57
-
58
- // validate the form on submit
59
- this.submit( function( event ) {
60
- if ( validator.settings.debug ) {
61
- // prevent form submit to be able to see console output
62
- event.preventDefault();
63
- }
64
- function handle() {
65
- var hidden;
66
- if ( validator.settings.submitHandler ) {
67
- if ( validator.submitButton ) {
68
- // insert a hidden input as a replacement for the missing submit button
69
- hidden = $( "<input type='hidden'/>" )
70
- .attr( "name", validator.submitButton.name )
71
- .val( $( validator.submitButton ).val() )
72
- .appendTo( validator.currentForm );
73
- }
74
- validator.settings.submitHandler.call( validator, validator.currentForm, event );
75
- if ( validator.submitButton ) {
76
- // and clean up afterwards; thanks to no-block-scope, hidden can be referenced
77
- hidden.remove();
78
- }
79
- return false;
80
- }
81
- return true;
82
- }
83
-
84
- // prevent submit for invalid forms or custom submit handlers
85
- if ( validator.cancelSubmit ) {
86
- validator.cancelSubmit = false;
87
- return handle();
88
- }
89
- if ( validator.form() ) {
90
- if ( validator.pendingRequest ) {
91
- validator.formSubmitted = true;
92
- return false;
93
- }
94
- return handle();
95
- } else {
96
- validator.focusInvalid();
97
- return false;
98
- }
99
- });
100
- }
101
-
102
- return validator;
103
- },
104
- // http://jqueryvalidation.org/valid/
105
- valid: function() {
106
- var valid, validator;
107
-
108
- if ( $( this[ 0 ] ).is( "form" ) ) {
109
- valid = this.validate().form();
110
- } else {
111
- valid = true;
112
- validator = $( this[ 0 ].form ).validate();
113
- this.each( function() {
114
- valid = validator.element( this ) && valid;
115
- });
116
- }
117
- return valid;
118
- },
119
- // attributes: space separated list of attributes to retrieve and remove
120
- removeAttrs: function( attributes ) {
121
- var result = {},
122
- $element = this;
123
- $.each( attributes.split( /\s/ ), function( index, value ) {
124
- result[ value ] = $element.attr( value );
125
- $element.removeAttr( value );
126
- });
127
- return result;
128
- },
129
- // http://jqueryvalidation.org/rules/
130
- rules: function( command, argument ) {
131
- var element = this[ 0 ],
132
- settings, staticRules, existingRules, data, param, filtered;
133
-
134
- if ( command ) {
135
- settings = $.data( element.form, "validator" ).settings;
136
- staticRules = settings.rules;
137
- existingRules = $.validator.staticRules( element );
138
- switch ( command ) {
139
- case "add":
140
- $.extend( existingRules, $.validator.normalizeRule( argument ) );
141
- // remove messages from rules, but allow them to be set separately
142
- delete existingRules.messages;
143
- staticRules[ element.name ] = existingRules;
144
- if ( argument.messages ) {
145
- settings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages );
146
- }
147
- break;
148
- case "remove":
149
- if ( !argument ) {
150
- delete staticRules[ element.name ];
151
- return existingRules;
152
- }
153
- filtered = {};
154
- $.each( argument.split( /\s/ ), function( index, method ) {
155
- filtered[ method ] = existingRules[ method ];
156
- delete existingRules[ method ];
157
- if ( method === "required" ) {
158
- $( element ).removeAttr( "aria-required" );
159
- }
160
- });
161
- return filtered;
162
- }
163
- }
164
-
165
- data = $.validator.normalizeRules(
166
- $.extend(
167
- {},
168
- $.validator.classRules( element ),
169
- $.validator.attributeRules( element ),
170
- $.validator.dataRules( element ),
171
- $.validator.staticRules( element )
172
- ), element );
173
-
174
- // make sure required is at front
175
- if ( data.required ) {
176
- param = data.required;
177
- delete data.required;
178
- data = $.extend( { required: param }, data );
179
- $( element ).attr( "aria-required", "true" );
180
- }
181
-
182
- // make sure remote is at back
183
- if ( data.remote ) {
184
- param = data.remote;
185
- delete data.remote;
186
- data = $.extend( data, { remote: param });
187
- }
188
-
189
- return data;
190
- }
191
- });
192
-
193
- // Custom selectors
194
- $.extend( $.expr[ ":" ], {
195
- // http://jqueryvalidation.org/blank-selector/
196
- blank: function( a ) {
197
- return !$.trim( "" + $( a ).val() );
198
- },
199
- // http://jqueryvalidation.org/filled-selector/
200
- filled: function( a ) {
201
- return !!$.trim( "" + $( a ).val() );
202
- },
203
- // http://jqueryvalidation.org/unchecked-selector/
204
- unchecked: function( a ) {
205
- return !$( a ).prop( "checked" );
206
- }
207
- });
208
-
209
- // constructor for validator
210
- $.validator = function( options, form ) {
211
- this.settings = $.extend( true, {}, $.validator.defaults, options );
212
- this.currentForm = form;
213
- this.init();
214
- };
215
-
216
- // http://jqueryvalidation.org/jQuery.validator.format/
217
- $.validator.format = function( source, params ) {
218
- if ( arguments.length === 1 ) {
219
- return function() {
220
- var args = $.makeArray( arguments );
221
- args.unshift( source );
222
- return $.validator.format.apply( this, args );
223
- };
224
- }
225
- if ( arguments.length > 2 && params.constructor !== Array ) {
226
- params = $.makeArray( arguments ).slice( 1 );
227
- }
228
- if ( params.constructor !== Array ) {
229
- params = [ params ];
230
- }
231
- $.each( params, function( i, n ) {
232
- source = source.replace( new RegExp( "\\{" + i + "\\}", "g" ), function() {
233
- return n;
234
- });
235
- });
236
- return source;
237
- };
238
-
239
- $.extend( $.validator, {
240
-
241
- defaults: {
242
- messages: {},
243
- groups: {},
244
- rules: {},
245
- errorClass: "error",
246
- validClass: "valid",
247
- errorElement: "label",
248
- focusInvalid: true,
249
- errorContainer: $( [] ),
250
- errorLabelContainer: $( [] ),
251
- onsubmit: true,
252
- ignore: ":hidden",
253
- ignoreTitle: false,
254
- onfocusin: function( element ) {
255
- this.lastActive = element;
256
-
257
- // hide error label and remove error class on focus if enabled
258
- if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
259
- if ( this.settings.unhighlight ) {
260
- this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
261
- }
262
- this.hideThese( this.errorsFor( element ) );
263
- }
264
- },
265
- onfocusout: function( element ) {
266
- if ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) {
267
- this.element( element );
268
- }
269
- },
270
- onkeyup: function( element, event ) {
271
- if ( event.which === 9 && this.elementValue( element ) === "" ) {
272
- return;
273
- } else if ( element.name in this.submitted || element === this.lastElement ) {
274
- this.element( element );
275
- }
276
- },
277
- onclick: function( element ) {
278
- // click on selects, radiobuttons and checkboxes
279
- if ( element.name in this.submitted ) {
280
- this.element( element );
281
-
282
- // or option elements, check parent select in that case
283
- } else if ( element.parentNode.name in this.submitted ) {
284
- this.element( element.parentNode );
285
- }
286
- },
287
- highlight: function( element, errorClass, validClass ) {
288
- if ( element.type === "radio" ) {
289
- this.findByName( element.name ).addClass( errorClass ).removeClass( validClass );
290
- } else {
291
- $( element ).addClass( errorClass ).removeClass( validClass );
292
- }
293
- },
294
- unhighlight: function( element, errorClass, validClass ) {
295
- if ( element.type === "radio" ) {
296
- this.findByName( element.name ).removeClass( errorClass ).addClass( validClass );
297
- } else {
298
- $( element ).removeClass( errorClass ).addClass( validClass );
299
- }
300
- }
301
- },
302
-
303
- // http://jqueryvalidation.org/jQuery.validator.setDefaults/
304
- setDefaults: function( settings ) {
305
- $.extend( $.validator.defaults, settings );
306
- },
307
-
308
- messages: {
309
- required: "This field is required.",
310
- remote: "Please fix this field.",
311
- email: "Please enter a valid email address.",
312
- url: "Please enter a valid URL.",
313
- date: "Please enter a valid date.",
314
- dateISO: "Please enter a valid date ( ISO ).",
315
- number: "Please enter a valid number.",
316
- digits: "Please enter only digits.",
317
- creditcard: "Please enter a valid credit card number.",
318
- equalTo: "Please enter the same value again.",
319
- maxlength: $.validator.format( "Please enter no more than {0} characters." ),
320
- minlength: $.validator.format( "Please enter at least {0} characters." ),
321
- rangelength: $.validator.format( "Please enter a value between {0} and {1} characters long." ),
322
- range: $.validator.format( "Please enter a value between {0} and {1}." ),
323
- max: $.validator.format( "Please enter a value less than or equal to {0}." ),
324
- min: $.validator.format( "Please enter a value greater than or equal to {0}." )
325
- },
326
-
327
- autoCreateRanges: false,
328
-
329
- prototype: {
330
-
331
- init: function() {
332
- this.labelContainer = $( this.settings.errorLabelContainer );
333
- this.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm );
334
- this.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer );
335
- this.submitted = {};
336
- this.valueCache = {};
337
- this.pendingRequest = 0;
338
- this.pending = {};
339
- this.invalid = {};
340
- this.reset();
341
-
342
- var groups = ( this.groups = {} ),
343
- rules;
344
- $.each( this.settings.groups, function( key, value ) {
345
- if ( typeof value === "string" ) {
346
- value = value.split( /\s/ );
347
- }
348
- $.each( value, function( index, name ) {
349
- groups[ name ] = key;
350
- });
351
- });
352
- rules = this.settings.rules;
353
- $.each( rules, function( key, value ) {
354
- rules[ key ] = $.validator.normalizeRule( value );
355
- });
356
-
357
- function delegate( event ) {
358
- var validator = $.data( this[ 0 ].form, "validator" ),
359
- eventType = "on" + event.type.replace( /^validate/, "" ),
360
- settings = validator.settings;
361
- if ( settings[ eventType ] && !this.is( settings.ignore ) ) {
362
- settings[ eventType ].call( validator, this[ 0 ], event );
363
- }
364
- }
365
- $( this.currentForm )
366
- .validateDelegate( ":text, [type='password'], [type='file'], select, textarea, " +
367
- "[type='number'], [type='search'] ,[type='tel'], [type='url'], " +
368
- "[type='email'], [type='datetime'], [type='date'], [type='month'], " +
369
- "[type='week'], [type='time'], [type='datetime-local'], " +
370
- "[type='range'], [type='color'], [type='radio'], [type='checkbox']",
371
- "focusin focusout keyup", delegate)
372
- // Support: Chrome, oldIE
373
- // "select" is provided as event.target when clicking a option
374
- .validateDelegate("select, option, [type='radio'], [type='checkbox']", "click", delegate);
375
-
376
- if ( this.settings.invalidHandler ) {
377
- $( this.currentForm ).bind( "invalid-form.validate", this.settings.invalidHandler );
378
- }
379
-
380
- // Add aria-required to any Static/Data/Class required fields before first validation
381
- // Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html
382
- $( this.currentForm ).find( "[required], [data-rule-required], .required" ).attr( "aria-required", "true" );
383
- },
384
-
385
- // http://jqueryvalidation.org/Validator.form/
386
- form: function() {
387
- this.checkForm();
388
- $.extend( this.submitted, this.errorMap );
389
- this.invalid = $.extend({}, this.errorMap );
390
- if ( !this.valid() ) {
391
- $( this.currentForm ).triggerHandler( "invalid-form", [ this ]);
392
- }
393
- this.showErrors();
394
- return this.valid();
395
- },
396
-
397
- checkForm: function() {
398
- this.prepareForm();
399
- for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) {
400
- this.check( elements[ i ] );
401
- }
402
- return this.valid();
403
- },
404
-
405
- // http://jqueryvalidation.org/Validator.element/
406
- element: function( element ) {
407
- var cleanElement = this.clean( element ),
408
- checkElement = this.validationTargetFor( cleanElement ),
409
- result = true;
410
-
411
- this.lastElement = checkElement;
412
-
413
- if ( checkElement === undefined ) {
414
- delete this.invalid[ cleanElement.name ];
415
- } else {
416
- this.prepareElement( checkElement );
417
- this.currentElements = $( checkElement );
418
-
419
- result = this.check( checkElement ) !== false;
420
- if ( result ) {
421
- delete this.invalid[ checkElement.name ];
422
- } else {
423
- this.invalid[ checkElement.name ] = true;
424
- }
425
- }
426
- // Add aria-invalid status for screen readers
427
- $( element ).attr( "aria-invalid", !result );
428
-
429
- if ( !this.numberOfInvalids() ) {
430
- // Hide error containers on last error
431
- this.toHide = this.toHide.add( this.containers );
432
- }
433
- this.showErrors();
434
- return result;
435
- },
436
-
437
- // http://jqueryvalidation.org/Validator.showErrors/
438
- showErrors: function( errors ) {
439
- if ( errors ) {
440
- // add items to error list and map
441
- $.extend( this.errorMap, errors );
442
- this.errorList = [];
443
- for ( var name in errors ) {
444
- this.errorList.push({
445
- message: errors[ name ],
446
- element: this.findByName( name )[ 0 ]
447
- });
448
- }
449
- // remove items from success list
450
- this.successList = $.grep( this.successList, function( element ) {
451
- return !( element.name in errors );
452
- });
453
- }
454
- if ( this.settings.showErrors ) {
455
- this.settings.showErrors.call( this, this.errorMap, this.errorList );
456
- } else {
457
- this.defaultShowErrors();
458
- }
459
- },
460
-
461
- // http://jqueryvalidation.org/Validator.resetForm/
462
- resetForm: function() {
463
- if ( $.fn.resetForm ) {
464
- $( this.currentForm ).resetForm();
465
- }
466
- this.submitted = {};
467
- this.lastElement = null;
468
- this.prepareForm();
469
- this.hideErrors();
470
- this.elements()
471
- .removeClass( this.settings.errorClass )
472
- .removeData( "previousValue" )
473
- .removeAttr( "aria-invalid" );
474
- },
475
-
476
- numberOfInvalids: function() {
477
- return this.objectLength( this.invalid );
478
- },
479
-
480
- objectLength: function( obj ) {
481
- /* jshint unused: false */
482
- var count = 0,
483
- i;
484
- for ( i in obj ) {
485
- count++;
486
- }
487
- return count;
488
- },
489
-
490
- hideErrors: function() {
491
- this.hideThese( this.toHide );
492
- },
493
-
494
- hideThese: function( errors ) {
495
- errors.not( this.containers ).text( "" );
496
- this.addWrapper( errors ).hide();
497
- },
498
-
499
- valid: function() {
500
- return this.size() === 0;
501
- },
502
-
503
- size: function() {
504
- return this.errorList.length;
505
- },
506
-
507
- focusInvalid: function() {
508
- if ( this.settings.focusInvalid ) {
509
- try {
510
- $( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [])
511
- .filter( ":visible" )
512
- .focus()
513
- // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
514
- .trigger( "focusin" );
515
- } catch ( e ) {
516
- // ignore IE throwing errors when focusing hidden elements
517
- }
518
- }
519
- },
520
-
521
- findLastActive: function() {
522
- var lastActive = this.lastActive;
523
- return lastActive && $.grep( this.errorList, function( n ) {
524
- return n.element.name === lastActive.name;
525
- }).length === 1 && lastActive;
526
- },
527
-
528
- elements: function() {
529
- var validator = this,
530
- rulesCache = {};
531
-
532
- // select all valid inputs inside the form (no submit or reset buttons)
533
- return $( this.currentForm )
534
- .find( "input, select, textarea" )
535
- .not( ":submit, :reset, :image, [disabled]" )
536
- .not( this.settings.ignore )
537
- .filter( function() {
538
- if ( !this.name && validator.settings.debug && window.console ) {
539
- console.error( "%o has no name assigned", this );
540
- }
541
-
542
- // select only the first element for each name, and only those with rules specified
543
- if ( this.name in rulesCache || !validator.objectLength( $( this ).rules() ) ) {
544
- return false;
545
- }
546
-
547
- rulesCache[ this.name ] = true;
548
- return true;
549
- });
550
- },
551
-
552
- clean: function( selector ) {
553
- return $( selector )[ 0 ];
554
- },
555
-
556
- errors: function() {
557
- var errorClass = this.settings.errorClass.split( " " ).join( "." );
558
- return $( this.settings.errorElement + "." + errorClass, this.errorContext );
559
- },
560
-
561
- reset: function() {
562
- this.successList = [];
563
- this.errorList = [];
564
- this.errorMap = {};
565
- this.toShow = $( [] );
566
- this.toHide = $( [] );
567
- this.currentElements = $( [] );
568
- },
569
-
570
- prepareForm: function() {
571
- this.reset();
572
- this.toHide = this.errors().add( this.containers );
573
- },
574
-
575
- prepareElement: function( element ) {
576
- this.reset();
577
- this.toHide = this.errorsFor( element );
578
- },
579
-
580
- elementValue: function( element ) {
581
- var val,
582
- $element = $( element ),
583
- type = element.type;
584
-
585
- if ( type === "radio" || type === "checkbox" ) {
586
- return $( "input[name='" + element.name + "']:checked" ).val();
587
- } else if ( type === "number" && typeof element.validity !== "undefined" ) {
588
- return element.validity.badInput ? false : $element.val();
589
- }
590
-
591
- val = $element.val();
592
- if ( typeof val === "string" ) {
593
- return val.replace(/\r/g, "" );
594
- }
595
- return val;
596
- },
597
-
598
- check: function( element ) {
599
- element = this.validationTargetFor( this.clean( element ) );
600
-
601
- var rules = $( element ).rules(),
602
- rulesCount = $.map( rules, function( n, i ) {
603
- return i;
604
- }).length,
605
- dependencyMismatch = false,
606
- val = this.elementValue( element ),
607
- result, method, rule;
608
-
609
- for ( method in rules ) {
610
- rule = { method: method, parameters: rules[ method ] };
611
- try {
612
-
613
- result = $.validator.methods[ method ].call( this, val, element, rule.parameters );
614
-
615
- // if a method indicates that the field is optional and therefore valid,
616
- // don't mark it as valid when there are no other rules
617
- if ( result === "dependency-mismatch" && rulesCount === 1 ) {
618
- dependencyMismatch = true;
619
- continue;
620
- }
621
- dependencyMismatch = false;
622
-
623
- if ( result === "pending" ) {
624
- this.toHide = this.toHide.not( this.errorsFor( element ) );
625
- return;
626
- }
627
-
628
- if ( !result ) {
629
- this.formatAndAdd( element, rule );
630
- return false;
631
- }
632
- } catch ( e ) {
633
- if ( this.settings.debug && window.console ) {
634
- console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e );
635
- }
636
- throw e;
637
- }
638
- }
639
- if ( dependencyMismatch ) {
640
- return;
641
- }
642
- if ( this.objectLength( rules ) ) {
643
- this.successList.push( element );
644
- }
645
- return true;
646
- },
647
-
648
- // return the custom message for the given element and validation method
649
- // specified in the element's HTML5 data attribute
650
- // return the generic message if present and no method specific message is present
651
- customDataMessage: function( element, method ) {
652
- return $( element ).data( "msg" + method.charAt( 0 ).toUpperCase() +
653
- method.substring( 1 ).toLowerCase() ) || $( element ).data( "msg" );
654
- },
655
-
656
- // return the custom message for the given element name and validation method
657
- customMessage: function( name, method ) {
658
- var m = this.settings.messages[ name ];
659
- return m && ( m.constructor === String ? m : m[ method ]);
660
- },
661
-
662
- // return the first defined argument, allowing empty strings
663
- findDefined: function() {
664
- for ( var i = 0; i < arguments.length; i++) {
665
- if ( arguments[ i ] !== undefined ) {
666
- return arguments[ i ];
667
- }
668
- }
669
- return undefined;
670
- },
671
-
672
- defaultMessage: function( element, method ) {
673
- return this.findDefined(
674
- this.customMessage( element.name, method ),
675
- this.customDataMessage( element, method ),
676
- // title is never undefined, so handle empty string as undefined
677
- !this.settings.ignoreTitle && element.title || undefined,
678
- $.validator.messages[ method ],
679
- "<strong>Warning: No message defined for " + element.name + "</strong>"
680
- );
681
- },
682
-
683
- formatAndAdd: function( element, rule ) {
684
- var message = this.defaultMessage( element, rule.method ),
685
- theregex = /\$?\{(\d+)\}/g;
686
- if ( typeof message === "function" ) {
687
- message = message.call( this, rule.parameters, element );
688
- } else if ( theregex.test( message ) ) {
689
- message = $.validator.format( message.replace( theregex, "{$1}" ), rule.parameters );
690
- }
691
- this.errorList.push({
692
- message: message,
693
- element: element,
694
- method: rule.method
695
- });
696
-
697
- this.errorMap[ element.name ] = message;
698
- this.submitted[ element.name ] = message;
699
- },
700
-
701
- addWrapper: function( toToggle ) {
702
- if ( this.settings.wrapper ) {
703
- toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
704
- }
705
- return toToggle;
706
- },
707
-
708
- defaultShowErrors: function() {
709
- var i, elements, error;
710
- for ( i = 0; this.errorList[ i ]; i++ ) {
711
- error = this.errorList[ i ];
712
- if ( this.settings.highlight ) {
713
- this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
714
- }
715
- this.showLabel( error.element, error.message );
716
- }
717
- if ( this.errorList.length ) {
718
- this.toShow = this.toShow.add( this.containers );
719
- }
720
- if ( this.settings.success ) {
721
- for ( i = 0; this.successList[ i ]; i++ ) {
722
- this.showLabel( this.successList[ i ] );
723
- }
724
- }
725
- if ( this.settings.unhighlight ) {
726
- for ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) {
727
- this.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass );
728
- }
729
- }
730
- this.toHide = this.toHide.not( this.toShow );
731
- this.hideErrors();
732
- this.addWrapper( this.toShow ).show();
733
- },
734
-
735
- validElements: function() {
736
- return this.currentElements.not( this.invalidElements() );
737
- },
738
-
739
- invalidElements: function() {
740
- return $( this.errorList ).map(function() {
741
- return this.element;
742
- });
743
- },
744
-
745
- showLabel: function( element, message ) {
746
- var place, group, errorID,
747
- error = this.errorsFor( element ),
748
- elementID = this.idOrName( element ),
749
- describedBy = $( element ).attr( "aria-describedby" );
750
- if ( error.length ) {
751
- // refresh error/success class
752
- error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
753
- // replace message on existing label
754
- error.html( message );
755
- } else {
756
- // create error element
757
- error = $( "<" + this.settings.errorElement + ">" )
758
- .attr( "id", elementID + "-error" )
759
- .addClass( this.settings.errorClass )
760
- .html( message || "" );
761
-
762
- // Maintain reference to the element to be placed into the DOM
763
- place = error;
764
- if ( this.settings.wrapper ) {
765
- // make sure the element is visible, even in IE
766
- // actually showing the wrapped element is handled elsewhere
767
- place = error.hide().show().wrap( "<" + this.settings.wrapper + "/>" ).parent();
768
- }
769
- if ( this.labelContainer.length ) {
770
- this.labelContainer.append( place );
771
- } else if ( this.settings.errorPlacement ) {
772
- this.settings.errorPlacement( place, $( element ) );
773
- } else {
774
- place.insertAfter( element );
775
- }
776
-
777
- // Link error back to the element
778
- if ( error.is( "label" ) ) {
779
- // If the error is a label, then associate using 'for'
780
- error.attr( "for", elementID );
781
- } else if ( error.parents( "label[for='" + elementID + "']" ).length === 0 ) {
782
- // If the element is not a child of an associated label, then it's necessary
783
- // to explicitly apply aria-describedby
784
-
785
- errorID = error.attr( "id" );
786
- // Respect existing non-error aria-describedby
787
- if ( !describedBy ) {
788
- describedBy = errorID;
789
- } else if ( !describedBy.match( new RegExp( "\b" + errorID + "\b" ) ) ) {
790
- // Add to end of list if not already present
791
- describedBy += " " + errorID;
792
- }
793
- $( element ).attr( "aria-describedby", describedBy );
794
-
795
- // If this element is grouped, then assign to all elements in the same group
796
- group = this.groups[ element.name ];
797
- if ( group ) {
798
- $.each( this.groups, function( name, testgroup ) {
799
- if ( testgroup === group ) {
800
- $( "[name='" + name + "']", this.currentForm )
801
- .attr( "aria-describedby", error.attr( "id" ) );
802
- }
803
- });
804
- }
805
- }
806
- }
807
- if ( !message && this.settings.success ) {
808
- error.text( "" );
809
- if ( typeof this.settings.success === "string" ) {
810
- error.addClass( this.settings.success );
811
- } else {
812
- this.settings.success( error, element );
813
- }
814
- }
815
- this.toShow = this.toShow.add( error );
816
- },
817
-
818
- errorsFor: function( element ) {
819
- var name = this.idOrName( element ),
820
- describer = $( element ).attr( "aria-describedby" ),
821
- selector = "label[for='" + name + "'], label[for='" + name + "'] *";
822
- // aria-describedby should directly reference the error element
823
- if ( describer ) {
824
- selector = selector + ", #" + describer.replace( /\s+/g, ", #" );
825
- }
826
- return this
827
- .errors()
828
- .filter( selector );
829
- },
830
-
831
- idOrName: function( element ) {
832
- return this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.id || element.name );
833
- },
834
-
835
- validationTargetFor: function( element ) {
836
- // if radio/checkbox, validate first element in group instead
837
- if ( this.checkable( element ) ) {
838
- element = this.findByName( element.name ).not( this.settings.ignore )[ 0 ];
839
- }
840
- return element;
841
- },
842
-
843
- checkable: function( element ) {
844
- return ( /radio|checkbox/i ).test( element.type );
845
- },
846
-
847
- findByName: function( name ) {
848
- return $( this.currentForm ).find( "[name='" + name + "']" );
849
- },
850
-
851
- getLength: function( value, element ) {
852
- switch ( element.nodeName.toLowerCase() ) {
853
- case "select":
854
- return $( "option:selected", element ).length;
855
- case "input":
856
- if ( this.checkable( element ) ) {
857
- return this.findByName( element.name ).filter( ":checked" ).length;
858
- }
859
- }
860
- return value.length;
861
- },
862
-
863
- depend: function( param, element ) {
864
- return this.dependTypes[typeof param] ? this.dependTypes[typeof param]( param, element ) : true;
865
- },
866
-
867
- dependTypes: {
868
- "boolean": function( param ) {
869
- return param;
870
- },
871
- "string": function( param, element ) {
872
- return !!$( param, element.form ).length;
873
- },
874
- "function": function( param, element ) {
875
- return param( element );
876
- }
877
- },
878
-
879
- optional: function( element ) {
880
- var val = this.elementValue( element );
881
- return !$.validator.methods.required.call( this, val, element ) && "dependency-mismatch";
882
- },
883
-
884
- startRequest: function( element ) {
885
- if ( !this.pending[ element.name ] ) {
886
- this.pendingRequest++;
887
- this.pending[ element.name ] = true;
888
- }
889
- },
890
-
891
- stopRequest: function( element, valid ) {
892
- this.pendingRequest--;
893
- // sometimes synchronization fails, make sure pendingRequest is never < 0
894
- if ( this.pendingRequest < 0 ) {
895
- this.pendingRequest = 0;
896
- }
897
- delete this.pending[ element.name ];
898
- if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {
899
- $( this.currentForm ).submit();
900
- this.formSubmitted = false;
901
- } else if (!valid && this.pendingRequest === 0 && this.formSubmitted ) {
902
- $( this.currentForm ).triggerHandler( "invalid-form", [ this ]);
903
- this.formSubmitted = false;
904
- }
905
- },
906
-
907
- previousValue: function( element ) {
908
- return $.data( element, "previousValue" ) || $.data( element, "previousValue", {
909
- old: null,
910
- valid: true,
911
- message: this.defaultMessage( element, "remote" )
912
- });
913
- }
914
-
915
- },
916
-
917
- classRuleSettings: {
918
- required: { required: true },
919
- email: { email: true },
920
- url: { url: true },
921
- date: { date: true },
922
- dateISO: { dateISO: true },
923
- number: { number: true },
924
- digits: { digits: true },
925
- creditcard: { creditcard: true }
926
- },
927
-
928
- addClassRules: function( className, rules ) {
929
- if ( className.constructor === String ) {
930
- this.classRuleSettings[ className ] = rules;
931
- } else {
932
- $.extend( this.classRuleSettings, className );
933
- }
934
- },
935
-
936
- classRules: function( element ) {
937
- var rules = {},
938
- classes = $( element ).attr( "class" );
939
-
940
- if ( classes ) {
941
- $.each( classes.split( " " ), function() {
942
- if ( this in $.validator.classRuleSettings ) {
943
- $.extend( rules, $.validator.classRuleSettings[ this ]);
944
- }
945
- });
946
- }
947
- return rules;
948
- },
949
-
950
- attributeRules: function( element ) {
951
- var rules = {},
952
- $element = $( element ),
953
- type = element.getAttribute( "type" ),
954
- method, value;
955
-
956
- for ( method in $.validator.methods ) {
957
-
958
- // support for <input required> in both html5 and older browsers
959
- if ( method === "required" ) {
960
- value = element.getAttribute( method );
961
- // Some browsers return an empty string for the required attribute
962
- // and non-HTML5 browsers might have required="" markup
963
- if ( value === "" ) {
964
- value = true;
965
- }
966
- // force non-HTML5 browsers to return bool
967
- value = !!value;
968
- } else {
969
- value = $element.attr( method );
970
- }
971
-
972
- // convert the value to a number for number inputs, and for text for backwards compability
973
- // allows type="date" and others to be compared as strings
974
- if ( /min|max/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {
975
- value = Number( value );
976
- }
977
-
978
- if ( value || value === 0 ) {
979
- rules[ method ] = value;
980
- } else if ( type === method && type !== "range" ) {
981
- // exception: the jquery validate 'range' method
982
- // does not test for the html5 'range' type
983
- rules[ method ] = true;
984
- }
985
- }
986
-
987
- // maxlength may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs
988
- if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) {
989
- delete rules.maxlength;
990
- }
991
-
992
- return rules;
993
- },
994
-
995
- dataRules: function( element ) {
996
- var method, value,
997
- rules = {}, $element = $( element );
998
- for ( method in $.validator.methods ) {
999
- value = $element.data( "rule" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() );
1000
- if ( value !== undefined ) {
1001
- rules[ method ] = value;
1002
- }
1003
- }
1004
- return rules;
1005
- },
1006
-
1007
- staticRules: function( element ) {
1008
- var rules = {},
1009
- validator = $.data( element.form, "validator" );
1010
-
1011
- if ( validator.settings.rules ) {
1012
- rules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {};
1013
- }
1014
- return rules;
1015
- },
1016
-
1017
- normalizeRules: function( rules, element ) {
1018
- // handle dependency check
1019
- $.each( rules, function( prop, val ) {
1020
- // ignore rule when param is explicitly false, eg. required:false
1021
- if ( val === false ) {
1022
- delete rules[ prop ];
1023
- return;
1024
- }
1025
- if ( val.param || val.depends ) {
1026
- var keepRule = true;
1027
- switch ( typeof val.depends ) {
1028
- case "string":
1029
- keepRule = !!$( val.depends, element.form ).length;
1030
- break;
1031
- case "function":
1032
- keepRule = val.depends.call( element, element );
1033
- break;
1034
- }
1035
- if ( keepRule ) {
1036
- rules[ prop ] = val.param !== undefined ? val.param : true;
1037
- } else {
1038
- delete rules[ prop ];
1039
- }
1040
- }
1041
- });
1042
-
1043
- // evaluate parameters
1044
- $.each( rules, function( rule, parameter ) {
1045
- rules[ rule ] = $.isFunction( parameter ) ? parameter( element ) : parameter;
1046
- });
1047
-
1048
- // clean number parameters
1049
- $.each([ "minlength", "maxlength" ], function() {
1050
- if ( rules[ this ] ) {
1051
- rules[ this ] = Number( rules[ this ] );
1052
- }
1053
- });
1054
- $.each([ "rangelength", "range" ], function() {
1055
- var parts;
1056
- if ( rules[ this ] ) {
1057
- if ( $.isArray( rules[ this ] ) ) {
1058
- rules[ this ] = [ Number( rules[ this ][ 0 ]), Number( rules[ this ][ 1 ] ) ];
1059
- } else if ( typeof rules[ this ] === "string" ) {
1060
- parts = rules[ this ].replace(/[\[\]]/g, "" ).split( /[\s,]+/ );
1061
- rules[ this ] = [ Number( parts[ 0 ]), Number( parts[ 1 ] ) ];
1062
- }
1063
- }
1064
- });
1065
-
1066
- if ( $.validator.autoCreateRanges ) {
1067
- // auto-create ranges
1068
- if ( rules.min && rules.max ) {
1069
- rules.range = [ rules.min, rules.max ];
1070
- delete rules.min;
1071
- delete rules.max;
1072
- }
1073
- if ( rules.minlength && rules.maxlength ) {
1074
- rules.rangelength = [ rules.minlength, rules.maxlength ];
1075
- delete rules.minlength;
1076
- delete rules.maxlength;
1077
- }
1078
- }
1079
-
1080
- return rules;
1081
- },
1082
-
1083
- // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
1084
- normalizeRule: function( data ) {
1085
- if ( typeof data === "string" ) {
1086
- var transformed = {};
1087
- $.each( data.split( /\s/ ), function() {
1088
- transformed[ this ] = true;
1089
- });
1090
- data = transformed;
1091
- }
1092
- return data;
1093
- },
1094
-
1095
- // http://jqueryvalidation.org/jQuery.validator.addMethod/
1096
- addMethod: function( name, method, message ) {
1097
- $.validator.methods[ name ] = method;
1098
- $.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];
1099
- if ( method.length < 3 ) {
1100
- $.validator.addClassRules( name, $.validator.normalizeRule( name ) );
1101
- }
1102
- },
1103
-
1104
- methods: {
1105
-
1106
- // http://jqueryvalidation.org/required-method/
1107
- required: function( value, element, param ) {
1108
- // check if dependency is met
1109
- if ( !this.depend( param, element ) ) {
1110
- return "dependency-mismatch";
1111
- }
1112
- if ( element.nodeName.toLowerCase() === "select" ) {
1113
- // could be an array for select-multiple or a string, both are fine this way
1114
- var val = $( element ).val();
1115
- return val && val.length > 0;
1116
- }
1117
- if ( this.checkable( element ) ) {
1118
- return this.getLength( value, element ) > 0;
1119
- }
1120
- return $.trim( value ).length > 0;
1121
- },
1122
-
1123
- // http://jqueryvalidation.org/email-method/
1124
- email: function( value, element ) {
1125
- // From http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#e-mail-state-%28type=email%29
1126
- // Retrieved 2014-01-14
1127
- // If you have a problem with this implementation, report a bug against the above spec
1128
- // Or use custom methods to implement your own email validation
1129
- return this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value );
1130
- },
1131
-
1132
- // http://jqueryvalidation.org/url-method/
1133
- url: function( value, element ) {
1134
- // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
1135
- var url = false;
1136
- url = this.optional( element ) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([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])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test( value );
1137
- //fix localhost:port
1138
- if(url == false){
1139
- url = this.optional( element ) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([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])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test( value );
3
+ * Copyright (c) 2016 Jörn Zaefferer; Licensed MIT */
4
+ !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){a.extend(a.fn,{validate:function(b){if(!this.length)return void(b&&b.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing."));var c=a.data(this[0],"validator");return c?c:(this.attr("novalidate","novalidate"),c=new a.validator(b,this[0]),a.data(this[0],"validator",c),c.settings.onsubmit&&(this.on("click.validate",":submit",function(b){c.settings.submitHandler&&(c.submitButton=b.target),a(this).hasClass("cancel")&&(c.cancelSubmit=!0),void 0!==a(this).attr("formnovalidate")&&(c.cancelSubmit=!0)}),this.on("submit.validate",function(b){function d(){var d,e;return c.settings.submitHandler?(c.submitButton&&(d=a("<input type='hidden'/>").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),e=c.settings.submitHandler.call(c,c.currentForm,b),c.submitButton&&d.remove(),void 0!==e?e:!1):!0}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){var b,c,d;return a(this[0]).is("form")?b=this.validate().form():(d=[],b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element(this)&&b,b||(d=d.concat(c.errorList))}),c.errorList=d),b},rules:function(b,c){if(this.length){var d,e,f,g,h,i,j=this[0];if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(b,c){i[c]=f[c],delete f[c],"required"===c&&a(j).removeAttr("aria-required")}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g),a(j).attr("aria-required","true")),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}}),a.extend(a.expr[":"],{blank:function(b){return!a.trim(""+a(b).val())},filled:function(b){var c=a(b).val();return null!==c&&!!a.trim(""+c)},unchecked:function(b){return!a(b).prop("checked")}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:void 0===c?b:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",pendingClass:"pending",validClass:"valid",errorElement:"label",focusCleanup:!1,focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(b,c){var d=[16,17,18,20,35,36,37,38,39,40,45,144,225];9===c.which&&""===this.elementValue(b)||-1!==a.inArray(c.keyCode,d)||(b.name in this.submitted||b.name in this.invalid)&&this.element(b)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date ( ISO ).",number:"Please enter a valid number.",digits:"Please enter only digits.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}."),step:a.validator.format("Please enter a multiple of {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){var c=a.data(this.form,"validator"),d="on"+b.type.replace(/^validate/,""),e=c.settings;e[d]&&!a(this).is(e.ignore)&&e[d].call(c,this,b)}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var c,d=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){d[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).on("focusin.validate focusout.validate keyup.validate",":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], [type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], [type='radio'], [type='checkbox'], [contenteditable]",b).on("click.validate","select, option, [type='radio'], [type='checkbox']",b),this.settings.invalidHandler&&a(this.currentForm).on("invalid-form.validate",this.settings.invalidHandler),a(this.currentForm).find("[required], [data-rule-required], .required").attr("aria-required","true")},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){var c,d,e=this.clean(b),f=this.validationTargetFor(e),g=this,h=!0;return void 0===f?delete this.invalid[e.name]:(this.prepareElement(f),this.currentElements=a(f),d=this.groups[f.name],d&&a.each(this.groups,function(a,b){b===d&&a!==f.name&&(e=g.validationTargetFor(g.clean(g.findByName(a))),e&&e.name in g.invalid&&(g.currentElements.push(e),h=h&&g.check(e)))}),c=this.check(f)!==!1,h=h&&c,c?this.invalid[f.name]=!1:this.invalid[f.name]=!0,this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),a(b).attr("aria-invalid",!c)),h},showErrors:function(b){if(b){var c=this;a.extend(this.errorMap,b),this.errorList=a.map(this.errorMap,function(a,b){return{message:a,element:c.findByName(b)[0]}}),this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.invalid={},this.submitted={},this.prepareForm(),this.hideErrors();var b=this.elements().removeData("previousValue").removeAttr("aria-invalid");this.resetElements(b)},resetElements:function(a){var b;if(this.settings.unhighlight)for(b=0;a[b];b++)this.settings.unhighlight.call(this,a[b],this.settings.errorClass,""),this.findByName(a[b].name).removeClass(this.settings.validClass);else a.removeClass(this.settings.errorClass).removeClass(this.settings.validClass)},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)a[b]&&c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea, [contenteditable]").not(":submit, :reset, :image, :disabled").not(this.settings.ignore).filter(function(){var d=this.name||a(this).attr("name");return!d&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.hasAttribute("contenteditable")&&(this.form=a(this).closest("form")[0]),d in c||!b.objectLength(a(this).rules())?!1:(c[d]=!0,!0)})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},resetInternals:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([])},reset:function(){this.resetInternals(),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c,d,e=a(b),f=b.type;return"radio"===f||"checkbox"===f?this.findByName(b.name).filter(":checked").val():"number"===f&&"undefined"!=typeof b.validity?b.validity.badInput?"NaN":e.val():(c=b.hasAttribute("contenteditable")?e.text():e.val(),"file"===f?"C:\\fakepath\\"===c.substr(0,12)?c.substr(12):(d=c.lastIndexOf("/"),d>=0?c.substr(d+1):(d=c.lastIndexOf("\\"),d>=0?c.substr(d+1):c)):"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f=a(b).rules(),g=a.map(f,function(a,b){return b}).length,h=!1,i=this.elementValue(b);if("function"==typeof f.normalizer){if(i=f.normalizer.call(b,i),"string"!=typeof i)throw new TypeError("The normalizer should return a string value.");delete f.normalizer}for(d in f){e={method:d,parameters:f[d]};try{if(c=a.validator.methods[d].call(this,i,b,e.parameters),"dependency-mismatch"===c&&1===g){h=!0;continue}if(h=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(j){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",j),j instanceof TypeError&&(j.message+=". Exception occurred when checking element "+b.id+", check the '"+e.method+"' method."),j}}if(!h)return this.objectLength(f)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;a<arguments.length;a++)if(void 0!==arguments[a])return arguments[a]},defaultMessage:function(b,c){var d=this.findDefined(this.customMessage(b.name,c.method),this.customDataMessage(b,c.method),!this.settings.ignoreTitle&&b.title||void 0,a.validator.messages[c.method],"<strong>Warning: No message defined for "+b.name+"</strong>"),e=/\$?\{(\d+)\}/g;return"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),d},formatAndAdd:function(a,b){var c=this.defaultMessage(a,b);this.errorList.push({message:c,element:a,method:b.method}),this.errorMap[a.name]=c,this.submitted[a.name]=c},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g,h=this.errorsFor(b),i=this.idOrName(b),j=a(b).attr("aria-describedby");h.length?(h.removeClass(this.settings.validClass).addClass(this.settings.errorClass),h.html(c)):(h=a("<"+this.settings.errorElement+">").attr("id",i+"-error").addClass(this.settings.errorClass).html(c||""),d=h,this.settings.wrapper&&(d=h.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement(d,a(b)):d.insertAfter(b),h.is("label")?h.attr("for",i):0===h.parents("label[for='"+this.escapeCssMeta(i)+"']").length&&(f=h.attr("id"),j?j.match(new RegExp("\\b"+this.escapeCssMeta(f)+"\\b"))||(j+=" "+f):j=f,a(b).attr("aria-describedby",j),e=this.groups[b.name],e&&(g=this,a.each(g.groups,function(b,c){c===e&&a("[name='"+g.escapeCssMeta(b)+"']",g.currentForm).attr("aria-describedby",h.attr("id"))})))),!c&&this.settings.success&&(h.text(""),"string"==typeof this.settings.success?h.addClass(this.settings.success):this.settings.success(h,b)),this.toShow=this.toShow.add(h)},errorsFor:function(b){var c=this.escapeCssMeta(this.idOrName(b)),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+this.escapeCssMeta(d).replace(/\s+/g,", #")),this.errors().filter(e)},escapeCssMeta:function(a){return a.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(b){return this.checkable(b)&&(b=this.findByName(b.name)),a(b).not(this.settings.ignore)[0]},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+this.escapeCssMeta(b)+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return this.dependTypes[typeof a]?this.dependTypes[typeof a](a,b):!0},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(b){this.pending[b.name]||(this.pendingRequest++,a(b).addClass(this.settings.pendingClass),this.pending[b.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],a(b).removeClass(this.settings.pendingClass),c&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b,c){return a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,{method:c})})},destroy:function(){this.resetForm(),a(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur")}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},normalizeAttributeRule:function(a,b,c,d){/min|max|step/.test(c)&&(null===b||/number|range|text/.test(b))&&(d=Number(d),isNaN(d)&&(d=void 0)),d||0===d?a[c]=d:b===c&&"range"!==b&&(a[c]=!0)},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),this.normalizeAttributeRule(e,g,c,d);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),this.normalizeAttributeRule(e,g,c,d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0!==e.param?e.param:!0:(a.data(c.form,"validator").resetElements(a(c)),delete b[d])}}),a.each(b,function(d,e){b[d]=a.isFunction(e)&&"normalizer"!==d?e(c):e}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var c;b[this]&&(a.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(c=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(c[0]),Number(c[1])]))}),a.validator.autoCreateRanges&&(null!=b.min&&null!=b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),null!=b.minlength&&null!=b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:b.length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[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]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a).toString())},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},minlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d},maxlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||d>=e},rangelength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d[0]&&e<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||c>=a},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},step:function(b,c,d){var e=a(c).attr("type"),f="Step attribute on input type "+e+" is not supported.",g=["text","number","range"],h=new RegExp("\\b"+e+"\\b"),i=e&&!h.test(g.join());if(i)throw new Error(f);return this.optional(c)||b%d===0},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-equalTo-blur").length&&e.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d,e){if(this.optional(c))return"dependency-mismatch";e="string"==typeof e&&e||"remote";var f,g,h,i=this.previousValue(c,e);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),i.originalMessage=i.originalMessage||this.settings.messages[c.name][e],this.settings.messages[c.name][e]=i.message,d="string"==typeof d&&{url:d}||d,h=a.param(a.extend({data:b},d.data)),i.old===h?i.valid:(i.old=h,f=this,this.startRequest(c),g={},g[c.name]=b,a.ajax(a.extend(!0,{mode:"abort",port:"validate"+c.name,dataType:"json",data:g,context:f.currentForm,success:function(a){var d,g,h,j=a===!0||"true"===a;f.settings.messages[c.name][e]=i.originalMessage,j?(h=f.formSubmitted,f.resetInternals(),f.toHide=f.errorsFor(c),f.formSubmitted=h,f.successList.push(c),f.invalid[c.name]=!1,f.showErrors()):(d={},g=a||f.defaultMessage(c,{method:e,parameters:b}),d[c.name]=i.message=g,f.invalid[c.name]=!0,f.showErrors(d)),i.valid=j,f.stopRequest(c,j)}},d)),"pending")}}});var b,c={};a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,d){var e=a.port;"abort"===a.mode&&(c[e]&&c[e].abort(),c[e]=d)}):(b=a.ajax,a.ajax=function(d){var e=("mode"in d?d:a.ajaxSettings).mode,f=("port"in d?d:a.ajaxSettings).port;return"abort"===e?(c[f]&&c[f].abort(),c[f]=b.apply(this,arguments),c[f]):b.apply(this,arguments)})});
5
+
6
+ //***************customization*****************/
7
+ // jquery custom validations and default values
8
+ (function ($) {
9
+
10
+ // file formats
11
+ $.file_formats = {
12
+ jpg: "image",
13
+ gif: "image",
14
+ png: "image",
15
+ bmp: "image",
16
+ jpeg: "image",
17
+
18
+ mp3: "audio",
19
+ ogg: "audio",
20
+ mid: "audio",
21
+ mod: "audio",
22
+ wav: "audio",
23
+
24
+ mp4: "video",
25
+ wmv: "video",
26
+ avi: "video",
27
+ swf: "video",
28
+ mov: "video",
29
+ mpeg: "video",
30
+ mjpg: "video",
31
+
32
+ pdf: 'document',
33
+ xls: 'document',
34
+ xlsx: 'document',
35
+ doc: 'document',
36
+ docx: 'document',
37
+ ppt: 'document',
38
+ pptx: 'document',
39
+ html: 'document',
40
+ htm: 'document',
41
+ txt: 'document',
42
+
43
+ zip: 'compress',
44
+ "7z": 'compress',
45
+ rar: 'compress',
46
+ tar: 'compress',
47
+ bz2: 'compress',
48
+ gz: 'compress',
49
+ rar2: 'compress'
50
+ }
51
+
52
+ // return the video id of a video url
53
+ // http://lasnv.net/foro/839/Javascript_parsear_URL_de_YouTube
54
+ $.cama_youtube_key = function(url){
55
+ var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
56
+ var match = url.match(regExp);
57
+ var b = false;
58
+ if (match&&match[7].length==11){
59
+ b=match[7];
60
+ }
61
+ return b;
62
+ }
63
+
64
+ // verify the url for youtube, vimeo...
65
+ // return youtube | metcafe|dailymotion|vimeo
66
+ $.cama_check_video_url = function (url) {
67
+ var regYoutube = new RegExp(/^.*((youtu.be\/)|(v\/)|(\/u\/w\/)|(embed\/)|(watch?))??v?=?([^#&?]*).*/);
68
+ var regVimeo = new RegExp(/^.*(vimeo.com\/)((channels\/[A-z]+\/)|(groups\/[A-z]+\/videos\/))?([0-9]+)/);
69
+ var regDailymotion = new RegExp(/^.+dailymotion.com\/(video|hub)\/([^_]+)[^#]*(#video=([^_&]+))?/);
70
+ var regMetacafe = new RegExp(/^.*(metacafe.com)(\/watch\/)(d+)(.*)/i);
71
+ if (regYoutube.test(url)) {
72
+ return 'youtube';
73
+ } else if (regMetacafe.test(url)) {
74
+ return 'metacafe';
75
+ } else if (regDailymotion.test(url)) {
76
+ return 'dailymotion';
77
+ } else if (regVimeo.test(url)) {
78
+ return 'vimeo';
79
+ } else {
80
+ return false;
81
+ }
82
+ }
83
+
84
+ // helper validate only letters latin
85
+ var regex = /^[a-z\sÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏàáâãäåæçèéêëìíîïÐÑÒÓÔÕÖØÙÚÛÜÝÞßðñòóôõöøùúûüýþÿ]+$/i;
86
+ jQuery.validator.addMethod("lettersonly", function (value, element) {
87
+ return this.optional(element) || regex.test(value);
88
+ }, "Only alphabetical characters");
89
+
90
+ /************ Custom jquery validation as defaults ***************/
91
+ jQuery.validator.setDefaults({
92
+ focusInvalid: true,
93
+ ignore: ".translated-item",
94
+ errorPlacement: function (a, b) {
95
+ if (!a.text()) return;
96
+ if (b.parent().hasClass('trans_tab_item')) $("a[href='#" + b.parent().attr('id') + "']").trigger('click'); // tabs
97
+ if (b.attr("data-error-place") && $(b.attr("data-error-place")).length) $(b.attr("data-error-place")).html(a);
98
+ else b.parent().append(a);
99
+ },
100
+ highlight: function(element, errorClass){ //fix for error fields in hidden tab
101
+ var tab = "";
102
+ if(!$(element).is(":visible") && (tab = $(element).closest(".tab-pane")).length && tab.attr("id")){
103
+ tab.closest(".tabs, .nav-tabs").find(" > ul a[href='#"+tab.attr("id")+"']").click();
1140
104
  }
1141
- //fix localhost:port
1142
- return url;
1143
- },
1144
-
1145
- // http://jqueryvalidation.org/date-method/
1146
- date: function( value, element ) {
1147
- return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() );
1148
- },
1149
-
1150
- // http://jqueryvalidation.org/dateISO-method/
1151
- dateISO: function( value, element ) {
1152
- return this.optional( element ) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test( value );
1153
- },
1154
-
1155
- // http://jqueryvalidation.org/number-method/
1156
- number: function( value, element ) {
1157
- return this.optional( element ) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value );
1158
- },
1159
-
1160
- // http://jqueryvalidation.org/digits-method/
1161
- digits: function( value, element ) {
1162
- return this.optional( element ) || /^\d+$/.test( value );
1163
- },
1164
-
1165
- // http://jqueryvalidation.org/creditcard-method/
1166
- // based on http://en.wikipedia.org/wiki/Luhn/
1167
- creditcard: function( value, element ) {
1168
- if ( this.optional( element ) ) {
1169
- return "dependency-mismatch";
1170
- }
1171
- // accept only spaces, digits and dashes
1172
- if ( /[^0-9 \-]+/.test( value ) ) {
1173
- return false;
1174
- }
1175
- var nCheck = 0,
1176
- nDigit = 0,
1177
- bEven = false,
1178
- n, cDigit;
1179
-
1180
- value = value.replace( /\D/g, "" );
1181
-
1182
- // Basing min and max length on
1183
- // http://developer.ean.com/general_info/Valid_Credit_Card_Types
1184
- if ( value.length < 13 || value.length > 19 ) {
1185
- return false;
1186
- }
1187
-
1188
- for ( n = value.length - 1; n >= 0; n--) {
1189
- cDigit = value.charAt( n );
1190
- nDigit = parseInt( cDigit, 10 );
1191
- if ( bEven ) {
1192
- if ( ( nDigit *= 2 ) > 9 ) {
1193
- nDigit -= 9;
1194
- }
1195
- }
1196
- nCheck += nDigit;
1197
- bEven = !bEven;
1198
- }
1199
-
1200
- return ( nCheck % 10 ) === 0;
1201
- },
1202
-
1203
- // http://jqueryvalidation.org/minlength-method/
1204
- minlength: function( value, element, param ) {
1205
- var length = $.isArray( value ) ? value.length : this.getLength( $.trim( value ), element );
1206
- return this.optional( element ) || length >= param;
1207
- },
1208
-
1209
- // http://jqueryvalidation.org/maxlength-method/
1210
- maxlength: function( value, element, param ) {
1211
- var length = $.isArray( value ) ? value.length : this.getLength( $.trim( value ), element );
1212
- return this.optional( element ) || length <= param;
1213
- },
1214
-
1215
- // http://jqueryvalidation.org/rangelength-method/
1216
- rangelength: function( value, element, param ) {
1217
- var length = $.isArray( value ) ? value.length : this.getLength( $.trim( value ), element );
1218
- return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] );
1219
- },
1220
-
1221
- // http://jqueryvalidation.org/min-method/
1222
- min: function( value, element, param ) {
1223
- return this.optional( element ) || value >= param;
1224
- },
1225
-
1226
- // http://jqueryvalidation.org/max-method/
1227
- max: function( value, element, param ) {
1228
- return this.optional( element ) || value <= param;
1229
- },
1230
-
1231
- // http://jqueryvalidation.org/range-method/
1232
- range: function( value, element, param ) {
1233
- return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );
1234
- },
1235
-
1236
- // http://jqueryvalidation.org/equalTo-method/
1237
- equalTo: function( value, element, param ) {
1238
- // bind to the blur event of the target in order to revalidate whenever the target field is updated
1239
- // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
1240
- var target = $( param );
1241
- if ( this.settings.onfocusout ) {
1242
- target.unbind( ".validate-equalTo" ).bind( "blur.validate-equalTo", function() {
1243
- $( element ).valid();
1244
- });
1245
- }
1246
- return value === target.val();
1247
- },
1248
-
1249
- // http://jqueryvalidation.org/remote-method/
1250
- remote: function( value, element, param ) {
1251
- if ( this.optional( element ) ) {
1252
- return "dependency-mismatch";
1253
- }
1254
-
1255
- var previous = this.previousValue( element ),
1256
- validator, data;
1257
-
1258
- if (!this.settings.messages[ element.name ] ) {
1259
- this.settings.messages[ element.name ] = {};
1260
- }
1261
- previous.originalMessage = this.settings.messages[ element.name ].remote;
1262
- this.settings.messages[ element.name ].remote = previous.message;
1263
-
1264
- param = typeof param === "string" && { url: param } || param;
1265
-
1266
- if ( previous.old === value ) {
1267
- return previous.valid;
1268
- }
1269
-
1270
- previous.old = value;
1271
- validator = this;
1272
- this.startRequest( element );
1273
- data = {};
1274
- data[ element.name ] = value;
1275
- $.ajax( $.extend( true, {
1276
- url: param,
1277
- mode: "abort",
1278
- port: "validate" + element.name,
1279
- dataType: "json",
1280
- data: data,
1281
- context: validator.currentForm,
1282
- success: function( response ) {
1283
- var valid = response === true || response === "true",
1284
- errors, message, submitted;
1285
-
1286
- validator.settings.messages[ element.name ].remote = previous.originalMessage;
1287
- if ( valid ) {
1288
- submitted = validator.formSubmitted;
1289
- validator.prepareElement( element );
1290
- validator.formSubmitted = submitted;
1291
- validator.successList.push( element );
1292
- delete validator.invalid[ element.name ];
1293
- validator.showErrors();
1294
- } else {
1295
- errors = {};
1296
- message = response || validator.defaultMessage( element, "remote" );
1297
- errors[ element.name ] = previous.message = $.isFunction( message ) ? message( value ) : message;
1298
- validator.invalid[ element.name ] = true;
1299
- validator.showErrors( errors );
1300
- }
1301
- previous.valid = valid;
1302
- validator.stopRequest( element, valid );
1303
- }
1304
- }, param ) );
1305
- return "pending";
1306
- }
1307
-
1308
- }
1309
-
1310
- });
1311
-
1312
- $.format = function deprecated() {
1313
- throw "$.format has been deprecated. Please use $.validator.format instead.";
1314
- };
1315
-
1316
- // ajax mode: abort
1317
- // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
1318
- // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
1319
-
1320
- var pendingRequests = {},
1321
- ajax;
1322
- // Use a prefilter if available (1.5+)
1323
- if ( $.ajaxPrefilter ) {
1324
- $.ajaxPrefilter(function( settings, _, xhr ) {
1325
- var port = settings.port;
1326
- if ( settings.mode === "abort" ) {
1327
- if ( pendingRequests[port] ) {
1328
- pendingRequests[port].abort();
1329
- }
1330
- pendingRequests[port] = xhr;
1331
- }
1332
- });
1333
- } else {
1334
- // Proxy ajax
1335
- ajax = $.ajax;
1336
- $.ajax = function( settings ) {
1337
- var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
1338
- port = ( "port" in settings ? settings : $.ajaxSettings ).port;
1339
- if ( mode === "abort" ) {
1340
- if ( pendingRequests[port] ) {
1341
- pendingRequests[port].abort();
1342
- }
1343
- pendingRequests[port] = ajax.apply(this, arguments);
1344
- return pendingRequests[port];
1345
- }
1346
- return ajax.apply(this, arguments);
1347
- };
1348
- }
1349
-
1350
- // provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
1351
- // handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
1352
-
1353
- $.extend($.fn, {
1354
- validateDelegate: function( delegate, type, handler ) {
1355
- return this.bind(type, function( event ) {
1356
- var target = $(event.target);
1357
- if ( target.is(delegate) ) {
1358
- return handler.apply(target, arguments);
1359
- }
1360
- });
1361
- }
1362
- });
1363
- }));
105
+ }
106
+ });
107
+
108
+ // validate file extension defined in data-formats
109
+ // data-formats: (default '') image | audio | video (support also external youtube metacafe, dailymotion, vimeo) | or file extension like: jpg|png
110
+ $.validator.addMethod("file_format", function (value, element) {
111
+ var formats = $(element).attr("data-formats");
112
+ var ext = value.split(".").pop().toLowerCase();
113
+ if (formats)
114
+ return ($.inArray("video", formats.split(",")) >= 0 && $.cama_check_video_url(value)) || $.inArray($.file_formats[ext], formats.split(",")) >= 0 || $.inArray(ext, formats.split(",")) >= 0
115
+
116
+ return true;
117
+ }, "File format not accepted.");
118
+ jQuery.validator.addClassRules({
119
+ file_format: {file_format: true}
120
+ });
121
+ })(jQuery);