Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Single-click to get the tooltip. Double-click to hyperlink to the branch graph. Click is approximate and does not require a direct hit on the graph line. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | tooltips |
| Files: | files | file ages | folders |
| SHA3-256: |
9dc74546513b070a641d4c0ab26a745d |
| User & Date: | drh 2019-05-18 02:07:20.818 |
Context
|
2019-05-18
| ||
| 14:00 | The tooltip pop-up contains a hyperlink to the branch ... (check-in: 19ba7390e2 user: drh tags: tooltips) | |
| 02:07 | Single-click to get the tooltip. Double-click to hyperlink to the branch graph. Click is approximate and does not require a direct hit on the graph line. ... (check-in: 9dc7454651 user: drh tags: tooltips) | |
| 00:13 | Merge all enhancements from trunk. ... (check-in: 1989a13acb user: drh tags: tooltips) | |
Changes
Changes to src/graph.js.
| ︙ | ︙ | |||
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
amendCssOnce = 0;
}
var tooltipObj = document.createElement("span");
tooltipObj.className = "tl-tooltip";
tooltipObj.style.visibility = "hidden";
document.getElementsByClassName("content")[0].appendChild(tooltipObj);
function TimelineGraph(tx){
var topObj = document.getElementById("timelineTable"+tx.iTableId);
amendCss(tx.circleNodes, tx.showArrowheads);
var canvasDiv;
var railPitch;
var mergeOffset;
var node, arrow, arrowSmall, line, mArrow, mLine, wArrow, wLine;
function initGraph(){
var parent = topObj.rows[0].cells[1];
parent.style.verticalAlign = "top";
canvasDiv = document.createElement("div");
canvasDiv.className = "tl-canvas";
canvasDiv.style.position = "absolute";
parent.appendChild(canvasDiv);
| > > > > | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
amendCssOnce = 0;
}
var tooltipObj = document.createElement("span");
tooltipObj.className = "tl-tooltip";
tooltipObj.style.visibility = "hidden";
document.getElementsByClassName("content")[0].appendChild(tooltipObj);
/* Construct that graph corresponding to the timeline-data-N object */
function TimelineGraph(tx){
var topObj = document.getElementById("timelineTable"+tx.iTableId);
amendCss(tx.circleNodes, tx.showArrowheads);
topObj.onclick = clickOnGraph
topObj.ondblclick = dblclickOnGraph
var canvasDiv;
var railPitch;
var mergeOffset;
var node, arrow, arrowSmall, line, mArrow, mLine, wArrow, wLine;
function initGraph(){
var parent = topObj.rows[0].cells[1];
parent.style.verticalAlign = "top";
canvasDiv = document.createElement("div");
canvasDiv.className = "tl-canvas";
canvasDiv.style.position = "absolute";
parent.appendChild(canvasDiv);
|
| ︙ | ︙ | |||
165 166 167 168 169 170 171 |
if( h ) n.style.height = h+"px";
if( color ) n.style.backgroundColor = color;
n.className = "tl-"+cls;
canvasDiv.appendChild(n);
return n;
}
function absoluteY(obj){
| | < | | | > | > > > > > | | 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
if( h ) n.style.height = h+"px";
if( color ) n.style.backgroundColor = color;
n.className = "tl-"+cls;
canvasDiv.appendChild(n);
return n;
}
function absoluteY(obj){
var y = 0;
do{
y += obj.offsetTop;
}while( obj = obj.offsetParent );
return y;
}
function absoluteX(obj){
var x = 0;
do{
x += obj.offsetLeft;
}while( obj = obj.offsetParent );
return x;
}
function miLineY(p){
return p.y + node.h - mLine.w - 1;
}
function drawLine(elem,color,x0,y0,x1,y1){
var cls = elem.cls + " ";
if( x1===null ){
|
| ︙ | ︙ | |||
210 211 212 213 214 215 216 |
var y0 = from.y + node.h/2;
var y1 = Math.ceil(to.y + node.h);
var n = drawLine(dotLine,null,x,y0,null,y1)
if( color ) n.style.borderColor = color
addToolTip(n,id)
}
function addToolTip(n,id){
| < < < < | < | 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
var y0 = from.y + node.h/2;
var y1 = Math.ceil(to.y + node.h);
var n = drawLine(dotLine,null,x,y0,null,y1)
if( color ) n.style.borderColor = color
addToolTip(n,id)
}
function addToolTip(n,id){
if( id ) n.setAttribute("data-ix",id-tx.iTopRow)
}
/* Draw thin horizontal or vertical lines representing merges */
function drawMergeLine(x0,y0,x1,y1){
drawLine(mLine,null,x0,y0,x1,y1);
}
function drawCherrypickLine(x0,y0,x1,y1){
drawLine(cpLine,null,x0,y0,x1,y1);
|
| ︙ | ︙ | |||
265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
var cls = node.cls;
if( p.hasOwnProperty('mi') && p.mi.length ) cls += " merge";
if( p.f&1 ) cls += " leaf";
var n = drawBox(cls,p.bg,p.x,p.y);
n.id = "tln"+p.id;
addToolTip(n,p.id)
n.onclick = clickOnNode;
n.style.zIndex = 10;
if( !tx.omitDescenders ){
if( p.u==0 ){
if( p.hasOwnProperty('mo') && p.r==p.mo ){
var ix = p.hasOwnProperty('cu') ? p.cu : p.mu;
var top = tx.rowinfo[ix-tx.iTopRow]
drawUpArrow(p,{x: p.x, y: top.y-node.h}, p.fg, p.id);
| > | 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 |
var cls = node.cls;
if( p.hasOwnProperty('mi') && p.mi.length ) cls += " merge";
if( p.f&1 ) cls += " leaf";
var n = drawBox(cls,p.bg,p.x,p.y);
n.id = "tln"+p.id;
addToolTip(n,p.id)
n.onclick = clickOnNode;
n.ondblclick = dblclickOnNode;
n.style.zIndex = 10;
if( !tx.omitDescenders ){
if( p.u==0 ){
if( p.hasOwnProperty('mo') && p.r==p.mo ){
var ix = p.hasOwnProperty('cu') ? p.cu : p.mu;
var top = tx.rowinfo[ix-tx.iTopRow]
drawUpArrow(p,{x: p.x, y: top.y-node.h}, p.fg, p.id);
|
| ︙ | ︙ | |||
404 405 406 407 408 409 410 |
var btm = absoluteY(tlBtm) - canvasY + tlBtm.offsetHeight;
for( var i=0; i<tx.nrail; i++) mergeBtm[i] = btm;
for( var i=tx.rowinfo.length-1; i>=0; i-- ){
drawNode(tx.rowinfo[i], btm);
}
}
var selRow;
| | > > > > > > | > > > > > > > > > > > > > > > | > > > > > > > > | | | | | | | | | > | > | > < < < | 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 |
var btm = absoluteY(tlBtm) - canvasY + tlBtm.offsetHeight;
for( var i=0; i<tx.nrail; i++) mergeBtm[i] = btm;
for( var i=tx.rowinfo.length-1; i>=0; i-- ){
drawNode(tx.rowinfo[i], btm);
}
}
var selRow;
function clickOnNode(e){
var p = tx.rowinfo[parseInt(this.id.match(/\d+$/)[0], 10)-tx.iTopRow];
if( !selRow ){
selRow = p;
this.className += " sel";
canvasDiv.className += " sel";
}else if( selRow==p ){
selRow = null;
this.className = this.className.replace(" sel", "");
canvasDiv.className = canvasDiv.className.replace(" sel", "");
}else{
if( tx.fileDiff ){
location.href=tx.baseUrl + "/fdiff?v1="+selRow.h+"&v2="+p.h
}else{
location.href=tx.baseUrl + "/vdiff?from="+selRow.h+"&to="+p.h
}
}
e.stopPropagation()
}
function dblclickOnNode(e){
var p = tx.rowinfo[parseInt(this.id.match(/\d+$/)[0], 10)-tx.iTopRow];
window.location.href = tx.baseUrl+"/info/"+p.h
e.stopPropagation()
}
function findTxIndex(e){
/* Look at all the graph elements. If any graph elements that is near
** the click-point "e" and has a "data-ix" attribute, then return
** the value of that attribute. Otherwise return -1 */
var x = e.x + window.pageXOffset - absoluteX(canvasDiv);
var y = e.y + window.pageYOffset - absoluteY(canvasDiv);
var aNode = canvasDiv.childNodes
var nNode = aNode.length;
var i;
for(i=0;i<nNode;i++){
var n = aNode[i]
if( !n.hasAttribute("data-ix") ) continue;
if( x<n.offsetLeft-5 ) continue;
if( x>n.offsetLeft+n.offsetWidth+5 ) continue;
if( y<n.offsetTop-5 ) continue;
if( y>n.offsetTop+n.offsetHeight ) continue;
return n.getAttribute("data-ix")
}
return -1
}
function clickOnGraph(e){
var ix = findTxIndex(e);
if( ix<0 ){
tooltipObj.style.display = "none"
}else{
tooltipObj.textContent = tx.rowinfo[ix].br
tooltipObj.style.display = "inline"
tooltipObj.style.position = "absolute"
var x = e.x + 4 + window.pageXOffset
tooltipObj.style.left = x+"px"
var y = e.y + window.pageYOffset - tooltipObj.clientHeight - 4
tooltipObj.style.top = y+"px"
tooltipObj.style.visibility = "visible"
}
}
function dblclickOnGraph(e){
if( tx.fileDiff ) return
var ix = findTxIndex(e);
var br = tx.rowinfo[ix].br
var dest = "/timeline?r=" + encodeURIComponent(br)
dest += "&c=" + encodeURIComponent(tx.rowinfo[ix].h)
tooltipObj.style.display = "none"
window.location.href = tx.baseUrl + dest
}
function changeDisplay(selector,value){
var x = document.getElementsByClassName(selector);
var n = x.length;
for(var i=0; i<n; i++) {x[i].style.display = value;}
}
function changeDisplayById(id,value){
var x = document.getElementById(id);
|
| ︙ | ︙ |
Changes to src/style.c.
| ︙ | ︙ | |||
576 577 578 579 580 581 582 583 584 585 586 587 588 589 |
if( needHrefJs ){
int nDelay = db_get_int("auto-hyperlink-delay",0);
int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0);
@ <script id='href-data' type='application/json'>\
@ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
}
@ <script nonce="%h(style_nonce())">
if( needHrefJs ){
cgi_append_content(builtin_text("href.js"),-1);
}
if( needSortJs ){
cgi_append_content(builtin_text("sorttable.js"),-1);
}
if( needGraphJs ){
| > > > > | 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 |
if( needHrefJs ){
int nDelay = db_get_int("auto-hyperlink-delay",0);
int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0);
@ <script id='href-data' type='application/json'>\
@ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
}
@ <script nonce="%h(style_nonce())">
@ function debugMsg(msg){
@ var n = document.getElementById("debugMsg");
@ if(n){n.textContent=msg;}
@ }
if( needHrefJs ){
cgi_append_content(builtin_text("href.js"),-1);
}
if( needSortJs ){
cgi_append_content(builtin_text("sorttable.js"),-1);
}
if( needGraphJs ){
|
| ︙ | ︙ | |||
741 742 743 744 745 746 747 |
@ </div>
}else{
if( zAd ){
@ <div class="adunit_banner">
cgi_append_content(zAd, -1);
@ </div>
}
| | | 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 |
@ </div>
}else{
if( zAd ){
@ <div class="adunit_banner">
cgi_append_content(zAd, -1);
@ </div>
}
@ <div class="content"><span id="debugMsg"></span>
}
cgi_destination(CGI_BODY);
if( sideboxUsed ){
/* Put the footer at the bottom of the page.
** the additional clear/both is needed to extend the content
** part to the end of an optional sidebox.
|
| ︙ | ︙ |