Index: src/graph.js
==================================================================
--- src/graph.js
+++ src/graph.js
@@ -116,10 +116,11 @@
** over a graph node. Or -1 when the mouse is not
** over anything. */
ixActive: -1, /* The item shown in the tooltip is tx.rowinfo[ixActive].
** ixActive is -1 if the tooltip is not visible */
nodeHover: null, /* Graph node under mouse when ixHover==-2 */
+ idNodeActive: 0, /* Element ID of the graph node with the tooltip. */
posX: 0, posY: 0 /* The last mouse position. */
};
/* Functions used to control the tooltip popup and its timer */
function onKeyDown(event){ /* Hide the tooltip when ESC key pressed */
@@ -132,10 +133,11 @@
function hideGraphTooltip(){ /* Hide the tooltip */
document.removeEventListener('keydown',onKeyDown,/* useCapture == */true);
stopCloseTimer();
tooltipObj.style.display = "none";
tooltipInfo.ixActive = -1;
+ tooltipInfo.idNodeActive = 0;
}
document.body.onunload = hideGraphTooltip
function stopDwellTimer(){
if(tooltipInfo.idTimer!=0){
clearTimeout(tooltipInfo.idTimer);
@@ -169,36 +171,11 @@
topObj.onclick = clickOnGraph
topObj.ondblclick = dblclickOnGraph
topObj.onmousemove = function(e) {
var ix = findTxIndex(e);
topObj.style.cursor = (ix<0) ? "" : "pointer"
- /* Keep the already visible tooltip at a constant position, as long as the
- ** mouse is over the same element. */
- if(tooltipObj.style.display != "none"){
- if(ix == tooltipInfo.ixHover) return;
- }
- /* The tooltip is either not visible, or the mouse is over a different
- ** element, so clear the dwell timer, and record the new element id and
- ** mouse position. */
- stopDwellTimer();
- if(ix >= 0){
- tooltipInfo.ixHover = ix;
- tooltipInfo.posX = e.clientX;
- tooltipInfo.posY = e.clientY;
- stopCloseTimer();
- if(tooltipInfo.dwellTimeout>0){
- tooltipInfo.idTimer = setTimeout(function() {
- tooltipInfo.idTimer = 0;
- stopCloseTimer();
- showGraphTooltip();
- },tooltipInfo.dwellTimeout);
- }
- }else{
- /* The mouse is not over an element with a tooltip */
- tooltipInfo.ixHover = -1;
- resumeCloseTimer();
- }
+ mouseOverGraph(e,ix,null);
};
topObj.onmouseleave = function(e) {
/* Hide the tooltip if the mouse is outside the "timelineTableN" element,
** and outside the tooltip. */
if(e.relatedTarget && e.relatedTarget != tooltipObj){
@@ -208,18 +185,26 @@
stopCloseTimer();
}
};
function mouseOverNode(e){ /* Invoked by mousemove events over a graph node */
e.stopPropagation()
- if(tooltipInfo.ixHover==-2) return
- tooltipInfo.ixHover = -2
- tooltipInfo.posX = e.clientX
- tooltipInfo.posY = e.clientY
- tooltipInfo.nodeHover = this
- stopCloseTimer();
- if(tooltipInfo.dwellTimeout>0){
- tooltipInfo.idTimer = setTimeout(function() {
+ mouseOverGraph(e,-2,this)
+ }
+ /* Combined mousemove handler for graph nodes and rails. */
+ function mouseOverGraph(e,ix,node){
+ stopDwellTimer(); // Mouse movement: reset the dwell timer.
+ var ownTooltip = // Check if the hovered element already has the tooltip.
+ (ix>=0 && ix==tooltipInfo.ixActive) ||
+ (ix==-2 && tooltipInfo.idNodeActive==node.id);
+ if(ownTooltip) stopCloseTimer(); // ownTooltip: clear the close timer.
+ else resumeCloseTimer(); // !ownTooltip: resume the close timer.
+ tooltipInfo.ixHover = ix;
+ tooltipInfo.nodeHover = node;
+ tooltipInfo.posX = e.clientX;
+ tooltipInfo.posY = e.clientY;
+ if(ix!=-1 && !ownTooltip && tooltipInfo.dwellTimeout>0){ // Go dwell timer.
+ tooltipInfo.idTimer = setTimeout(function(){
tooltipInfo.idTimer = 0;
stopCloseTimer();
showGraphTooltip();
},tooltipInfo.dwellTimeout);
}
@@ -605,10 +590,12 @@
dest += tx.fileDiff ? "&m&cf=" : "&m&c="
dest += encodeURIComponent(tx.rowinfo[ix].h)
return dest
}
function clickOnGraph(e){
+ stopCloseTimer();
+ stopDwellTimer();
tooltipInfo.ixHover = findTxIndex(e);
tooltipInfo.posX = e.clientX;
tooltipInfo.posY = e.clientY;
showGraphTooltip();
}
@@ -624,10 +611,11 @@
html = "artifact "+h+""
}else{
html = "check-in "+h+""
}
tooltipInfo.ixActive = -2;
+ tooltipInfo.idNodeActive = tooltipInfo.nodeHover.id;
}else if( tooltipInfo.ixHover>=0 ){
ix = tooltipInfo.ixHover
var br = tx.rowinfo[ix].br
var dest = branchHyperlink(ix)
var hbr = br.replace(/&/g, "&")
@@ -635,10 +623,11 @@
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
html = "branch "+hbr+""
tooltipInfo.ixActive = ix;
+ tooltipInfo.idNodeActive = 0;
}
if( html ){
/* Setup while hidden, to ensure proper dimensions. */
var s = getComputedStyle(document.body)
if( tx.rowinfo[ix].bg.length ){
Index: src/timeline.c
==================================================================
--- src/timeline.c
+++ src/timeline.c
@@ -870,11 +870,11 @@
@ "scrollToSelect": %d(scrollToSelect),
@ "nrail": %d(pGraph->mxRail+1),
@ "baseUrl": "%R",
@ "dwellTimeout": %d(dwellTimeout),
@ "closeTimeout": %d(closeTimeout),
- @ "hashDigit": %d(hash_digits(1)),
+ @ "hashDigits": %d(hash_digits(1)),
@ "bottomRowId": "btm-%d(iTableId)",
if( pGraph->nRow==0 ){
@ "rowinfo": null
}else{
@ "rowinfo": [