Improved internals of web app content menu system.

This commit is contained in:
Ylian Saint-Hilaire 2020-02-17 13:41:25 -08:00
parent 916e20fa9f
commit 40c6cdc88a

View File

@ -606,7 +606,7 @@
<div>
<div id="idx_termFullBtn2" onclick=deskToggleFull(event)>&nbsp;&#x2716;</div>
<input type="button" id="autoconnectbutton2" value="AutoConnect" onclick=autoConnectTerminal(event) onkeypress="return false" onkeydown="return false" style="display:none" />
<span id="connectbutton2span"><input type="button" id="connectbutton2" value="Connect" onclick=connectTerminal(event,1) onkeypress="return false" onkeydown="return false" disabled="disabled" /></span>
<span id="connectbutton2span"><input type="button" id="connectbutton2" cmenu="termConnectButton" value="Connect" onclick=connectTerminal(event,1) onkeypress="return false" onkeydown="return false" disabled="disabled" /></span>
<span id="connectbutton2hspan">&nbsp;<input type="button" id="connectbutton2h" value="HW Connect" title="Connect using Intel AMT hardware KVM" onclick=connectTerminal(event,2) onkeypress="return false" onkeydown="return false" disabled="disabled" /></span>
<span id="disconnectbutton2span">&nbsp;<input type="button" id="disconnectbutton2" value="Disconnect" onclick=connectTerminal(event,0) onkeypress="return false" onkeydown="return false" /></span>
&nbsp;<span id="termstatus">Disconnected</span><span id="termtitle"></span>
@ -3018,7 +3018,7 @@
var collapsed = CollapsedGroups[node.meshid];
r += '<img class=collapseImage id=\"DevxColImg' + deviceHeaderId + '\" src=images/c' + ((collapsed === true)?'1':'2') + '.png height=8 width=8 style=margin-left:2px;margin-right:2px;cursor:pointer onclick=toggleCollapseGroup(\"' + deviceHeaderId + '\",\"' + node.meshid + '\",' + view + ')></img>'; // Collapse action
}
r += '<span id=MxMESH tabindex=0 style=cursor:pointer onclick=gotoMesh("' + node.meshid + '") onkeypress="if (event.key==\'Enter\') gotoMesh(\'' + node.meshid + '\')">' + EscapeHtml(meshes[node.meshid].name) + '</span>' + getMeshActions(mesh2, meshrights) + '</div>';
r += '<span id=MxMESH cmenu=meshContextMenu tabindex=0 style=cursor:pointer onclick=gotoMesh("' + node.meshid + '") onkeypress="if (event.key==\'Enter\') gotoMesh(\'' + node.meshid + '\')">' + EscapeHtml(meshes[node.meshid].name) + '</span>' + getMeshActions(mesh2, meshrights) + '</div>';
if (view == 2) { r += '</div>'; }
current = node.meshid;
displayedMeshes[current] = 1;
@ -3062,7 +3062,7 @@
var icon = node.icon;
if ((!node.conn) || (node.conn == 0)) { icon += ' gray'; }
if (view == 1) {
r += '<div id=devs onmouseover=devMouseHover(this,1) onmouseout=devMouseHover(this,0) style=display:inline-block;width:' + deviceBoxWidth + 'px;height:50px;padding-top:1px;padding-bottom:1px><div style=width:22px;height:50%;float:left;padding-top:12px><input class="' + node.meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + node._id + ' type=checkbox></div><div style=height:100%;cursor:pointer tabindex=0 onclick=gotoDevice(\'' + node._id + '\',null,null,event) onkeypress="if (event.key==\'Enter\') gotoDevice(\'' + node._id + '\',null,null,event)"><div class="i' + icon + '" style=width:50px;float:left></div><div style=height:100%><div class=g1></div><div class=e2><div class=e1 style=width:' + (deviceBoxWidth - 100) + 'px title="' + title + '">' + name + '</div><div>' + NodeStateStr(node) + '</div></div><div class=g2></div></div></div></div>';
r += '<div id=devs cmenu=devsContentMenu onmouseover=devMouseHover(this,1) onmouseout=devMouseHover(this,0) style=display:inline-block;width:' + deviceBoxWidth + 'px;height:50px;padding-top:1px;padding-bottom:1px><div style=width:22px;height:50%;float:left;padding-top:12px><input class="' + node.meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + node._id + ' type=checkbox></div><div style=height:100%;cursor:pointer tabindex=0 onclick=gotoDevice(\'' + node._id + '\',null,null,event) onkeypress="if (event.key==\'Enter\') gotoDevice(\'' + node._id + '\',null,null,event)"><div class="i' + icon + '" style=width:50px;float:left></div><div style=height:100%><div class=g1></div><div class=e2><div class=e1 style=width:' + (deviceBoxWidth - 100) + 'px title="' + title + '">' + name + '</div><div>' + NodeStateStr(node) + '</div></div><div class=g2></div></div></div></div>';
} else if (view == 2) {
var states = [];
if (node.conn) {
@ -3999,65 +3999,56 @@
var contextelement = null;
function handleContextMenu(event) {
// When called, we look for elements with "cmenu=xxx" and show the right context menu for that element.
hideContextMenu();
var scrollLeft = (window.pageXOffset !== null) ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft;
var scrollTop = (window.pageYOffset !== null) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
var elem = document.elementFromPoint(event.pageX - scrollLeft, event.pageY - scrollTop);
//console.log('handleContextMenu', scrollLeft, scrollTop, elem, elem.parentElement, elem.parentElement.parentElement);
while (elem && elem != null && elem.attributes.cmenu == null) { elem = elem.parentElement; } // Go up until element with context menu or root is reached.
if (elem == null) return true; // No "cmenu=xxx" found at the element that was clicked.
var cmenu = elem.attributes.cmenu.value;
// Look for a file entry element
var fileElement = null, elx = elem;
while (elx && elx != null && elx.id != 'fileEntry') { elx = elx.parentElement; }
if (elx && (elx.id == 'fileEntry')) { fileElement = elx; }
if (elem && elem != null && elem.id == 'rdpClickOnceLink' && currentNode && currentNode.agent && (currentNode.agent.id > 0) && (currentNode.agent.id < 5)) {
contextelement = elem;
var contextmenudiv = document.getElementById('altPortContextMenu');
showContextMenuDiv(contextmenudiv, event.pageX, event.pageY);
} else if (elem && elem != null && elem.id == 'connectbutton2' && currentNode && currentNode.agent && (currentNode.agent.id > 0) && (currentNode.agent.id < 5)) {
contextelement = elem;
var contextmenudiv = document.getElementById('termShellContextMenu');
showContextMenuDiv(contextmenudiv, event.pageX, event.pageY);
} else if (elem && elem != null && elem.id == 'connectbutton2' && currentNode && currentNode.agent && (currentNode.agent.id > 4)) {
contextelement = elem;
var contextmenudiv = document.getElementById('termShellContextMenuLinux');
showContextMenuDiv(contextmenudiv, event.pageX, event.pageY);
} else if (fileElement && currentNode) {
contextelement = fileElement;
var contextmenudiv = document.getElementById('filesContextMenu');
showContextMenuDiv(contextmenudiv, event.pageX, event.pageY);
} else if (elem && elem != null && elem.id == 'MxMESH') {
contextelement = elem;
var contextmenudiv = document.getElementById('meshContextMenu');
showContextMenuDiv(contextmenudiv, event.pageX, event.pageY);
/*} else if (elem && elem != null && elem.classList.contains('pluginTab')) {
switch (cmenu) {
case 'termConnectButton': {
// Terminal connect button context menu
if ((currentNode == null) || (currentNode.agent == null)) return true;
contextelement = elem;
var contextmenudiv = document.getElementById('pluginTabContextMenu');
var contextmenudiv = document.getElementById('termShellContextMenu'); // Windows options (Power Shell)
if (currentNode.agent.id > 4) { contextmenudiv = document.getElementById('termShellContextMenuLinux'); } // Non-Windows options
showContextMenuDiv(contextmenudiv, event.pageX, event.pageY);
break;
}
case 'devsContentMenu': {
// Device content menu
contextelement = elem;
var contextmenudiv = document.getElementById('contextMenu');
showContextMenuDiv(contextmenudiv, event.pageX, event.pageY);
*/
} else {
while (elem && elem != null && elem.id != 'devs') { elem = elem.parentElement; }
if (!elem || elem == null) return true;
contextelement = elem;
var contextmenudiv = document.getElementById('contextMenu');
showContextMenuDiv(contextmenudiv, event.pageX, event.pageY);
// Get the node and set the menu options
var nodeid = contextelement.children[1].attributes.onclick.value;
var node = getNodeFromId(nodeid.substring(12, nodeid.length - 18));
var mesh = meshes[node.meshid];
var rights = GetNodeRights(node);
var consoleRights = ((rights & 16) != 0);
// Get the node and set the menu options
var nodeid = contextelement.children[1].attributes.onclick.value;
var node = getNodeFromId(nodeid.substring(12, nodeid.length - 18));
var mesh = meshes[node.meshid];
var rights = GetNodeRights(node);
var consoleRights = ((rights & 16) != 0);
// Check if we have terminal and file access
var terminalAccess = ((rights == 0xFFFFFFFF) || ((rights & 512) == 0));
var fileAccess = ((rights == 0xFFFFFFFF) || ((rights & 1024) == 0));
// Check if we have terminal and file access
var terminalAccess = ((rights == 0xFFFFFFFF) || ((rights & 512) == 0));
var fileAccess = ((rights == 0xFFFFFFFF) || ((rights & 1024) == 0));
QV('cxdesktop', ((mesh.mtype == 1) || (node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 1) != 0) || (node.intelamt && (node.intelamt.state == 2))) && ((rights & 8) || (rights & 256)));
QV('cxterminal', ((mesh.mtype == 1) || (node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 2) != 0) || (node.intelamt && (node.intelamt.state == 2))) && (rights & 8) && terminalAccess);
QV('cxfiles', ((mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 4) != 0))) && (rights & 8) && fileAccess);
QV('cxevents', (node.intelamt != null) && ((node.intelamt.state == 2) || (node.conn & 2)) && (rights & 8));
QV('cxconsole', (consoleRights && (mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 8) != 0))) && (rights & 8));
QV('cxdesktop', ((mesh.mtype == 1) || (node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 1) != 0) || (node.intelamt && (node.intelamt.state == 2))) && ((rights & 8) || (rights & 256)));
QV('cxterminal', ((mesh.mtype == 1) || (node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 2) != 0) || (node.intelamt && (node.intelamt.state == 2))) && (rights & 8) && terminalAccess);
QV('cxfiles', ((mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 4) != 0))) && (rights & 8) && fileAccess);
QV('cxevents', (node.intelamt != null) && ((node.intelamt.state == 2) || (node.conn & 2)) && (rights & 8));
QV('cxconsole', (consoleRights && (mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 8) != 0))) && (rights & 8));
break;
}
default: {
// Basic context menu
if ((contextmenudiv = document.getElementById(cmenu)) == null) return true;
contextelement = elem;
showContextMenuDiv(contextmenudiv, event.pageX, event.pageY);
break;
}
}
return haltEvent(event);
}
@ -4989,7 +4980,7 @@
// RDP link, show this link only of the remote machine is Windows.
if (((connectivity & 1) != 0) && (clickOnce == true) && (mesh.mtype == 2) && ((meshrights & 8) != 0)) {
if ((node.agent.id > 0) && (node.agent.id < 5)) { x += '<a href=# id=rdpClickOnceLink onclick=p10clickOnce("' + node._id + '","RDP2",3389) title=\"' + "Requires Microsoft ClickOnce support in your browser" + '.\">' + "RDP" + '</a>&nbsp;'; }
if ((node.agent.id > 0) && (node.agent.id < 5)) { x += '<a href=# cmenu=altPortContextMenu id=rdpClickOnceLink onclick=p10clickOnce("' + node._id + '","RDP2",3389) title=\"' + "Requires Microsoft ClickOnce support in your browser" + '.\">' + "RDP" + '</a>&nbsp;'; }
if (node.agent.id > 4) {
x += '<a href=# onclick=p10clickOnce("' + node._id + '","PSSH",22) title=\"' + "Requires Microsoft ClickOnce support in your browser." + '\">' + "Putty" + '</a>&nbsp;';
x += '<a href=# onclick=p10clickOnce("' + node._id + '","WSCP",22) title=\"' + "Requires Microsoft ClickOnce support in your browser." + '\">' + "WinSCP" + '</a>&nbsp;';
@ -6847,7 +6838,7 @@
} else {
var link = shortname;
if (f.s > 0) { link = '<a hrf=# rel=\"noreferrer noopener\" target=\"_blank\" style=cursor:pointer onclick=\"return p13downloadfile(\'' + encodeURIComponent(newlinkpath + '/' + name) + '\',\'' + encodeURIComponent(name) + '\',' + f.s + ')\">' + shortname + '</a>'; }
h = '<div id=fileEntry fileIndex=' + i + ' class=filelist file=3><input file=3 style=float:left name=fd class=fcb type=checkbox onchange=p13setActions() value=\'' + f.nx + '\'>&nbsp;<span class=fsize>' + fdatestr + '</span><span style=float:right>' + fsize + '</span><span><div class=fileIcon' + f.t + '></div>' + link + '</span></div>';
h = '<div id=fileEntry cmenu=filesContextMenu fileIndex=' + i + ' class=filelist file=3><input file=3 style=float:left name=fd class=fcb type=checkbox onchange=p13setActions() value=\'' + f.nx + '\'>&nbsp;<span class=fsize>' + fdatestr + '</span><span style=float:right>' + fsize + '</span><span><div class=fileIcon' + f.t + '></div>' + link + '</span></div>';
}
if (f.t < 3) { html1 += h; } else { html2 += h; }