Index: auto.def
==================================================================
--- auto.def
+++ auto.def
@@ -376,11 +376,10 @@
if {[string match *-darwin* [get-define host]]} {
if {[cctest -cflags {-Wdeprecated-declarations}]} {
define-append EXTRA_CFLAGS -Wdeprecated-declarations
}
}
- cc-check-function-in-lib BIO_ADDR_hostname_string ssl
} else {
user-error "OpenSSL not found. Consider --with-openssl=none to disable HTTPS support"
}
} else {
if {[info exists ::zlib_lib]} {
Index: src/branch.c
==================================================================
--- src/branch.c
+++ src/branch.c
@@ -657,9 +657,9 @@
** many descenders to (off-screen) parents. */
tmFlags = TIMELINE_DISJOINT | TIMELINE_NOSCROLL;
if( PB("ng")==0 ) tmFlags |= TIMELINE_GRAPH;
if( PB("brbg")!=0 ) tmFlags |= TIMELINE_BRCOLOR;
if( PB("ubg")!=0 ) tmFlags |= TIMELINE_UCOLOR;
- www_print_timeline(&q, tmFlags, 0, 0, 0, brtimeline_extra);
+ www_print_timeline(&q, tmFlags, 0, 0, 0, 0, brtimeline_extra);
db_finalize(&q);
style_footer();
}
Index: src/configure.c
==================================================================
--- src/configure.c
+++ src/configure.c
@@ -94,12 +94,17 @@
{ "logo-mimetype", CONFIGSET_SKIN },
{ "logo-image", CONFIGSET_SKIN },
{ "background-mimetype", CONFIGSET_SKIN },
{ "background-image", CONFIGSET_SKIN },
{ "timeline-block-markup", CONFIGSET_SKIN },
+ { "timeline-date-format", CONFIGSET_SKIN },
+ { "timeline-dwelltime", CONFIGSET_SKIN },
+ { "timeline-closetime", CONFIGSET_SKIN },
{ "timeline-max-comment", CONFIGSET_SKIN },
{ "timeline-plaintext", CONFIGSET_SKIN },
+ { "timeline-truncate-at-blank", CONFIGSET_SKIN },
+ { "timeline-utc", CONFIGSET_SKIN },
{ "adunit", CONFIGSET_SKIN },
{ "adunit-omit-if-admin", CONFIGSET_SKIN },
{ "adunit-omit-if-user", CONFIGSET_SKIN },
{ "sitemap-docidx", CONFIGSET_SKIN },
{ "sitemap-download", CONFIGSET_SKIN },
Index: src/default_css.txt
==================================================================
--- src/default_css.txt
+++ src/default_css.txt
@@ -196,22 +196,17 @@
border-left-width: 2px;
border-left-style: dotted;
background: rgba(255,255,255,0);
}
.tl-tooltip {
- background-color: #fecd4b;
- color: black;
text-align: center;
padding: 5px 1em;
border: 1px solid black;
border-radius: 6px;
position: absolute;
z-index: 100;
-}
-.tl-tooltip a {
- background-color: #fecd4b;
- color: black;
+ box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.75);
}
span.tagDsp {
font-weight: bold;
}
Index: src/descendants.c
==================================================================
--- src/descendants.c
+++ src/descendants.c
@@ -540,11 +540,11 @@
** many descenders to (off-screen) parents. */
tmFlags = TIMELINE_LEAFONLY | TIMELINE_DISJOINT | TIMELINE_NOSCROLL;
if( fNg==0 ) tmFlags |= TIMELINE_GRAPH;
if( fBrBg ) tmFlags |= TIMELINE_BRCOLOR;
if( fUBg ) tmFlags |= TIMELINE_UCOLOR;
- www_print_timeline(&q, tmFlags, 0, 0, 0, 0);
+ www_print_timeline(&q, tmFlags, 0, 0, 0, 0, 0);
db_finalize(&q);
@
style_footer();
}
Index: src/finfo.c
==================================================================
--- src/finfo.c
+++ src/finfo.c
@@ -645,11 +645,11 @@
@
}
db_finalize(&q);
db_finalize(&qparent);
if( pGraph ){
- graph_finish(pGraph, TIMELINE_DISJOINT);
+ graph_finish(pGraph, 0, TIMELINE_DISJOINT);
if( pGraph->nErr ){
graph_free(pGraph);
pGraph = 0;
}else{
@
\
Index: src/graph.c
==================================================================
--- src/graph.c
+++ src/graph.c
@@ -73,10 +73,11 @@
u8 isLeaf; /* True if this is a leaf node */
u8 isStepParent; /* pChild is actually a step-child */
u8 hasNormalOutMerge; /* Is parent of at laest 1 non-cherrypick merge */
u8 timeWarp; /* Child is earlier in time */
u8 bDescender; /* True if riser from bottom of graph to here. */
+ u8 selfUp; /* Space above this node but belonging */
i8 iRail; /* Which rail this check-in appears on. 0-based.*/
i8 mergeOut; /* Merge out to this rail. -1 if no merge-out */
u8 mergeIn[GR_MAX_RAIL]; /* Merge in from non-zero rails */
int aiRiser[GR_MAX_RAIL]; /* Risers from this node to a higher row. */
int mergeUpto; /* Draw the mergeOut rail up to this level */
@@ -96,10 +97,11 @@
int nBranch; /* Number of distinct branches */
char **azBranch; /* Names of the branches */
int nRow; /* Number of rows */
int nHash; /* Number of slots in apHash[] */
GraphRow **apHash; /* Hash table of GraphRow objects. Key: rid */
+ u8 aiRailMap[GR_MAX_RAIL]; /* Mapping of rails to actually columns */
};
#endif
/* The N-th bit */
@@ -318,11 +320,13 @@
}
/* Mask of additional rows for the riser to infinity */
if( !pPrior->isLeaf && (tmFlags & TIMELINE_DISJOINT)==0 ){
int n = RISER_MARGIN;
GraphRow *p;
+ pPrior->selfUp = 0;
for(p=pPrior; p && (n--)>0; p=p->pPrev){
+ pPrior->selfUp++;
p->railInUse |= mask;
}
}
}
@@ -344,16 +348,17 @@
if( u>0 && uidx ){
/* The thick arrow up to the next primary child of pDesc goes
** further up than the thin merge arrow riser, so draw them both
** on the same rail. */
pParent->mergeOut = pParent->iRail;
+ }else if( pParent->idx - pChild->idx < pParent->selfUp ){
+ pParent->mergeOut = pParent->iRail;
}else{
/* The thin merge arrow riser is taller than the thick primary
** child riser, so use separate rails. */
int iTarget = pParent->iRail;
- int iBtm = pParent->idx - (u==0 ? RISER_MARGIN : 1);
- pParent->mergeOut = findFreeRail(p, pChild->idx, iBtm, iTarget);
+ pParent->mergeOut = findFreeRail(p, pChild->idx, pParent->idx-1, iTarget);
mask = BIT(pParent->mergeOut);
for(pLoop=pChild->pNext; pLoop && pLoop->rid!=pParent->rid;
pLoop=pLoop->pNext){
pLoop->railInUse |= mask;
}
@@ -417,16 +422,17 @@
**
** TIMELINE_DISJOINT: Omit descenders
** TIMELINE_FILLGAPS: Use step-children
** TIMELINE_XMERGE: Omit off-graph merge lines
*/
-void graph_finish(GraphContext *p, u32 tmFlags){
+void graph_finish(GraphContext *p, const char *zLeftBranch, u32 tmFlags){
GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
int i, j;
u64 mask;
int hasDup = 0; /* True if one or more isDup entries */
const char *zTrunk;
+ u8 *aMap; /* Copy of p->aiRailMap */
int omitDescenders = (tmFlags & TIMELINE_DISJOINT)!=0;
/* If mergeRiserFrom[X]==Y that means rail X holds a merge riser
** coming up from the bottom of the graph from off-screen check-in Y
** where Y is the RID. There is no riser on rail X if mergeRiserFrom[X]==0.
@@ -516,19 +522,20 @@
pParent = hashFind(p, pRow->aParent[0]);
if( pParent==0 ) continue; /* Parent off-screen */
if( pParent->zBranch!=pRow->zBranch ) continue; /* Different branch */
if( pParent->idx <= pRow->idx ){
pParent->timeWarp = 1;
- }else if( pRow->idx < pParent->idx ){
+ }else if( pRow->idxTop < pParent->idxTop ){
pParent->pChild = pRow;
+ pParent->idxTop = pRow->idxTop;
}
}
if( tmFlags & TIMELINE_FILLGAPS ){
- /* If a node has no pChild but there is a node higher up in the graph
- ** that is in the same branch and that other node has no parent in
- ** the graph, the lower node a step-child of the upper node. This will
+ /* If a node has no pChild and there is a node higher up in the graph
+ ** that is in the same branch and has no in-graph parent, then
+ ** make the lower node a step-child of the upper node. This will
** be represented on the graph by a thick dotted line without an arrowhead.
*/
for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
if( pRow->pChild ) continue;
for(pLoop=pRow->pPrev; pLoop; pLoop=pLoop->pPrev){
@@ -713,7 +720,29 @@
/*
** Find the maximum rail number.
*/
find_max_rail(p);
+
+ /*
+ ** Compute the rail mapping.
+ */
+ aMap = p->aiRailMap;
+ for(i=0; i<=p->mxRail; i++) aMap[i] = i;
+ if( zLeftBranch ){
+ char *zLeft = persistBranchName(p, zLeftBranch);
+ j = 0;
+ for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
+ if( pRow->zBranch==zLeft && aMap[pRow->iRail]>=j ){
+ for(i=0; i<=p->mxRail; i++){
+ if( aMap[i]>=j && aMap[i]<=pRow->iRail ) aMap[i]++;
+ }
+ aMap[pRow->iRail] = j++;
+ }
+ }
+ cgi_printf("\n");
+ }
+
p->nErr = 0;
}
Index: src/graph.js
==================================================================
--- src/graph.js
+++ src/graph.js
@@ -1,6 +1,9 @@
/* This module contains javascript needed to render timeline graphs in Fossil.
+**
+** There can be multiple graphs on a single webpage, but this script is only
+** loaded once.
**
** Prior to sourcing this script, there should be a separate
**