Fossil SCM

Style improvements and code consolidation.

stephan 2020-05-04 16:22 checkin-without-checkout
Commit 67a2bfb0dc85711aff3a31118faec363a8bd4bd55ed58cfb7a145e554629647d
2 files changed +32 -10 +133 -58
--- src/default_css.txt
+++ src/default_css.txt
@@ -861,26 +861,35 @@
861861
// #setup_skinedit_css_defaults > tbody > tr > td:nth-of-type(2) > div {
862862
// max-width: 30em;
863863
// overflow: auto;
864864
// }
865865
// .fileedit-XXX => /fileedit page
866
-.fileedit-form textarea {
866
+form.fileedit textarea {
867867
font-family: monospace;
868868
width: 100%;
869869
}
870
-.fileedit-form fieldset {
870
+form.fileedit fieldset {
871
+ margin: 0.5em 0 0 0;
871872
border-radius: 0.5em;
873
+ border-color: inherit;
874
+ border-width: 1px;
875
+}
876
+form.fileedit fieldset > legend {
877
+ margin-left: 1em;
878
+}
879
+form.fileedit fieldset > div {
880
+ margin: 0 0.25em;
872881
}
873
-.fileedit-form .fileedit-options {
882
+form.fileedit fieldset > div > .input-with-label {
874883
padding: 0.5em;
875
- margin: 1em 0 0 0;
884
+ margin: 0.25em 0.5em;
876885
}
877
-.fileedit-form .fileedit-buttons > div > * {
878
- margin: 0 0.25em 0.25em 0.25em;
886
+form.fileedit fieldset > div > button {
887
+ margin: 0.25em 0.5em;
879888
}
880
-.fileedit-form .fileedit-options > div > * {
881
- margin: 0 0.25em 0.25em 0.25em;
889
+form.fileedit input:invalid {
890
+ border-left: 0.2em dashed red;
882891
}
883892
.fileedit-hint {
884893
font-size: 80%;
885894
opacity: 0.75;
886895
}
@@ -901,26 +910,39 @@
901910
padding: 0;
902911
}
903912
.fileedit-preview > div:first-child {
904913
border-bottom: 1px dashed;
905914
}
915
+
906916
.input-with-label {
907917
border: 1px inset #808080;
908918
border-radius: 0.5em;
909919
padding: 0.25em 0.4em;
910920
margin: 0 0.5em;
911921
display: inline-block;
912922
cursor: pointer;
913923
}
924
+.input-with-label > * {
925
+ vertical-align: middle;
926
+}
914927
.input-with-label > input {
915928
margin: 0;
929
+}
930
+.input-with-label > select {
931
+ margin: 0;
932
+}
933
+.input-with-label > input[type=text] {
934
+ margin: 0;
935
+}
936
+.input-with-label > textarea {
937
+ margin: 0;
916938
}
917939
.input-with-label > input[type=checkbox] {
918940
vertical-align: sub;
919941
}
920942
.input-with-label > input[type=radio] {
921943
vertical-align: sub;
922944
}
923945
.input-with-label > span {
924
- margin: 0 0 0 0.4em;
925
- vertical-align: text-bottom;
946
+ margin: 0 0.25em 0 0.25em;
947
+ vertical-align: middle;
926948
}
927949
--- src/default_css.txt
+++ src/default_css.txt
@@ -861,26 +861,35 @@
861 // #setup_skinedit_css_defaults > tbody > tr > td:nth-of-type(2) > div {
862 // max-width: 30em;
863 // overflow: auto;
864 // }
865 // .fileedit-XXX => /fileedit page
866 .fileedit-form textarea {
867 font-family: monospace;
868 width: 100%;
869 }
870 .fileedit-form fieldset {
 
871 border-radius: 0.5em;
 
 
 
 
 
 
 
 
872 }
873 .fileedit-form .fileedit-options {
874 padding: 0.5em;
875 margin: 1em 0 0 0;
876 }
877 .fileedit-form .fileedit-buttons > div > * {
878 margin: 0 0.25em 0.25em 0.25em;
879 }
880 .fileedit-form .fileedit-options > div > * {
881 margin: 0 0.25em 0.25em 0.25em;
882 }
883 .fileedit-hint {
884 font-size: 80%;
885 opacity: 0.75;
886 }
@@ -901,26 +910,39 @@
901 padding: 0;
902 }
903 .fileedit-preview > div:first-child {
904 border-bottom: 1px dashed;
905 }
 
906 .input-with-label {
907 border: 1px inset #808080;
908 border-radius: 0.5em;
909 padding: 0.25em 0.4em;
910 margin: 0 0.5em;
911 display: inline-block;
912 cursor: pointer;
913 }
 
 
 
914 .input-with-label > input {
915 margin: 0;
 
 
 
 
 
 
 
 
 
916 }
917 .input-with-label > input[type=checkbox] {
918 vertical-align: sub;
919 }
920 .input-with-label > input[type=radio] {
921 vertical-align: sub;
922 }
923 .input-with-label > span {
924 margin: 0 0 0 0.4em;
925 vertical-align: text-bottom;
926 }
927
--- src/default_css.txt
+++ src/default_css.txt
@@ -861,26 +861,35 @@
861 // #setup_skinedit_css_defaults > tbody > tr > td:nth-of-type(2) > div {
862 // max-width: 30em;
863 // overflow: auto;
864 // }
865 // .fileedit-XXX => /fileedit page
866 form.fileedit textarea {
867 font-family: monospace;
868 width: 100%;
869 }
870 form.fileedit fieldset {
871 margin: 0.5em 0 0 0;
872 border-radius: 0.5em;
873 border-color: inherit;
874 border-width: 1px;
875 }
876 form.fileedit fieldset > legend {
877 margin-left: 1em;
878 }
879 form.fileedit fieldset > div {
880 margin: 0 0.25em;
881 }
882 form.fileedit fieldset > div > .input-with-label {
883 padding: 0.5em;
884 margin: 0.25em 0.5em;
885 }
886 form.fileedit fieldset > div > button {
887 margin: 0.25em 0.5em;
888 }
889 form.fileedit input:invalid {
890 border-left: 0.2em dashed red;
891 }
892 .fileedit-hint {
893 font-size: 80%;
894 opacity: 0.75;
895 }
@@ -901,26 +910,39 @@
910 padding: 0;
911 }
912 .fileedit-preview > div:first-child {
913 border-bottom: 1px dashed;
914 }
915
916 .input-with-label {
917 border: 1px inset #808080;
918 border-radius: 0.5em;
919 padding: 0.25em 0.4em;
920 margin: 0 0.5em;
921 display: inline-block;
922 cursor: pointer;
923 }
924 .input-with-label > * {
925 vertical-align: middle;
926 }
927 .input-with-label > input {
928 margin: 0;
929 }
930 .input-with-label > select {
931 margin: 0;
932 }
933 .input-with-label > input[type=text] {
934 margin: 0;
935 }
936 .input-with-label > textarea {
937 margin: 0;
938 }
939 .input-with-label > input[type=checkbox] {
940 vertical-align: sub;
941 }
942 .input-with-label > input[type=radio] {
943 vertical-align: sub;
944 }
945 .input-with-label > span {
946 margin: 0 0.25em 0 0.25em;
947 vertical-align: middle;
948 }
949
+133 -58
--- src/fileedit.c
+++ src/fileedit.c
@@ -18,10 +18,11 @@
1818
** This file contains code for the /fileedit page and related code.
1919
*/
2020
#include "config.h"
2121
#include "fileedit.h"
2222
#include <assert.h>
23
+#include <stdarg.h>
2324
2425
/*
2526
** State for the "mini-checkin" infrastructure, which enables the
2627
** ability to commit changes to a single file without a checkout
2728
** db, e.g. for use via an HTTP request.
@@ -40,11 +41,11 @@
4041
relative to the top of the repo. */
4142
Blob fileContent; /* Content of file referred to by zFilename. */
4243
Blob fileHash; /* Hash of this->fileContent, using the repo's
4344
preferred hash method. */
4445
Blob comment; /* Check-in comment text */
45
- char *zMimetype; /* Mimetype of comment. May be NULL */
46
+ char *zCommentMimetype; /* Mimetype of comment. May be NULL */
4647
char *zUser; /* User name */
4748
char *zDate; /* Optionally force this date string (anything
4849
supported by date_in_standard_format()).
4950
Maybe be NULL. */
5051
Blob *pMfOut; /* If not NULL, checkin_mini() will write a
@@ -160,11 +161,11 @@
160161
manifest_destroy(p->pParent);
161162
}
162163
fossil_free(p->zFilename);
163164
fossil_free(p->zDate);
164165
fossil_free(p->zParentUuid);
165
- fossil_free(p->zMimetype);
166
+ fossil_free(p->zCommentMimetype);
166167
fossil_free(p->zUser);
167168
CheckinMiniInfo_init(p);
168169
}
169170
170171
/*
@@ -370,12 +371,12 @@
370371
}
371372
blob_appendf(pOut, "D %s\n", pCI->zDate);
372373
if(create_manifest_mini_fcards(pOut,pCI,asDelta,pErr)==0){
373374
return 0;
374375
}
375
- if(pCI->zMimetype!=0 && pCI->zMimetype[0]!=0){
376
- blob_appendf(pOut, "N %F\n", pCI->zMimetype);
376
+ if(pCI->zCommentMimetype!=0 && pCI->zCommentMimetype[0]!=0){
377
+ blob_appendf(pOut, "N %F\n", pCI->zCommentMimetype);
377378
}
378379
blob_appendf(pOut, "P %s\n", pCI->zParentUuid);
379380
blob_appendf(pOut, "U %F\n", pCI->zUser);
380381
md5sum_blob(pOut, &zCard);
381382
blob_appendf(pOut, "Z %b\n", &zCard);
@@ -979,18 +980,18 @@
979980
static void style_labeled_checkbox(const char *zFieldName,
980981
const char * zLabel,
981982
const char * zValue,
982983
const char * zTip,
983984
int isChecked){
984
- CX("<span class='input-with-label'");
985
+ CX("<div class='input-with-label'");
985986
if(zTip && *zTip){
986987
CX(" title='%h'", zTip);
987988
}
988989
CX("><input type='checkbox' name='%s' value='%T'%s/>",
989990
zFieldName,
990991
zValue ? zValue : "", isChecked ? " checked" : "");
991
- CX("<span>%h</span></span>", zLabel);
992
+ CX("<span>%h</span></div>", zLabel);
992993
}
993994
994995
enum fileedit_render_preview_flags {
995996
FE_PREVIEW_LINE_NUMBERS = 1
996997
};
@@ -1056,10 +1057,90 @@
10561057
break;
10571058
}
10581059
}
10591060
CX("</div><!--.fileedit-preview-->\n");
10601061
}
1062
+
1063
+/*
1064
+** Outputs a SELECT list from a compile-time list of integers.
1065
+** The vargs must be a list of (const char *, int) pairs, terminated
1066
+** with a single NULL. Each pair is interpreted as...
1067
+**
1068
+** If the (const char *) is NULL, it is the end of the list, else
1069
+** a new OPTION entry is created. If the string is empty, the
1070
+** label and value of the OPTION is the integer part of the pair.
1071
+** If the string is not empty, it becomes the label and the integer
1072
+** the value. If that value == selectedValue then that OPTION
1073
+** element gets the 'selected' attribute.
1074
+**
1075
+** Note that the pairs are not in (int, const char *) order because
1076
+** there is no well-known integer value which we can definitively use
1077
+** as a list terminator.
1078
+**
1079
+** zFieldName is the value of the form element's name attribute.
1080
+**
1081
+** zLabel is an optional string to use as a "label" for the element
1082
+** (see below).
1083
+**
1084
+** zTooltip is an optional value for the SELECT's title attribute.
1085
+**
1086
+** The structure of the emited HTML is:
1087
+**
1088
+** <div class='input-with-label'>
1089
+** <span>{{zLabel}}</span>
1090
+** <select>...</select>
1091
+** </div>
1092
+**
1093
+*/
1094
+static void style_select_list_int_v(const char *zFieldName,
1095
+ const char * zLabel,
1096
+ const char * zToolTip,
1097
+ int selectedVal, va_list vargs){
1098
+ CX("<div class='input-with-label'");
1099
+ if(zToolTip && *zToolTip){
1100
+ CX(" title='%h'",zToolTip);
1101
+ }
1102
+ CX(">");
1103
+ if(zLabel && *zLabel){
1104
+ CX("<span>%h</span>", zLabel);
1105
+ }
1106
+ CX("<select name='%s'>",zFieldName);
1107
+ while(1){
1108
+ const char * zOption = va_arg(vargs,char *);
1109
+ int v;
1110
+ if(NULL==zOption){
1111
+ break;
1112
+ }
1113
+ v = va_arg(vargs,int);
1114
+ CX("<option value='%d'%s>",
1115
+ v, v==selectedVal ? " selected" : "");
1116
+ if(*zOption){
1117
+ CX("%s", zOption);
1118
+ }else{
1119
+ CX("%d",v);
1120
+ }
1121
+ CX("</option>\n");
1122
+ }
1123
+ CX("</select>\n");
1124
+ if(zLabel && *zLabel){
1125
+ CX("</div>\n");
1126
+ }
1127
+}
1128
+
1129
+/*
1130
+** The ellipsis-args counterpart of style_select_list_int_v().
1131
+*/
1132
+void style_select_list_int(const char *zFieldName,
1133
+ const char * zLabel,
1134
+ const char * zToolTip,
1135
+ int selectedVal, ... ){
1136
+ va_list vargs;
1137
+ va_start(vargs,selectedVal);
1138
+ style_select_list_int_v(zFieldName, zLabel, zToolTip,
1139
+ selectedVal, vargs);
1140
+ va_end(vargs);
1141
+}
10611142
10621143
/*
10631144
** WEBPAGE: fileedit
10641145
**
10651146
** EXPERIMENTAL and subject to change and removal at any time. The goal
@@ -1139,11 +1220,11 @@
11391220
if(submitMode < SUBMIT_NONE || submitMode > SUBMIT_DIFF){
11401221
submitMode = 0;
11411222
}
11421223
zFlagCheck = P("comment_mimetype");
11431224
if(zFlagCheck){
1144
- cimi.zMimetype = mprintf("%s",zFlagCheck);
1225
+ cimi.zCommentMimetype = mprintf("%s",zFlagCheck);
11451226
zFlagCheck = 0;
11461227
}
11471228
cimi.zUser = mprintf("%s",g.zLogin);
11481229
11491230
style_header("File Editor");
@@ -1226,28 +1307,18 @@
12261307
CX("<p>This page is <em>far from complete</em> and may still have "
12271308
"significant bugs. USE AT YOUR OWN RISK, preferably on a test "
12281309
"repo.</p>\n");
12291310
12301311
CX("<form action='%R/fileedit#options' method='POST' "
1231
- "class='fileedit-form'>\n");
1312
+ "class='fileedit'>\n");
12321313
12331314
/******* Hidden fields *******/
12341315
CX("<input type='hidden' name='r' value='%s'>",
12351316
cimi.zParentUuid);
12361317
CX("<input type='hidden' name='file' value='%T'>",
12371318
zFilename);
12381319
1239
- /******* Comment *******/
1240
- CX("<h3>Checkin Comment</h3>\n");
1241
- CX("<textarea name='comment' rows='3' cols='80'>");
1242
- if(zComment && *zComment){
1243
- CX("%h"/*%h? %s?*/, zComment);
1244
- }
1245
- CX("</textarea>\n");
1246
- CX("<div class='fileedit-hint'>Comments use the Fossil wiki markup "
1247
- "syntax.</div>"/*TODO: radiobuttons for fossil/me/plain text*/);
1248
-
12491320
/******* Content *******/
12501321
CX("<h3>File Content</h3>\n");
12511322
CX("<textarea name='content' id='fileedit-content' "
12521323
"rows='20' cols='80'>");
12531324
if(0==loadMode){
@@ -1319,76 +1390,78 @@
13191390
switch(eolMode){
13201391
case 1: cimi.flags |= CIMINI_CONVERT_EOL_UNIX; break;
13211392
case 2: cimi.flags |= CIMINI_CONVERT_EOL_WINDOWS; break;
13221393
default: cimi.flags |= CIMINI_CONVERT_EOL_INHERIT; break;
13231394
}
1324
- CX("<select name='eol' "
1325
- "title='EOL conversion policy, noting that form-processing "
1326
- "may implicitly change the line endings of the input.'>");
1327
- CX("<option value='0'%s>Inherit EOLs</option>",
1328
- (eolMode!=1 && eolMode!=2) ? " selected" : "");
1329
- CX("<option value='1'%s/>Unix EOLs</option>",
1330
- eolMode==1 ? " selected" : "");
1331
- CX("<option value='2'%s>Windows EOLs</option>",
1332
- eolMode==2 ? " selected" : "");
1333
- CX("</select>");
1395
+ style_select_list_int("eol", "EOL Style",
1396
+ "EOL conversion policy, noting that "
1397
+ "form-processing may implicitly change the "
1398
+ "line endings of the input.",
1399
+ eolMode==1||eolMode==2 ? eolMode : 0,
1400
+ "Inherit", 0,
1401
+ "Unix", 1,
1402
+ "Windows", 2,
1403
+ NULL);
13341404
}
13351405
13361406
CX("</div></fieldset>") /* end of checkboxes */;
13371407
1408
+ /******* Comment *******/
1409
+ CX("<a id='comment'></a>");
1410
+ CX("<fieldset><legend>Commit message</legend><div>");
1411
+ CX("<textarea name='comment' rows='3' cols='80'>");
1412
+ /* ^^^ adding the 'required' attribute means we cannot even submit
1413
+ ** for PREVIEW mode if it's empty :/. */
1414
+ if(zComment && *zComment){
1415
+ CX("%h"/*%h? %s?*/, zComment);
1416
+ }
1417
+ CX("</textarea>\n");
1418
+ CX("<div class='fileedit-hint'>Comments use the Fossil wiki markup "
1419
+ "syntax.</div>\n"/*TODO: select for fossil/md/plain text*/);
1420
+ CX("</div></fieldset>\n");
1421
+
1422
+
1423
+
13381424
/******* Buttons *******/
13391425
CX("<a id='buttons'></a>");
13401426
CX("<fieldset class='fileedit-options'>"
13411427
"<legend>Tell the server to...</legend><div>");
13421428
CX("<button type='submit' name='submit' value='1'>"
13431429
"Save</button>");
13441430
CX("<button type='submit' name='submit' value='2'>"
13451431
"Preview</button>");
1346
- CX("<button type='submit' name='submit' value='3'>"
1347
- "Diff (TODO)</button>");
13481432
{
13491433
/* Preview rendering mode selection... */
13501434
previewRenderMode = atoi(PD("preview_render_mode","0"));
13511435
if(0==previewRenderMode){
13521436
previewRenderMode = fileedit_render_mode_for_mimetype(zFileMime);
13531437
}
1354
- CX("<br>");
1355
- CX("<select name='preview_render_mode'>\n");
1356
- CX("<option value='%d' disabled>Preview Mode</option>",
1357
- FE_RENDER_GUESS);
1358
- CX("<option value='%d'%s>Guess</option>",
1359
- FE_RENDER_GUESS,
1360
- FE_RENDER_GUESS==previewRenderMode ? " selected" : "");
1361
- CX("<option value='%d'%s>Wiki/Markdown</option>",
1362
- FE_RENDER_WIKI,
1363
- FE_RENDER_WIKI==previewRenderMode ? " selected" : "");
1364
- CX("<option value='%d'%s>HTML (iframe)</option>",
1365
- FE_RENDER_HTML,
1366
- FE_RENDER_HTML==previewRenderMode ? " selected" : "");
1367
- CX("<option value='%d'%s>Plain Text</option>",
1368
- FE_RENDER_PLAIN_TEXT,
1369
- FE_RENDER_PLAIN_TEXT==previewRenderMode ? " selected" : "");
1370
- CX("</select>\n");
1438
+ style_select_list_int("preview_render_mode",
1439
+ "Preview Mode",
1440
+ "Preview mode format.",
1441
+ previewRenderMode,
1442
+ "Guess", FE_RENDER_GUESS,
1443
+ "Wiki/Markdown", FE_RENDER_WIKI,
1444
+ "HTML (iframe)", FE_RENDER_HTML,
1445
+ "Plain Text", FE_RENDER_PLAIN_TEXT,
1446
+ NULL);
13711447
if(FE_RENDER_HTML==previewRenderMode){
13721448
/* HTML preview mode iframe height... */
1373
- int i;
13741449
if(submitMode==SUBMIT_PREVIEW){
13751450
previewHtmlHeight = atoi(PD("preview_html_ems","0"));
13761451
}else{
13771452
previewHtmlHeight = 40;
13781453
}
13791454
/* Allow selection of HTML preview iframe height */
1380
- CX("<select name='preview_html_ems' "
1381
- "title='Height (in EMs) of the iframe used for HTML "
1382
- "preview.'>\n");
1383
- CX("<option disabled value='40'>HTML Preview Height (EMs)"
1384
- "</option>\n");
1385
- for( i = 20; i <= 100; i+=20 ){
1386
- CX("<option value='%d'%s>%d</option>\n",
1387
- i, (previewHtmlHeight==i) ? " selected" : "", i);
1388
- }
1389
- CX("</select>\n");
1455
+ style_select_list_int("preview_html_ems",
1456
+ "Preview IFrame Height (EMs)",
1457
+ "Height (in EMs) of the iframe used for "
1458
+ "HTML preview",
1459
+ previewHtmlHeight,
1460
+ "", 20, "", 40,
1461
+ "", 60, "", 80,
1462
+ "", 100, NULL);
13901463
}
13911464
else if(FE_RENDER_PLAIN_TEXT==previewRenderMode){
13921465
style_labeled_checkbox("preview_ln",
13931466
"Add line numbers to plain-text previews?",
13941467
"1",
@@ -1395,10 +1468,12 @@
13951468
"If on, plain-text files (only) will get "
13961469
"line numbers added to the preview.",
13971470
previewLn);
13981471
}
13991472
}
1473
+ CX("<button type='submit' name='submit' value='3'>"
1474
+ "Diff (TODO)</button>");
14001475
CX("</div></fieldset>");
14011476
14021477
/******* End of form *******/
14031478
CX("</form>\n");
14041479
14051480
--- src/fileedit.c
+++ src/fileedit.c
@@ -18,10 +18,11 @@
18 ** This file contains code for the /fileedit page and related code.
19 */
20 #include "config.h"
21 #include "fileedit.h"
22 #include <assert.h>
 
23
24 /*
25 ** State for the "mini-checkin" infrastructure, which enables the
26 ** ability to commit changes to a single file without a checkout
27 ** db, e.g. for use via an HTTP request.
@@ -40,11 +41,11 @@
40 relative to the top of the repo. */
41 Blob fileContent; /* Content of file referred to by zFilename. */
42 Blob fileHash; /* Hash of this->fileContent, using the repo's
43 preferred hash method. */
44 Blob comment; /* Check-in comment text */
45 char *zMimetype; /* Mimetype of comment. May be NULL */
46 char *zUser; /* User name */
47 char *zDate; /* Optionally force this date string (anything
48 supported by date_in_standard_format()).
49 Maybe be NULL. */
50 Blob *pMfOut; /* If not NULL, checkin_mini() will write a
@@ -160,11 +161,11 @@
160 manifest_destroy(p->pParent);
161 }
162 fossil_free(p->zFilename);
163 fossil_free(p->zDate);
164 fossil_free(p->zParentUuid);
165 fossil_free(p->zMimetype);
166 fossil_free(p->zUser);
167 CheckinMiniInfo_init(p);
168 }
169
170 /*
@@ -370,12 +371,12 @@
370 }
371 blob_appendf(pOut, "D %s\n", pCI->zDate);
372 if(create_manifest_mini_fcards(pOut,pCI,asDelta,pErr)==0){
373 return 0;
374 }
375 if(pCI->zMimetype!=0 && pCI->zMimetype[0]!=0){
376 blob_appendf(pOut, "N %F\n", pCI->zMimetype);
377 }
378 blob_appendf(pOut, "P %s\n", pCI->zParentUuid);
379 blob_appendf(pOut, "U %F\n", pCI->zUser);
380 md5sum_blob(pOut, &zCard);
381 blob_appendf(pOut, "Z %b\n", &zCard);
@@ -979,18 +980,18 @@
979 static void style_labeled_checkbox(const char *zFieldName,
980 const char * zLabel,
981 const char * zValue,
982 const char * zTip,
983 int isChecked){
984 CX("<span class='input-with-label'");
985 if(zTip && *zTip){
986 CX(" title='%h'", zTip);
987 }
988 CX("><input type='checkbox' name='%s' value='%T'%s/>",
989 zFieldName,
990 zValue ? zValue : "", isChecked ? " checked" : "");
991 CX("<span>%h</span></span>", zLabel);
992 }
993
994 enum fileedit_render_preview_flags {
995 FE_PREVIEW_LINE_NUMBERS = 1
996 };
@@ -1056,10 +1057,90 @@
1056 break;
1057 }
1058 }
1059 CX("</div><!--.fileedit-preview-->\n");
1060 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1061
1062 /*
1063 ** WEBPAGE: fileedit
1064 **
1065 ** EXPERIMENTAL and subject to change and removal at any time. The goal
@@ -1139,11 +1220,11 @@
1139 if(submitMode < SUBMIT_NONE || submitMode > SUBMIT_DIFF){
1140 submitMode = 0;
1141 }
1142 zFlagCheck = P("comment_mimetype");
1143 if(zFlagCheck){
1144 cimi.zMimetype = mprintf("%s",zFlagCheck);
1145 zFlagCheck = 0;
1146 }
1147 cimi.zUser = mprintf("%s",g.zLogin);
1148
1149 style_header("File Editor");
@@ -1226,28 +1307,18 @@
1226 CX("<p>This page is <em>far from complete</em> and may still have "
1227 "significant bugs. USE AT YOUR OWN RISK, preferably on a test "
1228 "repo.</p>\n");
1229
1230 CX("<form action='%R/fileedit#options' method='POST' "
1231 "class='fileedit-form'>\n");
1232
1233 /******* Hidden fields *******/
1234 CX("<input type='hidden' name='r' value='%s'>",
1235 cimi.zParentUuid);
1236 CX("<input type='hidden' name='file' value='%T'>",
1237 zFilename);
1238
1239 /******* Comment *******/
1240 CX("<h3>Checkin Comment</h3>\n");
1241 CX("<textarea name='comment' rows='3' cols='80'>");
1242 if(zComment && *zComment){
1243 CX("%h"/*%h? %s?*/, zComment);
1244 }
1245 CX("</textarea>\n");
1246 CX("<div class='fileedit-hint'>Comments use the Fossil wiki markup "
1247 "syntax.</div>"/*TODO: radiobuttons for fossil/me/plain text*/);
1248
1249 /******* Content *******/
1250 CX("<h3>File Content</h3>\n");
1251 CX("<textarea name='content' id='fileedit-content' "
1252 "rows='20' cols='80'>");
1253 if(0==loadMode){
@@ -1319,76 +1390,78 @@
1319 switch(eolMode){
1320 case 1: cimi.flags |= CIMINI_CONVERT_EOL_UNIX; break;
1321 case 2: cimi.flags |= CIMINI_CONVERT_EOL_WINDOWS; break;
1322 default: cimi.flags |= CIMINI_CONVERT_EOL_INHERIT; break;
1323 }
1324 CX("<select name='eol' "
1325 "title='EOL conversion policy, noting that form-processing "
1326 "may implicitly change the line endings of the input.'>");
1327 CX("<option value='0'%s>Inherit EOLs</option>",
1328 (eolMode!=1 && eolMode!=2) ? " selected" : "");
1329 CX("<option value='1'%s/>Unix EOLs</option>",
1330 eolMode==1 ? " selected" : "");
1331 CX("<option value='2'%s>Windows EOLs</option>",
1332 eolMode==2 ? " selected" : "");
1333 CX("</select>");
1334 }
1335
1336 CX("</div></fieldset>") /* end of checkboxes */;
1337
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1338 /******* Buttons *******/
1339 CX("<a id='buttons'></a>");
1340 CX("<fieldset class='fileedit-options'>"
1341 "<legend>Tell the server to...</legend><div>");
1342 CX("<button type='submit' name='submit' value='1'>"
1343 "Save</button>");
1344 CX("<button type='submit' name='submit' value='2'>"
1345 "Preview</button>");
1346 CX("<button type='submit' name='submit' value='3'>"
1347 "Diff (TODO)</button>");
1348 {
1349 /* Preview rendering mode selection... */
1350 previewRenderMode = atoi(PD("preview_render_mode","0"));
1351 if(0==previewRenderMode){
1352 previewRenderMode = fileedit_render_mode_for_mimetype(zFileMime);
1353 }
1354 CX("<br>");
1355 CX("<select name='preview_render_mode'>\n");
1356 CX("<option value='%d' disabled>Preview Mode</option>",
1357 FE_RENDER_GUESS);
1358 CX("<option value='%d'%s>Guess</option>",
1359 FE_RENDER_GUESS,
1360 FE_RENDER_GUESS==previewRenderMode ? " selected" : "");
1361 CX("<option value='%d'%s>Wiki/Markdown</option>",
1362 FE_RENDER_WIKI,
1363 FE_RENDER_WIKI==previewRenderMode ? " selected" : "");
1364 CX("<option value='%d'%s>HTML (iframe)</option>",
1365 FE_RENDER_HTML,
1366 FE_RENDER_HTML==previewRenderMode ? " selected" : "");
1367 CX("<option value='%d'%s>Plain Text</option>",
1368 FE_RENDER_PLAIN_TEXT,
1369 FE_RENDER_PLAIN_TEXT==previewRenderMode ? " selected" : "");
1370 CX("</select>\n");
1371 if(FE_RENDER_HTML==previewRenderMode){
1372 /* HTML preview mode iframe height... */
1373 int i;
1374 if(submitMode==SUBMIT_PREVIEW){
1375 previewHtmlHeight = atoi(PD("preview_html_ems","0"));
1376 }else{
1377 previewHtmlHeight = 40;
1378 }
1379 /* Allow selection of HTML preview iframe height */
1380 CX("<select name='preview_html_ems' "
1381 "title='Height (in EMs) of the iframe used for HTML "
1382 "preview.'>\n");
1383 CX("<option disabled value='40'>HTML Preview Height (EMs)"
1384 "</option>\n");
1385 for( i = 20; i <= 100; i+=20 ){
1386 CX("<option value='%d'%s>%d</option>\n",
1387 i, (previewHtmlHeight==i) ? " selected" : "", i);
1388 }
1389 CX("</select>\n");
1390 }
1391 else if(FE_RENDER_PLAIN_TEXT==previewRenderMode){
1392 style_labeled_checkbox("preview_ln",
1393 "Add line numbers to plain-text previews?",
1394 "1",
@@ -1395,10 +1468,12 @@
1395 "If on, plain-text files (only) will get "
1396 "line numbers added to the preview.",
1397 previewLn);
1398 }
1399 }
 
 
1400 CX("</div></fieldset>");
1401
1402 /******* End of form *******/
1403 CX("</form>\n");
1404
1405
--- src/fileedit.c
+++ src/fileedit.c
@@ -18,10 +18,11 @@
18 ** This file contains code for the /fileedit page and related code.
19 */
20 #include "config.h"
21 #include "fileedit.h"
22 #include <assert.h>
23 #include <stdarg.h>
24
25 /*
26 ** State for the "mini-checkin" infrastructure, which enables the
27 ** ability to commit changes to a single file without a checkout
28 ** db, e.g. for use via an HTTP request.
@@ -40,11 +41,11 @@
41 relative to the top of the repo. */
42 Blob fileContent; /* Content of file referred to by zFilename. */
43 Blob fileHash; /* Hash of this->fileContent, using the repo's
44 preferred hash method. */
45 Blob comment; /* Check-in comment text */
46 char *zCommentMimetype; /* Mimetype of comment. May be NULL */
47 char *zUser; /* User name */
48 char *zDate; /* Optionally force this date string (anything
49 supported by date_in_standard_format()).
50 Maybe be NULL. */
51 Blob *pMfOut; /* If not NULL, checkin_mini() will write a
@@ -160,11 +161,11 @@
161 manifest_destroy(p->pParent);
162 }
163 fossil_free(p->zFilename);
164 fossil_free(p->zDate);
165 fossil_free(p->zParentUuid);
166 fossil_free(p->zCommentMimetype);
167 fossil_free(p->zUser);
168 CheckinMiniInfo_init(p);
169 }
170
171 /*
@@ -370,12 +371,12 @@
371 }
372 blob_appendf(pOut, "D %s\n", pCI->zDate);
373 if(create_manifest_mini_fcards(pOut,pCI,asDelta,pErr)==0){
374 return 0;
375 }
376 if(pCI->zCommentMimetype!=0 && pCI->zCommentMimetype[0]!=0){
377 blob_appendf(pOut, "N %F\n", pCI->zCommentMimetype);
378 }
379 blob_appendf(pOut, "P %s\n", pCI->zParentUuid);
380 blob_appendf(pOut, "U %F\n", pCI->zUser);
381 md5sum_blob(pOut, &zCard);
382 blob_appendf(pOut, "Z %b\n", &zCard);
@@ -979,18 +980,18 @@
980 static void style_labeled_checkbox(const char *zFieldName,
981 const char * zLabel,
982 const char * zValue,
983 const char * zTip,
984 int isChecked){
985 CX("<div class='input-with-label'");
986 if(zTip && *zTip){
987 CX(" title='%h'", zTip);
988 }
989 CX("><input type='checkbox' name='%s' value='%T'%s/>",
990 zFieldName,
991 zValue ? zValue : "", isChecked ? " checked" : "");
992 CX("<span>%h</span></div>", zLabel);
993 }
994
995 enum fileedit_render_preview_flags {
996 FE_PREVIEW_LINE_NUMBERS = 1
997 };
@@ -1056,10 +1057,90 @@
1057 break;
1058 }
1059 }
1060 CX("</div><!--.fileedit-preview-->\n");
1061 }
1062
1063 /*
1064 ** Outputs a SELECT list from a compile-time list of integers.
1065 ** The vargs must be a list of (const char *, int) pairs, terminated
1066 ** with a single NULL. Each pair is interpreted as...
1067 **
1068 ** If the (const char *) is NULL, it is the end of the list, else
1069 ** a new OPTION entry is created. If the string is empty, the
1070 ** label and value of the OPTION is the integer part of the pair.
1071 ** If the string is not empty, it becomes the label and the integer
1072 ** the value. If that value == selectedValue then that OPTION
1073 ** element gets the 'selected' attribute.
1074 **
1075 ** Note that the pairs are not in (int, const char *) order because
1076 ** there is no well-known integer value which we can definitively use
1077 ** as a list terminator.
1078 **
1079 ** zFieldName is the value of the form element's name attribute.
1080 **
1081 ** zLabel is an optional string to use as a "label" for the element
1082 ** (see below).
1083 **
1084 ** zTooltip is an optional value for the SELECT's title attribute.
1085 **
1086 ** The structure of the emited HTML is:
1087 **
1088 ** <div class='input-with-label'>
1089 ** <span>{{zLabel}}</span>
1090 ** <select>...</select>
1091 ** </div>
1092 **
1093 */
1094 static void style_select_list_int_v(const char *zFieldName,
1095 const char * zLabel,
1096 const char * zToolTip,
1097 int selectedVal, va_list vargs){
1098 CX("<div class='input-with-label'");
1099 if(zToolTip && *zToolTip){
1100 CX(" title='%h'",zToolTip);
1101 }
1102 CX(">");
1103 if(zLabel && *zLabel){
1104 CX("<span>%h</span>", zLabel);
1105 }
1106 CX("<select name='%s'>",zFieldName);
1107 while(1){
1108 const char * zOption = va_arg(vargs,char *);
1109 int v;
1110 if(NULL==zOption){
1111 break;
1112 }
1113 v = va_arg(vargs,int);
1114 CX("<option value='%d'%s>",
1115 v, v==selectedVal ? " selected" : "");
1116 if(*zOption){
1117 CX("%s", zOption);
1118 }else{
1119 CX("%d",v);
1120 }
1121 CX("</option>\n");
1122 }
1123 CX("</select>\n");
1124 if(zLabel && *zLabel){
1125 CX("</div>\n");
1126 }
1127 }
1128
1129 /*
1130 ** The ellipsis-args counterpart of style_select_list_int_v().
1131 */
1132 void style_select_list_int(const char *zFieldName,
1133 const char * zLabel,
1134 const char * zToolTip,
1135 int selectedVal, ... ){
1136 va_list vargs;
1137 va_start(vargs,selectedVal);
1138 style_select_list_int_v(zFieldName, zLabel, zToolTip,
1139 selectedVal, vargs);
1140 va_end(vargs);
1141 }
1142
1143 /*
1144 ** WEBPAGE: fileedit
1145 **
1146 ** EXPERIMENTAL and subject to change and removal at any time. The goal
@@ -1139,11 +1220,11 @@
1220 if(submitMode < SUBMIT_NONE || submitMode > SUBMIT_DIFF){
1221 submitMode = 0;
1222 }
1223 zFlagCheck = P("comment_mimetype");
1224 if(zFlagCheck){
1225 cimi.zCommentMimetype = mprintf("%s",zFlagCheck);
1226 zFlagCheck = 0;
1227 }
1228 cimi.zUser = mprintf("%s",g.zLogin);
1229
1230 style_header("File Editor");
@@ -1226,28 +1307,18 @@
1307 CX("<p>This page is <em>far from complete</em> and may still have "
1308 "significant bugs. USE AT YOUR OWN RISK, preferably on a test "
1309 "repo.</p>\n");
1310
1311 CX("<form action='%R/fileedit#options' method='POST' "
1312 "class='fileedit'>\n");
1313
1314 /******* Hidden fields *******/
1315 CX("<input type='hidden' name='r' value='%s'>",
1316 cimi.zParentUuid);
1317 CX("<input type='hidden' name='file' value='%T'>",
1318 zFilename);
1319
 
 
 
 
 
 
 
 
 
 
1320 /******* Content *******/
1321 CX("<h3>File Content</h3>\n");
1322 CX("<textarea name='content' id='fileedit-content' "
1323 "rows='20' cols='80'>");
1324 if(0==loadMode){
@@ -1319,76 +1390,78 @@
1390 switch(eolMode){
1391 case 1: cimi.flags |= CIMINI_CONVERT_EOL_UNIX; break;
1392 case 2: cimi.flags |= CIMINI_CONVERT_EOL_WINDOWS; break;
1393 default: cimi.flags |= CIMINI_CONVERT_EOL_INHERIT; break;
1394 }
1395 style_select_list_int("eol", "EOL Style",
1396 "EOL conversion policy, noting that "
1397 "form-processing may implicitly change the "
1398 "line endings of the input.",
1399 eolMode==1||eolMode==2 ? eolMode : 0,
1400 "Inherit", 0,
1401 "Unix", 1,
1402 "Windows", 2,
1403 NULL);
 
1404 }
1405
1406 CX("</div></fieldset>") /* end of checkboxes */;
1407
1408 /******* Comment *******/
1409 CX("<a id='comment'></a>");
1410 CX("<fieldset><legend>Commit message</legend><div>");
1411 CX("<textarea name='comment' rows='3' cols='80'>");
1412 /* ^^^ adding the 'required' attribute means we cannot even submit
1413 ** for PREVIEW mode if it's empty :/. */
1414 if(zComment && *zComment){
1415 CX("%h"/*%h? %s?*/, zComment);
1416 }
1417 CX("</textarea>\n");
1418 CX("<div class='fileedit-hint'>Comments use the Fossil wiki markup "
1419 "syntax.</div>\n"/*TODO: select for fossil/md/plain text*/);
1420 CX("</div></fieldset>\n");
1421
1422
1423
1424 /******* Buttons *******/
1425 CX("<a id='buttons'></a>");
1426 CX("<fieldset class='fileedit-options'>"
1427 "<legend>Tell the server to...</legend><div>");
1428 CX("<button type='submit' name='submit' value='1'>"
1429 "Save</button>");
1430 CX("<button type='submit' name='submit' value='2'>"
1431 "Preview</button>");
 
 
1432 {
1433 /* Preview rendering mode selection... */
1434 previewRenderMode = atoi(PD("preview_render_mode","0"));
1435 if(0==previewRenderMode){
1436 previewRenderMode = fileedit_render_mode_for_mimetype(zFileMime);
1437 }
1438 style_select_list_int("preview_render_mode",
1439 "Preview Mode",
1440 "Preview mode format.",
1441 previewRenderMode,
1442 "Guess", FE_RENDER_GUESS,
1443 "Wiki/Markdown", FE_RENDER_WIKI,
1444 "HTML (iframe)", FE_RENDER_HTML,
1445 "Plain Text", FE_RENDER_PLAIN_TEXT,
1446 NULL);
 
 
 
 
 
 
 
 
1447 if(FE_RENDER_HTML==previewRenderMode){
1448 /* HTML preview mode iframe height... */
 
1449 if(submitMode==SUBMIT_PREVIEW){
1450 previewHtmlHeight = atoi(PD("preview_html_ems","0"));
1451 }else{
1452 previewHtmlHeight = 40;
1453 }
1454 /* Allow selection of HTML preview iframe height */
1455 style_select_list_int("preview_html_ems",
1456 "Preview IFrame Height (EMs)",
1457 "Height (in EMs) of the iframe used for "
1458 "HTML preview",
1459 previewHtmlHeight,
1460 "", 20, "", 40,
1461 "", 60, "", 80,
1462 "", 100, NULL);
 
 
1463 }
1464 else if(FE_RENDER_PLAIN_TEXT==previewRenderMode){
1465 style_labeled_checkbox("preview_ln",
1466 "Add line numbers to plain-text previews?",
1467 "1",
@@ -1395,10 +1468,12 @@
1468 "If on, plain-text files (only) will get "
1469 "line numbers added to the preview.",
1470 previewLn);
1471 }
1472 }
1473 CX("<button type='submit' name='submit' value='3'>"
1474 "Diff (TODO)</button>");
1475 CX("</div></fieldset>");
1476
1477 /******* End of form *******/
1478 CX("</form>\n");
1479
1480

Keyboard Shortcuts

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