Fossil SCM

Move the attachments into their own tab and add a new option to Attacher to have it reverse its flex-layout direction so that it fits better in this context.

stephan 2026-06-06 12:24 UTC forum-editor-2026
Commit 934e38793e10b1099b3f0896fe94b14bd25b332984ad0a2f9079c73a322272ba
--- src/default.css
+++ src/default.css
@@ -2019,10 +2019,13 @@
20192019
margin-bottom: 1em;
20202020
display: flex;
20212021
flex-direction: column;
20222022
gap: 0.75em;
20232023
}
2024
+.Attacher.reverse {
2025
+ flex-direction: column-reverse;
2026
+}
20242027
.Attacher .attach-row {
20252028
display: flex;
20262029
flex-direction: column;
20272030
gap: 0.5em;
20282031
padding: 0.75em;
20292032
--- src/default.css
+++ src/default.css
@@ -2019,10 +2019,13 @@
2019 margin-bottom: 1em;
2020 display: flex;
2021 flex-direction: column;
2022 gap: 0.75em;
2023 }
 
 
 
2024 .Attacher .attach-row {
2025 display: flex;
2026 flex-direction: column;
2027 gap: 0.5em;
2028 padding: 0.75em;
2029
--- src/default.css
+++ src/default.css
@@ -2019,10 +2019,13 @@
2019 margin-bottom: 1em;
2020 display: flex;
2021 flex-direction: column;
2022 gap: 0.75em;
2023 }
2024 .Attacher.reverse {
2025 flex-direction: column-reverse;
2026 }
2027 .Attacher .attach-row {
2028 display: flex;
2029 flex-direction: column;
2030 gap: 0.5em;
2031 padding: 0.75em;
2032
--- src/fossil.attach.js
+++ src/fossil.attach.js
@@ -44,10 +44,14 @@
4444
are automatically activated, as if the user had tapped the Add
4545
button that many times.
4646
4747
opt.description[=true]: if true then show the file description
4848
field, otherwise elide it.
49
+
50
+ opt.reverse[=false]: reverses the flow of the widget such that
51
+ the Add button stays on the top and rows are ordered
52
+ most-recently-added.
4953
5054
opt.controls = [array of DOM elements]. Optional DOM elements
5155
to inject into the UI element which wraps the "Add" button.
5256
See this.controlsElement.
5357
@@ -79,13 +83,15 @@
7983
this.#opt = opt = F.nu({
8084
addButtonLabel: false,
8185
startWith: 0,
8286
limit: 0,
8387
dryRun: undefined,
84
- description: true
88
+ description: true,
89
+ reverse: false
8590
}, opt);
8691
this.#e.body = D.addClass(D.div(), 'Attacher');
92
+ if( opt.reverse ) this.#e.body.classList.add('reverse');
8793
const eBtnAdd = this.#e.btnAdd = D.addClass(
8894
D.button(this.#opt.addButtonLabel || 'Add attachment',
8995
()=>this.#addRow()),
9096
'attach-add-button'
9197
);
9298
--- src/fossil.attach.js
+++ src/fossil.attach.js
@@ -44,10 +44,14 @@
44 are automatically activated, as if the user had tapped the Add
45 button that many times.
46
47 opt.description[=true]: if true then show the file description
48 field, otherwise elide it.
 
 
 
 
49
50 opt.controls = [array of DOM elements]. Optional DOM elements
51 to inject into the UI element which wraps the "Add" button.
52 See this.controlsElement.
53
@@ -79,13 +83,15 @@
79 this.#opt = opt = F.nu({
80 addButtonLabel: false,
81 startWith: 0,
82 limit: 0,
83 dryRun: undefined,
84 description: true
 
85 }, opt);
86 this.#e.body = D.addClass(D.div(), 'Attacher');
 
87 const eBtnAdd = this.#e.btnAdd = D.addClass(
88 D.button(this.#opt.addButtonLabel || 'Add attachment',
89 ()=>this.#addRow()),
90 'attach-add-button'
91 );
92
--- src/fossil.attach.js
+++ src/fossil.attach.js
@@ -44,10 +44,14 @@
44 are automatically activated, as if the user had tapped the Add
45 button that many times.
46
47 opt.description[=true]: if true then show the file description
48 field, otherwise elide it.
49
50 opt.reverse[=false]: reverses the flow of the widget such that
51 the Add button stays on the top and rows are ordered
52 most-recently-added.
53
54 opt.controls = [array of DOM elements]. Optional DOM elements
55 to inject into the UI element which wraps the "Add" button.
56 See this.controlsElement.
57
@@ -79,13 +83,15 @@
83 this.#opt = opt = F.nu({
84 addButtonLabel: false,
85 startWith: 0,
86 limit: 0,
87 dryRun: undefined,
88 description: true,
89 reverse: false
90 }, opt);
91 this.#e.body = D.addClass(D.div(), 'Attacher');
92 if( opt.reverse ) this.#e.body.classList.add('reverse');
93 const eBtnAdd = this.#e.btnAdd = D.addClass(
94 D.button(this.#opt.addButtonLabel || 'Add attachment',
95 ()=>this.#addRow()),
96 'attach-add-button'
97 );
98
--- src/fossil.page.forumpost.js
+++ src/fossil.page.forumpost.js
@@ -32,11 +32,10 @@
3232
opt = this.#opt = F.nu({
3333
// todo: defaults once we determine the options
3434
// replyTo: hash
3535
// edit: hash
3636
}, opt);
37
- opt.isNew = !opt.edit && !opt.replyTo;
3837
const e = this.#e = F.nu({
3938
mimetype: F.nu(),
4039
button: F.nu()
4140
});
4241
const wrapper = e.widget = D.addClass(D.div(), 'ForumPostEditor');
@@ -126,20 +125,22 @@
126125
this.#tabs.addTab(e.debug);
127126
}
128127
e.buttons.append(e.mimetype.wrapper);
129128
if( F.user.mayAttachForum ){
130129
this.#att = new F.Attacher({
131
- addButtonLabel: 'Attach'
130
+ reverse: true
132131
});
133
- e.buttons.append( e.button.addAttach = this.#att.takeAddButton() );
134
- this.#toDisable.push( e.button.addAttach );
132
+ //e.buttons.append( e.button.addAttach = this.#att.takeAddButton() );
133
+ e.tabAttach = D.append(D.div(), this.#att.widget);
134
+ e.tabAttach.setAttribute('id', idPrefix+'-attach');
135
+ e.tabAttach.dataset.tabLabel = 'Attachments';
136
+ this.#tabs.addTab(e.tabAttach);
137
+ /* Reminder: we don't currently have a way to disable/enable
138
+ an Attacher's controls. */
135139
}
136140
e.buttons.append(e.button.preview, e.button.submit);
137141
this.#toDisable.push(e.button.preview);
138
- if( this.#att ){
139
- wrapper.append(this.#att.widget);
140
- }
141142
}/*constructor*/
142143
143144
get widget(){
144145
return this.#e.widget;
145146
}
146147
--- src/fossil.page.forumpost.js
+++ src/fossil.page.forumpost.js
@@ -32,11 +32,10 @@
32 opt = this.#opt = F.nu({
33 // todo: defaults once we determine the options
34 // replyTo: hash
35 // edit: hash
36 }, opt);
37 opt.isNew = !opt.edit && !opt.replyTo;
38 const e = this.#e = F.nu({
39 mimetype: F.nu(),
40 button: F.nu()
41 });
42 const wrapper = e.widget = D.addClass(D.div(), 'ForumPostEditor');
@@ -126,20 +125,22 @@
126 this.#tabs.addTab(e.debug);
127 }
128 e.buttons.append(e.mimetype.wrapper);
129 if( F.user.mayAttachForum ){
130 this.#att = new F.Attacher({
131 addButtonLabel: 'Attach'
132 });
133 e.buttons.append( e.button.addAttach = this.#att.takeAddButton() );
134 this.#toDisable.push( e.button.addAttach );
 
 
 
 
 
135 }
136 e.buttons.append(e.button.preview, e.button.submit);
137 this.#toDisable.push(e.button.preview);
138 if( this.#att ){
139 wrapper.append(this.#att.widget);
140 }
141 }/*constructor*/
142
143 get widget(){
144 return this.#e.widget;
145 }
146
--- src/fossil.page.forumpost.js
+++ src/fossil.page.forumpost.js
@@ -32,11 +32,10 @@
32 opt = this.#opt = F.nu({
33 // todo: defaults once we determine the options
34 // replyTo: hash
35 // edit: hash
36 }, opt);
 
37 const e = this.#e = F.nu({
38 mimetype: F.nu(),
39 button: F.nu()
40 });
41 const wrapper = e.widget = D.addClass(D.div(), 'ForumPostEditor');
@@ -126,20 +125,22 @@
125 this.#tabs.addTab(e.debug);
126 }
127 e.buttons.append(e.mimetype.wrapper);
128 if( F.user.mayAttachForum ){
129 this.#att = new F.Attacher({
130 reverse: true
131 });
132 //e.buttons.append( e.button.addAttach = this.#att.takeAddButton() );
133 e.tabAttach = D.append(D.div(), this.#att.widget);
134 e.tabAttach.setAttribute('id', idPrefix+'-attach');
135 e.tabAttach.dataset.tabLabel = 'Attachments';
136 this.#tabs.addTab(e.tabAttach);
137 /* Reminder: we don't currently have a way to disable/enable
138 an Attacher's controls. */
139 }
140 e.buttons.append(e.button.preview, e.button.submit);
141 this.#toDisable.push(e.button.preview);
 
 
 
142 }/*constructor*/
143
144 get widget(){
145 return this.#e.widget;
146 }
147

Keyboard Shortcuts

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