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