Revert "Updated jQuery Form Plugin from v2.17 to v2.36"

This reverts commit 72037d6143.

Until some of the XHR notice related bugs are sorted out in Opera and
Chromium, reverting back to the previous version. It throws slightly
less errors. XHR file attachments is still a bit problematic in
Opera 10.10/Ubuntu, Opera 10.10/Windows, and Chrome 4/Ubuntu. But this
revert will at least allow regular XHR notices to work okay in Opera
and Chromium.

Standards suck!
This commit is contained in:
Sarven Capadisli 2010-02-25 00:10:36 +01:00
parent ec4899e617
commit b782225ade
1 changed files with 632 additions and 660 deletions

View File

@ -1,12 +1,14 @@
/* /*
* jQuery Form Plugin * jQuery Form Plugin
* version: 2.36 (07-NOV-2009) * version: 2.17 (06-NOV-2008)
* @requires jQuery v1.2.6 or later * @requires jQuery v1.2.2 or later
* *
* Examples and documentation at: http://malsup.com/jquery/form/ * Examples and documentation at: http://malsup.com/jquery/form/
* Dual licensed under the MIT and GPL licenses: * Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php * http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html * http://www.gnu.org/licenses/gpl.html
*
* Revision: $Id$
*/ */
;(function($) { ;(function($) {
@ -53,17 +55,9 @@ $.fn.ajaxSubmit = function(options) {
if (typeof options == 'function') if (typeof options == 'function')
options = { success: options }; 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({ options = $.extend({
url: url, url: this.attr('action') || window.location.toString(),
type: this.attr('method') || 'GET', type: this.attr('method') || 'GET'
iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
}, options || {}); }, options || {});
// hook for manipulating the form data before it is extracted; // hook for manipulating the form data before it is extracted;
@ -87,7 +81,7 @@ $.fn.ajaxSubmit = function(options) {
for (var n in options.data) { for (var n in options.data) {
if(options.data[n] instanceof Array) { if(options.data[n] instanceof Array) {
for (var k in options.data[n]) for (var k in options.data[n])
a.push( { name: n, value: options.data[n][k] } ); a.push( { name: n, value: options.data[n][k] } )
} }
else else
a.push( { name: n, value: options.data[n] } ); a.push( { name: n, value: options.data[n] } );
@ -142,16 +136,11 @@ $.fn.ajaxSubmit = function(options) {
if (files[j]) if (files[j])
found = true; 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 // options.iframe allows user to force iframe mode
// 06-NOV-09: now defaulting to iframe mode if file input is detected if (options.iframe || found) {
if ((files.length && options.iframe !== false) || options.iframe || found || multipart) {
// hack to fix Safari hang (thanks to Tim Molendijk for this) // hack to fix Safari hang (thanks to Tim Molendijk for this)
// see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
if (options.closeKeepAlive) if ($.browser.safari && options.closeKeepAlive)
$.get(options.closeKeepAlive, fileUpload); $.get(options.closeKeepAlive, fileUpload);
else else
fileUpload(); fileUpload();
@ -174,12 +163,14 @@ $.fn.ajaxSubmit = function(options) {
} }
var opts = $.extend({}, $.ajaxSettings, options); var opts = $.extend({}, $.ajaxSettings, options);
var s = $.extend(true, {}, $.extend(true, {}, $.ajaxSettings), opts); var s = jQuery.extend(true, {}, $.extend(true, {}, $.ajaxSettings), opts);
var id = 'jqFormIO' + (new Date().getTime()); var id = 'jqFormIO' + (new Date().getTime());
var $io = $('<iframe id="' + id + '" name="' + id + '" src="'+ opts.iframeSrc +'" />'); var $io = $('<iframe id="' + id + '" name="' + id + '" />');
var io = $io[0]; var io = $io[0];
if ($.browser.msie || $.browser.opera)
io.src = 'javascript:false;document.write("");';
$io.css({ position: 'absolute', top: '-1000px', left: '-1000px' }); $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
var xhr = { // mock object var xhr = { // mock object
@ -193,7 +184,7 @@ $.fn.ajaxSubmit = function(options) {
setRequestHeader: function() {}, setRequestHeader: function() {},
abort: function() { abort: function() {
this.aborted = 1; this.aborted = 1;
$io.attr('src', opts.iframeSrc); // abort op in progress $io.attr('src','about:blank'); // abort op in progress
} }
}; };
@ -203,7 +194,7 @@ $.fn.ajaxSubmit = function(options) {
if (g) $.event.trigger("ajaxSend", [xhr, opts]); if (g) $.event.trigger("ajaxSend", [xhr, opts]);
if (s.beforeSend && s.beforeSend(xhr, s) === false) { if (s.beforeSend && s.beforeSend(xhr, s) === false) {
s.global && $.active--; s.global && jQuery.active--;
return; return;
} }
if (xhr.aborted) if (xhr.aborted)
@ -230,13 +221,11 @@ $.fn.ajaxSubmit = function(options) {
setTimeout(function() { setTimeout(function() {
// make sure form attrs are set // make sure form attrs are set
var t = $form.attr('target'), a = $form.attr('action'); var t = $form.attr('target'), a = $form.attr('action');
$form.attr({
// update form attrs in IE friendly way target: id,
form.setAttribute('target',id); method: 'POST',
if (form.getAttribute('method') != 'POST') action: opts.url
form.setAttribute('method', 'POST'); });
if (form.getAttribute('action') != opts.url)
form.setAttribute('action', opts.url);
// ie borks in some cases when setting encoding // ie borks in some cases when setting encoding
if (! options.skipEncodingOverride) { if (! options.skipEncodingOverride) {
@ -266,19 +255,18 @@ $.fn.ajaxSubmit = function(options) {
} }
finally { finally {
// reset attrs and remove "extra" input elements // reset attrs and remove "extra" input elements
form.setAttribute('action',a); $form.attr('action', a);
t ? form.setAttribute('target', t) : $form.removeAttr('target'); t ? $form.attr('target', t) : $form.removeAttr('target');
$(extraInputs).remove(); $(extraInputs).remove();
} }
}, 10); }, 10);
var domCheckCount = 50;
function cb() { function cb() {
if (cbInvoked++) return; if (cbInvoked++) return;
io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false); io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);
var operaHack = 0;
var ok = true; var ok = true;
try { try {
if (timedOut) throw 'timeout'; if (timedOut) throw 'timeout';
@ -287,19 +275,14 @@ $.fn.ajaxSubmit = function(options) {
doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document; doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
var isXml = opts.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc); if (doc.body == null && !operaHack && $.browser.opera) {
log('isXml='+isXml); // In Opera 9.2.x the iframe DOM is not always traversable when
if (!isXml && (doc.body == null || doc.body.innerHTML == '')) { // the onload callback fires so we give Opera 100ms to right itself
if (--domCheckCount) { operaHack = 1;
// in some browsers (Opera) the iframe DOM is not always traversable when cbInvoked--;
// the onload callback fires, so we loop a bit to accommodate
cbInvoked = 0;
setTimeout(cb, 100); setTimeout(cb, 100);
return; return;
} }
log('Could not access iframe DOM after 50 tries.');
return;
}
xhr.responseText = doc.body ? doc.body.innerHTML : null; xhr.responseText = doc.body ? doc.body.innerHTML : null;
xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc; xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
@ -309,16 +292,8 @@ $.fn.ajaxSubmit = function(options) {
}; };
if (opts.dataType == 'json' || opts.dataType == 'script') { if (opts.dataType == 'json' || opts.dataType == 'script') {
// see if user embedded response in textarea
var ta = doc.getElementsByTagName('textarea')[0]; var ta = doc.getElementsByTagName('textarea')[0];
if (ta) xhr.responseText = ta ? ta.value : xhr.responseText;
xhr.responseText = ta.value;
else {
// account for browsers injecting pre around json response
var pre = doc.getElementsByTagName('pre')[0];
if (pre)
xhr.responseText = pre.innerHTML;
}
} }
else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) { else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
xhr.responseXML = toXml(xhr.responseText); xhr.responseXML = toXml(xhr.responseText);
@ -375,42 +350,40 @@ $.fn.ajaxSubmit = function(options) {
* the form itself. * the form itself.
*/ */
$.fn.ajaxForm = function(options) { $.fn.ajaxForm = function(options) {
return this.ajaxFormUnbind().bind('submit.form-plugin', function() { return this.ajaxFormUnbind().bind('submit.form-plugin',function() {
$(this).ajaxSubmit(options); $(this).ajaxSubmit(options);
return false; return false;
}).bind('click.form-plugin', function(e) { }).each(function() {
var target = e.target; // store options in hash
var $el = $(target); $(":submit,input:image", this).bind('click.form-plugin',function(e) {
if (!($el.is(":submit,input:image"))) { var form = this.form;
// is this a child element of the submit el? (ex: a span within a button) form.clk = this;
var t = $el.closest(':submit'); if (this.type == 'image') {
if (t.length == 0)
return;
target = t[0];
}
var form = this;
form.clk = target;
if (target.type == 'image') {
if (e.offsetX != undefined) { if (e.offsetX != undefined) {
form.clk_x = e.offsetX; form.clk_x = e.offsetX;
form.clk_y = e.offsetY; form.clk_y = e.offsetY;
} else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
var offset = $el.offset(); var offset = $(this).offset();
form.clk_x = e.pageX - offset.left; form.clk_x = e.pageX - offset.left;
form.clk_y = e.pageY - offset.top; form.clk_y = e.pageY - offset.top;
} else { } else {
form.clk_x = e.pageX - target.offsetLeft; form.clk_x = e.pageX - this.offsetLeft;
form.clk_y = e.pageY - target.offsetTop; form.clk_y = e.pageY - this.offsetTop;
} }
} }
// clear form vars // clear form vars
setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100); setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 10);
});
}); });
}; };
// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm // ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
$.fn.ajaxFormUnbind = function() { $.fn.ajaxFormUnbind = function() {
return this.unbind('submit.form-plugin click.form-plugin'); this.unbind('submit.form-plugin');
return this.each(function() {
$(":submit,input:image", this).unbind('click.form-plugin');
});
}; };
/** /**
@ -438,10 +411,8 @@ $.fn.formToArray = function(semantic) {
if (semantic && form.clk && el.type == "image") { if (semantic && form.clk && el.type == "image") {
// handle image inputs on the fly when semantic == true // handle image inputs on the fly when semantic == true
if(!el.disabled && form.clk == el) { 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}); a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
}
continue; continue;
} }
@ -455,10 +426,12 @@ $.fn.formToArray = function(semantic) {
} }
if (!semantic && form.clk) { if (!semantic && form.clk) {
// input type=='image' are not found in elements array! handle it here // input type=='image' are not found in elements array! handle them here
var $input = $(form.clk), input = $input[0], n = input.name; var inputs = form.getElementsByTagName("input");
if (n && !input.disabled && input.type == 'image') { for(var i=0, max=inputs.length; i < max; i++) {
a.push({name: n, value: $input.val()}); var input = inputs[i];
var n = input.name;
if(n && !input.disabled && input.type == "image" && form.clk == input)
a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
} }
} }
@ -566,9 +539,8 @@ $.fieldValue = function(el, successful) {
for(var i=(one ? index : 0); i < max; i++) { for(var i=(one ? index : 0); i < max; i++) {
var op = ops[i]; var op = ops[i];
if (op.selected) { if (op.selected) {
var v = op.value; // extra pain for IE...
if (!v) // extra pain for IE... var v = $.browser.msie && !(op.attributes['value'].specified) ? op.text : op.value;
v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
if (one) return v; if (one) return v;
a.push(v); a.push(v);
} }
@ -598,7 +570,7 @@ $.fn.clearForm = function() {
$.fn.clearFields = $.fn.clearInputs = function() { $.fn.clearFields = $.fn.clearInputs = function() {
return this.each(function() { return this.each(function() {
var t = this.type, tag = this.tagName.toLowerCase(); var t = this.type, tag = this.tagName.toLowerCase();
if (t == 'text' || t == 'password' || tag == 'textarea') if (t == 'file' || t == 'text' || t == 'password' || tag == 'textarea')
this.value = ''; this.value = '';
else if (t == 'checkbox' || t == 'radio') else if (t == 'checkbox' || t == 'radio')
this.checked = false; this.checked = false;
@ -625,7 +597,7 @@ $.fn.resetForm = function() {
$.fn.enable = function(b) { $.fn.enable = function(b) {
if (b == undefined) b = true; if (b == undefined) b = true;
return this.each(function() { return this.each(function() {
this.disabled = !b; this.disabled = !b
}); });
}; };