944 lines
28 KiB
JavaScript
944 lines
28 KiB
JavaScript
var XHR = XMLHttpRequest
|
|
if (!XHR) throw new Error('missing XMLHttpRequest')
|
|
else console.log('HTTP Browser Module Ver. 1.1.3 initialized.');
|
|
|
|
Utils = {
|
|
addCSS : function (styles) {
|
|
var styleSheet = document.createElement("style")
|
|
styleSheet.type = "text/css"
|
|
styleSheet.innerText = styles
|
|
document.head.appendChild(styleSheet)
|
|
},
|
|
|
|
// Analyze JS using esprima
|
|
analyze : function (code) {
|
|
var more='';
|
|
try {
|
|
var ast = esprima.parse(code, { tolerant: true, loc:true });
|
|
if (ast.errors && ast.errors.length>0) more = ast.errors[0];
|
|
} catch (e) {
|
|
if (e.lineNumber) more = e+', in line '+e.lineNumber;
|
|
}
|
|
return more;
|
|
},
|
|
|
|
beep : function (duration,volume,frequency,type) {
|
|
if (!Utils.audioCtx) Utils.audioCtx=new(window.AudioContext || window.webkitAudioContext)();
|
|
|
|
var oscillator = Utils.audioCtx.createOscillator();
|
|
var gainNode = Utils.audioCtx.createGain();
|
|
duration=duration||10;
|
|
volume=volume||100;
|
|
frequency=frequency||1000;
|
|
type=type||'sine';
|
|
oscillator.connect(gainNode);
|
|
gainNode.connect(Utils.audioCtx.destination);
|
|
|
|
gainNode.gain.value = volume;
|
|
oscillator.frequency.value = frequency;
|
|
oscillator.type = type;
|
|
|
|
|
|
oscillator.start();
|
|
|
|
setTimeout(
|
|
function() {
|
|
oscillator.stop();
|
|
},
|
|
duration
|
|
);
|
|
|
|
oscillator.onended = function () {
|
|
Utils.audioCtx.close();
|
|
Utils.audioCtx=null;
|
|
};
|
|
},
|
|
|
|
BrowserVersion :(function(){
|
|
var ua= navigator.userAgent, tem,
|
|
M= ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
|
|
if(/trident/i.test(M[1])){
|
|
tem= /\brv[ :]+(\d+)/g.exec(ua) || [];
|
|
return 'IE '+(tem[1] || '');
|
|
}
|
|
if(M[1]=== 'Chrome'){
|
|
tem= ua.match(/\b(OPR|Edge)\/(\d+)/);
|
|
if(tem!= null) return tem.slice(1).join(' ').replace('OPR', 'Opera');
|
|
}
|
|
M= M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?'];
|
|
if((tem= ua.match(/version\/(\d+)/i))!= null) M.splice(1, 1, tem[1]);
|
|
return {name:M[0],version:M[1]};
|
|
})(),
|
|
|
|
/** Change CSS
|
|
*
|
|
*/
|
|
changeCSS: function changeCSS(theClass,element,value) {
|
|
var cssRules;
|
|
|
|
for (var S = 0; S < document.styleSheets.length; S++) {
|
|
try {
|
|
document.styleSheets[S].insertRule(theClass+' { '+element+': '+value+'; }',
|
|
document.styleSheets[S][cssRules].length);
|
|
} catch(err) {
|
|
try{
|
|
document.styleSheets[S].addRule(theClass,element+': '+value+';');
|
|
} catch(err){
|
|
try{
|
|
if (document.styleSheets[S]['rules']) {
|
|
cssRules = 'rules';
|
|
} else if (document.styleSheets[S]['cssRules']) {
|
|
cssRules = 'cssRules';
|
|
} else {
|
|
//no rules found... browser unknown
|
|
}
|
|
|
|
for (var R = 0; R < document.styleSheets[S][cssRules].length; R++) {
|
|
if (document.styleSheets[S][cssRules][R].selectorText == theClass) {
|
|
if(document.styleSheets[S][cssRules][R].style[element]){
|
|
document.styleSheets[S][cssRules][R].style[element] = value;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} catch (err){}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
copy : function (o) {
|
|
// recursively copy objects
|
|
var _o,p;
|
|
if (Utils.isArray(o)) {
|
|
if (typeof o[0] != 'object') return o.slice();
|
|
else return o.map(function (e) {
|
|
if (typeof e == 'object') return Utils.copy(e);
|
|
else return e;
|
|
});
|
|
|
|
} else if (Utils.isObject(o)) {
|
|
if (o instanceof Date) return o;
|
|
_o={};
|
|
for(p in o) _o[p]=(typeof o[p]=='object'?Utils.copy(o[p]):o[p]);
|
|
return _o;
|
|
}
|
|
else if (Utils.isString(o))
|
|
return o.slice();
|
|
else return o;
|
|
|
|
},
|
|
|
|
empty : function (v) {
|
|
if (v == undefined) return true;
|
|
if (Utils.isString(v)) return v=='';
|
|
if (Utils.isArray(v)) return v.length==0;
|
|
if (Utils.isObject(v)) return Object.keys(v).length==0;
|
|
return false
|
|
},
|
|
|
|
equal : function (o1,o2) {
|
|
if (Utils.isArray(o1) && Utils.isArray(o2)) {
|
|
if (o1.length!=o2.length) return false;
|
|
for(var i=0;i<o1.length;i++) if (o1[i]!=o2[i]) return false;
|
|
return true;
|
|
}
|
|
if (Utils.isObject(o1) && Utils.isObject(o2)) {
|
|
var keys = Object.keys(o1);
|
|
for(var i in keys) {
|
|
if (!Utils.equal(o1[keys[i]],o2[keys[i]])) return false;
|
|
}
|
|
var keys = Object.keys(o2);
|
|
for(var i in keys) {
|
|
if (!Utils.equal(o1[keys[i]],o2[keys[i]])) return false;
|
|
}
|
|
return true;
|
|
}
|
|
return o1==o2
|
|
},
|
|
|
|
eraseCookie:function eraseCookie(name) {
|
|
document.cookie = name+'=; Max-Age=-99999999;';
|
|
},
|
|
|
|
|
|
|
|
flatten: function flatten(array) {
|
|
var res=[];
|
|
var len=array.length;
|
|
var i;
|
|
for(i=0;i<len;i++) {
|
|
var element=array[i];
|
|
if (!Utils.isArray(element)) res.push(element);
|
|
else {
|
|
var j;
|
|
var len2=element.length;
|
|
for(j=0;j<len2;j++) {
|
|
var element2=element[j];
|
|
res.push(element2);
|
|
}
|
|
}
|
|
}
|
|
return res;
|
|
},
|
|
|
|
getCookie:function getCookie(name) {
|
|
var nameEQ = name + "=";
|
|
var ca = document.cookie.split(';');
|
|
for(var i=0;i < ca.length;i++) {
|
|
var c = ca[i];
|
|
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
|
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
|
|
}
|
|
return Utils.sessionCache[name]; // fallback
|
|
},
|
|
|
|
getCookieObject:function (name,def) {
|
|
var nameEQ = name + "=";
|
|
try {
|
|
var ca = document.cookie.split(';');
|
|
for(var i=0;i < ca.length;i++) {
|
|
var c = ca[i];
|
|
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
|
if (c.indexOf(nameEQ) == 0) return JSONfn.parse(c.substring(nameEQ.length,c.length));
|
|
}
|
|
return def;
|
|
} catch (e) {
|
|
console.log(e)
|
|
return def;
|
|
}
|
|
},
|
|
|
|
getOptions : function (text) {
|
|
var tokens=text.split(' ');
|
|
var options={}
|
|
tokens.forEach(function (av) {
|
|
var pl = av.split('=')
|
|
if (pl.length==2) options[pl[0]]=pl[1];
|
|
})
|
|
return options
|
|
},
|
|
|
|
|
|
hashCode: function hashCode(s) {
|
|
var h = 0, l = s.length, i = 0;
|
|
if ( l > 0 )
|
|
while (i < l)
|
|
h = (h << 5) - h + s.charCodeAt(i++) | 0;
|
|
return h;
|
|
},
|
|
|
|
info: function (o) {
|
|
switch (typeof o) {
|
|
case 'function':
|
|
return o.toString().match(/^(function[ ]*[a-zA-Z0-9_]*\([^\)]+\))/)[1];
|
|
}
|
|
},
|
|
|
|
inspect : inspect,
|
|
isArray: function isArray(o) {
|
|
if (o==_ || o ==null) return false;
|
|
else return typeof o == "array" || (typeof o == "object" && o.constructor === Array);
|
|
},
|
|
isArrayArray: function isArrayArray(o) {
|
|
if (o==_ || o ==null) return false;
|
|
else return Utils.isArray(o) &&
|
|
Utils.isArray(o[0]);
|
|
},
|
|
isArrayArrayArray: function isArrayArrayArray(o) {
|
|
if (o==_ || o ==null) return false;
|
|
else return Utils.isArray(o) &&
|
|
Utils.isArray(o[0]) &&
|
|
Utils.isArray(o[0][0]);
|
|
},
|
|
isBuffer: function isBuffer(o) {
|
|
if (o==_ || o ==null) return false;
|
|
else return o instanceof Buffer;
|
|
},
|
|
isEmpty: function isEmpty(o) {
|
|
for(var prop in o) {
|
|
if (o[prop]!=undefined) return false;
|
|
}
|
|
return true;
|
|
},
|
|
isError : function (o) {
|
|
return o instanceof Error
|
|
},
|
|
isFunction: function isFunction(o) {
|
|
return typeof o == "function";
|
|
},
|
|
isMatrix: function isMatrix(o,noarray) {
|
|
if (o==_ || o ==null) return false;
|
|
else return (!noarray && Utils.isArray(o) &&
|
|
Utils.isArray(o[0])) ||
|
|
(Math.MatrixTA && Math.MatrixTA.isMatrix(o)) ||
|
|
(Math.Matrix && Math.Matrix.isMatrix(o))
|
|
;
|
|
},
|
|
isObj: function isObj(o) {
|
|
return typeof o == "object";
|
|
},
|
|
isObject: function isObject(o) {
|
|
return typeof o == "object";
|
|
},
|
|
isRegex: function isRegex(o) {
|
|
return o instanceof RegExp;
|
|
},
|
|
isString: function isString(o) {
|
|
return typeof o == "string" || (typeof o == "object" && o.constructor === String);
|
|
},
|
|
isNumber: function isNumber(o) {
|
|
return typeof o == "number" || (typeof o == "object" && o.constructor === Number);
|
|
},
|
|
isBoolean: function isBoolean (o) {
|
|
return typeof o == "boolean"
|
|
},
|
|
isString: function isString(o) {
|
|
return typeof o == "string"
|
|
},
|
|
isStruct: function isStruct(o) {
|
|
return !Utils.isArray(o) && Utils.isObject(o)
|
|
},
|
|
isTypedArray: function isTypedArray(o) {
|
|
return Utils.isObject(o) && o.buffer instanceof ArrayBuffer
|
|
},
|
|
isVector: function isVector(o,noarray) {
|
|
if (o==_ || o ==null) return false;
|
|
else return (!noarray && Utils.isArray(o)) ||
|
|
(Math.VectorTA && Math.VectorTA.isVector(o)) ||
|
|
(Math.Vector && Math.Vector.isVector(o))
|
|
;
|
|
},
|
|
|
|
// toplevel entry for loading JS/JSON/JSOB/CSV files
|
|
load : function (url,mimetype,cb) {
|
|
var text;
|
|
function filedia(e,process) {
|
|
popup.confirm({
|
|
content : url+':<br>\n'+e+'<br>\n',
|
|
},function (reply) {
|
|
if (!reply.proceed) return;
|
|
Common.loadFile(function (data) {
|
|
if (!data) return;
|
|
cb(process(data));
|
|
},false)
|
|
});
|
|
}
|
|
if (typeof mimetype == 'function') cb=mimetype,mimetype=null;
|
|
if (!mimetype && url.match(/\.json$/)) mimetype='JSON';
|
|
if (!mimetype && url.match(/\.js/)) mimetype='JS';
|
|
if (!mimetype && url.match(/\.csv/)) mimetype='CSV';
|
|
switch (mimetype && mimetype.replace(/application\//,'')) {
|
|
case 'JSON':
|
|
if (cb) return Utils.loadFile(url,function (text,err) {
|
|
if (!err) cb(Utils.ofJSON(text));
|
|
else filedia(err,Utils.ofJSON);
|
|
});
|
|
else return Utils.ofJSON(Utils.loadFile(url));
|
|
case 'JSOB':
|
|
if (cb) return Utils.loadFile(url,function (text,err) {
|
|
if (!err) cb(Utils.ofString(text));
|
|
else filedia(err,Utils.ofString);
|
|
});
|
|
else return Utils.ofString(Utils.loadFile(url));
|
|
case 'CSV':
|
|
if (cb) return Utils.loadFile(url,function (text,err) {
|
|
if (!err) cb(Utils.ofCSV(text));
|
|
else filedia(err,Utils.ofCSV);
|
|
});
|
|
else {
|
|
text =Utils.loadFile(url,null,true);
|
|
if (typeof text != 'string') return text;
|
|
else return Utils.ofCSV(text);
|
|
}
|
|
case 'JS':
|
|
default:
|
|
return Utils.loadScript(url);
|
|
break;
|
|
};
|
|
|
|
},
|
|
|
|
loadFile: function (url,cb) {
|
|
var result,error,_cb=cb;
|
|
if (!_cb) _cb=function (_result,_error) { result=_result; error=_error; };
|
|
try {
|
|
// print(url+params)
|
|
var request = new XMLHttpRequest();
|
|
request.open("GET",url, cb);
|
|
request.onreadystatechange = function () {
|
|
if(request.readyState === 4)
|
|
{
|
|
if(request.status === 200 || request.status == 0)
|
|
{
|
|
var allText = request.responseText;
|
|
_cb(allText);
|
|
} else _cb(null,'GET from '+url+' failed (status)');
|
|
}
|
|
}
|
|
request.onerror = function (err) {
|
|
_cb(null,'GET from '+url+' failed (error)')
|
|
}
|
|
request.send(null);
|
|
} catch (e) {
|
|
_cb(null,e)
|
|
}
|
|
return error||result;
|
|
},
|
|
|
|
loadScript: function (filename) {
|
|
var fileref = document.createElement('script');
|
|
fileref.setAttribute("type", "text/javascript");
|
|
fileref.setAttribute("src", filename);
|
|
if (typeof fileref != "undefined")
|
|
document.getElementsByTagName("head")[0].appendChild(fileref)
|
|
},
|
|
|
|
name: function (o) {
|
|
switch (typeof o) {
|
|
case 'function':
|
|
return o.toString().match(/^function[ ]*([a-zA-Z0-9_]*)\([^\)]+\)/)[1];
|
|
}
|
|
},
|
|
|
|
ofCSV : function (source,convert) {
|
|
try {
|
|
Papa.parse(source,{
|
|
skipEmptyLines: true,
|
|
dynamicTyping: true,
|
|
complete: function(results) {
|
|
data=results.data;
|
|
if (convert) { // first line must be header
|
|
header=data.shift();
|
|
data=data.map(function (row) {
|
|
var r={};
|
|
header.forEach(function (col,i) { r[col]=row[i] });
|
|
return r;
|
|
})
|
|
}
|
|
}
|
|
});
|
|
if (data && data[0].length==1) data=data.map(function (row) { return row[0] });
|
|
return data;
|
|
} catch (e) {
|
|
return e;
|
|
}
|
|
},
|
|
|
|
ofJSON : function (source) {
|
|
return JSONfn.parse(source,{});
|
|
},
|
|
|
|
/** Convert agent text sources to agent code in JSOB format
|
|
*
|
|
*/
|
|
ofString : function (source) {
|
|
var code;
|
|
try {
|
|
// execute script in private context
|
|
eval('code = '+source);
|
|
} catch (e) { console.log(e,source) };
|
|
return code;
|
|
},
|
|
|
|
parseUrl : function (url) {
|
|
if (!url) return {};
|
|
var queryString = url.substring( url.indexOf('?') + 1 );
|
|
if (queryString == url) return {};
|
|
var params = {}, queries, temp, i, l;
|
|
|
|
// Split into key/value pairs
|
|
queries = queryString.split("&");
|
|
|
|
// Convert the array of strings into an object
|
|
for ( i = 0, l = queries.length; i < l; i++ ) {
|
|
temp = queries[i].split('=');
|
|
if (temp[1]==undefined) temp[1]='true';
|
|
params[temp[0]] = temp[1].replace('%20',' ');
|
|
}
|
|
|
|
return params;
|
|
},
|
|
|
|
|
|
save : function (path,data,mimetype) {
|
|
if (!mimetype && path.match(/\.json$/)) mimetype='JSON';
|
|
if (!mimetype && path.match(/\.csv/)) mimetype='CSV';
|
|
switch (mimetype && mimetype.replace(/application\//,'')) {
|
|
case 'JSON':
|
|
if (typeof data == 'object') data=JSONfn.stringify(data);
|
|
break;
|
|
}
|
|
return Common.saveFile(data,path);
|
|
},
|
|
|
|
strip: function strip(line) {
|
|
return line.replace(/\"/g,'')
|
|
.replace(/\'/g,'')
|
|
},
|
|
|
|
|
|
/** Cookie Management
|
|
*
|
|
*/
|
|
sessionCache : {},
|
|
|
|
setCookie:function setCookie(name,value,days) {
|
|
var expires = "";
|
|
if (days) {
|
|
var date = new Date();
|
|
date.setTime(date.getTime() + (days*24*60*60*1000));
|
|
expires = "; expires=" + date.toUTCString();
|
|
}
|
|
document.cookie = name + "=" + (value || "") + expires + "; path=/";
|
|
Utils.sessionCache[name]=value; // fallback if cookies are denied
|
|
},
|
|
|
|
setCookieObject:function (name,obj,days) {
|
|
var expires = "";
|
|
var value = JSONfn.stringify(obj);
|
|
if (days) {
|
|
var date = new Date();
|
|
date.setTime(date.getTime() + (days*24*60*60*1000));
|
|
expires = "; expires=" + date.toUTCString();
|
|
}
|
|
document.cookie = name + "=" + (value || "") + expires + "; path=/";
|
|
},
|
|
|
|
stringToArrayBuffer : function (str) {
|
|
var buf = new ArrayBuffer(str.length);
|
|
var bufView = new Uint8Array(buf);
|
|
|
|
for (var i=0, strLen=str.length; i<strLen; i++) {
|
|
bufView[i] = str.charCodeAt(i);
|
|
}
|
|
|
|
return buf;
|
|
},
|
|
|
|
stringToUint8Array : function (str) {
|
|
var bufView = new Uint8Array(str.length);
|
|
|
|
for (var i=0, strLen=str.length; i<strLen; i++) {
|
|
bufView[i] = str.charCodeAt(i);
|
|
}
|
|
|
|
return bufView;
|
|
},
|
|
|
|
time : function () { return Date.now() },
|
|
|
|
/** Convert any object to text source in JSOB format
|
|
*
|
|
*/
|
|
toString : function (o) {
|
|
var usebuffer=false;
|
|
var p,i,keys,s='',sep,tokens;
|
|
if (o===null) return 'null';
|
|
else if (Utils.isArray(o)) {
|
|
s='[';sep='';
|
|
for(p in o) {
|
|
s=s+sep+Utils.toString(o[p]);
|
|
sep=',';
|
|
}
|
|
s+=']';
|
|
} else if (o instanceof Buffer) {
|
|
s='Buffer([';sep='';
|
|
for(i=0;i<o.length;i++) {
|
|
s=s+sep+Utils.toString(o[i]);
|
|
sep=',';
|
|
}
|
|
s+='])';
|
|
} else if (o instanceof Error) {
|
|
s='(new Error("'+o.toString()+'"))';
|
|
} else if (Utils.isTypedArray(o)) {
|
|
s='(new '+Utils.TypedArrayToName(o)+'([';sep='';
|
|
var b=Array.prototype.slice.call(o);
|
|
for(i=0;i<b.length;i++) {
|
|
s=s+sep+String(b[i]);
|
|
sep=',';
|
|
}
|
|
s+=']))';
|
|
} else if (typeof o == 'object') {
|
|
s='{';sep='';
|
|
keys=Object.keys(o);
|
|
for(i in keys) {
|
|
p=keys[i];
|
|
if (o[p]==undefined) continue;
|
|
s=s+sep+"'"+p+"'"+':'+Utils.toString(o[p]);
|
|
sep=',';
|
|
}
|
|
s+='}';
|
|
if (o.__constructor__) s = '(function () { var o='+s+'; o.__proto__='+o.__constructor__+'.prototype; return o})()';
|
|
} else if (typeof o == 'string')
|
|
s="'"+
|
|
o.toString().replace(/'/g,'\\\'')
|
|
.replace(/\n/g,'\\n')+
|
|
"'";
|
|
else if (typeof o == 'function') {
|
|
s=o.toString(true); // try minification (true) if supported by platform
|
|
if (tokens=s.match(/function[ ]+([a-zA-Z0-9]+)[ ]*\(\)[ ]*{[^\[]*\[native code\][^}]*}/)) {
|
|
return tokens[1];
|
|
} else return s;
|
|
} else if (o != undefined)
|
|
s=o.toString();
|
|
else s='undefined';
|
|
return s;
|
|
},
|
|
|
|
|
|
/* TYPED ARRAY */
|
|
typed_arrays : [
|
|
Int8Array,
|
|
Uint8Array,
|
|
Int16Array,
|
|
Uint16Array,
|
|
Int32Array,
|
|
Uint32Array,
|
|
Float32Array,
|
|
Float64Array
|
|
],
|
|
|
|
TypedArrayOfName : {
|
|
Int8Array:Int8Array,
|
|
Uint8Array:Uint8Array,
|
|
Int16Array:Int16Array,
|
|
Uint16Array:Uint16Array,
|
|
Int32Array:Int32Array,
|
|
Uint32Array:Uint32Array,
|
|
Float32Array:Float32Array,
|
|
Float64Array:Float64Array
|
|
},
|
|
TypedArrayToName : function (ftyp) {
|
|
if (ftyp==Int8Array || ftyp instanceof Int8Array) return 'Int8Array';
|
|
if (ftyp==Uint8Array || ftyp instanceof Uint8Array) return 'Uint8Array';
|
|
if (ftyp==Int16Array || ftyp instanceof Int16Array) return 'Int16Array';
|
|
if (ftyp==Uint16Array || ftyp instanceof Uint16Array) return 'Uint16Array';
|
|
if (ftyp==Int32Array || ftyp instanceof Int32Array) return 'Int32Array';
|
|
if (ftyp==Uint32Array || ftyp instanceof Uint32Array) return 'Uint32Array';
|
|
if (ftyp==Float32Array || ftyp instanceof Float32Array) return 'Float32Array';
|
|
if (ftyp==Float64Array || ftyp instanceof Float64Array) return 'Float64Array';
|
|
},
|
|
|
|
|
|
uniqueID : function (length) {
|
|
var s='',
|
|
keys=['a','b','c','d','e','f','g','h','i','j','k','l',
|
|
'o','p','q','r','s','t','u','v','w','x','y','z'];
|
|
keys=keys.concat(keys,keys.map(function (k) { return k.toUpperCase() }));
|
|
keys=keys.concat([1,2,3,4,5,6,7,8,9]);
|
|
for(var i=0;i<length;i++) {
|
|
s+= (keys[(Math.random()*keys.length)|0]);
|
|
}
|
|
return s;
|
|
},
|
|
|
|
/** request
|
|
* typeof @options = { url:string, host: string, port:number, path:string, method:"GET"|"PUT", body?:string, headers:{} }
|
|
* typeof @callback = function (err, xhr, body)
|
|
*/
|
|
|
|
request : function (options, callback) {
|
|
var DEFAULT_TIMEOUT = 2000;
|
|
function is_crossDomain(url) {
|
|
var rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/
|
|
|
|
|
|
// jQuery #8138, IE may throw an exception when accessing
|
|
// a field from window.location if document.domain has been set
|
|
var ajaxLocation
|
|
try { ajaxLocation = location.href }
|
|
catch (e) {
|
|
// Use the href attribute of an A element since IE will modify it given document.location
|
|
ajaxLocation = document.createElement( "a" );
|
|
ajaxLocation.href = "";
|
|
ajaxLocation = ajaxLocation.href;
|
|
}
|
|
|
|
if (ajaxLocation.match('file:')) return true;
|
|
|
|
var ajaxLocParts = rurl.exec(ajaxLocation.toLowerCase()) || []
|
|
, parts = rurl.exec(url.toLowerCase() )
|
|
|
|
var result = !!(
|
|
parts &&
|
|
( parts[1] != ajaxLocParts[1]
|
|
|| parts[2] != ajaxLocParts[2]
|
|
|| (parts[3] || (parts[1] === "http:" ? 80 : 443)) != (ajaxLocParts[3] || (ajaxLocParts[1] === "http:" ? 80 : 443))
|
|
)
|
|
)
|
|
|
|
//console.debug('is_crossDomain('+url+') -> ' + result)
|
|
return result
|
|
}
|
|
|
|
try {
|
|
var xhr = new XHR(),
|
|
err,
|
|
url = options.url || options.uri || ((options.proto?options.proto:'http')+'://'+options.host+':'+(options.port?options.port:80)+'/'+options.path),
|
|
is_cors = is_crossDomain(url),
|
|
supports_cors = ('withCredentials' in xhr)
|
|
|
|
if(is_cors && !supports_cors) {
|
|
err = new Error('Browser does not support cross-origin request: ' + options.uri)
|
|
err.cors = 'unsupported'
|
|
return callback(err, xhr)
|
|
}
|
|
options.headers = options.headers || {};
|
|
options.timeout = options.timeout || DEFAULT_TIMEOUT;
|
|
options.headers = options.headers || {};
|
|
options.body = options.body || null;
|
|
|
|
if(is_cors) xhr.withCredentials = !! options.withCredentials;
|
|
xhr.timeout = options.timeout;
|
|
|
|
xhr.onopen = function () {
|
|
for (var key in options.headers)
|
|
xhr.setRequestHeader(key, options.headers[key])
|
|
}
|
|
|
|
xhr.onload = function () {
|
|
if(xhr.status === 0) {
|
|
err = new Error('EREQUEST')
|
|
callback(err, xhr)
|
|
}
|
|
else callback(null,xhr,xhr.responseText)
|
|
}
|
|
|
|
xhr.ontimeout = function () {
|
|
// XMLHttpRequest timed out. Do something here.
|
|
err = new Error('ETIMEOUT')
|
|
err.duration = options.timeout
|
|
callback(err,xhr, null)
|
|
};
|
|
|
|
xhr.onrror = function () {
|
|
// XMLHttpRequest failed. Do something here.
|
|
err = new Error('ESERVER')
|
|
callback(err,xhr, null)
|
|
};
|
|
|
|
xhr.onreadystatechange = function () {
|
|
if (xhr.readyState === XHR.DONE) {
|
|
if(xhr.status === 0) {
|
|
err = new Error('ENETWORK')
|
|
callback(err, xhr)
|
|
}
|
|
}
|
|
};
|
|
|
|
switch (options.method) {
|
|
case 'GET':
|
|
case 'get':
|
|
xhr.open('GET', url, true /* async */);
|
|
xhr.send()
|
|
break;
|
|
case 'PUT':
|
|
case 'POST':
|
|
case 'put':
|
|
case 'post':
|
|
xhr.open('POST', url, true /* async */);
|
|
xhr.send(options.body)
|
|
break;
|
|
}
|
|
} catch (e) { _log(options,e);console.log(['xhr error: ',options.host,options.path,e].join(' ')); }
|
|
},
|
|
|
|
GET: function (url,params,cb,sync) {
|
|
var result;
|
|
// if (sync && !cb) cb=function (_result) { result=_result };
|
|
if (url.indexOf('http')!=0) url = 'http://'+url;
|
|
try {
|
|
if (params) {
|
|
var o=params,sep='';
|
|
params='/?';
|
|
for(var p in o) {
|
|
params = params + sep + p + '='+o[p];
|
|
sep='&';
|
|
}
|
|
} else params='';
|
|
// print(url+params)
|
|
var request = new XMLHttpRequest();
|
|
request.open("GET",url+params, !sync);
|
|
request.onreadystatechange = function () {
|
|
if(request.readyState === 4)
|
|
{
|
|
if(request.status === 200 || request.status == 0)
|
|
{
|
|
var allText = request.responseText;
|
|
if (allText!='') result=JSONfn.parse(allText);
|
|
else result = new Error('GET data error (empty data)');
|
|
if (cb) cb(result);
|
|
} else {
|
|
result=new Error('GET from '+url+params+' failed (status '+request.status+')');
|
|
if (cb) cb(result)
|
|
}
|
|
}
|
|
}
|
|
request.onerror = function (error) {
|
|
result='Error: GET from '+url+params+' failed: '+error;
|
|
if (cb) cb(result);
|
|
}
|
|
request.send(null);
|
|
} catch (error) {
|
|
result=new Error('GET from '+url+params+' failed: '+error.toString());
|
|
if (cb) cb(result);
|
|
}
|
|
return result;
|
|
},
|
|
|
|
POST: function (url,data,cb,sync){
|
|
var result;
|
|
// if (sync && !cb) cb=function (_result) { result=_result };
|
|
if (url.indexOf('http')!=0) url = 'http://'+url;
|
|
try {
|
|
var request = new XMLHttpRequest();
|
|
request.open("POST", url, !sync);
|
|
request.onreadystatechange = function () {
|
|
if(request.readyState === 4)
|
|
{
|
|
if(request.status === 200 || request.status == 0)
|
|
{
|
|
var allText = request.responseText;
|
|
try {
|
|
if (allText!='') result=JSONfn.parse(allText)
|
|
else result=new Error('POST data error (empty data)');
|
|
} catch (e) {
|
|
result = new Error(e.toString());
|
|
}
|
|
if (cb) cb(result);
|
|
} else {
|
|
result = new Error('POST to '+url+' failed (status)');
|
|
if (cb) cb(result);
|
|
}
|
|
}
|
|
}
|
|
request.onerror = function (error) {
|
|
result = new Error('POST to '+url+' failed: '+error);
|
|
if (cb) cb(result)
|
|
}
|
|
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
|
request.send(JSONfn.stringify(data));
|
|
} catch (error) {
|
|
result=new Error('POST to '+url+' failed: '+error.toString());
|
|
if (cb) cb(result)
|
|
}
|
|
return result;
|
|
},
|
|
|
|
|
|
version: '1.5.1'
|
|
}
|
|
|
|
Utils._init = function () {
|
|
Object.addProperty = function (obj,name,fun) {
|
|
if (obj.prototype[name]) return;
|
|
obj.prototype[name]=fun;
|
|
Object.defineProperty(obj.prototype, name, {enumerable: false});
|
|
};
|
|
|
|
Object.updateProperty = function (obj,name,fun) {
|
|
obj.prototype[name]=fun;
|
|
Object.defineProperty(obj.prototype, name, {enumerable: false});
|
|
};
|
|
|
|
// Array static methods extensions
|
|
if (!Array.create) Array.create = function(length,init) {
|
|
var arr = [], i = length;
|
|
while (i--) {
|
|
arr[i] = init;
|
|
}
|
|
return arr;
|
|
}
|
|
|
|
if (!Array.matrix) Array.matrix = function (rows,cols,init) {
|
|
if (init==undefined) init=0;
|
|
var mat=[];
|
|
for(var i=0;i<rows;i++) {
|
|
var row=[];
|
|
for(j=0;j<cols;j++) row.push(typeof init == 'function'?init(i,j):init);
|
|
mat.push(row);
|
|
}
|
|
return mat;
|
|
};
|
|
|
|
// Array prototype extensions
|
|
Object.addProperty(Array,'last',function () { return this[this.length-1] });
|
|
|
|
// String static methods extensions
|
|
if (!String.create) String.create = function(size,init) {
|
|
var i, s='';
|
|
init=init||' ';
|
|
for(i=0;i<size;i++) s=s+init;
|
|
return s;
|
|
};
|
|
if (!String.copy) String.copy = function(src) {
|
|
var i,dst='';
|
|
for(i=0;i<src.length;i++) dst=dst+src.charAt(i);
|
|
return dst;
|
|
};
|
|
if (!String.get) String.get = function (str,index) {
|
|
return str.charAt(index);
|
|
}
|
|
if (!String.hex) String.hex = function (n,len) {
|
|
// format a hexadecimal number with 'len' figures.
|
|
switch (len) {
|
|
case 2: return (((n>>4) & 0xf).toString(16))+
|
|
((n&0xf).toString(16));
|
|
case 4: return (((n>>12) & 0xf).toString(16)+
|
|
((n>>8) & 0xf).toString(16)+
|
|
((n>>4) & 0xf).toString(16)+
|
|
(n&0xf).toString(16));
|
|
case 6: return (((n>>20) & 0xf).toString(16)+
|
|
((n>>16) & 0xf).toString(16)+
|
|
((n>>12) & 0xf).toString(16)+
|
|
((n>>8) & 0xf).toString(16)+
|
|
((n>>4) & 0xf).toString(16)+
|
|
(n&0xf).toString(16));
|
|
case 8: return (((n>>28) & 0xf).toString(16)+
|
|
((n>>24) & 0xf).toString(16)+
|
|
((n>>20) & 0xf).toString(16)+
|
|
((n>>16) & 0xf).toString(16)+
|
|
((n>>12) & 0xf).toString(16)+
|
|
((n>>8) & 0xf).toString(16)+
|
|
((n>>4) & 0xf).toString(16)+
|
|
(n&0xf).toString(16));
|
|
default: return 'format_hex??';
|
|
}
|
|
};
|
|
if (!String.set) String.set = function (str,index,char) {
|
|
return str.substr(0, index) + char + str.substr(index+1)
|
|
}
|
|
// String prototype extensions
|
|
Object.addProperty(String,'contains', function (el) {
|
|
return this.includes(el)
|
|
})
|
|
|
|
Object.addProperty(String, 'hashCode', function (seed) {
|
|
var str=this,seed=seed||0;
|
|
var h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
|
|
for (var i = 0, ch; i < str.length; i++) {
|
|
ch = str.charCodeAt(i);
|
|
h1 = Math.imul(h1 ^ ch, 2654435761);
|
|
h2 = Math.imul(h2 ^ ch, 1597334677);
|
|
}
|
|
h1 = Math.imul(h1 ^ (h1>>>16), 2246822507) ^ Math.imul(h2 ^ (h2>>>13), 3266489909);
|
|
h2 = Math.imul(h2 ^ (h2>>>16), 2246822507) ^ Math.imul(h1 ^ (h1>>>13), 3266489909);
|
|
return (4294967296 * (2097151 & h2) + (h1>>>0)).toString(16).toUpperCase();
|
|
});
|
|
|
|
if (typeof assert == 'undefined') assert = function(condmsg) {
|
|
if (condmsg != true) {
|
|
Io.out('** Assertion failed: '+condmsg+' **');
|
|
Io.stacktrace();
|
|
throw Error(condmsg);
|
|
}
|
|
};
|
|
}
|
|
|
|
Utils._init();
|
|
|
|
|
|
|
|
|