Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | When HTML diffs are generated from a webpage, include sufficient information in class names ids, and data- elements to permit JS to redraw the separators to include context fill-in buttons. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
c275a166b351d2b122ded0bbcfc0039c |
| User & Date: | drh 2021-09-07 18:45:25.829 |
Context
|
2021-09-07
| ||
| 19:09 | Add the /jtext webpage, intended for use by XHR. ... (check-in: 5f7fcbabf0 user: drh tags: trunk) | |
| 18:45 | When HTML diffs are generated from a webpage, include sufficient information in class names ids, and data- elements to permit JS to redraw the separators to include context fill-in buttons. ... (check-in: c275a166b3 user: drh tags: trunk) | |
| 17:11 | Fix the diff block alignment so that it correctly suppresses unnecessary diff marks, even when in ignore-whitespace mode. ... (check-in: 85ca2fe5b5 user: drh tags: trunk) | |
Changes
Changes to src/diff.c.
| ︙ | ︙ | |||
94 95 96 97 98 99 100 101 102 103 104 105 106 107 | u64 diffFlags; /* Diff flags */ int nContext; /* Number of lines of context */ int wColumn; /* Column width in -y mode */ u32 nFile; /* Number of files diffed so far */ const char *zDiffCmd; /* External diff command to use instead of builtin */ const char *zBinGlob; /* GLOB pattern for binary files */ ReCompiled *pRe; /* Show only changes matching this pattern */ }; #endif /* INTERFACE */ /* ** Initialize memory for a DiffConfig based on just a diffFlags integer. */ | > | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | u64 diffFlags; /* Diff flags */ int nContext; /* Number of lines of context */ int wColumn; /* Column width in -y mode */ u32 nFile; /* Number of files diffed so far */ const char *zDiffCmd; /* External diff command to use instead of builtin */ const char *zBinGlob; /* GLOB pattern for binary files */ ReCompiled *pRe; /* Show only changes matching this pattern */ const char *zLeftHash; /* HASH-id of the left file */ }; #endif /* INTERFACE */ /* ** Initialize memory for a DiffConfig based on just a diffFlags integer. */ |
| ︙ | ︙ | |||
895 896 897 898 899 900 901 902 903 904 905 906 907 908 | unsigned int lnLeft; /* Lines seen on the left (delete) side */ unsigned int lnRight; /* Lines seen on the right (insert) side */ unsigned int nPending; /* Number of pending lines */ int eState; /* State of the output */ int width; /* Display width */ Blob *pOut; /* Output blob */ Blob aCol[5]; /* Holding blobs */ }; /************************* DiffBuilderDebug ********************************/ /* This version of DiffBuilder is used for debugging the diff and diff ** diff formatter logic. It is accessed using the (undocumented) --debug ** option to the diff command. The output is human-readable text that ** describes the various method calls that are invoked agains the DiffBuilder | > | 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 | unsigned int lnLeft; /* Lines seen on the left (delete) side */ unsigned int lnRight; /* Lines seen on the right (insert) side */ unsigned int nPending; /* Number of pending lines */ int eState; /* State of the output */ int width; /* Display width */ Blob *pOut; /* Output blob */ Blob aCol[5]; /* Holding blobs */ DiffConfig *pCfg; /* Configuration information */ }; /************************* DiffBuilderDebug ********************************/ /* This version of DiffBuilder is used for debugging the diff and diff ** diff formatter logic. It is accessed using the (undocumented) --debug ** option to the diff command. The output is human-readable text that ** describes the various method calls that are invoked agains the DiffBuilder |
| ︙ | ︙ | |||
1249 1250 1251 1252 1253 1254 1255 |
static void dfunifiedStartRow(DiffBuilder *p){
if( blob_size(&p->aCol[0])>0 ) return;
blob_appendf(p->pOut,"<tr id=\"chunk%d\">"
"<td class=\"diffln difflnl\"><pre>\n", ++nChunk);
}
static void dfunifiedSkip(DiffBuilder *p, unsigned int n, int isFinal){
dfunifiedFinishRow(p);
| > > > > > > > | > > | 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 |
static void dfunifiedStartRow(DiffBuilder *p){
if( blob_size(&p->aCol[0])>0 ) return;
blob_appendf(p->pOut,"<tr id=\"chunk%d\">"
"<td class=\"diffln difflnl\"><pre>\n", ++nChunk);
}
static void dfunifiedSkip(DiffBuilder *p, unsigned int n, int isFinal){
dfunifiedFinishRow(p);
if( p->pCfg && p->pCfg->zLeftHash ){
blob_appendf(p->pOut,
"<tr class=\"diffskip\" data-startln=\"%d\" data-endln=\"%d\""
" id=\"skip%xh%xi%x\">\n",
p->lnLeft+1, p->lnLeft+n,
nChunk, p->lnLeft, n);
}else{
blob_append(p->pOut, "<tr>", 4);
}
blob_append(p->pOut, "<td class=\"diffln difflne\">"
"︙</td><td></td><td></td></tr>\n", -1);
p->lnLeft += n;
p->lnRight += n;
}
static void dfunifiedCommon(DiffBuilder *p, const DLine *pLine){
dfunifiedStartRow(p);
dfunifiedFinishDelete(p);
|
| ︙ | ︙ | |||
1370 1371 1372 1373 1374 1375 1376 |
p->nPending++;
}
static void dfunifiedEnd(DiffBuilder *p){
dfunifiedFinishRow(p);
blob_append(p->pOut, "</table>\n",-1);
fossil_free(p);
}
| | > > > > | > > | 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 |
p->nPending++;
}
static void dfunifiedEnd(DiffBuilder *p){
dfunifiedFinishRow(p);
blob_append(p->pOut, "</table>\n",-1);
fossil_free(p);
}
static DiffBuilder *dfunifiedNew(Blob *pOut, DiffConfig *pCfg){
DiffBuilder *p = fossil_malloc(sizeof(*p));
p->xSkip = dfunifiedSkip;
p->xCommon = dfunifiedCommon;
p->xInsert = dfunifiedInsert;
p->xDelete = dfunifiedDelete;
p->xReplace = dfunifiedReplace;
p->xEdit = dfunifiedEdit;
p->xEnd = dfunifiedEnd;
p->lnLeft = p->lnRight = 0;
p->eState = 0;
p->nPending = 0;
p->pOut = pOut;
if( pCfg->zLeftHash ){
blob_appendf(pOut, "<table class=\"diff udiff\" data-lefthash=\"%s\">\n",
pCfg->zLeftHash);
}else{
blob_append(pOut, "<table class=\"diff udiff\">\n", -1);
}
blob_init(&p->aCol[0], 0, 0);
blob_init(&p->aCol[1], 0, 0);
blob_init(&p->aCol[2], 0, 0);
blob_init(&p->aCol[3], 0, 0);
blob_init(&p->aCol[4], 0, 0);
p->pCfg = pCfg;
return p;
}
/************************* DiffBuilderSplit ******************************/
/* This formatter creates a side-by-side diff in HTML. The output is a
** <table> with 5 columns:
**
|
| ︙ | ︙ | |||
1461 1462 1463 1464 1465 1466 1467 |
if( blob_size(&p->aCol[0])>0 ) return;
blob_appendf(p->pOut,"<tr id=\"chunk%d\">"
"<td class=\"diffln difflnl\"><pre>\n", ++nChunk);
p->eState = 0;
}
static void dfsplitSkip(DiffBuilder *p, unsigned int n, int isFinal){
dfsplitFinishRow(p);
| > > > > > > > > > | | | | | | 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 |
if( blob_size(&p->aCol[0])>0 ) return;
blob_appendf(p->pOut,"<tr id=\"chunk%d\">"
"<td class=\"diffln difflnl\"><pre>\n", ++nChunk);
p->eState = 0;
}
static void dfsplitSkip(DiffBuilder *p, unsigned int n, int isFinal){
dfsplitFinishRow(p);
if( p->pCfg && p->pCfg->zLeftHash ){
blob_appendf(p->pOut,
"<tr class=\"diffskip\" data-startln=\"%d\" data-endln=\"%d\""
" id=\"skip%xh%xi%x\">\n",
p->lnLeft+1, p->lnLeft+n,
nChunk,p->lnLeft,n);
}else{
blob_append(p->pOut, "<tr>", 4);
}
blob_append(p->pOut,
"<td class=\"diffln difflnl difflne\">︙</td>"
"<td></td><td></td>"
"<td class=\"diffln difflnr difflne\">︙</td>"
"<td/td></tr>\n", -1);
p->lnLeft += n;
p->lnRight += n;
}
static void dfsplitCommon(DiffBuilder *p, const DLine *pLine){
dfsplitStartRow(p);
dfsplitChangeState(p, 0);
p->lnLeft++;
|
| ︙ | ︙ | |||
1578 1579 1580 1581 1582 1583 1584 |
blob_append_char(&p->aCol[3], '\n');
}
static void dfsplitEnd(DiffBuilder *p){
dfsplitFinishRow(p);
blob_append(p->pOut, "</table>\n",-1);
fossil_free(p);
}
| | > > > > > | > > | 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 |
blob_append_char(&p->aCol[3], '\n');
}
static void dfsplitEnd(DiffBuilder *p){
dfsplitFinishRow(p);
blob_append(p->pOut, "</table>\n",-1);
fossil_free(p);
}
static DiffBuilder *dfsplitNew(Blob *pOut, DiffConfig *pCfg){
DiffBuilder *p = fossil_malloc(sizeof(*p));
p->xSkip = dfsplitSkip;
p->xCommon = dfsplitCommon;
p->xInsert = dfsplitInsert;
p->xDelete = dfsplitDelete;
p->xReplace = dfsplitReplace;
p->xEdit = dfsplitEdit;
p->xEnd = dfsplitEnd;
p->lnLeft = p->lnRight = 0;
p->eState = 0;
p->pOut = pOut;
if( pCfg->zLeftHash ){
blob_appendf(pOut,
"<table class=\"diff splitdiff\" data-lefthash=\"%s\">\n",
pCfg->zLeftHash);
}else{
blob_append(pOut, "<table class=\"diff splitdiff\">\n", -1);
}
blob_init(&p->aCol[0], 0, 0);
blob_init(&p->aCol[1], 0, 0);
blob_init(&p->aCol[2], 0, 0);
blob_init(&p->aCol[3], 0, 0);
blob_init(&p->aCol[4], 0, 0);
p->pCfg = pCfg;
return p;
}
/************************* DiffBuilderSbs ******************************/
/* This formatter creates a side-by-side diff in text.
*/
static void dfsbsSkip(DiffBuilder *p, unsigned int n, int isFinal){
|
| ︙ | ︙ | |||
2712 2713 2714 2715 2716 2717 2718 |
blob_append_char(pOut, '\n');
}else if( pCfg->diffFlags & DIFF_TCL ){
DiffBuilder *pBuilder = dftclNew(pOut);
formatDiff(&c, pCfg, pBuilder);
}else if( pCfg->diffFlags & DIFF_SIDEBYSIDE ){
DiffBuilder *pBuilder;
if( pCfg->diffFlags & DIFF_HTML ){
| | | | 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 |
blob_append_char(pOut, '\n');
}else if( pCfg->diffFlags & DIFF_TCL ){
DiffBuilder *pBuilder = dftclNew(pOut);
formatDiff(&c, pCfg, pBuilder);
}else if( pCfg->diffFlags & DIFF_SIDEBYSIDE ){
DiffBuilder *pBuilder;
if( pCfg->diffFlags & DIFF_HTML ){
pBuilder = dfsplitNew(pOut, pCfg);
}else{
pBuilder = dfsbsNew(pOut, pCfg);
}
formatDiff(&c, pCfg, pBuilder);
}else if( pCfg->diffFlags & DIFF_DEBUG ){
DiffBuilder *pBuilder = dfdebugNew(pOut);
formatDiff(&c, pCfg, pBuilder);
}else if( pCfg->diffFlags & DIFF_HTML ){
DiffBuilder *pBuilder = dfunifiedNew(pOut, pCfg);
formatDiff(&c, pCfg, pBuilder);
}else{
contextDiff(&c, pOut, pCfg);
}
fossil_free(c.aFrom);
fossil_free(c.aTo);
fossil_free(c.aEdit);
|
| ︙ | ︙ |
Changes to src/info.c.
| ︙ | ︙ | |||
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 |
){
int fromid;
int toid;
Blob from, to;
if( zFrom ){
fromid = uuid_to_rid(zFrom, 0);
content_get(fromid, &from);
}else{
blob_zero(&from);
}
if( zTo ){
toid = uuid_to_rid(zTo, 0);
content_get(toid, &to);
}else{
blob_zero(&to);
}
if( pCfg->diffFlags & DIFF_SIDEBYSIDE ){
pCfg->diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
}else{
pCfg->diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
}
text_diff(&from, &to, cgi_output_blob(), pCfg);
blob_reset(&from);
blob_reset(&to);
}
/*
** Write a line of web-page output that shows changes that have occurred
** to a file between two check-ins.
| > > > | 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 |
){
int fromid;
int toid;
Blob from, to;
if( zFrom ){
fromid = uuid_to_rid(zFrom, 0);
content_get(fromid, &from);
pCfg->zLeftHash = zFrom;
}else{
blob_zero(&from);
pCfg->zLeftHash = 0;
}
if( zTo ){
toid = uuid_to_rid(zTo, 0);
content_get(toid, &to);
}else{
blob_zero(&to);
}
if( pCfg->diffFlags & DIFF_SIDEBYSIDE ){
pCfg->diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
}else{
pCfg->diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
}
text_diff(&from, &to, cgi_output_blob(), pCfg);
pCfg->zLeftHash = 0;
blob_reset(&from);
blob_reset(&to);
}
/*
** Write a line of web-page output that shows changes that have occurred
** to a file between two check-ins.
|
| ︙ | ︙ |