Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Refactored tr.diffsplit to hold enough information to allow partial chunk loads in either direction and to know where the next/previous chunks (if any) start/end. Actual loading is currently disabled, pending addition of controls which make use of this new state. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | diff-js-refactoring |
| Files: | files | file ages | folders |
| SHA3-256: |
cedcd3585b4cd8bd9997bca5de7e1f94 |
| User & Date: | stephan 2021-09-09 15:06:55.082 |
Context
|
2021-09-09
| ||
| 18:28 | Got jchunk loader buttons in place but they're currently non-functional. ... (check-in: 365ef58b8c user: stephan tags: diff-js-refactoring) | |
| 15:06 | Refactored tr.diffsplit to hold enough information to allow partial chunk loads in either direction and to know where the next/previous chunks (if any) start/end. Actual loading is currently disabled, pending addition of controls which make use of this new state. ... (check-in: cedcd3585b user: stephan tags: diff-js-refactoring) | |
| 15:01 | Fixed left/right arrow key scrolling in diff.js. ... (check-in: 566b7f1165 user: stephan tags: diff-js-refactoring) | |
Changes
Changes to src/default.css.
| ︙ | ︙ | |||
547 548 549 550 551 552 553 554 555 556 557 558 559 560 |
}
tr.diffskip.jchunk:hover {
/* jchunk gets added from JS to diffskip rows when they are
plugged into the /jchunk route and removed after that data
is fetched. */
background-color: rgba(127,127,127,0.5);
cursor: pointer;
}
td.diffln {
width: 1px;
text-align: right;
padding: 0 1em 0 0;
}
td.difflne {
| > > > > > > > > > > > > > > | 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 |
}
tr.diffskip.jchunk:hover {
/* jchunk gets added from JS to diffskip rows when they are
plugged into the /jchunk route and removed after that data
is fetched. */
background-color: rgba(127,127,127,0.5);
cursor: pointer;
}
tr.diffskip > td.chunkctrl {
text-align: left;
font-family: monospace;
/* Border is only for visibility during development. Remove it when done. */
border-width: 1px;
border-style: dotted;
}
tr.diffskip > td.chunkctrl > .button {
min-width: 1.5em;
min-height: 1.5em;
max-width: 1.5em;
max-height: 1.5em;
text-align: center;
}
td.diffln {
width: 1px;
text-align: right;
padding: 0 1em 0 0;
}
td.difflne {
|
| ︙ | ︙ |
Changes to src/fossil.diff.js.
| ︙ | ︙ | |||
78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
if(!fetchOpt.beforesend) fetchOpt.beforesend = Diff.config.chunkFetch.beforesend;
if(!fetchOpt.aftersend) fetchOpt.aftersend = Diff.config.chunkFetch.aftersend;
if(!fetchOpt.onerror) fetchOpt.onerror = Diff.config.chunkFetch.onerror;
fetchOpt.responseType = 'json';
return F.fetch('jchunk', fetchOpt);
};
/**
Fetches /jchunk for the given TR element then replaces the TR's
contents with data from the result of that request.
*/
const fetchTrChunk = function(tr){
if(tr.dataset.xfer /* already being fetched */) return;
const table = tr.parentElement.parentElement;
| > > > > > > > > > > > > > > > > > > > > > > > > | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
if(!fetchOpt.beforesend) fetchOpt.beforesend = Diff.config.chunkFetch.beforesend;
if(!fetchOpt.aftersend) fetchOpt.aftersend = Diff.config.chunkFetch.aftersend;
if(!fetchOpt.onerror) fetchOpt.onerror = Diff.config.chunkFetch.onerror;
fetchOpt.responseType = 'json';
return F.fetch('jchunk', fetchOpt);
};
/**
Extracts either the starting or ending line number from a
line-numer column in the given tr. isSplit must be true if tr
represents a split diff, else false. Expects its tr to be valid:
GIGO applies. Returns the starting line number if getStart, else
the ending line number. Returns the line number from the LHS file
if getLHS is true, else the RHS.
*/
const extractLineNo = function f(getLHS, getStart, tr, isSplit){
if(!f.rx){
f.rx = {
start: /^\s*(\d+)/,
end: /(\d+)\n?$/
}
}
const td = tr.querySelector('td:nth-child('+(
/* TD element with the line numbers */
getLHS ? 1 : (isSplit ? 4 : 2)
)+')');
const m = f.rx[getStart ? 'start' : 'end'].exec(td.innerText);
return m ? +m[1] : undefined/*"shouldn't happen"*/;
};
/**
Fetches /jchunk for the given TR element then replaces the TR's
contents with data from the result of that request.
*/
const fetchTrChunk = function(tr){
if(tr.dataset.xfer /* already being fetched */) return;
const table = tr.parentElement.parentElement;
|
| ︙ | ︙ | |||
145 146 147 148 149 150 151 |
D.append(cols[3], preCode[0]);
}
let lineno = [], i;
for( i = lineFrom; i <= lineTo; ++i ){
lineno.push(i);
}
preLines[0].append(lineno.join('\n')+'\n');
| > | | > < | < < < < < < < < < < < < < < < < < < < < | > > > > | > > > | > > > > > > | > > > > > | > > > > > > > > > > > > > | | > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > | > | | > > | 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 |
D.append(cols[3], preCode[0]);
}
let lineno = [], i;
for( i = lineFrom; i <= lineTo; ++i ){
lineno.push(i);
}
preLines[0].append(lineno.join('\n')+'\n');
if(1){
const code = result.join('\n')+'\n';
preCode.forEach((e)=>e.innerText = code);
}
//console.debug("Updated TR",tr);
Diff.initTableDiff(table).checkTableWidth(true);
/*
Reminders to self during development:
SBS diff col layout:
<td.diffln.difflnl><pre>...LHS line numbers...</pre></td>
<td.difftxt.difftxtl><pre>...code lines...</pre></td>
<td.diffsep>empty for this case (common lines)</td>
<td.diffln.difflnr><pre>...RHS line numbers...</pre></td>
<td.difftxt.difftxtr><pre>...dupe of col 2</pre></td>
Unified diff col layout:
<td.diffln.difflnl><pre>LHS line numbers</pre></td>
<td.diffln.difflnr><pre>RHS line numbers</pre></td>
<td.diffsep>empty in this case (common lines)</td>
<td.difftxt.difftxtu><pre>code line</pre></td>
C-side TODOs:
- If we have that data readily available, it would be a big
help (simplify our line calculations) if we stored the line
number ranges in all elements which have that state handy.
*/
}
});
};
/**
Installs chunk-loading controls into TR element tr. isSplit is true
if the parent table is a split diff, else false.)
*/
Diff.ChunkLoadControls = function(isSplit, tr){
this.isSplit = isSplit;
this.e = {/*DOM elements*/};
this.pos = {
start: +tr.dataset.startln,
end: +tr.dataset.endln
};
this.e.tr = tr;
D.clearElement(tr);
this.e.td = D.addClass(
D.attr(D.td(tr), 'colspan', isSplit ? 5 : 4),
'chunkctrl'
);
/**
Depending on various factors, we need one of:
- A single button to load all lines then remove this control
- A single button to load the initial chunk
- Two buttons: one to load upwards, one to load downwards
*/
if(tr.nextElementSibling){
this.pos.next = {
startLhs: extractLineNo(true, true, tr.nextElementSibling, isSplit),
startRhs: extractLineNo(false, true, tr.nextElementSibling, isSplit)
};
}
if(tr.previousElementSibling){
this.pos.prev = {
endLhs: extractLineNo(true, false, tr.previousElementSibling, isSplit),
endRhs: extractLineNo(false, false, tr.previousElementSibling, isSplit)
};
}
D.append(this.e.td,"Controls pending: ",JSON.stringify(this.pos));
};
Diff.ChunkLoadControls.prototype = {
config: {
glyphUp: '&#uarr;',
glyphDown: '&#darr;'
}
};
Diff.addDiffSkipHandlers = function(){
const tables = document.querySelectorAll('table.diff[data-lefthash]');
if(!tables.length) return F;
const addDiffSkipToTr = function f(isSplit, tr){
D.addClass(tr, 'jchunk');
if(!f._handler){
f._handler = function ff(event){
const e = this;
e.removeEventListener('click',ff);
D.removeClass(e, 'jchunk', 'diffskip');
fetchTrChunk(e);
};
}
/* TODO:
Depending on tr.dataset.{startln,endln}, install one or two
controls for loading the next diff chunk. For both types of
diff, put the control(s) into tr->td[0], delete tr->td[1],
give tr->td[0] a colspan of 2. Change the click handler to
address those controls, instead of the TR element, for
purposes of figuring out which lines to fetch. Use a helper
class to encapsulate the activation and updates of the
controls (e.g. removing controls which are no longer relevant
once a chunk is fully loaded).
Good example from github to use as a model:
https://github.com/msteveb/autosetup/commit/235925e914a52a542
*/
//tr.addEventListener('click', f._handler, false);
new Diff.ChunkLoadControls(isSplit, tr);
};
tables.forEach(function(table){
table.querySelectorAll('tr.diffskip[data-startln]').forEach(function(tr){
addDiffSkipToTr(table.classList.contains('splitdiff')/*else udiff*/, tr);
});
});
};
Diff.addDiffSkipHandlers();
});
/**
|
| ︙ | ︙ | |||
270 271 272 273 274 275 276 |
return this;
};
const scrollLeft = function(event){
//console.debug("scrollLeft",this,event);
const table = this.parentElement/*TD*/.parentElement/*TR*/.
parentElement/*TBODY*/.parentElement/*TABLE*/;
| | | 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 |
return this;
};
const scrollLeft = function(event){
//console.debug("scrollLeft",this,event);
const table = this.parentElement/*TD*/.parentElement/*TR*/.
parentElement/*TBODY*/.parentElement/*TABLE*/;
table.$txtPres.forEach((e)=>(e===this) ? 1 : (e.scrollLeft = this.scrollLeft));
return false;
};
Diff.initTableDiff = function f(diff){
if(!diff){
let i, diffs = document.querySelectorAll('table.splitdiff');
for(i=0; i<diffs.length; ++i){
f.call(this, diffs[i]);
|
| ︙ | ︙ | |||
304 305 306 307 308 309 310 |
diff.tabIndex = 0;
if(!diff.classList.contains('scroller')){
D.addClass(diff, 'scroller');
diff.addEventListener('keydown', function(e){
e = e || event;
const len = {37: -SCROLL_LEN, 39: SCROLL_LEN}[e.keyCode];
if( !len ) return;
| | | 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 |
diff.tabIndex = 0;
if(!diff.classList.contains('scroller')){
D.addClass(diff, 'scroller');
diff.addEventListener('keydown', function(e){
e = e || event;
const len = {37: -SCROLL_LEN, 39: SCROLL_LEN}[e.keyCode];
if( !len ) return;
this.$txtPres[0].scrollLeft += len;
return false;
}, false);
}
return this;
}
window.fossil.page.tweakSbsDiffs = function(){
document.querySelectorAll('table.splitdiff').forEach((e)=>Diff.initTableDiff);
};
Diff.initTableDiff().checkTableWidth();
window.addEventListener('resize', ()=>Diff.checkTableWidth());
}, false);
|