aboutsummaryrefslogtreecommitdiff
path: root/xp/navigator/main.js
diff options
context:
space:
mode:
Diffstat (limited to 'xp/navigator/main.js')
-rw-r--r--xp/navigator/main.js435
1 files changed, 435 insertions, 0 deletions
diff --git a/xp/navigator/main.js b/xp/navigator/main.js
new file mode 100644
index 0000000..c17d025
--- /dev/null
+++ b/xp/navigator/main.js
@@ -0,0 +1,435 @@
+let o={};
+const ui={};
+let curo,curp;
+let editinge=null;
+function getcookie(key)
+{return document.cookie.replace(new RegExp('(?:(?:^|.*;\\s*)'+key+'\\s*\\=\\s*([^;]*).*$)|^.*$'),'$1');}
+function make_sortable(e,updatefunc)
+{
+ let dragging,nxt;
+ function _drag(ev)
+ {
+ ev.preventDefault();
+ ev.dataTransfer.dropEffect='move';
+ const targ=ev.target;
+ if(targ&&targ!=dragging&&targ.draggable&&targ.parentNode==e)
+ {
+ const rect=targ.getBoundingClientRect();
+ const after=(ev.clientY-rect.top)/(rect.bottom-rect.top)>.5;
+ e.insertBefore(dragging,after?targ.nextSibling:targ);
+ }
+ }
+ function _drag_end(ev)
+ {
+ ev.preventDefault();
+ dragging.classList.remove('ghost');
+ e.removeEventListener('dragover',_drag,false);
+ e.removeEventListener('dragend',_drag_end,false);
+ if(nxt!=dragging.nextSibling)updatefunc(dragging);
+ }
+ function _drag_start(ev)
+ {
+ dragging=ev.target;
+ nxt=dragging.nextSibling;
+ ev.dataTransfer.effectAllowed='move';
+ ev.dataTransfer.setData('Text',dragging.textContent);
+ e.addEventListener('dragover',_drag,false);
+ e.addEventListener('dragend',_drag_end,false);
+ setTimeout(function(){dragging.classList.add('ghost');},0);
+ }
+ e.addEventListener('dragstart',_drag_start,false);
+}
+function remove_children(e)
+{
+ while(e.firstChild)e.removeChild(e.firstChild);
+}
+function switch_folder(path)
+{
+ //path starts and ends with /
+ ui.main.style.display='block';
+ ui.settings.style.display=null;
+ const p=path.split('/');
+ remove_children(ui.cont);
+ let cur=o;
+ for(let i=1;cur&&i<p.length-1;++i)
+ {
+ if(cur.type!='folder')break;
+ let k=-1;
+ for(let j=0;j<cur.content.length;++j)
+ if(cur.content[j].name==p[i]){k=j;break;}
+ if(k==-1||cur.content[k].type!='folder')break;
+ cur=cur.content[k];
+ }
+ curo=cur;
+ for(let i=0;i<curo.content.length;++i)
+ {
+ const e=document.createElement('li');
+ const a=document.createElement('a');
+ a.innerHTML=e.contname=curo.content[i].name;
+ if(curo.content[i].href)
+ a.href=curo.content[i].href;
+ e.draggable=true;
+ e.ondblclick=function(e){
+ edit(this);
+ }
+ e.appendChild(a);
+ if(curo.content[i].type=='folder')
+ {
+ e.style.backgroundColor='rgba(255,255,128,0.4)';
+ e.isfolder=true;
+ a.onclick=function(e){
+ e.preventDefault();
+ switch_folder(curp+=this.innerHTML+'/');
+ }
+ }
+ ui.cont.appendChild(e);
+ }
+ const e=document.createElement('li');
+ e.innerHTML='+';
+ e.ondblclick=function(e){
+ const ne=document.createElement('li');
+ const na=document.createElement('a');
+ ne.draggable=true;
+ ne.ondblclick=function(e){
+ edit(this);
+ }
+ ne.appendChild(na);
+ ui.cont.insertBefore(ne,ui.cont.lastChild);
+ edit(ne);
+ }
+ ui.cont.appendChild(e);
+ make_sortable(ui.cont,function(x){move(ui.cont,curo,x.contname);})
+}
+function edit(e)
+{
+ if(e==editinge)return;
+ if(editinge)finish_edit();
+ let clon=ui.templates.lnkmod;
+ if(e.isfolder||e.parentNode==ui.folderlist)
+ clon=ui.templates.fdrmod;
+ const cloned=clon.cloneNode(true);
+ cloned.id=cloned.id.substring(1);
+ for(let i=0;i<cloned.childNodes.length;++i)
+ if(cloned.childNodes[i].id)
+ {
+ cloned.childNodes[i].id=cloned.childNodes[i].id.substring(1);
+ }
+ e.firstChild.style.display='none';
+ e.appendChild(cloned);
+ if(e.isfolder||e.parentNode==ui.folderlist)
+ {
+ if(e.contname)document.getElementById('fdrname').value=e.contname;
+ document.getElementById('fdrname').focus();
+ }
+ else
+ {
+ if(e.contname)document.getElementById('lnkname').value=e.contname;
+ if(e.contname)document.getElementById('lnkhref').value=e.querySelector('a').href;
+ document.getElementById('lnkname').focus();
+ }
+ editinge=e;
+}
+function finish_edit()
+{
+ if(editinge)
+ {
+ const e=document.getElementById('lnkmod')||document.getElementById('fdrmod');
+ if(e.parentNode==editinge)
+ editinge.removeChild(e);
+ editinge.firstChild.style.display=null;
+ }
+ editinge=null;
+}
+function confirm_edit()
+{
+ if(!editinge)return;
+ if(editinge.parentNode==ui.folderlist)
+ {
+ if(editinge.contname)
+ {
+ for(let i=0;i<o.content.length;++i)
+ if(o.content[i].name==editinge.contname)
+ {
+ if(!document.getElementById('fdrname').value.length)
+ {
+ o.content.splice(i,1);
+ editinge.parentNode.removeChild(editinge);
+ editinge=null;
+ return;
+ }
+ o.content[i].name=document.getElementById('fdrname').value;
+ editinge.querySelector('a').innerHTML=editinge.contname=
+ o.content[i].name;
+ break;
+ }
+ }
+ else
+ {
+ if(!document.getElementById('fdrname').value.length)
+ {
+ finish_edit();
+ editinge.parentNode.removeChild(editinge);
+ }
+ let newo={};
+ newo.type='folder';
+ newo.name=document.getElementById('fdrname').value;
+ newo.content=[];
+ o.content.push(newo);
+ editinge.querySelector('a').innerHTML=editinge.contname=newo.name;
+ }
+ }
+ else
+ {
+ if(editinge.contname)
+ {
+ for(let i=0;i<curo.content.length;++i)
+ if(curo.content[i].name==editinge.contname)
+ {
+ curo.content[i].name=document.getElementById(editinge.isfolder?'fdrname':'lnkname').value;
+ if(!curo.content[i].name)
+ {
+ curo.content.splice(i,1);
+ editinge.parentNode.removeChild(editinge);
+ editinge=null;
+ return;
+ }
+ editinge.querySelector('a').innerHTML=editinge.contname=
+ curo.content[i].name;
+ if(!editinge.isfolder)
+ {
+ curo.content[i].href=document.getElementById('lnkhref').value;
+ editinge.querySelector('a').href=curo.content[i].href;
+ }
+ break;
+ }
+ }
+ else
+ {
+ if(!document.getElementById('lnkname').value.length)
+ {
+ finish_edit();
+ editinge.parentNode.removeChild(editinge);
+ }
+ let newo={};
+ newo.type=document.getElementById('lnkhref').value.length?'link':'folder';
+ newo.name=document.getElementById('lnkname').value;
+ editinge.querySelector('a').innerHTML=editinge.contname=newo.name;
+ if(newo.type=='folder')
+ {
+ newo.content=[];
+ editinge.style.backgroundColor='rgba(255,255,128,0.4)';
+ editinge.isfolder=true;
+ editinge.querySelector('a').onclick=function(e){
+ e.preventDefault();
+ switch_folder(curp+=this.innerHTML+'/');
+ }
+ }
+ else
+ {
+ newo.href=document.getElementById('lnkhref').value;
+ editinge.querySelector('a').href=newo.href;
+ }
+ curo.content.push(newo);
+ }
+ }
+ finish_edit();
+}
+function kp(e)
+{
+ e=e||window.event;
+ const keyCode=e.keyCode||e.which;
+ if(keyCode==13)confirm_edit();
+ if(keyCode==27)finish_edit();
+}
+function move(el,o,name)
+{
+ let origpos=-1,newpos=-1;
+ const qs=el.querySelectorAll('li');
+ for(let i=0;i<qs.length;++i)
+ if(qs[i].contname==name){newpos=i;break;}
+ for(let i=0;i<o.content.length;++i)
+ if(o.content[i].name==name){origpos=i;break;}
+ const ob=o.content.splice(origpos,1);
+ o.content.splice(newpos,0,ob[0]);
+}
+async function load_bookmarks()
+{
+ const qo={};
+ qo.op=1;
+ qo.token=getcookie("navigator_token");
+ const h=new Headers();h.append('Content-Type','application/json');
+ const resp=await fetch(new Request('/navigator/cgi-bin/navigator_api.cgi',{method:"POST",headers:h,body:JSON.stringify(qo)}));
+ const r=await resp.text();
+ const ro=JSON.parse(r);
+ if(ro.result)return -1;
+ else try{o=JSON.parse(ro.bookmarks);}catch(e){o={type:"folder",name:"",content:[]};}
+ return 0;
+}
+async function save_bookmarks()
+{
+ const qo={};
+ qo.op=2;
+ qo.token=getcookie("navigator_token");
+ qo.bookmarks=JSON.stringify(o);
+ const h=new Headers();h.append('Content-Type','application/json');
+ const resp=await fetch(new Request('/navigator/cgi-bin/navigator_api.cgi',{method:"POST",headers:h,body:JSON.stringify(qo)}));
+ const r=await resp.text();
+ const ro=JSON.parse(r);
+ if(ro.result)return -1;
+ return 0;
+}
+async function login_a()
+{
+ const o={};
+ o.op=0;
+ o.username=document.getElementById('usrname').value;
+ o.passwd=Sha256.hash(document.getElementById('passwd').value);
+ o.sessionname=document.getElementById('session').value;
+ const h=new Headers();h.append('Content-Type','application/json');
+ const resp=await fetch(new Request('/navigator/cgi-bin/navigator_api.cgi',{method:"POST",headers:h,body:JSON.stringify(o)}));
+ const r=await resp.text();
+ const ro=JSON.parse(r);
+ if(ro.result)return -1;
+ else document.cookie='navigator_token='+ro.token;
+ return 0;
+}
+function login()
+{
+ login_a().then(r=>{
+ if(r)
+ {
+ document.getElementById('loginerr').innerHTML='login failed:'
+ switch(r)
+ {
+ case 1:
+ document.getElementById('loginerr').innerHTML+='authentication failure';
+ break;
+ case 2:
+ document.getElementById('loginerr').innerHTML+='duplicate session';
+ break;
+ }
+ }
+ else
+ {
+ document.getElementById('loginerr').innerHTML='';
+ init();
+ }
+ }
+ );
+}
+function display_bookmarks()
+{
+ remove_children(ui.folderlist);
+ for(let i=0;i<o.content.length;++i)
+ {
+ const e=document.createElement('li');
+ const a=document.createElement('a');
+ a.classList.add('listitem');
+ e.draggable=true;
+ a.innerHTML=e.contname=o.content[i].name;
+ a.onclick=function(e){
+ e.preventDefault();
+ switch_folder(curp='/'+this.innerHTML+'/');
+ }
+ e.ondblclick=function(e){
+ edit(this);
+ }
+ e.appendChild(a);
+ ui.folderlist.appendChild(e);
+ }
+ const e=document.createElement('li');
+ const ea=document.createElement('a');
+ ea.innerHTML='+';e.appendChild(ea);
+ ea.classList.add('listitem');
+ e.ondblclick=function(e){
+ const ne=document.createElement('li');
+ const na=document.createElement('a');
+ na.classList.add('listitem');
+ ne.draggable=true;
+ na.onclick=function(e){
+ e.preventDefault();
+ switch_folder('/'+this.innerHTML+'/');
+ }
+ ne.ondblclick=function(e){
+ edit(this);
+ }
+ ne.appendChild(na);
+ ui.folderlist.insertBefore(ne,ui.folderlist.lastChild);
+ edit(ne);
+ }
+ make_sortable(ui.folderlist,function(x){move(ui.folderlist,o,x.contname);});
+ ui.folderlist.appendChild(e);
+}
+async function list_sessions()
+{
+ const o={};
+ o.op=3;o.token=getcookie("navigator_token");
+ const h=new Headers();h.append('Content-Type','application/json');
+ const resp=await fetch(new Request('/navigator/cgi-bin/navigator_api.cgi',{method:"POST",headers:h,body:JSON.stringify(o)}));
+ const r=await resp.text();
+ const ro=JSON.parse(r);
+ if(ro.result)return -1;
+ remove_children(ui.sessionlist);
+ for(let i=0;i<ro.sessions.length;++i)
+ {
+ const tr=document.createElement('tr');
+ const td1=document.createElement('td');
+ const td2=document.createElement('td');
+ const td3=document.createElement('td');
+ const a=document.createElement('a');
+ td1.innerHTML=ro.sessions[i].sessionname;
+ const d=new Date(ro.sessions[i].date*1000);
+ td2.innerHTML=d.toString();
+ a.innerHTML='x';
+ a.sessionname=ro.sessions[i].sessionname;
+ a.onclick=function(){remove_session(this.sessionname);}
+ a.href='javascript:void(0)';
+ td3.appendChild(a);
+ tr.appendChild(td1);tr.appendChild(td2);tr.appendChild(td3);
+ ui.sessionlist.appendChild(tr);
+ }
+}
+async function remove_session(s)
+{
+ const o={};
+ o.op=4;o.token=getcookie("navigator_token");o.session=s;
+ const h=new Headers();h.append('Content-Type','application/json');
+ const resp=await fetch(new Request('/navigator/cgi-bin/navigator_api.cgi',{method:"POST",headers:h,body:JSON.stringify(o)}));
+ const r=await resp.text();
+ const ro=JSON.parse(r);
+ if(ro.result)return -1;
+ return 0;
+}
+function showsettings()
+{
+ ui.main.style.display=null;
+ ui.settings.style.display='block';
+ list_sessions();
+}
+function init()
+{
+ ui.login=document.getElementById('login');
+ ui.main=document.getElementById('main');
+ ui.cont=document.getElementById('container');
+ ui.folderlist=document.getElementById('folderlist');
+ ui.sessionlist=document.getElementById('sessions');
+ ui.settings=document.getElementById('settings');
+ ui.templates={};
+ ui.templates.lnkmod=document.getElementById('_lnkmod');
+ ui.templates.fdrmod=document.getElementById('_fdrmod');
+ load_bookmarks().then(
+ r=>{
+ if(r)
+ {
+ ui.login.style.display='block';
+ ui.main.style.display=null;
+ }
+ else
+ {
+ ui.login.style.display=null;
+ display_bookmarks();
+ ui.main.style.display='block';
+ }
+ }
+ );
+}