social_stream 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1112 @@
1
+ /*
2
+ * jQuery validation plug-in pre-1.5.2
3
+ *
4
+ * http://bassistance.de/jquery-plugins/jquery-plugin-validation/
5
+ * http://docs.jquery.com/Plugins/Validation
6
+ *
7
+ * Copyright (c) 2006 - 2008 Jörn Zaefferer
8
+ *
9
+ * $Id: jquery.validate.js 6243 2009-02-19 11:40:49Z joern.zaefferer $
10
+ *
11
+ * Dual licensed under the MIT and GPL licenses:
12
+ * http://www.opensource.org/licenses/mit-license.php
13
+ * http://www.gnu.org/licenses/gpl.html
14
+ */
15
+
16
+ (function($) {
17
+
18
+ $.extend($.fn, {
19
+ // http://docs.jquery.com/Plugins/Validation/validate
20
+ validate: function( options ) {
21
+
22
+ // if nothing is selected, return nothing; can't chain anyway
23
+ if (!this.length) {
24
+ options && options.debug && window.console && console.warn( "nothing selected, can't validate, returning nothing" );
25
+ return;
26
+ }
27
+
28
+ // check if a validator for this form was already created
29
+ var validator = $.data(this[0], 'validator');
30
+ if ( validator ) {
31
+ return validator;
32
+ }
33
+
34
+ validator = new $.validator( options, this[0] );
35
+ $.data(this[0], 'validator', validator);
36
+
37
+ if ( validator.settings.onsubmit ) {
38
+
39
+ // allow suppresing validation by adding a cancel class to the submit button
40
+ this.find("input, button").filter(".cancel").click(function() {
41
+ validator.cancelSubmit = true;
42
+ });
43
+
44
+ // validate the form on submit
45
+ this.submit( function( event ) {
46
+ if ( validator.settings.debug )
47
+ // prevent form submit to be able to see console output
48
+ event.preventDefault();
49
+
50
+ function handle() {
51
+ if ( validator.settings.submitHandler ) {
52
+ validator.settings.submitHandler.call( validator, validator.currentForm );
53
+ return false;
54
+ }
55
+ return true;
56
+ }
57
+
58
+ // prevent submit for invalid forms or custom submit handlers
59
+ if ( validator.cancelSubmit ) {
60
+ validator.cancelSubmit = false;
61
+ return handle();
62
+ }
63
+ if ( validator.form() ) {
64
+ if ( validator.pendingRequest ) {
65
+ validator.formSubmitted = true;
66
+ return false;
67
+ }
68
+ return handle();
69
+ } else {
70
+ validator.focusInvalid();
71
+ return false;
72
+ }
73
+ });
74
+ }
75
+
76
+ return validator;
77
+ },
78
+ // http://docs.jquery.com/Plugins/Validation/valid
79
+ valid: function() {
80
+ if ( $(this[0]).is('form')) {
81
+ return this.validate().form();
82
+ } else {
83
+ var valid = false;
84
+ var validator = $(this[0].form).validate();
85
+ this.each(function() {
86
+ valid |= validator.element(this);
87
+ });
88
+ return valid;
89
+ }
90
+ },
91
+ // attributes: space seperated list of attributes to retrieve and remove
92
+ removeAttrs: function(attributes) {
93
+ var result = {},
94
+ $element = this;
95
+ $.each(attributes.split(/\s/), function(index, value) {
96
+ result[value] = $element.attr(value);
97
+ $element.removeAttr(value);
98
+ });
99
+ return result;
100
+ },
101
+ // http://docs.jquery.com/Plugins/Validation/rules
102
+ rules: function(command, argument) {
103
+ var element = this[0];
104
+
105
+ if (command) {
106
+ var settings = $.data(element.form, 'validator').settings;
107
+ var staticRules = settings.rules;
108
+ var existingRules = $.validator.staticRules(element);
109
+ switch(command) {
110
+ case "add":
111
+ $.extend(existingRules, $.validator.normalizeRule(argument));
112
+ staticRules[element.name] = existingRules;
113
+ if (argument.messages)
114
+ settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages );
115
+ break;
116
+ case "remove":
117
+ if (!argument) {
118
+ delete staticRules[element.name];
119
+ return existingRules;
120
+ }
121
+ var filtered = {};
122
+ $.each(argument.split(/\s/), function(index, method) {
123
+ filtered[method] = existingRules[method];
124
+ delete existingRules[method];
125
+ });
126
+ return filtered;
127
+ }
128
+ }
129
+
130
+ var data = $.validator.normalizeRules(
131
+ $.extend(
132
+ {},
133
+ $.validator.metadataRules(element),
134
+ $.validator.classRules(element),
135
+ $.validator.attributeRules(element),
136
+ $.validator.staticRules(element)
137
+ ), element);
138
+
139
+ // make sure required is at front
140
+ if (data.required) {
141
+ var param = data.required;
142
+ delete data.required;
143
+ data = $.extend({required: param}, data);
144
+ }
145
+
146
+ return data;
147
+ }
148
+ });
149
+
150
+ // Custom selectors
151
+ $.extend($.expr[":"], {
152
+ // http://docs.jquery.com/Plugins/Validation/blank
153
+ blank: function(a) {return !$.trim(a.value);},
154
+ // http://docs.jquery.com/Plugins/Validation/filled
155
+ filled: function(a) {return !!$.trim(a.value);},
156
+ // http://docs.jquery.com/Plugins/Validation/unchecked
157
+ unchecked: function(a) {return !a.checked;}
158
+ });
159
+
160
+
161
+ $.format = function(source, params) {
162
+ if ( arguments.length == 1 )
163
+ return function() {
164
+ var args = $.makeArray(arguments);
165
+ args.unshift(source);
166
+ return $.format.apply( this, args );
167
+ };
168
+ if ( arguments.length > 2 && params.constructor != Array ) {
169
+ params = $.makeArray(arguments).slice(1);
170
+ }
171
+ if ( params.constructor != Array ) {
172
+ params = [ params ];
173
+ }
174
+ $.each(params, function(i, n) {
175
+ source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n);
176
+ });
177
+ return source;
178
+ };
179
+
180
+ // constructor for validator
181
+ $.validator = function( options, form ) {
182
+ this.settings = $.extend( {}, $.validator.defaults, options );
183
+ this.currentForm = form;
184
+ this.init();
185
+ };
186
+
187
+ $.extend($.validator, {
188
+
189
+ defaults: {
190
+ messages: {},
191
+ groups: {},
192
+ rules: {},
193
+ errorClass: "error",
194
+ errorElement: "label",
195
+ focusInvalid: true,
196
+ errorContainer: $( [] ),
197
+ errorLabelContainer: $( [] ),
198
+ onsubmit: true,
199
+ ignore: [],
200
+ ignoreTitle: false,
201
+ onfocusin: function(element) {
202
+ this.lastActive = element;
203
+
204
+ // hide error label and remove error class on focus if enabled
205
+ if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
206
+ this.settings.unhighlight && this.settings.unhighlight.call( this, element, this.settings.errorClass );
207
+ this.errorsFor(element).hide();
208
+ }
209
+ },
210
+ onfocusout: function(element) {
211
+ if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {
212
+ this.element(element);
213
+ }
214
+ },
215
+ onkeyup: function(element) {
216
+ if ( element.name in this.submitted || element == this.lastElement ) {
217
+ this.element(element);
218
+ }
219
+ },
220
+ onclick: function(element) {
221
+ if ( element.name in this.submitted )
222
+ this.element(element);
223
+ },
224
+ highlight: function( element, errorClass ) {
225
+ $( element ).addClass( errorClass );
226
+ },
227
+ unhighlight: function( element, errorClass ) {
228
+ $( element ).removeClass( errorClass );
229
+ }
230
+ },
231
+
232
+ // http://docs.jquery.com/Plugins/Validation/Validator/setDefaults
233
+ setDefaults: function(settings) {
234
+ $.extend( $.validator.defaults, settings );
235
+ },
236
+
237
+ messages: {
238
+ required: "This field is required.",
239
+ remote: "Please fix this field.",
240
+ email: "Please enter a valid email address.",
241
+ url: "Please enter a valid URL.",
242
+ date: "Please enter a valid date.",
243
+ dateISO: "Please enter a valid date (ISO).",
244
+ dateDE: "Bitte geben Sie ein gültiges Datum ein.",
245
+ number: "Please enter a valid number.",
246
+ numberDE: "Bitte geben Sie eine Nummer ein.",
247
+ digits: "Please enter only digits",
248
+ creditcard: "Please enter a valid credit card number.",
249
+ equalTo: "Please enter the same value again.",
250
+ accept: "Please enter a value with a valid extension.",
251
+ maxlength: $.format("Please enter no more than {0} characters."),
252
+ minlength: $.format("Please enter at least {0} characters."),
253
+ rangelength: $.format("Please enter a value between {0} and {1} characters long."),
254
+ range: $.format("Please enter a value between {0} and {1}."),
255
+ max: $.format("Please enter a value less than or equal to {0}."),
256
+ min: $.format("Please enter a value greater than or equal to {0}.")
257
+ },
258
+
259
+ autoCreateRanges: false,
260
+
261
+ prototype: {
262
+
263
+ init: function() {
264
+ this.labelContainer = $(this.settings.errorLabelContainer);
265
+ this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
266
+ this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer );
267
+ this.submitted = {};
268
+ this.valueCache = {};
269
+ this.pendingRequest = 0;
270
+ this.pending = {};
271
+ this.invalid = {};
272
+ this.reset();
273
+
274
+ var groups = (this.groups = {});
275
+ $.each(this.settings.groups, function(key, value) {
276
+ $.each(value.split(/\s/), function(index, name) {
277
+ groups[name] = key;
278
+ });
279
+ });
280
+ var rules = this.settings.rules;
281
+ $.each(rules, function(key, value) {
282
+ rules[key] = $.validator.normalizeRule(value);
283
+ });
284
+
285
+ function delegate(event) {
286
+ var validator = $.data(this[0].form, "validator");
287
+ validator.settings["on" + event.type] && validator.settings["on" + event.type].call(validator, this[0] );
288
+ }
289
+ $(this.currentForm)
290
+ .delegate("focusin focusout keyup", ":text, :password, :file, select, textarea", delegate)
291
+ .delegate("click", ":radio, :checkbox", delegate);
292
+
293
+ if (this.settings.invalidHandler)
294
+ $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
295
+ },
296
+
297
+ // http://docs.jquery.com/Plugins/Validation/Validator/form
298
+ form: function() {
299
+ this.checkForm();
300
+ $.extend(this.submitted, this.errorMap);
301
+ this.invalid = $.extend({}, this.errorMap);
302
+ if (!this.valid())
303
+ $(this.currentForm).triggerHandler("invalid-form", [this]);
304
+ this.showErrors();
305
+ return this.valid();
306
+ },
307
+
308
+ checkForm: function() {
309
+ this.prepareForm();
310
+ for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {
311
+ this.check( elements[i] );
312
+ }
313
+ return this.valid();
314
+ },
315
+
316
+ // http://docs.jquery.com/Plugins/Validation/Validator/element
317
+ element: function( element ) {
318
+ element = this.clean( element );
319
+ this.lastElement = element;
320
+ this.prepareElement( element );
321
+ this.currentElements = $(element);
322
+ var result = this.check( element );
323
+ if ( result ) {
324
+ delete this.invalid[element.name];
325
+ } else {
326
+ this.invalid[element.name] = true;
327
+ }
328
+ if ( !this.numberOfInvalids() ) {
329
+ // Hide error containers on last error
330
+ this.toHide = this.toHide.add( this.containers );
331
+ }
332
+ this.showErrors();
333
+ return result;
334
+ },
335
+
336
+ // http://docs.jquery.com/Plugins/Validation/Validator/showErrors
337
+ showErrors: function(errors) {
338
+ if(errors) {
339
+ // add items to error list and map
340
+ $.extend( this.errorMap, errors );
341
+ this.errorList = [];
342
+ for ( var name in errors ) {
343
+ this.errorList.push({
344
+ message: errors[name],
345
+ element: this.findByName(name)[0]
346
+ });
347
+ }
348
+ // remove items from success list
349
+ this.successList = $.grep( this.successList, function(element) {
350
+ return !(element.name in errors);
351
+ });
352
+ }
353
+ this.settings.showErrors
354
+ ? this.settings.showErrors.call( this, this.errorMap, this.errorList )
355
+ : this.defaultShowErrors();
356
+ },
357
+
358
+ // http://docs.jquery.com/Plugins/Validation/Validator/resetForm
359
+ resetForm: function() {
360
+ if ( $.fn.resetForm )
361
+ $( this.currentForm ).resetForm();
362
+ this.submitted = {};
363
+ this.prepareForm();
364
+ this.hideErrors();
365
+ this.elements().removeClass( this.settings.errorClass );
366
+ },
367
+
368
+ numberOfInvalids: function() {
369
+ return this.objectLength(this.invalid);
370
+ },
371
+
372
+ objectLength: function( obj ) {
373
+ var count = 0;
374
+ for ( var i in obj )
375
+ count++;
376
+ return count;
377
+ },
378
+
379
+ hideErrors: function() {
380
+ this.addWrapper( this.toHide ).hide();
381
+ },
382
+
383
+ valid: function() {
384
+ return this.size() == 0;
385
+ },
386
+
387
+ size: function() {
388
+ return this.errorList.length;
389
+ },
390
+
391
+ focusInvalid: function() {
392
+ if( this.settings.focusInvalid ) {
393
+ try {
394
+ $(this.findLastActive() || this.errorList.length && this.errorList[0].element || []).filter(":visible").focus();
395
+ } catch(e) {
396
+ // ignore IE throwing errors when focusing hidden elements
397
+ }
398
+ }
399
+ },
400
+
401
+ findLastActive: function() {
402
+ var lastActive = this.lastActive;
403
+ return lastActive && $.grep(this.errorList, function(n) {
404
+ return n.element.name == lastActive.name;
405
+ }).length == 1 && lastActive;
406
+ },
407
+
408
+ elements: function() {
409
+ var validator = this,
410
+ rulesCache = {};
411
+
412
+ // select all valid inputs inside the form (no submit or reset buttons)
413
+ // workaround $Query([]).add until http://dev.jquery.com/ticket/2114 is solved
414
+ return $([]).add(this.currentForm.elements)
415
+ .filter(":input")
416
+ .not(":submit, :reset, :image, [disabled]")
417
+ .not( this.settings.ignore )
418
+ .filter(function() {
419
+ !this.name && validator.settings.debug && window.console && console.error( "%o has no name assigned", this);
420
+
421
+ // select only the first element for each name, and only those with rules specified
422
+ if ( this.name in rulesCache || !validator.objectLength($(this).rules()) )
423
+ return false;
424
+
425
+ rulesCache[this.name] = true;
426
+ return true;
427
+ });
428
+ },
429
+
430
+ clean: function( selector ) {
431
+ return $( selector )[0];
432
+ },
433
+
434
+ errors: function() {
435
+ return $( this.settings.errorElement + "." + this.settings.errorClass, this.errorContext );
436
+ },
437
+
438
+ reset: function() {
439
+ this.successList = [];
440
+ this.errorList = [];
441
+ this.errorMap = {};
442
+ this.toShow = $([]);
443
+ this.toHide = $([]);
444
+ this.formSubmitted = false;
445
+ this.currentElements = $([]);
446
+ },
447
+
448
+ prepareForm: function() {
449
+ this.reset();
450
+ this.toHide = this.errors().add( this.containers );
451
+ },
452
+
453
+ prepareElement: function( element ) {
454
+ this.reset();
455
+ this.toHide = this.errorsFor(element);
456
+ },
457
+
458
+ check: function( element ) {
459
+ element = this.clean( element );
460
+
461
+ // if radio/checkbox, validate first element in group instead
462
+ if (this.checkable(element)) {
463
+ element = this.findByName( element.name )[0];
464
+ }
465
+
466
+ var rules = $(element).rules();
467
+ var dependencyMismatch = false;
468
+ for( method in rules ) {
469
+ var rule = { method: method, parameters: rules[method] };
470
+ try {
471
+ var result = $.validator.methods[method].call( this, element.value.replace(/\r/g, ""), element, rule.parameters );
472
+
473
+ // if a method indicates that the field is optional and therefore valid,
474
+ // don't mark it as valid when there are no other rules
475
+ if ( result == "dependency-mismatch" ) {
476
+ dependencyMismatch = true;
477
+ continue;
478
+ }
479
+ dependencyMismatch = false;
480
+
481
+ if ( result == "pending" ) {
482
+ this.toHide = this.toHide.not( this.errorsFor(element) );
483
+ return;
484
+ }
485
+
486
+ if( !result ) {
487
+ this.formatAndAdd( element, rule );
488
+ return false;
489
+ }
490
+ } catch(e) {
491
+ this.settings.debug && window.console && console.log("exception occured when checking element " + element.id
492
+ + ", check the '" + rule.method + "' method");
493
+ throw e;
494
+ }
495
+ }
496
+ if (dependencyMismatch)
497
+ return;
498
+ if ( this.objectLength(rules) )
499
+ this.successList.push(element);
500
+ return true;
501
+ },
502
+
503
+ // return the custom message for the given element and validation method
504
+ // specified in the element's "messages" metadata
505
+ customMetaMessage: function(element, method) {
506
+ if (!$.metadata)
507
+ return;
508
+
509
+ var meta = this.settings.meta
510
+ ? $(element).metadata()[this.settings.meta]
511
+ : $(element).metadata();
512
+
513
+ return meta && meta.messages && meta.messages[method];
514
+ },
515
+
516
+ // return the custom message for the given element name and validation method
517
+ customMessage: function( name, method ) {
518
+ var m = this.settings.messages[name];
519
+ return m && (m.constructor == String
520
+ ? m
521
+ : m[method]);
522
+ },
523
+
524
+ // return the first defined argument, allowing empty strings
525
+ findDefined: function() {
526
+ for(var i = 0; i < arguments.length; i++) {
527
+ if (arguments[i] !== undefined)
528
+ return arguments[i];
529
+ }
530
+ return undefined;
531
+ },
532
+
533
+ defaultMessage: function( element, method) {
534
+ return this.findDefined(
535
+ this.customMessage( element.name, method ),
536
+ this.customMetaMessage( element, method ),
537
+ // title is never undefined, so handle empty string as undefined
538
+ !this.settings.ignoreTitle && element.title || undefined,
539
+ $.validator.messages[method],
540
+ "<strong>Warning: No message defined for " + element.name + "</strong>"
541
+ );
542
+ },
543
+
544
+ formatAndAdd: function( element, rule ) {
545
+ var message = this.defaultMessage( element, rule.method );
546
+ if ( typeof message == "function" )
547
+ message = message.call(this, rule.parameters, element);
548
+ this.errorList.push({
549
+ message: message,
550
+ element: element
551
+ });
552
+ this.errorMap[element.name] = message;
553
+ this.submitted[element.name] = message;
554
+ },
555
+
556
+ addWrapper: function(toToggle) {
557
+ if ( this.settings.wrapper )
558
+ toToggle = toToggle.add( toToggle.parents( this.settings.wrapper ) );
559
+ return toToggle;
560
+ },
561
+
562
+ defaultShowErrors: function() {
563
+ for ( var i = 0; this.errorList[i]; i++ ) {
564
+ var error = this.errorList[i];
565
+ this.settings.highlight && this.settings.highlight.call( this, error.element, this.settings.errorClass );
566
+ this.showLabel( error.element, error.message );
567
+ }
568
+ if( this.errorList.length ) {
569
+ this.toShow = this.toShow.add( this.containers );
570
+ }
571
+ if (this.settings.success) {
572
+ for ( var i = 0; this.successList[i]; i++ ) {
573
+ this.showLabel( this.successList[i] );
574
+ }
575
+ }
576
+ if (this.settings.unhighlight) {
577
+ for ( var i = 0, elements = this.validElements(); elements[i]; i++ ) {
578
+ this.settings.unhighlight.call( this, elements[i], this.settings.errorClass );
579
+ }
580
+ }
581
+ this.toHide = this.toHide.not( this.toShow );
582
+ this.hideErrors();
583
+ this.addWrapper( this.toShow ).show();
584
+ },
585
+
586
+ validElements: function() {
587
+ return this.currentElements.not(this.invalidElements());
588
+ },
589
+
590
+ invalidElements: function() {
591
+ return $(this.errorList).map(function() {
592
+ return this.element;
593
+ });
594
+ },
595
+
596
+ showLabel: function(element, message) {
597
+ var label = this.errorsFor( element );
598
+ if ( label.length ) {
599
+ // refresh error/success class
600
+ label.removeClass().addClass( this.settings.errorClass );
601
+
602
+ // check if we have a generated label, replace the message then
603
+ label.attr("generated") && label.html(message);
604
+ } else {
605
+ // create label
606
+ label = $("<" + this.settings.errorElement + "/>")
607
+ .attr({"for": this.idOrName(element), generated: true})
608
+ .addClass(this.settings.errorClass)
609
+ .html(message || "");
610
+ if ( this.settings.wrapper ) {
611
+ // make sure the element is visible, even in IE
612
+ // actually showing the wrapped element is handled elsewhere
613
+ label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
614
+ }
615
+ if ( !this.labelContainer.append(label).length )
616
+ this.settings.errorPlacement
617
+ ? this.settings.errorPlacement(label, $(element) )
618
+ : label.insertAfter(element);
619
+ }
620
+ if ( !message && this.settings.success ) {
621
+ label.text("");
622
+ typeof this.settings.success == "string"
623
+ ? label.addClass( this.settings.success )
624
+ : this.settings.success( label );
625
+ }
626
+ this.toShow = this.toShow.add(label);
627
+ },
628
+
629
+ errorsFor: function(element) {
630
+ return this.errors().filter("[for='" + this.idOrName(element) + "']");
631
+ },
632
+
633
+ idOrName: function(element) {
634
+ return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
635
+ },
636
+
637
+ checkable: function( element ) {
638
+ return /radio|checkbox/i.test(element.type);
639
+ },
640
+
641
+ findByName: function( name ) {
642
+ // select by name and filter by form for performance over form.find("[name=...]")
643
+ var form = this.currentForm;
644
+ return $(document.getElementsByName(name)).map(function(index, element) {
645
+ return element.form == form && element.name == name && element || null;
646
+ });
647
+ },
648
+
649
+ getLength: function(value, element) {
650
+ switch( element.nodeName.toLowerCase() ) {
651
+ case 'select':
652
+ return $("option:selected", element).length;
653
+ case 'input':
654
+ if( this.checkable( element) )
655
+ return this.findByName(element.name).filter(':checked').length;
656
+ }
657
+ return value.length;
658
+ },
659
+
660
+ depend: function(param, element) {
661
+ return this.dependTypes[typeof param]
662
+ ? this.dependTypes[typeof param](param, element)
663
+ : true;
664
+ },
665
+
666
+ dependTypes: {
667
+ "boolean": function(param, element) {
668
+ return param;
669
+ },
670
+ "string": function(param, element) {
671
+ return !!$(param, element.form).length;
672
+ },
673
+ "function": function(param, element) {
674
+ return param(element);
675
+ }
676
+ },
677
+
678
+ optional: function(element) {
679
+ return !$.validator.methods.required.call(this, $.trim(element.value), element) && "dependency-mismatch";
680
+ },
681
+
682
+ startRequest: function(element) {
683
+ if (!this.pending[element.name]) {
684
+ this.pendingRequest++;
685
+ this.pending[element.name] = true;
686
+ }
687
+ },
688
+
689
+ stopRequest: function(element, valid) {
690
+ this.pendingRequest--;
691
+ // sometimes synchronization fails, make sure pendingRequest is never < 0
692
+ if (this.pendingRequest < 0)
693
+ this.pendingRequest = 0;
694
+ delete this.pending[element.name];
695
+ if ( valid && this.pendingRequest == 0 && this.formSubmitted && this.form() ) {
696
+ $(this.currentForm).submit();
697
+ } else if (!valid && this.pendingRequest == 0 && this.formSubmitted) {
698
+ $(this.currentForm).triggerHandler("invalid-form", [this]);
699
+ }
700
+ },
701
+
702
+ previousValue: function(element) {
703
+ return $.data(element, "previousValue") || $.data(element, "previousValue", previous = {
704
+ old: null,
705
+ valid: true,
706
+ message: this.defaultMessage( element, "remote" )
707
+ });
708
+ }
709
+
710
+ },
711
+
712
+ classRuleSettings: {
713
+ required: {required: true},
714
+ email: {email: true},
715
+ url: {url: true},
716
+ date: {date: true},
717
+ dateISO: {dateISO: true},
718
+ dateDE: {dateDE: true},
719
+ number: {number: true},
720
+ numberDE: {numberDE: true},
721
+ digits: {digits: true},
722
+ creditcard: {creditcard: true}
723
+ },
724
+
725
+ addClassRules: function(className, rules) {
726
+ className.constructor == String ?
727
+ this.classRuleSettings[className] = rules :
728
+ $.extend(this.classRuleSettings, className);
729
+ },
730
+
731
+ classRules: function(element) {
732
+ var rules = {};
733
+ var classes = $(element).attr('class');
734
+ classes && $.each(classes.split(' '), function() {
735
+ if (this in $.validator.classRuleSettings) {
736
+ $.extend(rules, $.validator.classRuleSettings[this]);
737
+ }
738
+ });
739
+ return rules;
740
+ },
741
+
742
+ attributeRules: function(element) {
743
+ var rules = {};
744
+ var $element = $(element);
745
+
746
+ for (method in $.validator.methods) {
747
+ var value = $element.attr(method);
748
+ if (value) {
749
+ rules[method] = value;
750
+ }
751
+ }
752
+
753
+ // maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs
754
+ if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) {
755
+ delete rules.maxlength;
756
+ }
757
+
758
+ return rules;
759
+ },
760
+
761
+ metadataRules: function(element) {
762
+ if (!$.metadata) return {};
763
+
764
+ var meta = $.data(element.form, 'validator').settings.meta;
765
+ return meta ?
766
+ $(element).metadata()[meta] :
767
+ $(element).metadata();
768
+ },
769
+
770
+ staticRules: function(element) {
771
+ var rules = {};
772
+ var validator = $.data(element.form, 'validator');
773
+ if (validator.settings.rules) {
774
+ rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
775
+ }
776
+ return rules;
777
+ },
778
+
779
+ normalizeRules: function(rules, element) {
780
+ // handle dependency check
781
+ $.each(rules, function(prop, val) {
782
+ // ignore rule when param is explicitly false, eg. required:false
783
+ if (val === false) {
784
+ delete rules[prop];
785
+ return;
786
+ }
787
+ if (val.param || val.depends) {
788
+ var keepRule = true;
789
+ switch (typeof val.depends) {
790
+ case "string":
791
+ keepRule = !!$(val.depends, element.form).length;
792
+ break;
793
+ case "function":
794
+ keepRule = val.depends.call(element, element);
795
+ break;
796
+ }
797
+ if (keepRule) {
798
+ rules[prop] = val.param !== undefined ? val.param : true;
799
+ } else {
800
+ delete rules[prop];
801
+ }
802
+ }
803
+ });
804
+
805
+ // evaluate parameters
806
+ $.each(rules, function(rule, parameter) {
807
+ rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter;
808
+ });
809
+
810
+ // clean number parameters
811
+ $.each(['minlength', 'maxlength', 'min', 'max'], function() {
812
+ if (rules[this]) {
813
+ rules[this] = Number(rules[this]);
814
+ }
815
+ });
816
+ $.each(['rangelength', 'range'], function() {
817
+ if (rules[this]) {
818
+ rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
819
+ }
820
+ });
821
+
822
+ if ($.validator.autoCreateRanges) {
823
+ // auto-create ranges
824
+ if (rules.min && rules.max) {
825
+ rules.range = [rules.min, rules.max];
826
+ delete rules.min;
827
+ delete rules.max;
828
+ }
829
+ if (rules.minlength && rules.maxlength) {
830
+ rules.rangelength = [rules.minlength, rules.maxlength];
831
+ delete rules.minlength;
832
+ delete rules.maxlength;
833
+ }
834
+ }
835
+
836
+ // To support custom messages in metadata ignore rule methods titled "messages"
837
+ if (rules.messages) {
838
+ delete rules.messages
839
+ }
840
+
841
+ return rules;
842
+ },
843
+
844
+ // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
845
+ normalizeRule: function(data) {
846
+ if( typeof data == "string" ) {
847
+ var transformed = {};
848
+ $.each(data.split(/\s/), function() {
849
+ transformed[this] = true;
850
+ });
851
+ data = transformed;
852
+ }
853
+ return data;
854
+ },
855
+
856
+ // http://docs.jquery.com/Plugins/Validation/Validator/addMethod
857
+ addMethod: function(name, method, message) {
858
+ $.validator.methods[name] = method;
859
+ $.validator.messages[name] = message;
860
+ if (method.length < 3) {
861
+ $.validator.addClassRules(name, $.validator.normalizeRule(name));
862
+ }
863
+ },
864
+
865
+ methods: {
866
+
867
+ // http://docs.jquery.com/Plugins/Validation/Methods/required
868
+ required: function(value, element, param) {
869
+ // check if dependency is met
870
+ if ( !this.depend(param, element) )
871
+ return "dependency-mismatch";
872
+ switch( element.nodeName.toLowerCase() ) {
873
+ case 'select':
874
+ var options = $("option:selected", element);
875
+ return options.length > 0 && ( element.type == "select-multiple" || ($.browser.msie && !(options[0].attributes['value'].specified) ? options[0].text : options[0].value).length > 0);
876
+ case 'input':
877
+ if ( this.checkable(element) )
878
+ return this.getLength(value, element) > 0;
879
+ default:
880
+ return $.trim(value).length > 0;
881
+ }
882
+ },
883
+
884
+ // http://docs.jquery.com/Plugins/Validation/Methods/remote
885
+ remote: function(value, element, param) {
886
+ if ( this.optional(element) )
887
+ return "dependency-mismatch";
888
+
889
+ var previous = this.previousValue(element);
890
+
891
+ if (!this.settings.messages[element.name] )
892
+ this.settings.messages[element.name] = {};
893
+ this.settings.messages[element.name].remote = typeof previous.message == "function" ? previous.message(value) : previous.message;
894
+
895
+ param = typeof param == "string" && {url:param} || param;
896
+
897
+ if ( previous.old !== value ) {
898
+ previous.old = value;
899
+ var validator = this;
900
+ this.startRequest(element);
901
+ var data = {};
902
+ data[element.name] = value;
903
+ $.ajax($.extend(true, {
904
+ url: param,
905
+ mode: "abort",
906
+ port: "validate" + element.name,
907
+ dataType: "json",
908
+ data: data,
909
+ success: function(response) {
910
+ if ( response ) {
911
+ var submitted = validator.formSubmitted;
912
+ validator.prepareElement(element);
913
+ validator.formSubmitted = submitted;
914
+ validator.successList.push(element);
915
+ validator.showErrors();
916
+ } else {
917
+ var errors = {};
918
+ errors[element.name] = response || validator.defaultMessage( element, "remote" );
919
+ validator.showErrors(errors);
920
+ }
921
+ previous.valid = response;
922
+ validator.stopRequest(element, response);
923
+ }
924
+ }, param));
925
+ return "pending";
926
+ } else if( this.pending[element.name] ) {
927
+ return "pending";
928
+ }
929
+ return previous.valid;
930
+ },
931
+
932
+ // http://docs.jquery.com/Plugins/Validation/Methods/minlength
933
+ minlength: function(value, element, param) {
934
+ return this.optional(element) || this.getLength($.trim(value), element) >= param;
935
+ },
936
+
937
+ // http://docs.jquery.com/Plugins/Validation/Methods/maxlength
938
+ maxlength: function(value, element, param) {
939
+ return this.optional(element) || this.getLength($.trim(value), element) <= param;
940
+ },
941
+
942
+ // http://docs.jquery.com/Plugins/Validation/Methods/rangelength
943
+ rangelength: function(value, element, param) {
944
+ var length = this.getLength($.trim(value), element);
945
+ return this.optional(element) || ( length >= param[0] && length <= param[1] );
946
+ },
947
+
948
+ // http://docs.jquery.com/Plugins/Validation/Methods/min
949
+ min: function( value, element, param ) {
950
+ return this.optional(element) || value >= param;
951
+ },
952
+
953
+ // http://docs.jquery.com/Plugins/Validation/Methods/max
954
+ max: function( value, element, param ) {
955
+ return this.optional(element) || value <= param;
956
+ },
957
+
958
+ // http://docs.jquery.com/Plugins/Validation/Methods/range
959
+ range: function( value, element, param ) {
960
+ return this.optional(element) || ( value >= param[0] && value <= param[1] );
961
+ },
962
+
963
+ // http://docs.jquery.com/Plugins/Validation/Methods/email
964
+ email: function(value, element) {
965
+ // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
966
+ return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value);
967
+ },
968
+
969
+ // http://docs.jquery.com/Plugins/Validation/Methods/url
970
+ url: function(value, element) {
971
+ // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
972
+ return 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);
973
+ },
974
+
975
+ // http://docs.jquery.com/Plugins/Validation/Methods/date
976
+ date: function(value, element) {
977
+ return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
978
+ },
979
+
980
+ // http://docs.jquery.com/Plugins/Validation/Methods/dateISO
981
+ dateISO: function(value, element) {
982
+ return this.optional(element) || /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value);
983
+ },
984
+
985
+ // http://docs.jquery.com/Plugins/Validation/Methods/dateDE
986
+ dateDE: function(value, element) {
987
+ return this.optional(element) || /^\d\d?\.\d\d?\.\d\d\d?\d?$/.test(value);
988
+ },
989
+
990
+ // http://docs.jquery.com/Plugins/Validation/Methods/number
991
+ number: function(value, element) {
992
+ return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value);
993
+ },
994
+
995
+ // http://docs.jquery.com/Plugins/Validation/Methods/numberDE
996
+ numberDE: function(value, element) {
997
+ return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(value);
998
+ },
999
+
1000
+ // http://docs.jquery.com/Plugins/Validation/Methods/digits
1001
+ digits: function(value, element) {
1002
+ return this.optional(element) || /^\d+$/.test(value);
1003
+ },
1004
+
1005
+ // http://docs.jquery.com/Plugins/Validation/Methods/creditcard
1006
+ // based on http://en.wikipedia.org/wiki/Luhn
1007
+ creditcard: function(value, element) {
1008
+ if ( this.optional(element) )
1009
+ return "dependency-mismatch";
1010
+ // accept only digits and dashes
1011
+ if (/[^0-9-]+/.test(value))
1012
+ return false;
1013
+ var nCheck = 0,
1014
+ nDigit = 0,
1015
+ bEven = false;
1016
+
1017
+ value = value.replace(/\D/g, "");
1018
+
1019
+ for (n = value.length - 1; n >= 0; n--) {
1020
+ var cDigit = value.charAt(n);
1021
+ var nDigit = parseInt(cDigit, 10);
1022
+ if (bEven) {
1023
+ if ((nDigit *= 2) > 9)
1024
+ nDigit -= 9;
1025
+ }
1026
+ nCheck += nDigit;
1027
+ bEven = !bEven;
1028
+ }
1029
+
1030
+ return (nCheck % 10) == 0;
1031
+ },
1032
+
1033
+ // http://docs.jquery.com/Plugins/Validation/Methods/accept
1034
+ accept: function(value, element, param) {
1035
+ param = typeof param == "string" ? param : "png|jpe?g|gif";
1036
+ return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i"));
1037
+ },
1038
+
1039
+ // http://docs.jquery.com/Plugins/Validation/Methods/equalTo
1040
+ equalTo: function(value, element, param) {
1041
+ return value == $(param).val();
1042
+ }
1043
+
1044
+ }
1045
+
1046
+ });
1047
+
1048
+ })(jQuery);
1049
+
1050
+ // ajax mode: abort
1051
+ // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
1052
+ // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
1053
+ ;(function($) {
1054
+ var ajax = $.ajax;
1055
+ var pendingRequests = {};
1056
+ $.ajax = function(settings) {
1057
+ // create settings for compatibility with ajaxSetup
1058
+ settings = $.extend(settings, $.extend({}, $.ajaxSettings, settings));
1059
+ var port = settings.port;
1060
+ if (settings.mode == "abort") {
1061
+ if ( pendingRequests[port] ) {
1062
+ pendingRequests[port].abort();
1063
+ }
1064
+ return (pendingRequests[port] = ajax.apply(this, arguments));
1065
+ }
1066
+ return ajax.apply(this, arguments);
1067
+ };
1068
+ })(jQuery);
1069
+
1070
+ // provides cross-browser focusin and focusout events
1071
+ // IE has native support, in other browsers, use event caputuring (neither bubbles)
1072
+
1073
+ // provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
1074
+ // handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
1075
+
1076
+ // provides triggerEvent(type: String, target: Element) to trigger delegated events
1077
+ ;(function($) {
1078
+ $.each({
1079
+ focus: 'focusin',
1080
+ blur: 'focusout'
1081
+ }, function( original, fix ){
1082
+ $.event.special[fix] = {
1083
+ setup:function() {
1084
+ if ( $.browser.msie ) return false;
1085
+ this.addEventListener( original, $.event.special[fix].handler, true );
1086
+ },
1087
+ teardown:function() {
1088
+ if ( $.browser.msie ) return false;
1089
+ this.removeEventListener( original,
1090
+ $.event.special[fix].handler, true );
1091
+ },
1092
+ handler: function(e) {
1093
+ arguments[0] = $.event.fix(e);
1094
+ arguments[0].type = fix;
1095
+ return $.event.handle.apply(this, arguments);
1096
+ }
1097
+ };
1098
+ });
1099
+ $.extend($.fn, {
1100
+ delegate: function(type, delegate, handler) {
1101
+ return this.bind(type, function(event) {
1102
+ var target = $(event.target);
1103
+ if (target.is(delegate)) {
1104
+ return handler.apply(target, arguments);
1105
+ }
1106
+ });
1107
+ },
1108
+ triggerEvent: function(type, target) {
1109
+ return this.triggerHandler(type, [$.event.fix({ type: type, target: target })]);
1110
+ }
1111
+ })
1112
+ })(jQuery);