Fossil SCM

First draft to implement word-wrap for web UI diffs. The list of TODO items can be found on the branch wiki page.

florian 2024-08-17 16:03 trunk
Commit faf4b4718d51d887420f7e5254db4c374968d216f28b93a28d3a8b3369aea13d
+62 -109
--- src/default.css
+++ src/default.css
@@ -557,53 +557,35 @@
557557
table.diff {
558558
width: 100%;
559559
border-spacing: 0;
560560
border-radius: 5px;
561561
border: 1px solid black;
562
- font-size: 80%;
563
-}
564
-table.diff td.diffln{
565
- padding: 0;
566
-}
567
-table.diff td.diffln > pre{
568
- padding: 0 0.25em 0 0.5em;
569
- margin: 0;
570562
}
571563
table.diff td {
572564
vertical-align: top;
565
+ text-align: left;
566
+ margin: 0;
573567
padding: 0;
574
- overflow: hidden /*work around inner PRE slight overflow/overlap*/;
575
-}
576
-table.diff pre {
577
- margin: 0 0 0 0;
578
- padding: 0 0.5em;
579
- line-height: 1.275/*for mobile: forum post e6f4ee7de98b55c0*/;
580
- text-size-adjust: none
581
- /* ^^^ attempt to keep mobile from inflating some text */;
582
-}
583
-table.diff pre > ins,
584
-table.diff pre > del {
585
- /* Fill platform-dependent color gaps caused by
586
- inflated line-height */
587
- padding: 0.062em 0 0.062em 0;
588
-}
589
-table.diff pre > ins > *,
590
-table.diff pre > del > *{
591
- /* Avoid odd-looking color swatches in conjunction with
592
- (table.diff pre > ins/del) padding */
593
- padding: inherit;
594
-}
595
-table.diff td.diffln > pre {
596
- padding: 0 0.35em 0 0.5em;
597
-}
598
-table.diff td > pre {
599
- box-sizing: border-box;
600
- /* Workaround for "slight wiggle" when using mouse-wheel in some FF
601
- versions, apparently caused by the increased line-height forcing
602
- these elements to be a *tick* larger than they should be but not
603
- large enough to force a scroll bar to show up. */
604
- overflow-y: hidden;
568
+ border: 0;
569
+ font-family: monospace;
570
+ line-height: 1.2;
571
+ text-size-adjust: none;
572
+ white-space: pre-wrap;
573
+ word-wrap: break-word;
574
+}
575
+table.diff td.diffln {
576
+ width: 0%;
577
+ text-align: right;
578
+ padding: 0 0.16em 0 0.32em;
579
+}
580
+table.diff td.difflne {
581
+ text-align: left;
582
+ padding: 0 0.32em;
583
+}
584
+table.diff td.diffsep {
585
+ width: 0%;
586
+ padding: 0 0.32em 0 0.16em;
605587
}
606588
tr.diffskip.jchunk {
607589
/* jchunk gets added from JS to diffskip rows when they are
608590
plugged into the /jchunk route. */
609591
background-color: aliceblue;
@@ -623,11 +605,11 @@
623605
tr.diffskip > td.chunkctrl > div {
624606
display: flex;
625607
align-items: center;
626608
}
627609
tr.diffskip > td.chunkctrl > div > span.error {
628
- padding: 0.25em 0.5em;
610
+ padding: 2px;
629611
border-radius: 0.5em;
630612
}
631613
tr.diffskip > td.chunkctrl .jcbutton
632614
/* class name .button breaks w/ some skins! */ {
633615
min-width: 3.5ex;
@@ -668,79 +650,50 @@
668650
tr.diffskip > td.chunkctrl .jcbutton:hover {
669651
cursor: pointer;
670652
opacity: 1;
671653
filter: contrast(1);
672654
}
673
-tr.diffchunk {
674
- display: grid;
675
- gap: 0px 0px;
676
- grid-template-rows: 1fr;
677
-}
678
-table.splitdiff tr.diffchunk {
679
- grid-template-columns: auto 1fr auto auto 1fr;
680
- grid-template-areas: "difflnl difftxtl diffsep difflnr difftxtr";
681
-}
682
-table.udiff tr.diffchunk {
683
- grid-template-columns: auto auto auto 1fr;
684
- grid-template-areas: "difflnl difflnr diffsep difftxtu";
685
-}
686
-td.difflnl { grid-area: difflnl; }
687
-td.difflnr { grid-area: difflnr; }
688
-td.difftxtu { grid-area: difftxtu; }
689
-td.difftxtl { grid-area: difftxtl; }
690
-td.difftxtr { grid-area: difftxtr; }
691
-td.diffln {
692
- width: fit-content;
693
- text-align: right;
694
- padding: 0 1em 0 0;
695
-}
696
-td.difflne {
697
- padding-bottom: 0.4em;
698
-}
699
-td.diffsep {
700
- width: fit-content;
701
- padding: 0 0.3em 0 0.5em;
702
- grid-area: diffsep;
703
-}
704
-td.difftxt pre {
705
- overflow-x: auto;
706
-}
707
-td.diffln ins {
708
- background-color: #a0e4b2;
709
- text-decoration: none;
710
-}
711
-td.diffln del {
712
- background-color: #ffc0c0;
713
- text-decoration: none;
714
-}
715
-td.difftxt del {
716
- background-color: #ffe8e8;
717
- text-decoration: none;
718
-}
719
-td.difftxt del > del {
720
- background-color: #ffc0c0;
721
- text-decoration: none;
722
- font-weight: bold;
723
-}
724
-td.difftxt del > del.edit {
725
- background-color: #c0c0ff;
726
- text-decoration: none;
727
- font-weight: bold;
728
-}
729
-td.difftxt ins {
730
- background-color: #dafbe1;
731
- text-decoration: none;
732
-}
733
-td.difftxt ins > ins {
734
- background-color: #a0e4b2;
735
- text-decoration: none;
736
- font-weight: bold;
737
-}
738
-td.difftxt ins > ins.edit {
739
- background-color: #c0c0ff;
740
- text-decoration: none;
741
- font-weight: bold;
655
+td.difftxt {
656
+ max-width: 0;
657
+}
658
+td.difftxtu {
659
+ width: 100%;
660
+}
661
+td.difftxtl,
662
+td.difftxtr {
663
+ width: 50%;
664
+}
665
+td.diffln.nul,
666
+td.diffsep.nul,
667
+td.difftxt.nul {
668
+ background-color: #f9f9f9;
669
+}
670
+td.diffln.del,
671
+td.diffsep.del,
672
+td.difftxt.del {
673
+ background-color: #ffe8e8;
674
+}
675
+td.diffln.ins,
676
+td.diffsep.ins,
677
+td.difftxt.ins {
678
+ background-color: #dafbe1;
679
+}
680
+td.difftxt.del del {
681
+ background-color: #ffc0c0;
682
+ text-decoration: none;
683
+ display: inline-block;
684
+}
685
+td.difftxt.del del.edit {
686
+ background-color: #c0c0ff;
687
+}
688
+td.difftxt.ins ins {
689
+ background-color: #a0e4b2;
690
+ text-decoration: none;
691
+ display: inline-block;
692
+}
693
+td.difftxt.ins ins.edit {
694
+ background-color: #c0c0ff;
742695
}
743696
body.tkt div.content li > table.udiff {
744697
margin-left: 1.5em;
745698
margin-top: 0.5em;
746699
}
747700
--- src/default.css
+++ src/default.css
@@ -557,53 +557,35 @@
557 table.diff {
558 width: 100%;
559 border-spacing: 0;
560 border-radius: 5px;
561 border: 1px solid black;
562 font-size: 80%;
563 }
564 table.diff td.diffln{
565 padding: 0;
566 }
567 table.diff td.diffln > pre{
568 padding: 0 0.25em 0 0.5em;
569 margin: 0;
570 }
571 table.diff td {
572 vertical-align: top;
 
 
573 padding: 0;
574 overflow: hidden /*work around inner PRE slight overflow/overlap*/;
575 }
576 table.diff pre {
577 margin: 0 0 0 0;
578 padding: 0 0.5em;
579 line-height: 1.275/*for mobile: forum post e6f4ee7de98b55c0*/;
580 text-size-adjust: none
581 /* ^^^ attempt to keep mobile from inflating some text */;
582 }
583 table.diff pre > ins,
584 table.diff pre > del {
585 /* Fill platform-dependent color gaps caused by
586 inflated line-height */
587 padding: 0.062em 0 0.062em 0;
588 }
589 table.diff pre > ins > *,
590 table.diff pre > del > *{
591 /* Avoid odd-looking color swatches in conjunction with
592 (table.diff pre > ins/del) padding */
593 padding: inherit;
594 }
595 table.diff td.diffln > pre {
596 padding: 0 0.35em 0 0.5em;
597 }
598 table.diff td > pre {
599 box-sizing: border-box;
600 /* Workaround for "slight wiggle" when using mouse-wheel in some FF
601 versions, apparently caused by the increased line-height forcing
602 these elements to be a *tick* larger than they should be but not
603 large enough to force a scroll bar to show up. */
604 overflow-y: hidden;
605 }
606 tr.diffskip.jchunk {
607 /* jchunk gets added from JS to diffskip rows when they are
608 plugged into the /jchunk route. */
609 background-color: aliceblue;
@@ -623,11 +605,11 @@
623 tr.diffskip > td.chunkctrl > div {
624 display: flex;
625 align-items: center;
626 }
627 tr.diffskip > td.chunkctrl > div > span.error {
628 padding: 0.25em 0.5em;
629 border-radius: 0.5em;
630 }
631 tr.diffskip > td.chunkctrl .jcbutton
632 /* class name .button breaks w/ some skins! */ {
633 min-width: 3.5ex;
@@ -668,79 +650,50 @@
668 tr.diffskip > td.chunkctrl .jcbutton:hover {
669 cursor: pointer;
670 opacity: 1;
671 filter: contrast(1);
672 }
673 tr.diffchunk {
674 display: grid;
675 gap: 0px 0px;
676 grid-template-rows: 1fr;
677 }
678 table.splitdiff tr.diffchunk {
679 grid-template-columns: auto 1fr auto auto 1fr;
680 grid-template-areas: "difflnl difftxtl diffsep difflnr difftxtr";
681 }
682 table.udiff tr.diffchunk {
683 grid-template-columns: auto auto auto 1fr;
684 grid-template-areas: "difflnl difflnr diffsep difftxtu";
685 }
686 td.difflnl { grid-area: difflnl; }
687 td.difflnr { grid-area: difflnr; }
688 td.difftxtu { grid-area: difftxtu; }
689 td.difftxtl { grid-area: difftxtl; }
690 td.difftxtr { grid-area: difftxtr; }
691 td.diffln {
692 width: fit-content;
693 text-align: right;
694 padding: 0 1em 0 0;
695 }
696 td.difflne {
697 padding-bottom: 0.4em;
698 }
699 td.diffsep {
700 width: fit-content;
701 padding: 0 0.3em 0 0.5em;
702 grid-area: diffsep;
703 }
704 td.difftxt pre {
705 overflow-x: auto;
706 }
707 td.diffln ins {
708 background-color: #a0e4b2;
709 text-decoration: none;
710 }
711 td.diffln del {
712 background-color: #ffc0c0;
713 text-decoration: none;
714 }
715 td.difftxt del {
716 background-color: #ffe8e8;
717 text-decoration: none;
718 }
719 td.difftxt del > del {
720 background-color: #ffc0c0;
721 text-decoration: none;
722 font-weight: bold;
723 }
724 td.difftxt del > del.edit {
725 background-color: #c0c0ff;
726 text-decoration: none;
727 font-weight: bold;
728 }
729 td.difftxt ins {
730 background-color: #dafbe1;
731 text-decoration: none;
732 }
733 td.difftxt ins > ins {
734 background-color: #a0e4b2;
735 text-decoration: none;
736 font-weight: bold;
737 }
738 td.difftxt ins > ins.edit {
739 background-color: #c0c0ff;
740 text-decoration: none;
741 font-weight: bold;
742 }
743 body.tkt div.content li > table.udiff {
744 margin-left: 1.5em;
745 margin-top: 0.5em;
746 }
747
--- src/default.css
+++ src/default.css
@@ -557,53 +557,35 @@
557 table.diff {
558 width: 100%;
559 border-spacing: 0;
560 border-radius: 5px;
561 border: 1px solid black;
 
 
 
 
 
 
 
 
562 }
563 table.diff td {
564 vertical-align: top;
565 text-align: left;
566 margin: 0;
567 padding: 0;
568 border: 0;
569 font-family: monospace;
570 line-height: 1.2;
571 text-size-adjust: none;
572 white-space: pre-wrap;
573 word-wrap: break-word;
574 }
575 table.diff td.diffln {
576 width: 0%;
577 text-align: right;
578 padding: 0 0.16em 0 0.32em;
579 }
580 table.diff td.difflne {
581 text-align: left;
582 padding: 0 0.32em;
583 }
584 table.diff td.diffsep {
585 width: 0%;
586 padding: 0 0.32em 0 0.16em;
 
 
 
 
 
 
 
 
 
 
 
 
587 }
588 tr.diffskip.jchunk {
589 /* jchunk gets added from JS to diffskip rows when they are
590 plugged into the /jchunk route. */
591 background-color: aliceblue;
@@ -623,11 +605,11 @@
605 tr.diffskip > td.chunkctrl > div {
606 display: flex;
607 align-items: center;
608 }
609 tr.diffskip > td.chunkctrl > div > span.error {
610 padding: 2px;
611 border-radius: 0.5em;
612 }
613 tr.diffskip > td.chunkctrl .jcbutton
614 /* class name .button breaks w/ some skins! */ {
615 min-width: 3.5ex;
@@ -668,79 +650,50 @@
650 tr.diffskip > td.chunkctrl .jcbutton:hover {
651 cursor: pointer;
652 opacity: 1;
653 filter: contrast(1);
654 }
655 td.difftxt {
656 max-width: 0;
657 }
658 td.difftxtu {
659 width: 100%;
660 }
661 td.difftxtl,
662 td.difftxtr {
663 width: 50%;
664 }
665 td.diffln.nul,
666 td.diffsep.nul,
667 td.difftxt.nul {
668 background-color: #f9f9f9;
669 }
670 td.diffln.del,
671 td.diffsep.del,
672 td.difftxt.del {
673 background-color: #ffe8e8;
674 }
675 td.diffln.ins,
676 td.diffsep.ins,
677 td.difftxt.ins {
678 background-color: #dafbe1;
679 }
680 td.difftxt.del del {
681 background-color: #ffc0c0;
682 text-decoration: none;
683 display: inline-block;
684 }
685 td.difftxt.del del.edit {
686 background-color: #c0c0ff;
687 }
688 td.difftxt.ins ins {
689 background-color: #a0e4b2;
690 text-decoration: none;
691 display: inline-block;
692 }
693 td.difftxt.ins ins.edit {
694 background-color: #c0c0ff;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
695 }
696 body.tkt div.content li > table.udiff {
697 margin-left: 1.5em;
698 margin-top: 0.5em;
699 }
700
+156 -271
--- src/diff.c
+++ src/diff.c
@@ -928,15 +928,14 @@
928928
void (*xReplace)(DiffBuilder*,const DLine*,const DLine*);
929929
void (*xEdit)(DiffBuilder*,const DLine*,const DLine*);
930930
void (*xEnd)(DiffBuilder*);
931931
unsigned int lnLeft; /* Lines seen on the left (delete) side */
932932
unsigned int lnRight; /* Lines seen on the right (insert) side */
933
- unsigned int nPending; /* Number of pending lines */
934933
int eState; /* State of the output */
935934
int width; /* Display width */
936935
Blob *pOut; /* Output blob */
937
- Blob aCol[5]; /* Holding blobs */
936
+ Blob bBuf2; /* Storage to hold retained lines */
938937
DiffConfig *pCfg; /* Configuration information */
939938
};
940939
941940
/************************* DiffBuilderDebug ********************************/
942941
/* This version of DiffBuilder is used for debugging the diff and diff
@@ -1220,209 +1219,162 @@
12201219
**
12211220
** The result is a <table> with four columns. The four columns hold:
12221221
**
12231222
** 1. The line numbers for the first file.
12241223
** 2. The line numbers for the second file.
1225
-** 3. The "diff mark": "+" or "-" or just a space
1226
-** 4. Text of the line
1224
+** 3. The "diff mark": "+", "-" or blank.
1225
+** 4. Text of the line.
12271226
**
1228
-** Inserted lines are marked with <ins> and deleted lines are marked
1229
-** with <del>. The whole line is marked this way, not just the part that
1230
-** changed. The part that change has an additional nested <ins> or <del>.
1231
-** The CSS needs to be set up such that a single <ins> or <del> gives a
1232
-** light background and a nested <ins> or <del> gives a darker background.
1233
-** Additional attributes (like bold font) might also be added to nested
1234
-** <ins> and <del> since those are the characters that have actually
1235
-** changed.
1227
+** The table cells holding the inserted and deleted lines are assigned to CSS
1228
+** classes .nul, .ins or .del to color them accordingly. The changed parts of
1229
+** each line have additional <ins> or <del> elements. The CSS needs to be set
1230
+** up such that the <ins> or <del> intensify the background color of the .ins
1231
+** and .del CSS classes.
12361232
**
12371233
** Accumulator strategy:
12381234
**
1239
-** * Delete line numbers are output directly to p->pOut
1240
-** * Insert line numbers accumulate in p->aCol[0].
1241
-** * Separator marks accumulate in p->aCol[1].
1242
-** * Change text accumulates in p->aCol[2].
1243
-** * Pending insert line numbers go into p->aCol[3].
1244
-** * Pending insert text goes into p->aCol[4].
1235
+** * Retained insert text goes to p->bBuf2
1236
+** * Anything else goes directly to p->pOut
12451237
**
1246
-** eState is 1 if text has an open <del>
1238
+** eState is 1 if the last line was a deletion.
12471239
*/
12481240
static void dfunifiedFinishDelete(DiffBuilder *p){
12491241
if( p->eState==0 ) return;
1250
- blob_append(p->pOut, "</del>", 6);
1251
- blob_append(&p->aCol[2], "</del>", 6);
12521242
p->eState = 0;
12531243
}
12541244
static void dfunifiedFinishInsert(DiffBuilder *p){
1255
- unsigned int i;
1256
- if( p->nPending==0 ) return;
1245
+ if( blob_size(&p->bBuf2)==0 ) return;
12571246
dfunifiedFinishDelete(p);
1258
-
1259
- /* Blank lines for delete line numbers for each inserted line */
1260
- for(i=0; i<p->nPending; i++) blob_append_char(p->pOut, '\n');
1261
-
1262
- /* Insert line numbers */
1263
- blob_append(&p->aCol[0], "<ins>", 5);
1264
- blob_append_xfer(&p->aCol[0], &p->aCol[3]);
1265
- blob_append(&p->aCol[0], "</ins>", 6);
1266
-
1267
- /* "+" marks for the separator on inserted lines */
1268
- for(i=0; i<p->nPending; i++) blob_append(&p->aCol[1], "+\n", 2);
1269
-
1270
- /* Text of the inserted lines */
1271
- blob_append(&p->aCol[2], "<ins>", 5);
1272
- blob_append_xfer(&p->aCol[2], &p->aCol[4]);
1273
- blob_append(&p->aCol[2], "</ins>", 6);
1274
-
1275
- p->nPending = 0;
1247
+ blob_append_xfer(p->pOut,&p->bBuf2);
12761248
}
12771249
static void dfunifiedFinishRow(DiffBuilder *p){
12781250
dfunifiedFinishDelete(p);
12791251
dfunifiedFinishInsert(p);
1280
- if( blob_size(&p->aCol[0])==0 ) return;
1281
- blob_append(p->pOut, "</pre></td><td class=\"diffln difflnr\"><pre>\n", -1);
1282
- blob_append_xfer(p->pOut, &p->aCol[0]);
1283
- blob_append(p->pOut, "</pre></td><td class=\"diffsep\"><pre>\n", -1);
1284
- blob_append_xfer(p->pOut, &p->aCol[1]);
1285
- blob_append(p->pOut, "</pre></td><td class=\"difftxt difftxtu\"><pre>\n",-1);
1286
- blob_append_xfer(p->pOut, &p->aCol[2]);
1287
- blob_append(p->pOut, "</pre></td></tr>\n", -1);
12881252
}
12891253
static void dfunifiedStartRow(DiffBuilder *p){
1290
- if( blob_size(&p->aCol[0])>0 ) return;
1291
- blob_appendf(p->pOut,"<tr id=\"chunk%d\" class=\"diffchunk\">"
1292
- "<td class=\"diffln difflnl\"><pre>\n", ++nChunk);
12931254
}
12941255
static void dfunifiedSkip(DiffBuilder *p, unsigned int n, int isFinal){
12951256
dfunifiedFinishRow(p);
12961257
if( p->pCfg && p->pCfg->zLeftHash ){
12971258
blob_appendf(p->pOut,
12981259
"<tr class=\"diffskip\" data-startln=\"%d\" data-endln=\"%d\""
12991260
" id=\"skip%xh%xi%x\">\n",
1300
- p->lnLeft+1, p->lnLeft+n,
1301
- nChunk, p->lnLeft, n);
1261
+ p->lnLeft+1, p->lnLeft+n, nChunk, p->lnLeft, n);
13021262
}else{
13031263
blob_append(p->pOut, "<tr>", 4);
13041264
}
1305
- blob_append(p->pOut, "<td class=\"diffln difflne\">"
1306
- "&#xfe19;</td><td></td><td></td></tr>\n", -1);
1265
+ blob_append(p->pOut, "<td class=\"diffln difflne\" colspan=\"4\">"
1266
+ "&#xfe19;</td></tr>\n", -1);
13071267
p->lnLeft += n;
13081268
p->lnRight += n;
13091269
}
13101270
static void dfunifiedCommon(DiffBuilder *p, const DLine *pLine){
13111271
dfunifiedStartRow(p);
13121272
dfunifiedFinishDelete(p);
13131273
dfunifiedFinishInsert(p);
13141274
p->lnLeft++;
13151275
p->lnRight++;
1316
- blob_appendf(p->pOut,"%d\n", p->lnLeft);
1317
- blob_appendf(&p->aCol[0],"%d\n",p->lnRight);
1318
- blob_append_char(&p->aCol[1], '\n');
1319
- htmlize_to_blob(&p->aCol[2], pLine->z, (int)pLine->n);
1320
- blob_append_char(&p->aCol[2], '\n');
1276
+ blob_append (p->pOut, "<tr class=\"diffline\">", 21);
1277
+ blob_appendf(p->pOut, "<td class=\"diffln difflnl\">%d</td>", p->lnLeft);
1278
+ blob_appendf(p->pOut, "<td class=\"diffln difflnr\">%d</td>", p->lnRight);
1279
+ blob_append (p->pOut, "<td class=\"diffsep\"></td>", 25);
1280
+ blob_append (p->pOut, "<td class=\"difftxt difftxtu\">", 29);
1281
+ htmlize_to_blob(p->pOut, pLine->z, (int)pLine->n);
1282
+ blob_append (p->pOut, "</td>", 5);
1283
+ blob_append (p->pOut, "</tr>\n", 6);
13211284
}
13221285
static void dfunifiedInsert(DiffBuilder *p, const DLine *pLine){
13231286
dfunifiedStartRow(p);
13241287
p->lnRight++;
1325
- blob_appendf(&p->aCol[3],"%d\n", p->lnRight);
1326
- blob_append(&p->aCol[4], "<ins>", 5);
1327
- htmlize_to_blob(&p->aCol[4], pLine->z, (int)pLine->n);
1328
- blob_append(&p->aCol[4], "</ins>\n", 7);
1329
- p->nPending++;
1288
+ blob_append (&p->bBuf2, "<tr class=\"diffline\">", 21);
1289
+ blob_append (&p->bBuf2, "<td class=\"diffln difflnl ins\"></td>", 36);
1290
+ blob_appendf(&p->bBuf2, "<td class=\"diffln difflnr ins\">%d</td>",
1291
+ p->lnRight);
1292
+ blob_append (&p->bBuf2, "<td class=\"diffsep ins\">+</td>", 30);
1293
+ blob_append (&p->bBuf2, "<td class=\"difftxt difftxtu ins\"><ins>", 38);
1294
+ htmlize_to_blob(&p->bBuf2, pLine->z, (int)pLine->n);
1295
+ blob_append (&p->bBuf2, "</ins></td>", 11);
1296
+ blob_append (&p->bBuf2, "</tr>\n", 6);
13301297
}
13311298
static void dfunifiedDelete(DiffBuilder *p, const DLine *pLine){
13321299
dfunifiedStartRow(p);
13331300
dfunifiedFinishInsert(p);
13341301
if( p->eState==0 ){
13351302
dfunifiedFinishInsert(p);
1336
- blob_append(p->pOut, "<del>", 5);
1337
- blob_append(&p->aCol[2], "<del>", 5);
1338
- p->eState = 1;
1339
- }
1340
- p->lnLeft++;
1341
- blob_appendf(p->pOut,"%d\n", p->lnLeft);
1342
- blob_append_char(&p->aCol[0],'\n');
1343
- blob_append(&p->aCol[1],"-\n",2);
1344
- blob_append(&p->aCol[2], "<del>", 5);
1345
- htmlize_to_blob(&p->aCol[2], pLine->z, (int)pLine->n);
1346
- blob_append(&p->aCol[2], "</del>\n", 7);
1347
-}
1348
-static void dfunifiedReplace(DiffBuilder *p, const DLine *pX, const DLine *pY){
1349
- dfunifiedStartRow(p);
1350
- if( p->eState==0 ){
1351
- dfunifiedFinishInsert(p);
1352
- blob_append(p->pOut, "<del>", 5);
1353
- blob_append(&p->aCol[2], "<del>", 5);
1354
- p->eState = 1;
1355
- }
1356
- p->lnLeft++;
1357
- p->lnRight++;
1358
- blob_appendf(p->pOut,"%d\n", p->lnLeft);
1359
- blob_append_char(&p->aCol[0], '\n');
1360
- blob_append(&p->aCol[1], "-\n", 2);
1361
-
1362
- htmlize_to_blob(&p->aCol[2], pX->z, pX->n);
1363
- blob_append_char(&p->aCol[2], '\n');
1364
-
1365
- blob_appendf(&p->aCol[3],"%d\n", p->lnRight);
1366
-
1367
- htmlize_to_blob(&p->aCol[4], pY->z, pY->n);
1368
- blob_append_char(&p->aCol[4], '\n');
1369
- p->nPending++;
1303
+ p->eState = 1;
1304
+ }
1305
+ p->lnLeft++;
1306
+ blob_append (p->pOut, "<tr class=\"diffline\">", 21);
1307
+ blob_appendf(p->pOut, "<td class=\"diffln difflnl del\">%d</td>", p->lnLeft);
1308
+ blob_append (p->pOut, "<td class=\"diffln difflnr del\"></td>", 36);
1309
+ blob_append (p->pOut, "<td class=\"diffsep del\">-</td>", 30);
1310
+ blob_append (p->pOut, "<td class=\"difftxt difftxtu del\"><del>", 38);
1311
+ htmlize_to_blob(p->pOut, pLine->z, (int)pLine->n);
1312
+ blob_append (p->pOut, "</del></td>", 11);
1313
+ blob_append (p->pOut, "</tr>\n", 6);
1314
+}
1315
+static void dfunifiedReplace(DiffBuilder *p, const DLine *pX, const DLine *pY){
1316
+ assert( 0 && "The seemingly unused function dfunifiedReplace() was called!");
13701317
}
13711318
static void dfunifiedEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
13721319
int i;
13731320
int x;
13741321
LineChange chng;
13751322
oneLineChange(pX, pY, &chng);
13761323
dfunifiedStartRow(p);
13771324
if( p->eState==0 ){
13781325
dfunifiedFinishInsert(p);
1379
- blob_append(p->pOut, "<del>", 5);
1380
- blob_append(&p->aCol[2], "<del>", 5);
13811326
p->eState = 1;
13821327
}
13831328
p->lnLeft++;
13841329
p->lnRight++;
1385
- blob_appendf(p->pOut,"%d\n", p->lnLeft);
1386
- blob_append_char(&p->aCol[0], '\n');
1387
- blob_append(&p->aCol[1], "-\n", 2);
1388
-
1389
- for(i=x=0; i<chng.n; i++){
1330
+ blob_append (p->pOut, "<tr class=\"diffline\">", 21);
1331
+ blob_appendf(p->pOut, "<td class=\"diffln difflnl del\">%d</td>", p->lnLeft);
1332
+ blob_append (p->pOut, "<td class=\"diffln difflnr del\"></td>", 36);
1333
+ blob_append (p->pOut, "<td class=\"diffsep del\">-</td>", 30);
1334
+ blob_append (p->pOut, "<td class=\"difftxt difftxtu del\">", 33);
1335
+ for( i=x=0; i<chng.n; i++ ){
13901336
int ofst = chng.a[i].iStart1;
13911337
int len = chng.a[i].iLen1;
13921338
if( len ){
1393
- htmlize_to_blob(&p->aCol[2], pX->z+x, ofst - x);
1339
+ htmlize_to_blob(p->pOut, pX->z+x, ofst - x);
13941340
x = ofst;
1395
- blob_append(&p->aCol[2], "<del>", 5);
1396
- htmlize_to_blob(&p->aCol[2], pX->z+x, len);
1341
+ blob_append(p->pOut, "<del>", 5);
1342
+ htmlize_to_blob(p->pOut, pX->z+x, len);
13971343
x += len;
1398
- blob_append(&p->aCol[2], "</del>", 6);
1344
+ blob_append(p->pOut, "</del>", 6);
13991345
}
14001346
}
1401
- htmlize_to_blob(&p->aCol[2], pX->z+x, pX->n - x);
1402
- blob_append_char(&p->aCol[2], '\n');
1403
-
1404
- blob_appendf(&p->aCol[3],"%d\n", p->lnRight);
1405
- for(i=x=0; i<chng.n; i++){
1347
+ htmlize_to_blob(p->pOut, pX->z+x, pX->n - x);
1348
+ blob_append (p->pOut, "</td>", 5);
1349
+ blob_append (p->pOut, "</tr>\n", 6);
1350
+ blob_append (&p->bBuf2, "<tr class=\"diffline\">", 21);
1351
+ blob_append (&p->bBuf2, "<td class=\"diffln difflnl ins\"></td>", 36);
1352
+ blob_appendf(&p->bBuf2, "<td class=\"diffln difflnr ins\">%d</td>",
1353
+ p->lnRight);
1354
+ blob_append (&p->bBuf2, "<td class=\"diffsep ins\">+</td>", 30);
1355
+ blob_append (&p->bBuf2, "<td class=\"difftxt difftxtu ins\">", 33);
1356
+ for( i=x=0; i<chng.n; i++ ){
14061357
int ofst = chng.a[i].iStart2;
14071358
int len = chng.a[i].iLen2;
14081359
if( len ){
1409
- htmlize_to_blob(&p->aCol[4], pY->z+x, ofst - x);
1360
+ htmlize_to_blob(&p->bBuf2, pY->z+x, ofst - x);
14101361
x = ofst;
1411
- blob_append(&p->aCol[4], "<ins>", 5);
1412
- htmlize_to_blob(&p->aCol[4], pY->z+x, len);
1362
+ blob_append(&p->bBuf2, "<ins>", 5);
1363
+ htmlize_to_blob(&p->bBuf2, pY->z+x, len);
14131364
x += len;
1414
- blob_append(&p->aCol[4], "</ins>", 6);
1365
+ blob_append(&p->bBuf2, "</ins>", 6);
14151366
}
14161367
}
1417
- htmlize_to_blob(&p->aCol[4], pY->z+x, pY->n - x);
1418
- blob_append_char(&p->aCol[4], '\n');
1419
- p->nPending++;
1368
+ htmlize_to_blob(&p->bBuf2, pY->z+x, pY->n - x);
1369
+ blob_append (&p->bBuf2, "</td>", 5);
1370
+ blob_append (&p->bBuf2, "</tr>\n", 6);
14201371
}
14211372
static void dfunifiedEnd(DiffBuilder *p){
14221373
dfunifiedFinishRow(p);
1423
- blob_append(p->pOut, "</table>\n",-1);
1374
+ blob_append(p->pOut, "</table>\n", 9);
1375
+ blob_reset(&p->bBuf2);
14241376
fossil_free(p);
14251377
}
14261378
static DiffBuilder *dfunifiedNew(Blob *pOut, DiffConfig *pCfg){
14271379
DiffBuilder *p = fossil_malloc(sizeof(*p));
14281380
p->xSkip = dfunifiedSkip;
@@ -1432,220 +1384,158 @@
14321384
p->xReplace = dfunifiedReplace;
14331385
p->xEdit = dfunifiedEdit;
14341386
p->xEnd = dfunifiedEnd;
14351387
p->lnLeft = p->lnRight = 0;
14361388
p->eState = 0;
1437
- p->nPending = 0;
14381389
p->pOut = pOut;
14391390
if( pCfg->zLeftHash ){
14401391
blob_appendf(pOut, "<table class=\"diff udiff\" data-lefthash=\"%s\">\n",
1441
- pCfg->zLeftHash);
1392
+ pCfg->zLeftHash);
14421393
}else{
1443
- blob_append(pOut, "<table class=\"diff udiff\">\n", -1);
1394
+ blob_append(pOut, "<table class=\"diff udiff\">\n", 27);
14441395
}
1445
- blob_init(&p->aCol[0], 0, 0);
1446
- blob_init(&p->aCol[1], 0, 0);
1447
- blob_init(&p->aCol[2], 0, 0);
1448
- blob_init(&p->aCol[3], 0, 0);
1449
- blob_init(&p->aCol[4], 0, 0);
1396
+ blob_init(&p->bBuf2, 0, 0);
14501397
p->pCfg = pCfg;
14511398
return p;
14521399
}
14531400
14541401
/************************* DiffBuilderSplit ******************************/
14551402
/* This formatter creates a side-by-side diff in HTML. The output is a
1456
-** <table> with 5 columns:
1457
-**
1458
-** 1. Line numbers for the first file.
1459
-** 2. Text for the first file.
1460
-** 3. The difference mark. "<", ">", "|" or blank
1461
-** 4. Line numbers for the second file.
1462
-** 5. Text for the second file.
1463
-**
1464
-** The <ins> and <del> strategy is the same as for unified diff above.
1465
-** In fact, the same CSS can be used for both.
1403
+** <table> with 6 columns:
1404
+**
1405
+** 1. Line numbers for the first file.
1406
+** 2. First difference mark: "+", "-" or blank.
1407
+** 3. Text for the first file.
1408
+** 4. Line numbers for the second file.
1409
+** 5. Second difference mark: "+", "-" or blank.
1410
+** 6. Text for the second file.
1411
+**
1412
+** The styling approach with .nul, .ins and .del CSS classes and <ins> and
1413
+** <del> elements is the same as for the unified diffs above. In fact, the
1414
+** same CSS can be used for both.
14661415
**
14671416
** Accumulator strategy:
14681417
**
1469
-** * Left line numbers are output directly to p->pOut
1470
-** * Left text accumulates in p->aCol[0].
1471
-** * Edit marks accumulates in p->aCol[1].
1472
-** * Right line numbers accumulate in p->aCol[2].
1473
-** * Right text accumulates in p->aCol[3].
1418
+** * All output goes directly to p->pOut
14741419
**
1475
-** eState:
1476
-** 0 In common block
1477
-** 1 Have <del> on the left
1478
-** 2 Have <ins> on the right
1479
-** 3 Have <del> on left and <ins> on the right
1420
+** eState is not unused.
14801421
*/
1481
-static void dfsplitChangeState(DiffBuilder *p, int newState){
1482
- if( p->eState == newState ) return;
1483
- if( (p->eState&1)==0 && (newState & 1)!=0 ){
1484
- blob_append(p->pOut, "<del>", 5);
1485
- blob_append(&p->aCol[0], "<del>", 5);
1486
- p->eState |= 1;
1487
- }else if( (p->eState&1)!=0 && (newState & 1)==0 ){
1488
- blob_append(p->pOut, "</del>", 6);
1489
- blob_append(&p->aCol[0], "</del>", 6);
1490
- p->eState &= ~1;
1491
- }
1492
- if( (p->eState&2)==0 && (newState & 2)!=0 ){
1493
- blob_append(&p->aCol[2], "<ins>", 5);
1494
- blob_append(&p->aCol[3], "<ins>", 5);
1495
- p->eState |= 2;
1496
- }else if( (p->eState&2)!=0 && (newState & 2)==0 ){
1497
- blob_append(&p->aCol[2], "</ins>", 6);
1498
- blob_append(&p->aCol[3], "</ins>", 6);
1499
- p->eState &= ~2;
1500
- }
1501
-}
1502
-static void dfsplitFinishRow(DiffBuilder *p){
1503
- if( blob_size(&p->aCol[0])==0 ) return;
1504
- dfsplitChangeState(p, 0);
1505
- blob_append(p->pOut, "</pre></td><td class=\"difftxt difftxtl\"><pre>\n",-1);
1506
- blob_append_xfer(p->pOut, &p->aCol[0]);
1507
- blob_append(p->pOut, "</pre></td><td class=\"diffsep\"><pre>\n", -1);
1508
- blob_append_xfer(p->pOut, &p->aCol[1]);
1509
- blob_append(p->pOut, "</pre></td><td class=\"diffln difflnr\"><pre>\n",-1);
1510
- blob_append_xfer(p->pOut, &p->aCol[2]);
1511
- blob_append(p->pOut, "</pre></td><td class=\"difftxt difftxtr\"><pre>\n",-1);
1512
- blob_append_xfer(p->pOut, &p->aCol[3]);
1513
- blob_append(p->pOut, "</pre></td></tr>\n", -1);
1514
-}
1515
-static void dfsplitStartRow(DiffBuilder *p){
1516
- if( blob_size(&p->aCol[0])>0 ) return;
1517
- blob_appendf(p->pOut,"<tr id=\"chunk%d\" class=\"diffchunk\">"
1518
- "<td class=\"diffln difflnl\"><pre>\n", ++nChunk);
1519
- p->eState = 0;
1520
-}
15211422
static void dfsplitSkip(DiffBuilder *p, unsigned int n, int isFinal){
1522
- dfsplitFinishRow(p);
15231423
if( p->pCfg && p->pCfg->zLeftHash ){
15241424
blob_appendf(p->pOut,
15251425
"<tr class=\"diffskip\" data-startln=\"%d\" data-endln=\"%d\""
15261426
" id=\"skip%xh%xi%x\">\n",
1527
- p->lnLeft+1, p->lnLeft+n,
1528
- nChunk,p->lnLeft,n);
1427
+ p->lnLeft+1, p->lnLeft+n, nChunk, p->lnLeft, n);
15291428
}else{
15301429
blob_append(p->pOut, "<tr>", 4);
15311430
}
15321431
blob_append(p->pOut,
1533
- "<td class=\"diffln difflnl difflne\">&#xfe19;</td>"
1534
- "<td></td><td></td>"
1535
- "<td class=\"diffln difflnr difflne\">&#xfe19;</td>"
1536
- "<td/td></tr>\n", -1);
1432
+ "<td class=\"diffln difflnl difflne\" colspan=\"3\">&#xfe19;</td>"
1433
+ "<td class=\"diffln difflnr difflne\" colspan=\"3\">&#xfe19;</td>"
1434
+ "</tr>\n", -1);
15371435
p->lnLeft += n;
15381436
p->lnRight += n;
15391437
}
15401438
static void dfsplitCommon(DiffBuilder *p, const DLine *pLine){
1541
- dfsplitStartRow(p);
1542
- dfsplitChangeState(p, 0);
15431439
p->lnLeft++;
15441440
p->lnRight++;
1545
- blob_appendf(p->pOut,"%d\n", p->lnLeft);
1546
- htmlize_to_blob(&p->aCol[0], pLine->z, (int)pLine->n);
1547
- blob_append_char(&p->aCol[0], '\n');
1548
- blob_append_char(&p->aCol[1], '\n');
1549
- blob_appendf(&p->aCol[2],"%d\n",p->lnRight);
1550
- htmlize_to_blob(&p->aCol[3], pLine->z, (int)pLine->n);
1551
- blob_append_char(&p->aCol[3], '\n');
1441
+ blob_append (p->pOut, "<tr class=\"diffline\">", 21);
1442
+ blob_appendf(p->pOut, "<td class=\"diffln difflnl\">%d</td>", p->lnLeft);
1443
+ blob_append (p->pOut, "<td class=\"diffsep\"></td>", 25);
1444
+ blob_append (p->pOut, "<td class=\"difftxt difftxtl\">", 29);
1445
+ htmlize_to_blob(p->pOut, pLine->z, (int)pLine->n);
1446
+ blob_append (p->pOut, "</td>", 5);
1447
+ blob_appendf(p->pOut, "<td class=\"diffln difflnr\">%d</td>", p->lnRight);
1448
+ blob_append (p->pOut, "<td class=\"diffsep\"></td>", 25);
1449
+ blob_append (p->pOut, "<td class=\"difftxt difftxtr\">", 29);
1450
+ htmlize_to_blob(p->pOut, pLine->z, (int)pLine->n);
1451
+ blob_append (p->pOut, "</td>", 5);
1452
+ blob_append (p->pOut, "</tr>\n", 6);
15521453
}
15531454
static void dfsplitInsert(DiffBuilder *p, const DLine *pLine){
1554
- dfsplitStartRow(p);
1555
- dfsplitChangeState(p, 2);
15561455
p->lnRight++;
1557
- blob_append_char(p->pOut, '\n');
1558
- blob_append_char(&p->aCol[0], '\n');
1559
- blob_append(&p->aCol[1], "&gt;\n", -1);
1560
- blob_appendf(&p->aCol[2],"%d\n", p->lnRight);
1561
- blob_append(&p->aCol[3], "<ins>", 5);
1562
- htmlize_to_blob(&p->aCol[3], pLine->z, (int)pLine->n);
1563
- blob_append(&p->aCol[3], "</ins>\n", 7);
1456
+ blob_append (p->pOut, "<tr class=\"diffline\">", 21);
1457
+ blob_append (p->pOut, "<td class=\"diffln difflnl nul\"></td>", 36);
1458
+ blob_append (p->pOut, "<td class=\"diffsep nul\"></td>", 29);
1459
+ blob_append (p->pOut, "<td class=\"difftxt difftxtl nul\"></td>", 38);
1460
+ blob_appendf(p->pOut, "<td class=\"diffln difflnr ins\">%d</td>", p->lnRight);
1461
+ blob_append (p->pOut, "<td class=\"diffsep ins\">+</td>", 30);
1462
+ blob_append (p->pOut, "<td class=\"difftxt difftxtr ins\"><ins>", 38);
1463
+ htmlize_to_blob(p->pOut, pLine->z, (int)pLine->n);
1464
+ blob_append (p->pOut, "</ins></td>", 11);
1465
+ blob_append (p->pOut, "</tr>\n", 6);
15641466
}
15651467
static void dfsplitDelete(DiffBuilder *p, const DLine *pLine){
1566
- dfsplitStartRow(p);
1567
- dfsplitChangeState(p, 1);
15681468
p->lnLeft++;
1569
- blob_appendf(p->pOut,"%d\n", p->lnLeft);
1570
- blob_append(&p->aCol[0], "<del>", 5);
1571
- htmlize_to_blob(&p->aCol[0], pLine->z, (int)pLine->n);
1572
- blob_append(&p->aCol[0], "</del>\n", 7);
1573
- blob_append(&p->aCol[1], "&lt;\n", -1);
1574
- blob_append_char(&p->aCol[2],'\n');
1575
- blob_append_char(&p->aCol[3],'\n');
1469
+ blob_append (p->pOut, "<tr class=\"diffline\">", 21);
1470
+ blob_appendf(p->pOut, "<td class=\"diffln difflnl del\">%d</td>", p->lnLeft);
1471
+ blob_append (p->pOut, "<td class=\"diffsep del\">-</td>", 30);
1472
+ blob_append (p->pOut, "<td class=\"difftxt difftxtl del\"><del>", 38);
1473
+ htmlize_to_blob(p->pOut, pLine->z, (int)pLine->n);
1474
+ blob_append (p->pOut, "</del></td>", 11);
1475
+ blob_append (p->pOut, "<td class=\"diffln difflnr nul\"></td>", 36);
1476
+ blob_append (p->pOut, "<td class=\"diffsep nul\"></td>", 29);
1477
+ blob_append (p->pOut, "<td class=\"difftxt difftxtr nul\"></td>", 38);
1478
+ blob_append (p->pOut, "</tr>\n", 6);
15761479
}
15771480
static void dfsplitReplace(DiffBuilder *p, const DLine *pX, const DLine *pY){
1578
- dfsplitStartRow(p);
1579
- dfsplitChangeState(p, 3);
1580
- p->lnLeft++;
1581
- p->lnRight++;
1582
- blob_appendf(p->pOut,"%d\n", p->lnLeft);
1583
- htmlize_to_blob(&p->aCol[0], pX->z, pX->n);
1584
- blob_append_char(&p->aCol[0], '\n');
1585
-
1586
- blob_append(&p->aCol[1], "|\n", 2);
1587
-
1588
- blob_appendf(&p->aCol[2],"%d\n", p->lnRight);
1589
-
1590
- htmlize_to_blob(&p->aCol[3], pY->z, pY->n);
1591
- blob_append_char(&p->aCol[3], '\n');
1481
+ assert( 0 && "The seemingly unused function dfsplitReplace() was called!");
15921482
}
15931483
static void dfsplitEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
15941484
int i;
15951485
int x;
15961486
LineChange chng;
15971487
oneLineChange(pX, pY, &chng);
1598
- dfsplitStartRow(p);
1599
- dfsplitChangeState(p, 3);
16001488
p->lnLeft++;
16011489
p->lnRight++;
1602
- blob_appendf(p->pOut,"%d\n", p->lnLeft);
1603
- for(i=x=0; i<chng.n; i++){
1490
+ blob_append (p->pOut, "<tr class=\"diffline\">", 21);
1491
+ blob_appendf(p->pOut, "<td class=\"diffln difflnl del\">%d</td>", p->lnLeft);
1492
+ blob_append (p->pOut, "<td class=\"diffsep del\">-</td>", 30);
1493
+ blob_append (p->pOut, "<td class=\"difftxt difftxtl del\">", 33);
1494
+ for( i=x=0; i<chng.n; i++ ){
16041495
int ofst = chng.a[i].iStart1;
16051496
int len = chng.a[i].iLen1;
16061497
if( len ){
1607
- htmlize_to_blob(&p->aCol[0], pX->z+x, ofst - x);
1498
+ htmlize_to_blob(p->pOut, pX->z+x, ofst - x);
16081499
x = ofst;
16091500
if( chng.a[i].iLen2 ){
1610
- blob_append(&p->aCol[0], "<del class='edit'>", -1);
1501
+ blob_append(p->pOut, "<del class=\"edit\">", 18);
16111502
}else{
1612
- blob_append(&p->aCol[0], "<del>", 5);
1503
+ blob_append(p->pOut, "<del>", 5);
16131504
}
1614
- htmlize_to_blob(&p->aCol[0], pX->z+x, len);
1505
+ htmlize_to_blob(p->pOut, pX->z+x, len);
16151506
x += len;
1616
- blob_append(&p->aCol[0], "</del>", 6);
1507
+ blob_append(p->pOut, "</del>", 6);
16171508
}
16181509
}
1619
- htmlize_to_blob(&p->aCol[0], pX->z+x, pX->n - x);
1620
- blob_append_char(&p->aCol[0], '\n');
1621
-
1622
- blob_append(&p->aCol[1], "|\n", 2);
1623
-
1624
- blob_appendf(&p->aCol[2],"%d\n", p->lnRight);
1625
- for(i=x=0; i<chng.n; i++){
1510
+ htmlize_to_blob(p->pOut, pX->z+x, pX->n - x);
1511
+ blob_append (p->pOut, "</td>", 5);
1512
+ blob_appendf(p->pOut, "<td class=\"diffln difflnr ins\">%d</td>", p->lnRight);
1513
+ blob_append (p->pOut, "<td class=\"diffsep ins\">+</td>", 30);
1514
+ blob_append (p->pOut, "<td class=\"difftxt difftxtr ins\">", 33);
1515
+ for( i=x=0; i<chng.n; i++ ){
16261516
int ofst = chng.a[i].iStart2;
16271517
int len = chng.a[i].iLen2;
16281518
if( len ){
1629
- htmlize_to_blob(&p->aCol[3], pY->z+x, ofst - x);
1519
+ htmlize_to_blob(p->pOut, pY->z+x, ofst - x);
16301520
x = ofst;
16311521
if( chng.a[i].iLen1 ){
1632
- blob_append(&p->aCol[3], "<ins class='edit'>", -1);
1522
+ blob_append(p->pOut, "<ins class=\"edit\">", 18);
16331523
}else{
1634
- blob_append(&p->aCol[3], "<ins>", 5);
1524
+ blob_append(p->pOut, "<ins>", 5);
16351525
}
1636
- htmlize_to_blob(&p->aCol[3], pY->z+x, len);
1526
+ htmlize_to_blob(p->pOut, pY->z+x, len);
16371527
x += len;
1638
- blob_append(&p->aCol[3], "</ins>", 6);
1528
+ blob_append(p->pOut, "</ins>", 6);
16391529
}
16401530
}
1641
- htmlize_to_blob(&p->aCol[3], pY->z+x, pY->n - x);
1642
- blob_append_char(&p->aCol[3], '\n');
1531
+ htmlize_to_blob(p->pOut, pY->z+x, pY->n - x);
1532
+ blob_append (p->pOut, "</td>", 5);
1533
+ blob_append (p->pOut, "</tr>\n", 6);
16431534
}
16441535
static void dfsplitEnd(DiffBuilder *p){
1645
- dfsplitFinishRow(p);
1646
- blob_append(p->pOut, "</table>\n",-1);
1536
+ blob_append(p->pOut, "</table>\n", 9);
16471537
fossil_free(p);
16481538
}
16491539
static DiffBuilder *dfsplitNew(Blob *pOut, DiffConfig *pCfg){
16501540
DiffBuilder *p = fossil_malloc(sizeof(*p));
16511541
p->xSkip = dfsplitSkip;
@@ -1661,17 +1551,12 @@
16611551
if( pCfg->zLeftHash ){
16621552
blob_appendf(pOut,
16631553
"<table class=\"diff splitdiff\" data-lefthash=\"%s\">\n",
16641554
pCfg->zLeftHash);
16651555
}else{
1666
- blob_append(pOut, "<table class=\"diff splitdiff\">\n", -1);
1556
+ blob_append(pOut, "<table class=\"diff splitdiff\">\n", 31);
16671557
}
1668
- blob_init(&p->aCol[0], 0, 0);
1669
- blob_init(&p->aCol[1], 0, 0);
1670
- blob_init(&p->aCol[2], 0, 0);
1671
- blob_init(&p->aCol[3], 0, 0);
1672
- blob_init(&p->aCol[4], 0, 0);
16731558
p->pCfg = pCfg;
16741559
return p;
16751560
}
16761561
16771562
/************************* DiffBuilderSbs ******************************/
16781563
--- src/diff.c
+++ src/diff.c
@@ -928,15 +928,14 @@
928 void (*xReplace)(DiffBuilder*,const DLine*,const DLine*);
929 void (*xEdit)(DiffBuilder*,const DLine*,const DLine*);
930 void (*xEnd)(DiffBuilder*);
931 unsigned int lnLeft; /* Lines seen on the left (delete) side */
932 unsigned int lnRight; /* Lines seen on the right (insert) side */
933 unsigned int nPending; /* Number of pending lines */
934 int eState; /* State of the output */
935 int width; /* Display width */
936 Blob *pOut; /* Output blob */
937 Blob aCol[5]; /* Holding blobs */
938 DiffConfig *pCfg; /* Configuration information */
939 };
940
941 /************************* DiffBuilderDebug ********************************/
942 /* This version of DiffBuilder is used for debugging the diff and diff
@@ -1220,209 +1219,162 @@
1220 **
1221 ** The result is a <table> with four columns. The four columns hold:
1222 **
1223 ** 1. The line numbers for the first file.
1224 ** 2. The line numbers for the second file.
1225 ** 3. The "diff mark": "+" or "-" or just a space
1226 ** 4. Text of the line
1227 **
1228 ** Inserted lines are marked with <ins> and deleted lines are marked
1229 ** with <del>. The whole line is marked this way, not just the part that
1230 ** changed. The part that change has an additional nested <ins> or <del>.
1231 ** The CSS needs to be set up such that a single <ins> or <del> gives a
1232 ** light background and a nested <ins> or <del> gives a darker background.
1233 ** Additional attributes (like bold font) might also be added to nested
1234 ** <ins> and <del> since those are the characters that have actually
1235 ** changed.
1236 **
1237 ** Accumulator strategy:
1238 **
1239 ** * Delete line numbers are output directly to p->pOut
1240 ** * Insert line numbers accumulate in p->aCol[0].
1241 ** * Separator marks accumulate in p->aCol[1].
1242 ** * Change text accumulates in p->aCol[2].
1243 ** * Pending insert line numbers go into p->aCol[3].
1244 ** * Pending insert text goes into p->aCol[4].
1245 **
1246 ** eState is 1 if text has an open <del>
1247 */
1248 static void dfunifiedFinishDelete(DiffBuilder *p){
1249 if( p->eState==0 ) return;
1250 blob_append(p->pOut, "</del>", 6);
1251 blob_append(&p->aCol[2], "</del>", 6);
1252 p->eState = 0;
1253 }
1254 static void dfunifiedFinishInsert(DiffBuilder *p){
1255 unsigned int i;
1256 if( p->nPending==0 ) return;
1257 dfunifiedFinishDelete(p);
1258
1259 /* Blank lines for delete line numbers for each inserted line */
1260 for(i=0; i<p->nPending; i++) blob_append_char(p->pOut, '\n');
1261
1262 /* Insert line numbers */
1263 blob_append(&p->aCol[0], "<ins>", 5);
1264 blob_append_xfer(&p->aCol[0], &p->aCol[3]);
1265 blob_append(&p->aCol[0], "</ins>", 6);
1266
1267 /* "+" marks for the separator on inserted lines */
1268 for(i=0; i<p->nPending; i++) blob_append(&p->aCol[1], "+\n", 2);
1269
1270 /* Text of the inserted lines */
1271 blob_append(&p->aCol[2], "<ins>", 5);
1272 blob_append_xfer(&p->aCol[2], &p->aCol[4]);
1273 blob_append(&p->aCol[2], "</ins>", 6);
1274
1275 p->nPending = 0;
1276 }
1277 static void dfunifiedFinishRow(DiffBuilder *p){
1278 dfunifiedFinishDelete(p);
1279 dfunifiedFinishInsert(p);
1280 if( blob_size(&p->aCol[0])==0 ) return;
1281 blob_append(p->pOut, "</pre></td><td class=\"diffln difflnr\"><pre>\n", -1);
1282 blob_append_xfer(p->pOut, &p->aCol[0]);
1283 blob_append(p->pOut, "</pre></td><td class=\"diffsep\"><pre>\n", -1);
1284 blob_append_xfer(p->pOut, &p->aCol[1]);
1285 blob_append(p->pOut, "</pre></td><td class=\"difftxt difftxtu\"><pre>\n",-1);
1286 blob_append_xfer(p->pOut, &p->aCol[2]);
1287 blob_append(p->pOut, "</pre></td></tr>\n", -1);
1288 }
1289 static void dfunifiedStartRow(DiffBuilder *p){
1290 if( blob_size(&p->aCol[0])>0 ) return;
1291 blob_appendf(p->pOut,"<tr id=\"chunk%d\" class=\"diffchunk\">"
1292 "<td class=\"diffln difflnl\"><pre>\n", ++nChunk);
1293 }
1294 static void dfunifiedSkip(DiffBuilder *p, unsigned int n, int isFinal){
1295 dfunifiedFinishRow(p);
1296 if( p->pCfg && p->pCfg->zLeftHash ){
1297 blob_appendf(p->pOut,
1298 "<tr class=\"diffskip\" data-startln=\"%d\" data-endln=\"%d\""
1299 " id=\"skip%xh%xi%x\">\n",
1300 p->lnLeft+1, p->lnLeft+n,
1301 nChunk, p->lnLeft, n);
1302 }else{
1303 blob_append(p->pOut, "<tr>", 4);
1304 }
1305 blob_append(p->pOut, "<td class=\"diffln difflne\">"
1306 "&#xfe19;</td><td></td><td></td></tr>\n", -1);
1307 p->lnLeft += n;
1308 p->lnRight += n;
1309 }
1310 static void dfunifiedCommon(DiffBuilder *p, const DLine *pLine){
1311 dfunifiedStartRow(p);
1312 dfunifiedFinishDelete(p);
1313 dfunifiedFinishInsert(p);
1314 p->lnLeft++;
1315 p->lnRight++;
1316 blob_appendf(p->pOut,"%d\n", p->lnLeft);
1317 blob_appendf(&p->aCol[0],"%d\n",p->lnRight);
1318 blob_append_char(&p->aCol[1], '\n');
1319 htmlize_to_blob(&p->aCol[2], pLine->z, (int)pLine->n);
1320 blob_append_char(&p->aCol[2], '\n');
 
 
 
1321 }
1322 static void dfunifiedInsert(DiffBuilder *p, const DLine *pLine){
1323 dfunifiedStartRow(p);
1324 p->lnRight++;
1325 blob_appendf(&p->aCol[3],"%d\n", p->lnRight);
1326 blob_append(&p->aCol[4], "<ins>", 5);
1327 htmlize_to_blob(&p->aCol[4], pLine->z, (int)pLine->n);
1328 blob_append(&p->aCol[4], "</ins>\n", 7);
1329 p->nPending++;
 
 
 
 
1330 }
1331 static void dfunifiedDelete(DiffBuilder *p, const DLine *pLine){
1332 dfunifiedStartRow(p);
1333 dfunifiedFinishInsert(p);
1334 if( p->eState==0 ){
1335 dfunifiedFinishInsert(p);
1336 blob_append(p->pOut, "<del>", 5);
1337 blob_append(&p->aCol[2], "<del>", 5);
1338 p->eState = 1;
1339 }
1340 p->lnLeft++;
1341 blob_appendf(p->pOut,"%d\n", p->lnLeft);
1342 blob_append_char(&p->aCol[0],'\n');
1343 blob_append(&p->aCol[1],"-\n",2);
1344 blob_append(&p->aCol[2], "<del>", 5);
1345 htmlize_to_blob(&p->aCol[2], pLine->z, (int)pLine->n);
1346 blob_append(&p->aCol[2], "</del>\n", 7);
1347 }
1348 static void dfunifiedReplace(DiffBuilder *p, const DLine *pX, const DLine *pY){
1349 dfunifiedStartRow(p);
1350 if( p->eState==0 ){
1351 dfunifiedFinishInsert(p);
1352 blob_append(p->pOut, "<del>", 5);
1353 blob_append(&p->aCol[2], "<del>", 5);
1354 p->eState = 1;
1355 }
1356 p->lnLeft++;
1357 p->lnRight++;
1358 blob_appendf(p->pOut,"%d\n", p->lnLeft);
1359 blob_append_char(&p->aCol[0], '\n');
1360 blob_append(&p->aCol[1], "-\n", 2);
1361
1362 htmlize_to_blob(&p->aCol[2], pX->z, pX->n);
1363 blob_append_char(&p->aCol[2], '\n');
1364
1365 blob_appendf(&p->aCol[3],"%d\n", p->lnRight);
1366
1367 htmlize_to_blob(&p->aCol[4], pY->z, pY->n);
1368 blob_append_char(&p->aCol[4], '\n');
1369 p->nPending++;
1370 }
1371 static void dfunifiedEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
1372 int i;
1373 int x;
1374 LineChange chng;
1375 oneLineChange(pX, pY, &chng);
1376 dfunifiedStartRow(p);
1377 if( p->eState==0 ){
1378 dfunifiedFinishInsert(p);
1379 blob_append(p->pOut, "<del>", 5);
1380 blob_append(&p->aCol[2], "<del>", 5);
1381 p->eState = 1;
1382 }
1383 p->lnLeft++;
1384 p->lnRight++;
1385 blob_appendf(p->pOut,"%d\n", p->lnLeft);
1386 blob_append_char(&p->aCol[0], '\n');
1387 blob_append(&p->aCol[1], "-\n", 2);
1388
1389 for(i=x=0; i<chng.n; i++){
 
1390 int ofst = chng.a[i].iStart1;
1391 int len = chng.a[i].iLen1;
1392 if( len ){
1393 htmlize_to_blob(&p->aCol[2], pX->z+x, ofst - x);
1394 x = ofst;
1395 blob_append(&p->aCol[2], "<del>", 5);
1396 htmlize_to_blob(&p->aCol[2], pX->z+x, len);
1397 x += len;
1398 blob_append(&p->aCol[2], "</del>", 6);
1399 }
1400 }
1401 htmlize_to_blob(&p->aCol[2], pX->z+x, pX->n - x);
1402 blob_append_char(&p->aCol[2], '\n');
1403
1404 blob_appendf(&p->aCol[3],"%d\n", p->lnRight);
1405 for(i=x=0; i<chng.n; i++){
 
 
 
 
 
1406 int ofst = chng.a[i].iStart2;
1407 int len = chng.a[i].iLen2;
1408 if( len ){
1409 htmlize_to_blob(&p->aCol[4], pY->z+x, ofst - x);
1410 x = ofst;
1411 blob_append(&p->aCol[4], "<ins>", 5);
1412 htmlize_to_blob(&p->aCol[4], pY->z+x, len);
1413 x += len;
1414 blob_append(&p->aCol[4], "</ins>", 6);
1415 }
1416 }
1417 htmlize_to_blob(&p->aCol[4], pY->z+x, pY->n - x);
1418 blob_append_char(&p->aCol[4], '\n');
1419 p->nPending++;
1420 }
1421 static void dfunifiedEnd(DiffBuilder *p){
1422 dfunifiedFinishRow(p);
1423 blob_append(p->pOut, "</table>\n",-1);
 
1424 fossil_free(p);
1425 }
1426 static DiffBuilder *dfunifiedNew(Blob *pOut, DiffConfig *pCfg){
1427 DiffBuilder *p = fossil_malloc(sizeof(*p));
1428 p->xSkip = dfunifiedSkip;
@@ -1432,220 +1384,158 @@
1432 p->xReplace = dfunifiedReplace;
1433 p->xEdit = dfunifiedEdit;
1434 p->xEnd = dfunifiedEnd;
1435 p->lnLeft = p->lnRight = 0;
1436 p->eState = 0;
1437 p->nPending = 0;
1438 p->pOut = pOut;
1439 if( pCfg->zLeftHash ){
1440 blob_appendf(pOut, "<table class=\"diff udiff\" data-lefthash=\"%s\">\n",
1441 pCfg->zLeftHash);
1442 }else{
1443 blob_append(pOut, "<table class=\"diff udiff\">\n", -1);
1444 }
1445 blob_init(&p->aCol[0], 0, 0);
1446 blob_init(&p->aCol[1], 0, 0);
1447 blob_init(&p->aCol[2], 0, 0);
1448 blob_init(&p->aCol[3], 0, 0);
1449 blob_init(&p->aCol[4], 0, 0);
1450 p->pCfg = pCfg;
1451 return p;
1452 }
1453
1454 /************************* DiffBuilderSplit ******************************/
1455 /* This formatter creates a side-by-side diff in HTML. The output is a
1456 ** <table> with 5 columns:
1457 **
1458 ** 1. Line numbers for the first file.
1459 ** 2. Text for the first file.
1460 ** 3. The difference mark. "<", ">", "|" or blank
1461 ** 4. Line numbers for the second file.
1462 ** 5. Text for the second file.
1463 **
1464 ** The <ins> and <del> strategy is the same as for unified diff above.
1465 ** In fact, the same CSS can be used for both.
 
 
1466 **
1467 ** Accumulator strategy:
1468 **
1469 ** * Left line numbers are output directly to p->pOut
1470 ** * Left text accumulates in p->aCol[0].
1471 ** * Edit marks accumulates in p->aCol[1].
1472 ** * Right line numbers accumulate in p->aCol[2].
1473 ** * Right text accumulates in p->aCol[3].
1474 **
1475 ** eState:
1476 ** 0 In common block
1477 ** 1 Have <del> on the left
1478 ** 2 Have <ins> on the right
1479 ** 3 Have <del> on left and <ins> on the right
1480 */
1481 static void dfsplitChangeState(DiffBuilder *p, int newState){
1482 if( p->eState == newState ) return;
1483 if( (p->eState&1)==0 && (newState & 1)!=0 ){
1484 blob_append(p->pOut, "<del>", 5);
1485 blob_append(&p->aCol[0], "<del>", 5);
1486 p->eState |= 1;
1487 }else if( (p->eState&1)!=0 && (newState & 1)==0 ){
1488 blob_append(p->pOut, "</del>", 6);
1489 blob_append(&p->aCol[0], "</del>", 6);
1490 p->eState &= ~1;
1491 }
1492 if( (p->eState&2)==0 && (newState & 2)!=0 ){
1493 blob_append(&p->aCol[2], "<ins>", 5);
1494 blob_append(&p->aCol[3], "<ins>", 5);
1495 p->eState |= 2;
1496 }else if( (p->eState&2)!=0 && (newState & 2)==0 ){
1497 blob_append(&p->aCol[2], "</ins>", 6);
1498 blob_append(&p->aCol[3], "</ins>", 6);
1499 p->eState &= ~2;
1500 }
1501 }
1502 static void dfsplitFinishRow(DiffBuilder *p){
1503 if( blob_size(&p->aCol[0])==0 ) return;
1504 dfsplitChangeState(p, 0);
1505 blob_append(p->pOut, "</pre></td><td class=\"difftxt difftxtl\"><pre>\n",-1);
1506 blob_append_xfer(p->pOut, &p->aCol[0]);
1507 blob_append(p->pOut, "</pre></td><td class=\"diffsep\"><pre>\n", -1);
1508 blob_append_xfer(p->pOut, &p->aCol[1]);
1509 blob_append(p->pOut, "</pre></td><td class=\"diffln difflnr\"><pre>\n",-1);
1510 blob_append_xfer(p->pOut, &p->aCol[2]);
1511 blob_append(p->pOut, "</pre></td><td class=\"difftxt difftxtr\"><pre>\n",-1);
1512 blob_append_xfer(p->pOut, &p->aCol[3]);
1513 blob_append(p->pOut, "</pre></td></tr>\n", -1);
1514 }
1515 static void dfsplitStartRow(DiffBuilder *p){
1516 if( blob_size(&p->aCol[0])>0 ) return;
1517 blob_appendf(p->pOut,"<tr id=\"chunk%d\" class=\"diffchunk\">"
1518 "<td class=\"diffln difflnl\"><pre>\n", ++nChunk);
1519 p->eState = 0;
1520 }
1521 static void dfsplitSkip(DiffBuilder *p, unsigned int n, int isFinal){
1522 dfsplitFinishRow(p);
1523 if( p->pCfg && p->pCfg->zLeftHash ){
1524 blob_appendf(p->pOut,
1525 "<tr class=\"diffskip\" data-startln=\"%d\" data-endln=\"%d\""
1526 " id=\"skip%xh%xi%x\">\n",
1527 p->lnLeft+1, p->lnLeft+n,
1528 nChunk,p->lnLeft,n);
1529 }else{
1530 blob_append(p->pOut, "<tr>", 4);
1531 }
1532 blob_append(p->pOut,
1533 "<td class=\"diffln difflnl difflne\">&#xfe19;</td>"
1534 "<td></td><td></td>"
1535 "<td class=\"diffln difflnr difflne\">&#xfe19;</td>"
1536 "<td/td></tr>\n", -1);
1537 p->lnLeft += n;
1538 p->lnRight += n;
1539 }
1540 static void dfsplitCommon(DiffBuilder *p, const DLine *pLine){
1541 dfsplitStartRow(p);
1542 dfsplitChangeState(p, 0);
1543 p->lnLeft++;
1544 p->lnRight++;
1545 blob_appendf(p->pOut,"%d\n", p->lnLeft);
1546 htmlize_to_blob(&p->aCol[0], pLine->z, (int)pLine->n);
1547 blob_append_char(&p->aCol[0], '\n');
1548 blob_append_char(&p->aCol[1], '\n');
1549 blob_appendf(&p->aCol[2],"%d\n",p->lnRight);
1550 htmlize_to_blob(&p->aCol[3], pLine->z, (int)pLine->n);
1551 blob_append_char(&p->aCol[3], '\n');
 
 
 
 
 
1552 }
1553 static void dfsplitInsert(DiffBuilder *p, const DLine *pLine){
1554 dfsplitStartRow(p);
1555 dfsplitChangeState(p, 2);
1556 p->lnRight++;
1557 blob_append_char(p->pOut, '\n');
1558 blob_append_char(&p->aCol[0], '\n');
1559 blob_append(&p->aCol[1], "&gt;\n", -1);
1560 blob_appendf(&p->aCol[2],"%d\n", p->lnRight);
1561 blob_append(&p->aCol[3], "<ins>", 5);
1562 htmlize_to_blob(&p->aCol[3], pLine->z, (int)pLine->n);
1563 blob_append(&p->aCol[3], "</ins>\n", 7);
 
 
 
1564 }
1565 static void dfsplitDelete(DiffBuilder *p, const DLine *pLine){
1566 dfsplitStartRow(p);
1567 dfsplitChangeState(p, 1);
1568 p->lnLeft++;
1569 blob_appendf(p->pOut,"%d\n", p->lnLeft);
1570 blob_append(&p->aCol[0], "<del>", 5);
1571 htmlize_to_blob(&p->aCol[0], pLine->z, (int)pLine->n);
1572 blob_append(&p->aCol[0], "</del>\n", 7);
1573 blob_append(&p->aCol[1], "&lt;\n", -1);
1574 blob_append_char(&p->aCol[2],'\n');
1575 blob_append_char(&p->aCol[3],'\n');
 
 
 
1576 }
1577 static void dfsplitReplace(DiffBuilder *p, const DLine *pX, const DLine *pY){
1578 dfsplitStartRow(p);
1579 dfsplitChangeState(p, 3);
1580 p->lnLeft++;
1581 p->lnRight++;
1582 blob_appendf(p->pOut,"%d\n", p->lnLeft);
1583 htmlize_to_blob(&p->aCol[0], pX->z, pX->n);
1584 blob_append_char(&p->aCol[0], '\n');
1585
1586 blob_append(&p->aCol[1], "|\n", 2);
1587
1588 blob_appendf(&p->aCol[2],"%d\n", p->lnRight);
1589
1590 htmlize_to_blob(&p->aCol[3], pY->z, pY->n);
1591 blob_append_char(&p->aCol[3], '\n');
1592 }
1593 static void dfsplitEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
1594 int i;
1595 int x;
1596 LineChange chng;
1597 oneLineChange(pX, pY, &chng);
1598 dfsplitStartRow(p);
1599 dfsplitChangeState(p, 3);
1600 p->lnLeft++;
1601 p->lnRight++;
1602 blob_appendf(p->pOut,"%d\n", p->lnLeft);
1603 for(i=x=0; i<chng.n; i++){
 
 
 
1604 int ofst = chng.a[i].iStart1;
1605 int len = chng.a[i].iLen1;
1606 if( len ){
1607 htmlize_to_blob(&p->aCol[0], pX->z+x, ofst - x);
1608 x = ofst;
1609 if( chng.a[i].iLen2 ){
1610 blob_append(&p->aCol[0], "<del class='edit'>", -1);
1611 }else{
1612 blob_append(&p->aCol[0], "<del>", 5);
1613 }
1614 htmlize_to_blob(&p->aCol[0], pX->z+x, len);
1615 x += len;
1616 blob_append(&p->aCol[0], "</del>", 6);
1617 }
1618 }
1619 htmlize_to_blob(&p->aCol[0], pX->z+x, pX->n - x);
1620 blob_append_char(&p->aCol[0], '\n');
1621
1622 blob_append(&p->aCol[1], "|\n", 2);
1623
1624 blob_appendf(&p->aCol[2],"%d\n", p->lnRight);
1625 for(i=x=0; i<chng.n; i++){
1626 int ofst = chng.a[i].iStart2;
1627 int len = chng.a[i].iLen2;
1628 if( len ){
1629 htmlize_to_blob(&p->aCol[3], pY->z+x, ofst - x);
1630 x = ofst;
1631 if( chng.a[i].iLen1 ){
1632 blob_append(&p->aCol[3], "<ins class='edit'>", -1);
1633 }else{
1634 blob_append(&p->aCol[3], "<ins>", 5);
1635 }
1636 htmlize_to_blob(&p->aCol[3], pY->z+x, len);
1637 x += len;
1638 blob_append(&p->aCol[3], "</ins>", 6);
1639 }
1640 }
1641 htmlize_to_blob(&p->aCol[3], pY->z+x, pY->n - x);
1642 blob_append_char(&p->aCol[3], '\n');
 
1643 }
1644 static void dfsplitEnd(DiffBuilder *p){
1645 dfsplitFinishRow(p);
1646 blob_append(p->pOut, "</table>\n",-1);
1647 fossil_free(p);
1648 }
1649 static DiffBuilder *dfsplitNew(Blob *pOut, DiffConfig *pCfg){
1650 DiffBuilder *p = fossil_malloc(sizeof(*p));
1651 p->xSkip = dfsplitSkip;
@@ -1661,17 +1551,12 @@
1661 if( pCfg->zLeftHash ){
1662 blob_appendf(pOut,
1663 "<table class=\"diff splitdiff\" data-lefthash=\"%s\">\n",
1664 pCfg->zLeftHash);
1665 }else{
1666 blob_append(pOut, "<table class=\"diff splitdiff\">\n", -1);
1667 }
1668 blob_init(&p->aCol[0], 0, 0);
1669 blob_init(&p->aCol[1], 0, 0);
1670 blob_init(&p->aCol[2], 0, 0);
1671 blob_init(&p->aCol[3], 0, 0);
1672 blob_init(&p->aCol[4], 0, 0);
1673 p->pCfg = pCfg;
1674 return p;
1675 }
1676
1677 /************************* DiffBuilderSbs ******************************/
1678
--- src/diff.c
+++ src/diff.c
@@ -928,15 +928,14 @@
928 void (*xReplace)(DiffBuilder*,const DLine*,const DLine*);
929 void (*xEdit)(DiffBuilder*,const DLine*,const DLine*);
930 void (*xEnd)(DiffBuilder*);
931 unsigned int lnLeft; /* Lines seen on the left (delete) side */
932 unsigned int lnRight; /* Lines seen on the right (insert) side */
 
933 int eState; /* State of the output */
934 int width; /* Display width */
935 Blob *pOut; /* Output blob */
936 Blob bBuf2; /* Storage to hold retained lines */
937 DiffConfig *pCfg; /* Configuration information */
938 };
939
940 /************************* DiffBuilderDebug ********************************/
941 /* This version of DiffBuilder is used for debugging the diff and diff
@@ -1220,209 +1219,162 @@
1219 **
1220 ** The result is a <table> with four columns. The four columns hold:
1221 **
1222 ** 1. The line numbers for the first file.
1223 ** 2. The line numbers for the second file.
1224 ** 3. The "diff mark": "+", "-" or blank.
1225 ** 4. Text of the line.
1226 **
1227 ** The table cells holding the inserted and deleted lines are assigned to CSS
1228 ** classes .nul, .ins or .del to color them accordingly. The changed parts of
1229 ** each line have additional <ins> or <del> elements. The CSS needs to be set
1230 ** up such that the <ins> or <del> intensify the background color of the .ins
1231 ** and .del CSS classes.
 
 
 
1232 **
1233 ** Accumulator strategy:
1234 **
1235 ** * Retained insert text goes to p->bBuf2
1236 ** * Anything else goes directly to p->pOut
 
 
 
 
1237 **
1238 ** eState is 1 if the last line was a deletion.
1239 */
1240 static void dfunifiedFinishDelete(DiffBuilder *p){
1241 if( p->eState==0 ) return;
 
 
1242 p->eState = 0;
1243 }
1244 static void dfunifiedFinishInsert(DiffBuilder *p){
1245 if( blob_size(&p->bBuf2)==0 ) return;
 
1246 dfunifiedFinishDelete(p);
1247 blob_append_xfer(p->pOut,&p->bBuf2);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1248 }
1249 static void dfunifiedFinishRow(DiffBuilder *p){
1250 dfunifiedFinishDelete(p);
1251 dfunifiedFinishInsert(p);
 
 
 
 
 
 
 
 
1252 }
1253 static void dfunifiedStartRow(DiffBuilder *p){
 
 
 
1254 }
1255 static void dfunifiedSkip(DiffBuilder *p, unsigned int n, int isFinal){
1256 dfunifiedFinishRow(p);
1257 if( p->pCfg && p->pCfg->zLeftHash ){
1258 blob_appendf(p->pOut,
1259 "<tr class=\"diffskip\" data-startln=\"%d\" data-endln=\"%d\""
1260 " id=\"skip%xh%xi%x\">\n",
1261 p->lnLeft+1, p->lnLeft+n, nChunk, p->lnLeft, n);
 
1262 }else{
1263 blob_append(p->pOut, "<tr>", 4);
1264 }
1265 blob_append(p->pOut, "<td class=\"diffln difflne\" colspan=\"4\">"
1266 "&#xfe19;</td></tr>\n", -1);
1267 p->lnLeft += n;
1268 p->lnRight += n;
1269 }
1270 static void dfunifiedCommon(DiffBuilder *p, const DLine *pLine){
1271 dfunifiedStartRow(p);
1272 dfunifiedFinishDelete(p);
1273 dfunifiedFinishInsert(p);
1274 p->lnLeft++;
1275 p->lnRight++;
1276 blob_append (p->pOut, "<tr class=\"diffline\">", 21);
1277 blob_appendf(p->pOut, "<td class=\"diffln difflnl\">%d</td>", p->lnLeft);
1278 blob_appendf(p->pOut, "<td class=\"diffln difflnr\">%d</td>", p->lnRight);
1279 blob_append (p->pOut, "<td class=\"diffsep\"></td>", 25);
1280 blob_append (p->pOut, "<td class=\"difftxt difftxtu\">", 29);
1281 htmlize_to_blob(p->pOut, pLine->z, (int)pLine->n);
1282 blob_append (p->pOut, "</td>", 5);
1283 blob_append (p->pOut, "</tr>\n", 6);
1284 }
1285 static void dfunifiedInsert(DiffBuilder *p, const DLine *pLine){
1286 dfunifiedStartRow(p);
1287 p->lnRight++;
1288 blob_append (&p->bBuf2, "<tr class=\"diffline\">", 21);
1289 blob_append (&p->bBuf2, "<td class=\"diffln difflnl ins\"></td>", 36);
1290 blob_appendf(&p->bBuf2, "<td class=\"diffln difflnr ins\">%d</td>",
1291 p->lnRight);
1292 blob_append (&p->bBuf2, "<td class=\"diffsep ins\">+</td>", 30);
1293 blob_append (&p->bBuf2, "<td class=\"difftxt difftxtu ins\"><ins>", 38);
1294 htmlize_to_blob(&p->bBuf2, pLine->z, (int)pLine->n);
1295 blob_append (&p->bBuf2, "</ins></td>", 11);
1296 blob_append (&p->bBuf2, "</tr>\n", 6);
1297 }
1298 static void dfunifiedDelete(DiffBuilder *p, const DLine *pLine){
1299 dfunifiedStartRow(p);
1300 dfunifiedFinishInsert(p);
1301 if( p->eState==0 ){
1302 dfunifiedFinishInsert(p);
1303 p->eState = 1;
1304 }
1305 p->lnLeft++;
1306 blob_append (p->pOut, "<tr class=\"diffline\">", 21);
1307 blob_appendf(p->pOut, "<td class=\"diffln difflnl del\">%d</td>", p->lnLeft);
1308 blob_append (p->pOut, "<td class=\"diffln difflnr del\"></td>", 36);
1309 blob_append (p->pOut, "<td class=\"diffsep del\">-</td>", 30);
1310 blob_append (p->pOut, "<td class=\"difftxt difftxtu del\"><del>", 38);
1311 htmlize_to_blob(p->pOut, pLine->z, (int)pLine->n);
1312 blob_append (p->pOut, "</del></td>", 11);
1313 blob_append (p->pOut, "</tr>\n", 6);
1314 }
1315 static void dfunifiedReplace(DiffBuilder *p, const DLine *pX, const DLine *pY){
1316 assert( 0 && "The seemingly unused function dfunifiedReplace() was called!");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1317 }
1318 static void dfunifiedEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
1319 int i;
1320 int x;
1321 LineChange chng;
1322 oneLineChange(pX, pY, &chng);
1323 dfunifiedStartRow(p);
1324 if( p->eState==0 ){
1325 dfunifiedFinishInsert(p);
 
 
1326 p->eState = 1;
1327 }
1328 p->lnLeft++;
1329 p->lnRight++;
1330 blob_append (p->pOut, "<tr class=\"diffline\">", 21);
1331 blob_appendf(p->pOut, "<td class=\"diffln difflnl del\">%d</td>", p->lnLeft);
1332 blob_append (p->pOut, "<td class=\"diffln difflnr del\"></td>", 36);
1333 blob_append (p->pOut, "<td class=\"diffsep del\">-</td>", 30);
1334 blob_append (p->pOut, "<td class=\"difftxt difftxtu del\">", 33);
1335 for( i=x=0; i<chng.n; i++ ){
1336 int ofst = chng.a[i].iStart1;
1337 int len = chng.a[i].iLen1;
1338 if( len ){
1339 htmlize_to_blob(p->pOut, pX->z+x, ofst - x);
1340 x = ofst;
1341 blob_append(p->pOut, "<del>", 5);
1342 htmlize_to_blob(p->pOut, pX->z+x, len);
1343 x += len;
1344 blob_append(p->pOut, "</del>", 6);
1345 }
1346 }
1347 htmlize_to_blob(p->pOut, pX->z+x, pX->n - x);
1348 blob_append (p->pOut, "</td>", 5);
1349 blob_append (p->pOut, "</tr>\n", 6);
1350 blob_append (&p->bBuf2, "<tr class=\"diffline\">", 21);
1351 blob_append (&p->bBuf2, "<td class=\"diffln difflnl ins\"></td>", 36);
1352 blob_appendf(&p->bBuf2, "<td class=\"diffln difflnr ins\">%d</td>",
1353 p->lnRight);
1354 blob_append (&p->bBuf2, "<td class=\"diffsep ins\">+</td>", 30);
1355 blob_append (&p->bBuf2, "<td class=\"difftxt difftxtu ins\">", 33);
1356 for( i=x=0; i<chng.n; i++ ){
1357 int ofst = chng.a[i].iStart2;
1358 int len = chng.a[i].iLen2;
1359 if( len ){
1360 htmlize_to_blob(&p->bBuf2, pY->z+x, ofst - x);
1361 x = ofst;
1362 blob_append(&p->bBuf2, "<ins>", 5);
1363 htmlize_to_blob(&p->bBuf2, pY->z+x, len);
1364 x += len;
1365 blob_append(&p->bBuf2, "</ins>", 6);
1366 }
1367 }
1368 htmlize_to_blob(&p->bBuf2, pY->z+x, pY->n - x);
1369 blob_append (&p->bBuf2, "</td>", 5);
1370 blob_append (&p->bBuf2, "</tr>\n", 6);
1371 }
1372 static void dfunifiedEnd(DiffBuilder *p){
1373 dfunifiedFinishRow(p);
1374 blob_append(p->pOut, "</table>\n", 9);
1375 blob_reset(&p->bBuf2);
1376 fossil_free(p);
1377 }
1378 static DiffBuilder *dfunifiedNew(Blob *pOut, DiffConfig *pCfg){
1379 DiffBuilder *p = fossil_malloc(sizeof(*p));
1380 p->xSkip = dfunifiedSkip;
@@ -1432,220 +1384,158 @@
1384 p->xReplace = dfunifiedReplace;
1385 p->xEdit = dfunifiedEdit;
1386 p->xEnd = dfunifiedEnd;
1387 p->lnLeft = p->lnRight = 0;
1388 p->eState = 0;
 
1389 p->pOut = pOut;
1390 if( pCfg->zLeftHash ){
1391 blob_appendf(pOut, "<table class=\"diff udiff\" data-lefthash=\"%s\">\n",
1392 pCfg->zLeftHash);
1393 }else{
1394 blob_append(pOut, "<table class=\"diff udiff\">\n", 27);
1395 }
1396 blob_init(&p->bBuf2, 0, 0);
 
 
 
 
1397 p->pCfg = pCfg;
1398 return p;
1399 }
1400
1401 /************************* DiffBuilderSplit ******************************/
1402 /* This formatter creates a side-by-side diff in HTML. The output is a
1403 ** <table> with 6 columns:
1404 **
1405 ** 1. Line numbers for the first file.
1406 ** 2. First difference mark: "+", "-" or blank.
1407 ** 3. Text for the first file.
1408 ** 4. Line numbers for the second file.
1409 ** 5. Second difference mark: "+", "-" or blank.
1410 ** 6. Text for the second file.
1411 **
1412 ** The styling approach with .nul, .ins and .del CSS classes and <ins> and
1413 ** <del> elements is the same as for the unified diffs above. In fact, the
1414 ** same CSS can be used for both.
1415 **
1416 ** Accumulator strategy:
1417 **
1418 ** * All output goes directly to p->pOut
 
 
 
 
1419 **
1420 ** eState is not unused.
 
 
 
 
1421 */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1422 static void dfsplitSkip(DiffBuilder *p, unsigned int n, int isFinal){
 
1423 if( p->pCfg && p->pCfg->zLeftHash ){
1424 blob_appendf(p->pOut,
1425 "<tr class=\"diffskip\" data-startln=\"%d\" data-endln=\"%d\""
1426 " id=\"skip%xh%xi%x\">\n",
1427 p->lnLeft+1, p->lnLeft+n, nChunk, p->lnLeft, n);
 
1428 }else{
1429 blob_append(p->pOut, "<tr>", 4);
1430 }
1431 blob_append(p->pOut,
1432 "<td class=\"diffln difflnl difflne\" colspan=\"3\">&#xfe19;</td>"
1433 "<td class=\"diffln difflnr difflne\" colspan=\"3\">&#xfe19;</td>"
1434 "</tr>\n", -1);
 
1435 p->lnLeft += n;
1436 p->lnRight += n;
1437 }
1438 static void dfsplitCommon(DiffBuilder *p, const DLine *pLine){
 
 
1439 p->lnLeft++;
1440 p->lnRight++;
1441 blob_append (p->pOut, "<tr class=\"diffline\">", 21);
1442 blob_appendf(p->pOut, "<td class=\"diffln difflnl\">%d</td>", p->lnLeft);
1443 blob_append (p->pOut, "<td class=\"diffsep\"></td>", 25);
1444 blob_append (p->pOut, "<td class=\"difftxt difftxtl\">", 29);
1445 htmlize_to_blob(p->pOut, pLine->z, (int)pLine->n);
1446 blob_append (p->pOut, "</td>", 5);
1447 blob_appendf(p->pOut, "<td class=\"diffln difflnr\">%d</td>", p->lnRight);
1448 blob_append (p->pOut, "<td class=\"diffsep\"></td>", 25);
1449 blob_append (p->pOut, "<td class=\"difftxt difftxtr\">", 29);
1450 htmlize_to_blob(p->pOut, pLine->z, (int)pLine->n);
1451 blob_append (p->pOut, "</td>", 5);
1452 blob_append (p->pOut, "</tr>\n", 6);
1453 }
1454 static void dfsplitInsert(DiffBuilder *p, const DLine *pLine){
 
 
1455 p->lnRight++;
1456 blob_append (p->pOut, "<tr class=\"diffline\">", 21);
1457 blob_append (p->pOut, "<td class=\"diffln difflnl nul\"></td>", 36);
1458 blob_append (p->pOut, "<td class=\"diffsep nul\"></td>", 29);
1459 blob_append (p->pOut, "<td class=\"difftxt difftxtl nul\"></td>", 38);
1460 blob_appendf(p->pOut, "<td class=\"diffln difflnr ins\">%d</td>", p->lnRight);
1461 blob_append (p->pOut, "<td class=\"diffsep ins\">+</td>", 30);
1462 blob_append (p->pOut, "<td class=\"difftxt difftxtr ins\"><ins>", 38);
1463 htmlize_to_blob(p->pOut, pLine->z, (int)pLine->n);
1464 blob_append (p->pOut, "</ins></td>", 11);
1465 blob_append (p->pOut, "</tr>\n", 6);
1466 }
1467 static void dfsplitDelete(DiffBuilder *p, const DLine *pLine){
 
 
1468 p->lnLeft++;
1469 blob_append (p->pOut, "<tr class=\"diffline\">", 21);
1470 blob_appendf(p->pOut, "<td class=\"diffln difflnl del\">%d</td>", p->lnLeft);
1471 blob_append (p->pOut, "<td class=\"diffsep del\">-</td>", 30);
1472 blob_append (p->pOut, "<td class=\"difftxt difftxtl del\"><del>", 38);
1473 htmlize_to_blob(p->pOut, pLine->z, (int)pLine->n);
1474 blob_append (p->pOut, "</del></td>", 11);
1475 blob_append (p->pOut, "<td class=\"diffln difflnr nul\"></td>", 36);
1476 blob_append (p->pOut, "<td class=\"diffsep nul\"></td>", 29);
1477 blob_append (p->pOut, "<td class=\"difftxt difftxtr nul\"></td>", 38);
1478 blob_append (p->pOut, "</tr>\n", 6);
1479 }
1480 static void dfsplitReplace(DiffBuilder *p, const DLine *pX, const DLine *pY){
1481 assert( 0 && "The seemingly unused function dfsplitReplace() was called!");
 
 
 
 
 
 
 
 
 
 
 
 
 
1482 }
1483 static void dfsplitEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
1484 int i;
1485 int x;
1486 LineChange chng;
1487 oneLineChange(pX, pY, &chng);
 
 
1488 p->lnLeft++;
1489 p->lnRight++;
1490 blob_append (p->pOut, "<tr class=\"diffline\">", 21);
1491 blob_appendf(p->pOut, "<td class=\"diffln difflnl del\">%d</td>", p->lnLeft);
1492 blob_append (p->pOut, "<td class=\"diffsep del\">-</td>", 30);
1493 blob_append (p->pOut, "<td class=\"difftxt difftxtl del\">", 33);
1494 for( i=x=0; i<chng.n; i++ ){
1495 int ofst = chng.a[i].iStart1;
1496 int len = chng.a[i].iLen1;
1497 if( len ){
1498 htmlize_to_blob(p->pOut, pX->z+x, ofst - x);
1499 x = ofst;
1500 if( chng.a[i].iLen2 ){
1501 blob_append(p->pOut, "<del class=\"edit\">", 18);
1502 }else{
1503 blob_append(p->pOut, "<del>", 5);
1504 }
1505 htmlize_to_blob(p->pOut, pX->z+x, len);
1506 x += len;
1507 blob_append(p->pOut, "</del>", 6);
1508 }
1509 }
1510 htmlize_to_blob(p->pOut, pX->z+x, pX->n - x);
1511 blob_append (p->pOut, "</td>", 5);
1512 blob_appendf(p->pOut, "<td class=\"diffln difflnr ins\">%d</td>", p->lnRight);
1513 blob_append (p->pOut, "<td class=\"diffsep ins\">+</td>", 30);
1514 blob_append (p->pOut, "<td class=\"difftxt difftxtr ins\">", 33);
1515 for( i=x=0; i<chng.n; i++ ){
 
1516 int ofst = chng.a[i].iStart2;
1517 int len = chng.a[i].iLen2;
1518 if( len ){
1519 htmlize_to_blob(p->pOut, pY->z+x, ofst - x);
1520 x = ofst;
1521 if( chng.a[i].iLen1 ){
1522 blob_append(p->pOut, "<ins class=\"edit\">", 18);
1523 }else{
1524 blob_append(p->pOut, "<ins>", 5);
1525 }
1526 htmlize_to_blob(p->pOut, pY->z+x, len);
1527 x += len;
1528 blob_append(p->pOut, "</ins>", 6);
1529 }
1530 }
1531 htmlize_to_blob(p->pOut, pY->z+x, pY->n - x);
1532 blob_append (p->pOut, "</td>", 5);
1533 blob_append (p->pOut, "</tr>\n", 6);
1534 }
1535 static void dfsplitEnd(DiffBuilder *p){
1536 blob_append(p->pOut, "</table>\n", 9);
 
1537 fossil_free(p);
1538 }
1539 static DiffBuilder *dfsplitNew(Blob *pOut, DiffConfig *pCfg){
1540 DiffBuilder *p = fossil_malloc(sizeof(*p));
1541 p->xSkip = dfsplitSkip;
@@ -1661,17 +1551,12 @@
1551 if( pCfg->zLeftHash ){
1552 blob_appendf(pOut,
1553 "<table class=\"diff splitdiff\" data-lefthash=\"%s\">\n",
1554 pCfg->zLeftHash);
1555 }else{
1556 blob_append(pOut, "<table class=\"diff splitdiff\">\n", 31);
1557 }
 
 
 
 
 
1558 p->pCfg = pCfg;
1559 return p;
1560 }
1561
1562 /************************* DiffBuilderSbs ******************************/
1563
+2 -73
--- src/diff.js
+++ src/diff.js
@@ -1,73 +1,2 @@
1
-/* Refinements to the display of unified and side-by-side diffs.
2
-**
3
-** In all cases, the table columns tagged with "difftxt" are expanded,
4
-** where possible, to fill the width of the screen.
5
-**
6
-** For a side-by-side diff, if either column is two wide to fit on the
7
-** display, scrollbars are added. The scrollbars are linked, so that
8
-** both sides scroll together. Left and right arrows also scroll.
9
-*/
10
-window.addEventListener('load',function(){
11
- var SCROLL_LEN = 25;
12
- function initDiff(diff){
13
- var txtCols = diff.querySelectorAll('td.difftxt');
14
- var txtPres = diff.querySelectorAll('td.difftxt pre');
15
- var width = 0;
16
- if(txtPres.length>=2){
17
- width = Math.max(txtPres[0].scrollWidth, txtPres[1].scrollWidth);
18
- }
19
- var i;
20
- for(i=0; i<txtCols.length; i++){
21
- txtCols[i].style.width = width + 'px';
22
- txtPres[i].style.maxWidth = width + 'px';
23
- txtPres[i].style.width = width + 'px';
24
- txtPres[i].onscroll = function(e){
25
- for(var j=0; j<txtPres.length; j++) txtPres[j].scrollLeft = this.scrollLeft;
26
- };
27
- }
28
- diff.tabIndex = 0;
29
- diff.onkeydown = function(e){
30
- e = e || event;
31
- var len = {37: -SCROLL_LEN, 39: SCROLL_LEN}[e.keyCode];
32
- if( !len ) return;
33
- txtPres[0].scrollLeft += len;
34
- return false;
35
- };
36
- }
37
- var i, diffs = document.querySelectorAll('table.splitdiff')
38
- for(i=0; i<diffs.length; i++){
39
- initDiff(diffs[i]);
40
- }
41
- const checkWidth = function f(){
42
- if(undefined === f.lastWidth){
43
- f.lastWidth = 0;
44
- }
45
- if( document.body.clientWidth===f.lastWidth ) return;
46
- f.lastWidth = document.body.clientWidth;
47
- var w = f.lastWidth*0.5 - 100;
48
- if(!f.colsL){
49
- f.colsL = document.querySelectorAll('td.difftxtl pre');
50
- }
51
- for(let i=0; i<f.colsL.length; i++){
52
- f.colsL[i].style.width = w + "px";
53
- f.colsL[i].style.maxWidth = w + "px";
54
- }
55
- if(!f.colsR){
56
- f.colsR = document.querySelectorAll('td.difftxtr pre');
57
- }
58
- for(let i=0; i<f.colsR.length; i++){
59
- f.colsR[i].style.width = w + "px";
60
- f.colsR[i].style.maxWidth = w + "px";
61
- }
62
- if(!f.allDiffs){
63
- f.allDiffs = document.querySelectorAll('table.diff');
64
- }
65
- w = f.lastWidth;
66
- for(let i=0; i<f.allDiffs.length; i++){
67
- f.allDiffs[i].style.width = '100%'; // setting to w causes unsightly horiz. scrollbar
68
- f.allDiffs[i].style.maxWidth = w + "px";
69
- }
70
- };
71
- checkWidth();
72
- window.addEventListener('resize', checkWidth);
73
-}, false);
1
+/* TODO: Run tools/makemake.tcl to regenerate the makefiles and to remove this
2
+** file from the built-in files if it remains unused. */
743
--- src/diff.js
+++ src/diff.js
@@ -1,73 +1,2 @@
1 /* Refinements to the display of unified and side-by-side diffs.
2 **
3 ** In all cases, the table columns tagged with "difftxt" are expanded,
4 ** where possible, to fill the width of the screen.
5 **
6 ** For a side-by-side diff, if either column is two wide to fit on the
7 ** display, scrollbars are added. The scrollbars are linked, so that
8 ** both sides scroll together. Left and right arrows also scroll.
9 */
10 window.addEventListener('load',function(){
11 var SCROLL_LEN = 25;
12 function initDiff(diff){
13 var txtCols = diff.querySelectorAll('td.difftxt');
14 var txtPres = diff.querySelectorAll('td.difftxt pre');
15 var width = 0;
16 if(txtPres.length>=2){
17 width = Math.max(txtPres[0].scrollWidth, txtPres[1].scrollWidth);
18 }
19 var i;
20 for(i=0; i<txtCols.length; i++){
21 txtCols[i].style.width = width + 'px';
22 txtPres[i].style.maxWidth = width + 'px';
23 txtPres[i].style.width = width + 'px';
24 txtPres[i].onscroll = function(e){
25 for(var j=0; j<txtPres.length; j++) txtPres[j].scrollLeft = this.scrollLeft;
26 };
27 }
28 diff.tabIndex = 0;
29 diff.onkeydown = function(e){
30 e = e || event;
31 var len = {37: -SCROLL_LEN, 39: SCROLL_LEN}[e.keyCode];
32 if( !len ) return;
33 txtPres[0].scrollLeft += len;
34 return false;
35 };
36 }
37 var i, diffs = document.querySelectorAll('table.splitdiff')
38 for(i=0; i<diffs.length; i++){
39 initDiff(diffs[i]);
40 }
41 const checkWidth = function f(){
42 if(undefined === f.lastWidth){
43 f.lastWidth = 0;
44 }
45 if( document.body.clientWidth===f.lastWidth ) return;
46 f.lastWidth = document.body.clientWidth;
47 var w = f.lastWidth*0.5 - 100;
48 if(!f.colsL){
49 f.colsL = document.querySelectorAll('td.difftxtl pre');
50 }
51 for(let i=0; i<f.colsL.length; i++){
52 f.colsL[i].style.width = w + "px";
53 f.colsL[i].style.maxWidth = w + "px";
54 }
55 if(!f.colsR){
56 f.colsR = document.querySelectorAll('td.difftxtr pre');
57 }
58 for(let i=0; i<f.colsR.length; i++){
59 f.colsR[i].style.width = w + "px";
60 f.colsR[i].style.maxWidth = w + "px";
61 }
62 if(!f.allDiffs){
63 f.allDiffs = document.querySelectorAll('table.diff');
64 }
65 w = f.lastWidth;
66 for(let i=0; i<f.allDiffs.length; i++){
67 f.allDiffs[i].style.width = '100%'; // setting to w causes unsightly horiz. scrollbar
68 f.allDiffs[i].style.maxWidth = w + "px";
69 }
70 };
71 checkWidth();
72 window.addEventListener('resize', checkWidth);
73 }, false);
74
--- src/diff.js
+++ src/diff.js
@@ -1,73 +1,2 @@
1 /* TODO: Run tools/makemake.tcl to regenerate the makefiles and to remove this
2 ** file from the built-in files if it remains unused. */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
+156 -182
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -230,123 +230,111 @@
230230
@ background-color: white;
231231
@ }
232232
@ h1 {
233233
@ font-size: 150%;
234234
@ }
235
-@
236235
@ table.diff {
237236
@ width: 100%;
238237
@ border-spacing: 0;
238
+@ border-radius: 5px;
239239
@ border: 1px solid black;
240
-@ line-height: inherit;
241
-@ font-size: inherit;
242240
@ }
243241
@ table.diff td {
244242
@ vertical-align: top;
245
-@ line-height: inherit;
246
-@ font-size: inherit;
247
-@ }
248
-@ table.diff pre {
249
-@ margin: 0 0 0 0;
250
-@ line-height: inherit;
251
-@ font-size: inherit;
252
-@ }
253
-@ td.diffln {
254
-@ width: 1px;
255
-@ text-align: right;
256
-@ padding: 0 1em 0 0;
257
-@ }
258
-@ td.difflne {
259
-@ padding-bottom: 0.4em;
260
-@ }
261
-@ td.diffsep {
262
-@ width: 1px;
263
-@ padding: 0 0.3em 0 1em;
264
-@ line-height: inherit;
265
-@ font-size: inherit;
266
-@ }
267
-@ td.diffsep pre {
268
-@ line-height: inherit;
269
-@ font-size: inherit;
270
-@ }
271
-@ td.difftxt pre {
272
-@ overflow-x: auto;
273
-@ }
274
-@ td.diffln ins {
275
-@ background-color: #a0e4b2;
276
-@ text-decoration: none;
277
-@ line-height: inherit;
278
-@ font-size: inherit;
279
-@ }
280
-@ td.diffln del {
281
-@ background-color: #ffc0c0;
282
-@ text-decoration: none;
283
-@ line-height: inherit;
284
-@ font-size: inherit;
285
-@ }
286
-@ td.difftxt del {
287
-@ background-color: #ffe8e8;
288
-@ text-decoration: none;
289
-@ line-height: inherit;
290
-@ font-size: inherit;
291
-@ }
292
-@ td.difftxt del > del {
293
-@ background-color: #ffc0c0;
294
-@ text-decoration: none;
295
-@ font-weight: bold;
296
-@ }
297
-@ td.difftxt del > del.edit {
298
-@ background-color: #c0c0ff;
299
-@ text-decoration: none;
300
-@ font-weight: bold;
301
-@ }
302
-@ td.difftxt ins {
303
-@ background-color: #dafbe1;
304
-@ text-decoration: none;
305
-@ line-height: inherit;
306
-@ font-size: inherit;
307
-@ }
308
-@ td.difftxt ins > ins {
309
-@ background-color: #a0e4b2;
310
-@ text-decoration: none;
311
-@ font-weight: bold;
312
-@ }
313
-@ td.difftxt ins > ins.edit {
314
-@ background-color: #c0c0ff;
315
-@ text-decoration: none;
316
-@ font-weight: bold;
243
+@ text-align: left;
244
+@ margin: 0;
245
+@ padding: 0;
246
+@ border: 0;
247
+@ font-family: monospace;
248
+@ line-height: 1.2;
249
+@ text-size-adjust: none;
250
+@ white-space: pre-wrap;
251
+@ word-wrap: break-word;
252
+@ }
253
+@ table.diff td.diffln {
254
+@ width: 0%;
255
+@ text-align: right;
256
+@ padding: 0 0.16em 0 0.32em;
257
+@ }
258
+@ table.diff td.difflne {
259
+@ text-align: left;
260
+@ padding: 0 0.32em;
261
+@ }
262
+@ table.diff td.diffsep {
263
+@ width: 0%;
264
+@ padding: 0 0.32em 0 0.16em;
265
+@ }
266
+@ td.difftxt {
267
+@ max-width: 0;
268
+@ }
269
+@ td.difftxtu {
270
+@ width: 100%;
271
+@ }
272
+@ td.difftxtl,
273
+@ td.difftxtr {
274
+@ width: 50%;
275
+@ }
276
+@ td.diffln.nul,
277
+@ td.diffsep.nul,
278
+@ td.difftxt.nul {
279
+@ background-color: #f9f9f9;
280
+@ }
281
+@ td.diffln.del,
282
+@ td.diffsep.del,
283
+@ td.difftxt.del {
284
+@ background-color: #ffe8e8;
285
+@ }
286
+@ td.diffln.ins,
287
+@ td.diffsep.ins,
288
+@ td.difftxt.ins {
289
+@ background-color: #dafbe1;
290
+@ }
291
+@ td.difftxt.del del {
292
+@ background-color: #ffc0c0;
293
+@ text-decoration: none;
294
+@ display: inline-block;
295
+@ }
296
+@ td.difftxt.del del.edit {
297
+@ background-color: #c0c0ff;
298
+@ }
299
+@ td.difftxt.ins ins {
300
+@ background-color: #a0e4b2;
301
+@ text-decoration: none;
302
+@ display: inline-block;
303
+@ }
304
+@ td.difftxt.ins ins.edit {
305
+@ background-color: #c0c0ff;
317306
@ }
318307
@ @media (prefers-color-scheme: dark) {
319308
@ body {
320
-@ background-color: #353535;
321
-@ color: #ffffff;
322
-@ }
323
-@ td.diffln ins {
324
-@ background-color: #559855;
325
-@ color: #000000;
326
-@ }
327
-@ td.diffln del {
328
-@ background-color: #cc5555;
329
-@ color: #000000;
330
-@ }
331
-@ td.difftxt del {
309
+@ color: #fff;
310
+@ background-color: #353535;
311
+@ }
312
+@ td.diffln.nul,
313
+@ td.diffsep.nul,
314
+@ td.difftxt.nul {
315
+@ background-color: #454545;
316
+@ }
317
+@ td.diffln.del,
318
+@ td.diffsep.del,
319
+@ td.difftxt.del {
320
+@ color: #000;
332321
@ background-color: #f9cfcf;
333
-@ color: #000000;
334
-@ }
335
-@ td.difftxt del > del {
336
-@ background-color: #cc5555;
337
-@ color: #000000;
338
-@ }
339
-@ td.difftxt ins {
340
-@ background-color: #a2dbb2;
341
-@ color: #000000;
342
-@ }
343
-@ td.difftxt ins > ins {
322
+@ }
323
+@ td.diffln.ins,
324
+@ td.diffsep.ins,
325
+@ td.difftxt.ins {
326
+@ color: #000;
327
+@ background-color: #a2dbb2;
328
+@ }
329
+@ td.difftxt.del del {
330
+@ background-color: #cc5555;
331
+@ }
332
+@ td.difftxt.ins ins {
344333
@ background-color: #559855;
345334
@ }
346335
@ }
347
-@
348336
@ </style>
349337
@ </head>
350338
@ <body>
351339
;
352340
static const char zWebpageHdrDark[] =
@@ -354,105 +342,91 @@
354342
@ <html>
355343
@ <head>
356344
@ <meta charset="UTF-8">
357345
@ <style>
358346
@ body {
347
+@ color: #fff;
359348
@ background-color: #353535;
360
-@ color: #ffffff;
361349
@ }
362350
@ h1 {
363351
@ font-size: 150%;
364352
@ }
365
-@
366353
@ table.diff {
367354
@ width: 100%;
368355
@ border-spacing: 0;
356
+@ border-radius: 5px;
369357
@ border: 1px solid black;
370
-@ line-height: inherit;
371
-@ font-size: inherit;
372358
@ }
373359
@ table.diff td {
374360
@ vertical-align: top;
375
-@ line-height: inherit;
376
-@ font-size: inherit;
377
-@ }
378
-@ table.diff pre {
379
-@ margin: 0 0 0 0;
380
-@ line-height: inherit;
381
-@ font-size: inherit;
382
-@ }
383
-@ td.diffln {
384
-@ width: 1px;
385
-@ text-align: right;
386
-@ padding: 0 1em 0 0;
387
-@ }
388
-@ td.difflne {
389
-@ padding-bottom: 0.4em;
390
-@ }
391
-@ td.diffsep {
392
-@ width: 1px;
393
-@ padding: 0 0.3em 0 1em;
394
-@ line-height: inherit;
395
-@ font-size: inherit;
396
-@ }
397
-@ td.diffsep pre {
398
-@ line-height: inherit;
399
-@ font-size: inherit;
400
-@ }
401
-@ td.difftxt pre {
402
-@ overflow-x: auto;
403
-@ }
404
-@ td.diffln ins {
405
-@ background-color: #559855;
406
-@ color: #000000;
407
-@ text-decoration: none;
408
-@ line-height: inherit;
409
-@ font-size: inherit;
410
-@ }
411
-@ td.diffln del {
412
-@ background-color: #cc5555;
413
-@ color: #000000;
414
-@ text-decoration: none;
415
-@ line-height: inherit;
416
-@ font-size: inherit;
417
-@ }
418
-@ td.difftxt del {
419
-@ background-color: #f9cfcf;
420
-@ color: #000000;
421
-@ text-decoration: none;
422
-@ line-height: inherit;
423
-@ font-size: inherit;
424
-@ }
425
-@ td.difftxt del > del {
426
-@ background-color: #cc5555;
427
-@ color: #000000;
428
-@ text-decoration: none;
429
-@ font-weight: bold;
430
-@ }
431
-@ td.difftxt del > del.edit {
432
-@ background-color: #c0c0ff;
433
-@ text-decoration: none;
434
-@ font-weight: bold;
435
-@ }
436
-@ td.difftxt ins {
437
-@ background-color: #a2dbb2;
438
-@ color: #000000;
439
-@ text-decoration: none;
440
-@ line-height: inherit;
441
-@ font-size: inherit;
442
-@ }
443
-@ td.difftxt ins > ins {
444
-@ background-color: #559855;
445
-@ text-decoration: none;
446
-@ font-weight: bold;
447
-@ }
448
-@ td.difftxt ins > ins.edit {
449
-@ background-color: #c0c0ff;
450
-@ text-decoration: none;
451
-@ font-weight: bold;
452
-@ }
453
-@
361
+@ text-align: left;
362
+@ margin: 0;
363
+@ padding: 0;
364
+@ border: 0;
365
+@ font-family: monospace;
366
+@ line-height: 1.2;
367
+@ text-size-adjust: none;
368
+@ white-space: pre-wrap;
369
+@ word-wrap: break-word;
370
+@ }
371
+@ table.diff td.diffln {
372
+@ width: 0%;
373
+@ text-align: right;
374
+@ padding: 0 0.16em 0 0.32em;
375
+@ }
376
+@ table.diff td.difflne {
377
+@ text-align: left;
378
+@ padding: 0 0.32em;
379
+@ }
380
+@ table.diff td.diffsep {
381
+@ width: 0%;
382
+@ padding: 0 0.32em 0 0.16em;
383
+@ }
384
+@ td.difftxt {
385
+@ max-width: 0;
386
+@ }
387
+@ td.difftxtu {
388
+@ width: 100%;
389
+@ }
390
+@ td.difftxtl,
391
+@ td.difftxtr {
392
+@ width: 50%;
393
+@ }
394
+@ td.diffln.nul,
395
+@ td.diffsep.nul,
396
+@ td.difftxt.nul {
397
+@ background-color: #454545;
398
+@ }
399
+@ td.diffln.del,
400
+@ td.diffsep.del,
401
+@ td.difftxt.del {
402
+@ color: #000;
403
+@ background-color: #f9cfcf;
404
+@ }
405
+@ td.diffln.ins,
406
+@ td.diffsep.ins,
407
+@ td.difftxt.ins {
408
+@ color: #000;
409
+@ background-color: #a2dbb2;
410
+@ }
411
+@ td.difftxt.del del {
412
+@ color: #000;
413
+@ background-color: #cc5555;
414
+@ text-decoration: none;
415
+@ display: inline-block;
416
+@ }
417
+@ td.difftxt.del del.edit {
418
+@ background-color: #c0c0ff;
419
+@ }
420
+@ td.difftxt.ins ins {
421
+@ background-color: #559855;
422
+@ text-decoration: none;
423
+@ display: inline-block;
424
+@ }
425
+@ td.difftxt.ins ins.edit {
426
+@ background-color: #c0c0ff;
427
+@ }
454428
@ </style>
455429
@ </head>
456430
@ <body>
457431
;
458432
const char zWebpageEnd[] =
459433
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -230,123 +230,111 @@
230 @ background-color: white;
231 @ }
232 @ h1 {
233 @ font-size: 150%;
234 @ }
235 @
236 @ table.diff {
237 @ width: 100%;
238 @ border-spacing: 0;
 
239 @ border: 1px solid black;
240 @ line-height: inherit;
241 @ font-size: inherit;
242 @ }
243 @ table.diff td {
244 @ vertical-align: top;
245 @ line-height: inherit;
246 @ font-size: inherit;
247 @ }
248 @ table.diff pre {
249 @ margin: 0 0 0 0;
250 @ line-height: inherit;
251 @ font-size: inherit;
252 @ }
253 @ td.diffln {
254 @ width: 1px;
255 @ text-align: right;
256 @ padding: 0 1em 0 0;
257 @ }
258 @ td.difflne {
259 @ padding-bottom: 0.4em;
260 @ }
261 @ td.diffsep {
262 @ width: 1px;
263 @ padding: 0 0.3em 0 1em;
264 @ line-height: inherit;
265 @ font-size: inherit;
266 @ }
267 @ td.diffsep pre {
268 @ line-height: inherit;
269 @ font-size: inherit;
270 @ }
271 @ td.difftxt pre {
272 @ overflow-x: auto;
273 @ }
274 @ td.diffln ins {
275 @ background-color: #a0e4b2;
276 @ text-decoration: none;
277 @ line-height: inherit;
278 @ font-size: inherit;
279 @ }
280 @ td.diffln del {
281 @ background-color: #ffc0c0;
282 @ text-decoration: none;
283 @ line-height: inherit;
284 @ font-size: inherit;
285 @ }
286 @ td.difftxt del {
287 @ background-color: #ffe8e8;
288 @ text-decoration: none;
289 @ line-height: inherit;
290 @ font-size: inherit;
291 @ }
292 @ td.difftxt del > del {
293 @ background-color: #ffc0c0;
294 @ text-decoration: none;
295 @ font-weight: bold;
296 @ }
297 @ td.difftxt del > del.edit {
298 @ background-color: #c0c0ff;
299 @ text-decoration: none;
300 @ font-weight: bold;
301 @ }
302 @ td.difftxt ins {
303 @ background-color: #dafbe1;
304 @ text-decoration: none;
305 @ line-height: inherit;
306 @ font-size: inherit;
307 @ }
308 @ td.difftxt ins > ins {
309 @ background-color: #a0e4b2;
310 @ text-decoration: none;
311 @ font-weight: bold;
312 @ }
313 @ td.difftxt ins > ins.edit {
314 @ background-color: #c0c0ff;
315 @ text-decoration: none;
316 @ font-weight: bold;
317 @ }
318 @ @media (prefers-color-scheme: dark) {
319 @ body {
320 @ background-color: #353535;
321 @ color: #ffffff;
322 @ }
323 @ td.diffln ins {
324 @ background-color: #559855;
325 @ color: #000000;
326 @ }
327 @ td.diffln del {
328 @ background-color: #cc5555;
329 @ color: #000000;
330 @ }
331 @ td.difftxt del {
332 @ background-color: #f9cfcf;
333 @ color: #000000;
334 @ }
335 @ td.difftxt del > del {
336 @ background-color: #cc5555;
337 @ color: #000000;
338 @ }
339 @ td.difftxt ins {
340 @ background-color: #a2dbb2;
341 @ color: #000000;
342 @ }
343 @ td.difftxt ins > ins {
344 @ background-color: #559855;
345 @ }
346 @ }
347 @
348 @ </style>
349 @ </head>
350 @ <body>
351 ;
352 static const char zWebpageHdrDark[] =
@@ -354,105 +342,91 @@
354 @ <html>
355 @ <head>
356 @ <meta charset="UTF-8">
357 @ <style>
358 @ body {
 
359 @ background-color: #353535;
360 @ color: #ffffff;
361 @ }
362 @ h1 {
363 @ font-size: 150%;
364 @ }
365 @
366 @ table.diff {
367 @ width: 100%;
368 @ border-spacing: 0;
 
369 @ border: 1px solid black;
370 @ line-height: inherit;
371 @ font-size: inherit;
372 @ }
373 @ table.diff td {
374 @ vertical-align: top;
375 @ line-height: inherit;
376 @ font-size: inherit;
377 @ }
378 @ table.diff pre {
379 @ margin: 0 0 0 0;
380 @ line-height: inherit;
381 @ font-size: inherit;
382 @ }
383 @ td.diffln {
384 @ width: 1px;
385 @ text-align: right;
386 @ padding: 0 1em 0 0;
387 @ }
388 @ td.difflne {
389 @ padding-bottom: 0.4em;
390 @ }
391 @ td.diffsep {
392 @ width: 1px;
393 @ padding: 0 0.3em 0 1em;
394 @ line-height: inherit;
395 @ font-size: inherit;
396 @ }
397 @ td.diffsep pre {
398 @ line-height: inherit;
399 @ font-size: inherit;
400 @ }
401 @ td.difftxt pre {
402 @ overflow-x: auto;
403 @ }
404 @ td.diffln ins {
405 @ background-color: #559855;
406 @ color: #000000;
407 @ text-decoration: none;
408 @ line-height: inherit;
409 @ font-size: inherit;
410 @ }
411 @ td.diffln del {
412 @ background-color: #cc5555;
413 @ color: #000000;
414 @ text-decoration: none;
415 @ line-height: inherit;
416 @ font-size: inherit;
417 @ }
418 @ td.difftxt del {
419 @ background-color: #f9cfcf;
420 @ color: #000000;
421 @ text-decoration: none;
422 @ line-height: inherit;
423 @ font-size: inherit;
424 @ }
425 @ td.difftxt del > del {
426 @ background-color: #cc5555;
427 @ color: #000000;
428 @ text-decoration: none;
429 @ font-weight: bold;
430 @ }
431 @ td.difftxt del > del.edit {
432 @ background-color: #c0c0ff;
433 @ text-decoration: none;
434 @ font-weight: bold;
435 @ }
436 @ td.difftxt ins {
437 @ background-color: #a2dbb2;
438 @ color: #000000;
439 @ text-decoration: none;
440 @ line-height: inherit;
441 @ font-size: inherit;
442 @ }
443 @ td.difftxt ins > ins {
444 @ background-color: #559855;
445 @ text-decoration: none;
446 @ font-weight: bold;
447 @ }
448 @ td.difftxt ins > ins.edit {
449 @ background-color: #c0c0ff;
450 @ text-decoration: none;
451 @ font-weight: bold;
452 @ }
453 @
454 @ </style>
455 @ </head>
456 @ <body>
457 ;
458 const char zWebpageEnd[] =
459
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -230,123 +230,111 @@
230 @ background-color: white;
231 @ }
232 @ h1 {
233 @ font-size: 150%;
234 @ }
 
235 @ table.diff {
236 @ width: 100%;
237 @ border-spacing: 0;
238 @ border-radius: 5px;
239 @ border: 1px solid black;
 
 
240 @ }
241 @ table.diff td {
242 @ vertical-align: top;
243 @ text-align: left;
244 @ margin: 0;
245 @ padding: 0;
246 @ border: 0;
247 @ font-family: monospace;
248 @ line-height: 1.2;
249 @ text-size-adjust: none;
250 @ white-space: pre-wrap;
251 @ word-wrap: break-word;
252 @ }
253 @ table.diff td.diffln {
254 @ width: 0%;
255 @ text-align: right;
256 @ padding: 0 0.16em 0 0.32em;
257 @ }
258 @ table.diff td.difflne {
259 @ text-align: left;
260 @ padding: 0 0.32em;
261 @ }
262 @ table.diff td.diffsep {
263 @ width: 0%;
264 @ padding: 0 0.32em 0 0.16em;
265 @ }
266 @ td.difftxt {
267 @ max-width: 0;
268 @ }
269 @ td.difftxtu {
270 @ width: 100%;
271 @ }
272 @ td.difftxtl,
273 @ td.difftxtr {
274 @ width: 50%;
275 @ }
276 @ td.diffln.nul,
277 @ td.diffsep.nul,
278 @ td.difftxt.nul {
279 @ background-color: #f9f9f9;
280 @ }
281 @ td.diffln.del,
282 @ td.diffsep.del,
283 @ td.difftxt.del {
284 @ background-color: #ffe8e8;
285 @ }
286 @ td.diffln.ins,
287 @ td.diffsep.ins,
288 @ td.difftxt.ins {
289 @ background-color: #dafbe1;
290 @ }
291 @ td.difftxt.del del {
292 @ background-color: #ffc0c0;
293 @ text-decoration: none;
294 @ display: inline-block;
295 @ }
296 @ td.difftxt.del del.edit {
297 @ background-color: #c0c0ff;
298 @ }
299 @ td.difftxt.ins ins {
300 @ background-color: #a0e4b2;
301 @ text-decoration: none;
302 @ display: inline-block;
303 @ }
304 @ td.difftxt.ins ins.edit {
305 @ background-color: #c0c0ff;
 
 
 
 
 
 
 
 
 
306 @ }
307 @ @media (prefers-color-scheme: dark) {
308 @ body {
309 @ color: #fff;
310 @ background-color: #353535;
311 @ }
312 @ td.diffln.nul,
313 @ td.diffsep.nul,
314 @ td.difftxt.nul {
315 @ background-color: #454545;
316 @ }
317 @ td.diffln.del,
318 @ td.diffsep.del,
319 @ td.difftxt.del {
320 @ color: #000;
321 @ background-color: #f9cfcf;
322 @ }
323 @ td.diffln.ins,
324 @ td.diffsep.ins,
325 @ td.difftxt.ins {
326 @ color: #000;
327 @ background-color: #a2dbb2;
328 @ }
329 @ td.difftxt.del del {
330 @ background-color: #cc5555;
331 @ }
332 @ td.difftxt.ins ins {
333 @ background-color: #559855;
334 @ }
335 @ }
 
336 @ </style>
337 @ </head>
338 @ <body>
339 ;
340 static const char zWebpageHdrDark[] =
@@ -354,105 +342,91 @@
342 @ <html>
343 @ <head>
344 @ <meta charset="UTF-8">
345 @ <style>
346 @ body {
347 @ color: #fff;
348 @ background-color: #353535;
 
349 @ }
350 @ h1 {
351 @ font-size: 150%;
352 @ }
 
353 @ table.diff {
354 @ width: 100%;
355 @ border-spacing: 0;
356 @ border-radius: 5px;
357 @ border: 1px solid black;
 
 
358 @ }
359 @ table.diff td {
360 @ vertical-align: top;
361 @ text-align: left;
362 @ margin: 0;
363 @ padding: 0;
364 @ border: 0;
365 @ font-family: monospace;
366 @ line-height: 1.2;
367 @ text-size-adjust: none;
368 @ white-space: pre-wrap;
369 @ word-wrap: break-word;
370 @ }
371 @ table.diff td.diffln {
372 @ width: 0%;
373 @ text-align: right;
374 @ padding: 0 0.16em 0 0.32em;
375 @ }
376 @ table.diff td.difflne {
377 @ text-align: left;
378 @ padding: 0 0.32em;
379 @ }
380 @ table.diff td.diffsep {
381 @ width: 0%;
382 @ padding: 0 0.32em 0 0.16em;
383 @ }
384 @ td.difftxt {
385 @ max-width: 0;
386 @ }
387 @ td.difftxtu {
388 @ width: 100%;
389 @ }
390 @ td.difftxtl,
391 @ td.difftxtr {
392 @ width: 50%;
393 @ }
394 @ td.diffln.nul,
395 @ td.diffsep.nul,
396 @ td.difftxt.nul {
397 @ background-color: #454545;
398 @ }
399 @ td.diffln.del,
400 @ td.diffsep.del,
401 @ td.difftxt.del {
402 @ color: #000;
403 @ background-color: #f9cfcf;
404 @ }
405 @ td.diffln.ins,
406 @ td.diffsep.ins,
407 @ td.difftxt.ins {
408 @ color: #000;
409 @ background-color: #a2dbb2;
410 @ }
411 @ td.difftxt.del del {
412 @ color: #000;
413 @ background-color: #cc5555;
414 @ text-decoration: none;
415 @ display: inline-block;
416 @ }
417 @ td.difftxt.del del.edit {
418 @ background-color: #c0c0ff;
419 @ }
420 @ td.difftxt.ins ins {
421 @ background-color: #559855;
422 @ text-decoration: none;
423 @ display: inline-block;
424 @ }
425 @ td.difftxt.ins ins.edit {
426 @ background-color: #c0c0ff;
427 @ }
 
 
 
 
 
 
 
 
 
 
 
 
428 @ </style>
429 @ </head>
430 @ <body>
431 ;
432 const char zWebpageEnd[] =
433
+66 -142
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -93,22 +93,12 @@
9393
GIGO applies. Returns the starting line number if getStart, else
9494
the ending line number. Returns the line number from the LHS file
9595
if getLHS is true, else the RHS.
9696
*/
9797
const extractLineNo = function f(getLHS, getStart, tr, isSplit){
98
- if(!f.rx){
99
- f.rx = {
100
- start: /^\s*(\d+)/,
101
- end: /(\d+)\n?$/
102
- }
103
- }
104
- const td = tr.querySelector('td:nth-child('+(
105
- /* TD element with the line numbers */
106
- getLHS ? 1 : (isSplit ? 4 : 2)
107
- )+')');
108
- const m = f.rx[getStart ? 'start' : 'end'].exec(td.innerText);
109
- return m ? +m[1] : undefined/*"shouldn't happen"*/;
98
+ var n = getLHS ? 0 : isSplit ? 3 : 1;
99
+ return parseInt(tr.childNodes[n].innerText);
110100
};
111101
112102
/**
113103
Installs chunk-loading controls into TR.diffskip element tr.
114104
Each instance corresponds to a single TR.diffskip element.
@@ -136,11 +126,11 @@
136126
endLhs: +tr.dataset.endln
137127
};
138128
D.clearElement(tr);
139129
this.e.td = D.addClass(
140130
/* Holder for our UI controls */
141
- D.attr(D.td(tr), 'colspan', this.isSplit ? 5 : 4),
131
+ D.attr(D.td(tr), 'colspan', this.isSplit ? 6 : 4),
142132
'chunkctrl'
143133
);
144134
this.e.msgWidget = D.addClass(D.span(), 'hidden');
145135
this.e.btnWrapper = D.div();
146136
D.append(this.e.td, this.e.btnWrapper);
@@ -301,157 +291,91 @@
301291
/* No more data to load */
302292
this.destroy();
303293
return this;
304294
}
305295
this.msg(false);
306
- //console.debug("Loaded line range ",
307
- //urlParam.from,"-",urlParam.to, "fetchType ",fetchType);
308
- const lineno = [],
309
- trPrev = this.e.tr.previousElementSibling,
310
- trNext = this.e.tr.nextElementSibling,
311
- doAppend = (
312
- !!trPrev && fetchType>=this.FetchType.FillGap
313
- ) /* true to append to previous TR, else prepend to NEXT TR */;
314
- const tr = doAppend ? trPrev : trNext;
315
- const joinTr = (
316
- this.FetchType.FillGap===fetchType && trPrev && trNext
317
- ) ? trNext : false
318
- /* Truthy if we want to combine trPrev, the new content, and
319
- trNext into trPrev and then remove trNext. */;
320
- let i, td;
321
- if(!f.convertLines){
322
- /* Reminder: string.replaceAll() is a relatively new
323
- JS feature, not available in some still-widely-used
324
- browser versions. */
325
- f.rx = [[/&/g, '&amp;'], [/</g, '&lt;']];
326
- f.convertLines = function(li){
327
- var s = li.join('\n');
328
- f.rx.forEach((a)=>s=s.replace(a[0],a[1]));
329
- return s + '\n';
330
- };
331
- }
332
- if(1){ // LHS line numbers...
333
- const selector = '.difflnl > pre';
334
- td = tr.querySelector(selector);
335
- const lnTo = Math.min(urlParam.to,
336
- urlParam.from +
337
- lines.length - 1/*b/c request range is inclusive*/);
338
- for( i = urlParam.from; i <= lnTo; ++i ){
339
- lineno.push(i);
340
- }
341
- const lineNoTxt = lineno.join('\n')+'\n';
342
- const content = [td.innerHTML];
343
- if(doAppend) content.push(lineNoTxt);
344
- else content.unshift(lineNoTxt);
345
- if(joinTr){
346
- content.push(trNext.querySelector(selector).innerHTML);
347
- }
348
- td.innerHTML = content.join('');
349
- }
350
-
351
- if(1){// code block(s)...
352
- const selector = '.difftxt > pre';
353
- td = tr.querySelectorAll(selector);
354
- const code = f.convertLines(lines);
355
- let joinNdx = 0/*selector[X] index to join together*/;
356
- td.forEach(function(e){
357
- const content = [e.innerHTML];
358
- if(doAppend) content.push(code);
359
- else content.unshift(code);
360
- if(joinTr){
361
- content.push(trNext.querySelectorAll(selector)[joinNdx++].innerHTML)
362
- }
363
- e.innerHTML = content.join('');
364
- });
365
- }
366
-
367
- if(1){// Add blank lines in (.diffsep>pre)
368
- const selector = '.diffsep > pre';
369
- td = tr.querySelector(selector);
370
- for(i = 0; i < lineno.length; ++i) lineno[i] = '';
371
- const blanks = lineno.join('\n')+'\n';
372
- const content = [td.innerHTML];
373
- if(doAppend) content.push(blanks);
374
- else content.unshift(blanks);
375
- if(joinTr){
376
- content.push(trNext.querySelector(selector).innerHTML);
377
- }
378
- td.innerHTML = content.join('');
379
- }
380
-
381
- if(this.FetchType.FillGap===fetchType){
382
- /* Closing the whole gap between two chunks or a whole gap
383
- at the start or end of a diff. */
384
- // RHS line numbers...
385
- let startLnR = this.pos.prev
386
- ? this.pos.prev.endRhs+1 /* Closing the whole gap between two chunks
387
- or end-of-file gap. */
388
- : this.pos.next.startRhs - lines.length /* start-of-file gap */;
389
- lineno.length = lines.length;
390
- for( i = startLnR; i < startLnR + lines.length; ++i ){
391
- lineno[i-startLnR] = i;
392
- }
393
- const selector = '.difflnr > pre';
394
- td = tr.querySelector(selector);
395
- const lineNoTxt = lineno.join('\n')+'\n';
396
- lineno.length = 0;
397
- const content = [td.innerHTML];
398
- if(doAppend) content.push(lineNoTxt);
399
- else content.unshift(lineNoTxt);
400
- if(joinTr){
401
- content.push(trNext.querySelector(selector).innerHTML);
402
- }
403
- td.innerHTML = content.join('');
404
- if(joinTr) D.remove(joinTr);
296
+ var startLnR = -2147483648; /* ⚠ */
297
+ switch( fetchType ){
298
+ case this.FetchType.PrevDown:
299
+ startLnR = this.pos.prev.endRhs + 1;
300
+ break;
301
+ case this.FetchType.NextUp:
302
+ startLnR = this.pos.next.startRhs - lines.length;
303
+ break;
304
+ case this.FetchType.FillGap:
305
+ startLnR = this.pos.prev ?
306
+ this.pos.prev.endRhs + 1 :
307
+ this.pos.next.startRhs - lines.length;
308
+ break;
309
+ }
310
+ const lnTo = Math.min(urlParam.to,
311
+ urlParam.from +
312
+ lines.length - 1/*b/c request range is inclusive*/);
313
+ function createDiffCommonLine(isSplit,lnl,lnr,txt){
314
+ var tr, td;
315
+ tr = document.createElement('tr');
316
+ tr.className = 'diffline';
317
+ td = document.createElement('td');
318
+ td.className = 'diffln difflnl';
319
+ td.appendChild(document.createTextNode(lnl));
320
+ tr.appendChild(td);
321
+ if( isSplit ){
322
+ td = document.createElement('td');
323
+ td.className = 'diffsep';
324
+ tr.appendChild(td);
325
+ td = document.createElement('td');
326
+ td.className = 'difftxt difftxtl';
327
+ td.appendChild(document.createTextNode(txt));
328
+ tr.appendChild(td);
329
+ }
330
+ td = document.createElement('td');
331
+ td.className = 'diffln difflnlr';
332
+ td.appendChild(document.createTextNode(lnr));
333
+ tr.appendChild(td);
334
+ td = document.createElement('td');
335
+ td.className = 'diffsep';
336
+ tr.appendChild(td);
337
+ td = document.createElement('td');
338
+ td.className = 'difftxt difftxt' + isSplit ? 'r' : 'u';
339
+ td.appendChild(document.createTextNode(txt));
340
+ tr.appendChild(td);
341
+ return tr;
342
+ }
343
+ if( fetchType==this.FetchType.NextUp ){
344
+ for( i=lnTo; i>=urlParam.from; i-- ){
345
+ var tr =
346
+ createDiffCommonLine(
347
+ this.isSplit,i,startLnR+i-urlParam.from,lines[i-urlParam.from]);
348
+ this.e.tr.parentElement.insertBefore(tr,this.e.tr.nextElementSibling);
349
+ }
350
+ }else{
351
+ for( i=urlParam.from; i<=lnTo; i++ ){
352
+ var tr =
353
+ createDiffCommonLine(
354
+ this.isSplit,i,startLnR+i-urlParam.from,lines[i-urlParam.from]);
355
+ this.e.tr.parentElement.insertBefore(tr,this.e.tr);
356
+ }
357
+ }
358
+ if(this.FetchType.FillGap===fetchType){
405359
this.destroy();
406360
return this;
407361
}else if(this.FetchType.PrevDown===fetchType){
408
- /* Append context to previous TR. */
409
- // RHS line numbers...
410
- let startLnR = this.pos.prev.endRhs+1;
411
- lineno.length = lines.length;
412
- for( i = startLnR; i < startLnR + lines.length; ++i ){
413
- lineno[i-startLnR] = i;
414
- }
415362
this.pos.startLhs += lines.length;
416363
this.pos.prev.endRhs += lines.length;
417364
this.pos.prev.endLhs += lines.length;
418
- const selector = '.difflnr > pre';
419
- td = tr.querySelector(selector);
420
- const lineNoTxt = lineno.join('\n')+'\n';
421
- lineno.length = 0;
422
- const content = [td.innerHTML];
423
- if(doAppend) content.push(lineNoTxt);
424
- else content.unshift(lineNoTxt);
425
- td.innerHTML = content.join('');
426365
if(lines.length < (urlParam.to - urlParam.from)){
427366
/* No more data. */
428367
this.destroy();
429368
}else{
430369
this.maybeReplaceButtons();
431370
this.updatePosDebug();
432371
}
433372
return this;
434373
}else if(this.FetchType.NextUp===fetchType){
435
- /* Prepend content to next TR. */
436
- // RHS line numbers...
437
- if(doAppend){
438
- throw new Error("Internal precondition violation: doAppend is true.");
439
- }
440
- let startLnR = this.pos.next.startRhs - lines.length;
441
- lineno.length = lines.length;
442
- for( i = startLnR; i < startLnR + lines.length; ++i ){
443
- lineno[i-startLnR] = i;
444
- }
445374
this.pos.endLhs -= lines.length;
446375
this.pos.next.startRhs -= lines.length;
447376
this.pos.next.startLhs -= lines.length;
448
- const selector = '.difflnr > pre';
449
- td = tr.querySelector(selector);
450
- const lineNoTxt = lineno.join('\n')+'\n';
451
- lineno.length = 0;
452
- td.innerHTML = lineNoTxt + td.innerHTML;
453377
if(this.pos.endLhs<1
454378
|| lines.length < (urlParam.to - urlParam.from)){
455379
/* No more data. */
456380
this.destroy();
457381
}else{
458382
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -93,22 +93,12 @@
93 GIGO applies. Returns the starting line number if getStart, else
94 the ending line number. Returns the line number from the LHS file
95 if getLHS is true, else the RHS.
96 */
97 const extractLineNo = function f(getLHS, getStart, tr, isSplit){
98 if(!f.rx){
99 f.rx = {
100 start: /^\s*(\d+)/,
101 end: /(\d+)\n?$/
102 }
103 }
104 const td = tr.querySelector('td:nth-child('+(
105 /* TD element with the line numbers */
106 getLHS ? 1 : (isSplit ? 4 : 2)
107 )+')');
108 const m = f.rx[getStart ? 'start' : 'end'].exec(td.innerText);
109 return m ? +m[1] : undefined/*"shouldn't happen"*/;
110 };
111
112 /**
113 Installs chunk-loading controls into TR.diffskip element tr.
114 Each instance corresponds to a single TR.diffskip element.
@@ -136,11 +126,11 @@
136 endLhs: +tr.dataset.endln
137 };
138 D.clearElement(tr);
139 this.e.td = D.addClass(
140 /* Holder for our UI controls */
141 D.attr(D.td(tr), 'colspan', this.isSplit ? 5 : 4),
142 'chunkctrl'
143 );
144 this.e.msgWidget = D.addClass(D.span(), 'hidden');
145 this.e.btnWrapper = D.div();
146 D.append(this.e.td, this.e.btnWrapper);
@@ -301,157 +291,91 @@
301 /* No more data to load */
302 this.destroy();
303 return this;
304 }
305 this.msg(false);
306 //console.debug("Loaded line range ",
307 //urlParam.from,"-",urlParam.to, "fetchType ",fetchType);
308 const lineno = [],
309 trPrev = this.e.tr.previousElementSibling,
310 trNext = this.e.tr.nextElementSibling,
311 doAppend = (
312 !!trPrev && fetchType>=this.FetchType.FillGap
313 ) /* true to append to previous TR, else prepend to NEXT TR */;
314 const tr = doAppend ? trPrev : trNext;
315 const joinTr = (
316 this.FetchType.FillGap===fetchType && trPrev && trNext
317 ) ? trNext : false
318 /* Truthy if we want to combine trPrev, the new content, and
319 trNext into trPrev and then remove trNext. */;
320 let i, td;
321 if(!f.convertLines){
322 /* Reminder: string.replaceAll() is a relatively new
323 JS feature, not available in some still-widely-used
324 browser versions. */
325 f.rx = [[/&/g, '&amp;'], [/</g, '&lt;']];
326 f.convertLines = function(li){
327 var s = li.join('\n');
328 f.rx.forEach((a)=>s=s.replace(a[0],a[1]));
329 return s + '\n';
330 };
331 }
332 if(1){ // LHS line numbers...
333 const selector = '.difflnl > pre';
334 td = tr.querySelector(selector);
335 const lnTo = Math.min(urlParam.to,
336 urlParam.from +
337 lines.length - 1/*b/c request range is inclusive*/);
338 for( i = urlParam.from; i <= lnTo; ++i ){
339 lineno.push(i);
340 }
341 const lineNoTxt = lineno.join('\n')+'\n';
342 const content = [td.innerHTML];
343 if(doAppend) content.push(lineNoTxt);
344 else content.unshift(lineNoTxt);
345 if(joinTr){
346 content.push(trNext.querySelector(selector).innerHTML);
347 }
348 td.innerHTML = content.join('');
349 }
350
351 if(1){// code block(s)...
352 const selector = '.difftxt > pre';
353 td = tr.querySelectorAll(selector);
354 const code = f.convertLines(lines);
355 let joinNdx = 0/*selector[X] index to join together*/;
356 td.forEach(function(e){
357 const content = [e.innerHTML];
358 if(doAppend) content.push(code);
359 else content.unshift(code);
360 if(joinTr){
361 content.push(trNext.querySelectorAll(selector)[joinNdx++].innerHTML)
362 }
363 e.innerHTML = content.join('');
364 });
365 }
366
367 if(1){// Add blank lines in (.diffsep>pre)
368 const selector = '.diffsep > pre';
369 td = tr.querySelector(selector);
370 for(i = 0; i < lineno.length; ++i) lineno[i] = '';
371 const blanks = lineno.join('\n')+'\n';
372 const content = [td.innerHTML];
373 if(doAppend) content.push(blanks);
374 else content.unshift(blanks);
375 if(joinTr){
376 content.push(trNext.querySelector(selector).innerHTML);
377 }
378 td.innerHTML = content.join('');
379 }
380
381 if(this.FetchType.FillGap===fetchType){
382 /* Closing the whole gap between two chunks or a whole gap
383 at the start or end of a diff. */
384 // RHS line numbers...
385 let startLnR = this.pos.prev
386 ? this.pos.prev.endRhs+1 /* Closing the whole gap between two chunks
387 or end-of-file gap. */
388 : this.pos.next.startRhs - lines.length /* start-of-file gap */;
389 lineno.length = lines.length;
390 for( i = startLnR; i < startLnR + lines.length; ++i ){
391 lineno[i-startLnR] = i;
392 }
393 const selector = '.difflnr > pre';
394 td = tr.querySelector(selector);
395 const lineNoTxt = lineno.join('\n')+'\n';
396 lineno.length = 0;
397 const content = [td.innerHTML];
398 if(doAppend) content.push(lineNoTxt);
399 else content.unshift(lineNoTxt);
400 if(joinTr){
401 content.push(trNext.querySelector(selector).innerHTML);
402 }
403 td.innerHTML = content.join('');
404 if(joinTr) D.remove(joinTr);
405 this.destroy();
406 return this;
407 }else if(this.FetchType.PrevDown===fetchType){
408 /* Append context to previous TR. */
409 // RHS line numbers...
410 let startLnR = this.pos.prev.endRhs+1;
411 lineno.length = lines.length;
412 for( i = startLnR; i < startLnR + lines.length; ++i ){
413 lineno[i-startLnR] = i;
414 }
415 this.pos.startLhs += lines.length;
416 this.pos.prev.endRhs += lines.length;
417 this.pos.prev.endLhs += lines.length;
418 const selector = '.difflnr > pre';
419 td = tr.querySelector(selector);
420 const lineNoTxt = lineno.join('\n')+'\n';
421 lineno.length = 0;
422 const content = [td.innerHTML];
423 if(doAppend) content.push(lineNoTxt);
424 else content.unshift(lineNoTxt);
425 td.innerHTML = content.join('');
426 if(lines.length < (urlParam.to - urlParam.from)){
427 /* No more data. */
428 this.destroy();
429 }else{
430 this.maybeReplaceButtons();
431 this.updatePosDebug();
432 }
433 return this;
434 }else if(this.FetchType.NextUp===fetchType){
435 /* Prepend content to next TR. */
436 // RHS line numbers...
437 if(doAppend){
438 throw new Error("Internal precondition violation: doAppend is true.");
439 }
440 let startLnR = this.pos.next.startRhs - lines.length;
441 lineno.length = lines.length;
442 for( i = startLnR; i < startLnR + lines.length; ++i ){
443 lineno[i-startLnR] = i;
444 }
445 this.pos.endLhs -= lines.length;
446 this.pos.next.startRhs -= lines.length;
447 this.pos.next.startLhs -= lines.length;
448 const selector = '.difflnr > pre';
449 td = tr.querySelector(selector);
450 const lineNoTxt = lineno.join('\n')+'\n';
451 lineno.length = 0;
452 td.innerHTML = lineNoTxt + td.innerHTML;
453 if(this.pos.endLhs<1
454 || lines.length < (urlParam.to - urlParam.from)){
455 /* No more data. */
456 this.destroy();
457 }else{
458
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -93,22 +93,12 @@
93 GIGO applies. Returns the starting line number if getStart, else
94 the ending line number. Returns the line number from the LHS file
95 if getLHS is true, else the RHS.
96 */
97 const extractLineNo = function f(getLHS, getStart, tr, isSplit){
98 var n = getLHS ? 0 : isSplit ? 3 : 1;
99 return parseInt(tr.childNodes[n].innerText);
 
 
 
 
 
 
 
 
 
 
100 };
101
102 /**
103 Installs chunk-loading controls into TR.diffskip element tr.
104 Each instance corresponds to a single TR.diffskip element.
@@ -136,11 +126,11 @@
126 endLhs: +tr.dataset.endln
127 };
128 D.clearElement(tr);
129 this.e.td = D.addClass(
130 /* Holder for our UI controls */
131 D.attr(D.td(tr), 'colspan', this.isSplit ? 6 : 4),
132 'chunkctrl'
133 );
134 this.e.msgWidget = D.addClass(D.span(), 'hidden');
135 this.e.btnWrapper = D.div();
136 D.append(this.e.td, this.e.btnWrapper);
@@ -301,157 +291,91 @@
291 /* No more data to load */
292 this.destroy();
293 return this;
294 }
295 this.msg(false);
296 var startLnR = -2147483648; /* ⚠ */
297 switch( fetchType ){
298 case this.FetchType.PrevDown:
299 startLnR = this.pos.prev.endRhs + 1;
300 break;
301 case this.FetchType.NextUp:
302 startLnR = this.pos.next.startRhs - lines.length;
303 break;
304 case this.FetchType.FillGap:
305 startLnR = this.pos.prev ?
306 this.pos.prev.endRhs + 1 :
307 this.pos.next.startRhs - lines.length;
308 break;
309 }
310 const lnTo = Math.min(urlParam.to,
311 urlParam.from +
312 lines.length - 1/*b/c request range is inclusive*/);
313 function createDiffCommonLine(isSplit,lnl,lnr,txt){
314 var tr, td;
315 tr = document.createElement('tr');
316 tr.className = 'diffline';
317 td = document.createElement('td');
318 td.className = 'diffln difflnl';
319 td.appendChild(document.createTextNode(lnl));
320 tr.appendChild(td);
321 if( isSplit ){
322 td = document.createElement('td');
323 td.className = 'diffsep';
324 tr.appendChild(td);
325 td = document.createElement('td');
326 td.className = 'difftxt difftxtl';
327 td.appendChild(document.createTextNode(txt));
328 tr.appendChild(td);
329 }
330 td = document.createElement('td');
331 td.className = 'diffln difflnlr';
332 td.appendChild(document.createTextNode(lnr));
333 tr.appendChild(td);
334 td = document.createElement('td');
335 td.className = 'diffsep';
336 tr.appendChild(td);
337 td = document.createElement('td');
338 td.className = 'difftxt difftxt' + isSplit ? 'r' : 'u';
339 td.appendChild(document.createTextNode(txt));
340 tr.appendChild(td);
341 return tr;
342 }
343 if( fetchType==this.FetchType.NextUp ){
344 for( i=lnTo; i>=urlParam.from; i-- ){
345 var tr =
346 createDiffCommonLine(
347 this.isSplit,i,startLnR+i-urlParam.from,lines[i-urlParam.from]);
348 this.e.tr.parentElement.insertBefore(tr,this.e.tr.nextElementSibling);
349 }
350 }else{
351 for( i=urlParam.from; i<=lnTo; i++ ){
352 var tr =
353 createDiffCommonLine(
354 this.isSplit,i,startLnR+i-urlParam.from,lines[i-urlParam.from]);
355 this.e.tr.parentElement.insertBefore(tr,this.e.tr);
356 }
357 }
358 if(this.FetchType.FillGap===fetchType){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
359 this.destroy();
360 return this;
361 }else if(this.FetchType.PrevDown===fetchType){
 
 
 
 
 
 
 
362 this.pos.startLhs += lines.length;
363 this.pos.prev.endRhs += lines.length;
364 this.pos.prev.endLhs += lines.length;
 
 
 
 
 
 
 
 
365 if(lines.length < (urlParam.to - urlParam.from)){
366 /* No more data. */
367 this.destroy();
368 }else{
369 this.maybeReplaceButtons();
370 this.updatePosDebug();
371 }
372 return this;
373 }else if(this.FetchType.NextUp===fetchType){
 
 
 
 
 
 
 
 
 
 
374 this.pos.endLhs -= lines.length;
375 this.pos.next.startRhs -= lines.length;
376 this.pos.next.startLhs -= lines.length;
 
 
 
 
 
377 if(this.pos.endLhs<1
378 || lines.length < (urlParam.to - urlParam.from)){
379 /* No more data. */
380 this.destroy();
381 }else{
382

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button