Skip to content
Permalink
Browse files

Extracts the serialization code from the ajax module so that alternat…

…ive ajax implementations can use it without the need for the whole ajax module to be included in the build.
  • Loading branch information
jaubourg committed Jul 13, 2012
1 parent c29660c commit ced5e9037a8a1d7306fa6c735ba7f314022c3289
Showing with 301 additions and 292 deletions.
  1. +1 −0 grunt.js
  2. +53 −160 src/ajax.js
  3. +101 −0 src/serialize.js
  4. +1 −0 test/index.html
  5. +0 −132 test/unit/ajax.js
  6. +145 −0 test/unit/serialize.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"] },
@@ -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,

@@ -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 );
}
}
@@ -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>

1 comment on commit ced5e90

@staabm

This comment has been minimized.

Copy link
Contributor

staabm commented on ced5e90 Nov 1, 2012

Is serialize.js considered a jquery module and therefore should be noted in the readmes section for modules?

Please sign in to comment.
You can’t perform that action at this time.