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';
}
}
);
}