Fossil SCM
Merged in trunk. /chat changed jump-to-message animation to fade out/in, per requests. Added HTML5 history to /chat clicks on #NNN message references but it's disabled because it's behaving unexpectedly.
Commit
99b23d0fa357acce0f9445f6192284cd8008e8500e1dab0e432f869d55a80a1d
Parent
4539bf879254548…
15 files changed
+2
-3
+2
-3
-16
+7
-5
+7
-5
+31
-14
+83
-2
+97
+1
-1
+8
+8
+2
+1
-1
+2
-2
+1
-1
+2
-3
| --- src/chat.c | ||
| +++ src/chat.c | ||
| @@ -217,24 +217,23 @@ | ||
| 217 | 217 | /* Always in-line the javascript for the chat page */ |
| 218 | 218 | @ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */ |
| 219 | 219 | /* We need an onload handler to ensure that window.fossil is |
| 220 | 220 | initialized before the chat init code runs. */ |
| 221 | 221 | @ window.addEventListener('load', function(){ |
| 222 | - @ document.body.classList.add('chat') | |
| 222 | + @ document.body.classList.add('chat'); | |
| 223 | 223 | @ /*^^^for skins which add their own BODY tag */; |
| 224 | 224 | @ window.fossil.config.chat = { |
| 225 | 225 | @ fromcli: %h(PB("cli")?"true":"false"), |
| 226 | 226 | @ alertSound: "%h(zAlert)", |
| 227 | 227 | @ initSize: %d(db_get_int("chat-initial-history",50)), |
| 228 | 228 | @ imagesInline: !!%d(db_get_boolean("chat-inline-images",1)) |
| 229 | 229 | @ }; |
| 230 | 230 | ajax_emit_js_preview_modes(0); |
| 231 | 231 | chat_emit_alert_list(); |
| 232 | - cgi_append_content(builtin_text("chat.js"),-1); | |
| 233 | 232 | @ }, false); |
| 234 | 233 | @ </script> |
| 235 | - | |
| 234 | + builtin_request_js("fossil.page.chat.js"); | |
| 236 | 235 | style_finish_page(); |
| 237 | 236 | } |
| 238 | 237 | |
| 239 | 238 | /* Definition of repository tables used by chat |
| 240 | 239 | */ |
| 241 | 240 | |
| 242 | 241 | DELETED src/chat.js |
| --- src/chat.c | |
| +++ src/chat.c | |
| @@ -217,24 +217,23 @@ | |
| 217 | /* Always in-line the javascript for the chat page */ |
| 218 | @ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */ |
| 219 | /* We need an onload handler to ensure that window.fossil is |
| 220 | initialized before the chat init code runs. */ |
| 221 | @ window.addEventListener('load', function(){ |
| 222 | @ document.body.classList.add('chat') |
| 223 | @ /*^^^for skins which add their own BODY tag */; |
| 224 | @ window.fossil.config.chat = { |
| 225 | @ fromcli: %h(PB("cli")?"true":"false"), |
| 226 | @ alertSound: "%h(zAlert)", |
| 227 | @ initSize: %d(db_get_int("chat-initial-history",50)), |
| 228 | @ imagesInline: !!%d(db_get_boolean("chat-inline-images",1)) |
| 229 | @ }; |
| 230 | ajax_emit_js_preview_modes(0); |
| 231 | chat_emit_alert_list(); |
| 232 | cgi_append_content(builtin_text("chat.js"),-1); |
| 233 | @ }, false); |
| 234 | @ </script> |
| 235 | |
| 236 | style_finish_page(); |
| 237 | } |
| 238 | |
| 239 | /* Definition of repository tables used by chat |
| 240 | */ |
| 241 | |
| 242 | ELETED src/chat.js |
| --- src/chat.c | |
| +++ src/chat.c | |
| @@ -217,24 +217,23 @@ | |
| 217 | /* Always in-line the javascript for the chat page */ |
| 218 | @ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */ |
| 219 | /* We need an onload handler to ensure that window.fossil is |
| 220 | initialized before the chat init code runs. */ |
| 221 | @ window.addEventListener('load', function(){ |
| 222 | @ document.body.classList.add('chat'); |
| 223 | @ /*^^^for skins which add their own BODY tag */; |
| 224 | @ window.fossil.config.chat = { |
| 225 | @ fromcli: %h(PB("cli")?"true":"false"), |
| 226 | @ alertSound: "%h(zAlert)", |
| 227 | @ initSize: %d(db_get_int("chat-initial-history",50)), |
| 228 | @ imagesInline: !!%d(db_get_boolean("chat-inline-images",1)) |
| 229 | @ }; |
| 230 | ajax_emit_js_preview_modes(0); |
| 231 | chat_emit_alert_list(); |
| 232 | @ }, false); |
| 233 | @ </script> |
| 234 | builtin_request_js("fossil.page.chat.js"); |
| 235 | style_finish_page(); |
| 236 | } |
| 237 | |
| 238 | /* Definition of repository tables used by chat |
| 239 | */ |
| 240 | |
| 241 | ELETED src/chat.js |
+2
-3
| --- src/chat.c | ||
| +++ src/chat.c | ||
| @@ -217,24 +217,23 @@ | ||
| 217 | 217 | /* Always in-line the javascript for the chat page */ |
| 218 | 218 | @ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */ |
| 219 | 219 | /* We need an onload handler to ensure that window.fossil is |
| 220 | 220 | initialized before the chat init code runs. */ |
| 221 | 221 | @ window.addEventListener('load', function(){ |
| 222 | - @ document.body.classList.add('chat') | |
| 222 | + @ document.body.classList.add('chat'); | |
| 223 | 223 | @ /*^^^for skins which add their own BODY tag */; |
| 224 | 224 | @ window.fossil.config.chat = { |
| 225 | 225 | @ fromcli: %h(PB("cli")?"true":"false"), |
| 226 | 226 | @ alertSound: "%h(zAlert)", |
| 227 | 227 | @ initSize: %d(db_get_int("chat-initial-history",50)), |
| 228 | 228 | @ imagesInline: !!%d(db_get_boolean("chat-inline-images",1)) |
| 229 | 229 | @ }; |
| 230 | 230 | ajax_emit_js_preview_modes(0); |
| 231 | 231 | chat_emit_alert_list(); |
| 232 | - cgi_append_content(builtin_text("chat.js"),-1); | |
| 233 | 232 | @ }, false); |
| 234 | 233 | @ </script> |
| 235 | - | |
| 234 | + builtin_request_js("fossil.page.chat.js"); | |
| 236 | 235 | style_finish_page(); |
| 237 | 236 | } |
| 238 | 237 | |
| 239 | 238 | /* Definition of repository tables used by chat |
| 240 | 239 | */ |
| 241 | 240 | |
| 242 | 241 | DELETED src/chat.js |
| --- src/chat.c | |
| +++ src/chat.c | |
| @@ -217,24 +217,23 @@ | |
| 217 | /* Always in-line the javascript for the chat page */ |
| 218 | @ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */ |
| 219 | /* We need an onload handler to ensure that window.fossil is |
| 220 | initialized before the chat init code runs. */ |
| 221 | @ window.addEventListener('load', function(){ |
| 222 | @ document.body.classList.add('chat') |
| 223 | @ /*^^^for skins which add their own BODY tag */; |
| 224 | @ window.fossil.config.chat = { |
| 225 | @ fromcli: %h(PB("cli")?"true":"false"), |
| 226 | @ alertSound: "%h(zAlert)", |
| 227 | @ initSize: %d(db_get_int("chat-initial-history",50)), |
| 228 | @ imagesInline: !!%d(db_get_boolean("chat-inline-images",1)) |
| 229 | @ }; |
| 230 | ajax_emit_js_preview_modes(0); |
| 231 | chat_emit_alert_list(); |
| 232 | cgi_append_content(builtin_text("chat.js"),-1); |
| 233 | @ }, false); |
| 234 | @ </script> |
| 235 | |
| 236 | style_finish_page(); |
| 237 | } |
| 238 | |
| 239 | /* Definition of repository tables used by chat |
| 240 | */ |
| 241 | |
| 242 | ELETED src/chat.js |
| --- src/chat.c | |
| +++ src/chat.c | |
| @@ -217,24 +217,23 @@ | |
| 217 | /* Always in-line the javascript for the chat page */ |
| 218 | @ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */ |
| 219 | /* We need an onload handler to ensure that window.fossil is |
| 220 | initialized before the chat init code runs. */ |
| 221 | @ window.addEventListener('load', function(){ |
| 222 | @ document.body.classList.add('chat'); |
| 223 | @ /*^^^for skins which add their own BODY tag */; |
| 224 | @ window.fossil.config.chat = { |
| 225 | @ fromcli: %h(PB("cli")?"true":"false"), |
| 226 | @ alertSound: "%h(zAlert)", |
| 227 | @ initSize: %d(db_get_int("chat-initial-history",50)), |
| 228 | @ imagesInline: !!%d(db_get_boolean("chat-inline-images",1)) |
| 229 | @ }; |
| 230 | ajax_emit_js_preview_modes(0); |
| 231 | chat_emit_alert_list(); |
| 232 | @ }, false); |
| 233 | @ </script> |
| 234 | builtin_request_js("fossil.page.chat.js"); |
| 235 | style_finish_page(); |
| 236 | } |
| 237 | |
| 238 | /* Definition of repository tables used by chat |
| 239 | */ |
| 240 | |
| 241 | ELETED src/chat.js |
D
src/chat.js
-16
| --- a/src/chat.js | ||
| +++ b/src/chat.js | ||
| @@ -1,16 +0,0 @@ | ||
| 1 | -f =tru//li.push( d.tf =tru//li.push( d.t/li.pusbody > div.header'), | |
| 2 | - body > div.mainmenu'),'), | |
| 3 | - body > #hbdrop'), | |
| 4 | - body > div.footer') | |
| 5 | - ]; | |
| 6 | - const contentArea = E1('div.content')divf =tru//li.push( d.t E1('#chat-clear-filterD8@1R8,H:: { | |
| 7 | - user:8@8Lu,S: activeTag: undefined, | |
| 8 | - f@1ds,p: return !this.activeTag || this.activeTag===uname; | |
| 9 | -N@Bul,9:matchElemP@IXT,x: return !this.activeTag || this.activeTag===e.dataset.xfromN@IvG,I:, | |
| 10 | - hashtag:8@8Lu,u: activeTag: undefined, | |
| 11 | - match: function(tag){J@JU~,f: !this.activeTag || tag===this.activeTag; | |
| 12 | -N@Bul,9:matchElemP@IXT,O: return !this.activeTag8@HYy,11: || !!e.querySelector('[data-hashtag="'+this.activeTag+'"]'O@A5G,11:, | |
| 13 | - current: undefined/*gets set to current active filter*/J@4n~,vt@1fm,12:this.filter.current | |
| 14 | - && !this.filter.current.matchElem(eoe@2bG,3:[];K@G8C,H@KVF,5: | |
| 15 | - 8@35A,J:["body > div.headerG@120,K:"body > div.mainmenuG@120,I:"body > div.footerG@120,B:"#debugMsg"9@H1C,G: ].join(',') | |
| 16 | -A@BVF,a:).for |
| --- a/src/chat.js | |
| +++ b/src/chat.js | |
| @@ -1,16 +0,0 @@ | |
| 1 | f =tru//li.push( d.tf =tru//li.push( d.t/li.pusbody > div.header'), |
| 2 | body > div.mainmenu'),'), |
| 3 | body > #hbdrop'), |
| 4 | body > div.footer') |
| 5 | ]; |
| 6 | const contentArea = E1('div.content')divf =tru//li.push( d.t E1('#chat-clear-filterD8@1R8,H:: { |
| 7 | user:8@8Lu,S: activeTag: undefined, |
| 8 | f@1ds,p: return !this.activeTag || this.activeTag===uname; |
| 9 | N@Bul,9:matchElemP@IXT,x: return !this.activeTag || this.activeTag===e.dataset.xfromN@IvG,I:, |
| 10 | hashtag:8@8Lu,u: activeTag: undefined, |
| 11 | match: function(tag){J@JU~,f: !this.activeTag || tag===this.activeTag; |
| 12 | N@Bul,9:matchElemP@IXT,O: return !this.activeTag8@HYy,11: || !!e.querySelector('[data-hashtag="'+this.activeTag+'"]'O@A5G,11:, |
| 13 | current: undefined/*gets set to current active filter*/J@4n~,vt@1fm,12:this.filter.current |
| 14 | && !this.filter.current.matchElem(eoe@2bG,3:[];K@G8C,H@KVF,5: |
| 15 | 8@35A,J:["body > div.headerG@120,K:"body > div.mainmenuG@120,I:"body > div.footerG@120,B:"#debugMsg"9@H1C,G: ].join(',') |
| 16 | A@BVF,a:).for |
| --- a/src/chat.js | |
| +++ b/src/chat.js | |
| @@ -1,16 +0,0 @@ | |
+7
-5
| --- src/fossil.bootstrap.js | ||
| +++ src/fossil.bootstrap.js | ||
| @@ -280,15 +280,17 @@ | ||
| 280 | 280 | } |
| 281 | 281 | return this; |
| 282 | 282 | }; |
| 283 | 283 | |
| 284 | 284 | /** |
| 285 | - Sets the innerText of the page's TITLE tag to | |
| 286 | - the given text and returns this object. | |
| 285 | + Sets the innerText of the page's TITLE tag to the given text and | |
| 286 | + returns this object. If passed a falsy value then the title is | |
| 287 | + reverted to its page-load-time value. | |
| 287 | 288 | */ |
| 288 | - F.page.setPageTitle = function(title){ | |
| 289 | + F.page.setPageTitle = function f(title){ | |
| 289 | 290 | const t = document.querySelector('title'); |
| 290 | - if(t) t.innerText = title; | |
| 291 | + if(t) t.innerText = title || f.$orig; | |
| 291 | 292 | return this; |
| 292 | 293 | }; |
| 293 | - | |
| 294 | + F.onPageLoad(()=>F.page.setPageTitle.$orig | |
| 295 | + = document.querySelector('title').innerText); | |
| 294 | 296 | })(window); |
| 295 | 297 |
| --- src/fossil.bootstrap.js | |
| +++ src/fossil.bootstrap.js | |
| @@ -280,15 +280,17 @@ | |
| 280 | } |
| 281 | return this; |
| 282 | }; |
| 283 | |
| 284 | /** |
| 285 | Sets the innerText of the page's TITLE tag to |
| 286 | the given text and returns this object. |
| 287 | */ |
| 288 | F.page.setPageTitle = function(title){ |
| 289 | const t = document.querySelector('title'); |
| 290 | if(t) t.innerText = title; |
| 291 | return this; |
| 292 | }; |
| 293 | |
| 294 | })(window); |
| 295 |
| --- src/fossil.bootstrap.js | |
| +++ src/fossil.bootstrap.js | |
| @@ -280,15 +280,17 @@ | |
| 280 | } |
| 281 | return this; |
| 282 | }; |
| 283 | |
| 284 | /** |
| 285 | Sets the innerText of the page's TITLE tag to the given text and |
| 286 | returns this object. If passed a falsy value then the title is |
| 287 | reverted to its page-load-time value. |
| 288 | */ |
| 289 | F.page.setPageTitle = function f(title){ |
| 290 | const t = document.querySelector('title'); |
| 291 | if(t) t.innerText = title || f.$orig; |
| 292 | return this; |
| 293 | }; |
| 294 | F.onPageLoad(()=>F.page.setPageTitle.$orig |
| 295 | = document.querySelector('title').innerText); |
| 296 | })(window); |
| 297 |
+7
-5
| --- src/fossil.bootstrap.js | ||
| +++ src/fossil.bootstrap.js | ||
| @@ -280,15 +280,17 @@ | ||
| 280 | 280 | } |
| 281 | 281 | return this; |
| 282 | 282 | }; |
| 283 | 283 | |
| 284 | 284 | /** |
| 285 | - Sets the innerText of the page's TITLE tag to | |
| 286 | - the given text and returns this object. | |
| 285 | + Sets the innerText of the page's TITLE tag to the given text and | |
| 286 | + returns this object. If passed a falsy value then the title is | |
| 287 | + reverted to its page-load-time value. | |
| 287 | 288 | */ |
| 288 | - F.page.setPageTitle = function(title){ | |
| 289 | + F.page.setPageTitle = function f(title){ | |
| 289 | 290 | const t = document.querySelector('title'); |
| 290 | - if(t) t.innerText = title; | |
| 291 | + if(t) t.innerText = title || f.$orig; | |
| 291 | 292 | return this; |
| 292 | 293 | }; |
| 293 | - | |
| 294 | + F.onPageLoad(()=>F.page.setPageTitle.$orig | |
| 295 | + = document.querySelector('title').innerText); | |
| 294 | 296 | })(window); |
| 295 | 297 |
| --- src/fossil.bootstrap.js | |
| +++ src/fossil.bootstrap.js | |
| @@ -280,15 +280,17 @@ | |
| 280 | } |
| 281 | return this; |
| 282 | }; |
| 283 | |
| 284 | /** |
| 285 | Sets the innerText of the page's TITLE tag to |
| 286 | the given text and returns this object. |
| 287 | */ |
| 288 | F.page.setPageTitle = function(title){ |
| 289 | const t = document.querySelector('title'); |
| 290 | if(t) t.innerText = title; |
| 291 | return this; |
| 292 | }; |
| 293 | |
| 294 | })(window); |
| 295 |
| --- src/fossil.bootstrap.js | |
| +++ src/fossil.bootstrap.js | |
| @@ -280,15 +280,17 @@ | |
| 280 | } |
| 281 | return this; |
| 282 | }; |
| 283 | |
| 284 | /** |
| 285 | Sets the innerText of the page's TITLE tag to the given text and |
| 286 | returns this object. If passed a falsy value then the title is |
| 287 | reverted to its page-load-time value. |
| 288 | */ |
| 289 | F.page.setPageTitle = function f(title){ |
| 290 | const t = document.querySelector('title'); |
| 291 | if(t) t.innerText = title || f.$orig; |
| 292 | return this; |
| 293 | }; |
| 294 | F.onPageLoad(()=>F.page.setPageTitle.$orig |
| 295 | = document.querySelector('title').innerText); |
| 296 | })(window); |
| 297 |
+31
-14
| --- src/fossil.diff.js | ||
| +++ src/fossil.diff.js | ||
| @@ -117,10 +117,11 @@ | ||
| 117 | 117 | example of which, for use as a model, is: |
| 118 | 118 | |
| 119 | 119 | https://github.com/msteveb/autosetup/commit/235925e914a52a542 |
| 120 | 120 | */ |
| 121 | 121 | const ChunkLoadControls = function(tr){ |
| 122 | + this.$fetchQueue = []; | |
| 122 | 123 | this.e = {/*DOM elements*/ |
| 123 | 124 | tr: tr, |
| 124 | 125 | table: tr.parentElement/*TBODY*/.parentElement |
| 125 | 126 | }; |
| 126 | 127 | this.isSplit = this.e.table.classList.contains('splitdiff')/*else udiff*/; |
| @@ -209,17 +210,13 @@ | ||
| 209 | 210 | /** Fill a complete gap between the previous/next diff chunks |
| 210 | 211 | or at the start of the next chunk or end of the previous |
| 211 | 212 | chunks. */ |
| 212 | 213 | FillGap: 0, |
| 213 | 214 | /** Prepend context to the start of the next diff chunk. */ |
| 214 | - NextUp: -1 | |
| 215 | - }, | |
| 216 | - config: { | |
| 217 | - /* | |
| 218 | - glyphUp: '⇡', //'&#uarr;', | |
| 219 | - glyphDown: '⇣' //'&#darr;' | |
| 220 | - */ | |
| 215 | + NextUp: -1, | |
| 216 | + /** Process the next queued action. */ | |
| 217 | + ProcessQueue: 0x7fffffff | |
| 221 | 218 | }, |
| 222 | 219 | |
| 223 | 220 | /** |
| 224 | 221 | Creates and returns a button element for fetching a chunk in |
| 225 | 222 | the given fetchType (as documented for fetchChunk()). |
| @@ -262,10 +259,11 @@ | ||
| 262 | 259 | }, |
| 263 | 260 | |
| 264 | 261 | /* Attempt to clean up resources and remove some circular references to |
| 265 | 262 | that GC can do the right thing. */ |
| 266 | 263 | destroy: function(){ |
| 264 | + delete this.$fetchQueue; | |
| 267 | 265 | D.remove(this.e.tr); |
| 268 | 266 | delete this.e.tr.$chunker; |
| 269 | 267 | delete this.e.tr; |
| 270 | 268 | delete this.e; |
| 271 | 269 | delete this.pos; |
| @@ -282,10 +280,13 @@ | ||
| 282 | 280 | maybeReplaceButtons: function(){ |
| 283 | 281 | if(this.pos.next && this.pos.prev |
| 284 | 282 | && (this.pos.endLhs - this.pos.startLhs <= Diff.config.chunkLoadLines)){ |
| 285 | 283 | D.clearElement(this.e.btnWrapper); |
| 286 | 284 | D.append(this.e.btnWrapper, this.createButton(this.FetchType.FillGap)); |
| 285 | + if( this.$fetchQueue && this.$fetchQueue.length>0 ){ | |
| 286 | + this.$fetchQueue = [this.FetchType.FillGap]; | |
| 287 | + } | |
| 287 | 288 | } |
| 288 | 289 | return this; |
| 289 | 290 | }, |
| 290 | 291 | |
| 291 | 292 | /** |
| @@ -501,28 +502,42 @@ | ||
| 501 | 502 | This is an async operation. While it is in transit, any calls |
| 502 | 503 | to this function will have no effect except (possibly) to emit |
| 503 | 504 | a warning. Returns this object. |
| 504 | 505 | */ |
| 505 | 506 | fetchChunk: function(fetchType){ |
| 507 | + if( !this.$fetchQueue ) return this; // HACKHACK: are we destroyed? | |
| 508 | + if( fetchType==this.FetchType.ProcessQueue ){ | |
| 509 | + if( this.$fetchQueue.length==0 ) return this; | |
| 510 | + //console.log('fetchChunk: processing queue ...'); | |
| 511 | + } | |
| 512 | + else{ | |
| 513 | + this.$fetchQueue.push(fetchType); | |
| 514 | + if( this.$fetchQueue.length!=1 ) return this; | |
| 515 | + //console.log('fetchChunk: processing user input ...'); | |
| 516 | + } | |
| 517 | + fetchType = this.$fetchQueue[0]; | |
| 506 | 518 | /* Forewarning, this is a bit confusing: when fetching the |
| 507 | 519 | previous lines, we're doing so on behalf of the *next* diff |
| 508 | 520 | chunk (this.pos.next), and vice versa. */ |
| 509 | - if(this.$isFetching){ | |
| 510 | - return this.msg(true,"Cannot load chunk while a load is pending."); | |
| 511 | - } | |
| 512 | 521 | if(fetchType===this.FetchType.NextUp && !this.pos.next |
| 513 | 522 | || fetchType===this.FetchType.PrevDown && !this.pos.prev){ |
| 514 | 523 | console.error("Attempt to fetch diff lines but don't have any."); |
| 515 | 524 | return this; |
| 516 | 525 | } |
| 517 | 526 | this.msg(false,"Fetching diff chunk..."); |
| 527 | + const self = this; | |
| 518 | 528 | const fOpt = { |
| 519 | 529 | urlParams:{ |
| 520 | 530 | name: this.fileHash, from: 0, to: 0 |
| 521 | 531 | }, |
| 522 | - aftersend: ()=>delete this.$isFetching, | |
| 523 | - onload: (list)=>this.injectResponse(fetchType,up,list) | |
| 532 | + aftersend: ()=>this.msg(false), | |
| 533 | + onload: function(list){ | |
| 534 | + self.injectResponse(fetchType,up,list); | |
| 535 | + if( !self.$fetchQueue || self.$fetchQueue.length==0 ) return; | |
| 536 | + self.$fetchQueue.shift(); | |
| 537 | + setTimeout(self.fetchChunk.bind(self,self.FetchType.ProcessQueue)); | |
| 538 | + } | |
| 524 | 539 | }; |
| 525 | 540 | const up = fOpt.urlParams; |
| 526 | 541 | if(fetchType===this.FetchType.FillGap){ |
| 527 | 542 | /* Easiest case: filling a whole gap. */ |
| 528 | 543 | up.from = this.pos.startLhs; |
| @@ -551,13 +566,15 @@ | ||
| 551 | 566 | if( this.pos.prev && this.pos.prev.endLhs >= up.from ){ |
| 552 | 567 | up.from = this.pos.prev.endLhs + 1; |
| 553 | 568 | fetchType = this.FetchType.FillGap; |
| 554 | 569 | } |
| 555 | 570 | } |
| 556 | - this.$isFetching = true; | |
| 557 | 571 | //console.debug("fetchChunk(",fetchType,")",up); |
| 558 | - fOpt.onerror = (err)=>this.msg(true,err.message); | |
| 572 | + fOpt.onerror = function(err){ | |
| 573 | + self.msg(true,err.message); | |
| 574 | + self.$fetchQueue = []; | |
| 575 | + }; | |
| 559 | 576 | Diff.fetchArtifactChunk(fOpt); |
| 560 | 577 | return this; |
| 561 | 578 | } |
| 562 | 579 | }; |
| 563 | 580 | |
| 564 | 581 | |
| 565 | 582 | ADDED src/fossil.page.chat.js |
| --- src/fossil.diff.js | |
| +++ src/fossil.diff.js | |
| @@ -117,10 +117,11 @@ | |
| 117 | example of which, for use as a model, is: |
| 118 | |
| 119 | https://github.com/msteveb/autosetup/commit/235925e914a52a542 |
| 120 | */ |
| 121 | const ChunkLoadControls = function(tr){ |
| 122 | this.e = {/*DOM elements*/ |
| 123 | tr: tr, |
| 124 | table: tr.parentElement/*TBODY*/.parentElement |
| 125 | }; |
| 126 | this.isSplit = this.e.table.classList.contains('splitdiff')/*else udiff*/; |
| @@ -209,17 +210,13 @@ | |
| 209 | /** Fill a complete gap between the previous/next diff chunks |
| 210 | or at the start of the next chunk or end of the previous |
| 211 | chunks. */ |
| 212 | FillGap: 0, |
| 213 | /** Prepend context to the start of the next diff chunk. */ |
| 214 | NextUp: -1 |
| 215 | }, |
| 216 | config: { |
| 217 | /* |
| 218 | glyphUp: '⇡', //'&#uarr;', |
| 219 | glyphDown: '⇣' //'&#darr;' |
| 220 | */ |
| 221 | }, |
| 222 | |
| 223 | /** |
| 224 | Creates and returns a button element for fetching a chunk in |
| 225 | the given fetchType (as documented for fetchChunk()). |
| @@ -262,10 +259,11 @@ | |
| 262 | }, |
| 263 | |
| 264 | /* Attempt to clean up resources and remove some circular references to |
| 265 | that GC can do the right thing. */ |
| 266 | destroy: function(){ |
| 267 | D.remove(this.e.tr); |
| 268 | delete this.e.tr.$chunker; |
| 269 | delete this.e.tr; |
| 270 | delete this.e; |
| 271 | delete this.pos; |
| @@ -282,10 +280,13 @@ | |
| 282 | maybeReplaceButtons: function(){ |
| 283 | if(this.pos.next && this.pos.prev |
| 284 | && (this.pos.endLhs - this.pos.startLhs <= Diff.config.chunkLoadLines)){ |
| 285 | D.clearElement(this.e.btnWrapper); |
| 286 | D.append(this.e.btnWrapper, this.createButton(this.FetchType.FillGap)); |
| 287 | } |
| 288 | return this; |
| 289 | }, |
| 290 | |
| 291 | /** |
| @@ -501,28 +502,42 @@ | |
| 501 | This is an async operation. While it is in transit, any calls |
| 502 | to this function will have no effect except (possibly) to emit |
| 503 | a warning. Returns this object. |
| 504 | */ |
| 505 | fetchChunk: function(fetchType){ |
| 506 | /* Forewarning, this is a bit confusing: when fetching the |
| 507 | previous lines, we're doing so on behalf of the *next* diff |
| 508 | chunk (this.pos.next), and vice versa. */ |
| 509 | if(this.$isFetching){ |
| 510 | return this.msg(true,"Cannot load chunk while a load is pending."); |
| 511 | } |
| 512 | if(fetchType===this.FetchType.NextUp && !this.pos.next |
| 513 | || fetchType===this.FetchType.PrevDown && !this.pos.prev){ |
| 514 | console.error("Attempt to fetch diff lines but don't have any."); |
| 515 | return this; |
| 516 | } |
| 517 | this.msg(false,"Fetching diff chunk..."); |
| 518 | const fOpt = { |
| 519 | urlParams:{ |
| 520 | name: this.fileHash, from: 0, to: 0 |
| 521 | }, |
| 522 | aftersend: ()=>delete this.$isFetching, |
| 523 | onload: (list)=>this.injectResponse(fetchType,up,list) |
| 524 | }; |
| 525 | const up = fOpt.urlParams; |
| 526 | if(fetchType===this.FetchType.FillGap){ |
| 527 | /* Easiest case: filling a whole gap. */ |
| 528 | up.from = this.pos.startLhs; |
| @@ -551,13 +566,15 @@ | |
| 551 | if( this.pos.prev && this.pos.prev.endLhs >= up.from ){ |
| 552 | up.from = this.pos.prev.endLhs + 1; |
| 553 | fetchType = this.FetchType.FillGap; |
| 554 | } |
| 555 | } |
| 556 | this.$isFetching = true; |
| 557 | //console.debug("fetchChunk(",fetchType,")",up); |
| 558 | fOpt.onerror = (err)=>this.msg(true,err.message); |
| 559 | Diff.fetchArtifactChunk(fOpt); |
| 560 | return this; |
| 561 | } |
| 562 | }; |
| 563 | |
| 564 | |
| 565 | DDED src/fossil.page.chat.js |
| --- src/fossil.diff.js | |
| +++ src/fossil.diff.js | |
| @@ -117,10 +117,11 @@ | |
| 117 | example of which, for use as a model, is: |
| 118 | |
| 119 | https://github.com/msteveb/autosetup/commit/235925e914a52a542 |
| 120 | */ |
| 121 | const ChunkLoadControls = function(tr){ |
| 122 | this.$fetchQueue = []; |
| 123 | this.e = {/*DOM elements*/ |
| 124 | tr: tr, |
| 125 | table: tr.parentElement/*TBODY*/.parentElement |
| 126 | }; |
| 127 | this.isSplit = this.e.table.classList.contains('splitdiff')/*else udiff*/; |
| @@ -209,17 +210,13 @@ | |
| 210 | /** Fill a complete gap between the previous/next diff chunks |
| 211 | or at the start of the next chunk or end of the previous |
| 212 | chunks. */ |
| 213 | FillGap: 0, |
| 214 | /** Prepend context to the start of the next diff chunk. */ |
| 215 | NextUp: -1, |
| 216 | /** Process the next queued action. */ |
| 217 | ProcessQueue: 0x7fffffff |
| 218 | }, |
| 219 | |
| 220 | /** |
| 221 | Creates and returns a button element for fetching a chunk in |
| 222 | the given fetchType (as documented for fetchChunk()). |
| @@ -262,10 +259,11 @@ | |
| 259 | }, |
| 260 | |
| 261 | /* Attempt to clean up resources and remove some circular references to |
| 262 | that GC can do the right thing. */ |
| 263 | destroy: function(){ |
| 264 | delete this.$fetchQueue; |
| 265 | D.remove(this.e.tr); |
| 266 | delete this.e.tr.$chunker; |
| 267 | delete this.e.tr; |
| 268 | delete this.e; |
| 269 | delete this.pos; |
| @@ -282,10 +280,13 @@ | |
| 280 | maybeReplaceButtons: function(){ |
| 281 | if(this.pos.next && this.pos.prev |
| 282 | && (this.pos.endLhs - this.pos.startLhs <= Diff.config.chunkLoadLines)){ |
| 283 | D.clearElement(this.e.btnWrapper); |
| 284 | D.append(this.e.btnWrapper, this.createButton(this.FetchType.FillGap)); |
| 285 | if( this.$fetchQueue && this.$fetchQueue.length>0 ){ |
| 286 | this.$fetchQueue = [this.FetchType.FillGap]; |
| 287 | } |
| 288 | } |
| 289 | return this; |
| 290 | }, |
| 291 | |
| 292 | /** |
| @@ -501,28 +502,42 @@ | |
| 502 | This is an async operation. While it is in transit, any calls |
| 503 | to this function will have no effect except (possibly) to emit |
| 504 | a warning. Returns this object. |
| 505 | */ |
| 506 | fetchChunk: function(fetchType){ |
| 507 | if( !this.$fetchQueue ) return this; // HACKHACK: are we destroyed? |
| 508 | if( fetchType==this.FetchType.ProcessQueue ){ |
| 509 | if( this.$fetchQueue.length==0 ) return this; |
| 510 | //console.log('fetchChunk: processing queue ...'); |
| 511 | } |
| 512 | else{ |
| 513 | this.$fetchQueue.push(fetchType); |
| 514 | if( this.$fetchQueue.length!=1 ) return this; |
| 515 | //console.log('fetchChunk: processing user input ...'); |
| 516 | } |
| 517 | fetchType = this.$fetchQueue[0]; |
| 518 | /* Forewarning, this is a bit confusing: when fetching the |
| 519 | previous lines, we're doing so on behalf of the *next* diff |
| 520 | chunk (this.pos.next), and vice versa. */ |
| 521 | if(fetchType===this.FetchType.NextUp && !this.pos.next |
| 522 | || fetchType===this.FetchType.PrevDown && !this.pos.prev){ |
| 523 | console.error("Attempt to fetch diff lines but don't have any."); |
| 524 | return this; |
| 525 | } |
| 526 | this.msg(false,"Fetching diff chunk..."); |
| 527 | const self = this; |
| 528 | const fOpt = { |
| 529 | urlParams:{ |
| 530 | name: this.fileHash, from: 0, to: 0 |
| 531 | }, |
| 532 | aftersend: ()=>this.msg(false), |
| 533 | onload: function(list){ |
| 534 | self.injectResponse(fetchType,up,list); |
| 535 | if( !self.$fetchQueue || self.$fetchQueue.length==0 ) return; |
| 536 | self.$fetchQueue.shift(); |
| 537 | setTimeout(self.fetchChunk.bind(self,self.FetchType.ProcessQueue)); |
| 538 | } |
| 539 | }; |
| 540 | const up = fOpt.urlParams; |
| 541 | if(fetchType===this.FetchType.FillGap){ |
| 542 | /* Easiest case: filling a whole gap. */ |
| 543 | up.from = this.pos.startLhs; |
| @@ -551,13 +566,15 @@ | |
| 566 | if( this.pos.prev && this.pos.prev.endLhs >= up.from ){ |
| 567 | up.from = this.pos.prev.endLhs + 1; |
| 568 | fetchType = this.FetchType.FillGap; |
| 569 | } |
| 570 | } |
| 571 | //console.debug("fetchChunk(",fetchType,")",up); |
| 572 | fOpt.onerror = function(err){ |
| 573 | self.msg(true,err.message); |
| 574 | self.$fetchQueue = []; |
| 575 | }; |
| 576 | Diff.fetchArtifactChunk(fOpt); |
| 577 | return this; |
| 578 | } |
| 579 | }; |
| 580 | |
| 581 | |
| 582 | DDED src/fossil.page.chat.js |
+83
-2
| --- a/src/fossil.page.chat.js | ||
| +++ b/src/fossil.page.chat.js | ||
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | f =tru//li.push( d.tf =tru//li.push( d.t/li.pusbody > div.header'), |
| 2 | - body > div.mainmenu'),'), | |
| 2 | + body > div.mainmenu'), | |
| 3 | 3 | body > #hbdrop'), |
| 4 | 4 | body > div.footer') |
| 5 | 5 | ]; |
| @@ -13,4 +13,85 @@ | ||
| 13 | 13 | current: undefined/*gets set to current active filter*/J@4n~,vt@1fm,12:this.filter.current |
| 14 | 14 | && !this.filter.current.matchElem(eoe@2bG,3:[];K@G8C,H@KVF,5: |
| 15 | 15 | 8@35A,J:["body > div.headerG@120,K:"body > div.mainmenuG@120,I:"body > div.footerG@120,B:"#debugMsg"9@H1C,G: ].join(',') |
| 16 | -A@BVF,a:).for | |
| 16 | +A@BVF,a:).forEach((e)=>f.elemsToToggle.push(e1L6@3Ql,8:D.removeN@5vE,Ha@4mY,J:.user.activeTag===uH@APW,By@53h,15: | |
| 17 | + For each Chat.MessageWidget element (X.message-widget) for | |
| 18 | +9@9NF,u:which predicate(elem) returns true, the 'hidden' class isA@5NB,5A:removed from that message. For all others, 'hidden' is | |
| 19 | + added. If predicate is falsy, 'hidden' is removed from all | |
| 20 | + elements. After filtering, it will try to scroll the last | |
| 21 | + not-filsage into view, but exactly where it | |
| 22 | + scrolls into view (top, middle, button) is | |
| 23 | + unpredictableM@5GB,2C: | |
| 24 | + | |
| 25 | + The argument may optionally be an object from this.filter, | |
| 26 | + in which case its matchElem() method becomes the predicate. | |
| 27 | + | |
| 28 | +9@Jkj,2i:Note that this does not encapsulate certain filter-specific | |
| 29 | + logic which applies changes to elements other than the | |
| 30 | + main message list or this.e.btnClearFiltJ@3O0,b:applyMessageFilter: function(predicateB@HBh,R@AzV,J@5aF,o:console.debug("applyMessageFilter(",predicate,")");9@3rt,E:if(!predicate)Q@3VT,4:this1c@5bA0 ?){} : (function fif('function'!==typeof predicateH@BFG,~:&& predicate.matchElem){ | |
| 31 | + /* assume Chat.filter objectK@77z,F:p = predicate; | |
| 32 | +A@Af6,T:predicate = (e)=>p.matchElem(M@2Ul,B:if(predicatJ@6_l,l@5bB,U@KV~,K: if(predicate(eG@J_W,3: eJ@Jpy,I@HoF,H: eLast = e; | |
| 33 | +X@AoW,Z@2bU,S@5gS,a: D.removeClass(this.e.btnClearFilterL@9x~,6:} | |
| 34 | + n@DS9,1Q@5gz,e@4dl,A:Clears theG@5X0,X: filter, if any, a */ | |
| 35 | + if(!f.elemsToCount){ | |
| 36 | +d.tf =tru//li.f =tru//li.push(ggle.push(e1L6@3Ql,8:D.removggle.push(e1L6@3Ql,8:D.removeN@5v#hbdrop'), | |
| 37 | + d.tf =tru//li.push( d.t/li.f =tru//li.pumessage-submit'), | |
| 38 | + inputSingsingle'), | |
| 39 | +inputMultimulti'), | |
| 40 | + inputCpreview-buttonvaluevalue-clear-filterD8@1R8,Hf =tru//li.push( d.tf =tru//li.push( d.t/li.pusbody > div.header'), | |
| 41 | + body > div.mainmenu'), | |
| 42 | + body > #hbdrop'), | |
| 43 | + body > div.footer') | |
| 44 | + ]; | |
| 45 | + const contentArea = E1('div.content')divf =tru//li.push( d.t E1('#chat-clear-filterD8@1R8,H:: { | |
| 46 | + user:8@8Lu,S: acCurrent-clear-filterD8@1R8,H:f =tru//li.push( d.tToggleSingleMulticonst old = this.e.inputCurrentcontentArea = E1('f =tru//li.inputCurrent = this.e.inputMulti;inputLinesingle-lineul,9:matchElemP@IXTf =tru//li.push( d.tf =tru//li.pusru//li.push( d.tf =ti.push( d.t/li.pusbody > diChat.e.inputSinglkeydown@3VT,4:this1c@5bA0 ?if(13===ev.keyCode/*ENTER*/} | |
| 47 | + }inputMultikeydown@3VT,4:this1c@5bA0 ?if(ev.ctrlKey && } | |
| 48 | + }refif(0)ole.debug("onpopstate event",event.state, event); | |
| 49 | + if(event.state && event.state.msgIevent.state.msgId+'"]'); | |
| 50 | + event.state//F.page.setPageTitle("Fossi1?"console.debug("History length =f =tru//li.push( d.tf =tru//li.push( d.t/li.pusbody > div.header'), | |
| 51 | + body > div.mainmenu'), | |
| 52 | + body > #hbdrop'), | |
| 53 | + body > div.footer') | |
| 54 | + ]; | |
| 55 | + const contentArea = E1('div.content')divf =tru//li.push( d.t E1('#chat-clear-filterD8@1R8,H:: { | |
| 56 | + user:8@8Lu,S: activeTag: undefined, | |
| 57 | + f@1ds,p: return !this.activeTag || this.activeTag===uname; | |
| 58 | +N@Bul,9:matchElemP@IXT,x: return !this.activeTag || this.activeTag===e.dataset.xfromN@IvG,I:, | |
| 59 | + hashtag:8@8Lu,u: activeTag: undefined, | |
| 60 | + match: function(tag){J@JU~,f: !this.activeTag || tag===this.activeTag; | |
| 61 | +N@Bul,9:matchElemP@IXT,O: return !this.activeTag8@HYy,11: || !!e.querySelector('[data-hashtag="'+this.activeTag+'"]'O@A5G,11:, | |
| 62 | + current: undefined/*gets set to current active filter*/J@4n~,vt@1fm,12:this.filter.current | |
| 63 | + && !this.filter.current.matchElem(eoe@2bG,3:[];K@G8C,H@KVF,5: | |
| 64 | + 8@35A,J:["body > div.headerG@120,K:"body > div.mainmenuG@120,I:"body > div.footerG@120,B:"#debugMsg"9@H1C,G: ].join(',') | |
| 65 | +A@BVF,a:).forEach((e)=>f.elemsToToggle.push(e1L6@3Ql,8:D.removeN@5vE,Ha@4mY,J:.user.activeTag===uH@APW,By@53h,15: | |
| 66 | + For each Chat.MessageWidget element (X.message-widget) for | |
| 67 | +9@9NF,u:which predicate(elem) returns true, the 'hidden' class isA@5NB,5A:removed from that message. For all others, 'hidden' is | |
| 68 | + added. If predicate is falsy, 'hidden' is removed from all | |
| 69 | + elements. After filtering, it will try to scroll the last | |
| 70 | + not-filsage into view, but exactly where it | |
| 71 | + scrolls into view (top, middle, button) is | |
| 72 | + unpredictableM@5GB,2C: | |
| 73 | + | |
| 74 | + The argument may optionally be an object from this.filter, | |
| 75 | + in which case its matchElem() method becomes the predicate. | |
| 76 | + | |
| 77 | +9@Jkj,2i:Note that this does not encapsulate certain filter-specific | |
| 78 | + logic which applies changes to elements other than the | |
| 79 | + main message list or this.e.btnClearFiltJ@3O0,b:applyMessageFilter: function(predicateB@HBh,R@AzV,J@5aF,o:console.debug("applyMessageFilter(",predicate,")");9@3rt,E:if(!predicate)Q@3VT,4:this1c@5bA0 ?){} : (function fif('function'!==typeof predicateH@BFG,~:&& predicate.matchElem){ | |
| 80 | + /* assume Chat.filter objectK@77z,F:p = predicate; | |
| 81 | +A@Af6,T:predicate = (e)=>p.matchElem(M@2Ul,B:if(predicatJ@6_l,l@5bB,U@KV~,K: if(predicate(eG@J_W,3: eJ@Jpy,I@HoF,H: eLast = e; | |
| 82 | +X@AoW,Z@2bU,S@5gS,a: D.removeClass(this.e.btnClearFilterL@9x~,6:} | |
| 83 | + n@DS9,1Q@5gz,e@4dl,A:Clears theG@5X0,X: filter, if any, a */ | |
| 84 | + if(!f.elemsToCount){ | |
| 85 | +d.tf =tru//li.f =tru//li.push(ggle.push(e1L6@3Ql,8:D.removggle.push(e1L6@3Ql,8:D.removeN@5v#hbdrop'), | |
| 86 | + d.tf =tru//li.push( d.t/li.f =tru//li.pumessage-submit'), | |
| 87 | + inputSingsingle'), | |
| 88 | +inputMultimulti'), | |
| 89 | + inputCpreview-buttonvaluevalue-clear-filterD8@1R8,Hf =tru//li.push( d.tf =tru//li.push( d.t/li.pusbody > div.header'), | |
| 90 | + body > div.mainmenu'), | |
| 91 | + body > #hbdrop'), | |
| 92 | + body > div.footer') | |
| 93 | + ]; | |
| 94 | + const contentArea = E1('div.content')divf =tru//li.push( d.t E1('#chat-clear-filterD8@1R8,H:: { | |
| 95 | + user:8@8Lu,S: acCurrent-clear-filterD8@1R8,H:f =tru//li.push( d.tToggleSingleMulticonst old = this.e.inputCurrentcontentArea = E1('f =tru//li.inputCurrent = this.e.inputMulti;inputLinesingle-lineul,9:matchElemP@IXTf =tru//li.push( d.tf =tru//li.pusru//li.push( d.tf =ti.push( d.t/li.pusbody > diChat.e.inputSinglkeydown@3VT,4:this1c@5bA0 ?if(13===ev.keyCode/*ENTER*/} | |
| 96 | + }inputMultikeydown@3VT,4:this1c@5bA0 ?if(ev.ctrlKey && } | |
| 97 | + } |
| --- a/src/fossil.page.chat.js | |
| +++ b/src/fossil.page.chat.js | |
| @@ -1,5 +1,5 @@ | |
| 1 | f =tru//li.push( d.tf =tru//li.push( d.t/li.pusbody > div.header'), |
| 2 | body > div.mainmenu'),'), |
| 3 | body > #hbdrop'), |
| 4 | body > div.footer') |
| 5 | ]; |
| @@ -13,4 +13,85 @@ | |
| 13 | current: undefined/*gets set to current active filter*/J@4n~,vt@1fm,12:this.filter.current |
| 14 | && !this.filter.current.matchElem(eoe@2bG,3:[];K@G8C,H@KVF,5: |
| 15 | 8@35A,J:["body > div.headerG@120,K:"body > div.mainmenuG@120,I:"body > div.footerG@120,B:"#debugMsg"9@H1C,G: ].join(',') |
| 16 | A@BVF,a:).for |
| --- a/src/fossil.page.chat.js | |
| +++ b/src/fossil.page.chat.js | |
| @@ -1,5 +1,5 @@ | |
| 1 | f =tru//li.push( d.tf =tru//li.push( d.t/li.pusbody > div.header'), |
| 2 | body > div.mainmenu'), |
| 3 | body > #hbdrop'), |
| 4 | body > div.footer') |
| 5 | ]; |
| @@ -13,4 +13,85 @@ | |
| 13 | current: undefined/*gets set to current active filter*/J@4n~,vt@1fm,12:this.filter.current |
| 14 | && !this.filter.current.matchElem(eoe@2bG,3:[];K@G8C,H@KVF,5: |
| 15 | 8@35A,J:["body > div.headerG@120,K:"body > div.mainmenuG@120,I:"body > div.footerG@120,B:"#debugMsg"9@H1C,G: ].join(',') |
| 16 | A@BVF,a:).forEach((e)=>f.elemsToToggle.push(e1L6@3Ql,8:D.removeN@5vE,Ha@4mY,J:.user.activeTag===uH@APW,By@53h,15: |
| 17 | For each Chat.MessageWidget element (X.message-widget) for |
| 18 | 9@9NF,u:which predicate(elem) returns true, the 'hidden' class isA@5NB,5A:removed from that message. For all others, 'hidden' is |
| 19 | added. If predicate is falsy, 'hidden' is removed from all |
| 20 | elements. After filtering, it will try to scroll the last |
| 21 | not-filsage into view, but exactly where it |
| 22 | scrolls into view (top, middle, button) is |
| 23 | unpredictableM@5GB,2C: |
| 24 | |
| 25 | The argument may optionally be an object from this.filter, |
| 26 | in which case its matchElem() method becomes the predicate. |
| 27 | |
| 28 | 9@Jkj,2i:Note that this does not encapsulate certain filter-specific |
| 29 | logic which applies changes to elements other than the |
| 30 | main message list or this.e.btnClearFiltJ@3O0,b:applyMessageFilter: function(predicateB@HBh,R@AzV,J@5aF,o:console.debug("applyMessageFilter(",predicate,")");9@3rt,E:if(!predicate)Q@3VT,4:this1c@5bA0 ?){} : (function fif('function'!==typeof predicateH@BFG,~:&& predicate.matchElem){ |
| 31 | /* assume Chat.filter objectK@77z,F:p = predicate; |
| 32 | A@Af6,T:predicate = (e)=>p.matchElem(M@2Ul,B:if(predicatJ@6_l,l@5bB,U@KV~,K: if(predicate(eG@J_W,3: eJ@Jpy,I@HoF,H: eLast = e; |
| 33 | X@AoW,Z@2bU,S@5gS,a: D.removeClass(this.e.btnClearFilterL@9x~,6:} |
| 34 | n@DS9,1Q@5gz,e@4dl,A:Clears theG@5X0,X: filter, if any, a */ |
| 35 | if(!f.elemsToCount){ |
| 36 | d.tf =tru//li.f =tru//li.push(ggle.push(e1L6@3Ql,8:D.removggle.push(e1L6@3Ql,8:D.removeN@5v#hbdrop'), |
| 37 | d.tf =tru//li.push( d.t/li.f =tru//li.pumessage-submit'), |
| 38 | inputSingsingle'), |
| 39 | inputMultimulti'), |
| 40 | inputCpreview-buttonvaluevalue-clear-filterD8@1R8,Hf =tru//li.push( d.tf =tru//li.push( d.t/li.pusbody > div.header'), |
| 41 | body > div.mainmenu'), |
| 42 | body > #hbdrop'), |
| 43 | body > div.footer') |
| 44 | ]; |
| 45 | const contentArea = E1('div.content')divf =tru//li.push( d.t E1('#chat-clear-filterD8@1R8,H:: { |
| 46 | user:8@8Lu,S: acCurrent-clear-filterD8@1R8,H:f =tru//li.push( d.tToggleSingleMulticonst old = this.e.inputCurrentcontentArea = E1('f =tru//li.inputCurrent = this.e.inputMulti;inputLinesingle-lineul,9:matchElemP@IXTf =tru//li.push( d.tf =tru//li.pusru//li.push( d.tf =ti.push( d.t/li.pusbody > diChat.e.inputSinglkeydown@3VT,4:this1c@5bA0 ?if(13===ev.keyCode/*ENTER*/} |
| 47 | }inputMultikeydown@3VT,4:this1c@5bA0 ?if(ev.ctrlKey && } |
| 48 | }refif(0)ole.debug("onpopstate event",event.state, event); |
| 49 | if(event.state && event.state.msgIevent.state.msgId+'"]'); |
| 50 | event.state//F.page.setPageTitle("Fossi1?"console.debug("History length =f =tru//li.push( d.tf =tru//li.push( d.t/li.pusbody > div.header'), |
| 51 | body > div.mainmenu'), |
| 52 | body > #hbdrop'), |
| 53 | body > div.footer') |
| 54 | ]; |
| 55 | const contentArea = E1('div.content')divf =tru//li.push( d.t E1('#chat-clear-filterD8@1R8,H:: { |
| 56 | user:8@8Lu,S: activeTag: undefined, |
| 57 | f@1ds,p: return !this.activeTag || this.activeTag===uname; |
| 58 | N@Bul,9:matchElemP@IXT,x: return !this.activeTag || this.activeTag===e.dataset.xfromN@IvG,I:, |
| 59 | hashtag:8@8Lu,u: activeTag: undefined, |
| 60 | match: function(tag){J@JU~,f: !this.activeTag || tag===this.activeTag; |
| 61 | N@Bul,9:matchElemP@IXT,O: return !this.activeTag8@HYy,11: || !!e.querySelector('[data-hashtag="'+this.activeTag+'"]'O@A5G,11:, |
| 62 | current: undefined/*gets set to current active filter*/J@4n~,vt@1fm,12:this.filter.current |
| 63 | && !this.filter.current.matchElem(eoe@2bG,3:[];K@G8C,H@KVF,5: |
| 64 | 8@35A,J:["body > div.headerG@120,K:"body > div.mainmenuG@120,I:"body > div.footerG@120,B:"#debugMsg"9@H1C,G: ].join(',') |
| 65 | A@BVF,a:).forEach((e)=>f.elemsToToggle.push(e1L6@3Ql,8:D.removeN@5vE,Ha@4mY,J:.user.activeTag===uH@APW,By@53h,15: |
| 66 | For each Chat.MessageWidget element (X.message-widget) for |
| 67 | 9@9NF,u:which predicate(elem) returns true, the 'hidden' class isA@5NB,5A:removed from that message. For all others, 'hidden' is |
| 68 | added. If predicate is falsy, 'hidden' is removed from all |
| 69 | elements. After filtering, it will try to scroll the last |
| 70 | not-filsage into view, but exactly where it |
| 71 | scrolls into view (top, middle, button) is |
| 72 | unpredictableM@5GB,2C: |
| 73 | |
| 74 | The argument may optionally be an object from this.filter, |
| 75 | in which case its matchElem() method becomes the predicate. |
| 76 | |
| 77 | 9@Jkj,2i:Note that this does not encapsulate certain filter-specific |
| 78 | logic which applies changes to elements other than the |
| 79 | main message list or this.e.btnClearFiltJ@3O0,b:applyMessageFilter: function(predicateB@HBh,R@AzV,J@5aF,o:console.debug("applyMessageFilter(",predicate,")");9@3rt,E:if(!predicate)Q@3VT,4:this1c@5bA0 ?){} : (function fif('function'!==typeof predicateH@BFG,~:&& predicate.matchElem){ |
| 80 | /* assume Chat.filter objectK@77z,F:p = predicate; |
| 81 | A@Af6,T:predicate = (e)=>p.matchElem(M@2Ul,B:if(predicatJ@6_l,l@5bB,U@KV~,K: if(predicate(eG@J_W,3: eJ@Jpy,I@HoF,H: eLast = e; |
| 82 | X@AoW,Z@2bU,S@5gS,a: D.removeClass(this.e.btnClearFilterL@9x~,6:} |
| 83 | n@DS9,1Q@5gz,e@4dl,A:Clears theG@5X0,X: filter, if any, a */ |
| 84 | if(!f.elemsToCount){ |
| 85 | d.tf =tru//li.f =tru//li.push(ggle.push(e1L6@3Ql,8:D.removggle.push(e1L6@3Ql,8:D.removeN@5v#hbdrop'), |
| 86 | d.tf =tru//li.push( d.t/li.f =tru//li.pumessage-submit'), |
| 87 | inputSingsingle'), |
| 88 | inputMultimulti'), |
| 89 | inputCpreview-buttonvaluevalue-clear-filterD8@1R8,Hf =tru//li.push( d.tf =tru//li.push( d.t/li.pusbody > div.header'), |
| 90 | body > div.mainmenu'), |
| 91 | body > #hbdrop'), |
| 92 | body > div.footer') |
| 93 | ]; |
| 94 | const contentArea = E1('div.content')divf =tru//li.push( d.t E1('#chat-clear-filterD8@1R8,H:: { |
| 95 | user:8@8Lu,S: acCurrent-clear-filterD8@1R8,H:f =tru//li.push( d.tToggleSingleMulticonst old = this.e.inputCurrentcontentArea = E1('f =tru//li.inputCurrent = this.e.inputMulti;inputLinesingle-lineul,9:matchElemP@IXTf =tru//li.push( d.tf =tru//li.pusru//li.push( d.tf =ti.push( d.t/li.pusbody > diChat.e.inputSinglkeydown@3VT,4:this1c@5bA0 ?if(13===ev.keyCode/*ENTER*/} |
| 96 | }inputMultikeydown@3VT,4:this1c@5bA0 ?if(ev.ctrlKey && } |
| 97 | } |
+97
| --- a/src/fossil.page.chat.js | ||
| +++ b/src/fossil.page.chat.js | ||
| @@ -0,0 +1,97 @@ | ||
| 1 | +f =tru//li.push( d.tf =tru//li.push( d.t/li.pusbody > div.header'), | |
| 2 | + body > div.mainmenu'), | |
| 3 | + body > #hbdrop'), | |
| 4 | + body > div.footer') | |
| 5 | + ]; | |
| 6 | + const contentArea = E1('div.content')divf =tru//li.push( d.t E1('#chat-clear-filterD8@1R8,H:: { | |
| 7 | + user:8@8Lu,S: activeTag: undefined, | |
| 8 | + f@1ds,p: return !this.activeTag || this.activeTag===uname; | |
| 9 | +N@Bul,9:matchElemP@IXT,x: return !this.activeTag || this.activeTag===e.dataset.xfromN@IvG,I:, | |
| 10 | + hashtag:8@8Lu,u: activeTag: undefined, | |
| 11 | + match: function(tag){J@JU~,f: !this.activeTag || tag===this.activeTag; | |
| 12 | +N@Bul,9:matchElemP@IXT,O: return !this.activeTag8@HYy,11: || !!e.querySelector('[data-hashtag="'+this.activeTag+'"]'O@A5G,11:, | |
| 13 | + current: undefined/*gets set to current active filter*/J@4n~,vt@1fm,12:this.filter.current | |
| 14 | + && !this.filter.current.matchElem(eoe@2bG,3:[];K@G8C,H@KVF,5: | |
| 15 | + 8@35A,J:["body > div.headerG@120,K:"body > div.mainmenuG@120,I:"body > div.footerG@120,B:"#debugMsg"9@H1C,G: ].join(',') | |
| 16 | +A@BVF,a:).forEach((e)=>f.elemsToToggle.push(e1L6@3Ql,8:D.removeN@5vE,Ha@4mY,J:.user.activeTag===uH@APW,By@53h,15: | |
| 17 | + For each Chat.MessageWidget element (X.message-widget) for | |
| 18 | +9@9NF,u:which predicate(elem) returns true, the 'hidden' class isA@5NB,5A:removed from that message. For all others, 'hidden' is | |
| 19 | + added. If predicate is falsy, 'hidden' is removed from all | |
| 20 | + elements. After filtering, it will try to scroll the last | |
| 21 | + not-filsage into view, but exactly where it | |
| 22 | + scrolls into view (top, middle, button) is | |
| 23 | + unpredictableM@5GB,2C: | |
| 24 | + | |
| 25 | + The argument may optionally be an object from this.filter, | |
| 26 | + in which case its matchElem() method becomes the predicate. | |
| 27 | + | |
| 28 | +9@Jkj,2i:Note that this does not encapsulate certain filter-specific | |
| 29 | + logic which applies changes to elements other than the | |
| 30 | + main message list or this.e.btnClearFiltJ@3O0,b:applyMessageFilter: function(predicateB@HBh,R@AzV,J@5aF,o:console.debug("applyMessageFilter(",predicate,")");9@3rt,E:if(!predicate)Q@3VT,4:this1c@5bA0 ?){} : (function fif('function'!==typeof predicateH@BFG,~:&& predicate.matchElem){ | |
| 31 | + /* assume Chat.filter objectK@77z,F:p = predicate; | |
| 32 | +A@Af6,T:predicate = (e)=>p.matchElem(M@2Ul,B:if(predicatJ@6_l,l@5bB,U@KV~,K: if(predicate(eG@J_W,3: eJ@Jpy,I@HoF,H: eLast = e; | |
| 33 | +X@AoW,Z@2bU,S@5gS,a: D.removeClass(this.e.btnClearFilterL@9x~,6:} | |
| 34 | + n@DS9,1Q@5gz,e@4dl,A:Clears theG@5X0,X: filter, if any, a */ | |
| 35 | + if(!f.elemsToCount){ | |
| 36 | +d.tf =tru//li.f =tru//li.push(ggle.push(e1L6@3Ql,8:D.removggle.push(e1L6@3Ql,8:D.removeN@5v#hbdrop'), | |
| 37 | + d.tf =tru//li.push( d.t/li.f =tru//li.pumessage-submit'), | |
| 38 | + inputSingsingle'), | |
| 39 | +inputMultimulti'), | |
| 40 | + inputCpreview-buttonvaluevalue-clear-filterD8@1R8,Hf =tru//li.push( d.tf =tru//li.push( d.t/li.pusbody > div.header'), | |
| 41 | + body > div.mainmenu'), | |
| 42 | + body > #hbdrop'), | |
| 43 | + body > div.footer') | |
| 44 | + ]; | |
| 45 | + const contentArea = E1('div.content')divf =tru//li.push( d.t E1('#chat-clear-filterD8@1R8,H:: { | |
| 46 | + user:8@8Lu,S: acCurrent-clear-filterD8@1R8,H:f =tru//li.push( d.tToggleSingleMulticonst old = this.e.inputCurrentcontentArea = E1('f =tru//li.inputCurrent = this.e.inputMulti;inputLinesingle-lineul,9:matchElemP@IXTf =tru//li.push( d.tf =tru//li.pusru//li.push( d.tf =ti.push( d.t/li.pusbody > diChat.e.inputSinglkeydown@3VT,4:this1c@5bA0 ?if(13===ev.keyCode/*ENTER*/} | |
| 47 | + }inputMultikeydown@3VT,4:this1c@5bA0 ?if(ev.ctrlKey && } | |
| 48 | + }refif(0)ole.debug("onpopstate event",event.state, event); | |
| 49 | + if(event.state && event.state.msgIevent.state.msgId+'"]'); | |
| 50 | + event.state//F.page.setPageTitle("Fossi1?"console.debug("History length =f =tru//li.push( d.tf =tru//li.push( d.t/li.pusbody > div.header'), | |
| 51 | + body > div.mainmenu'), | |
| 52 | + body > #hbdrop'), | |
| 53 | + body > div.footer') | |
| 54 | + ]; | |
| 55 | + const contentArea = E1('div.content')divf =tru//li.push( d.t E1('#chat-clear-filterD8@1R8,H:: { | |
| 56 | + user:8@8Lu,S: activeTag: undefined, | |
| 57 | + f@1ds,p: return !this.activeTag || this.activeTag===uname; | |
| 58 | +N@Bul,9:matchElemP@IXT,x: return !this.activeTag || this.activeTag===e.dataset.xfromN@IvG,I:, | |
| 59 | + hashtag:8@8Lu,u: activeTag: undefined, | |
| 60 | + match: function(tag){J@JU~,f: !this.activeTag || tag===this.activeTag; | |
| 61 | +N@Bul,9:matchElemP@IXT,O: return !this.activeTag8@HYy,11: || !!e.querySelector('[data-hashtag="'+this.activeTag+'"]'O@A5G,11:, | |
| 62 | + current: undefined/*gets set to current active filter*/J@4n~,vt@1fm,12:this.filter.current | |
| 63 | + && !this.filter.current.matchElem(eoe@2bG,3:[];K@G8C,H@KVF,5: | |
| 64 | + 8@35A,J:["body > div.headerG@120,K:"body > div.mainmenuG@120,I:"body > div.footerG@120,B:"#debugMsg"9@H1C,G: ].join(',') | |
| 65 | +A@BVF,a:).forEach((e)=>f.elemsToToggle.push(e1L6@3Ql,8:D.removeN@5vE,Ha@4mY,J:.user.activeTag===uH@APW,By@53h,15: | |
| 66 | + For each Chat.MessageWidget element (X.message-widget) for | |
| 67 | +9@9NF,u:which predicate(elem) returns true, the 'hidden' class isA@5NB,5A:removed from that message. For all others, 'hidden' is | |
| 68 | + added. If predicate is falsy, 'hidden' is removed from all | |
| 69 | + elements. After filtering, it will try to scroll the last | |
| 70 | + not-filsage into view, but exactly where it | |
| 71 | + scrolls into view (top, middle, button) is | |
| 72 | + unpredictableM@5GB,2C: | |
| 73 | + | |
| 74 | + The argument may optionally be an object from this.filter, | |
| 75 | + in which case its matchElem() method becomes the predicate. | |
| 76 | + | |
| 77 | +9@Jkj,2i:Note that this does not encapsulate certain filter-specific | |
| 78 | + logic which applies changes to elements other than the | |
| 79 | + main message list or this.e.btnClearFiltJ@3O0,b:applyMessageFilter: function(predicateB@HBh,R@AzV,J@5aF,o:console.debug("applyMessageFilter(",predicate,")");9@3rt,E:if(!predicate)Q@3VT,4:this1c@5bA0 ?){} : (function fif('function'!==typeof predicateH@BFG,~:&& predicate.matchElem){ | |
| 80 | + /* assume Chat.filter objectK@77z,F:p = predicate; | |
| 81 | +A@Af6,T:predicate = (e)=>p.matchElem(M@2Ul,B:if(predicatJ@6_l,l@5bB,U@KV~,K: if(predicate(eG@J_W,3: eJ@Jpy,I@HoF,H: eLast = e; | |
| 82 | +X@AoW,Z@2bU,S@5gS,a: D.removeClass(this.e.btnClearFilterL@9x~,6:} | |
| 83 | + n@DS9,1Q@5gz,e@4dl,A:Clears theG@5X0,X: filter, if any, a */ | |
| 84 | + if(!f.elemsToCount){ | |
| 85 | +d.tf =tru//li.f =tru//li.push(ggle.push(e1L6@3Ql,8:D.removggle.push(e1L6@3Ql,8:D.removeN@5v#hbdrop'), | |
| 86 | + d.tf =tru//li.push( d.t/li.f =tru//li.pumessage-submit'), | |
| 87 | + inputSingsingle'), | |
| 88 | +inputMultimulti'), | |
| 89 | + inputCpreview-buttonvaluevalue-clear-filterD8@1R8,Hf =tru//li.push( d.tf =tru//li.push( d.t/li.pusbody > div.header'), | |
| 90 | + body > div.mainmenu'), | |
| 91 | + body > #hbdrop'), | |
| 92 | + body > div.footer') | |
| 93 | + ]; | |
| 94 | + const contentArea = E1('div.content')divf =tru//li.push( d.t E1('#chat-clear-filterD8@1R8,H:: { | |
| 95 | + user:8@8Lu,S: acCurrent-clear-filterD8@1R8,H:f =tru//li.push( d.tToggleSingleMulticonst old = this.e.inputCurrentcontentArea = E1('f =tru//li.inputCurrent = this.e.inputMulti;inputLinesingle-lineul,9:matchElemP@IXTf =tru//li.push( d.tf =tru//li.pusru//li.push( d.tf =ti.push( d.t/li.pusbody > diChat.e.inputSinglkeydown@3VT,4:this1c@5bA0 ?if(13===ev.keyCode/*ENTER*/} | |
| 96 | + }inputMultikeydown@3VT,4:this1c@5bA0 ?if(ev.ctrlKey && } | |
| 97 | + } |
| --- a/src/fossil.page.chat.js | |
| +++ b/src/fossil.page.chat.js | |
| @@ -0,0 +1,97 @@ | |
| --- a/src/fossil.page.chat.js | |
| +++ b/src/fossil.page.chat.js | |
| @@ -0,0 +1,97 @@ | |
| 1 | f =tru//li.push( d.tf =tru//li.push( d.t/li.pusbody > div.header'), |
| 2 | body > div.mainmenu'), |
| 3 | body > #hbdrop'), |
| 4 | body > div.footer') |
| 5 | ]; |
| 6 | const contentArea = E1('div.content')divf =tru//li.push( d.t E1('#chat-clear-filterD8@1R8,H:: { |
| 7 | user:8@8Lu,S: activeTag: undefined, |
| 8 | f@1ds,p: return !this.activeTag || this.activeTag===uname; |
| 9 | N@Bul,9:matchElemP@IXT,x: return !this.activeTag || this.activeTag===e.dataset.xfromN@IvG,I:, |
| 10 | hashtag:8@8Lu,u: activeTag: undefined, |
| 11 | match: function(tag){J@JU~,f: !this.activeTag || tag===this.activeTag; |
| 12 | N@Bul,9:matchElemP@IXT,O: return !this.activeTag8@HYy,11: || !!e.querySelector('[data-hashtag="'+this.activeTag+'"]'O@A5G,11:, |
| 13 | current: undefined/*gets set to current active filter*/J@4n~,vt@1fm,12:this.filter.current |
| 14 | && !this.filter.current.matchElem(eoe@2bG,3:[];K@G8C,H@KVF,5: |
| 15 | 8@35A,J:["body > div.headerG@120,K:"body > div.mainmenuG@120,I:"body > div.footerG@120,B:"#debugMsg"9@H1C,G: ].join(',') |
| 16 | A@BVF,a:).forEach((e)=>f.elemsToToggle.push(e1L6@3Ql,8:D.removeN@5vE,Ha@4mY,J:.user.activeTag===uH@APW,By@53h,15: |
| 17 | For each Chat.MessageWidget element (X.message-widget) for |
| 18 | 9@9NF,u:which predicate(elem) returns true, the 'hidden' class isA@5NB,5A:removed from that message. For all others, 'hidden' is |
| 19 | added. If predicate is falsy, 'hidden' is removed from all |
| 20 | elements. After filtering, it will try to scroll the last |
| 21 | not-filsage into view, but exactly where it |
| 22 | scrolls into view (top, middle, button) is |
| 23 | unpredictableM@5GB,2C: |
| 24 | |
| 25 | The argument may optionally be an object from this.filter, |
| 26 | in which case its matchElem() method becomes the predicate. |
| 27 | |
| 28 | 9@Jkj,2i:Note that this does not encapsulate certain filter-specific |
| 29 | logic which applies changes to elements other than the |
| 30 | main message list or this.e.btnClearFiltJ@3O0,b:applyMessageFilter: function(predicateB@HBh,R@AzV,J@5aF,o:console.debug("applyMessageFilter(",predicate,")");9@3rt,E:if(!predicate)Q@3VT,4:this1c@5bA0 ?){} : (function fif('function'!==typeof predicateH@BFG,~:&& predicate.matchElem){ |
| 31 | /* assume Chat.filter objectK@77z,F:p = predicate; |
| 32 | A@Af6,T:predicate = (e)=>p.matchElem(M@2Ul,B:if(predicatJ@6_l,l@5bB,U@KV~,K: if(predicate(eG@J_W,3: eJ@Jpy,I@HoF,H: eLast = e; |
| 33 | X@AoW,Z@2bU,S@5gS,a: D.removeClass(this.e.btnClearFilterL@9x~,6:} |
| 34 | n@DS9,1Q@5gz,e@4dl,A:Clears theG@5X0,X: filter, if any, a */ |
| 35 | if(!f.elemsToCount){ |
| 36 | d.tf =tru//li.f =tru//li.push(ggle.push(e1L6@3Ql,8:D.removggle.push(e1L6@3Ql,8:D.removeN@5v#hbdrop'), |
| 37 | d.tf =tru//li.push( d.t/li.f =tru//li.pumessage-submit'), |
| 38 | inputSingsingle'), |
| 39 | inputMultimulti'), |
| 40 | inputCpreview-buttonvaluevalue-clear-filterD8@1R8,Hf =tru//li.push( d.tf =tru//li.push( d.t/li.pusbody > div.header'), |
| 41 | body > div.mainmenu'), |
| 42 | body > #hbdrop'), |
| 43 | body > div.footer') |
| 44 | ]; |
| 45 | const contentArea = E1('div.content')divf =tru//li.push( d.t E1('#chat-clear-filterD8@1R8,H:: { |
| 46 | user:8@8Lu,S: acCurrent-clear-filterD8@1R8,H:f =tru//li.push( d.tToggleSingleMulticonst old = this.e.inputCurrentcontentArea = E1('f =tru//li.inputCurrent = this.e.inputMulti;inputLinesingle-lineul,9:matchElemP@IXTf =tru//li.push( d.tf =tru//li.pusru//li.push( d.tf =ti.push( d.t/li.pusbody > diChat.e.inputSinglkeydown@3VT,4:this1c@5bA0 ?if(13===ev.keyCode/*ENTER*/} |
| 47 | }inputMultikeydown@3VT,4:this1c@5bA0 ?if(ev.ctrlKey && } |
| 48 | }refif(0)ole.debug("onpopstate event",event.state, event); |
| 49 | if(event.state && event.state.msgIevent.state.msgId+'"]'); |
| 50 | event.state//F.page.setPageTitle("Fossi1?"console.debug("History length =f =tru//li.push( d.tf =tru//li.push( d.t/li.pusbody > div.header'), |
| 51 | body > div.mainmenu'), |
| 52 | body > #hbdrop'), |
| 53 | body > div.footer') |
| 54 | ]; |
| 55 | const contentArea = E1('div.content')divf =tru//li.push( d.t E1('#chat-clear-filterD8@1R8,H:: { |
| 56 | user:8@8Lu,S: activeTag: undefined, |
| 57 | f@1ds,p: return !this.activeTag || this.activeTag===uname; |
| 58 | N@Bul,9:matchElemP@IXT,x: return !this.activeTag || this.activeTag===e.dataset.xfromN@IvG,I:, |
| 59 | hashtag:8@8Lu,u: activeTag: undefined, |
| 60 | match: function(tag){J@JU~,f: !this.activeTag || tag===this.activeTag; |
| 61 | N@Bul,9:matchElemP@IXT,O: return !this.activeTag8@HYy,11: || !!e.querySelector('[data-hashtag="'+this.activeTag+'"]'O@A5G,11:, |
| 62 | current: undefined/*gets set to current active filter*/J@4n~,vt@1fm,12:this.filter.current |
| 63 | && !this.filter.current.matchElem(eoe@2bG,3:[];K@G8C,H@KVF,5: |
| 64 | 8@35A,J:["body > div.headerG@120,K:"body > div.mainmenuG@120,I:"body > div.footerG@120,B:"#debugMsg"9@H1C,G: ].join(',') |
| 65 | A@BVF,a:).forEach((e)=>f.elemsToToggle.push(e1L6@3Ql,8:D.removeN@5vE,Ha@4mY,J:.user.activeTag===uH@APW,By@53h,15: |
| 66 | For each Chat.MessageWidget element (X.message-widget) for |
| 67 | 9@9NF,u:which predicate(elem) returns true, the 'hidden' class isA@5NB,5A:removed from that message. For all others, 'hidden' is |
| 68 | added. If predicate is falsy, 'hidden' is removed from all |
| 69 | elements. After filtering, it will try to scroll the last |
| 70 | not-filsage into view, but exactly where it |
| 71 | scrolls into view (top, middle, button) is |
| 72 | unpredictableM@5GB,2C: |
| 73 | |
| 74 | The argument may optionally be an object from this.filter, |
| 75 | in which case its matchElem() method becomes the predicate. |
| 76 | |
| 77 | 9@Jkj,2i:Note that this does not encapsulate certain filter-specific |
| 78 | logic which applies changes to elements other than the |
| 79 | main message list or this.e.btnClearFiltJ@3O0,b:applyMessageFilter: function(predicateB@HBh,R@AzV,J@5aF,o:console.debug("applyMessageFilter(",predicate,")");9@3rt,E:if(!predicate)Q@3VT,4:this1c@5bA0 ?){} : (function fif('function'!==typeof predicateH@BFG,~:&& predicate.matchElem){ |
| 80 | /* assume Chat.filter objectK@77z,F:p = predicate; |
| 81 | A@Af6,T:predicate = (e)=>p.matchElem(M@2Ul,B:if(predicatJ@6_l,l@5bB,U@KV~,K: if(predicate(eG@J_W,3: eJ@Jpy,I@HoF,H: eLast = e; |
| 82 | X@AoW,Z@2bU,S@5gS,a: D.removeClass(this.e.btnClearFilterL@9x~,6:} |
| 83 | n@DS9,1Q@5gz,e@4dl,A:Clears theG@5X0,X: filter, if any, a */ |
| 84 | if(!f.elemsToCount){ |
| 85 | d.tf =tru//li.f =tru//li.push(ggle.push(e1L6@3Ql,8:D.removggle.push(e1L6@3Ql,8:D.removeN@5v#hbdrop'), |
| 86 | d.tf =tru//li.push( d.t/li.f =tru//li.pumessage-submit'), |
| 87 | inputSingsingle'), |
| 88 | inputMultimulti'), |
| 89 | inputCpreview-buttonvaluevalue-clear-filterD8@1R8,Hf =tru//li.push( d.tf =tru//li.push( d.t/li.pusbody > div.header'), |
| 90 | body > div.mainmenu'), |
| 91 | body > #hbdrop'), |
| 92 | body > div.footer') |
| 93 | ]; |
| 94 | const contentArea = E1('div.content')divf =tru//li.push( d.t E1('#chat-clear-filterD8@1R8,H:: { |
| 95 | user:8@8Lu,S: acCurrent-clear-filterD8@1R8,H:f =tru//li.push( d.tToggleSingleMulticonst old = this.e.inputCurrentcontentArea = E1('f =tru//li.inputCurrent = this.e.inputMulti;inputLinesingle-lineul,9:matchElemP@IXTf =tru//li.push( d.tf =tru//li.pusru//li.push( d.tf =ti.push( d.t/li.pusbody > diChat.e.inputSinglkeydown@3VT,4:this1c@5bA0 ?if(13===ev.keyCode/*ENTER*/} |
| 96 | }inputMultikeydown@3VT,4:this1c@5bA0 ?if(ev.ctrlKey && } |
| 97 | } |
+1
-1
| --- src/main.mk | ||
| +++ src/main.mk | ||
| @@ -214,11 +214,10 @@ | ||
| 214 | 214 | $(SRCDIR)/accordion.js \ |
| 215 | 215 | $(SRCDIR)/alerts/bflat2.wav \ |
| 216 | 216 | $(SRCDIR)/alerts/bflat3.wav \ |
| 217 | 217 | $(SRCDIR)/alerts/bloop.wav \ |
| 218 | 218 | $(SRCDIR)/alerts/plunk.wav \ |
| 219 | - $(SRCDIR)/chat.js \ | |
| 220 | 219 | $(SRCDIR)/ci_edit.js \ |
| 221 | 220 | $(SRCDIR)/copybtn.js \ |
| 222 | 221 | $(SRCDIR)/default.css \ |
| 223 | 222 | $(SRCDIR)/diff.js \ |
| 224 | 223 | $(SRCDIR)/diff.tcl \ |
| @@ -229,10 +228,11 @@ | ||
| 229 | 228 | $(SRCDIR)/fossil.diff.js \ |
| 230 | 229 | $(SRCDIR)/fossil.dom.js \ |
| 231 | 230 | $(SRCDIR)/fossil.fetch.js \ |
| 232 | 231 | $(SRCDIR)/fossil.numbered-lines.js \ |
| 233 | 232 | $(SRCDIR)/fossil.page.brlist.js \ |
| 233 | + $(SRCDIR)/fossil.page.chat.js \ | |
| 234 | 234 | $(SRCDIR)/fossil.page.fileedit.js \ |
| 235 | 235 | $(SRCDIR)/fossil.page.forumpost.js \ |
| 236 | 236 | $(SRCDIR)/fossil.page.pikchrshow.js \ |
| 237 | 237 | $(SRCDIR)/fossil.page.whistory.js \ |
| 238 | 238 | $(SRCDIR)/fossil.page.wikiedit.js \ |
| 239 | 239 |
| --- src/main.mk | |
| +++ src/main.mk | |
| @@ -214,11 +214,10 @@ | |
| 214 | $(SRCDIR)/accordion.js \ |
| 215 | $(SRCDIR)/alerts/bflat2.wav \ |
| 216 | $(SRCDIR)/alerts/bflat3.wav \ |
| 217 | $(SRCDIR)/alerts/bloop.wav \ |
| 218 | $(SRCDIR)/alerts/plunk.wav \ |
| 219 | $(SRCDIR)/chat.js \ |
| 220 | $(SRCDIR)/ci_edit.js \ |
| 221 | $(SRCDIR)/copybtn.js \ |
| 222 | $(SRCDIR)/default.css \ |
| 223 | $(SRCDIR)/diff.js \ |
| 224 | $(SRCDIR)/diff.tcl \ |
| @@ -229,10 +228,11 @@ | |
| 229 | $(SRCDIR)/fossil.diff.js \ |
| 230 | $(SRCDIR)/fossil.dom.js \ |
| 231 | $(SRCDIR)/fossil.fetch.js \ |
| 232 | $(SRCDIR)/fossil.numbered-lines.js \ |
| 233 | $(SRCDIR)/fossil.page.brlist.js \ |
| 234 | $(SRCDIR)/fossil.page.fileedit.js \ |
| 235 | $(SRCDIR)/fossil.page.forumpost.js \ |
| 236 | $(SRCDIR)/fossil.page.pikchrshow.js \ |
| 237 | $(SRCDIR)/fossil.page.whistory.js \ |
| 238 | $(SRCDIR)/fossil.page.wikiedit.js \ |
| 239 |
| --- src/main.mk | |
| +++ src/main.mk | |
| @@ -214,11 +214,10 @@ | |
| 214 | $(SRCDIR)/accordion.js \ |
| 215 | $(SRCDIR)/alerts/bflat2.wav \ |
| 216 | $(SRCDIR)/alerts/bflat3.wav \ |
| 217 | $(SRCDIR)/alerts/bloop.wav \ |
| 218 | $(SRCDIR)/alerts/plunk.wav \ |
| 219 | $(SRCDIR)/ci_edit.js \ |
| 220 | $(SRCDIR)/copybtn.js \ |
| 221 | $(SRCDIR)/default.css \ |
| 222 | $(SRCDIR)/diff.js \ |
| 223 | $(SRCDIR)/diff.tcl \ |
| @@ -229,10 +228,11 @@ | |
| 228 | $(SRCDIR)/fossil.diff.js \ |
| 229 | $(SRCDIR)/fossil.dom.js \ |
| 230 | $(SRCDIR)/fossil.fetch.js \ |
| 231 | $(SRCDIR)/fossil.numbered-lines.js \ |
| 232 | $(SRCDIR)/fossil.page.brlist.js \ |
| 233 | $(SRCDIR)/fossil.page.chat.js \ |
| 234 | $(SRCDIR)/fossil.page.fileedit.js \ |
| 235 | $(SRCDIR)/fossil.page.forumpost.js \ |
| 236 | $(SRCDIR)/fossil.page.pikchrshow.js \ |
| 237 | $(SRCDIR)/fossil.page.whistory.js \ |
| 238 | $(SRCDIR)/fossil.page.wikiedit.js \ |
| 239 |
+8
| --- src/style.chat.css | ||
| +++ src/style.chat.css | ||
| @@ -444,5 +444,13 @@ | ||
| 444 | 444 | } |
| 445 | 445 | @keyframes fade-out { |
| 446 | 446 | from { opacity: 1; } |
| 447 | 447 | to { opacity: 0; } |
| 448 | 448 | } |
| 449 | + | |
| 450 | +body.chat .anim-fade-out-in { | |
| 451 | + animation: fade-out-in 1000ms linear; | |
| 452 | +} | |
| 453 | +@keyframes fade-out-in { | |
| 454 | + 0%,100% { opacity: 0 } | |
| 455 | + 50% { opacity: 1 } | |
| 456 | +} | |
| 449 | 457 |
| --- src/style.chat.css | |
| +++ src/style.chat.css | |
| @@ -444,5 +444,13 @@ | |
| 444 | } |
| 445 | @keyframes fade-out { |
| 446 | from { opacity: 1; } |
| 447 | to { opacity: 0; } |
| 448 | } |
| 449 |
| --- src/style.chat.css | |
| +++ src/style.chat.css | |
| @@ -444,5 +444,13 @@ | |
| 444 | } |
| 445 | @keyframes fade-out { |
| 446 | from { opacity: 1; } |
| 447 | to { opacity: 0; } |
| 448 | } |
| 449 | |
| 450 | body.chat .anim-fade-out-in { |
| 451 | animation: fade-out-in 1000ms linear; |
| 452 | } |
| 453 | @keyframes fade-out-in { |
| 454 | 0%,100% { opacity: 0 } |
| 455 | 50% { opacity: 1 } |
| 456 | } |
| 457 |
+8
| --- src/style.chat.css | ||
| +++ src/style.chat.css | ||
| @@ -444,5 +444,13 @@ | ||
| 444 | 444 | } |
| 445 | 445 | @keyframes fade-out { |
| 446 | 446 | from { opacity: 1; } |
| 447 | 447 | to { opacity: 0; } |
| 448 | 448 | } |
| 449 | + | |
| 450 | +body.chat .anim-fade-out-in { | |
| 451 | + animation: fade-out-in 1000ms linear; | |
| 452 | +} | |
| 453 | +@keyframes fade-out-in { | |
| 454 | + 0%,100% { opacity: 0 } | |
| 455 | + 50% { opacity: 1 } | |
| 456 | +} | |
| 449 | 457 |
| --- src/style.chat.css | |
| +++ src/style.chat.css | |
| @@ -444,5 +444,13 @@ | |
| 444 | } |
| 445 | @keyframes fade-out { |
| 446 | from { opacity: 1; } |
| 447 | to { opacity: 0; } |
| 448 | } |
| 449 |
| --- src/style.chat.css | |
| +++ src/style.chat.css | |
| @@ -444,5 +444,13 @@ | |
| 444 | } |
| 445 | @keyframes fade-out { |
| 446 | from { opacity: 1; } |
| 447 | to { opacity: 0; } |
| 448 | } |
| 449 | |
| 450 | body.chat .anim-fade-out-in { |
| 451 | animation: fade-out-in 1000ms linear; |
| 452 | } |
| 453 | @keyframes fade-out-in { |
| 454 | 0%,100% { opacity: 0 } |
| 455 | 50% { opacity: 1 } |
| 456 | } |
| 457 |
+2
| --- test/tester.tcl | ||
| +++ test/tester.tcl | ||
| @@ -305,10 +305,11 @@ | ||
| 305 | 305 | diff-command \ |
| 306 | 306 | dont-push \ |
| 307 | 307 | dotfiles \ |
| 308 | 308 | editor \ |
| 309 | 309 | email-admin \ |
| 310 | + email-renew-interval \ | |
| 310 | 311 | email-self \ |
| 311 | 312 | email-send-command \ |
| 312 | 313 | email-send-db \ |
| 313 | 314 | email-send-dir \ |
| 314 | 315 | email-send-method \ |
| @@ -331,10 +332,11 @@ | ||
| 331 | 332 | localauth \ |
| 332 | 333 | lock-timeout \ |
| 333 | 334 | main-branch \ |
| 334 | 335 | mainmenu \ |
| 335 | 336 | manifest \ |
| 337 | + max-cache-entry \ | |
| 336 | 338 | max-loadavg \ |
| 337 | 339 | max-upload \ |
| 338 | 340 | mimetypes \ |
| 339 | 341 | mtime-changes \ |
| 340 | 342 | pgp-command \ |
| 341 | 343 |
| --- test/tester.tcl | |
| +++ test/tester.tcl | |
| @@ -305,10 +305,11 @@ | |
| 305 | diff-command \ |
| 306 | dont-push \ |
| 307 | dotfiles \ |
| 308 | editor \ |
| 309 | email-admin \ |
| 310 | email-self \ |
| 311 | email-send-command \ |
| 312 | email-send-db \ |
| 313 | email-send-dir \ |
| 314 | email-send-method \ |
| @@ -331,10 +332,11 @@ | |
| 331 | localauth \ |
| 332 | lock-timeout \ |
| 333 | main-branch \ |
| 334 | mainmenu \ |
| 335 | manifest \ |
| 336 | max-loadavg \ |
| 337 | max-upload \ |
| 338 | mimetypes \ |
| 339 | mtime-changes \ |
| 340 | pgp-command \ |
| 341 |
| --- test/tester.tcl | |
| +++ test/tester.tcl | |
| @@ -305,10 +305,11 @@ | |
| 305 | diff-command \ |
| 306 | dont-push \ |
| 307 | dotfiles \ |
| 308 | editor \ |
| 309 | email-admin \ |
| 310 | email-renew-interval \ |
| 311 | email-self \ |
| 312 | email-send-command \ |
| 313 | email-send-db \ |
| 314 | email-send-dir \ |
| 315 | email-send-method \ |
| @@ -331,10 +332,11 @@ | |
| 332 | localauth \ |
| 333 | lock-timeout \ |
| 334 | main-branch \ |
| 335 | mainmenu \ |
| 336 | manifest \ |
| 337 | max-cache-entry \ |
| 338 | max-loadavg \ |
| 339 | max-upload \ |
| 340 | mimetypes \ |
| 341 | mtime-changes \ |
| 342 | pgp-command \ |
| 343 |
+1
-1
| --- win/Makefile.mingw | ||
| +++ win/Makefile.mingw | ||
| @@ -623,11 +623,10 @@ | ||
| 623 | 623 | $(SRCDIR)/accordion.js \ |
| 624 | 624 | $(SRCDIR)/alerts/bflat2.wav \ |
| 625 | 625 | $(SRCDIR)/alerts/bflat3.wav \ |
| 626 | 626 | $(SRCDIR)/alerts/bloop.wav \ |
| 627 | 627 | $(SRCDIR)/alerts/plunk.wav \ |
| 628 | - $(SRCDIR)/chat.js \ | |
| 629 | 628 | $(SRCDIR)/ci_edit.js \ |
| 630 | 629 | $(SRCDIR)/copybtn.js \ |
| 631 | 630 | $(SRCDIR)/default.css \ |
| 632 | 631 | $(SRCDIR)/diff.js \ |
| 633 | 632 | $(SRCDIR)/diff.tcl \ |
| @@ -638,10 +637,11 @@ | ||
| 638 | 637 | $(SRCDIR)/fossil.diff.js \ |
| 639 | 638 | $(SRCDIR)/fossil.dom.js \ |
| 640 | 639 | $(SRCDIR)/fossil.fetch.js \ |
| 641 | 640 | $(SRCDIR)/fossil.numbered-lines.js \ |
| 642 | 641 | $(SRCDIR)/fossil.page.brlist.js \ |
| 642 | + $(SRCDIR)/fossil.page.chat.js \ | |
| 643 | 643 | $(SRCDIR)/fossil.page.fileedit.js \ |
| 644 | 644 | $(SRCDIR)/fossil.page.forumpost.js \ |
| 645 | 645 | $(SRCDIR)/fossil.page.pikchrshow.js \ |
| 646 | 646 | $(SRCDIR)/fossil.page.whistory.js \ |
| 647 | 647 | $(SRCDIR)/fossil.page.wikiedit.js \ |
| 648 | 648 |
| --- win/Makefile.mingw | |
| +++ win/Makefile.mingw | |
| @@ -623,11 +623,10 @@ | |
| 623 | $(SRCDIR)/accordion.js \ |
| 624 | $(SRCDIR)/alerts/bflat2.wav \ |
| 625 | $(SRCDIR)/alerts/bflat3.wav \ |
| 626 | $(SRCDIR)/alerts/bloop.wav \ |
| 627 | $(SRCDIR)/alerts/plunk.wav \ |
| 628 | $(SRCDIR)/chat.js \ |
| 629 | $(SRCDIR)/ci_edit.js \ |
| 630 | $(SRCDIR)/copybtn.js \ |
| 631 | $(SRCDIR)/default.css \ |
| 632 | $(SRCDIR)/diff.js \ |
| 633 | $(SRCDIR)/diff.tcl \ |
| @@ -638,10 +637,11 @@ | |
| 638 | $(SRCDIR)/fossil.diff.js \ |
| 639 | $(SRCDIR)/fossil.dom.js \ |
| 640 | $(SRCDIR)/fossil.fetch.js \ |
| 641 | $(SRCDIR)/fossil.numbered-lines.js \ |
| 642 | $(SRCDIR)/fossil.page.brlist.js \ |
| 643 | $(SRCDIR)/fossil.page.fileedit.js \ |
| 644 | $(SRCDIR)/fossil.page.forumpost.js \ |
| 645 | $(SRCDIR)/fossil.page.pikchrshow.js \ |
| 646 | $(SRCDIR)/fossil.page.whistory.js \ |
| 647 | $(SRCDIR)/fossil.page.wikiedit.js \ |
| 648 |
| --- win/Makefile.mingw | |
| +++ win/Makefile.mingw | |
| @@ -623,11 +623,10 @@ | |
| 623 | $(SRCDIR)/accordion.js \ |
| 624 | $(SRCDIR)/alerts/bflat2.wav \ |
| 625 | $(SRCDIR)/alerts/bflat3.wav \ |
| 626 | $(SRCDIR)/alerts/bloop.wav \ |
| 627 | $(SRCDIR)/alerts/plunk.wav \ |
| 628 | $(SRCDIR)/ci_edit.js \ |
| 629 | $(SRCDIR)/copybtn.js \ |
| 630 | $(SRCDIR)/default.css \ |
| 631 | $(SRCDIR)/diff.js \ |
| 632 | $(SRCDIR)/diff.tcl \ |
| @@ -638,10 +637,11 @@ | |
| 637 | $(SRCDIR)/fossil.diff.js \ |
| 638 | $(SRCDIR)/fossil.dom.js \ |
| 639 | $(SRCDIR)/fossil.fetch.js \ |
| 640 | $(SRCDIR)/fossil.numbered-lines.js \ |
| 641 | $(SRCDIR)/fossil.page.brlist.js \ |
| 642 | $(SRCDIR)/fossil.page.chat.js \ |
| 643 | $(SRCDIR)/fossil.page.fileedit.js \ |
| 644 | $(SRCDIR)/fossil.page.forumpost.js \ |
| 645 | $(SRCDIR)/fossil.page.pikchrshow.js \ |
| 646 | $(SRCDIR)/fossil.page.whistory.js \ |
| 647 | $(SRCDIR)/fossil.page.wikiedit.js \ |
| 648 |
+2
-2
| --- win/Makefile.msc | ||
| +++ win/Makefile.msc | ||
| @@ -565,11 +565,10 @@ | ||
| 565 | 565 | "$(SRCDIR)\accordion.js" \ |
| 566 | 566 | "$(SRCDIR)\alerts\bflat2.wav" \ |
| 567 | 567 | "$(SRCDIR)\alerts\bflat3.wav" \ |
| 568 | 568 | "$(SRCDIR)\alerts\bloop.wav" \ |
| 569 | 569 | "$(SRCDIR)\alerts\plunk.wav" \ |
| 570 | - "$(SRCDIR)\chat.js" \ | |
| 571 | 570 | "$(SRCDIR)\ci_edit.js" \ |
| 572 | 571 | "$(SRCDIR)\copybtn.js" \ |
| 573 | 572 | "$(SRCDIR)\default.css" \ |
| 574 | 573 | "$(SRCDIR)\diff.js" \ |
| 575 | 574 | "$(SRCDIR)\diff.tcl" \ |
| @@ -580,10 +579,11 @@ | ||
| 580 | 579 | "$(SRCDIR)\fossil.diff.js" \ |
| 581 | 580 | "$(SRCDIR)\fossil.dom.js" \ |
| 582 | 581 | "$(SRCDIR)\fossil.fetch.js" \ |
| 583 | 582 | "$(SRCDIR)\fossil.numbered-lines.js" \ |
| 584 | 583 | "$(SRCDIR)\fossil.page.brlist.js" \ |
| 584 | + "$(SRCDIR)\fossil.page.chat.js" \ | |
| 585 | 585 | "$(SRCDIR)\fossil.page.fileedit.js" \ |
| 586 | 586 | "$(SRCDIR)\fossil.page.forumpost.js" \ |
| 587 | 587 | "$(SRCDIR)\fossil.page.pikchrshow.js" \ |
| 588 | 588 | "$(SRCDIR)\fossil.page.whistory.js" \ |
| 589 | 589 | "$(SRCDIR)\fossil.page.wikiedit.js" \ |
| @@ -1174,11 +1174,10 @@ | ||
| 1174 | 1174 | echo "$(SRCDIR)\accordion.js" >> $@ |
| 1175 | 1175 | echo "$(SRCDIR)\alerts/bflat2.wav" >> $@ |
| 1176 | 1176 | echo "$(SRCDIR)\alerts/bflat3.wav" >> $@ |
| 1177 | 1177 | echo "$(SRCDIR)\alerts/bloop.wav" >> $@ |
| 1178 | 1178 | echo "$(SRCDIR)\alerts/plunk.wav" >> $@ |
| 1179 | - echo "$(SRCDIR)\chat.js" >> $@ | |
| 1180 | 1179 | echo "$(SRCDIR)\ci_edit.js" >> $@ |
| 1181 | 1180 | echo "$(SRCDIR)\copybtn.js" >> $@ |
| 1182 | 1181 | echo "$(SRCDIR)\default.css" >> $@ |
| 1183 | 1182 | echo "$(SRCDIR)\diff.js" >> $@ |
| 1184 | 1183 | echo "$(SRCDIR)\diff.tcl" >> $@ |
| @@ -1189,10 +1188,11 @@ | ||
| 1189 | 1188 | echo "$(SRCDIR)\fossil.diff.js" >> $@ |
| 1190 | 1189 | echo "$(SRCDIR)\fossil.dom.js" >> $@ |
| 1191 | 1190 | echo "$(SRCDIR)\fossil.fetch.js" >> $@ |
| 1192 | 1191 | echo "$(SRCDIR)\fossil.numbered-lines.js" >> $@ |
| 1193 | 1192 | echo "$(SRCDIR)\fossil.page.brlist.js" >> $@ |
| 1193 | + echo "$(SRCDIR)\fossil.page.chat.js" >> $@ | |
| 1194 | 1194 | echo "$(SRCDIR)\fossil.page.fileedit.js" >> $@ |
| 1195 | 1195 | echo "$(SRCDIR)\fossil.page.forumpost.js" >> $@ |
| 1196 | 1196 | echo "$(SRCDIR)\fossil.page.pikchrshow.js" >> $@ |
| 1197 | 1197 | echo "$(SRCDIR)\fossil.page.whistory.js" >> $@ |
| 1198 | 1198 | echo "$(SRCDIR)\fossil.page.wikiedit.js" >> $@ |
| 1199 | 1199 |
| --- win/Makefile.msc | |
| +++ win/Makefile.msc | |
| @@ -565,11 +565,10 @@ | |
| 565 | "$(SRCDIR)\accordion.js" \ |
| 566 | "$(SRCDIR)\alerts\bflat2.wav" \ |
| 567 | "$(SRCDIR)\alerts\bflat3.wav" \ |
| 568 | "$(SRCDIR)\alerts\bloop.wav" \ |
| 569 | "$(SRCDIR)\alerts\plunk.wav" \ |
| 570 | "$(SRCDIR)\chat.js" \ |
| 571 | "$(SRCDIR)\ci_edit.js" \ |
| 572 | "$(SRCDIR)\copybtn.js" \ |
| 573 | "$(SRCDIR)\default.css" \ |
| 574 | "$(SRCDIR)\diff.js" \ |
| 575 | "$(SRCDIR)\diff.tcl" \ |
| @@ -580,10 +579,11 @@ | |
| 580 | "$(SRCDIR)\fossil.diff.js" \ |
| 581 | "$(SRCDIR)\fossil.dom.js" \ |
| 582 | "$(SRCDIR)\fossil.fetch.js" \ |
| 583 | "$(SRCDIR)\fossil.numbered-lines.js" \ |
| 584 | "$(SRCDIR)\fossil.page.brlist.js" \ |
| 585 | "$(SRCDIR)\fossil.page.fileedit.js" \ |
| 586 | "$(SRCDIR)\fossil.page.forumpost.js" \ |
| 587 | "$(SRCDIR)\fossil.page.pikchrshow.js" \ |
| 588 | "$(SRCDIR)\fossil.page.whistory.js" \ |
| 589 | "$(SRCDIR)\fossil.page.wikiedit.js" \ |
| @@ -1174,11 +1174,10 @@ | |
| 1174 | echo "$(SRCDIR)\accordion.js" >> $@ |
| 1175 | echo "$(SRCDIR)\alerts/bflat2.wav" >> $@ |
| 1176 | echo "$(SRCDIR)\alerts/bflat3.wav" >> $@ |
| 1177 | echo "$(SRCDIR)\alerts/bloop.wav" >> $@ |
| 1178 | echo "$(SRCDIR)\alerts/plunk.wav" >> $@ |
| 1179 | echo "$(SRCDIR)\chat.js" >> $@ |
| 1180 | echo "$(SRCDIR)\ci_edit.js" >> $@ |
| 1181 | echo "$(SRCDIR)\copybtn.js" >> $@ |
| 1182 | echo "$(SRCDIR)\default.css" >> $@ |
| 1183 | echo "$(SRCDIR)\diff.js" >> $@ |
| 1184 | echo "$(SRCDIR)\diff.tcl" >> $@ |
| @@ -1189,10 +1188,11 @@ | |
| 1189 | echo "$(SRCDIR)\fossil.diff.js" >> $@ |
| 1190 | echo "$(SRCDIR)\fossil.dom.js" >> $@ |
| 1191 | echo "$(SRCDIR)\fossil.fetch.js" >> $@ |
| 1192 | echo "$(SRCDIR)\fossil.numbered-lines.js" >> $@ |
| 1193 | echo "$(SRCDIR)\fossil.page.brlist.js" >> $@ |
| 1194 | echo "$(SRCDIR)\fossil.page.fileedit.js" >> $@ |
| 1195 | echo "$(SRCDIR)\fossil.page.forumpost.js" >> $@ |
| 1196 | echo "$(SRCDIR)\fossil.page.pikchrshow.js" >> $@ |
| 1197 | echo "$(SRCDIR)\fossil.page.whistory.js" >> $@ |
| 1198 | echo "$(SRCDIR)\fossil.page.wikiedit.js" >> $@ |
| 1199 |
| --- win/Makefile.msc | |
| +++ win/Makefile.msc | |
| @@ -565,11 +565,10 @@ | |
| 565 | "$(SRCDIR)\accordion.js" \ |
| 566 | "$(SRCDIR)\alerts\bflat2.wav" \ |
| 567 | "$(SRCDIR)\alerts\bflat3.wav" \ |
| 568 | "$(SRCDIR)\alerts\bloop.wav" \ |
| 569 | "$(SRCDIR)\alerts\plunk.wav" \ |
| 570 | "$(SRCDIR)\ci_edit.js" \ |
| 571 | "$(SRCDIR)\copybtn.js" \ |
| 572 | "$(SRCDIR)\default.css" \ |
| 573 | "$(SRCDIR)\diff.js" \ |
| 574 | "$(SRCDIR)\diff.tcl" \ |
| @@ -580,10 +579,11 @@ | |
| 579 | "$(SRCDIR)\fossil.diff.js" \ |
| 580 | "$(SRCDIR)\fossil.dom.js" \ |
| 581 | "$(SRCDIR)\fossil.fetch.js" \ |
| 582 | "$(SRCDIR)\fossil.numbered-lines.js" \ |
| 583 | "$(SRCDIR)\fossil.page.brlist.js" \ |
| 584 | "$(SRCDIR)\fossil.page.chat.js" \ |
| 585 | "$(SRCDIR)\fossil.page.fileedit.js" \ |
| 586 | "$(SRCDIR)\fossil.page.forumpost.js" \ |
| 587 | "$(SRCDIR)\fossil.page.pikchrshow.js" \ |
| 588 | "$(SRCDIR)\fossil.page.whistory.js" \ |
| 589 | "$(SRCDIR)\fossil.page.wikiedit.js" \ |
| @@ -1174,11 +1174,10 @@ | |
| 1174 | echo "$(SRCDIR)\accordion.js" >> $@ |
| 1175 | echo "$(SRCDIR)\alerts/bflat2.wav" >> $@ |
| 1176 | echo "$(SRCDIR)\alerts/bflat3.wav" >> $@ |
| 1177 | echo "$(SRCDIR)\alerts/bloop.wav" >> $@ |
| 1178 | echo "$(SRCDIR)\alerts/plunk.wav" >> $@ |
| 1179 | echo "$(SRCDIR)\ci_edit.js" >> $@ |
| 1180 | echo "$(SRCDIR)\copybtn.js" >> $@ |
| 1181 | echo "$(SRCDIR)\default.css" >> $@ |
| 1182 | echo "$(SRCDIR)\diff.js" >> $@ |
| 1183 | echo "$(SRCDIR)\diff.tcl" >> $@ |
| @@ -1189,10 +1188,11 @@ | |
| 1188 | echo "$(SRCDIR)\fossil.diff.js" >> $@ |
| 1189 | echo "$(SRCDIR)\fossil.dom.js" >> $@ |
| 1190 | echo "$(SRCDIR)\fossil.fetch.js" >> $@ |
| 1191 | echo "$(SRCDIR)\fossil.numbered-lines.js" >> $@ |
| 1192 | echo "$(SRCDIR)\fossil.page.brlist.js" >> $@ |
| 1193 | echo "$(SRCDIR)\fossil.page.chat.js" >> $@ |
| 1194 | echo "$(SRCDIR)\fossil.page.fileedit.js" >> $@ |
| 1195 | echo "$(SRCDIR)\fossil.page.forumpost.js" >> $@ |
| 1196 | echo "$(SRCDIR)\fossil.page.pikchrshow.js" >> $@ |
| 1197 | echo "$(SRCDIR)\fossil.page.whistory.js" >> $@ |
| 1198 | echo "$(SRCDIR)\fossil.page.wikiedit.js" >> $@ |
| 1199 |
+1
-1
| --- www/changes.wiki | ||
| +++ www/changes.wiki | ||
| @@ -28,11 +28,11 @@ | ||
| 28 | 28 | the --verbose option. |
| 29 | 29 | * Add the <tt>close</tt>, <tt>reopen</tt>, <tt>hide</tt>, and |
| 30 | 30 | </tt>unhide</tt> subcommands to [/help?cmd=branch|the branch command]. |
| 31 | 31 | * The "-p" option to [/help?cmd=branch|fossil branch list] shows only |
| 32 | 32 | private branches. |
| 33 | - * The [/mdrules|Markdown formatter] now interprets the content of | |
| 33 | + * The [/md_rules|Markdown formatter] now interprets the content of | |
| 34 | 34 | block HTML markup (such as <table>) in most cases. Only content |
| 35 | 35 | of <pre> and <script> is passed through verbatim. |
| 36 | 36 | * The [/help?cmd=wiki|wiki list command] no longer lists "deleted" |
| 37 | 37 | pages by default. Use the new <tt>--all</tt> option to include deleted |
| 38 | 38 | pages in the output. |
| 39 | 39 |
| --- www/changes.wiki | |
| +++ www/changes.wiki | |
| @@ -28,11 +28,11 @@ | |
| 28 | the --verbose option. |
| 29 | * Add the <tt>close</tt>, <tt>reopen</tt>, <tt>hide</tt>, and |
| 30 | </tt>unhide</tt> subcommands to [/help?cmd=branch|the branch command]. |
| 31 | * The "-p" option to [/help?cmd=branch|fossil branch list] shows only |
| 32 | private branches. |
| 33 | * The [/mdrules|Markdown formatter] now interprets the content of |
| 34 | block HTML markup (such as <table>) in most cases. Only content |
| 35 | of <pre> and <script> is passed through verbatim. |
| 36 | * The [/help?cmd=wiki|wiki list command] no longer lists "deleted" |
| 37 | pages by default. Use the new <tt>--all</tt> option to include deleted |
| 38 | pages in the output. |
| 39 |
| --- www/changes.wiki | |
| +++ www/changes.wiki | |
| @@ -28,11 +28,11 @@ | |
| 28 | the --verbose option. |
| 29 | * Add the <tt>close</tt>, <tt>reopen</tt>, <tt>hide</tt>, and |
| 30 | </tt>unhide</tt> subcommands to [/help?cmd=branch|the branch command]. |
| 31 | * The "-p" option to [/help?cmd=branch|fossil branch list] shows only |
| 32 | private branches. |
| 33 | * The [/md_rules|Markdown formatter] now interprets the content of |
| 34 | block HTML markup (such as <table>) in most cases. Only content |
| 35 | of <pre> and <script> is passed through verbatim. |
| 36 | * The [/help?cmd=wiki|wiki list command] no longer lists "deleted" |
| 37 | pages by default. Use the new <tt>--all</tt> option to include deleted |
| 38 | pages in the output. |
| 39 |