Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch diff-js-fetchqueue Excluding Merge-Ins
This is equivalent to a diff from 55a5b701 to b4dbdec8
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
| ||
17:18 | Added an optional widget to /chat which gives an overview of who is actively posting and enables filtering messages by users. ... (check-in: ce0d61bb user: stephan tags: trunk) | |
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) | |
18:14 | Improve the decision about when to stop doing HTTP round-trips while doing a clone so that the clone will continue as long as new content is being received and we have not yet seen the "clone_seqno 0" card. Proposed fix for the issue discussed in forum thread 60d48c2896. ... (check-in: ea5afad3 user: drh tags: trunk) | |
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 */; |
︙ | ︙ | |||
172 173 174 175 176 177 178 | this.pos.prev refers to the line numbers in the previous TR's chunk. */ if(this.pos.prev && this.pos.next && ((this.pos.next.startLhs - this.pos.prev.endLhs) <= Diff.config.chunkLoadLines)){ /* Place a single button to load the whole block, rather than separate up/down buttons. */ | | | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | this.pos.prev refers to the line numbers in the previous TR's chunk. */ if(this.pos.prev && this.pos.next && ((this.pos.next.startLhs - this.pos.prev.endLhs) <= Diff.config.chunkLoadLines)){ /* Place a single button to load the whole block, rather than separate up/down buttons. */ btnDown = this.createButton(this.FetchType.FillGap); btnUp = this.createButton(this.FetchType.FillGap); }else{ /* Figure out which chunk-load buttons to add... */ if(this.pos.prev){ btnDown = this.createButton(this.FetchType.PrevDown); } if(this.pos.next){ |
︙ | ︙ | |||
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 | } 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); | > > | > > > > | 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 301 302 | } 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); for( var i=0; i<2; i++ ){ 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. */ | > > > > > > > > > > > < < < | | | > > > > | 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 550 551 | 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; } } | < > | > > | 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 | 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 |
︙ | ︙ |