Fossil SCM

Remove dead captcha-rendering code from the forum editor. Minor internal cleanups.

stephan 2026-06-13 12:35 UTC forum-editor-2026
Commit 0313a31ed14d6c856057bec2e484cef4189dbc5bbf1b723dec34686f38d7b74a
1 file changed +16 -32
--- src/fossil.page.forumpost.js
+++ src/fossil.page.forumpost.js
@@ -193,25 +193,10 @@
193193
e.error = D.addClass(D.div(), 'error', 'hidden');
194194
wrapper.append(e.error);
195195
e.error.addEventListener('dblclick',()=>this.reportError());
196196
}
197197
198
- if( opt.captcha ){
199
- const eCap = opt.captcha;
200
- const w = D.div();
201
- w.style.display = 'flex';
202
- w.style.flexDirection = 'row';
203
- w.style.gap = '1em';
204
- eCap.style.fontFamily = 'monospace';
205
- eCap.style.whiteSpace = 'pre';
206
- eCap.style.fontSize = '50%';
207
- e.captcha = D.attr(D.input('text'), 'size', 8);
208
- w.append("Enter captcha value:", e.captcha);
209
- wrapper.append(eCap, w);
210
- eCap.classList.remove('hidden');
211
- }
212
-
213198
const idPrefix = 'FormPostEditor'+(++idCounter)/* TabManager requires IDs */;
214199
{ /* Main tabs... */
215200
e.tabs = D.attr(
216201
D.addClass(D.div(), 'tab-container'),
217202
'id', idPrefix+'-tabs'
@@ -575,13 +560,10 @@
575560
}else if( (v = (this.#e.title?.value?.trim?.() || this.#opt.edit?.H)) ){
576561
fd.append('title', v);
577562
}
578563
fd.append('mimetype', this.mimetype);
579564
fd.append('content', addThisContent || this.editorContent.trim());
580
- if( this.#e.captcha ){
581
- fd.append('captcha', this.#e.captcha.value);
582
- }
583565
return fd;
584566
}
585567
586568
async #fetchPreview(content){
587569
/* TODO: fetch preview */
@@ -670,14 +652,10 @@
670652
D.enable(this.#toDisable);
671653
});
672654
}
673655
674656
#validate(tgt){
675
- if( this.#e.captcha && 8!==this.#e.captcha.value.length ){
676
- this.reportError("Enter the captcha value.");
677
- return;
678
- }
679657
if( this.#e.title ){
680658
const v = this.#e.title.value.trim();
681659
if( !v ){
682660
this.reportError("A non-empty title is required.");
683661
return;
@@ -793,11 +771,11 @@
793771
static purgeOldDrafts(key, days=10){
794772
const age = (3600 * 24 * days) * 1000/*ms*/;
795773
const now = Date.now();
796774
const check = (k)=>{
797775
const o = F.storage.getJSON(k);
798
- if( o && (!days || (o.mtime+age < now)) ){
776
+ if( o && o.mtime && (!days || (o.mtime+age <= now)) ){
799777
F.storage.remove(k);
800778
}
801779
};
802780
if( key instanceof RegExp ){
803781
for(const k of F.storage.keys(false).filter(v=>key.test(v))){
@@ -1002,23 +980,24 @@
1002980
});
1003981
});
1004982
});
1005983
}
1006984
1007
- /* Page-specific style tweaks for a ForumPostEditor instance. */
1008
- const initFPEWidget = (ePost, fpe)=>{
985
+ /* Apply page-specific tweaks for ForumPostEditor instance fpe
986
+ then plug it into the UI at the end of ePost. */
987
+ const initFPEWidget = (fpe, ePost)=>{
1009988
const w = fpe.widget;
1010989
fpe.eUnhideThenWhenDone = [
1011990
/* List of elements to hide while editing/replying and reveal
1012991
when discarding or saving. */
1013992
];
1014
- ePost.querySelectorAll(
993
+ for( const ee of ePost.querySelectorAll(
1015994
'.forumpost-single-controls, fieldset.forum-status-selection'
1016
- ).forEach(ee=>{
995
+ ) ){
1017996
ee.hidden = true;
1018997
fpe.eUnhideThenWhenDone.push(ee);
1019
- });
998
+ }
1020999
w.classList.add('animate-entrance');
10211000
ePost.append(w);
10221001
requestAnimationFrame(() => {
10231002
w.scrollIntoView({
10241003
behavior: 'smooth',
@@ -1197,11 +1176,11 @@
11971176
}
11981177
},
11991178
inReplyTo: fpid,
12001179
draftKey
12011180
}));
1202
- initFPEWidget(ePost, fpe);
1181
+ initFPEWidget(fpe, ePost);
12031182
}/*replyClicked()*/;
12041183
12051184
/**
12061185
Plug in an editor widget representing an edit to a post.
12071186
form = a (.forum-post-single-controls > form) element. The
@@ -1280,11 +1259,11 @@
12801259
draftKey,
12811260
edit: artifact,
12821261
status: eStatusSelect?.value,
12831262
inReplyTo: firt
12841263
}));
1285
- initFPEWidget(ePost, fpe);
1264
+ initFPEWidget(fpe, ePost);
12861265
})
12871266
.catch(err=>{
12881267
if( releaseLock ){
12891268
releaseLock();
12901269
releaseLock = null;
@@ -1355,19 +1334,24 @@
13551334
clients. */
13561335
e.classList.remove('initially-hidden');
13571336
});
13581337
13591338
if( plugInEditor ){
1360
- document.body.querySelectorAll('.remove-if-replaced').forEach(e=>e.remove());
1339
+ document.body.querySelectorAll('.remove-if-replaced').forEach(
1340
+ /* Remove remaining legacy UI elements. */ e=>e.remove()
1341
+ );
13611342
/* Purge old drafts only every now and then. */
13621343
const now = Date.now();
13631344
const lastPurge = +F.storage.get('forum-drafts-last-purge', 0);
13641345
if( now - lastPurge > (24 * 60 * 60 * 1000 /*1 day ms*/) ){
13651346
F.storage.set('forum-drafts-last-purge', now);
13661347
setTimeout(()=>{
13671348
/* Don't block the UI while we're doing I/O */
1368
- F.ForumPostEditor.purgeOldDrafts(/^draft-(reply|forumedit)-.*/);
1349
+ F.ForumPostEditor.purgeOldDrafts(
1350
+ /^draft-(reply|forumedit)-.*/
1351
+ /* Intentionally leaving draft-forumnew in place. */
1352
+ );
13691353
}, 50);
13701354
}
13711355
}
13721356
})/*F.onPageLoad callback*/;
13731357
})(window.fossil);
13741358
--- src/fossil.page.forumpost.js
+++ src/fossil.page.forumpost.js
@@ -193,25 +193,10 @@
193 e.error = D.addClass(D.div(), 'error', 'hidden');
194 wrapper.append(e.error);
195 e.error.addEventListener('dblclick',()=>this.reportError());
196 }
197
198 if( opt.captcha ){
199 const eCap = opt.captcha;
200 const w = D.div();
201 w.style.display = 'flex';
202 w.style.flexDirection = 'row';
203 w.style.gap = '1em';
204 eCap.style.fontFamily = 'monospace';
205 eCap.style.whiteSpace = 'pre';
206 eCap.style.fontSize = '50%';
207 e.captcha = D.attr(D.input('text'), 'size', 8);
208 w.append("Enter captcha value:", e.captcha);
209 wrapper.append(eCap, w);
210 eCap.classList.remove('hidden');
211 }
212
213 const idPrefix = 'FormPostEditor'+(++idCounter)/* TabManager requires IDs */;
214 { /* Main tabs... */
215 e.tabs = D.attr(
216 D.addClass(D.div(), 'tab-container'),
217 'id', idPrefix+'-tabs'
@@ -575,13 +560,10 @@
575 }else if( (v = (this.#e.title?.value?.trim?.() || this.#opt.edit?.H)) ){
576 fd.append('title', v);
577 }
578 fd.append('mimetype', this.mimetype);
579 fd.append('content', addThisContent || this.editorContent.trim());
580 if( this.#e.captcha ){
581 fd.append('captcha', this.#e.captcha.value);
582 }
583 return fd;
584 }
585
586 async #fetchPreview(content){
587 /* TODO: fetch preview */
@@ -670,14 +652,10 @@
670 D.enable(this.#toDisable);
671 });
672 }
673
674 #validate(tgt){
675 if( this.#e.captcha && 8!==this.#e.captcha.value.length ){
676 this.reportError("Enter the captcha value.");
677 return;
678 }
679 if( this.#e.title ){
680 const v = this.#e.title.value.trim();
681 if( !v ){
682 this.reportError("A non-empty title is required.");
683 return;
@@ -793,11 +771,11 @@
793 static purgeOldDrafts(key, days=10){
794 const age = (3600 * 24 * days) * 1000/*ms*/;
795 const now = Date.now();
796 const check = (k)=>{
797 const o = F.storage.getJSON(k);
798 if( o && (!days || (o.mtime+age < now)) ){
799 F.storage.remove(k);
800 }
801 };
802 if( key instanceof RegExp ){
803 for(const k of F.storage.keys(false).filter(v=>key.test(v))){
@@ -1002,23 +980,24 @@
1002 });
1003 });
1004 });
1005 }
1006
1007 /* Page-specific style tweaks for a ForumPostEditor instance. */
1008 const initFPEWidget = (ePost, fpe)=>{
 
1009 const w = fpe.widget;
1010 fpe.eUnhideThenWhenDone = [
1011 /* List of elements to hide while editing/replying and reveal
1012 when discarding or saving. */
1013 ];
1014 ePost.querySelectorAll(
1015 '.forumpost-single-controls, fieldset.forum-status-selection'
1016 ).forEach(ee=>{
1017 ee.hidden = true;
1018 fpe.eUnhideThenWhenDone.push(ee);
1019 });
1020 w.classList.add('animate-entrance');
1021 ePost.append(w);
1022 requestAnimationFrame(() => {
1023 w.scrollIntoView({
1024 behavior: 'smooth',
@@ -1197,11 +1176,11 @@
1197 }
1198 },
1199 inReplyTo: fpid,
1200 draftKey
1201 }));
1202 initFPEWidget(ePost, fpe);
1203 }/*replyClicked()*/;
1204
1205 /**
1206 Plug in an editor widget representing an edit to a post.
1207 form = a (.forum-post-single-controls > form) element. The
@@ -1280,11 +1259,11 @@
1280 draftKey,
1281 edit: artifact,
1282 status: eStatusSelect?.value,
1283 inReplyTo: firt
1284 }));
1285 initFPEWidget(ePost, fpe);
1286 })
1287 .catch(err=>{
1288 if( releaseLock ){
1289 releaseLock();
1290 releaseLock = null;
@@ -1355,19 +1334,24 @@
1355 clients. */
1356 e.classList.remove('initially-hidden');
1357 });
1358
1359 if( plugInEditor ){
1360 document.body.querySelectorAll('.remove-if-replaced').forEach(e=>e.remove());
 
 
1361 /* Purge old drafts only every now and then. */
1362 const now = Date.now();
1363 const lastPurge = +F.storage.get('forum-drafts-last-purge', 0);
1364 if( now - lastPurge > (24 * 60 * 60 * 1000 /*1 day ms*/) ){
1365 F.storage.set('forum-drafts-last-purge', now);
1366 setTimeout(()=>{
1367 /* Don't block the UI while we're doing I/O */
1368 F.ForumPostEditor.purgeOldDrafts(/^draft-(reply|forumedit)-.*/);
 
 
 
1369 }, 50);
1370 }
1371 }
1372 })/*F.onPageLoad callback*/;
1373 })(window.fossil);
1374
--- src/fossil.page.forumpost.js
+++ src/fossil.page.forumpost.js
@@ -193,25 +193,10 @@
193 e.error = D.addClass(D.div(), 'error', 'hidden');
194 wrapper.append(e.error);
195 e.error.addEventListener('dblclick',()=>this.reportError());
196 }
197
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198 const idPrefix = 'FormPostEditor'+(++idCounter)/* TabManager requires IDs */;
199 { /* Main tabs... */
200 e.tabs = D.attr(
201 D.addClass(D.div(), 'tab-container'),
202 'id', idPrefix+'-tabs'
@@ -575,13 +560,10 @@
560 }else if( (v = (this.#e.title?.value?.trim?.() || this.#opt.edit?.H)) ){
561 fd.append('title', v);
562 }
563 fd.append('mimetype', this.mimetype);
564 fd.append('content', addThisContent || this.editorContent.trim());
 
 
 
565 return fd;
566 }
567
568 async #fetchPreview(content){
569 /* TODO: fetch preview */
@@ -670,14 +652,10 @@
652 D.enable(this.#toDisable);
653 });
654 }
655
656 #validate(tgt){
 
 
 
 
657 if( this.#e.title ){
658 const v = this.#e.title.value.trim();
659 if( !v ){
660 this.reportError("A non-empty title is required.");
661 return;
@@ -793,11 +771,11 @@
771 static purgeOldDrafts(key, days=10){
772 const age = (3600 * 24 * days) * 1000/*ms*/;
773 const now = Date.now();
774 const check = (k)=>{
775 const o = F.storage.getJSON(k);
776 if( o && o.mtime && (!days || (o.mtime+age <= now)) ){
777 F.storage.remove(k);
778 }
779 };
780 if( key instanceof RegExp ){
781 for(const k of F.storage.keys(false).filter(v=>key.test(v))){
@@ -1002,23 +980,24 @@
980 });
981 });
982 });
983 }
984
985 /* Apply page-specific tweaks for ForumPostEditor instance fpe
986 then plug it into the UI at the end of ePost. */
987 const initFPEWidget = (fpe, ePost)=>{
988 const w = fpe.widget;
989 fpe.eUnhideThenWhenDone = [
990 /* List of elements to hide while editing/replying and reveal
991 when discarding or saving. */
992 ];
993 for( const ee of ePost.querySelectorAll(
994 '.forumpost-single-controls, fieldset.forum-status-selection'
995 ) ){
996 ee.hidden = true;
997 fpe.eUnhideThenWhenDone.push(ee);
998 }
999 w.classList.add('animate-entrance');
1000 ePost.append(w);
1001 requestAnimationFrame(() => {
1002 w.scrollIntoView({
1003 behavior: 'smooth',
@@ -1197,11 +1176,11 @@
1176 }
1177 },
1178 inReplyTo: fpid,
1179 draftKey
1180 }));
1181 initFPEWidget(fpe, ePost);
1182 }/*replyClicked()*/;
1183
1184 /**
1185 Plug in an editor widget representing an edit to a post.
1186 form = a (.forum-post-single-controls > form) element. The
@@ -1280,11 +1259,11 @@
1259 draftKey,
1260 edit: artifact,
1261 status: eStatusSelect?.value,
1262 inReplyTo: firt
1263 }));
1264 initFPEWidget(fpe, ePost);
1265 })
1266 .catch(err=>{
1267 if( releaseLock ){
1268 releaseLock();
1269 releaseLock = null;
@@ -1355,19 +1334,24 @@
1334 clients. */
1335 e.classList.remove('initially-hidden');
1336 });
1337
1338 if( plugInEditor ){
1339 document.body.querySelectorAll('.remove-if-replaced').forEach(
1340 /* Remove remaining legacy UI elements. */ e=>e.remove()
1341 );
1342 /* Purge old drafts only every now and then. */
1343 const now = Date.now();
1344 const lastPurge = +F.storage.get('forum-drafts-last-purge', 0);
1345 if( now - lastPurge > (24 * 60 * 60 * 1000 /*1 day ms*/) ){
1346 F.storage.set('forum-drafts-last-purge', now);
1347 setTimeout(()=>{
1348 /* Don't block the UI while we're doing I/O */
1349 F.ForumPostEditor.purgeOldDrafts(
1350 /^draft-(reply|forumedit)-.*/
1351 /* Intentionally leaving draft-forumnew in place. */
1352 );
1353 }, 50);
1354 }
1355 }
1356 })/*F.onPageLoad callback*/;
1357 })(window.fossil);
1358

Keyboard Shortcuts

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