Fossil SCM

Add an error message to each attached file which exceeds the attachment-size-limit setting. This tentatively won't prevent it from being submitted because the limit may have changed since the page was loaded (and the limit recorded).

stephan 2026-06-03 08:45 UTC attach-v2
Commit ee430462c41f07b500ecafd5ca6e874cdb68729d9d8247698a6b43171bd12268
--- src/default.css
+++ src/default.css
@@ -2023,10 +2023,15 @@
20232023
gap: 0.5em;
20242024
padding: 0.75em;
20252025
border: 1px dashed #ccc;
20262026
border-radius: 0.25em;
20272027
background-color: #fafafa;
2028
+}
2029
+.attach-widget .error {
2030
+ padding: 0.5em;
2031
+ background-color: #d32f2f;
2032
+ color: #fff;
20282033
}
20292034
body.fossil-dark-style .attach-widget .attach-row {
20302035
background-color: initial;
20312036
}
20322037
.attach-widget .attach-dropzone {
@@ -2065,10 +2070,11 @@
20652070
border-color: #03a9f4;
20662071
}
20672072
.attach-widget .thumbnail {
20682073
max-width: 10em;
20692074
max-height: 10em;
2075
+ margin: 0 1em;
20702076
}
20712077
.attach-widget .attach-row-info{
20722078
font-family: monospace;
20732079
flex-grow: 1;
20742080
display: flex;
20752081
--- src/default.css
+++ src/default.css
@@ -2023,10 +2023,15 @@
2023 gap: 0.5em;
2024 padding: 0.75em;
2025 border: 1px dashed #ccc;
2026 border-radius: 0.25em;
2027 background-color: #fafafa;
 
 
 
 
 
2028 }
2029 body.fossil-dark-style .attach-widget .attach-row {
2030 background-color: initial;
2031 }
2032 .attach-widget .attach-dropzone {
@@ -2065,10 +2070,11 @@
2065 border-color: #03a9f4;
2066 }
2067 .attach-widget .thumbnail {
2068 max-width: 10em;
2069 max-height: 10em;
 
2070 }
2071 .attach-widget .attach-row-info{
2072 font-family: monospace;
2073 flex-grow: 1;
2074 display: flex;
2075
--- src/default.css
+++ src/default.css
@@ -2023,10 +2023,15 @@
2023 gap: 0.5em;
2024 padding: 0.75em;
2025 border: 1px dashed #ccc;
2026 border-radius: 0.25em;
2027 background-color: #fafafa;
2028 }
2029 .attach-widget .error {
2030 padding: 0.5em;
2031 background-color: #d32f2f;
2032 color: #fff;
2033 }
2034 body.fossil-dark-style .attach-widget .attach-row {
2035 background-color: initial;
2036 }
2037 .attach-widget .attach-dropzone {
@@ -2065,10 +2070,11 @@
2070 border-color: #03a9f4;
2071 }
2072 .attach-widget .thumbnail {
2073 max-width: 10em;
2074 max-height: 10em;
2075 margin: 0 1em;
2076 }
2077 .attach-widget .attach-row-info{
2078 font-family: monospace;
2079 flex-grow: 1;
2080 display: flex;
2081
--- src/fossil.attach.js
+++ src/fossil.attach.js
@@ -164,10 +164,27 @@
164164
b.classList.remove('hidden');
165165
//b.removeAttribute('disabled');
166166
this.#e.list.append(this.#e.controls/*move to the end*/);
167167
}
168168
}
169
+
170
+ #rowError(rowObj, ...msg){
171
+ let e = rowObj.e.err;
172
+ if( e ){
173
+ D.clearElement(e);
174
+ }else{
175
+ if( !msg.length ) return;
176
+ e = rowObj.e.err = D.addClass(D.span(), 'error');
177
+ rowObj.e.info.append(e);
178
+ }
179
+ if( msg.length ){
180
+ e.append(...msg);
181
+ e.classList.remove('hidden');
182
+ }else{
183
+ e.classList.add('hidden');
184
+ }
185
+ }
169186
170187
#addRow(){
171188
const id = ++idCounter;
172189
const rowObj = F.nu({
173190
id, file: null, mimeType: ''
@@ -335,10 +352,21 @@
335352
img.classList.add('thumbnail');
336353
rowObj.e.dropzone.insertBefore(img, rowObj.e.remove);
337354
const reader = new FileReader();
338355
reader.onload = (e)=>img.setAttribute('src', e.target.result);
339356
reader.readAsDataURL(file);
357
+ }
358
+ if( file.size>F.config.attachmentSizeLimit ){
359
+ /* Problem: tapping this link propagates its click event through
360
+ to eDropzone. Thus... */
361
+ const eLink = D.a(F.repoUrl('help/attachment-size-limit'),'limit');
362
+ eLink.addEventListener('click', ev=>ev.stopPropagation());
363
+ this.#rowError(rowObj, "Too large: ", eLink,
364
+ " is ",F.config.attachmentSizeLimit," bytes");
365
+ rowObj.ok = false;
366
+ }else{
367
+ rowObj.ok = true;
340368
}
341369
this.#events.dispatchEvent(
342370
new CustomEvent('entry-populated',{
343371
detail: F.nu({
344372
type: 'entry-populated',
@@ -354,17 +382,17 @@
354382
attachments.
355383
*/
356384
collectState(){
357385
const rv = [];
358386
for(let r of this.#rows){
359
- if( !r.eDropzone?.classList?.contains?.('populated') ){
387
+ if( !r.e.dropzone?.classList?.contains?.('populated') ){
360388
continue;
361389
}
362390
rv.push(F.nu({
363391
name: r.name || r.file.name || `pasted-content-${r.id}.${r.mimeType.split('/')[1] || 'txt'}`,
364392
content: r.file,
365
- description: r.eDesc?.value || '',
393
+ description: r.e.desc?.value || '',
366394
mimeType: r.mimeType
367395
}));
368396
}
369397
return rv;
370398
}
@@ -415,8 +443,9 @@
415443
startWith: 1,
416444
listener: F.nu({all: cbAttacherChange}),
417445
controls: [eBtnSubmit]
418446
});
419447
updateBtnSubmit(att);
448
+ F.page.attacher = att /* only for testing via dev console */;
420449
}/* /attachaddV2 */
421450
422451
})(window.fossil);
423452
--- src/fossil.attach.js
+++ src/fossil.attach.js
@@ -164,10 +164,27 @@
164 b.classList.remove('hidden');
165 //b.removeAttribute('disabled');
166 this.#e.list.append(this.#e.controls/*move to the end*/);
167 }
168 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
170 #addRow(){
171 const id = ++idCounter;
172 const rowObj = F.nu({
173 id, file: null, mimeType: ''
@@ -335,10 +352,21 @@
335 img.classList.add('thumbnail');
336 rowObj.e.dropzone.insertBefore(img, rowObj.e.remove);
337 const reader = new FileReader();
338 reader.onload = (e)=>img.setAttribute('src', e.target.result);
339 reader.readAsDataURL(file);
 
 
 
 
 
 
 
 
 
 
 
340 }
341 this.#events.dispatchEvent(
342 new CustomEvent('entry-populated',{
343 detail: F.nu({
344 type: 'entry-populated',
@@ -354,17 +382,17 @@
354 attachments.
355 */
356 collectState(){
357 const rv = [];
358 for(let r of this.#rows){
359 if( !r.eDropzone?.classList?.contains?.('populated') ){
360 continue;
361 }
362 rv.push(F.nu({
363 name: r.name || r.file.name || `pasted-content-${r.id}.${r.mimeType.split('/')[1] || 'txt'}`,
364 content: r.file,
365 description: r.eDesc?.value || '',
366 mimeType: r.mimeType
367 }));
368 }
369 return rv;
370 }
@@ -415,8 +443,9 @@
415 startWith: 1,
416 listener: F.nu({all: cbAttacherChange}),
417 controls: [eBtnSubmit]
418 });
419 updateBtnSubmit(att);
 
420 }/* /attachaddV2 */
421
422 })(window.fossil);
423
--- src/fossil.attach.js
+++ src/fossil.attach.js
@@ -164,10 +164,27 @@
164 b.classList.remove('hidden');
165 //b.removeAttribute('disabled');
166 this.#e.list.append(this.#e.controls/*move to the end*/);
167 }
168 }
169
170 #rowError(rowObj, ...msg){
171 let e = rowObj.e.err;
172 if( e ){
173 D.clearElement(e);
174 }else{
175 if( !msg.length ) return;
176 e = rowObj.e.err = D.addClass(D.span(), 'error');
177 rowObj.e.info.append(e);
178 }
179 if( msg.length ){
180 e.append(...msg);
181 e.classList.remove('hidden');
182 }else{
183 e.classList.add('hidden');
184 }
185 }
186
187 #addRow(){
188 const id = ++idCounter;
189 const rowObj = F.nu({
190 id, file: null, mimeType: ''
@@ -335,10 +352,21 @@
352 img.classList.add('thumbnail');
353 rowObj.e.dropzone.insertBefore(img, rowObj.e.remove);
354 const reader = new FileReader();
355 reader.onload = (e)=>img.setAttribute('src', e.target.result);
356 reader.readAsDataURL(file);
357 }
358 if( file.size>F.config.attachmentSizeLimit ){
359 /* Problem: tapping this link propagates its click event through
360 to eDropzone. Thus... */
361 const eLink = D.a(F.repoUrl('help/attachment-size-limit'),'limit');
362 eLink.addEventListener('click', ev=>ev.stopPropagation());
363 this.#rowError(rowObj, "Too large: ", eLink,
364 " is ",F.config.attachmentSizeLimit," bytes");
365 rowObj.ok = false;
366 }else{
367 rowObj.ok = true;
368 }
369 this.#events.dispatchEvent(
370 new CustomEvent('entry-populated',{
371 detail: F.nu({
372 type: 'entry-populated',
@@ -354,17 +382,17 @@
382 attachments.
383 */
384 collectState(){
385 const rv = [];
386 for(let r of this.#rows){
387 if( !r.e.dropzone?.classList?.contains?.('populated') ){
388 continue;
389 }
390 rv.push(F.nu({
391 name: r.name || r.file.name || `pasted-content-${r.id}.${r.mimeType.split('/')[1] || 'txt'}`,
392 content: r.file,
393 description: r.e.desc?.value || '',
394 mimeType: r.mimeType
395 }));
396 }
397 return rv;
398 }
@@ -415,8 +443,9 @@
443 startWith: 1,
444 listener: F.nu({all: cbAttacherChange}),
445 controls: [eBtnSubmit]
446 });
447 updateBtnSubmit(att);
448 F.page.attacher = att /* only for testing via dev console */;
449 }/* /attachaddV2 */
450
451 })(window.fossil);
452

Keyboard Shortcuts

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