PageSourceSearch

https://static.goodwearmall.com/resources/js/libs/jquery.form.js?timestamp=202610061606

js goodwearmall.com collected 2026-10-07 04:10:40 UTC 43,890 bytes, 1,275 lines download raw bytes

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

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.