Fossil SCM

Got jchunk loader buttons in place but they're currently non-functional.

stephan 2021-09-09 18:28 diff-js-refactoring
Commit 365ef58b8c108473eee300563f261d4bb6601c0a8aef1a90d1fa7c42deff64cd
2 files changed +35 -7 +67 -28
+35 -7
--- src/default.css
+++ src/default.css
@@ -547,26 +547,54 @@
547547
}
548548
tr.diffskip.jchunk:hover {
549549
/* jchunk gets added from JS to diffskip rows when they are
550550
plugged into the /jchunk route and removed after that data
551551
is fetched. */
552
- background-color: rgba(127,127,127,0.5);
553
- cursor: pointer;
552
+}
553
+tr.diffskip.jchunk:hover {
554
+ /*background-color: rgba(127,127,127,0.5);
555
+ cursor: pointer;*/
554556
}
555557
tr.diffskip > td.chunkctrl {
556558
text-align: left;
557559
font-family: monospace;
558560
/* Border is only for visibility during development. Remove it when done. */
559561
border-width: 1px;
560562
border-style: dotted;
561563
}
562
-tr.diffskip > td.chunkctrl > .button {
563
- min-width: 1.5em;
564
- min-height: 1.5em;
565
- max-width: 1.5em;
566
- max-height: 1.5em;
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;
567570
text-align: center;
571
+ display: inline-block;
572
+ padding: 0.1em 1em;
573
+ margin: 0 1em 0 0;
574
+ background-color: rgba(127,127,127,0.3);
575
+ border-style: outset;
576
+ border-width: 1px;
577
+ border-color: rgba(0,0,0,0);
578
+ border-radius: 0.5em;
579
+}
580
+tr.diffskip > td.chunkctrl > div > .button > span {
581
+ /* In order to increase the glyph size w/o increasing the button size,
582
+ we need an extra layer of DOM element for the glyph. */
583
+ font-size: 150%;
584
+}
585
+tr.diffskip > td.chunkctrl > div > .button.up:not(.down){
586
+ /* Simulate an error pointing up */
587
+ border-radius: 3em 3em 0.25em 0.25em;
588
+}
589
+tr.diffskip > td.chunkctrl > div > .button.down:not(.up){
590
+ /* Simulate an error pointing down */
591
+ border-radius: 0.25em 0.25em 3em 3em;
592
+}
593
+tr.diffskip > td.chunkctrl > div > .button:hover {
594
+ border-color: rgba(0,0,0,1);
595
+ cursor: pointer;
568596
}
569597
td.diffln {
570598
width: 1px;
571599
text-align: right;
572600
padding: 0 1em 0 0;
573601
--- src/default.css
+++ src/default.css
@@ -547,26 +547,54 @@
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 background-color: rgba(127,127,127,0.5);
553 cursor: pointer;
 
 
554 }
555 tr.diffskip > td.chunkctrl {
556 text-align: left;
557 font-family: monospace;
558 /* Border is only for visibility during development. Remove it when done. */
559 border-width: 1px;
560 border-style: dotted;
561 }
562 tr.diffskip > td.chunkctrl > .button {
563 min-width: 1.5em;
564 min-height: 1.5em;
565 max-width: 1.5em;
566 max-height: 1.5em;
 
567 text-align: center;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
568 }
569 td.diffln {
570 width: 1px;
571 text-align: right;
572 padding: 0 1em 0 0;
573
--- src/default.css
+++ src/default.css
@@ -547,26 +547,54 @@
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;
573 margin: 0 1em 0 0;
574 background-color: rgba(127,127,127,0.3);
575 border-style: outset;
576 border-width: 1px;
577 border-color: rgba(0,0,0,0);
578 border-radius: 0.5em;
579 }
580 tr.diffskip > td.chunkctrl > div > .button > span {
581 /* In order to increase the glyph size w/o increasing the button size,
582 we need an extra layer of DOM element for the glyph. */
583 font-size: 150%;
584 }
585 tr.diffskip > td.chunkctrl > div > .button.up:not(.down){
586 /* Simulate an error pointing up */
587 border-radius: 3em 3em 0.25em 0.25em;
588 }
589 tr.diffskip > td.chunkctrl > div > .button.down:not(.up){
590 /* Simulate an error pointing down */
591 border-radius: 0.25em 0.25em 3em 3em;
592 }
593 tr.diffskip > td.chunkctrl > div > .button:hover {
594 border-color: rgba(0,0,0,1);
595 cursor: pointer;
596 }
597 td.diffln {
598 width: 1px;
599 text-align: right;
600 padding: 0 1em 0 0;
601
+67 -28
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -206,24 +206,33 @@
206206
};
207207
208208
/**
209209
Installs chunk-loading controls into TR element tr. isSplit is true
210210
if the parent table is a split diff, else false.)
211
- */
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
+ */
212218
Diff.ChunkLoadControls = function(isSplit, tr){
213219
this.isSplit = isSplit;
214220
this.e = {/*DOM elements*/};
215221
this.pos = {
216222
start: +tr.dataset.startln,
217223
end: +tr.dataset.endln
218224
};
225
+ tr.$chunker = this /* keep GC from reaping this */;
219226
this.e.tr = tr;
220227
D.clearElement(tr);
221228
this.e.td = D.addClass(
222229
D.attr(D.td(tr), 'colspan', isSplit ? 5 : 4),
223230
'chunkctrl'
224231
);
232
+ this.e.btnWrapper = D.div();
233
+ D.append(this.e.td, this.e.btnWrapper);
225234
/**
226235
Depending on various factors, we need one of:
227236
228237
- A single button to load all lines then remove this control
229238
@@ -241,50 +250,80 @@
241250
this.pos.prev = {
242251
endLhs: extractLineNo(true, false, tr.previousElementSibling, isSplit),
243252
endRhs: extractLineNo(false, false, tr.previousElementSibling, isSplit)
244253
};
245254
}
246
- D.append(this.e.td,"Controls pending: ",JSON.stringify(this.pos));
255
+ let btnUp = false, btnDown = false;
256
+ if(this.pos.prev && this.pos.next
257
+ && ((this.pos.next.startLhs - this.pos.prev.endLhs)
258
+ <= Diff.config.chunkLoadLines)){
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)));
247284
};
248285
249286
Diff.ChunkLoadControls.prototype = {
250287
config: {
251
- glyphUp: '&#uarr;',
252
- glyphDown: '&#darr;'
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).
299
+ */
300
+ newTR: function(){
301
+ const tr = D.tr();
302
+ if(this.isSplit){
303
+ D.append(D.addClass( D.td(tr), 'diffln', 'difflnl' ), D.pre());
304
+ D.append(D.addClass( D.td(tr), 'difftxt', 'difftxtl' ), D.pre());
305
+ D.addClass( D.td(tr), 'diffsep' );
306
+ D.append(D.addClass( D.td(tr), 'diffln', 'difflnr' ), D.pre());
307
+ D.append(D.addClass( D.td(tr), 'difftxt', 'difftxtr' ), D.pre());
308
+ }else{
309
+ D.append(D.addClass( D.td(tr), 'diffln', 'difflnl' ), D.pre());
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;
253315
}
254316
};
255317
256318
Diff.addDiffSkipHandlers = function(){
257319
const tables = document.querySelectorAll('table.diff[data-lefthash]');
258320
if(!tables.length) return F;
259321
const addDiffSkipToTr = function f(isSplit, tr){
260322
D.addClass(tr, 'jchunk');
261
- if(!f._handler){
262
- f._handler = function ff(event){
263
- const e = this;
264
- e.removeEventListener('click',ff);
265
- D.removeClass(e, 'jchunk', 'diffskip');
266
- fetchTrChunk(e);
267
- };
268
- }
269
- /* TODO:
270
-
271
- Depending on tr.dataset.{startln,endln}, install one or two
272
- controls for loading the next diff chunk. For both types of
273
- diff, put the control(s) into tr->td[0], delete tr->td[1],
274
- give tr->td[0] a colspan of 2. Change the click handler to
275
- address those controls, instead of the TR element, for
276
- purposes of figuring out which lines to fetch. Use a helper
277
- class to encapsulate the activation and updates of the
278
- controls (e.g. removing controls which are no longer relevant
279
- once a chunk is fully loaded).
280
-
281
- Good example from github to use as a model:
282
-
283
- https://github.com/msteveb/autosetup/commit/235925e914a52a542
284
- */
285323
//tr.addEventListener('click', f._handler, false);
324
+ /* TODO/in progress... */
286325
new Diff.ChunkLoadControls(isSplit, tr);
287326
};
288327
tables.forEach(function(table){
289328
table.querySelectorAll('tr.diffskip[data-startln]').forEach(function(tr){
290329
addDiffSkipToTr(table.classList.contains('splitdiff')/*else udiff*/, tr);
291330
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -206,24 +206,33 @@
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 Diff.ChunkLoadControls = function(isSplit, tr){
213 this.isSplit = isSplit;
214 this.e = {/*DOM elements*/};
215 this.pos = {
216 start: +tr.dataset.startln,
217 end: +tr.dataset.endln
218 };
 
219 this.e.tr = tr;
220 D.clearElement(tr);
221 this.e.td = D.addClass(
222 D.attr(D.td(tr), 'colspan', isSplit ? 5 : 4),
223 'chunkctrl'
224 );
 
 
225 /**
226 Depending on various factors, we need one of:
227
228 - A single button to load all lines then remove this control
229
@@ -241,50 +250,80 @@
241 this.pos.prev = {
242 endLhs: extractLineNo(true, false, tr.previousElementSibling, isSplit),
243 endRhs: extractLineNo(false, false, tr.previousElementSibling, isSplit)
244 };
245 }
246 D.append(this.e.td,"Controls pending: ",JSON.stringify(this.pos));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247 };
248
249 Diff.ChunkLoadControls.prototype = {
250 config: {
251 glyphUp: '&#uarr;',
252 glyphDown: '&#darr;'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253 }
254 };
255
256 Diff.addDiffSkipHandlers = function(){
257 const tables = document.querySelectorAll('table.diff[data-lefthash]');
258 if(!tables.length) return F;
259 const addDiffSkipToTr = function f(isSplit, tr){
260 D.addClass(tr, 'jchunk');
261 if(!f._handler){
262 f._handler = function ff(event){
263 const e = this;
264 e.removeEventListener('click',ff);
265 D.removeClass(e, 'jchunk', 'diffskip');
266 fetchTrChunk(e);
267 };
268 }
269 /* TODO:
270
271 Depending on tr.dataset.{startln,endln}, install one or two
272 controls for loading the next diff chunk. For both types of
273 diff, put the control(s) into tr->td[0], delete tr->td[1],
274 give tr->td[0] a colspan of 2. Change the click handler to
275 address those controls, instead of the TR element, for
276 purposes of figuring out which lines to fetch. Use a helper
277 class to encapsulate the activation and updates of the
278 controls (e.g. removing controls which are no longer relevant
279 once a chunk is fully loaded).
280
281 Good example from github to use as a model:
282
283 https://github.com/msteveb/autosetup/commit/235925e914a52a542
284 */
285 //tr.addEventListener('click', f._handler, false);
 
286 new Diff.ChunkLoadControls(isSplit, tr);
287 };
288 tables.forEach(function(table){
289 table.querySelectorAll('tr.diffskip[data-startln]').forEach(function(tr){
290 addDiffSkipToTr(table.classList.contains('splitdiff')/*else udiff*/, tr);
291
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -206,24 +206,33 @@
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
@@ -241,50 +250,80 @@
250 this.pos.prev = {
251 endLhs: extractLineNo(true, false, tr.previousElementSibling, isSplit),
252 endRhs: extractLineNo(false, false, tr.previousElementSibling, isSplit)
253 };
254 }
255 let btnUp = false, btnDown = false;
256 if(this.pos.prev && this.pos.next
257 && ((this.pos.next.startLhs - this.pos.prev.endLhs)
258 <= Diff.config.chunkLoadLines)){
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).
299 */
300 newTR: function(){
301 const tr = D.tr();
302 if(this.isSplit){
303 D.append(D.addClass( D.td(tr), 'diffln', 'difflnl' ), D.pre());
304 D.append(D.addClass( D.td(tr), 'difftxt', 'difftxtl' ), D.pre());
305 D.addClass( D.td(tr), 'diffsep' );
306 D.append(D.addClass( D.td(tr), 'diffln', 'difflnr' ), D.pre());
307 D.append(D.addClass( D.td(tr), 'difftxt', 'difftxtr' ), D.pre());
308 }else{
309 D.append(D.addClass( D.td(tr), 'diffln', 'difflnl' ), D.pre());
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

Keyboard Shortcuts

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