You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

293 lines
8.5 KiB

/**
* mui ajax
* @param {type} $
* @returns {undefined}
*/
(function($, window, undefined) {
var jsonType = 'application/json';
var htmlType = 'text/html';
var rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi;
var scriptTypeRE = /^(?:text|application)\/javascript/i;
var xmlTypeRE = /^(?:text|application)\/xml/i;
var blankRE = /^\s*$/;
$.ajaxSettings = {
type: 'GET',
beforeSend: $.noop,
success: $.noop,
error: $.noop,
complete: $.noop,
context: null,
xhr: function(protocol) {
return new window.XMLHttpRequest();
},
accepts: {
script: 'text/javascript, application/javascript, application/x-javascript',
json: jsonType,
xml: 'application/xml, text/xml',
html: htmlType,
text: 'text/plain'
},
timeout: 0,
processData: true,
cache: true
};
var ajaxBeforeSend = function(xhr, settings) {
var context = settings.context
if(settings.beforeSend.call(context, xhr, settings) === false) {
return false;
}
};
var ajaxSuccess = function(data, xhr, settings) {
settings.success.call(settings.context, data, 'success', xhr);
ajaxComplete('success', xhr, settings);
};
// type: "timeout", "error", "abort", "parsererror"
var ajaxError = function(error, type, xhr, settings) {
settings.error.call(settings.context, xhr, type, error);
ajaxComplete(type, xhr, settings);
};
// status: "success", "notmodified", "error", "timeout", "abort", "parsererror"
var ajaxComplete = function(status, xhr, settings) {
settings.complete.call(settings.context, xhr, status);
};
var serialize = function(params, obj, traditional, scope) {
var type, array = $.isArray(obj),
hash = $.isPlainObject(obj);
$.each(obj, function(key, value) {
type = $.type(value);
if(scope) {
key = traditional ? scope :
scope + '[' + (hash || type === 'object' || type === 'array' ? key : '') + ']';
}
// handle data in serializeArray() format
if(!scope && array) {
params.add(value.name, value.value);
}
// recurse into nested objects
else if(type === "array" || (!traditional && type === "object")) {
serialize(params, value, traditional, key);
} else {
params.add(key, value);
}
});
};
var serializeData = function(options) {
if(options.processData && options.data && typeof options.data !== "string") {
var contentType = options.contentType;
if(!contentType && options.headers) {
contentType = options.headers['Content-Type'];
}
if(contentType && ~contentType.indexOf(jsonType)) { //application/json
options.data = JSON.stringify(options.data);
} else {
options.data = $.param(options.data, options.traditional);
}
}
if(options.data && (!options.type || options.type.toUpperCase() === 'GET')) {
options.url = appendQuery(options.url, options.data);
options.data = undefined;
}
};
var appendQuery = function(url, query) {
if(query === '') {
return url;
}
return(url + '&' + query).replace(/[&?]{1,2}/, '?');
};
var mimeToDataType = function(mime) {
if(mime) {
mime = mime.split(';', 2)[0];
}
return mime && (mime === htmlType ? 'html' :
mime === jsonType ? 'json' :
scriptTypeRE.test(mime) ? 'script' :
xmlTypeRE.test(mime) && 'xml') || 'text';
};
var parseArguments = function(url, data, success, dataType) {
if($.isFunction(data)) {
dataType = success, success = data, data = undefined;
}
if(!$.isFunction(success)) {
dataType = success, success = undefined;
}
return {
url: url,
data: data,
success: success,
dataType: dataType
};
};
$.ajax = function(url, options) {
if(typeof url === "object") {
options = url;
url = undefined;
}
var settings = options || {};
settings.url = url || settings.url;
for(var key in $.ajaxSettings) {
if(settings[key] === undefined) {
settings[key] = $.ajaxSettings[key];
}
}
serializeData(settings);
var dataType = settings.dataType;
if(settings.cache === false || ((!options || options.cache !== true) && ('script' === dataType))) {
settings.url = appendQuery(settings.url, '_=' + $.now());
}
var mime = settings.accepts[dataType && dataType.toLowerCase()];
var headers = {};
var setHeader = function(name, value) {
headers[name.toLowerCase()] = [name, value];
};
var protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol;
var xhr = settings.xhr(settings);
var nativeSetHeader = xhr.setRequestHeader;
var abortTimeout;
setHeader('X-Requested-With', 'XMLHttpRequest');
setHeader('Accept', mime || '*/*');
if(!!(mime = settings.mimeType || mime)) {
if(mime.indexOf(',') > -1) {
mime = mime.split(',', 2)[0];
}
xhr.overrideMimeType && xhr.overrideMimeType(mime);
}
if(settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() !== 'GET')) {
setHeader('Content-Type', settings.contentType || 'application/x-www-form-urlencoded');
}
if(settings.headers) {
for(var name in settings.headers)
setHeader(name, settings.headers[name]);
}
xhr.setRequestHeader = setHeader;
xhr.onreadystatechange = function() {
if(xhr.readyState === 4) {
xhr.onreadystatechange = $.noop;
clearTimeout(abortTimeout);
var result, error = false;
var isLocal = protocol === 'file:';
if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || (xhr.status === 0 && isLocal && xhr.responseText)) {
dataType = dataType || mimeToDataType(settings.mimeType || xhr.getResponseHeader('content-type'));
result = xhr.responseText;
try {
// http://perfectionkills.com/global-eval-what-are-the-options/
if(dataType === 'script') {
(1, eval)(result);
} else if(dataType === 'xml') {
result = xhr.responseXML;
} else if(dataType === 'json') {
result = blankRE.test(result) ? null : $.parseJSON(result);
}
} catch(e) {
error = e;
}
if(error) {
ajaxError(error, 'parsererror', xhr, settings);
} else {
ajaxSuccess(result, xhr, settings);
}
} else {
var status = xhr.status ? 'error' : 'abort';
var statusText = xhr.statusText || null;
if(isLocal) {
status = 'error';
statusText = '404';
}
ajaxError(statusText, status, xhr, settings);
}
}
};
if(ajaxBeforeSend(xhr, settings) === false) {
xhr.abort();
ajaxError(null, 'abort', xhr, settings);
return xhr;
}
if(settings.xhrFields) {
for(var name in settings.xhrFields) {
xhr[name] = settings.xhrFields[name];
}
}
var async = 'async' in settings ? settings.async : true;
xhr.open(settings.type.toUpperCase(), settings.url, async, settings.username, settings.password);
for(var name in headers) {
if(headers.hasOwnProperty(name)) {
nativeSetHeader.apply(xhr, headers[name]);
}
}
if(settings.timeout > 0) {
abortTimeout = setTimeout(function() {
xhr.onreadystatechange = $.noop;
xhr.abort();
ajaxError(null, 'timeout', xhr, settings);
}, settings.timeout);
}
xhr.send(settings.data ? settings.data : null);
return xhr;
};
$.param = function(obj, traditional) {
var params = [];
params.add = function(k, v) {
this.push(encodeURIComponent(k) + '=' + encodeURIComponent(v));
};
serialize(params, obj, traditional);
return params.join('&').replace(/%20/g, '+');
};
$.get = function( /* url, data, success, dataType */ ) {
return $.ajax(parseArguments.apply(null, arguments));
};
$.post = function( /* url, data, success, dataType */ ) {
var options = parseArguments.apply(null, arguments);
options.type = 'POST';
return $.ajax(options);
};
$.getJSON = function( /* url, data, success */ ) {
var options = parseArguments.apply(null, arguments);
options.dataType = 'json';
return $.ajax(options);
};
$.fn.load = function(url, data, success) {
if(!this.length)
return this;
var self = this,
parts = url.split(/\s/),
selector,
options = parseArguments(url, data, success),
callback = options.success;
if(parts.length > 1)
options.url = parts[0], selector = parts[1];
options.success = function(response) {
if(selector) {
var div = document.createElement('div');
div.innerHTML = response.replace(rscript, "");
var selectorDiv = document.createElement('div');
var childs = div.querySelectorAll(selector);
if(childs && childs.length > 0) {
for(var i = 0, len = childs.length; i < len; i++) {
selectorDiv.appendChild(childs[i]);
}
}
self[0].innerHTML = selectorDiv.innerHTML;
} else {
self[0].innerHTML = response;
}
callback && callback.apply(self, arguments);
};
$.ajax(options);
return this;
};
})(mui, window);