| | @@ -255,11 +255,10 @@ |
| 255 | 255 | int vid = 0; /* Current checkout version */ |
| 256 | 256 | int dateFormat = 0; /* 0: HH:MM (default) */ |
| 257 | 257 | int bCommentGitStyle = 0; /* Only show comments through first blank line */ |
| 258 | 258 | const char *zStyle; /* Sub-name for classes for the style */ |
| 259 | 259 | const char *zDateFmt; |
| 260 | | - int iTableId = timeline_tableid(); |
| 261 | 260 | |
| 262 | 261 | if( fossil_strcmp(g.zIpAddr, "127.0.0.1")==0 && db_open_local(0) ){ |
| 263 | 262 | vid = db_lget_int("checkout", 0); |
| 264 | 263 | } |
| 265 | 264 | zPrevDate[0] = 0; |
| | @@ -286,11 +285,11 @@ |
| 286 | 285 | db_static_prepare(&qbranch, |
| 287 | 286 | "SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0 AND rid=:rid", |
| 288 | 287 | TAG_BRANCH |
| 289 | 288 | ); |
| 290 | 289 | |
| 291 | | - @ <table id="timelineTable%d(iTableId)" class="timelineTable"> |
| 290 | + @ <table id="timelineTable" class="timelineTable"> |
| 292 | 291 | blob_zero(&comment); |
| 293 | 292 | while( db_step(pQuery)==SQLITE_ROW ){ |
| 294 | 293 | int rid = db_column_int(pQuery, 0); |
| 295 | 294 | const char *zUuid = db_column_text(pQuery, 1); |
| 296 | 295 | int isLeaf = db_column_int(pQuery, 5); |
| | @@ -723,11 +722,11 @@ |
| 723 | 722 | @ <tr class="timelineBottom"><td></td><td></td><td></td></tr> |
| 724 | 723 | } |
| 725 | 724 | } |
| 726 | 725 | @ </table> |
| 727 | 726 | if( fchngQueryInit ) db_finalize(&fchngQuery); |
| 728 | | - timeline_output_graph_javascript(pGraph, (tmFlags & TIMELINE_DISJOINT)!=0, iTableId, 0); |
| 727 | + timeline_output_graph_javascript(pGraph, (tmFlags & TIMELINE_DISJOINT)!=0, 0); |
| 729 | 728 | } |
| 730 | 729 | |
| 731 | 730 | /* |
| 732 | 731 | ** Change the RGB background color given in the argument in a foreground |
| 733 | 732 | ** color with the same hue. |
| | @@ -764,11 +763,10 @@ |
| 764 | 763 | ** graph. |
| 765 | 764 | */ |
| 766 | 765 | void timeline_output_graph_javascript( |
| 767 | 766 | GraphContext *pGraph, /* The graph to be displayed */ |
| 768 | 767 | int omitDescenders, /* True to omit descenders */ |
| 769 | | - int iTableId, /* Identifier for the timelineTable */ |
| 770 | 768 | int fileDiff /* True for file diff. False for check-in diff */ |
| 771 | 769 | ){ |
| 772 | 770 | if( pGraph && pGraph->nErr==0 && pGraph->nRow>0 ){ |
| 773 | 771 | GraphRow *pRow; |
| 774 | 772 | int i; |
| | @@ -781,25 +779,25 @@ |
| 781 | 779 | |
| 782 | 780 | iRailPitch = atoi(PD("railpitch","0")); |
| 783 | 781 | showArrowheads = skin_detail_boolean("timeline-arrowheads"); |
| 784 | 782 | circleNodes = skin_detail_boolean("timeline-circle-nodes"); |
| 785 | 783 | colorGraph = skin_detail_boolean("timeline-color-graph-lines"); |
| 786 | | - |
| 787 | | - @ <script> |
| 788 | | - @ "use strict"; |
| 789 | | - @ var css = ""; |
| 790 | | - if( circleNodes ){ |
| 791 | | - @ css += ".tl-node, .tl-node:after { border-radius: 50%%; }"; |
| 792 | | - } |
| 793 | | - if( !showArrowheads ){ |
| 794 | | - @ css += ".tl-arrow.u { display: none; }"; |
| 795 | | - } |
| 796 | | - @ if( css!=="" ){ |
| 797 | | - @ var style = document.createElement("style"); |
| 798 | | - @ style.textContent = css; |
| 799 | | - @ document.querySelector("head").appendChild(style); |
| 800 | | - @ } |
| 784 | + iTopRow = pGraph->pFirst ? pGraph->pFirst->idx : 0; |
| 785 | + |
| 786 | + @ <script id='timeline-data' type='application/json'>{ |
| 787 | + @ "circleNodes": %d(circleNodes), |
| 788 | + @ "showArrowheads": %d(showArrowheads), |
| 789 | + @ "iRailPitch": %d(iRailPitch), |
| 790 | + @ "colorGraph": %d(colorGraph), |
| 791 | + @ "nomo": %d(PB("nomo")), |
| 792 | + @ "iTopRow": %d(iTopRow), |
| 793 | + @ "omitDescenders": %d(omitDescenders), |
| 794 | + @ "fileDiff": %d(fileDiff), |
| 795 | + @ "nrail": %d(pGraph->mxRail+1), |
| 796 | + @ "baseUrl": "%R", |
| 797 | + @ "rowinfo": [ |
| 798 | + |
| 801 | 799 | /* the rowinfo[] array contains all the information needed to generate |
| 802 | 800 | ** the graph. Each entry contains information for a single row: |
| 803 | 801 | ** |
| 804 | 802 | ** id: The id of the <div> element for the row. This is an integer. |
| 805 | 803 | ** to get an actual id, prepend "m" to the integer. The top node |
| | @@ -827,24 +825,20 @@ |
| 827 | 825 | ** negative, then the rail position is the absolute value of mi[] |
| 828 | 826 | ** and a thin merge-arrow descender is drawn to the bottom of |
| 829 | 827 | ** the screen. |
| 830 | 828 | ** h: The artifact hash of the object being graphed |
| 831 | 829 | */ |
| 832 | | - iTopRow = pGraph->pFirst ? pGraph->pFirst->idx : 0; |
| 833 | | - cgi_printf("var rowinfo = [\n"); |
| 834 | 830 | for(pRow=pGraph->pFirst; pRow; pRow=pRow->pNext){ |
| 835 | | - cgi_printf("{id:%d,bg:\"%s\",r:%d,d:%d,mo:%d,mu:%d,u:%d,f:%d,au:", |
| 836 | | - pRow->idx, /* id */ |
| 837 | | - pRow->zBgClr, /* bg */ |
| 838 | | - pRow->iRail, /* r */ |
| 839 | | - pRow->bDescender, /* d */ |
| 840 | | - pRow->mergeOut, /* mo */ |
| 841 | | - pRow->mergeUpto, /* mu */ |
| 842 | | - pRow->aiRiser[pRow->iRail], /* u */ |
| 843 | | - pRow->isLeaf ? 1 : 0 /* f */ |
| 844 | | - ); |
| 845 | | - /* au */ |
| 831 | + cgi_printf("{\"id\":%d,", pRow->idx); |
| 832 | + cgi_printf("\"bg\":\"%s\",", pRow->zBgClr); |
| 833 | + cgi_printf("\"r\":%d,", pRow->iRail); |
| 834 | + cgi_printf("\"d\":%d,", pRow->bDescender); |
| 835 | + cgi_printf("\"mo\":%d,", pRow->mergeOut); |
| 836 | + cgi_printf("\"mu\":%d,", pRow->mergeUpto); |
| 837 | + cgi_printf("\"u\":%d,", pRow->aiRiser[pRow->iRail]); |
| 838 | + cgi_printf("\"f\":%d,", pRow->isLeaf ? 1 : 0); |
| 839 | + cgi_printf("\"au\":"); |
| 846 | 840 | cSep = '['; |
| 847 | 841 | for(i=0; i<GR_MAX_RAIL; i++){ |
| 848 | 842 | if( i==pRow->iRail ) continue; |
| 849 | 843 | if( pRow->aiRiser[i]>0 ){ |
| 850 | 844 | cgi_printf("%c%d,%d", cSep, i, pRow->aiRiser[i]); |
| | @@ -852,14 +846,14 @@ |
| 852 | 846 | } |
| 853 | 847 | } |
| 854 | 848 | if( cSep=='[' ) cgi_printf("["); |
| 855 | 849 | cgi_printf("],"); |
| 856 | 850 | if( colorGraph && pRow->zBgClr[0]=='#' ){ |
| 857 | | - cgi_printf("fg:\"%s\",", bg_to_fg(pRow->zBgClr)); |
| 851 | + cgi_printf("\"fg\":\"%s\",", bg_to_fg(pRow->zBgClr)); |
| 858 | 852 | } |
| 859 | 853 | /* mi */ |
| 860 | | - cgi_printf("mi:"); |
| 854 | + cgi_printf("\"mi\":"); |
| 861 | 855 | cSep = '['; |
| 862 | 856 | for(i=0; i<GR_MAX_RAIL; i++){ |
| 863 | 857 | if( pRow->mergeIn[i] ){ |
| 864 | 858 | int mi = i; |
| 865 | 859 | if( (pRow->mergeDown >> i) & 1 ) mi = -mi; |
| | @@ -866,308 +860,16 @@ |
| 866 | 860 | cgi_printf("%c%d", cSep, mi); |
| 867 | 861 | cSep = ','; |
| 868 | 862 | } |
| 869 | 863 | } |
| 870 | 864 | if( cSep=='[' ) cgi_printf("["); |
| 871 | | - cgi_printf("],h:\"%!S\"}%s", pRow->zUuid, pRow->pNext ? ",\n" : "];\n"); |
| 872 | | - } |
| 873 | | - cgi_printf("var nrail = %d\n", pGraph->mxRail+1); |
| 874 | | - graph_free(pGraph); |
| 875 | | - @ var canvasDiv; |
| 876 | | - @ var railPitch; |
| 877 | | - @ var mergeOffset; |
| 878 | | - @ var node, arrow, arrowSmall, line, mArrow, mLine, wArrow, wLine; |
| 879 | | - @ function initGraph(){ |
| 880 | | - @ var parent = gebi("timelineTable%d(iTableId)").rows[0].cells[1]; |
| 881 | | - @ parent.style.verticalAlign = "top"; |
| 882 | | - @ canvasDiv = document.createElement("div"); |
| 883 | | - @ canvasDiv.className = "tl-canvas"; |
| 884 | | - @ canvasDiv.style.position = "absolute"; |
| 885 | | - @ parent.appendChild(canvasDiv); |
| 886 | | - @ |
| 887 | | - @ var elems = {}; |
| 888 | | - @ var elemClasses = [ |
| 889 | | - @ "rail", "mergeoffset", "node", "arrow u", "arrow u sm", "line", |
| 890 | | - @ "arrow merge r", "line merge", "arrow warp", "line warp" |
| 891 | | - @ ]; |
| 892 | | - @ for( var i=0; i<elemClasses.length; i++ ){ |
| 893 | | - @ var cls = elemClasses[i]; |
| 894 | | - @ var elem = document.createElement("div"); |
| 895 | | - @ elem.className = "tl-" + cls; |
| 896 | | - @ if( cls.indexOf("line")==0 ) elem.className += " v"; |
| 897 | | - @ canvasDiv.appendChild(elem); |
| 898 | | - @ var k = cls.replace(/\s/g, "_"); |
| 899 | | - @ var r = elem.getBoundingClientRect(); |
| 900 | | - @ var w = Math.round(r.right - r.left); |
| 901 | | - @ var h = Math.round(r.bottom - r.top); |
| 902 | | - @ elems[k] = {w: w, h: h, cls: cls}; |
| 903 | | - @ } |
| 904 | | - @ node = elems.node; |
| 905 | | - @ arrow = elems.arrow_u; |
| 906 | | - @ arrowSmall = elems.arrow_u_sm; |
| 907 | | - @ line = elems.line; |
| 908 | | - @ mArrow = elems.arrow_merge_r; |
| 909 | | - @ mLine = elems.line_merge; |
| 910 | | - @ wArrow = elems.arrow_warp; |
| 911 | | - @ wLine = elems.line_warp; |
| 912 | | - @ |
| 913 | | - @ var minRailPitch = Math.ceil((node.w+line.w)/2 + mArrow.w + 1); |
| 914 | | - if( iRailPitch ){ |
| 915 | | - @ railPitch = %d(iRailPitch); |
| 916 | | - }else{ |
| 917 | | - @ railPitch = elems.rail.w; |
| 918 | | - @ railPitch -= Math.floor((nrail-1)*(railPitch-minRailPitch)/21); |
| 919 | | - } |
| 920 | | - @ railPitch = Math.max(railPitch, minRailPitch); |
| 921 | | - @ |
| 922 | | - if( PB("nomo") ){ |
| 923 | | - @ mergeOffset = 0; |
| 924 | | - }else{ |
| 925 | | - @ mergeOffset = railPitch-minRailPitch-mLine.w; |
| 926 | | - @ mergeOffset = Math.min(mergeOffset, elems.mergeoffset.w); |
| 927 | | - @ mergeOffset = mergeOffset>0 ? mergeOffset + line.w/2 : 0; |
| 928 | | - } |
| 929 | | - @ |
| 930 | | - @ var canvasWidth = (nrail-1)*railPitch + node.w; |
| 931 | | - @ canvasDiv.style.width = canvasWidth + "px"; |
| 932 | | - @ canvasDiv.style.position = "relative"; |
| 933 | | - @ } |
| 934 | | - @ function drawBox(cls,color,x0,y0,x1,y1){ |
| 935 | | - @ var n = document.createElement("div"); |
| 936 | | - @ x0 = Math.floor(x0); |
| 937 | | - @ y0 = Math.floor(y0); |
| 938 | | - @ x1 = x1 || x1===0 ? Math.floor(x1) : x0; |
| 939 | | - @ y1 = y1 || y1===0 ? Math.floor(y1) : y0; |
| 940 | | - @ if( x0>x1 ){ var t=x0; x0=x1; x1=t; } |
| 941 | | - @ if( y0>y1 ){ var t=y0; y0=y1; y1=t; } |
| 942 | | - @ var w = x1-x0; |
| 943 | | - @ var h = y1-y0; |
| 944 | | - @ n.style.position = "absolute"; |
| 945 | | - @ n.style.left = x0+"px"; |
| 946 | | - @ n.style.top = y0+"px"; |
| 947 | | - @ if( w ) n.style.width = w+"px"; |
| 948 | | - @ if( h ) n.style.height = h+"px"; |
| 949 | | - @ if( color ) n.style.backgroundColor = color; |
| 950 | | - @ n.className = "tl-"+cls; |
| 951 | | - @ canvasDiv.appendChild(n); |
| 952 | | - @ return n; |
| 953 | | - @ } |
| 954 | | - @ function absoluteY(obj){ |
| 955 | | - @ var top = 0; |
| 956 | | - @ if( obj.offsetParent ){ |
| 957 | | - @ do{ |
| 958 | | - @ top += obj.offsetTop; |
| 959 | | - @ }while( obj = obj.offsetParent ); |
| 960 | | - @ } |
| 961 | | - @ return top; |
| 962 | | - @ } |
| 963 | | - @ function miLineY(p){ |
| 964 | | - @ return p.y + node.h - mLine.w - 1; |
| 965 | | - @ } |
| 966 | | - @ function drawLine(elem,color,x0,y0,x1,y1){ |
| 967 | | - @ var cls = elem.cls + " "; |
| 968 | | - @ if( x1===null ){ |
| 969 | | - @ x1 = x0+elem.w; |
| 970 | | - @ cls += "v"; |
| 971 | | - @ }else{ |
| 972 | | - @ y1 = y0+elem.w; |
| 973 | | - @ cls += "h"; |
| 974 | | - @ } |
| 975 | | - @ drawBox(cls,color,x0,y0,x1,y1); |
| 976 | | - @ } |
| 977 | | - @ function drawUpArrow(from,to,color){ |
| 978 | | - @ var y = to.y + node.h; |
| 979 | | - @ var arrowSpace = from.y - y + (!from.id || from.r!=to.r ? node.h/2 : 0); |
| 980 | | - @ var arw = arrowSpace < arrow.h*1.5 ? arrowSmall : arrow; |
| 981 | | - @ var x = to.x + (node.w-line.w)/2; |
| 982 | | - @ var y0 = from.y + node.h/2; |
| 983 | | - @ var y1 = Math.ceil(to.y + node.h + arw.h/2); |
| 984 | | - @ drawLine(line,color,x,y0,null,y1); |
| 985 | | - @ x = to.x + (node.w-arw.w)/2; |
| 986 | | - @ var n = drawBox(arw.cls,null,x,y); |
| 987 | | - @ n.style.borderBottomColor = color; |
| 988 | | - @ } |
| 989 | | - @ function drawMergeLine(x0,y0,x1,y1){ |
| 990 | | - @ drawLine(mLine,null,x0,y0,x1,y1); |
| 991 | | - @ } |
| 992 | | - @ function drawMergeArrow(p,rail){ |
| 993 | | - @ var x0 = rail*railPitch + node.w/2; |
| 994 | | - @ if( rail in mergeLines ){ |
| 995 | | - @ x0 += mergeLines[rail]; |
| 996 | | - @ if( p.r<rail ) x0 += mLine.w; |
| 997 | | - @ }else{ |
| 998 | | - @ x0 += (p.r<rail ? -1 : 1)*line.w/2; |
| 999 | | - @ } |
| 1000 | | - @ var x1 = mArrow.w ? mArrow.w/2 : -node.w/2; |
| 1001 | | - @ x1 = p.x + (p.r<rail ? node.w + Math.ceil(x1) : -x1); |
| 1002 | | - @ var y = miLineY(p); |
| 1003 | | - @ drawMergeLine(x0,y,x1,null); |
| 1004 | | - @ var x = p.x + (p.r<rail ? node.w : -mArrow.w); |
| 1005 | | - @ var cls = "arrow merge " + (p.r<rail ? "l" : "r"); |
| 1006 | | - @ drawBox(cls,null,x,y+(mLine.w-mArrow.h)/2); |
| 1007 | | - @ } |
| 1008 | | - @ function drawNode(p, btm){ |
| 1009 | | - @ if( p.u>0 ) drawUpArrow(p,rowinfo[p.u-%d(iTopRow)],p.fg); |
| 1010 | | - @ var cls = node.cls; |
| 1011 | | - @ if( p.mi.length ) cls += " merge"; |
| 1012 | | - @ if( p.f&1 ) cls += " leaf"; |
| 1013 | | - @ var n = drawBox(cls,p.bg,p.x,p.y); |
| 1014 | | - @ n.id = "tln"+p.id; |
| 1015 | | - @ n.onclick = clickOnNode; |
| 1016 | | - @ n.style.zIndex = 10; |
| 1017 | | - if( !omitDescenders ){ |
| 1018 | | - @ if( p.u==0 ) drawUpArrow(p,{x: p.x, y: -node.h},p.fg); |
| 1019 | | - @ if( p.d ) drawUpArrow({x: p.x, y: btm-node.h/2},p,p.fg); |
| 1020 | | - } |
| 1021 | | - @ if( p.mo>=0 ){ |
| 1022 | | - @ var x0 = p.x + node.w/2; |
| 1023 | | - @ var x1 = p.mo*railPitch + node.w/2; |
| 1024 | | - @ var u = rowinfo[p.mu-%d(iTopRow)]; |
| 1025 | | - @ var y1 = miLineY(u); |
| 1026 | | - @ if( p.u<0 || p.mo!=p.r ){ |
| 1027 | | - @ x1 += mergeLines[p.mo] = -mLine.w/2; |
| 1028 | | - @ var y0 = p.y+2; |
| 1029 | | - @ if( p.r!=p.mo ) drawMergeLine(x0,y0,x1+(x0<x1 ? mLine.w : 0),null); |
| 1030 | | - @ drawMergeLine(x1,y0+mLine.w,null,y1); |
| 1031 | | - @ }else if( mergeOffset ){ |
| 1032 | | - @ mergeLines[p.mo] = u.r<p.r ? -mergeOffset-mLine.w : mergeOffset; |
| 1033 | | - @ x1 += mergeLines[p.mo]; |
| 1034 | | - @ drawMergeLine(x1,p.y+node.h/2,null,y1); |
| 1035 | | - @ }else{ |
| 1036 | | - @ delete mergeLines[p.mo]; |
| 1037 | | - @ } |
| 1038 | | - @ } |
| 1039 | | - @ for( var i=0; i<p.au.length; i+=2 ){ |
| 1040 | | - @ var rail = p.au[i]; |
| 1041 | | - @ var x0 = p.x + node.w/2; |
| 1042 | | - @ var x1 = rail*railPitch + (node.w-line.w)/2; |
| 1043 | | - @ if( x0<x1 ){ |
| 1044 | | - @ x0 = Math.ceil(x0); |
| 1045 | | - @ x1 += line.w; |
| 1046 | | - @ } |
| 1047 | | - @ var y0 = p.y + (node.h-line.w)/2; |
| 1048 | | - @ var u = rowinfo[p.au[i+1]-%d(iTopRow)]; |
| 1049 | | - @ if( u.id<p.id ){ |
| 1050 | | - @ drawLine(line,u.fg,x0,y0,x1,null); |
| 1051 | | - @ drawUpArrow(p,u,u.fg); |
| 1052 | | - @ }else{ |
| 1053 | | - @ var y1 = u.y + (node.h-line.w)/2; |
| 1054 | | - @ drawLine(wLine,u.fg,x0,y0,x1,null); |
| 1055 | | - @ drawLine(wLine,u.fg,x1-line.w,y0,null,y1+line.w); |
| 1056 | | - @ drawLine(wLine,u.fg,x1,y1,u.x-wArrow.w/2,null); |
| 1057 | | - @ var x = u.x-wArrow.w; |
| 1058 | | - @ var y = u.y+(node.h-wArrow.h)/2; |
| 1059 | | - @ var n = drawBox(wArrow.cls,null,x,y); |
| 1060 | | - @ if( u.fg ) n.style.borderLeftColor = u.fg; |
| 1061 | | - @ } |
| 1062 | | - @ } |
| 1063 | | - @ for( var i=0; i<p.mi.length; i++ ){ |
| 1064 | | - @ var rail = p.mi[i]; |
| 1065 | | - @ if( rail<0 ){ |
| 1066 | | - @ rail = -rail; |
| 1067 | | - @ mergeLines[rail] = -mLine.w/2; |
| 1068 | | - @ var x = rail*railPitch + (node.w-mLine.w)/2; |
| 1069 | | - @ drawMergeLine(x,miLineY(p),null,btm); |
| 1070 | | - @ } |
| 1071 | | - @ drawMergeArrow(p,rail); |
| 1072 | | - @ } |
| 1073 | | - @ } |
| 1074 | | - @ var mergeLines; |
| 1075 | | - @ function renderGraph(){ |
| 1076 | | - @ mergeLines = {}; |
| 1077 | | - @ canvasDiv.innerHTML = ""; |
| 1078 | | - @ var canvasY = absoluteY(canvasDiv); |
| 1079 | | - @ for( var i=0; i<rowinfo.length; i++ ){ |
| 1080 | | - @ rowinfo[i].y = absoluteY(gebi("m"+rowinfo[i].id)) - canvasY; |
| 1081 | | - @ rowinfo[i].x = rowinfo[i].r*railPitch; |
| 1082 | | - @ } |
| 1083 | | - @ var tlBtm = document.querySelector(".timelineBottom"); |
| 1084 | | - @ if( tlBtm.offsetHeight<node.h ){ |
| 1085 | | - @ tlBtm.style.height = node.h + "px"; |
| 1086 | | - @ } |
| 1087 | | - @ var btm = absoluteY(tlBtm) - canvasY + tlBtm.offsetHeight; |
| 1088 | | - @ for( var i=rowinfo.length-1; i>=0; i-- ){ |
| 1089 | | - @ drawNode(rowinfo[i], btm); |
| 1090 | | - @ } |
| 1091 | | - @ } |
| 1092 | | - @ var selRow; |
| 1093 | | - @ function clickOnNode(){ |
| 1094 | | - @ var p = rowinfo[parseInt(this.id.match(/\d+$/)[0], 10)-%d(iTopRow)]; |
| 1095 | | - @ if( !selRow ){ |
| 1096 | | - @ selRow = p; |
| 1097 | | - @ this.className += " sel"; |
| 1098 | | - @ canvasDiv.className += " sel"; |
| 1099 | | - @ }else if( selRow==p ){ |
| 1100 | | - @ selRow = null; |
| 1101 | | - @ this.className = this.className.replace(" sel", ""); |
| 1102 | | - @ canvasDiv.className = canvasDiv.className.replace(" sel", ""); |
| 1103 | | - @ }else{ |
| 1104 | | - if( fileDiff ){ |
| 1105 | | - @ location.href="%R/fdiff?v1="+selRow.h+"&v2="+p.h+"&sbs=1"; |
| 1106 | | - }else{ |
| 1107 | | - if( db_get_boolean("show-version-diffs", 0)==0 ){ |
| 1108 | | - @ location.href="%R/vdiff?from="+selRow.h+"&to="+p.h+"&sbs=0"; |
| 1109 | | - }else{ |
| 1110 | | - @ location.href="%R/vdiff?from="+selRow.h+"&to="+p.h+"&sbs=1"; |
| 1111 | | - } |
| 1112 | | - } |
| 1113 | | - @ } |
| 1114 | | - @ } |
| 1115 | | - @ function changeDisplay(selector,value){ |
| 1116 | | - @ var x = document.getElementsByClassName(selector); |
| 1117 | | - @ var n = x.length; |
| 1118 | | - @ for(var i=0; i<n; i++) {x[i].style.display = value;} |
| 1119 | | - @ } |
| 1120 | | - @ function declutter(){ |
| 1121 | | - @ changeDisplay('clutter','none'); |
| 1122 | | - @ changeDisplay('anticlutter','inline'); |
| 1123 | | - @ checkHeight(); |
| 1124 | | - @ } |
| 1125 | | - @ function reclutter(){ |
| 1126 | | - @ changeDisplay('clutter','inline'); |
| 1127 | | - @ changeDisplay('anticlutter','none'); |
| 1128 | | - @ checkHeight(); |
| 1129 | | - @ } |
| 1130 | | - @ function changeDisplayById(id,value){ |
| 1131 | | - @ var x = document.getElementById(id); |
| 1132 | | - @ if(x) x.style.display=value; |
| 1133 | | - @ } |
| 1134 | | - @ function toggleDetail(id){ |
| 1135 | | - @ var x = gebi("detail-"+id); |
| 1136 | | - @ if( x.style.display=="inline" ){ |
| 1137 | | - @ x.style.display="none"; |
| 1138 | | - @ changeDisplayById("ellipsis-"+id,"inline"); |
| 1139 | | - @ changeDisplayById("links-"+id,"none"); |
| 1140 | | - @ }else{ |
| 1141 | | - @ x.style.display="inline"; |
| 1142 | | - @ changeDisplayById("ellipsis-"+id,"none"); |
| 1143 | | - @ changeDisplayById("links-"+id,"inline"); |
| 1144 | | - @ } |
| 1145 | | - @ checkHeight(); |
| 1146 | | - @ } |
| 1147 | | - @ function scrollToSelected(){ |
| 1148 | | - @ var x = document.getElementsByClassName('timelineSelected'); |
| 1149 | | - @ if(x[0]){ |
| 1150 | | - @ var h = window.innerHeight; |
| 1151 | | - @ var y = absoluteY(x[0]) - h/2; |
| 1152 | | - @ if( y>0 ) window.scrollTo(0, y); |
| 1153 | | - @ } |
| 1154 | | - @ } |
| 1155 | | - @ var lastRow = gebi("m"+rowinfo[rowinfo.length-1].id); |
| 1156 | | - @ var lastY = 0; |
| 1157 | | - @ function checkHeight(){ |
| 1158 | | - @ var h = absoluteY(lastRow); |
| 1159 | | - @ if( h!=lastY ){ |
| 1160 | | - @ renderGraph(); |
| 1161 | | - @ lastY = h; |
| 1162 | | - @ } |
| 1163 | | - @ setTimeout(checkHeight, 1000); |
| 1164 | | - @ } |
| 1165 | | - @ initGraph(); |
| 1166 | | - @ checkHeight(); |
| 1167 | | - @ scrollToSelected(); |
| 1168 | | - @ </script> |
| 865 | + cgi_printf("],\"h\":\"%!S\"}%s", |
| 866 | + pRow->zUuid, pRow->pNext ? ",\n" : "]\n"); |
| 867 | + } |
| 868 | + @ }</script> |
| 869 | + style_load_one_js_file("graph.js"); |
| 870 | + graph_free(pGraph); |
| 1169 | 871 | } |
| 1170 | 872 | } |
| 1171 | 873 | |
| 1172 | 874 | /* |
| 1173 | 875 | ** Create a temporary table suitable for storing timeline data. |
| 1174 | 876 | |