Fossil SCM
Merged in trunk for latest changes.
Commit
09f86815c6ca0f27903440aba7052bf54ca5ff950a9794b6d31264353db7b401
Parent
9df3fc6b0f2c4be…
14 files changed
+12
-4
+12
-4
+1
-1
+11
-2
+22
-17
+22
-17
+2
-2
+3
-2
+2
-2
+1
-1
+3
+3
-1
+1
-1
+5
+12
-4
| --- src/chat.c | ||
| +++ src/chat.c | ||
| @@ -142,35 +142,42 @@ | ||
| 142 | 142 | ** send new chat message, delete older messages, or poll for changes. |
| 143 | 143 | */ |
| 144 | 144 | void chat_webpage(void){ |
| 145 | 145 | char *zAlert; |
| 146 | 146 | char *zProjectName; |
| 147 | + const char * zInputPlaceholder1 = /* Placeholder for 1-line input */ | |
| 148 | + "Enter sends and Shift-Enter previews."; | |
| 149 | + const char * zInputPlaceholder2 = /* Placeholder for textarea input*/ | |
| 150 | + "Ctrl-Enter sends and Shift-Enter previews."; | |
| 151 | + char * zInputPlaceholder0; /* Common text input placeholder value */ | |
| 147 | 152 | login_check_credentials(); |
| 148 | 153 | if( !g.perm.Chat ){ |
| 149 | 154 | login_needed(g.anon.Chat); |
| 150 | 155 | return; |
| 151 | 156 | } |
| 152 | 157 | zAlert = mprintf("%s/builtin/%s", g.zBaseURL, |
| 153 | 158 | db_get("chat-alert-sound","alerts/plunk.wav")); |
| 154 | 159 | zProjectName = db_get("project-name","Unnamed project"); |
| 160 | + zInputPlaceholder0 = | |
| 161 | + mprintf("Type markdown-formatted message for %h.", zProjectName); | |
| 155 | 162 | style_set_current_feature("chat"); |
| 156 | 163 | style_header("Chat"); |
| 157 | 164 | @ <div id='chat-input-area'> |
| 158 | 165 | @ <div id='chat-input-line' class='single-line'> |
| 159 | 166 | @ <input type="text" name="msg" id="chat-input-single" \ |
| 160 | - @ placeholder="Type markdown-formatted message for %h(zProjectName)." \ | |
| 167 | + @ placeholder="%h(zInputPlaceholder0) %h(zInputPlaceholder1)" \ | |
| 161 | 168 | @ autocomplete="off"> |
| 162 | 169 | @ <textarea rows="8" id="chat-input-multi" \ |
| 163 | - @ placeholder="Type markdown-formatted message for %h(zProjectName). Ctrl-Enter sends it." \ | |
| 170 | + @ placeholder="%h(zInputPlaceholder0) %h(zInputPlaceholder2)" \ | |
| 164 | 171 | @ class="hidden"></textarea> |
| 165 | 172 | @ <div id='chat-edit-buttons'> |
| 166 | 173 | @ <button id="chat-preview-button" \ |
| 167 | - @ title="Preview message">👁</button> | |
| 174 | + @ title="Preview message (Shift-Enter)">👁</button> | |
| 168 | 175 | @ <button id="chat-settings-button" \ |
| 169 | 176 | @ title="Configure chat">⚙</button> |
| 170 | 177 | @ <button id="chat-message-submit" \ |
| 171 | - @ title="Send message">📤</button> | |
| 178 | + @ title="Send message (Ctrl-Enter)">📤</button> | |
| 172 | 179 | @ </div> |
| 173 | 180 | @ </div> |
| 174 | 181 | @ <div id='chat-input-file-area'> |
| 175 | 182 | @ <div class='file-selection-wrapper'> |
| 176 | 183 | @ <div class='help-buttonlet'> |
| @@ -210,10 +217,11 @@ | ||
| 210 | 217 | @ <div id='chat-messages-wrapper' class='chat-view'> |
| 211 | 218 | /* New chat messages get inserted immediately after this element */ |
| 212 | 219 | @ <span id='message-inject-point'></span> |
| 213 | 220 | @ </div> |
| 214 | 221 | fossil_free(zProjectName); |
| 222 | + fossil_free(zInputPlaceholder0); | |
| 215 | 223 | builtin_fossil_js_bundle_or("popupwidget", "storage", "fetch", |
| 216 | 224 | "pikchr", "confirmer", NULL); |
| 217 | 225 | /* Always in-line the javascript for the chat page */ |
| 218 | 226 | @ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */ |
| 219 | 227 | /* We need an onload handler to ensure that window.fossil is |
| 220 | 228 |
| --- src/chat.c | |
| +++ src/chat.c | |
| @@ -142,35 +142,42 @@ | |
| 142 | ** send new chat message, delete older messages, or poll for changes. |
| 143 | */ |
| 144 | void chat_webpage(void){ |
| 145 | char *zAlert; |
| 146 | char *zProjectName; |
| 147 | login_check_credentials(); |
| 148 | if( !g.perm.Chat ){ |
| 149 | login_needed(g.anon.Chat); |
| 150 | return; |
| 151 | } |
| 152 | zAlert = mprintf("%s/builtin/%s", g.zBaseURL, |
| 153 | db_get("chat-alert-sound","alerts/plunk.wav")); |
| 154 | zProjectName = db_get("project-name","Unnamed project"); |
| 155 | style_set_current_feature("chat"); |
| 156 | style_header("Chat"); |
| 157 | @ <div id='chat-input-area'> |
| 158 | @ <div id='chat-input-line' class='single-line'> |
| 159 | @ <input type="text" name="msg" id="chat-input-single" \ |
| 160 | @ placeholder="Type markdown-formatted message for %h(zProjectName)." \ |
| 161 | @ autocomplete="off"> |
| 162 | @ <textarea rows="8" id="chat-input-multi" \ |
| 163 | @ placeholder="Type markdown-formatted message for %h(zProjectName). Ctrl-Enter sends it." \ |
| 164 | @ class="hidden"></textarea> |
| 165 | @ <div id='chat-edit-buttons'> |
| 166 | @ <button id="chat-preview-button" \ |
| 167 | @ title="Preview message">👁</button> |
| 168 | @ <button id="chat-settings-button" \ |
| 169 | @ title="Configure chat">⚙</button> |
| 170 | @ <button id="chat-message-submit" \ |
| 171 | @ title="Send message">📤</button> |
| 172 | @ </div> |
| 173 | @ </div> |
| 174 | @ <div id='chat-input-file-area'> |
| 175 | @ <div class='file-selection-wrapper'> |
| 176 | @ <div class='help-buttonlet'> |
| @@ -210,10 +217,11 @@ | |
| 210 | @ <div id='chat-messages-wrapper' class='chat-view'> |
| 211 | /* New chat messages get inserted immediately after this element */ |
| 212 | @ <span id='message-inject-point'></span> |
| 213 | @ </div> |
| 214 | fossil_free(zProjectName); |
| 215 | builtin_fossil_js_bundle_or("popupwidget", "storage", "fetch", |
| 216 | "pikchr", "confirmer", NULL); |
| 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 |
| --- src/chat.c | |
| +++ src/chat.c | |
| @@ -142,35 +142,42 @@ | |
| 142 | ** send new chat message, delete older messages, or poll for changes. |
| 143 | */ |
| 144 | void chat_webpage(void){ |
| 145 | char *zAlert; |
| 146 | char *zProjectName; |
| 147 | const char * zInputPlaceholder1 = /* Placeholder for 1-line input */ |
| 148 | "Enter sends and Shift-Enter previews."; |
| 149 | const char * zInputPlaceholder2 = /* Placeholder for textarea input*/ |
| 150 | "Ctrl-Enter sends and Shift-Enter previews."; |
| 151 | char * zInputPlaceholder0; /* Common text input placeholder value */ |
| 152 | login_check_credentials(); |
| 153 | if( !g.perm.Chat ){ |
| 154 | login_needed(g.anon.Chat); |
| 155 | return; |
| 156 | } |
| 157 | zAlert = mprintf("%s/builtin/%s", g.zBaseURL, |
| 158 | db_get("chat-alert-sound","alerts/plunk.wav")); |
| 159 | zProjectName = db_get("project-name","Unnamed project"); |
| 160 | zInputPlaceholder0 = |
| 161 | mprintf("Type markdown-formatted message for %h.", zProjectName); |
| 162 | style_set_current_feature("chat"); |
| 163 | style_header("Chat"); |
| 164 | @ <div id='chat-input-area'> |
| 165 | @ <div id='chat-input-line' class='single-line'> |
| 166 | @ <input type="text" name="msg" id="chat-input-single" \ |
| 167 | @ placeholder="%h(zInputPlaceholder0) %h(zInputPlaceholder1)" \ |
| 168 | @ autocomplete="off"> |
| 169 | @ <textarea rows="8" id="chat-input-multi" \ |
| 170 | @ placeholder="%h(zInputPlaceholder0) %h(zInputPlaceholder2)" \ |
| 171 | @ class="hidden"></textarea> |
| 172 | @ <div id='chat-edit-buttons'> |
| 173 | @ <button id="chat-preview-button" \ |
| 174 | @ title="Preview message (Shift-Enter)">👁</button> |
| 175 | @ <button id="chat-settings-button" \ |
| 176 | @ title="Configure chat">⚙</button> |
| 177 | @ <button id="chat-message-submit" \ |
| 178 | @ title="Send message (Ctrl-Enter)">📤</button> |
| 179 | @ </div> |
| 180 | @ </div> |
| 181 | @ <div id='chat-input-file-area'> |
| 182 | @ <div class='file-selection-wrapper'> |
| 183 | @ <div class='help-buttonlet'> |
| @@ -210,10 +217,11 @@ | |
| 217 | @ <div id='chat-messages-wrapper' class='chat-view'> |
| 218 | /* New chat messages get inserted immediately after this element */ |
| 219 | @ <span id='message-inject-point'></span> |
| 220 | @ </div> |
| 221 | fossil_free(zProjectName); |
| 222 | fossil_free(zInputPlaceholder0); |
| 223 | builtin_fossil_js_bundle_or("popupwidget", "storage", "fetch", |
| 224 | "pikchr", "confirmer", NULL); |
| 225 | /* Always in-line the javascript for the chat page */ |
| 226 | @ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */ |
| 227 | /* We need an onload handler to ensure that window.fossil is |
| 228 |
+12
-4
| --- src/chat.c | ||
| +++ src/chat.c | ||
| @@ -142,35 +142,42 @@ | ||
| 142 | 142 | ** send new chat message, delete older messages, or poll for changes. |
| 143 | 143 | */ |
| 144 | 144 | void chat_webpage(void){ |
| 145 | 145 | char *zAlert; |
| 146 | 146 | char *zProjectName; |
| 147 | + const char * zInputPlaceholder1 = /* Placeholder for 1-line input */ | |
| 148 | + "Enter sends and Shift-Enter previews."; | |
| 149 | + const char * zInputPlaceholder2 = /* Placeholder for textarea input*/ | |
| 150 | + "Ctrl-Enter sends and Shift-Enter previews."; | |
| 151 | + char * zInputPlaceholder0; /* Common text input placeholder value */ | |
| 147 | 152 | login_check_credentials(); |
| 148 | 153 | if( !g.perm.Chat ){ |
| 149 | 154 | login_needed(g.anon.Chat); |
| 150 | 155 | return; |
| 151 | 156 | } |
| 152 | 157 | zAlert = mprintf("%s/builtin/%s", g.zBaseURL, |
| 153 | 158 | db_get("chat-alert-sound","alerts/plunk.wav")); |
| 154 | 159 | zProjectName = db_get("project-name","Unnamed project"); |
| 160 | + zInputPlaceholder0 = | |
| 161 | + mprintf("Type markdown-formatted message for %h.", zProjectName); | |
| 155 | 162 | style_set_current_feature("chat"); |
| 156 | 163 | style_header("Chat"); |
| 157 | 164 | @ <div id='chat-input-area'> |
| 158 | 165 | @ <div id='chat-input-line' class='single-line'> |
| 159 | 166 | @ <input type="text" name="msg" id="chat-input-single" \ |
| 160 | - @ placeholder="Type markdown-formatted message for %h(zProjectName)." \ | |
| 167 | + @ placeholder="%h(zInputPlaceholder0) %h(zInputPlaceholder1)" \ | |
| 161 | 168 | @ autocomplete="off"> |
| 162 | 169 | @ <textarea rows="8" id="chat-input-multi" \ |
| 163 | - @ placeholder="Type markdown-formatted message for %h(zProjectName). Ctrl-Enter sends it." \ | |
| 170 | + @ placeholder="%h(zInputPlaceholder0) %h(zInputPlaceholder2)" \ | |
| 164 | 171 | @ class="hidden"></textarea> |
| 165 | 172 | @ <div id='chat-edit-buttons'> |
| 166 | 173 | @ <button id="chat-preview-button" \ |
| 167 | - @ title="Preview message">👁</button> | |
| 174 | + @ title="Preview message (Shift-Enter)">👁</button> | |
| 168 | 175 | @ <button id="chat-settings-button" \ |
| 169 | 176 | @ title="Configure chat">⚙</button> |
| 170 | 177 | @ <button id="chat-message-submit" \ |
| 171 | - @ title="Send message">📤</button> | |
| 178 | + @ title="Send message (Ctrl-Enter)">📤</button> | |
| 172 | 179 | @ </div> |
| 173 | 180 | @ </div> |
| 174 | 181 | @ <div id='chat-input-file-area'> |
| 175 | 182 | @ <div class='file-selection-wrapper'> |
| 176 | 183 | @ <div class='help-buttonlet'> |
| @@ -210,10 +217,11 @@ | ||
| 210 | 217 | @ <div id='chat-messages-wrapper' class='chat-view'> |
| 211 | 218 | /* New chat messages get inserted immediately after this element */ |
| 212 | 219 | @ <span id='message-inject-point'></span> |
| 213 | 220 | @ </div> |
| 214 | 221 | fossil_free(zProjectName); |
| 222 | + fossil_free(zInputPlaceholder0); | |
| 215 | 223 | builtin_fossil_js_bundle_or("popupwidget", "storage", "fetch", |
| 216 | 224 | "pikchr", "confirmer", NULL); |
| 217 | 225 | /* Always in-line the javascript for the chat page */ |
| 218 | 226 | @ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */ |
| 219 | 227 | /* We need an onload handler to ensure that window.fossil is |
| 220 | 228 |
| --- src/chat.c | |
| +++ src/chat.c | |
| @@ -142,35 +142,42 @@ | |
| 142 | ** send new chat message, delete older messages, or poll for changes. |
| 143 | */ |
| 144 | void chat_webpage(void){ |
| 145 | char *zAlert; |
| 146 | char *zProjectName; |
| 147 | login_check_credentials(); |
| 148 | if( !g.perm.Chat ){ |
| 149 | login_needed(g.anon.Chat); |
| 150 | return; |
| 151 | } |
| 152 | zAlert = mprintf("%s/builtin/%s", g.zBaseURL, |
| 153 | db_get("chat-alert-sound","alerts/plunk.wav")); |
| 154 | zProjectName = db_get("project-name","Unnamed project"); |
| 155 | style_set_current_feature("chat"); |
| 156 | style_header("Chat"); |
| 157 | @ <div id='chat-input-area'> |
| 158 | @ <div id='chat-input-line' class='single-line'> |
| 159 | @ <input type="text" name="msg" id="chat-input-single" \ |
| 160 | @ placeholder="Type markdown-formatted message for %h(zProjectName)." \ |
| 161 | @ autocomplete="off"> |
| 162 | @ <textarea rows="8" id="chat-input-multi" \ |
| 163 | @ placeholder="Type markdown-formatted message for %h(zProjectName). Ctrl-Enter sends it." \ |
| 164 | @ class="hidden"></textarea> |
| 165 | @ <div id='chat-edit-buttons'> |
| 166 | @ <button id="chat-preview-button" \ |
| 167 | @ title="Preview message">👁</button> |
| 168 | @ <button id="chat-settings-button" \ |
| 169 | @ title="Configure chat">⚙</button> |
| 170 | @ <button id="chat-message-submit" \ |
| 171 | @ title="Send message">📤</button> |
| 172 | @ </div> |
| 173 | @ </div> |
| 174 | @ <div id='chat-input-file-area'> |
| 175 | @ <div class='file-selection-wrapper'> |
| 176 | @ <div class='help-buttonlet'> |
| @@ -210,10 +217,11 @@ | |
| 210 | @ <div id='chat-messages-wrapper' class='chat-view'> |
| 211 | /* New chat messages get inserted immediately after this element */ |
| 212 | @ <span id='message-inject-point'></span> |
| 213 | @ </div> |
| 214 | fossil_free(zProjectName); |
| 215 | builtin_fossil_js_bundle_or("popupwidget", "storage", "fetch", |
| 216 | "pikchr", "confirmer", NULL); |
| 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 |
| --- src/chat.c | |
| +++ src/chat.c | |
| @@ -142,35 +142,42 @@ | |
| 142 | ** send new chat message, delete older messages, or poll for changes. |
| 143 | */ |
| 144 | void chat_webpage(void){ |
| 145 | char *zAlert; |
| 146 | char *zProjectName; |
| 147 | const char * zInputPlaceholder1 = /* Placeholder for 1-line input */ |
| 148 | "Enter sends and Shift-Enter previews."; |
| 149 | const char * zInputPlaceholder2 = /* Placeholder for textarea input*/ |
| 150 | "Ctrl-Enter sends and Shift-Enter previews."; |
| 151 | char * zInputPlaceholder0; /* Common text input placeholder value */ |
| 152 | login_check_credentials(); |
| 153 | if( !g.perm.Chat ){ |
| 154 | login_needed(g.anon.Chat); |
| 155 | return; |
| 156 | } |
| 157 | zAlert = mprintf("%s/builtin/%s", g.zBaseURL, |
| 158 | db_get("chat-alert-sound","alerts/plunk.wav")); |
| 159 | zProjectName = db_get("project-name","Unnamed project"); |
| 160 | zInputPlaceholder0 = |
| 161 | mprintf("Type markdown-formatted message for %h.", zProjectName); |
| 162 | style_set_current_feature("chat"); |
| 163 | style_header("Chat"); |
| 164 | @ <div id='chat-input-area'> |
| 165 | @ <div id='chat-input-line' class='single-line'> |
| 166 | @ <input type="text" name="msg" id="chat-input-single" \ |
| 167 | @ placeholder="%h(zInputPlaceholder0) %h(zInputPlaceholder1)" \ |
| 168 | @ autocomplete="off"> |
| 169 | @ <textarea rows="8" id="chat-input-multi" \ |
| 170 | @ placeholder="%h(zInputPlaceholder0) %h(zInputPlaceholder2)" \ |
| 171 | @ class="hidden"></textarea> |
| 172 | @ <div id='chat-edit-buttons'> |
| 173 | @ <button id="chat-preview-button" \ |
| 174 | @ title="Preview message (Shift-Enter)">👁</button> |
| 175 | @ <button id="chat-settings-button" \ |
| 176 | @ title="Configure chat">⚙</button> |
| 177 | @ <button id="chat-message-submit" \ |
| 178 | @ title="Send message (Ctrl-Enter)">📤</button> |
| 179 | @ </div> |
| 180 | @ </div> |
| 181 | @ <div id='chat-input-file-area'> |
| 182 | @ <div class='file-selection-wrapper'> |
| 183 | @ <div class='help-buttonlet'> |
| @@ -210,10 +217,11 @@ | |
| 217 | @ <div id='chat-messages-wrapper' class='chat-view'> |
| 218 | /* New chat messages get inserted immediately after this element */ |
| 219 | @ <span id='message-inject-point'></span> |
| 220 | @ </div> |
| 221 | fossil_free(zProjectName); |
| 222 | fossil_free(zInputPlaceholder0); |
| 223 | builtin_fossil_js_bundle_or("popupwidget", "storage", "fetch", |
| 224 | "pikchr", "confirmer", NULL); |
| 225 | /* Always in-line the javascript for the chat page */ |
| 226 | @ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */ |
| 227 | /* We need an onload handler to ensure that window.fossil is |
| 228 |
+1
-1
| --- src/default.css | ||
| +++ src/default.css | ||
| @@ -553,11 +553,11 @@ | ||
| 553 | 553 | overflow: hidden /*work around inner PRE slight overflow/overlap*/; |
| 554 | 554 | } |
| 555 | 555 | table.diff pre { |
| 556 | 556 | margin: 0 0 0 0; |
| 557 | 557 | padding: 0 0.5em; |
| 558 | - line-height: 1.225/*for mobile: forum post e6f4ee7de98b55c0*/; | |
| 558 | + line-height: 1.275/*for mobile: forum post e6f4ee7de98b55c0*/; | |
| 559 | 559 | text-size-adjust: none |
| 560 | 560 | /* ^^^ attempt to keep mobile from inflating some text */; |
| 561 | 561 | } |
| 562 | 562 | table.diff pre > ins, |
| 563 | 563 | table.diff pre > del { |
| 564 | 564 |
| --- src/default.css | |
| +++ src/default.css | |
| @@ -553,11 +553,11 @@ | |
| 553 | overflow: hidden /*work around inner PRE slight overflow/overlap*/; |
| 554 | } |
| 555 | table.diff pre { |
| 556 | margin: 0 0 0 0; |
| 557 | padding: 0 0.5em; |
| 558 | line-height: 1.225/*for mobile: forum post e6f4ee7de98b55c0*/; |
| 559 | text-size-adjust: none |
| 560 | /* ^^^ attempt to keep mobile from inflating some text */; |
| 561 | } |
| 562 | table.diff pre > ins, |
| 563 | table.diff pre > del { |
| 564 |
| --- src/default.css | |
| +++ src/default.css | |
| @@ -553,11 +553,11 @@ | |
| 553 | overflow: hidden /*work around inner PRE slight overflow/overlap*/; |
| 554 | } |
| 555 | table.diff pre { |
| 556 | margin: 0 0 0 0; |
| 557 | padding: 0 0.5em; |
| 558 | line-height: 1.275/*for mobile: forum post e6f4ee7de98b55c0*/; |
| 559 | text-size-adjust: none |
| 560 | /* ^^^ attempt to keep mobile from inflating some text */; |
| 561 | } |
| 562 | table.diff pre > ins, |
| 563 | table.diff pre > del { |
| 564 |
+11
-2
| --- src/fossil.diff.js | ||
| +++ src/fossil.diff.js | ||
| @@ -448,11 +448,11 @@ | ||
| 448 | 448 | const selector = '.difflnr > pre'; |
| 449 | 449 | td = tr.querySelector(selector); |
| 450 | 450 | const lineNoTxt = lineno.join('\n')+'\n'; |
| 451 | 451 | lineno.length = 0; |
| 452 | 452 | td.innerHTML = lineNoTxt + td.innerHTML; |
| 453 | - if(this.pos.endLhs<=1 | |
| 453 | + if(this.pos.endLhs<1 | |
| 454 | 454 | || lines.length < (urlParam.to - urlParam.from)){ |
| 455 | 455 | /* No more data. */ |
| 456 | 456 | this.destroy(); |
| 457 | 457 | }else{ |
| 458 | 458 | this.maybeReplaceButtons(); |
| @@ -504,19 +504,25 @@ | ||
| 504 | 504 | a warning. Returns this object. |
| 505 | 505 | */ |
| 506 | 506 | fetchChunk: function(fetchType){ |
| 507 | 507 | if( !this.$fetchQueue ) return this; // HACKHACK: are we destroyed? |
| 508 | 508 | if( fetchType==this.FetchType.ProcessQueue ){ |
| 509 | + this.$fetchQueue.shift(); | |
| 509 | 510 | if( this.$fetchQueue.length==0 ) return this; |
| 510 | 511 | //console.log('fetchChunk: processing queue ...'); |
| 511 | 512 | } |
| 512 | 513 | else{ |
| 513 | 514 | this.$fetchQueue.push(fetchType); |
| 514 | 515 | if( this.$fetchQueue.length!=1 ) return this; |
| 515 | 516 | //console.log('fetchChunk: processing user input ...'); |
| 516 | 517 | } |
| 517 | 518 | fetchType = this.$fetchQueue[0]; |
| 519 | + if( fetchType==this.FetchType.ProcessQueue ){ | |
| 520 | + /* Unexpected! Clear queue so recovery (manual restart) is possible. */ | |
| 521 | + this.$fetchQueue.length = 0; | |
| 522 | + return this; | |
| 523 | + } | |
| 518 | 524 | /* Forewarning, this is a bit confusing: when fetching the |
| 519 | 525 | previous lines, we're doing so on behalf of the *next* diff |
| 520 | 526 | chunk (this.pos.next), and vice versa. */ |
| 521 | 527 | if(fetchType===this.FetchType.NextUp && !this.pos.next |
| 522 | 528 | || fetchType===this.FetchType.PrevDown && !this.pos.prev){ |
| @@ -531,11 +537,14 @@ | ||
| 531 | 537 | }, |
| 532 | 538 | aftersend: ()=>this.msg(false), |
| 533 | 539 | onload: function(list){ |
| 534 | 540 | self.injectResponse(fetchType,up,list); |
| 535 | 541 | if( !self.$fetchQueue || self.$fetchQueue.length==0 ) return; |
| 536 | - self.$fetchQueue.shift(); | |
| 542 | + /* Keep queue length > 0, or clicks stalled during (unusually lengthy) | |
| 543 | + injectResponse() may sneak in as soon as setTimeout() allows, find | |
| 544 | + an empty queue, and therefore start over with queue processing. */ | |
| 545 | + self.$fetchQueue[0] = self.FetchType.ProcessQueue; | |
| 537 | 546 | setTimeout(self.fetchChunk.bind(self,self.FetchType.ProcessQueue)); |
| 538 | 547 | } |
| 539 | 548 | }; |
| 540 | 549 | const up = fOpt.urlParams; |
| 541 | 550 | if(fetchType===this.FetchType.FillGap){ |
| 542 | 551 |
| --- src/fossil.diff.js | |
| +++ src/fossil.diff.js | |
| @@ -448,11 +448,11 @@ | |
| 448 | const selector = '.difflnr > pre'; |
| 449 | td = tr.querySelector(selector); |
| 450 | const lineNoTxt = lineno.join('\n')+'\n'; |
| 451 | lineno.length = 0; |
| 452 | td.innerHTML = lineNoTxt + td.innerHTML; |
| 453 | if(this.pos.endLhs<=1 |
| 454 | || lines.length < (urlParam.to - urlParam.from)){ |
| 455 | /* No more data. */ |
| 456 | this.destroy(); |
| 457 | }else{ |
| 458 | this.maybeReplaceButtons(); |
| @@ -504,19 +504,25 @@ | |
| 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){ |
| @@ -531,11 +537,14 @@ | |
| 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 |
| --- src/fossil.diff.js | |
| +++ src/fossil.diff.js | |
| @@ -448,11 +448,11 @@ | |
| 448 | const selector = '.difflnr > pre'; |
| 449 | td = tr.querySelector(selector); |
| 450 | const lineNoTxt = lineno.join('\n')+'\n'; |
| 451 | lineno.length = 0; |
| 452 | td.innerHTML = lineNoTxt + td.innerHTML; |
| 453 | if(this.pos.endLhs<1 |
| 454 | || lines.length < (urlParam.to - urlParam.from)){ |
| 455 | /* No more data. */ |
| 456 | this.destroy(); |
| 457 | }else{ |
| 458 | this.maybeReplaceButtons(); |
| @@ -504,19 +504,25 @@ | |
| 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 | this.$fetchQueue.shift(); |
| 510 | if( this.$fetchQueue.length==0 ) return this; |
| 511 | //console.log('fetchChunk: processing queue ...'); |
| 512 | } |
| 513 | else{ |
| 514 | this.$fetchQueue.push(fetchType); |
| 515 | if( this.$fetchQueue.length!=1 ) return this; |
| 516 | //console.log('fetchChunk: processing user input ...'); |
| 517 | } |
| 518 | fetchType = this.$fetchQueue[0]; |
| 519 | if( fetchType==this.FetchType.ProcessQueue ){ |
| 520 | /* Unexpected! Clear queue so recovery (manual restart) is possible. */ |
| 521 | this.$fetchQueue.length = 0; |
| 522 | return this; |
| 523 | } |
| 524 | /* Forewarning, this is a bit confusing: when fetching the |
| 525 | previous lines, we're doing so on behalf of the *next* diff |
| 526 | chunk (this.pos.next), and vice versa. */ |
| 527 | if(fetchType===this.FetchType.NextUp && !this.pos.next |
| 528 | || fetchType===this.FetchType.PrevDown && !this.pos.prev){ |
| @@ -531,11 +537,14 @@ | |
| 537 | }, |
| 538 | aftersend: ()=>this.msg(false), |
| 539 | onload: function(list){ |
| 540 | self.injectResponse(fetchType,up,list); |
| 541 | if( !self.$fetchQueue || self.$fetchQueue.length==0 ) return; |
| 542 | /* Keep queue length > 0, or clicks stalled during (unusually lengthy) |
| 543 | injectResponse() may sneak in as soon as setTimeout() allows, find |
| 544 | an empty queue, and therefore start over with queue processing. */ |
| 545 | self.$fetchQueue[0] = self.FetchType.ProcessQueue; |
| 546 | setTimeout(self.fetchChunk.bind(self,self.FetchType.ProcessQueue)); |
| 547 | } |
| 548 | }; |
| 549 | const up = fOpt.urlParams; |
| 550 | if(fetchType===this.FetchType.FillGap){ |
| 551 |
+22
-17
| --- src/fossil.page.chat.js | ||
| +++ src/fossil.page.chat.js | ||
| @@ -218,11 +218,10 @@ | ||
| 218 | 218 | D.removeClass(this.e.inputCurrent, 'hidden'); |
| 219 | 219 | const mh2 = m.clientHeight; |
| 220 | 220 | m.scrollTo(0, sTop + (mh1-mh2)); |
| 221 | 221 | this.e.inputCurrent.value = old.value; |
| 222 | 222 | old.value = ''; |
| 223 | - this.animate(this.e.inputCurrent, "anim-flip-v"); | |
| 224 | 223 | return this; |
| 225 | 224 | }, |
| 226 | 225 | /** |
| 227 | 226 | If passed true or no arguments, switches to multi-line mode |
| 228 | 227 | if currently in single-line mode. If passed false, switches |
| @@ -1375,26 +1374,32 @@ | ||
| 1375 | 1374 | }); |
| 1376 | 1375 | BlobXferState.clear(); |
| 1377 | 1376 | Chat.inputValue("").inputFocus(); |
| 1378 | 1377 | }; |
| 1379 | 1378 | |
| 1380 | - Chat.e.inputSingle.addEventListener('keydown',function(ev){ | |
| 1381 | - if(13===ev.keyCode/*ENTER*/){ | |
| 1382 | - ev.preventDefault(); | |
| 1383 | - ev.stopPropagation(); | |
| 1384 | - Chat.submitMessage(); | |
| 1385 | - return false; | |
| 1386 | - } | |
| 1387 | - }, false); | |
| 1388 | - Chat.e.inputMulti.addEventListener('keydown',function(ev){ | |
| 1389 | - if(ev.ctrlKey && 13 === ev.keyCode){ | |
| 1390 | - ev.preventDefault(); | |
| 1391 | - ev.stopPropagation(); | |
| 1392 | - Chat.submitMessage(); | |
| 1393 | - return false; | |
| 1394 | - } | |
| 1395 | - }, false); | |
| 1379 | + const inputWidgetKeydown = function(ev){ | |
| 1380 | + if(13 === ev.keyCode){ | |
| 1381 | + if(ev.shiftKey){ | |
| 1382 | + ev.preventDefault(); | |
| 1383 | + ev.stopPropagation(); | |
| 1384 | + Chat.e.btnPreview.click(); | |
| 1385 | + return false; | |
| 1386 | + }else if((Chat.e.inputSingle===ev.target) | |
| 1387 | + || (ev.ctrlKey && Chat.e.inputMulti===ev.target)){ | |
| 1388 | + /* ^^^ note that it is intended that both ctrl-enter and enter | |
| 1389 | + work for single-line input mode. */ | |
| 1390 | + ev.preventDefault(); | |
| 1391 | + ev.stopPropagation(); | |
| 1392 | + Chat.submitMessage(); | |
| 1393 | + return false; | |
| 1394 | + } | |
| 1395 | + } | |
| 1396 | + }; | |
| 1397 | + Chat.e.inputSingle | |
| 1398 | + .addEventListener('keydown', inputWidgetKeydown, false); | |
| 1399 | + Chat.e.inputMulti | |
| 1400 | + .addEventListener('keydown', inputWidgetKeydown, false); | |
| 1396 | 1401 | Chat.e.btnSubmit.addEventListener('click',(e)=>{ |
| 1397 | 1402 | e.preventDefault(); |
| 1398 | 1403 | Chat.submitMessage(); |
| 1399 | 1404 | return false; |
| 1400 | 1405 | }); |
| 1401 | 1406 |
| --- src/fossil.page.chat.js | |
| +++ src/fossil.page.chat.js | |
| @@ -218,11 +218,10 @@ | |
| 218 | D.removeClass(this.e.inputCurrent, 'hidden'); |
| 219 | const mh2 = m.clientHeight; |
| 220 | m.scrollTo(0, sTop + (mh1-mh2)); |
| 221 | this.e.inputCurrent.value = old.value; |
| 222 | old.value = ''; |
| 223 | this.animate(this.e.inputCurrent, "anim-flip-v"); |
| 224 | return this; |
| 225 | }, |
| 226 | /** |
| 227 | If passed true or no arguments, switches to multi-line mode |
| 228 | if currently in single-line mode. If passed false, switches |
| @@ -1375,26 +1374,32 @@ | |
| 1375 | }); |
| 1376 | BlobXferState.clear(); |
| 1377 | Chat.inputValue("").inputFocus(); |
| 1378 | }; |
| 1379 | |
| 1380 | Chat.e.inputSingle.addEventListener('keydown',function(ev){ |
| 1381 | if(13===ev.keyCode/*ENTER*/){ |
| 1382 | ev.preventDefault(); |
| 1383 | ev.stopPropagation(); |
| 1384 | Chat.submitMessage(); |
| 1385 | return false; |
| 1386 | } |
| 1387 | }, false); |
| 1388 | Chat.e.inputMulti.addEventListener('keydown',function(ev){ |
| 1389 | if(ev.ctrlKey && 13 === ev.keyCode){ |
| 1390 | ev.preventDefault(); |
| 1391 | ev.stopPropagation(); |
| 1392 | Chat.submitMessage(); |
| 1393 | return false; |
| 1394 | } |
| 1395 | }, false); |
| 1396 | Chat.e.btnSubmit.addEventListener('click',(e)=>{ |
| 1397 | e.preventDefault(); |
| 1398 | Chat.submitMessage(); |
| 1399 | return false; |
| 1400 | }); |
| 1401 |
| --- src/fossil.page.chat.js | |
| +++ src/fossil.page.chat.js | |
| @@ -218,11 +218,10 @@ | |
| 218 | D.removeClass(this.e.inputCurrent, 'hidden'); |
| 219 | const mh2 = m.clientHeight; |
| 220 | m.scrollTo(0, sTop + (mh1-mh2)); |
| 221 | this.e.inputCurrent.value = old.value; |
| 222 | old.value = ''; |
| 223 | return this; |
| 224 | }, |
| 225 | /** |
| 226 | If passed true or no arguments, switches to multi-line mode |
| 227 | if currently in single-line mode. If passed false, switches |
| @@ -1375,26 +1374,32 @@ | |
| 1374 | }); |
| 1375 | BlobXferState.clear(); |
| 1376 | Chat.inputValue("").inputFocus(); |
| 1377 | }; |
| 1378 | |
| 1379 | const inputWidgetKeydown = function(ev){ |
| 1380 | if(13 === ev.keyCode){ |
| 1381 | if(ev.shiftKey){ |
| 1382 | ev.preventDefault(); |
| 1383 | ev.stopPropagation(); |
| 1384 | Chat.e.btnPreview.click(); |
| 1385 | return false; |
| 1386 | }else if((Chat.e.inputSingle===ev.target) |
| 1387 | || (ev.ctrlKey && Chat.e.inputMulti===ev.target)){ |
| 1388 | /* ^^^ note that it is intended that both ctrl-enter and enter |
| 1389 | work for single-line input mode. */ |
| 1390 | ev.preventDefault(); |
| 1391 | ev.stopPropagation(); |
| 1392 | Chat.submitMessage(); |
| 1393 | return false; |
| 1394 | } |
| 1395 | } |
| 1396 | }; |
| 1397 | Chat.e.inputSingle |
| 1398 | .addEventListener('keydown', inputWidgetKeydown, false); |
| 1399 | Chat.e.inputMulti |
| 1400 | .addEventListener('keydown', inputWidgetKeydown, false); |
| 1401 | Chat.e.btnSubmit.addEventListener('click',(e)=>{ |
| 1402 | e.preventDefault(); |
| 1403 | Chat.submitMessage(); |
| 1404 | return false; |
| 1405 | }); |
| 1406 |
+22
-17
| --- src/fossil.page.chat.js | ||
| +++ src/fossil.page.chat.js | ||
| @@ -218,11 +218,10 @@ | ||
| 218 | 218 | D.removeClass(this.e.inputCurrent, 'hidden'); |
| 219 | 219 | const mh2 = m.clientHeight; |
| 220 | 220 | m.scrollTo(0, sTop + (mh1-mh2)); |
| 221 | 221 | this.e.inputCurrent.value = old.value; |
| 222 | 222 | old.value = ''; |
| 223 | - this.animate(this.e.inputCurrent, "anim-flip-v"); | |
| 224 | 223 | return this; |
| 225 | 224 | }, |
| 226 | 225 | /** |
| 227 | 226 | If passed true or no arguments, switches to multi-line mode |
| 228 | 227 | if currently in single-line mode. If passed false, switches |
| @@ -1375,26 +1374,32 @@ | ||
| 1375 | 1374 | }); |
| 1376 | 1375 | BlobXferState.clear(); |
| 1377 | 1376 | Chat.inputValue("").inputFocus(); |
| 1378 | 1377 | }; |
| 1379 | 1378 | |
| 1380 | - Chat.e.inputSingle.addEventListener('keydown',function(ev){ | |
| 1381 | - if(13===ev.keyCode/*ENTER*/){ | |
| 1382 | - ev.preventDefault(); | |
| 1383 | - ev.stopPropagation(); | |
| 1384 | - Chat.submitMessage(); | |
| 1385 | - return false; | |
| 1386 | - } | |
| 1387 | - }, false); | |
| 1388 | - Chat.e.inputMulti.addEventListener('keydown',function(ev){ | |
| 1389 | - if(ev.ctrlKey && 13 === ev.keyCode){ | |
| 1390 | - ev.preventDefault(); | |
| 1391 | - ev.stopPropagation(); | |
| 1392 | - Chat.submitMessage(); | |
| 1393 | - return false; | |
| 1394 | - } | |
| 1395 | - }, false); | |
| 1379 | + const inputWidgetKeydown = function(ev){ | |
| 1380 | + if(13 === ev.keyCode){ | |
| 1381 | + if(ev.shiftKey){ | |
| 1382 | + ev.preventDefault(); | |
| 1383 | + ev.stopPropagation(); | |
| 1384 | + Chat.e.btnPreview.click(); | |
| 1385 | + return false; | |
| 1386 | + }else if((Chat.e.inputSingle===ev.target) | |
| 1387 | + || (ev.ctrlKey && Chat.e.inputMulti===ev.target)){ | |
| 1388 | + /* ^^^ note that it is intended that both ctrl-enter and enter | |
| 1389 | + work for single-line input mode. */ | |
| 1390 | + ev.preventDefault(); | |
| 1391 | + ev.stopPropagation(); | |
| 1392 | + Chat.submitMessage(); | |
| 1393 | + return false; | |
| 1394 | + } | |
| 1395 | + } | |
| 1396 | + }; | |
| 1397 | + Chat.e.inputSingle | |
| 1398 | + .addEventListener('keydown', inputWidgetKeydown, false); | |
| 1399 | + Chat.e.inputMulti | |
| 1400 | + .addEventListener('keydown', inputWidgetKeydown, false); | |
| 1396 | 1401 | Chat.e.btnSubmit.addEventListener('click',(e)=>{ |
| 1397 | 1402 | e.preventDefault(); |
| 1398 | 1403 | Chat.submitMessage(); |
| 1399 | 1404 | return false; |
| 1400 | 1405 | }); |
| 1401 | 1406 |
| --- src/fossil.page.chat.js | |
| +++ src/fossil.page.chat.js | |
| @@ -218,11 +218,10 @@ | |
| 218 | D.removeClass(this.e.inputCurrent, 'hidden'); |
| 219 | const mh2 = m.clientHeight; |
| 220 | m.scrollTo(0, sTop + (mh1-mh2)); |
| 221 | this.e.inputCurrent.value = old.value; |
| 222 | old.value = ''; |
| 223 | this.animate(this.e.inputCurrent, "anim-flip-v"); |
| 224 | return this; |
| 225 | }, |
| 226 | /** |
| 227 | If passed true or no arguments, switches to multi-line mode |
| 228 | if currently in single-line mode. If passed false, switches |
| @@ -1375,26 +1374,32 @@ | |
| 1375 | }); |
| 1376 | BlobXferState.clear(); |
| 1377 | Chat.inputValue("").inputFocus(); |
| 1378 | }; |
| 1379 | |
| 1380 | Chat.e.inputSingle.addEventListener('keydown',function(ev){ |
| 1381 | if(13===ev.keyCode/*ENTER*/){ |
| 1382 | ev.preventDefault(); |
| 1383 | ev.stopPropagation(); |
| 1384 | Chat.submitMessage(); |
| 1385 | return false; |
| 1386 | } |
| 1387 | }, false); |
| 1388 | Chat.e.inputMulti.addEventListener('keydown',function(ev){ |
| 1389 | if(ev.ctrlKey && 13 === ev.keyCode){ |
| 1390 | ev.preventDefault(); |
| 1391 | ev.stopPropagation(); |
| 1392 | Chat.submitMessage(); |
| 1393 | return false; |
| 1394 | } |
| 1395 | }, false); |
| 1396 | Chat.e.btnSubmit.addEventListener('click',(e)=>{ |
| 1397 | e.preventDefault(); |
| 1398 | Chat.submitMessage(); |
| 1399 | return false; |
| 1400 | }); |
| 1401 |
| --- src/fossil.page.chat.js | |
| +++ src/fossil.page.chat.js | |
| @@ -218,11 +218,10 @@ | |
| 218 | D.removeClass(this.e.inputCurrent, 'hidden'); |
| 219 | const mh2 = m.clientHeight; |
| 220 | m.scrollTo(0, sTop + (mh1-mh2)); |
| 221 | this.e.inputCurrent.value = old.value; |
| 222 | old.value = ''; |
| 223 | return this; |
| 224 | }, |
| 225 | /** |
| 226 | If passed true or no arguments, switches to multi-line mode |
| 227 | if currently in single-line mode. If passed false, switches |
| @@ -1375,26 +1374,32 @@ | |
| 1374 | }); |
| 1375 | BlobXferState.clear(); |
| 1376 | Chat.inputValue("").inputFocus(); |
| 1377 | }; |
| 1378 | |
| 1379 | const inputWidgetKeydown = function(ev){ |
| 1380 | if(13 === ev.keyCode){ |
| 1381 | if(ev.shiftKey){ |
| 1382 | ev.preventDefault(); |
| 1383 | ev.stopPropagation(); |
| 1384 | Chat.e.btnPreview.click(); |
| 1385 | return false; |
| 1386 | }else if((Chat.e.inputSingle===ev.target) |
| 1387 | || (ev.ctrlKey && Chat.e.inputMulti===ev.target)){ |
| 1388 | /* ^^^ note that it is intended that both ctrl-enter and enter |
| 1389 | work for single-line input mode. */ |
| 1390 | ev.preventDefault(); |
| 1391 | ev.stopPropagation(); |
| 1392 | Chat.submitMessage(); |
| 1393 | return false; |
| 1394 | } |
| 1395 | } |
| 1396 | }; |
| 1397 | Chat.e.inputSingle |
| 1398 | .addEventListener('keydown', inputWidgetKeydown, false); |
| 1399 | Chat.e.inputMulti |
| 1400 | .addEventListener('keydown', inputWidgetKeydown, false); |
| 1401 | Chat.e.btnSubmit.addEventListener('click',(e)=>{ |
| 1402 | e.preventDefault(); |
| 1403 | Chat.submitMessage(); |
| 1404 | return false; |
| 1405 | }); |
| 1406 |
+2
-2
| --- src/fossil.page.fileedit.js | ||
| +++ src/fossil.page.fileedit.js | ||
| @@ -724,11 +724,11 @@ | ||
| 724 | 724 | ); |
| 725 | 725 | //////////////////////////////////////////////////////////// |
| 726 | 726 | // Trigger preview on Ctrl-Enter. This only works on the built-in |
| 727 | 727 | // editor widget, not a client-provided one. |
| 728 | 728 | P.e.taEditor.addEventListener('keydown',function(ev){ |
| 729 | - if(ev.ctrlKey && 13 === ev.keyCode){ | |
| 729 | + if(ev.shiftKey && 13 === ev.keyCode){ | |
| 730 | 730 | ev.preventDefault(); |
| 731 | 731 | ev.stopPropagation(); |
| 732 | 732 | P.e.taEditor.blur(/*force change event, if needed*/); |
| 733 | 733 | P.tabs.switchToTab(P.e.tabs.preview); |
| 734 | 734 | if(!P.e.cbAutoPreview.checked){/* If NOT in auto-preview mode, trigger an update. */ |
| @@ -737,11 +737,11 @@ | ||
| 737 | 737 | return false; |
| 738 | 738 | } |
| 739 | 739 | }, false); |
| 740 | 740 | // If we're in the preview tab, have ctrl-enter switch back to the editor. |
| 741 | 741 | document.body.addEventListener('keydown',function(ev){ |
| 742 | - if(ev.ctrlKey && 13 === ev.keyCode){ | |
| 742 | + if(ev.shiftKey && 13 === ev.keyCode){ | |
| 743 | 743 | if(currentTab === P.e.tabs.preview){ |
| 744 | 744 | ev.preventDefault(); |
| 745 | 745 | ev.stopPropagation(); |
| 746 | 746 | P.tabs.switchToTab(P.e.tabs.content); |
| 747 | 747 | P.e.taEditor.focus(/*doesn't work for client-supplied editor widget! |
| 748 | 748 |
| --- src/fossil.page.fileedit.js | |
| +++ src/fossil.page.fileedit.js | |
| @@ -724,11 +724,11 @@ | |
| 724 | ); |
| 725 | //////////////////////////////////////////////////////////// |
| 726 | // Trigger preview on Ctrl-Enter. This only works on the built-in |
| 727 | // editor widget, not a client-provided one. |
| 728 | P.e.taEditor.addEventListener('keydown',function(ev){ |
| 729 | if(ev.ctrlKey && 13 === ev.keyCode){ |
| 730 | ev.preventDefault(); |
| 731 | ev.stopPropagation(); |
| 732 | P.e.taEditor.blur(/*force change event, if needed*/); |
| 733 | P.tabs.switchToTab(P.e.tabs.preview); |
| 734 | if(!P.e.cbAutoPreview.checked){/* If NOT in auto-preview mode, trigger an update. */ |
| @@ -737,11 +737,11 @@ | |
| 737 | return false; |
| 738 | } |
| 739 | }, false); |
| 740 | // If we're in the preview tab, have ctrl-enter switch back to the editor. |
| 741 | document.body.addEventListener('keydown',function(ev){ |
| 742 | if(ev.ctrlKey && 13 === ev.keyCode){ |
| 743 | if(currentTab === P.e.tabs.preview){ |
| 744 | ev.preventDefault(); |
| 745 | ev.stopPropagation(); |
| 746 | P.tabs.switchToTab(P.e.tabs.content); |
| 747 | P.e.taEditor.focus(/*doesn't work for client-supplied editor widget! |
| 748 |
| --- src/fossil.page.fileedit.js | |
| +++ src/fossil.page.fileedit.js | |
| @@ -724,11 +724,11 @@ | |
| 724 | ); |
| 725 | //////////////////////////////////////////////////////////// |
| 726 | // Trigger preview on Ctrl-Enter. This only works on the built-in |
| 727 | // editor widget, not a client-provided one. |
| 728 | P.e.taEditor.addEventListener('keydown',function(ev){ |
| 729 | if(ev.shiftKey && 13 === ev.keyCode){ |
| 730 | ev.preventDefault(); |
| 731 | ev.stopPropagation(); |
| 732 | P.e.taEditor.blur(/*force change event, if needed*/); |
| 733 | P.tabs.switchToTab(P.e.tabs.preview); |
| 734 | if(!P.e.cbAutoPreview.checked){/* If NOT in auto-preview mode, trigger an update. */ |
| @@ -737,11 +737,11 @@ | |
| 737 | return false; |
| 738 | } |
| 739 | }, false); |
| 740 | // If we're in the preview tab, have ctrl-enter switch back to the editor. |
| 741 | document.body.addEventListener('keydown',function(ev){ |
| 742 | if(ev.shiftKey && 13 === ev.keyCode){ |
| 743 | if(currentTab === P.e.tabs.preview){ |
| 744 | ev.preventDefault(); |
| 745 | ev.stopPropagation(); |
| 746 | P.tabs.switchToTab(P.e.tabs.content); |
| 747 | P.e.taEditor.focus(/*doesn't work for client-supplied editor widget! |
| 748 |
+3
-2
| --- src/fossil.page.pikchrshow.js | ||
| +++ src/fossil.page.pikchrshow.js | ||
| @@ -98,13 +98,13 @@ | ||
| 98 | 98 | P.e.previewCopyButton, |
| 99 | 99 | P.e.previewModeLabel, |
| 100 | 100 | P.e.markupAlignWrapper ); |
| 101 | 101 | |
| 102 | 102 | //////////////////////////////////////////////////////////// |
| 103 | - // Trigger preview on Ctrl-Enter. | |
| 103 | + // Trigger preview on Shift-Enter. | |
| 104 | 104 | P.e.taContent.addEventListener('keydown',function(ev){ |
| 105 | - if(ev.ctrlKey && 13 === ev.keyCode){ | |
| 105 | + if(ev.shiftKey && 13 === ev.keyCode){ | |
| 106 | 106 | ev.preventDefault(); |
| 107 | 107 | ev.stopPropagation(); |
| 108 | 108 | P.preview(); |
| 109 | 109 | return false; |
| 110 | 110 | } |
| @@ -390,10 +390,11 @@ | ||
| 390 | 390 | } |
| 391 | 391 | D.append(D.clearElement(preTgt), this.e.taPreviewText); |
| 392 | 392 | break; |
| 393 | 393 | } |
| 394 | 394 | this.e.previewModeLabel.innerText = label; |
| 395 | + this.e.taContent.focus(/*not sure why this gets lost on preview!*/); | |
| 395 | 396 | }; |
| 396 | 397 | |
| 397 | 398 | /** |
| 398 | 399 | Fetches the preview from the server and updates the preview to |
| 399 | 400 | the rendered SVG content or error report. |
| 400 | 401 |
| --- src/fossil.page.pikchrshow.js | |
| +++ src/fossil.page.pikchrshow.js | |
| @@ -98,13 +98,13 @@ | |
| 98 | P.e.previewCopyButton, |
| 99 | P.e.previewModeLabel, |
| 100 | P.e.markupAlignWrapper ); |
| 101 | |
| 102 | //////////////////////////////////////////////////////////// |
| 103 | // Trigger preview on Ctrl-Enter. |
| 104 | P.e.taContent.addEventListener('keydown',function(ev){ |
| 105 | if(ev.ctrlKey && 13 === ev.keyCode){ |
| 106 | ev.preventDefault(); |
| 107 | ev.stopPropagation(); |
| 108 | P.preview(); |
| 109 | return false; |
| 110 | } |
| @@ -390,10 +390,11 @@ | |
| 390 | } |
| 391 | D.append(D.clearElement(preTgt), this.e.taPreviewText); |
| 392 | break; |
| 393 | } |
| 394 | this.e.previewModeLabel.innerText = label; |
| 395 | }; |
| 396 | |
| 397 | /** |
| 398 | Fetches the preview from the server and updates the preview to |
| 399 | the rendered SVG content or error report. |
| 400 |
| --- src/fossil.page.pikchrshow.js | |
| +++ src/fossil.page.pikchrshow.js | |
| @@ -98,13 +98,13 @@ | |
| 98 | P.e.previewCopyButton, |
| 99 | P.e.previewModeLabel, |
| 100 | P.e.markupAlignWrapper ); |
| 101 | |
| 102 | //////////////////////////////////////////////////////////// |
| 103 | // Trigger preview on Shift-Enter. |
| 104 | P.e.taContent.addEventListener('keydown',function(ev){ |
| 105 | if(ev.shiftKey && 13 === ev.keyCode){ |
| 106 | ev.preventDefault(); |
| 107 | ev.stopPropagation(); |
| 108 | P.preview(); |
| 109 | return false; |
| 110 | } |
| @@ -390,10 +390,11 @@ | |
| 390 | } |
| 391 | D.append(D.clearElement(preTgt), this.e.taPreviewText); |
| 392 | break; |
| 393 | } |
| 394 | this.e.previewModeLabel.innerText = label; |
| 395 | this.e.taContent.focus(/*not sure why this gets lost on preview!*/); |
| 396 | }; |
| 397 | |
| 398 | /** |
| 399 | Fetches the preview from the server and updates the preview to |
| 400 | the rendered SVG content or error report. |
| 401 |
+2
-2
| --- src/fossil.page.wikiedit.js | ||
| +++ src/fossil.page.wikiedit.js | ||
| @@ -914,11 +914,11 @@ | ||
| 914 | 914 | ); |
| 915 | 915 | //////////////////////////////////////////////////////////// |
| 916 | 916 | // Trigger preview on Ctrl-Enter. This only works on the built-in |
| 917 | 917 | // editor widget, not a client-provided one. |
| 918 | 918 | P.e.taEditor.addEventListener('keydown',function(ev){ |
| 919 | - if(ev.ctrlKey && 13 === ev.keyCode){ | |
| 919 | + if(ev.shiftKey && 13 === ev.keyCode){ | |
| 920 | 920 | ev.preventDefault(); |
| 921 | 921 | ev.stopPropagation(); |
| 922 | 922 | P.e.taEditor.blur(/*force change event, if needed*/); |
| 923 | 923 | P.tabs.switchToTab(P.e.tabs.preview); |
| 924 | 924 | if(!P.e.cbAutoPreview.checked){/* If NOT in auto-preview mode, trigger an update. */ |
| @@ -926,11 +926,11 @@ | ||
| 926 | 926 | } |
| 927 | 927 | } |
| 928 | 928 | }, false); |
| 929 | 929 | // If we're in the preview tab, have ctrl-enter switch back to the editor. |
| 930 | 930 | document.body.addEventListener('keydown',function(ev){ |
| 931 | - if(ev.ctrlKey && 13 === ev.keyCode){ | |
| 931 | + if(ev.shiftKey && 13 === ev.keyCode){ | |
| 932 | 932 | if(currentTab === P.e.tabs.preview){ |
| 933 | 933 | ev.preventDefault(); |
| 934 | 934 | ev.stopPropagation(); |
| 935 | 935 | P.tabs.switchToTab(P.e.tabs.content); |
| 936 | 936 | P.e.taEditor.focus(/*doesn't work for client-supplied editor widget! |
| 937 | 937 |
| --- src/fossil.page.wikiedit.js | |
| +++ src/fossil.page.wikiedit.js | |
| @@ -914,11 +914,11 @@ | |
| 914 | ); |
| 915 | //////////////////////////////////////////////////////////// |
| 916 | // Trigger preview on Ctrl-Enter. This only works on the built-in |
| 917 | // editor widget, not a client-provided one. |
| 918 | P.e.taEditor.addEventListener('keydown',function(ev){ |
| 919 | if(ev.ctrlKey && 13 === ev.keyCode){ |
| 920 | ev.preventDefault(); |
| 921 | ev.stopPropagation(); |
| 922 | P.e.taEditor.blur(/*force change event, if needed*/); |
| 923 | P.tabs.switchToTab(P.e.tabs.preview); |
| 924 | if(!P.e.cbAutoPreview.checked){/* If NOT in auto-preview mode, trigger an update. */ |
| @@ -926,11 +926,11 @@ | |
| 926 | } |
| 927 | } |
| 928 | }, false); |
| 929 | // If we're in the preview tab, have ctrl-enter switch back to the editor. |
| 930 | document.body.addEventListener('keydown',function(ev){ |
| 931 | if(ev.ctrlKey && 13 === ev.keyCode){ |
| 932 | if(currentTab === P.e.tabs.preview){ |
| 933 | ev.preventDefault(); |
| 934 | ev.stopPropagation(); |
| 935 | P.tabs.switchToTab(P.e.tabs.content); |
| 936 | P.e.taEditor.focus(/*doesn't work for client-supplied editor widget! |
| 937 |
| --- src/fossil.page.wikiedit.js | |
| +++ src/fossil.page.wikiedit.js | |
| @@ -914,11 +914,11 @@ | |
| 914 | ); |
| 915 | //////////////////////////////////////////////////////////// |
| 916 | // Trigger preview on Ctrl-Enter. This only works on the built-in |
| 917 | // editor widget, not a client-provided one. |
| 918 | P.e.taEditor.addEventListener('keydown',function(ev){ |
| 919 | if(ev.shiftKey && 13 === ev.keyCode){ |
| 920 | ev.preventDefault(); |
| 921 | ev.stopPropagation(); |
| 922 | P.e.taEditor.blur(/*force change event, if needed*/); |
| 923 | P.tabs.switchToTab(P.e.tabs.preview); |
| 924 | if(!P.e.cbAutoPreview.checked){/* If NOT in auto-preview mode, trigger an update. */ |
| @@ -926,11 +926,11 @@ | |
| 926 | } |
| 927 | } |
| 928 | }, false); |
| 929 | // If we're in the preview tab, have ctrl-enter switch back to the editor. |
| 930 | document.body.addEventListener('keydown',function(ev){ |
| 931 | if(ev.shiftKey && 13 === ev.keyCode){ |
| 932 | if(currentTab === P.e.tabs.preview){ |
| 933 | ev.preventDefault(); |
| 934 | ev.stopPropagation(); |
| 935 | P.tabs.switchToTab(P.e.tabs.content); |
| 936 | P.e.taEditor.focus(/*doesn't work for client-supplied editor widget! |
| 937 |
+1
-1
| --- src/pikchrshow.c | ||
| +++ src/pikchrshow.c | ||
| @@ -335,11 +335,11 @@ | ||
| 335 | 335 | CX("body.pikchrshow .v-align-middle{" |
| 336 | 336 | "vertical-align: middle" |
| 337 | 337 | "}\n"); |
| 338 | 338 | CX(".dragover {border: 3px dotted rgba(0,255,0,0.6)}\n"); |
| 339 | 339 | } CX("</style>"); |
| 340 | - CX("<div>Input pikchr code and tap Preview (or Ctrl-Enter) to render " | |
| 340 | + CX("<div>Input pikchr code and tap Preview (or Shift-Enter) to render " | |
| 341 | 341 | "it:</div>"); |
| 342 | 342 | CX("<div id='sbs-wrapper'>"); { |
| 343 | 343 | CX("<div id='pikchrshow-form'>"); { |
| 344 | 344 | CX("<textarea id='content' name='content' rows='15'>" |
| 345 | 345 | "%s</textarea>",zContent/*safe-for-%s*/); |
| 346 | 346 |
| --- src/pikchrshow.c | |
| +++ src/pikchrshow.c | |
| @@ -335,11 +335,11 @@ | |
| 335 | CX("body.pikchrshow .v-align-middle{" |
| 336 | "vertical-align: middle" |
| 337 | "}\n"); |
| 338 | CX(".dragover {border: 3px dotted rgba(0,255,0,0.6)}\n"); |
| 339 | } CX("</style>"); |
| 340 | CX("<div>Input pikchr code and tap Preview (or Ctrl-Enter) to render " |
| 341 | "it:</div>"); |
| 342 | CX("<div id='sbs-wrapper'>"); { |
| 343 | CX("<div id='pikchrshow-form'>"); { |
| 344 | CX("<textarea id='content' name='content' rows='15'>" |
| 345 | "%s</textarea>",zContent/*safe-for-%s*/); |
| 346 |
| --- src/pikchrshow.c | |
| +++ src/pikchrshow.c | |
| @@ -335,11 +335,11 @@ | |
| 335 | CX("body.pikchrshow .v-align-middle{" |
| 336 | "vertical-align: middle" |
| 337 | "}\n"); |
| 338 | CX(".dragover {border: 3px dotted rgba(0,255,0,0.6)}\n"); |
| 339 | } CX("</style>"); |
| 340 | CX("<div>Input pikchr code and tap Preview (or Shift-Enter) to render " |
| 341 | "it:</div>"); |
| 342 | CX("<div id='sbs-wrapper'>"); { |
| 343 | CX("<div id='pikchrshow-form'>"); { |
| 344 | CX("<textarea id='content' name='content' rows='15'>" |
| 345 | "%s</textarea>",zContent/*safe-for-%s*/); |
| 346 |
| --- src/style.fileedit.css | ||
| +++ src/style.fileedit.css | ||
| @@ -70,10 +70,13 @@ | ||
| 70 | 70 | body.fileedit #fileedit-tabs { |
| 71 | 71 | margin: 0.5em 0 0 0; |
| 72 | 72 | } |
| 73 | 73 | body.fileedit #fileedit-tab-preview-wrapper { |
| 74 | 74 | overflow: auto; |
| 75 | +} | |
| 76 | +body.fileedit #fileedit-tab-preview-wrapper > pre { | |
| 77 | + margin: 0; | |
| 75 | 78 | } |
| 76 | 79 | body.fileedit #fileedit-tab-fileselect > h1 { |
| 77 | 80 | margin: 0; |
| 78 | 81 | } |
| 79 | 82 | body.fileedit .fileedit-options.commit-message > div { |
| 80 | 83 |
| --- src/style.fileedit.css | |
| +++ src/style.fileedit.css | |
| @@ -70,10 +70,13 @@ | |
| 70 | body.fileedit #fileedit-tabs { |
| 71 | margin: 0.5em 0 0 0; |
| 72 | } |
| 73 | body.fileedit #fileedit-tab-preview-wrapper { |
| 74 | overflow: auto; |
| 75 | } |
| 76 | body.fileedit #fileedit-tab-fileselect > h1 { |
| 77 | margin: 0; |
| 78 | } |
| 79 | body.fileedit .fileedit-options.commit-message > div { |
| 80 |
| --- src/style.fileedit.css | |
| +++ src/style.fileedit.css | |
| @@ -70,10 +70,13 @@ | |
| 70 | body.fileedit #fileedit-tabs { |
| 71 | margin: 0.5em 0 0 0; |
| 72 | } |
| 73 | body.fileedit #fileedit-tab-preview-wrapper { |
| 74 | overflow: auto; |
| 75 | } |
| 76 | body.fileedit #fileedit-tab-preview-wrapper > pre { |
| 77 | margin: 0; |
| 78 | } |
| 79 | body.fileedit #fileedit-tab-fileselect > h1 { |
| 80 | margin: 0; |
| 81 | } |
| 82 | body.fileedit .fileedit-options.commit-message > div { |
| 83 |
+3
-1
| --- src/url.c | ||
| +++ src/url.c | ||
| @@ -196,10 +196,11 @@ | ||
| 196 | 196 | i++; |
| 197 | 197 | while( (c = zUrl[i])!=0 && fossil_isdigit(c) ){ |
| 198 | 198 | pUrlData->port = pUrlData->port*10 + c - '0'; |
| 199 | 199 | i++; |
| 200 | 200 | } |
| 201 | + if( c!=0 && c!='/' ) fossil_fatal("url missing '/' after port number"); | |
| 201 | 202 | pUrlData->hostname = mprintf("%s:%d", pUrlData->name, pUrlData->port); |
| 202 | 203 | }else{ |
| 203 | 204 | pUrlData->port = pUrlData->dfltPort; |
| 204 | 205 | pUrlData->hostname = pUrlData->name; |
| 205 | 206 | } |
| @@ -676,11 +677,12 @@ | ||
| 676 | 677 | ** But don't remove the "www." prefix if what follows is the suffix. |
| 677 | 678 | ** forum:/forumpost/74e111a2ee */ |
| 678 | 679 | zTail += 4; |
| 679 | 680 | } |
| 680 | 681 | if( zTail[0]==0 ) return 0; |
| 681 | - for(i=0; zTail[i] && zTail[i]!='.' && zTail[i]!='?'; i++){} | |
| 682 | + for(i=0; zTail[i] && zTail[i]!='.' && zTail[i]!='?' && | |
| 683 | + zTail[i]!=':' && zTail[i]!='/'; i++){} | |
| 682 | 684 | if( i==0 ) return 0; |
| 683 | 685 | return mprintf("%.*s", i, zTail); |
| 684 | 686 | } |
| 685 | 687 | |
| 686 | 688 | /* |
| 687 | 689 |
| --- src/url.c | |
| +++ src/url.c | |
| @@ -196,10 +196,11 @@ | |
| 196 | i++; |
| 197 | while( (c = zUrl[i])!=0 && fossil_isdigit(c) ){ |
| 198 | pUrlData->port = pUrlData->port*10 + c - '0'; |
| 199 | i++; |
| 200 | } |
| 201 | pUrlData->hostname = mprintf("%s:%d", pUrlData->name, pUrlData->port); |
| 202 | }else{ |
| 203 | pUrlData->port = pUrlData->dfltPort; |
| 204 | pUrlData->hostname = pUrlData->name; |
| 205 | } |
| @@ -676,11 +677,12 @@ | |
| 676 | ** But don't remove the "www." prefix if what follows is the suffix. |
| 677 | ** forum:/forumpost/74e111a2ee */ |
| 678 | zTail += 4; |
| 679 | } |
| 680 | if( zTail[0]==0 ) return 0; |
| 681 | for(i=0; zTail[i] && zTail[i]!='.' && zTail[i]!='?'; i++){} |
| 682 | if( i==0 ) return 0; |
| 683 | return mprintf("%.*s", i, zTail); |
| 684 | } |
| 685 | |
| 686 | /* |
| 687 |
| --- src/url.c | |
| +++ src/url.c | |
| @@ -196,10 +196,11 @@ | |
| 196 | i++; |
| 197 | while( (c = zUrl[i])!=0 && fossil_isdigit(c) ){ |
| 198 | pUrlData->port = pUrlData->port*10 + c - '0'; |
| 199 | i++; |
| 200 | } |
| 201 | if( c!=0 && c!='/' ) fossil_fatal("url missing '/' after port number"); |
| 202 | pUrlData->hostname = mprintf("%s:%d", pUrlData->name, pUrlData->port); |
| 203 | }else{ |
| 204 | pUrlData->port = pUrlData->dfltPort; |
| 205 | pUrlData->hostname = pUrlData->name; |
| 206 | } |
| @@ -676,11 +677,12 @@ | |
| 677 | ** But don't remove the "www." prefix if what follows is the suffix. |
| 678 | ** forum:/forumpost/74e111a2ee */ |
| 679 | zTail += 4; |
| 680 | } |
| 681 | if( zTail[0]==0 ) return 0; |
| 682 | for(i=0; zTail[i] && zTail[i]!='.' && zTail[i]!='?' && |
| 683 | zTail[i]!=':' && zTail[i]!='/'; i++){} |
| 684 | if( i==0 ) return 0; |
| 685 | return mprintf("%.*s", i, zTail); |
| 686 | } |
| 687 | |
| 688 | /* |
| 689 |
+1
-1
| --- src/wiki.c | ||
| +++ src/wiki.c | ||
| @@ -2428,11 +2428,11 @@ | ||
| 2428 | 2428 | verify_all_options(); |
| 2429 | 2429 | if (fTechnote==0){ |
| 2430 | 2430 | db_prepare(&q, listAllWikiPages/*works-like:""*/); |
| 2431 | 2431 | }else{ |
| 2432 | 2432 | db_prepare(&q, |
| 2433 | - "SELECT datetime(e.mtime), substr(t.tagname,7)" | |
| 2433 | + "SELECT datetime(e.mtime), substr(t.tagname,7), e.objid" | |
| 2434 | 2434 | " FROM event e, tag t" |
| 2435 | 2435 | " WHERE e.type='e'" |
| 2436 | 2436 | " AND e.tagid IS NOT NULL" |
| 2437 | 2437 | " AND t.tagid=e.tagid" |
| 2438 | 2438 | " ORDER BY e.mtime DESC /*sort*/" |
| 2439 | 2439 |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -2428,11 +2428,11 @@ | |
| 2428 | verify_all_options(); |
| 2429 | if (fTechnote==0){ |
| 2430 | db_prepare(&q, listAllWikiPages/*works-like:""*/); |
| 2431 | }else{ |
| 2432 | db_prepare(&q, |
| 2433 | "SELECT datetime(e.mtime), substr(t.tagname,7)" |
| 2434 | " FROM event e, tag t" |
| 2435 | " WHERE e.type='e'" |
| 2436 | " AND e.tagid IS NOT NULL" |
| 2437 | " AND t.tagid=e.tagid" |
| 2438 | " ORDER BY e.mtime DESC /*sort*/" |
| 2439 |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -2428,11 +2428,11 @@ | |
| 2428 | verify_all_options(); |
| 2429 | if (fTechnote==0){ |
| 2430 | db_prepare(&q, listAllWikiPages/*works-like:""*/); |
| 2431 | }else{ |
| 2432 | db_prepare(&q, |
| 2433 | "SELECT datetime(e.mtime), substr(t.tagname,7), e.objid" |
| 2434 | " FROM event e, tag t" |
| 2435 | " WHERE e.type='e'" |
| 2436 | " AND e.tagid IS NOT NULL" |
| 2437 | " AND t.tagid=e.tagid" |
| 2438 | " ORDER BY e.mtime DESC /*sort*/" |
| 2439 |
+5
| --- www/changes.wiki | ||
| +++ www/changes.wiki | ||
| @@ -45,10 +45,15 @@ | ||
| 45 | 45 | markdown features, instead of the prior small subset of markup it |
| 46 | 46 | previously supported. This retroactively applies to all chat messages, |
| 47 | 47 | as they are markdown-processed when they are sent instead of when they |
| 48 | 48 | are saved. Added a preview mode so messages can be previewed before |
| 49 | 49 | being sent. See [./chat.md#usage|the chat docs] for more details. |
| 50 | + * The hotkey to activate preview mode in [/help?cmd=/wikiedit|/wikiedit], | |
| 51 | + [/help?cmd=/fileedit|/fileedit], and [/help?cmd=/pikchrshow|/pikchrshow] | |
| 52 | + was changed from ctrl-enter to shift-enter in order to align with | |
| 53 | + [/help?cmd=/chat|/chat]'s new preview feature and related future | |
| 54 | + changes. | |
| 50 | 55 | |
| 51 | 56 | <h2 id='v2_16'>Changes for Version 2.16 (2021-07-02)</h2> |
| 52 | 57 | * <b>Security:</b> Fix the client-side TLS so that it verifies that the |
| 53 | 58 | server hostname matches its certificate. |
| 54 | 59 | * The default "ssh" command on Windows is changed to "ssh" instead of the |
| 55 | 60 |
| --- www/changes.wiki | |
| +++ www/changes.wiki | |
| @@ -45,10 +45,15 @@ | |
| 45 | markdown features, instead of the prior small subset of markup it |
| 46 | previously supported. This retroactively applies to all chat messages, |
| 47 | as they are markdown-processed when they are sent instead of when they |
| 48 | are saved. Added a preview mode so messages can be previewed before |
| 49 | being sent. See [./chat.md#usage|the chat docs] for more details. |
| 50 | |
| 51 | <h2 id='v2_16'>Changes for Version 2.16 (2021-07-02)</h2> |
| 52 | * <b>Security:</b> Fix the client-side TLS so that it verifies that the |
| 53 | server hostname matches its certificate. |
| 54 | * The default "ssh" command on Windows is changed to "ssh" instead of the |
| 55 |
| --- www/changes.wiki | |
| +++ www/changes.wiki | |
| @@ -45,10 +45,15 @@ | |
| 45 | markdown features, instead of the prior small subset of markup it |
| 46 | previously supported. This retroactively applies to all chat messages, |
| 47 | as they are markdown-processed when they are sent instead of when they |
| 48 | are saved. Added a preview mode so messages can be previewed before |
| 49 | being sent. See [./chat.md#usage|the chat docs] for more details. |
| 50 | * The hotkey to activate preview mode in [/help?cmd=/wikiedit|/wikiedit], |
| 51 | [/help?cmd=/fileedit|/fileedit], and [/help?cmd=/pikchrshow|/pikchrshow] |
| 52 | was changed from ctrl-enter to shift-enter in order to align with |
| 53 | [/help?cmd=/chat|/chat]'s new preview feature and related future |
| 54 | changes. |
| 55 | |
| 56 | <h2 id='v2_16'>Changes for Version 2.16 (2021-07-02)</h2> |
| 57 | * <b>Security:</b> Fix the client-side TLS so that it verifies that the |
| 58 | server hostname matches its certificate. |
| 59 | * The default "ssh" command on Windows is changed to "ssh" instead of the |
| 60 |