Fossil SCM

Add shift-enter-toggles-preview option, as in /chat, /wikiedit, and /fileedit. This is generally useful but some software keyboards misinteract with it.

stephan 2026-06-06 15:17 UTC forum-editor-2026
Commit 806ab64561c6872dbe0bbc6d02f25124da44be9502ebfe31072094a0468fb642
+2 -1
--- src/forum.c
+++ src/forum.c
@@ -1483,11 +1483,12 @@
14831483
** to all forum-related pages. It does not include page-specific
14841484
** code (e.g. "forum.js").
14851485
*/
14861486
static void forum_emit_js(void){
14871487
builtin_fossil_js_bundle_or("copybutton", "pikchr", "confirmer",
1488
- "attach", "tabs", "storage", NULL);
1488
+ "attach", "tabs", "storage",
1489
+ "popupwidget", NULL);
14891490
builtin_request_js("fossil.page.forumpost.js");
14901491
}
14911492
14921493
/*
14931494
** WEBPAGE: forumpost
14941495
--- src/forum.c
+++ src/forum.c
@@ -1483,11 +1483,12 @@
1483 ** to all forum-related pages. It does not include page-specific
1484 ** code (e.g. "forum.js").
1485 */
1486 static void forum_emit_js(void){
1487 builtin_fossil_js_bundle_or("copybutton", "pikchr", "confirmer",
1488 "attach", "tabs", "storage", NULL);
 
1489 builtin_request_js("fossil.page.forumpost.js");
1490 }
1491
1492 /*
1493 ** WEBPAGE: forumpost
1494
--- src/forum.c
+++ src/forum.c
@@ -1483,11 +1483,12 @@
1483 ** to all forum-related pages. It does not include page-specific
1484 ** code (e.g. "forum.js").
1485 */
1486 static void forum_emit_js(void){
1487 builtin_fossil_js_bundle_or("copybutton", "pikchr", "confirmer",
1488 "attach", "tabs", "storage",
1489 "popupwidget", NULL);
1490 builtin_request_js("fossil.page.forumpost.js");
1491 }
1492
1493 /*
1494 ** WEBPAGE: forumpost
1495
--- src/fossil.page.forumpost.js
+++ src/fossil.page.forumpost.js
@@ -180,10 +180,62 @@
180180
181181
if( opt.hiddenFields ){
182182
this.addHiddenFields( opt.hiddenFields );
183183
delete opt.hiddenFields;
184184
}
185
+
186
+ { /* Shift-enter pieces... */
187
+ const eCb = D.checkbox(1);
188
+ const eLbl = D.label();
189
+ const eHelp = D.append(
190
+ D.addClass(D.span(), "help-buttonlet"), [
191
+ 'When checked, shift-enter will toggle between preview ',
192
+ 'and edit modes. This is generally useful but some ',
193
+ 'software keyboards misinteract with it. If the preview ',
194
+ 'starts when you tap Enter, turn this setting off.'
195
+ ].join('')
196
+ );
197
+ eCb.checked = F.storage.getBool('edit-shift-enter-preview', true);
198
+ eCb.addEventListener('change', (ev)=>{
199
+ F.storage.set('edit-shift-enter-preview', eCb.checked);
200
+ });
201
+ F.helpButtonlets.setup(eHelp);
202
+ eLbl.append("Shift-enter toggles preview?", eCb, eHelp);
203
+ e.buttons.append(eLbl);
204
+ const isShiftEnter = (ev)=>eCb.checked && ev.shiftKey && 13===ev.keyCode;
205
+ e.editor.addEventListener('keydown',(ev)=>{
206
+ /**
207
+ If eCb.checked is true, a keyboard combo of shift-enter
208
+ (from the editor) toggles between preview and edit modes.
209
+ This is normally desired but at least one software
210
+ keyboard is known to misinteract with this, treating an
211
+ Enter after automatically-capitalized letters as a
212
+ shift-enter:
213
+
214
+ https://fossil-scm.org/forum/forumpost/dbd5b68366147ce8
215
+ */
216
+ if(!isShiftEnter(ev)) return;
217
+ ev.preventDefault();
218
+ ev.stopPropagation();
219
+ e.editor.blur(/*force change event, if needed*/);
220
+ this.#tabs.switchToTab(e.preview);
221
+ this.#preview();
222
+ }, false);
223
+ // If we're in the preview tab, have ctrl-enter switch back to the editor.
224
+ document.body.addEventListener('keydown',(ev)=>{
225
+ if(!isShiftEnter(ev)) return;
226
+ console.warn("this.#activeTab =",this.#activeTab);
227
+ if(this.#activeTab !== e.tabEdit){
228
+ ev.preventDefault();
229
+ ev.stopPropagation();
230
+ this.#tabs.switchToTab(e.tabEdit);
231
+ e.editor.focus(/*slow as molasses for long docs, as focus()
232
+ forces a document reflow. */);
233
+ return false;
234
+ }
235
+ }, true);
236
+ }/*shift-enter preview bits*/
185237
186238
}/*constructor*/
187239
188240
/** This widget's top-most DOM element. */
189241
get widget(){
190242
--- src/fossil.page.forumpost.js
+++ src/fossil.page.forumpost.js
@@ -180,10 +180,62 @@
180
181 if( opt.hiddenFields ){
182 this.addHiddenFields( opt.hiddenFields );
183 delete opt.hiddenFields;
184 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
186 }/*constructor*/
187
188 /** This widget's top-most DOM element. */
189 get widget(){
190
--- src/fossil.page.forumpost.js
+++ src/fossil.page.forumpost.js
@@ -180,10 +180,62 @@
180
181 if( opt.hiddenFields ){
182 this.addHiddenFields( opt.hiddenFields );
183 delete opt.hiddenFields;
184 }
185
186 { /* Shift-enter pieces... */
187 const eCb = D.checkbox(1);
188 const eLbl = D.label();
189 const eHelp = D.append(
190 D.addClass(D.span(), "help-buttonlet"), [
191 'When checked, shift-enter will toggle between preview ',
192 'and edit modes. This is generally useful but some ',
193 'software keyboards misinteract with it. If the preview ',
194 'starts when you tap Enter, turn this setting off.'
195 ].join('')
196 );
197 eCb.checked = F.storage.getBool('edit-shift-enter-preview', true);
198 eCb.addEventListener('change', (ev)=>{
199 F.storage.set('edit-shift-enter-preview', eCb.checked);
200 });
201 F.helpButtonlets.setup(eHelp);
202 eLbl.append("Shift-enter toggles preview?", eCb, eHelp);
203 e.buttons.append(eLbl);
204 const isShiftEnter = (ev)=>eCb.checked && ev.shiftKey && 13===ev.keyCode;
205 e.editor.addEventListener('keydown',(ev)=>{
206 /**
207 If eCb.checked is true, a keyboard combo of shift-enter
208 (from the editor) toggles between preview and edit modes.
209 This is normally desired but at least one software
210 keyboard is known to misinteract with this, treating an
211 Enter after automatically-capitalized letters as a
212 shift-enter:
213
214 https://fossil-scm.org/forum/forumpost/dbd5b68366147ce8
215 */
216 if(!isShiftEnter(ev)) return;
217 ev.preventDefault();
218 ev.stopPropagation();
219 e.editor.blur(/*force change event, if needed*/);
220 this.#tabs.switchToTab(e.preview);
221 this.#preview();
222 }, false);
223 // If we're in the preview tab, have ctrl-enter switch back to the editor.
224 document.body.addEventListener('keydown',(ev)=>{
225 if(!isShiftEnter(ev)) return;
226 console.warn("this.#activeTab =",this.#activeTab);
227 if(this.#activeTab !== e.tabEdit){
228 ev.preventDefault();
229 ev.stopPropagation();
230 this.#tabs.switchToTab(e.tabEdit);
231 e.editor.focus(/*slow as molasses for long docs, as focus()
232 forces a document reflow. */);
233 return false;
234 }
235 }, true);
236 }/*shift-enter preview bits*/
237
238 }/*constructor*/
239
240 /** This widget's top-most DOM element. */
241 get widget(){
242
--- src/style.forum.css
+++ src/style.forum.css
@@ -57,9 +57,21 @@
5757
max-width: initial;
5858
color: initial;
5959
}
6060
6161
.ForumPostEditor > .buttons {
62
+ font-size: 90%;
6263
display: flex;
6364
flex-direction: row;
6465
gap: 0.75em;
66
+ flex-wrap: wrap;
67
+}
68
+.ForumPostEditor > .buttons > label {
69
+ white-space: nowrap;
70
+ display: flex;
71
+ flex-direction: row;
72
+ align-items: last baseline;
73
+ cursor: pointer;
74
+}
75
+.ForumPostEditor > .buttons > label > input[type=checkbox]{
76
+ cursor: pointer;
6577
}
6678
--- src/style.forum.css
+++ src/style.forum.css
@@ -57,9 +57,21 @@
57 max-width: initial;
58 color: initial;
59 }
60
61 .ForumPostEditor > .buttons {
 
62 display: flex;
63 flex-direction: row;
64 gap: 0.75em;
 
 
 
 
 
 
 
 
 
 
 
65 }
66
--- src/style.forum.css
+++ src/style.forum.css
@@ -57,9 +57,21 @@
57 max-width: initial;
58 color: initial;
59 }
60
61 .ForumPostEditor > .buttons {
62 font-size: 90%;
63 display: flex;
64 flex-direction: row;
65 gap: 0.75em;
66 flex-wrap: wrap;
67 }
68 .ForumPostEditor > .buttons > label {
69 white-space: nowrap;
70 display: flex;
71 flex-direction: row;
72 align-items: last baseline;
73 cursor: pointer;
74 }
75 .ForumPostEditor > .buttons > label > input[type=checkbox]{
76 cursor: pointer;
77 }
78

Keyboard Shortcuts

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