PageSourceSearch

https://www.pintradingdb.com/js/jquery.form.js

js pintradingdb.com collected 2026-09-24 09:22:18 UTC 42,211 bytes, 1,204 lines download raw bytes

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

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.