Contact Form 7 - Version 3.3

Version Description

  • New: Introduce a new special mail tag [_user_agent] for user agent information.
  • New: Make WordPress Comment Blacklist applicable for inputs through contact forms.
  • New: Introduce new form of mail tag [_raw_{field name}]. This allows to output raw user input those have not been modified with pipes.
  • New: Make mail tags available in response messages.
  • New: Introduce new additional setting on_submit. It works like on_sent_ok and has one-line JavaScript code, but on_submit code is fired regardless of whether or not the mail has been sent successfully.
  • New: Introduce 5 new jQuery custom event triggers (invalid.wpcf7, spam.wpcf7, mailsent.wpcf7, mailfailed.wpcf7, submit.wpcf7).
  • Fix: Nonce used in a form have been changed to have no time limit.
  • Fix: Make every post metas key have underscore prefix.
  • The jQuery Form Plugin (jquery.form.js) has been updated to 3.15 and compressed with YUI compressor.
  • The required WordPress version has been changed and now requires WordPress 3.3 or higher. If you use WordPress 3.2, you will need to upgrade WordPress.
  • Translations for Arabic and German have been updated.

=

Download this release

Release Info

Developer takayukister
Plugin Icon 128x128 Contact Form 7
Version 3.3
Comparing to
See all releases

Code changes from version 3.2.1 to 3.3

admin/admin.php CHANGED
@@ -235,34 +235,6 @@ function wpcf7_admin_enqueue_scripts( $hook_suffix ) {
235
'tagGenerators' => wpcf7_tag_generators() ) );
236
}
237
238
- add_action( 'admin_print_footer_scripts', 'wpcf7_print_taggenerators_json', 20 );
239
-
240
- function wpcf7_print_taggenerators_json() { // for backward compatibility
241
- global $plugin_page, $wpcf7_tag_generators;
242
-
243
- if ( ! version_compare( get_bloginfo( 'version' ), '3.3-dev', '<' ) )
244
- return;
245
-
246
- if ( ! isset( $plugin_page ) || 'wpcf7' != $plugin_page )
247
- return;
248
-
249
- $taggenerators = array();
250
-
251
- foreach ( (array) $wpcf7_tag_generators as $name => $tg ) {
252
- $taggenerators[$name] = array_merge(
253
- (array) $tg['options'],
254
- array( 'title' => $tg['title'], 'content' => $tg['content'] ) );
255
- }
256
-
257
- ?>
258
- <script type="text/javascript">
259
- /* <![CDATA[ */
260
- _wpcf7.tagGenerators = <?php echo json_encode( $taggenerators ) ?>;
261
- /* ]]> */
262
- </script>
263
- <?php
264
- }
265
-
266
function wpcf7_admin_management_page() {
267
global $wpcf7_contact_form;
268
235
'tagGenerators' => wpcf7_tag_generators() ) );
236
}
237
238
function wpcf7_admin_management_page() {
239
global $wpcf7_contact_form;
240
includes/classes.php CHANGED
@@ -65,11 +65,14 @@ class WPCF7_ContactForm {
65
$this->id = $post->ID;
66
$this->title = $post->post_title;
67
68
- $this->form = get_post_meta( $post->ID, 'form', true );
69
- $this->mail = get_post_meta( $post->ID, 'mail', true );
70
- $this->mail_2 = get_post_meta( $post->ID, 'mail_2', true );
71
- $this->messages = get_post_meta( $post->ID, 'messages', true );
72
- $this->additional_settings = get_post_meta( $post->ID, 'additional_settings', true );
73
74
$this->upgrade();
75
}
@@ -77,6 +80,17 @@ class WPCF7_ContactForm {
77
do_action_ref_array( 'wpcf7_contact_form', array( &$this ) );
78
}
79
80
// Return true if this form is the same one as currently POSTed.
81
function is_posted() {
82
if ( ! isset( $_POST['_wpcf7_unit_tag'] ) || empty( $_POST['_wpcf7_unit_tag'] ) )
@@ -119,16 +133,14 @@ class WPCF7_ContactForm {
119
$class = 'wpcf7-form';
120
121
if ( $this->is_posted() ) {
122
- if ( ! empty( $_POST['_wpcf7_validation_errors'] ) ) {
123
$class .= ' invalid';
124
- } elseif ( ! empty( $_POST['_wpcf7_mail_sent'] ) ) {
125
- if ( ! empty( $_POST['_wpcf7_mail_sent']['spam'] ) )
126
- $class .= ' spam';
127
- elseif ( ! empty( $_POST['_wpcf7_mail_sent']['ok'] ) )
128
- $class .= ' sent';
129
- else
130
- $class .= ' failed';
131
- }
132
}
133
134
$class = apply_filters( 'wpcf7_form_class_attr', $class );
@@ -159,7 +171,7 @@ class WPCF7_ContactForm {
159
'_wpcf7_unit_tag' => $this->unit_tag );
160
161
if ( WPCF7_VERIFY_NONCE )
162
- $hidden_fields['_wpnonce'] = wpcf7_create_nonce( $this->unit_tag );
163
164
$content = '';
165
@@ -177,20 +189,18 @@ class WPCF7_ContactForm {
177
$content = '';
178
179
if ( $this->is_posted() ) { // Post response output for non-AJAX
180
- if ( isset( $_POST['_wpcf7_mail_sent'] ) && $_POST['_wpcf7_mail_sent']['id'] == $this->id ) {
181
- if ( $_POST['_wpcf7_mail_sent']['ok'] ) {
182
- $class .= ' wpcf7-mail-sent-ok';
183
- $content = $_POST['_wpcf7_mail_sent']['message'];
184
- } else {
185
- $class .= ' wpcf7-mail-sent-ng';
186
- if ( $_POST['_wpcf7_mail_sent']['spam'] )
187
- $class .= ' wpcf7-spam-blocked';
188
- $content = $_POST['_wpcf7_mail_sent']['message'];
189
- }
190
- } elseif ( isset( $_POST['_wpcf7_validation_errors'] ) && $_POST['_wpcf7_validation_errors']['id'] == $this->id ) {
191
$class .= ' wpcf7-validation-errors';
192
- $content = $this->message( 'validation_error' );
193
- }
194
} else {
195
$class .= ' wpcf7-display-none';
196
}
@@ -204,17 +214,16 @@ class WPCF7_ContactForm {
204
if ( ! $this->is_posted() )
205
return '';
206
207
- if ( ! isset( $_POST['_wpcf7_validation_errors']['messages'][$name] ) )
208
return '';
209
210
- $ve = trim( $_POST['_wpcf7_validation_errors']['messages'][$name] );
211
212
- if ( ! empty( $ve ) ) {
213
- $ve = '<span class="wpcf7-not-valid-tip-no-ajax">' . esc_html( $ve ) . '</span>';
214
- return apply_filters( 'wpcf7_validation_error', $ve, $name, $this );
215
- }
216
217
- return '';
218
}
219
220
/* Form Elements */
@@ -334,7 +343,8 @@ class WPCF7_ContactForm {
334
'spam' => false,
335
'message' => '',
336
'mail_sent' => false,
337
- 'scripts_on_sent_ok' => null );
338
339
$this->setup_posted_data();
340
@@ -371,6 +381,13 @@ class WPCF7_ContactForm {
371
$result['message'] = $this->message( 'mail_sent_ng' );
372
}
373
374
// remove upload files
375
foreach ( (array) $this->uploaded_files as $name => $path ) {
376
@unlink( $path );
@@ -407,11 +424,24 @@ class WPCF7_ContactForm {
407
if ( WPCF7_VERIFY_NONCE && ! $this->verify_nonce() )
408
$spam = true;
409
410
return apply_filters( 'wpcf7_spam', $spam );
411
}
412
413
function verify_nonce() {
414
- return wpcf7_verify_nonce( $_POST['_wpnonce'], $_POST['_wpcf7_unit_tag'] );
415
}
416
417
/* Mail */
@@ -464,24 +494,18 @@ class WPCF7_ContactForm {
464
function compose_mail( $mail_template, $send = true ) {
465
$this->mail_template_in_process = $mail_template;
466
467
- $regex = '/(\[?)\[\s*([a-zA-Z_][0-9a-zA-Z:._-]*)\s*\](\]?)/';
468
-
469
$use_html = (bool) $mail_template['use_html'];
470
471
- $callback = array( &$this, 'mail_callback' );
472
- $callback_html = array( &$this, 'mail_callback_html' );
473
-
474
- $subject = preg_replace_callback( $regex, $callback, $mail_template['subject'] );
475
- $sender = preg_replace_callback( $regex, $callback, $mail_template['sender'] );
476
- $recipient = preg_replace_callback( $regex, $callback, $mail_template['recipient'] );
477
- $additional_headers =
478
- preg_replace_callback( $regex, $callback, $mail_template['additional_headers'] );
479
480
if ( $use_html ) {
481
- $body = preg_replace_callback( $regex, $callback_html, $mail_template['body'] );
482
$body = wpautop( $body );
483
} else {
484
- $body = preg_replace_callback( $regex, $callback, $mail_template['body'] );
485
}
486
487
$attachments = array();
@@ -514,6 +538,17 @@ class WPCF7_ContactForm {
514
return compact( 'subject', 'sender', 'body', 'recipient', 'headers', 'attachments' );
515
}
516
517
function mail_callback_html( $matches ) {
518
return $this->mail_callback( $matches, true );
519
}
@@ -536,12 +571,12 @@ class WPCF7_ContactForm {
536
$replaced = wptexturize( $replaced );
537
}
538
539
- $replaced = apply_filters( 'wpcf7_mail_tag_replaced', $replaced, $submitted );
540
541
return stripslashes( $replaced );
542
}
543
544
- if ( $special = apply_filters( 'wpcf7_special_mail_tags', '', $matches[2] ) )
545
return $special;
546
547
return $matches[0];
@@ -553,6 +588,8 @@ class WPCF7_ContactForm {
553
$messages = $this->messages;
554
$message = isset( $messages[$status] ) ? $messages[$status] : '';
555
556
return apply_filters( 'wpcf7_display_message', $message, $status );
557
}
558
@@ -610,16 +647,9 @@ class WPCF7_ContactForm {
610
/* Save */
611
612
function save() {
613
- $metas = array( 'form', 'mail', 'mail_2', 'messages', 'additional_settings' );
614
615
- $post_content = '';
616
-
617
- foreach ( $metas as $meta ) {
618
- $props = (array) $this->{$meta};
619
-
620
- foreach ( $props as $prop )
621
- $post_content .= "\n" . trim( $prop );
622
- }
623
624
if ( $this->initial ) {
625
$post_id = wp_insert_post( array(
@@ -636,8 +666,8 @@ class WPCF7_ContactForm {
636
}
637
638
if ( $post_id ) {
639
- foreach ( $metas as $meta )
640
- update_post_meta( $post_id, $meta, wpcf7_normalize_newline_deep( $this->{$meta} ) );
641
642
if ( $this->initial ) {
643
$this->initial = false;
@@ -658,11 +688,10 @@ class WPCF7_ContactForm {
658
$new->initial = true;
659
$new->title = $this->title . '_copy';
660
661
- $new->form = $this->form;
662
- $new->mail = $this->mail;
663
- $new->mail_2 = $this->mail_2;
664
- $new->messages = $this->messages;
665
- $new->additional_settings = $this->additional_settings;
666
667
$new = apply_filters_ref_array( 'wpcf7_copy', array( &$new, &$this ) );
668
@@ -738,11 +767,10 @@ function wpcf7_get_contact_form_default_pack( $args = '' ) {
738
739
$contact_form->title = ( $title ? $title : __( 'Untitled', 'wpcf7' ) );
740
741
- $contact_form->form = wpcf7_get_default_template( 'form' );
742
- $contact_form->mail = wpcf7_get_default_template( 'mail' );
743
- $contact_form->mail_2 = wpcf7_get_default_template( 'mail_2' );
744
- $contact_form->messages = wpcf7_get_default_template( 'messages' );
745
- $contact_form->additional_settings = wpcf7_get_default_template( 'additional_settings' );
746
747
if ( isset( $mo_orig ) )
748
$l10n['wpcf7'] = $mo_orig;
65
$this->id = $post->ID;
66
$this->title = $post->post_title;
67
68
+ $props = $this->get_properties();
69
+
70
+ foreach ( $props as $prop => $value ) {
71
+ if ( metadata_exists( 'post', $post->ID, '_' . $prop ) )
72
+ $this->{$prop} = get_post_meta( $post->ID, '_' . $prop, true );
73
+ else
74
+ $this->{$prop} = get_post_meta( $post->ID, $prop, true );
75
+ }
76
77
$this->upgrade();
78
}
80
do_action_ref_array( 'wpcf7_contact_form', array( &$this ) );
81
}
82
83
+ function get_properties() {
84
+ $prop_names = array( 'form', 'mail', 'mail_2', 'messages', 'additional_settings' );
85
+
86
+ $properties = array();
87
+
88
+ foreach ( $prop_names as $prop_name )
89
+ $properties[$prop_name] = isset( $this->{$prop_name} ) ? $this->{$prop_name} : '';
90
+
91
+ return apply_filters( 'wpcf7_contact_form_properties', $properties, $this );
92
+ }
93
+
94
// Return true if this form is the same one as currently POSTed.
95
function is_posted() {
96
if ( ! isset( $_POST['_wpcf7_unit_tag'] ) || empty( $_POST['_wpcf7_unit_tag'] ) )
133
$class = 'wpcf7-form';
134
135
if ( $this->is_posted() ) {
136
+ if ( empty( $_POST['_wpcf7_result']['valid'] ) )
137
$class .= ' invalid';
138
+ elseif ( ! empty( $_POST['_wpcf7_result']['spam'] ) )
139
+ $class .= ' spam';
140
+ elseif ( ! empty( $_POST['_wpcf7_result']['mail_sent'] ) )
141
+ $class .= ' sent';
142
+ else
143
+ $class .= ' failed';
144
}
145
146
$class = apply_filters( 'wpcf7_form_class_attr', $class );
171
'_wpcf7_unit_tag' => $this->unit_tag );
172
173
if ( WPCF7_VERIFY_NONCE )
174
+ $hidden_fields['_wpnonce'] = wpcf7_create_nonce( $this->id );
175
176
$content = '';
177
189
$content = '';
190
191
if ( $this->is_posted() ) { // Post response output for non-AJAX
192
+
193
+ if ( empty( $_POST['_wpcf7_result']['valid'] ) )
194
$class .= ' wpcf7-validation-errors';
195
+ elseif ( ! empty( $_POST['_wpcf7_result']['spam'] ) )
196
+ $class .= ' wpcf7-spam-blocked';
197
+ elseif ( ! empty( $_POST['_wpcf7_result']['mail_sent'] ) )
198
+ $class .= ' wpcf7-mail-sent-ok';
199
+ else
200
+ $class .= ' wpcf7-mail-sent-ng';
201
+
202
+ $content = $_POST['_wpcf7_result']['message'];
203
+
204
} else {
205
$class .= ' wpcf7-display-none';
206
}
214
if ( ! $this->is_posted() )
215
return '';
216
217
+ if ( ! isset( $_POST['_wpcf7_result']['invalid_reasons'][$name] ) )
218
return '';
219
220
+ $ve = trim( $_POST['_wpcf7_result']['invalid_reasons'][$name] );
221
222
+ if ( empty( $ve ) )
223
+ return '';
224
225
+ $ve = '<span class="wpcf7-not-valid-tip-no-ajax">' . esc_html( $ve ) . '</span>';
226
+ return apply_filters( 'wpcf7_validation_error', $ve, $name, $this );
227
}
228
229
/* Form Elements */
343
'spam' => false,
344
'message' => '',
345
'mail_sent' => false,
346
+ 'scripts_on_sent_ok' => null,
347
+ 'scripts_on_submit' => null );
348
349
$this->setup_posted_data();
350
381
$result['message'] = $this->message( 'mail_sent_ng' );
382
}
383
384
+ if ( $ajax ) {
385
+ $on_submit = $this->additional_setting( 'on_submit', false );
386
+
387
+ if ( ! empty( $on_submit ) )
388
+ $result['scripts_on_submit'] = array_map( 'wpcf7_strip_quote', $on_submit );
389
+ }
390
+
391
// remove upload files
392
foreach ( (array) $this->uploaded_files as $name => $path ) {
393
@unlink( $path );
424
if ( WPCF7_VERIFY_NONCE && ! $this->verify_nonce() )
425
$spam = true;
426
427
+ if ( $this->blacklist_check() )
428
+ $spam = true;
429
+
430
return apply_filters( 'wpcf7_spam', $spam );
431
}
432
433
function verify_nonce() {
434
+ return wpcf7_verify_nonce( $_POST['_wpnonce'], $this->id );
435
+ }
436
+
437
+ function blacklist_check() {
438
+ $target = wpcf7_array_flatten( $this->posted_data );
439
+ $target[] = $_SERVER['REMOTE_ADDR'];
440
+ $target[] = $_SERVER['HTTP_USER_AGENT'];
441
+
442
+ $target = implode( "\n", $target );
443
+
444
+ return wpcf7_blacklist_check( $target );
445
}
446
447
/* Mail */
494
function compose_mail( $mail_template, $send = true ) {
495
$this->mail_template_in_process = $mail_template;
496
497
$use_html = (bool) $mail_template['use_html'];
498
499
+ $subject = $this->replace_mail_tags( $mail_template['subject'] );
500
+ $sender = $this->replace_mail_tags( $mail_template['sender'] );
501
+ $recipient = $this->replace_mail_tags( $mail_template['recipient'] );
502
+ $additional_headers = $this->replace_mail_tags( $mail_template['additional_headers'] );
503
504
if ( $use_html ) {
505
+ $body = $this->replace_mail_tags( $mail_template['body'], true );
506
$body = wpautop( $body );
507
} else {
508
+ $body = $this->replace_mail_tags( $mail_template['body'] );
509
}
510
511
$attachments = array();
538
return compact( 'subject', 'sender', 'body', 'recipient', 'headers', 'attachments' );
539
}
540
541
+ function replace_mail_tags( $content, $html = false ) {
542
+ $regex = '/(\[?)\[\s*([a-zA-Z_][0-9a-zA-Z:._-]*)\s*\](\]?)/';
543
+
544
+ if ( $html )
545
+ $callback = array( &$this, 'mail_callback_html' );
546
+ else
547
+ $callback = array( &$this, 'mail_callback' );
548
+
549
+ return preg_replace_callback( $regex, $callback, $content );
550
+ }
551
+
552
function mail_callback_html( $matches ) {
553
return $this->mail_callback( $matches, true );
554
}
571
$replaced = wptexturize( $replaced );
572
}
573
574
+ $replaced = apply_filters( 'wpcf7_mail_tag_replaced', $replaced, $submitted, $html );
575
576
return stripslashes( $replaced );
577
}
578
579
+ if ( $special = apply_filters( 'wpcf7_special_mail_tags', '', $matches[2], $html ) )
580
return $special;
581
582
return $matches[0];
588
$messages = $this->messages;
589
$message = isset( $messages[$status] ) ? $messages[$status] : '';
590
591
+ $message = $this->replace_mail_tags( $message, true );
592
+
593
return apply_filters( 'wpcf7_display_message', $message, $status );
594
}
595
647
/* Save */
648
649
function save() {
650
+ $props = $this->get_properties();
651
652
+ $post_content = implode( "\n", wpcf7_array_flatten( $props ) );
653
654
if ( $this->initial ) {
655
$post_id = wp_insert_post( array(
666
}
667
668
if ( $post_id ) {
669
+ foreach ( $props as $prop => $value )
670
+ update_post_meta( $post_id, '_' . $prop, wpcf7_normalize_newline_deep( $value ) );
671
672
if ( $this->initial ) {
673
$this->initial = false;
688
$new->initial = true;
689
$new->title = $this->title . '_copy';
690
691
+ $props = $this->get_properties();
692
+
693
+ foreach ( $props as $prop => $value )
694
+ $new->{$prop} = $value;
695
696
$new = apply_filters_ref_array( 'wpcf7_copy', array( &$new, &$this ) );
697
767
768
$contact_form->title = ( $title ? $title : __( 'Untitled', 'wpcf7' ) );
769
770
+ $props = $contact_form->get_properties();
771
+
772
+ foreach ( $props as $prop => $value )
773
+ $contact_form->{$prop} = wpcf7_get_default_template( $prop );
774
775
if ( isset( $mo_orig ) )
776
$l10n['wpcf7'] = $mo_orig;
includes/controller.php CHANGED
@@ -80,6 +80,9 @@ function wpcf7_ajax_json_echo() {
80
if ( ! empty( $result['scripts_on_sent_ok'] ) )
81
$items['onSentOk'] = $result['scripts_on_sent_ok'];
82
83
$items = apply_filters( 'wpcf7_ajax_json_echo', $items, $result );
84
85
$wpcf7_contact_form = null;
@@ -114,23 +117,10 @@ function wpcf7_submit_nonajax() {
114
115
$id = (int) $_POST['_wpcf7'];
116
117
- if ( $wpcf7_contact_form = wpcf7_contact_form( $id ) ) {
118
- $result = $wpcf7_contact_form->submit();
119
-
120
- if ( ! $result['valid'] ) {
121
- $_POST['_wpcf7_validation_errors'] = array(
122
- 'id' => $id,
123
- 'messages' => $result['invalid_reasons'] );
124
- } else {
125
- $_POST['_wpcf7_mail_sent'] = array(
126
- 'id' => $id,
127
- 'ok' => $result['mail_sent'],
128
- 'message' => $result['message'],
129
- 'spam' => $result['spam'] );
130
- }
131
132
- $wpcf7_contact_form = null;
133
- }
134
}
135
136
add_action( 'the_post', 'wpcf7_the_post' );
@@ -237,8 +227,8 @@ function wpcf7_enqueue_scripts() {
237
// so we need to deregister it and re-register the latest one
238
wp_deregister_script( 'jquery-form' );
239
wp_register_script( 'jquery-form',
240
- wpcf7_plugin_url( 'includes/js/jquery.form.js' ),
241
- array( 'jquery' ), '3.14', true );
242
243
$in_footer = true;
244
if ( 'header' === WPCF7_LOAD_JS )
80
if ( ! empty( $result['scripts_on_sent_ok'] ) )
81
$items['onSentOk'] = $result['scripts_on_sent_ok'];
82
83
+ if ( ! empty( $result['scripts_on_submit'] ) )
84
+ $items['onSubmit'] = $result['scripts_on_submit'];
85
+
86
$items = apply_filters( 'wpcf7_ajax_json_echo', $items, $result );
87
88
$wpcf7_contact_form = null;
117
118
$id = (int) $_POST['_wpcf7'];
119
120
+ if ( $wpcf7_contact_form = wpcf7_contact_form( $id ) )
121
+ $_POST['_wpcf7_result'] = $wpcf7_contact_form->submit();
122
123
+ $wpcf7_contact_form = null;
124
}
125
126
add_action( 'the_post', 'wpcf7_the_post' );
227
// so we need to deregister it and re-register the latest one
228
wp_deregister_script( 'jquery-form' );
229
wp_register_script( 'jquery-form',
230
+ wpcf7_plugin_url( 'includes/js/jquery.form.min.js' ),
231
+ array( 'jquery' ), '3.15', true );
232
233
$in_footer = true;
234
if ( 'header' === WPCF7_LOAD_JS )
includes/functions.php CHANGED
@@ -262,32 +262,48 @@ function wpcf7_ajax_loader() {
262
return apply_filters( 'wpcf7_ajax_loader', $url );
263
}
264
265
- /* Nonce functions: wpcf7_verify_nonce() and wpcf7_create_nonce()
266
- * For front-end use only.
267
- * Almost the same as wp_verify_nonce() and wp_create_nonce() except that $uid is always 0.
268
- */
269
-
270
function wpcf7_verify_nonce( $nonce, $action = -1 ) {
271
- $i = wp_nonce_tick();
272
- $uid = 0;
273
274
- // Nonce generated 0-12 hours ago
275
- if ( substr( wp_hash( $i . $action . $uid, 'nonce' ), -12, 10 ) == $nonce )
276
- return 1;
277
278
- // Nonce generated 12-24 hours ago
279
- if ( substr( wp_hash( ( $i - 1 ) . $action . $uid, 'nonce' ), -12, 10 ) == $nonce )
280
- return 2;
281
282
- // Invalid nonce
283
return false;
284
}
285
286
- function wpcf7_create_nonce( $action = -1 ) {
287
- $i = wp_nonce_tick();
288
- $uid = 0;
289
290
- return substr( wp_hash( $i . $action . $uid, 'nonce' ), -12, 10 );
291
}
292
293
?>
262
return apply_filters( 'wpcf7_ajax_loader', $url );
263
}
264
265
function wpcf7_verify_nonce( $nonce, $action = -1 ) {
266
+ if ( substr( wp_hash( $action, 'nonce' ), -12, 10 ) == $nonce )
267
+ return true;
268
+
269
+ return false;
270
+ }
271
+
272
+ function wpcf7_create_nonce( $action = -1 ) {
273
+ return substr( wp_hash( $action, 'nonce' ), -12, 10 );
274
+ }
275
+
276
+ function wpcf7_blacklist_check( $target ) {
277
+ $mod_keys = trim( get_option( 'blacklist_keys' ) );
278
279
+ if ( empty( $mod_keys ) )
280
+ return false;
281
282
+ $words = explode( "\n", $mod_keys );
283
+
284
+ foreach ( (array) $words as $word ) {
285
+ $word = trim( $word );
286
+
287
+ if ( empty( $word ) )
288
+ continue;
289
+
290
+ if ( preg_match( '#' . preg_quote( $word, '#' ) . '#', $target ) )
291
+ return true;
292
+ }
293
294
return false;
295
}
296
297
+ function wpcf7_array_flatten( $input ) {
298
+ if ( ! is_array( $input ) )
299
+ return array( $input );
300
+
301
+ $output = array();
302
+
303
+ foreach ( $input as $value )
304
+ $output = array_merge( $output, wpcf7_array_flatten( $value ) );
305
306
+ return $output;
307
}
308
309
?>
includes/js/jquery.form.dev.js DELETED
@@ -1,1089 +0,0 @@
1
- /*!
2
- * jQuery Form Plugin
3
- * version: 3.14 (30-JUL-2012)
4
- * @requires jQuery v1.3.2 or later
5
- *
6
- * Examples and documentation at: http://malsup.com/jquery/form/
7
- * Project repository: https://github.com/malsup/form
8
- * Dual licensed under the MIT and GPL licenses:
9
- * http://malsup.github.com/mit-license.txt
10
- * http://malsup.github.com/gpl-license-v2.txt
11
- */
12
- /*global ActiveXObject alert */
13
- ;(function($) {
14
- "use strict";
15
-
16
- /*
17
- Usage Note:
18
- -----------
19
- Do not use both ajaxSubmit and ajaxForm on the same form. These
20
- functions are mutually exclusive. Use ajaxSubmit if you want
21
- to bind your own submit handler to the form. For example,
22
-
23
- $(document).ready(function() {
24
- $('#myForm').on('submit', function(e) {
25
- e.preventDefault(); // <-- important
26
- $(this).ajaxSubmit({
27
- target: '#output'
28
- });
29
- });
30
- });
31
-
32
- Use ajaxForm when you want the plugin to manage all the event binding
33
- for you. For example,
34
-
35
- $(document).ready(function() {
36
- $('#myForm').ajaxForm({
37
- target: '#output'
38
- });
39
- });
40
-
41
- You can also use ajaxForm with delegation (requires jQuery v1.7+), so the
42
- form does not have to exist when you invoke ajaxForm:
43
-
44
- $('#myForm').ajaxForm({
45
- delegation: true,
46
- target: '#output'
47
- });
48
-
49
- When using ajaxForm, the ajaxSubmit function will be invoked for you
50
- at the appropriate time.
51
- */
52
-
53
- /**
54
- * Feature detection
55
- */
56
- var feature = {};
57
- feature.fileapi = $("<input type='file'/>").get(0).files !== undefined;
58
- feature.formdata = window.FormData !== undefined;
59
-
60
- /**
61
- * ajaxSubmit() provides a mechanism for immediately submitting
62
- * an HTML form using AJAX.
63
- */
64
- $.fn.ajaxSubmit = function(options) {
65
- /*jshint scripturl:true */
66
-
67
- // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
68
- if (!this.length) {
69
- log('ajaxSubmit: skipping submit process - no element selected');
70
- return this;
71
- }
72
-
73
- var method, action, url, $form = this;
74
-
75
- if (typeof options == 'function') {
76
- options = { success: options };
77
- }
78
-
79
- method = this.attr('method');
80
- action = this.attr('action');
81
- url = (typeof action === 'string') ? $.trim(action) : '';
82
- url = url || window.location.href || '';
83
- if (url) {
84
- // clean url (don't include hash vaue)
85
- url = (url.match(/^([^#]+)/)||[])[1];
86
- }
87
-
88
- options = $.extend(true, {
89
- url: url,
90
- success: $.ajaxSettings.success,
91
- type: method || 'GET',
92
- iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
93
- }, options);
94
-
95
- // hook for manipulating the form data before it is extracted;
96
- // convenient for use with rich editors like tinyMCE or FCKEditor
97
- var veto = {};
98
- this.trigger('form-pre-serialize', [this, options, veto]);
99
- if (veto.veto) {
100
- log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
101
- return this;
102
- }
103
-
104
- // provide opportunity to alter form data before it is serialized
105
- if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
106
- log('ajaxSubmit: submit aborted via beforeSerialize callback');
107
- return this;
108
- }
109
-
110
- var traditional = options.traditional;
111
- if ( traditional === undefined ) {
112
- traditional = $.ajaxSettings.traditional;
113
- }
114
-
115
- var elements = [];
116
- var qx, a = this.formToArray(options.semantic, elements);
117
- if (options.data) {
118
- options.extraData = options.data;
119
- qx = $.param(options.data, traditional);
120
- }
121
-
122
- // give pre-submit callback an opportunity to abort the submit
123
- if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
124
- log('ajaxSubmit: submit aborted via beforeSubmit callback');
125
- return this;
126
- }
127
-
128
- // fire vetoable 'validate' event
129
- this.trigger('form-submit-validate', [a, this, options, veto]);
130
- if (veto.veto) {
131
- log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
132
- return this;
133
- }
134
-
135
- var q = $.param(a, traditional);
136
- if (qx) {
137
- q = ( q ? (q + '&' + qx) : qx );
138
- }
139
- if (options.type.toUpperCase() == 'GET') {
140
- options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
141
- options.data = null; // data is null for 'get'
142
- }
143
- else {
144
- options.data = q; // data is the query string for 'post'
145
- }
146
-
147
- var callbacks = [];
148
- if (options.resetForm) {
149
- callbacks.push(function() { $form.resetForm(); });
150
- }
151
- if (options.clearForm) {
152
- callbacks.push(function() { $form.clearForm(options.includeHidden); });
153
- }
154
-
155
- // perform a load on the target only if dataType is not provided
156
- if (!options.dataType && options.target) {
157
- var oldSuccess = options.success || function(){};
158
- callbacks.push(function(data) {
159
- var fn = options.replaceTarget ? 'replaceWith' : 'html';
160
- $(options.target)[fn](data).each(oldSuccess, arguments);
161
- });
162
- }
163
- else if (options.success) {
164
- callbacks.push(options.success);
165
- }
166
-
167
- options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
168
- var context = options.context || this ; // jQuery 1.4+ supports scope context
169
- for (var i=0, max=callbacks.length; i < max; i++) {
170
- callbacks[i].apply(context, [data, status, xhr || $form, $form]);
171
- }
172
- };
173
-
174
- // are there files to upload?
175
- var fileInputs = $('input:file:enabled[value]', this); // [value] (issue #113)
176
- var hasFileInputs = fileInputs.length > 0;
177
- var mp = 'multipart/form-data';
178
- var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
179
-
180
- var fileAPI = feature.fileapi && feature.formdata;
181
- log("fileAPI :" + fileAPI);
182
- var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;
183
-
184
- // options.iframe allows user to force iframe mode
185
- // 06-NOV-09: now defaulting to iframe mode if file input is detected
186
- if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
187
- // hack to fix Safari hang (thanks to Tim Molendijk for this)
188
- // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
189
- if (options.closeKeepAlive) {
190
- $.get(options.closeKeepAlive, function() {
191
- fileUploadIframe(a);
192
- });
193
- }
194
- else {
195
- fileUploadIframe(a);
196
- }
197
- }
198
- else if ((hasFileInputs || multipart) && fileAPI) {
199
- fileUploadXhr(a);
200
- }
201
- else {
202
- $.ajax(options);
203
- }
204
-
205
- // clear element array
206
- for (var k=0; k < elements.length; k++)
207
- elements[k] = null;
208
-
209
- // fire 'notify' event
210
- this.trigger('form-submit-notify', [this, options]);
211
- return this;
212
-
213
- // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)
214
- function fileUploadXhr(a) {
215
- var formdata = new FormData();
216
-
217
- for (var i=0; i < a.length; i++) {
218
- formdata.append(a[i].name, a[i].value);
219
- }
220
-
221
- if (options.extraData) {
222
- for (var p in options.extraData)
223
- if (options.extraData.hasOwnProperty(p))
224
- formdata.append(p, options.extraData[p]);
225
- }
226
-
227
- options.data = null;
228
-
229
- var s = $.extend(true, {}, $.ajaxSettings, options, {
230
- contentType: false,
231
- processData: false,
232
- cache: false,
233
- type: 'POST'
234
- });
235
-
236
- if (options.uploadProgress) {
237
- // workaround because jqXHR does not expose upload property
238
- s.xhr = function() {
239
- var xhr = jQuery.ajaxSettings.xhr();
240
- if (xhr.upload) {
241
- xhr.upload.onprogress = function(event) {
242
- var percent = 0;
243
- var position = event.loaded || event.position; /*event.position is deprecated*/
244
- var total = event.total;
245
- if (event.lengthComputable) {
246
- percent = Math.ceil(position / total * 100);
247
- }
248
- options.uploadProgress(event, position, total, percent);
249
- };
250
- }
251
- return xhr;
252
- };
253
- }
254
-
255
- s.data = null;
256
- var beforeSend = s.beforeSend;
257
- s.beforeSend = function(xhr, o) {
258
- o.data = formdata;
259
- if(beforeSend)
260
- beforeSend.call(this, xhr, o);
261
- };
262
- $.ajax(s);
263
- }
264
-
265
- // private function for handling file uploads (hat tip to YAHOO!)
266
- function fileUploadIframe(a) {
267
- var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
268
- var useProp = !!$.fn.prop;
269
-
270
- if ($(':input[name=submit],:input[id=submit]', form).length) {
271
- // if there is an input with a name or id of 'submit' then we won't be
272
- // able to invoke the submit fn on the form (at least not x-browser)
273
- alert('Error: Form elements must not have name or id of "submit".');
274
- return;
275
- }
276
-
277
- if (a) {
278
- // ensure that every serialized input is still enabled
279
- for (i=0; i < elements.length; i++) {
280
- el = $(elements[i]);
281
- if ( useProp )
282
- el.prop('disabled', false);
283
- else
284
- el.removeAttr('disabled');
285
- }
286
- }
287
-
288
- s = $.extend(true, {}, $.ajaxSettings, options);
289
- s.context = s.context || s;
290
- id = 'jqFormIO' + (new Date().getTime());
291
- if (s.iframeTarget) {
292
- $io = $(s.iframeTarget);
293
- n = $io.attr('name');
294
- if (!n)
295
- $io.attr('name', id);
296
- else
297
- id = n;
298
- }
299
- else {
300
- $io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />');
301
- $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
302
- }
303
- io = $io[0];
304
-
305
-
306
- xhr = { // mock object
307
- aborted: 0,
308
- responseText: null,
309
- responseXML: null,
310
- status: 0,
311
- statusText: 'n/a',
312
- getAllResponseHeaders: function() {},
313
- getResponseHeader: function() {},
314
- setRequestHeader: function() {},
315
- abort: function(status) {
316
- var e = (status === 'timeout' ? 'timeout' : 'aborted');
317
- log('aborting upload... ' + e);
318
- this.aborted = 1;
319
- // #214
320
- if (io.contentWindow.document.execCommand) {
321
- try { // #214
322
- io.contentWindow.document.execCommand('Stop');
323
- } catch(ignore) {}
324
- }
325
- $io.attr('src', s.iframeSrc); // abort op in progress
326
- xhr.error = e;
327
- if (s.error)
328
- s.error.call(s.context, xhr, e, status);
329
- if (g)
330
- $.event.trigger("ajaxError", [xhr, s, e]);
331
- if (s.complete)
332
- s.complete.call(s.context, xhr, e);
333
- }
334
- };
335
-
336
- g = s.global;
337
- // trigger ajax global events so that activity/block indicators work like normal
338
- if (g && 0 === $.active++) {
339
- $.event.trigger("ajaxStart");
340
- }
341
- if (g) {
342
- $.event.trigger("ajaxSend", [xhr, s]);
343
- }
344
-
345
- if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
346
- if (s.global) {
347
- $.active--;
348
- }
349
- return;
350
- }
351
- if (xhr.aborted) {
352
- return;
353
- }
354
-
355
- // add submitting element to data if we know it
356
- sub = form.clk;
357
- if (sub) {
358
- n = sub.name;
359
- if (n && !sub.disabled) {
360
- s.extraData = s.extraData || {};
361
- s.extraData[n] = sub.value;
362
- if (sub.type == "image") {
363
- s.extraData[n+'.x'] = form.clk_x;
364
- s.extraData[n+'.y'] = form.clk_y;
365
- }
366
- }
367
- }
368
-
369
- var CLIENT_TIMEOUT_ABORT = 1;
370
- var SERVER_ABORT = 2;
371
-
372
- function getDoc(frame) {
373
- var doc = frame.contentWindow ? frame.contentWindow.document : frame.contentDocument ? frame.contentDocument : frame.document;
374
- return doc;
375
- }
376
-
377
- // Rails CSRF hack (thanks to Yvan Barthelemy)
378
- var csrf_token = $('meta[name=csrf-token]').attr('content');
379
- var csrf_param = $('meta[name=csrf-param]').attr('content');
380
- if (csrf_param && csrf_token) {
381
- s.extraData = s.extraData || {};
382
- s.extraData[csrf_param] = csrf_token;
383
- }
384
-
385
- // take a breath so that pending repaints get some cpu time before the upload starts
386
- function doSubmit() {
387
- // make sure form attrs are set
388
- var t = $form.attr('target'), a = $form.attr('action');
389
-
390
- // update form attrs in IE friendly way
391
- form.setAttribute('target',id);
392
- if (!method) {
393
- form.setAttribute('method', 'POST');
394
- }
395
- if (a != s.url) {
396
- form.setAttribute('action', s.url);
397
- }
398
-
399
- // ie borks in some cases when setting encoding
400
- if (! s.skipEncodingOverride && (!method || /post/i.test(method))) {
401
- $form.attr({
402
- encoding: 'multipart/form-data',
403
- enctype: 'multipart/form-data'
404
- });
405
- }
406
-
407
- // support timout
408
- if (s.timeout) {
409
- timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout);
410
- }
411
-
412
- // look for server aborts
413
- function checkState() {
414
- try {
415
- var state = getDoc(io).readyState;
416
- log('state = ' + state);
417
- if (state && state.toLowerCase() == 'uninitialized')
418
- setTimeout(checkState,50);
419
- }
420
- catch(e) {
421
- log('Server abort: ' , e, ' (', e.name, ')');
422
- cb(SERVER_ABORT);
423
- if (timeoutHandle)
424
- clearTimeout(timeoutHandle);
425
- timeoutHandle = undefined;
426
- }
427
- }
428
-
429
- // add "extra" data to form if provided in options
430
- var extraInputs = [];
431
- try {
432
- if (s.extraData) {
433
- for (var n in s.extraData) {
434
- if (s.extraData.hasOwnProperty(n)) {
435
- // if using the $.param format that allows for multiple values with the same name
436
- if($.isPlainObject(s.extraData[n]) && s.extraData[n].hasOwnProperty('name') && s.extraData[n].hasOwnProperty('value')) {
437
- extraInputs.push(
438
- $('<input type="hidden" name="'+s.extraData[n].name+'">').attr('value',s.extraData[n].value)
439
- .appendTo(form)[0]);
440
- } else {
441
- extraInputs.push(
442
- $('<input type="hidden" name="'+n+'">').attr('value',s.extraData[n])
443
- .appendTo(form)[0]);
444
- }
445
- }
446
- }
447
- }
448
-
449
- if (!s.iframeTarget) {
450
- // add iframe to doc and submit the form
451
- $io.appendTo('body');
452
- if (io.attachEvent)
453
- io.attachEvent('onload', cb);
454
- else
455
- io.addEventListener('load', cb, false);
456
- }
457
- setTimeout(checkState,15);
458
- form.submit();
459
- }
460
- finally {
461
- // reset attrs and remove "extra" input elements
462
- form.setAttribute('action',a);
463
- if(t) {
464
- form.setAttribute('target', t);
465
- } else {
466
- $form.removeAttr('target');
467
- }
468
- $(extraInputs).remove();
469
- }
470
- }
471
-
472
- if (s.forceSync) {
473
- doSubmit();
474
- }
475
- else {
476
- setTimeout(doSubmit, 10); // this lets dom updates render
477
- }
478
-
479
- var data, doc, domCheckCount = 50, callbackProcessed;
480
-
481
- function cb(e) {
482
- if (xhr.aborted || callbackProcessed) {
483
- return;
484
- }
485
- try {
486
- doc = getDoc(io);
487
- }
488
- catch(ex) {
489
- log('cannot access response document: ', ex);
490
- e = SERVER_ABORT;
491
- }
492
- if (e === CLIENT_TIMEOUT_ABORT && xhr) {
493
- xhr.abort('timeout');
494
- return;
495
- }
496
- else if (e == SERVER_ABORT && xhr) {
497
- xhr.abort('server abort');
498
- return;
499
- }
500
-
501
- if (!doc || doc.location.href == s.iframeSrc) {
502
- // response not received yet
503
- if (!timedOut)
504
- return;
505
- }
506
- if (io.detachEvent)
507
- io.detachEvent('onload', cb);
508
- else
509
- io.removeEventListener('load', cb, false);
510
-
511
- var status = 'success', errMsg;
512
- try {
513
- if (timedOut) {
514
- throw 'timeout';
515
- }
516
-
517
- var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
518
- log('isXml='+isXml);
519
- if (!isXml && window.opera && (doc.body === null || !doc.body.innerHTML)) {
520
- if (--domCheckCount) {
521
- // in some browsers (Opera) the iframe DOM is not always traversable when
522
- // the onload callback fires, so we loop a bit to accommodate
523
- log('requeing onLoad callback, DOM not available');
524
- setTimeout(cb, 250);
525
- return;
526
- }
527
- // let this fall through because server response could be an empty document
528
- //log('Could not access iframe DOM after mutiple tries.');
529
- //throw 'DOMException: not available';
530
- }
531
-
532
- //log('response detected');
533
- var docRoot = doc.body ? doc.body : doc.documentElement;
534
- xhr.responseText = docRoot ? docRoot.innerHTML : null;
535
- xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
536
- if (isXml)
537
- s.dataType = 'xml';
538
- xhr.getResponseHeader = function(header){
539
- var headers = {'content-type': s.dataType};
540
- return headers[header];
541
- };
542
- // support for XHR 'status' & 'statusText' emulation :
543
- if (docRoot) {
544
- xhr.status = Number( docRoot.getAttribute('status') ) || xhr.status;
545
- xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText;
546
- }
547
-
548
- var dt = (s.dataType || '').toLowerCase();
549
- var scr = /(json|script|text)/.test(dt);
550
- if (scr || s.textarea) {
551
- // see if user embedded response in textarea
552
- var ta = doc.getElementsByTagName('textarea')[0];
553
- if (ta) {
554
- xhr.responseText = ta.value;
555
- // support for XHR 'status' & 'statusText' emulation :
556
- xhr.status = Number( ta.getAttribute('status') ) || xhr.status;
557
- xhr.statusText = ta.getAttribute('statusText') || xhr.statusText;
558
- }
559
- else if (scr) {
560
- // account for browsers injecting pre around json response
561
- var pre = doc.getElementsByTagName('pre')[0];
562
- var b = doc.getElementsByTagName('body')[0];
563
- if (pre) {
564
- xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;
565
- }
566
- else if (b) {
567
- xhr.responseText = b.textContent ? b.textContent : b.innerText;
568
- }
569
- }
570
- }
571
- else if (dt == 'xml' && !xhr.responseXML && xhr.responseText) {
572
- xhr.responseXML = toXml(xhr.responseText);
573
- }
574
-
575
- try {
576
- data = httpData(xhr, dt, s);
577
- }
578
- catch (e) {
579
- status = 'parsererror';
580
- xhr.error = errMsg = (e || status);
581
- }
582
- }
583
- catch (e) {
584
- log('error caught: ',e);
585
- status = 'error';
586
- xhr.error = errMsg = (e || status);
587
- }
588
-
589
- if (xhr.aborted) {
590
- log('upload aborted');
591
- status = null;
592
- }
593
-
594
- if (xhr.status) { // we've set xhr.status
595
- status = (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) ? 'success' : 'error';
596
- }
597
-
598
- // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
599
- if (status === 'success') {
600
- if (s.success)
601
- s.success.call(s.context, data, 'success', xhr);
602
- if (g)
603
- $.event.trigger("ajaxSuccess", [xhr, s]);
604
- }
605
- else if (status) {
606
- if (errMsg === undefined)
607
- errMsg = xhr.statusText;
608
- if (s.error)
609
- s.error.call(s.context, xhr, status, errMsg);
610
- if (g)
611
- $.event.trigger("ajaxError", [xhr, s, errMsg]);
612
- }
613
-
614
- if (g)
615
- $.event.trigger("ajaxComplete", [xhr, s]);
616
-
617
- if (g && ! --$.active) {
618
- $.event.trigger("ajaxStop");
619
- }
620
-
621
- if (s.complete)
622
- s.complete.call(s.context, xhr, status);
623
-
624
- callbackProcessed = true;
625
- if (s.timeout)
626
- clearTimeout(timeoutHandle);
627
-
628
- // clean up
629
- setTimeout(function() {
630
- if (!s.iframeTarget)
631
- $io.remove();
632
- xhr.responseXML = null;
633
- }, 100);
634
- }
635
-
636
- var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
637
- if (window.ActiveXObject) {
638
- doc = new ActiveXObject('Microsoft.XMLDOM');
639
- doc.async = 'false';
640
- doc.loadXML(s);
641
- }
642
- else {
643
- doc = (new DOMParser()).parseFromString(s, 'text/xml');
644
- }
645
- return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null;
646
- };
647
- var parseJSON = $.parseJSON || function(s) {
648
- /*jslint evil:true */
649
- return window['eval']('(' + s + ')');
650
- };
651
-
652
- var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4
653
-
654
- var ct = xhr.getResponseHeader('content-type') || '',
655
- xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,
656
- data = xml ? xhr.responseXML : xhr.responseText;
657
-
658
- if (xml && data.documentElement.nodeName === 'parsererror') {
659
- if ($.error)
660
- $.error('parsererror');
661
- }
662
- if (s && s.dataFilter) {
663
- data = s.dataFilter(data, type);
664
- }
665
- if (typeof data === 'string') {
666
- if (type === 'json' || !type && ct.indexOf('json') >= 0) {
667
- data = parseJSON(data);
668
- } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
669
- $.globalEval(data);
670
- }
671
- }
672
- return data;
673
- };
674
- }
675
- };
676
-
677
- /**
678
- * ajaxForm() provides a mechanism for fully automating form submission.
679
- *
680
- * The advantages of using this method instead of ajaxSubmit() are:
681
- *
682
- * 1: This method will include coordinates for <input type="image" /> elements (if the element
683
- * is used to submit the form).
684
- * 2. This method will include the submit element's name/value data (for the element that was
685
- * used to submit the form).
686
- * 3. This method binds the submit() method to the form for you.
687
- *
688
- * The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely
689
- * passes the options argument along after properly binding events for submit elements and
690
- * the form itself.
691
- */
692
- $.fn.ajaxForm = function(options) {
693
- options = options || {};
694
- options.delegation = options.delegation && $.isFunction($.fn.on);
695
-
696
- // in jQuery 1.3+ we can fix mistakes with the ready state
697
- if (!options.delegation && this.length === 0) {
698
- var o = { s: this.selector, c: this.context };
699
- if (!$.isReady && o.s) {
700
- log('DOM not ready, queuing ajaxForm');
701
- $(function() {
702
- $(o.s,o.c).ajaxForm(options);
703
- });
704
- return this;
705
- }
706
- // is your DOM ready? http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
707
- log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
708
- return this;
709
- }
710
-
711
- if ( options.delegation ) {
712
- $(document)
713
- .off('submit.form-plugin', this.selector, doAjaxSubmit)
714
- .off('click.form-plugin', this.selector, captureSubmittingElement)
715
- .on('submit.form-plugin', this.selector, options, doAjaxSubmit)
716
- .on('click.form-plugin', this.selector, options, captureSubmittingElement);
717
- return this;
718
- }
719
-
720
- return this.ajaxFormUnbind()
721
- .bind('submit.form-plugin', options, doAjaxSubmit)
722
- .bind('click.form-plugin', options, captureSubmittingElement);
723
- };
724
-
725
- // private event handlers
726
- function doAjaxSubmit(e) {
727
- /*jshint validthis:true */
728
- var options = e.data;
729
- if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
730
- e.preventDefault();
731
- $(this).ajaxSubmit(options);
732
- }
733
- }
734
-
735
- function captureSubmittingElement(e) {
736
- /*jshint validthis:true */
737
- var target = e.target;
738
- var $el = $(target);
739
- if (!($el.is(":submit,input:image"))) {
740
- // is this a child element of the submit el? (ex: a span within a button)
741
- var t = $el.closest(':submit');
742
- if (t.length === 0) {
743
- return;
744
- }
745
- target = t[0];
746
- }
747
- var form = this;
748
- form.clk = target;
749
- if (target.type == 'image') {
750
- if (e.offsetX !== undefined) {
751
- form.clk_x = e.offsetX;
752
- form.clk_y = e.offsetY;
753
- } else if (typeof $.fn.offset == 'function') {
754
- var offset = $el.offset();
755
- form.clk_x = e.pageX - offset.left;
756
- form.clk_y = e.pageY - offset.top;
757
- } else {
758
- form.clk_x = e.pageX - target.offsetLeft;
759
- form.clk_y = e.pageY - target.offsetTop;
760
- }
761
- }
762
- // clear form vars
763
- setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
764
- }
765
-
766
-
767
- // ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
768
- $.fn.ajaxFormUnbind = function() {
769
- return this.unbind('submit.form-plugin click.form-plugin');
770
- };
771
-
772
- /**
773
- * formToArray() gathers form element data into an array of objects that can
774
- * be passed to any of the following ajax functions: $.get, $.post, or load.
775
- * Each object in the array has both a 'name' and 'value' property. An example of
776
- * an array for a simple login form might be:
777
- *
778
- * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
779
- *
780
- * It is this array that is passed to pre-submit callback functions provided to the
781
- * ajaxSubmit() and ajaxForm() methods.
782
- */
783
- $.fn.formToArray = function(semantic, elements) {
784
- var a = [];
785
- if (this.length === 0) {
786
- return a;
787
- }
788
-
789
- var form = this[0];
790
- var els = semantic ? form.getElementsByTagName('*') : form.elements;
791
- if (!els) {
792
- return a;
793
- }
794
-
795
- var i,j,n,v,el,max,jmax;
796
- for(i=0, max=els.length; i < max; i++) {
797
- el = els[i];
798
- n = el.name;
799
- if (!n) {
800
- continue;
801
- }
802
-
803
- if (semantic && form.clk && el.type == "image") {
804
- // handle image inputs on the fly when semantic == true
805
- if(!el.disabled && form.clk == el) {
806
- a.push({name: n, value: $(el).val(), type: el.type });
807
- a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
808
- }
809
- continue;
810
- }
811
-
812
- v = $.fieldValue(el, true);
813
- if (v && v.constructor == Array) {
814
- if (elements)
815
- elements.push(el);
816
- for(j=0, jmax=v.length; j < jmax; j++) {
817
- a.push({name: n, value: v[j]});
818
- }
819
- }
820
- else if (feature.fileapi && el.type == 'file' && !el.disabled) {
821
- if (elements)
822
- elements.push(el);
823
- var files = el.files;
824
- if (files.length) {
825
- for (j=0; j < files.length; j++) {
826
- a.push({name: n, value: files[j], type: el.type});
827
- }
828
- }
829
- else {
830
- // #180
831
- a.push({ name: n, value: '', type: el.type });
832
- }
833
- }
834
- else if (v !== null && typeof v != 'undefined') {
835
- if (elements)
836
- elements.push(el);
837
- a.push({name: n, value: v, type: el.type, required: el.required});
838
- }
839
- }
840
-
841
- if (!semantic && form.clk) {
842
- // input type=='image' are not found in elements array! handle it here
843
- var $input = $(form.clk), input = $input[0];
844
- n = input.name;
845
- if (n && !input.disabled && input.type == 'image') {
846
- a.push({name: n, value: $input.val()});
847
- a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
848
- }
849
- }
850
- return a;
851
- };
852
-
853
- /**
854
- * Serializes form data into a 'submittable' string. This method will return a string
855
- * in the format: name1=value1&amp;name2=value2
856
- */
857
- $.fn.formSerialize = function(semantic) {
858
- //hand off to jQuery.param for proper encoding
859
- return $.param(this.formToArray(semantic));
860
- };
861
-
862
- /**
863
- * Serializes all field elements in the jQuery object into a query string.
864
- * This method will return a string in the format: name1=value1&amp;name2=value2
865
- */
866
- $.fn.fieldSerialize = function(successful) {
867
- var a = [];
868
- this.each(function() {
869
- var n = this.name;
870
- if (!n) {
871
- return;
872
- }
873
- var v = $.fieldValue(this, successful);
874
- if (v && v.constructor == Array) {
875
- for (var i=0,max=v.length; i < max; i++) {
876
- a.push({name: n, value: v[i]});
877
- }
878
- }
879
- else if (v !== null && typeof v != 'undefined') {
880
- a.push({name: this.name, value: v});
881
- }
882
- });
883
- //hand off to jQuery.param for proper encoding
884
- return $.param(a);
885
- };
886
-
887
- /**
888
- * Returns the value(s) of the element in the matched set. For example, consider the following form:
889
- *
890
- * <form><fieldset>
891
- * <input name="A" type="text" />
892
- * <input name="A" type="text" />
893
- * <input name="B" type="checkbox" value="B1" />
894
- * <input name="B" type="checkbox" value="B2"/>
895
- * <input name="C" type="radio" value="C1" />
896
- * <input name="C" type="radio" value="C2" />
897
- * </fieldset></form>
898
- *
899
- * var v = $(':text').fieldValue();
900
- * // if no values are entered into the text inputs
901
- * v == ['','']
902
- * // if values entered into the text inputs are 'foo' and 'bar'
903
- * v == ['foo','bar']
904
- *
905
- * var v = $(':checkbox').fieldValue();
906
- * // if neither checkbox is checked
907
- * v === undefined
908
- * // if both checkboxes are checked
909
- * v == ['B1', 'B2']
910
- *
911
- * var v = $(':radio').fieldValue();
912
- * // if neither radio is checked
913
- * v === undefined
914
- * // if first radio is checked
915
- * v == ['C1']
916
- *
917
- * The successful argument controls whether or not the field element must be 'successful'
918
- * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
919
- * The default value of the successful argument is true. If this value is false the value(s)
920
- * for each element is returned.
921
- *
922
- * Note: This method *always* returns an array. If no valid value can be determined the
923
- * array will be empty, otherwise it will contain one or more values.
924
- */
925
- $.fn.fieldValue = function(successful) {
926
- for (var val=[], i=0, max=this.length; i < max; i++) {
927
- var el = this[i];
928
- var v = $.fieldValue(el, successful);
929
- if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
930
- continue;
931
- }
932
- if (v.constructor == Array)
933
- $.merge(val, v);
934
- else
935
- val.push(v);
936
- }
937
- return val;
938
- };
939
-
940
- /**
941
- * Returns the value of the field element.
942
- */
943
- $.fieldValue = function(el, successful) {
944
- var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
945
- if (successful === undefined) {
946
- successful = true;
947
- }
948
-
949
- if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
950
- (t == 'checkbox' || t == 'radio') && !el.checked ||
951
- (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
952
- tag == 'select' && el.selectedIndex == -1)) {
953
- return null;
954
- }
955
-
956
- if (tag == 'select') {
957
- var index = el.selectedIndex;
958
- if (index < 0) {
959
- return null;
960
- }
961
- var a = [], ops = el.options;
962
- var one = (t == 'select-one');
963
- var max = (one ? index+1 : ops.length);
964
- for(var i=(one ? index : 0); i < max; i++) {
965
- var op = ops[i];
966
- if (op.selected) {
967
- var v = op.value;
968
- if (!v) { // extra pain for IE...
969
- v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
970
- }
971
- if (one) {
972
- return v;
973
- }
974
- a.push(v);
975
- }
976
- }
977
- return a;
978
- }
979
- return $(el).val();
980
- };
981
-
982
- /**
983
- * Clears the form data. Takes the following actions on the form's input fields:
984
- * - input text fields will have their 'value' property set to the empty string
985
- * - select elements will have their 'selectedIndex' property set to -1
986
- * - checkbox and radio inputs will have their 'checked' property set to false
987
- * - inputs of type submit, button, reset, and hidden will *not* be effected
988
- * - button elements will *not* be effected
989
- */
990
- $.fn.clearForm = function(includeHidden) {
991
- return this.each(function() {
992
- $('input,select,textarea', this).clearFields(includeHidden);
993
- });
994
- };
995
-
996
- /**
997
- * Clears the selected form elements.
998
- */
999
- $.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
1000
- var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)#x2F;i; // 'hidden' is not in this list
1001
- return this.each(function() {
1002
- var t = this.type, tag = this.tagName.toLowerCase();
1003
- if (re.test(t) || tag == 'textarea') {
1004
- this.value = '';
1005
- }
1006
- else if (t == 'checkbox' || t == 'radio') {
1007
- this.checked = false;
1008
- }
1009
- else if (tag == 'select') {
1010
- this.selectedIndex = -1;
1011
- }
1012
- else if (includeHidden) {
1013
- // includeHidden can be the value true, or it can be a selector string
1014
- // indicating a special test; for example:
1015
- // $('#myForm').clearForm('.special:hidden')
1016
- // the above would clean hidden inputs that have the class of 'special'
1017
- if ( (includeHidden === true && /hidden/.test(t)) ||
1018
- (typeof includeHidden == 'string' && $(this).is(includeHidden)) )
1019
- this.value = '';
1020
- }
1021
- });
1022
- };
1023
-
1024
- /**
1025
- * Resets the form data. Causes all form elements to be reset to their original value.
1026
- */
1027
- $.fn.resetForm = function() {
1028
- return this.each(function() {
1029
- // guard against an input with the name of 'reset'
1030
- // note that IE reports the reset function as an 'object'
1031
- if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {
1032
- this.reset();
1033
- }
1034
- });
1035
- };
1036
-
1037
- /**
1038
- * Enables or disables any matching elements.
1039
- */
1040
- $.fn.enable = function(b) {
1041
- if (b === undefined) {
1042
- b = true;
1043
- }
1044
- return this.each(function() {
1045
- this.disabled = !b;
1046
- });
1047
- };
1048
-
1049
- /**
1050
- * Checks/unchecks any matching checkboxes or radio buttons and
1051
- * selects/deselects and matching option elements.
1052
- */
1053
- $.fn.selected = function(select) {
1054
- if (select === undefined) {
1055
- select = true;
1056
- }
1057
- return this.each(function() {
1058
- var t = this.type;
1059
- if (t == 'checkbox' || t == 'radio') {
1060
- this.checked = select;
1061
- }
1062
- else if (this.tagName.toLowerCase() == 'option') {
1063
- var $sel = $(this).parent('select');
1064
- if (select && $sel[0] && $sel[0].type == 'select-one') {
1065
- // deselect all other options
1066
- $sel.find('option').selected(false);
1067
- }
1068
- this.selected = select;
1069
- }
1070
- });
1071
- };
1072
-
1073
- // expose debug var
1074
- $.fn.ajaxSubmit.debug = false;
1075
-
1076
- // helper fn for console logging
1077
- function log() {
1078
- if (!$.fn.ajaxSubmit.debug)
1079
- return;
1080
- var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
1081
- if (window.console && window.console.log) {
1082
- window.console.log(msg);
1083
- }
1084
- else if (window.opera && window.opera.postError) {
1085
- window.opera.postError(msg);
1086
- }
1087
- }
1088
-
1089
- })(jQuery);
includes/js/jquery.form.js CHANGED
@@ -1,6 +1,6 @@
1
/*!
2
* jQuery Form Plugin
3
- * version: 3.14 (30-JUL-2012)
4
* @requires jQuery v1.3.2 or later
5
*
6
* Examples and documentation at: http://malsup.com/jquery/form/
@@ -9,4 +9,1095 @@
9
* http://malsup.github.com/mit-license.txt
10
* http://malsup.github.com/gpl-license-v2.txt
11
*/
12
- (function(e){var c={};c.fileapi=e("<input type='file'/>").get(0).files!==undefined;c.formdata=window.FormData!==undefined;e.fn.ajaxSubmit=function(g){if(!this.length){d("ajaxSubmit: skipping submit process - no element selected");return this}var f,w,i,l=this;if(typeof g=="function"){g={success:g}}f=this.attr("method");w=this.attr("action");i=(typeof w==="string")?e.trim(w):"";i=i||window.location.href||"";if(i){i=(i.match(/^([^#]+)/)||[])[1]}g=e.extend(true,{url:i,success:e.ajaxSettings.success,type:f||"GET",iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank"},g);var r={};this.trigger("form-pre-serialize",[this,g,r]);if(r.veto){d("ajaxSubmit: submit vetoed via form-pre-serialize trigger");return this}if(g.beforeSerialize&&g.beforeSerialize(this,g)===false){d("ajaxSubmit: submit aborted via beforeSerialize callback");return this}var j=g.traditional;if(j===undefined){j=e.ajaxSettings.traditional}var o=[];var z,A=this.formToArray(g.semantic,o);if(g.data){g.extraData=g.data;z=e.param(g.data,j)}if(g.beforeSubmit&&g.beforeSubmit(A,this,g)===false){d("ajaxSubmit: submit aborted via beforeSubmit callback");return this}this.trigger("form-submit-validate",[A,this,g,r]);if(r.veto){d("ajaxSubmit: submit vetoed via form-submit-validate trigger");return this}var u=e.param(A,j);if(z){u=(u?(u+"&"+z):z)}if(g.type.toUpperCase()=="GET"){g.url+=(g.url.indexOf("?")>=0?"&":"?")+u;g.data=null}else{g.data=u}var C=[];if(g.resetForm){C.push(function(){l.resetForm()})}if(g.clearForm){C.push(function(){l.clearForm(g.includeHidden)})}if(!g.dataType&&g.target){var h=g.success||function(){};C.push(function(q){var k=g.replaceTarget?"replaceWith":"html";e(g.target)[k](q).each(h,arguments)})}else{if(g.success){C.push(g.success)}}g.success=function(F,q,G){var E=g.context||this;for(var D=0,k=C.length;D<k;D++){C[D].apply(E,[F,q,G||l,l])}};var y=e("input:file:enabled[value]",this);var m=y.length>0;var x="multipart/form-data";var t=(l.attr("enctype")==x||l.attr("encoding")==x);var s=c.fileapi&&c.formdata;d("fileAPI :"+s);var n=(m||t)&&!s;if(g.iframe!==false&&(g.iframe||n)){if(g.closeKeepAlive){e.get(g.closeKeepAlive,function(){B(A)})}else{B(A)}}else{if((m||t)&&s){p(A)}else{e.ajax(g)}}for(var v=0;v<o.length;v++){o[v]=null}this.trigger("form-submit-notify",[this,g]);return this;function p(q){var k=new FormData();for(var D=0;D<q.length;D++){k.append(q[D].name,q[D].value)}if(g.extraData){for(var G in g.extraData){if(g.extraData.hasOwnProperty(G)){k.append(G,g.extraData[G])}}}g.data=null;var F=e.extend(true,{},e.ajaxSettings,g,{contentType:false,processData:false,cache:false,type:"POST"});if(g.uploadProgress){F.xhr=function(){var H=jQuery.ajaxSettings.xhr();if(H.upload){H.upload.onprogress=function(L){var K=0;var I=L.loaded||L.position;var J=L.total;if(L.lengthComputable){K=Math.ceil(I/J*100)}g.uploadProgress(L,I,J,K)}}return H}}F.data=null;var E=F.beforeSend;F.beforeSend=function(I,H){H.data=k;if(E){E.call(this,I,H)}};e.ajax(F)}function B(ab){var G=l[0],F,X,R,Z,U,I,M,K,L,V,Y,P;var J=!!e.fn.prop;if(e(":input[name=submit],:input[id=submit]",G).length){alert('Error: Form elements must not have name or id of "submit".');return}if(ab){for(X=0;X<o.length;X++){F=e(o[X]);if(J){F.prop("disabled",false)}else{F.removeAttr("disabled")}}}R=e.extend(true,{},e.ajaxSettings,g);R.context=R.context||R;U="jqFormIO"+(new Date().getTime());if(R.iframeTarget){I=e(R.iframeTarget);V=I.attr("name");if(!V){I.attr("name",U)}else{U=V}}else{I=e('<iframe name="'+U+'" src="'+R.iframeSrc+'" />');I.css({position:"absolute",top:"-1000px",left:"-1000px"})}M=I[0];K={aborted:0,responseText:null,responseXML:null,status:0,statusText:"n/a",getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){},abort:function(ae){var af=(ae==="timeout"?"timeout":"aborted");d("aborting upload... "+af);this.aborted=1;if(M.contentWindow.document.execCommand){try{M.contentWindow.document.execCommand("Stop")}catch(ag){}}I.attr("src",R.iframeSrc);K.error=af;if(R.error){R.error.call(R.context,K,af,ae)}if(Z){e.event.trigger("ajaxError",[K,R,af])}if(R.complete){R.complete.call(R.context,K,af)}}};Z=R.global;if(Z&&0===e.active++){e.event.trigger("ajaxStart")}if(Z){e.event.trigger("ajaxSend",[K,R])}if(R.beforeSend&&R.beforeSend.call(R.context,K,R)===false){if(R.global){e.active--}return}if(K.aborted){return}L=G.clk;if(L){V=L.name;if(V&&!L.disabled){R.extraData=R.extraData||{};R.extraData[V]=L.value;if(L.type=="image"){R.extraData[V+".x"]=G.clk_x;R.extraData[V+".y"]=G.clk_y}}}var Q=1;var N=2;function O(af){var ae=af.contentWindow?af.contentWindow.document:af.contentDocument?af.contentDocument:af.document;return ae}var E=e("meta[name=csrf-token]").attr("content");var D=e("meta[name=csrf-param]").attr("content");if(D&&E){R.extraData=R.extraData||{};R.extraData[D]=E}function W(){var ag=l.attr("target"),ae=l.attr("action");G.setAttribute("target",U);if(!f){G.setAttribute("method","POST")}if(ae!=R.url){G.setAttribute("action",R.url)}if(!R.skipEncodingOverride&&(!f||/post/i.test(f))){l.attr({encoding:"multipart/form-data",enctype:"multipart/form-data"})}if(R.timeout){P=setTimeout(function(){Y=true;T(Q)},R.timeout)}function ah(){try{var aj=O(M).readyState;d("state = "+aj);if(aj&&aj.toLowerCase()=="uninitialized"){setTimeout(ah,50)}}catch(ak){d("Server abort: ",ak," (",ak.name,")");T(N);if(P){clearTimeout(P)}P=undefined}}var af=[];try{if(R.extraData){for(var ai in R.extraData){if(R.extraData.hasOwnProperty(ai)){if(e.isPlainObject(R.extraData[ai])&&R.extraData[ai].hasOwnProperty("name")&&R.extraData[ai].hasOwnProperty("value")){af.push(e('<input type="hidden" name="'+R.extraData[ai].name+'">').attr("value",R.extraData[ai].value).appendTo(G)[0])}else{af.push(e('<input type="hidden" name="'+ai+'">').attr("value",R.extraData[ai]).appendTo(G)[0])}}}}if(!R.iframeTarget){I.appendTo("body");if(M.attachEvent){M.attachEvent("onload",T)}else{M.addEventListener("load",T,false)}}setTimeout(ah,15);G.submit()}finally{G.setAttribute("action",ae);if(ag){G.setAttribute("target",ag)}else{l.removeAttr("target")}e(af).remove()}}if(R.forceSync){W()}else{setTimeout(W,10)}var ac,ad,aa=50,H;function T(aj){if(K.aborted||H){return}try{ad=O(M)}catch(am){d("cannot access response document: ",am);aj=N}if(aj===Q&&K){K.abort("timeout");return}else{if(aj==N&&K){K.abort("server abort");return}}if(!ad||ad.location.href==R.iframeSrc){if(!Y){return}}if(M.detachEvent){M.detachEvent("onload",T)}else{M.removeEventListener("load",T,false)}var ah="success",al;try{if(Y){throw"timeout"}var ag=R.dataType=="xml"||ad.XMLDocument||e.isXMLDoc(ad);d("isXml="+ag);if(!ag&&window.opera&&(ad.body===null||!ad.body.innerHTML)){if(--aa){d("requeing onLoad callback, DOM not available");setTimeout(T,250);return}}var an=ad.body?ad.body:ad.documentElement;K.responseText=an?an.innerHTML:null;K.responseXML=ad.XMLDocument?ad.XMLDocument:ad;if(ag){R.dataType="xml"}K.getResponseHeader=function(aq){var ap={"content-type":R.dataType};return ap[aq]};if(an){K.status=Number(an.getAttribute("status"))||K.status;K.statusText=an.getAttribute("statusText")||K.statusText}var ae=(R.dataType||"").toLowerCase();var ak=/(json|script|text)/.test(ae);if(ak||R.textarea){var ai=ad.getElementsByTagName("textarea")[0];if(ai){K.responseText=ai.value;K.status=Number(ai.getAttribute("status"))||K.status;K.statusText=ai.getAttribute("statusText")||K.statusText}else{if(ak){var af=ad.getElementsByTagName("pre")[0];var ao=ad.getElementsByTagName("body")[0];if(af){K.responseText=af.textContent?af.textContent:af.innerText}else{if(ao){K.responseText=ao.textContent?ao.textContent:ao.innerText}}}}}else{if(ae=="xml"&&!K.responseXML&&K.responseText){K.responseXML=S(K.responseText)}}try{ac=k(K,ae,R)}catch(aj){ah="parsererror";K.error=al=(aj||ah)}}catch(aj){d("error caught: ",aj);ah="error";K.error=al=(aj||ah)}if(K.aborted){d("upload aborted");ah=null}if(K.status){ah=(K.status>=200&&K.status<300||K.status===304)?"success":"error"}if(ah==="success"){if(R.success){R.success.call(R.context,ac,"success",K)}if(Z){e.event.trigger("ajaxSuccess",[K,R])}}else{if(ah){if(al===undefined){al=K.statusText}if(R.error){R.error.call(R.context,K,ah,al)}if(Z){e.event.trigger("ajaxError",[K,R,al])}}}if(Z){e.event.trigger("ajaxComplete",[K,R])}if(Z&&!--e.active){e.event.trigger("ajaxStop")}if(R.complete){R.complete.call(R.context,K,ah)}H=true;if(R.timeout){clearTimeout(P)}setTimeout(function(){if(!R.iframeTarget){I.remove()}K.responseXML=null},100)}var S=e.parseXML||function(ae,af){if(window.ActiveXObject){af=new ActiveXObject("Microsoft.XMLDOM");af.async="false";af.loadXML(ae)}else{af=(new DOMParser()).parseFromString(ae,"text/xml")}return(af&&af.documentElement&&af.documentElement.nodeName!="parsererror")?af:null};var q=e.parseJSON||function(ae){return window["eval"]("("+ae+")")};var k=function(aj,ah,ag){var af=aj.getResponseHeader("content-type")||"",ae=ah==="xml"||!ah&&af.indexOf("xml")>=0,ai=ae?aj.responseXML:aj.responseText;if(ae&&ai.documentElement.nodeName==="parsererror"){if(e.error){e.error("parsererror")}}if(ag&&ag.dataFilter){ai=ag.dataFilter(ai,ah)}if(typeof ai==="string"){if(ah==="json"||!ah&&af.indexOf("json")>=0){ai=q(ai)}else{if(ah==="script"||!ah&&af.indexOf("javascript")>=0){e.globalEval(ai)}}}return ai}}};e.fn.ajaxForm=function(f){f=f||{};f.delegation=f.delegation&&e.isFunction(e.fn.on);if(!f.delegation&&this.length===0){var g={s:this.selector,c:this.context};if(!e.isReady&&g.s){d("DOM not ready, queuing ajaxForm");e(function(){e(g.s,g.c).ajaxForm(f)});return this}d("terminating; zero elements found by selector"+(e.isReady?"":" (DOM not ready)"));return this}if(f.delegation){e(document).off("submit.form-plugin",this.selector,b).off("click.form-plugin",this.selector,a).on("submit.form-plugin",this.selector,f,b).on("click.form-plugin",this.selector,f,a);return this}return this.ajaxFormUnbind().bind("submit.form-plugin",f,b).bind("click.form-plugin",f,a)};function b(g){var f=g.data;if(!g.isDefaultPrevented()){g.preventDefault();e(this).ajaxSubmit(f)}}function a(j){var i=j.target;var g=e(i);if(!(g.is(":submit,input:image"))){var f=g.closest(":submit");if(f.length===0){return}i=f[0]}var h=this;h.clk=i;if(i.type=="image"){if(j.offsetX!==undefined){h.clk_x=j.offsetX;h.clk_y=j.offsetY}else{if(typeof e.fn.offset=="function"){var k=g.offset();h.clk_x=j.pageX-k.left;h.clk_y=j.pageY-k.top}else{h.clk_x=j.pageX-i.offsetLeft;h.clk_y=j.pageY-i.offsetTop}}}setTimeout(function(){h.clk=h.clk_x=h.clk_y=null},100)}e.fn.ajaxFormUnbind=function(){return this.unbind("submit.form-plugin click.form-plugin")};e.fn.formToArray=function(w,f){var u=[];if(this.length===0){return u}var k=this[0];var o=w?k.getElementsByTagName("*"):k.elements;if(!o){return u}var q,p,m,x,l,s,h;for(q=0,s=o.length;q<s;q++){l=o[q];m=l.name;if(!m){continue}if(w&&k.clk&&l.type=="image"){if(!l.disabled&&k.clk==l){u.push({name:m,value:e(l).val(),type:l.type});u.push({name:m+".x",value:k.clk_x},{name:m+".y",value:k.clk_y})}continue}x=e.fieldValue(l,true);if(x&&x.constructor==Array){if(f){f.push(l)}for(p=0,h=x.length;p<h;p++){u.push({name:m,value:x[p]})}}else{if(c.fileapi&&l.type=="file"&&!l.disabled){if(f){f.push(l)}var g=l.files;if(g.length){for(p=0;p<g.length;p++){u.push({name:m,value:g[p],type:l.type})}}else{u.push({name:m,value:"",type:l.type})}}else{if(x!==null&&typeof x!="undefined"){if(f){f.push(l)}u.push({name:m,value:x,type:l.type,required:l.required})}}}}if(!w&&k.clk){var r=e(k.clk),t=r[0];m=t.name;if(m&&!t.disabled&&t.type=="image"){u.push({name:m,value:r.val()});u.push({name:m+".x",value:k.clk_x},{name:m+".y",value:k.clk_y})}}return u};e.fn.formSerialize=function(f){return e.param(this.formToArray(f))};e.fn.fieldSerialize=function(g){var f=[];this.each(function(){var l=this.name;if(!l){return}var j=e.fieldValue(this,g);if(j&&j.constructor==Array){for(var k=0,h=j.length;k<h;k++){f.push({name:l,value:j[k]})}}else{if(j!==null&&typeof j!="undefined"){f.push({name:this.name,value:j})}}});return e.param(f)};e.fn.fieldValue=function(l){for(var k=[],h=0,f=this.length;h<f;h++){var j=this[h];var g=e.fieldValue(j,l);if(g===null||typeof g=="undefined"||(g.constructor==Array&&!g.length)){continue}if(g.constructor==Array){e.merge(k,g)}else{k.push(g)}}return k};e.fieldValue=function(f,m){var h=f.name,s=f.type,u=f.tagName.toLowerCase();if(m===undefined){m=true}if(m&&(!h||f.disabled||s=="reset"||s=="button"||(s=="checkbox"||s=="radio")&&!f.checked||(s=="submit"||s=="image")&&f.form&&f.form.clk!=f||u=="select"&&f.selectedIndex==-1)){return null}if(u=="select"){var o=f.selectedIndex;if(o<0){return null}var q=[],g=f.options;var k=(s=="select-one");var p=(k?o+1:g.length);for(var j=(k?o:0);j<p;j++){var l=g[j];if(l.selected){var r=l.value;if(!r){r=(l.attributes&&l.attributes.value&&!(l.attributes.value.specified))?l.text:l.value}if(k){return r}q.push(r)}}return q}return e(f).val()};e.fn.clearForm=function(f){return this.each(function(){e("input,select,textarea",this).clearFields(f)})};e.fn.clearFields=e.fn.clearInputs=function(f){var g=/^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)#x2F;i;return this.each(function(){var i=this.type,h=this.tagName.toLowerCase();if(g.test(i)||h=="textarea"){this.value=""}else{if(i=="checkbox"||i=="radio"){this.checked=false}else{if(h=="select"){this.selectedIndex=-1}else{if(f){if((f===true&&/hidden/.test(i))||(typeof f=="string"&&e(this).is(f))){this.value=""}}}}}})};e.fn.resetForm=function(){return this.each(function(){if(typeof this.reset=="function"||(typeof this.reset=="object"&&!this.reset.nodeType)){this.reset()}})};e.fn.enable=function(f){if(f===undefined){f=true}return this.each(function(){this.disabled=!f})};e.fn.selected=function(f){if(f===undefined){f=true}return this.each(function(){var g=this.type;if(g=="checkbox"||g=="radio"){this.checked=f}else{if(this.tagName.toLowerCase()=="option"){var h=e(this).parent("select");if(f&&h[0]&&h[0].type=="select-one"){h.find("option").selected(false)}this.selected=f}}})};e.fn.ajaxSubmit.debug=false;function d(){if(!e.fn.ajaxSubmit.debug){return}var f="[jquery.form] "+Array.prototype.join.call(arguments,"");if(window.console&&window.console.log){window.console.log(f)}else{if(window.opera&&window.opera.postError){window.opera.postError(f)}}}})(jQuery);