Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Experiment to implement a click-queue for the buttons dynamically loading diff context. See Forum Post c8919e12dd for comments and potential TODOs. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | diff-js-fetchqueue |
Files: | files | file ages | folders |
SHA3-256: |
c714f2515e06d0011e3fc06938bd48a6 |
User & Date: | florian 2021-09-24 12:04:00 |
Context
2021-09-26
| ||
12:53 | Merged in diff context multi-click load queue on behalf of Florian B., as discussed in/around forum post c8919e12dd76bf23. ... (check-in: a49393a9 user: stephan tags: trunk) | |
2021-09-25
| ||
08:57 | Possible solution to the problem of buttons randomly jumping away from under the mouse cursor. ... (Leaf check-in: b4dbdec8 user: florian tags: diff-js-fetchqueue) | |
2021-09-24
| ||
12:04 | Experiment to implement a click-queue for the buttons dynamically loading diff context. See Forum Post c8919e12dd for comments and potential TODOs. ... (check-in: c714f251 user: florian tags: diff-js-fetchqueue) | |
2021-09-23
| ||
19:47 | Earlier detection of unresolved deltas due to an incomplete clone. ... (check-in: 55a5b701 user: drh tags: trunk) | |
Changes
Changes to src/fossil.diff.js.
︙ | ︙ | |||
115 116 117 118 119 120 121 122 123 124 125 126 127 128 | The goal is to base these controls roughly on github's, a good example of which, for use as a model, is: https://github.com/msteveb/autosetup/commit/235925e914a52a542 */ const ChunkLoadControls = function(tr){ this.e = {/*DOM elements*/ tr: tr, table: tr.parentElement/*TBODY*/.parentElement }; this.isSplit = this.e.table.classList.contains('splitdiff')/*else udiff*/; this.fileHash = this.e.table.dataset.lefthash; tr.$chunker = this /* keep GC from reaping this */; | > | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | The goal is to base these controls roughly on github's, a good example of which, for use as a model, is: https://github.com/msteveb/autosetup/commit/235925e914a52a542 */ const ChunkLoadControls = function(tr){ this.$fetchQueue = []; this.e = {/*DOM elements*/ tr: tr, table: tr.parentElement/*TBODY*/.parentElement }; this.isSplit = this.e.table.classList.contains('splitdiff')/*else udiff*/; this.fileHash = this.e.table.dataset.lefthash; tr.$chunker = this /* keep GC from reaping this */; |
︙ | ︙ | |||
207 208 209 210 211 212 213 | /** Append context to the bottom of the previous diff chunk. */ PrevDown: 1, /** Fill a complete gap between the previous/next diff chunks or at the start of the next chunk or end of the previous chunks. */ FillGap: 0, /** Prepend context to the start of the next diff chunk. */ | | > > | 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | /** Append context to the bottom of the previous diff chunk. */ PrevDown: 1, /** Fill a complete gap between the previous/next diff chunks or at the start of the next chunk or end of the previous chunks. */ FillGap: 0, /** Prepend context to the start of the next diff chunk. */ NextUp: -1, /** Process the next queued action. */ ProcessQueue: 0x7fffffff }, config: { /* glyphUp: '⇡', //'&#uarr;', glyphDown: '⇣' //'&#darr;' */ }, |
︙ | ︙ | |||
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 | } return this; }, /* Attempt to clean up resources and remove some circular references to that GC can do the right thing. */ destroy: function(){ D.remove(this.e.tr); delete this.e.tr.$chunker; delete this.e.tr; delete this.e; delete this.pos; }, /** If the gap between this.pos.endLhs/startLhs is less than or equal to Diff.config.chunkLoadLines then this function replaces any up/down buttons with a gap-filler button, else it's a no-op. Returns this object. As a special case, do not apply this at the start or bottom of the diff, only between two diff chunks. */ maybeReplaceButtons: function(){ if(this.pos.next && this.pos.prev && (this.pos.endLhs - this.pos.startLhs <= Diff.config.chunkLoadLines)){ D.clearElement(this.e.btnWrapper); D.append(this.e.btnWrapper, this.createButton(this.FetchType.FillGap)); } return this; }, /** Callack for /jchunk responses. */ | > > > > | 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 299 300 | } return this; }, /* Attempt to clean up resources and remove some circular references to that GC can do the right thing. */ destroy: function(){ delete this.$fetchQueue; D.remove(this.e.tr); delete this.e.tr.$chunker; delete this.e.tr; delete this.e; delete this.pos; }, /** If the gap between this.pos.endLhs/startLhs is less than or equal to Diff.config.chunkLoadLines then this function replaces any up/down buttons with a gap-filler button, else it's a no-op. Returns this object. As a special case, do not apply this at the start or bottom of the diff, only between two diff chunks. */ maybeReplaceButtons: function(){ if(this.pos.next && this.pos.prev && (this.pos.endLhs - this.pos.startLhs <= Diff.config.chunkLoadLines)){ D.clearElement(this.e.btnWrapper); D.append(this.e.btnWrapper, this.createButton(this.FetchType.FillGap)); if( this.$fetchQueue && this.$fetchQueue.length>0 ){ this.$fetchQueue = [this.FetchType.FillGap]; } } return this; }, /** Callack for /jchunk responses. */ |
︙ | ︙ | |||
499 500 501 502 503 504 505 506 507 508 | fetchTypes NextUp and PrevDown. This is an async operation. While it is in transit, any calls to this function will have no effect except (possibly) to emit a warning. Returns this object. */ fetchChunk: function(fetchType){ /* Forewarning, this is a bit confusing: when fetching the previous lines, we're doing so on behalf of the *next* diff chunk (this.pos.next), and vice versa. */ | > > > > > > > > > > > < < < | | | > > > > | 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 | fetchTypes NextUp and PrevDown. This is an async operation. While it is in transit, any calls to this function will have no effect except (possibly) to emit a warning. Returns this object. */ fetchChunk: function(fetchType){ if( !this.$fetchQueue ) return this; // HACKHACK: are we destroyed? if( fetchType==this.FetchType.ProcessQueue ){ if( this.$fetchQueue.length==0 ) return this; //console.log('fetchChunk: processing queue ...'); } else{ this.$fetchQueue.push(fetchType); if( this.$fetchQueue.length!=1 ) return this; //console.log('fetchChunk: processing user input ...'); } fetchType = this.$fetchQueue[0]; /* Forewarning, this is a bit confusing: when fetching the previous lines, we're doing so on behalf of the *next* diff chunk (this.pos.next), and vice versa. */ if(fetchType===this.FetchType.NextUp && !this.pos.next || fetchType===this.FetchType.PrevDown && !this.pos.prev){ console.error("Attempt to fetch diff lines but don't have any."); return this; } this.msg(false); const fOpt = { urlParams:{ name: this.fileHash, from: 0, to: 0 }, onload: function(list){ this.injectResponse(fetchType,up,list); if( !this.$fetchQueue || this.$fetchQueue.length==0 ) return; this.$fetchQueue.shift(); setTimeout(this.fetchChunk.bind(this,this.FetchType.ProcessQueue)); }.bind(this) }; const up = fOpt.urlParams; if(fetchType===this.FetchType.FillGap){ /* Easiest case: filling a whole gap. */ up.from = this.pos.startLhs; up.to = this.pos.endLhs; }else if(this.FetchType.PrevDown===fetchType){ |
︙ | ︙ | |||
549 550 551 552 553 554 555 | up.to = this.pos.next.startLhs - 1; up.from = Math.max(1, up.to - Diff.config.chunkLoadLines + 1); if( this.pos.prev && this.pos.prev.endLhs >= up.from ){ up.from = this.pos.prev.endLhs + 1; fetchType = this.FetchType.FillGap; } } | < > | > > | 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 | up.to = this.pos.next.startLhs - 1; up.from = Math.max(1, up.to - Diff.config.chunkLoadLines + 1); if( this.pos.prev && this.pos.prev.endLhs >= up.from ){ up.from = this.pos.prev.endLhs + 1; fetchType = this.FetchType.FillGap; } } //console.debug("fetchChunk(",fetchType,")",up); fOpt.onerror = function(err){ this.msg(true,err.message); this.$fetchQueue = []; }.bind(this); Diff.fetchArtifactChunk(fOpt); return this; } }; /** Adds context-loading buttons to one or more tables. The argument |
︙ | ︙ |