Fossil SCM
Improvements to branch linkage from the tooltip. Branch linkage now works even from a file history graph. And the source check-in is always highlighted in the linked timeline.
Commit
a27ca27f1de01da545e6e350b534845fbb6bb56275a98a0e112f057ef9b29f6a
Parent
d6b83f54ddf35b1…
2 files changed
+11
-7
+13
+11
-7
| --- src/graph.js | ||
| +++ src/graph.js | ||
| @@ -455,19 +455,26 @@ | ||
| 455 | 455 | if( y<n.offsetTop-5 ) continue; |
| 456 | 456 | if( y>n.offsetTop+n.offsetHeight ) continue; |
| 457 | 457 | return n.getAttribute("data-ix") |
| 458 | 458 | } |
| 459 | 459 | return -1 |
| 460 | + } | |
| 461 | + /* Compute the hyperlink for the branch graph for tx.rowinfo[ix] */ | |
| 462 | + function branchHyperlink(ix){ | |
| 463 | + var br = tx.rowinfo[ix].br | |
| 464 | + var dest = tx.baseUrl + "/timeline?r=" + encodeURIComponent(br) | |
| 465 | + dest += tx.fileDiff ? "&m&cf=" : "&m&c=" | |
| 466 | + dest += encodeURIComponent(tx.rowinfo[ix].h) | |
| 467 | + return dest | |
| 460 | 468 | } |
| 461 | 469 | function clickOnGraph(e){ |
| 462 | 470 | var ix = findTxIndex(e); |
| 463 | 471 | if( ix<0 ){ |
| 464 | 472 | tooltipObj.style.display = "none" |
| 465 | 473 | }else{ |
| 466 | 474 | var br = tx.rowinfo[ix].br |
| 467 | - var dest = tx.baseUrl + "/timeline?r=" + encodeURIComponent(br) | |
| 468 | - dest += "&c=" + encodeURIComponent(tx.rowinfo[ix].h) | |
| 475 | + var dest = branchHyperlink(ix) | |
| 469 | 476 | var hbr = br.replace(/&/g, "&") |
| 470 | 477 | .replace(/</g, "<") |
| 471 | 478 | .replace(/>/g, ">") |
| 472 | 479 | .replace(/"/g, """) |
| 473 | 480 | .replace(/'/g, "'"); |
| @@ -480,17 +487,14 @@ | ||
| 480 | 487 | tooltipObj.style.top = y+"px" |
| 481 | 488 | tooltipObj.style.visibility = "visible" |
| 482 | 489 | } |
| 483 | 490 | } |
| 484 | 491 | function dblclickOnGraph(e){ |
| 485 | - if( tx.fileDiff ) return | |
| 486 | 492 | var ix = findTxIndex(e); |
| 487 | - var br = tx.rowinfo[ix].br | |
| 488 | - var dest = "/timeline?r=" + encodeURIComponent(br) | |
| 489 | - dest += "&c=" + encodeURIComponent(tx.rowinfo[ix].h) | |
| 493 | + var dest = branchHyperlink(ix) | |
| 490 | 494 | tooltipObj.style.display = "none" |
| 491 | - window.location.href = tx.baseUrl + dest | |
| 495 | + window.location.href = dest | |
| 492 | 496 | } |
| 493 | 497 | function changeDisplay(selector,value){ |
| 494 | 498 | var x = document.getElementsByClassName(selector); |
| 495 | 499 | var n = x.length; |
| 496 | 500 | for(var i=0; i<n; i++) {x[i].style.display = value;} |
| 497 | 501 |
| --- src/graph.js | |
| +++ src/graph.js | |
| @@ -455,19 +455,26 @@ | |
| 455 | if( y<n.offsetTop-5 ) continue; |
| 456 | if( y>n.offsetTop+n.offsetHeight ) continue; |
| 457 | return n.getAttribute("data-ix") |
| 458 | } |
| 459 | return -1 |
| 460 | } |
| 461 | function clickOnGraph(e){ |
| 462 | var ix = findTxIndex(e); |
| 463 | if( ix<0 ){ |
| 464 | tooltipObj.style.display = "none" |
| 465 | }else{ |
| 466 | var br = tx.rowinfo[ix].br |
| 467 | var dest = tx.baseUrl + "/timeline?r=" + encodeURIComponent(br) |
| 468 | dest += "&c=" + encodeURIComponent(tx.rowinfo[ix].h) |
| 469 | var hbr = br.replace(/&/g, "&") |
| 470 | .replace(/</g, "<") |
| 471 | .replace(/>/g, ">") |
| 472 | .replace(/"/g, """) |
| 473 | .replace(/'/g, "'"); |
| @@ -480,17 +487,14 @@ | |
| 480 | tooltipObj.style.top = y+"px" |
| 481 | tooltipObj.style.visibility = "visible" |
| 482 | } |
| 483 | } |
| 484 | function dblclickOnGraph(e){ |
| 485 | if( tx.fileDiff ) return |
| 486 | var ix = findTxIndex(e); |
| 487 | var br = tx.rowinfo[ix].br |
| 488 | var dest = "/timeline?r=" + encodeURIComponent(br) |
| 489 | dest += "&c=" + encodeURIComponent(tx.rowinfo[ix].h) |
| 490 | tooltipObj.style.display = "none" |
| 491 | window.location.href = tx.baseUrl + dest |
| 492 | } |
| 493 | function changeDisplay(selector,value){ |
| 494 | var x = document.getElementsByClassName(selector); |
| 495 | var n = x.length; |
| 496 | for(var i=0; i<n; i++) {x[i].style.display = value;} |
| 497 |
| --- src/graph.js | |
| +++ src/graph.js | |
| @@ -455,19 +455,26 @@ | |
| 455 | if( y<n.offsetTop-5 ) continue; |
| 456 | if( y>n.offsetTop+n.offsetHeight ) continue; |
| 457 | return n.getAttribute("data-ix") |
| 458 | } |
| 459 | return -1 |
| 460 | } |
| 461 | /* Compute the hyperlink for the branch graph for tx.rowinfo[ix] */ |
| 462 | function branchHyperlink(ix){ |
| 463 | var br = tx.rowinfo[ix].br |
| 464 | var dest = tx.baseUrl + "/timeline?r=" + encodeURIComponent(br) |
| 465 | dest += tx.fileDiff ? "&m&cf=" : "&m&c=" |
| 466 | dest += encodeURIComponent(tx.rowinfo[ix].h) |
| 467 | return dest |
| 468 | } |
| 469 | function clickOnGraph(e){ |
| 470 | var ix = findTxIndex(e); |
| 471 | if( ix<0 ){ |
| 472 | tooltipObj.style.display = "none" |
| 473 | }else{ |
| 474 | var br = tx.rowinfo[ix].br |
| 475 | var dest = branchHyperlink(ix) |
| 476 | var hbr = br.replace(/&/g, "&") |
| 477 | .replace(/</g, "<") |
| 478 | .replace(/>/g, ">") |
| 479 | .replace(/"/g, """) |
| 480 | .replace(/'/g, "'"); |
| @@ -480,17 +487,14 @@ | |
| 487 | tooltipObj.style.top = y+"px" |
| 488 | tooltipObj.style.visibility = "visible" |
| 489 | } |
| 490 | } |
| 491 | function dblclickOnGraph(e){ |
| 492 | var ix = findTxIndex(e); |
| 493 | var dest = branchHyperlink(ix) |
| 494 | tooltipObj.style.display = "none" |
| 495 | window.location.href = dest |
| 496 | } |
| 497 | function changeDisplay(selector,value){ |
| 498 | var x = document.getElementsByClassName(selector); |
| 499 | var n = x.length; |
| 500 | for(var i=0; i<n; i++) {x[i].style.display = value;} |
| 501 |
+13
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -1477,10 +1477,11 @@ | ||
| 1477 | 1477 | ** Query parameters: |
| 1478 | 1478 | ** |
| 1479 | 1479 | ** a=TIMEORTAG After this event |
| 1480 | 1480 | ** b=TIMEORTAG Before this event |
| 1481 | 1481 | ** c=TIMEORTAG "Circa" this event |
| 1482 | +** cf=FILEHASH "Circa" the first use of the file with FILEHASH | |
| 1482 | 1483 | ** m=TIMEORTAG Mark this event |
| 1483 | 1484 | ** n=COUNT Maximum number of events. "all" for no limit |
| 1484 | 1485 | ** p=CHECKIN Parents and ancestors of CHECKIN |
| 1485 | 1486 | ** d=CHECKIN Children and descendants of CHECKIN |
| 1486 | 1487 | ** dp=CHECKIN The same as d=CHECKIN&p=CHECKIN |
| @@ -1639,10 +1640,22 @@ | ||
| 1639 | 1640 | cookie_write_parameter("y","y",zType); |
| 1640 | 1641 | } |
| 1641 | 1642 | cookie_render(); |
| 1642 | 1643 | url_initialize(&url, "timeline"); |
| 1643 | 1644 | cgi_query_parameters_to_url(&url); |
| 1645 | + | |
| 1646 | + /* Convert the cf=FILEHASH query parameter into a c=CHECKINHASH value */ | |
| 1647 | + if( P("cf")!=0 ){ | |
| 1648 | + zCirca = db_text(0, | |
| 1649 | + "SELECT (SELECT uuid FROM blob WHERE rid=mlink.mid)" | |
| 1650 | + " FROM mlink, event" | |
| 1651 | + " WHERE mlink.fid=(SELECT rid FROM blob WHERE uuid LIKE '%q%%')" | |
| 1652 | + " AND event.objid=mlink.mid" | |
| 1653 | + " ORDER BY event.mtime LIMIT 1", | |
| 1654 | + P("cf") | |
| 1655 | + ); | |
| 1656 | + } | |
| 1644 | 1657 | |
| 1645 | 1658 | /* Convert r=TAG to t=TAG&rel. */ |
| 1646 | 1659 | if( zBrName && !related ){ |
| 1647 | 1660 | cgi_delete_query_parameter("r"); |
| 1648 | 1661 | cgi_set_query_parameter("t", zBrName); |
| 1649 | 1662 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1477,10 +1477,11 @@ | |
| 1477 | ** Query parameters: |
| 1478 | ** |
| 1479 | ** a=TIMEORTAG After this event |
| 1480 | ** b=TIMEORTAG Before this event |
| 1481 | ** c=TIMEORTAG "Circa" this event |
| 1482 | ** m=TIMEORTAG Mark this event |
| 1483 | ** n=COUNT Maximum number of events. "all" for no limit |
| 1484 | ** p=CHECKIN Parents and ancestors of CHECKIN |
| 1485 | ** d=CHECKIN Children and descendants of CHECKIN |
| 1486 | ** dp=CHECKIN The same as d=CHECKIN&p=CHECKIN |
| @@ -1639,10 +1640,22 @@ | |
| 1639 | cookie_write_parameter("y","y",zType); |
| 1640 | } |
| 1641 | cookie_render(); |
| 1642 | url_initialize(&url, "timeline"); |
| 1643 | cgi_query_parameters_to_url(&url); |
| 1644 | |
| 1645 | /* Convert r=TAG to t=TAG&rel. */ |
| 1646 | if( zBrName && !related ){ |
| 1647 | cgi_delete_query_parameter("r"); |
| 1648 | cgi_set_query_parameter("t", zBrName); |
| 1649 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1477,10 +1477,11 @@ | |
| 1477 | ** Query parameters: |
| 1478 | ** |
| 1479 | ** a=TIMEORTAG After this event |
| 1480 | ** b=TIMEORTAG Before this event |
| 1481 | ** c=TIMEORTAG "Circa" this event |
| 1482 | ** cf=FILEHASH "Circa" the first use of the file with FILEHASH |
| 1483 | ** m=TIMEORTAG Mark this event |
| 1484 | ** n=COUNT Maximum number of events. "all" for no limit |
| 1485 | ** p=CHECKIN Parents and ancestors of CHECKIN |
| 1486 | ** d=CHECKIN Children and descendants of CHECKIN |
| 1487 | ** dp=CHECKIN The same as d=CHECKIN&p=CHECKIN |
| @@ -1639,10 +1640,22 @@ | |
| 1640 | cookie_write_parameter("y","y",zType); |
| 1641 | } |
| 1642 | cookie_render(); |
| 1643 | url_initialize(&url, "timeline"); |
| 1644 | cgi_query_parameters_to_url(&url); |
| 1645 | |
| 1646 | /* Convert the cf=FILEHASH query parameter into a c=CHECKINHASH value */ |
| 1647 | if( P("cf")!=0 ){ |
| 1648 | zCirca = db_text(0, |
| 1649 | "SELECT (SELECT uuid FROM blob WHERE rid=mlink.mid)" |
| 1650 | " FROM mlink, event" |
| 1651 | " WHERE mlink.fid=(SELECT rid FROM blob WHERE uuid LIKE '%q%%')" |
| 1652 | " AND event.objid=mlink.mid" |
| 1653 | " ORDER BY event.mtime LIMIT 1", |
| 1654 | P("cf") |
| 1655 | ); |
| 1656 | } |
| 1657 | |
| 1658 | /* Convert r=TAG to t=TAG&rel. */ |
| 1659 | if( zBrName && !related ){ |
| 1660 | cgi_delete_query_parameter("r"); |
| 1661 | cgi_set_query_parameter("t", zBrName); |
| 1662 |