Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Style improvements and code consolidation. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | checkin-without-checkout |
| Files: | files | file ages | folders |
| SHA3-256: |
67a2bfb0dc85711aff3a31118faec363 |
| User & Date: | stephan 2020-05-04 16:22:50.813 |
Context
|
2020-05-04
| ||
| 17:44 | Added SBS/unified diff to /fileedit. ... (check-in: ae8e24d021 user: stephan tags: checkin-without-checkout) | |
| 16:22 | Style improvements and code consolidation. ... (check-in: 67a2bfb0dc user: stephan tags: checkin-without-checkout) | |
| 13:12 | Added preview render mode selection list. ... (check-in: 65b6c01afd user: stephan tags: checkin-without-checkout) | |
Changes
Changes to src/default_css.txt.
| ︙ | ︙ | |||
859 860 861 862 863 864 865 |
// vertical-align: top;
// }
// #setup_skinedit_css_defaults > tbody > tr > td:nth-of-type(2) > div {
// max-width: 30em;
// overflow: auto;
// }
// .fileedit-XXX => /fileedit page
| | | > > > > > > | > > > | | | | | | 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 |
// vertical-align: top;
// }
// #setup_skinedit_css_defaults > tbody > tr > td:nth-of-type(2) > div {
// max-width: 30em;
// overflow: auto;
// }
// .fileedit-XXX => /fileedit page
form.fileedit textarea {
font-family: monospace;
width: 100%;
}
form.fileedit fieldset {
margin: 0.5em 0 0 0;
border-radius: 0.5em;
border-color: inherit;
border-width: 1px;
}
form.fileedit fieldset > legend {
margin-left: 1em;
}
form.fileedit fieldset > div {
margin: 0 0.25em;
}
form.fileedit fieldset > div > .input-with-label {
padding: 0.5em;
margin: 0.25em 0.5em;
}
form.fileedit fieldset > div > button {
margin: 0.25em 0.5em;
}
form.fileedit input:invalid {
border-left: 0.2em dashed red;
}
.fileedit-hint {
font-size: 80%;
opacity: 0.75;
}
.fileedit-error-report {
background: yellow;
|
| ︙ | ︙ | |||
899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 |
div.fileedit-preview {
margin: 0;
padding: 0;
}
.fileedit-preview > div:first-child {
border-bottom: 1px dashed;
}
.input-with-label {
border: 1px inset #808080;
border-radius: 0.5em;
padding: 0.25em 0.4em;
margin: 0 0.5em;
display: inline-block;
cursor: pointer;
}
.input-with-label > input {
margin: 0;
}
.input-with-label > input[type=checkbox] {
vertical-align: sub;
}
.input-with-label > input[type=radio] {
vertical-align: sub;
}
.input-with-label > span {
| > > > > > > > > > > > > > | | | 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 |
div.fileedit-preview {
margin: 0;
padding: 0;
}
.fileedit-preview > div:first-child {
border-bottom: 1px dashed;
}
.input-with-label {
border: 1px inset #808080;
border-radius: 0.5em;
padding: 0.25em 0.4em;
margin: 0 0.5em;
display: inline-block;
cursor: pointer;
}
.input-with-label > * {
vertical-align: middle;
}
.input-with-label > input {
margin: 0;
}
.input-with-label > select {
margin: 0;
}
.input-with-label > input[type=text] {
margin: 0;
}
.input-with-label > textarea {
margin: 0;
}
.input-with-label > input[type=checkbox] {
vertical-align: sub;
}
.input-with-label > input[type=radio] {
vertical-align: sub;
}
.input-with-label > span {
margin: 0 0.25em 0 0.25em;
vertical-align: middle;
}
|
Changes to src/fileedit.c.
| ︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 | ******************************************************************************* ** ** This file contains code for the /fileedit page and related code. */ #include "config.h" #include "fileedit.h" #include <assert.h> /* ** State for the "mini-checkin" infrastructure, which enables the ** ability to commit changes to a single file without a checkout ** db, e.g. for use via an HTTP request. ** ** Use CheckinMiniInfo_init() to cleanly initialize one to a known | > | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | ******************************************************************************* ** ** This file contains code for the /fileedit page and related code. */ #include "config.h" #include "fileedit.h" #include <assert.h> #include <stdarg.h> /* ** State for the "mini-checkin" infrastructure, which enables the ** ability to commit changes to a single file without a checkout ** db, e.g. for use via an HTTP request. ** ** Use CheckinMiniInfo_init() to cleanly initialize one to a known |
| ︙ | ︙ | |||
38 39 40 41 42 43 44 |
char *zParentUuid; /* Full UUID of pParent */
char *zFilename; /* Name of single file to commit. Must be
relative to the top of the repo. */
Blob fileContent; /* Content of file referred to by zFilename. */
Blob fileHash; /* Hash of this->fileContent, using the repo's
preferred hash method. */
Blob comment; /* Check-in comment text */
| | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
char *zParentUuid; /* Full UUID of pParent */
char *zFilename; /* Name of single file to commit. Must be
relative to the top of the repo. */
Blob fileContent; /* Content of file referred to by zFilename. */
Blob fileHash; /* Hash of this->fileContent, using the repo's
preferred hash method. */
Blob comment; /* Check-in comment text */
char *zCommentMimetype; /* Mimetype of comment. May be NULL */
char *zUser; /* User name */
char *zDate; /* Optionally force this date string (anything
supported by date_in_standard_format()).
Maybe be NULL. */
Blob *pMfOut; /* If not NULL, checkin_mini() will write a
copy of the generated manifest here. This
memory is NOT owned by CheckinMiniInfo. */
|
| ︙ | ︙ | |||
158 159 160 161 162 163 164 |
blob_reset(&p->fileHash);
if(p->pParent){
manifest_destroy(p->pParent);
}
fossil_free(p->zFilename);
fossil_free(p->zDate);
fossil_free(p->zParentUuid);
| | | 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
blob_reset(&p->fileHash);
if(p->pParent){
manifest_destroy(p->pParent);
}
fossil_free(p->zFilename);
fossil_free(p->zDate);
fossil_free(p->zParentUuid);
fossil_free(p->zCommentMimetype);
fossil_free(p->zUser);
CheckinMiniInfo_init(p);
}
/*
** Internal helper which returns an F-card perms string suitable for
** writing into a manifest.
|
| ︙ | ︙ | |||
368 369 370 371 372 373 374 |
}else{
blob_append(pOut, "C (no\\scomment)\n", 16);
}
blob_appendf(pOut, "D %s\n", pCI->zDate);
if(create_manifest_mini_fcards(pOut,pCI,asDelta,pErr)==0){
return 0;
}
| | | | 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 |
}else{
blob_append(pOut, "C (no\\scomment)\n", 16);
}
blob_appendf(pOut, "D %s\n", pCI->zDate);
if(create_manifest_mini_fcards(pOut,pCI,asDelta,pErr)==0){
return 0;
}
if(pCI->zCommentMimetype!=0 && pCI->zCommentMimetype[0]!=0){
blob_appendf(pOut, "N %F\n", pCI->zCommentMimetype);
}
blob_appendf(pOut, "P %s\n", pCI->zParentUuid);
blob_appendf(pOut, "U %F\n", pCI->zUser);
md5sum_blob(pOut, &zCard);
blob_appendf(pOut, "Z %b\n", &zCard);
blob_reset(&zCard);
return 1;
|
| ︙ | ︙ | |||
977 978 979 980 981 982 983 |
** zFieldName, zLabel, and zValue are required. zTip is optional.
*/
static void style_labeled_checkbox(const char *zFieldName,
const char * zLabel,
const char * zValue,
const char * zTip,
int isChecked){
| | | | 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 |
** zFieldName, zLabel, and zValue are required. zTip is optional.
*/
static void style_labeled_checkbox(const char *zFieldName,
const char * zLabel,
const char * zValue,
const char * zTip,
int isChecked){
CX("<div class='input-with-label'");
if(zTip && *zTip){
CX(" title='%h'", zTip);
}
CX("><input type='checkbox' name='%s' value='%T'%s/>",
zFieldName,
zValue ? zValue : "", isChecked ? " checked" : "");
CX("<span>%h</span></div>", zLabel);
}
enum fileedit_render_preview_flags {
FE_PREVIEW_LINE_NUMBERS = 1
};
enum fileedit_render_modes {
FE_RENDER_GUESS = 0,
|
| ︙ | ︙ | |||
1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 |
CX("<pre>%h</pre>", zExt+1, zContent);
}
break;
}
}
CX("</div><!--.fileedit-preview-->\n");
}
/*
** WEBPAGE: fileedit
**
** EXPERIMENTAL and subject to change and removal at any time. The goal
** is to allow online edits of files.
**
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 |
CX("<pre>%h</pre>", zExt+1, zContent);
}
break;
}
}
CX("</div><!--.fileedit-preview-->\n");
}
/*
** Outputs a SELECT list from a compile-time list of integers.
** The vargs must be a list of (const char *, int) pairs, terminated
** with a single NULL. Each pair is interpreted as...
**
** If the (const char *) is NULL, it is the end of the list, else
** a new OPTION entry is created. If the string is empty, the
** label and value of the OPTION is the integer part of the pair.
** If the string is not empty, it becomes the label and the integer
** the value. If that value == selectedValue then that OPTION
** element gets the 'selected' attribute.
**
** Note that the pairs are not in (int, const char *) order because
** there is no well-known integer value which we can definitively use
** as a list terminator.
**
** zFieldName is the value of the form element's name attribute.
**
** zLabel is an optional string to use as a "label" for the element
** (see below).
**
** zTooltip is an optional value for the SELECT's title attribute.
**
** The structure of the emited HTML is:
**
** <div class='input-with-label'>
** <span>{{zLabel}}</span>
** <select>...</select>
** </div>
**
*/
static void style_select_list_int_v(const char *zFieldName,
const char * zLabel,
const char * zToolTip,
int selectedVal, va_list vargs){
CX("<div class='input-with-label'");
if(zToolTip && *zToolTip){
CX(" title='%h'",zToolTip);
}
CX(">");
if(zLabel && *zLabel){
CX("<span>%h</span>", zLabel);
}
CX("<select name='%s'>",zFieldName);
while(1){
const char * zOption = va_arg(vargs,char *);
int v;
if(NULL==zOption){
break;
}
v = va_arg(vargs,int);
CX("<option value='%d'%s>",
v, v==selectedVal ? " selected" : "");
if(*zOption){
CX("%s", zOption);
}else{
CX("%d",v);
}
CX("</option>\n");
}
CX("</select>\n");
if(zLabel && *zLabel){
CX("</div>\n");
}
}
/*
** The ellipsis-args counterpart of style_select_list_int_v().
*/
void style_select_list_int(const char *zFieldName,
const char * zLabel,
const char * zToolTip,
int selectedVal, ... ){
va_list vargs;
va_start(vargs,selectedVal);
style_select_list_int_v(zFieldName, zLabel, zToolTip,
selectedVal, vargs);
va_end(vargs);
}
/*
** WEBPAGE: fileedit
**
** EXPERIMENTAL and subject to change and removal at any time. The goal
** is to allow online edits of files.
**
|
| ︙ | ︙ | |||
1137 1138 1139 1140 1141 1142 1143 |
CheckinMiniInfo_init(&cimi);
submitMode = atoi(PD("submit","0"));
if(submitMode < SUBMIT_NONE || submitMode > SUBMIT_DIFF){
submitMode = 0;
}
zFlagCheck = P("comment_mimetype");
if(zFlagCheck){
| | | 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 |
CheckinMiniInfo_init(&cimi);
submitMode = atoi(PD("submit","0"));
if(submitMode < SUBMIT_NONE || submitMode > SUBMIT_DIFF){
submitMode = 0;
}
zFlagCheck = P("comment_mimetype");
if(zFlagCheck){
cimi.zCommentMimetype = mprintf("%s",zFlagCheck);
zFlagCheck = 0;
}
cimi.zUser = mprintf("%s",g.zLogin);
style_header("File Editor");
/* As of this point, don't use return or fossil_fatal(), use
** fail((&err,...)) instead so that we can be sure to do any
|
| ︙ | ︙ | |||
1224 1225 1226 1227 1228 1229 1230 |
zFilename, cimi.zParentUuid);
CX("</p>");
CX("<p>This page is <em>far from complete</em> and may still have "
"significant bugs. USE AT YOUR OWN RISK, preferably on a test "
"repo.</p>\n");
CX("<form action='%R/fileedit#options' method='POST' "
| | < < < < < < < < < < | 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 |
zFilename, cimi.zParentUuid);
CX("</p>");
CX("<p>This page is <em>far from complete</em> and may still have "
"significant bugs. USE AT YOUR OWN RISK, preferably on a test "
"repo.</p>\n");
CX("<form action='%R/fileedit#options' method='POST' "
"class='fileedit'>\n");
/******* Hidden fields *******/
CX("<input type='hidden' name='r' value='%s'>",
cimi.zParentUuid);
CX("<input type='hidden' name='file' value='%T'>",
zFilename);
/******* Content *******/
CX("<h3>File Content</h3>\n");
CX("<textarea name='content' id='fileedit-content' "
"rows='20' cols='80'>");
if(0==loadMode){
CX("%h",blob_str(&cimi.fileContent));
}else{
|
| ︙ | ︙ | |||
1317 1318 1319 1320 1321 1322 1323 |
const int eolMode = submitMode==SUBMIT_NONE
? 0 : atoi(PD("eol","0"));
switch(eolMode){
case 1: cimi.flags |= CIMINI_CONVERT_EOL_UNIX; break;
case 2: cimi.flags |= CIMINI_CONVERT_EOL_WINDOWS; break;
default: cimi.flags |= CIMINI_CONVERT_EOL_INHERIT; break;
}
| | | > | > | < | < | > > | | | > > > > > > > > | > > > | > > < < < | | > | < | < < | < < | < < | < | < | > | | < < < < | < < > > > > > | 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 |
const int eolMode = submitMode==SUBMIT_NONE
? 0 : atoi(PD("eol","0"));
switch(eolMode){
case 1: cimi.flags |= CIMINI_CONVERT_EOL_UNIX; break;
case 2: cimi.flags |= CIMINI_CONVERT_EOL_WINDOWS; break;
default: cimi.flags |= CIMINI_CONVERT_EOL_INHERIT; break;
}
style_select_list_int("eol", "EOL Style",
"EOL conversion policy, noting that "
"form-processing may implicitly change the "
"line endings of the input.",
eolMode==1||eolMode==2 ? eolMode : 0,
"Inherit", 0,
"Unix", 1,
"Windows", 2,
NULL);
}
CX("</div></fieldset>") /* end of checkboxes */;
/******* Comment *******/
CX("<a id='comment'></a>");
CX("<fieldset><legend>Commit message</legend><div>");
CX("<textarea name='comment' rows='3' cols='80'>");
/* ^^^ adding the 'required' attribute means we cannot even submit
** for PREVIEW mode if it's empty :/. */
if(zComment && *zComment){
CX("%h"/*%h? %s?*/, zComment);
}
CX("</textarea>\n");
CX("<div class='fileedit-hint'>Comments use the Fossil wiki markup "
"syntax.</div>\n"/*TODO: select for fossil/md/plain text*/);
CX("</div></fieldset>\n");
/******* Buttons *******/
CX("<a id='buttons'></a>");
CX("<fieldset class='fileedit-options'>"
"<legend>Tell the server to...</legend><div>");
CX("<button type='submit' name='submit' value='1'>"
"Save</button>");
CX("<button type='submit' name='submit' value='2'>"
"Preview</button>");
{
/* Preview rendering mode selection... */
previewRenderMode = atoi(PD("preview_render_mode","0"));
if(0==previewRenderMode){
previewRenderMode = fileedit_render_mode_for_mimetype(zFileMime);
}
style_select_list_int("preview_render_mode",
"Preview Mode",
"Preview mode format.",
previewRenderMode,
"Guess", FE_RENDER_GUESS,
"Wiki/Markdown", FE_RENDER_WIKI,
"HTML (iframe)", FE_RENDER_HTML,
"Plain Text", FE_RENDER_PLAIN_TEXT,
NULL);
if(FE_RENDER_HTML==previewRenderMode){
/* HTML preview mode iframe height... */
if(submitMode==SUBMIT_PREVIEW){
previewHtmlHeight = atoi(PD("preview_html_ems","0"));
}else{
previewHtmlHeight = 40;
}
/* Allow selection of HTML preview iframe height */
style_select_list_int("preview_html_ems",
"Preview IFrame Height (EMs)",
"Height (in EMs) of the iframe used for "
"HTML preview",
previewHtmlHeight,
"", 20, "", 40,
"", 60, "", 80,
"", 100, NULL);
}
else if(FE_RENDER_PLAIN_TEXT==previewRenderMode){
style_labeled_checkbox("preview_ln",
"Add line numbers to plain-text previews?",
"1",
"If on, plain-text files (only) will get "
"line numbers added to the preview.",
previewLn);
}
}
CX("<button type='submit' name='submit' value='3'>"
"Diff (TODO)</button>");
CX("</div></fieldset>");
/******* End of form *******/
CX("</form>\n");
/* Dynamically populate the editor... */
if(1==loadMode || (2==loadMode && submitMode>SUBMIT_NONE)){
|
| ︙ | ︙ |