Fossil SCM

Put an "Add Wiki" button in the submenu for /timeline displays of branches and tags. Add the "Add Wiki:" line to the overview section of check-in /info pages.

drh 2019-01-02 03:08 trunk
Commit 867fe0ea9664321a224b7543c555e76fc2d061f66d04d4bcfa924f752376e3b2
3 files changed +42 -16 +3 -4 +94 -27
+42 -16
--- src/info.c
+++ src/info.c
@@ -691,11 +691,12 @@
691691
const char *zComment;
692692
const char *zDate;
693693
const char *zOrigDate;
694694
const char *zBrName;
695695
int okWiki = 0;
696
- Blob wiki_links = BLOB_INITIALIZER;
696
+ Blob wiki_read_links = BLOB_INITIALIZER;
697
+ Blob wiki_add_links = BLOB_INITIALIZER;
697698
698699
style_header("Check-in [%S]", zUuid);
699700
login_anonymous_available();
700701
zEUser = db_text(0,
701702
"SELECT value FROM tagxref"
@@ -761,19 +762,25 @@
761762
" AND +tag.tagname GLOB 'sym-*'", rid);
762763
while( db_step(&q2)==SQLITE_ROW ){
763764
const char *zTagName = db_column_text(&q2, 0);
764765
if( fossil_strcmp(zTagName,zBrName)==0 ){
765766
@ | %z(href("%R/timeline?r=%T&unhide",zTagName))%h(zTagName)</a>
766
- if( g.perm.Write || wiki_tagid2("branch",zTagName)!=0 ){
767
- blob_appendf(&wiki_links, " | %z%h</a>",
767
+ if( wiki_tagid2("branch",zTagName)!=0 ){
768
+ blob_appendf(&wiki_read_links, " | %z%h</a>",
768769
href("%R/wiki?name=branch/%h",zTagName), zTagName);
770
+ }else if( g.perm.Write && g.perm.WrWiki ){
771
+ blob_appendf(&wiki_add_links, " | %z%h</a>",
772
+ href("%R/wikiedit?name=branch/%h",zTagName), zTagName);
769773
}
770774
}else{
771775
@ | %z(href("%R/timeline?t=%T&unhide",zTagName))%h(zTagName)</a>
772
- if( g.perm.Write || wiki_tagid2("tag",zTagName)!=0 ){
773
- blob_appendf(&wiki_links, " | %z%h</a>",
776
+ if( wiki_tagid2("tag",zTagName)!=0 ){
777
+ blob_appendf(&wiki_read_links, " | %z%h</a>",
774778
href("%R/wiki?name=tag/%h",zTagName), zTagName);
779
+ }else if( g.perm.Write && g.perm.WrWiki ){
780
+ blob_appendf(&wiki_add_links, " | %z%h</a>",
781
+ href("%R/wikiedit?name=tag/%h",zTagName), zTagName);
775782
}
776783
}
777784
}
778785
db_finalize(&q2);
779786
@ </td></tr>
@@ -821,23 +828,41 @@
821828
@ <td>%h(zUser) @ %h(zIpAddr) on %s(zDate)</td></tr>
822829
}
823830
db_finalize(&q2);
824831
}
825832
826
- /* Only show links to wiki pages if the users can read wiki,
827
- ** and only if the wiki pages already exist or the user has the
828
- ** ability to create new ones. */
833
+ /* Only show links to read wiki pages if the users can read wiki
834
+ ** and if the wiki pages already exist */
829835
if( g.perm.RdWiki
830
- && (g.perm.Write || blob_size(&wiki_links)>0
831
- || (okWiki = wiki_tagid2("checkin",zUuid))!=0)
836
+ && ((okWiki = wiki_tagid2("checkin",zUuid))!=0 ||
837
+ blob_size(&wiki_read_links)>0)
838
+ && db_get_boolean("wiki-about",1)
839
+ ){
840
+ const char *zLinks = blob_str(&wiki_read_links);
841
+ @ <tr><th>Wiki:</th><td>\
842
+ if( okWiki ){
843
+ @ %z(href("%R/wiki?name=checkin/%s",zUuid))this checkin</a>\
844
+ }else if( zLinks[0] ){
845
+ zLinks += 3;
846
+ }
847
+ @ %s(zLinks)</td></tr>
848
+ }
849
+
850
+ /* Only show links to create new wiki pages if the users can write wiki
851
+ ** and if the wiki pages do not already exist */
852
+ if( g.perm.WrWiki
853
+ && g.perm.RdWiki
854
+ && g.perm.Write
855
+ && (blob_size(&wiki_add_links)>0 || !okWiki)
832856
&& db_get_boolean("wiki-about",1)
833857
){
834
- const char *zLinks = blob_str(&wiki_links);
835
- if( zLinks[0] ) zLinks += 3;
836
- @ <tr><th>Wiki:</th><td>\
837
- if( g.perm.Write || okWiki ){
838
- @ %z(href("%R/wiki?name=checkin/%s",zUuid))this checkin</a> | \
858
+ const char *zLinks = blob_str(&wiki_add_links);
859
+ @ <tr><th>Add&nbsp;Wiki:</th><td>\
860
+ if( !okWiki ){
861
+ @ %z(href("%R/wikiedit?name=checkin/%s",zUuid))this checkin</a>\
862
+ }else if( zLinks[0] ){
863
+ zLinks += 3;
839864
}
840865
@ %s(zLinks)</td></tr>
841866
}
842867
843868
if( g.perm.Hyperlink ){
@@ -853,11 +878,12 @@
853878
}
854879
@ </td>
855880
@ </tr>
856881
}
857882
@ </table>
858
- blob_reset(&wiki_links);
883
+ blob_reset(&wiki_read_links);
884
+ blob_reset(&wiki_add_links);
859885
}else{
860886
style_header("Check-in Information");
861887
login_anonymous_available();
862888
}
863889
db_finalize(&q1);
864890
--- src/info.c
+++ src/info.c
@@ -691,11 +691,12 @@
691 const char *zComment;
692 const char *zDate;
693 const char *zOrigDate;
694 const char *zBrName;
695 int okWiki = 0;
696 Blob wiki_links = BLOB_INITIALIZER;
 
697
698 style_header("Check-in [%S]", zUuid);
699 login_anonymous_available();
700 zEUser = db_text(0,
701 "SELECT value FROM tagxref"
@@ -761,19 +762,25 @@
761 " AND +tag.tagname GLOB 'sym-*'", rid);
762 while( db_step(&q2)==SQLITE_ROW ){
763 const char *zTagName = db_column_text(&q2, 0);
764 if( fossil_strcmp(zTagName,zBrName)==0 ){
765 @ | %z(href("%R/timeline?r=%T&unhide",zTagName))%h(zTagName)</a>
766 if( g.perm.Write || wiki_tagid2("branch",zTagName)!=0 ){
767 blob_appendf(&wiki_links, " | %z%h</a>",
768 href("%R/wiki?name=branch/%h",zTagName), zTagName);
 
 
 
769 }
770 }else{
771 @ | %z(href("%R/timeline?t=%T&unhide",zTagName))%h(zTagName)</a>
772 if( g.perm.Write || wiki_tagid2("tag",zTagName)!=0 ){
773 blob_appendf(&wiki_links, " | %z%h</a>",
774 href("%R/wiki?name=tag/%h",zTagName), zTagName);
 
 
 
775 }
776 }
777 }
778 db_finalize(&q2);
779 @ </td></tr>
@@ -821,23 +828,41 @@
821 @ <td>%h(zUser) @ %h(zIpAddr) on %s(zDate)</td></tr>
822 }
823 db_finalize(&q2);
824 }
825
826 /* Only show links to wiki pages if the users can read wiki,
827 ** and only if the wiki pages already exist or the user has the
828 ** ability to create new ones. */
829 if( g.perm.RdWiki
830 && (g.perm.Write || blob_size(&wiki_links)>0
831 || (okWiki = wiki_tagid2("checkin",zUuid))!=0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
832 && db_get_boolean("wiki-about",1)
833 ){
834 const char *zLinks = blob_str(&wiki_links);
835 if( zLinks[0] ) zLinks += 3;
836 @ <tr><th>Wiki:</th><td>\
837 if( g.perm.Write || okWiki ){
838 @ %z(href("%R/wiki?name=checkin/%s",zUuid))this checkin</a> | \
 
839 }
840 @ %s(zLinks)</td></tr>
841 }
842
843 if( g.perm.Hyperlink ){
@@ -853,11 +878,12 @@
853 }
854 @ </td>
855 @ </tr>
856 }
857 @ </table>
858 blob_reset(&wiki_links);
 
859 }else{
860 style_header("Check-in Information");
861 login_anonymous_available();
862 }
863 db_finalize(&q1);
864
--- src/info.c
+++ src/info.c
@@ -691,11 +691,12 @@
691 const char *zComment;
692 const char *zDate;
693 const char *zOrigDate;
694 const char *zBrName;
695 int okWiki = 0;
696 Blob wiki_read_links = BLOB_INITIALIZER;
697 Blob wiki_add_links = BLOB_INITIALIZER;
698
699 style_header("Check-in [%S]", zUuid);
700 login_anonymous_available();
701 zEUser = db_text(0,
702 "SELECT value FROM tagxref"
@@ -761,19 +762,25 @@
762 " AND +tag.tagname GLOB 'sym-*'", rid);
763 while( db_step(&q2)==SQLITE_ROW ){
764 const char *zTagName = db_column_text(&q2, 0);
765 if( fossil_strcmp(zTagName,zBrName)==0 ){
766 @ | %z(href("%R/timeline?r=%T&unhide",zTagName))%h(zTagName)</a>
767 if( wiki_tagid2("branch",zTagName)!=0 ){
768 blob_appendf(&wiki_read_links, " | %z%h</a>",
769 href("%R/wiki?name=branch/%h",zTagName), zTagName);
770 }else if( g.perm.Write && g.perm.WrWiki ){
771 blob_appendf(&wiki_add_links, " | %z%h</a>",
772 href("%R/wikiedit?name=branch/%h",zTagName), zTagName);
773 }
774 }else{
775 @ | %z(href("%R/timeline?t=%T&unhide",zTagName))%h(zTagName)</a>
776 if( wiki_tagid2("tag",zTagName)!=0 ){
777 blob_appendf(&wiki_read_links, " | %z%h</a>",
778 href("%R/wiki?name=tag/%h",zTagName), zTagName);
779 }else if( g.perm.Write && g.perm.WrWiki ){
780 blob_appendf(&wiki_add_links, " | %z%h</a>",
781 href("%R/wikiedit?name=tag/%h",zTagName), zTagName);
782 }
783 }
784 }
785 db_finalize(&q2);
786 @ </td></tr>
@@ -821,23 +828,41 @@
828 @ <td>%h(zUser) @ %h(zIpAddr) on %s(zDate)</td></tr>
829 }
830 db_finalize(&q2);
831 }
832
833 /* Only show links to read wiki pages if the users can read wiki
834 ** and if the wiki pages already exist */
 
835 if( g.perm.RdWiki
836 && ((okWiki = wiki_tagid2("checkin",zUuid))!=0 ||
837 blob_size(&wiki_read_links)>0)
838 && db_get_boolean("wiki-about",1)
839 ){
840 const char *zLinks = blob_str(&wiki_read_links);
841 @ <tr><th>Wiki:</th><td>\
842 if( okWiki ){
843 @ %z(href("%R/wiki?name=checkin/%s",zUuid))this checkin</a>\
844 }else if( zLinks[0] ){
845 zLinks += 3;
846 }
847 @ %s(zLinks)</td></tr>
848 }
849
850 /* Only show links to create new wiki pages if the users can write wiki
851 ** and if the wiki pages do not already exist */
852 if( g.perm.WrWiki
853 && g.perm.RdWiki
854 && g.perm.Write
855 && (blob_size(&wiki_add_links)>0 || !okWiki)
856 && db_get_boolean("wiki-about",1)
857 ){
858 const char *zLinks = blob_str(&wiki_add_links);
859 @ <tr><th>Add&nbsp;Wiki:</th><td>\
860 if( !okWiki ){
861 @ %z(href("%R/wikiedit?name=checkin/%s",zUuid))this checkin</a>\
862 }else if( zLinks[0] ){
863 zLinks += 3;
864 }
865 @ %s(zLinks)</td></tr>
866 }
867
868 if( g.perm.Hyperlink ){
@@ -853,11 +878,12 @@
878 }
879 @ </td>
880 @ </tr>
881 }
882 @ </table>
883 blob_reset(&wiki_read_links);
884 blob_reset(&wiki_add_links);
885 }else{
886 style_header("Check-in Information");
887 login_anonymous_available();
888 }
889 db_finalize(&q1);
890
+3 -4
--- src/timeline.c
+++ src/timeline.c
@@ -2274,20 +2274,19 @@
22742274
if( fossil_islower(desc.aData[0]) ){
22752275
desc.aData[0] = fossil_toupper(desc.aData[0]);
22762276
}
22772277
if( zBrName
22782278
&& !PB("nowiki")
2279
- && wiki_render_associated("branch", zBrName,
2280
- WIKIASSOC_FULL_TITLE|WIKIASSOC_MENU)
2279
+ && wiki_render_associated("branch", zBrName, WIKIASSOC_ALL)
22812280
){
22822281
@ <div class="section">%b(&desc)</div>
22832282
}else
22842283
if( zTagName
22852284
&& matchStyle==MS_EXACT
2285
+ && zBrName==0
22862286
&& !PB("nowiki")
2287
- && wiki_render_associated("tag", zTagName,
2288
- WIKIASSOC_FULL_TITLE|WIKIASSOC_MENU)
2287
+ && wiki_render_associated("tag", zTagName, WIKIASSOC_ALL)
22892288
){
22902289
@ <div class="section">%b(&desc)</div>
22912290
} else{
22922291
@ <h2>%b(&desc)</h2>
22932292
}
22942293
--- src/timeline.c
+++ src/timeline.c
@@ -2274,20 +2274,19 @@
2274 if( fossil_islower(desc.aData[0]) ){
2275 desc.aData[0] = fossil_toupper(desc.aData[0]);
2276 }
2277 if( zBrName
2278 && !PB("nowiki")
2279 && wiki_render_associated("branch", zBrName,
2280 WIKIASSOC_FULL_TITLE|WIKIASSOC_MENU)
2281 ){
2282 @ <div class="section">%b(&desc)</div>
2283 }else
2284 if( zTagName
2285 && matchStyle==MS_EXACT
 
2286 && !PB("nowiki")
2287 && wiki_render_associated("tag", zTagName,
2288 WIKIASSOC_FULL_TITLE|WIKIASSOC_MENU)
2289 ){
2290 @ <div class="section">%b(&desc)</div>
2291 } else{
2292 @ <h2>%b(&desc)</h2>
2293 }
2294
--- src/timeline.c
+++ src/timeline.c
@@ -2274,20 +2274,19 @@
2274 if( fossil_islower(desc.aData[0]) ){
2275 desc.aData[0] = fossil_toupper(desc.aData[0]);
2276 }
2277 if( zBrName
2278 && !PB("nowiki")
2279 && wiki_render_associated("branch", zBrName, WIKIASSOC_ALL)
 
2280 ){
2281 @ <div class="section">%b(&desc)</div>
2282 }else
2283 if( zTagName
2284 && matchStyle==MS_EXACT
2285 && zBrName==0
2286 && !PB("nowiki")
2287 && wiki_render_associated("tag", zTagName, WIKIASSOC_ALL)
 
2288 ){
2289 @ <div class="section">%b(&desc)</div>
2290 } else{
2291 @ <h2>%b(&desc)</h2>
2292 }
2293
+94 -27
--- src/wiki.c
+++ src/wiki.c
@@ -348,36 +348,74 @@
348348
wiki_standard_submenu(W_HELP|W_LIST|W_SANDBOX);
349349
search_screen(SRCH_WIKI, 0);
350350
style_footer();
351351
}
352352
353
+/* Return values from wiki_page_type() */
354
+#define WIKITYPE_UNKNOWN (-1)
355
+#define WIKITYPE_NORMAL 0
356
+#define WIKITYPE_BRANCH 1
357
+#define WIKITYPE_CHECKIN 2
358
+#define WIKITYPE_TAG 3
359
+
353360
/*
354
-** Add an appropriate style_header() for either the /wiki or /wikiedit page
355
-** for zPageName.
361
+** Figure out what type of wiki page we are dealing with.
356362
*/
357
-static void wiki_page_header(const char *zPageName, const char *zExtra){
363
+static int wiki_page_type(const char *zPageName){
358364
if( db_get_boolean("wiki-about",1)==0 ){
359
- style_header("%s%s", zExtra, zPageName);
365
+ return WIKITYPE_NORMAL;
360366
}else
361367
if( sqlite3_strglob("checkin/*", zPageName)==0
362368
&& db_exists("SELECT 1 FROM blob WHERE uuid=%Q",zPageName+8)
363369
){
364
- style_header("Notes About Checkin %S", zPageName + 8);
365
- style_submenu_element("Checkin Timeline","%R/timeline?f=%s",zPageName + 8);
366
- style_submenu_element("Checkin Info","%R/info/%s",zPageName + 8);
370
+ return WIKITYPE_CHECKIN;
367371
}else
368372
if( sqlite3_strglob("branch/*", zPageName)==0 ){
369
- style_header("Notes About Branch %h", zPageName + 7);
370
- style_submenu_element("Branch Timeline","%R/timeline?r=%t",zPageName + 7);
373
+ return WIKITYPE_BRANCH;
371374
}else
372375
if( sqlite3_strglob("tag/*", zPageName)==0 ){
373
- style_header("Notes About Tag %h", zPageName + 4);
374
- style_submenu_element("Tag Timeline","%R/timeline?t=%t",zPageName + 4);
376
+ return WIKITYPE_TAG;
375377
}
376
- else{
377
- style_header("%s%s", zExtra, zPageName);
378
+ return WIKITYPE_NORMAL;
379
+}
380
+
381
+/*
382
+** Add an appropriate style_header() for either the /wiki or /wikiedit page
383
+** for zPageName.
384
+*/
385
+static int wiki_page_header(
386
+ int eType, /* Page type. -1 for unknown */
387
+ const char *zPageName, /* Name of the page */
388
+ const char *zExtra /* Extra prefix text on the page header */
389
+){
390
+ if( eType<0 ) eType = wiki_page_type(zPageName);
391
+ switch( eType ){
392
+ case WIKITYPE_NORMAL: {
393
+ style_header("%s%s", zExtra, zPageName);
394
+ break;
395
+ }
396
+ case WIKITYPE_CHECKIN: {
397
+ zPageName += 8;
398
+ style_header("Notes About Checkin %S", zPageName);
399
+ style_submenu_element("Checkin Timeline","%R/timeline?f=%s", zPageName);
400
+ style_submenu_element("Checkin Info","%R/info/%s", zPageName);
401
+ break;
402
+ }
403
+ case WIKITYPE_BRANCH: {
404
+ zPageName += 7;
405
+ style_header("Notes About Branch %h", zPageName);
406
+ style_submenu_element("Branch Timeline","%R/timeline?r=%t", zPageName);
407
+ break;
408
+ }
409
+ case WIKITYPE_TAG: {
410
+ zPageName += 4;
411
+ style_header("Notes About Tag %h", zPageName);
412
+ style_submenu_element("Tag Timeline","%R/timeline?t=%t",zPageName);
413
+ break;
414
+ }
378415
}
416
+ return eType;
379417
}
380418
381419
/*
382420
** Wiki pages with special names "branch/...", "checkin/...", and "tag/..."
383421
** requires perm.Write privilege in addition to perm.WrWiki in order
@@ -464,11 +502,11 @@
464502
style_submenu_element("History", "%s/whistory?name=%T",
465503
g.zTop, zPageName);
466504
}
467505
}
468506
style_set_current_page("%T?name=%T", g.zPath, zPageName);
469
- wiki_page_header(zPageName, "");
507
+ wiki_page_header(WIKITYPE_UNKNOWN, zPageName, "");
470508
wiki_standard_submenu(submenuFlags);
471509
if( zBody[0]==0 ){
472510
@ <i>This page has been deleted</i>
473511
}else{
474512
blob_init(&wiki, zBody, -1);
@@ -546,10 +584,11 @@
546584
const char *z;
547585
char *zBody = (char*)P("w");
548586
const char *zMimetype = wiki_filter_mimetypes(P("mimetype"));
549587
int isWysiwyg = P("wysiwyg")!=0;
550588
int goodCaptcha = 1;
589
+ int eType = WIKITYPE_UNKNOWN;
551590
552591
if( P("edit-wysiwyg")!=0 ){ isWysiwyg = 1; zBody = 0; }
553592
if( P("edit-markup")!=0 ){ isWysiwyg = 0; zBody = 0; }
554593
if( zBody ){
555594
if( isWysiwyg ){
@@ -634,14 +673,14 @@
634673
if( P("cancel")!=0 ){
635674
cgi_redirectf("wiki?name=%T", zPageName);
636675
return;
637676
}
638677
if( zBody==0 ){
639
- zBody = mprintf("<i>Empty Page</i>");
678
+ zBody = mprintf("");
640679
}
641680
style_set_current_page("%T?name=%T", g.zPath, zPageName);
642
- wiki_page_header(zPageName, "Edit: ");
681
+ eType = wiki_page_header(WIKITYPE_UNKNOWN, zPageName, "Edit: ");
643682
if( rid && !isSandbox && g.perm.ApndWiki ){
644683
if( g.perm.Attach ){
645684
style_submenu_element("Attach",
646685
"%s/attachadd?page=%T&from=%s/wiki%%3fname=%T",
647686
g.zTop, zPageName, g.zTop, zPageName);
@@ -652,11 +691,11 @@
652691
if( !goodCaptcha ){
653692
@ <p class="generalError">Error: Incorrect security code.</p>
654693
}
655694
blob_zero(&wiki);
656695
blob_append(&wiki, zBody, -1);
657
- if( P("preview")!=0 ){
696
+ if( P("preview")!=0 && zBody[0] ){
658697
@ Preview:<hr />
659698
wiki_render_by_mimetype(&wiki, zMimetype);
660699
@ <hr />
661700
blob_reset(&wiki);
662701
}
@@ -665,16 +704,37 @@
665704
}
666705
if( n<20 ) n = 20;
667706
if( n>30 ) n = 30;
668707
if( !isWysiwyg ){
669708
/* Traditional markup-only editing */
709
+ char *zPlaceholder = 0;
710
+ switch( eType ){
711
+ case WIKITYPE_NORMAL: {
712
+ zPlaceholder = mprintf("Enter text for wiki page %s", zPageName);
713
+ break;
714
+ }
715
+ case WIKITYPE_BRANCH: {
716
+ zPlaceholder = mprintf("Enter notes about branch %s", zPageName+7);
717
+ break;
718
+ }
719
+ case WIKITYPE_CHECKIN: {
720
+ zPlaceholder = mprintf("Enter notes about check-in %.20s", zPageName+8);
721
+ break;
722
+ }
723
+ case WIKITYPE_TAG: {
724
+ zPlaceholder = mprintf("Enter notes about tag %s", zPageName+4);
725
+ break;
726
+ }
727
+ }
670728
form_begin(0, "%R/wikiedit");
671729
@ <div>Markup style:
672730
mimetype_option_menu(zMimetype);
673
- @ <br /><textarea name="w" class="wikiedit" cols="80"
674
- @ rows="%d(n)" wrap="virtual">%h(zBody)</textarea>
731
+ @ <br /><textarea name="w" class="wikiedit" cols="80" \
732
+ @ rows="%d(n)" wrap="virtual" placeholder="%h(zPlaceholder)">\
733
+ @ %h(zBody)</textarea>
675734
@ <br />
735
+ fossil_free(zPlaceholder);
676736
if( db_get_boolean("wysiwyg-wiki", 0) ){
677737
@ <input type="submit" name="edit-wysiwyg" value="Wysiwyg Editor"
678738
@ onclick='return confirm("Switching to WYSIWYG-mode\nwill erase your markup\nedits. Continue?")' />
679739
}
680740
@ <input type="submit" name="preview" value="Preview Your Changes" />
@@ -1555,11 +1615,13 @@
15551615
/*
15561616
** Allowed flags for wiki_render_associated
15571617
*/
15581618
#if INTERFACE
15591619
#define WIKIASSOC_FULL_TITLE 0x00001 /* Full title */
1560
-#define WIKIASSOC_MENU 0x00002 /* Add a submenu to the About section */
1620
+#define WIKIASSOC_MENU_READ 0x00002 /* Add submenu link to read wiki */
1621
+#define WIKIASSOC_MENU_WRITE 0x00004 /* Add submenu link to add wiki */
1622
+#define WIKIASSOC_ALL 0x00007 /* All of the above */
15611623
#endif
15621624
15631625
/*
15641626
** Show the default Section label for an associated wiki page.
15651627
*/
@@ -1576,18 +1638,18 @@
15761638
@ <div class="section">About %s(zPrefix) %h(zName)</div>
15771639
}
15781640
}
15791641
15801642
/*
1581
-** Add an "Wiki" button in a submenu for a Wiki page.
1643
+** Add an "Wiki" button in a submenu that links to the read-wiki page.
15821644
*/
1583
-static void wiki_section_menu(
1645
+static void wiki_submenu_to_read_wiki(
15841646
const char *zPrefix, /* "branch", "tag", or "checkin" */
15851647
const char *zName, /* Name of the object */
15861648
unsigned int mFlags /* Zero or more WIKIASSOC_* flags */
15871649
){
1588
- if( g.perm.WrWiki && (mFlags & WIKIASSOC_MENU)!=0 ){
1650
+ if( g.perm.RdWiki && (mFlags & WIKIASSOC_MENU_READ)!=0 ){
15891651
style_submenu_element("Wiki", "%R/wiki?name=%s/%t", zPrefix, zName);
15901652
}
15911653
}
15921654
15931655
/*
@@ -1609,11 +1671,16 @@
16091671
"SELECT rid FROM tagxref"
16101672
" WHERE tagid=(SELECT tagid FROM tag WHERE tagname='wiki-%q/%q')"
16111673
" ORDER BY mtime DESC LIMIT 1",
16121674
zPrefix, zName
16131675
);
1614
- if( rid==0 ) return 0;
1676
+ if( rid==0 ){
1677
+ if( g.perm.WrWiki && g.perm.Write && (mFlags & WIKIASSOC_MENU_WRITE)!=0 ){
1678
+ style_submenu_element("Add Wiki", "%R/wikiedit?name=%s/%t",
1679
+ zPrefix, zName);
1680
+ }
1681
+ }
16151682
pWiki = manifest_get(rid, CFTYPE_WIKI, 0);
16161683
if( pWiki==0 ) return 0;
16171684
if( fossil_strcmp(pWiki->zMimetype, "text/x-markdown")==0 ){
16181685
Blob tail = BLOB_INITIALIZER;
16191686
Blob title = BLOB_INITIALIZER;
@@ -1623,18 +1690,18 @@
16231690
if( blob_size(&title) ){
16241691
@ <div class="section">%h(blob_str(&title))</div>
16251692
}else{
16261693
wiki_section_label(zPrefix, zName, mFlags);
16271694
}
1628
- wiki_section_menu(zPrefix, zName, mFlags);
1695
+ wiki_submenu_to_read_wiki(zPrefix, zName, mFlags);
16291696
convert_href_and_output(&tail);
16301697
blob_reset(&tail);
16311698
blob_reset(&title);
16321699
blob_reset(&markdown);
16331700
}else if( fossil_strcmp(pWiki->zMimetype, "text/plain")==0 ){
16341701
wiki_section_label(zPrefix, zName, mFlags);
1635
- wiki_section_menu(zPrefix, zName, mFlags);
1702
+ wiki_submenu_to_read_wiki(zPrefix, zName, mFlags);
16361703
@ <pre>
16371704
@ %h(pWiki->zWiki)
16381705
@ </pre>
16391706
}else{
16401707
Blob tail = BLOB_INITIALIZER;
@@ -1647,11 +1714,11 @@
16471714
pBody = &tail;
16481715
}else{
16491716
wiki_section_label(zPrefix, zName, mFlags);
16501717
pBody = &wiki;
16511718
}
1652
- wiki_section_menu(zPrefix, zName, mFlags);
1719
+ wiki_submenu_to_read_wiki(zPrefix, zName, mFlags);
16531720
@ <div class="wiki">
16541721
wiki_convert(pBody, 0, WIKI_BUTTONS);
16551722
@ </div>
16561723
blob_reset(&tail);
16571724
blob_reset(&title);
16581725
--- src/wiki.c
+++ src/wiki.c
@@ -348,36 +348,74 @@
348 wiki_standard_submenu(W_HELP|W_LIST|W_SANDBOX);
349 search_screen(SRCH_WIKI, 0);
350 style_footer();
351 }
352
 
 
 
 
 
 
 
353 /*
354 ** Add an appropriate style_header() for either the /wiki or /wikiedit page
355 ** for zPageName.
356 */
357 static void wiki_page_header(const char *zPageName, const char *zExtra){
358 if( db_get_boolean("wiki-about",1)==0 ){
359 style_header("%s%s", zExtra, zPageName);
360 }else
361 if( sqlite3_strglob("checkin/*", zPageName)==0
362 && db_exists("SELECT 1 FROM blob WHERE uuid=%Q",zPageName+8)
363 ){
364 style_header("Notes About Checkin %S", zPageName + 8);
365 style_submenu_element("Checkin Timeline","%R/timeline?f=%s",zPageName + 8);
366 style_submenu_element("Checkin Info","%R/info/%s",zPageName + 8);
367 }else
368 if( sqlite3_strglob("branch/*", zPageName)==0 ){
369 style_header("Notes About Branch %h", zPageName + 7);
370 style_submenu_element("Branch Timeline","%R/timeline?r=%t",zPageName + 7);
371 }else
372 if( sqlite3_strglob("tag/*", zPageName)==0 ){
373 style_header("Notes About Tag %h", zPageName + 4);
374 style_submenu_element("Tag Timeline","%R/timeline?t=%t",zPageName + 4);
375 }
376 else{
377 style_header("%s%s", zExtra, zPageName);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
378 }
 
379 }
380
381 /*
382 ** Wiki pages with special names "branch/...", "checkin/...", and "tag/..."
383 ** requires perm.Write privilege in addition to perm.WrWiki in order
@@ -464,11 +502,11 @@
464 style_submenu_element("History", "%s/whistory?name=%T",
465 g.zTop, zPageName);
466 }
467 }
468 style_set_current_page("%T?name=%T", g.zPath, zPageName);
469 wiki_page_header(zPageName, "");
470 wiki_standard_submenu(submenuFlags);
471 if( zBody[0]==0 ){
472 @ <i>This page has been deleted</i>
473 }else{
474 blob_init(&wiki, zBody, -1);
@@ -546,10 +584,11 @@
546 const char *z;
547 char *zBody = (char*)P("w");
548 const char *zMimetype = wiki_filter_mimetypes(P("mimetype"));
549 int isWysiwyg = P("wysiwyg")!=0;
550 int goodCaptcha = 1;
 
551
552 if( P("edit-wysiwyg")!=0 ){ isWysiwyg = 1; zBody = 0; }
553 if( P("edit-markup")!=0 ){ isWysiwyg = 0; zBody = 0; }
554 if( zBody ){
555 if( isWysiwyg ){
@@ -634,14 +673,14 @@
634 if( P("cancel")!=0 ){
635 cgi_redirectf("wiki?name=%T", zPageName);
636 return;
637 }
638 if( zBody==0 ){
639 zBody = mprintf("<i>Empty Page</i>");
640 }
641 style_set_current_page("%T?name=%T", g.zPath, zPageName);
642 wiki_page_header(zPageName, "Edit: ");
643 if( rid && !isSandbox && g.perm.ApndWiki ){
644 if( g.perm.Attach ){
645 style_submenu_element("Attach",
646 "%s/attachadd?page=%T&from=%s/wiki%%3fname=%T",
647 g.zTop, zPageName, g.zTop, zPageName);
@@ -652,11 +691,11 @@
652 if( !goodCaptcha ){
653 @ <p class="generalError">Error: Incorrect security code.</p>
654 }
655 blob_zero(&wiki);
656 blob_append(&wiki, zBody, -1);
657 if( P("preview")!=0 ){
658 @ Preview:<hr />
659 wiki_render_by_mimetype(&wiki, zMimetype);
660 @ <hr />
661 blob_reset(&wiki);
662 }
@@ -665,16 +704,37 @@
665 }
666 if( n<20 ) n = 20;
667 if( n>30 ) n = 30;
668 if( !isWysiwyg ){
669 /* Traditional markup-only editing */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
670 form_begin(0, "%R/wikiedit");
671 @ <div>Markup style:
672 mimetype_option_menu(zMimetype);
673 @ <br /><textarea name="w" class="wikiedit" cols="80"
674 @ rows="%d(n)" wrap="virtual">%h(zBody)</textarea>
 
675 @ <br />
 
676 if( db_get_boolean("wysiwyg-wiki", 0) ){
677 @ <input type="submit" name="edit-wysiwyg" value="Wysiwyg Editor"
678 @ onclick='return confirm("Switching to WYSIWYG-mode\nwill erase your markup\nedits. Continue?")' />
679 }
680 @ <input type="submit" name="preview" value="Preview Your Changes" />
@@ -1555,11 +1615,13 @@
1555 /*
1556 ** Allowed flags for wiki_render_associated
1557 */
1558 #if INTERFACE
1559 #define WIKIASSOC_FULL_TITLE 0x00001 /* Full title */
1560 #define WIKIASSOC_MENU 0x00002 /* Add a submenu to the About section */
 
 
1561 #endif
1562
1563 /*
1564 ** Show the default Section label for an associated wiki page.
1565 */
@@ -1576,18 +1638,18 @@
1576 @ <div class="section">About %s(zPrefix) %h(zName)</div>
1577 }
1578 }
1579
1580 /*
1581 ** Add an "Wiki" button in a submenu for a Wiki page.
1582 */
1583 static void wiki_section_menu(
1584 const char *zPrefix, /* "branch", "tag", or "checkin" */
1585 const char *zName, /* Name of the object */
1586 unsigned int mFlags /* Zero or more WIKIASSOC_* flags */
1587 ){
1588 if( g.perm.WrWiki && (mFlags & WIKIASSOC_MENU)!=0 ){
1589 style_submenu_element("Wiki", "%R/wiki?name=%s/%t", zPrefix, zName);
1590 }
1591 }
1592
1593 /*
@@ -1609,11 +1671,16 @@
1609 "SELECT rid FROM tagxref"
1610 " WHERE tagid=(SELECT tagid FROM tag WHERE tagname='wiki-%q/%q')"
1611 " ORDER BY mtime DESC LIMIT 1",
1612 zPrefix, zName
1613 );
1614 if( rid==0 ) return 0;
 
 
 
 
 
1615 pWiki = manifest_get(rid, CFTYPE_WIKI, 0);
1616 if( pWiki==0 ) return 0;
1617 if( fossil_strcmp(pWiki->zMimetype, "text/x-markdown")==0 ){
1618 Blob tail = BLOB_INITIALIZER;
1619 Blob title = BLOB_INITIALIZER;
@@ -1623,18 +1690,18 @@
1623 if( blob_size(&title) ){
1624 @ <div class="section">%h(blob_str(&title))</div>
1625 }else{
1626 wiki_section_label(zPrefix, zName, mFlags);
1627 }
1628 wiki_section_menu(zPrefix, zName, mFlags);
1629 convert_href_and_output(&tail);
1630 blob_reset(&tail);
1631 blob_reset(&title);
1632 blob_reset(&markdown);
1633 }else if( fossil_strcmp(pWiki->zMimetype, "text/plain")==0 ){
1634 wiki_section_label(zPrefix, zName, mFlags);
1635 wiki_section_menu(zPrefix, zName, mFlags);
1636 @ <pre>
1637 @ %h(pWiki->zWiki)
1638 @ </pre>
1639 }else{
1640 Blob tail = BLOB_INITIALIZER;
@@ -1647,11 +1714,11 @@
1647 pBody = &tail;
1648 }else{
1649 wiki_section_label(zPrefix, zName, mFlags);
1650 pBody = &wiki;
1651 }
1652 wiki_section_menu(zPrefix, zName, mFlags);
1653 @ <div class="wiki">
1654 wiki_convert(pBody, 0, WIKI_BUTTONS);
1655 @ </div>
1656 blob_reset(&tail);
1657 blob_reset(&title);
1658
--- src/wiki.c
+++ src/wiki.c
@@ -348,36 +348,74 @@
348 wiki_standard_submenu(W_HELP|W_LIST|W_SANDBOX);
349 search_screen(SRCH_WIKI, 0);
350 style_footer();
351 }
352
353 /* Return values from wiki_page_type() */
354 #define WIKITYPE_UNKNOWN (-1)
355 #define WIKITYPE_NORMAL 0
356 #define WIKITYPE_BRANCH 1
357 #define WIKITYPE_CHECKIN 2
358 #define WIKITYPE_TAG 3
359
360 /*
361 ** Figure out what type of wiki page we are dealing with.
 
362 */
363 static int wiki_page_type(const char *zPageName){
364 if( db_get_boolean("wiki-about",1)==0 ){
365 return WIKITYPE_NORMAL;
366 }else
367 if( sqlite3_strglob("checkin/*", zPageName)==0
368 && db_exists("SELECT 1 FROM blob WHERE uuid=%Q",zPageName+8)
369 ){
370 return WIKITYPE_CHECKIN;
 
 
371 }else
372 if( sqlite3_strglob("branch/*", zPageName)==0 ){
373 return WIKITYPE_BRANCH;
 
374 }else
375 if( sqlite3_strglob("tag/*", zPageName)==0 ){
376 return WIKITYPE_TAG;
 
377 }
378 return WIKITYPE_NORMAL;
379 }
380
381 /*
382 ** Add an appropriate style_header() for either the /wiki or /wikiedit page
383 ** for zPageName.
384 */
385 static int wiki_page_header(
386 int eType, /* Page type. -1 for unknown */
387 const char *zPageName, /* Name of the page */
388 const char *zExtra /* Extra prefix text on the page header */
389 ){
390 if( eType<0 ) eType = wiki_page_type(zPageName);
391 switch( eType ){
392 case WIKITYPE_NORMAL: {
393 style_header("%s%s", zExtra, zPageName);
394 break;
395 }
396 case WIKITYPE_CHECKIN: {
397 zPageName += 8;
398 style_header("Notes About Checkin %S", zPageName);
399 style_submenu_element("Checkin Timeline","%R/timeline?f=%s", zPageName);
400 style_submenu_element("Checkin Info","%R/info/%s", zPageName);
401 break;
402 }
403 case WIKITYPE_BRANCH: {
404 zPageName += 7;
405 style_header("Notes About Branch %h", zPageName);
406 style_submenu_element("Branch Timeline","%R/timeline?r=%t", zPageName);
407 break;
408 }
409 case WIKITYPE_TAG: {
410 zPageName += 4;
411 style_header("Notes About Tag %h", zPageName);
412 style_submenu_element("Tag Timeline","%R/timeline?t=%t",zPageName);
413 break;
414 }
415 }
416 return eType;
417 }
418
419 /*
420 ** Wiki pages with special names "branch/...", "checkin/...", and "tag/..."
421 ** requires perm.Write privilege in addition to perm.WrWiki in order
@@ -464,11 +502,11 @@
502 style_submenu_element("History", "%s/whistory?name=%T",
503 g.zTop, zPageName);
504 }
505 }
506 style_set_current_page("%T?name=%T", g.zPath, zPageName);
507 wiki_page_header(WIKITYPE_UNKNOWN, zPageName, "");
508 wiki_standard_submenu(submenuFlags);
509 if( zBody[0]==0 ){
510 @ <i>This page has been deleted</i>
511 }else{
512 blob_init(&wiki, zBody, -1);
@@ -546,10 +584,11 @@
584 const char *z;
585 char *zBody = (char*)P("w");
586 const char *zMimetype = wiki_filter_mimetypes(P("mimetype"));
587 int isWysiwyg = P("wysiwyg")!=0;
588 int goodCaptcha = 1;
589 int eType = WIKITYPE_UNKNOWN;
590
591 if( P("edit-wysiwyg")!=0 ){ isWysiwyg = 1; zBody = 0; }
592 if( P("edit-markup")!=0 ){ isWysiwyg = 0; zBody = 0; }
593 if( zBody ){
594 if( isWysiwyg ){
@@ -634,14 +673,14 @@
673 if( P("cancel")!=0 ){
674 cgi_redirectf("wiki?name=%T", zPageName);
675 return;
676 }
677 if( zBody==0 ){
678 zBody = mprintf("");
679 }
680 style_set_current_page("%T?name=%T", g.zPath, zPageName);
681 eType = wiki_page_header(WIKITYPE_UNKNOWN, zPageName, "Edit: ");
682 if( rid && !isSandbox && g.perm.ApndWiki ){
683 if( g.perm.Attach ){
684 style_submenu_element("Attach",
685 "%s/attachadd?page=%T&from=%s/wiki%%3fname=%T",
686 g.zTop, zPageName, g.zTop, zPageName);
@@ -652,11 +691,11 @@
691 if( !goodCaptcha ){
692 @ <p class="generalError">Error: Incorrect security code.</p>
693 }
694 blob_zero(&wiki);
695 blob_append(&wiki, zBody, -1);
696 if( P("preview")!=0 && zBody[0] ){
697 @ Preview:<hr />
698 wiki_render_by_mimetype(&wiki, zMimetype);
699 @ <hr />
700 blob_reset(&wiki);
701 }
@@ -665,16 +704,37 @@
704 }
705 if( n<20 ) n = 20;
706 if( n>30 ) n = 30;
707 if( !isWysiwyg ){
708 /* Traditional markup-only editing */
709 char *zPlaceholder = 0;
710 switch( eType ){
711 case WIKITYPE_NORMAL: {
712 zPlaceholder = mprintf("Enter text for wiki page %s", zPageName);
713 break;
714 }
715 case WIKITYPE_BRANCH: {
716 zPlaceholder = mprintf("Enter notes about branch %s", zPageName+7);
717 break;
718 }
719 case WIKITYPE_CHECKIN: {
720 zPlaceholder = mprintf("Enter notes about check-in %.20s", zPageName+8);
721 break;
722 }
723 case WIKITYPE_TAG: {
724 zPlaceholder = mprintf("Enter notes about tag %s", zPageName+4);
725 break;
726 }
727 }
728 form_begin(0, "%R/wikiedit");
729 @ <div>Markup style:
730 mimetype_option_menu(zMimetype);
731 @ <br /><textarea name="w" class="wikiedit" cols="80" \
732 @ rows="%d(n)" wrap="virtual" placeholder="%h(zPlaceholder)">\
733 @ %h(zBody)</textarea>
734 @ <br />
735 fossil_free(zPlaceholder);
736 if( db_get_boolean("wysiwyg-wiki", 0) ){
737 @ <input type="submit" name="edit-wysiwyg" value="Wysiwyg Editor"
738 @ onclick='return confirm("Switching to WYSIWYG-mode\nwill erase your markup\nedits. Continue?")' />
739 }
740 @ <input type="submit" name="preview" value="Preview Your Changes" />
@@ -1555,11 +1615,13 @@
1615 /*
1616 ** Allowed flags for wiki_render_associated
1617 */
1618 #if INTERFACE
1619 #define WIKIASSOC_FULL_TITLE 0x00001 /* Full title */
1620 #define WIKIASSOC_MENU_READ 0x00002 /* Add submenu link to read wiki */
1621 #define WIKIASSOC_MENU_WRITE 0x00004 /* Add submenu link to add wiki */
1622 #define WIKIASSOC_ALL 0x00007 /* All of the above */
1623 #endif
1624
1625 /*
1626 ** Show the default Section label for an associated wiki page.
1627 */
@@ -1576,18 +1638,18 @@
1638 @ <div class="section">About %s(zPrefix) %h(zName)</div>
1639 }
1640 }
1641
1642 /*
1643 ** Add an "Wiki" button in a submenu that links to the read-wiki page.
1644 */
1645 static void wiki_submenu_to_read_wiki(
1646 const char *zPrefix, /* "branch", "tag", or "checkin" */
1647 const char *zName, /* Name of the object */
1648 unsigned int mFlags /* Zero or more WIKIASSOC_* flags */
1649 ){
1650 if( g.perm.RdWiki && (mFlags & WIKIASSOC_MENU_READ)!=0 ){
1651 style_submenu_element("Wiki", "%R/wiki?name=%s/%t", zPrefix, zName);
1652 }
1653 }
1654
1655 /*
@@ -1609,11 +1671,16 @@
1671 "SELECT rid FROM tagxref"
1672 " WHERE tagid=(SELECT tagid FROM tag WHERE tagname='wiki-%q/%q')"
1673 " ORDER BY mtime DESC LIMIT 1",
1674 zPrefix, zName
1675 );
1676 if( rid==0 ){
1677 if( g.perm.WrWiki && g.perm.Write && (mFlags & WIKIASSOC_MENU_WRITE)!=0 ){
1678 style_submenu_element("Add Wiki", "%R/wikiedit?name=%s/%t",
1679 zPrefix, zName);
1680 }
1681 }
1682 pWiki = manifest_get(rid, CFTYPE_WIKI, 0);
1683 if( pWiki==0 ) return 0;
1684 if( fossil_strcmp(pWiki->zMimetype, "text/x-markdown")==0 ){
1685 Blob tail = BLOB_INITIALIZER;
1686 Blob title = BLOB_INITIALIZER;
@@ -1623,18 +1690,18 @@
1690 if( blob_size(&title) ){
1691 @ <div class="section">%h(blob_str(&title))</div>
1692 }else{
1693 wiki_section_label(zPrefix, zName, mFlags);
1694 }
1695 wiki_submenu_to_read_wiki(zPrefix, zName, mFlags);
1696 convert_href_and_output(&tail);
1697 blob_reset(&tail);
1698 blob_reset(&title);
1699 blob_reset(&markdown);
1700 }else if( fossil_strcmp(pWiki->zMimetype, "text/plain")==0 ){
1701 wiki_section_label(zPrefix, zName, mFlags);
1702 wiki_submenu_to_read_wiki(zPrefix, zName, mFlags);
1703 @ <pre>
1704 @ %h(pWiki->zWiki)
1705 @ </pre>
1706 }else{
1707 Blob tail = BLOB_INITIALIZER;
@@ -1647,11 +1714,11 @@
1714 pBody = &tail;
1715 }else{
1716 wiki_section_label(zPrefix, zName, mFlags);
1717 pBody = &wiki;
1718 }
1719 wiki_submenu_to_read_wiki(zPrefix, zName, mFlags);
1720 @ <div class="wiki">
1721 wiki_convert(pBody, 0, WIKI_BUTTONS);
1722 @ </div>
1723 blob_reset(&tail);
1724 blob_reset(&title);
1725

Keyboard Shortcuts

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