pome-ui
Version:
Front-end MVC library
352 lines (307 loc) • 11.6 kB
JavaScript
// Copyright (c) Yuko(Yisheng) Zheng. All rights reserved.
// Licensed under the GPL v3. See LICENSE in the project root for license information.
(function (exports) {
if (typeof exports != 'undefined' && exports.get) {
return exports;
}
function _combineObject(src, dest) {
if (!src) {
return;
}
var fields = Object.getOwnPropertyNames(src);
for (var i = 0; i < fields.length; ++i) {
dest[fields[i]] = src[fields[i]];
}
};
var _options = {
isPagedResult(result) {
if (result.totalRecords == undefined
|| result.totalPages === undefined
|| result.currentPage === undefined
|| result.pageSize === undefined)
return false;
else
return true;
},
beforeSend: function (xhr) {
},
onError: function (err, xhr) {
return Promise.resolve(err);
},
onSucceeded: function (ret, xhr) {
return Promise.resolve(ret);
},
baseUrl: null,
batch: null,
batchInterval: null,
batchTimeout: 10
};
var _batchRequests = [];
var cloneArray = function (array) {
var ret = [];
for (var i = 0; i < array.length; ++i) {
ret.push(array[i]);
}
return ret;
}
if (_options.batch) {
setInterval(function () {
if (!_batchRequests.length) {
return;
}
_options.batch(_batchRequests, _xhrRequest, _options);
_batchRequests = [];
}, _options.batchInterval || 50);
}
function clone(x) {
var json = JSON.stringify(x);
return JSON.parse(json);
}
function getFields(obj) {
var ret = [];
if (!obj || typeof obj !== 'object') return ret;
for (var x in obj) {
if (obj[x])
ret.push(x);
}
return ret;
}
var __cache = {};
var __cacheDictionary = {};
var __cacheExpire = {};
function randomString(length, chars = null) {
chars = chars || '1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM';
var result = '';
for (var i = length; i > 0; --i) {
result += chars[Math.floor(Math.random() * chars.length)]
};
return result;
}
function UseConfig(options) {
_combineObject(options, _options);
}
function _toUrlString(params, questionMark = true, ignore = null) {
var keys = Object.keys(params).sort();
if (!keys.length)
return '';
var ret = questionMark ? '?' : '';
for (var i = 0; i < keys.length; i++) {
if (ignore) {
if (ignore.some(x => x == keys[i])) {
continue;
}
}
ret += keys[i] + '=' + encodeURI(params[keys[i]]) + '&';
}
return ret.substr(0, ret.length - 1);
};
function _urlStringToObject(str) {
str = str.substr(str.indexOf('?') + 1);
var splitedKeyValuePairs = str.split('&');
var ret = {};
for (var i = 0; i < splitedKeyValuePairs.length; i++) {
var splitedKeyValuePair = splitedKeyValuePairs[i].split('=');
ret[splitedKeyValuePair[0]] = decodeURI(splitedKeyValuePair[1]);
}
return ret;
};
function _generateCacheKey(endpoint, params, isPaged) {
var par = clone(params);
if (isPaged && par.page) delete par.page;
return endpoint + _toUrlString(par);
};
function _isPagedResult(result) {
return _options.isPagedResult(result);
};
function _xhrRequest(options) {
var xhr = new XMLHttpRequest();
xhr.open(options.type, options.url);
xhr.setRequestHeader('Content-Type', options.contentType);
if (options.beforeSend) {
options.beforeSend(xhr);
}
if (typeof options.data !== 'string') {
if (options.contentType.toLocaleLowerCase() == 'application/json') {
options.data = JSON.stringify(options.data);
} else if (options.contentType.toLocaleLowerCase() == 'application/octet-stream') {
} else {
options.data = _toUrlString(options.data, false);
}
}
xhr.send(options.data);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
var ret = options.dataType == 'json' ? JSON.parse(xhr.responseText) : xhr.responseText;
if (xhr.status >= 200 && xhr.status < 300) {
options.success(ret, xhr);
} else {
options.error(ret, xhr);
}
}
};
return xhr;
};
function parseUrl(url) {
if (url.indexOf('//') >= 0) {
return url;
} else if (_options.baseUrl) {
return _options.baseUrl + url
} else {
return url;
}
}
function request(endpoint, method, params, dataType, contentType) {
dataType = dataType || 'json';
contentType = contentType || 'application/json';
params = method == 'GET' ? null : params;
endpoint = parseUrl(endpoint);
if (!_options.batch || dataType != 'json' || contentType != 'application/json') {
var self = this;
return new Promise(function (resolve, reject) {
var xhr = _xhrRequest({
url: endpoint,
type: method,
dataType: dataType,
contentType: contentType || 'application/json',
data: method == 'GET' ? null : params,
success: function (ret) {
_options.onSucceeded(ret, xhr).then(function (ret) {
resolve(ret);
});
},
error: function (err) {
return _options.onError(err, xhr).then(function (err) {
reject(err);
});
},
beforeSend: function (xhr) {
_options.beforeSend(xhr);
}
});
});
} else {
return new Promise(function (res, rej) {
_batchRequests.push({
resolve: res,
reject: rej,
request: {
requestId: randomString(32),
url: endpoint,
method: method,
body: params
? JSON.stringify(params)
: null,
contentType: 'application/json',
timeout: _options.batchTimeout
}
});
});
}
}
function getSync(endpoint, params, dataType = 'json') {
var names = Object.getOwnPropertyNames(params || {});
if (names.length) {
if (endpoint.indexOf('?') >= 0) {
endpoint += '&';
} else {
endpoint += '?';
}
}
for (var i = 0; i < names.length; ++i) {
var name = names[i];
endpoint += encodeURIComponent(name) + '=' + encodeURIComponent(params[name] || '') + '&';
}
if (names.length) {
endpoint = endpoint.substr(0, endpoint.length - 1);
}
var xhr = new XMLHttpRequest();
xhr.open('get', endpoint, false);
if (_options.beforeSend) {
_options.beforeSend(xhr);
}
xhr.send();
return dataType == 'json' ? JSON.parse(xhr.responseText) : xhr.responseText;
};
function get(endpoint, params, dataType, contentType) {
var names = Object.getOwnPropertyNames(params || {});
if (names.length) {
if (endpoint.indexOf('?') >= 0) {
endpoint += '&';
} else {
endpoint += '?';
}
}
for (var i = 0; i < names.length; ++i) {
var name = names[i];
endpoint += encodeURIComponent(name) + '=' + encodeURIComponent(params[name] || '') + '&';
}
if (names.length) {
endpoint = endpoint.substr(0, endpoint.length - 1);
}
return request(endpoint, 'GET', params, dataType, contentType);
};
function post(endpoint, params, dataType, contentType) {
return request(endpoint, 'POST', params, dataType, contentType);
};
function patch(endpoint, params, dataType, contentType) {
return request(endpoint, 'PATCH', params, dataType, contentType);
};
function put(endpoint, params, dataType, contentType) {
return request(endpoint, 'PUT', params, dataType, contentType);
};
function _delete(endpoint, params, dataType) {
var names = Object.getOwnPropertyNames(params || {});
if (names.length) {
if (endpoint.indexOf('?') >= 0) {
endpoint += '&';
} else {
endpoint += '?';
}
}
for (var i = 0; i < names.length; ++i) {
var name = names[i];
endpoint += encodeURIComponent(name) + '=' + encodeURIComponent(params[name] || '') + '&';
}
if (names.length) {
endpoint = endpoint.substr(0, endpoint.length - 1);
}
return request(endpoint, 'DELETE', params, dataType);
};
function removeCache(endpoint, params) {
var fields = getFields(params);
var key = _generateCacheKey(endpoint, params, fields.some(x => x === 'page'));
if (__cache[key]) {
delete __cache[key];
}
};
function cache(endpoint, params, result, expire) {
var key;
if (!__cacheDictionary[endpoint])
__cacheDictionary[endpoint] = [];
var isPagedResult = _isPagedResult(result);
if (!isPagedResult) {
key = _generateCacheKey(endpoint, params);
__cache[key] = result;
} else {
key = _generateCacheKey(endpoint, params, true);
if (!__cache[key]) __cache[key] = { isPaged: true };
__cache[key][result.data.current] = result;
}
if (!__cacheDictionary[endpoint].some(x => x == key))
__cacheDictionary[endpoint].push(key);
if (expire)
__cacheExpire[key] = new Date().getTime() + expire;
};
exports.generateQueryStringFromObject = _toUrlString;
exports.generateObjectFromQueryString = _urlStringToObject;
exports.xhrRequest = _xhrRequest;
exports.request = request;
exports.get = get;
exports.getSync = getSync;
exports.post = post;
exports.put = put;
exports.patch = patch;
exports.delete = _delete;
exports.useConfig = UseConfig;
return exports;
})(typeof exports === 'object' && typeof module !== 'undefined' ? exports : (function () { window.cq = {}; return window.cq })());