168 lines
5.0 KiB
JavaScript
168 lines
5.0 KiB
JavaScript
//
|
|
// AJAX
|
|
//
|
|
(function() {
|
|
|
|
var defaultOpts = {
|
|
json: true
|
|
};
|
|
|
|
function createXMLHttpRequest() {
|
|
if (window.XMLHttpRequest)
|
|
return new XMLHttpRequest();
|
|
|
|
var xhr;
|
|
try {
|
|
xhr = new ActiveXObject('Msxml2.XMLHTTP');
|
|
} catch (e) {
|
|
try {
|
|
xhr = new ActiveXObject('Microsoft.XMLHTTP');
|
|
} catch (e) {}
|
|
}
|
|
if (!xhr) {
|
|
console.error('Your browser doesn\'t support XMLHttpRequest.');
|
|
}
|
|
return xhr;
|
|
}
|
|
|
|
function request(method, url, data, optarg1, optarg2) {
|
|
data = data || null;
|
|
|
|
var opts, callback;
|
|
if (optarg2 !== undefined) {
|
|
opts = optarg1;
|
|
callback = optarg2;
|
|
} else {
|
|
callback = optarg1;
|
|
}
|
|
|
|
opts = opts || {};
|
|
|
|
if (typeof callback != 'function') {
|
|
throw new Error('callback must be a function');
|
|
}
|
|
|
|
if (!url) {
|
|
throw new Error('no url specified');
|
|
}
|
|
|
|
switch (method) {
|
|
case 'GET':
|
|
if (isObject(data)) {
|
|
for (var k in data) {
|
|
if (data.hasOwnProperty(k)) {
|
|
url += (url.indexOf('?') === -1 ? '?' : '&')+encodeURIComponent(k)+'='+encodeURIComponent(data[k])
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'POST':
|
|
if (isObject(data) && !(data instanceof FormData)) {
|
|
var sdata = [];
|
|
for (var k in data) {
|
|
if (data.hasOwnProperty(k)) {
|
|
sdata.push(encodeURIComponent(k)+'='+encodeURIComponent(data[k]));
|
|
}
|
|
}
|
|
data = sdata.join('&');
|
|
}
|
|
break;
|
|
}
|
|
|
|
opts = Object.assign({}, defaultOpts, opts);
|
|
|
|
var xhr = createXMLHttpRequest();
|
|
var aborted = false;
|
|
|
|
xhr.open(method, url);
|
|
|
|
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
|
if (method === 'POST' && !(data instanceof FormData))
|
|
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
|
|
|
var callbackFired = false;
|
|
xhr.onreadystatechange = function() {
|
|
if (callbackFired || aborted)
|
|
return
|
|
|
|
if (xhr.readyState === 4) {
|
|
if (opts.json) {
|
|
var resp = JSON.parse(xhr.responseText)
|
|
if (!isObject(resp))
|
|
throw new Error('ajax: object expected')
|
|
|
|
callbackFired = true;
|
|
if (resp.error)
|
|
callback(resp.error, null, xhr.status);
|
|
else
|
|
callback(null, resp.response, xhr.status);
|
|
} else {
|
|
callback(null, xhr.responseText, xhr.status);
|
|
}
|
|
}
|
|
};
|
|
|
|
xhr.onerror = function(e) {
|
|
if (aborted)
|
|
return
|
|
callback(e, null, 0);
|
|
};
|
|
|
|
xhr.send(method === 'GET' ? null : data);
|
|
|
|
return {
|
|
xhr: xhr,
|
|
abort: function() {
|
|
aborted = true;
|
|
try {
|
|
xhr.abort();
|
|
} catch (e) {}
|
|
}
|
|
};
|
|
}
|
|
|
|
window.ajax = {
|
|
get: request.bind(request, 'GET'),
|
|
post: request.bind(request, 'POST')
|
|
}
|
|
|
|
})();
|
|
|
|
//
|
|
// History API polyfill
|
|
//
|
|
(function() {
|
|
var supportsHistoryAPI = window.history && window.history.pushState && window.history.replaceState;
|
|
|
|
function redirectToHashbangPath() {
|
|
if (!supportsHistoryAPI) {
|
|
var hash = window.location.hash;
|
|
if (hash.startsWith("#!")) {
|
|
var path = hash.substring(2); // Remove the '#!' to get the path
|
|
window.location.replace(path);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!supportsHistoryAPI) {
|
|
var originalTitle = document.title;
|
|
window.history.pushState = function(state, title, url) {
|
|
var path = url.substring(url.indexOf("/", url.indexOf("//") + 2));
|
|
sessionStorage.setItem('!' + path, JSON.stringify(state));
|
|
window.location.hash = '!' + path;
|
|
document.title = title || originalTitle;
|
|
};
|
|
window.history.replaceState = function(state, title, url) {
|
|
var path = url.substring(url.indexOf("/", url.indexOf("//") + 2));
|
|
sessionStorage.setItem('!' + path, JSON.stringify(state));
|
|
var currentUrlWithoutHash = window.location.href.split('#')[0];
|
|
window.location.replace(currentUrlWithoutHash + '#!' + path);
|
|
document.title = title || originalTitle;
|
|
};
|
|
window.addEventListener("hashchange", redirectToHashbangPath, false);
|
|
}
|
|
|
|
// Initial check for redirect only if the browser does not support History API
|
|
redirectToHashbangPath();
|
|
})(); |