]> source.dussan.org Git - jquery.git/commitdiff
Extracts the serialization code from the ajax module so that alternative ajax impleme...
authorjaubourg <j@ubourg.net>
Fri, 13 Jul 2012 07:44:21 +0000 (09:44 +0200)
committerjaubourg <j@ubourg.net>
Fri, 13 Jul 2012 07:47:43 +0000 (09:47 +0200)
grunt.js
src/ajax.js
src/serialize.js [new file with mode: 0644]
test/index.html
test/unit/ajax.js
test/unit/serialize.js [new file with mode: 0644]

index a4e99a3c5b5e1c57bb73972f1f8c19629b3f66b8..39f999c2fefe1ece765b3e3e7f6a4bb4b95a935a 100644 (file)
--- a/grunt.js
+++ b/grunt.js
@@ -67,6 +67,7 @@ module.exports = function( grunt ) {
 
                                { flag: "deprecated", src: "src/deprecated.js" },
                                { flag: "css", src: "src/css.js" },
+                               "src/serialize.js",
                                { flag: "ajax", src: "src/ajax.js" },
                                { flag: "ajax/jsonp", src: "src/ajax/jsonp.js", needs: [ "ajax", "ajax/script" ]  },
                                { flag: "ajax/script", src: "src/ajax/script.js", needs: ["ajax"]  },
index 90ac20486b41cb5e6f96a5d735b69276b6610466..053bd696bb01baef0cbd192fe96eab6b16a4af10 100644 (file)
@@ -3,19 +3,14 @@ var // Document location
        // Document location segments
        ajaxLocParts,
 
-       r20 = /%20/g,
-       rbracket = /\[\]$/,
-       rCRLF = /\r?\n/g,
        rhash = /#.*$/,
        rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
-       rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
        // #7653, #8125, #8152: local protocol detection
        rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,
        rnoContent = /^(?:GET|HEAD)$/,
        rprotocol = /^\/\//,
        rquery = /\?/,
        rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
-       rselectTextarea = /^(?:select|textarea)/i,
        rts = /([?&])_=[^&]*/,
        rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
 
@@ -148,103 +143,75 @@ function ajaxExtend( target, src ) {
        }
 }
 
-jQuery.fn.extend({
-       load: function( url, params, callback ) {
-               if ( typeof url !== "string" && _load ) {
-                       return _load.apply( this, arguments );
-               }
-
-               // Don't do a request if no elements are being requested
-               if ( !this.length ) {
-                       return this;
-               }
+jQuery.fn.load = function( url, params, callback ) {
+       if ( typeof url !== "string" && _load ) {
+               return _load.apply( this, arguments );
+       }
 
-               var selector, type, response,
-                       self = this,
-                       off = url.indexOf(" ");
+       // Don't do a request if no elements are being requested
+       if ( !this.length ) {
+               return this;
+       }
 
-               if ( off >= 0 ) {
-                       selector = url.slice( off, url.length );
-                       url = url.slice( 0, off );
-               }
+       var selector, type, response,
+               self = this,
+               off = url.indexOf(" ");
 
-               // If it's a function
-               if ( jQuery.isFunction( params ) ) {
+       if ( off >= 0 ) {
+               selector = url.slice( off, url.length );
+               url = url.slice( 0, off );
+       }
 
-                       // We assume that it's the callback
-                       callback = params;
-                       params = undefined;
+       // If it's a function
+       if ( jQuery.isFunction( params ) ) {
 
-               // Otherwise, build a param string
-               } else if ( typeof params === "object" ) {
-                       type = "POST";
-               }
+               // We assume that it's the callback
+               callback = params;
+               params = undefined;
 
-               // Request the remote document
-               jQuery.ajax({
-                       url: url,
+       // Otherwise, build a param string
+       } else if ( typeof params === "object" ) {
+               type = "POST";
+       }
 
-                       // if "type" variable is undefined, then "GET" method will be used
-                       type: type,
-                       dataType: "html",
-                       data: params,
-                       complete: function( jqXHR, status ) {
-                               if ( callback ) {
-                                       self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
-                               }
+       // Request the remote document
+       jQuery.ajax({
+               url: url,
+
+               // if "type" variable is undefined, then "GET" method will be used
+               type: type,
+               dataType: "html",
+               data: params,
+               complete: function( jqXHR, status ) {
+                       if ( callback ) {
+                               self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
                        }
-               }).done(function( responseText ) {
-
-                       // Save response for use in complete callback
-                       response = arguments;
-
-                       // See if a selector was specified
-                       self.html( selector ?
+               }
+       }).done(function( responseText ) {
 
-                               // Create a dummy div to hold the results
-                               jQuery("<div>")
+               // Save response for use in complete callback
+               response = arguments;
 
-                                       // inject the contents of the document in, removing the scripts
-                                       // to avoid any 'Permission Denied' errors in IE
-                                       .append( responseText.replace( rscript, "" ) )
+               // See if a selector was specified
+               self.html( selector ?
 
-                                       // Locate the specified elements
-                                       .find( selector ) :
+                       // Create a dummy div to hold the results
+                       jQuery("<div>")
 
-                               // If not, just inject the full result
-                               responseText );
+                               // inject the contents of the document in, removing the scripts
+                               // to avoid any 'Permission Denied' errors in IE
+                               .append( responseText.replace( rscript, "" ) )
 
-               });
+                               // Locate the specified elements
+                               .find( selector ) :
 
-               return this;
-       },
+                       // If not, just inject the full result
+                       responseText );
 
-       serialize: function() {
-               return jQuery.param( this.serializeArray() );
-       },
+       });
 
-       serializeArray: function() {
-               return this.map(function(){
-                       return this.elements ? jQuery.makeArray( this.elements ) : this;
-               })
-               .filter(function(){
-                       return this.name && !this.disabled &&
-                               ( this.checked || rselectTextarea.test( this.nodeName ) ||
-                                       rinput.test( this.type ) );
-               })
-               .map(function( i, elem ){
-                       var val = jQuery( this ).val();
-
-                       return val == null ?
-                               null :
-                               jQuery.isArray( val ) ?
-                                       jQuery.map( val, function( val, i ){
-                                               return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
-                                       }) :
-                                       { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
-               }).get();
-       }
-});
+       return this;
+};
 
 // Attach a bunch of functions for handling common AJAX events
 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
@@ -753,80 +720,6 @@ jQuery.extend({
                return jqXHR;
        },
 
-       // Serialize an array of form elements or a set of
-       // key/values into a query string
-       param: function( a, traditional ) {
-               var prefix,
-                       s = [],
-                       add = function( key, value ) {
-                               // If value is a function, invoke it and return its value
-                               value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
-                               s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
-                       };
-
-               // Set traditional to true for jQuery <= 1.3.2 behavior.
-               if ( traditional === undefined ) {
-                       traditional = jQuery.ajaxSettings.traditional;
-               }
-
-               // If an array was passed in, assume that it is an array of form elements.
-               if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
-                       // Serialize the form elements
-                       jQuery.each( a, function() {
-                               add( this.name, this.value );
-                       });
-
-               } else {
-                       // If traditional, encode the "old" way (the way 1.3.2 or older
-                       // did it), otherwise encode params recursively.
-                       for ( prefix in a ) {
-                               buildParams( prefix, a[ prefix ], traditional, add );
-                       }
-               }
-
-               // Return the resulting serialization
-               return s.join( "&" ).replace( r20, "+" );
-       }
-});
-
-function buildParams( prefix, obj, traditional, add ) {
-       var name;
-
-       if ( jQuery.isArray( obj ) ) {
-               // Serialize array item.
-               jQuery.each( obj, function( i, v ) {
-                       if ( traditional || rbracket.test( prefix ) ) {
-                               // Treat each array item as a scalar.
-                               add( prefix, v );
-
-                       } else {
-                               // If array item is non-scalar (array or object), encode its
-                               // numeric index to resolve deserialization ambiguity issues.
-                               // Note that rack (as of 1.0.0) can't currently deserialize
-                               // nested arrays properly, and attempting to do so may cause
-                               // a server error. Possible fixes are to modify rack's
-                               // deserialization algorithm or to provide an option or flag
-                               // to force array serialization to be shallow.
-                               buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
-                       }
-               });
-
-       } else if ( !traditional && jQuery.type( obj ) === "object" ) {
-               // Serialize object item.
-               for ( name in obj ) {
-                       buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
-               }
-
-       } else {
-               // Serialize scalar item.
-               add( prefix, obj );
-       }
-}
-
-// This is still on the jQuery object... for now
-// Want to move this to jQuery.ajax some day
-jQuery.extend({
-
        // Counter for holding the number of active queries
        active: 0,
 
diff --git a/src/serialize.js b/src/serialize.js
new file mode 100644 (file)
index 0000000..212640c
--- /dev/null
@@ -0,0 +1,101 @@
+var r20 = /%20/g,
+       rbracket = /\[\]$/,
+       rCRLF = /\r?\n/g,
+       rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
+       rselectTextarea = /^(?:select|textarea)/i;
+
+jQuery.fn.extend({
+       serialize: function() {
+               return jQuery.param( this.serializeArray() );
+       },
+       serializeArray: function() {
+               return this.map(function(){
+                       return this.elements ? jQuery.makeArray( this.elements ) : this;
+               })
+               .filter(function(){
+                       return this.name && !this.disabled &&
+                               ( this.checked || rselectTextarea.test( this.nodeName ) ||
+                                       rinput.test( this.type ) );
+               })
+               .map(function( i, elem ){
+                       var val = jQuery( this ).val();
+
+                       return val == null ?
+                               null :
+                               jQuery.isArray( val ) ?
+                                       jQuery.map( val, function( val, i ){
+                                               return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+                                       }) :
+                                       { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+               }).get();
+       }
+});
+
+//Serialize an array of form elements or a set of
+//key/values into a query string
+jQuery.param = function( a, traditional ) {
+       var prefix,
+               s = [],
+               add = function( key, value ) {
+                       // If value is a function, invoke it and return its value
+                       value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
+                       s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
+               };
+
+       // Set traditional to true for jQuery <= 1.3.2 behavior.
+       if ( traditional === undefined ) {
+               traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
+       }
+
+       // If an array was passed in, assume that it is an array of form elements.
+       if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
+               // Serialize the form elements
+               jQuery.each( a, function() {
+                       add( this.name, this.value );
+               });
+
+       } else {
+               // If traditional, encode the "old" way (the way 1.3.2 or older
+               // did it), otherwise encode params recursively.
+               for ( prefix in a ) {
+                       buildParams( prefix, a[ prefix ], traditional, add );
+               }
+       }
+
+       // Return the resulting serialization
+       return s.join( "&" ).replace( r20, "+" );
+};
+
+function buildParams( prefix, obj, traditional, add ) {
+       var name;
+
+       if ( jQuery.isArray( obj ) ) {
+               // Serialize array item.
+               jQuery.each( obj, function( i, v ) {
+                       if ( traditional || rbracket.test( prefix ) ) {
+                               // Treat each array item as a scalar.
+                               add( prefix, v );
+
+                       } else {
+                               // If array item is non-scalar (array or object), encode its
+                               // numeric index to resolve deserialization ambiguity issues.
+                               // Note that rack (as of 1.0.0) can't currently deserialize
+                               // nested arrays properly, and attempting to do so may cause
+                               // a server error. Possible fixes are to modify rack's
+                               // deserialization algorithm or to provide an option or flag
+                               // to force array serialization to be shallow.
+                               buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
+                       }
+               });
+
+       } else if ( !traditional && jQuery.type( obj ) === "object" ) {
+               // Serialize object item.
+               for ( name in obj ) {
+                       buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
+               }
+
+       } else {
+               // Serialize scalar item.
+               add( prefix, obj );
+       }
+}
index 59dfad62de74614f820b9ee9a0d735925d95851c..aeb9362d6d249f4e2436d0699f638f90650b704e 100644 (file)
@@ -46,6 +46,7 @@
        <script src="unit/traversing.js"></script>
        <script src="unit/manipulation.js"></script>
        <script src="unit/css.js"></script>
+       <script src="unit/serialize.js"></script>
        <script src="unit/ajax.js"></script>
        <script src="unit/effects.js"></script>
        <script src="unit/offset.js"></script>
index 86d4c9535be7f513a7444a34effdd4eea11883d5..85069b482b6606def40a46a17fa2c4b3f0a50763 100644 (file)
@@ -929,138 +929,6 @@ test("jQuery.ajax - dataType html", function() {
        });
 });
 
-test("serialize()", function() {
-       expect(5);
-
-       // Add html5 elements only for serialize because selector can't yet find them on non-html5 browsers
-       jQuery("#search").after(
-               "<input type='email' id='html5email' name='email' value='dave@jquery.com' />"+
-               "<input type='number' id='html5number' name='number' value='43' />"
-       );
-
-       equal( jQuery("#form").serialize(),
-               "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&select5=3",
-               "Check form serialization as query string");
-
-       equal( jQuery("#form :input").serialize(),
-               "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&select5=3",
-               "Check input serialization as query string");
-
-       equal( jQuery("#testForm").serialize(),
-               "T3=%3F%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=",
-               "Check form serialization as query string");
-
-       equal( jQuery("#testForm :input").serialize(),
-               "T3=%3F%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=",
-               "Check input serialization as query string");
-
-       equal( jQuery("#form, #testForm").serialize(),
-               "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&select5=3&T3=%3F%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=",
-               "Multiple form serialization as query string");
-
-       /* Temporarily disabled. Opera 10 has problems with form serialization.
-       equal( jQuery("#form, #testForm :input").serialize(),
-               "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&T3=%3F%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=",
-               "Mixed form/input serialization as query string");
-       */
-       jQuery("#html5email, #html5number").remove();
-});
-
-test("jQuery.param()", function() {
-       expect(22);
-
-       equal( !jQuery.ajaxSettings.traditional, true, "traditional flag, falsy by default" );
-
-       var params = {"foo":"bar", "baz":42, "quux":"All your base are belong to us"};
-       equal( jQuery.param(params), "foo=bar&baz=42&quux=All+your+base+are+belong+to+us", "simple" );
-
-       params = {"string":"foo","null":null,"undefined":undefined};
-       equal( jQuery.param(params), "string=foo&null=&undefined=", "handle nulls and undefineds properly" );
-
-       params = {"someName": [1, 2, 3], "regularThing": "blah" };
-       equal( jQuery.param(params), "someName%5B%5D=1&someName%5B%5D=2&someName%5B%5D=3&regularThing=blah", "with array" );
-
-       params = {"foo": ["a", "b", "c"]};
-       equal( jQuery.param(params), "foo%5B%5D=a&foo%5B%5D=b&foo%5B%5D=c", "with array of strings" );
-
-       params = {"foo": ["baz", 42, "All your base are belong to us"] };
-       equal( jQuery.param(params), "foo%5B%5D=baz&foo%5B%5D=42&foo%5B%5D=All+your+base+are+belong+to+us", "more array" );
-
-       params = {"foo": { "bar": "baz", "beep": 42, "quux": "All your base are belong to us" } };
-       equal( jQuery.param(params), "foo%5Bbar%5D=baz&foo%5Bbeep%5D=42&foo%5Bquux%5D=All+your+base+are+belong+to+us", "even more arrays" );
-
-       params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" };
-       equal( decodeURIComponent( jQuery.param(params) ), "a[]=1&a[]=2&b[c]=3&b[d][]=4&b[d][]=5&b[e][x][]=6&b[e][y]=7&b[e][z][]=8&b[e][z][]=9&b[f]=true&b[g]=false&b[h]=&i[]=10&i[]=11&j=true&k=false&l[]=&l[]=0&m=cowboy+hat?", "huge structure" );
-
-       params = { "a": [ 0, [ 1, 2 ], [ 3, [ 4, 5 ], [ 6 ] ], { "b": [ 7, [ 8, 9 ], [ { "c": 10, "d": 11 } ], [ [ 12 ] ], [ [ [ 13 ] ] ], { "e": { "f": { "g": [ 14, [ 15 ] ] } } }, 16 ] }, 17 ] };
-       equal( decodeURIComponent( jQuery.param(params) ), "a[]=0&a[1][]=1&a[1][]=2&a[2][]=3&a[2][1][]=4&a[2][1][]=5&a[2][2][]=6&a[3][b][]=7&a[3][b][1][]=8&a[3][b][1][]=9&a[3][b][2][0][c]=10&a[3][b][2][0][d]=11&a[3][b][3][0][]=12&a[3][b][4][0][0][]=13&a[3][b][5][e][f][g][]=14&a[3][b][5][e][f][g][1][]=15&a[3][b][]=16&a[]=17", "nested arrays" );
-
-       params = { "a":[1,2], "b":{ "c":3, "d":[4,5], "e":{ "x":[6], "y":7, "z":[8,9] }, "f":true, "g":false, "h":undefined }, "i":[10,11], "j":true, "k":false, "l":[undefined,0], "m":"cowboy hat?" };
-       equal( jQuery.param(params,true), "a=1&a=2&b=%5Bobject+Object%5D&i=10&i=11&j=true&k=false&l=&l=0&m=cowboy+hat%3F", "huge structure, forced traditional" );
-
-       equal( decodeURIComponent( jQuery.param({ "a": [1,2,3], "b[]": [4,5,6], "c[d]": [7,8,9], "e": { "f": [10], "g": [11,12], "h": 13 } }) ), "a[]=1&a[]=2&a[]=3&b[]=4&b[]=5&b[]=6&c[d][]=7&c[d][]=8&c[d][]=9&e[f][]=10&e[g][]=11&e[g][]=12&e[h]=13", "Make sure params are not double-encoded." );
-
-       // #7945
-       equal( jQuery.param({"jquery": "1.4.2"}), "jquery=1.4.2", "Check that object with a jQuery property get serialized correctly" );
-
-       jQuery.ajaxSetup({ traditional: true });
-
-       params = {"foo":"bar", "baz":42, "quux":"All your base are belong to us"};
-       equal( jQuery.param(params), "foo=bar&baz=42&quux=All+your+base+are+belong+to+us", "simple" );
-
-       params = {"someName": [1, 2, 3], "regularThing": "blah" };
-       equal( jQuery.param(params), "someName=1&someName=2&someName=3&regularThing=blah", "with array" );
-
-       params = {"foo": ["a", "b", "c"]};
-       equal( jQuery.param(params), "foo=a&foo=b&foo=c", "with array of strings" );
-
-       params = {"foo[]":["baz", 42, "All your base are belong to us"]};
-       equal( jQuery.param(params), "foo%5B%5D=baz&foo%5B%5D=42&foo%5B%5D=All+your+base+are+belong+to+us", "more array" );
-
-       params = {"foo[bar]":"baz", "foo[beep]":42, "foo[quux]":"All your base are belong to us"};
-       equal( jQuery.param(params), "foo%5Bbar%5D=baz&foo%5Bbeep%5D=42&foo%5Bquux%5D=All+your+base+are+belong+to+us", "even more arrays" );
-
-       params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" };
-       equal( jQuery.param(params), "a=1&a=2&b=%5Bobject+Object%5D&i=10&i=11&j=true&k=false&l=&l=0&m=cowboy+hat%3F", "huge structure" );
-
-       params = { "a": [ 0, [ 1, 2 ], [ 3, [ 4, 5 ], [ 6 ] ], { "b": [ 7, [ 8, 9 ], [ { "c": 10, d: 11 } ], [ [ 12 ] ], [ [ [ 13 ] ] ], { "e": { "f": { "g": [ 14, [ 15 ] ] } } }, 16 ] }, 17 ] };
-       equal( jQuery.param(params), "a=0&a=1%2C2&a=3%2C4%2C5%2C6&a=%5Bobject+Object%5D&a=17", "nested arrays (not possible when jQuery.param.traditional == true)" );
-
-       params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" };
-       equal( decodeURIComponent( jQuery.param(params,false) ), "a[]=1&a[]=2&b[c]=3&b[d][]=4&b[d][]=5&b[e][x][]=6&b[e][y]=7&b[e][z][]=8&b[e][z][]=9&b[f]=true&b[g]=false&b[h]=&i[]=10&i[]=11&j=true&k=false&l[]=&l[]=0&m=cowboy+hat?", "huge structure, forced not traditional" );
-
-       params = { "param1": null };
-       equal( jQuery.param(params,false), "param1=", "Make sure that null params aren't traversed." );
-
-       params = {"test": {"length": 3, "foo": "bar"} };
-       equal( jQuery.param( params, false ), "test%5Blength%5D=3&test%5Bfoo%5D=bar", "Sub-object with a length property" );
-});
-
-test("jQuery.param() Constructed prop values", function() {
-       expect( 4 );
-
-       /** @constructor */
-       function Record() {
-               this["prop"] = "val";
-       }
-
-       var MyString = String,
-                       MyNumber = Number,
-                       params = { "test": new MyString("foo") };
-
-       equal( jQuery.param( params, false ), "test=foo", "Do not mistake new String() for a plain object" );
-
-       params = { "test": new MyNumber(5) };
-       equal( jQuery.param( params, false ), "test=5", "Do not mistake new Number() for a plain object" );
-
-       params = { "test": new Date() };
-       ok( jQuery.param( params, false ), "(Non empty string returned) Do not mistake new Date() for a plain object" );
-
-       // should allow non-native constructed objects
-       params = { "test": new Record() };
-       equal( jQuery.param( params, false ), jQuery.param({ "test": { "prop": "val" } }), "Allow non-native constructed objects" );
-});
-
 test("synchronous request", function() {
        expect(1);
        var response = jQuery.ajax({
diff --git a/test/unit/serialize.js b/test/unit/serialize.js
new file mode 100644 (file)
index 0000000..ab5d1c4
--- /dev/null
@@ -0,0 +1,145 @@
+module("serialize", { teardown: moduleTeardown });
+
+test("jQuery.param()", function() {
+       expect(22);
+
+       equal( !( jQuery.ajaxSettings && jQuery.ajaxSettings.traditional ), true, "traditional flag, falsy by default" );
+
+       var params = {"foo":"bar", "baz":42, "quux":"All your base are belong to us"};
+       equal( jQuery.param(params), "foo=bar&baz=42&quux=All+your+base+are+belong+to+us", "simple" );
+
+       params = {"string":"foo","null":null,"undefined":undefined};
+       equal( jQuery.param(params), "string=foo&null=&undefined=", "handle nulls and undefineds properly" );
+
+       params = {"someName": [1, 2, 3], "regularThing": "blah" };
+       equal( jQuery.param(params), "someName%5B%5D=1&someName%5B%5D=2&someName%5B%5D=3&regularThing=blah", "with array" );
+
+       params = {"foo": ["a", "b", "c"]};
+       equal( jQuery.param(params), "foo%5B%5D=a&foo%5B%5D=b&foo%5B%5D=c", "with array of strings" );
+
+       params = {"foo": ["baz", 42, "All your base are belong to us"] };
+       equal( jQuery.param(params), "foo%5B%5D=baz&foo%5B%5D=42&foo%5B%5D=All+your+base+are+belong+to+us", "more array" );
+
+       params = {"foo": { "bar": "baz", "beep": 42, "quux": "All your base are belong to us" } };
+       equal( jQuery.param(params), "foo%5Bbar%5D=baz&foo%5Bbeep%5D=42&foo%5Bquux%5D=All+your+base+are+belong+to+us", "even more arrays" );
+
+       params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" };
+       equal( decodeURIComponent( jQuery.param(params) ), "a[]=1&a[]=2&b[c]=3&b[d][]=4&b[d][]=5&b[e][x][]=6&b[e][y]=7&b[e][z][]=8&b[e][z][]=9&b[f]=true&b[g]=false&b[h]=&i[]=10&i[]=11&j=true&k=false&l[]=&l[]=0&m=cowboy+hat?", "huge structure" );
+
+       params = { "a": [ 0, [ 1, 2 ], [ 3, [ 4, 5 ], [ 6 ] ], { "b": [ 7, [ 8, 9 ], [ { "c": 10, "d": 11 } ], [ [ 12 ] ], [ [ [ 13 ] ] ], { "e": { "f": { "g": [ 14, [ 15 ] ] } } }, 16 ] }, 17 ] };
+       equal( decodeURIComponent( jQuery.param(params) ), "a[]=0&a[1][]=1&a[1][]=2&a[2][]=3&a[2][1][]=4&a[2][1][]=5&a[2][2][]=6&a[3][b][]=7&a[3][b][1][]=8&a[3][b][1][]=9&a[3][b][2][0][c]=10&a[3][b][2][0][d]=11&a[3][b][3][0][]=12&a[3][b][4][0][0][]=13&a[3][b][5][e][f][g][]=14&a[3][b][5][e][f][g][1][]=15&a[3][b][]=16&a[]=17", "nested arrays" );
+
+       params = { "a":[1,2], "b":{ "c":3, "d":[4,5], "e":{ "x":[6], "y":7, "z":[8,9] }, "f":true, "g":false, "h":undefined }, "i":[10,11], "j":true, "k":false, "l":[undefined,0], "m":"cowboy hat?" };
+       equal( jQuery.param(params,true), "a=1&a=2&b=%5Bobject+Object%5D&i=10&i=11&j=true&k=false&l=&l=0&m=cowboy+hat%3F", "huge structure, forced traditional" );
+
+       equal( decodeURIComponent( jQuery.param({ "a": [1,2,3], "b[]": [4,5,6], "c[d]": [7,8,9], "e": { "f": [10], "g": [11,12], "h": 13 } }) ), "a[]=1&a[]=2&a[]=3&b[]=4&b[]=5&b[]=6&c[d][]=7&c[d][]=8&c[d][]=9&e[f][]=10&e[g][]=11&e[g][]=12&e[h]=13", "Make sure params are not double-encoded." );
+
+       // #7945
+       equal( jQuery.param({"jquery": "1.4.2"}), "jquery=1.4.2", "Check that object with a jQuery property get serialized correctly" );
+
+       var settings = { traditional: true };
+
+       if ( jQuery.ajaxSettings ) {
+               jQuery.ajaxSetup( settings );
+       } else {
+               jQuery.ajaxSettings = settings;
+       }
+
+       params = {"foo":"bar", "baz":42, "quux":"All your base are belong to us"};
+       equal( jQuery.param(params), "foo=bar&baz=42&quux=All+your+base+are+belong+to+us", "simple" );
+
+       params = {"someName": [1, 2, 3], "regularThing": "blah" };
+       equal( jQuery.param(params), "someName=1&someName=2&someName=3&regularThing=blah", "with array" );
+
+       params = {"foo": ["a", "b", "c"]};
+       equal( jQuery.param(params), "foo=a&foo=b&foo=c", "with array of strings" );
+
+       params = {"foo[]":["baz", 42, "All your base are belong to us"]};
+       equal( jQuery.param(params), "foo%5B%5D=baz&foo%5B%5D=42&foo%5B%5D=All+your+base+are+belong+to+us", "more array" );
+
+       params = {"foo[bar]":"baz", "foo[beep]":42, "foo[quux]":"All your base are belong to us"};
+       equal( jQuery.param(params), "foo%5Bbar%5D=baz&foo%5Bbeep%5D=42&foo%5Bquux%5D=All+your+base+are+belong+to+us", "even more arrays" );
+
+       params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" };
+       equal( jQuery.param(params), "a=1&a=2&b=%5Bobject+Object%5D&i=10&i=11&j=true&k=false&l=&l=0&m=cowboy+hat%3F", "huge structure" );
+
+       params = { "a": [ 0, [ 1, 2 ], [ 3, [ 4, 5 ], [ 6 ] ], { "b": [ 7, [ 8, 9 ], [ { "c": 10, d: 11 } ], [ [ 12 ] ], [ [ [ 13 ] ] ], { "e": { "f": { "g": [ 14, [ 15 ] ] } } }, 16 ] }, 17 ] };
+       equal( jQuery.param(params), "a=0&a=1%2C2&a=3%2C4%2C5%2C6&a=%5Bobject+Object%5D&a=17", "nested arrays (not possible when jQuery.param.traditional == true)" );
+
+       params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" };
+       equal( decodeURIComponent( jQuery.param(params,false) ), "a[]=1&a[]=2&b[c]=3&b[d][]=4&b[d][]=5&b[e][x][]=6&b[e][y]=7&b[e][z][]=8&b[e][z][]=9&b[f]=true&b[g]=false&b[h]=&i[]=10&i[]=11&j=true&k=false&l[]=&l[]=0&m=cowboy+hat?", "huge structure, forced not traditional" );
+
+       params = { "param1": null };
+       equal( jQuery.param(params,false), "param1=", "Make sure that null params aren't traversed." );
+
+       params = {"test": {"length": 3, "foo": "bar"} };
+       equal( jQuery.param( params, false ), "test%5Blength%5D=3&test%5Bfoo%5D=bar", "Sub-object with a length property" );
+
+       if ( jQuery.ajaxSettings === settings ) {
+               delete jQuery.ajaxSettings;
+       } else {
+               jQuery.ajaxSetup({ traditional: false });
+       }
+});
+
+test("jQuery.param() Constructed prop values", function() {
+       expect( 4 );
+
+       /** @constructor */
+       function Record() {
+               this["prop"] = "val";
+       }
+
+       var MyString = String,
+                       MyNumber = Number,
+                       params = { "test": new MyString("foo") };
+
+       equal( jQuery.param( params, false ), "test=foo", "Do not mistake new String() for a plain object" );
+
+       params = { "test": new MyNumber(5) };
+       equal( jQuery.param( params, false ), "test=5", "Do not mistake new Number() for a plain object" );
+
+       params = { "test": new Date() };
+       ok( jQuery.param( params, false ), "(Non empty string returned) Do not mistake new Date() for a plain object" );
+
+       // should allow non-native constructed objects
+       params = { "test": new Record() };
+       equal( jQuery.param( params, false ), jQuery.param({ "test": { "prop": "val" } }), "Allow non-native constructed objects" );
+});
+
+test("serialize()", function() {
+       expect(5);
+
+       // Add html5 elements only for serialize because selector can't yet find them on non-html5 browsers
+       jQuery("#search").after(
+               "<input type='email' id='html5email' name='email' value='dave@jquery.com' />"+
+               "<input type='number' id='html5number' name='number' value='43' />"
+       );
+
+       equal( jQuery("#form").serialize(),
+               "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&select5=3",
+               "Check form serialization as query string");
+
+       equal( jQuery("#form :input").serialize(),
+               "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&select5=3",
+               "Check input serialization as query string");
+
+       equal( jQuery("#testForm").serialize(),
+               "T3=%3F%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=",
+               "Check form serialization as query string");
+
+       equal( jQuery("#testForm :input").serialize(),
+               "T3=%3F%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=",
+               "Check input serialization as query string");
+
+       equal( jQuery("#form, #testForm").serialize(),
+               "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&select5=3&T3=%3F%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=",
+               "Multiple form serialization as query string");
+
+       /* Temporarily disabled. Opera 10 has problems with form serialization.
+       equal( jQuery("#form, #testForm :input").serialize(),
+               "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&T3=%3F%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=",
+               "Mixed form/input serialization as query string");
+       */
+       jQuery("#html5email, #html5number").remove();
+});