diff options
| -rw-r--r-- | vendors/jquery/jquery.form.js | 1150 | 
1 files changed, 666 insertions, 484 deletions
diff --git a/vendors/jquery/jquery.form.js b/vendors/jquery/jquery.form.js index c027f19c0..c0fba53cf 100644 --- a/vendors/jquery/jquery.form.js +++ b/vendors/jquery/jquery.form.js @@ -1,7 +1,7 @@ -/* +/*!   * jQuery Form Plugin - * version: 2.28 (10-MAY-2009) - * @requires jQuery v1.2.2 or later + * version: 2.73 (03-MAY-2011) + * @requires jQuery v1.3.2 or later   *   * Examples and documentation at: http://malsup.com/jquery/form/   * Dual licensed under the MIT and GPL licenses: @@ -11,32 +11,32 @@  ;(function($) {  /* -    Usage Note: -    ----------- -    Do not use both ajaxSubmit and ajaxForm on the same form.  These -    functions are intended to be exclusive.  Use ajaxSubmit if you want -    to bind your own submit handler to the form.  For example, - -    $(document).ready(function() { -        $('#myForm').bind('submit', function() { -            $(this).ajaxSubmit({ -                target: '#output' -            }); -            return false; // <-- important! -        }); -    }); - -    Use ajaxForm when you want the plugin to manage all the event binding -    for you.  For example, - -    $(document).ready(function() { -        $('#myForm').ajaxForm({ -            target: '#output' -        }); -    }); - -    When using ajaxForm, the ajaxSubmit function will be invoked for you -    at the appropriate time. +	Usage Note: +	----------- +	Do not use both ajaxSubmit and ajaxForm on the same form.  These +	functions are intended to be exclusive.  Use ajaxSubmit if you want +	to bind your own submit handler to the form.  For example, + +	$(document).ready(function() { +		$('#myForm').bind('submit', function(e) { +			e.preventDefault(); // <-- important +			$(this).ajaxSubmit({ +				target: '#output' +			}); +		}); +	}); + +	Use ajaxForm when you want the plugin to manage all the event binding +	for you.  For example, + +	$(document).ready(function() { +		$('#myForm').ajaxForm({ +			target: '#output' +		}); +	}); + +	When using ajaxForm, the ajaxSubmit function will be invoked for you +	at the appropriate time.  */  /** @@ -44,304 +44,426 @@   * an HTML form using AJAX.   */  $.fn.ajaxSubmit = function(options) { -    // fast fail if nothing selected (http://dev.jquery.com/ticket/2752) -    if (!this.length) { -        log('ajaxSubmit: skipping submit process - no element selected'); -        return this; -    } - -    if (typeof options == 'function') -        options = { success: options }; - -    var url = $.trim(this.attr('action')); -    if (url) { -	    // clean url (don't include hash vaue) -	    url = (url.match(/^([^#]+)/)||[])[1]; -   	} -   	url = url || window.location.href || '' - -    options = $.extend({ -        url:  url, -        type: this.attr('method') || 'GET' -    }, options || {}); - -    // hook for manipulating the form data before it is extracted; -    // convenient for use with rich editors like tinyMCE or FCKEditor -    var veto = {}; -    this.trigger('form-pre-serialize', [this, options, veto]); -    if (veto.veto) { -        log('ajaxSubmit: submit vetoed via form-pre-serialize trigger'); -        return this; -    } - -    // provide opportunity to alter form data before it is serialized -    if (options.beforeSerialize && options.beforeSerialize(this, options) === false) { -        log('ajaxSubmit: submit aborted via beforeSerialize callback'); -        return this; -    } - -    var a = this.formToArray(options.semantic); -    if (options.data) { -        options.extraData = options.data; -        for (var n in options.data) { -          if(options.data[n] instanceof Array) { -            for (var k in options.data[n]) -              a.push( { name: n, value: options.data[n][k] } ); -          } -          else -             a.push( { name: n, value: options.data[n] } ); -        } -    } - -    // give pre-submit callback an opportunity to abort the submit -    if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) { -        log('ajaxSubmit: submit aborted via beforeSubmit callback'); -        return this; -    } - -    // fire vetoable 'validate' event -    this.trigger('form-submit-validate', [a, this, options, veto]); -    if (veto.veto) { -        log('ajaxSubmit: submit vetoed via form-submit-validate trigger'); -        return this; -    } - -    var q = $.param(a); - -    if (options.type.toUpperCase() == 'GET') { -        options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; -        options.data = null;  // data is null for 'get' -    } -    else -        options.data = q; // data is the query string for 'post' - -    var $form = this, callbacks = []; -    if (options.resetForm) callbacks.push(function() { $form.resetForm(); }); -    if (options.clearForm) callbacks.push(function() { $form.clearForm(); }); - -    // perform a load on the target only if dataType is not provided -    if (!options.dataType && options.target) { -        var oldSuccess = options.success || function(){}; -        callbacks.push(function(data) { -            $(options.target).html(data).each(oldSuccess, arguments); -        }); -    } -    else if (options.success) -        callbacks.push(options.success); - -    options.success = function(data, status) { -        for (var i=0, max=callbacks.length; i < max; i++) -            callbacks[i].apply(options, [data, status, $form]); -    }; - -    // are there files to upload? -    var files = $('input:file', this).fieldValue(); -    var found = false; -    for (var j=0; j < files.length; j++) -        if (files[j]) -            found = true; - -	var multipart = false; -//	var mp = 'multipart/form-data'; -//	multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp); - -    // options.iframe allows user to force iframe mode -   if (options.iframe || found || multipart) { -       // hack to fix Safari hang (thanks to Tim Molendijk for this) -       // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d -       if (options.closeKeepAlive) -           $.get(options.closeKeepAlive, fileUpload); -       else -           fileUpload(); -       } -   else -       $.ajax(options); - -    // fire 'notify' event -    this.trigger('form-submit-notify', [this, options]); -    return this; - - -    // private function for handling file uploads (hat tip to YAHOO!) -    function fileUpload() { -        var form = $form[0]; - -        if ($(':input[name=submit]', form).length) { -            alert('Error: Form elements must not be named "submit".'); -            return; -        } - -        var opts = $.extend({}, $.ajaxSettings, options); -		var s = $.extend(true, {}, $.extend(true, {}, $.ajaxSettings), opts); - -        var id = 'jqFormIO' + (new Date().getTime()); -        var $io = $('<iframe id="' + id + '" name="' + id + '" src="about:blank" />'); -        var io = $io[0]; - -        $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' }); - -        var xhr = { // mock object -            aborted: 0, -            responseText: null, -            responseXML: null, -            status: 0, -            statusText: 'n/a', -            getAllResponseHeaders: function() {}, -            getResponseHeader: function() {}, -            setRequestHeader: function() {}, -            abort: function() { -                this.aborted = 1; -                $io.attr('src','about:blank'); // abort op in progress -            } -        }; - -        var g = opts.global; -        // trigger ajax global events so that activity/block indicators work like normal -        if (g && ! $.active++) $.event.trigger("ajaxStart"); -        if (g) $.event.trigger("ajaxSend", [xhr, opts]); - -		if (s.beforeSend && s.beforeSend(xhr, s) === false) { -			s.global && $.active--; +	// fast fail if nothing selected (http://dev.jquery.com/ticket/2752) +	if (!this.length) { +		log('ajaxSubmit: skipping submit process - no element selected'); +		return this; +	} + +	if (typeof options == 'function') { +		options = { success: options }; +	} + +	var action = this.attr('action'); +	var url = (typeof action === 'string') ? $.trim(action) : ''; +	if (url) { +		// clean url (don't include hash vaue) +		url = (url.match(/^([^#]+)/)||[])[1]; +	} +	url = url || window.location.href || ''; + +	options = $.extend(true, { +		url:  url, +		success: $.ajaxSettings.success, +		type: this[0].getAttribute('method') || 'GET', // IE7 massage (see issue 57) +		iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank' +	}, options); + +	// hook for manipulating the form data before it is extracted; +	// convenient for use with rich editors like tinyMCE or FCKEditor +	var veto = {}; +	this.trigger('form-pre-serialize', [this, options, veto]); +	if (veto.veto) { +		log('ajaxSubmit: submit vetoed via form-pre-serialize trigger'); +		return this; +	} + +	// provide opportunity to alter form data before it is serialized +	if (options.beforeSerialize && options.beforeSerialize(this, options) === false) { +		log('ajaxSubmit: submit aborted via beforeSerialize callback'); +		return this; +	} + +	var n,v,a = this.formToArray(options.semantic); +	if (options.data) { +		options.extraData = options.data; +		for (n in options.data) { +			if(options.data[n] instanceof Array) { +				for (var k in options.data[n]) { +					a.push( { name: n, value: options.data[n][k] } ); +				} +			} +			else { +				v = options.data[n]; +				v = $.isFunction(v) ? v() : v; // if value is fn, invoke it +				a.push( { name: n, value: v } ); +			} +		} +	} + +	// give pre-submit callback an opportunity to abort the submit +	if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) { +		log('ajaxSubmit: submit aborted via beforeSubmit callback'); +		return this; +	} + +	// fire vetoable 'validate' event +	this.trigger('form-submit-validate', [a, this, options, veto]); +	if (veto.veto) { +		log('ajaxSubmit: submit vetoed via form-submit-validate trigger'); +		return this; +	} + +	var q = $.param(a); + +	if (options.type.toUpperCase() == 'GET') { +		options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; +		options.data = null;  // data is null for 'get' +	} +	else { +		options.data = q; // data is the query string for 'post' +	} + +	var $form = this, callbacks = []; +	if (options.resetForm) { +		callbacks.push(function() { $form.resetForm(); }); +	} +	if (options.clearForm) { +		callbacks.push(function() { $form.clearForm(); }); +	} + +	// perform a load on the target only if dataType is not provided +	if (!options.dataType && options.target) { +		var oldSuccess = options.success || function(){}; +		callbacks.push(function(data) { +			var fn = options.replaceTarget ? 'replaceWith' : 'html'; +			$(options.target)[fn](data).each(oldSuccess, arguments); +		}); +	} +	else if (options.success) { +		callbacks.push(options.success); +	} + +	options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg +		var context = options.context || options;   // jQuery 1.4+ supports scope context  +		for (var i=0, max=callbacks.length; i < max; i++) { +			callbacks[i].apply(context, [data, status, xhr || $form, $form]); +		} +	}; + +	// are there files to upload? +	var fileInputs = $('input:file', this).length > 0; +	var mp = 'multipart/form-data'; +	var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp); + +	// options.iframe allows user to force iframe mode +	// 06-NOV-09: now defaulting to iframe mode if file input is detected +   if (options.iframe !== false && (fileInputs || options.iframe || multipart)) { +	   // hack to fix Safari hang (thanks to Tim Molendijk for this) +	   // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d +	   if (options.closeKeepAlive) { +		   $.get(options.closeKeepAlive, fileUpload); +		} +	   else { +		   fileUpload(); +		} +   } +   else { +		$.ajax(options); +   } + +	// fire 'notify' event +	this.trigger('form-submit-notify', [this, options]); +	return this; + + +	// private function for handling file uploads (hat tip to YAHOO!) +	function fileUpload() { +		var form = $form[0]; + +		if ($(':input[name=submit],:input[id=submit]', form).length) { +			// if there is an input with a name or id of 'submit' then we won't be +			// able to invoke the submit fn on the form (at least not x-browser) +			alert('Error: Form elements must not have name or id of "submit".'); +			return; +		} +		 +		var s = $.extend(true, {}, $.ajaxSettings, options); +		s.context = s.context || s; +		var id = 'jqFormIO' + (new Date().getTime()), fn = '_'+id; +		var $io = $('<iframe id="' + id + '" name="' + id + '" src="'+ s.iframeSrc +'" />'); +		var io = $io[0]; + +		$io.css({ position: 'absolute', top: '-1000px', left: '-1000px' }); + +		var xhr = { // mock object +			aborted: 0, +			responseText: null, +			responseXML: null, +			status: 0, +			statusText: 'n/a', +			getAllResponseHeaders: function() {}, +			getResponseHeader: function() {}, +			setRequestHeader: function() {}, +			abort: function(status) { +				var e = (status === 'timeout' ? 'timeout' : 'aborted'); +				log('aborting upload... ' + e); +				this.aborted = 1; +				$io.attr('src', s.iframeSrc); // abort op in progress +				xhr.error = e; +				s.error && s.error.call(s.context, xhr, e, e); +				g && $.event.trigger("ajaxError", [xhr, s, e]); +				s.complete && s.complete.call(s.context, xhr, e); +			} +		}; + +		var g = s.global; +		// trigger ajax global events so that activity/block indicators work like normal +		if (g && ! $.active++) { +			$.event.trigger("ajaxStart"); +		} +		if (g) { +			$.event.trigger("ajaxSend", [xhr, s]); +		} + +		if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) { +			if (s.global) {  +				$.active--; +			}  			return; -        } -        if (xhr.aborted) -            return; - -        var cbInvoked = 0; -        var timedOut = 0; - -        // add submitting element to data if we know it -        var sub = form.clk; -        if (sub) { -            var n = sub.name; -            if (n && !sub.disabled) { -                options.extraData = options.extraData || {}; -                options.extraData[n] = sub.value; -                if (sub.type == "image") { -                    options.extraData[name+'.x'] = form.clk_x; -                    options.extraData[name+'.y'] = form.clk_y; -                } -            } -        } - -        // take a breath so that pending repaints get some cpu time before the upload starts -        setTimeout(function() { -            // make sure form attrs are set -            var t = $form.attr('target'), a = $form.attr('action'); +		} +		if (xhr.aborted) { +			return; +		} + +		var timedOut = 0, timeoutHandle; + +		// add submitting element to data if we know it +		var sub = form.clk; +		if (sub) { +			var n = sub.name; +			if (n && !sub.disabled) { +				s.extraData = s.extraData || {}; +				s.extraData[n] = sub.value; +				if (sub.type == "image") { +					s.extraData[n+'.x'] = form.clk_x; +					s.extraData[n+'.y'] = form.clk_y; +				} +			} +		} + +		// take a breath so that pending repaints get some cpu time before the upload starts +		function doSubmit() { +			// make sure form attrs are set +			var t = $form.attr('target'), a = $form.attr('action');  			// update form attrs in IE friendly way  			form.setAttribute('target',id); -			if (form.getAttribute('method') != 'POST') +			if (form.getAttribute('method') != 'POST') {  				form.setAttribute('method', 'POST'); -			if (form.getAttribute('action') != opts.url) -				form.setAttribute('action', opts.url); - -            // ie borks in some cases when setting encoding -            if (! options.skipEncodingOverride) { -                $form.attr({ -                    encoding: 'multipart/form-data', -                    enctype:  'multipart/form-data' -                }); -            } - -            // support timout -            if (opts.timeout) -                setTimeout(function() { timedOut = true; cb(); }, opts.timeout); - -            // add "extra" data to form if provided in options -            var extraInputs = []; -            try { -                if (options.extraData) -                    for (var n in options.extraData) -                        extraInputs.push( -                            $('<input type="hidden" name="'+n+'" value="'+options.extraData[n]+'" />') -                                .appendTo(form)[0]); - -                // add iframe to doc and submit the form -                $io.appendTo('body'); +			} +			if (form.getAttribute('action') != s.url) { +				form.setAttribute('action', s.url); +			} + +			// ie borks in some cases when setting encoding +			if (! s.skipEncodingOverride) { +				$form.attr({ +					encoding: 'multipart/form-data', +					enctype:  'multipart/form-data' +				}); +			} + +			// support timout +			if (s.timeout) { +				timeoutHandle = setTimeout(function() { timedOut = true; cb(true); }, s.timeout); +			} + +			// add "extra" data to form if provided in options +			var extraInputs = []; +			try { +				if (s.extraData) { +					for (var n in s.extraData) { +						extraInputs.push( +							$('<input type="hidden" name="'+n+'" value="'+s.extraData[n]+'" />') +								.appendTo(form)[0]); +					} +				} + +				// add iframe to doc and submit the form +				$io.appendTo('body');                  io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false); -                form.submit(); -            } -            finally { -                // reset attrs and remove "extra" input elements +				form.submit(); +			} +			finally { +				// reset attrs and remove "extra" input elements  				form.setAttribute('action',a); -                t ? form.setAttribute('target', t) : $form.removeAttr('target'); -                $(extraInputs).remove(); -            } -        }, 10); - -        var nullCheckFlag = 0; - -        function cb() { -            if (cbInvoked++) return; - +				if(t) { +					form.setAttribute('target', t); +				} else { +					$form.removeAttr('target'); +				} +				$(extraInputs).remove(); +			} +		} + +		if (s.forceSync) { +			doSubmit(); +		} +		else { +			setTimeout(doSubmit, 10); // this lets dom updates render +		} +	 +		var data, doc, domCheckCount = 50, callbackProcessed; + +		function cb(e) { +			if (xhr.aborted || callbackProcessed) { +				return; +			} +			if (e === true && xhr) { +				xhr.abort('timeout'); +				return; +			} +			 +			var doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document; +			if (!doc || doc.location.href == s.iframeSrc) { +				// response not received yet +				if (!timedOut) +					return; +			}              io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false); -            var ok = true; -            try { -                if (timedOut) throw 'timeout'; -                // extract the server response from the iframe -                var data, doc; - -                doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document; - -                if ((doc.body == null || doc.body.innerHTML == '') && !nullCheckFlag) { -                    // in some browsers (cough, Opera 9.2.x) the iframe DOM is not always traversable when -                    // the onload callback fires, so we give them a 2nd chance -                    nullCheckFlag = 1; -                    cbInvoked--; -                    setTimeout(cb, 100); -                    return; -                } - -                xhr.responseText = doc.body ? doc.body.innerHTML : null; -                xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc; -                xhr.getResponseHeader = function(header){ -                    var headers = {'content-type': opts.dataType}; -                    return headers[header]; -                }; - -                if (opts.dataType == 'json' || opts.dataType == 'script') { -                    var ta = doc.getElementsByTagName('textarea')[0]; -                    xhr.responseText = ta ? ta.value : xhr.responseText; -                } -                else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) { -                    xhr.responseXML = toXml(xhr.responseText); -                } -                data = $.httpData(xhr, opts.dataType); -            } -            catch(e){ -                ok = false; -                $.handleError(opts, xhr, 'error', e); -            } - -            // ordering of these callbacks/triggers is odd, but that's how $.ajax does it -            if (ok) { -                opts.success(data, 'success'); -                if (g) $.event.trigger("ajaxSuccess", [xhr, opts]); -            } -            if (g) $.event.trigger("ajaxComplete", [xhr, opts]); -            if (g && ! --$.active) $.event.trigger("ajaxStop"); -            if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error'); - -            // clean up -            setTimeout(function() { -                $io.remove(); -                xhr.responseXML = null; -            }, 100); -        }; - -        function toXml(s, doc) { -            if (window.ActiveXObject) { -                doc = new ActiveXObject('Microsoft.XMLDOM'); -                doc.async = 'false'; -                doc.loadXML(s); -            } -            else -                doc = (new DOMParser()).parseFromString(s, 'text/xml'); -            return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null; -        }; -    }; +			var ok = true; +			try { +				if (timedOut) { +					throw 'timeout'; +				} + +				var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc); +				log('isXml='+isXml); +				if (!isXml && window.opera && (doc.body == null || doc.body.innerHTML == '')) { +					if (--domCheckCount) { +						// in some browsers (Opera) the iframe DOM is not always traversable when +						// the onload callback fires, so we loop a bit to accommodate +						log('requeing onLoad callback, DOM not available'); +						setTimeout(cb, 250); +						return; +					} +					// let this fall through because server response could be an empty document +					//log('Could not access iframe DOM after mutiple tries.'); +					//throw 'DOMException: not available'; +				} + +				//log('response detected'); +				xhr.responseText = doc.body ? doc.body.innerHTML : doc.documentElement ? doc.documentElement.innerHTML : null;  +				xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc; +				if (isXml) +					s.dataType = 'xml'; +				xhr.getResponseHeader = function(header){ +					var headers = {'content-type': s.dataType}; +					return headers[header]; +				}; + +				var scr = /(json|script|text)/.test(s.dataType); +				if (scr || s.textarea) { +					// see if user embedded response in textarea +					var ta = doc.getElementsByTagName('textarea')[0]; +					if (ta) { +						xhr.responseText = ta.value; +					} +					else if (scr) { +						// account for browsers injecting pre around json response +						var pre = doc.getElementsByTagName('pre')[0]; +						var b = doc.getElementsByTagName('body')[0]; +						if (pre) { +							xhr.responseText = pre.textContent; +						} +						else if (b) { +							xhr.responseText = b.innerHTML; +						} +					}			   +				} +				else if (s.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) { +					xhr.responseXML = toXml(xhr.responseText); +				} +				 +				data = httpData(xhr, s.dataType, s); +			} +			catch(e){ +				log('error caught:',e); +				ok = false; +				xhr.error = e; +				s.error && s.error.call(s.context, xhr, 'error', e); +				g && $.event.trigger("ajaxError", [xhr, s, e]); +			} +			 +			if (xhr.aborted) { +				log('upload aborted'); +				ok = false; +			} + +			// ordering of these callbacks/triggers is odd, but that's how $.ajax does it +			if (ok) { +				s.success && s.success.call(s.context, data, 'success', xhr); +				g && $.event.trigger("ajaxSuccess", [xhr, s]); +			} +			 +			g && $.event.trigger("ajaxComplete", [xhr, s]); + +			if (g && ! --$.active) { +				$.event.trigger("ajaxStop"); +			} +			 +			s.complete && s.complete.call(s.context, xhr, ok ? 'success' : 'error'); + +			callbackProcessed = true; +			if (s.timeout) +				clearTimeout(timeoutHandle); + +			// clean up +			setTimeout(function() { +				$io.removeData('form-plugin-onload'); +				$io.remove(); +				xhr.responseXML = null; +			}, 100); +		} + +		var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+) +			if (window.ActiveXObject) { +				doc = new ActiveXObject('Microsoft.XMLDOM'); +				doc.async = 'false'; +				doc.loadXML(s); +			} +			else { +				doc = (new DOMParser()).parseFromString(s, 'text/xml'); +			} +			return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null; +		}; +		var parseJSON = $.parseJSON || function(s) { +			return window['eval']('(' + s + ')'); +		}; +		 +		var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4 +			var ct = xhr.getResponseHeader('content-type') || '', +				xml = type === 'xml' || !type && ct.indexOf('xml') >= 0, +				data = xml ? xhr.responseXML : xhr.responseText; + +			if (xml && data.documentElement.nodeName === 'parsererror') { +				$.error && $.error('parsererror'); +			} +			if (s && s.dataFilter) { +				data = s.dataFilter(data, type); +			} +			if (typeof data === 'string') { +				if (type === 'json' || !type && ct.indexOf('json') >= 0) { +					data = parseJSON(data); +				} else if (type === "script" || !type && ct.indexOf("javascript") >= 0) { +					$.globalEval(data); +				} +			} +			return data; +		}; +	}  };  /** @@ -350,9 +472,9 @@ $.fn.ajaxSubmit = function(options) {   * The advantages of using this method instead of ajaxSubmit() are:   *   * 1: This method will include coordinates for <input type="image" /> elements (if the element - *    is used to submit the form). + *	is used to submit the form).   * 2. This method will include the submit element's name/value data (for the element that was - *    used to submit the form). + *	used to submit the form).   * 3. This method binds the submit() method to the form for you.   *   * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely @@ -360,40 +482,60 @@ $.fn.ajaxSubmit = function(options) {   * the form itself.   */  $.fn.ajaxForm = function(options) { -    return this.ajaxFormUnbind().bind('submit.form-plugin',function() { -        $(this).ajaxSubmit(options); -        return false; -    }).each(function() { -        // store options in hash -        $(":submit,input:image", this).bind('click.form-plugin',function(e) { -            var form = this.form; -            form.clk = this; -            if (this.type == 'image') { -                if (e.offsetX != undefined) { -                    form.clk_x = e.offsetX; -                    form.clk_y = e.offsetY; -                } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin -                    var offset = $(this).offset(); -                    form.clk_x = e.pageX - offset.left; -                    form.clk_y = e.pageY - offset.top; -                } else { -                    form.clk_x = e.pageX - this.offsetLeft; -                    form.clk_y = e.pageY - this.offsetTop; -                } -            } -            // clear form vars -            setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 10); -        }); -    }); +	// in jQuery 1.3+ we can fix mistakes with the ready state +	if (this.length === 0) { +		var o = { s: this.selector, c: this.context }; +		if (!$.isReady && o.s) { +			log('DOM not ready, queuing ajaxForm'); +			$(function() { +				$(o.s,o.c).ajaxForm(options); +			}); +			return this; +		} +		// is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready() +		log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)')); +		return this; +	} +	 +	return this.ajaxFormUnbind().bind('submit.form-plugin', function(e) { +		if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed +			e.preventDefault(); +			$(this).ajaxSubmit(options); +		} +	}).bind('click.form-plugin', function(e) { +		var target = e.target; +		var $el = $(target); +		if (!($el.is(":submit,input:image"))) { +			// is this a child element of the submit el?  (ex: a span within a button) +			var t = $el.closest(':submit'); +			if (t.length == 0) { +				return; +			} +			target = t[0]; +		} +		var form = this; +		form.clk = target; +		if (target.type == 'image') { +			if (e.offsetX != undefined) { +				form.clk_x = e.offsetX; +				form.clk_y = e.offsetY; +			} else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin +				var offset = $el.offset(); +				form.clk_x = e.pageX - offset.left; +				form.clk_y = e.pageY - offset.top; +			} else { +				form.clk_x = e.pageX - target.offsetLeft; +				form.clk_y = e.pageY - target.offsetTop; +			} +		} +		// clear form vars +		setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100); +	});  };  // ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm  $.fn.ajaxFormUnbind = function() { -    this.unbind('submit.form-plugin'); -    return this.each(function() { -        $(":submit,input:image", this).unbind('click.form-plugin'); -    }); - +	return this.unbind('submit.form-plugin click.form-plugin');  };  /** @@ -408,44 +550,55 @@ $.fn.ajaxFormUnbind = function() {   * ajaxSubmit() and ajaxForm() methods.   */  $.fn.formToArray = function(semantic) { -    var a = []; -    if (this.length == 0) return a; - -    var form = this[0]; -    var els = semantic ? form.getElementsByTagName('*') : form.elements; -    if (!els) return a; -    for(var i=0, max=els.length; i < max; i++) { -        var el = els[i]; -        var n = el.name; -        if (!n) continue; - -        if (semantic && form.clk && el.type == "image") { -            // handle image inputs on the fly when semantic == true -            if(!el.disabled && form.clk == el) { -            	a.push({name: n, value: $(el).val()}); -                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); -            } -            continue; -        } - -        var v = $.fieldValue(el, true); -        if (v && v.constructor == Array) { -            for(var j=0, jmax=v.length; j < jmax; j++) -                a.push({name: n, value: v[j]}); -        } -        else if (v !== null && typeof v != 'undefined') -            a.push({name: n, value: v}); -    } - -    if (!semantic && form.clk) { -        // input type=='image' are not found in elements array! handle it here -        var $input = $(form.clk), input = $input[0], n = input.name; -        if (n && !input.disabled && input.type == 'image') { -        	a.push({name: n, value: $input.val()}); -            a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); -        } -    } -    return a; +	var a = []; +	if (this.length === 0) { +		return a; +	} + +	var form = this[0]; +	var els = semantic ? form.getElementsByTagName('*') : form.elements; +	if (!els) { +		return a; +	} +	 +	var i,j,n,v,el,max,jmax; +	for(i=0, max=els.length; i < max; i++) { +		el = els[i]; +		n = el.name; +		if (!n) { +			continue; +		} + +		if (semantic && form.clk && el.type == "image") { +			// handle image inputs on the fly when semantic == true +			if(!el.disabled && form.clk == el) { +				a.push({name: n, value: $(el).val()}); +				a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); +			} +			continue; +		} + +		v = $.fieldValue(el, true); +		if (v && v.constructor == Array) { +			for(j=0, jmax=v.length; j < jmax; j++) { +				a.push({name: n, value: v[j]}); +			} +		} +		else if (v !== null && typeof v != 'undefined') { +			a.push({name: n, value: v}); +		} +	} + +	if (!semantic && form.clk) { +		// input type=='image' are not found in elements array! handle it here +		var $input = $(form.clk), input = $input[0]; +		n = input.name; +		if (n && !input.disabled && input.type == 'image') { +			a.push({name: n, value: $input.val()}); +			a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); +		} +	} +	return a;  };  /** @@ -453,8 +606,8 @@ $.fn.formToArray = function(semantic) {   * in the format: name1=value1&name2=value2   */  $.fn.formSerialize = function(semantic) { -    //hand off to jQuery.param for proper encoding -    return $.param(this.formToArray(semantic)); +	//hand off to jQuery.param for proper encoding +	return $.param(this.formToArray(semantic));  };  /** @@ -462,32 +615,36 @@ $.fn.formSerialize = function(semantic) {   * This method will return a string in the format: name1=value1&name2=value2   */  $.fn.fieldSerialize = function(successful) { -    var a = []; -    this.each(function() { -        var n = this.name; -        if (!n) return; -        var v = $.fieldValue(this, successful); -        if (v && v.constructor == Array) { -            for (var i=0,max=v.length; i < max; i++) -                a.push({name: n, value: v[i]}); -        } -        else if (v !== null && typeof v != 'undefined') -            a.push({name: this.name, value: v}); -    }); -    //hand off to jQuery.param for proper encoding -    return $.param(a); +	var a = []; +	this.each(function() { +		var n = this.name; +		if (!n) { +			return; +		} +		var v = $.fieldValue(this, successful); +		if (v && v.constructor == Array) { +			for (var i=0,max=v.length; i < max; i++) { +				a.push({name: n, value: v[i]}); +			} +		} +		else if (v !== null && typeof v != 'undefined') { +			a.push({name: this.name, value: v}); +		} +	}); +	//hand off to jQuery.param for proper encoding +	return $.param(a);  };  /**   * Returns the value(s) of the element in the matched set.  For example, consider the following form:   *   *  <form><fieldset> - *      <input name="A" type="text" /> - *      <input name="A" type="text" /> - *      <input name="B" type="checkbox" value="B1" /> - *      <input name="B" type="checkbox" value="B2"/> - *      <input name="C" type="radio" value="C1" /> - *      <input name="C" type="radio" value="C2" /> + *	  <input name="A" type="text" /> + *	  <input name="A" type="text" /> + *	  <input name="B" type="checkbox" value="B1" /> + *	  <input name="B" type="checkbox" value="B2"/> + *	  <input name="C" type="radio" value="C1" /> + *	  <input name="C" type="radio" value="C2" />   *  </fieldset></form>   *   *  var v = $(':text').fieldValue(); @@ -514,51 +671,60 @@ $.fn.fieldSerialize = function(successful) {   * for each element is returned.   *   * Note: This method *always* returns an array.  If no valid value can be determined the - *       array will be empty, otherwise it will contain one or more values. + *	   array will be empty, otherwise it will contain one or more values.   */  $.fn.fieldValue = function(successful) { -    for (var val=[], i=0, max=this.length; i < max; i++) { -        var el = this[i]; -        var v = $.fieldValue(el, successful); -        if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) -            continue; -        v.constructor == Array ? $.merge(val, v) : val.push(v); -    } -    return val; +	for (var val=[], i=0, max=this.length; i < max; i++) { +		var el = this[i]; +		var v = $.fieldValue(el, successful); +		if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) { +			continue; +		} +		v.constructor == Array ? $.merge(val, v) : val.push(v); +	} +	return val;  };  /**   * Returns the value of the field element.   */  $.fieldValue = function(el, successful) { -    var n = el.name, t = el.type, tag = el.tagName.toLowerCase(); -    if (typeof successful == 'undefined') successful = true; - -    if (successful && (!n || el.disabled || t == 'reset' || t == 'button' || -        (t == 'checkbox' || t == 'radio') && !el.checked || -        (t == 'submit' || t == 'image') && el.form && el.form.clk != el || -        tag == 'select' && el.selectedIndex == -1)) -            return null; - -    if (tag == 'select') { -        var index = el.selectedIndex; -        if (index < 0) return null; -        var a = [], ops = el.options; -        var one = (t == 'select-one'); -        var max = (one ? index+1 : ops.length); -        for(var i=(one ? index : 0); i < max; i++) { -            var op = ops[i]; -            if (op.selected) { +	var n = el.name, t = el.type, tag = el.tagName.toLowerCase(); +	if (successful === undefined) { +		successful = true; +	} + +	if (successful && (!n || el.disabled || t == 'reset' || t == 'button' || +		(t == 'checkbox' || t == 'radio') && !el.checked || +		(t == 'submit' || t == 'image') && el.form && el.form.clk != el || +		tag == 'select' && el.selectedIndex == -1)) { +			return null; +	} + +	if (tag == 'select') { +		var index = el.selectedIndex; +		if (index < 0) { +			return null; +		} +		var a = [], ops = el.options; +		var one = (t == 'select-one'); +		var max = (one ? index+1 : ops.length); +		for(var i=(one ? index : 0); i < max; i++) { +			var op = ops[i]; +			if (op.selected) {  				var v = op.value; -				if (!v) // extra pain for IE... -                	v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value; -                if (one) return v; -                a.push(v); -            } -        } -        return a; -    } -    return el.value; +				if (!v) { // extra pain for IE... +					v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value; +				} +				if (one) { +					return v; +				} +				a.push(v); +			} +		} +		return a; +	} +	return $(el).val();  };  /** @@ -570,46 +736,52 @@ $.fieldValue = function(el, successful) {   *  - button elements will *not* be effected   */  $.fn.clearForm = function() { -    return this.each(function() { -        $('input,select,textarea', this).clearFields(); -    }); +	return this.each(function() { +		$('input,select,textarea', this).clearFields(); +	});  };  /**   * Clears the selected form elements.   */  $.fn.clearFields = $.fn.clearInputs = function() { -    return this.each(function() { -        var t = this.type, tag = this.tagName.toLowerCase(); -        if (t == 'text' || t == 'password' || tag == 'textarea') -            this.value = ''; -        else if (t == 'checkbox' || t == 'radio') -            this.checked = false; -        else if (tag == 'select') -            this.selectedIndex = -1; -    }); +	return this.each(function() { +		var t = this.type, tag = this.tagName.toLowerCase(); +		if (t == 'text' || t == 'password' || tag == 'textarea') { +			this.value = ''; +		} +		else if (t == 'checkbox' || t == 'radio') { +			this.checked = false; +		} +		else if (tag == 'select') { +			this.selectedIndex = -1; +		} +	});  };  /**   * Resets the form data.  Causes all form elements to be reset to their original value.   */  $.fn.resetForm = function() { -    return this.each(function() { -        // guard against an input with the name of 'reset' -        // note that IE reports the reset function as an 'object' -        if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) -            this.reset(); -    }); +	return this.each(function() { +		// guard against an input with the name of 'reset' +		// note that IE reports the reset function as an 'object' +		if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) { +			this.reset(); +		} +	});  };  /**   * Enables or disables any matching elements.   */  $.fn.enable = function(b) { -    if (b == undefined) b = true; -    return this.each(function() { -        this.disabled = !b; -    }); +	if (b === undefined) { +		b = true; +	} +	return this.each(function() { +		this.disabled = !b; +	});  };  /** @@ -617,27 +789,37 @@ $.fn.enable = function(b) {   * selects/deselects and matching option elements.   */  $.fn.selected = function(select) { -    if (select == undefined) select = true; -    return this.each(function() { -        var t = this.type; -        if (t == 'checkbox' || t == 'radio') -            this.checked = select; -        else if (this.tagName.toLowerCase() == 'option') { -            var $sel = $(this).parent('select'); -            if (select && $sel[0] && $sel[0].type == 'select-one') { -                // deselect all other options -                $sel.find('option').selected(false); -            } -            this.selected = select; -        } -    }); +	if (select === undefined) { +		select = true; +	} +	return this.each(function() { +		var t = this.type; +		if (t == 'checkbox' || t == 'radio') { +			this.checked = select; +		} +		else if (this.tagName.toLowerCase() == 'option') { +			var $sel = $(this).parent('select'); +			if (select && $sel[0] && $sel[0].type == 'select-one') { +				// deselect all other options +				$sel.find('option').selected(false); +			} +			this.selected = select; +		} +	});  };  // helper fn for console logging  // set $.fn.ajaxSubmit.debug to true to enable debug logging  function log() { -    if ($.fn.ajaxSubmit.debug && window.console && window.console.log) -        window.console.log('[jquery.form] ' + Array.prototype.join.call(arguments,'')); +	if ($.fn.ajaxSubmit.debug) { +		var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,''); +		if (window.console && window.console.log) { +			window.console.log(msg); +		} +		else if (window.opera && window.opera.postError) { +			window.opera.postError(msg); +		} +	}  };  })(jQuery);  | 
