Fossil SCM

Initial go at using CSS grid layout for side-by-side diffs, rather than using JS to dynamically fit the columns. See discussion at [forum:93398561d3986c41|forum post 93398561d3986c41].

stephan 2024-07-30 12:03 trunk
Commit 375f2af4841c17ee76b9e064f44635bdfb53d490dda47da8434cec12fcd768e6
+20 -3
--- src/default.css
+++ src/default.css
@@ -663,27 +663,44 @@
663663
content: '⇣';
664664
}
665665
tr.diffskip > td.chunkctrl .jcbutton.up.down > span::before {
666666
content: '⇡⇣';
667667
}
668
-
669668
tr.diffskip > td.chunkctrl .jcbutton:hover {
670669
cursor: pointer;
671670
opacity: 1;
672671
filter: contrast(1);
673672
}
673
+
674
+table.splitdiff tr.diffchunk {
675
+ display: grid;
676
+ gap: 0px 0px;
677
+ grid-template-rows: 1fr;
678
+ grid-template-columns: auto 1fr auto auto 1fr;
679
+ grid-template-areas: "difflnl difftxtl diffsep difflnr difftxtr";
680
+}
681
+table.udiff tr.diffchunk {
682
+ grid-template-columns: auto auto auto 1fr;
683
+ grid-template-areas: "difflnl difflnr diffsep difftxtu";
684
+}
685
+td.difflnr { grid-area: difflnr; }
686
+td.difftxtu { grid-area: difftxtu; }
687
+td.difftxtl { grid-area: difftxtl; }
688
+td.difftxtr { grid-area: difftxtr; }
674689
td.diffln {
675
- width: 1px;
690
+ width: fit-content;
676691
text-align: right;
677692
padding: 0 1em 0 0;
693
+ grid-area: difflnl;
678694
}
679695
td.difflne {
680696
padding-bottom: 0.4em;
681697
}
682698
td.diffsep {
683
- width: 1px;
699
+ width: fit-content;
684700
padding: 0 0.3em 0 0.5em;
701
+ grid-area: diffsep;
685702
}
686703
td.difftxt pre {
687704
overflow-x: auto;
688705
}
689706
td.diffln ins {
690707
--- src/default.css
+++ src/default.css
@@ -663,27 +663,44 @@
663 content: '⇣';
664 }
665 tr.diffskip > td.chunkctrl .jcbutton.up.down > span::before {
666 content: '⇡⇣';
667 }
668
669 tr.diffskip > td.chunkctrl .jcbutton:hover {
670 cursor: pointer;
671 opacity: 1;
672 filter: contrast(1);
673 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
674 td.diffln {
675 width: 1px;
676 text-align: right;
677 padding: 0 1em 0 0;
 
678 }
679 td.difflne {
680 padding-bottom: 0.4em;
681 }
682 td.diffsep {
683 width: 1px;
684 padding: 0 0.3em 0 0.5em;
 
685 }
686 td.difftxt pre {
687 overflow-x: auto;
688 }
689 td.diffln ins {
690
--- src/default.css
+++ src/default.css
@@ -663,27 +663,44 @@
663 content: '⇣';
664 }
665 tr.diffskip > td.chunkctrl .jcbutton.up.down > span::before {
666 content: '⇡⇣';
667 }
 
668 tr.diffskip > td.chunkctrl .jcbutton:hover {
669 cursor: pointer;
670 opacity: 1;
671 filter: contrast(1);
672 }
673
674 table.splitdiff tr.diffchunk {
675 display: grid;
676 gap: 0px 0px;
677 grid-template-rows: 1fr;
678 grid-template-columns: auto 1fr auto auto 1fr;
679 grid-template-areas: "difflnl difftxtl diffsep difflnr difftxtr";
680 }
681 table.udiff tr.diffchunk {
682 grid-template-columns: auto auto auto 1fr;
683 grid-template-areas: "difflnl difflnr diffsep difftxtu";
684 }
685 td.difflnr { grid-area: difflnr; }
686 td.difftxtu { grid-area: difftxtu; }
687 td.difftxtl { grid-area: difftxtl; }
688 td.difftxtr { grid-area: difftxtr; }
689 td.diffln {
690 width: fit-content;
691 text-align: right;
692 padding: 0 1em 0 0;
693 grid-area: difflnl;
694 }
695 td.difflne {
696 padding-bottom: 0.4em;
697 }
698 td.diffsep {
699 width: fit-content;
700 padding: 0 0.3em 0 0.5em;
701 grid-area: diffsep;
702 }
703 td.difftxt pre {
704 overflow-x: auto;
705 }
706 td.diffln ins {
707
+2 -2
--- src/diff.c
+++ src/diff.c
@@ -1286,11 +1286,11 @@
12861286
blob_append_xfer(p->pOut, &p->aCol[2]);
12871287
blob_append(p->pOut, "</pre></td></tr>\n", -1);
12881288
}
12891289
static void dfunifiedStartRow(DiffBuilder *p){
12901290
if( blob_size(&p->aCol[0])>0 ) return;
1291
- blob_appendf(p->pOut,"<tr id=\"chunk%d\">"
1291
+ blob_appendf(p->pOut,"<tr id=\"chunk%d\" class=\"diffchunk\">"
12921292
"<td class=\"diffln difflnl\"><pre>\n", ++nChunk);
12931293
}
12941294
static void dfunifiedSkip(DiffBuilder *p, unsigned int n, int isFinal){
12951295
dfunifiedFinishRow(p);
12961296
if( p->pCfg && p->pCfg->zLeftHash ){
@@ -1512,11 +1512,11 @@
15121512
blob_append_xfer(p->pOut, &p->aCol[3]);
15131513
blob_append(p->pOut, "</pre></td></tr>\n", -1);
15141514
}
15151515
static void dfsplitStartRow(DiffBuilder *p){
15161516
if( blob_size(&p->aCol[0])>0 ) return;
1517
- blob_appendf(p->pOut,"<tr id=\"chunk%d\">"
1517
+ blob_appendf(p->pOut,"<tr id=\"chunk%d\" class=\"diffchunk\">"
15181518
"<td class=\"diffln difflnl\"><pre>\n", ++nChunk);
15191519
p->eState = 0;
15201520
}
15211521
static void dfsplitSkip(DiffBuilder *p, unsigned int n, int isFinal){
15221522
dfsplitFinishRow(p);
15231523
--- src/diff.c
+++ src/diff.c
@@ -1286,11 +1286,11 @@
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\">"
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 ){
@@ -1512,11 +1512,11 @@
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\">"
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
--- src/diff.c
+++ src/diff.c
@@ -1286,11 +1286,11 @@
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 ){
@@ -1512,11 +1512,11 @@
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
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -106,11 +106,11 @@
106106
getLHS ? 1 : (isSplit ? 4 : 2)
107107
)+')');
108108
const m = f.rx[getStart ? 'start' : 'end'].exec(td.innerText);
109109
return m ? +m[1] : undefined/*"shouldn't happen"*/;
110110
};
111
-
111
+
112112
/**
113113
Installs chunk-loading controls into TR.diffskip element tr.
114114
Each instance corresponds to a single TR.diffskip element.
115115
116116
The goal is to base these controls roughly on github's, a good
@@ -638,10 +638,18 @@
638638
window.fossil.onPageLoad(function(){
639639
const SCROLL_LEN = 25;
640640
const F = window.fossil, D = F.dom, Diff = F.diff;
641641
var lastWidth;
642642
Diff.checkTableWidth = function f(force){
643
+ if(1){
644
+ return this;
645
+ /**
646
+ What follows is largely obsolete but we will want parts of it
647
+ if we decide to retain the synchronous-scroll feature of
648
+ SBS diffs (which we otherwise lose in the CSS-based reimplementation).
649
+ */
650
+ }
643651
if(undefined === f.contentNode){
644652
f.contentNode = document.querySelector('div.content');
645653
}
646654
force = true;
647655
const parentCS = window.getComputedStyle(f.contentNode);
@@ -750,12 +758,22 @@
750758
}, false);
751759
}
752760
}
753761
return this;
754762
}
755
- window.fossil.page.tweakSbsDiffs = function(){
756
- document.querySelectorAll('table.splitdiff').forEach((e)=>Diff.initTableDiff(e));
757
- Diff.checkTableWidth();
758
- };
759
- Diff.initTableDiff().checkTableWidth();
760
- window.addEventListener('resize', F.debounce(()=>Diff.checkTableWidth()));
763
+ if(0){
764
+ window.fossil.page.tweakSbsDiffs = function(){
765
+ document.querySelectorAll('table.splitdiff').forEach((e)=>Diff.initTableDiff(e));
766
+ Diff.checkTableWidth();
767
+ };
768
+ Diff.initTableDiff().checkTableWidth();
769
+ window.addEventListener('resize', F.debounce(()=>Diff.checkTableWidth()));
770
+ }else{
771
+ /* tweakSbsDiffs() is called by /fileedit and /wikieedit when it
772
+ runs an SBS diff. We _might_ want to retain this function to
773
+ re-enable synchronized sbs diff scrolling. If we decided to not
774
+ retain that feature with the CSS-based SBS diff, we can remove
775
+ this block and the corresponding calls to this function in
776
+ fossil.page.{wikiedit,fileedit}.js. */
777
+ window.fossil.page.tweakSbsDiffs = function(){};
778
+ }
761779
}, false);
762780
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -106,11 +106,11 @@
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.
115
116 The goal is to base these controls roughly on github's, a good
@@ -638,10 +638,18 @@
638 window.fossil.onPageLoad(function(){
639 const SCROLL_LEN = 25;
640 const F = window.fossil, D = F.dom, Diff = F.diff;
641 var lastWidth;
642 Diff.checkTableWidth = function f(force){
 
 
 
 
 
 
 
 
643 if(undefined === f.contentNode){
644 f.contentNode = document.querySelector('div.content');
645 }
646 force = true;
647 const parentCS = window.getComputedStyle(f.contentNode);
@@ -750,12 +758,22 @@
750 }, false);
751 }
752 }
753 return this;
754 }
755 window.fossil.page.tweakSbsDiffs = function(){
756 document.querySelectorAll('table.splitdiff').forEach((e)=>Diff.initTableDiff(e));
757 Diff.checkTableWidth();
758 };
759 Diff.initTableDiff().checkTableWidth();
760 window.addEventListener('resize', F.debounce(()=>Diff.checkTableWidth()));
 
 
 
 
 
 
 
 
 
 
761 }, false);
762
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -106,11 +106,11 @@
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.
115
116 The goal is to base these controls roughly on github's, a good
@@ -638,10 +638,18 @@
638 window.fossil.onPageLoad(function(){
639 const SCROLL_LEN = 25;
640 const F = window.fossil, D = F.dom, Diff = F.diff;
641 var lastWidth;
642 Diff.checkTableWidth = function f(force){
643 if(1){
644 return this;
645 /**
646 What follows is largely obsolete but we will want parts of it
647 if we decide to retain the synchronous-scroll feature of
648 SBS diffs (which we otherwise lose in the CSS-based reimplementation).
649 */
650 }
651 if(undefined === f.contentNode){
652 f.contentNode = document.querySelector('div.content');
653 }
654 force = true;
655 const parentCS = window.getComputedStyle(f.contentNode);
@@ -750,12 +758,22 @@
758 }, false);
759 }
760 }
761 return this;
762 }
763 if(0){
764 window.fossil.page.tweakSbsDiffs = function(){
765 document.querySelectorAll('table.splitdiff').forEach((e)=>Diff.initTableDiff(e));
766 Diff.checkTableWidth();
767 };
768 Diff.initTableDiff().checkTableWidth();
769 window.addEventListener('resize', F.debounce(()=>Diff.checkTableWidth()));
770 }else{
771 /* tweakSbsDiffs() is called by /fileedit and /wikieedit when it
772 runs an SBS diff. We _might_ want to retain this function to
773 re-enable synchronized sbs diff scrolling. If we decided to not
774 retain that feature with the CSS-based SBS diff, we can remove
775 this block and the corresponding calls to this function in
776 fossil.page.{wikiedit,fileedit}.js. */
777 window.fossil.page.tweakSbsDiffs = function(){};
778 }
779 }, false);
780

Keyboard Shortcuts

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