Mon 21 Jul 22:43:21 CEST 2025
This commit is contained in:
parent
1a8594d75f
commit
11b3c17a54
943
js/web/utils.js
Normal file
943
js/web/utils.js
Normal file
|
@ -0,0 +1,943 @@
|
|||
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();
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user