Fossil SCM

Resolve the fork.

florian 2019-05-21 08:27 UTC tooltip-experiments merge
Commit fde231b274e3b0e6abe3e17e2f587c913291ff7a7b0c2eec594dd397a121a10d
2 files changed +76 -26 +76 -26
+76 -26
--- src/graph.js
+++ src/graph.js
@@ -75,20 +75,60 @@
7575
}
7676
amendCssOnce = 0;
7777
}
7878
var tooltipObj = document.createElement("span");
7979
tooltipObj.className = "tl-tooltip";
80
-tooltipObj.style.visibility = "hidden";
80
+tooltipObj.style.display = "none";
8181
document.getElementsByClassName("content")[0].appendChild(tooltipObj);
82
+/* Clear the close timer if the mouse is over the tooltip. */
83
+tooltipObj.onmouseenter = function(e) {
84
+ stopCloseTimer();
85
+};
86
+/* Init the close timer if the mouse is no longer over the tooltip. */
87
+tooltipObj.onmouseleave = function(e) {
88
+ if (tooltipInfo.ixActive != -1)
89
+ resumeCloseTimer();
90
+};
8291
/* This object must be in the global scope, so that (non-shadowed) access is
8392
** possible from within a setTimeout() closure. */
8493
window.tooltipInfo = {
8594
dwellTimeout: 250, /* The tooltip dwell timeout. */
86
- idTimer: 0, /* The tooltip dwell timer. */
87
- ixElement: -1, /* The id of the last hovered element. */
95
+ closeTimeout: 3000, /* The tooltip close timeout. */
96
+ idTimer: 0, /* The tooltip dwell timer id. */
97
+ idTimerClose: 0, /* The tooltip close timer id. */
98
+ ixHover: -1, /* The id of the element with the mouse. */
99
+ ixActive: -1, /* The id of the element with the tooltip. */
88100
posX: 0, posY: 0 /* The last mouse position. */
89101
};
102
+/* These functions must be in the global scope, so that access is possible from
103
+** within (non-local) event handlers. */
104
+var hideGraphTooltip = function() {
105
+ stopCloseTimer();
106
+ tooltipObj.style.display = "none";
107
+ this.tooltipInfo.ixActive = -1;
108
+}.bind(window);
109
+var stopDwellTimer = function() {
110
+ if (this.tooltipInfo.idTimer != 0) {
111
+ clearTimeout(this.tooltipInfo.idTimer);
112
+ this.tooltipInfo.idTimer = 0;
113
+ }
114
+}.bind(window);
115
+var resumeCloseTimer = function() {
116
+ /* This timer must be stopped explicitly to reset the elapsed timeout. */
117
+ if (this.tooltipInfo.idTimerClose == 0) {
118
+ this.tooltipInfo.idTimerClose = setTimeout(function() {
119
+ this.tooltipInfo.idTimerClose = 0;
120
+ hideGraphTooltip();
121
+ }.bind(window),this.tooltipInfo.closeTimeout);
122
+ }
123
+}.bind(window);
124
+var stopCloseTimer = function() {
125
+ if (this.tooltipInfo.idTimerClose != 0) {
126
+ clearTimeout(this.tooltipInfo.idTimerClose);
127
+ this.tooltipInfo.idTimerClose = 0;
128
+ }
129
+}.bind(window);
90130
91131
/* Construct that graph corresponding to the timeline-data-N object */
92132
function TimelineGraph(tx){
93133
var topObj = document.getElementById("timelineTable"+tx.iTableId);
94134
amendCss(tx.circleNodes, tx.showArrowheads);
@@ -99,52 +139,63 @@
99139
var ix = findTxIndex(e);
100140
var cursor = (ix<0) ? "" : "pointer"; /* Or: cursor = "help"? */
101141
document.getElementsByTagName('body')[0].style.cursor = cursor;
102142
/* Keep the already visible tooltip at a constant position, as long as the
103143
** mouse is over the same element. */
104
- if (tooltipObj.style.display != "none" && ix == tooltipInfo.ixElement)
105
- return;
144
+ var isReentry = false; // Detect mouse move back to same element.
145
+ if (tooltipObj.style.display != "none") {
146
+ if (ix == tooltipInfo.ixHover)
147
+ return;
148
+ if (-1 == tooltipInfo.ixHover && ix == tooltipInfo.ixActive)
149
+ isReentry = true;
150
+ }
106151
/* The tooltip is either not visible, or the mouse is over a different
107152
** element, so clear the dwell timer, and record the new element id and
108153
** mouse position. */
109
- if (tooltipInfo.idTimer != 0) {
110
- clearTimeout(tooltipInfo.idTimer);
111
- tooltipInfo.idTimer = 0;
112
- }
154
+ stopDwellTimer();
113155
if (ix >= 0) {
114156
/* Close the tooltip only if the mouse is over another element, and init
115157
** the dwell timer again. */
116
- tooltipObj.style.display = "none";
117
- tooltipInfo.ixElement = ix;
158
+ if (!isReentry)
159
+ hideGraphTooltip();
160
+ tooltipInfo.ixHover = ix;
118161
tooltipInfo.posX = e.x;
119162
tooltipInfo.posY = e.y;
120
- if( tooltipInfo.dwellTimeout>0 ){
163
+ /* Clear the close timer, if not already cleared by hideGraphTooltip(). */
164
+ stopCloseTimer();
165
+ if (!isReentry && tooltipInfo.dwellTimeout>0) {
121166
tooltipInfo.idTimer = setTimeout(function() {
122167
this.tooltipInfo.idTimer = 0;
168
+ /* Clear the timer to hide the tooltip. */
169
+ stopCloseTimer();
123170
showGraphTooltip(
124
- this.tooltipInfo.ixElement,
171
+ this.tooltipInfo.ixHover,
125172
this.tooltipInfo.posX,
126173
this.tooltipInfo.posY);
174
+ this.tooltipInfo.ixActive = this.tooltipInfo.ixHover;
127175
}.bind(window),tooltipInfo.dwellTimeout);
128176
}
129177
}
130
- else
131
- tooltipInfo.ixElement = -1;
178
+ else {
179
+ tooltipInfo.ixHover = -1;
180
+ /* The mouse is not over an element with a tooltip, init the hide
181
+ ** timer. */
182
+ resumeCloseTimer();
183
+ }
132184
};
133185
topObj.onmouseleave = function(e) {
134186
/* Hide the tooltip if the mouse is outside the "timelineTableN" element,
135187
** and outside the tooltip. */
136188
if (tooltipObj.style.display != "none" &&
137189
e.relatedTarget &&
138190
e.relatedTarget != tooltipObj) {
139
- tooltipObj.style.display = "none";
191
+ tooltipInfo.ixHover = -1;
192
+ hideGraphTooltip();
140193
/* Clear the dwell timer. */
141
- if (tooltipInfo.idTimer != 0) {
142
- clearTimeout(tooltipInfo.idTimer);
143
- tooltipInfo.idTimer = 0;
144
- }
145
- tooltipInfo.ixElement = -1;
194
+ stopDwellTimer();
195
+ /* Clear the close timer. */
196
+ stopCloseTimer();
146197
}
147198
};
148199
var canvasDiv;
149200
var railPitch;
150201
var mergeOffset;
@@ -472,11 +523,11 @@
472523
drawNode(tx.rowinfo[i], btm);
473524
}
474525
}
475526
var selRow;
476527
function clickOnNode(e){
477
- tooltipObj.style.display = "none"
528
+ hideGraphTooltip()
478529
var p = tx.rowinfo[parseInt(this.id.match(/\d+$/)[0], 10)-tx.iTopRow];
479530
if( !selRow ){
480531
selRow = p;
481532
this.className += " sel";
482533
canvasDiv.className += " sel";
@@ -530,33 +581,32 @@
530581
var ix = findTxIndex(e);
531582
showGraphTooltip(ix,e.x,e.y);
532583
}
533584
function showGraphTooltip(ix,posX,posY){
534585
if( ix<0 ){
535
- tooltipObj.style.display = "none"
586
+ hideGraphTooltip()
536587
}else{
537588
var br = tx.rowinfo[ix].br
538589
var dest = branchHyperlink(ix)
539590
var hbr = br.replace(/&/g, "&amp;")
540591
.replace(/</g, "&lt;")
541592
.replace(/>/g, "&gt;")
542593
.replace(/"/g, "&quot;")
543594
.replace(/'/g, "&#039;");
544595
tooltipObj.innerHTML = "<a href=\""+dest+"\">"+hbr+"</a>"
545
- tooltipObj.style.display = "inline"
546596
tooltipObj.style.position = "absolute"
547597
var x = posX + 4 + window.pageXOffset
548598
tooltipObj.style.left = x+"px"
549599
var y = posY + window.pageYOffset - tooltipObj.clientHeight - 4
550600
tooltipObj.style.top = y+"px"
551
- tooltipObj.style.visibility = "visible"
601
+ tooltipObj.style.display = "inline"
552602
}
553603
}
554604
function dblclickOnGraph(e){
555605
var ix = findTxIndex(e);
556606
var dest = branchHyperlink(ix)
557
- tooltipObj.style.display = "none"
607
+ hideGraphTooltip()
558608
window.location.href = dest
559609
}
560610
function changeDisplay(selector,value){
561611
var x = document.getElementsByClassName(selector);
562612
var n = x.length;
563613
--- src/graph.js
+++ src/graph.js
@@ -75,20 +75,60 @@
75 }
76 amendCssOnce = 0;
77 }
78 var tooltipObj = document.createElement("span");
79 tooltipObj.className = "tl-tooltip";
80 tooltipObj.style.visibility = "hidden";
81 document.getElementsByClassName("content")[0].appendChild(tooltipObj);
 
 
 
 
 
 
 
 
 
82 /* This object must be in the global scope, so that (non-shadowed) access is
83 ** possible from within a setTimeout() closure. */
84 window.tooltipInfo = {
85 dwellTimeout: 250, /* The tooltip dwell timeout. */
86 idTimer: 0, /* The tooltip dwell timer. */
87 ixElement: -1, /* The id of the last hovered element. */
 
 
 
88 posX: 0, posY: 0 /* The last mouse position. */
89 };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
91 /* Construct that graph corresponding to the timeline-data-N object */
92 function TimelineGraph(tx){
93 var topObj = document.getElementById("timelineTable"+tx.iTableId);
94 amendCss(tx.circleNodes, tx.showArrowheads);
@@ -99,52 +139,63 @@
99 var ix = findTxIndex(e);
100 var cursor = (ix<0) ? "" : "pointer"; /* Or: cursor = "help"? */
101 document.getElementsByTagName('body')[0].style.cursor = cursor;
102 /* Keep the already visible tooltip at a constant position, as long as the
103 ** mouse is over the same element. */
104 if (tooltipObj.style.display != "none" && ix == tooltipInfo.ixElement)
105 return;
 
 
 
 
 
106 /* The tooltip is either not visible, or the mouse is over a different
107 ** element, so clear the dwell timer, and record the new element id and
108 ** mouse position. */
109 if (tooltipInfo.idTimer != 0) {
110 clearTimeout(tooltipInfo.idTimer);
111 tooltipInfo.idTimer = 0;
112 }
113 if (ix >= 0) {
114 /* Close the tooltip only if the mouse is over another element, and init
115 ** the dwell timer again. */
116 tooltipObj.style.display = "none";
117 tooltipInfo.ixElement = ix;
 
118 tooltipInfo.posX = e.x;
119 tooltipInfo.posY = e.y;
120 if( tooltipInfo.dwellTimeout>0 ){
 
 
121 tooltipInfo.idTimer = setTimeout(function() {
122 this.tooltipInfo.idTimer = 0;
 
 
123 showGraphTooltip(
124 this.tooltipInfo.ixElement,
125 this.tooltipInfo.posX,
126 this.tooltipInfo.posY);
 
127 }.bind(window),tooltipInfo.dwellTimeout);
128 }
129 }
130 else
131 tooltipInfo.ixElement = -1;
 
 
 
 
132 };
133 topObj.onmouseleave = function(e) {
134 /* Hide the tooltip if the mouse is outside the "timelineTableN" element,
135 ** and outside the tooltip. */
136 if (tooltipObj.style.display != "none" &&
137 e.relatedTarget &&
138 e.relatedTarget != tooltipObj) {
139 tooltipObj.style.display = "none";
 
140 /* Clear the dwell timer. */
141 if (tooltipInfo.idTimer != 0) {
142 clearTimeout(tooltipInfo.idTimer);
143 tooltipInfo.idTimer = 0;
144 }
145 tooltipInfo.ixElement = -1;
146 }
147 };
148 var canvasDiv;
149 var railPitch;
150 var mergeOffset;
@@ -472,11 +523,11 @@
472 drawNode(tx.rowinfo[i], btm);
473 }
474 }
475 var selRow;
476 function clickOnNode(e){
477 tooltipObj.style.display = "none"
478 var p = tx.rowinfo[parseInt(this.id.match(/\d+$/)[0], 10)-tx.iTopRow];
479 if( !selRow ){
480 selRow = p;
481 this.className += " sel";
482 canvasDiv.className += " sel";
@@ -530,33 +581,32 @@
530 var ix = findTxIndex(e);
531 showGraphTooltip(ix,e.x,e.y);
532 }
533 function showGraphTooltip(ix,posX,posY){
534 if( ix<0 ){
535 tooltipObj.style.display = "none"
536 }else{
537 var br = tx.rowinfo[ix].br
538 var dest = branchHyperlink(ix)
539 var hbr = br.replace(/&/g, "&amp;")
540 .replace(/</g, "&lt;")
541 .replace(/>/g, "&gt;")
542 .replace(/"/g, "&quot;")
543 .replace(/'/g, "&#039;");
544 tooltipObj.innerHTML = "<a href=\""+dest+"\">"+hbr+"</a>"
545 tooltipObj.style.display = "inline"
546 tooltipObj.style.position = "absolute"
547 var x = posX + 4 + window.pageXOffset
548 tooltipObj.style.left = x+"px"
549 var y = posY + window.pageYOffset - tooltipObj.clientHeight - 4
550 tooltipObj.style.top = y+"px"
551 tooltipObj.style.visibility = "visible"
552 }
553 }
554 function dblclickOnGraph(e){
555 var ix = findTxIndex(e);
556 var dest = branchHyperlink(ix)
557 tooltipObj.style.display = "none"
558 window.location.href = dest
559 }
560 function changeDisplay(selector,value){
561 var x = document.getElementsByClassName(selector);
562 var n = x.length;
563
--- src/graph.js
+++ src/graph.js
@@ -75,20 +75,60 @@
75 }
76 amendCssOnce = 0;
77 }
78 var tooltipObj = document.createElement("span");
79 tooltipObj.className = "tl-tooltip";
80 tooltipObj.style.display = "none";
81 document.getElementsByClassName("content")[0].appendChild(tooltipObj);
82 /* Clear the close timer if the mouse is over the tooltip. */
83 tooltipObj.onmouseenter = function(e) {
84 stopCloseTimer();
85 };
86 /* Init the close timer if the mouse is no longer over the tooltip. */
87 tooltipObj.onmouseleave = function(e) {
88 if (tooltipInfo.ixActive != -1)
89 resumeCloseTimer();
90 };
91 /* This object must be in the global scope, so that (non-shadowed) access is
92 ** possible from within a setTimeout() closure. */
93 window.tooltipInfo = {
94 dwellTimeout: 250, /* The tooltip dwell timeout. */
95 closeTimeout: 3000, /* The tooltip close timeout. */
96 idTimer: 0, /* The tooltip dwell timer id. */
97 idTimerClose: 0, /* The tooltip close timer id. */
98 ixHover: -1, /* The id of the element with the mouse. */
99 ixActive: -1, /* The id of the element with the tooltip. */
100 posX: 0, posY: 0 /* The last mouse position. */
101 };
102 /* These functions must be in the global scope, so that access is possible from
103 ** within (non-local) event handlers. */
104 var hideGraphTooltip = function() {
105 stopCloseTimer();
106 tooltipObj.style.display = "none";
107 this.tooltipInfo.ixActive = -1;
108 }.bind(window);
109 var stopDwellTimer = function() {
110 if (this.tooltipInfo.idTimer != 0) {
111 clearTimeout(this.tooltipInfo.idTimer);
112 this.tooltipInfo.idTimer = 0;
113 }
114 }.bind(window);
115 var resumeCloseTimer = function() {
116 /* This timer must be stopped explicitly to reset the elapsed timeout. */
117 if (this.tooltipInfo.idTimerClose == 0) {
118 this.tooltipInfo.idTimerClose = setTimeout(function() {
119 this.tooltipInfo.idTimerClose = 0;
120 hideGraphTooltip();
121 }.bind(window),this.tooltipInfo.closeTimeout);
122 }
123 }.bind(window);
124 var stopCloseTimer = function() {
125 if (this.tooltipInfo.idTimerClose != 0) {
126 clearTimeout(this.tooltipInfo.idTimerClose);
127 this.tooltipInfo.idTimerClose = 0;
128 }
129 }.bind(window);
130
131 /* Construct that graph corresponding to the timeline-data-N object */
132 function TimelineGraph(tx){
133 var topObj = document.getElementById("timelineTable"+tx.iTableId);
134 amendCss(tx.circleNodes, tx.showArrowheads);
@@ -99,52 +139,63 @@
139 var ix = findTxIndex(e);
140 var cursor = (ix<0) ? "" : "pointer"; /* Or: cursor = "help"? */
141 document.getElementsByTagName('body')[0].style.cursor = cursor;
142 /* Keep the already visible tooltip at a constant position, as long as the
143 ** mouse is over the same element. */
144 var isReentry = false; // Detect mouse move back to same element.
145 if (tooltipObj.style.display != "none") {
146 if (ix == tooltipInfo.ixHover)
147 return;
148 if (-1 == tooltipInfo.ixHover && ix == tooltipInfo.ixActive)
149 isReentry = true;
150 }
151 /* The tooltip is either not visible, or the mouse is over a different
152 ** element, so clear the dwell timer, and record the new element id and
153 ** mouse position. */
154 stopDwellTimer();
 
 
 
155 if (ix >= 0) {
156 /* Close the tooltip only if the mouse is over another element, and init
157 ** the dwell timer again. */
158 if (!isReentry)
159 hideGraphTooltip();
160 tooltipInfo.ixHover = ix;
161 tooltipInfo.posX = e.x;
162 tooltipInfo.posY = e.y;
163 /* Clear the close timer, if not already cleared by hideGraphTooltip(). */
164 stopCloseTimer();
165 if (!isReentry && tooltipInfo.dwellTimeout>0) {
166 tooltipInfo.idTimer = setTimeout(function() {
167 this.tooltipInfo.idTimer = 0;
168 /* Clear the timer to hide the tooltip. */
169 stopCloseTimer();
170 showGraphTooltip(
171 this.tooltipInfo.ixHover,
172 this.tooltipInfo.posX,
173 this.tooltipInfo.posY);
174 this.tooltipInfo.ixActive = this.tooltipInfo.ixHover;
175 }.bind(window),tooltipInfo.dwellTimeout);
176 }
177 }
178 else {
179 tooltipInfo.ixHover = -1;
180 /* The mouse is not over an element with a tooltip, init the hide
181 ** timer. */
182 resumeCloseTimer();
183 }
184 };
185 topObj.onmouseleave = function(e) {
186 /* Hide the tooltip if the mouse is outside the "timelineTableN" element,
187 ** and outside the tooltip. */
188 if (tooltipObj.style.display != "none" &&
189 e.relatedTarget &&
190 e.relatedTarget != tooltipObj) {
191 tooltipInfo.ixHover = -1;
192 hideGraphTooltip();
193 /* Clear the dwell timer. */
194 stopDwellTimer();
195 /* Clear the close timer. */
196 stopCloseTimer();
 
 
197 }
198 };
199 var canvasDiv;
200 var railPitch;
201 var mergeOffset;
@@ -472,11 +523,11 @@
523 drawNode(tx.rowinfo[i], btm);
524 }
525 }
526 var selRow;
527 function clickOnNode(e){
528 hideGraphTooltip()
529 var p = tx.rowinfo[parseInt(this.id.match(/\d+$/)[0], 10)-tx.iTopRow];
530 if( !selRow ){
531 selRow = p;
532 this.className += " sel";
533 canvasDiv.className += " sel";
@@ -530,33 +581,32 @@
581 var ix = findTxIndex(e);
582 showGraphTooltip(ix,e.x,e.y);
583 }
584 function showGraphTooltip(ix,posX,posY){
585 if( ix<0 ){
586 hideGraphTooltip()
587 }else{
588 var br = tx.rowinfo[ix].br
589 var dest = branchHyperlink(ix)
590 var hbr = br.replace(/&/g, "&amp;")
591 .replace(/</g, "&lt;")
592 .replace(/>/g, "&gt;")
593 .replace(/"/g, "&quot;")
594 .replace(/'/g, "&#039;");
595 tooltipObj.innerHTML = "<a href=\""+dest+"\">"+hbr+"</a>"
 
596 tooltipObj.style.position = "absolute"
597 var x = posX + 4 + window.pageXOffset
598 tooltipObj.style.left = x+"px"
599 var y = posY + window.pageYOffset - tooltipObj.clientHeight - 4
600 tooltipObj.style.top = y+"px"
601 tooltipObj.style.display = "inline"
602 }
603 }
604 function dblclickOnGraph(e){
605 var ix = findTxIndex(e);
606 var dest = branchHyperlink(ix)
607 hideGraphTooltip()
608 window.location.href = dest
609 }
610 function changeDisplay(selector,value){
611 var x = document.getElementsByClassName(selector);
612 var n = x.length;
613
+76 -26
--- src/graph.js
+++ src/graph.js
@@ -75,20 +75,60 @@
7575
}
7676
amendCssOnce = 0;
7777
}
7878
var tooltipObj = document.createElement("span");
7979
tooltipObj.className = "tl-tooltip";
80
-tooltipObj.style.visibility = "hidden";
80
+tooltipObj.style.display = "none";
8181
document.getElementsByClassName("content")[0].appendChild(tooltipObj);
82
+/* Clear the close timer if the mouse is over the tooltip. */
83
+tooltipObj.onmouseenter = function(e) {
84
+ stopCloseTimer();
85
+};
86
+/* Init the close timer if the mouse is no longer over the tooltip. */
87
+tooltipObj.onmouseleave = function(e) {
88
+ if (tooltipInfo.ixActive != -1)
89
+ resumeCloseTimer();
90
+};
8291
/* This object must be in the global scope, so that (non-shadowed) access is
8392
** possible from within a setTimeout() closure. */
8493
window.tooltipInfo = {
8594
dwellTimeout: 250, /* The tooltip dwell timeout. */
86
- idTimer: 0, /* The tooltip dwell timer. */
87
- ixElement: -1, /* The id of the last hovered element. */
95
+ closeTimeout: 3000, /* The tooltip close timeout. */
96
+ idTimer: 0, /* The tooltip dwell timer id. */
97
+ idTimerClose: 0, /* The tooltip close timer id. */
98
+ ixHover: -1, /* The id of the element with the mouse. */
99
+ ixActive: -1, /* The id of the element with the tooltip. */
88100
posX: 0, posY: 0 /* The last mouse position. */
89101
};
102
+/* These functions must be in the global scope, so that access is possible from
103
+** within (non-local) event handlers. */
104
+var hideGraphTooltip = function() {
105
+ stopCloseTimer();
106
+ tooltipObj.style.display = "none";
107
+ this.tooltipInfo.ixActive = -1;
108
+}.bind(window);
109
+var stopDwellTimer = function() {
110
+ if (this.tooltipInfo.idTimer != 0) {
111
+ clearTimeout(this.tooltipInfo.idTimer);
112
+ this.tooltipInfo.idTimer = 0;
113
+ }
114
+}.bind(window);
115
+var resumeCloseTimer = function() {
116
+ /* This timer must be stopped explicitly to reset the elapsed timeout. */
117
+ if (this.tooltipInfo.idTimerClose == 0) {
118
+ this.tooltipInfo.idTimerClose = setTimeout(function() {
119
+ this.tooltipInfo.idTimerClose = 0;
120
+ hideGraphTooltip();
121
+ }.bind(window),this.tooltipInfo.closeTimeout);
122
+ }
123
+}.bind(window);
124
+var stopCloseTimer = function() {
125
+ if (this.tooltipInfo.idTimerClose != 0) {
126
+ clearTimeout(this.tooltipInfo.idTimerClose);
127
+ this.tooltipInfo.idTimerClose = 0;
128
+ }
129
+}.bind(window);
90130
91131
/* Construct that graph corresponding to the timeline-data-N object */
92132
function TimelineGraph(tx){
93133
var topObj = document.getElementById("timelineTable"+tx.iTableId);
94134
amendCss(tx.circleNodes, tx.showArrowheads);
@@ -99,52 +139,63 @@
99139
var ix = findTxIndex(e);
100140
var cursor = (ix<0) ? "" : "pointer"; /* Or: cursor = "help"? */
101141
document.getElementsByTagName('body')[0].style.cursor = cursor;
102142
/* Keep the already visible tooltip at a constant position, as long as the
103143
** mouse is over the same element. */
104
- if (tooltipObj.style.display != "none" && ix == tooltipInfo.ixElement)
105
- return;
144
+ var isReentry = false; // Detect mouse move back to same element.
145
+ if (tooltipObj.style.display != "none") {
146
+ if (ix == tooltipInfo.ixHover)
147
+ return;
148
+ if (-1 == tooltipInfo.ixHover && ix == tooltipInfo.ixActive)
149
+ isReentry = true;
150
+ }
106151
/* The tooltip is either not visible, or the mouse is over a different
107152
** element, so clear the dwell timer, and record the new element id and
108153
** mouse position. */
109
- if (tooltipInfo.idTimer != 0) {
110
- clearTimeout(tooltipInfo.idTimer);
111
- tooltipInfo.idTimer = 0;
112
- }
154
+ stopDwellTimer();
113155
if (ix >= 0) {
114156
/* Close the tooltip only if the mouse is over another element, and init
115157
** the dwell timer again. */
116
- tooltipObj.style.display = "none";
117
- tooltipInfo.ixElement = ix;
158
+ if (!isReentry)
159
+ hideGraphTooltip();
160
+ tooltipInfo.ixHover = ix;
118161
tooltipInfo.posX = e.x;
119162
tooltipInfo.posY = e.y;
120
- if( tooltipInfo.dwellTimeout>0 ){
163
+ /* Clear the close timer, if not already cleared by hideGraphTooltip(). */
164
+ stopCloseTimer();
165
+ if (!isReentry && tooltipInfo.dwellTimeout>0) {
121166
tooltipInfo.idTimer = setTimeout(function() {
122167
this.tooltipInfo.idTimer = 0;
168
+ /* Clear the timer to hide the tooltip. */
169
+ stopCloseTimer();
123170
showGraphTooltip(
124
- this.tooltipInfo.ixElement,
171
+ this.tooltipInfo.ixHover,
125172
this.tooltipInfo.posX,
126173
this.tooltipInfo.posY);
174
+ this.tooltipInfo.ixActive = this.tooltipInfo.ixHover;
127175
}.bind(window),tooltipInfo.dwellTimeout);
128176
}
129177
}
130
- else
131
- tooltipInfo.ixElement = -1;
178
+ else {
179
+ tooltipInfo.ixHover = -1;
180
+ /* The mouse is not over an element with a tooltip, init the hide
181
+ ** timer. */
182
+ resumeCloseTimer();
183
+ }
132184
};
133185
topObj.onmouseleave = function(e) {
134186
/* Hide the tooltip if the mouse is outside the "timelineTableN" element,
135187
** and outside the tooltip. */
136188
if (tooltipObj.style.display != "none" &&
137189
e.relatedTarget &&
138190
e.relatedTarget != tooltipObj) {
139
- tooltipObj.style.display = "none";
191
+ tooltipInfo.ixHover = -1;
192
+ hideGraphTooltip();
140193
/* Clear the dwell timer. */
141
- if (tooltipInfo.idTimer != 0) {
142
- clearTimeout(tooltipInfo.idTimer);
143
- tooltipInfo.idTimer = 0;
144
- }
145
- tooltipInfo.ixElement = -1;
194
+ stopDwellTimer();
195
+ /* Clear the close timer. */
196
+ stopCloseTimer();
146197
}
147198
};
148199
var canvasDiv;
149200
var railPitch;
150201
var mergeOffset;
@@ -472,11 +523,11 @@
472523
drawNode(tx.rowinfo[i], btm);
473524
}
474525
}
475526
var selRow;
476527
function clickOnNode(e){
477
- tooltipObj.style.display = "none"
528
+ hideGraphTooltip()
478529
var p = tx.rowinfo[parseInt(this.id.match(/\d+$/)[0], 10)-tx.iTopRow];
479530
if( !selRow ){
480531
selRow = p;
481532
this.className += " sel";
482533
canvasDiv.className += " sel";
@@ -530,33 +581,32 @@
530581
var ix = findTxIndex(e);
531582
showGraphTooltip(ix,e.x,e.y);
532583
}
533584
function showGraphTooltip(ix,posX,posY){
534585
if( ix<0 ){
535
- tooltipObj.style.display = "none"
586
+ hideGraphTooltip()
536587
}else{
537588
var br = tx.rowinfo[ix].br
538589
var dest = branchHyperlink(ix)
539590
var hbr = br.replace(/&/g, "&amp;")
540591
.replace(/</g, "&lt;")
541592
.replace(/>/g, "&gt;")
542593
.replace(/"/g, "&quot;")
543594
.replace(/'/g, "&#039;");
544595
tooltipObj.innerHTML = "<a href=\""+dest+"\">"+hbr+"</a>"
545
- tooltipObj.style.display = "inline"
546596
tooltipObj.style.position = "absolute"
547597
var x = posX + 4 + window.pageXOffset
548598
tooltipObj.style.left = x+"px"
549599
var y = posY + window.pageYOffset - tooltipObj.clientHeight - 4
550600
tooltipObj.style.top = y+"px"
551
- tooltipObj.style.visibility = "visible"
601
+ tooltipObj.style.display = "inline"
552602
}
553603
}
554604
function dblclickOnGraph(e){
555605
var ix = findTxIndex(e);
556606
var dest = branchHyperlink(ix)
557
- tooltipObj.style.display = "none"
607
+ hideGraphTooltip()
558608
window.location.href = dest
559609
}
560610
function changeDisplay(selector,value){
561611
var x = document.getElementsByClassName(selector);
562612
var n = x.length;
563613
--- src/graph.js
+++ src/graph.js
@@ -75,20 +75,60 @@
75 }
76 amendCssOnce = 0;
77 }
78 var tooltipObj = document.createElement("span");
79 tooltipObj.className = "tl-tooltip";
80 tooltipObj.style.visibility = "hidden";
81 document.getElementsByClassName("content")[0].appendChild(tooltipObj);
 
 
 
 
 
 
 
 
 
82 /* This object must be in the global scope, so that (non-shadowed) access is
83 ** possible from within a setTimeout() closure. */
84 window.tooltipInfo = {
85 dwellTimeout: 250, /* The tooltip dwell timeout. */
86 idTimer: 0, /* The tooltip dwell timer. */
87 ixElement: -1, /* The id of the last hovered element. */
 
 
 
88 posX: 0, posY: 0 /* The last mouse position. */
89 };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
91 /* Construct that graph corresponding to the timeline-data-N object */
92 function TimelineGraph(tx){
93 var topObj = document.getElementById("timelineTable"+tx.iTableId);
94 amendCss(tx.circleNodes, tx.showArrowheads);
@@ -99,52 +139,63 @@
99 var ix = findTxIndex(e);
100 var cursor = (ix<0) ? "" : "pointer"; /* Or: cursor = "help"? */
101 document.getElementsByTagName('body')[0].style.cursor = cursor;
102 /* Keep the already visible tooltip at a constant position, as long as the
103 ** mouse is over the same element. */
104 if (tooltipObj.style.display != "none" && ix == tooltipInfo.ixElement)
105 return;
 
 
 
 
 
106 /* The tooltip is either not visible, or the mouse is over a different
107 ** element, so clear the dwell timer, and record the new element id and
108 ** mouse position. */
109 if (tooltipInfo.idTimer != 0) {
110 clearTimeout(tooltipInfo.idTimer);
111 tooltipInfo.idTimer = 0;
112 }
113 if (ix >= 0) {
114 /* Close the tooltip only if the mouse is over another element, and init
115 ** the dwell timer again. */
116 tooltipObj.style.display = "none";
117 tooltipInfo.ixElement = ix;
 
118 tooltipInfo.posX = e.x;
119 tooltipInfo.posY = e.y;
120 if( tooltipInfo.dwellTimeout>0 ){
 
 
121 tooltipInfo.idTimer = setTimeout(function() {
122 this.tooltipInfo.idTimer = 0;
 
 
123 showGraphTooltip(
124 this.tooltipInfo.ixElement,
125 this.tooltipInfo.posX,
126 this.tooltipInfo.posY);
 
127 }.bind(window),tooltipInfo.dwellTimeout);
128 }
129 }
130 else
131 tooltipInfo.ixElement = -1;
 
 
 
 
132 };
133 topObj.onmouseleave = function(e) {
134 /* Hide the tooltip if the mouse is outside the "timelineTableN" element,
135 ** and outside the tooltip. */
136 if (tooltipObj.style.display != "none" &&
137 e.relatedTarget &&
138 e.relatedTarget != tooltipObj) {
139 tooltipObj.style.display = "none";
 
140 /* Clear the dwell timer. */
141 if (tooltipInfo.idTimer != 0) {
142 clearTimeout(tooltipInfo.idTimer);
143 tooltipInfo.idTimer = 0;
144 }
145 tooltipInfo.ixElement = -1;
146 }
147 };
148 var canvasDiv;
149 var railPitch;
150 var mergeOffset;
@@ -472,11 +523,11 @@
472 drawNode(tx.rowinfo[i], btm);
473 }
474 }
475 var selRow;
476 function clickOnNode(e){
477 tooltipObj.style.display = "none"
478 var p = tx.rowinfo[parseInt(this.id.match(/\d+$/)[0], 10)-tx.iTopRow];
479 if( !selRow ){
480 selRow = p;
481 this.className += " sel";
482 canvasDiv.className += " sel";
@@ -530,33 +581,32 @@
530 var ix = findTxIndex(e);
531 showGraphTooltip(ix,e.x,e.y);
532 }
533 function showGraphTooltip(ix,posX,posY){
534 if( ix<0 ){
535 tooltipObj.style.display = "none"
536 }else{
537 var br = tx.rowinfo[ix].br
538 var dest = branchHyperlink(ix)
539 var hbr = br.replace(/&/g, "&amp;")
540 .replace(/</g, "&lt;")
541 .replace(/>/g, "&gt;")
542 .replace(/"/g, "&quot;")
543 .replace(/'/g, "&#039;");
544 tooltipObj.innerHTML = "<a href=\""+dest+"\">"+hbr+"</a>"
545 tooltipObj.style.display = "inline"
546 tooltipObj.style.position = "absolute"
547 var x = posX + 4 + window.pageXOffset
548 tooltipObj.style.left = x+"px"
549 var y = posY + window.pageYOffset - tooltipObj.clientHeight - 4
550 tooltipObj.style.top = y+"px"
551 tooltipObj.style.visibility = "visible"
552 }
553 }
554 function dblclickOnGraph(e){
555 var ix = findTxIndex(e);
556 var dest = branchHyperlink(ix)
557 tooltipObj.style.display = "none"
558 window.location.href = dest
559 }
560 function changeDisplay(selector,value){
561 var x = document.getElementsByClassName(selector);
562 var n = x.length;
563
--- src/graph.js
+++ src/graph.js
@@ -75,20 +75,60 @@
75 }
76 amendCssOnce = 0;
77 }
78 var tooltipObj = document.createElement("span");
79 tooltipObj.className = "tl-tooltip";
80 tooltipObj.style.display = "none";
81 document.getElementsByClassName("content")[0].appendChild(tooltipObj);
82 /* Clear the close timer if the mouse is over the tooltip. */
83 tooltipObj.onmouseenter = function(e) {
84 stopCloseTimer();
85 };
86 /* Init the close timer if the mouse is no longer over the tooltip. */
87 tooltipObj.onmouseleave = function(e) {
88 if (tooltipInfo.ixActive != -1)
89 resumeCloseTimer();
90 };
91 /* This object must be in the global scope, so that (non-shadowed) access is
92 ** possible from within a setTimeout() closure. */
93 window.tooltipInfo = {
94 dwellTimeout: 250, /* The tooltip dwell timeout. */
95 closeTimeout: 3000, /* The tooltip close timeout. */
96 idTimer: 0, /* The tooltip dwell timer id. */
97 idTimerClose: 0, /* The tooltip close timer id. */
98 ixHover: -1, /* The id of the element with the mouse. */
99 ixActive: -1, /* The id of the element with the tooltip. */
100 posX: 0, posY: 0 /* The last mouse position. */
101 };
102 /* These functions must be in the global scope, so that access is possible from
103 ** within (non-local) event handlers. */
104 var hideGraphTooltip = function() {
105 stopCloseTimer();
106 tooltipObj.style.display = "none";
107 this.tooltipInfo.ixActive = -1;
108 }.bind(window);
109 var stopDwellTimer = function() {
110 if (this.tooltipInfo.idTimer != 0) {
111 clearTimeout(this.tooltipInfo.idTimer);
112 this.tooltipInfo.idTimer = 0;
113 }
114 }.bind(window);
115 var resumeCloseTimer = function() {
116 /* This timer must be stopped explicitly to reset the elapsed timeout. */
117 if (this.tooltipInfo.idTimerClose == 0) {
118 this.tooltipInfo.idTimerClose = setTimeout(function() {
119 this.tooltipInfo.idTimerClose = 0;
120 hideGraphTooltip();
121 }.bind(window),this.tooltipInfo.closeTimeout);
122 }
123 }.bind(window);
124 var stopCloseTimer = function() {
125 if (this.tooltipInfo.idTimerClose != 0) {
126 clearTimeout(this.tooltipInfo.idTimerClose);
127 this.tooltipInfo.idTimerClose = 0;
128 }
129 }.bind(window);
130
131 /* Construct that graph corresponding to the timeline-data-N object */
132 function TimelineGraph(tx){
133 var topObj = document.getElementById("timelineTable"+tx.iTableId);
134 amendCss(tx.circleNodes, tx.showArrowheads);
@@ -99,52 +139,63 @@
139 var ix = findTxIndex(e);
140 var cursor = (ix<0) ? "" : "pointer"; /* Or: cursor = "help"? */
141 document.getElementsByTagName('body')[0].style.cursor = cursor;
142 /* Keep the already visible tooltip at a constant position, as long as the
143 ** mouse is over the same element. */
144 var isReentry = false; // Detect mouse move back to same element.
145 if (tooltipObj.style.display != "none") {
146 if (ix == tooltipInfo.ixHover)
147 return;
148 if (-1 == tooltipInfo.ixHover && ix == tooltipInfo.ixActive)
149 isReentry = true;
150 }
151 /* The tooltip is either not visible, or the mouse is over a different
152 ** element, so clear the dwell timer, and record the new element id and
153 ** mouse position. */
154 stopDwellTimer();
 
 
 
155 if (ix >= 0) {
156 /* Close the tooltip only if the mouse is over another element, and init
157 ** the dwell timer again. */
158 if (!isReentry)
159 hideGraphTooltip();
160 tooltipInfo.ixHover = ix;
161 tooltipInfo.posX = e.x;
162 tooltipInfo.posY = e.y;
163 /* Clear the close timer, if not already cleared by hideGraphTooltip(). */
164 stopCloseTimer();
165 if (!isReentry && tooltipInfo.dwellTimeout>0) {
166 tooltipInfo.idTimer = setTimeout(function() {
167 this.tooltipInfo.idTimer = 0;
168 /* Clear the timer to hide the tooltip. */
169 stopCloseTimer();
170 showGraphTooltip(
171 this.tooltipInfo.ixHover,
172 this.tooltipInfo.posX,
173 this.tooltipInfo.posY);
174 this.tooltipInfo.ixActive = this.tooltipInfo.ixHover;
175 }.bind(window),tooltipInfo.dwellTimeout);
176 }
177 }
178 else {
179 tooltipInfo.ixHover = -1;
180 /* The mouse is not over an element with a tooltip, init the hide
181 ** timer. */
182 resumeCloseTimer();
183 }
184 };
185 topObj.onmouseleave = function(e) {
186 /* Hide the tooltip if the mouse is outside the "timelineTableN" element,
187 ** and outside the tooltip. */
188 if (tooltipObj.style.display != "none" &&
189 e.relatedTarget &&
190 e.relatedTarget != tooltipObj) {
191 tooltipInfo.ixHover = -1;
192 hideGraphTooltip();
193 /* Clear the dwell timer. */
194 stopDwellTimer();
195 /* Clear the close timer. */
196 stopCloseTimer();
 
 
197 }
198 };
199 var canvasDiv;
200 var railPitch;
201 var mergeOffset;
@@ -472,11 +523,11 @@
523 drawNode(tx.rowinfo[i], btm);
524 }
525 }
526 var selRow;
527 function clickOnNode(e){
528 hideGraphTooltip()
529 var p = tx.rowinfo[parseInt(this.id.match(/\d+$/)[0], 10)-tx.iTopRow];
530 if( !selRow ){
531 selRow = p;
532 this.className += " sel";
533 canvasDiv.className += " sel";
@@ -530,33 +581,32 @@
581 var ix = findTxIndex(e);
582 showGraphTooltip(ix,e.x,e.y);
583 }
584 function showGraphTooltip(ix,posX,posY){
585 if( ix<0 ){
586 hideGraphTooltip()
587 }else{
588 var br = tx.rowinfo[ix].br
589 var dest = branchHyperlink(ix)
590 var hbr = br.replace(/&/g, "&amp;")
591 .replace(/</g, "&lt;")
592 .replace(/>/g, "&gt;")
593 .replace(/"/g, "&quot;")
594 .replace(/'/g, "&#039;");
595 tooltipObj.innerHTML = "<a href=\""+dest+"\">"+hbr+"</a>"
 
596 tooltipObj.style.position = "absolute"
597 var x = posX + 4 + window.pageXOffset
598 tooltipObj.style.left = x+"px"
599 var y = posY + window.pageYOffset - tooltipObj.clientHeight - 4
600 tooltipObj.style.top = y+"px"
601 tooltipObj.style.display = "inline"
602 }
603 }
604 function dblclickOnGraph(e){
605 var ix = findTxIndex(e);
606 var dest = branchHyperlink(ix)
607 hideGraphTooltip()
608 window.location.href = dest
609 }
610 function changeDisplay(selector,value){
611 var x = document.getElementsByClassName(selector);
612 var n = x.length;
613

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button