niman
Version:
A Flexible Installation Manager for Node JS ( NVM plus )
327 lines (274 loc) • 13.4 kB
JavaScript
var ND
, _ = _ || {}
, leftPad = _padLeft.func
, _W = window
, _D = document
, _O = Object
, _C = console
, _B = _D.body
, _FN = Function.apply
, _ById = function (id) { return _D.getElementById (id); }
, _ByQs = function (id) { return _D.querySelector (id); }
, _newHtmlEl = function (el) { return _D.createElementNS ('http://www.w3.org/1999/xhtml', el); }
, _newSvgEl = function (el) { return _D.createElementNS ('http://www.w3.org/2000/svg' , el); }
, _newEL = function (elm,id) { var el=_D.createElement (elm); if (id) el.id=id; return el; }
, _newTXT = function (txt) { var el=_D.createTextNode (txt); return el; }
, _setAttr = function (e,a,v) { e.setAttribute(a,v); return e; }
, _Ajax = function (req , cb , err, sts ) {
var xhttp;
if (window.XMLHttpRequest) {
xhttp = new XMLHttpRequest();
xhttp.timeout = 12000;
}
else {
// code for IE6, IE5
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xhttp.onreadystatechange = function() {
if (sts) sts(xhttp);
switch (xhttp.readyState ) {
case 4: {
switch(xhttp.status) {
case 200:
cb (xhttp.responseText);
break;
default:
err ({'sts' : xhttp.status ,'txt' : xhttp.responseText});
break;
}
}
default:
//log(xhttp.readyState,xhttp.status);
}
};
xhttp.open("GET", req, true);
try {
xhttp.send();
}
catch (e) { log (e); }
}
, getLang = function () {
if (navigator.languages !== ND) return navigator.languages[0];
else return navigator.language;
}
, toLocale = function (ds) {
var da = ds.split("-")
, date = new Date(da[0], da[1]-1,da[2])
;
return date.toLocaleDateString(getLang(),{ 'month' : 'short','year':'numeric','day':'numeric'})
}
, _newHtmlEl = function (el) { return _D.createElementNS ('http://www.w3.org/1999/xhtml', el); }
, _log = function () { _FN.call(console.log, console, arguments); }
, _OrEmpty = function (v) { return v?v:''; }
, showError = function (lbl, err) {
var tbl=_ById('list');
tbl.innerHTML+='<TR><TD colspan=10>'+lbl+'ERROR: ' + err.sts+' '+ (err.txt?err.txt:'') +'</TD></TR>';
}
, onlyMainVersions= function (list) {
var vi = {}
, vl = []
, v
, i
, hiv
, n
;
for (i in list){
v = list[i];
n = numeric(v.version);
hiv = n.substring(0,3);
vo = vi[hiv];
if (vo==ND || (vo.version - v.version)>0) vi[hiv]=v;
}
for (i in vi) vl.push(vi[i]);
return vl;
}
, showList = function (list) {
list=onlyMainVersions(list);
var tbl=_ById('list');
for (v in list){
var ver=list[v];
tbl.innerHTML+='<TR><TD><A target=dist href="' + (ver.origin == 'NODE' ? 'https://nodejs.org/dist/' : 'https://iojs.org/dist/') + ver.version + '/">' +ver.version+'</A>'
+'</TD><TD>'+_OrEmpty(ver.origin )
+'</TD><TD>'+_OrEmpty(toLocale(ver.date) )
+'</TD><TD>'+_OrEmpty(ver.lts )
+'</TD><TD>'+_OrEmpty(ver.npm )
+'</TD><TD>'+_OrEmpty(ver.v8 )
+'</TD><TD>'+_OrEmpty(ver.openssl )
+'</TD><TD>'+_OrEmpty(ver.zlib )
+'</TD><TD>'+_OrEmpty(ver.uv )
+'</TD></TR>';
}
}
, getNodeListInProgress = true
, getIoJsListInProgress = true
, nodeList
, nodeError
, iojsList
, iojsError
, numeric = function ( vs ) {
vs = vs.substring(1);
vs = vs.split('.');
var len = vs.length;
if (len!=3) return 0;
var num= leftPad(vs[0],3,0) + leftPad(vs[1],3,0) + leftPad(vs[2],4,0) ;
return num;
}
, compareVersion = function ( nV ,iV) { return numeric(nV) > numeric(iV); }
, raimbowCol = function (i, ofMax, r, ph) {
var
f = 360 / ofMax
, rd = Math.PI / 180
, mid = 128
, ph = (ph || 40) % 360
, r = (r || 127)
, R = Math.round(Math.sin((f*i- 0+ph)*rd) * r + mid)
, G = Math.round(Math.sin((f*i-120+ph)*rd) * r + mid)
, B = Math.round(Math.sin((f*i-240+ph)*rd) * r + mid)
, c
;
R= R>160?255:R>96?127:0;
G= G>160?255:G>96?127:0;
B= B>160?255:B>96?127:0;
c = (R*0x10000+G*0x100+B)
return c;
}
, addYearMark = function (dv, date,start,step) {
var mrk = _newHtmlEl('div')
mrk.setAttribute('class','yearMark');
var x= (date.getTime()-start) * step;
mrk.innerHTML=date.getFullYear();
mrk.setAttribute('style','left: '+(x>>0)+'px; top:0px; height:100%;');
dv.appendChild(mrk);
}
, showGraph = function (values,col) {
var my = this
, dv = _ById('svgDiv')
, bound = dv.getBoundingClientRect()
, W = bound.width
, H = bound.height
, len = values.length
, min = new Date(values[len-1].date).getTime()
, max = new Date(values[0] .date).getTime()
, step = (W-64)/(max-min)
, i = 0
, x = 0
, y = 0
;
addYearMark(dv,new Date('1-1-2012'),min,step);
addYearMark(dv,new Date('1-1-2013'),min,step);
addYearMark(dv,new Date('1-1-2014'),min,step);
addYearMark(dv,new Date('1-1-2015'),min,step);
addYearMark(dv,new Date('1-1-2016'),min,step);
addYearMark(dv,new Date('1-1-2017'),min,step);
var alt = _newHtmlEl('div')
, altTxt = null
;
alt.setAttribute('class','altLabl');
document.body.appendChild(alt);
for (i=0; i<len; i++) {
var val = values[len-i-1];
y = H-numeric(val.version) / 100000000*H *1.01
x = (new Date(val.date).getTime()-min) * step
var col = raimbowCol(i,len/2).toString(16)
col = '0'.repeat(6-col.length)+col;
var el = _newHtmlEl('div')
el.setAttribute('class','verLab');
el.setAttribute('style','left: '+((x>>0))+'px; top:'+((y>>0)-32)+'px; color:#'+col+';');
if (val.origin=='NODE')
el.innerHTML='<a target=DOCs href="https://nodejs.org/docs/'+val.version+'/api/">'+val.version+'</a>';
else el.innerHTML='<a target=DOCs href="https://iojs.org/docs/' +val.version+'/api/">'+val.version+'</a>';
el.addEventListener('mouseenter', function (e){
if (!altTxt) {
alt.innerHTML= altTxt = this.innerHTML;
alt.style.visibility = 'visible';
}
this.xx=e.clientX;
this.yy=e.clientY;
});
el.addEventListener('mousemove', function (e){
alt.style.top = ''+ (e.clientY -48) +'px';
alt.style.left = ''+ (e.clientX -48) +'px';
});
el.addEventListener('mouseout', function (e){
alt.style.visibility = 'hidden';
altTxt = null;
alt.innerHTML = '';
});
dv.appendChild(el);
}
}
, onAcquiredLists = function () {
if (getNodeListInProgress || getIoJsListInProgress) {
if (nodeError) {}
if (iojsError) {}
return; // not having both ready!
}
var total = 0
, nodeLen = nodeList? nodeList.length : 0
, iojsLen = iojsList? iojsList.length : 0
, i
, j = 0
, k = 0
, merged = []
, empty = 'v'
, smmry = _ById('smmry');
;
if (nodeError) { log(nodeError); showError('NODE:',nodeError); }
else total += nodeLen;
if (iojsError) { log(iojsError); showError('IOJS:',iojsError); }
else total += iojsLen;
for (i=0; i < total; i++) {
var nodeVer = (nodeList && nodeList[j]) ? nodeList[j].version : empty;
var iojsVer = (iojsList && iojsList[k]) ? iojsList[k].version : empty;
if (compareVersion(nodeVer,iojsVer)) { merged[i]=nodeList[j++]; merged[i].origin='NODE'; }
else { merged[i]=iojsList[k++]; merged[i].origin='IO.JS'; }
}
_log (j,k, merged.length);
smmry.innerHTML = "Found <b>"+merged.length+"</b> releases ..<br> ("+j+") from NODE and ("+k+") from IO.JS"
;
showList(merged);
showGraph(merged);
}
, doUse = function (el) {
alert('doUse: '+el );
}
;
_onDocReady ( function () { _log('DOM is Ready ..');
_Ajax ('/cmmnd?list'
, function (res) {
var list = JSON.parse(res)
, inUse = _ById('inUse')
;
_log('installed list',list);
for (i in list){
var oo=list[i];
for (v in oo) if (v!='xyw') break;
inUse.innerHTML += '<TR '+(oo.xyw?'class=inUseV':'') +'>'
+ '<TD><div onclick=doUse(this) class=" btn paper paper-lift">'+v +'</div></TD>'
+ '<TD><div class="arch btn paper paper-lift">'+oo[v] +'</div></TD>'
+ '</TR>';
}
}
, function (err) { _log('ERR:',err); }
);
_Ajax ('node_dist.json' //'http://nodejs.org/dist/index.json'
, function (res) {
var list = JSON.parse(res);
nodeList = list;
getNodeListInProgress=false;
_log('got Node list');
onAcquiredLists();
}
, function (err) { nodeError=err; _log('ERR:',err); onAcquiredLists(); }
);
_Ajax ('iojs_dist.json' //'https://iojs.org/dist/index.json'
, function (res) {
var list = JSON.parse(res);
iojsList = list;
getIoJsListInProgress=false;
_log('got IoJs list');
onAcquiredLists();
}
, function (err) { iojsError=err; _log('ERR:',err); onAcquiredLists(); }
);
});