Index: src/checkin.c ================================================================== --- src/checkin.c +++ src/checkin.c @@ -99,12 +99,15 @@ } free(zFullName); } blob_reset(&rewrittenPathname); db_finalize(&q); + /* -3 holds the baseline-based merges - nor cherrypick nor backout. + * Now we can't report easily the baseline-based merges, because + * we don't store the baseline point in vmerge */ db_prepare(&q, "SELECT uuid, id FROM vmerge JOIN blob ON merge=rid" - " WHERE id<=0"); + " WHERE id<=0 AND id >= -2"); while( db_step(&q)==SQLITE_ROW ){ const char *zLabel = "MERGED_WITH"; switch( db_column_int(&q, 1) ){ case -1: zLabel = "CHERRYPICK "; break; case -2: zLabel = "BACKOUT "; break; @@ -1211,13 +1214,14 @@ blob_zero(&ans); prompt_user("continue (y/N)? ", &ans); cReply = blob_str(&ans)[0]; if( cReply!='y' && cReply!='Y' ) fossil_exit(1);; } + /* id=0 means that it introduces a new parent */ isAMerge = db_exists("SELECT 1 FROM vmerge WHERE id=0"); if( g.aCommitFile && isAMerge ){ - fossil_fatal("cannot do a partial commit of a merge"); + fossil_fatal("cannot do a partial commit of a graph merge"); } /* Doing "fossil mv fileA fileB; fossil add fileA; fossil commit fileA" ** will generate a manifest that has two fileA entries, which is illegal. ** When you think about it, the sequence above makes no sense. So detect Index: src/db.c ================================================================== --- src/db.c +++ src/db.c @@ -2070,10 +2070,11 @@ { "encoding-glob", 0, 40, 1, "" }, { "gdiff-command", 0, 40, 0, "gdiff" }, { "gmerge-command",0, 40, 0, "" }, { "http-port", 0, 16, 0, "8080" }, { "https-login", 0, 0, 0, "off" }, + { "href-targets", 0, 0, 0, "on" }, { "ignore-glob", 0, 40, 1, "" }, { "localauth", 0, 0, 0, "off" }, { "main-branch", 0, 40, 0, "trunk" }, { "manifest", 0, 0, 1, "off" }, #ifdef FOSSIL_ENABLE_MARKDOWN Index: src/diff.c ================================================================== --- src/diff.c +++ src/diff.c @@ -57,10 +57,11 @@ /* ** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes) */ #define LENGTH_MASK_SZ 13 +#define TABLENGTH 4 #define LENGTH_MASK ((1<<LENGTH_MASK_SZ)-1) /* ** Information about each line of a file being diffed. ** @@ -618,10 +619,12 @@ appendDiffLine(pOut, ' ', &B[b+j], html, 0); } } } +static int maxwidth; + /* ** Status of a single output line */ typedef struct SbsLine SbsLine; struct SbsLine { @@ -659,63 +662,92 @@ int k; /* Cursor position */ int needEndSpan = 0; const char *zIn = pLine->z; char *z = &p->zLine[p->n]; int w = p->width; + int colorize = p->escHtml; if( colorize && p->pRe && re_dline_match(p->pRe, pLine, 1)==0 ){ colorize = 0; } - for(i=j=k=0; k<w && i<n; i++, k++){ + + /* In the case w == 0, we want to calculate the output line + * width (k), but not write anything to 'z', because it has + * a buffer of limited size. */ + for(i=j=k=0; (w == 0 || k<w) && i<n; i++, k++){ char c = zIn[i]; if( colorize ){ if( i==p->iStart ){ int x = strlen(p->zStart); - memcpy(z+j, p->zStart, x); + if (w != 0) + memcpy(z+j, p->zStart, x); j += x; needEndSpan = 1; if( p->iStart2 ){ p->iStart = p->iStart2; p->zStart = p->zStart2; p->iStart2 = 0; } }else if( i==p->iEnd ){ - memcpy(z+j, "</span>", 7); + if (w != 0) + memcpy(z+j, "</span>", 7); j += 7; needEndSpan = 0; if( p->iEnd2 ){ p->iEnd = p->iEnd2; p->iEnd2 = 0; } } } if( c=='\t' ){ - z[j++] = ' '; - while( (k&7)!=7 && k<w ){ z[j++] = ' '; k++; } + if (w != 0) + z[j++] = ' '; + while( (k%TABLENGTH)!=0 && (w == 0 || k<w) ){ + if (w != 0) + z[j++] = ' '; + k++; + } }else if( c=='\r' || c=='\f' ){ - z[j++] = ' '; + if (w != 0) + z[j++] = ' '; }else if( c=='<' && p->escHtml ){ - memcpy(&z[j], "<", 4); - j += 4; + if (w != 0) { + memcpy(&z[j], "<", 4); + j += 4; + } }else if( c=='&' && p->escHtml ){ - memcpy(&z[j], "&", 5); - j += 5; + if (w != 0) { + memcpy(&z[j], "&", 5); + j += 5; + } }else if( c=='>' && p->escHtml ){ - memcpy(&z[j], ">", 4); - j += 4; + if (w != 0) { + memcpy(&z[j], ">", 4); + j += 4; + } }else if( c=='"' && p->escHtml ){ - memcpy(&z[j], """, 6); - j += 6; + if (w != 0) { + memcpy(&z[j], """, 6); + j += 6; + } }else{ - z[j++] = c; + if (w != 0) { + z[j++] = c; + } if( (c&0xc0)==0x80 ) k--; } } if( needEndSpan ){ - memcpy(&z[j], "</span>", 7); - j += 7; + if (w != 0) { + memcpy(&z[j], "</span>", 7); + j += 7; + } } + + if (k > maxwidth) + maxwidth = k; + if( (flags & SBS_PAD)!=0 ){ while( k<w ){ k++; z[j++] = ' '; } } if( flags & SBS_NEWLINE ){ z[j++] = '\n'; @@ -1241,10 +1273,18 @@ int nContext; /* Lines of context above and below each change */ int showDivider = 0; /* True to show the divider */ memset(&s, 0, sizeof(s)); s.width = diff_width(diffFlags); + if( s.width == 0 ) { /* May Autocalculate */ + Blob dump; + maxwidth = -1; /* The webserver may call sbsDiff more than once per process */ + blob_zero(&dump); + sbsDiff(p, &dump, pRe, diffFlags | DIFF_WIDTH_MASK); + s.width = maxwidth; + blob_reset(&dump); + } s.zLine = fossil_malloc( 15*s.width + 200 ); if( s.zLine==0 ) return; nContext = diff_context_lines(diffFlags); s.escHtml = (diffFlags & DIFF_HTML)!=0; s.pRe = pRe; @@ -1863,11 +1903,10 @@ ** Extract the width of columns for side-by-side diff. Supply an ** appropriate default if no width is given. */ int diff_width(u64 diffFlags){ int w = (diffFlags & DIFF_WIDTH_MASK)/(DIFF_CONTEXT_MASK+1); - if( w==0 ) w = 80; return w; } /* ** Generate a report of the differences between files pA and pB. @@ -2175,11 +2214,12 @@ ** by its filename number (filename.fnid) and the baseline in which ** it was checked in (mlink.mid). */ static void annotate_file( Annotator *p, /* The annotator */ - int fnid, /* The name of the file to be annotated */ + const char *zFilename,/* The name of the file to be annotated */ + int fnid, /* The file name id of the file to be annotated */ int mid, /* Use the version of the file in this check-in */ int webLabel, /* Use web-style annotations if true */ int iLimit, /* Limit the number of levels if greater than zero */ int annFlags /* Flags to alter the annotation */ ){ @@ -2187,10 +2227,15 @@ Blob step; /* Text of previous revision */ int rid; /* Artifact ID of the file being annotated */ char *zLabel; /* Label to apply to a line */ Stmt q; /* Query returning all ancestor versions */ int cnt = 0; /* Number of versions examined */ + const char *zInfoTarget; /* String for target info window */ + const char *zDiffTarget; /* String for target diff window */ + + zInfoTarget = db_get_boolean("href-targets", 1) ? "target='infowindow'" : ""; + zDiffTarget = db_get_boolean("href-targets", 1) ? "target='diffwindow'" : ""; /* Initialize the annotation */ rid = db_int(0, "SELECT fid FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid); if( rid==0 ){ fossil_panic("file #%d is unchanged in manifest #%d", fnid, mid); @@ -2201,10 +2246,12 @@ if( iLimit<=0 ) iLimit = 1000000000; annotation_start(p, &toAnnotate); db_prepare(&q, "SELECT (SELECT uuid FROM blob WHERE rid=mlink.%s)," + " (SELECT uuid FROM blob WHERE rid=mlink.fid)," + " (SELECT uuid FROM blob WHERE rid=mlink.pid)," " date(event.mtime)," " coalesce(event.euser,event.user)," " mlink.pid" " FROM mlink, event" " WHERE mlink.fid=:rid" @@ -2215,18 +2262,31 @@ db_bind_int(&q, ":rid", rid); if( iLimit==0 ) iLimit = 1000000000; while( rid && iLimit>cnt && db_step(&q)==SQLITE_ROW ){ const char *zUuid = db_column_text(&q, 0); - const char *zDate = db_column_text(&q, 1); - const char *zUser = db_column_text(&q, 2); - int prevId = db_column_int(&q, 3); + const char *zUuidFile = db_column_text(&q, 1); + const char *zUuidParentFile = db_column_text(&q, 2); + const char *zDate = db_column_text(&q, 3); + const char *zUser = db_column_text(&q, 4); + int prevId = db_column_int(&q, 5); if( webLabel ){ - zLabel = mprintf( - "<a href='%R/info/%s' target='infowindow'>%.10s</a> %s %13.13s", - zUuid, zUuid, zDate, zUser - ); + if (zUuidParentFile) { + zLabel = mprintf( + "<a href='%R/info/%s' %s>%.10s</a> " + "<a href='%R/fdiff?v1=%s&v2=%s' %s>d</a> " + "%s %13.13s", + zUuid, zInfoTarget, zUuid, + zUuidParentFile, zUuidFile, zDiffTarget, + zDate, zUser); + }else{ + zLabel = mprintf( + "<a href='%R/info/%s' %s>%.10s</a> " + "%s %13.13s", + zUuid, zInfoTarget, zUuid, + zDate, zUser); + } }else{ zLabel = mprintf("%.10s %s %13.13s", zUuid, zDate, zUser); } p->nVers++; p->azVers = fossil_realloc(p->azVers, p->nVers*sizeof(p->azVers[0]) ); @@ -2271,11 +2331,11 @@ if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){ fossil_redirect_home(); } style_header("File Annotation"); if( P("filevers") ) annFlags |= ANN_FILE_VERS; - annotate_file(&ann, fnid, mid, g.perm.Hyperlink, iLimit, annFlags); + annotate_file(&ann, P("filename"), fnid, mid, g.perm.Hyperlink, iLimit, annFlags); if( P("log") ){ int i; @ <h2>Versions analyzed:</h2> @ <ol> for(i=0; i<ann.nVers; i++){ @@ -2362,11 +2422,11 @@ fid, fnid); if( mid==0 ){ fossil_panic("unable to find manifest"); } if( fileVers ) annFlags |= ANN_FILE_VERS; - annotate_file(&ann, fnid, mid, 0, iLimit, annFlags); + annotate_file(&ann, zFilename, fnid, mid, 0, iLimit, annFlags); if( showLog ){ for(i=0; i<ann.nVers; i++){ printf("version %3d: %s\n", i+1, ann.azVers[i]); } printf("---------------------------------------------------\n"); Index: src/diffcmd.c ================================================================== --- src/diffcmd.c +++ src/diffcmd.c @@ -50,12 +50,19 @@ /* no-op */ }else if( diffFlags & DIFF_SIDEBYSIDE ){ int w = diff_width(diffFlags); int n1 = strlen(zLeft); int x; - if( n1>w*2 ) n1 = w*2; - x = w*2+17 - (n1+2); + if (w > 0) { + if( n1>w*2 ) n1 = w*2; + x = w*2+17 - (n1+2); + }else{ + /* Autocalculate width + * We can't know the width in advance, so we'll make it + * output three = around the name */ + x = 6; + } z = mprintf("%.*c %.*s %.*c\n", x/2, '=', n1, zLeft, (x+1)/2, '='); }else{ z = mprintf("--- %s\n+++ %s\n", zLeft, zRight); } Index: src/doc.c ================================================================== --- src/doc.c +++ src/doc.c @@ -188,10 +188,13 @@ { "mpga", 4, "audio/mpeg" }, { "ms", 2, "application/x-troff-ms" }, { "msh", 3, "model/mesh" }, { "nc", 2, "application/x-netcdf" }, { "oda", 3, "application/oda" }, + { "odp", 3, "application/vnd.oasis.opendocument.presentation" }, + { "ods", 3, "application/vnd.oasis.opendocument.spreadsheet" }, + { "odt", 3, "application/vnd.oasis.opendocument.text" }, { "ogg", 3, "application/ogg" }, { "ogm", 3, "application/ogg" }, { "pbm", 3, "image/x-portable-bitmap" }, { "pdb", 3, "chemical/x-pdb" }, { "pdf", 3, "application/pdf" }, Index: src/info.c ================================================================== --- src/info.c +++ src/info.c @@ -407,12 +407,13 @@ }else{ int x; if( sideBySide ){ diffFlags = DIFF_SIDEBYSIDE | DIFF_IGNORE_EOLWS; - /* "dw" query parameter determines width of each column */ - x = atoi(PD("dw","80"))*(DIFF_CONTEXT_MASK+1); + /* "dw" query parameter determines width of each column + * 0 means autocalculate. */ + x = atoi(PD("dw","0"))*(DIFF_CONTEXT_MASK+1); if( x<0 || x>DIFF_WIDTH_MASK ) x = DIFF_WIDTH_MASK; diffFlags += x; }else{ diffFlags = DIFF_INLINE | DIFF_IGNORE_EOLWS; } @@ -650,10 +651,12 @@ @ <tr><th>Other Links:</th> @ <td> @ %z(href("%R/dir?ci=%S",zUuid))files</a> @ | %z(href("%R/fileage?name=%S",zUuid))file ages</a> @ | %z(href("%R/artifact/%S",zUuid))manifest</a> + @ | <a href="%s(g.zTop)/vdiff?from=pbranch:%S(zUuid)&to=%S(zUuid)"> + @ vdiff to parent branch</a> if( g.perm.Write ){ @ | %z(href("%R/ci_edit?r=%S",zUuid))edit</a> } @ </td> @ </tr> @@ -875,29 +878,34 @@ static void checkin_description(int rid){ Stmt q; db_prepare(&q, "SELECT datetime(mtime), coalesce(euser,user)," " coalesce(ecomment,comment), uuid," + " coalesce((SELECT value FROM tagxref" + " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid),'trunk')," " (SELECT group_concat(substr(tagname,5), ', ') FROM tag, tagxref" " WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid" " AND tagxref.rid=blob.rid AND tagxref.tagtype>0)" " FROM event, blob" " WHERE event.objid=%d AND type='ci'" " AND blob.rid=%d", - rid, rid + TAG_BRANCH, rid, rid ); while( db_step(&q)==SQLITE_ROW ){ const char *zDate = db_column_text(&q, 0); const char *zUser = db_column_text(&q, 1); const char *zUuid = db_column_text(&q, 3); + const char *zBranch = db_column_text(&q, 4); const char *zTagList = db_column_text(&q, 4); Blob comment; int wikiFlags = WIKI_INLINE|WIKI_NOBADLINKS; if( db_get_boolean("timeline-block-markup", 0)==0 ){ wikiFlags |= WIKI_NOBLOCK; } hyperlink_to_uuid(zUuid); + @ on branch <a href="%R/timeline?r=%s(zBranch)&nd&c=%T(zDate)"> + @ %s(zBranch)</a> - blob_zero(&comment); db_column_blob(&q, 2, &comment); wiki_convert(&comment, 0, wikiFlags); blob_reset(&comment); @ (user: @@ -974,19 +982,28 @@ sideBySide = atoi(PD("sbs","1")); showDetail = atoi(PD("detail","0")); if( !showDetail && sideBySide ) showDetail = 1; zFrom = P("from"); zTo = P("to"); - if( !sideBySide ){ - style_submenu_element("Side-by-side Diff", "sbsdiff", - "%R/vdiff?from=%T&to=%T&detail=%d&sbs=1", - zFrom, zTo, showDetail); - }else{ + if (showDetail){ + style_submenu_element("Abstract", "abstract", + "%s/vdiff?from=%T&to=%T&detail=0&sbs=0", + g.zTop, zFrom, zTo); + } + if( !showDetail || sideBySide ){ style_submenu_element("Unified Diff", "udiff", - "%R/vdiff?from=%T&to=%T&detail=%d&sbs=0", - zFrom, zTo, showDetail); + "%R/vdiff?from=%T&to=%T&detail=1&sbs=0", + zFrom, zTo); } + if (!sideBySide){ + style_submenu_element("Side-by-side Diff", "sbsdiff", + "%R/vdiff?from=%T&to=%T&detail=1&sbs=1", + zFrom, zTo); + } + style_submenu_element("Patch", "patch", + "%s/vpatch?from=%T&to=%T", + g.zTop, zFrom, zTo); style_submenu_element("Invert", "invert", "%R/vdiff?from=%T&to=%T&detail=%d&sbs=%d", zTo, zFrom, showDetail, sideBySide); style_header("Check-in Differences"); @ <h2>Difference From:</h2><blockquote> Index: src/merge.c ================================================================== --- src/merge.c +++ src/merge.c @@ -630,11 +630,11 @@ /* ** Clean up the mid and pid VFILE entries. Then commit the changes. */ db_multi_exec("DELETE FROM vfile WHERE vid!=%d", vid); db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(%d,%d)", - pickFlag ? -1 : (backoutFlag ? -2 : 0), mid); + pickFlag ? -1 : (backoutFlag ? -2 : (zPivot ? -3 : 0)), mid); if( pickFlag ){ /* For a cherry-pick merge, make the default check-in comment the same ** as the check-in comment on the check-in that is being merged in. */ db_multi_exec( "REPLACE INTO vvar(name,value)" Index: src/name.c ================================================================== --- src/name.c +++ src/name.c @@ -112,10 +112,18 @@ " WHERE mtime<=julianday(%Q,'utc') AND type GLOB '%q'" " ORDER BY mtime DESC LIMIT 1", &zTag[5], zType); return rid; } + + if( memcmp(zTag, "pbranch:", 8)==0 ){ + int branchRid = symbolic_name_to_rid(&zTag[8], zType); + if (branchRid == 0) return 0; + rid = get_parent_branch_rid(branchRid); + return rid; + } + if( fossil_isdate(zTag) ){ rid = db_int(0, "SELECT objid FROM event" " WHERE mtime<=julianday(%Q,'utc') AND type GLOB '%q'" " ORDER BY mtime DESC LIMIT 1", @@ -522,5 +530,97 @@ comment_print(db_column_text(&q,4), 10, 78); } db_finalize(&q); } } + +int get_parent_branch_rid(int ridRequested){ + Stmt s; + const char *branchName; /* Name of the branch requested at rid */ + const char *parentBranchName; /* Name of the parent branch */ + int rid; + + /* Get the name of the current branch */ + branchName = db_text(0, + "SELECT value FROM tagxref" + " WHERE tagid=%d" + " AND tagxref.tagtype>0" + " AND rid=%d", + TAG_BRANCH, ridRequested); + + if ( !branchName ) + return 0; + + /* Find the name of the branch this was forked from */ + db_prepare(&s, + "SELECT pid, tagxref.value FROM plink JOIN tagxref" + " WHERE cid=:rid" + " AND isprim=1" + " AND tagxref.tagid=%d" + " AND tagxref.tagtype>0" + " AND tagxref.rid=pid", + TAG_BRANCH); + + rid = ridRequested; + while( rid > 0 ) { + db_bind_int(&s, ":rid", rid); + if ( db_step(&s) == SQLITE_ROW ) { + rid = db_column_int(&s, 0); + parentBranchName = db_column_text(&s, 1); + if ( !parentBranchName ) { + rid = 0; + break; + } + + if ( fossil_strcmp(parentBranchName, branchName) ) { + parentBranchName = fossil_strdup(parentBranchName); + break; + } + }else{ + rid = 0; + break; + } + db_reset(&s); + } + db_finalize(&s); + + if (rid == 0) + return 0; + + /* Find the last checkin coming from the parent branch */ + db_prepare(&s, + "SELECT pid, tagxref.value FROM plink JOIN tagxref" + " WHERE cid=:rid" + " AND tagxref.tagid=%d" + " AND tagxref.tagtype>0" + " AND tagxref.rid=pid ORDER BY isprim ASC", + TAG_BRANCH); + + rid = ridRequested; + while( rid > 0 ) { + db_bind_int(&s, ":rid", rid); + int found = 0; + while ( db_step(&s) == SQLITE_ROW ) { + const char *branchNamePid; /* Branch name of the pid */ + + ++found; + rid = db_column_int(&s, 0); + branchNamePid = db_column_text(&s, 1); + if ( !branchNamePid ) { + break; + } + if ( fossil_strcmp(parentBranchName, branchNamePid)==0 ) { + /* Found the last merge from the parent branch */ + db_finalize(&s); + return rid; + } + } + + if (found == 0) { + break; + } + db_reset(&s); + } + db_finalize(&s); + + return 0; +} Index: src/timeline.c ================================================================== --- src/timeline.c +++ src/timeline.c @@ -119,40 +119,36 @@ */ char *hash_color(const char *z){ int i; /* Loop counter */ unsigned int h = 0; /* Hash on the branch name */ int r, g, b; /* Values for red, green, and blue */ - int h1, h2, h3, h4; /* Elements of the hash value */ - int mx, mn; /* Components of HSV */ static char zColor[10]; /* The resulting color */ - static int ix[2] = {0,0}; /* Color chooser parameters */ + static int whitefg = -1; + int cpc = 4; /* colours per component */ + int cfactor = 128/cpc; /* Factor so n*cpc < 128 */ + int cmin = cfactor - 1; /* Factor so the max component is 127 + and the min is different than the bg */ - if( ix[0]==0 ){ - if( db_get_boolean("white-foreground", 0) ){ - ix[0] = 140; - ix[1] = 40; - }else{ - ix[0] = 216; - ix[1] = 16; - } - } - for(i=0; z[i]; i++ ){ + if( whitefg = -1 ) + whitefg = db_get_boolean("white-foreground", 0); + + /* Calculate the hash based on the branch name */ + for( i=0; z[i]; i++ ){ h = (h<<11) ^ (h<<1) ^ (h>>3) ^ z[i]; } - h1 = h % 6; h /= 6; - h3 = h % 30; h /= 30; - h4 = h % 40; h /= 40; - mx = ix[0] - h3; - mn = mx - h4 - ix[1]; - h2 = (h%(mx - mn)) + mn; - switch( h1 ){ - case 0: r = mx; g = h2, b = mn; break; - case 1: r = h2; g = mx, b = mn; break; - case 2: r = mn; g = mx, b = h2; break; - case 3: r = mn; g = h2, b = mx; break; - case 4: r = h2; g = mn, b = mx; break; - default: r = mx; g = mn, b = h2; break; + + /* 'cpc' different random values per component, between 'cmin' and 127 */ + r = cmin + (h % cpc) * cfactor; h /= cpc; + g = cmin + (h % cpc) * cfactor; h /= cpc; + b = cmin + (h % cpc) * cfactor; h /= cpc; + + /* In case of blackfg, get the inverse effect */ + if( !whitefg ) + { + r = 255 - r; + g = 255 - g; + b = 255 - b; } sqlite3_snprintf(8, zColor, "#%02x%02x%02x", r,g,b); return zColor; } @@ -202,14 +198,17 @@ GraphContext *pGraph = 0; int prevWasDivider = 0; /* True if previous output row was <hr> */ int fchngQueryInit = 0; /* True if fchngQuery is initialized */ Stmt fchngQuery; /* Query for file changes on check-ins */ static Stmt qbranch; + const char *zDiffTarget; /* String for the target diff window */ int pendingEndTr = 0; /* True if a </td></tr> is needed */ zPrevDate[0] = 0; mxWikiLen = db_get_int("timeline-max-comment", 0); + zDiffTarget = db_get_boolean("href-targets", 1) ? + "target='diffwindow'": ""; if( tmFlags & TIMELINE_GRAPH ){ pGraph = graph_init(); /* style is not moved to css, because this is ** a technical div for the timeline graph */ @@ -447,25 +446,25 @@ @ <ul class="filelist"> inUl = 1; } if( isNew ){ @ <li> %h(zFilename) (new file) - @ %z(xhref("target='diffwindow'","%R/artifact/%S",zNew)) + @ %z(xhref(zDiffTarget,"%R/artifact/%S",zNew)) @ [view]</a></li> }else if( isDel ){ @ <li> %h(zFilename) (deleted)</li> }else if( fossil_strcmp(zOld,zNew)==0 && zOldName!=0 ){ @ <li> %h(zOldName) → %h(zFilename) - @ %z(xhref("target='diffwindow'","%R/artifact/%S",zNew)) + @ %z(xhref(zDiffTarget,"%R/artifact/%S",zNew)) @ [view]</a></li> }else{ if( zOldName!=0 ){ @ <li> %h(zOldName) → %h(zFilename) }else{ @ <li> %h(zFilename) } - @ %z(xhref("target='diffwindow'","%R/fdiff?v1=%S&v2=%S",zOld,zNew)) + @ %z(xhref(zDiffTarget,"%R/fdiff?v1=%S&v2=%S",zOld,zNew)) @ [diff]</a></li> } } db_reset(&fchngQuery); if( inUl ){