Fossil SCM

Teach the JS-generated /forumnew editor widget to honor the new forum-max-title setting. It does not alert the user to the limit or warn if the limit is reached but it arguably should. Split the JS forum-specific window.fossil.config pieces into their own config.forum property.

stephan 2026-10-23 14:15 UTC trunk
Commit a6b17d2a7e68cc18022dac97a88b477038fe9ada17f592f61aeb8160b0cf6b31
+5 -2
--- src/builtin.c
+++ src/builtin.c
@@ -679,21 +679,24 @@
679679
CX("isDark: %s"
680680
"/*true if the current skin has the 'white-foreground' detail*/",
681681
skin_detail_boolean("white-foreground") ? "true" : "false");
682682
CX("}\n"/*fossil.config.skin*/);
683683
CX("};\n"/* fossil.config */);
684
+ CX("window.fossil.config.forum = {");
684685
if( forum_statuses()->n>1 ){
685686
const ForumStatusList * fsl = forum_statuses();
686687
int i;
687
- CX("window.fossil.config.forumStatuses = [");
688
+ CX("statuses: [");
688689
for(i = 0; i < fsl->n; ++i){
689690
const ForumStatus *fs = &fsl->aStatus[i];
690691
if(i) CX(",");
691692
CX("{label:%!j, value:%!j}", fs->zLabel, fs->zValue);
692693
}
693
- CX("];\n");
694
+ CX("],\n");
694695
}
696
+ CX("maxTitleLength: %d", db_get_int("forum-max-title", 0));
697
+ CX("};\n"/*window.fossil.config.forum*/);
695698
#define JBOOL(COND) ((COND) ? "true" : "false")
696699
CX("window.fossil.user = {");
697700
CX("name: %!j,", (g.zLogin&&*g.zLogin) ? g.zLogin : "guest");
698701
CX("isAdmin: %s,", JBOOL(g.perm.Admin || g.perm.Setup));
699702
CX("mayAttachForum: %s,", JBOOL(g.perm.AttachForum));
700703
--- src/builtin.c
+++ src/builtin.c
@@ -679,21 +679,24 @@
679 CX("isDark: %s"
680 "/*true if the current skin has the 'white-foreground' detail*/",
681 skin_detail_boolean("white-foreground") ? "true" : "false");
682 CX("}\n"/*fossil.config.skin*/);
683 CX("};\n"/* fossil.config */);
 
684 if( forum_statuses()->n>1 ){
685 const ForumStatusList * fsl = forum_statuses();
686 int i;
687 CX("window.fossil.config.forumStatuses = [");
688 for(i = 0; i < fsl->n; ++i){
689 const ForumStatus *fs = &fsl->aStatus[i];
690 if(i) CX(",");
691 CX("{label:%!j, value:%!j}", fs->zLabel, fs->zValue);
692 }
693 CX("];\n");
694 }
 
 
695 #define JBOOL(COND) ((COND) ? "true" : "false")
696 CX("window.fossil.user = {");
697 CX("name: %!j,", (g.zLogin&&*g.zLogin) ? g.zLogin : "guest");
698 CX("isAdmin: %s,", JBOOL(g.perm.Admin || g.perm.Setup));
699 CX("mayAttachForum: %s,", JBOOL(g.perm.AttachForum));
700
--- src/builtin.c
+++ src/builtin.c
@@ -679,21 +679,24 @@
679 CX("isDark: %s"
680 "/*true if the current skin has the 'white-foreground' detail*/",
681 skin_detail_boolean("white-foreground") ? "true" : "false");
682 CX("}\n"/*fossil.config.skin*/);
683 CX("};\n"/* fossil.config */);
684 CX("window.fossil.config.forum = {");
685 if( forum_statuses()->n>1 ){
686 const ForumStatusList * fsl = forum_statuses();
687 int i;
688 CX("statuses: [");
689 for(i = 0; i < fsl->n; ++i){
690 const ForumStatus *fs = &fsl->aStatus[i];
691 if(i) CX(",");
692 CX("{label:%!j, value:%!j}", fs->zLabel, fs->zValue);
693 }
694 CX("],\n");
695 }
696 CX("maxTitleLength: %d", db_get_int("forum-max-title", 0));
697 CX("};\n"/*window.fossil.config.forum*/);
698 #define JBOOL(COND) ((COND) ? "true" : "false")
699 CX("window.fossil.user = {");
700 CX("name: %!j,", (g.zLogin&&*g.zLogin) ? g.zLogin : "guest");
701 CX("isAdmin: %s,", JBOOL(g.perm.Admin || g.perm.Setup));
702 CX("mayAttachForum: %s,", JBOOL(g.perm.AttachForum));
703
--- src/fossil.page.forumpost.js
+++ src/fossil.page.forumpost.js
@@ -119,11 +119,12 @@
119119
e.title = D.attr(
120120
D.addClass(D.input('text'), 'title'),
121121
'placeholder',
122122
'Thread title (required)'
123123
);
124
- e.title.setAttribute('maxlength', 125);
124
+ const maxLen = F.config.forum.maxTitleLength;
125
+ e.title.setAttribute('maxlength', (maxLen>0) ? maxLen : 125);
125126
e.titleBar.append(
126127
D.append(D.span(), "Title:"),
127128
e.title
128129
);
129130
if( this.#draft ){
@@ -310,25 +311,25 @@
310311
}
311312
e.buttons.append(e.mimetype.wrapper);
312313
313314
if( opt.edit
314315
&& !opt.inReplyTo
315
- && F.config.forumStatuses?.length>0 ){
316
+ && F.config.forum?.statuses?.length>0 ){
316317
const sel = e.status = D.select();
317318
sel.setAttribute('title', 'The status tag value for this post.');
318319
D.option(sel, "", "- Status -").disabled = true;
319
- for( const status of F.config.forumStatuses ){
320
+ for( const status of F.config.forum.statuses ){
320321
D.option(sel, status.value, status.label);
321322
}
322323
e.buttons.append(sel);
323324
if( opt.status ){
324325
sel.value = opt.status;
325326
}else if( this.#draft ){
326327
if( this.#draft.status ){
327328
sel.value = this.#draft.status;
328329
}else{
329
- this.#draft.status = sel.value = F.config.forumStatuses[0].value;
330
+ this.#draft.status = sel.value = F.config.forum.statuses[0].value;
330331
}
331332
sel.addEventListener('change',ev=>{
332333
const v = sel.value;
333334
if( this.#draft.status !== v ){
334335
this.#draft.status = v;
335336
--- src/fossil.page.forumpost.js
+++ src/fossil.page.forumpost.js
@@ -119,11 +119,12 @@
119 e.title = D.attr(
120 D.addClass(D.input('text'), 'title'),
121 'placeholder',
122 'Thread title (required)'
123 );
124 e.title.setAttribute('maxlength', 125);
 
125 e.titleBar.append(
126 D.append(D.span(), "Title:"),
127 e.title
128 );
129 if( this.#draft ){
@@ -310,25 +311,25 @@
310 }
311 e.buttons.append(e.mimetype.wrapper);
312
313 if( opt.edit
314 && !opt.inReplyTo
315 && F.config.forumStatuses?.length>0 ){
316 const sel = e.status = D.select();
317 sel.setAttribute('title', 'The status tag value for this post.');
318 D.option(sel, "", "- Status -").disabled = true;
319 for( const status of F.config.forumStatuses ){
320 D.option(sel, status.value, status.label);
321 }
322 e.buttons.append(sel);
323 if( opt.status ){
324 sel.value = opt.status;
325 }else if( this.#draft ){
326 if( this.#draft.status ){
327 sel.value = this.#draft.status;
328 }else{
329 this.#draft.status = sel.value = F.config.forumStatuses[0].value;
330 }
331 sel.addEventListener('change',ev=>{
332 const v = sel.value;
333 if( this.#draft.status !== v ){
334 this.#draft.status = v;
335
--- src/fossil.page.forumpost.js
+++ src/fossil.page.forumpost.js
@@ -119,11 +119,12 @@
119 e.title = D.attr(
120 D.addClass(D.input('text'), 'title'),
121 'placeholder',
122 'Thread title (required)'
123 );
124 const maxLen = F.config.forum.maxTitleLength;
125 e.title.setAttribute('maxlength', (maxLen>0) ? maxLen : 125);
126 e.titleBar.append(
127 D.append(D.span(), "Title:"),
128 e.title
129 );
130 if( this.#draft ){
@@ -310,25 +311,25 @@
311 }
312 e.buttons.append(e.mimetype.wrapper);
313
314 if( opt.edit
315 && !opt.inReplyTo
316 && F.config.forum?.statuses?.length>0 ){
317 const sel = e.status = D.select();
318 sel.setAttribute('title', 'The status tag value for this post.');
319 D.option(sel, "", "- Status -").disabled = true;
320 for( const status of F.config.forum.statuses ){
321 D.option(sel, status.value, status.label);
322 }
323 e.buttons.append(sel);
324 if( opt.status ){
325 sel.value = opt.status;
326 }else if( this.#draft ){
327 if( this.#draft.status ){
328 sel.value = this.#draft.status;
329 }else{
330 this.#draft.status = sel.value = F.config.forum.statuses[0].value;
331 }
332 sel.addEventListener('change',ev=>{
333 const v = sel.value;
334 if( this.#draft.status !== v ){
335 this.#draft.status = v;
336

Keyboard Shortcuts

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