PageSourceSearch

https://360branded.com/wp-includes/js/jquery/jquery.form.js?ver=4.3.0

js 360branded.com collected 2026-09-24 12:43:52 UTC 41,911 bytes, 1,540 lines download raw bytes

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

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.