Fossil SCM

Style improvements. Hooked up the buttons but they don't yet fetch anything.

stephan 2021-09-09 20:03 diff-js-refactoring
Commit f0984389baa138b60a386cfdc121077c7549e4f2fbb28a1322dfb6348935a483
2 files changed +32 -17 +76 -27
+32 -17
--- src/default.css
+++ src/default.css
@@ -535,38 +535,43 @@
535535
/* Rules governing diff layout and colors */
536536
table.diff {
537537
width: 100%;
538538
border-spacing: 0;
539539
border: 1px solid black;
540
- padding: 0 0.5em;
540
+}
541
+table.diff td.diffln{
542
+ padding: 0 0.25em 0 0.5em;
541543
}
542544
table.diff td {
543545
vertical-align: top;
544546
}
545547
table.diff pre {
546548
margin: 0 0 0 0;
547549
}
548
-tr.diffskip.jchunk:hover {
550
+tr.diffskip.jchunk {
549551
/* jchunk gets added from JS to diffskip rows when they are
550552
plugged into the /jchunk route and removed after that data
551553
is fetched. */
554
+ background-color: aliceblue;
555
+ padding: 0;
556
+}
557
+tr.diffskip.jchunk > td {
558
+ padding: 0.25em 0.5em;
559
+ margin: 0;
552560
}
553561
tr.diffskip.jchunk:hover {
554562
/*background-color: rgba(127,127,127,0.5);
555563
cursor: pointer;*/
556564
}
557565
tr.diffskip > td.chunkctrl {
558566
text-align: left;
559567
font-family: monospace;
560
- /* Border is only for visibility during development. Remove it when done. */
561
- border-width: 1px;
562
- border-style: dotted;
563568
}
564569
tr.diffskip > td.chunkctrl > div {
565570
/* Exists solely for layout purposes. */
566571
}
567
-tr.diffskip > td.chunkctrl > div > .button {
572
+tr.diffskip > td.chunkctrl .button {
568573
min-width: 2.5em;
569574
max-width: 2.5em;
570575
text-align: center;
571576
display: inline-block;
572577
padding: 0.1em 1em;
@@ -578,25 +583,35 @@
578583
border-color: rgba(0,0,0,0);*/
579584
border-radius: 0.5em;
580585
opacity: 0.7;
581586
/*filter: drop-shadow(0.08em 0.08em 0.08em black);*/
582587
}
583
-tr.diffskip > td.chunkctrl > div > .button > span {
588
+tr.diffskip > td.chunkctrl .button.up:not(.down){
589
+ /* Simulate an arrow pointing up */
590
+ border-radius: 3em 3em 0.25em 0.25em;
591
+}
592
+tr.diffskip > td.chunkctrl .button.down:not(.up){
593
+ /* Simulate an arrow pointing down */
594
+ border-radius: 0.25em 0.25em 3em 3em;
595
+}
596
+tr.diffskip > td.chunkctrl .button > span {
584597
/* In order to increase the glyph size w/o increasing the em-based
585598
button size or border-radius, we need an extra layer of DOM
586599
element for the glyph. */
587600
font-size: 150%;
588601
}
589
-tr.diffskip > td.chunkctrl > div > .button.up:not(.down){
590
- /* Simulate an arrow pointing up */
591
- border-radius: 3em 3em 0.25em 0.25em;
592
-}
593
-tr.diffskip > td.chunkctrl > div > .button.down:not(.up){
594
- /* Simulate an arrow pointing down */
595
- border-radius: 0.25em 0.25em 3em 3em;
596
-}
597
-tr.diffskip > td.chunkctrl > div > .button:hover {
602
+tr.diffskip > td.chunkctrl .button.up:not(.down) > span::before {
603
+ content: '⇡';
604
+}
605
+tr.diffskip > td.chunkctrl .button.down:not(.up) > span::before {
606
+ content: '⇣';
607
+}
608
+tr.diffskip > td.chunkctrl .button.up.down > span::before {
609
+ content: '⇡⇣';
610
+}
611
+
612
+tr.diffskip > td.chunkctrl .button:hover {
598613
/*border-color: rgba(75,75,75,1);*/
599614
cursor: pointer;
600615
opacity: 1;
601616
filter: contrast(3);
602617
}
@@ -608,11 +623,11 @@
608623
td.difflne {
609624
padding-bottom: 0.4em;
610625
}
611626
td.diffsep {
612627
width: 1px;
613
- padding: 0 0.3em 0 1em;
628
+ padding: 0 0.3em 0 0.5em;
614629
}
615630
td.difftxt pre {
616631
overflow-x: auto;
617632
}
618633
td.diffln ins {
619634
--- src/default.css
+++ src/default.css
@@ -535,38 +535,43 @@
535 /* Rules governing diff layout and colors */
536 table.diff {
537 width: 100%;
538 border-spacing: 0;
539 border: 1px solid black;
540 padding: 0 0.5em;
 
 
541 }
542 table.diff td {
543 vertical-align: top;
544 }
545 table.diff pre {
546 margin: 0 0 0 0;
547 }
548 tr.diffskip.jchunk:hover {
549 /* jchunk gets added from JS to diffskip rows when they are
550 plugged into the /jchunk route and removed after that data
551 is fetched. */
 
 
 
 
 
 
552 }
553 tr.diffskip.jchunk:hover {
554 /*background-color: rgba(127,127,127,0.5);
555 cursor: pointer;*/
556 }
557 tr.diffskip > td.chunkctrl {
558 text-align: left;
559 font-family: monospace;
560 /* Border is only for visibility during development. Remove it when done. */
561 border-width: 1px;
562 border-style: dotted;
563 }
564 tr.diffskip > td.chunkctrl > div {
565 /* Exists solely for layout purposes. */
566 }
567 tr.diffskip > td.chunkctrl > div > .button {
568 min-width: 2.5em;
569 max-width: 2.5em;
570 text-align: center;
571 display: inline-block;
572 padding: 0.1em 1em;
@@ -578,25 +583,35 @@
578 border-color: rgba(0,0,0,0);*/
579 border-radius: 0.5em;
580 opacity: 0.7;
581 /*filter: drop-shadow(0.08em 0.08em 0.08em black);*/
582 }
583 tr.diffskip > td.chunkctrl > div > .button > span {
 
 
 
 
 
 
 
 
584 /* In order to increase the glyph size w/o increasing the em-based
585 button size or border-radius, we need an extra layer of DOM
586 element for the glyph. */
587 font-size: 150%;
588 }
589 tr.diffskip > td.chunkctrl > div > .button.up:not(.down){
590 /* Simulate an arrow pointing up */
591 border-radius: 3em 3em 0.25em 0.25em;
592 }
593 tr.diffskip > td.chunkctrl > div > .button.down:not(.up){
594 /* Simulate an arrow pointing down */
595 border-radius: 0.25em 0.25em 3em 3em;
596 }
597 tr.diffskip > td.chunkctrl > div > .button:hover {
 
 
598 /*border-color: rgba(75,75,75,1);*/
599 cursor: pointer;
600 opacity: 1;
601 filter: contrast(3);
602 }
@@ -608,11 +623,11 @@
608 td.difflne {
609 padding-bottom: 0.4em;
610 }
611 td.diffsep {
612 width: 1px;
613 padding: 0 0.3em 0 1em;
614 }
615 td.difftxt pre {
616 overflow-x: auto;
617 }
618 td.diffln ins {
619
--- src/default.css
+++ src/default.css
@@ -535,38 +535,43 @@
535 /* Rules governing diff layout and colors */
536 table.diff {
537 width: 100%;
538 border-spacing: 0;
539 border: 1px solid black;
540 }
541 table.diff td.diffln{
542 padding: 0 0.25em 0 0.5em;
543 }
544 table.diff td {
545 vertical-align: top;
546 }
547 table.diff pre {
548 margin: 0 0 0 0;
549 }
550 tr.diffskip.jchunk {
551 /* jchunk gets added from JS to diffskip rows when they are
552 plugged into the /jchunk route and removed after that data
553 is fetched. */
554 background-color: aliceblue;
555 padding: 0;
556 }
557 tr.diffskip.jchunk > td {
558 padding: 0.25em 0.5em;
559 margin: 0;
560 }
561 tr.diffskip.jchunk:hover {
562 /*background-color: rgba(127,127,127,0.5);
563 cursor: pointer;*/
564 }
565 tr.diffskip > td.chunkctrl {
566 text-align: left;
567 font-family: monospace;
 
 
 
568 }
569 tr.diffskip > td.chunkctrl > div {
570 /* Exists solely for layout purposes. */
571 }
572 tr.diffskip > td.chunkctrl .button {
573 min-width: 2.5em;
574 max-width: 2.5em;
575 text-align: center;
576 display: inline-block;
577 padding: 0.1em 1em;
@@ -578,25 +583,35 @@
583 border-color: rgba(0,0,0,0);*/
584 border-radius: 0.5em;
585 opacity: 0.7;
586 /*filter: drop-shadow(0.08em 0.08em 0.08em black);*/
587 }
588 tr.diffskip > td.chunkctrl .button.up:not(.down){
589 /* Simulate an arrow pointing up */
590 border-radius: 3em 3em 0.25em 0.25em;
591 }
592 tr.diffskip > td.chunkctrl .button.down:not(.up){
593 /* Simulate an arrow pointing down */
594 border-radius: 0.25em 0.25em 3em 3em;
595 }
596 tr.diffskip > td.chunkctrl .button > span {
597 /* In order to increase the glyph size w/o increasing the em-based
598 button size or border-radius, we need an extra layer of DOM
599 element for the glyph. */
600 font-size: 150%;
601 }
602 tr.diffskip > td.chunkctrl .button.up:not(.down) > span::before {
603 content: '⇡';
604 }
605 tr.diffskip > td.chunkctrl .button.down:not(.up) > span::before {
606 content: '⇣';
607 }
608 tr.diffskip > td.chunkctrl .button.up.down > span::before {
609 content: '⇡⇣';
610 }
611
612 tr.diffskip > td.chunkctrl .button:hover {
613 /*border-color: rgba(75,75,75,1);*/
614 cursor: pointer;
615 opacity: 1;
616 filter: contrast(3);
617 }
@@ -608,11 +623,11 @@
623 td.difflne {
624 padding-bottom: 0.4em;
625 }
626 td.diffsep {
627 width: 1px;
628 padding: 0 0.3em 0 0.5em;
629 }
630 td.difftxt pre {
631 overflow-x: auto;
632 }
633 td.diffln ins {
634
+76 -27
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -205,42 +205,51 @@
205205
});
206206
};
207207
208208
/**
209209
Installs chunk-loading controls into TR element tr. isSplit is true
210
- if the parent table is a split diff, else false.)
211
-
210
+ if the parent table is a split diff, else false.
212211
213212
The goal is to base these controls closely on github's, a good example
214213
of which, for use as a model, is:
215214
216215
https://github.com/msteveb/autosetup/commit/235925e914a52a542
216
+
217
+ Each instance corresponds to a single TR.diffskip element.
217218
*/
218219
Diff.ChunkLoadControls = function(isSplit, tr){
219220
this.isSplit = isSplit;
220
- this.e = {/*DOM elements*/};
221
- this.pos = {
222
- start: +tr.dataset.startln,
223
- end: +tr.dataset.endln
221
+ this.e = {/*DOM elements*/
222
+ tr: tr
224223
};
225224
tr.$chunker = this /* keep GC from reaping this */;
226
- this.e.tr = tr;
225
+ this.pos = {
226
+ /* These line numbers correspond to the LHS file. Because the
227
+ contents are common to both sides, we have the same number
228
+ for the RHS, but need to extract those line numbers from the
229
+ neighboring TR blocks */
230
+ startLhs: +tr.dataset.startln,
231
+ endLhs: +tr.dataset.endln
232
+ };
227233
D.clearElement(tr);
228234
this.e.td = D.addClass(
235
+ /* Holder for our UI controls */
229236
D.attr(D.td(tr), 'colspan', isSplit ? 5 : 4),
230237
'chunkctrl'
231238
);
232239
this.e.btnWrapper = D.div();
233240
D.append(this.e.td, this.e.btnWrapper);
234241
/**
235
- Depending on various factors, we need one of:
242
+ Depending on various factors, we need one or more of:
243
+
244
+ - A single button to load the initial chunk incrementally
236245
237246
- A single button to load all lines then remove this control
238247
239
- - A single button to load the initial chunk
240
-
241248
- Two buttons: one to load upwards, one to load downwards
249
+
250
+ - A single button to load the final chunk incrementally
242251
*/
243252
if(tr.nextElementSibling){
244253
this.pos.next = {
245254
startLhs: extractLineNo(true, true, tr.nextElementSibling, isSplit),
246255
startRhs: extractLineNo(false, true, tr.nextElementSibling, isSplit)
@@ -259,40 +268,65 @@
259268
/* Place a single button to load the whole block, rather
260269
than separate up/down buttons. */
261270
btnDown = false;
262271
btnUp = D.append(
263272
D.addClass(D.span(), 'button', 'up', 'down'),
264
- D.append(D.span(), this.config.glyphDown, this.config.glyphUp)
273
+ D.span(/*glyph holder*/)
274
+ //D.append(D.span(), this.config.glyphDown, this.config.glyphUp)
265275
);
266276
}else{
267277
/* Figure out which chunk-load buttons to add... */
268278
if(this.pos.prev){
269279
btnDown = D.append(
270280
D.addClass(D.span(), 'button', 'down'),
271
- D.append(D.span(), this.config.glyphDown)
281
+ D.span(/*glyph holder*/)
282
+ //D.append(D.span(), this.config.glyphDown)
272283
);
273284
}
274285
if(this.pos.next){
275286
btnUp = D.append(
276287
D.addClass(D.span(), 'button', 'up'),
277
- D.append(D.span(), this.config.glyphUp)
288
+ D.span(/*glyph holder*/)
289
+ //D.append(D.span(), this.config.glyphUp)
278290
);
279291
}
280292
}
281
- if(btnDown) D.append(this.e.btnWrapper, btnDown);
282
- if(btnUp) D.append(this.e.btnWrapper, btnUp);
283
- D.append(this.e.btnWrapper, D.append(D.span(), JSON.stringify(this.pos)));
293
+ if(btnDown){
294
+ D.append(this.e.btnWrapper, btnDown);
295
+ btnDown.addEventListener('click', ()=>this.fetchChunk(1),false);
296
+ }
297
+ if(btnUp){
298
+ D.append(this.e.btnWrapper, btnUp);
299
+ btnUp.addEventListener(
300
+ 'click', ()=>this.fetchChunk(btnUp.classList.contains('down') ? 0 : -1),
301
+ false);
302
+ }
303
+ /* For debugging only... */
304
+ this.e.posState = D.span();
305
+ D.append(this.e.btnWrapper, this.e.posState);
306
+ this.updatePosDebug();
284307
};
285308
286309
Diff.ChunkLoadControls.prototype = {
287310
config: {
311
+ /*
288312
glyphUp: '⇡', //'&#uarr;',
289313
glyphDown: '⇣' //'&#darr;'
314
+ */
315
+ },
316
+ updatePosDebug: function(){
317
+ if(this.e.posState){
318
+ D.append(D.clearElement(this.e.posState), JSON.stringify(this.pos));
319
+ }
320
+ return this;
290321
},
322
+
291323
destroy: function(){
292324
delete this.tr.$chunker;
293
- D.remove(this.tr);
325
+ D.remove(this.e.tr);
326
+ delete this.e;
327
+ delete this.pos;
294328
},
295329
/**
296330
Creates and returns a new TR element, including its TD elements (depending
297331
on this.isSplit), but does not fill it with any information nor inject it
298332
into the table (it doesn't know where to do so).
@@ -310,29 +344,44 @@
310344
D.append(D.addClass( D.td(tr), 'diffln', 'difflnr' ), D.pre());
311345
D.addClass( D.td(tr), 'diffsep' );
312346
D.append(D.addClass( D.td(tr), 'difftxt', 'difftxtu' ), D.pre());
313347
}
314348
return tr;
349
+ },
350
+
351
+ fetchChunk: function(direction/*-1=prev, 1=next, 0=both*/){
352
+ /* Forewarning, this is a bit confusing: when fetching the
353
+ previous lines, we're doing so on behalf of the *next* diff
354
+ chunk (this.pos.next), and vice versa. */
355
+ if(this.isFetching) return this;
356
+ if(direction<0/*prev chunk*/ && !this.pos.next){
357
+ console.error("Attempt to fetch previous diff lines but don't have any.");
358
+ return this;
359
+ }else if(direction>0/*next chunk*/ && !this.pos.prev){
360
+ console.error("Attempt to fetch next diff lines but don't have any.");
361
+ return this;
362
+ }
363
+ console.debug("Going to fetch in direction",direction);
364
+ this.updatePosDebug();
365
+ return this;
315366
}
316367
};
317368
318369
Diff.addDiffSkipHandlers = function(){
319
- const tables = document.querySelectorAll('table.diff[data-lefthash]');
320
- if(!tables.length) return F;
321
- const addDiffSkipToTr = function f(isSplit, tr){
322
- D.addClass(tr, 'jchunk');
323
- //tr.addEventListener('click', f._handler, false);
324
- /* TODO/in progress... */
325
- new Diff.ChunkLoadControls(isSplit, tr);
326
- };
370
+ const tables = document.querySelectorAll('table.diff[data-lefthash]:not(.diffskipped)');
371
+ /* Potential performance-related TODO: instead of installing all
372
+ of these at once, install them as the corresponding TR is
373
+ scrolled into view. */
327374
tables.forEach(function(table){
375
+ D.addClass(table, 'diffskipped'/*avoid processing these more than once */);
376
+ const isSplit = table.classList.contains('splitdiff')/*else udiff*/;
328377
table.querySelectorAll('tr.diffskip[data-startln]').forEach(function(tr){
329
- addDiffSkipToTr(table.classList.contains('splitdiff')/*else udiff*/, tr);
378
+ new Diff.ChunkLoadControls(isSplit, D.addClass(tr, 'jchunk'));
330379
});
331380
});
381
+ return F;
332382
};
333
-
334383
Diff.addDiffSkipHandlers();
335384
});
336385
337386
/**
338387
2021-09-07: refactoring the following for use in the higher-level
339388
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -205,42 +205,51 @@
205 });
206 };
207
208 /**
209 Installs chunk-loading controls into TR element tr. isSplit is true
210 if the parent table is a split diff, else false.)
211
212
213 The goal is to base these controls closely on github's, a good example
214 of which, for use as a model, is:
215
216 https://github.com/msteveb/autosetup/commit/235925e914a52a542
 
 
217 */
218 Diff.ChunkLoadControls = function(isSplit, tr){
219 this.isSplit = isSplit;
220 this.e = {/*DOM elements*/};
221 this.pos = {
222 start: +tr.dataset.startln,
223 end: +tr.dataset.endln
224 };
225 tr.$chunker = this /* keep GC from reaping this */;
226 this.e.tr = tr;
 
 
 
 
 
 
 
227 D.clearElement(tr);
228 this.e.td = D.addClass(
 
229 D.attr(D.td(tr), 'colspan', isSplit ? 5 : 4),
230 'chunkctrl'
231 );
232 this.e.btnWrapper = D.div();
233 D.append(this.e.td, this.e.btnWrapper);
234 /**
235 Depending on various factors, we need one of:
 
 
236
237 - A single button to load all lines then remove this control
238
239 - A single button to load the initial chunk
240
241 - Two buttons: one to load upwards, one to load downwards
 
 
242 */
243 if(tr.nextElementSibling){
244 this.pos.next = {
245 startLhs: extractLineNo(true, true, tr.nextElementSibling, isSplit),
246 startRhs: extractLineNo(false, true, tr.nextElementSibling, isSplit)
@@ -259,40 +268,65 @@
259 /* Place a single button to load the whole block, rather
260 than separate up/down buttons. */
261 btnDown = false;
262 btnUp = D.append(
263 D.addClass(D.span(), 'button', 'up', 'down'),
264 D.append(D.span(), this.config.glyphDown, this.config.glyphUp)
 
265 );
266 }else{
267 /* Figure out which chunk-load buttons to add... */
268 if(this.pos.prev){
269 btnDown = D.append(
270 D.addClass(D.span(), 'button', 'down'),
271 D.append(D.span(), this.config.glyphDown)
 
272 );
273 }
274 if(this.pos.next){
275 btnUp = D.append(
276 D.addClass(D.span(), 'button', 'up'),
277 D.append(D.span(), this.config.glyphUp)
 
278 );
279 }
280 }
281 if(btnDown) D.append(this.e.btnWrapper, btnDown);
282 if(btnUp) D.append(this.e.btnWrapper, btnUp);
283 D.append(this.e.btnWrapper, D.append(D.span(), JSON.stringify(this.pos)));
 
 
 
 
 
 
 
 
 
 
 
284 };
285
286 Diff.ChunkLoadControls.prototype = {
287 config: {
 
288 glyphUp: '⇡', //'&#uarr;',
289 glyphDown: '⇣' //'&#darr;'
 
 
 
 
 
 
 
290 },
 
291 destroy: function(){
292 delete this.tr.$chunker;
293 D.remove(this.tr);
 
 
294 },
295 /**
296 Creates and returns a new TR element, including its TD elements (depending
297 on this.isSplit), but does not fill it with any information nor inject it
298 into the table (it doesn't know where to do so).
@@ -310,29 +344,44 @@
310 D.append(D.addClass( D.td(tr), 'diffln', 'difflnr' ), D.pre());
311 D.addClass( D.td(tr), 'diffsep' );
312 D.append(D.addClass( D.td(tr), 'difftxt', 'difftxtu' ), D.pre());
313 }
314 return tr;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
315 }
316 };
317
318 Diff.addDiffSkipHandlers = function(){
319 const tables = document.querySelectorAll('table.diff[data-lefthash]');
320 if(!tables.length) return F;
321 const addDiffSkipToTr = function f(isSplit, tr){
322 D.addClass(tr, 'jchunk');
323 //tr.addEventListener('click', f._handler, false);
324 /* TODO/in progress... */
325 new Diff.ChunkLoadControls(isSplit, tr);
326 };
327 tables.forEach(function(table){
 
 
328 table.querySelectorAll('tr.diffskip[data-startln]').forEach(function(tr){
329 addDiffSkipToTr(table.classList.contains('splitdiff')/*else udiff*/, tr);
330 });
331 });
 
332 };
333
334 Diff.addDiffSkipHandlers();
335 });
336
337 /**
338 2021-09-07: refactoring the following for use in the higher-level
339
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -205,42 +205,51 @@
205 });
206 };
207
208 /**
209 Installs chunk-loading controls into TR element tr. isSplit is true
210 if the parent table is a split diff, else false.
 
211
212 The goal is to base these controls closely on github's, a good example
213 of which, for use as a model, is:
214
215 https://github.com/msteveb/autosetup/commit/235925e914a52a542
216
217 Each instance corresponds to a single TR.diffskip element.
218 */
219 Diff.ChunkLoadControls = function(isSplit, tr){
220 this.isSplit = isSplit;
221 this.e = {/*DOM elements*/
222 tr: tr
 
 
223 };
224 tr.$chunker = this /* keep GC from reaping this */;
225 this.pos = {
226 /* These line numbers correspond to the LHS file. Because the
227 contents are common to both sides, we have the same number
228 for the RHS, but need to extract those line numbers from the
229 neighboring TR blocks */
230 startLhs: +tr.dataset.startln,
231 endLhs: +tr.dataset.endln
232 };
233 D.clearElement(tr);
234 this.e.td = D.addClass(
235 /* Holder for our UI controls */
236 D.attr(D.td(tr), 'colspan', isSplit ? 5 : 4),
237 'chunkctrl'
238 );
239 this.e.btnWrapper = D.div();
240 D.append(this.e.td, this.e.btnWrapper);
241 /**
242 Depending on various factors, we need one or more of:
243
244 - A single button to load the initial chunk incrementally
245
246 - A single button to load all lines then remove this control
247
 
 
248 - Two buttons: one to load upwards, one to load downwards
249
250 - A single button to load the final chunk incrementally
251 */
252 if(tr.nextElementSibling){
253 this.pos.next = {
254 startLhs: extractLineNo(true, true, tr.nextElementSibling, isSplit),
255 startRhs: extractLineNo(false, true, tr.nextElementSibling, isSplit)
@@ -259,40 +268,65 @@
268 /* Place a single button to load the whole block, rather
269 than separate up/down buttons. */
270 btnDown = false;
271 btnUp = D.append(
272 D.addClass(D.span(), 'button', 'up', 'down'),
273 D.span(/*glyph holder*/)
274 //D.append(D.span(), this.config.glyphDown, this.config.glyphUp)
275 );
276 }else{
277 /* Figure out which chunk-load buttons to add... */
278 if(this.pos.prev){
279 btnDown = D.append(
280 D.addClass(D.span(), 'button', 'down'),
281 D.span(/*glyph holder*/)
282 //D.append(D.span(), this.config.glyphDown)
283 );
284 }
285 if(this.pos.next){
286 btnUp = D.append(
287 D.addClass(D.span(), 'button', 'up'),
288 D.span(/*glyph holder*/)
289 //D.append(D.span(), this.config.glyphUp)
290 );
291 }
292 }
293 if(btnDown){
294 D.append(this.e.btnWrapper, btnDown);
295 btnDown.addEventListener('click', ()=>this.fetchChunk(1),false);
296 }
297 if(btnUp){
298 D.append(this.e.btnWrapper, btnUp);
299 btnUp.addEventListener(
300 'click', ()=>this.fetchChunk(btnUp.classList.contains('down') ? 0 : -1),
301 false);
302 }
303 /* For debugging only... */
304 this.e.posState = D.span();
305 D.append(this.e.btnWrapper, this.e.posState);
306 this.updatePosDebug();
307 };
308
309 Diff.ChunkLoadControls.prototype = {
310 config: {
311 /*
312 glyphUp: '⇡', //'&#uarr;',
313 glyphDown: '⇣' //'&#darr;'
314 */
315 },
316 updatePosDebug: function(){
317 if(this.e.posState){
318 D.append(D.clearElement(this.e.posState), JSON.stringify(this.pos));
319 }
320 return this;
321 },
322
323 destroy: function(){
324 delete this.tr.$chunker;
325 D.remove(this.e.tr);
326 delete this.e;
327 delete this.pos;
328 },
329 /**
330 Creates and returns a new TR element, including its TD elements (depending
331 on this.isSplit), but does not fill it with any information nor inject it
332 into the table (it doesn't know where to do so).
@@ -310,29 +344,44 @@
344 D.append(D.addClass( D.td(tr), 'diffln', 'difflnr' ), D.pre());
345 D.addClass( D.td(tr), 'diffsep' );
346 D.append(D.addClass( D.td(tr), 'difftxt', 'difftxtu' ), D.pre());
347 }
348 return tr;
349 },
350
351 fetchChunk: function(direction/*-1=prev, 1=next, 0=both*/){
352 /* Forewarning, this is a bit confusing: when fetching the
353 previous lines, we're doing so on behalf of the *next* diff
354 chunk (this.pos.next), and vice versa. */
355 if(this.isFetching) return this;
356 if(direction<0/*prev chunk*/ && !this.pos.next){
357 console.error("Attempt to fetch previous diff lines but don't have any.");
358 return this;
359 }else if(direction>0/*next chunk*/ && !this.pos.prev){
360 console.error("Attempt to fetch next diff lines but don't have any.");
361 return this;
362 }
363 console.debug("Going to fetch in direction",direction);
364 this.updatePosDebug();
365 return this;
366 }
367 };
368
369 Diff.addDiffSkipHandlers = function(){
370 const tables = document.querySelectorAll('table.diff[data-lefthash]:not(.diffskipped)');
371 /* Potential performance-related TODO: instead of installing all
372 of these at once, install them as the corresponding TR is
373 scrolled into view. */
 
 
 
 
374 tables.forEach(function(table){
375 D.addClass(table, 'diffskipped'/*avoid processing these more than once */);
376 const isSplit = table.classList.contains('splitdiff')/*else udiff*/;
377 table.querySelectorAll('tr.diffskip[data-startln]').forEach(function(tr){
378 new Diff.ChunkLoadControls(isSplit, D.addClass(tr, 'jchunk'));
379 });
380 });
381 return F;
382 };
 
383 Diff.addDiffSkipHandlers();
384 });
385
386 /**
387 2021-09-07: refactoring the following for use in the higher-level
388

Keyboard Shortcuts

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