Fossil SCM

Correct redirection of /attachadd after attach to target=WikiPageName. Add some pieces to hypothetically support a NOSCRIPT fallback for file attachment using the legacy form, but it's completely tested.

stephan 2026-06-03 20:27 UTC attach-v2
Commit 31d882879aed1364ca151cec5ca9cbc36641189f0cb469b603b55ee09562eaa6
+59 -32
--- src/attach.c
+++ src/attach.c
@@ -445,10 +445,41 @@
445445
blob_appendf(&manifest, "Z %b\n", &cksum);
446446
attach_put(&manifest, rid, needModerator);
447447
assert( blob_is_reset(&manifest) );
448448
db_end_transaction(0);
449449
}
450
+
451
+static void attach_render_legacy_form(const char *zForumPost,
452
+ const char *zTechNote,
453
+ const char *zTicket,
454
+ const char *zWikiPage,
455
+ const char *zComment,
456
+ const char *zFrom){
457
+ form_begin("enctype='multipart/form-data'", "%R/attachadd");
458
+ @ <div>\
459
+ @ File to Attach:
460
+ @ <input type="file" name="f" size="60"><br>
461
+ @ Description:<br>
462
+ @ <textarea name="comment" cols="80" rows="5" wrap="virtual"\
463
+ @ >%h(zComment)</textarea><br>
464
+ if( zForumPost ){
465
+ @ <input type="hidden" name="forumpost" value="%h(zForumPost)">\
466
+ }else if( zTicket ){
467
+ @ <input type="hidden" name="tkt" value="%h(zTicket)">\
468
+ }else if( zTechNote ){
469
+ @ <input type="hidden" name="technote" value="%h(zTechNote)">\
470
+ }else if( zWikiPage ){
471
+ @ <input type="hidden" name="page" value="%h(zWikiPage)">\
472
+ }
473
+ @ <input type="hidden" name="from" value="%h(zFrom)">\
474
+ @ <input type="submit" name="ok" value="Add Attachment">\
475
+ @ <input type="submit" name="cancel" value="Cancel">\
476
+ @ </div>
477
+ captcha_generate(0);
478
+ login_insert_csrf_secret();
479
+ @ </form>
480
+}
450481
451482
/*
452483
** WEBPAGE: attachadd
453484
** Add a new attachment.
454485
**
@@ -586,33 +617,12 @@
586617
style_header("Add Attachment");
587618
if( !goodCaptcha ){
588619
@ <p class="generalError">Error: Incorrect security code.</p>
589620
}
590621
@ <h2>Add Attachment To %s(zTargetType)</h2>
591
- form_begin("enctype='multipart/form-data'", "%R/attachadd");
592
- @ <div>
593
- @ File to Attach:
594
- @ <input type="file" name="f" size="60"><br>
595
- @ Description:<br>
596
- @ <textarea name="comment" cols="80" rows="5" wrap="virtual"\
597
- @ >%h(zComment)</textarea><br>
598
- if( zForumPost ){
599
- @ <input type="hidden" name="forumpost" value="%h(zTarget)">
600
- }else if( zTkt ){
601
- @ <input type="hidden" name="tkt" value="%h(zTkt)">
602
- }else if( zTechNote ){
603
- @ <input type="hidden" name="technote" value="%h(zTechNote)">
604
- }else{
605
- @ <input type="hidden" name="page" value="%h(zPage)">
606
- }
607
- @ <input type="hidden" name="from" value="%h(zFrom)">
608
- @ <input type="submit" name="ok" value="Add Attachment">
609
- @ <input type="submit" name="cancel" value="Cancel">
610
- @ </div>
611
- captcha_generate(0);
612
- login_insert_csrf_secret();
613
- @ </form>
622
+ attach_render_legacy_form(zForumPost, zTechNote, zTechNote, zPage,
623
+ zComment, zFrom);
614624
builtin_fossil_js_bundle_or("attach", NULL);
615625
style_finish_page();
616626
fossil_free(zTargetType);
617627
fossil_free(zExtraFree);
618628
}
@@ -657,10 +667,11 @@
657667
return;
658668
}
659669
db_begin_transaction();
660670
zTarget = P("target");
661671
iTgtType = attachment_target_type(zTarget);
672
+ CX("{");
662673
switch( iTgtType ){
663674
default:
664675
case 0:
665676
ajax_route_error(400, "Invalid attachment target.");
666677
db_rollback_transaction();
@@ -754,11 +765,11 @@
754765
bNeedsModeration, P(aKeyDesc));
755766
}
756767
}
757768
fossil_free(zExtraFree);
758769
if( !bRollback ){
759
- CX("{}");
770
+ CX("}");
760771
if( atoi(PD("dryrun","0"))>0 ){
761772
bRollback = 1;
762773
}
763774
}
764775
db_end_transaction(bRollback);
@@ -778,14 +789,14 @@
778789
**
779790
** Lists attachments for, and can add them to, a target artifact.
780791
**
781792
** target=TKT_HASH|WIKIPAGE_NAME|TECHNOTE_HASH|FORUMPOST_HASH
782793
** from=ORIGINATING_URL
783
-** to=URL_ON_COMPLETION
784794
**
785795
** Works like /attachadd but uses a JS-based interactive attachment
786
-** selector.
796
+** selector. If from=X is set, this page arrganges for a redirect
797
+** back to X after attaching.
787798
**
788799
** from=X and to=X tell it how to redirect when it's done. to=X
789800
** overrides from=X. If neither is set, it will redirect back to this
790801
** page to render the updated attachment list.
791802
**
@@ -795,21 +806,21 @@
795806
const char *zFrom = P("from");
796807
const char *zTarget = P("target");
797808
char *zTo = 0;
798809
char *zTargetType = 0;
799810
char *zExtraFree = 0;
800
- int iTgtType = 0;
811
+ int eTgtType = 0;
801812
int goodCaptcha = 1;
813
+ char const * noJsArgs[] = {0,0,0,0}; /* Args for noscript form */
802814
803
- if( zFrom==0 ) zFrom = mprintf("%R/home");
804815
if( P("cancel") ) cgi_redirect(zFrom);
805816
if( 0==zTarget ){
806817
webpage_error("Requires target=X");
807818
}
808819
login_check_credentials();
809
- iTgtType = attachment_target_type(zTarget);
810
- switch( iTgtType ){
820
+ eTgtType = attachment_target_type(zTarget);
821
+ switch( eTgtType ){
811822
default:
812823
case 0:
813824
webpage_error("Cannot resolve target=%h.", zTarget);
814825
break;
815826
case CFTYPE_FORUM:{
@@ -824,10 +835,11 @@
824835
}else if( !g.perm.Admin && !forumpost_is_owner(fpid, 0) ){
825836
webpage_error("Only admins can attach files to other users' "
826837
"forum posts.");
827838
}
828839
zTarget = zExtraFree = rid_to_uuid(fpid);
840
+ noJsArgs[0] = zTarget;
829841
zTargetType = mprintf("Forum post <a href=\"%R/forumpost/%S\">%.16h</a>",
830842
zTarget, zTarget);
831843
zTo = mprintf("%R/forumpost/%S", zTarget);
832844
break;
833845
}
@@ -839,12 +851,14 @@
839851
if( !db_exists("SELECT 1 FROM tag WHERE tagname='event-%q'", zTarget) ){
840852
zTarget = db_text(0, "SELECT substr(tagname,7) FROM tag"
841853
" WHERE tagname GLOB 'event-%q*'", zTarget);
842854
if( zTarget==0) fossil_redirect_home();
843855
}
856
+ zTo = zFrom ? 0 : mprintf("%R/technote?name=%T", zTarget);
844857
zTargetType = mprintf("Tech Note <a href=\"%R/technote/%s\">%S</a>",
845858
zTarget, zTarget);
859
+ noJsArgs[1] = zTarget;
846860
break;
847861
}
848862
case CFTYPE_TICKET:{
849863
if( g.perm.ApndTkt==0 || g.perm.Attach==0 ){
850864
login_needed(g.anon.ApndTkt && g.anon.Attach);
@@ -853,12 +867,14 @@
853867
if( !db_exists("SELECT 1 FROM tag WHERE tagname='tkt-%q'", zTarget) ){
854868
zTarget = db_text(0, "SELECT substr(tagname,5) FROM tag"
855869
" WHERE tagname GLOB 'tkt-%q*'", zTarget);
856870
if( zTarget==0 ) fossil_redirect_home();
857871
}
872
+ zTo = zFrom ? 0 : mprintf("%R/tktview/%t", zTarget);
858873
zTargetType = mprintf("Ticket <a href=\"%R/tktview/%s\">%S</a>",
859874
zTarget, zTarget);
875
+ noJsArgs[2] = zTarget;
860876
break;
861877
}
862878
case CFTYPE_WIKI:{
863879
if( g.perm.ApndWiki==0 || g.perm.Attach==0 ){
864880
login_needed(g.anon.ApndWiki && g.anon.Attach);
@@ -865,12 +881,14 @@
865881
return;
866882
}
867883
if( !db_exists("SELECT 1 FROM tag WHERE tagname='wiki-%q'", zTarget) ){
868884
fossil_redirect_home();
869885
}
886
+ zTo = zFrom ? 0 : mprintf("%R/wiki?name=%T", zTarget);
870887
zTargetType = mprintf("Wiki Page <a href=\"%R/wiki?name=%h\">%h</a>",
871888
zTarget, zTarget);
889
+ noJsArgs[3] = zTarget;
872890
break;
873891
}
874892
}
875893
876894
db_begin_transaction();
@@ -879,14 +897,23 @@
879897
style_header("Add Attachment");
880898
if( !goodCaptcha ){
881899
@ <p class="generalError">Error: Incorrect security code.</p>
882900
}
883901
@ <h2>Attachments for %s(zTargetType)</h2>
902
+ if(1){
903
+ /* noscript fallback is completely tested */
904
+ @ <noscript>
905
+ attach_render_legacy_form(noJsArgs[0], noJsArgs[1], noJsArgs[2],
906
+ noJsArgs[3], 0,
907
+ zFrom ? zFrom : mprintf("%R/home"));
908
+ @ </noscript>
909
+ }
884910
attachment_list(zTarget, NULL,
885911
ATTACHLIST_SIZE | ATTACHLIST_HIDE_UNAPPROVED);
886
- @ <div id='attachadd-form-wrapper'>
887
- /* JS code imports these hidden fields into a form it generates. */
912
+ @ <div id='attachadd-form-wrapper' class='hidden'>
913
+ /* fossil.attach.js populates this DIV with the attachment widget
914
+ ** and imports these hidden fields. */
888915
@ <input type="hidden" name="target" value="%h(zTarget)">
889916
if( zFrom ){
890917
@ <input type="hidden" name="from" value="%h(zFrom)">
891918
}
892919
if( zTo ){
893920
--- src/attach.c
+++ src/attach.c
@@ -445,10 +445,41 @@
445 blob_appendf(&manifest, "Z %b\n", &cksum);
446 attach_put(&manifest, rid, needModerator);
447 assert( blob_is_reset(&manifest) );
448 db_end_transaction(0);
449 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
450
451 /*
452 ** WEBPAGE: attachadd
453 ** Add a new attachment.
454 **
@@ -586,33 +617,12 @@
586 style_header("Add Attachment");
587 if( !goodCaptcha ){
588 @ <p class="generalError">Error: Incorrect security code.</p>
589 }
590 @ <h2>Add Attachment To %s(zTargetType)</h2>
591 form_begin("enctype='multipart/form-data'", "%R/attachadd");
592 @ <div>
593 @ File to Attach:
594 @ <input type="file" name="f" size="60"><br>
595 @ Description:<br>
596 @ <textarea name="comment" cols="80" rows="5" wrap="virtual"\
597 @ >%h(zComment)</textarea><br>
598 if( zForumPost ){
599 @ <input type="hidden" name="forumpost" value="%h(zTarget)">
600 }else if( zTkt ){
601 @ <input type="hidden" name="tkt" value="%h(zTkt)">
602 }else if( zTechNote ){
603 @ <input type="hidden" name="technote" value="%h(zTechNote)">
604 }else{
605 @ <input type="hidden" name="page" value="%h(zPage)">
606 }
607 @ <input type="hidden" name="from" value="%h(zFrom)">
608 @ <input type="submit" name="ok" value="Add Attachment">
609 @ <input type="submit" name="cancel" value="Cancel">
610 @ </div>
611 captcha_generate(0);
612 login_insert_csrf_secret();
613 @ </form>
614 builtin_fossil_js_bundle_or("attach", NULL);
615 style_finish_page();
616 fossil_free(zTargetType);
617 fossil_free(zExtraFree);
618 }
@@ -657,10 +667,11 @@
657 return;
658 }
659 db_begin_transaction();
660 zTarget = P("target");
661 iTgtType = attachment_target_type(zTarget);
 
662 switch( iTgtType ){
663 default:
664 case 0:
665 ajax_route_error(400, "Invalid attachment target.");
666 db_rollback_transaction();
@@ -754,11 +765,11 @@
754 bNeedsModeration, P(aKeyDesc));
755 }
756 }
757 fossil_free(zExtraFree);
758 if( !bRollback ){
759 CX("{}");
760 if( atoi(PD("dryrun","0"))>0 ){
761 bRollback = 1;
762 }
763 }
764 db_end_transaction(bRollback);
@@ -778,14 +789,14 @@
778 **
779 ** Lists attachments for, and can add them to, a target artifact.
780 **
781 ** target=TKT_HASH|WIKIPAGE_NAME|TECHNOTE_HASH|FORUMPOST_HASH
782 ** from=ORIGINATING_URL
783 ** to=URL_ON_COMPLETION
784 **
785 ** Works like /attachadd but uses a JS-based interactive attachment
786 ** selector.
 
787 **
788 ** from=X and to=X tell it how to redirect when it's done. to=X
789 ** overrides from=X. If neither is set, it will redirect back to this
790 ** page to render the updated attachment list.
791 **
@@ -795,21 +806,21 @@
795 const char *zFrom = P("from");
796 const char *zTarget = P("target");
797 char *zTo = 0;
798 char *zTargetType = 0;
799 char *zExtraFree = 0;
800 int iTgtType = 0;
801 int goodCaptcha = 1;
 
802
803 if( zFrom==0 ) zFrom = mprintf("%R/home");
804 if( P("cancel") ) cgi_redirect(zFrom);
805 if( 0==zTarget ){
806 webpage_error("Requires target=X");
807 }
808 login_check_credentials();
809 iTgtType = attachment_target_type(zTarget);
810 switch( iTgtType ){
811 default:
812 case 0:
813 webpage_error("Cannot resolve target=%h.", zTarget);
814 break;
815 case CFTYPE_FORUM:{
@@ -824,10 +835,11 @@
824 }else if( !g.perm.Admin && !forumpost_is_owner(fpid, 0) ){
825 webpage_error("Only admins can attach files to other users' "
826 "forum posts.");
827 }
828 zTarget = zExtraFree = rid_to_uuid(fpid);
 
829 zTargetType = mprintf("Forum post <a href=\"%R/forumpost/%S\">%.16h</a>",
830 zTarget, zTarget);
831 zTo = mprintf("%R/forumpost/%S", zTarget);
832 break;
833 }
@@ -839,12 +851,14 @@
839 if( !db_exists("SELECT 1 FROM tag WHERE tagname='event-%q'", zTarget) ){
840 zTarget = db_text(0, "SELECT substr(tagname,7) FROM tag"
841 " WHERE tagname GLOB 'event-%q*'", zTarget);
842 if( zTarget==0) fossil_redirect_home();
843 }
 
844 zTargetType = mprintf("Tech Note <a href=\"%R/technote/%s\">%S</a>",
845 zTarget, zTarget);
 
846 break;
847 }
848 case CFTYPE_TICKET:{
849 if( g.perm.ApndTkt==0 || g.perm.Attach==0 ){
850 login_needed(g.anon.ApndTkt && g.anon.Attach);
@@ -853,12 +867,14 @@
853 if( !db_exists("SELECT 1 FROM tag WHERE tagname='tkt-%q'", zTarget) ){
854 zTarget = db_text(0, "SELECT substr(tagname,5) FROM tag"
855 " WHERE tagname GLOB 'tkt-%q*'", zTarget);
856 if( zTarget==0 ) fossil_redirect_home();
857 }
 
858 zTargetType = mprintf("Ticket <a href=\"%R/tktview/%s\">%S</a>",
859 zTarget, zTarget);
 
860 break;
861 }
862 case CFTYPE_WIKI:{
863 if( g.perm.ApndWiki==0 || g.perm.Attach==0 ){
864 login_needed(g.anon.ApndWiki && g.anon.Attach);
@@ -865,12 +881,14 @@
865 return;
866 }
867 if( !db_exists("SELECT 1 FROM tag WHERE tagname='wiki-%q'", zTarget) ){
868 fossil_redirect_home();
869 }
 
870 zTargetType = mprintf("Wiki Page <a href=\"%R/wiki?name=%h\">%h</a>",
871 zTarget, zTarget);
 
872 break;
873 }
874 }
875
876 db_begin_transaction();
@@ -879,14 +897,23 @@
879 style_header("Add Attachment");
880 if( !goodCaptcha ){
881 @ <p class="generalError">Error: Incorrect security code.</p>
882 }
883 @ <h2>Attachments for %s(zTargetType)</h2>
 
 
 
 
 
 
 
 
884 attachment_list(zTarget, NULL,
885 ATTACHLIST_SIZE | ATTACHLIST_HIDE_UNAPPROVED);
886 @ <div id='attachadd-form-wrapper'>
887 /* JS code imports these hidden fields into a form it generates. */
 
888 @ <input type="hidden" name="target" value="%h(zTarget)">
889 if( zFrom ){
890 @ <input type="hidden" name="from" value="%h(zFrom)">
891 }
892 if( zTo ){
893
--- src/attach.c
+++ src/attach.c
@@ -445,10 +445,41 @@
445 blob_appendf(&manifest, "Z %b\n", &cksum);
446 attach_put(&manifest, rid, needModerator);
447 assert( blob_is_reset(&manifest) );
448 db_end_transaction(0);
449 }
450
451 static void attach_render_legacy_form(const char *zForumPost,
452 const char *zTechNote,
453 const char *zTicket,
454 const char *zWikiPage,
455 const char *zComment,
456 const char *zFrom){
457 form_begin("enctype='multipart/form-data'", "%R/attachadd");
458 @ <div>\
459 @ File to Attach:
460 @ <input type="file" name="f" size="60"><br>
461 @ Description:<br>
462 @ <textarea name="comment" cols="80" rows="5" wrap="virtual"\
463 @ >%h(zComment)</textarea><br>
464 if( zForumPost ){
465 @ <input type="hidden" name="forumpost" value="%h(zForumPost)">\
466 }else if( zTicket ){
467 @ <input type="hidden" name="tkt" value="%h(zTicket)">\
468 }else if( zTechNote ){
469 @ <input type="hidden" name="technote" value="%h(zTechNote)">\
470 }else if( zWikiPage ){
471 @ <input type="hidden" name="page" value="%h(zWikiPage)">\
472 }
473 @ <input type="hidden" name="from" value="%h(zFrom)">\
474 @ <input type="submit" name="ok" value="Add Attachment">\
475 @ <input type="submit" name="cancel" value="Cancel">\
476 @ </div>
477 captcha_generate(0);
478 login_insert_csrf_secret();
479 @ </form>
480 }
481
482 /*
483 ** WEBPAGE: attachadd
484 ** Add a new attachment.
485 **
@@ -586,33 +617,12 @@
617 style_header("Add Attachment");
618 if( !goodCaptcha ){
619 @ <p class="generalError">Error: Incorrect security code.</p>
620 }
621 @ <h2>Add Attachment To %s(zTargetType)</h2>
622 attach_render_legacy_form(zForumPost, zTechNote, zTechNote, zPage,
623 zComment, zFrom);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
624 builtin_fossil_js_bundle_or("attach", NULL);
625 style_finish_page();
626 fossil_free(zTargetType);
627 fossil_free(zExtraFree);
628 }
@@ -657,10 +667,11 @@
667 return;
668 }
669 db_begin_transaction();
670 zTarget = P("target");
671 iTgtType = attachment_target_type(zTarget);
672 CX("{");
673 switch( iTgtType ){
674 default:
675 case 0:
676 ajax_route_error(400, "Invalid attachment target.");
677 db_rollback_transaction();
@@ -754,11 +765,11 @@
765 bNeedsModeration, P(aKeyDesc));
766 }
767 }
768 fossil_free(zExtraFree);
769 if( !bRollback ){
770 CX("}");
771 if( atoi(PD("dryrun","0"))>0 ){
772 bRollback = 1;
773 }
774 }
775 db_end_transaction(bRollback);
@@ -778,14 +789,14 @@
789 **
790 ** Lists attachments for, and can add them to, a target artifact.
791 **
792 ** target=TKT_HASH|WIKIPAGE_NAME|TECHNOTE_HASH|FORUMPOST_HASH
793 ** from=ORIGINATING_URL
 
794 **
795 ** Works like /attachadd but uses a JS-based interactive attachment
796 ** selector. If from=X is set, this page arrganges for a redirect
797 ** back to X after attaching.
798 **
799 ** from=X and to=X tell it how to redirect when it's done. to=X
800 ** overrides from=X. If neither is set, it will redirect back to this
801 ** page to render the updated attachment list.
802 **
@@ -795,21 +806,21 @@
806 const char *zFrom = P("from");
807 const char *zTarget = P("target");
808 char *zTo = 0;
809 char *zTargetType = 0;
810 char *zExtraFree = 0;
811 int eTgtType = 0;
812 int goodCaptcha = 1;
813 char const * noJsArgs[] = {0,0,0,0}; /* Args for noscript form */
814
 
815 if( P("cancel") ) cgi_redirect(zFrom);
816 if( 0==zTarget ){
817 webpage_error("Requires target=X");
818 }
819 login_check_credentials();
820 eTgtType = attachment_target_type(zTarget);
821 switch( eTgtType ){
822 default:
823 case 0:
824 webpage_error("Cannot resolve target=%h.", zTarget);
825 break;
826 case CFTYPE_FORUM:{
@@ -824,10 +835,11 @@
835 }else if( !g.perm.Admin && !forumpost_is_owner(fpid, 0) ){
836 webpage_error("Only admins can attach files to other users' "
837 "forum posts.");
838 }
839 zTarget = zExtraFree = rid_to_uuid(fpid);
840 noJsArgs[0] = zTarget;
841 zTargetType = mprintf("Forum post <a href=\"%R/forumpost/%S\">%.16h</a>",
842 zTarget, zTarget);
843 zTo = mprintf("%R/forumpost/%S", zTarget);
844 break;
845 }
@@ -839,12 +851,14 @@
851 if( !db_exists("SELECT 1 FROM tag WHERE tagname='event-%q'", zTarget) ){
852 zTarget = db_text(0, "SELECT substr(tagname,7) FROM tag"
853 " WHERE tagname GLOB 'event-%q*'", zTarget);
854 if( zTarget==0) fossil_redirect_home();
855 }
856 zTo = zFrom ? 0 : mprintf("%R/technote?name=%T", zTarget);
857 zTargetType = mprintf("Tech Note <a href=\"%R/technote/%s\">%S</a>",
858 zTarget, zTarget);
859 noJsArgs[1] = zTarget;
860 break;
861 }
862 case CFTYPE_TICKET:{
863 if( g.perm.ApndTkt==0 || g.perm.Attach==0 ){
864 login_needed(g.anon.ApndTkt && g.anon.Attach);
@@ -853,12 +867,14 @@
867 if( !db_exists("SELECT 1 FROM tag WHERE tagname='tkt-%q'", zTarget) ){
868 zTarget = db_text(0, "SELECT substr(tagname,5) FROM tag"
869 " WHERE tagname GLOB 'tkt-%q*'", zTarget);
870 if( zTarget==0 ) fossil_redirect_home();
871 }
872 zTo = zFrom ? 0 : mprintf("%R/tktview/%t", zTarget);
873 zTargetType = mprintf("Ticket <a href=\"%R/tktview/%s\">%S</a>",
874 zTarget, zTarget);
875 noJsArgs[2] = zTarget;
876 break;
877 }
878 case CFTYPE_WIKI:{
879 if( g.perm.ApndWiki==0 || g.perm.Attach==0 ){
880 login_needed(g.anon.ApndWiki && g.anon.Attach);
@@ -865,12 +881,14 @@
881 return;
882 }
883 if( !db_exists("SELECT 1 FROM tag WHERE tagname='wiki-%q'", zTarget) ){
884 fossil_redirect_home();
885 }
886 zTo = zFrom ? 0 : mprintf("%R/wiki?name=%T", zTarget);
887 zTargetType = mprintf("Wiki Page <a href=\"%R/wiki?name=%h\">%h</a>",
888 zTarget, zTarget);
889 noJsArgs[3] = zTarget;
890 break;
891 }
892 }
893
894 db_begin_transaction();
@@ -879,14 +897,23 @@
897 style_header("Add Attachment");
898 if( !goodCaptcha ){
899 @ <p class="generalError">Error: Incorrect security code.</p>
900 }
901 @ <h2>Attachments for %s(zTargetType)</h2>
902 if(1){
903 /* noscript fallback is completely tested */
904 @ <noscript>
905 attach_render_legacy_form(noJsArgs[0], noJsArgs[1], noJsArgs[2],
906 noJsArgs[3], 0,
907 zFrom ? zFrom : mprintf("%R/home"));
908 @ </noscript>
909 }
910 attachment_list(zTarget, NULL,
911 ATTACHLIST_SIZE | ATTACHLIST_HIDE_UNAPPROVED);
912 @ <div id='attachadd-form-wrapper' class='hidden'>
913 /* fossil.attach.js populates this DIV with the attachment widget
914 ** and imports these hidden fields. */
915 @ <input type="hidden" name="target" value="%h(zTarget)">
916 if( zFrom ){
917 @ <input type="hidden" name="from" value="%h(zFrom)">
918 }
919 if( zTo ){
920
--- src/fossil.attach.js
+++ src/fossil.attach.js
@@ -488,10 +488,11 @@
488488
F.Attacher = Attacher;
489489
490490
const eFormWrapper = document.querySelector('#attachadd-form-wrapper');
491491
if( eFormWrapper ){
492492
/* Inject a file-attachment form. */
493
+ eFormWrapper.classList.remove('hidden');
493494
const urlArgs = new URLSearchParams(window.location.search);
494495
let zTarget = urlArgs.get('target');
495496
let zTo = urlArgs.get('to') || urlArgs.get('from');
496497
const eBtnSubmit = D.button("Submit");
497498
eBtnSubmit.type = 'button';
498499
--- src/fossil.attach.js
+++ src/fossil.attach.js
@@ -488,10 +488,11 @@
488 F.Attacher = Attacher;
489
490 const eFormWrapper = document.querySelector('#attachadd-form-wrapper');
491 if( eFormWrapper ){
492 /* Inject a file-attachment form. */
 
493 const urlArgs = new URLSearchParams(window.location.search);
494 let zTarget = urlArgs.get('target');
495 let zTo = urlArgs.get('to') || urlArgs.get('from');
496 const eBtnSubmit = D.button("Submit");
497 eBtnSubmit.type = 'button';
498
--- src/fossil.attach.js
+++ src/fossil.attach.js
@@ -488,10 +488,11 @@
488 F.Attacher = Attacher;
489
490 const eFormWrapper = document.querySelector('#attachadd-form-wrapper');
491 if( eFormWrapper ){
492 /* Inject a file-attachment form. */
493 eFormWrapper.classList.remove('hidden');
494 const urlArgs = new URLSearchParams(window.location.search);
495 let zTarget = urlArgs.get('target');
496 let zTo = urlArgs.get('to') || urlArgs.get('from');
497 const eBtnSubmit = D.button("Submit");
498 eBtnSubmit.type = 'button';
499

Keyboard Shortcuts

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