Rewrote the data conversion logic in ajax. Should be cleaner and faster.
This commit is contained in:
parent
0daf7223d0
commit
38101be048
29
src/ajax.js
29
src/ajax.js
|
@ -181,12 +181,7 @@ jQuery.extend({
|
||||||
xhr: function() {
|
xhr: function() {
|
||||||
return new window.XMLHttpRequest();
|
return new window.XMLHttpRequest();
|
||||||
},
|
},
|
||||||
xhrResponseFields: {
|
|
||||||
xml: "XML",
|
|
||||||
text: "Text",
|
|
||||||
json: "JSON"
|
|
||||||
},
|
|
||||||
|
|
||||||
accepts: {
|
accepts: {
|
||||||
xml: "application/xml, text/xml",
|
xml: "application/xml, text/xml",
|
||||||
html: "text/html",
|
html: "text/html",
|
||||||
|
@ -194,13 +189,13 @@ jQuery.extend({
|
||||||
json: "application/json, text/javascript",
|
json: "application/json, text/javascript",
|
||||||
"*": "*/*"
|
"*": "*/*"
|
||||||
},
|
},
|
||||||
|
|
||||||
autoDataType: {
|
autoDataType: {
|
||||||
xml: /xml/,
|
xml: /xml/,
|
||||||
html: /html/,
|
html: /html/,
|
||||||
json: /json/
|
json: /json/
|
||||||
},
|
},
|
||||||
|
|
||||||
// Prefilters
|
// Prefilters
|
||||||
// 1) They are useful to introduce custom dataTypes (see transport/jsonp for an example)
|
// 1) They are useful to introduce custom dataTypes (see transport/jsonp for an example)
|
||||||
// 2) These are called:
|
// 2) These are called:
|
||||||
|
@ -210,26 +205,26 @@ jQuery.extend({
|
||||||
// 4) the catchall symbol "*" can be used
|
// 4) the catchall symbol "*" can be used
|
||||||
// 5) execution will start with transport dataType and THEN continue down to "*" if needed
|
// 5) execution will start with transport dataType and THEN continue down to "*" if needed
|
||||||
prefilters: {},
|
prefilters: {},
|
||||||
|
|
||||||
// Transports bindings
|
// Transports bindings
|
||||||
// 1) key is the dataType
|
// 1) key is the dataType
|
||||||
// 2) the catchall symbol "*" can be used
|
// 2) the catchall symbol "*" can be used
|
||||||
// 3) selection will start with transport dataType and THEN go to "*" if needed
|
// 3) selection will start with transport dataType and THEN go to "*" if needed
|
||||||
transports: {},
|
transports: {},
|
||||||
|
|
||||||
// Checkers
|
// Checkers
|
||||||
// 1) key is dataType
|
// 1) key is dataType
|
||||||
// 2) they are called to control successful response
|
// 2) they are called to control successful response
|
||||||
// 3) error throws is used as error data
|
// 3) error throws is used as error data
|
||||||
dataCheckers: {
|
dataCheckers: {
|
||||||
|
|
||||||
// Check if data is a string
|
// Check if data is a string
|
||||||
"text": function(data) {
|
"text": function(data) {
|
||||||
if ( typeof data != "string" ) {
|
if ( typeof data != "string" ) {
|
||||||
jQuery.error("typeerror");
|
jQuery.error("typeerror");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Check if xml has been properly parsed
|
// Check if xml has been properly parsed
|
||||||
"xml": function(data) {
|
"xml": function(data) {
|
||||||
var documentElement = data ? data.documentElement : data;
|
var documentElement = data ? data.documentElement : data;
|
||||||
|
@ -241,25 +236,25 @@ jQuery.extend({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// List of data converters
|
// List of data converters
|
||||||
// 1) key format is "source_type => destination_type" (spaces required)
|
// 1) key format is "source_type => destination_type" (spaces required)
|
||||||
// 2) the catchall symbol "*" can be used for source_type
|
// 2) the catchall symbol "*" can be used for source_type
|
||||||
dataConverters: {
|
dataConverters: {
|
||||||
|
|
||||||
// Convert anything to text
|
// Convert anything to text
|
||||||
"* => text": function(data) {
|
"* => text": function(data) {
|
||||||
return "" + data;
|
return "" + data;
|
||||||
},
|
},
|
||||||
|
|
||||||
// Text to html (no transformation)
|
// Text to html (no transformation)
|
||||||
"text => html": function(data) {
|
"text => html": function(data) {
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
|
|
||||||
// Evaluate text as a json expression
|
// Evaluate text as a json expression
|
||||||
"text => json": jQuery.parseJSON,
|
"text => json": jQuery.parseJSON,
|
||||||
|
|
||||||
// Parse text as xml
|
// Parse text as xml
|
||||||
"text => xml": function(data) {
|
"text => xml": function(data) {
|
||||||
var xml, parser;
|
var xml, parser;
|
||||||
|
|
163
src/xhr.js
163
src/xhr.js
|
@ -7,9 +7,7 @@ var rquery_xhr = /\?/,
|
||||||
rts = /([?&])_=[^&]*/,
|
rts = /([?&])_=[^&]*/,
|
||||||
rurl = /^(\w+:)?\/\/([^\/?#]+)/,
|
rurl = /^(\w+:)?\/\/([^\/?#]+)/,
|
||||||
|
|
||||||
sliceFunc = Array.prototype.slice,
|
sliceFunc = Array.prototype.slice;
|
||||||
|
|
||||||
isFunction = jQuery.isFunction;
|
|
||||||
|
|
||||||
// Creates a jQuery xhr object
|
// Creates a jQuery xhr object
|
||||||
jQuery.xhr = function( _native ) {
|
jQuery.xhr = function( _native ) {
|
||||||
|
@ -147,7 +145,7 @@ jQuery.xhr = function( _native ) {
|
||||||
requestHeaders[ i.toLowerCase() ] = headers[ i ];
|
requestHeaders[ i.toLowerCase() ] = headers[ i ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
callbackContext = s.context || s;
|
callbackContext = s.context || s;
|
||||||
globalEventContext = s.context ? jQuery(s.context) : jQuery.event;
|
globalEventContext = s.context ? jQuery(s.context) : jQuery.event;
|
||||||
|
|
||||||
|
@ -224,111 +222,76 @@ jQuery.xhr = function( _native ) {
|
||||||
// (if an exception is thrown in the process, it'll be notified as an error)
|
// (if an exception is thrown in the process, it'll be notified as an error)
|
||||||
try {
|
try {
|
||||||
|
|
||||||
function checkData(data) {
|
var i,
|
||||||
if ( data !== undefined ) {
|
current,
|
||||||
var testFunction = s.dataCheckers[srcDataType];
|
prev,
|
||||||
if ( isFunction( testFunction ) ) {
|
checker,
|
||||||
testFunction(data);
|
conv1,
|
||||||
}
|
conv2,
|
||||||
}
|
oneConv,
|
||||||
}
|
convertion,
|
||||||
|
dataTypes = s.dataTypes,
|
||||||
function convertData (data) {
|
dataCheckers = s.dataCheckers,
|
||||||
var conversionFunction = dataConverters[srcDataType+" => "+destDataType] ||
|
|
||||||
dataConverters["* => "+destDataType],
|
|
||||||
noFunction = ! isFunction( conversionFunction );
|
|
||||||
if ( noFunction ) {
|
|
||||||
if ( srcDataType != "text" && destDataType != "text" ) {
|
|
||||||
// We try to put text inbetween
|
|
||||||
var first = dataConverters[srcDataType+" => text"] ||
|
|
||||||
dataConverters["* => text"],
|
|
||||||
second = dataConverters["text => "+destDataType] ||
|
|
||||||
dataConverters["* => "+destDataType],
|
|
||||||
areFunctions = isFunction( first ) && isFunction( second );
|
|
||||||
if ( areFunctions ) {
|
|
||||||
conversionFunction = function (data) {
|
|
||||||
return second( first ( data ) );
|
|
||||||
};
|
|
||||||
}
|
|
||||||
noFunction = ! areFunctions;
|
|
||||||
}
|
|
||||||
if ( noFunction ) {
|
|
||||||
jQuery.error( "no data converter between " + srcDataType + " and " + destDataType );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return conversionFunction(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
var dataTypes = s.dataTypes,
|
|
||||||
i,
|
|
||||||
length,
|
|
||||||
data = response,
|
|
||||||
dataConverters = s.dataConverters,
|
dataConverters = s.dataConverters,
|
||||||
srcDataType,
|
dataFilter = s.dataFilter,
|
||||||
destDataType,
|
responses = {
|
||||||
responseTypes = s.xhrResponseFields;
|
"xml": "XML",
|
||||||
|
"text": "Text"
|
||||||
|
};
|
||||||
|
|
||||||
|
for( i = 0 ; i < dataTypes.length ; i++ ) {
|
||||||
|
|
||||||
for ( i = 0, length = dataTypes.length ; i < length ; i++ ) {
|
current = dataTypes[ i ];
|
||||||
|
|
||||||
destDataType = dataTypes[i];
|
|
||||||
|
|
||||||
if ( !srcDataType ) { // First time
|
if ( i ) {
|
||||||
|
|
||||||
// Copy type
|
prev = dataTypes[ i - 1 ];
|
||||||
srcDataType = destDataType;
|
|
||||||
// Check
|
if ( prev === "*" ) {
|
||||||
checkData(data);
|
|
||||||
// Apply dataFilter
|
prev = current;
|
||||||
if ( isFunction( s.dataFilter ) ) {
|
|
||||||
data = s.dataFilter(data, s.dataType);
|
} else if ( current !== "*" && prev !== current ) {
|
||||||
// Recheck data
|
|
||||||
checkData(data);
|
oneConv = conv1 =
|
||||||
|
dataConverters[ ( conversion = prev + " => " + current ) ] ||
|
||||||
|
dataConverters[ "* => " + current ];
|
||||||
|
|
||||||
|
if ( ! oneConv && prev !== "text" && current !== "text" ) {
|
||||||
|
conv1 = dataConverters[ prev + " => text" ] || dataConverters[ "* => text" ];
|
||||||
|
conv2 = dataConverters[ "text => " + current ];
|
||||||
|
}
|
||||||
|
if ( oneConv || conv1 && conv2 ) {
|
||||||
|
response = oneConv ? conv1( response ) : conv2( conv1( response ) );
|
||||||
|
} else {
|
||||||
|
throw "no " + conversion;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else { // Subsequent times
|
|
||||||
|
|
||||||
// handle auto
|
|
||||||
// JULIAN: for reasons unknown to me === doesn't work here
|
|
||||||
if (destDataType == "*") {
|
|
||||||
|
|
||||||
destDataType = srcDataType;
|
|
||||||
|
|
||||||
} else if ( srcDataType != destDataType ) {
|
|
||||||
|
|
||||||
// Convert
|
|
||||||
data = convertData(data);
|
|
||||||
// Copy type & check
|
|
||||||
srcDataType = destDataType;
|
|
||||||
checkData(data);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy response into the xhr if it hasn't been already
|
|
||||||
var responseDataType,
|
|
||||||
responseType = responseTypes[srcDataType];
|
|
||||||
|
|
||||||
if ( responseType ) {
|
|
||||||
|
|
||||||
responseDataType = srcDataType;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
responseType = responseTypes[ responseDataType = "text" ];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( responseType !== 1 ) {
|
|
||||||
xhr[ "response" + responseType ] = data;
|
|
||||||
responseTypes[ responseType ] = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checker = dataCheckers[ current ];
|
||||||
|
|
||||||
|
if ( response != null && checker ) {
|
||||||
|
checker( response );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( responses[ current ] ) {
|
||||||
|
xhr[ "response" + responses[ current ] ] = response;
|
||||||
|
responses[ current ] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! i && dataFilter ) {
|
||||||
|
|
||||||
|
response = dataFilter( response );
|
||||||
|
|
||||||
|
dataTypes = s.dataTypes;
|
||||||
|
dataFilter = 0;
|
||||||
|
i--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have a real success
|
// We have a real success
|
||||||
success = data;
|
success = response;
|
||||||
isSuccess = 1;
|
isSuccess = 1;
|
||||||
|
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
@ -406,7 +369,7 @@ jQuery.xhr = function( _native ) {
|
||||||
// Ready state change
|
// Ready state change
|
||||||
function setState( value ) {
|
function setState( value ) {
|
||||||
xhr.readyState = value;
|
xhr.readyState = value;
|
||||||
if ( isFunction( xhr.onreadystatechange ) ) {
|
if ( jQuery.isFunction( xhr.onreadystatechange ) ) {
|
||||||
xhr.onreadystatechange();
|
xhr.onreadystatechange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue