Fossil SCM

When pasting in the attachment description field, if it's a clipboarded file then attach it rather than paste its name. Suggested by Martin G.

stephan 2026-06-08 14:41 UTC forum-editor-2026
Commit 45c5ce742b88778f6b3d6976ef2560592334da281d8cd3e8d11f155d0294cc76
1 file changed +19 -8
--- src/fossil.attach.js
+++ src/fossil.attach.js
@@ -343,42 +343,53 @@
343343
}
344344
this.#injestBlob(rowObj, blob);
345345
return true;
346346
}
347347
return false;
348
+ };
349
+ const pasteThing = (event, thing)=>{
350
+ console.debug("pasteThing 1",thing);
351
+ if( pasteImage(event, thing) ) return true;
352
+ console.debug("pasteThing 2",thing);
353
+ if( 'file' === thing.kind ){
354
+ event.preventDefault();
355
+ const blob = thing.getAsFile();
356
+ if( blob ){
357
+ console.debug("Pasting unknown thing...", thing, blob);
358
+ this.#injestBlob(rowObj, blob);
359
+ return true;
360
+ }
361
+ }
362
+ console.debug("pasteThing nope", thing);
363
+ return false;
348364
};
349365
eDesc?.addEventListener?.('paste', (e) => {
350366
e.stopPropagation();
351367
const items = (e.clipboardData || e.originalEvent.clipboardData)?.items;
352368
if( !items ) return;
353369
for( let i = 0; i < items.length; ++i ){
354370
const item = items[i];
355
- if( pasteImage(e, item) ){
371
+ if( pasteThing(e, item) ){
356372
break;
357373
}
358374
}
359375
});
360376
eRow.addEventListener('paste', (e) => {
361377
const items = (e.clipboardData || e.originalEvent.clipboardData)?.items;
362378
if( !items ) return;
363379
for( let i = 0; i < items.length; ++i ){
364380
const item = items[i];
365
- if( pasteImage(e, item) ){
366
- break;
367
- }else if( item.type === 'text/plain' ){
381
+ if( item.type === 'text/plain' ){
368382
e.preventDefault();
369383
item.getAsString((text) => {
370384
rowObj.overrideName = `pasted-text-${Date.now()}.txt`;
371385
const blob = new File([text], rowObj.overrideName,
372386
{type: 'text/plain'});
373387
this.#injestBlob(rowObj, blob);
374388
});
375389
break;
376
- }else if(0){
377
- e.preventDefault();
378
- const blob = undefined /* ??? */;
379
- this.#injestBlob(rowObj, blob);
390
+ }else if( pasteThing(e, item) ){
380391
break;
381392
}
382393
}
383394
});
384395
eRow.append(eDropzone);
385396
--- src/fossil.attach.js
+++ src/fossil.attach.js
@@ -343,42 +343,53 @@
343 }
344 this.#injestBlob(rowObj, blob);
345 return true;
346 }
347 return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
348 };
349 eDesc?.addEventListener?.('paste', (e) => {
350 e.stopPropagation();
351 const items = (e.clipboardData || e.originalEvent.clipboardData)?.items;
352 if( !items ) return;
353 for( let i = 0; i < items.length; ++i ){
354 const item = items[i];
355 if( pasteImage(e, item) ){
356 break;
357 }
358 }
359 });
360 eRow.addEventListener('paste', (e) => {
361 const items = (e.clipboardData || e.originalEvent.clipboardData)?.items;
362 if( !items ) return;
363 for( let i = 0; i < items.length; ++i ){
364 const item = items[i];
365 if( pasteImage(e, item) ){
366 break;
367 }else if( item.type === 'text/plain' ){
368 e.preventDefault();
369 item.getAsString((text) => {
370 rowObj.overrideName = `pasted-text-${Date.now()}.txt`;
371 const blob = new File([text], rowObj.overrideName,
372 {type: 'text/plain'});
373 this.#injestBlob(rowObj, blob);
374 });
375 break;
376 }else if(0){
377 e.preventDefault();
378 const blob = undefined /* ??? */;
379 this.#injestBlob(rowObj, blob);
380 break;
381 }
382 }
383 });
384 eRow.append(eDropzone);
385
--- src/fossil.attach.js
+++ src/fossil.attach.js
@@ -343,42 +343,53 @@
343 }
344 this.#injestBlob(rowObj, blob);
345 return true;
346 }
347 return false;
348 };
349 const pasteThing = (event, thing)=>{
350 console.debug("pasteThing 1",thing);
351 if( pasteImage(event, thing) ) return true;
352 console.debug("pasteThing 2",thing);
353 if( 'file' === thing.kind ){
354 event.preventDefault();
355 const blob = thing.getAsFile();
356 if( blob ){
357 console.debug("Pasting unknown thing...", thing, blob);
358 this.#injestBlob(rowObj, blob);
359 return true;
360 }
361 }
362 console.debug("pasteThing nope", thing);
363 return false;
364 };
365 eDesc?.addEventListener?.('paste', (e) => {
366 e.stopPropagation();
367 const items = (e.clipboardData || e.originalEvent.clipboardData)?.items;
368 if( !items ) return;
369 for( let i = 0; i < items.length; ++i ){
370 const item = items[i];
371 if( pasteThing(e, item) ){
372 break;
373 }
374 }
375 });
376 eRow.addEventListener('paste', (e) => {
377 const items = (e.clipboardData || e.originalEvent.clipboardData)?.items;
378 if( !items ) return;
379 for( let i = 0; i < items.length; ++i ){
380 const item = items[i];
381 if( item.type === 'text/plain' ){
 
 
382 e.preventDefault();
383 item.getAsString((text) => {
384 rowObj.overrideName = `pasted-text-${Date.now()}.txt`;
385 const blob = new File([text], rowObj.overrideName,
386 {type: 'text/plain'});
387 this.#injestBlob(rowObj, blob);
388 });
389 break;
390 }else if( pasteThing(e, item) ){
 
 
 
391 break;
392 }
393 }
394 });
395 eRow.append(eDropzone);
396

Keyboard Shortcuts

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