modify copyright year
[msb/discovery.git] / discovery-ui / src / main / resources / iui / microservices / js / jquery-validation / jquery.validate.js
1 /*
2  * Copyright 2016-2017 ZTE, Inc. and others.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 (function( factory ) {
17         if ( typeof define === "function" && define.amd ) {
18                 define( ["jquery"], factory );
19         } else {
20                 factory( jQuery );
21         }
22 }(function( $ ) {
23
24 $.extend($.fn, {
25         // http://jqueryvalidation.org/validate/
26         validate: function( options ) {
27
28                 // if nothing is selected, return nothing; can't chain anyway
29                 if ( !this.length ) {
30                         if ( options && options.debug && window.console ) {
31                                 console.warn( "Nothing selected, can't validate, returning nothing." );
32                         }
33                         return;
34                 }
35
36                 // check if a validator for this form was already created
37                 var validator = $.data( this[ 0 ], "validator" );
38                 if ( validator ) {
39                         return validator;
40                 }
41
42                 // Add novalidate tag if HTML5.
43                 this.attr( "novalidate", "novalidate" );
44
45                 validator = new $.validator( options, this[ 0 ] );
46                 $.data( this[ 0 ], "validator", validator );
47
48                 if ( validator.settings.onsubmit ) {
49
50                         this.validateDelegate( ":submit", "click", function( event ) {
51                                 if ( validator.settings.submitHandler ) {
52                                         validator.submitButton = event.target;
53                                 }
54                                 // allow suppressing validation by adding a cancel class to the submit button
55                                 if ( $( event.target ).hasClass( "cancel" ) ) {
56                                         validator.cancelSubmit = true;
57                                 }
58
59                                 // allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
60                                 if ( $( event.target ).attr( "formnovalidate" ) !== undefined ) {
61                                         validator.cancelSubmit = true;
62                                 }
63                         });
64
65                         // validate the form on submit
66                         this.submit( function( event ) {
67                                 if ( validator.settings.debug ) {
68                                         // prevent form submit to be able to see console output
69                                         event.preventDefault();
70                                 }
71                                 function handle() {
72                                         var hidden;
73                                         if ( validator.settings.submitHandler ) {
74                                                 if ( validator.submitButton ) {
75                                                         // insert a hidden input as a replacement for the missing submit button
76                                                         hidden = $( "<input type='hidden'/>" )
77                                                                 .attr( "name", validator.submitButton.name )
78                                                                 .val( $( validator.submitButton ).val() )
79                                                                 .appendTo( validator.currentForm );
80                                                 }
81                                                 validator.settings.submitHandler.call( validator, validator.currentForm, event );
82                                                 if ( validator.submitButton ) {
83                                                         // and clean up afterwards; thanks to no-block-scope, hidden can be referenced
84                                                         hidden.remove();
85                                                 }
86                                                 return false;
87                                         }
88                                         return true;
89                                 }
90
91                                 // prevent submit for invalid forms or custom submit handlers
92                                 if ( validator.cancelSubmit ) {
93                                         validator.cancelSubmit = false;
94                                         return handle();
95                                 }
96                                 if ( validator.form() ) {
97                                         if ( validator.pendingRequest ) {
98                                                 validator.formSubmitted = true;
99                                                 return false;
100                                         }
101                                         return handle();
102                                 } else {
103                                         validator.focusInvalid();
104                                         return false;
105                                 }
106                         });
107                 }
108
109                 return validator;
110         },
111         // http://jqueryvalidation.org/valid/
112         valid: function() {
113                 var valid, validator;
114
115                 if ( $( this[ 0 ] ).is( "form" ) ) {
116                         valid = this.validate().form();
117                 } else {
118                         valid = true;
119                         validator = $( this[ 0 ].form ).validate();
120                         this.each( function() {
121                                 valid = validator.element( this ) && valid;
122                         });
123                 }
124                 return valid;
125         },
126         // attributes: space separated list of attributes to retrieve and remove
127         removeAttrs: function( attributes ) {
128                 var result = {},
129                         $element = this;
130                 $.each( attributes.split( /\s/ ), function( index, value ) {
131                         result[ value ] = $element.attr( value );
132                         $element.removeAttr( value );
133                 });
134                 return result;
135         },
136         // http://jqueryvalidation.org/rules/
137         rules: function( command, argument ) {
138                 var element = this[ 0 ],
139                         settings, staticRules, existingRules, data, param, filtered;
140
141                 if ( command ) {
142                         settings = $.data( element.form, "validator" ).settings;
143                         staticRules = settings.rules;
144                         existingRules = $.validator.staticRules( element );
145                         switch ( command ) {
146                         case "add":
147                                 $.extend( existingRules, $.validator.normalizeRule( argument ) );
148                                 // remove messages from rules, but allow them to be set separately
149                                 delete existingRules.messages;
150                                 staticRules[ element.name ] = existingRules;
151                                 if ( argument.messages ) {
152                                         settings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages );
153                                 }
154                                 break;
155                         case "remove":
156                                 if ( !argument ) {
157                                         delete staticRules[ element.name ];
158                                         return existingRules;
159                                 }
160                                 filtered = {};
161                                 $.each( argument.split( /\s/ ), function( index, method ) {
162                                         filtered[ method ] = existingRules[ method ];
163                                         delete existingRules[ method ];
164                                         if ( method === "required" ) {
165                                                 $( element ).removeAttr( "aria-required" );
166                                         }
167                                 });
168                                 return filtered;
169                         }
170                 }
171
172                 data = $.validator.normalizeRules(
173                 $.extend(
174                         {},
175                         $.validator.classRules( element ),
176                         $.validator.attributeRules( element ),
177                         $.validator.dataRules( element ),
178                         $.validator.staticRules( element )
179                 ), element );
180
181                 // make sure required is at front
182                 if ( data.required ) {
183                         param = data.required;
184                         delete data.required;
185                         data = $.extend( { required: param }, data );
186                         $( element ).attr( "aria-required", "true" );
187                 }
188
189                 // make sure remote is at back
190                 if ( data.remote ) {
191                         param = data.remote;
192                         delete data.remote;
193                         data = $.extend( data, { remote: param });
194                 }
195
196                 return data;
197         }
198 });
199
200 // Custom selectors
201 $.extend( $.expr[ ":" ], {
202         // http://jqueryvalidation.org/blank-selector/
203         blank: function( a ) {
204                 return !$.trim( "" + $( a ).val() );
205         },
206         // http://jqueryvalidation.org/filled-selector/
207         filled: function( a ) {
208                 return !!$.trim( "" + $( a ).val() );
209         },
210         // http://jqueryvalidation.org/unchecked-selector/
211         unchecked: function( a ) {
212                 return !$( a ).prop( "checked" );
213         }
214 });
215
216 // constructor for validator
217 $.validator = function( options, form ) {
218         this.settings = $.extend( true, {}, $.validator.defaults, options );
219         this.currentForm = form;
220         this.init();
221 };
222
223 // http://jqueryvalidation.org/jQuery.validator.format/
224 $.validator.format = function( source, params ) {
225         if ( arguments.length === 1 ) {
226                 return function() {
227                         var args = $.makeArray( arguments );
228                         args.unshift( source );
229                         return $.validator.format.apply( this, args );
230                 };
231         }
232         if ( arguments.length > 2 && params.constructor !== Array  ) {
233                 params = $.makeArray( arguments ).slice( 1 );
234         }
235         if ( params.constructor !== Array ) {
236                 params = [ params ];
237         }
238         $.each( params, function( i, n ) {
239                 source = source.replace( new RegExp( "\\{" + i + "\\}", "g" ), function() {
240                         return n;
241                 });
242         });
243         return source;
244 };
245
246 $.extend( $.validator, {
247
248         defaults: {
249                 messages: {},
250                 groups: {},
251                 rules: {},
252                 errorClass: "error",
253                 validClass: "valid",
254                 errorElement: "label",
255                 focusInvalid: true,
256                 errorContainer: $( [] ),
257                 errorLabelContainer: $( [] ),
258                 onsubmit: true,
259                 ignore: ":hidden",
260                 ignoreTitle: false,
261                 onfocusin: function( element ) {
262                         this.lastActive = element;
263
264                         // hide error label and remove error class on focus if enabled
265                         if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
266                                 if ( this.settings.unhighlight ) {
267                                         this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
268                                 }
269                                 this.hideThese( this.errorsFor( element ) );
270                         }
271                 },
272                 onfocusout: function( element ) {
273                         if ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) {
274                                 this.element( element );
275                         }
276                 },
277                 onkeyup: function( element, event ) {
278                         if ( event.which === 9 && this.elementValue( element ) === "" ) {
279                                 return;
280                         } else if ( element.name in this.submitted || element === this.lastElement ) {
281                                 this.element( element );
282                         }
283                 },
284                 onclick: function( element ) {
285                         // click on selects, radiobuttons and checkboxes
286                         if ( element.name in this.submitted ) {
287                                 this.element( element );
288
289                         // or option elements, check parent select in that case
290                         } else if ( element.parentNode.name in this.submitted ) {
291                                 this.element( element.parentNode );
292                         }
293                 },
294                 highlight: function( element, errorClass, validClass ) {
295                         if ( element.type === "radio" ) {
296                                 this.findByName( element.name ).addClass( errorClass ).removeClass( validClass );
297                         } else {
298                                 $( element ).addClass( errorClass ).removeClass( validClass );
299                         }
300                 },
301                 unhighlight: function( element, errorClass, validClass ) {
302                         if ( element.type === "radio" ) {
303                                 this.findByName( element.name ).removeClass( errorClass ).addClass( validClass );
304                         } else {
305                                 $( element ).removeClass( errorClass ).addClass( validClass );
306                         }
307                 }
308         },
309
310         // http://jqueryvalidation.org/jQuery.validator.setDefaults/
311         setDefaults: function( settings ) {
312                 $.extend( $.validator.defaults, settings );
313         },
314
315         messages: {
316                 required: "This field is required.",
317                 remote: "Please fix this field.",
318                 email: "Please enter a valid email address.",
319                 url: "Please enter a valid URL.",
320                 date: "Please enter a valid date.",
321                 dateISO: "Please enter a valid date ( ISO ).",
322                 number: "Please enter a valid number.",
323                 digits: "Please enter only digits.",
324                 creditcard: "Please enter a valid credit card number.",
325                 equalTo: "Please enter the same value again.",
326                 maxlength: $.validator.format( "Please enter no more than {0} characters." ),
327                 minlength: $.validator.format( "Please enter at least {0} characters." ),
328                 rangelength: $.validator.format( "Please enter a value between {0} and {1} characters long." ),
329                 range: $.validator.format( "Please enter a value between {0} and {1}." ),
330                 max: $.validator.format( "Please enter a value less than or equal to {0}." ),
331                 min: $.validator.format( "Please enter a value greater than or equal to {0}." )
332         },
333
334         autoCreateRanges: false,
335
336         prototype: {
337
338                 init: function() {
339                         this.labelContainer = $( this.settings.errorLabelContainer );
340                         this.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm );
341                         this.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer );
342                         this.submitted = {};
343                         this.valueCache = {};
344                         this.pendingRequest = 0;
345                         this.pending = {};
346                         this.invalid = {};
347                         this.reset();
348
349                         var groups = ( this.groups = {} ),
350                                 rules;
351                         $.each( this.settings.groups, function( key, value ) {
352                                 if ( typeof value === "string" ) {
353                                         value = value.split( /\s/ );
354                                 }
355                                 $.each( value, function( index, name ) {
356                                         groups[ name ] = key;
357                                 });
358                         });
359                         rules = this.settings.rules;
360                         $.each( rules, function( key, value ) {
361                                 rules[ key ] = $.validator.normalizeRule( value );
362                         });
363
364                         function delegate( event ) {
365                                 var validator = $.data( this[ 0 ].form, "validator" ),
366                                         eventType = "on" + event.type.replace( /^validate/, "" ),
367                                         settings = validator.settings;
368                                 if ( settings[ eventType ] && !this.is( settings.ignore ) ) {
369                                         settings[ eventType ].call( validator, this[ 0 ], event );
370                                 }
371                         }
372                         $( this.currentForm )
373                                 .validateDelegate( ":text, [type='password'], [type='file'], select, textarea, " +
374                                         "[type='number'], [type='search'] ,[type='tel'], [type='url'], " +
375                                         "[type='email'], [type='datetime'], [type='date'], [type='month'], " +
376                                         "[type='week'], [type='time'], [type='datetime-local'], " +
377                                         "[type='range'], [type='color'], [type='radio'], [type='checkbox']",
378                                         "focusin focusout keyup", delegate)
379                                 // Support: Chrome, oldIE
380                                 // "select" is provided as event.target when clicking a option
381                                 .validateDelegate("select, option, [type='radio'], [type='checkbox']", "click", delegate);
382
383                         if ( this.settings.invalidHandler ) {
384                                 $( this.currentForm ).bind( "invalid-form.validate", this.settings.invalidHandler );
385                         }
386
387                         // Add aria-required to any Static/Data/Class required fields before first validation
388                         // Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html
389                         $( this.currentForm ).find( "[required], [data-rule-required], .required" ).attr( "aria-required", "true" );
390                 },
391
392                 // http://jqueryvalidation.org/Validator.form/
393                 form: function() {
394                         this.checkForm();
395                         $.extend( this.submitted, this.errorMap );
396                         this.invalid = $.extend({}, this.errorMap );
397                         if ( !this.valid() ) {
398                                 $( this.currentForm ).triggerHandler( "invalid-form", [ this ]);
399                         }
400                         this.showErrors();
401                         return this.valid();
402                 },
403
404                 checkForm: function() {
405                         this.prepareForm();
406                         for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) {
407                                 this.check( elements[ i ] );
408                         }
409                         return this.valid();
410                 },
411
412                 // http://jqueryvalidation.org/Validator.element/
413                 element: function( element ) {
414                         var cleanElement = this.clean( element ),
415                                 checkElement = this.validationTargetFor( cleanElement ),
416                                 result = true;
417
418                         this.lastElement = checkElement;
419
420                         if ( checkElement === undefined ) {
421                                 delete this.invalid[ cleanElement.name ];
422                         } else {
423                                 this.prepareElement( checkElement );
424                                 this.currentElements = $( checkElement );
425
426                                 result = this.check( checkElement ) !== false;
427                                 if ( result ) {
428                                         delete this.invalid[ checkElement.name ];
429                                 } else {
430                                         this.invalid[ checkElement.name ] = true;
431                                 }
432                         }
433                         // Add aria-invalid status for screen readers
434                         $( element ).attr( "aria-invalid", !result );
435
436                         if ( !this.numberOfInvalids() ) {
437                                 // Hide error containers on last error
438                                 this.toHide = this.toHide.add( this.containers );
439                         }
440                         this.showErrors();
441                         return result;
442                 },
443
444                 // http://jqueryvalidation.org/Validator.showErrors/
445                 showErrors: function( errors ) {
446                         if ( errors ) {
447                                 // add items to error list and map
448                                 $.extend( this.errorMap, errors );
449                                 this.errorList = [];
450                                 for ( var name in errors ) {
451                                         this.errorList.push({
452                                                 message: errors[ name ],
453                                                 element: this.findByName( name )[ 0 ]
454                                         });
455                                 }
456                                 // remove items from success list
457                                 this.successList = $.grep( this.successList, function( element ) {
458                                         return !( element.name in errors );
459                                 });
460                         }
461                         if ( this.settings.showErrors ) {
462                                 this.settings.showErrors.call( this, this.errorMap, this.errorList );
463                         } else {
464                                 this.defaultShowErrors();
465                         }
466                 },
467
468                 // http://jqueryvalidation.org/Validator.resetForm/
469                 resetForm: function() {
470                         if ( $.fn.resetForm ) {
471                                 $( this.currentForm ).resetForm();
472                         }
473                         this.submitted = {};
474                         this.lastElement = null;
475                         this.prepareForm();
476                         this.hideErrors();
477                         this.elements()
478                                         .removeClass( this.settings.errorClass )
479                                         .removeData( "previousValue" )
480                                         .removeAttr( "aria-invalid" );
481                 },
482
483                 numberOfInvalids: function() {
484                         return this.objectLength( this.invalid );
485                 },
486
487                 objectLength: function( obj ) {
488                         /* jshint unused: false */
489                         var count = 0,
490                                 i;
491                         for ( i in obj ) {
492                                 count++;
493                         }
494                         return count;
495                 },
496
497                 hideErrors: function() {
498                         this.hideThese( this.toHide );
499                 },
500
501                 hideThese: function( errors ) {
502                         errors.not( this.containers ).text( "" );
503                         this.addWrapper( errors ).hide();
504                 },
505
506                 valid: function() {
507                         return this.size() === 0;
508                 },
509
510                 size: function() {
511                         return this.errorList.length;
512                 },
513
514                 focusInvalid: function() {
515                         if ( this.settings.focusInvalid ) {
516                                 try {
517                                         $( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [])
518                                         .filter( ":visible" )
519                                         .focus()
520                                         // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
521                                         .trigger( "focusin" );
522                                 } catch ( e ) {
523                                         // ignore IE throwing errors when focusing hidden elements
524                                 }
525                         }
526                 },
527
528                 findLastActive: function() {
529                         var lastActive = this.lastActive;
530                         return lastActive && $.grep( this.errorList, function( n ) {
531                                 return n.element.name === lastActive.name;
532                         }).length === 1 && lastActive;
533                 },
534
535                 elements: function() {
536                         var validator = this,
537                                 rulesCache = {};
538
539                         // select all valid inputs inside the form (no submit or reset buttons)
540                         return $( this.currentForm )
541                         .find( "input, select, textarea" )
542                         .not( ":submit, :reset, :image, [disabled]" )
543                         .not( this.settings.ignore )
544                         .filter( function() {
545                                 if ( !this.name && validator.settings.debug && window.console ) {
546                                         console.error( "%o has no name assigned", this );
547                                 }
548
549                                 // select only the first element for each name, and only those with rules specified
550                                 if ( this.name in rulesCache || !validator.objectLength( $( this ).rules() ) ) {
551                                         return false;
552                                 }
553
554                                 rulesCache[ this.name ] = true;
555                                 return true;
556                         });
557                 },
558
559                 clean: function( selector ) {
560                         return $( selector )[ 0 ];
561                 },
562
563                 errors: function() {
564                         var errorClass = this.settings.errorClass.split( " " ).join( "." );
565                         return $( this.settings.errorElement + "." + errorClass, this.errorContext );
566                 },
567
568                 reset: function() {
569                         this.successList = [];
570                         this.errorList = [];
571                         this.errorMap = {};
572                         this.toShow = $( [] );
573                         this.toHide = $( [] );
574                         this.currentElements = $( [] );
575                 },
576
577                 prepareForm: function() {
578                         this.reset();
579                         this.toHide = this.errors().add( this.containers );
580                 },
581
582                 prepareElement: function( element ) {
583                         this.reset();
584                         this.toHide = this.errorsFor( element );
585                 },
586
587                 elementValue: function( element ) {
588                         var val,
589                                 $element = $( element ),
590                                 type = element.type;
591
592                         if ( type === "radio" || type === "checkbox" ) {
593                                 return $( "input[name='" + element.name + "']:checked" ).val();
594                         } else if ( type === "number" && typeof element.validity !== "undefined" ) {
595                                 return element.validity.badInput ? false : $element.val();
596                         }
597
598                         val = $element.val();
599                         if ( typeof val === "string" ) {
600                                 return val.replace(/\r/g, "" );
601                         }
602                         return val;
603                 },
604
605                 check: function( element ) {
606                         element = this.validationTargetFor( this.clean( element ) );
607
608                         var rules = $( element ).rules(),
609                                 rulesCount = $.map( rules, function( n, i ) {
610                                         return i;
611                                 }).length,
612                                 dependencyMismatch = false,
613                                 val = this.elementValue( element ),
614                                 result, method, rule;
615
616                         for ( method in rules ) {
617                                 rule = { method: method, parameters: rules[ method ] };
618                                 try {
619
620                                         result = $.validator.methods[ method ].call( this, val, element, rule.parameters );
621
622                                         // if a method indicates that the field is optional and therefore valid,
623                                         // don't mark it as valid when there are no other rules
624                                         if ( result === "dependency-mismatch" && rulesCount === 1 ) {
625                                                 dependencyMismatch = true;
626                                                 continue;
627                                         }
628                                         dependencyMismatch = false;
629
630                                         if ( result === "pending" ) {
631                                                 this.toHide = this.toHide.not( this.errorsFor( element ) );
632                                                 return;
633                                         }
634
635                                         if ( !result ) {
636                                                 this.formatAndAdd( element, rule );
637                                                 return false;
638                                         }
639                                 } catch ( e ) {
640                                         if ( this.settings.debug && window.console ) {
641                                                 console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e );
642                                         }
643                                         throw e;
644                                 }
645                         }
646                         if ( dependencyMismatch ) {
647                                 return;
648                         }
649                         if ( this.objectLength( rules ) ) {
650                                 this.successList.push( element );
651                         }
652                         return true;
653                 },
654
655                 // return the custom message for the given element and validation method
656                 // specified in the element's HTML5 data attribute
657                 // return the generic message if present and no method specific message is present
658                 customDataMessage: function( element, method ) {
659                         return $( element ).data( "msg" + method.charAt( 0 ).toUpperCase() +
660                                 method.substring( 1 ).toLowerCase() ) || $( element ).data( "msg" );
661                 },
662
663                 // return the custom message for the given element name and validation method
664                 customMessage: function( name, method ) {
665                         var m = this.settings.messages[ name ];
666                         return m && ( m.constructor === String ? m : m[ method ]);
667                 },
668
669                 // return the first defined argument, allowing empty strings
670                 findDefined: function() {
671                         for ( var i = 0; i < arguments.length; i++) {
672                                 if ( arguments[ i ] !== undefined ) {
673                                         return arguments[ i ];
674                                 }
675                         }
676                         return undefined;
677                 },
678
679                 defaultMessage: function( element, method ) {
680                         return this.findDefined(
681                                 this.customMessage( element.name, method ),
682                                 this.customDataMessage( element, method ),
683                                 // title is never undefined, so handle empty string as undefined
684                                 !this.settings.ignoreTitle && element.title || undefined,
685                                 $.validator.messages[ method ],
686                                 "<strong>Warning: No message defined for " + element.name + "</strong>"
687                         );
688                 },
689
690                 formatAndAdd: function( element, rule ) {
691                         var message = this.defaultMessage( element, rule.method ),
692                                 theregex = /\$?\{(\d+)\}/g;
693                         if ( typeof message === "function" ) {
694                                 message = message.call( this, rule.parameters, element );
695                         } else if ( theregex.test( message ) ) {
696                                 message = $.validator.format( message.replace( theregex, "{$1}" ), rule.parameters );
697                         }
698                         this.errorList.push({
699                                 message: message,
700                                 element: element,
701                                 method: rule.method
702                         });
703
704                         this.errorMap[ element.name ] = message;
705                         this.submitted[ element.name ] = message;
706                 },
707
708                 addWrapper: function( toToggle ) {
709                         if ( this.settings.wrapper ) {
710                                 toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
711                         }
712                         return toToggle;
713                 },
714
715                 defaultShowErrors: function() {
716                         var i, elements, error;
717                         for ( i = 0; this.errorList[ i ]; i++ ) {
718                                 error = this.errorList[ i ];
719                                 if ( this.settings.highlight ) {
720                                         this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
721                                 }
722                                 this.showLabel( error.element, error.message );
723                         }
724                         if ( this.errorList.length ) {
725                                 this.toShow = this.toShow.add( this.containers );
726                         }
727                         if ( this.settings.success ) {
728                                 for ( i = 0; this.successList[ i ]; i++ ) {
729                                         this.showLabel( this.successList[ i ] );
730                                 }
731                         }
732                         if ( this.settings.unhighlight ) {
733                                 for ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) {
734                                         this.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass );
735                                 }
736                         }
737                         this.toHide = this.toHide.not( this.toShow );
738                         this.hideErrors();
739                         this.addWrapper( this.toShow ).show();
740                 },
741
742                 validElements: function() {
743                         return this.currentElements.not( this.invalidElements() );
744                 },
745
746                 invalidElements: function() {
747                         return $( this.errorList ).map(function() {
748                                 return this.element;
749                         });
750                 },
751
752                 showLabel: function( element, message ) {
753                         var place, group, errorID,
754                                 error = this.errorsFor( element ),
755                                 elementID = this.idOrName( element ),
756                                 describedBy = $( element ).attr( "aria-describedby" );
757                         if ( error.length ) {
758                                 // refresh error/success class
759                                 error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
760                                 // replace message on existing label
761                                 error.html( message );
762                         } else {
763                                 // create error element
764                                 error = $( "<" + this.settings.errorElement + ">" )
765                                         .attr( "id", elementID + "-error" )
766                                         .addClass( this.settings.errorClass )
767                                         .html( message || "" );
768
769                                 // Maintain reference to the element to be placed into the DOM
770                                 place = error;
771                                 if ( this.settings.wrapper ) {
772                                         // make sure the element is visible, even in IE
773                                         // actually showing the wrapped element is handled elsewhere
774                                         place = error.hide().show().wrap( "<" + this.settings.wrapper + "/>" ).parent();
775                                 }
776                                 if ( this.labelContainer.length ) {
777                                         this.labelContainer.append( place );
778                                 } else if ( this.settings.errorPlacement ) {
779                                         this.settings.errorPlacement( place, $( element ) );
780                                 } else {
781                                         place.insertAfter( element );
782                                 }
783
784                                 // Link error back to the element
785                                 if ( error.is( "label" ) ) {
786                                         // If the error is a label, then associate using 'for'
787                                         error.attr( "for", elementID );
788                                 } else if ( error.parents( "label[for='" + elementID + "']" ).length === 0 ) {
789                                         // If the element is not a child of an associated label, then it's necessary
790                                         // to explicitly apply aria-describedby
791
792                                         errorID = error.attr( "id" );
793                                         // Respect existing non-error aria-describedby
794                                         if ( !describedBy ) {
795                                                 describedBy = errorID;
796                                         } else if ( !describedBy.match( new RegExp( "\b" + errorID + "\b" ) ) ) {
797                                                 // Add to end of list if not already present
798                                                 describedBy += " " + errorID;
799                                         }
800                                         $( element ).attr( "aria-describedby", describedBy );
801
802                                         // If this element is grouped, then assign to all elements in the same group
803                                         group = this.groups[ element.name ];
804                                         if ( group ) {
805                                                 $.each( this.groups, function( name, testgroup ) {
806                                                         if ( testgroup === group ) {
807                                                                 $( "[name='" + name + "']", this.currentForm )
808                                                                         .attr( "aria-describedby", error.attr( "id" ) );
809                                                         }
810                                                 });
811                                         }
812                                 }
813                         }
814                         if ( !message && this.settings.success ) {
815                                 error.text( "" );
816                                 if ( typeof this.settings.success === "string" ) {
817                                         error.addClass( this.settings.success );
818                                 } else {
819                                         this.settings.success( error, element );
820                                 }
821                         }
822                         this.toShow = this.toShow.add( error );
823                 },
824
825                 errorsFor: function( element ) {
826                         var name = this.idOrName( element ),
827                                 describer = $( element ).attr( "aria-describedby" ),
828                                 selector = "label[for='" + name + "'], label[for='" + name + "'] *";
829                         // aria-describedby should directly reference the error element
830                         if ( describer ) {
831                                 selector = selector + ", #" + describer.replace( /\s+/g, ", #" );
832                         }
833                         return this
834                                 .errors()
835                                 .filter( selector );
836                 },
837
838                 idOrName: function( element ) {
839                         return this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.id || element.name );
840                 },
841
842                 validationTargetFor: function( element ) {
843                         // if radio/checkbox, validate first element in group instead
844                         if ( this.checkable( element ) ) {
845                                 element = this.findByName( element.name ).not( this.settings.ignore )[ 0 ];
846                         }
847                         return element;
848                 },
849
850                 checkable: function( element ) {
851                         return ( /radio|checkbox/i ).test( element.type );
852                 },
853
854                 findByName: function( name ) {
855                         return $( this.currentForm ).find( "[name='" + name + "']" );
856                 },
857
858                 getLength: function( value, element ) {
859                         switch ( element.nodeName.toLowerCase() ) {
860                         case "select":
861                                 return $( "option:selected", element ).length;
862                         case "input":
863                                 if ( this.checkable( element ) ) {
864                                         return this.findByName( element.name ).filter( ":checked" ).length;
865                                 }
866                         }
867                         return value.length;
868                 },
869
870                 depend: function( param, element ) {
871                         return this.dependTypes[typeof param] ? this.dependTypes[typeof param]( param, element ) : true;
872                 },
873
874                 dependTypes: {
875                         "boolean": function( param ) {
876                                 return param;
877                         },
878                         "string": function( param, element ) {
879                                 return !!$( param, element.form ).length;
880                         },
881                         "function": function( param, element ) {
882                                 return param( element );
883                         }
884                 },
885
886                 optional: function( element ) {
887                         var val = this.elementValue( element );
888                         return !$.validator.methods.required.call( this, val, element ) && "dependency-mismatch";
889                 },
890
891                 startRequest: function( element ) {
892                         if ( !this.pending[ element.name ] ) {
893                                 this.pendingRequest++;
894                                 this.pending[ element.name ] = true;
895                         }
896                 },
897
898                 stopRequest: function( element, valid ) {
899                         this.pendingRequest--;
900                         // sometimes synchronization fails, make sure pendingRequest is never < 0
901                         if ( this.pendingRequest < 0 ) {
902                                 this.pendingRequest = 0;
903                         }
904                         delete this.pending[ element.name ];
905                         if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {
906                                 $( this.currentForm ).submit();
907                                 this.formSubmitted = false;
908                         } else if (!valid && this.pendingRequest === 0 && this.formSubmitted ) {
909                                 $( this.currentForm ).triggerHandler( "invalid-form", [ this ]);
910                                 this.formSubmitted = false;
911                         }
912                 },
913
914                 previousValue: function( element ) {
915                         return $.data( element, "previousValue" ) || $.data( element, "previousValue", {
916                                 old: null,
917                                 valid: true,
918                                 message: this.defaultMessage( element, "remote" )
919                         });
920                 }
921
922         },
923
924         classRuleSettings: {
925                 required: { required: true },
926                 email: { email: true },
927                 url: { url: true },
928                 date: { date: true },
929                 dateISO: { dateISO: true },
930                 number: { number: true },
931                 digits: { digits: true },
932                 creditcard: { creditcard: true }
933         },
934
935         addClassRules: function( className, rules ) {
936                 if ( className.constructor === String ) {
937                         this.classRuleSettings[ className ] = rules;
938                 } else {
939                         $.extend( this.classRuleSettings, className );
940                 }
941         },
942
943         classRules: function( element ) {
944                 var rules = {},
945                         classes = $( element ).attr( "class" );
946
947                 if ( classes ) {
948                         $.each( classes.split( " " ), function() {
949                                 if ( this in $.validator.classRuleSettings ) {
950                                         $.extend( rules, $.validator.classRuleSettings[ this ]);
951                                 }
952                         });
953                 }
954                 return rules;
955         },
956
957         attributeRules: function( element ) {
958                 var rules = {},
959                         $element = $( element ),
960                         type = element.getAttribute( "type" ),
961                         method, value;
962
963                 for ( method in $.validator.methods ) {
964
965                         // support for <input required> in both html5 and older browsers
966                         if ( method === "required" ) {
967                                 value = element.getAttribute( method );
968                                 // Some browsers return an empty string for the required attribute
969                                 // and non-HTML5 browsers might have required="" markup
970                                 if ( value === "" ) {
971                                         value = true;
972                                 }
973                                 // force non-HTML5 browsers to return bool
974                                 value = !!value;
975                         } else {
976                                 value = $element.attr( method );
977                         }
978
979                         // convert the value to a number for number inputs, and for text for backwards compability
980                         // allows type="date" and others to be compared as strings
981                         if ( /min|max/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {
982                                 value = Number( value );
983                         }
984
985                         if ( value || value === 0 ) {
986                                 rules[ method ] = value;
987                         } else if ( type === method && type !== "range" ) {
988                                 // exception: the jquery validate 'range' method
989                                 // does not test for the html5 'range' type
990                                 rules[ method ] = true;
991                         }
992                 }
993
994                 // maxlength may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs
995                 if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) {
996                         delete rules.maxlength;
997                 }
998
999                 return rules;
1000         },
1001
1002         dataRules: function( element ) {
1003                 var method, value,
1004                         rules = {}, $element = $( element );
1005                 for ( method in $.validator.methods ) {
1006                         value = $element.data( "rule" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() );
1007                         if ( value !== undefined ) {
1008                                 rules[ method ] = value;
1009                         }
1010                 }
1011                 return rules;
1012         },
1013
1014         staticRules: function( element ) {
1015                 var rules = {},
1016                         validator = $.data( element.form, "validator" );
1017
1018                 if ( validator.settings.rules ) {
1019                         rules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {};
1020                 }
1021                 return rules;
1022         },
1023
1024         normalizeRules: function( rules, element ) {
1025                 // handle dependency check
1026                 $.each( rules, function( prop, val ) {
1027                         // ignore rule when param is explicitly false, eg. required:false
1028                         if ( val === false ) {
1029                                 delete rules[ prop ];
1030                                 return;
1031                         }
1032                         if ( val.param || val.depends ) {
1033                                 var keepRule = true;
1034                                 switch ( typeof val.depends ) {
1035                                 case "string":
1036                                         keepRule = !!$( val.depends, element.form ).length;
1037                                         break;
1038                                 case "function":
1039                                         keepRule = val.depends.call( element, element );
1040                                         break;
1041                                 }
1042                                 if ( keepRule ) {
1043                                         rules[ prop ] = val.param !== undefined ? val.param : true;
1044                                 } else {
1045                                         delete rules[ prop ];
1046                                 }
1047                         }
1048                 });
1049
1050                 // evaluate parameters
1051                 $.each( rules, function( rule, parameter ) {
1052                         rules[ rule ] = $.isFunction( parameter ) ? parameter( element ) : parameter;
1053                 });
1054
1055                 // clean number parameters
1056                 $.each([ "minlength", "maxlength" ], function() {
1057                         if ( rules[ this ] ) {
1058                                 rules[ this ] = Number( rules[ this ] );
1059                         }
1060                 });
1061                 $.each([ "rangelength", "range" ], function() {
1062                         var parts;
1063                         if ( rules[ this ] ) {
1064                                 if ( $.isArray( rules[ this ] ) ) {
1065                                         rules[ this ] = [ Number( rules[ this ][ 0 ]), Number( rules[ this ][ 1 ] ) ];
1066                                 } else if ( typeof rules[ this ] === "string" ) {
1067                                         parts = rules[ this ].replace(/[\[\]]/g, "" ).split( /[\s,]+/ );
1068                                         rules[ this ] = [ Number( parts[ 0 ]), Number( parts[ 1 ] ) ];
1069                                 }
1070                         }
1071                 });
1072
1073                 if ( $.validator.autoCreateRanges ) {
1074                         // auto-create ranges
1075                         if ( rules.min && rules.max ) {
1076                                 rules.range = [ rules.min, rules.max ];
1077                                 delete rules.min;
1078                                 delete rules.max;
1079                         }
1080                         if ( rules.minlength && rules.maxlength ) {
1081                                 rules.rangelength = [ rules.minlength, rules.maxlength ];
1082                                 delete rules.minlength;
1083                                 delete rules.maxlength;
1084                         }
1085                 }
1086
1087                 return rules;
1088         },
1089
1090         // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
1091         normalizeRule: function( data ) {
1092                 if ( typeof data === "string" ) {
1093                         var transformed = {};
1094                         $.each( data.split( /\s/ ), function() {
1095                                 transformed[ this ] = true;
1096                         });
1097                         data = transformed;
1098                 }
1099                 return data;
1100         },
1101
1102         // http://jqueryvalidation.org/jQuery.validator.addMethod/
1103         addMethod: function( name, method, message ) {
1104                 $.validator.methods[ name ] = method;
1105                 $.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];
1106                 if ( method.length < 3 ) {
1107                         $.validator.addClassRules( name, $.validator.normalizeRule( name ) );
1108                 }
1109         },
1110
1111         methods: {
1112
1113                 // http://jqueryvalidation.org/required-method/
1114                 required: function( value, element, param ) {
1115                         // check if dependency is met
1116                         if ( !this.depend( param, element ) ) {
1117                                 return "dependency-mismatch";
1118                         }
1119                         if ( element.nodeName.toLowerCase() === "select" ) {
1120                                 // could be an array for select-multiple or a string, both are fine this way
1121                                 var val = $( element ).val();
1122                                 return val && val.length > 0;
1123                         }
1124                         if ( this.checkable( element ) ) {
1125                                 return this.getLength( value, element ) > 0;
1126                         }
1127                         return $.trim( value ).length > 0;
1128                 },
1129
1130                 // http://jqueryvalidation.org/email-method/
1131                 email: function( value, element ) {
1132                         // From http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#e-mail-state-%28type=email%29
1133                         // Retrieved 2014-01-14
1134                         // If you have a problem with this implementation, report a bug against the above spec
1135                         // Or use custom methods to implement your own email validation
1136                         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 );
1137                 },
1138
1139                 // http://jqueryvalidation.org/url-method/
1140                 url: function( value, element ) {
1141                         // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
1142                         return this.optional( element ) || /^(https?|s?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 );
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
1364 }));