Fossil SCM

Re-enable the forum post status selection in the editor since the previous check-in made it safe to use, in that changing only the status from the editor will no longer create a new copy of an otherwise unedited post.

stephan 2026-06-09 19:59 UTC forum-editor-2026
Commit 0f539c6c29f090dabc2f8a1717a66eeae710be93c4c13b1a6a4005433b2c32ac
1 file changed +17 -24
--- src/fossil.page.forumpost.js
+++ src/fossil.page.forumpost.js
@@ -37,11 +37,12 @@
3737
Options:
3838
3939
opt.draftKey[string=undefined]: if set then this object's state
4040
will be stored in fossil.storage when the relevant input fields
4141
lose focus. If old state is found, the form is pre-populated
42
- from it. The state is cleared on a successful submit.
42
+ from it. The state is cleared on a discard() or successful
43
+ submit.
4344
4445
opt.ondiscard[=function]: if set, a Discard button is added
4546
which, when activated, clears the current draft and removes
4647
this object's widget from the DOM. After doing so,
4748
opt.ondiscard() is called and passed no arguments. Exceptions
@@ -48,14 +49,12 @@
4849
thrown by ondiscard() are ignored but may be logged.
4950
5051
opt.onsubmit[=function]: if set, this function is called
5152
immediately after the post has been successfully saved, and
5253
passed this object and a JSON-format response object from the
53
- save request. On a successful edit, if the artifact was
54
- actually modified then submission will redirect the page to
55
- /forumpost/THE_POST_ID. Exceptions thrown by onsubmit()
56
- are ignored but may be logged.
54
+ save request. It is generally then up to the caller to close()
55
+ this object and/or redirect to /forumpost/${arguments[1].uuid}.
5756
5857
opt.hiddenFields: an optional list of input elements to
5958
incorporate into the form for requests which request the
6059
preview or save the post.
6160
@@ -257,24 +256,13 @@
257256
}
258257
this.#tabs.addTab(e.debug);
259258
}
260259
e.buttons.append(e.mimetype.wrapper);
261260
262
- if( 0 /* 2026-06-09: disabling the status selection to keep
263
- people from using the editor to change just that,
264
- because doing so leaves us in a staet where we know
265
- whether or not a Submit modifies the post, but not
266
- whether or not out-of-band state like the status and
267
- attachments were modified. */
268
- && opt.edit
261
+ if( opt.edit
269262
&& !opt.inReplyTo
270263
&& F.config.forumStatuses?.length>0 ){
271
- /* Status selection. We probably don't _really_ want this in
272
- the editor because people will open the editor, change the
273
- status, and tap submit, resulting in a whole new, unedited
274
- copy of the post, differing only in the new 'status' tag
275
- added to it. */
276264
const sel = e.status = D.select();
277265
D.option(sel, "", "- Status -").disabled = true;
278266
for( const status of F.config.forumStatuses ){
279267
D.option(sel, status.value, status.label);
280268
}
@@ -696,11 +684,11 @@
696684
reload to render those changes (if any). The other option
697685
is to tell the user "nothing changed" and leave them in
698686
the editor, but that could be a lie because we don't know
699687
if any attachments or tags were changed.
700688
*/
701
- if( 0 ){
689
+ else if( 0 ){
702690
if( this.#opt.edit.uuid === j.uuid
703691
&& !j.statusModified && 0===j.attachedCount ){
704692
this.reportError("No changes made.");
705693
}else{
706694
window.location = F.repoUrl('forumpost/'+j.uuid);
@@ -971,12 +959,12 @@
971959
draftKey: 'draft-forumnew',
972960
hiddenFields: eForumNew.querySelectorAll('input[type=hidden]'),
973961
ondiscard: ()=>{
974962
window.location = F.repoUrl('forum');
975963
},
976
- onsubmit: (fpe, artifact)=>{
977
- window.location = F.repoUrl('forumpost/'+artifact.uuid);
964
+ onsubmit: (fpe, response)=>{
965
+ window.location = F.repoUrl('forumpost/'+response.uuid);
978966
}
979967
});
980968
eForumNew.parentElement.insertBefore(fpe.widget, eForumNew);
981969
eForumNew.remove();
982970
fossil.page.fpe = fpe /* for testing via the console */;
@@ -1083,11 +1071,11 @@
10831071
hiddenFields: form.querySelectorAll('input[type=hidden]'),
10841072
ondiscard: ondone,
10851073
onsubmit: ondone,
10861074
draftKey: 'draft-forumedit-'+(fEditHead || fpid).substr(0,12),
10871075
edit: artifact,
1088
- //status: eStatusSelect?.value,
1076
+ status: eStatusSelect?.value,
10891077
inReplyTo: firt
10901078
});
10911079
initFPEWidget(ePost, fpe);
10921080
});
10931081
}/*editClicked()*/;
@@ -1094,19 +1082,24 @@
10941082
10951083
document.body.querySelectorAll(
10961084
'.forumpost-single-controls > form'
10971085
).forEach(form=>{
10981086
/* For each forum post... */
1099
- const eToDisable = [];
1100
- const eThePost = form.parentElement.parentElement;
1087
+ const eToDisable = [
1088
+ /* List of non-editor DOM elements which need to be disabled
1089
+ when the editor is active. */
1090
+ ];
1091
+ const eThePost = form.parentElement.parentElement/*main post DOM element*/;
11011092
if( !eThePost?.dataset?.fpid ){
1093
+ /* The server injects these. */
11021094
console.warn("Unexpected missing fpid", eThePost);
11031095
return;
11041096
}
1097
+ /* Replace the Reply and Edit buttons with ones which will activate
1098
+ a ForumPostEditor. */
11051099
const btnReply = form.querySelector('input[type=submit][name=reply]');
11061100
if( btnReply ){
1107
- //console.debug("hacking Reply button", btnReply);
11081101
const b = D.button("Reply", ()=>replyClicked(form, eThePost, b, eToDisable));
11091102
b.type = 'button'/*keep container form from submitting*/;
11101103
eToDisable.push(b);
11111104
btnReply.parentElement.insertBefore(b, btnReply);
11121105
btnReply.remove();
11131106
--- src/fossil.page.forumpost.js
+++ src/fossil.page.forumpost.js
@@ -37,11 +37,12 @@
37 Options:
38
39 opt.draftKey[string=undefined]: if set then this object's state
40 will be stored in fossil.storage when the relevant input fields
41 lose focus. If old state is found, the form is pre-populated
42 from it. The state is cleared on a successful submit.
 
43
44 opt.ondiscard[=function]: if set, a Discard button is added
45 which, when activated, clears the current draft and removes
46 this object's widget from the DOM. After doing so,
47 opt.ondiscard() is called and passed no arguments. Exceptions
@@ -48,14 +49,12 @@
48 thrown by ondiscard() are ignored but may be logged.
49
50 opt.onsubmit[=function]: if set, this function is called
51 immediately after the post has been successfully saved, and
52 passed this object and a JSON-format response object from the
53 save request. On a successful edit, if the artifact was
54 actually modified then submission will redirect the page to
55 /forumpost/THE_POST_ID. Exceptions thrown by onsubmit()
56 are ignored but may be logged.
57
58 opt.hiddenFields: an optional list of input elements to
59 incorporate into the form for requests which request the
60 preview or save the post.
61
@@ -257,24 +256,13 @@
257 }
258 this.#tabs.addTab(e.debug);
259 }
260 e.buttons.append(e.mimetype.wrapper);
261
262 if( 0 /* 2026-06-09: disabling the status selection to keep
263 people from using the editor to change just that,
264 because doing so leaves us in a staet where we know
265 whether or not a Submit modifies the post, but not
266 whether or not out-of-band state like the status and
267 attachments were modified. */
268 && opt.edit
269 && !opt.inReplyTo
270 && F.config.forumStatuses?.length>0 ){
271 /* Status selection. We probably don't _really_ want this in
272 the editor because people will open the editor, change the
273 status, and tap submit, resulting in a whole new, unedited
274 copy of the post, differing only in the new 'status' tag
275 added to it. */
276 const sel = e.status = D.select();
277 D.option(sel, "", "- Status -").disabled = true;
278 for( const status of F.config.forumStatuses ){
279 D.option(sel, status.value, status.label);
280 }
@@ -696,11 +684,11 @@
696 reload to render those changes (if any). The other option
697 is to tell the user "nothing changed" and leave them in
698 the editor, but that could be a lie because we don't know
699 if any attachments or tags were changed.
700 */
701 if( 0 ){
702 if( this.#opt.edit.uuid === j.uuid
703 && !j.statusModified && 0===j.attachedCount ){
704 this.reportError("No changes made.");
705 }else{
706 window.location = F.repoUrl('forumpost/'+j.uuid);
@@ -971,12 +959,12 @@
971 draftKey: 'draft-forumnew',
972 hiddenFields: eForumNew.querySelectorAll('input[type=hidden]'),
973 ondiscard: ()=>{
974 window.location = F.repoUrl('forum');
975 },
976 onsubmit: (fpe, artifact)=>{
977 window.location = F.repoUrl('forumpost/'+artifact.uuid);
978 }
979 });
980 eForumNew.parentElement.insertBefore(fpe.widget, eForumNew);
981 eForumNew.remove();
982 fossil.page.fpe = fpe /* for testing via the console */;
@@ -1083,11 +1071,11 @@
1083 hiddenFields: form.querySelectorAll('input[type=hidden]'),
1084 ondiscard: ondone,
1085 onsubmit: ondone,
1086 draftKey: 'draft-forumedit-'+(fEditHead || fpid).substr(0,12),
1087 edit: artifact,
1088 //status: eStatusSelect?.value,
1089 inReplyTo: firt
1090 });
1091 initFPEWidget(ePost, fpe);
1092 });
1093 }/*editClicked()*/;
@@ -1094,19 +1082,24 @@
1094
1095 document.body.querySelectorAll(
1096 '.forumpost-single-controls > form'
1097 ).forEach(form=>{
1098 /* For each forum post... */
1099 const eToDisable = [];
1100 const eThePost = form.parentElement.parentElement;
 
 
 
1101 if( !eThePost?.dataset?.fpid ){
 
1102 console.warn("Unexpected missing fpid", eThePost);
1103 return;
1104 }
 
 
1105 const btnReply = form.querySelector('input[type=submit][name=reply]');
1106 if( btnReply ){
1107 //console.debug("hacking Reply button", btnReply);
1108 const b = D.button("Reply", ()=>replyClicked(form, eThePost, b, eToDisable));
1109 b.type = 'button'/*keep container form from submitting*/;
1110 eToDisable.push(b);
1111 btnReply.parentElement.insertBefore(b, btnReply);
1112 btnReply.remove();
1113
--- src/fossil.page.forumpost.js
+++ src/fossil.page.forumpost.js
@@ -37,11 +37,12 @@
37 Options:
38
39 opt.draftKey[string=undefined]: if set then this object's state
40 will be stored in fossil.storage when the relevant input fields
41 lose focus. If old state is found, the form is pre-populated
42 from it. The state is cleared on a discard() or successful
43 submit.
44
45 opt.ondiscard[=function]: if set, a Discard button is added
46 which, when activated, clears the current draft and removes
47 this object's widget from the DOM. After doing so,
48 opt.ondiscard() is called and passed no arguments. Exceptions
@@ -48,14 +49,12 @@
49 thrown by ondiscard() are ignored but may be logged.
50
51 opt.onsubmit[=function]: if set, this function is called
52 immediately after the post has been successfully saved, and
53 passed this object and a JSON-format response object from the
54 save request. It is generally then up to the caller to close()
55 this object and/or redirect to /forumpost/${arguments[1].uuid}.
 
 
56
57 opt.hiddenFields: an optional list of input elements to
58 incorporate into the form for requests which request the
59 preview or save the post.
60
@@ -257,24 +256,13 @@
256 }
257 this.#tabs.addTab(e.debug);
258 }
259 e.buttons.append(e.mimetype.wrapper);
260
261 if( opt.edit
 
 
 
 
 
 
262 && !opt.inReplyTo
263 && F.config.forumStatuses?.length>0 ){
 
 
 
 
 
264 const sel = e.status = D.select();
265 D.option(sel, "", "- Status -").disabled = true;
266 for( const status of F.config.forumStatuses ){
267 D.option(sel, status.value, status.label);
268 }
@@ -696,11 +684,11 @@
684 reload to render those changes (if any). The other option
685 is to tell the user "nothing changed" and leave them in
686 the editor, but that could be a lie because we don't know
687 if any attachments or tags were changed.
688 */
689 else if( 0 ){
690 if( this.#opt.edit.uuid === j.uuid
691 && !j.statusModified && 0===j.attachedCount ){
692 this.reportError("No changes made.");
693 }else{
694 window.location = F.repoUrl('forumpost/'+j.uuid);
@@ -971,12 +959,12 @@
959 draftKey: 'draft-forumnew',
960 hiddenFields: eForumNew.querySelectorAll('input[type=hidden]'),
961 ondiscard: ()=>{
962 window.location = F.repoUrl('forum');
963 },
964 onsubmit: (fpe, response)=>{
965 window.location = F.repoUrl('forumpost/'+response.uuid);
966 }
967 });
968 eForumNew.parentElement.insertBefore(fpe.widget, eForumNew);
969 eForumNew.remove();
970 fossil.page.fpe = fpe /* for testing via the console */;
@@ -1083,11 +1071,11 @@
1071 hiddenFields: form.querySelectorAll('input[type=hidden]'),
1072 ondiscard: ondone,
1073 onsubmit: ondone,
1074 draftKey: 'draft-forumedit-'+(fEditHead || fpid).substr(0,12),
1075 edit: artifact,
1076 status: eStatusSelect?.value,
1077 inReplyTo: firt
1078 });
1079 initFPEWidget(ePost, fpe);
1080 });
1081 }/*editClicked()*/;
@@ -1094,19 +1082,24 @@
1082
1083 document.body.querySelectorAll(
1084 '.forumpost-single-controls > form'
1085 ).forEach(form=>{
1086 /* For each forum post... */
1087 const eToDisable = [
1088 /* List of non-editor DOM elements which need to be disabled
1089 when the editor is active. */
1090 ];
1091 const eThePost = form.parentElement.parentElement/*main post DOM element*/;
1092 if( !eThePost?.dataset?.fpid ){
1093 /* The server injects these. */
1094 console.warn("Unexpected missing fpid", eThePost);
1095 return;
1096 }
1097 /* Replace the Reply and Edit buttons with ones which will activate
1098 a ForumPostEditor. */
1099 const btnReply = form.querySelector('input[type=submit][name=reply]');
1100 if( btnReply ){
 
1101 const b = D.button("Reply", ()=>replyClicked(form, eThePost, b, eToDisable));
1102 b.type = 'button'/*keep container form from submitting*/;
1103 eToDisable.push(b);
1104 btnReply.parentElement.insertBefore(b, btnReply);
1105 btnReply.remove();
1106

Keyboard Shortcuts

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