Fossil SCM

Merged in the Ajax-based /wikiedit reimplementation.

stephan 2020-08-01 13:53 trunk merge
Commit 19f275352230d801df693e344e1a70dd7e906f421b9a2d106351fb27f0d667be
+13 -1
--- src/ajax.c
+++ src/ajax.c
@@ -163,10 +163,20 @@
163163
}else{
164164
CX("<pre class='udiff'>%b</pre>",&out);
165165
}
166166
blob_reset(&out);
167167
}
168
+
169
+/*
170
+** Uses P(zKey) to fetch a CGI environment variable. If that var is
171
+** NULL or starts with '0' or 'f' then this function returns false,
172
+** else it returns true.
173
+*/
174
+int ajax_p_bool(char const *zKey){
175
+ const char * zVal = P(zKey);
176
+ return (!zVal || '0'==*zVal || 'f'==*zVal) ? 0 : 1;
177
+}
168178
169179
/*
170180
** Helper for /ajax routes. Clears the CGI content buffer, sets an
171181
** HTTP error status code, and queues up a JSON response in the form
172182
** of an object:
@@ -323,10 +333,11 @@
323333
if(zRenderMode!=0){
324334
cgi_printf_header("x-ajax-render-mode: %s\r\n", zRenderMode);
325335
}
326336
}
327337
338
+#if INTERFACE
328339
/*
329340
** Internal mapping of ajax sub-route names to various metadata.
330341
*/
331342
struct AjaxRoute {
332343
const char *zName; /* Name part of the route after "ajax/" */
@@ -334,16 +345,17 @@
334345
int bWriteMode; /* True if requires write mode */
335346
int bPost; /* True if requires POST (i.e. CSRF
336347
** verification) */
337348
};
338349
typedef struct AjaxRoute AjaxRoute;
350
+#endif /*INTERFACE*/
339351
340352
/*
341353
** Comparison function for bsearch() for searching an AjaxRoute
342354
** list for a matching name.
343355
*/
344
-static int cmp_ajax_route_name(const void *a, const void *b){
356
+int cmp_ajax_route_name(const void *a, const void *b){
345357
const AjaxRoute * rA = (const AjaxRoute*)a;
346358
const AjaxRoute * rB = (const AjaxRoute*)b;
347359
return fossil_strcmp(rA->zName, rB->zName);
348360
}
349361
350362
--- src/ajax.c
+++ src/ajax.c
@@ -163,10 +163,20 @@
163 }else{
164 CX("<pre class='udiff'>%b</pre>",&out);
165 }
166 blob_reset(&out);
167 }
 
 
 
 
 
 
 
 
 
 
168
169 /*
170 ** Helper for /ajax routes. Clears the CGI content buffer, sets an
171 ** HTTP error status code, and queues up a JSON response in the form
172 ** of an object:
@@ -323,10 +333,11 @@
323 if(zRenderMode!=0){
324 cgi_printf_header("x-ajax-render-mode: %s\r\n", zRenderMode);
325 }
326 }
327
 
328 /*
329 ** Internal mapping of ajax sub-route names to various metadata.
330 */
331 struct AjaxRoute {
332 const char *zName; /* Name part of the route after "ajax/" */
@@ -334,16 +345,17 @@
334 int bWriteMode; /* True if requires write mode */
335 int bPost; /* True if requires POST (i.e. CSRF
336 ** verification) */
337 };
338 typedef struct AjaxRoute AjaxRoute;
 
339
340 /*
341 ** Comparison function for bsearch() for searching an AjaxRoute
342 ** list for a matching name.
343 */
344 static int cmp_ajax_route_name(const void *a, const void *b){
345 const AjaxRoute * rA = (const AjaxRoute*)a;
346 const AjaxRoute * rB = (const AjaxRoute*)b;
347 return fossil_strcmp(rA->zName, rB->zName);
348 }
349
350
--- src/ajax.c
+++ src/ajax.c
@@ -163,10 +163,20 @@
163 }else{
164 CX("<pre class='udiff'>%b</pre>",&out);
165 }
166 blob_reset(&out);
167 }
168
169 /*
170 ** Uses P(zKey) to fetch a CGI environment variable. If that var is
171 ** NULL or starts with '0' or 'f' then this function returns false,
172 ** else it returns true.
173 */
174 int ajax_p_bool(char const *zKey){
175 const char * zVal = P(zKey);
176 return (!zVal || '0'==*zVal || 'f'==*zVal) ? 0 : 1;
177 }
178
179 /*
180 ** Helper for /ajax routes. Clears the CGI content buffer, sets an
181 ** HTTP error status code, and queues up a JSON response in the form
182 ** of an object:
@@ -323,10 +333,11 @@
333 if(zRenderMode!=0){
334 cgi_printf_header("x-ajax-render-mode: %s\r\n", zRenderMode);
335 }
336 }
337
338 #if INTERFACE
339 /*
340 ** Internal mapping of ajax sub-route names to various metadata.
341 */
342 struct AjaxRoute {
343 const char *zName; /* Name part of the route after "ajax/" */
@@ -334,16 +345,17 @@
345 int bWriteMode; /* True if requires write mode */
346 int bPost; /* True if requires POST (i.e. CSRF
347 ** verification) */
348 };
349 typedef struct AjaxRoute AjaxRoute;
350 #endif /*INTERFACE*/
351
352 /*
353 ** Comparison function for bsearch() for searching an AjaxRoute
354 ** list for a matching name.
355 */
356 int cmp_ajax_route_name(const void *a, const void *b){
357 const AjaxRoute * rA = (const AjaxRoute*)a;
358 const AjaxRoute * rB = (const AjaxRoute*)b;
359 return fossil_strcmp(rA->zName, rB->zName);
360 }
361
362
--- src/default.css
+++ src/default.css
@@ -919,5 +919,178 @@
919919
}
920920
img {
921921
max-width: 100%;
922922
height: auto;
923923
}
924
+
925
+/**
926
+ .tab-xxx: styles for fossil.tabs.js.
927
+*/
928
+.tab-container {
929
+ width: 100%;
930
+ display: flex;
931
+ flex-direction: column;
932
+ align-items: stretch;
933
+}
934
+.tab-container > #fossil-status-bar {
935
+ margin-top: 0;
936
+}
937
+.tab-container > .tabs {
938
+ padding: 0.25em;
939
+ margin: 0;
940
+ display: flex;
941
+ flex-direction: column;
942
+ border-width: 1px;
943
+ border-style: outset;
944
+ border-color: inherit;
945
+}
946
+.tab-container > .tabs > .tab-panel {
947
+ align-self: stretch;
948
+ flex: 10 1 auto;
949
+ display: block;
950
+}
951
+.tab-container > .tab-bar {
952
+ display: flex;
953
+ flex-direction: row;
954
+ flex: 1 10 auto;
955
+ align-self: stretch;
956
+ flex-wrap: wrap;
957
+}
958
+.tab-container > .tab-bar > .tab-button {
959
+ display: inline-block;
960
+ border-radius: 0.25em 0.25em 0 0;
961
+ margin: 0 0.1em;
962
+ padding: 0.25em 0.75em;
963
+ align-self: baseline;
964
+ border-color: inherit;
965
+ border-width: 1px;
966
+ border-bottom: none;
967
+ border-top-style: inset;
968
+ border-left-style: inset;
969
+ border-right-style: inset;
970
+ cursor: pointer;
971
+ opacity: 0.6;
972
+}
973
+.tab-container > .tab-bar > .tab-button.selected {
974
+ text-decoration: underline;
975
+ opacity: 1.0;
976
+ border-top-style: outset;
977
+ border-left-style: outset;
978
+ border-right-style: outset;
979
+}
980
+
981
+/**
982
+ The flex-xxx classes can be used to create basic flexbox layouts
983
+ through the application of classes to the containing/contained
984
+ objects.
985
+*/
986
+.flex-container {
987
+ display: flex;
988
+}
989
+.flex-container.flex-row {
990
+ flex-direction: row;
991
+ flex-wrap: wrap;
992
+ justify-content: center;
993
+ align-items: center;
994
+}
995
+.flex-container .flex-grow {
996
+ flex-grow: 10;
997
+ flex-shrink: 0;
998
+}
999
+.flex-container .flex-shrink {
1000
+ flex-grow: 0;
1001
+ flex-shrink: 10;
1002
+}
1003
+.flex-container.flex-row.stretch {
1004
+ flex-wrap: wrap;
1005
+ align-items: baseline;
1006
+ justify-content: stretch;
1007
+ margin: 0;
1008
+}
1009
+.flex-container.flex-column {
1010
+ flex-direction: column;
1011
+ flex-wrap: wrap;
1012
+ justify-content: center;
1013
+ align-items: center;
1014
+}
1015
+.flex-container.flex-column.stretch {
1016
+ align-items: stretch;
1017
+ margin: 0;
1018
+}
1019
+.flex-container.child-gap-small > * {
1020
+ margin: 0.25em;
1021
+}
1022
+#fossil-status-bar {
1023
+ display: block;
1024
+ font-family: monospace;
1025
+ border-width: 1px;
1026
+ border-style: inset;
1027
+ border-color: inherit;
1028
+ min-height: 1.5em;
1029
+ font-size: 1.2em;
1030
+ padding: 0.2em;
1031
+ margin: 0.25em 0;
1032
+ flex: 0 0 auto;
1033
+}
1034
+.font-size-100 {
1035
+ font-size: 100%;
1036
+}
1037
+.font-size-125 {
1038
+ font-size: 125%;
1039
+}
1040
+.font-size-150 {
1041
+ font-size: 150%;
1042
+}
1043
+.font-size-175 {
1044
+ font-size: 175%;
1045
+}
1046
+.font-size-200 {
1047
+ font-size: 200%;
1048
+}
1049
+
1050
+/**
1051
+ .input-with-label is intended to be a wrapper element which
1052
+ contain both a LABEL tag and an INPUT or SELECT control.
1053
+ The wrapper is "necessary", as opposed to placing the INPUT
1054
+ in the LABEL, so that we can include multiple INPUT
1055
+ elements (e.g. a set of radio buttons).
1056
+*/
1057
+.input-with-label {
1058
+ border: 1px inset #808080;
1059
+ border-radius: 0.25em;
1060
+ padding: 0.25em 0.4em;
1061
+ margin: 0 0.5em;
1062
+ display: inline-block;
1063
+ cursor: default;
1064
+}
1065
+.input-with-label > * {
1066
+ vertical-align: middle;
1067
+}
1068
+.input-with-label > label {
1069
+ display: inline; /* some skins set label display to block! */
1070
+}
1071
+.input-with-label > input {
1072
+ margin: 0;
1073
+}
1074
+.input-with-label > button {
1075
+ margin: 0;
1076
+}
1077
+.input-with-label > select {
1078
+ margin: 0;
1079
+}
1080
+.input-with-label > input[type=text] {
1081
+ margin: 0;
1082
+}
1083
+.input-with-label > textarea {
1084
+ margin: 0;
1085
+}
1086
+.input-with-label > input[type=checkbox] {
1087
+ vertical-align: sub;
1088
+}
1089
+.input-with-label > input[type=radio] {
1090
+ vertical-align: sub;
1091
+}
1092
+.input-with-label > label {
1093
+ font-weight: initial;
1094
+ margin: 0 0.25em 0 0.25em;
1095
+ vertical-align: middle;
1096
+}
9241097
--- src/default.css
+++ src/default.css
@@ -919,5 +919,178 @@
919 }
920 img {
921 max-width: 100%;
922 height: auto;
923 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
924
--- src/default.css
+++ src/default.css
@@ -919,5 +919,178 @@
919 }
920 img {
921 max-width: 100%;
922 height: auto;
923 }
924
925 /**
926 .tab-xxx: styles for fossil.tabs.js.
927 */
928 .tab-container {
929 width: 100%;
930 display: flex;
931 flex-direction: column;
932 align-items: stretch;
933 }
934 .tab-container > #fossil-status-bar {
935 margin-top: 0;
936 }
937 .tab-container > .tabs {
938 padding: 0.25em;
939 margin: 0;
940 display: flex;
941 flex-direction: column;
942 border-width: 1px;
943 border-style: outset;
944 border-color: inherit;
945 }
946 .tab-container > .tabs > .tab-panel {
947 align-self: stretch;
948 flex: 10 1 auto;
949 display: block;
950 }
951 .tab-container > .tab-bar {
952 display: flex;
953 flex-direction: row;
954 flex: 1 10 auto;
955 align-self: stretch;
956 flex-wrap: wrap;
957 }
958 .tab-container > .tab-bar > .tab-button {
959 display: inline-block;
960 border-radius: 0.25em 0.25em 0 0;
961 margin: 0 0.1em;
962 padding: 0.25em 0.75em;
963 align-self: baseline;
964 border-color: inherit;
965 border-width: 1px;
966 border-bottom: none;
967 border-top-style: inset;
968 border-left-style: inset;
969 border-right-style: inset;
970 cursor: pointer;
971 opacity: 0.6;
972 }
973 .tab-container > .tab-bar > .tab-button.selected {
974 text-decoration: underline;
975 opacity: 1.0;
976 border-top-style: outset;
977 border-left-style: outset;
978 border-right-style: outset;
979 }
980
981 /**
982 The flex-xxx classes can be used to create basic flexbox layouts
983 through the application of classes to the containing/contained
984 objects.
985 */
986 .flex-container {
987 display: flex;
988 }
989 .flex-container.flex-row {
990 flex-direction: row;
991 flex-wrap: wrap;
992 justify-content: center;
993 align-items: center;
994 }
995 .flex-container .flex-grow {
996 flex-grow: 10;
997 flex-shrink: 0;
998 }
999 .flex-container .flex-shrink {
1000 flex-grow: 0;
1001 flex-shrink: 10;
1002 }
1003 .flex-container.flex-row.stretch {
1004 flex-wrap: wrap;
1005 align-items: baseline;
1006 justify-content: stretch;
1007 margin: 0;
1008 }
1009 .flex-container.flex-column {
1010 flex-direction: column;
1011 flex-wrap: wrap;
1012 justify-content: center;
1013 align-items: center;
1014 }
1015 .flex-container.flex-column.stretch {
1016 align-items: stretch;
1017 margin: 0;
1018 }
1019 .flex-container.child-gap-small > * {
1020 margin: 0.25em;
1021 }
1022 #fossil-status-bar {
1023 display: block;
1024 font-family: monospace;
1025 border-width: 1px;
1026 border-style: inset;
1027 border-color: inherit;
1028 min-height: 1.5em;
1029 font-size: 1.2em;
1030 padding: 0.2em;
1031 margin: 0.25em 0;
1032 flex: 0 0 auto;
1033 }
1034 .font-size-100 {
1035 font-size: 100%;
1036 }
1037 .font-size-125 {
1038 font-size: 125%;
1039 }
1040 .font-size-150 {
1041 font-size: 150%;
1042 }
1043 .font-size-175 {
1044 font-size: 175%;
1045 }
1046 .font-size-200 {
1047 font-size: 200%;
1048 }
1049
1050 /**
1051 .input-with-label is intended to be a wrapper element which
1052 contain both a LABEL tag and an INPUT or SELECT control.
1053 The wrapper is "necessary", as opposed to placing the INPUT
1054 in the LABEL, so that we can include multiple INPUT
1055 elements (e.g. a set of radio buttons).
1056 */
1057 .input-with-label {
1058 border: 1px inset #808080;
1059 border-radius: 0.25em;
1060 padding: 0.25em 0.4em;
1061 margin: 0 0.5em;
1062 display: inline-block;
1063 cursor: default;
1064 }
1065 .input-with-label > * {
1066 vertical-align: middle;
1067 }
1068 .input-with-label > label {
1069 display: inline; /* some skins set label display to block! */
1070 }
1071 .input-with-label > input {
1072 margin: 0;
1073 }
1074 .input-with-label > button {
1075 margin: 0;
1076 }
1077 .input-with-label > select {
1078 margin: 0;
1079 }
1080 .input-with-label > input[type=text] {
1081 margin: 0;
1082 }
1083 .input-with-label > textarea {
1084 margin: 0;
1085 }
1086 .input-with-label > input[type=checkbox] {
1087 vertical-align: sub;
1088 }
1089 .input-with-label > input[type=radio] {
1090 vertical-align: sub;
1091 }
1092 .input-with-label > label {
1093 font-weight: initial;
1094 margin: 0 0.25em 0 0.25em;
1095 vertical-align: middle;
1096 }
1097
+25 -18
--- src/fileedit.c
+++ src/fileedit.c
@@ -1630,15 +1630,19 @@
16301630
/* will be moved into the tab container via JS */);
16311631
16321632
/* Main tab container... */
16331633
CX("<div id='fileedit-tabs' class='tab-container'></div>");
16341634
1635
+ /* The .hidden class on the following tab elements is to help lessen
1636
+ the FOUC effect of the tabs before JS re-assembles them. */
1637
+
16351638
/***** File/version info tab *****/
16361639
{
16371640
CX("<div id='fileedit-tab-fileselect' "
16381641
"data-tab-parent='fileedit-tabs' "
1639
- "data-tab-label='File Info &amp; Selection'"
1642
+ "data-tab-label='File Info &amp; Selection' "
1643
+ "class='hidden'"
16401644
">");
16411645
CX("<fieldset id='file-version-details'>"
16421646
"<legend>File/Version</legend>"
16431647
"<div>No file loaded.</div>"
16441648
"</fieldset>");
@@ -1649,11 +1653,12 @@
16491653
16501654
/******* Content tab *******/
16511655
{
16521656
CX("<div id='fileedit-tab-content' "
16531657
"data-tab-parent='fileedit-tabs' "
1654
- "data-tab-label='File Content'"
1658
+ "data-tab-label='File Content' "
1659
+ "class='hidden'"
16551660
">");
16561661
CX("<div class='flex-container flex-row child-gap-small'>");
16571662
CX("<button class='fileedit-content-reload confirmer' "
16581663
"title='Reload the file from the server, discarding "
16591664
"any local edits. To help avoid accidental loss of "
@@ -1679,11 +1684,12 @@
16791684
16801685
/****** Preview tab ******/
16811686
{
16821687
CX("<div id='fileedit-tab-preview' "
16831688
"data-tab-parent='fileedit-tabs' "
1684
- "data-tab-label='Preview'"
1689
+ "data-tab-label='Preview' "
1690
+ "class='hidden'"
16851691
">");
16861692
CX("<div class='fileedit-options flex-container flex-row'>");
16871693
CX("<button id='btn-preview-refresh' "
16881694
"data-f-preview-from='fileContent' "
16891695
/* ^^^ fossil.page[methodName]() OR text source elem ID,
@@ -1741,11 +1747,12 @@
17411747
17421748
/****** Diff tab ******/
17431749
{
17441750
CX("<div id='fileedit-tab-diff' "
17451751
"data-tab-parent='fileedit-tabs' "
1746
- "data-tab-label='Diff'"
1752
+ "data-tab-label='Diff' "
1753
+ "class='hidden'"
17471754
">");
17481755
17491756
CX("<div class='fileedit-options flex-container flex-row' "
17501757
"id='fileedit-tab-diff-buttons'>");
17511758
CX("<button class='sbs'>Side-by-side</button>"
@@ -1773,11 +1780,12 @@
17731780
}
17741781
17751782
/****** Commit ******/
17761783
CX("<div id='fileedit-tab-commit' "
17771784
"data-tab-parent='fileedit-tabs' "
1778
- "data-tab-label='Commit'"
1785
+ "data-tab-label='Commit' "
1786
+ "class='hidden'"
17791787
">");
17801788
{
17811789
/******* Commit flags/options *******/
17821790
CX("<div class='fileedit-options flex-container flex-row'>");
17831791
style_labeled_checkbox("cb-dry-run",
@@ -1894,11 +1902,12 @@
18941902
CX("</div>"/*#fileedit-tab-commit*/);
18951903
18961904
/****** Help/Tips ******/
18971905
CX("<div id='fileedit-tab-help' "
18981906
"data-tab-parent='fileedit-tabs' "
1899
- "data-tab-label='Help'"
1907
+ "data-tab-label='Help' "
1908
+ "class='hidden'"
19001909
">");
19011910
{
19021911
CX("<h1>Help &amp; Tips</h1>");
19031912
CX("<ul>");
19041913
CX("<li><strong>Only files matching the <code>fileedit-glob</code> "
@@ -1949,28 +1958,26 @@
19491958
blob_appendf(&endScript,");\n");
19501959
}
19511960
19521961
blob_reset(&err);
19531962
CheckinMiniInfo_cleanup(&cimi);
1954
- style_emit_script_fossil_bootstrap(0);
1955
- append_diff_javascript(1);
1956
- builtin_request_js("fossil.fetch.js");
1957
- builtin_request_js("fossil.dom.js");
1958
- builtin_request_js("fossil.tabs.js");
1959
- builtin_request_js("fossil.confirmer.js");
1960
- builtin_request_js("fossil.storage.js");
1961
-
1963
+
1964
+ builtin_request_js("sbsdiff.js");
1965
+ style_emit_fossil_js_apis(0, "fetch", "dom", "tabs", "confirmer",
1966
+ "storage", 0);
1967
+ builtin_fulfill_js_requests();
19621968
/*
19631969
** Set up a JS-side mapping of the AJAX_RENDER_xyz values. This is
19641970
** used for dynamically toggling certain UI components on and off.
1965
- ** Must come before fossil.page.fileedit.js and after the fetches
1966
- ** above.
1971
+ ** Must come after window.fossil has been intialized and before
1972
+ ** fossil.page.fileedit.js. Potential TODO: move this into the
1973
+ ** window.fossil bootstrapping so that we don't have to "fulfill"
1974
+ ** the JS multiple times.
19671975
*/
1968
- builtin_fulfill_js_requests();
19691976
ajax_emit_js_preview_modes(1);
1970
-
19711977
builtin_request_js("fossil.page.fileedit.js");
1978
+ builtin_fulfill_js_requests();
19721979
if(blob_size(&endScript)>0){
19731980
style_emit_script_tag(0,0);
19741981
CX("\n(function(){\n");
19751982
CX("try{\n%b}\n"
19761983
"catch(e){"
19771984
--- src/fileedit.c
+++ src/fileedit.c
@@ -1630,15 +1630,19 @@
1630 /* will be moved into the tab container via JS */);
1631
1632 /* Main tab container... */
1633 CX("<div id='fileedit-tabs' class='tab-container'></div>");
1634
 
 
 
1635 /***** File/version info tab *****/
1636 {
1637 CX("<div id='fileedit-tab-fileselect' "
1638 "data-tab-parent='fileedit-tabs' "
1639 "data-tab-label='File Info &amp; Selection'"
 
1640 ">");
1641 CX("<fieldset id='file-version-details'>"
1642 "<legend>File/Version</legend>"
1643 "<div>No file loaded.</div>"
1644 "</fieldset>");
@@ -1649,11 +1653,12 @@
1649
1650 /******* Content tab *******/
1651 {
1652 CX("<div id='fileedit-tab-content' "
1653 "data-tab-parent='fileedit-tabs' "
1654 "data-tab-label='File Content'"
 
1655 ">");
1656 CX("<div class='flex-container flex-row child-gap-small'>");
1657 CX("<button class='fileedit-content-reload confirmer' "
1658 "title='Reload the file from the server, discarding "
1659 "any local edits. To help avoid accidental loss of "
@@ -1679,11 +1684,12 @@
1679
1680 /****** Preview tab ******/
1681 {
1682 CX("<div id='fileedit-tab-preview' "
1683 "data-tab-parent='fileedit-tabs' "
1684 "data-tab-label='Preview'"
 
1685 ">");
1686 CX("<div class='fileedit-options flex-container flex-row'>");
1687 CX("<button id='btn-preview-refresh' "
1688 "data-f-preview-from='fileContent' "
1689 /* ^^^ fossil.page[methodName]() OR text source elem ID,
@@ -1741,11 +1747,12 @@
1741
1742 /****** Diff tab ******/
1743 {
1744 CX("<div id='fileedit-tab-diff' "
1745 "data-tab-parent='fileedit-tabs' "
1746 "data-tab-label='Diff'"
 
1747 ">");
1748
1749 CX("<div class='fileedit-options flex-container flex-row' "
1750 "id='fileedit-tab-diff-buttons'>");
1751 CX("<button class='sbs'>Side-by-side</button>"
@@ -1773,11 +1780,12 @@
1773 }
1774
1775 /****** Commit ******/
1776 CX("<div id='fileedit-tab-commit' "
1777 "data-tab-parent='fileedit-tabs' "
1778 "data-tab-label='Commit'"
 
1779 ">");
1780 {
1781 /******* Commit flags/options *******/
1782 CX("<div class='fileedit-options flex-container flex-row'>");
1783 style_labeled_checkbox("cb-dry-run",
@@ -1894,11 +1902,12 @@
1894 CX("</div>"/*#fileedit-tab-commit*/);
1895
1896 /****** Help/Tips ******/
1897 CX("<div id='fileedit-tab-help' "
1898 "data-tab-parent='fileedit-tabs' "
1899 "data-tab-label='Help'"
 
1900 ">");
1901 {
1902 CX("<h1>Help &amp; Tips</h1>");
1903 CX("<ul>");
1904 CX("<li><strong>Only files matching the <code>fileedit-glob</code> "
@@ -1949,28 +1958,26 @@
1949 blob_appendf(&endScript,");\n");
1950 }
1951
1952 blob_reset(&err);
1953 CheckinMiniInfo_cleanup(&cimi);
1954 style_emit_script_fossil_bootstrap(0);
1955 append_diff_javascript(1);
1956 builtin_request_js("fossil.fetch.js");
1957 builtin_request_js("fossil.dom.js");
1958 builtin_request_js("fossil.tabs.js");
1959 builtin_request_js("fossil.confirmer.js");
1960 builtin_request_js("fossil.storage.js");
1961
1962 /*
1963 ** Set up a JS-side mapping of the AJAX_RENDER_xyz values. This is
1964 ** used for dynamically toggling certain UI components on and off.
1965 ** Must come before fossil.page.fileedit.js and after the fetches
1966 ** above.
 
 
1967 */
1968 builtin_fulfill_js_requests();
1969 ajax_emit_js_preview_modes(1);
1970
1971 builtin_request_js("fossil.page.fileedit.js");
 
1972 if(blob_size(&endScript)>0){
1973 style_emit_script_tag(0,0);
1974 CX("\n(function(){\n");
1975 CX("try{\n%b}\n"
1976 "catch(e){"
1977
--- src/fileedit.c
+++ src/fileedit.c
@@ -1630,15 +1630,19 @@
1630 /* will be moved into the tab container via JS */);
1631
1632 /* Main tab container... */
1633 CX("<div id='fileedit-tabs' class='tab-container'></div>");
1634
1635 /* The .hidden class on the following tab elements is to help lessen
1636 the FOUC effect of the tabs before JS re-assembles them. */
1637
1638 /***** File/version info tab *****/
1639 {
1640 CX("<div id='fileedit-tab-fileselect' "
1641 "data-tab-parent='fileedit-tabs' "
1642 "data-tab-label='File Info &amp; Selection' "
1643 "class='hidden'"
1644 ">");
1645 CX("<fieldset id='file-version-details'>"
1646 "<legend>File/Version</legend>"
1647 "<div>No file loaded.</div>"
1648 "</fieldset>");
@@ -1649,11 +1653,12 @@
1653
1654 /******* Content tab *******/
1655 {
1656 CX("<div id='fileedit-tab-content' "
1657 "data-tab-parent='fileedit-tabs' "
1658 "data-tab-label='File Content' "
1659 "class='hidden'"
1660 ">");
1661 CX("<div class='flex-container flex-row child-gap-small'>");
1662 CX("<button class='fileedit-content-reload confirmer' "
1663 "title='Reload the file from the server, discarding "
1664 "any local edits. To help avoid accidental loss of "
@@ -1679,11 +1684,12 @@
1684
1685 /****** Preview tab ******/
1686 {
1687 CX("<div id='fileedit-tab-preview' "
1688 "data-tab-parent='fileedit-tabs' "
1689 "data-tab-label='Preview' "
1690 "class='hidden'"
1691 ">");
1692 CX("<div class='fileedit-options flex-container flex-row'>");
1693 CX("<button id='btn-preview-refresh' "
1694 "data-f-preview-from='fileContent' "
1695 /* ^^^ fossil.page[methodName]() OR text source elem ID,
@@ -1741,11 +1747,12 @@
1747
1748 /****** Diff tab ******/
1749 {
1750 CX("<div id='fileedit-tab-diff' "
1751 "data-tab-parent='fileedit-tabs' "
1752 "data-tab-label='Diff' "
1753 "class='hidden'"
1754 ">");
1755
1756 CX("<div class='fileedit-options flex-container flex-row' "
1757 "id='fileedit-tab-diff-buttons'>");
1758 CX("<button class='sbs'>Side-by-side</button>"
@@ -1773,11 +1780,12 @@
1780 }
1781
1782 /****** Commit ******/
1783 CX("<div id='fileedit-tab-commit' "
1784 "data-tab-parent='fileedit-tabs' "
1785 "data-tab-label='Commit' "
1786 "class='hidden'"
1787 ">");
1788 {
1789 /******* Commit flags/options *******/
1790 CX("<div class='fileedit-options flex-container flex-row'>");
1791 style_labeled_checkbox("cb-dry-run",
@@ -1894,11 +1902,12 @@
1902 CX("</div>"/*#fileedit-tab-commit*/);
1903
1904 /****** Help/Tips ******/
1905 CX("<div id='fileedit-tab-help' "
1906 "data-tab-parent='fileedit-tabs' "
1907 "data-tab-label='Help' "
1908 "class='hidden'"
1909 ">");
1910 {
1911 CX("<h1>Help &amp; Tips</h1>");
1912 CX("<ul>");
1913 CX("<li><strong>Only files matching the <code>fileedit-glob</code> "
@@ -1949,28 +1958,26 @@
1958 blob_appendf(&endScript,");\n");
1959 }
1960
1961 blob_reset(&err);
1962 CheckinMiniInfo_cleanup(&cimi);
1963
1964 builtin_request_js("sbsdiff.js");
1965 style_emit_fossil_js_apis(0, "fetch", "dom", "tabs", "confirmer",
1966 "storage", 0);
1967 builtin_fulfill_js_requests();
 
 
 
1968 /*
1969 ** Set up a JS-side mapping of the AJAX_RENDER_xyz values. This is
1970 ** used for dynamically toggling certain UI components on and off.
1971 ** Must come after window.fossil has been intialized and before
1972 ** fossil.page.fileedit.js. Potential TODO: move this into the
1973 ** window.fossil bootstrapping so that we don't have to "fulfill"
1974 ** the JS multiple times.
1975 */
 
1976 ajax_emit_js_preview_modes(1);
 
1977 builtin_request_js("fossil.page.fileedit.js");
1978 builtin_fulfill_js_requests();
1979 if(blob_size(&endScript)>0){
1980 style_emit_script_tag(0,0);
1981 CX("\n(function(){\n");
1982 CX("try{\n%b}\n"
1983 "catch(e){"
1984
+25 -18
--- src/fileedit.c
+++ src/fileedit.c
@@ -1630,15 +1630,19 @@
16301630
/* will be moved into the tab container via JS */);
16311631
16321632
/* Main tab container... */
16331633
CX("<div id='fileedit-tabs' class='tab-container'></div>");
16341634
1635
+ /* The .hidden class on the following tab elements is to help lessen
1636
+ the FOUC effect of the tabs before JS re-assembles them. */
1637
+
16351638
/***** File/version info tab *****/
16361639
{
16371640
CX("<div id='fileedit-tab-fileselect' "
16381641
"data-tab-parent='fileedit-tabs' "
1639
- "data-tab-label='File Info &amp; Selection'"
1642
+ "data-tab-label='File Info &amp; Selection' "
1643
+ "class='hidden'"
16401644
">");
16411645
CX("<fieldset id='file-version-details'>"
16421646
"<legend>File/Version</legend>"
16431647
"<div>No file loaded.</div>"
16441648
"</fieldset>");
@@ -1649,11 +1653,12 @@
16491653
16501654
/******* Content tab *******/
16511655
{
16521656
CX("<div id='fileedit-tab-content' "
16531657
"data-tab-parent='fileedit-tabs' "
1654
- "data-tab-label='File Content'"
1658
+ "data-tab-label='File Content' "
1659
+ "class='hidden'"
16551660
">");
16561661
CX("<div class='flex-container flex-row child-gap-small'>");
16571662
CX("<button class='fileedit-content-reload confirmer' "
16581663
"title='Reload the file from the server, discarding "
16591664
"any local edits. To help avoid accidental loss of "
@@ -1679,11 +1684,12 @@
16791684
16801685
/****** Preview tab ******/
16811686
{
16821687
CX("<div id='fileedit-tab-preview' "
16831688
"data-tab-parent='fileedit-tabs' "
1684
- "data-tab-label='Preview'"
1689
+ "data-tab-label='Preview' "
1690
+ "class='hidden'"
16851691
">");
16861692
CX("<div class='fileedit-options flex-container flex-row'>");
16871693
CX("<button id='btn-preview-refresh' "
16881694
"data-f-preview-from='fileContent' "
16891695
/* ^^^ fossil.page[methodName]() OR text source elem ID,
@@ -1741,11 +1747,12 @@
17411747
17421748
/****** Diff tab ******/
17431749
{
17441750
CX("<div id='fileedit-tab-diff' "
17451751
"data-tab-parent='fileedit-tabs' "
1746
- "data-tab-label='Diff'"
1752
+ "data-tab-label='Diff' "
1753
+ "class='hidden'"
17471754
">");
17481755
17491756
CX("<div class='fileedit-options flex-container flex-row' "
17501757
"id='fileedit-tab-diff-buttons'>");
17511758
CX("<button class='sbs'>Side-by-side</button>"
@@ -1773,11 +1780,12 @@
17731780
}
17741781
17751782
/****** Commit ******/
17761783
CX("<div id='fileedit-tab-commit' "
17771784
"data-tab-parent='fileedit-tabs' "
1778
- "data-tab-label='Commit'"
1785
+ "data-tab-label='Commit' "
1786
+ "class='hidden'"
17791787
">");
17801788
{
17811789
/******* Commit flags/options *******/
17821790
CX("<div class='fileedit-options flex-container flex-row'>");
17831791
style_labeled_checkbox("cb-dry-run",
@@ -1894,11 +1902,12 @@
18941902
CX("</div>"/*#fileedit-tab-commit*/);
18951903
18961904
/****** Help/Tips ******/
18971905
CX("<div id='fileedit-tab-help' "
18981906
"data-tab-parent='fileedit-tabs' "
1899
- "data-tab-label='Help'"
1907
+ "data-tab-label='Help' "
1908
+ "class='hidden'"
19001909
">");
19011910
{
19021911
CX("<h1>Help &amp; Tips</h1>");
19031912
CX("<ul>");
19041913
CX("<li><strong>Only files matching the <code>fileedit-glob</code> "
@@ -1949,28 +1958,26 @@
19491958
blob_appendf(&endScript,");\n");
19501959
}
19511960
19521961
blob_reset(&err);
19531962
CheckinMiniInfo_cleanup(&cimi);
1954
- style_emit_script_fossil_bootstrap(0);
1955
- append_diff_javascript(1);
1956
- builtin_request_js("fossil.fetch.js");
1957
- builtin_request_js("fossil.dom.js");
1958
- builtin_request_js("fossil.tabs.js");
1959
- builtin_request_js("fossil.confirmer.js");
1960
- builtin_request_js("fossil.storage.js");
1961
-
1963
+
1964
+ builtin_request_js("sbsdiff.js");
1965
+ style_emit_fossil_js_apis(0, "fetch", "dom", "tabs", "confirmer",
1966
+ "storage", 0);
1967
+ builtin_fulfill_js_requests();
19621968
/*
19631969
** Set up a JS-side mapping of the AJAX_RENDER_xyz values. This is
19641970
** used for dynamically toggling certain UI components on and off.
1965
- ** Must come before fossil.page.fileedit.js and after the fetches
1966
- ** above.
1971
+ ** Must come after window.fossil has been intialized and before
1972
+ ** fossil.page.fileedit.js. Potential TODO: move this into the
1973
+ ** window.fossil bootstrapping so that we don't have to "fulfill"
1974
+ ** the JS multiple times.
19671975
*/
1968
- builtin_fulfill_js_requests();
19691976
ajax_emit_js_preview_modes(1);
1970
-
19711977
builtin_request_js("fossil.page.fileedit.js");
1978
+ builtin_fulfill_js_requests();
19721979
if(blob_size(&endScript)>0){
19731980
style_emit_script_tag(0,0);
19741981
CX("\n(function(){\n");
19751982
CX("try{\n%b}\n"
19761983
"catch(e){"
19771984
--- src/fileedit.c
+++ src/fileedit.c
@@ -1630,15 +1630,19 @@
1630 /* will be moved into the tab container via JS */);
1631
1632 /* Main tab container... */
1633 CX("<div id='fileedit-tabs' class='tab-container'></div>");
1634
 
 
 
1635 /***** File/version info tab *****/
1636 {
1637 CX("<div id='fileedit-tab-fileselect' "
1638 "data-tab-parent='fileedit-tabs' "
1639 "data-tab-label='File Info &amp; Selection'"
 
1640 ">");
1641 CX("<fieldset id='file-version-details'>"
1642 "<legend>File/Version</legend>"
1643 "<div>No file loaded.</div>"
1644 "</fieldset>");
@@ -1649,11 +1653,12 @@
1649
1650 /******* Content tab *******/
1651 {
1652 CX("<div id='fileedit-tab-content' "
1653 "data-tab-parent='fileedit-tabs' "
1654 "data-tab-label='File Content'"
 
1655 ">");
1656 CX("<div class='flex-container flex-row child-gap-small'>");
1657 CX("<button class='fileedit-content-reload confirmer' "
1658 "title='Reload the file from the server, discarding "
1659 "any local edits. To help avoid accidental loss of "
@@ -1679,11 +1684,12 @@
1679
1680 /****** Preview tab ******/
1681 {
1682 CX("<div id='fileedit-tab-preview' "
1683 "data-tab-parent='fileedit-tabs' "
1684 "data-tab-label='Preview'"
 
1685 ">");
1686 CX("<div class='fileedit-options flex-container flex-row'>");
1687 CX("<button id='btn-preview-refresh' "
1688 "data-f-preview-from='fileContent' "
1689 /* ^^^ fossil.page[methodName]() OR text source elem ID,
@@ -1741,11 +1747,12 @@
1741
1742 /****** Diff tab ******/
1743 {
1744 CX("<div id='fileedit-tab-diff' "
1745 "data-tab-parent='fileedit-tabs' "
1746 "data-tab-label='Diff'"
 
1747 ">");
1748
1749 CX("<div class='fileedit-options flex-container flex-row' "
1750 "id='fileedit-tab-diff-buttons'>");
1751 CX("<button class='sbs'>Side-by-side</button>"
@@ -1773,11 +1780,12 @@
1773 }
1774
1775 /****** Commit ******/
1776 CX("<div id='fileedit-tab-commit' "
1777 "data-tab-parent='fileedit-tabs' "
1778 "data-tab-label='Commit'"
 
1779 ">");
1780 {
1781 /******* Commit flags/options *******/
1782 CX("<div class='fileedit-options flex-container flex-row'>");
1783 style_labeled_checkbox("cb-dry-run",
@@ -1894,11 +1902,12 @@
1894 CX("</div>"/*#fileedit-tab-commit*/);
1895
1896 /****** Help/Tips ******/
1897 CX("<div id='fileedit-tab-help' "
1898 "data-tab-parent='fileedit-tabs' "
1899 "data-tab-label='Help'"
 
1900 ">");
1901 {
1902 CX("<h1>Help &amp; Tips</h1>");
1903 CX("<ul>");
1904 CX("<li><strong>Only files matching the <code>fileedit-glob</code> "
@@ -1949,28 +1958,26 @@
1949 blob_appendf(&endScript,");\n");
1950 }
1951
1952 blob_reset(&err);
1953 CheckinMiniInfo_cleanup(&cimi);
1954 style_emit_script_fossil_bootstrap(0);
1955 append_diff_javascript(1);
1956 builtin_request_js("fossil.fetch.js");
1957 builtin_request_js("fossil.dom.js");
1958 builtin_request_js("fossil.tabs.js");
1959 builtin_request_js("fossil.confirmer.js");
1960 builtin_request_js("fossil.storage.js");
1961
1962 /*
1963 ** Set up a JS-side mapping of the AJAX_RENDER_xyz values. This is
1964 ** used for dynamically toggling certain UI components on and off.
1965 ** Must come before fossil.page.fileedit.js and after the fetches
1966 ** above.
 
 
1967 */
1968 builtin_fulfill_js_requests();
1969 ajax_emit_js_preview_modes(1);
1970
1971 builtin_request_js("fossil.page.fileedit.js");
 
1972 if(blob_size(&endScript)>0){
1973 style_emit_script_tag(0,0);
1974 CX("\n(function(){\n");
1975 CX("try{\n%b}\n"
1976 "catch(e){"
1977
--- src/fileedit.c
+++ src/fileedit.c
@@ -1630,15 +1630,19 @@
1630 /* will be moved into the tab container via JS */);
1631
1632 /* Main tab container... */
1633 CX("<div id='fileedit-tabs' class='tab-container'></div>");
1634
1635 /* The .hidden class on the following tab elements is to help lessen
1636 the FOUC effect of the tabs before JS re-assembles them. */
1637
1638 /***** File/version info tab *****/
1639 {
1640 CX("<div id='fileedit-tab-fileselect' "
1641 "data-tab-parent='fileedit-tabs' "
1642 "data-tab-label='File Info &amp; Selection' "
1643 "class='hidden'"
1644 ">");
1645 CX("<fieldset id='file-version-details'>"
1646 "<legend>File/Version</legend>"
1647 "<div>No file loaded.</div>"
1648 "</fieldset>");
@@ -1649,11 +1653,12 @@
1653
1654 /******* Content tab *******/
1655 {
1656 CX("<div id='fileedit-tab-content' "
1657 "data-tab-parent='fileedit-tabs' "
1658 "data-tab-label='File Content' "
1659 "class='hidden'"
1660 ">");
1661 CX("<div class='flex-container flex-row child-gap-small'>");
1662 CX("<button class='fileedit-content-reload confirmer' "
1663 "title='Reload the file from the server, discarding "
1664 "any local edits. To help avoid accidental loss of "
@@ -1679,11 +1684,12 @@
1684
1685 /****** Preview tab ******/
1686 {
1687 CX("<div id='fileedit-tab-preview' "
1688 "data-tab-parent='fileedit-tabs' "
1689 "data-tab-label='Preview' "
1690 "class='hidden'"
1691 ">");
1692 CX("<div class='fileedit-options flex-container flex-row'>");
1693 CX("<button id='btn-preview-refresh' "
1694 "data-f-preview-from='fileContent' "
1695 /* ^^^ fossil.page[methodName]() OR text source elem ID,
@@ -1741,11 +1747,12 @@
1747
1748 /****** Diff tab ******/
1749 {
1750 CX("<div id='fileedit-tab-diff' "
1751 "data-tab-parent='fileedit-tabs' "
1752 "data-tab-label='Diff' "
1753 "class='hidden'"
1754 ">");
1755
1756 CX("<div class='fileedit-options flex-container flex-row' "
1757 "id='fileedit-tab-diff-buttons'>");
1758 CX("<button class='sbs'>Side-by-side</button>"
@@ -1773,11 +1780,12 @@
1780 }
1781
1782 /****** Commit ******/
1783 CX("<div id='fileedit-tab-commit' "
1784 "data-tab-parent='fileedit-tabs' "
1785 "data-tab-label='Commit' "
1786 "class='hidden'"
1787 ">");
1788 {
1789 /******* Commit flags/options *******/
1790 CX("<div class='fileedit-options flex-container flex-row'>");
1791 style_labeled_checkbox("cb-dry-run",
@@ -1894,11 +1902,12 @@
1902 CX("</div>"/*#fileedit-tab-commit*/);
1903
1904 /****** Help/Tips ******/
1905 CX("<div id='fileedit-tab-help' "
1906 "data-tab-parent='fileedit-tabs' "
1907 "data-tab-label='Help' "
1908 "class='hidden'"
1909 ">");
1910 {
1911 CX("<h1>Help &amp; Tips</h1>");
1912 CX("<ul>");
1913 CX("<li><strong>Only files matching the <code>fileedit-glob</code> "
@@ -1949,28 +1958,26 @@
1958 blob_appendf(&endScript,");\n");
1959 }
1960
1961 blob_reset(&err);
1962 CheckinMiniInfo_cleanup(&cimi);
1963
1964 builtin_request_js("sbsdiff.js");
1965 style_emit_fossil_js_apis(0, "fetch", "dom", "tabs", "confirmer",
1966 "storage", 0);
1967 builtin_fulfill_js_requests();
 
 
 
1968 /*
1969 ** Set up a JS-side mapping of the AJAX_RENDER_xyz values. This is
1970 ** used for dynamically toggling certain UI components on and off.
1971 ** Must come after window.fossil has been intialized and before
1972 ** fossil.page.fileedit.js. Potential TODO: move this into the
1973 ** window.fossil bootstrapping so that we don't have to "fulfill"
1974 ** the JS multiple times.
1975 */
 
1976 ajax_emit_js_preview_modes(1);
 
1977 builtin_request_js("fossil.page.fileedit.js");
1978 builtin_fulfill_js_requests();
1979 if(blob_size(&endScript)>0){
1980 style_emit_script_tag(0,0);
1981 CX("\n(function(){\n");
1982 CX("try{\n%b}\n"
1983 "catch(e){"
1984
+4 -8
--- src/forum.c
+++ src/forum.c
@@ -749,22 +749,18 @@
749749
forumthread_delete(pThread);
750750
return target;
751751
}
752752
753753
/*
754
-** The first time this is called, it emits SCRIPT tags to load various
755
-** forum-related JavaScript. Ideally it should be called near the end
756
-** of the page, immediately before the call to style_footer() (which
757
-** closes the document's <BODY> and <HTML> tags). Calls after the first
758
-** are a no-op.
754
+** Emits all JS code required by /forumpost.
759755
*/
760
-static void forum_emit_page_js(){
756
+static void forumpost_emit_page_js(){
761757
static int once = 0;
762758
if(0==once){
763759
once = 1;
760
+ style_emit_script_fossil_bootstrap(1);
764761
builtin_request_js("forum.js");
765
- style_emit_script_fossil_bootstrap(0);
766762
builtin_request_js("fossil.dom.js");
767763
builtin_request_js("fossil.page.forumpost.js");
768764
}
769765
}
770766
@@ -894,11 +890,11 @@
894890
}else{
895891
style_submenu_element("Chronological", "%R/%s/%s?t=c", g.zPath, zName);
896892
style_submenu_element("Unformatted", "%R/%s/%s?t=r", g.zPath, zName);
897893
forum_display_hierarchical(froot, fpid);
898894
}
899
- forum_emit_page_js();
895
+ forumpost_emit_page_js();
900896
style_footer();
901897
}
902898
903899
/*
904900
** Return true if a forum post should be moderated.
905901
--- src/forum.c
+++ src/forum.c
@@ -749,22 +749,18 @@
749 forumthread_delete(pThread);
750 return target;
751 }
752
753 /*
754 ** The first time this is called, it emits SCRIPT tags to load various
755 ** forum-related JavaScript. Ideally it should be called near the end
756 ** of the page, immediately before the call to style_footer() (which
757 ** closes the document's <BODY> and <HTML> tags). Calls after the first
758 ** are a no-op.
759 */
760 static void forum_emit_page_js(){
761 static int once = 0;
762 if(0==once){
763 once = 1;
 
764 builtin_request_js("forum.js");
765 style_emit_script_fossil_bootstrap(0);
766 builtin_request_js("fossil.dom.js");
767 builtin_request_js("fossil.page.forumpost.js");
768 }
769 }
770
@@ -894,11 +890,11 @@
894 }else{
895 style_submenu_element("Chronological", "%R/%s/%s?t=c", g.zPath, zName);
896 style_submenu_element("Unformatted", "%R/%s/%s?t=r", g.zPath, zName);
897 forum_display_hierarchical(froot, fpid);
898 }
899 forum_emit_page_js();
900 style_footer();
901 }
902
903 /*
904 ** Return true if a forum post should be moderated.
905
--- src/forum.c
+++ src/forum.c
@@ -749,22 +749,18 @@
749 forumthread_delete(pThread);
750 return target;
751 }
752
753 /*
754 ** Emits all JS code required by /forumpost.
 
 
 
 
755 */
756 static void forumpost_emit_page_js(){
757 static int once = 0;
758 if(0==once){
759 once = 1;
760 style_emit_script_fossil_bootstrap(1);
761 builtin_request_js("forum.js");
 
762 builtin_request_js("fossil.dom.js");
763 builtin_request_js("fossil.page.forumpost.js");
764 }
765 }
766
@@ -894,11 +890,11 @@
890 }else{
891 style_submenu_element("Chronological", "%R/%s/%s?t=c", g.zPath, zName);
892 style_submenu_element("Unformatted", "%R/%s/%s?t=r", g.zPath, zName);
893 forum_display_hierarchical(froot, fpid);
894 }
895 forumpost_emit_page_js();
896 style_footer();
897 }
898
899 /*
900 ** Return true if a forum post should be moderated.
901
+1 -1
--- src/forum.js
+++ src/forum.js
@@ -14,6 +14,6 @@
1414
var h = x[0].scrollHeight;
1515
var y = absoluteY(x[0]);
1616
if( w>h ) y = y + (h-w)/2;
1717
if( y>0 ) window.scrollTo(0, y);
1818
}
19
-})()
19
+})();
2020
--- src/forum.js
+++ src/forum.js
@@ -14,6 +14,6 @@
14 var h = x[0].scrollHeight;
15 var y = absoluteY(x[0]);
16 if( w>h ) y = y + (h-w)/2;
17 if( y>0 ) window.scrollTo(0, y);
18 }
19 })()
20
--- src/forum.js
+++ src/forum.js
@@ -14,6 +14,6 @@
14 var h = x[0].scrollHeight;
15 var y = absoluteY(x[0]);
16 if( w>h ) y = y + (h-w)/2;
17 if( y>0 ) window.scrollTo(0, y);
18 }
19 })();
20
--- src/fossil.page.fileedit.js
+++ src/fossil.page.fileedit.js
@@ -121,11 +121,11 @@
121121
and that would be horribly inefficient (meaning "battery-consuming"
122122
on mobile devices).
123123
*/
124124
const $stash = {
125125
keys: {
126
- index: F.page.name+'/index'
126
+ index: F.page.name+'.index'
127127
},
128128
/**
129129
index: {
130130
"CHECKIN_HASH:FILENAME": {file info w/o content}
131131
...
@@ -149,27 +149,12 @@
149149
/** Returns the index object, fetching it from the stash or creating
150150
it anew on the first call. */
151151
getIndex: function(){
152152
if(!this.index){
153153
this.index = F.storage.getJSON(
154
- this.keys.index, undefined
154
+ this.keys.index, {}
155155
);
156
- if(!this.index){
157
- /*check for and remove/replace older name. This whole block
158
- can be removed once the test phase is done (don't want to
159
- invalidate the testers' edits on the test server). When
160
- doing so, be sure to replace undefined in the above
161
- getJSON() call with {}. */
162
- const oldName = F.page.name+':index';
163
- this.index = F.storage.getJSON(oldName,undefined);
164
- if(this.index){
165
- F.storage.remove(oldName);
166
- this.storeIndex();
167
- }else{
168
- this.index = {};
169
- }
170
- }
171156
}
172157
return this.index;
173158
},
174159
_fireStashEvent: function(){
175160
if(this._disableNextEvent) delete this._disableNextEvent;
176161
177162
ADDED src/fossil.page.wikiedit.js
--- src/fossil.page.fileedit.js
+++ src/fossil.page.fileedit.js
@@ -121,11 +121,11 @@
121 and that would be horribly inefficient (meaning "battery-consuming"
122 on mobile devices).
123 */
124 const $stash = {
125 keys: {
126 index: F.page.name+'/index'
127 },
128 /**
129 index: {
130 "CHECKIN_HASH:FILENAME": {file info w/o content}
131 ...
@@ -149,27 +149,12 @@
149 /** Returns the index object, fetching it from the stash or creating
150 it anew on the first call. */
151 getIndex: function(){
152 if(!this.index){
153 this.index = F.storage.getJSON(
154 this.keys.index, undefined
155 );
156 if(!this.index){
157 /*check for and remove/replace older name. This whole block
158 can be removed once the test phase is done (don't want to
159 invalidate the testers' edits on the test server). When
160 doing so, be sure to replace undefined in the above
161 getJSON() call with {}. */
162 const oldName = F.page.name+':index';
163 this.index = F.storage.getJSON(oldName,undefined);
164 if(this.index){
165 F.storage.remove(oldName);
166 this.storeIndex();
167 }else{
168 this.index = {};
169 }
170 }
171 }
172 return this.index;
173 },
174 _fireStashEvent: function(){
175 if(this._disableNextEvent) delete this._disableNextEvent;
176
177 DDED src/fossil.page.wikiedit.js
--- src/fossil.page.fileedit.js
+++ src/fossil.page.fileedit.js
@@ -121,11 +121,11 @@
121 and that would be horribly inefficient (meaning "battery-consuming"
122 on mobile devices).
123 */
124 const $stash = {
125 keys: {
126 index: F.page.name+'.index'
127 },
128 /**
129 index: {
130 "CHECKIN_HASH:FILENAME": {file info w/o content}
131 ...
@@ -149,27 +149,12 @@
149 /** Returns the index object, fetching it from the stash or creating
150 it anew on the first call. */
151 getIndex: function(){
152 if(!this.index){
153 this.index = F.storage.getJSON(
154 this.keys.index, {}
155 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156 }
157 return this.index;
158 },
159 _fireStashEvent: function(){
160 if(this._disableNextEvent) delete this._disableNextEvent;
161
162 DDED src/fossil.page.wikiedit.js
--- a/src/fossil.page.wikiedit.js
+++ b/src/fossil.page.wikiedit.js
@@ -0,0 +1,176 @@
1
+notag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
2
+ parent: parent UUID string or null if no parent,
3
+ isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
4
+ "use strict";
5
+ /**
6
+ Clienuires that
7
+ the fossil JS bootstrapping is complete and that several fossil
8
+ JS APIs have been installed: fossil.fetch, fossil.dom,
9
+ fossil.tabs, fossil.storage, fossil.confirmer, fossil.popupwidget.
10
+
11
+ Custom events which can be listened for via
12
+ fossil.page.addEventListener():
13
+
14
+ - Event 'wiki-page-loaded': passes on information when it
15
+ loads a wiki (whether from the network or its internal local-edit
16
+ Note that
17
+ the symbols themselves are *actually* defined in CSS, so if
18
+ they're changed there they also need to be changed here. cache), in the form of an "winfo" objec
19
+ 'change',n information when it
20
+ loads a wiki (whether from the networcontent: stringinnerHTML =for a sandbox page or new page,
21
+ parent: parent UUID string or null if no parent,
22
+ isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
23
+ "use strict";
24
+ /**
25
+ Client-side implementation of the /wikiedit app. Requires that
26
+ the fossil JS bootfileedit-file-loadedtarget.innerHTML =for notag" |(functionnotag" |(function(F/*ttnotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
27
+ parent: par {
28
+ isNew: '[+]',
29
+ isModified: '[*]'I@2Ek,1eq@cX,1:P2h3@2HN,P@4yl,N@1tj,2:itJ@2Ej,iG@5~7,g@6lD,3r@6gz,H@4xk,jJ@6m9,1:346@7Vu,1:3Kf@7_S,x@8B2,H@4xk,1c@80s,K:delete P.winfo;
30
+ I@Apl,79@82h,1:PI@7c0,Q@4y0,I@8dV,A:())
31
+ I@7Tk,H@8dW,1:(Di@8Cl,1:,1g@8QT,9:[history]t@8SF,E:[attachments]"W@8SG,13@8To,8:[attach]x4@8Ux,P@8nF,G:page-loaded', r)1bU@9Rt,3qU_12;
32
+ local*/
33
+ (){const select = this.e.select,Object.keys(opt = if(stashed}else{
34
+}
35
+}Wiki p.isModified" = page has local edits.isNew Clienuires that
36
+ the fossil JS bootstrapping is complete and that several fossil
37
+ JS APIs have been installed: fossil.fetch, fossil.dom,
38
+ fossil.tabs, fossil.storage, fossil.confirmer, fossil.popupwidget.
39
+
40
+ Custom events which can be listened for via
41
+ fossil.page.addEventListener():
42
+
43
+ - Event 'wiki-page-loaded': passes on information when it
44
+ loads a wiki (whether from the network or its internal local-edit
45
+ cache), in the form of an "winfo" objec
46
+ 'change',n information when it
47
+ loads a wiki (whether from the networcontent: stringinnerHTML =for a sandbox page or new page,
48
+ parent: parent UUID string or null if no parent,
49
+ isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
50
+ "use strict";
51
+ /**
52
+ Client-side implementation of the /wikiedit app. Requires that
53
+ the fossil JS bootfileedit-file-loadedtarget.innerHTML =for notag" |(functionnotag" |(function(F/*ttnotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
54
+ parent: par {
55
+ isNew: '[+]',
56
+ isModified: '[*]'I@2Ek,1eq@cX,1:P2h3@2HN,P@4yl,N@1tj,2:itJ@2Ej,iG@5~7,g@6lD,3r@6gz,H@4xk,jJ@6m9,1:346@7Vu,1:3Kf@7_S,x@8B2,H@4xk,1c@80s,K:denotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
57
+ parent: parent UUID string or null if no parent,
58
+ isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
59
+ "use strict";
60
+ /**
61
+ Clienuires that
62
+ the fossil JS bootstrapping is complete and that several fossil
63
+ JS APIs have been installed: fossil.fetch, fossil.dom,
64
+ fossil.tabs, fossil.storage, fossil.confirmer, fossil.popupwidget.
65
+
66
+ Custom events which can be listened for via
67
+ fossil.page.addEventListener():
68
+
69
+ - Event 'wiki-page-loaded': passes on information when it
70
+ loads a wiki (whether from the network or its internal local-edit
71
+ cache), in the form of an "winfo" objec
72
+ 'change',n information when it
73
+ loads a wiki (whether from the networcontent: stringinnerHTML =for a sandbox page or new page,
74
+ parent: parent UUID string or null if no parent,
75
+ isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
76
+ "use strict";
77
+ /**
78
+ Client-side implementation of the /wikiedit app. Requires that
79
+ the fossil JS bootfileedit-file-loadedtarget.innerHTML =for notag" |(functionnotag" |(function(F/*ttnotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
80
+ parent: par {
81
+ isNew: '[+]',
82
+ isModified: '[*]'I@2Ek,1eq@cX,1:P2h3@2HN,P@4yl,N@1tj,2:itJ@2Ej,iG@5~7,g@6lD,3r@6gz,H@4xk,jJ@6m9,1:346@7Vu,1:3Kf@7_S,x@8B2,H@4xk,1c@80s,K:delete P.winfo;
83
+ I@Apl,79@82h,1:PI@7c0,Q@4y0,I@8dV,A:())
84
+ I@7Tk,H@8dW,1:(Di@8Cl,1:,1g@8QT,9:[history]t@8SF,E:[attachments]"W@8SG,13@8To,8:[attach]x4@8Ux,P@8nF,G:page-loaded', r)1bU@9Rt,3qU_12;);
85
+editFlag/*for use editFlag || '';
86
+ if(0===arguments){
87
+ if(!wi.version && 'sandbox'!==wi.type) marker.isNewag" |(function(Fnotag" |(function()) marker.isModified;
88
+ }var title, marker = '';;
89
+ if(wi){
90
+ if(!wi.version && 'sandbox'!==wi.type) marker.isNewag" |(function(Fnotag" |(function()) marker.isModified;
91
+ title = wi.nametitle = 'no page loaded';
92
+ }marker);
93
+There are n
94
+stashWattachmentWrappermisc){
95
+ errorAttachmentView |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
96
+ parent: parent UUID string or null if no parent,
97
+ isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
98
+ "use strict";
99
+ erHTML =for a sandbox page fossil.tabs, fossil.storage, fossil.confirmer, fossil.popupwidget.
100
+
101
+ Custom events which can be listened for via
102
+ fossil.page.addEventListener():
103
+
104
+ - Event 'wiki-page-loaded': passes on information when it
105
+ loads a wiki (whether from the network or its internal local-edit
106
+ cache), in the form of an "winfo" objec
107
+ 'change',n information when it
108
+ loads a wiki (whether from the networcontent: stringinnerHTML =for a sandbox page or new page,
109
+ parent: parent UUID string or null if no parent,
110
+ isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
111
+ "use strict";
112
+ /**
113
+ Client-side implementation of the /wikiedit app. Requires that
114
+ the fossil JS bootfileedit-file-loadedtarget.innerHTML =for notag" |(functionnotag" |(function(F/*ttnotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
115
+ parent: par {
116
+ isNew: '[+]',
117
+ isModified: '[*]'I@2Ek,1eq@cX,1:P2h3@2HN,P@4yl,N@1tj,2:itJ@2Ej,iG@5~7,g@6lD,3r@6gz,H@4xk,jJ@6m9,1:346@7Vu,1:3Kf@7_S,x@8B2,H@4xk,1c@80s,K:denotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
118
+ parent: parent UUID string or null if no parent,
119
+ isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
120
+ "use strict";
121
+ /**
122
+ Clienuires that
123
+ the fossil JS bootstrapping is complete and that several fossil
124
+ JS APIs have been installed: fossil.fetch, fossil.dom,
125
+ fossil.tabs, fossil.storage, fossil.confirmer, fossil.popupwidget.
126
+
127
+ Custom events which can be listened for via
128
+ fossil.page.addEventListener():
129
+
130
+ - Event 'wiki-page-loaded': passes on information when it
131
+ loads a wiki (whether from the network or its internal local-edit
132
+ cache), in the form of an "winfo" objec
133
+ 'change',n information when it
134
+ loads a wiki (whether from the networcontent: stringinnerHTML =for a sandbox page or new page,
135
+ parent: parent UUID string or null if no parent,
136
+ isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
137
+ "use strict";
138
+ /**
139
+ Client-side implementation of the /wikiedit app. Requires that
140
+ the fossil JS bootfileedit-file-loadedtarget.innerHTML =for notag" |(functionnotag" |(function(F/*ttnotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
141
+ parent: par {
142
+ isNew: '[+]',
143
+ isModified: '[*]'I@2Ek,1eq@cX,1:P2h3@2HN,P@4yl,N@1tj,2:itJ@2Ej,iG@5~7,g@6lD,3r@6gz,H@4xk,jJ@6m9,1:346@7Vu,1:3Kf@7_S,x@8B2,H@4xk,1c@80s,K:delete P.winfo;
144
+ I@Apl,79@82h,1:PI@7c0,Q@4y0,I@8dV,A:())
145
+ I@7Tk,H@8dW,1:(Di@8Cl,1:,1g@8QT,9:[history]t@8SF,E:[attachments]"W@8SG,13@8To,8:[attach]x4@8Ux,P@8nF,G:page-loaded', r)1bU@9Rt,3qU_12;);
146
+editFlag/*for use editFlag || '';
147
+ if(0===arguments){
148
+ if(!wi.version && 'sandbox'!==wi.type) marker.isNewag" |(function(Fnotag" |(function()) marker.isModified;
149
+ }var title, marker = '';;
150
+ if(wi){
151
+ if(!wi.version && 'sandbox'!==wi.type) marker.isNewag" |(function(Fnotag" |(function()) marker.isModified;
152
+ title = wi.nametitle = 'no page loaded';
153
+ }marker);
154
+There are n
155
+stashW('#wikiedit-page-name > span = []title.push(New)title.push()
156
+ title.push(wi.name);
157
+title.push(}
158
+ title = title.join(' ');
159
+ f.pageTitleHeader.innerText = title;' + title; Updates attachment-related links and returns this. */
160
+ P.updateAttachmentViewconst wrapwrapper);
161
+ const ul = D.ul();
162
+ D.append(wrapper, ul);
163
+ if(!P.winfoD.li(ul "Load a page to get access to itselse if(!P.winfoD.li(ul "Acannot have aD.append(
164
+ D.li(ul),
165
+
166
+page:wi.name,
167
+
168
+ name: wi.name
169
+ })
170
+ }), "Add attachments.")
171
+ );
172
+D.li(ul),
173
+list',{page:wi.name}),
174
+ "List attachments"),
175
+ " (if any)."
176
+
--- a/src/fossil.page.wikiedit.js
+++ b/src/fossil.page.wikiedit.js
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/src/fossil.page.wikiedit.js
+++ b/src/fossil.page.wikiedit.js
@@ -0,0 +1,176 @@
1 notag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
2 parent: parent UUID string or null if no parent,
3 isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
4 "use strict";
5 /**
6 Clienuires that
7 the fossil JS bootstrapping is complete and that several fossil
8 JS APIs have been installed: fossil.fetch, fossil.dom,
9 fossil.tabs, fossil.storage, fossil.confirmer, fossil.popupwidget.
10
11 Custom events which can be listened for via
12 fossil.page.addEventListener():
13
14 - Event 'wiki-page-loaded': passes on information when it
15 loads a wiki (whether from the network or its internal local-edit
16 Note that
17 the symbols themselves are *actually* defined in CSS, so if
18 they're changed there they also need to be changed here. cache), in the form of an "winfo" objec
19 'change',n information when it
20 loads a wiki (whether from the networcontent: stringinnerHTML =for a sandbox page or new page,
21 parent: parent UUID string or null if no parent,
22 isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
23 "use strict";
24 /**
25 Client-side implementation of the /wikiedit app. Requires that
26 the fossil JS bootfileedit-file-loadedtarget.innerHTML =for notag" |(functionnotag" |(function(F/*ttnotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
27 parent: par {
28 isNew: '[+]',
29 isModified: '[*]'I@2Ek,1eq@cX,1:P2h3@2HN,P@4yl,N@1tj,2:itJ@2Ej,iG@5~7,g@6lD,3r@6gz,H@4xk,jJ@6m9,1:346@7Vu,1:3Kf@7_S,x@8B2,H@4xk,1c@80s,K:delete P.winfo;
30 I@Apl,79@82h,1:PI@7c0,Q@4y0,I@8dV,A:())
31 I@7Tk,H@8dW,1:(Di@8Cl,1:,1g@8QT,9:[history]t@8SF,E:[attachments]"W@8SG,13@8To,8:[attach]x4@8Ux,P@8nF,G:page-loaded', r)1bU@9Rt,3qU_12;
32 local*/
33 (){const select = this.e.select,Object.keys(opt = if(stashed}else{
34 }
35 }Wiki p.isModified" = page has local edits.isNew Clienuires that
36 the fossil JS bootstrapping is complete and that several fossil
37 JS APIs have been installed: fossil.fetch, fossil.dom,
38 fossil.tabs, fossil.storage, fossil.confirmer, fossil.popupwidget.
39
40 Custom events which can be listened for via
41 fossil.page.addEventListener():
42
43 - Event 'wiki-page-loaded': passes on information when it
44 loads a wiki (whether from the network or its internal local-edit
45 cache), in the form of an "winfo" objec
46 'change',n information when it
47 loads a wiki (whether from the networcontent: stringinnerHTML =for a sandbox page or new page,
48 parent: parent UUID string or null if no parent,
49 isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
50 "use strict";
51 /**
52 Client-side implementation of the /wikiedit app. Requires that
53 the fossil JS bootfileedit-file-loadedtarget.innerHTML =for notag" |(functionnotag" |(function(F/*ttnotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
54 parent: par {
55 isNew: '[+]',
56 isModified: '[*]'I@2Ek,1eq@cX,1:P2h3@2HN,P@4yl,N@1tj,2:itJ@2Ej,iG@5~7,g@6lD,3r@6gz,H@4xk,jJ@6m9,1:346@7Vu,1:3Kf@7_S,x@8B2,H@4xk,1c@80s,K:denotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
57 parent: parent UUID string or null if no parent,
58 isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
59 "use strict";
60 /**
61 Clienuires that
62 the fossil JS bootstrapping is complete and that several fossil
63 JS APIs have been installed: fossil.fetch, fossil.dom,
64 fossil.tabs, fossil.storage, fossil.confirmer, fossil.popupwidget.
65
66 Custom events which can be listened for via
67 fossil.page.addEventListener():
68
69 - Event 'wiki-page-loaded': passes on information when it
70 loads a wiki (whether from the network or its internal local-edit
71 cache), in the form of an "winfo" objec
72 'change',n information when it
73 loads a wiki (whether from the networcontent: stringinnerHTML =for a sandbox page or new page,
74 parent: parent UUID string or null if no parent,
75 isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
76 "use strict";
77 /**
78 Client-side implementation of the /wikiedit app. Requires that
79 the fossil JS bootfileedit-file-loadedtarget.innerHTML =for notag" |(functionnotag" |(function(F/*ttnotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
80 parent: par {
81 isNew: '[+]',
82 isModified: '[*]'I@2Ek,1eq@cX,1:P2h3@2HN,P@4yl,N@1tj,2:itJ@2Ej,iG@5~7,g@6lD,3r@6gz,H@4xk,jJ@6m9,1:346@7Vu,1:3Kf@7_S,x@8B2,H@4xk,1c@80s,K:delete P.winfo;
83 I@Apl,79@82h,1:PI@7c0,Q@4y0,I@8dV,A:())
84 I@7Tk,H@8dW,1:(Di@8Cl,1:,1g@8QT,9:[history]t@8SF,E:[attachments]"W@8SG,13@8To,8:[attach]x4@8Ux,P@8nF,G:page-loaded', r)1bU@9Rt,3qU_12;);
85 editFlag/*for use editFlag || '';
86 if(0===arguments){
87 if(!wi.version && 'sandbox'!==wi.type) marker.isNewag" |(function(Fnotag" |(function()) marker.isModified;
88 }var title, marker = '';;
89 if(wi){
90 if(!wi.version && 'sandbox'!==wi.type) marker.isNewag" |(function(Fnotag" |(function()) marker.isModified;
91 title = wi.nametitle = 'no page loaded';
92 }marker);
93 There are n
94 stashWattachmentWrappermisc){
95 errorAttachmentView |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
96 parent: parent UUID string or null if no parent,
97 isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
98 "use strict";
99 erHTML =for a sandbox page fossil.tabs, fossil.storage, fossil.confirmer, fossil.popupwidget.
100
101 Custom events which can be listened for via
102 fossil.page.addEventListener():
103
104 - Event 'wiki-page-loaded': passes on information when it
105 loads a wiki (whether from the network or its internal local-edit
106 cache), in the form of an "winfo" objec
107 'change',n information when it
108 loads a wiki (whether from the networcontent: stringinnerHTML =for a sandbox page or new page,
109 parent: parent UUID string or null if no parent,
110 isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
111 "use strict";
112 /**
113 Client-side implementation of the /wikiedit app. Requires that
114 the fossil JS bootfileedit-file-loadedtarget.innerHTML =for notag" |(functionnotag" |(function(F/*ttnotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
115 parent: par {
116 isNew: '[+]',
117 isModified: '[*]'I@2Ek,1eq@cX,1:P2h3@2HN,P@4yl,N@1tj,2:itJ@2Ej,iG@5~7,g@6lD,3r@6gz,H@4xk,jJ@6m9,1:346@7Vu,1:3Kf@7_S,x@8B2,H@4xk,1c@80s,K:denotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
118 parent: parent UUID string or null if no parent,
119 isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
120 "use strict";
121 /**
122 Clienuires that
123 the fossil JS bootstrapping is complete and that several fossil
124 JS APIs have been installed: fossil.fetch, fossil.dom,
125 fossil.tabs, fossil.storage, fossil.confirmer, fossil.popupwidget.
126
127 Custom events which can be listened for via
128 fossil.page.addEventListener():
129
130 - Event 'wiki-page-loaded': passes on information when it
131 loads a wiki (whether from the network or its internal local-edit
132 cache), in the form of an "winfo" objec
133 'change',n information when it
134 loads a wiki (whether from the networcontent: stringinnerHTML =for a sandbox page or new page,
135 parent: parent UUID string or null if no parent,
136 isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
137 "use strict";
138 /**
139 Client-side implementation of the /wikiedit app. Requires that
140 the fossil JS bootfileedit-file-loadedtarget.innerHTML =for notag" |(functionnotag" |(function(F/*ttnotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
141 parent: par {
142 isNew: '[+]',
143 isModified: '[*]'I@2Ek,1eq@cX,1:P2h3@2HN,P@4yl,N@1tj,2:itJ@2Ej,iG@5~7,g@6lD,3r@6gz,H@4xk,jJ@6m9,1:346@7Vu,1:3Kf@7_S,x@8B2,H@4xk,1c@80s,K:delete P.winfo;
144 I@Apl,79@82h,1:PI@7c0,Q@4y0,I@8dV,A:())
145 I@7Tk,H@8dW,1:(Di@8Cl,1:,1g@8QT,9:[history]t@8SF,E:[attachments]"W@8SG,13@8To,8:[attach]x4@8Ux,P@8nF,G:page-loaded', r)1bU@9Rt,3qU_12;);
146 editFlag/*for use editFlag || '';
147 if(0===arguments){
148 if(!wi.version && 'sandbox'!==wi.type) marker.isNewag" |(function(Fnotag" |(function()) marker.isModified;
149 }var title, marker = '';;
150 if(wi){
151 if(!wi.version && 'sandbox'!==wi.type) marker.isNewag" |(function(Fnotag" |(function()) marker.isModified;
152 title = wi.nametitle = 'no page loaded';
153 }marker);
154 There are n
155 stashW('#wikiedit-page-name > span = []title.push(New)title.push()
156 title.push(wi.name);
157 title.push(}
158 title = title.join(' ');
159 f.pageTitleHeader.innerText = title;' + title; Updates attachment-related links and returns this. */
160 P.updateAttachmentViewconst wrapwrapper);
161 const ul = D.ul();
162 D.append(wrapper, ul);
163 if(!P.winfoD.li(ul "Load a page to get access to itselse if(!P.winfoD.li(ul "Acannot have aD.append(
164 D.li(ul),
165
166 page:wi.name,
167
168 name: wi.name
169 })
170 }), "Add attachments.")
171 );
172 D.li(ul),
173 list',{page:wi.name}),
174 "List attachments"),
175 " (if any)."
176
--- a/src/fossil.page.wikiedit.js
+++ b/src/fossil.page.wikiedit.js
@@ -1 +1,176 @@
1
-notag" |(
1
+notag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
2
+ parent: parent UUID string or null if no parent,
3
+ isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
4
+ "use strict";
5
+ /**
6
+ Clienuires that
7
+ the fossil JS bootstrapping is complete and that several fossil
8
+ JS APIs have been installed: fossil.fetch, fossil.dom,
9
+ fossil.tabs, fossil.storage, fossil.confirmer, fossil.popupwidget.
10
+
11
+ Custom events which can be listened for via
12
+ fossil.page.addEventListener():
13
+
14
+ - Event 'wiki-page-loaded': passes on information when it
15
+ loads a wiki (whether from the network or its internal local-edit
16
+ Note that
17
+ the symbols themselves are *actually* defined in CSS, so if
18
+ they're changed there they also need to be changed here. cache), in the form of an "winfo" objec
19
+ 'change',n information when it
20
+ loads a wiki (whether from the networcontent: stringinnerHTML =for a sandbox page or new page,
21
+ parent: parent UUID string or null if no parent,
22
+ isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
23
+ "use strict";
24
+ /**
25
+ Client-side implementation of the /wikiedit app. Requires that
26
+ the fossil JS bootfileedit-file-loadedtarget.innerHTML =for notag" |(functionnotag" |(function(F/*ttnotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
27
+ parent: par {
28
+ isNew: '[+]',
29
+ isModified: '[*]'I@2Ek,1eq@cX,1:P2h3@2HN,P@4yl,N@1tj,2:itJ@2Ej,iG@5~7,g@6lD,3r@6gz,H@4xk,jJ@6m9,1:346@7Vu,1:3Kf@7_S,x@8B2,H@4xk,1c@80s,K:delete P.winfo;
30
+ I@Apl,79@82h,1:PI@7c0,Q@4y0,I@8dV,A:())
31
+ I@7Tk,H@8dW,1:(Di@8Cl,1:,1g@8QT,9:[history]t@8SF,E:[attachments]"W@8SG,13@8To,8:[attach]x4@8Ux,P@8nF,G:page-loaded', r)1bU@9Rt,3qU_12;
32
+ local*/
33
+ (){const select = this.e.select,Object.keys(opt = if(stashed}else{
34
+}
35
+}Wiki p.isModified" = page has local edits.isNew Clienuires that
36
+ the fossil JS bootstrapping is complete and that several fossil
37
+ JS APIs have been installed: fossil.fetch, fossil.dom,
38
+ fossil.tabs, fossil.storage, fossil.confirmer, fossil.popupwidget.
39
+
40
+ Custom events which can be listened for via
41
+ fossil.page.addEventListener():
42
+
43
+ - Event 'wiki-page-loaded': passes on information when it
44
+ loads a wiki (whether from the network or its internal local-edit
45
+ cache), in the form of an "winfo" objec
46
+ 'change',n information when it
47
+ loads a wiki (whether from the networcontent: stringinnerHTML =for a sandbox page or new page,
48
+ parent: parent UUID string or null if no parent,
49
+ isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
50
+ "use strict";
51
+ /**
52
+ Client-side implementation of the /wikiedit app. Requires that
53
+ the fossil JS bootfileedit-file-loadedtarget.innerHTML =for notag" |(functionnotag" |(function(F/*ttnotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
54
+ parent: par {
55
+ isNew: '[+]',
56
+ isModified: '[*]'I@2Ek,1eq@cX,1:P2h3@2HN,P@4yl,N@1tj,2:itJ@2Ej,iG@5~7,g@6lD,3r@6gz,H@4xk,jJ@6m9,1:346@7Vu,1:3Kf@7_S,x@8B2,H@4xk,1c@80s,K:denotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
57
+ parent: parent UUID string or null if no parent,
58
+ isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
59
+ "use strict";
60
+ /**
61
+ Clienuires that
62
+ the fossil JS bootstrapping is complete and that several fossil
63
+ JS APIs have been installed: fossil.fetch, fossil.dom,
64
+ fossil.tabs, fossil.storage, fossil.confirmer, fossil.popupwidget.
65
+
66
+ Custom events which can be listened for via
67
+ fossil.page.addEventListener():
68
+
69
+ - Event 'wiki-page-loaded': passes on information when it
70
+ loads a wiki (whether from the network or its internal local-edit
71
+ cache), in the form of an "winfo" objec
72
+ 'change',n information when it
73
+ loads a wiki (whether from the networcontent: stringinnerHTML =for a sandbox page or new page,
74
+ parent: parent UUID string or null if no parent,
75
+ isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
76
+ "use strict";
77
+ /**
78
+ Client-side implementation of the /wikiedit app. Requires that
79
+ the fossil JS bootfileedit-file-loadedtarget.innerHTML =for notag" |(functionnotag" |(function(F/*ttnotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
80
+ parent: par {
81
+ isNew: '[+]',
82
+ isModified: '[*]'I@2Ek,1eq@cX,1:P2h3@2HN,P@4yl,N@1tj,2:itJ@2Ej,iG@5~7,g@6lD,3r@6gz,H@4xk,jJ@6m9,1:346@7Vu,1:3Kf@7_S,x@8B2,H@4xk,1c@80s,K:delete P.winfo;
83
+ I@Apl,79@82h,1:PI@7c0,Q@4y0,I@8dV,A:())
84
+ I@7Tk,H@8dW,1:(Di@8Cl,1:,1g@8QT,9:[history]t@8SF,E:[attachments]"W@8SG,13@8To,8:[attach]x4@8Ux,P@8nF,G:page-loaded', r)1bU@9Rt,3qU_12;);
85
+editFlag/*for use editFlag || '';
86
+ if(0===arguments){
87
+ if(!wi.version && 'sandbox'!==wi.type) marker.isNewag" |(function(Fnotag" |(function()) marker.isModified;
88
+ }var title, marker = '';;
89
+ if(wi){
90
+ if(!wi.version && 'sandbox'!==wi.type) marker.isNewag" |(function(Fnotag" |(function()) marker.isModified;
91
+ title = wi.nametitle = 'no page loaded';
92
+ }marker);
93
+There are n
94
+stashWattachmentWrappermisc){
95
+ errorAttachmentView |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
96
+ parent: parent UUID string or null if no parent,
97
+ isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
98
+ "use strict";
99
+ erHTML =for a sandbox page fossil.tabs, fossil.storage, fossil.confirmer, fossil.popupwidget.
100
+
101
+ Custom events which can be listened for via
102
+ fossil.page.addEventListener():
103
+
104
+ - Event 'wiki-page-loaded': passes on information when it
105
+ loads a wiki (whether from the network or its internal local-edit
106
+ cache), in the form of an "winfo" objec
107
+ 'change',n information when it
108
+ loads a wiki (whether from the networcontent: stringinnerHTML =for a sandbox page or new page,
109
+ parent: parent UUID string or null if no parent,
110
+ isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
111
+ "use strict";
112
+ /**
113
+ Client-side implementation of the /wikiedit app. Requires that
114
+ the fossil JS bootfileedit-file-loadedtarget.innerHTML =for notag" |(functionnotag" |(function(F/*ttnotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
115
+ parent: par {
116
+ isNew: '[+]',
117
+ isModified: '[*]'I@2Ek,1eq@cX,1:P2h3@2HN,P@4yl,N@1tj,2:itJ@2Ej,iG@5~7,g@6lD,3r@6gz,H@4xk,jJ@6m9,1:346@7Vu,1:3Kf@7_S,x@8B2,H@4xk,1c@80s,K:denotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
118
+ parent: parent UUID string or null if no parent,
119
+ isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
120
+ "use strict";
121
+ /**
122
+ Clienuires that
123
+ the fossil JS bootstrapping is complete and that several fossil
124
+ JS APIs have been installed: fossil.fetch, fossil.dom,
125
+ fossil.tabs, fossil.storage, fossil.confirmer, fossil.popupwidget.
126
+
127
+ Custom events which can be listened for via
128
+ fossil.page.addEventListener():
129
+
130
+ - Event 'wiki-page-loaded': passes on information when it
131
+ loads a wiki (whether from the network or its internal local-edit
132
+ cache), in the form of an "winfo" objec
133
+ 'change',n information when it
134
+ loads a wiki (whether from the networcontent: stringinnerHTML =for a sandbox page or new page,
135
+ parent: parent UUID string or null if no parent,
136
+ isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
137
+ "use strict";
138
+ /**
139
+ Client-side implementation of the /wikiedit app. Requires that
140
+ the fossil JS bootfileedit-file-loadedtarget.innerHTML =for notag" |(functionnotag" |(function(F/*ttnotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
141
+ parent: par {
142
+ isNew: '[+]',
143
+ isModified: '[*]'I@2Ek,1eq@cX,1:P2h3@2HN,P@4yl,N@1tj,2:itJ@2Ej,iG@5~7,g@6lD,3r@6gz,H@4xk,jJ@6m9,1:346@7Vu,1:3Kf@7_S,x@8B2,H@4xk,1c@80s,K:delete P.winfo;
144
+ I@Apl,79@82h,1:PI@7c0,Q@4y0,I@8dV,A:())
145
+ I@7Tk,H@8dW,1:(Di@8Cl,1:,1g@8QT,9:[history]t@8SF,E:[attachments]"W@8SG,13@8To,8:[attach]x4@8Ux,P@8nF,G:page-loaded', r)1bU@9Rt,3qU_12;);
146
+editFlag/*for use editFlag || '';
147
+ if(0===arguments){
148
+ if(!wi.version && 'sandbox'!==wi.type) marker.isNewag" |(function(Fnotag" |(function()) marker.isModified;
149
+ }var title, marker = '';;
150
+ if(wi){
151
+ if(!wi.version && 'sandbox'!==wi.type) marker.isNewag" |(function(Fnotag" |(function()) marker.isModified;
152
+ title = wi.nametitle = 'no page loaded';
153
+ }marker);
154
+There are n
155
+stashW('#wikiedit-page-name > span = []title.push(New)title.push()
156
+ title.push(wi.name);
157
+title.push(}
158
+ title = title.join(' ');
159
+ f.pageTitleHeader.innerText = title;' + title; Updates attachment-related links and returns this. */
160
+ P.updateAttachmentViewconst wrapwrapper);
161
+ const ul = D.ul();
162
+ D.append(wrapper, ul);
163
+ if(!P.winfoD.li(ul "Load a page to get access to itselse if(!P.winfoD.li(ul "Acannot have aD.append(
164
+ D.li(ul),
165
+
166
+page:wi.name,
167
+
168
+ name: wi.name
169
+ })
170
+ }), "Add attachments.")
171
+ );
172
+D.li(ul),
173
+list',{page:wi.name}),
174
+ "List attachments"),
175
+ " (if any)."
176
+
--- a/src/fossil.page.wikiedit.js
+++ b/src/fossil.page.wikiedit.js
@@ -1 +1,176 @@
1 notag" |(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/src/fossil.page.wikiedit.js
+++ b/src/fossil.page.wikiedit.js
@@ -1 +1,176 @@
1 notag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
2 parent: parent UUID string or null if no parent,
3 isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
4 "use strict";
5 /**
6 Clienuires that
7 the fossil JS bootstrapping is complete and that several fossil
8 JS APIs have been installed: fossil.fetch, fossil.dom,
9 fossil.tabs, fossil.storage, fossil.confirmer, fossil.popupwidget.
10
11 Custom events which can be listened for via
12 fossil.page.addEventListener():
13
14 - Event 'wiki-page-loaded': passes on information when it
15 loads a wiki (whether from the network or its internal local-edit
16 Note that
17 the symbols themselves are *actually* defined in CSS, so if
18 they're changed there they also need to be changed here. cache), in the form of an "winfo" objec
19 'change',n information when it
20 loads a wiki (whether from the networcontent: stringinnerHTML =for a sandbox page or new page,
21 parent: parent UUID string or null if no parent,
22 isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
23 "use strict";
24 /**
25 Client-side implementation of the /wikiedit app. Requires that
26 the fossil JS bootfileedit-file-loadedtarget.innerHTML =for notag" |(functionnotag" |(function(F/*ttnotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
27 parent: par {
28 isNew: '[+]',
29 isModified: '[*]'I@2Ek,1eq@cX,1:P2h3@2HN,P@4yl,N@1tj,2:itJ@2Ej,iG@5~7,g@6lD,3r@6gz,H@4xk,jJ@6m9,1:346@7Vu,1:3Kf@7_S,x@8B2,H@4xk,1c@80s,K:delete P.winfo;
30 I@Apl,79@82h,1:PI@7c0,Q@4y0,I@8dV,A:())
31 I@7Tk,H@8dW,1:(Di@8Cl,1:,1g@8QT,9:[history]t@8SF,E:[attachments]"W@8SG,13@8To,8:[attach]x4@8Ux,P@8nF,G:page-loaded', r)1bU@9Rt,3qU_12;
32 local*/
33 (){const select = this.e.select,Object.keys(opt = if(stashed}else{
34 }
35 }Wiki p.isModified" = page has local edits.isNew Clienuires that
36 the fossil JS bootstrapping is complete and that several fossil
37 JS APIs have been installed: fossil.fetch, fossil.dom,
38 fossil.tabs, fossil.storage, fossil.confirmer, fossil.popupwidget.
39
40 Custom events which can be listened for via
41 fossil.page.addEventListener():
42
43 - Event 'wiki-page-loaded': passes on information when it
44 loads a wiki (whether from the network or its internal local-edit
45 cache), in the form of an "winfo" objec
46 'change',n information when it
47 loads a wiki (whether from the networcontent: stringinnerHTML =for a sandbox page or new page,
48 parent: parent UUID string or null if no parent,
49 isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
50 "use strict";
51 /**
52 Client-side implementation of the /wikiedit app. Requires that
53 the fossil JS bootfileedit-file-loadedtarget.innerHTML =for notag" |(functionnotag" |(function(F/*ttnotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
54 parent: par {
55 isNew: '[+]',
56 isModified: '[*]'I@2Ek,1eq@cX,1:P2h3@2HN,P@4yl,N@1tj,2:itJ@2Ej,iG@5~7,g@6lD,3r@6gz,H@4xk,jJ@6m9,1:346@7Vu,1:3Kf@7_S,x@8B2,H@4xk,1c@80s,K:denotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
57 parent: parent UUID string or null if no parent,
58 isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
59 "use strict";
60 /**
61 Clienuires that
62 the fossil JS bootstrapping is complete and that several fossil
63 JS APIs have been installed: fossil.fetch, fossil.dom,
64 fossil.tabs, fossil.storage, fossil.confirmer, fossil.popupwidget.
65
66 Custom events which can be listened for via
67 fossil.page.addEventListener():
68
69 - Event 'wiki-page-loaded': passes on information when it
70 loads a wiki (whether from the network or its internal local-edit
71 cache), in the form of an "winfo" objec
72 'change',n information when it
73 loads a wiki (whether from the networcontent: stringinnerHTML =for a sandbox page or new page,
74 parent: parent UUID string or null if no parent,
75 isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
76 "use strict";
77 /**
78 Client-side implementation of the /wikiedit app. Requires that
79 the fossil JS bootfileedit-file-loadedtarget.innerHTML =for notag" |(functionnotag" |(function(F/*ttnotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
80 parent: par {
81 isNew: '[+]',
82 isModified: '[*]'I@2Ek,1eq@cX,1:P2h3@2HN,P@4yl,N@1tj,2:itJ@2Ej,iG@5~7,g@6lD,3r@6gz,H@4xk,jJ@6m9,1:346@7Vu,1:3Kf@7_S,x@8B2,H@4xk,1c@80s,K:delete P.winfo;
83 I@Apl,79@82h,1:PI@7c0,Q@4y0,I@8dV,A:())
84 I@7Tk,H@8dW,1:(Di@8Cl,1:,1g@8QT,9:[history]t@8SF,E:[attachments]"W@8SG,13@8To,8:[attach]x4@8Ux,P@8nF,G:page-loaded', r)1bU@9Rt,3qU_12;);
85 editFlag/*for use editFlag || '';
86 if(0===arguments){
87 if(!wi.version && 'sandbox'!==wi.type) marker.isNewag" |(function(Fnotag" |(function()) marker.isModified;
88 }var title, marker = '';;
89 if(wi){
90 if(!wi.version && 'sandbox'!==wi.type) marker.isNewag" |(function(Fnotag" |(function()) marker.isModified;
91 title = wi.nametitle = 'no page loaded';
92 }marker);
93 There are n
94 stashWattachmentWrappermisc){
95 errorAttachmentView |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
96 parent: parent UUID string or null if no parent,
97 isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
98 "use strict";
99 erHTML =for a sandbox page fossil.tabs, fossil.storage, fossil.confirmer, fossil.popupwidget.
100
101 Custom events which can be listened for via
102 fossil.page.addEventListener():
103
104 - Event 'wiki-page-loaded': passes on information when it
105 loads a wiki (whether from the network or its internal local-edit
106 cache), in the form of an "winfo" objec
107 'change',n information when it
108 loads a wiki (whether from the networcontent: stringinnerHTML =for a sandbox page or new page,
109 parent: parent UUID string or null if no parent,
110 isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
111 "use strict";
112 /**
113 Client-side implementation of the /wikiedit app. Requires that
114 the fossil JS bootfileedit-file-loadedtarget.innerHTML =for notag" |(functionnotag" |(function(F/*ttnotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
115 parent: par {
116 isNew: '[+]',
117 isModified: '[*]'I@2Ek,1eq@cX,1:P2h3@2HN,P@4yl,N@1tj,2:itJ@2Ej,iG@5~7,g@6lD,3r@6gz,H@4xk,jJ@6m9,1:346@7Vu,1:3Kf@7_S,x@8B2,H@4xk,1c@80s,K:denotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
118 parent: parent UUID string or null if no parent,
119 isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
120 "use strict";
121 /**
122 Clienuires that
123 the fossil JS bootstrapping is complete and that several fossil
124 JS APIs have been installed: fossil.fetch, fossil.dom,
125 fossil.tabs, fossil.storage, fossil.confirmer, fossil.popupwidget.
126
127 Custom events which can be listened for via
128 fossil.page.addEventListener():
129
130 - Event 'wiki-page-loaded': passes on information when it
131 loads a wiki (whether from the network or its internal local-edit
132 cache), in the form of an "winfo" objec
133 'change',n information when it
134 loads a wiki (whether from the networcontent: stringinnerHTML =for a sandbox page or new page,
135 parent: parent UUID string or null if no parent,
136 isEmpty: true if page has no content (is "dele ctrnormal" | "tag" |(function(F/*the fossil object*/){
137 "use strict";
138 /**
139 Client-side implementation of the /wikiedit app. Requires that
140 the fossil JS bootfileedit-file-loadedtarget.innerHTML =for notag" |(functionnotag" |(function(F/*ttnotag" |(function(F/*ttarget.innerHTML =for a sandbox page or new page,
141 parent: par {
142 isNew: '[+]',
143 isModified: '[*]'I@2Ek,1eq@cX,1:P2h3@2HN,P@4yl,N@1tj,2:itJ@2Ej,iG@5~7,g@6lD,3r@6gz,H@4xk,jJ@6m9,1:346@7Vu,1:3Kf@7_S,x@8B2,H@4xk,1c@80s,K:delete P.winfo;
144 I@Apl,79@82h,1:PI@7c0,Q@4y0,I@8dV,A:())
145 I@7Tk,H@8dW,1:(Di@8Cl,1:,1g@8QT,9:[history]t@8SF,E:[attachments]"W@8SG,13@8To,8:[attach]x4@8Ux,P@8nF,G:page-loaded', r)1bU@9Rt,3qU_12;);
146 editFlag/*for use editFlag || '';
147 if(0===arguments){
148 if(!wi.version && 'sandbox'!==wi.type) marker.isNewag" |(function(Fnotag" |(function()) marker.isModified;
149 }var title, marker = '';;
150 if(wi){
151 if(!wi.version && 'sandbox'!==wi.type) marker.isNewag" |(function(Fnotag" |(function()) marker.isModified;
152 title = wi.nametitle = 'no page loaded';
153 }marker);
154 There are n
155 stashW('#wikiedit-page-name > span = []title.push(New)title.push()
156 title.push(wi.name);
157 title.push(}
158 title = title.join(' ');
159 f.pageTitleHeader.innerText = title;' + title; Updates attachment-related links and returns this. */
160 P.updateAttachmentViewconst wrapwrapper);
161 const ul = D.ul();
162 D.append(wrapper, ul);
163 if(!P.winfoD.li(ul "Load a page to get access to itselse if(!P.winfoD.li(ul "Acannot have aD.append(
164 D.li(ul),
165
166 page:wi.name,
167
168 name: wi.name
169 })
170 }), "Add attachments.")
171 );
172 D.li(ul),
173 list',{page:wi.name}),
174 "List attachments"),
175 " (if any)."
176
+27 -12
--- src/main.c
+++ src/main.c
@@ -2095,10 +2095,14 @@
20952095
** REPO for a check-in or ticket that matches the
20962096
** value of "name", then redirect to URL. There
20972097
** can be multiple "redirect:" lines that are
20982098
** processed in order. If the REPO is "*", then
20992099
** an unconditional redirect to URL is taken.
2100
+**
2101
+** jsmode: VALUE Specifies the delivery mode for JavaScript
2102
+** files. See the help text for the --jsmode
2103
+** flag of the http command.
21002104
**
21012105
** Most CGI files contain only a "repository:" line. It is uncommon to
21022106
** use any other option.
21032107
**
21042108
** See also: http, server, winsrv
@@ -2274,15 +2278,17 @@
22742278
continue;
22752279
}
22762280
if( blob_eq(&key, "jsmode:") && blob_token(&line, &value) ){
22772281
/* jsmode: MODE
22782282
**
2279
- ** Change how javascript resources are delivered with each HTML
2283
+ ** Change how JavaScript resources are delivered with each HTML
22802284
** page. MODE is "inline" to put all JS inline, or "separate" to
22812285
** cause each JS file to be requested using a separate HTTP request,
22822286
** or "bundled" to have all JS files to be fetched with a single
2283
- ** auxiliary HTTP request.
2287
+ ** auxiliary HTTP request. Noting, however, that "single" might
2288
+ ** actually mean more than one, depending on the script-timing
2289
+ ** requirements of any given page.
22842290
*/
22852291
builtin_set_js_delivery_mode(blob_str(&value),0);
22862292
blob_reset(&value);
22872293
continue;
22882294
}
@@ -2468,18 +2474,23 @@
24682474
** --files GLOB comma-separate glob patterns for static file to serve
24692475
** --host NAME specify hostname of the server
24702476
** --https signal a request coming in via https
24712477
** --in FILE Take input from FILE instead of standard input
24722478
** --ipaddr ADDR Assume the request comes from the given IP address
2473
-** --jsmode MODE Determine how javascript is delivered with pages.
2479
+** --jsmode MODE Determine how JavaScript is delivered with pages.
24742480
** Mode can be one of:
2475
-** inline All javascript is inserted inline at
2476
-** the end of the HTML file.
2481
+** inline All JavaScript is inserted inline at
2482
+** one or more points in the HTML file.
24772483
** separate Separate HTTP requests are made for
2478
-** each javascript file.
2479
-** bundled One single separate HTTP fetches all
2480
-** javascript concatenated together.
2484
+** each JavaScript file.
2485
+** bundled Groups JavaScript files into one or
2486
+** more bundled requests which
2487
+** concatenate scripts together.
2488
+** Depending on the needs of any given page, inline
2489
+** and bundled modes might result in a single
2490
+** amalgamated script or several, but both approaches
2491
+** result in fewer HTTP requests than the separate mode.
24812492
** --localauth enable automatic login for local connections
24822493
** --nocompress do not compress HTTP replies
24832494
** --nodelay omit backoffice processing if it would delay process exit
24842495
** --nojail drop root privilege but do not enter the chroot jail
24852496
** --nossl signal that no SSL connections are available
@@ -2736,18 +2747,22 @@
27362747
** --files GLOBLIST Comma-separated list of glob patterns for static files
27372748
** --localauth enable automatic login for requests from localhost
27382749
** --localhost listen on 127.0.0.1 only (always true for "ui")
27392750
** --https Indicates that the input is coming through a reverse
27402751
** proxy that has already translated HTTPS into HTTP.
2741
-** --jsmode MODE Determine how javascript is delivered with pages.
2752
+** --jsmode MODE Determine how JavaScript is delivered with pages.
27422753
** Mode can be one of:
2743
-** inline All javascript is inserted inline at
2754
+** inline All JavaScript is inserted inline at
27442755
** the end of the HTML file.
27452756
** separate Separate HTTP requests are made for
2746
-** each javascript file.
2757
+** each JavaScript file.
27472758
** bundled One single separate HTTP fetches all
2748
-** javascript concatenated together.
2759
+** JavaScript concatenated together.
2760
+** Depending on the needs of any given page, inline
2761
+** and bundled modes might result in a single
2762
+** amalgamated script or several, but both approaches
2763
+** result in fewer HTTP requests than the separate mode.
27492764
** --max-latency N Do not let any single HTTP request run for more than N
27502765
** seconds (only works on unix)
27512766
** --nocompress Do not compress HTTP replies
27522767
** --nojail Drop root privileges but do not enter the chroot jail
27532768
** --nossl signal that no SSL connections are available (Always
27542769
--- src/main.c
+++ src/main.c
@@ -2095,10 +2095,14 @@
2095 ** REPO for a check-in or ticket that matches the
2096 ** value of "name", then redirect to URL. There
2097 ** can be multiple "redirect:" lines that are
2098 ** processed in order. If the REPO is "*", then
2099 ** an unconditional redirect to URL is taken.
 
 
 
 
2100 **
2101 ** Most CGI files contain only a "repository:" line. It is uncommon to
2102 ** use any other option.
2103 **
2104 ** See also: http, server, winsrv
@@ -2274,15 +2278,17 @@
2274 continue;
2275 }
2276 if( blob_eq(&key, "jsmode:") && blob_token(&line, &value) ){
2277 /* jsmode: MODE
2278 **
2279 ** Change how javascript resources are delivered with each HTML
2280 ** page. MODE is "inline" to put all JS inline, or "separate" to
2281 ** cause each JS file to be requested using a separate HTTP request,
2282 ** or "bundled" to have all JS files to be fetched with a single
2283 ** auxiliary HTTP request.
 
 
2284 */
2285 builtin_set_js_delivery_mode(blob_str(&value),0);
2286 blob_reset(&value);
2287 continue;
2288 }
@@ -2468,18 +2474,23 @@
2468 ** --files GLOB comma-separate glob patterns for static file to serve
2469 ** --host NAME specify hostname of the server
2470 ** --https signal a request coming in via https
2471 ** --in FILE Take input from FILE instead of standard input
2472 ** --ipaddr ADDR Assume the request comes from the given IP address
2473 ** --jsmode MODE Determine how javascript is delivered with pages.
2474 ** Mode can be one of:
2475 ** inline All javascript is inserted inline at
2476 ** the end of the HTML file.
2477 ** separate Separate HTTP requests are made for
2478 ** each javascript file.
2479 ** bundled One single separate HTTP fetches all
2480 ** javascript concatenated together.
 
 
 
 
 
2481 ** --localauth enable automatic login for local connections
2482 ** --nocompress do not compress HTTP replies
2483 ** --nodelay omit backoffice processing if it would delay process exit
2484 ** --nojail drop root privilege but do not enter the chroot jail
2485 ** --nossl signal that no SSL connections are available
@@ -2736,18 +2747,22 @@
2736 ** --files GLOBLIST Comma-separated list of glob patterns for static files
2737 ** --localauth enable automatic login for requests from localhost
2738 ** --localhost listen on 127.0.0.1 only (always true for "ui")
2739 ** --https Indicates that the input is coming through a reverse
2740 ** proxy that has already translated HTTPS into HTTP.
2741 ** --jsmode MODE Determine how javascript is delivered with pages.
2742 ** Mode can be one of:
2743 ** inline All javascript is inserted inline at
2744 ** the end of the HTML file.
2745 ** separate Separate HTTP requests are made for
2746 ** each javascript file.
2747 ** bundled One single separate HTTP fetches all
2748 ** javascript concatenated together.
 
 
 
 
2749 ** --max-latency N Do not let any single HTTP request run for more than N
2750 ** seconds (only works on unix)
2751 ** --nocompress Do not compress HTTP replies
2752 ** --nojail Drop root privileges but do not enter the chroot jail
2753 ** --nossl signal that no SSL connections are available (Always
2754
--- src/main.c
+++ src/main.c
@@ -2095,10 +2095,14 @@
2095 ** REPO for a check-in or ticket that matches the
2096 ** value of "name", then redirect to URL. There
2097 ** can be multiple "redirect:" lines that are
2098 ** processed in order. If the REPO is "*", then
2099 ** an unconditional redirect to URL is taken.
2100 **
2101 ** jsmode: VALUE Specifies the delivery mode for JavaScript
2102 ** files. See the help text for the --jsmode
2103 ** flag of the http command.
2104 **
2105 ** Most CGI files contain only a "repository:" line. It is uncommon to
2106 ** use any other option.
2107 **
2108 ** See also: http, server, winsrv
@@ -2274,15 +2278,17 @@
2278 continue;
2279 }
2280 if( blob_eq(&key, "jsmode:") && blob_token(&line, &value) ){
2281 /* jsmode: MODE
2282 **
2283 ** Change how JavaScript resources are delivered with each HTML
2284 ** page. MODE is "inline" to put all JS inline, or "separate" to
2285 ** cause each JS file to be requested using a separate HTTP request,
2286 ** or "bundled" to have all JS files to be fetched with a single
2287 ** auxiliary HTTP request. Noting, however, that "single" might
2288 ** actually mean more than one, depending on the script-timing
2289 ** requirements of any given page.
2290 */
2291 builtin_set_js_delivery_mode(blob_str(&value),0);
2292 blob_reset(&value);
2293 continue;
2294 }
@@ -2468,18 +2474,23 @@
2474 ** --files GLOB comma-separate glob patterns for static file to serve
2475 ** --host NAME specify hostname of the server
2476 ** --https signal a request coming in via https
2477 ** --in FILE Take input from FILE instead of standard input
2478 ** --ipaddr ADDR Assume the request comes from the given IP address
2479 ** --jsmode MODE Determine how JavaScript is delivered with pages.
2480 ** Mode can be one of:
2481 ** inline All JavaScript is inserted inline at
2482 ** one or more points in the HTML file.
2483 ** separate Separate HTTP requests are made for
2484 ** each JavaScript file.
2485 ** bundled Groups JavaScript files into one or
2486 ** more bundled requests which
2487 ** concatenate scripts together.
2488 ** Depending on the needs of any given page, inline
2489 ** and bundled modes might result in a single
2490 ** amalgamated script or several, but both approaches
2491 ** result in fewer HTTP requests than the separate mode.
2492 ** --localauth enable automatic login for local connections
2493 ** --nocompress do not compress HTTP replies
2494 ** --nodelay omit backoffice processing if it would delay process exit
2495 ** --nojail drop root privilege but do not enter the chroot jail
2496 ** --nossl signal that no SSL connections are available
@@ -2736,18 +2747,22 @@
2747 ** --files GLOBLIST Comma-separated list of glob patterns for static files
2748 ** --localauth enable automatic login for requests from localhost
2749 ** --localhost listen on 127.0.0.1 only (always true for "ui")
2750 ** --https Indicates that the input is coming through a reverse
2751 ** proxy that has already translated HTTPS into HTTP.
2752 ** --jsmode MODE Determine how JavaScript is delivered with pages.
2753 ** Mode can be one of:
2754 ** inline All JavaScript is inserted inline at
2755 ** the end of the HTML file.
2756 ** separate Separate HTTP requests are made for
2757 ** each JavaScript file.
2758 ** bundled One single separate HTTP fetches all
2759 ** JavaScript concatenated together.
2760 ** Depending on the needs of any given page, inline
2761 ** and bundled modes might result in a single
2762 ** amalgamated script or several, but both approaches
2763 ** result in fewer HTTP requests than the separate mode.
2764 ** --max-latency N Do not let any single HTTP request run for more than N
2765 ** seconds (only works on unix)
2766 ** --nocompress Do not compress HTTP replies
2767 ** --nojail Drop root privileges but do not enter the chroot jail
2768 ** --nossl signal that no SSL connections are available (Always
2769
+2 -12
--- src/main.mk
+++ src/main.mk
@@ -154,11 +154,10 @@
154154
$(SRCDIR)/webmail.c \
155155
$(SRCDIR)/wiki.c \
156156
$(SRCDIR)/wikiformat.c \
157157
$(SRCDIR)/winfile.c \
158158
$(SRCDIR)/winhttp.c \
159
- $(SRCDIR)/wysiwyg.c \
160159
$(SRCDIR)/xfer.c \
161160
$(SRCDIR)/xfersetup.c \
162161
$(SRCDIR)/zip.c
163162
164163
EXTRA_FILES = \
@@ -228,10 +227,11 @@
228227
$(SRCDIR)/fossil.confirmer.js \
229228
$(SRCDIR)/fossil.dom.js \
230229
$(SRCDIR)/fossil.fetch.js \
231230
$(SRCDIR)/fossil.page.fileedit.js \
232231
$(SRCDIR)/fossil.page.forumpost.js \
232
+ $(SRCDIR)/fossil.page.wikiedit.js \
233233
$(SRCDIR)/fossil.storage.js \
234234
$(SRCDIR)/fossil.tabs.js \
235235
$(SRCDIR)/graph.js \
236236
$(SRCDIR)/href.js \
237237
$(SRCDIR)/login.js \
@@ -257,10 +257,11 @@
257257
$(SRCDIR)/sounds/d.wav \
258258
$(SRCDIR)/sounds/e.wav \
259259
$(SRCDIR)/sounds/f.wav \
260260
$(SRCDIR)/style.admin_log.css \
261261
$(SRCDIR)/style.fileedit.css \
262
+ $(SRCDIR)/style.wikiedit.css \
262263
$(SRCDIR)/tree.js \
263264
$(SRCDIR)/useredit.js \
264265
$(SRCDIR)/wiki.wiki
265266
266267
TRANS_SRC = \
@@ -402,11 +403,10 @@
402403
$(OBJDIR)/webmail_.c \
403404
$(OBJDIR)/wiki_.c \
404405
$(OBJDIR)/wikiformat_.c \
405406
$(OBJDIR)/winfile_.c \
406407
$(OBJDIR)/winhttp_.c \
407
- $(OBJDIR)/wysiwyg_.c \
408408
$(OBJDIR)/xfer_.c \
409409
$(OBJDIR)/xfersetup_.c \
410410
$(OBJDIR)/zip_.c
411411
412412
OBJ = \
@@ -548,11 +548,10 @@
548548
$(OBJDIR)/webmail.o \
549549
$(OBJDIR)/wiki.o \
550550
$(OBJDIR)/wikiformat.o \
551551
$(OBJDIR)/winfile.o \
552552
$(OBJDIR)/winhttp.o \
553
- $(OBJDIR)/wysiwyg.o \
554553
$(OBJDIR)/xfer.o \
555554
$(OBJDIR)/xfersetup.o \
556555
$(OBJDIR)/zip.o
557556
all: $(OBJDIR) $(APPNAME)
558557
@@ -884,11 +883,10 @@
884883
$(OBJDIR)/webmail_.c:$(OBJDIR)/webmail.h \
885884
$(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h \
886885
$(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h \
887886
$(OBJDIR)/winfile_.c:$(OBJDIR)/winfile.h \
888887
$(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h \
889
- $(OBJDIR)/wysiwyg_.c:$(OBJDIR)/wysiwyg.h \
890888
$(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h \
891889
$(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h \
892890
$(OBJDIR)/zip_.c:$(OBJDIR)/zip.h \
893891
$(SRCDIR)/sqlite3.h \
894892
$(SRCDIR)/th.h \
@@ -2015,18 +2013,10 @@
20152013
$(OBJDIR)/winhttp.o: $(OBJDIR)/winhttp_.c $(OBJDIR)/winhttp.h $(SRCDIR)/config.h
20162014
$(XTCC) -o $(OBJDIR)/winhttp.o -c $(OBJDIR)/winhttp_.c
20172015
20182016
$(OBJDIR)/winhttp.h: $(OBJDIR)/headers
20192017
2020
-$(OBJDIR)/wysiwyg_.c: $(SRCDIR)/wysiwyg.c $(OBJDIR)/translate
2021
- $(OBJDIR)/translate $(SRCDIR)/wysiwyg.c >$@
2022
-
2023
-$(OBJDIR)/wysiwyg.o: $(OBJDIR)/wysiwyg_.c $(OBJDIR)/wysiwyg.h $(SRCDIR)/config.h
2024
- $(XTCC) -o $(OBJDIR)/wysiwyg.o -c $(OBJDIR)/wysiwyg_.c
2025
-
2026
-$(OBJDIR)/wysiwyg.h: $(OBJDIR)/headers
2027
-
20282018
$(OBJDIR)/xfer_.c: $(SRCDIR)/xfer.c $(OBJDIR)/translate
20292019
$(OBJDIR)/translate $(SRCDIR)/xfer.c >$@
20302020
20312021
$(OBJDIR)/xfer.o: $(OBJDIR)/xfer_.c $(OBJDIR)/xfer.h $(SRCDIR)/config.h
20322022
$(XTCC) -o $(OBJDIR)/xfer.o -c $(OBJDIR)/xfer_.c
20332023
--- src/main.mk
+++ src/main.mk
@@ -154,11 +154,10 @@
154 $(SRCDIR)/webmail.c \
155 $(SRCDIR)/wiki.c \
156 $(SRCDIR)/wikiformat.c \
157 $(SRCDIR)/winfile.c \
158 $(SRCDIR)/winhttp.c \
159 $(SRCDIR)/wysiwyg.c \
160 $(SRCDIR)/xfer.c \
161 $(SRCDIR)/xfersetup.c \
162 $(SRCDIR)/zip.c
163
164 EXTRA_FILES = \
@@ -228,10 +227,11 @@
228 $(SRCDIR)/fossil.confirmer.js \
229 $(SRCDIR)/fossil.dom.js \
230 $(SRCDIR)/fossil.fetch.js \
231 $(SRCDIR)/fossil.page.fileedit.js \
232 $(SRCDIR)/fossil.page.forumpost.js \
 
233 $(SRCDIR)/fossil.storage.js \
234 $(SRCDIR)/fossil.tabs.js \
235 $(SRCDIR)/graph.js \
236 $(SRCDIR)/href.js \
237 $(SRCDIR)/login.js \
@@ -257,10 +257,11 @@
257 $(SRCDIR)/sounds/d.wav \
258 $(SRCDIR)/sounds/e.wav \
259 $(SRCDIR)/sounds/f.wav \
260 $(SRCDIR)/style.admin_log.css \
261 $(SRCDIR)/style.fileedit.css \
 
262 $(SRCDIR)/tree.js \
263 $(SRCDIR)/useredit.js \
264 $(SRCDIR)/wiki.wiki
265
266 TRANS_SRC = \
@@ -402,11 +403,10 @@
402 $(OBJDIR)/webmail_.c \
403 $(OBJDIR)/wiki_.c \
404 $(OBJDIR)/wikiformat_.c \
405 $(OBJDIR)/winfile_.c \
406 $(OBJDIR)/winhttp_.c \
407 $(OBJDIR)/wysiwyg_.c \
408 $(OBJDIR)/xfer_.c \
409 $(OBJDIR)/xfersetup_.c \
410 $(OBJDIR)/zip_.c
411
412 OBJ = \
@@ -548,11 +548,10 @@
548 $(OBJDIR)/webmail.o \
549 $(OBJDIR)/wiki.o \
550 $(OBJDIR)/wikiformat.o \
551 $(OBJDIR)/winfile.o \
552 $(OBJDIR)/winhttp.o \
553 $(OBJDIR)/wysiwyg.o \
554 $(OBJDIR)/xfer.o \
555 $(OBJDIR)/xfersetup.o \
556 $(OBJDIR)/zip.o
557 all: $(OBJDIR) $(APPNAME)
558
@@ -884,11 +883,10 @@
884 $(OBJDIR)/webmail_.c:$(OBJDIR)/webmail.h \
885 $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h \
886 $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h \
887 $(OBJDIR)/winfile_.c:$(OBJDIR)/winfile.h \
888 $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h \
889 $(OBJDIR)/wysiwyg_.c:$(OBJDIR)/wysiwyg.h \
890 $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h \
891 $(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h \
892 $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h \
893 $(SRCDIR)/sqlite3.h \
894 $(SRCDIR)/th.h \
@@ -2015,18 +2013,10 @@
2015 $(OBJDIR)/winhttp.o: $(OBJDIR)/winhttp_.c $(OBJDIR)/winhttp.h $(SRCDIR)/config.h
2016 $(XTCC) -o $(OBJDIR)/winhttp.o -c $(OBJDIR)/winhttp_.c
2017
2018 $(OBJDIR)/winhttp.h: $(OBJDIR)/headers
2019
2020 $(OBJDIR)/wysiwyg_.c: $(SRCDIR)/wysiwyg.c $(OBJDIR)/translate
2021 $(OBJDIR)/translate $(SRCDIR)/wysiwyg.c >$@
2022
2023 $(OBJDIR)/wysiwyg.o: $(OBJDIR)/wysiwyg_.c $(OBJDIR)/wysiwyg.h $(SRCDIR)/config.h
2024 $(XTCC) -o $(OBJDIR)/wysiwyg.o -c $(OBJDIR)/wysiwyg_.c
2025
2026 $(OBJDIR)/wysiwyg.h: $(OBJDIR)/headers
2027
2028 $(OBJDIR)/xfer_.c: $(SRCDIR)/xfer.c $(OBJDIR)/translate
2029 $(OBJDIR)/translate $(SRCDIR)/xfer.c >$@
2030
2031 $(OBJDIR)/xfer.o: $(OBJDIR)/xfer_.c $(OBJDIR)/xfer.h $(SRCDIR)/config.h
2032 $(XTCC) -o $(OBJDIR)/xfer.o -c $(OBJDIR)/xfer_.c
2033
--- src/main.mk
+++ src/main.mk
@@ -154,11 +154,10 @@
154 $(SRCDIR)/webmail.c \
155 $(SRCDIR)/wiki.c \
156 $(SRCDIR)/wikiformat.c \
157 $(SRCDIR)/winfile.c \
158 $(SRCDIR)/winhttp.c \
 
159 $(SRCDIR)/xfer.c \
160 $(SRCDIR)/xfersetup.c \
161 $(SRCDIR)/zip.c
162
163 EXTRA_FILES = \
@@ -228,10 +227,11 @@
227 $(SRCDIR)/fossil.confirmer.js \
228 $(SRCDIR)/fossil.dom.js \
229 $(SRCDIR)/fossil.fetch.js \
230 $(SRCDIR)/fossil.page.fileedit.js \
231 $(SRCDIR)/fossil.page.forumpost.js \
232 $(SRCDIR)/fossil.page.wikiedit.js \
233 $(SRCDIR)/fossil.storage.js \
234 $(SRCDIR)/fossil.tabs.js \
235 $(SRCDIR)/graph.js \
236 $(SRCDIR)/href.js \
237 $(SRCDIR)/login.js \
@@ -257,10 +257,11 @@
257 $(SRCDIR)/sounds/d.wav \
258 $(SRCDIR)/sounds/e.wav \
259 $(SRCDIR)/sounds/f.wav \
260 $(SRCDIR)/style.admin_log.css \
261 $(SRCDIR)/style.fileedit.css \
262 $(SRCDIR)/style.wikiedit.css \
263 $(SRCDIR)/tree.js \
264 $(SRCDIR)/useredit.js \
265 $(SRCDIR)/wiki.wiki
266
267 TRANS_SRC = \
@@ -402,11 +403,10 @@
403 $(OBJDIR)/webmail_.c \
404 $(OBJDIR)/wiki_.c \
405 $(OBJDIR)/wikiformat_.c \
406 $(OBJDIR)/winfile_.c \
407 $(OBJDIR)/winhttp_.c \
 
408 $(OBJDIR)/xfer_.c \
409 $(OBJDIR)/xfersetup_.c \
410 $(OBJDIR)/zip_.c
411
412 OBJ = \
@@ -548,11 +548,10 @@
548 $(OBJDIR)/webmail.o \
549 $(OBJDIR)/wiki.o \
550 $(OBJDIR)/wikiformat.o \
551 $(OBJDIR)/winfile.o \
552 $(OBJDIR)/winhttp.o \
 
553 $(OBJDIR)/xfer.o \
554 $(OBJDIR)/xfersetup.o \
555 $(OBJDIR)/zip.o
556 all: $(OBJDIR) $(APPNAME)
557
@@ -884,11 +883,10 @@
883 $(OBJDIR)/webmail_.c:$(OBJDIR)/webmail.h \
884 $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h \
885 $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h \
886 $(OBJDIR)/winfile_.c:$(OBJDIR)/winfile.h \
887 $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h \
 
888 $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h \
889 $(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h \
890 $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h \
891 $(SRCDIR)/sqlite3.h \
892 $(SRCDIR)/th.h \
@@ -2015,18 +2013,10 @@
2013 $(OBJDIR)/winhttp.o: $(OBJDIR)/winhttp_.c $(OBJDIR)/winhttp.h $(SRCDIR)/config.h
2014 $(XTCC) -o $(OBJDIR)/winhttp.o -c $(OBJDIR)/winhttp_.c
2015
2016 $(OBJDIR)/winhttp.h: $(OBJDIR)/headers
2017
 
 
 
 
 
 
 
 
2018 $(OBJDIR)/xfer_.c: $(SRCDIR)/xfer.c $(OBJDIR)/translate
2019 $(OBJDIR)/translate $(SRCDIR)/xfer.c >$@
2020
2021 $(OBJDIR)/xfer.o: $(OBJDIR)/xfer_.c $(OBJDIR)/xfer.h $(SRCDIR)/config.h
2022 $(XTCC) -o $(OBJDIR)/xfer.o -c $(OBJDIR)/xfer_.c
2023
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -164,11 +164,10 @@
164164
webmail
165165
wiki
166166
wikiformat
167167
winfile
168168
winhttp
169
- wysiwyg
170169
xfer
171170
xfersetup
172171
zip
173172
http_ssl
174173
}
175174
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -164,11 +164,10 @@
164 webmail
165 wiki
166 wikiformat
167 winfile
168 winhttp
169 wysiwyg
170 xfer
171 xfersetup
172 zip
173 http_ssl
174 }
175
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -164,11 +164,10 @@
164 webmail
165 wiki
166 wikiformat
167 winfile
168 winhttp
 
169 xfer
170 xfersetup
171 zip
172 http_ssl
173 }
174
+1 -11
--- src/setup.c
+++ src/setup.c
@@ -1077,24 +1077,14 @@
10771077
@ in forum posts, make this setting be "<b>btw</b>". The default is an
10781078
@ empty string which means that Fossil never allows Markdown documents
10791079
@ to generate unsafe HTML.
10801080
@ (Property: "safe-html")</p>
10811081
@ <hr />
1082
- @ <hr />
1083
- onoff_attribute("Enable WYSIWYG Wiki Editing",
1084
- "wysiwyg-wiki", "wysiwyg-wiki", 0, 0);
1085
- @ <p>Enable what-you-see-is-what-you-get (WYSIWYG) editing of wiki pages.
1086
- @ The WYSIWYG editor generates HTML instead of markup, which makes
1087
- @ subsequent manual editing more difficult.
1088
- @ (Property: "wysiwyg-wiki")</p>
1089
- @ <hr />
10901082
onoff_attribute("Use HTML as wiki markup language",
10911083
"wiki-use-html", "wiki-use-html", 0, 0);
10921084
@ <p>Use HTML as the wiki markup language. Wiki links will still be parsed
1093
- @ but all other wiki formatting will be ignored. This option is helpful
1094
- @ if you have chosen to use a rich HTML editor for wiki markup such as
1095
- @ TinyMCE.</p>
1085
+ @ but all other wiki formatting will be ignored.</p>
10961086
@ <p><strong>CAUTION:</strong> when
10971087
@ enabling, <i>all</i> HTML tags and attributes are accepted in the wiki.
10981088
@ No sanitization is done. This means that it is very possible for malicious
10991089
@ users to inject dangerous HTML, CSS and JavaScript code into your wiki.</p>
11001090
@ <p>This should <strong>only</strong> be enabled when wiki editing is limited
11011091
--- src/setup.c
+++ src/setup.c
@@ -1077,24 +1077,14 @@
1077 @ in forum posts, make this setting be "<b>btw</b>". The default is an
1078 @ empty string which means that Fossil never allows Markdown documents
1079 @ to generate unsafe HTML.
1080 @ (Property: "safe-html")</p>
1081 @ <hr />
1082 @ <hr />
1083 onoff_attribute("Enable WYSIWYG Wiki Editing",
1084 "wysiwyg-wiki", "wysiwyg-wiki", 0, 0);
1085 @ <p>Enable what-you-see-is-what-you-get (WYSIWYG) editing of wiki pages.
1086 @ The WYSIWYG editor generates HTML instead of markup, which makes
1087 @ subsequent manual editing more difficult.
1088 @ (Property: "wysiwyg-wiki")</p>
1089 @ <hr />
1090 onoff_attribute("Use HTML as wiki markup language",
1091 "wiki-use-html", "wiki-use-html", 0, 0);
1092 @ <p>Use HTML as the wiki markup language. Wiki links will still be parsed
1093 @ but all other wiki formatting will be ignored. This option is helpful
1094 @ if you have chosen to use a rich HTML editor for wiki markup such as
1095 @ TinyMCE.</p>
1096 @ <p><strong>CAUTION:</strong> when
1097 @ enabling, <i>all</i> HTML tags and attributes are accepted in the wiki.
1098 @ No sanitization is done. This means that it is very possible for malicious
1099 @ users to inject dangerous HTML, CSS and JavaScript code into your wiki.</p>
1100 @ <p>This should <strong>only</strong> be enabled when wiki editing is limited
1101
--- src/setup.c
+++ src/setup.c
@@ -1077,24 +1077,14 @@
1077 @ in forum posts, make this setting be "<b>btw</b>". The default is an
1078 @ empty string which means that Fossil never allows Markdown documents
1079 @ to generate unsafe HTML.
1080 @ (Property: "safe-html")</p>
1081 @ <hr />
 
 
 
 
 
 
 
 
1082 onoff_attribute("Use HTML as wiki markup language",
1083 "wiki-use-html", "wiki-use-html", 0, 0);
1084 @ <p>Use HTML as the wiki markup language. Wiki links will still be parsed
1085 @ but all other wiki formatting will be ignored.</p>
 
 
1086 @ <p><strong>CAUTION:</strong> when
1087 @ enabling, <i>all</i> HTML tags and attributes are accepted in the wiki.
1088 @ No sanitization is done. This means that it is very possible for malicious
1089 @ users to inject dangerous HTML, CSS and JavaScript code into your wiki.</p>
1090 @ <p>This should <strong>only</strong> be enabled when wiki editing is limited
1091
+46 -11
--- src/style.c
+++ src/style.c
@@ -1423,24 +1423,27 @@
14231423
** bootstrap the window.fossil object, using the built-in file
14241424
** fossil.bootstrap.js (not to be confused with bootstrap.js).
14251425
**
14261426
** Subsequent calls are no-ops.
14271427
**
1428
-** If passed a true value, it emits the contents directly to the page
1429
-** output, else it emits a script tag with a src=builtin/... to load
1430
-** the script. It always outputs a small pre-bootstrap element in its
1431
-** own script tag to initialize parts which need C-runtime-level
1432
-** information, before loading the main fossil.bootstrap.js either
1433
-** inline or via a <script src=...>, as specified by the first
1434
-** argument.
1428
+** It emits 2 parts:
1429
+**
1430
+** 1) window.fossil core object, some of which depends on C-level
1431
+** runtime data. That part of the script is always emitted inline. If
1432
+** addScriptTag is true then it is wrapped in its own SCRIPT tag, else
1433
+** it is assumed that the caller already opened a tag.
1434
+**
1435
+** 2) Emits the static fossil.bootstrap.js using builtin_request_js().
14351436
*/
1436
-void style_emit_script_fossil_bootstrap(int asInline){
1437
+void style_emit_script_fossil_bootstrap(int addScriptTag){
14371438
static int once = 0;
14381439
if(0==once++){
14391440
/* Set up the generic/app-agnostic parts of window.fossil
14401441
** which require C-level state... */
1441
- style_emit_script_tag(0,0);
1442
+ if(addScriptTag!=0){
1443
+ style_emit_script_tag(0,0);
1444
+ }
14421445
CX("(function(){\n"
14431446
"if(!window.fossil) window.fossil={};\n"
14441447
"window.fossil.version = %!j;\n"
14451448
/* fossil.rootPath is the top-most CGI/server path,
14461449
** including a trailing slash. */
@@ -1465,13 +1468,15 @@
14651468
*/
14661469
CX("window.fossil.page = {"
14671470
"name:\"%T\""
14681471
"};\n", g.zPath);
14691472
CX("})();\n");
1470
- /* The remaining fossil object bootstrap code is not dependent on
1473
+ if(addScriptTag!=0){
1474
+ style_emit_script_tag(1,0);
1475
+ }
1476
+ /* The remaining window.fossil bootstrap code is not dependent on
14711477
** C-runtime state... */
1472
- style_emit_script_tag(1,0);
14731478
builtin_request_js("fossil.bootstrap.js");
14741479
}
14751480
}
14761481
14771482
/*
@@ -1501,5 +1506,35 @@
15011506
}
15021507
}else{
15031508
CX("</script>\n");
15041509
}
15051510
}
1511
+
1512
+/*
1513
+** Convenience wrapper which calls builtin_request_js() for a series
1514
+** of builtin scripts named fossil.NAME.js. The first time it is
1515
+** called, it also calls style_emit_script_fossil_bootstrap() to
1516
+** initialize the window.fossil JS API. The first argument is a
1517
+** no-meaning dummy required by the va_start() interface. All
1518
+** subsequent arguments must be strings of the NAME part of
1519
+** fossil.NAME.js, followed by a NULL argument to terminate the list.
1520
+**
1521
+** e.g. pass it (0, "fetch", "dom", "tabs", 0) to load those 3
1522
+** APIs. Do not forget the trailing 0!
1523
+*/
1524
+void style_emit_fossil_js_apis( int dummy, ... ) {
1525
+ static int once = 0;
1526
+ const char *zArg;
1527
+ char * zName;
1528
+ va_list vargs;
1529
+
1530
+ if(0==once++){
1531
+ style_emit_script_fossil_bootstrap(1);
1532
+ }
1533
+ va_start(vargs,dummy);
1534
+ while( (zArg = va_arg (vargs, const char *))!=0 ){
1535
+ zName = mprintf("fossil.%s.js", zArg);
1536
+ builtin_request_js(zName);
1537
+ fossil_free(zName);
1538
+ }
1539
+ va_end(vargs);
1540
+}
15061541
--- src/style.c
+++ src/style.c
@@ -1423,24 +1423,27 @@
1423 ** bootstrap the window.fossil object, using the built-in file
1424 ** fossil.bootstrap.js (not to be confused with bootstrap.js).
1425 **
1426 ** Subsequent calls are no-ops.
1427 **
1428 ** If passed a true value, it emits the contents directly to the page
1429 ** output, else it emits a script tag with a src=builtin/... to load
1430 ** the script. It always outputs a small pre-bootstrap element in its
1431 ** own script tag to initialize parts which need C-runtime-level
1432 ** information, before loading the main fossil.bootstrap.js either
1433 ** inline or via a <script src=...>, as specified by the first
1434 ** argument.
 
1435 */
1436 void style_emit_script_fossil_bootstrap(int asInline){
1437 static int once = 0;
1438 if(0==once++){
1439 /* Set up the generic/app-agnostic parts of window.fossil
1440 ** which require C-level state... */
1441 style_emit_script_tag(0,0);
 
 
1442 CX("(function(){\n"
1443 "if(!window.fossil) window.fossil={};\n"
1444 "window.fossil.version = %!j;\n"
1445 /* fossil.rootPath is the top-most CGI/server path,
1446 ** including a trailing slash. */
@@ -1465,13 +1468,15 @@
1465 */
1466 CX("window.fossil.page = {"
1467 "name:\"%T\""
1468 "};\n", g.zPath);
1469 CX("})();\n");
1470 /* The remaining fossil object bootstrap code is not dependent on
 
 
 
1471 ** C-runtime state... */
1472 style_emit_script_tag(1,0);
1473 builtin_request_js("fossil.bootstrap.js");
1474 }
1475 }
1476
1477 /*
@@ -1501,5 +1506,35 @@
1501 }
1502 }else{
1503 CX("</script>\n");
1504 }
1505 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1506
--- src/style.c
+++ src/style.c
@@ -1423,24 +1423,27 @@
1423 ** bootstrap the window.fossil object, using the built-in file
1424 ** fossil.bootstrap.js (not to be confused with bootstrap.js).
1425 **
1426 ** Subsequent calls are no-ops.
1427 **
1428 ** It emits 2 parts:
1429 **
1430 ** 1) window.fossil core object, some of which depends on C-level
1431 ** runtime data. That part of the script is always emitted inline. If
1432 ** addScriptTag is true then it is wrapped in its own SCRIPT tag, else
1433 ** it is assumed that the caller already opened a tag.
1434 **
1435 ** 2) Emits the static fossil.bootstrap.js using builtin_request_js().
1436 */
1437 void style_emit_script_fossil_bootstrap(int addScriptTag){
1438 static int once = 0;
1439 if(0==once++){
1440 /* Set up the generic/app-agnostic parts of window.fossil
1441 ** which require C-level state... */
1442 if(addScriptTag!=0){
1443 style_emit_script_tag(0,0);
1444 }
1445 CX("(function(){\n"
1446 "if(!window.fossil) window.fossil={};\n"
1447 "window.fossil.version = %!j;\n"
1448 /* fossil.rootPath is the top-most CGI/server path,
1449 ** including a trailing slash. */
@@ -1465,13 +1468,15 @@
1468 */
1469 CX("window.fossil.page = {"
1470 "name:\"%T\""
1471 "};\n", g.zPath);
1472 CX("})();\n");
1473 if(addScriptTag!=0){
1474 style_emit_script_tag(1,0);
1475 }
1476 /* The remaining window.fossil bootstrap code is not dependent on
1477 ** C-runtime state... */
 
1478 builtin_request_js("fossil.bootstrap.js");
1479 }
1480 }
1481
1482 /*
@@ -1501,5 +1506,35 @@
1506 }
1507 }else{
1508 CX("</script>\n");
1509 }
1510 }
1511
1512 /*
1513 ** Convenience wrapper which calls builtin_request_js() for a series
1514 ** of builtin scripts named fossil.NAME.js. The first time it is
1515 ** called, it also calls style_emit_script_fossil_bootstrap() to
1516 ** initialize the window.fossil JS API. The first argument is a
1517 ** no-meaning dummy required by the va_start() interface. All
1518 ** subsequent arguments must be strings of the NAME part of
1519 ** fossil.NAME.js, followed by a NULL argument to terminate the list.
1520 **
1521 ** e.g. pass it (0, "fetch", "dom", "tabs", 0) to load those 3
1522 ** APIs. Do not forget the trailing 0!
1523 */
1524 void style_emit_fossil_js_apis( int dummy, ... ) {
1525 static int once = 0;
1526 const char *zArg;
1527 char * zName;
1528 va_list vargs;
1529
1530 if(0==once++){
1531 style_emit_script_fossil_bootstrap(1);
1532 }
1533 va_start(vargs,dummy);
1534 while( (zArg = va_arg (vargs, const char *))!=0 ){
1535 zName = mprintf("fossil.%s.js", zArg);
1536 builtin_request_js(zName);
1537 fossil_free(zName);
1538 }
1539 va_end(vargs);
1540 }
1541
+46 -11
--- src/style.c
+++ src/style.c
@@ -1423,24 +1423,27 @@
14231423
** bootstrap the window.fossil object, using the built-in file
14241424
** fossil.bootstrap.js (not to be confused with bootstrap.js).
14251425
**
14261426
** Subsequent calls are no-ops.
14271427
**
1428
-** If passed a true value, it emits the contents directly to the page
1429
-** output, else it emits a script tag with a src=builtin/... to load
1430
-** the script. It always outputs a small pre-bootstrap element in its
1431
-** own script tag to initialize parts which need C-runtime-level
1432
-** information, before loading the main fossil.bootstrap.js either
1433
-** inline or via a <script src=...>, as specified by the first
1434
-** argument.
1428
+** It emits 2 parts:
1429
+**
1430
+** 1) window.fossil core object, some of which depends on C-level
1431
+** runtime data. That part of the script is always emitted inline. If
1432
+** addScriptTag is true then it is wrapped in its own SCRIPT tag, else
1433
+** it is assumed that the caller already opened a tag.
1434
+**
1435
+** 2) Emits the static fossil.bootstrap.js using builtin_request_js().
14351436
*/
1436
-void style_emit_script_fossil_bootstrap(int asInline){
1437
+void style_emit_script_fossil_bootstrap(int addScriptTag){
14371438
static int once = 0;
14381439
if(0==once++){
14391440
/* Set up the generic/app-agnostic parts of window.fossil
14401441
** which require C-level state... */
1441
- style_emit_script_tag(0,0);
1442
+ if(addScriptTag!=0){
1443
+ style_emit_script_tag(0,0);
1444
+ }
14421445
CX("(function(){\n"
14431446
"if(!window.fossil) window.fossil={};\n"
14441447
"window.fossil.version = %!j;\n"
14451448
/* fossil.rootPath is the top-most CGI/server path,
14461449
** including a trailing slash. */
@@ -1465,13 +1468,15 @@
14651468
*/
14661469
CX("window.fossil.page = {"
14671470
"name:\"%T\""
14681471
"};\n", g.zPath);
14691472
CX("})();\n");
1470
- /* The remaining fossil object bootstrap code is not dependent on
1473
+ if(addScriptTag!=0){
1474
+ style_emit_script_tag(1,0);
1475
+ }
1476
+ /* The remaining window.fossil bootstrap code is not dependent on
14711477
** C-runtime state... */
1472
- style_emit_script_tag(1,0);
14731478
builtin_request_js("fossil.bootstrap.js");
14741479
}
14751480
}
14761481
14771482
/*
@@ -1501,5 +1506,35 @@
15011506
}
15021507
}else{
15031508
CX("</script>\n");
15041509
}
15051510
}
1511
+
1512
+/*
1513
+** Convenience wrapper which calls builtin_request_js() for a series
1514
+** of builtin scripts named fossil.NAME.js. The first time it is
1515
+** called, it also calls style_emit_script_fossil_bootstrap() to
1516
+** initialize the window.fossil JS API. The first argument is a
1517
+** no-meaning dummy required by the va_start() interface. All
1518
+** subsequent arguments must be strings of the NAME part of
1519
+** fossil.NAME.js, followed by a NULL argument to terminate the list.
1520
+**
1521
+** e.g. pass it (0, "fetch", "dom", "tabs", 0) to load those 3
1522
+** APIs. Do not forget the trailing 0!
1523
+*/
1524
+void style_emit_fossil_js_apis( int dummy, ... ) {
1525
+ static int once = 0;
1526
+ const char *zArg;
1527
+ char * zName;
1528
+ va_list vargs;
1529
+
1530
+ if(0==once++){
1531
+ style_emit_script_fossil_bootstrap(1);
1532
+ }
1533
+ va_start(vargs,dummy);
1534
+ while( (zArg = va_arg (vargs, const char *))!=0 ){
1535
+ zName = mprintf("fossil.%s.js", zArg);
1536
+ builtin_request_js(zName);
1537
+ fossil_free(zName);
1538
+ }
1539
+ va_end(vargs);
1540
+}
15061541
--- src/style.c
+++ src/style.c
@@ -1423,24 +1423,27 @@
1423 ** bootstrap the window.fossil object, using the built-in file
1424 ** fossil.bootstrap.js (not to be confused with bootstrap.js).
1425 **
1426 ** Subsequent calls are no-ops.
1427 **
1428 ** If passed a true value, it emits the contents directly to the page
1429 ** output, else it emits a script tag with a src=builtin/... to load
1430 ** the script. It always outputs a small pre-bootstrap element in its
1431 ** own script tag to initialize parts which need C-runtime-level
1432 ** information, before loading the main fossil.bootstrap.js either
1433 ** inline or via a <script src=...>, as specified by the first
1434 ** argument.
 
1435 */
1436 void style_emit_script_fossil_bootstrap(int asInline){
1437 static int once = 0;
1438 if(0==once++){
1439 /* Set up the generic/app-agnostic parts of window.fossil
1440 ** which require C-level state... */
1441 style_emit_script_tag(0,0);
 
 
1442 CX("(function(){\n"
1443 "if(!window.fossil) window.fossil={};\n"
1444 "window.fossil.version = %!j;\n"
1445 /* fossil.rootPath is the top-most CGI/server path,
1446 ** including a trailing slash. */
@@ -1465,13 +1468,15 @@
1465 */
1466 CX("window.fossil.page = {"
1467 "name:\"%T\""
1468 "};\n", g.zPath);
1469 CX("})();\n");
1470 /* The remaining fossil object bootstrap code is not dependent on
 
 
 
1471 ** C-runtime state... */
1472 style_emit_script_tag(1,0);
1473 builtin_request_js("fossil.bootstrap.js");
1474 }
1475 }
1476
1477 /*
@@ -1501,5 +1506,35 @@
1501 }
1502 }else{
1503 CX("</script>\n");
1504 }
1505 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1506
--- src/style.c
+++ src/style.c
@@ -1423,24 +1423,27 @@
1423 ** bootstrap the window.fossil object, using the built-in file
1424 ** fossil.bootstrap.js (not to be confused with bootstrap.js).
1425 **
1426 ** Subsequent calls are no-ops.
1427 **
1428 ** It emits 2 parts:
1429 **
1430 ** 1) window.fossil core object, some of which depends on C-level
1431 ** runtime data. That part of the script is always emitted inline. If
1432 ** addScriptTag is true then it is wrapped in its own SCRIPT tag, else
1433 ** it is assumed that the caller already opened a tag.
1434 **
1435 ** 2) Emits the static fossil.bootstrap.js using builtin_request_js().
1436 */
1437 void style_emit_script_fossil_bootstrap(int addScriptTag){
1438 static int once = 0;
1439 if(0==once++){
1440 /* Set up the generic/app-agnostic parts of window.fossil
1441 ** which require C-level state... */
1442 if(addScriptTag!=0){
1443 style_emit_script_tag(0,0);
1444 }
1445 CX("(function(){\n"
1446 "if(!window.fossil) window.fossil={};\n"
1447 "window.fossil.version = %!j;\n"
1448 /* fossil.rootPath is the top-most CGI/server path,
1449 ** including a trailing slash. */
@@ -1465,13 +1468,15 @@
1468 */
1469 CX("window.fossil.page = {"
1470 "name:\"%T\""
1471 "};\n", g.zPath);
1472 CX("})();\n");
1473 if(addScriptTag!=0){
1474 style_emit_script_tag(1,0);
1475 }
1476 /* The remaining window.fossil bootstrap code is not dependent on
1477 ** C-runtime state... */
 
1478 builtin_request_js("fossil.bootstrap.js");
1479 }
1480 }
1481
1482 /*
@@ -1501,5 +1506,35 @@
1506 }
1507 }else{
1508 CX("</script>\n");
1509 }
1510 }
1511
1512 /*
1513 ** Convenience wrapper which calls builtin_request_js() for a series
1514 ** of builtin scripts named fossil.NAME.js. The first time it is
1515 ** called, it also calls style_emit_script_fossil_bootstrap() to
1516 ** initialize the window.fossil JS API. The first argument is a
1517 ** no-meaning dummy required by the va_start() interface. All
1518 ** subsequent arguments must be strings of the NAME part of
1519 ** fossil.NAME.js, followed by a NULL argument to terminate the list.
1520 **
1521 ** e.g. pass it (0, "fetch", "dom", "tabs", 0) to load those 3
1522 ** APIs. Do not forget the trailing 0!
1523 */
1524 void style_emit_fossil_js_apis( int dummy, ... ) {
1525 static int once = 0;
1526 const char *zArg;
1527 char * zName;
1528 va_list vargs;
1529
1530 if(0==once++){
1531 style_emit_script_fossil_bootstrap(1);
1532 }
1533 va_start(vargs,dummy);
1534 while( (zArg = va_arg (vargs, const char *))!=0 ){
1535 zName = mprintf("fossil.%s.js", zArg);
1536 builtin_request_js(zName);
1537 fossil_free(zName);
1538 }
1539 va_end(vargs);
1540 }
1541
--- src/style.fileedit.css
+++ src/style.fileedit.css
@@ -183,186 +183,5 @@
183183
width: initial;
184184
}
185185
body.fileedit .sbsdiffcols div.difftxtcol pre {
186186
max-width: 44em;
187187
}
188
-
189
-/**
190
- Styles for fossil.tabs.js. As of this writing, currently
191
- only used by /fileedit, but it is anticipated that these
192
- will eventually need to migrate to default_css.txt for use
193
- in the wiki and/or forum pages when implementing tabbed
194
- ajax-based previews.
195
-*/
196
-.tab-container {
197
- width: 100%;
198
- display: flex;
199
- flex-direction: column;
200
- align-items: stretch;
201
-}
202
-.tab-container > #fossil-status-bar {
203
- margin-top: 0;
204
-}
205
-.tab-container > .tabs {
206
- padding: 0.25em;
207
- margin: 0;
208
- display: flex;
209
- flex-direction: column;
210
- border-width: 1px;
211
- border-style: outset;
212
- border-color: inherit;
213
-}
214
-.tab-container > .tabs > .tab-panel {
215
- align-self: stretch;
216
- flex: 10 1 auto;
217
- display: block;
218
-}
219
-.tab-container > .tab-bar {
220
- display: flex;
221
- flex-direction: row;
222
- flex: 1 10 auto;
223
- align-self: stretch;
224
- flex-wrap: wrap;
225
-}
226
-.tab-container > .tab-bar > .tab-button {
227
- display: inline-block;
228
- border-radius: 0.5em 0.5em 0 0;
229
- margin: 0 0.1em;
230
- padding: 0.25em 0.75em;
231
- align-self: baseline;
232
- border-color: inherit;
233
- border-width: 1px;
234
- border-bottom: none;
235
- border-top-style: inset;
236
- border-left-style: inset;
237
- border-right-style: inset;
238
- cursor: pointer;
239
- opacity: 0.6;
240
-}
241
-.tab-container > .tab-bar > .tab-button.selected {
242
- text-decoration: underline;
243
- opacity: 1.0;
244
- border-top-style: outset;
245
- border-left-style: outset;
246
- border-right-style: outset;
247
-}
248
-
249
-/**
250
- Styles developed for /fileedit but which have wider
251
- applicability...
252
-
253
- As of this writing, these are only used by /fileedit, but it is
254
- anticipated that they will eventually need to be migrated over to
255
- default_css.txt for use in other pages (specifically wiki and forum
256
- page/post editors).
257
-*/
258
-.flex-container {
259
- display: flex;
260
-}
261
-.flex-container.flex-row {
262
- flex-direction: row;
263
- flex-wrap: wrap;
264
- justify-content: center;
265
- align-items: center;
266
-}
267
-.flex-container .flex-grow {
268
- flex-grow: 10;
269
- flex-shrink: 0;
270
-}
271
-.flex-container .flex-shrink {
272
- flex-grow: 0;
273
- flex-shrink: 10;
274
-}
275
-.flex-container.flex-row.stretch {
276
- flex-wrap: wrap;
277
- align-items: baseline;
278
- justify-content: stretch;
279
- margin: 0;
280
-}
281
-.flex-container.flex-column {
282
- flex-direction: column;
283
- flex-wrap: wrap;
284
- justify-content: center;
285
- align-items: center;
286
-}
287
-.flex-container.flex-column.stretch {
288
- align-items: stretch;
289
- margin: 0;
290
-}
291
-.flex-container.child-gap-small > * {
292
- margin: 0.25em;
293
-}
294
-#fossil-status-bar {
295
- display: block;
296
- font-family: monospace;
297
- border-width: 1px;
298
- border-style: inset;
299
- border-color: inherit;
300
- min-height: 1.5em;
301
- font-size: 1.2em;
302
- padding: 0.2em;
303
- margin: 0.25em 0;
304
- flex: 0 0 auto;
305
-}
306
-.font-size-100 {
307
- font-size: 100%;
308
-}
309
-.font-size-125 {
310
- font-size: 125%;
311
-}
312
-.font-size-150 {
313
- font-size: 150%;
314
-}
315
-.font-size-175 {
316
- font-size: 175%;
317
-}
318
-.font-size-200 {
319
- font-size: 200%;
320
-}
321
-
322
-/**
323
- .input-with-label is intended to be a wrapper element which
324
- contain both a LABEL tag and an INPUT or SELECT control.
325
- The wrapper is "necessary", as opposed to placing the INPUT
326
- in the LABEL, so that we can include multiple INPUT
327
- elements (e.g. a set of radio buttons).
328
-*/
329
-.input-with-label {
330
- border: 1px inset #808080;
331
- border-radius: 0.5em;
332
- padding: 0.25em 0.4em;
333
- margin: 0 0.5em;
334
- display: inline-block;
335
- cursor: default;
336
-}
337
-.input-with-label > * {
338
- vertical-align: middle;
339
-}
340
-.input-with-label > label {
341
- display: inline; /* some skins set label display to block! */
342
-}
343
-.input-with-label > input {
344
- margin: 0;
345
-}
346
-.input-with-label > button {
347
- margin: 0;
348
-}
349
-.input-with-label > select {
350
- margin: 0;
351
-}
352
-.input-with-label > input[type=text] {
353
- margin: 0;
354
-}
355
-.input-with-label > textarea {
356
- margin: 0;
357
-}
358
-.input-with-label > input[type=checkbox] {
359
- vertical-align: sub;
360
-}
361
-.input-with-label > input[type=radio] {
362
- vertical-align: sub;
363
-}
364
-.input-with-label > label {
365
- font-weight: initial;
366
- margin: 0 0.25em 0 0.25em;
367
- vertical-align: middle;
368
-}
369188
370189
ADDED src/style.wikiedit.css
--- src/style.fileedit.css
+++ src/style.fileedit.css
@@ -183,186 +183,5 @@
183 width: initial;
184 }
185 body.fileedit .sbsdiffcols div.difftxtcol pre {
186 max-width: 44em;
187 }
188
189 /**
190 Styles for fossil.tabs.js. As of this writing, currently
191 only used by /fileedit, but it is anticipated that these
192 will eventually need to migrate to default_css.txt for use
193 in the wiki and/or forum pages when implementing tabbed
194 ajax-based previews.
195 */
196 .tab-container {
197 width: 100%;
198 display: flex;
199 flex-direction: column;
200 align-items: stretch;
201 }
202 .tab-container > #fossil-status-bar {
203 margin-top: 0;
204 }
205 .tab-container > .tabs {
206 padding: 0.25em;
207 margin: 0;
208 display: flex;
209 flex-direction: column;
210 border-width: 1px;
211 border-style: outset;
212 border-color: inherit;
213 }
214 .tab-container > .tabs > .tab-panel {
215 align-self: stretch;
216 flex: 10 1 auto;
217 display: block;
218 }
219 .tab-container > .tab-bar {
220 display: flex;
221 flex-direction: row;
222 flex: 1 10 auto;
223 align-self: stretch;
224 flex-wrap: wrap;
225 }
226 .tab-container > .tab-bar > .tab-button {
227 display: inline-block;
228 border-radius: 0.5em 0.5em 0 0;
229 margin: 0 0.1em;
230 padding: 0.25em 0.75em;
231 align-self: baseline;
232 border-color: inherit;
233 border-width: 1px;
234 border-bottom: none;
235 border-top-style: inset;
236 border-left-style: inset;
237 border-right-style: inset;
238 cursor: pointer;
239 opacity: 0.6;
240 }
241 .tab-container > .tab-bar > .tab-button.selected {
242 text-decoration: underline;
243 opacity: 1.0;
244 border-top-style: outset;
245 border-left-style: outset;
246 border-right-style: outset;
247 }
248
249 /**
250 Styles developed for /fileedit but which have wider
251 applicability...
252
253 As of this writing, these are only used by /fileedit, but it is
254 anticipated that they will eventually need to be migrated over to
255 default_css.txt for use in other pages (specifically wiki and forum
256 page/post editors).
257 */
258 .flex-container {
259 display: flex;
260 }
261 .flex-container.flex-row {
262 flex-direction: row;
263 flex-wrap: wrap;
264 justify-content: center;
265 align-items: center;
266 }
267 .flex-container .flex-grow {
268 flex-grow: 10;
269 flex-shrink: 0;
270 }
271 .flex-container .flex-shrink {
272 flex-grow: 0;
273 flex-shrink: 10;
274 }
275 .flex-container.flex-row.stretch {
276 flex-wrap: wrap;
277 align-items: baseline;
278 justify-content: stretch;
279 margin: 0;
280 }
281 .flex-container.flex-column {
282 flex-direction: column;
283 flex-wrap: wrap;
284 justify-content: center;
285 align-items: center;
286 }
287 .flex-container.flex-column.stretch {
288 align-items: stretch;
289 margin: 0;
290 }
291 .flex-container.child-gap-small > * {
292 margin: 0.25em;
293 }
294 #fossil-status-bar {
295 display: block;
296 font-family: monospace;
297 border-width: 1px;
298 border-style: inset;
299 border-color: inherit;
300 min-height: 1.5em;
301 font-size: 1.2em;
302 padding: 0.2em;
303 margin: 0.25em 0;
304 flex: 0 0 auto;
305 }
306 .font-size-100 {
307 font-size: 100%;
308 }
309 .font-size-125 {
310 font-size: 125%;
311 }
312 .font-size-150 {
313 font-size: 150%;
314 }
315 .font-size-175 {
316 font-size: 175%;
317 }
318 .font-size-200 {
319 font-size: 200%;
320 }
321
322 /**
323 .input-with-label is intended to be a wrapper element which
324 contain both a LABEL tag and an INPUT or SELECT control.
325 The wrapper is "necessary", as opposed to placing the INPUT
326 in the LABEL, so that we can include multiple INPUT
327 elements (e.g. a set of radio buttons).
328 */
329 .input-with-label {
330 border: 1px inset #808080;
331 border-radius: 0.5em;
332 padding: 0.25em 0.4em;
333 margin: 0 0.5em;
334 display: inline-block;
335 cursor: default;
336 }
337 .input-with-label > * {
338 vertical-align: middle;
339 }
340 .input-with-label > label {
341 display: inline; /* some skins set label display to block! */
342 }
343 .input-with-label > input {
344 margin: 0;
345 }
346 .input-with-label > button {
347 margin: 0;
348 }
349 .input-with-label > select {
350 margin: 0;
351 }
352 .input-with-label > input[type=text] {
353 margin: 0;
354 }
355 .input-with-label > textarea {
356 margin: 0;
357 }
358 .input-with-label > input[type=checkbox] {
359 vertical-align: sub;
360 }
361 .input-with-label > input[type=radio] {
362 vertical-align: sub;
363 }
364 .input-with-label > label {
365 font-weight: initial;
366 margin: 0 0.25em 0 0.25em;
367 vertical-align: middle;
368 }
369
370 DDED src/style.wikiedit.css
--- src/style.fileedit.css
+++ src/style.fileedit.css
@@ -183,186 +183,5 @@
183 width: initial;
184 }
185 body.fileedit .sbsdiffcols div.difftxtcol pre {
186 max-width: 44em;
187 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
189 DDED src/style.wikiedit.css
--- a/src/style.wikiedit.css
+++ b/src/style.wikiedit.css
@@ -0,0 +1,6 @@
1
+>}
2
+ height */.5emselect option.stashed::before {
3
+/* Maintenance reminder: the option.stashed/stashed-new "content" values
4
+ are duplicated in fossil.page.wikiedit.js and need to be changed there
5
+ if they are changed here: see fossil.page.config.editStateMarkers */
6
+ content: "[*] "select option.stashed-new: "[+] "I@ZG,3Z@Rb,H@Fl,_@W3,H@Fl,J5@XF,~@r0,2gWxR1;page-name > span {}
--- a/src/style.wikiedit.css
+++ b/src/style.wikiedit.css
@@ -0,0 +1,6 @@
 
 
 
 
 
 
--- a/src/style.wikiedit.css
+++ b/src/style.wikiedit.css
@@ -0,0 +1,6 @@
1 >}
2 height */.5emselect option.stashed::before {
3 /* Maintenance reminder: the option.stashed/stashed-new "content" values
4 are duplicated in fossil.page.wikiedit.js and need to be changed there
5 if they are changed here: see fossil.page.config.editStateMarkers */
6 content: "[*] "select option.stashed-new: "[+] "I@ZG,3Z@Rb,H@Fl,_@W3,H@Fl,J5@XF,~@r0,2gWxR1;page-name > span {}
+640 -202
--- src/wiki.c
+++ src/wiki.c
@@ -102,11 +102,10 @@
102102
" WHERE tagid=%d AND mtime<%.16g"
103103
" ORDER BY mtime DESC LIMIT 1",
104104
tagid, mtime);
105105
}
106106
107
-
108107
/*
109108
** WEBPAGE: home
110109
** WEBPAGE: index
111110
** WEBPAGE: not_found
112111
**
@@ -398,10 +397,24 @@
398397
if( sqlite3_strglob("tag/*", zPageName)==0 ){
399398
return WIKITYPE_TAG;
400399
}
401400
return WIKITYPE_NORMAL;
402401
}
402
+
403
+/*
404
+** Returns a JSON-friendly string form of the integer value returned
405
+** by wiki_page_type(zPageName).
406
+*/
407
+const char * wiki_page_type_name(const char *zPageName){
408
+ switch(wiki_page_type(zPageName)){
409
+ case WIKITYPE_CHECKIN: return "checkin";
410
+ case WIKITYPE_BRANCH: return "branch";
411
+ case WIKITYPE_TAG: return "tag";
412
+ case WIKITYPE_NORMAL:
413
+ default: return "normal";
414
+ }
415
+}
403416
404417
/*
405418
** Add an appropriate style_header() for either the /wiki or /wikiedit page
406419
** for zPageName. zExtra is an empty string for /wiki but has the text
407420
** "Edit: " for /wikiedit.
@@ -541,16 +554,11 @@
541554
zMimetype = wiki_filter_mimetypes(zMimetype);
542555
if( !g.isHome && !noSubmenu ){
543556
if( ((rid && g.perm.WrWiki) || (!rid && g.perm.NewWiki))
544557
&& wiki_special_permission(zPageName)
545558
){
546
- if( db_get_boolean("wysiwyg-wiki", 0) ){
547
- style_submenu_element("Edit", "%R/wikiedit?name=%T&wysiwyg=1",
548
- zPageName);
549
- }else{
550
- style_submenu_element("Edit", "%R/wikiedit?name=%T", zPageName);
551
- }
559
+ style_submenu_element("Edit", "%R/wikiedit?name=%T", zPageName);
552560
}else if( rid && g.perm.ApndWiki ){
553561
style_submenu_element("Edit", "%R/wikiappend?name=%T", zPageName);
554562
}
555563
if( g.perm.Hyperlink ){
556564
style_submenu_element("History", "%R/whistory?name=%T", zPageName);
@@ -620,220 +628,656 @@
620628
return azStyles[i+1];
621629
}
622630
}
623631
return azStyles[1];
624632
}
633
+
634
+/*
635
+ ** Tries to fetch a wiki page for the given name. If found, it
636
+ ** returns true, else false.
637
+ **
638
+ ** versionsBack specifies how many versions back in the history to
639
+ ** fetch. Use 0 for the latest version, 1 for its parent, etc.
640
+ **
641
+ ** If pRid is not NULL then if a result is found *pRid is set to its
642
+ ** RID. If ppWiki is not NULL then if found *ppWiki is set to the
643
+ ** loaded wiki object, which the caller is responsible for passing to
644
+ ** manifest_destroy().
645
+ */
646
+static int wiki_fetch_by_name( const char *zPageName,
647
+ unsigned int versionsBack,
648
+ int * pRid, Manifest **ppWiki ){
649
+ Manifest *pWiki = 0;
650
+ char *zTag = mprintf("wiki-%s", zPageName);
651
+ Stmt q = empty_Stmt;
652
+ int rid = 0;
653
+
654
+ db_prepare(&q, "SELECT rid FROM tagxref"
655
+ " WHERE tagid=(SELECT tagid FROM tag WHERE"
656
+ " tagname=%Q) "
657
+ " ORDER BY mtime DESC LIMIT -1 OFFSET %u", zTag,
658
+ versionsBack);
659
+ fossil_free(zTag);
660
+ if(SQLITE_ROW == db_step(&q)){
661
+ rid = db_column_int(&q, 0);
662
+ }
663
+ db_finalize(&q);
664
+ if( rid == 0 ){
665
+ return 0;
666
+ }
667
+ else if(pRid){
668
+ *pRid = rid;
669
+ }
670
+ if(ppWiki){
671
+ pWiki = manifest_get(rid, CFTYPE_WIKI, 0);
672
+ if( pWiki==0 ){
673
+ /* "Cannot happen." */
674
+ return 0;
675
+ }
676
+ *ppWiki = pWiki;
677
+ }
678
+ return 1;
679
+}
680
+
681
+/*
682
+** Determines whether the wiki page with the given name can be edited
683
+** or created by the current user. If not, an AJAX error is queued and
684
+** false is returned, else true is returned. A NULL, empty, or
685
+** malformed name is considered non-writable, regardless of the user.
686
+**
687
+** If pRid is not NULL then this function writes the page's rid to
688
+** *pRid (whether or not access is granted). On error or if the page
689
+** does not yet exist, *pRid will be set to 0.
690
+**
691
+** Note that the sandbox is a special case: it is a pseudo-page with
692
+** no rid and the /wikiajax API does not allow anyone to actually save
693
+** a sandbox page, but it is reported as writable here (with rid 0).
694
+*/
695
+static int wiki_ajax_can_write(const char *zPageName, int * pRid){
696
+ int rid = 0;
697
+ const char * zErr = 0;
698
+
699
+ if(pRid) *pRid = 0;
700
+ if(!zPageName || !*zPageName
701
+ || !wiki_name_is_wellformed((unsigned const char *)zPageName)){
702
+ zErr = "Invalid page name.";
703
+ }else if(is_sandbox(zPageName)){
704
+ return 1;
705
+ }else{
706
+ wiki_fetch_by_name(zPageName, 0, &rid, 0);
707
+ if(pRid) *pRid = rid;
708
+ if(!wiki_special_permission(zPageName)){
709
+ zErr = "Editing this page requires non-wiki write permissions.";
710
+ }else if( (rid && g.perm.WrWiki) || (!rid && g.perm.NewWiki) ){
711
+ return 3;
712
+ }else if(rid && !g.perm.WrWiki){
713
+ zErr = "Requires wiki-write permissions.";
714
+ }else if(!rid && !g.perm.NewWiki){
715
+ zErr = "Requires new-wiki permissions.";
716
+ }else{
717
+ zErr = "Cannot happen! Please report this as a bug.";
718
+ }
719
+ }
720
+ ajax_route_error(403, "%s", zErr);
721
+ return 0;
722
+}
723
+
724
+/*
725
+** Loads the given wiki page, sets the response type to
726
+** application/json, and emits it as a JSON object. If zPageName is a
727
+** sandbox page then a "fake" object is emitted, as the wikiajax API
728
+** does not permit saving the sandbox.
729
+**
730
+** Returns true on success, false on error, and on error it
731
+** queues up a JSON-format error response.
732
+**
733
+** Output JSON format:
734
+**
735
+** { name: "page name",
736
+** type: "normal" | "tag" | "checkin" | "branch" | "sandbox",
737
+** mimetype: "mime type",
738
+** version: UUID string or null for a sandbox page,
739
+** parent: "parent uuid" or null if no parent,
740
+** content: "page content"
741
+** }
742
+**
743
+** If includeContent is false then the content member is elided.
744
+*/
745
+static int wiki_ajax_emit_page_object(const char *zPageName,
746
+ int includeContent){
747
+ Manifest * pWiki = 0;
748
+ char * zUuid;
749
+
750
+ cgi_set_content_type("application/json");
751
+ if( is_sandbox(zPageName) ){
752
+ char * zMimetype =
753
+ db_get("sandbox-mimetype","text/x-fossil-wiki");
754
+ char * zBody = db_get("sandbox","");
755
+ CX("{\"name\": %!j, \"type\": \"sandbox\", "
756
+ "\"mimetype\": %!j, \"version\": null, \"parent\": null",
757
+ zPageName, zMimetype);
758
+ if(includeContent){
759
+ CX(", \"content\": %!j",
760
+ zBody);
761
+ }
762
+ CX("}");
763
+ fossil_free(zMimetype);
764
+ fossil_free(zBody);
765
+ return 1;
766
+ }else if( !wiki_fetch_by_name(zPageName, 0, 0, &pWiki) ){
767
+ ajax_route_error(404, "Wiki page could not be loaded: %s",
768
+ zPageName);
769
+ return 0;
770
+ }else{
771
+ zUuid = rid_to_uuid(pWiki->rid);
772
+ CX("{\"name\": %!j, \"type\": %!j, "
773
+ "\"version\": %!j, "
774
+ "\"mimetype\": %!j, ",
775
+ pWiki->zWikiTitle,
776
+ wiki_page_type_name(pWiki->zWikiTitle),
777
+ zUuid,
778
+ pWiki->zMimetype ? pWiki->zMimetype : "text/x-fossil-wiki");
779
+ CX("\"parent\": ");
780
+ if(pWiki->nParent){
781
+ CX("%!j", pWiki->azParent[0]);
782
+ }else{
783
+ CX("null");
784
+ }
785
+ if(includeContent){
786
+ CX(", \"content\": %!j", pWiki->zWiki);
787
+ }
788
+ CX("}");
789
+ fossil_free(zUuid);
790
+ manifest_destroy(pWiki);
791
+ return 2;
792
+ }
793
+}
794
+
795
+/*
796
+** Ajax route handler for /wikiajax/save.
797
+**
798
+** URL params:
799
+**
800
+** page = the wiki page name.
801
+** mimetype = content mime type.
802
+** content = page content. Fossil considers an empty page to
803
+** be "deleted".
804
+** isnew = 1 if the page is to be newly-created, else 0 or
805
+** not send.
806
+**
807
+** Responds with JSON. On error, an object in the form documented by
808
+** ajax_route_error(). On success, an object in the form documented
809
+** for wiki_ajax_emit_page_object().
810
+**
811
+** The wikiajax API disallows saving of a sandbox pseudo-page, and
812
+** will respond with an error if asked to save one.
813
+**
814
+** Reminder: the original implementation implements sandbox-page
815
+** saving using:
816
+**
817
+** db_set("sandbox",zBody,0);
818
+** db_set("sandbox-mimetype",zMimetype,0);
819
+**
820
+*/
821
+static void wiki_ajax_route_save(void){
822
+ const char *zPageName = P("page");
823
+ const char *zMimetype = P("mimetype");
824
+ const char *zContent = P("content");
825
+ const int isNew = atoi(PD("isnew","0"))==1;
826
+ Blob content = empty_blob;
827
+ int parentRid = 0;
828
+ int rollback = 0;
829
+
830
+ if(!wiki_ajax_can_write(zPageName, &parentRid)){
831
+ return;
832
+ }else if(is_sandbox(zPageName)){
833
+ ajax_route_error(403,"Saving a sandbox page is prohibited.");
834
+ return;
835
+ }
836
+
837
+ /* These isNew checks are just me being pedantic. The hope is
838
+ to avoid accidental addition of new pages which differ only
839
+ by the case of their name. We could just as easily derive
840
+ isNew based on whether or not the page already exists. */
841
+ if(isNew){
842
+ if(parentRid>0){
843
+ ajax_route_error(403,"Requested a new page, "
844
+ "but it already exists with RID %d: %s",
845
+ parentRid, zPageName);
846
+ return;
847
+ }
848
+ }else if(parentRid==0){
849
+ ajax_route_error(403,"Creating new page [%s] requires passing "
850
+ "isnew=1.", zPageName);
851
+ return;
852
+ }
853
+
854
+ blob_init(&content, zContent ? zContent : "", -1);
855
+ db_begin_transaction();
856
+ wiki_cmd_commit(zPageName, parentRid, &content, zMimetype, 0);
857
+ rollback = wiki_ajax_emit_page_object(zPageName, 1) ? 0 : 1;
858
+ db_end_transaction(rollback);
859
+}
860
+
861
+/*
862
+** Ajax route handler for /wikiajax/fetch.
863
+**
864
+** URL params:
865
+**
866
+** page = the wiki page name
867
+**
868
+** Responds with JSON. On error, an object in the form documented by
869
+** ajax_route_error(). On success, an object in the form documented
870
+** for wiki_ajax_emit_page_object().
871
+*/
872
+static void wiki_ajax_route_fetch(void){
873
+ const char * zPageName = P("page");
874
+
875
+ if( zPageName==0 || zPageName[0]==0 ){
876
+ ajax_route_error(400,"Missing page name.");
877
+ return;
878
+ }
879
+ wiki_ajax_emit_page_object(zPageName, 1);
880
+}
881
+
882
+/*
883
+** Ajax route handler for /wikiajax/diff.
884
+**
885
+** URL params:
886
+**
887
+** page = the wiki page name
888
+** content = the new/edited wiki page content
889
+**
890
+** Requires that the user have write access solely to avoid some
891
+** potential abuse cases. It does not actually write anything.
892
+*/
893
+static void wiki_ajax_route_diff(void){
894
+ const char * zPageName = P("page");
895
+ Blob contentNew = empty_blob, contentOrig = empty_blob;
896
+ Manifest * pParent = 0;
897
+ const char * zContent = P("content");
898
+ u64 diffFlags = DIFF_HTML | DIFF_NOTTOOBIG | DIFF_STRIP_EOLCR;
899
+
900
+ if( zPageName==0 || zPageName[0]==0 ){
901
+ ajax_route_error(400,"Missing page name.");
902
+ return;
903
+ }else if(!wiki_ajax_can_write(zPageName, 0)){
904
+ return;
905
+ }
906
+ switch(atoi(PD("sbs","0"))){
907
+ case 0: diffFlags |= DIFF_LINENO; break;
908
+ default: diffFlags |= DIFF_SIDEBYSIDE;
909
+ }
910
+ switch(atoi(PD("ws","2"))){
911
+ case 1: diffFlags |= DIFF_IGNORE_EOLWS; break;
912
+ case 2: diffFlags |= DIFF_IGNORE_ALLWS; break;
913
+ default: break;
914
+ }
915
+ wiki_fetch_by_name( zPageName, 0, 0, &pParent );
916
+ if( pParent && pParent->zWiki && *pParent->zWiki ){
917
+ blob_init(&contentOrig, pParent->zWiki, -1);
918
+ }else{
919
+ blob_init(&contentOrig, "", 0);
920
+ }
921
+ blob_init(&contentNew, zContent ? zContent : "", -1);
922
+ cgi_set_content_type("text/html");
923
+ ajax_render_diff(&contentOrig, &contentNew, diffFlags);
924
+ blob_reset(&contentNew);
925
+ blob_reset(&contentOrig);
926
+ manifest_destroy(pParent);
927
+}
928
+
929
+/*
930
+** Ajax route handler for /wikiajax/preview.
931
+**
932
+** URL params:
933
+**
934
+** page = wiki page name. This is only needed for authorization
935
+** checking.
936
+** mimetype = the wiki page mimetype (determines rendering style)
937
+** content = the wiki page content
938
+*/
939
+static void wiki_ajax_route_preview(void){
940
+ const char * zPageName = P("page");
941
+ const char * zContent = P("content");
942
+
943
+ if(!wiki_ajax_can_write(zPageName, 0)){
944
+ return;
945
+ }else if( zContent==0 ){
946
+ ajax_route_error(400,"Missing content to preview.");
947
+ return;
948
+ }else{
949
+ Blob content = empty_blob;
950
+ const char * zMimetype = PD("mimetype","text/x-fossil-wiki");
951
+
952
+ blob_init(&content, zContent, -1);
953
+ cgi_set_content_type("text/html");
954
+ wiki_render_by_mimetype(&content, zMimetype);
955
+ blob_reset(&content);
956
+ }
957
+}
958
+
959
+/*
960
+** Ajax route handler for /wikiajax/list.
961
+**
962
+** Optional parameters: verbose, includeContent (see below).
963
+**
964
+** Responds with JSON. On error, an object in the form documented by
965
+** ajax_route_error().
966
+**
967
+** On success, it emits an array of strings (page names) sorted
968
+** case-insensitively. If the "verbose" parameter is passed in then
969
+** the result list contains objects in the format documented for
970
+** wiki_ajax_emit_page_object(). The content of each object is elided
971
+** unless the "includeContent" parameter is passed on.
972
+**
973
+** The result list always contains an entry
974
+** named "sandbox" which represents the sandbox pseudo-page.
975
+*/
976
+static void wiki_ajax_route_list(void){
977
+ Stmt q = empty_Stmt;
978
+ int n = 0;
979
+ const int verbose = ajax_p_bool("verbose");
980
+ const int includeContent = ajax_p_bool("includeContent");
981
+
982
+ cgi_set_content_type("application/json");
983
+ db_begin_transaction();
984
+ db_prepare(&q, "SELECT"
985
+ " substr(tagname,6) AS name"
986
+ " FROM tag WHERE tagname GLOB 'wiki-*'"
987
+ " UNION SELECT 'Sandbox' AS name"
988
+ " ORDER BY name COLLATE NOCASE");
989
+ CX("[");
990
+ while( SQLITE_ROW==db_step(&q) ){
991
+ char const * zName = db_column_text(&q,0);
992
+ if(n++){
993
+ CX(",");
994
+ }
995
+ if(verbose==0){
996
+ CX("%!j", zName);
997
+ }else{
998
+ wiki_ajax_emit_page_object(zName, includeContent);
999
+ }
1000
+ }
1001
+ db_finalize(&q);
1002
+ db_end_transaction(0);
1003
+ CX("]");
1004
+}
1005
+
1006
+
1007
+/*
1008
+** WEBPAGE: wikiajax
1009
+**
1010
+** An internal dispatcher for wiki AJAX operations. Not for direct
1011
+** client use. All routes defined by this interface are app-internal,
1012
+** subject to change
1013
+*/
1014
+void wiki_ajax_page(void){
1015
+ const char * zName = P("name");
1016
+ AjaxRoute routeName = {0,0,0,0};
1017
+ const AjaxRoute * pRoute = 0;
1018
+ const AjaxRoute routes[] = {
1019
+ /* Keep these sorted by zName (for bsearch()) */
1020
+ {"diff", wiki_ajax_route_diff, 1, 1},
1021
+ {"fetch", wiki_ajax_route_fetch, 0, 0},
1022
+ {"list", wiki_ajax_route_list, 0, 0},
1023
+ {"preview", wiki_ajax_route_preview, 0, 1}
1024
+ /* preview access mode: whether or not wiki-write mode is needed
1025
+ really depends on multiple factors. e.g. the sandbox page does
1026
+ not normally require more than anonymous access. We set its
1027
+ write-mode to false and do those checks manually in that route's
1028
+ handler.
1029
+ */,
1030
+ {"save", wiki_ajax_route_save, 1, 1}
1031
+ };
1032
+
1033
+ if(zName==0 || zName[0]==0){
1034
+ ajax_route_error(400,"Missing required [route] 'name' parameter.");
1035
+ return;
1036
+ }
1037
+ routeName.zName = zName;
1038
+ pRoute = (const AjaxRoute *)bsearch(&routeName, routes,
1039
+ count(routes), sizeof routes[0],
1040
+ cmp_ajax_route_name);
1041
+ if(pRoute==0){
1042
+ ajax_route_error(404,"Ajax route not found.");
1043
+ return;
1044
+ }
1045
+ login_check_credentials();
1046
+ if( pRoute->bWriteMode!=0 && g.perm.WrWiki==0 ){
1047
+ ajax_route_error(403,"Write permissions required.");
1048
+ return;
1049
+ }else if(0==cgi_csrf_safe(pRoute->bPost)){
1050
+ ajax_route_error(403,
1051
+ "CSRF violation (make sure sending of HTTP "
1052
+ "Referer headers is enabled for XHR "
1053
+ "connections).");
1054
+ return;
1055
+ }
1056
+ pRoute->xCallback();
1057
+}
6251058
6261059
/*
6271060
** WEBPAGE: wikiedit
628
-** URL: /wikiedit?name=PAGENAME
1061
+** URL: /wikedit?name=PAGENAME
1062
+**
1063
+** The main front-end for the Ajax-based wiki editor app. Passing
1064
+** in the name of an unknown page will trigger the creation
1065
+** of a new page (which is not actually created in the database
1066
+** until the user explicitly saves it). If passed no page name,
1067
+** the user may select a page from the list on the first UI tab.
6291068
**
630
-** Edit a wiki page.
1069
+** When creating a new page, the mimetype URL parameter may optionally
1070
+** be used to set its mimetype to one of text/x-fossil-wiki,
1071
+** text/x-markdown, or text/plain, defauling to the former.
6311072
*/
6321073
void wikiedit_page(void){
633
- char *zTag;
634
- int rid = 0;
1074
+ const char *zPageName;
1075
+ const char * zMimetype = P("mimetype");
6351076
int isSandbox;
636
- Blob wiki;
637
- Manifest *pWiki = 0;
638
- const char *zPageName;
639
- int n;
640
- const char *z;
641
- char *zBody = (char*)P("w");
642
- const char *zMimetype = wiki_filter_mimetypes(P("mimetype"));
643
- int isWysiwyg = P("wysiwyg")!=0;
644
- int goodCaptcha = 1;
645
- int eType = WIKITYPE_UNKNOWN;
646
- int havePreview = 0;
647
-
648
- if( P("edit-wysiwyg")!=0 ){ isWysiwyg = 1; zBody = 0; }
649
- if( P("edit-markup")!=0 ){ isWysiwyg = 0; zBody = 0; }
650
- if( zBody ){
651
- if( isWysiwyg ){
652
- Blob body;
653
- blob_zero(&body);
654
- htmlTidy(zBody, &body);
655
- zBody = blob_str(&body);
656
- }else{
657
- zBody = mprintf("%s", zBody);
658
- }
659
- }
1077
+ int found = 0;
1078
+
6601079
login_check_credentials();
6611080
zPageName = PD("name","");
662
- if( check_name(zPageName) ) return;
1081
+ if(zPageName && *zPageName){
1082
+ if( check_name(zPageName) ) return;
1083
+ }
6631084
isSandbox = is_sandbox(zPageName);
6641085
if( isSandbox ){
6651086
if( !g.perm.WrWiki ){
6661087
login_needed(g.anon.WrWiki);
6671088
return;
6681089
}
669
- if( zBody==0 ){
670
- zBody = db_get("sandbox","");
671
- zMimetype = db_get("sandbox-mimetype","text/x-fossil-wiki");
672
- }
673
- }else{
674
- zTag = mprintf("wiki-%s", zPageName);
675
- rid = db_int(0,
676
- "SELECT rid FROM tagxref"
677
- " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
678
- " ORDER BY mtime DESC", zTag
679
- );
680
- free(zTag);
1090
+ found = 1;
1091
+ }else if( zPageName!=0 ){
1092
+ int rid = 0;
6811093
if( !wiki_special_permission(zPageName) ){
6821094
login_needed(0);
6831095
return;
6841096
}
1097
+ found = wiki_fetch_by_name(zPageName, 0, &rid, 0);
6851098
if( (rid && !g.perm.WrWiki) || (!rid && !g.perm.NewWiki) ){
6861099
login_needed(rid ? g.anon.WrWiki : g.anon.NewWiki);
6871100
return;
6881101
}
689
- if( zBody==0 && (pWiki = manifest_get(rid, CFTYPE_WIKI, 0))!=0 ){
690
- zBody = pWiki->zWiki;
691
- zMimetype = pWiki->zMimetype;
692
- }
693
- }
694
- if( P("submit")!=0 && zBody!=0
695
- && (goodCaptcha = captcha_is_correct(0))
696
- ){
697
- char *zDate;
698
- Blob cksum;
699
- blob_zero(&wiki);
700
- db_begin_transaction();
701
- if( isSandbox ){
702
- db_set("sandbox",zBody,0);
703
- db_set("sandbox-mimetype",zMimetype,0);
704
- }else{
705
- login_verify_csrf_secret();
706
- zDate = date_in_standard_format("now");
707
- blob_appendf(&wiki, "D %s\n", zDate);
708
- free(zDate);
709
- blob_appendf(&wiki, "L %F\n", zPageName);
710
- if( fossil_strcmp(zMimetype,"text/x-fossil-wiki")!=0 ){
711
- blob_appendf(&wiki, "N %s\n", zMimetype);
712
- }
713
- if( rid ){
714
- char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
715
- blob_appendf(&wiki, "P %s\n", zUuid);
716
- free(zUuid);
717
- }
718
- if( !login_is_nobody() ){
719
- blob_appendf(&wiki, "U %F\n", login_name());
720
- }
721
- blob_appendf(&wiki, "W %d\n%s\n", strlen(zBody), zBody);
722
- md5sum_blob(&wiki, &cksum);
723
- blob_appendf(&wiki, "Z %b\n", &cksum);
724
- blob_reset(&cksum);
725
- wiki_put(&wiki, 0, wiki_need_moderation(0));
726
- }
727
- db_end_transaction(0);
728
- cgi_redirectf("wiki?name=%T", zPageName);
729
- }
730
- if( P("cancel")!=0 ){
731
- cgi_redirectf("wiki?name=%T", zPageName);
732
- return;
733
- }
734
- if( zBody==0 ){
735
- zBody = mprintf("");
736
- }
737
- style_set_current_page("%T?name=%T", g.zPath, zPageName);
738
- eType = wiki_page_header(WIKITYPE_UNKNOWN, zPageName, "Edit: ");
739
- if( rid && !isSandbox && g.perm.ApndWiki ){
740
- if( g.perm.Attach ){
741
- style_submenu_element("Attach",
742
- "%s/attachadd?page=%T&from=%s/wiki%%3fname=%T",
743
- g.zTop, zPageName, g.zTop, zPageName);
744
- }
745
- }
746
- if( !goodCaptcha ){
747
- @ <p class="generalError">Error: Incorrect security code.</p>
748
- }
749
- blob_zero(&wiki);
750
- while( fossil_isspace(zBody[0]) ) zBody++;
751
- blob_append(&wiki, zBody, -1);
752
- if( P("preview")!=0 ){
753
- havePreview = 1;
754
- if( zBody[0] ){
755
- @ Preview:<hr />
756
- safe_html_context(DOCSRC_WIKI);
757
- wiki_render_by_mimetype(&wiki, zMimetype);
758
- @ <hr />
759
- blob_reset(&wiki);
760
- }
761
- }
762
- for(n=2, z=zBody; z[0]; z++){
763
- if( z[0]=='\n' ) n++;
764
- }
765
- if( n<20 ) n = 20;
766
- if( n>30 ) n = 30;
767
- if( !isWysiwyg ){
768
- /* Traditional markup-only editing */
769
- char *zPlaceholder = 0;
770
- switch( eType ){
771
- case WIKITYPE_NORMAL: {
772
- zPlaceholder = mprintf("Enter text for wiki page %s", zPageName);
773
- break;
774
- }
775
- case WIKITYPE_BRANCH: {
776
- zPlaceholder = mprintf("Enter notes about branch %s", zPageName+7);
777
- break;
778
- }
779
- case WIKITYPE_CHECKIN: {
780
- zPlaceholder = mprintf("Enter notes about check-in %.20s", zPageName+8);
781
- break;
782
- }
783
- case WIKITYPE_TAG: {
784
- zPlaceholder = mprintf("Enter notes about tag %s", zPageName+4);
785
- break;
786
- }
787
- }
788
- form_begin(0, "%R/wikiedit");
789
- @ <div>%z(href("%R/markup_help"))Markup style</a>:
790
- mimetype_option_menu(zMimetype);
791
- @ <br /><textarea name="w" class="wikiedit" cols="80" \
792
- @ rows="%d(n)" wrap="virtual" placeholder="%h(zPlaceholder)">\
793
- @ %h(zBody)</textarea>
794
- @ <br />
795
- fossil_free(zPlaceholder);
796
- if( db_get_boolean("wysiwyg-wiki", 0) ){
797
- @ <input type="submit" name="edit-wysiwyg" value="Wysiwyg Editor"
798
- @ onclick='return confirm("Switching to WYSIWYG-mode\nwill erase your markup\nedits. Continue?")' />
799
- }
800
- @ <input type="submit" name="preview" value="Preview Your Changes" />
801
- }else{
802
- /* Wysiwyg editing */
803
- Blob html, temp;
804
- havePreview = 1;
805
- form_begin("", "%R/wikiedit");
806
- @ <div>
807
- @ <input type="hidden" name="wysiwyg" value="1" />
808
- blob_zero(&temp);
809
- wiki_convert(&wiki, &temp, 0);
810
- blob_zero(&html);
811
- htmlTidy(blob_str(&temp), &html);
812
- blob_reset(&temp);
813
- wysiwygEditor("w", blob_str(&html), 60, n);
814
- blob_reset(&html);
815
- @ <br />
816
- @ <input type="submit" name="edit-markup" value="Markup Editor"
817
- @ onclick='return confirm("Switching to markup-mode\nwill erase your WYSIWYG\nedits. Continue?")' />
818
- }
819
- login_insert_csrf_secret();
820
- if( havePreview ){
821
- if( isWysiwyg || zBody[0] ){
822
- @ <input type="submit" name="submit" value="Apply These Changes" />
823
- }else{
824
- @ <input type="submit" name="submit" value="Delete This Wiki Page" />
825
- }
826
- }
827
- @ <input type="hidden" name="name" value="%h(zPageName)" />
828
- @ <input type="submit" name="cancel" value="Cancel"
829
- @ onclick='confirm("Abandon your changes?")' />
830
- @ </div>
831
- captcha_generate(0);
832
- @ </form>
833
- manifest_destroy(pWiki);
834
- blob_reset(&wiki);
1102
+ }
1103
+ style_header("Wiki Editor");
1104
+
1105
+ /* Status bar */
1106
+ CX("<div id='fossil-status-bar' "
1107
+ "title='Status message area. Double-click to clear them.'>"
1108
+ "Status messages will go here.</div>\n"
1109
+ /* will be moved into the tab container via JS */);
1110
+
1111
+ CX("<div id='wikiedit-page-name'>Editing: <span>(no file loaded)</span></div>");
1112
+
1113
+ /* Main tab container... */
1114
+ CX("<div id='wikiedit-tabs' class='tab-container'>Loading...</div>");
1115
+ /* The .hidden class on the following tab elements is to help lessen
1116
+ the FOUC effect of the tabs before JS re-assembles them. */
1117
+
1118
+ /******* Page list *******/
1119
+ {
1120
+ CX("<div id='wikiedit-tab-pages' "
1121
+ "data-tab-parent='wikiedit-tabs' "
1122
+ "data-tab-label='Wiki Page List' "
1123
+ "class='hidden'"
1124
+ ">");
1125
+ CX("<div>Loading wiki pages list...</div>");
1126
+ CX("</div>"/*#wikiedit-tab-pages*/);
1127
+ }
1128
+
1129
+ /******* Content tab *******/
1130
+ {
1131
+ CX("<div id='wikiedit-tab-content' "
1132
+ "data-tab-parent='wikiedit-tabs' "
1133
+ "data-tab-label='Editor' "
1134
+ "class='hidden'"
1135
+ ">");
1136
+ CX("<div class='flex-container flex-row child-gap-small'>");
1137
+ CX("<span class='input-with-label'>"
1138
+ "<label>Mime type</label>");
1139
+ mimetype_option_menu(0);
1140
+ CX("</span>");
1141
+ style_select_list_int("select-font-size",
1142
+ "editor_font_size", "Editor font size",
1143
+ NULL/*tooltip*/,
1144
+ 100,
1145
+ "100%", 100, "125%", 125,
1146
+ "150%", 150, "175%", 175,
1147
+ "200%", 200, NULL);
1148
+ CX("<button class='wikiedit-content-reload' "
1149
+ "title='Reload the file from the server, discarding "
1150
+ "any local edits. To help avoid accidental loss of "
1151
+ "edits, it requires confirmation (a second click) within "
1152
+ "a few seconds or it will not reload.'"
1153
+ ">Discard &amp; Reload</button>");
1154
+ CX("<button class='wikiedit-save' disabled='disabled'>"
1155
+ "Save</button>"/*will get moved around dynamically*/);
1156
+ CX("<span class='save-button-slot'></span>");
1157
+ CX("</div>");
1158
+ CX("<div class='flex-container flex-column stretch'>");
1159
+ CX("<textarea name='content' id='wikiedit-content-editor' "
1160
+ "class='wikiedit' "
1161
+ "rows='25' cols='80'>");
1162
+ CX("</textarea>");
1163
+ CX("</div>"/*textarea wrapper*/);
1164
+ CX("</div>"/*#tab-file-content*/);
1165
+ }
1166
+ /****** Preview tab ******/
1167
+ {
1168
+ CX("<div id='wikiedit-tab-preview' "
1169
+ "data-tab-parent='wikiedit-tabs' "
1170
+ "data-tab-label='Preview' "
1171
+ "class='hidden'"
1172
+ ">");
1173
+ CX("<div class='wikiedit-options flex-container flex-row'>");
1174
+ CX("<button id='btn-preview-refresh' "
1175
+ "data-f-preview-from='wikiContent' "
1176
+ /* ^^^ fossil.page[methodName]() OR text source elem ID,
1177
+ ** but we need a method in order to support clients swapping out
1178
+ ** the text editor with their own. */
1179
+ "data-f-preview-via='_postPreview' "
1180
+ /* ^^^ fossil.page[methodName](content, callback) */
1181
+ "data-f-preview-to='#wikiedit-tab-preview-wrapper' "
1182
+ /* ^^^ dest elem ID */
1183
+ ">Refresh</button>");
1184
+ /* Toggle auto-update of preview when the Preview tab is selected. */
1185
+ style_labeled_checkbox("cb-preview-autoupdate",
1186
+ NULL,
1187
+ "Auto-refresh?",
1188
+ "1", 1,
1189
+ "If on, the preview will automatically "
1190
+ "refresh when this tab is selected.");
1191
+ CX("<span class='save-button-slot'></span>");
1192
+ CX("</div>"/*.wikiedit-options*/);
1193
+ CX("<div id='wikiedit-tab-preview-wrapper'></div>");
1194
+ CX("</div>"/*#wikiedit-tab-preview*/);
1195
+ }
1196
+
1197
+ /****** Diff tab ******/
1198
+ {
1199
+ CX("<div id='wikiedit-tab-diff' "
1200
+ "data-tab-parent='wikiedit-tabs' "
1201
+ "data-tab-label='Diff' "
1202
+ "class='hidden'"
1203
+ ">");
1204
+
1205
+ CX("<div class='wikiedit-options flex-container flex-row' "
1206
+ "id='wikiedit-tab-diff-buttons'>");
1207
+ CX("<button class='sbs'>Side-by-side</button>"
1208
+ "<button class='unified'>Unified</button>");
1209
+ CX("<span class='save-button-slot'></span>");
1210
+ CX("</div>");
1211
+ CX("<div id='wikiedit-tab-diff-wrapper'>"
1212
+ "Diffs will be shown here."
1213
+ "</div>");
1214
+ CX("</div>"/*#wikiedit-tab-diff*/);
1215
+ }
1216
+
1217
+ /****** The obligatory "Misc" tab ******/
1218
+ {
1219
+ CX("<div id='wikiedit-tab-misc' "
1220
+ "data-tab-parent='wikiedit-tabs' "
1221
+ "data-tab-label='Help, Attachments, etc.' "
1222
+ "class='hidden'"
1223
+ ">");
1224
+ CX("<h3>Wiki formatting rules</h3>");
1225
+ CX("<ul>");
1226
+ CX("<li><a href='%R/wiki_rules'>Fossil wiki format</a></li>");
1227
+ CX("<li><a href='%R/md_rules'>Markdown format</a></li>");
1228
+ CX("<li>Plain-text pages use no special formatting.</li>");
1229
+ CX("</ul>");
1230
+ CX("<hr><h3>Attachments</h3>");
1231
+ CX("<div id='wikiedit-attachments'></div>"
1232
+ /* Filled out by JS */);
1233
+ CX("<hr><h3>The \"Sandbox\" Page</h3>");
1234
+ CX("<p>The page named \"Sandbox\" is not a real wiki page. "
1235
+ "It provides a place where users may test out wiki syntax "
1236
+ "without having to actually save anything, nor pollute "
1237
+ "the repo with endless test runs. Any attempt to save the "
1238
+ "sandbox page will fail.</p>");
1239
+ CX("<hr><h3>Wiki Name Rules</h3>");
1240
+ well_formed_wiki_name_rules();
1241
+ CX("</div>"/*#wikiedit-tab-save*/);
1242
+ }
1243
+
1244
+ builtin_request_js("sbsdiff.js");
1245
+ style_emit_fossil_js_apis(0, "fetch", "dom", "tabs", "confirmer",
1246
+ "storage", "page.wikiedit", 0);
1247
+ builtin_fulfill_js_requests();
1248
+ /* Dynamically populate the editor... */
1249
+ style_emit_script_tag(0,0);
1250
+ CX("\nfossil.onPageLoad(function(){\n");
1251
+ CX("const P = fossil.page;\n"
1252
+ "try{\n");
1253
+ if(!found && zPageName && *zPageName){
1254
+ /* For a new page, stick a dummy entry in the JS-side stash
1255
+ and "load" it from there. */
1256
+ CX("const winfo = {"
1257
+ "\"name\": %!j, \"mimetype\": %!j, "
1258
+ "\"type\": %!j, "
1259
+ "\"parent\": null, \"version\": null"
1260
+ "};\n",
1261
+ zPageName,
1262
+ zMimetype ? zMimetype : "text/x-fossil-wiki",
1263
+ wiki_page_type_name(zPageName));
1264
+ /* If the JS-side stash already has this page, load that
1265
+ copy from the stash, otherwise inject a new stash entry
1266
+ for it and load *that* one... */
1267
+ CX("if(!P.$stash.getWinfo(winfo)){"
1268
+ "P.$stash.updateWinfo(winfo,'');"
1269
+ "}\n");
1270
+ }
1271
+ if(zPageName && *zPageName){
1272
+ CX("P.loadPage(%!j);\n", zPageName);
1273
+ }
1274
+ CX("}catch(e){"
1275
+ "fossil.error(e); console.error('Exception:',e);"
1276
+ "}\n");
1277
+ CX("});\n"/*fossil.onPageLoad()*/);
1278
+ style_emit_script_tag(1,0);
8351279
style_footer();
8361280
}
8371281
8381282
/*
8391283
** WEBPAGE: wikinew
@@ -851,17 +1295,11 @@
8511295
return;
8521296
}
8531297
zName = PD("name","");
8541298
zMimetype = wiki_filter_mimetypes(P("mimetype"));
8551299
if( zName[0] && wiki_name_is_wellformed((const unsigned char *)zName) ){
856
- if( fossil_strcmp(zMimetype,"text/x-fossil-wiki")==0
857
- && db_get_boolean("wysiwyg-wiki", 0)
858
- ){
859
- cgi_redirectf("wikiedit?name=%T&wysiwyg=1", zName);
860
- }else{
861
- cgi_redirectf("wikiedit?name=%T&mimetype=%s", zName, zMimetype);
862
- }
1300
+ cgi_redirectf("wikiedit?name=%T&mimetype=%s", zName, zMimetype);
8631301
}
8641302
style_header("Create A New Wiki Page");
8651303
wiki_standard_submenu(W_ALL_BUT(W_NEW));
8661304
@ <p>Rules for wiki page names:</p>
8671305
well_formed_wiki_name_rules();
@@ -1441,11 +1879,11 @@
14411879
** -M|--mimetype TEXT-FORMAT The mime type of the update.
14421880
** Defaults to the type used by
14431881
** the previous version of the
14441882
** page, or text/x-fossil-wiki.
14451883
** Valid values are: text/x-fossil-wiki,
1446
-** text/markdown and text/plain. fossil,
1884
+** text/x-markdown and text/plain. fossil,
14471885
** markdown or plain can be specified as
14481886
** synonyms of these values.
14491887
** -t|--technote DATETIME Specifies the timestamp of
14501888
** the technote to be created or
14511889
** updated. When updating a tech note
14521890
14531891
DELETED src/wysiwyg.c
--- src/wiki.c
+++ src/wiki.c
@@ -102,11 +102,10 @@
102 " WHERE tagid=%d AND mtime<%.16g"
103 " ORDER BY mtime DESC LIMIT 1",
104 tagid, mtime);
105 }
106
107
108 /*
109 ** WEBPAGE: home
110 ** WEBPAGE: index
111 ** WEBPAGE: not_found
112 **
@@ -398,10 +397,24 @@
398 if( sqlite3_strglob("tag/*", zPageName)==0 ){
399 return WIKITYPE_TAG;
400 }
401 return WIKITYPE_NORMAL;
402 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
403
404 /*
405 ** Add an appropriate style_header() for either the /wiki or /wikiedit page
406 ** for zPageName. zExtra is an empty string for /wiki but has the text
407 ** "Edit: " for /wikiedit.
@@ -541,16 +554,11 @@
541 zMimetype = wiki_filter_mimetypes(zMimetype);
542 if( !g.isHome && !noSubmenu ){
543 if( ((rid && g.perm.WrWiki) || (!rid && g.perm.NewWiki))
544 && wiki_special_permission(zPageName)
545 ){
546 if( db_get_boolean("wysiwyg-wiki", 0) ){
547 style_submenu_element("Edit", "%R/wikiedit?name=%T&wysiwyg=1",
548 zPageName);
549 }else{
550 style_submenu_element("Edit", "%R/wikiedit?name=%T", zPageName);
551 }
552 }else if( rid && g.perm.ApndWiki ){
553 style_submenu_element("Edit", "%R/wikiappend?name=%T", zPageName);
554 }
555 if( g.perm.Hyperlink ){
556 style_submenu_element("History", "%R/whistory?name=%T", zPageName);
@@ -620,220 +628,656 @@
620 return azStyles[i+1];
621 }
622 }
623 return azStyles[1];
624 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
625
626 /*
627 ** WEBPAGE: wikiedit
628 ** URL: /wikiedit?name=PAGENAME
 
 
 
 
 
 
629 **
630 ** Edit a wiki page.
 
 
631 */
632 void wikiedit_page(void){
633 char *zTag;
634 int rid = 0;
635 int isSandbox;
636 Blob wiki;
637 Manifest *pWiki = 0;
638 const char *zPageName;
639 int n;
640 const char *z;
641 char *zBody = (char*)P("w");
642 const char *zMimetype = wiki_filter_mimetypes(P("mimetype"));
643 int isWysiwyg = P("wysiwyg")!=0;
644 int goodCaptcha = 1;
645 int eType = WIKITYPE_UNKNOWN;
646 int havePreview = 0;
647
648 if( P("edit-wysiwyg")!=0 ){ isWysiwyg = 1; zBody = 0; }
649 if( P("edit-markup")!=0 ){ isWysiwyg = 0; zBody = 0; }
650 if( zBody ){
651 if( isWysiwyg ){
652 Blob body;
653 blob_zero(&body);
654 htmlTidy(zBody, &body);
655 zBody = blob_str(&body);
656 }else{
657 zBody = mprintf("%s", zBody);
658 }
659 }
660 login_check_credentials();
661 zPageName = PD("name","");
662 if( check_name(zPageName) ) return;
 
 
663 isSandbox = is_sandbox(zPageName);
664 if( isSandbox ){
665 if( !g.perm.WrWiki ){
666 login_needed(g.anon.WrWiki);
667 return;
668 }
669 if( zBody==0 ){
670 zBody = db_get("sandbox","");
671 zMimetype = db_get("sandbox-mimetype","text/x-fossil-wiki");
672 }
673 }else{
674 zTag = mprintf("wiki-%s", zPageName);
675 rid = db_int(0,
676 "SELECT rid FROM tagxref"
677 " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
678 " ORDER BY mtime DESC", zTag
679 );
680 free(zTag);
681 if( !wiki_special_permission(zPageName) ){
682 login_needed(0);
683 return;
684 }
 
685 if( (rid && !g.perm.WrWiki) || (!rid && !g.perm.NewWiki) ){
686 login_needed(rid ? g.anon.WrWiki : g.anon.NewWiki);
687 return;
688 }
689 if( zBody==0 && (pWiki = manifest_get(rid, CFTYPE_WIKI, 0))!=0 ){
690 zBody = pWiki->zWiki;
691 zMimetype = pWiki->zMimetype;
692 }
693 }
694 if( P("submit")!=0 && zBody!=0
695 && (goodCaptcha = captcha_is_correct(0))
696 ){
697 char *zDate;
698 Blob cksum;
699 blob_zero(&wiki);
700 db_begin_transaction();
701 if( isSandbox ){
702 db_set("sandbox",zBody,0);
703 db_set("sandbox-mimetype",zMimetype,0);
704 }else{
705 login_verify_csrf_secret();
706 zDate = date_in_standard_format("now");
707 blob_appendf(&wiki, "D %s\n", zDate);
708 free(zDate);
709 blob_appendf(&wiki, "L %F\n", zPageName);
710 if( fossil_strcmp(zMimetype,"text/x-fossil-wiki")!=0 ){
711 blob_appendf(&wiki, "N %s\n", zMimetype);
712 }
713 if( rid ){
714 char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
715 blob_appendf(&wiki, "P %s\n", zUuid);
716 free(zUuid);
717 }
718 if( !login_is_nobody() ){
719 blob_appendf(&wiki, "U %F\n", login_name());
720 }
721 blob_appendf(&wiki, "W %d\n%s\n", strlen(zBody), zBody);
722 md5sum_blob(&wiki, &cksum);
723 blob_appendf(&wiki, "Z %b\n", &cksum);
724 blob_reset(&cksum);
725 wiki_put(&wiki, 0, wiki_need_moderation(0));
726 }
727 db_end_transaction(0);
728 cgi_redirectf("wiki?name=%T", zPageName);
729 }
730 if( P("cancel")!=0 ){
731 cgi_redirectf("wiki?name=%T", zPageName);
732 return;
733 }
734 if( zBody==0 ){
735 zBody = mprintf("");
736 }
737 style_set_current_page("%T?name=%T", g.zPath, zPageName);
738 eType = wiki_page_header(WIKITYPE_UNKNOWN, zPageName, "Edit: ");
739 if( rid && !isSandbox && g.perm.ApndWiki ){
740 if( g.perm.Attach ){
741 style_submenu_element("Attach",
742 "%s/attachadd?page=%T&from=%s/wiki%%3fname=%T",
743 g.zTop, zPageName, g.zTop, zPageName);
744 }
745 }
746 if( !goodCaptcha ){
747 @ <p class="generalError">Error: Incorrect security code.</p>
748 }
749 blob_zero(&wiki);
750 while( fossil_isspace(zBody[0]) ) zBody++;
751 blob_append(&wiki, zBody, -1);
752 if( P("preview")!=0 ){
753 havePreview = 1;
754 if( zBody[0] ){
755 @ Preview:<hr />
756 safe_html_context(DOCSRC_WIKI);
757 wiki_render_by_mimetype(&wiki, zMimetype);
758 @ <hr />
759 blob_reset(&wiki);
760 }
761 }
762 for(n=2, z=zBody; z[0]; z++){
763 if( z[0]=='\n' ) n++;
764 }
765 if( n<20 ) n = 20;
766 if( n>30 ) n = 30;
767 if( !isWysiwyg ){
768 /* Traditional markup-only editing */
769 char *zPlaceholder = 0;
770 switch( eType ){
771 case WIKITYPE_NORMAL: {
772 zPlaceholder = mprintf("Enter text for wiki page %s", zPageName);
773 break;
774 }
775 case WIKITYPE_BRANCH: {
776 zPlaceholder = mprintf("Enter notes about branch %s", zPageName+7);
777 break;
778 }
779 case WIKITYPE_CHECKIN: {
780 zPlaceholder = mprintf("Enter notes about check-in %.20s", zPageName+8);
781 break;
782 }
783 case WIKITYPE_TAG: {
784 zPlaceholder = mprintf("Enter notes about tag %s", zPageName+4);
785 break;
786 }
787 }
788 form_begin(0, "%R/wikiedit");
789 @ <div>%z(href("%R/markup_help"))Markup style</a>:
790 mimetype_option_menu(zMimetype);
791 @ <br /><textarea name="w" class="wikiedit" cols="80" \
792 @ rows="%d(n)" wrap="virtual" placeholder="%h(zPlaceholder)">\
793 @ %h(zBody)</textarea>
794 @ <br />
795 fossil_free(zPlaceholder);
796 if( db_get_boolean("wysiwyg-wiki", 0) ){
797 @ <input type="submit" name="edit-wysiwyg" value="Wysiwyg Editor"
798 @ onclick='return confirm("Switching to WYSIWYG-mode\nwill erase your markup\nedits. Continue?")' />
799 }
800 @ <input type="submit" name="preview" value="Preview Your Changes" />
801 }else{
802 /* Wysiwyg editing */
803 Blob html, temp;
804 havePreview = 1;
805 form_begin("", "%R/wikiedit");
806 @ <div>
807 @ <input type="hidden" name="wysiwyg" value="1" />
808 blob_zero(&temp);
809 wiki_convert(&wiki, &temp, 0);
810 blob_zero(&html);
811 htmlTidy(blob_str(&temp), &html);
812 blob_reset(&temp);
813 wysiwygEditor("w", blob_str(&html), 60, n);
814 blob_reset(&html);
815 @ <br />
816 @ <input type="submit" name="edit-markup" value="Markup Editor"
817 @ onclick='return confirm("Switching to markup-mode\nwill erase your WYSIWYG\nedits. Continue?")' />
818 }
819 login_insert_csrf_secret();
820 if( havePreview ){
821 if( isWysiwyg || zBody[0] ){
822 @ <input type="submit" name="submit" value="Apply These Changes" />
823 }else{
824 @ <input type="submit" name="submit" value="Delete This Wiki Page" />
825 }
826 }
827 @ <input type="hidden" name="name" value="%h(zPageName)" />
828 @ <input type="submit" name="cancel" value="Cancel"
829 @ onclick='confirm("Abandon your changes?")' />
830 @ </div>
831 captcha_generate(0);
832 @ </form>
833 manifest_destroy(pWiki);
834 blob_reset(&wiki);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
835 style_footer();
836 }
837
838 /*
839 ** WEBPAGE: wikinew
@@ -851,17 +1295,11 @@
851 return;
852 }
853 zName = PD("name","");
854 zMimetype = wiki_filter_mimetypes(P("mimetype"));
855 if( zName[0] && wiki_name_is_wellformed((const unsigned char *)zName) ){
856 if( fossil_strcmp(zMimetype,"text/x-fossil-wiki")==0
857 && db_get_boolean("wysiwyg-wiki", 0)
858 ){
859 cgi_redirectf("wikiedit?name=%T&wysiwyg=1", zName);
860 }else{
861 cgi_redirectf("wikiedit?name=%T&mimetype=%s", zName, zMimetype);
862 }
863 }
864 style_header("Create A New Wiki Page");
865 wiki_standard_submenu(W_ALL_BUT(W_NEW));
866 @ <p>Rules for wiki page names:</p>
867 well_formed_wiki_name_rules();
@@ -1441,11 +1879,11 @@
1441 ** -M|--mimetype TEXT-FORMAT The mime type of the update.
1442 ** Defaults to the type used by
1443 ** the previous version of the
1444 ** page, or text/x-fossil-wiki.
1445 ** Valid values are: text/x-fossil-wiki,
1446 ** text/markdown and text/plain. fossil,
1447 ** markdown or plain can be specified as
1448 ** synonyms of these values.
1449 ** -t|--technote DATETIME Specifies the timestamp of
1450 ** the technote to be created or
1451 ** updated. When updating a tech note
1452
1453 ELETED src/wysiwyg.c
--- src/wiki.c
+++ src/wiki.c
@@ -102,11 +102,10 @@
102 " WHERE tagid=%d AND mtime<%.16g"
103 " ORDER BY mtime DESC LIMIT 1",
104 tagid, mtime);
105 }
106
 
107 /*
108 ** WEBPAGE: home
109 ** WEBPAGE: index
110 ** WEBPAGE: not_found
111 **
@@ -398,10 +397,24 @@
397 if( sqlite3_strglob("tag/*", zPageName)==0 ){
398 return WIKITYPE_TAG;
399 }
400 return WIKITYPE_NORMAL;
401 }
402
403 /*
404 ** Returns a JSON-friendly string form of the integer value returned
405 ** by wiki_page_type(zPageName).
406 */
407 const char * wiki_page_type_name(const char *zPageName){
408 switch(wiki_page_type(zPageName)){
409 case WIKITYPE_CHECKIN: return "checkin";
410 case WIKITYPE_BRANCH: return "branch";
411 case WIKITYPE_TAG: return "tag";
412 case WIKITYPE_NORMAL:
413 default: return "normal";
414 }
415 }
416
417 /*
418 ** Add an appropriate style_header() for either the /wiki or /wikiedit page
419 ** for zPageName. zExtra is an empty string for /wiki but has the text
420 ** "Edit: " for /wikiedit.
@@ -541,16 +554,11 @@
554 zMimetype = wiki_filter_mimetypes(zMimetype);
555 if( !g.isHome && !noSubmenu ){
556 if( ((rid && g.perm.WrWiki) || (!rid && g.perm.NewWiki))
557 && wiki_special_permission(zPageName)
558 ){
559 style_submenu_element("Edit", "%R/wikiedit?name=%T", zPageName);
 
 
 
 
 
560 }else if( rid && g.perm.ApndWiki ){
561 style_submenu_element("Edit", "%R/wikiappend?name=%T", zPageName);
562 }
563 if( g.perm.Hyperlink ){
564 style_submenu_element("History", "%R/whistory?name=%T", zPageName);
@@ -620,220 +628,656 @@
628 return azStyles[i+1];
629 }
630 }
631 return azStyles[1];
632 }
633
634 /*
635 ** Tries to fetch a wiki page for the given name. If found, it
636 ** returns true, else false.
637 **
638 ** versionsBack specifies how many versions back in the history to
639 ** fetch. Use 0 for the latest version, 1 for its parent, etc.
640 **
641 ** If pRid is not NULL then if a result is found *pRid is set to its
642 ** RID. If ppWiki is not NULL then if found *ppWiki is set to the
643 ** loaded wiki object, which the caller is responsible for passing to
644 ** manifest_destroy().
645 */
646 static int wiki_fetch_by_name( const char *zPageName,
647 unsigned int versionsBack,
648 int * pRid, Manifest **ppWiki ){
649 Manifest *pWiki = 0;
650 char *zTag = mprintf("wiki-%s", zPageName);
651 Stmt q = empty_Stmt;
652 int rid = 0;
653
654 db_prepare(&q, "SELECT rid FROM tagxref"
655 " WHERE tagid=(SELECT tagid FROM tag WHERE"
656 " tagname=%Q) "
657 " ORDER BY mtime DESC LIMIT -1 OFFSET %u", zTag,
658 versionsBack);
659 fossil_free(zTag);
660 if(SQLITE_ROW == db_step(&q)){
661 rid = db_column_int(&q, 0);
662 }
663 db_finalize(&q);
664 if( rid == 0 ){
665 return 0;
666 }
667 else if(pRid){
668 *pRid = rid;
669 }
670 if(ppWiki){
671 pWiki = manifest_get(rid, CFTYPE_WIKI, 0);
672 if( pWiki==0 ){
673 /* "Cannot happen." */
674 return 0;
675 }
676 *ppWiki = pWiki;
677 }
678 return 1;
679 }
680
681 /*
682 ** Determines whether the wiki page with the given name can be edited
683 ** or created by the current user. If not, an AJAX error is queued and
684 ** false is returned, else true is returned. A NULL, empty, or
685 ** malformed name is considered non-writable, regardless of the user.
686 **
687 ** If pRid is not NULL then this function writes the page's rid to
688 ** *pRid (whether or not access is granted). On error or if the page
689 ** does not yet exist, *pRid will be set to 0.
690 **
691 ** Note that the sandbox is a special case: it is a pseudo-page with
692 ** no rid and the /wikiajax API does not allow anyone to actually save
693 ** a sandbox page, but it is reported as writable here (with rid 0).
694 */
695 static int wiki_ajax_can_write(const char *zPageName, int * pRid){
696 int rid = 0;
697 const char * zErr = 0;
698
699 if(pRid) *pRid = 0;
700 if(!zPageName || !*zPageName
701 || !wiki_name_is_wellformed((unsigned const char *)zPageName)){
702 zErr = "Invalid page name.";
703 }else if(is_sandbox(zPageName)){
704 return 1;
705 }else{
706 wiki_fetch_by_name(zPageName, 0, &rid, 0);
707 if(pRid) *pRid = rid;
708 if(!wiki_special_permission(zPageName)){
709 zErr = "Editing this page requires non-wiki write permissions.";
710 }else if( (rid && g.perm.WrWiki) || (!rid && g.perm.NewWiki) ){
711 return 3;
712 }else if(rid && !g.perm.WrWiki){
713 zErr = "Requires wiki-write permissions.";
714 }else if(!rid && !g.perm.NewWiki){
715 zErr = "Requires new-wiki permissions.";
716 }else{
717 zErr = "Cannot happen! Please report this as a bug.";
718 }
719 }
720 ajax_route_error(403, "%s", zErr);
721 return 0;
722 }
723
724 /*
725 ** Loads the given wiki page, sets the response type to
726 ** application/json, and emits it as a JSON object. If zPageName is a
727 ** sandbox page then a "fake" object is emitted, as the wikiajax API
728 ** does not permit saving the sandbox.
729 **
730 ** Returns true on success, false on error, and on error it
731 ** queues up a JSON-format error response.
732 **
733 ** Output JSON format:
734 **
735 ** { name: "page name",
736 ** type: "normal" | "tag" | "checkin" | "branch" | "sandbox",
737 ** mimetype: "mime type",
738 ** version: UUID string or null for a sandbox page,
739 ** parent: "parent uuid" or null if no parent,
740 ** content: "page content"
741 ** }
742 **
743 ** If includeContent is false then the content member is elided.
744 */
745 static int wiki_ajax_emit_page_object(const char *zPageName,
746 int includeContent){
747 Manifest * pWiki = 0;
748 char * zUuid;
749
750 cgi_set_content_type("application/json");
751 if( is_sandbox(zPageName) ){
752 char * zMimetype =
753 db_get("sandbox-mimetype","text/x-fossil-wiki");
754 char * zBody = db_get("sandbox","");
755 CX("{\"name\": %!j, \"type\": \"sandbox\", "
756 "\"mimetype\": %!j, \"version\": null, \"parent\": null",
757 zPageName, zMimetype);
758 if(includeContent){
759 CX(", \"content\": %!j",
760 zBody);
761 }
762 CX("}");
763 fossil_free(zMimetype);
764 fossil_free(zBody);
765 return 1;
766 }else if( !wiki_fetch_by_name(zPageName, 0, 0, &pWiki) ){
767 ajax_route_error(404, "Wiki page could not be loaded: %s",
768 zPageName);
769 return 0;
770 }else{
771 zUuid = rid_to_uuid(pWiki->rid);
772 CX("{\"name\": %!j, \"type\": %!j, "
773 "\"version\": %!j, "
774 "\"mimetype\": %!j, ",
775 pWiki->zWikiTitle,
776 wiki_page_type_name(pWiki->zWikiTitle),
777 zUuid,
778 pWiki->zMimetype ? pWiki->zMimetype : "text/x-fossil-wiki");
779 CX("\"parent\": ");
780 if(pWiki->nParent){
781 CX("%!j", pWiki->azParent[0]);
782 }else{
783 CX("null");
784 }
785 if(includeContent){
786 CX(", \"content\": %!j", pWiki->zWiki);
787 }
788 CX("}");
789 fossil_free(zUuid);
790 manifest_destroy(pWiki);
791 return 2;
792 }
793 }
794
795 /*
796 ** Ajax route handler for /wikiajax/save.
797 **
798 ** URL params:
799 **
800 ** page = the wiki page name.
801 ** mimetype = content mime type.
802 ** content = page content. Fossil considers an empty page to
803 ** be "deleted".
804 ** isnew = 1 if the page is to be newly-created, else 0 or
805 ** not send.
806 **
807 ** Responds with JSON. On error, an object in the form documented by
808 ** ajax_route_error(). On success, an object in the form documented
809 ** for wiki_ajax_emit_page_object().
810 **
811 ** The wikiajax API disallows saving of a sandbox pseudo-page, and
812 ** will respond with an error if asked to save one.
813 **
814 ** Reminder: the original implementation implements sandbox-page
815 ** saving using:
816 **
817 ** db_set("sandbox",zBody,0);
818 ** db_set("sandbox-mimetype",zMimetype,0);
819 **
820 */
821 static void wiki_ajax_route_save(void){
822 const char *zPageName = P("page");
823 const char *zMimetype = P("mimetype");
824 const char *zContent = P("content");
825 const int isNew = atoi(PD("isnew","0"))==1;
826 Blob content = empty_blob;
827 int parentRid = 0;
828 int rollback = 0;
829
830 if(!wiki_ajax_can_write(zPageName, &parentRid)){
831 return;
832 }else if(is_sandbox(zPageName)){
833 ajax_route_error(403,"Saving a sandbox page is prohibited.");
834 return;
835 }
836
837 /* These isNew checks are just me being pedantic. The hope is
838 to avoid accidental addition of new pages which differ only
839 by the case of their name. We could just as easily derive
840 isNew based on whether or not the page already exists. */
841 if(isNew){
842 if(parentRid>0){
843 ajax_route_error(403,"Requested a new page, "
844 "but it already exists with RID %d: %s",
845 parentRid, zPageName);
846 return;
847 }
848 }else if(parentRid==0){
849 ajax_route_error(403,"Creating new page [%s] requires passing "
850 "isnew=1.", zPageName);
851 return;
852 }
853
854 blob_init(&content, zContent ? zContent : "", -1);
855 db_begin_transaction();
856 wiki_cmd_commit(zPageName, parentRid, &content, zMimetype, 0);
857 rollback = wiki_ajax_emit_page_object(zPageName, 1) ? 0 : 1;
858 db_end_transaction(rollback);
859 }
860
861 /*
862 ** Ajax route handler for /wikiajax/fetch.
863 **
864 ** URL params:
865 **
866 ** page = the wiki page name
867 **
868 ** Responds with JSON. On error, an object in the form documented by
869 ** ajax_route_error(). On success, an object in the form documented
870 ** for wiki_ajax_emit_page_object().
871 */
872 static void wiki_ajax_route_fetch(void){
873 const char * zPageName = P("page");
874
875 if( zPageName==0 || zPageName[0]==0 ){
876 ajax_route_error(400,"Missing page name.");
877 return;
878 }
879 wiki_ajax_emit_page_object(zPageName, 1);
880 }
881
882 /*
883 ** Ajax route handler for /wikiajax/diff.
884 **
885 ** URL params:
886 **
887 ** page = the wiki page name
888 ** content = the new/edited wiki page content
889 **
890 ** Requires that the user have write access solely to avoid some
891 ** potential abuse cases. It does not actually write anything.
892 */
893 static void wiki_ajax_route_diff(void){
894 const char * zPageName = P("page");
895 Blob contentNew = empty_blob, contentOrig = empty_blob;
896 Manifest * pParent = 0;
897 const char * zContent = P("content");
898 u64 diffFlags = DIFF_HTML | DIFF_NOTTOOBIG | DIFF_STRIP_EOLCR;
899
900 if( zPageName==0 || zPageName[0]==0 ){
901 ajax_route_error(400,"Missing page name.");
902 return;
903 }else if(!wiki_ajax_can_write(zPageName, 0)){
904 return;
905 }
906 switch(atoi(PD("sbs","0"))){
907 case 0: diffFlags |= DIFF_LINENO; break;
908 default: diffFlags |= DIFF_SIDEBYSIDE;
909 }
910 switch(atoi(PD("ws","2"))){
911 case 1: diffFlags |= DIFF_IGNORE_EOLWS; break;
912 case 2: diffFlags |= DIFF_IGNORE_ALLWS; break;
913 default: break;
914 }
915 wiki_fetch_by_name( zPageName, 0, 0, &pParent );
916 if( pParent && pParent->zWiki && *pParent->zWiki ){
917 blob_init(&contentOrig, pParent->zWiki, -1);
918 }else{
919 blob_init(&contentOrig, "", 0);
920 }
921 blob_init(&contentNew, zContent ? zContent : "", -1);
922 cgi_set_content_type("text/html");
923 ajax_render_diff(&contentOrig, &contentNew, diffFlags);
924 blob_reset(&contentNew);
925 blob_reset(&contentOrig);
926 manifest_destroy(pParent);
927 }
928
929 /*
930 ** Ajax route handler for /wikiajax/preview.
931 **
932 ** URL params:
933 **
934 ** page = wiki page name. This is only needed for authorization
935 ** checking.
936 ** mimetype = the wiki page mimetype (determines rendering style)
937 ** content = the wiki page content
938 */
939 static void wiki_ajax_route_preview(void){
940 const char * zPageName = P("page");
941 const char * zContent = P("content");
942
943 if(!wiki_ajax_can_write(zPageName, 0)){
944 return;
945 }else if( zContent==0 ){
946 ajax_route_error(400,"Missing content to preview.");
947 return;
948 }else{
949 Blob content = empty_blob;
950 const char * zMimetype = PD("mimetype","text/x-fossil-wiki");
951
952 blob_init(&content, zContent, -1);
953 cgi_set_content_type("text/html");
954 wiki_render_by_mimetype(&content, zMimetype);
955 blob_reset(&content);
956 }
957 }
958
959 /*
960 ** Ajax route handler for /wikiajax/list.
961 **
962 ** Optional parameters: verbose, includeContent (see below).
963 **
964 ** Responds with JSON. On error, an object in the form documented by
965 ** ajax_route_error().
966 **
967 ** On success, it emits an array of strings (page names) sorted
968 ** case-insensitively. If the "verbose" parameter is passed in then
969 ** the result list contains objects in the format documented for
970 ** wiki_ajax_emit_page_object(). The content of each object is elided
971 ** unless the "includeContent" parameter is passed on.
972 **
973 ** The result list always contains an entry
974 ** named "sandbox" which represents the sandbox pseudo-page.
975 */
976 static void wiki_ajax_route_list(void){
977 Stmt q = empty_Stmt;
978 int n = 0;
979 const int verbose = ajax_p_bool("verbose");
980 const int includeContent = ajax_p_bool("includeContent");
981
982 cgi_set_content_type("application/json");
983 db_begin_transaction();
984 db_prepare(&q, "SELECT"
985 " substr(tagname,6) AS name"
986 " FROM tag WHERE tagname GLOB 'wiki-*'"
987 " UNION SELECT 'Sandbox' AS name"
988 " ORDER BY name COLLATE NOCASE");
989 CX("[");
990 while( SQLITE_ROW==db_step(&q) ){
991 char const * zName = db_column_text(&q,0);
992 if(n++){
993 CX(",");
994 }
995 if(verbose==0){
996 CX("%!j", zName);
997 }else{
998 wiki_ajax_emit_page_object(zName, includeContent);
999 }
1000 }
1001 db_finalize(&q);
1002 db_end_transaction(0);
1003 CX("]");
1004 }
1005
1006
1007 /*
1008 ** WEBPAGE: wikiajax
1009 **
1010 ** An internal dispatcher for wiki AJAX operations. Not for direct
1011 ** client use. All routes defined by this interface are app-internal,
1012 ** subject to change
1013 */
1014 void wiki_ajax_page(void){
1015 const char * zName = P("name");
1016 AjaxRoute routeName = {0,0,0,0};
1017 const AjaxRoute * pRoute = 0;
1018 const AjaxRoute routes[] = {
1019 /* Keep these sorted by zName (for bsearch()) */
1020 {"diff", wiki_ajax_route_diff, 1, 1},
1021 {"fetch", wiki_ajax_route_fetch, 0, 0},
1022 {"list", wiki_ajax_route_list, 0, 0},
1023 {"preview", wiki_ajax_route_preview, 0, 1}
1024 /* preview access mode: whether or not wiki-write mode is needed
1025 really depends on multiple factors. e.g. the sandbox page does
1026 not normally require more than anonymous access. We set its
1027 write-mode to false and do those checks manually in that route's
1028 handler.
1029 */,
1030 {"save", wiki_ajax_route_save, 1, 1}
1031 };
1032
1033 if(zName==0 || zName[0]==0){
1034 ajax_route_error(400,"Missing required [route] 'name' parameter.");
1035 return;
1036 }
1037 routeName.zName = zName;
1038 pRoute = (const AjaxRoute *)bsearch(&routeName, routes,
1039 count(routes), sizeof routes[0],
1040 cmp_ajax_route_name);
1041 if(pRoute==0){
1042 ajax_route_error(404,"Ajax route not found.");
1043 return;
1044 }
1045 login_check_credentials();
1046 if( pRoute->bWriteMode!=0 && g.perm.WrWiki==0 ){
1047 ajax_route_error(403,"Write permissions required.");
1048 return;
1049 }else if(0==cgi_csrf_safe(pRoute->bPost)){
1050 ajax_route_error(403,
1051 "CSRF violation (make sure sending of HTTP "
1052 "Referer headers is enabled for XHR "
1053 "connections).");
1054 return;
1055 }
1056 pRoute->xCallback();
1057 }
1058
1059 /*
1060 ** WEBPAGE: wikiedit
1061 ** URL: /wikedit?name=PAGENAME
1062 **
1063 ** The main front-end for the Ajax-based wiki editor app. Passing
1064 ** in the name of an unknown page will trigger the creation
1065 ** of a new page (which is not actually created in the database
1066 ** until the user explicitly saves it). If passed no page name,
1067 ** the user may select a page from the list on the first UI tab.
1068 **
1069 ** When creating a new page, the mimetype URL parameter may optionally
1070 ** be used to set its mimetype to one of text/x-fossil-wiki,
1071 ** text/x-markdown, or text/plain, defauling to the former.
1072 */
1073 void wikiedit_page(void){
1074 const char *zPageName;
1075 const char * zMimetype = P("mimetype");
1076 int isSandbox;
1077 int found = 0;
1078
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1079 login_check_credentials();
1080 zPageName = PD("name","");
1081 if(zPageName && *zPageName){
1082 if( check_name(zPageName) ) return;
1083 }
1084 isSandbox = is_sandbox(zPageName);
1085 if( isSandbox ){
1086 if( !g.perm.WrWiki ){
1087 login_needed(g.anon.WrWiki);
1088 return;
1089 }
1090 found = 1;
1091 }else if( zPageName!=0 ){
1092 int rid = 0;
 
 
 
 
 
 
 
 
 
1093 if( !wiki_special_permission(zPageName) ){
1094 login_needed(0);
1095 return;
1096 }
1097 found = wiki_fetch_by_name(zPageName, 0, &rid, 0);
1098 if( (rid && !g.perm.WrWiki) || (!rid && !g.perm.NewWiki) ){
1099 login_needed(rid ? g.anon.WrWiki : g.anon.NewWiki);
1100 return;
1101 }
1102 }
1103 style_header("Wiki Editor");
1104
1105 /* Status bar */
1106 CX("<div id='fossil-status-bar' "
1107 "title='Status message area. Double-click to clear them.'>"
1108 "Status messages will go here.</div>\n"
1109 /* will be moved into the tab container via JS */);
1110
1111 CX("<div id='wikiedit-page-name'>Editing: <span>(no file loaded)</span></div>");
1112
1113 /* Main tab container... */
1114 CX("<div id='wikiedit-tabs' class='tab-container'>Loading...</div>");
1115 /* The .hidden class on the following tab elements is to help lessen
1116 the FOUC effect of the tabs before JS re-assembles them. */
1117
1118 /******* Page list *******/
1119 {
1120 CX("<div id='wikiedit-tab-pages' "
1121 "data-tab-parent='wikiedit-tabs' "
1122 "data-tab-label='Wiki Page List' "
1123 "class='hidden'"
1124 ">");
1125 CX("<div>Loading wiki pages list...</div>");
1126 CX("</div>"/*#wikiedit-tab-pages*/);
1127 }
1128
1129 /******* Content tab *******/
1130 {
1131 CX("<div id='wikiedit-tab-content' "
1132 "data-tab-parent='wikiedit-tabs' "
1133 "data-tab-label='Editor' "
1134 "class='hidden'"
1135 ">");
1136 CX("<div class='flex-container flex-row child-gap-small'>");
1137 CX("<span class='input-with-label'>"
1138 "<label>Mime type</label>");
1139 mimetype_option_menu(0);
1140 CX("</span>");
1141 style_select_list_int("select-font-size",
1142 "editor_font_size", "Editor font size",
1143 NULL/*tooltip*/,
1144 100,
1145 "100%", 100, "125%", 125,
1146 "150%", 150, "175%", 175,
1147 "200%", 200, NULL);
1148 CX("<button class='wikiedit-content-reload' "
1149 "title='Reload the file from the server, discarding "
1150 "any local edits. To help avoid accidental loss of "
1151 "edits, it requires confirmation (a second click) within "
1152 "a few seconds or it will not reload.'"
1153 ">Discard &amp; Reload</button>");
1154 CX("<button class='wikiedit-save' disabled='disabled'>"
1155 "Save</button>"/*will get moved around dynamically*/);
1156 CX("<span class='save-button-slot'></span>");
1157 CX("</div>");
1158 CX("<div class='flex-container flex-column stretch'>");
1159 CX("<textarea name='content' id='wikiedit-content-editor' "
1160 "class='wikiedit' "
1161 "rows='25' cols='80'>");
1162 CX("</textarea>");
1163 CX("</div>"/*textarea wrapper*/);
1164 CX("</div>"/*#tab-file-content*/);
1165 }
1166 /****** Preview tab ******/
1167 {
1168 CX("<div id='wikiedit-tab-preview' "
1169 "data-tab-parent='wikiedit-tabs' "
1170 "data-tab-label='Preview' "
1171 "class='hidden'"
1172 ">");
1173 CX("<div class='wikiedit-options flex-container flex-row'>");
1174 CX("<button id='btn-preview-refresh' "
1175 "data-f-preview-from='wikiContent' "
1176 /* ^^^ fossil.page[methodName]() OR text source elem ID,
1177 ** but we need a method in order to support clients swapping out
1178 ** the text editor with their own. */
1179 "data-f-preview-via='_postPreview' "
1180 /* ^^^ fossil.page[methodName](content, callback) */
1181 "data-f-preview-to='#wikiedit-tab-preview-wrapper' "
1182 /* ^^^ dest elem ID */
1183 ">Refresh</button>");
1184 /* Toggle auto-update of preview when the Preview tab is selected. */
1185 style_labeled_checkbox("cb-preview-autoupdate",
1186 NULL,
1187 "Auto-refresh?",
1188 "1", 1,
1189 "If on, the preview will automatically "
1190 "refresh when this tab is selected.");
1191 CX("<span class='save-button-slot'></span>");
1192 CX("</div>"/*.wikiedit-options*/);
1193 CX("<div id='wikiedit-tab-preview-wrapper'></div>");
1194 CX("</div>"/*#wikiedit-tab-preview*/);
1195 }
1196
1197 /****** Diff tab ******/
1198 {
1199 CX("<div id='wikiedit-tab-diff' "
1200 "data-tab-parent='wikiedit-tabs' "
1201 "data-tab-label='Diff' "
1202 "class='hidden'"
1203 ">");
1204
1205 CX("<div class='wikiedit-options flex-container flex-row' "
1206 "id='wikiedit-tab-diff-buttons'>");
1207 CX("<button class='sbs'>Side-by-side</button>"
1208 "<button class='unified'>Unified</button>");
1209 CX("<span class='save-button-slot'></span>");
1210 CX("</div>");
1211 CX("<div id='wikiedit-tab-diff-wrapper'>"
1212 "Diffs will be shown here."
1213 "</div>");
1214 CX("</div>"/*#wikiedit-tab-diff*/);
1215 }
1216
1217 /****** The obligatory "Misc" tab ******/
1218 {
1219 CX("<div id='wikiedit-tab-misc' "
1220 "data-tab-parent='wikiedit-tabs' "
1221 "data-tab-label='Help, Attachments, etc.' "
1222 "class='hidden'"
1223 ">");
1224 CX("<h3>Wiki formatting rules</h3>");
1225 CX("<ul>");
1226 CX("<li><a href='%R/wiki_rules'>Fossil wiki format</a></li>");
1227 CX("<li><a href='%R/md_rules'>Markdown format</a></li>");
1228 CX("<li>Plain-text pages use no special formatting.</li>");
1229 CX("</ul>");
1230 CX("<hr><h3>Attachments</h3>");
1231 CX("<div id='wikiedit-attachments'></div>"
1232 /* Filled out by JS */);
1233 CX("<hr><h3>The \"Sandbox\" Page</h3>");
1234 CX("<p>The page named \"Sandbox\" is not a real wiki page. "
1235 "It provides a place where users may test out wiki syntax "
1236 "without having to actually save anything, nor pollute "
1237 "the repo with endless test runs. Any attempt to save the "
1238 "sandbox page will fail.</p>");
1239 CX("<hr><h3>Wiki Name Rules</h3>");
1240 well_formed_wiki_name_rules();
1241 CX("</div>"/*#wikiedit-tab-save*/);
1242 }
1243
1244 builtin_request_js("sbsdiff.js");
1245 style_emit_fossil_js_apis(0, "fetch", "dom", "tabs", "confirmer",
1246 "storage", "page.wikiedit", 0);
1247 builtin_fulfill_js_requests();
1248 /* Dynamically populate the editor... */
1249 style_emit_script_tag(0,0);
1250 CX("\nfossil.onPageLoad(function(){\n");
1251 CX("const P = fossil.page;\n"
1252 "try{\n");
1253 if(!found && zPageName && *zPageName){
1254 /* For a new page, stick a dummy entry in the JS-side stash
1255 and "load" it from there. */
1256 CX("const winfo = {"
1257 "\"name\": %!j, \"mimetype\": %!j, "
1258 "\"type\": %!j, "
1259 "\"parent\": null, \"version\": null"
1260 "};\n",
1261 zPageName,
1262 zMimetype ? zMimetype : "text/x-fossil-wiki",
1263 wiki_page_type_name(zPageName));
1264 /* If the JS-side stash already has this page, load that
1265 copy from the stash, otherwise inject a new stash entry
1266 for it and load *that* one... */
1267 CX("if(!P.$stash.getWinfo(winfo)){"
1268 "P.$stash.updateWinfo(winfo,'');"
1269 "}\n");
1270 }
1271 if(zPageName && *zPageName){
1272 CX("P.loadPage(%!j);\n", zPageName);
1273 }
1274 CX("}catch(e){"
1275 "fossil.error(e); console.error('Exception:',e);"
1276 "}\n");
1277 CX("});\n"/*fossil.onPageLoad()*/);
1278 style_emit_script_tag(1,0);
1279 style_footer();
1280 }
1281
1282 /*
1283 ** WEBPAGE: wikinew
@@ -851,17 +1295,11 @@
1295 return;
1296 }
1297 zName = PD("name","");
1298 zMimetype = wiki_filter_mimetypes(P("mimetype"));
1299 if( zName[0] && wiki_name_is_wellformed((const unsigned char *)zName) ){
1300 cgi_redirectf("wikiedit?name=%T&mimetype=%s", zName, zMimetype);
 
 
 
 
 
 
1301 }
1302 style_header("Create A New Wiki Page");
1303 wiki_standard_submenu(W_ALL_BUT(W_NEW));
1304 @ <p>Rules for wiki page names:</p>
1305 well_formed_wiki_name_rules();
@@ -1441,11 +1879,11 @@
1879 ** -M|--mimetype TEXT-FORMAT The mime type of the update.
1880 ** Defaults to the type used by
1881 ** the previous version of the
1882 ** page, or text/x-fossil-wiki.
1883 ** Valid values are: text/x-fossil-wiki,
1884 ** text/x-markdown and text/plain. fossil,
1885 ** markdown or plain can be specified as
1886 ** synonyms of these values.
1887 ** -t|--technote DATETIME Specifies the timestamp of
1888 ** the technote to be created or
1889 ** updated. When updating a tech note
1890
1891 ELETED src/wysiwyg.c
D src/wysiwyg.c
-328
--- a/src/wysiwyg.c
+++ b/src/wysiwyg.c
@@ -1,328 +0,0 @@
1
-/*
2
-** Copyright (c) 2012 D. Richard Hipp
3
-**
4
-** This program is free software; you can redistribute it and/or
5
-** modify it under the terms of the Simplified BSD License (also
6
-** known as the "2-Clause License" or "FreeBSD License".)
7
-**
8
-** This program is distributed in the hope that it will be useful,
9
-** but without any warranty; without even the implied warranty of
10
-** merchantability or fitness for a particular purpose.
11
-**
12
-** Author contact information:
13
-** [email protected]
14
-** http://www.hwaci.com/drh/
15
-**
16
-*******************************************************************************
17
-**
18
-** This file contains code that generates WYSIWYG text editors on
19
-** web pages.
20
-*/
21
-#include "config.h"
22
-#include <assert.h>
23
-#include <ctype.h>
24
-#include "wysiwyg.h"
25
-
26
-
27
-/*
28
-** Output code for a WYSIWYG editor. The caller must have already generated
29
-** the <form> that will contain the editor, and the call must generate the
30
-** corresponding </form> after this routine returns. The caller must include
31
-** an onsubmit= attribute on the <form> element that invokes the
32
-** wysiwygSubmit() function.
33
-**
34
-** There can only be a single WYSIWYG editor per frame.
35
-*/
36
-void wysiwygEditor(
37
- const char *zId, /* ID for this editor */
38
- const char *zContent, /* Initial content (HTML) */
39
- int w, int h /* Initial width and height */
40
-){
41
-
42
- @ <style type="text/css">
43
- @ .intLink { cursor: pointer; }
44
- @ img.intLink { border: 0; }
45
- @ #wysiwygBox {
46
- @ border: 1px #000000 solid;
47
- @ padding: 12px;
48
- @ }
49
- @ #editMode label { cursor: pointer; }
50
- @ </style>
51
-
52
- @ <input id="wysiwygValue" type="hidden" name="%s(zId)">
53
- @ <div id="editModeDiv">Edit mode:
54
- @ <select id="editMode" size=1>
55
- @ <option value="0">WYSIWYG</option>
56
- @ <option value="1">Raw HTML</option>
57
- @ </select></div>
58
- @ <div id="toolBar1">
59
- @ <select class="format" data-format="formatblock">
60
- @ <option selected>- formatting -</option>
61
- @ <option value="h1">Title 1 &lt;h1&gt;</option>
62
- @ <option value="h2">Title 2 &lt;h2&gt;</option>
63
- @ <option value="h3">Title 3 &lt;h3&gt;</option>
64
- @ <option value="h4">Title 4 &lt;h4&gt;</option>
65
- @ <option value="h5">Title 5 &lt;h5&gt;</option>
66
- @ <option value="h6">Subtitle &lt;h6&gt;</option>
67
- @ <option value="p">Paragraph &lt;p&gt;</option>
68
- @ <option value="pre">Preformatted &lt;pre&gt;</option>
69
- @ </select>
70
- @ <select class="format" data-format="fontname">
71
- @ <option class="heading" selected>- font -</option>
72
- @ <option>Arial</option>
73
- @ <option>Arial Black</option>
74
- @ <option>Courier New</option>
75
- @ <option>Times New Roman</option>
76
- @ </select>
77
- @ <select class="format" data-format="fontsize">
78
- @ <option class="heading" selected>- size -</option>
79
- @ <option value="1">Very small</option>
80
- @ <option value="2">A bit small</option>
81
- @ <option value="3">Normal</option>
82
- @ <option value="4">Medium-large</option>
83
- @ <option value="5">Big</option>
84
- @ <option value="6">Very big</option>
85
- @ <option value="7">Maximum</option>
86
- @ </select>
87
- @ <select class="format" data-format="forecolor">
88
- @ <option class="heading" selected>- color -</option>
89
- @ <option value="red">Red</option>
90
- @ <option value="blue">Blue</option>
91
- @ <option value="green">Green</option>
92
- @ <option value="black">Black</option>
93
- @ </select>
94
- @ </div>
95
- @ <div id="toolBar2">
96
- @ <img class="intLink" title="Undo" data-format="undo"
97
- @ src="data:image/gif;base64,R0lGODlhFgAWAOMKADljwliE33mOrpGjuYKl8aezxqPD+7
98
- @ /I19DV3NHa7P///////////////////////yH5BAEKAA8ALAAAAAAWABYAAARR8MlJq704680
99
- @ 7TkaYeJJBnES4EeUJvIGapWYAC0CsocQ7SDlWJkAkCA6ToMYWIARGQF3mRQVIEjkkSVLIbSfE
100
- @ whdRIH4fh/DZMICe3/C4nBQBADs=">
101
-
102
- @ <img class="intLink" title="Redo" data-format="redo"
103
- @ src="data:image/gif;base64,R0lGODlhFgAWAMIHAB1ChDljwl9vj1iE34Kl8aPD+7/I1/
104
- @ ///yH5BAEKAAcALAAAAAAWABYAAANKeLrc/jDKSesyphi7SiEgsVXZEATDICqBVJjpqWZt9Na
105
- @ EDNbQK1wCQsxlYnxMAImhyDoFAElJasRRvAZVRqqQXUy7Cgx4TC6bswkAOw==">
106
-
107
- @ <img class="intLink" title="Remove formatting" data-format="removeFormat"
108
- @ src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AA
109
- @ AABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAOxAAADsQBlSsOGwA
110
- @ AAAd0SU1FB9oECQMCKPI8CIIAAAAIdEVYdENvbW1lbnQA9syWvwAAAuhJREFUOMtjYBgFxAB5
111
- @ 01ZWBvVaL2nHnlmk6mXCJbF69zU+Hz/9fB5O1lx+bg45qhl8/fYr5it3XrP/YWTUvvvk3VeqG
112
- @ Xz70TvbJy8+Wv39+2/Hz19/mGwjZzuTYjALuoBv9jImaXHeyD3H7kU8fPj2ICML8z92dlbtMz
113
- @ deiG3fco7J08foH1kurkm3E9iw54YvKwuTuom+LPt/BgbWf3//sf37/1/c02cCG1lB8f//f95
114
- @ DZx74MTMzshhoSm6szrQ/a6Ir/Z2RkfEjBxuLYFpDiDi6Af///2ckaHBp7+7wmavP5n76+P2C
115
- @ lrLIYl8H9W36auJCbCxM4szMTJac7Kza////R3H1w2cfWAgafPbqs5g7D95++/P1B4+ECK8tA
116
- @ wMDw/1H7159+/7r7ZcvPz4fOHbzEwMDwx8GBgaGnNatfHZx8zqrJ+4VJBh5CQEGOySEua/v3n
117
- @ 7hXmqI8WUGBgYGL3vVG7fuPK3i5GD9/fja7ZsMDAzMG/Ze52mZeSj4yu1XEq/ff7W5dvfVAS1
118
- @ lsXc4Db7z8C3r8p7Qjf///2dnZGxlqJuyr3rPqQd/Hhyu7oSpYWScylDQsd3kzvnH738wMDzj
119
- @ 5GBN1VIWW4c3KDon7VOvm7S3paB9u5qsU5/x5KUnlY+eexQbkLNsErK61+++VnAJcfkyMTIwf
120
- @ fj0QwZbJDKjcETs1Y8evyd48toz8y/ffzv//vPP4veffxpX77z6l5JewHPu8MqTDAwMDLzyrj
121
- @ b/mZm0JcT5Lj+89+Ybm6zz95oMh7s4XbygN3Sluq4Mj5K8iKMgP4f0////fv77//8nLy+7MCc
122
- @ XmyYDAwODS9jM9tcvPypd35pne3ljdjvj26+H2dhYpuENikgfvQeXNmSl3tqepxXsqhXPyc66
123
- @ 6s+fv1fMdKR3TK72zpix8nTc7bdfhfkEeVbC9KhbK/9iYWHiErbu6MWbY/7//8/4//9/pgOnH
124
- @ 6jGVazvFDRtq2VgiBIZrUTIBgCk+ivHvuEKwAAAAABJRU5ErkJggg==">
125
-
126
- @ <img class="intLink" title="Bold" data-format="bold"
127
- @ src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB
128
- @ YAQAInhI+pa+H9mJy0LhdgtrxzDG5WGFVk6aXqyk6Y9kXvKKNuLbb6zgMFADs=" />
129
-
130
- @ <img class="intLink" title="Italic" data-format="italic"
131
- @ src="data:image/gif;base64,R0lGODlhFgAWAKEDAAAAAF9vj5WIbf///yH5BAEAAAMALA
132
- @ AAAAAWABYAAAIjnI+py+0Po5x0gXvruEKHrF2BB1YiCWgbMFIYpsbyTNd2UwAAOw==" />
133
-
134
- @ <img class="intLink" title="Underline" data-format="underline"
135
- @ src="data:image/gif;base64,R0lGODlhFgAWAKECAAAAAF9vj////////yH5BAEAAAIALA
136
- @ AAAAAWABYAAAIrlI+py+0Po5zUgAsEzvEeL4Ea15EiJJ5PSqJmuwKBEKgxVuXWtun+DwxCCgA
137
- @ 7" />
138
-
139
- @ <img class="intLink" title="Left align" data-format="justifyleft"
140
- @ src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB
141
- @ YAQAIghI+py+0Po5y02ouz3jL4D4JMGELkGYxo+qzl4nKyXAAAOw==" />
142
-
143
- @ <img class="intLink" title="Center align" data-format="justifycenter"
144
- @ src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB
145
- @ YAQAIfhI+py+0Po5y02ouz3jL4D4JOGI7kaZ5Bqn4sycVbAQA7" />
146
-
147
- @ <img class="intLink" title="Right align" data-format="justifyright"
148
- @ src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB
149
- @ YAQAIghI+py+0Po5y02ouz3jL4D4JQGDLkGYxouqzl43JyVgAAOw==" />
150
- @ <img class="intLink" title="Numbered list"
151
- @ data-format="insertorderedlist"
152
- @ src="data:image/gif;base64,R0lGODlhFgAWAMIGAAAAADljwliE35GjuaezxtHa7P////
153
- @ ///yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKSespwjoRFvggCBUBoTFBeq6QIAysQnRHaEO
154
- @ zyaZ07Lu9lUBnC0UGQU1K52s6n5oEADs=" />
155
-
156
- @ <img class="intLink" title="Dotted list"
157
- @ data-format="insertunorderedlist"
158
- @ src="data:image/gif;base64,R0lGODlhFgAWAMIGAAAAAB1ChF9vj1iE33mOrqezxv////
159
- @ ///yH5BAEAAAcALAAAAAAWABYAAAMyeLrc/jDKSesppNhGRlBAKIZRERBbqm6YtnbfMY7lud6
160
- @ 4UwiuKnigGQliQuWOyKQykgAAOw==" />
161
-
162
- @ <img class="intLink" title="Quote" data-format="formatblock"
163
- @ src="data:image/gif;base64,R0lGODlhFgAWAIQXAC1NqjFRjkBgmT9nqUJnsk9xrFJ7u2
164
- @ R9qmKBt1iGzHmOrm6Sz4OXw3Odz4Cl2ZSnw6KxyqO306K63bG70bTB0rDI3bvI4P/////////
165
- @ //////////////////////////yH5BAEKAB8ALAAAAAAWABYAAAVP4CeOZGmeaKqubEs2Cekk
166
- @ ErvEI1zZuOgYFlakECEZFi0GgTGKEBATFmJAVXweVOoKEQgABB9IQDCmrLpjETrQQlhHjINrT
167
- @ q/b7/i8fp8PAQA7" />
168
-
169
- @ <img class="intLink" title="Delete indentation" data-format="outdent"
170
- @ src="data:image/gif;base64,R0lGODlhFgAWAMIHAAAAADljwliE35GjuaezxtDV3NHa7P
171
- @ ///yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKCQG9F2i7u8agQgyK1z2EIBil+TWqEMxhMcz
172
- @ sYVJ3e4ahk+sFnAgtxSQDqWw6n5cEADs=" />
173
-
174
- @ <img class="intLink" title="Add indentation" data-format="indent"
175
- @ src="data:image/gif;base64,R0lGODlhFgAWAOMIAAAAADljwl9vj1iE35GjuaezxtDV3N
176
- @ Ha7P///////////////////////////////yH5BAEAAAgALAAAAAAWABYAAAQ7EMlJq704650
177
- @ B/x8gemMpgugwHJNZXodKsO5oqUOgo5KhBwWESyMQsCRDHu9VOyk5TM9zSpFSr9gsJwIAOw==">
178
-
179
- @ <img class="intLink" title="Hyperlink" data-format="createlink"
180
- @ src="data:image/gif;base64,R0lGODlhFgAWAOMKAB1ChDRLY19vj3mOrpGjuaezxrCztb
181
- @ /I19Ha7Pv8/f///////////////////////yH5BAEKAA8ALAAAAAAWABYAAARY8MlJq704682
182
- @ 7/2BYIQVhHg9pEgVGIklyDEUBy/RlE4FQF4dCj2AQXAiJQDCWQCAEBwIioEMQBgSAFhDAGghG
183
- @ i9XgHAhMNoSZgJkJei33UESv2+/4vD4TAQA7" />
184
-
185
-#if 0 /* Cut/Copy/Paste requires special browser permissions for security
186
- ** reasons. So omit these buttons */
187
- @ <img class="intLink" title="Cut" data-format="cut"
188
- @ src="data:image/gif;base64,R0lGODlhFgAWAIQSAB1ChBFNsRJTySJYwjljwkxwl19vj1
189
- @ dusYODhl6MnHmOrpqbmpGjuaezxrCztcDCxL/I18rL1P/////////////////////////////
190
- @ //////////////////////////yH5BAEAAB8ALAAAAAAWABYAAAVu4CeOZGmeaKqubDs6TNnE
191
- @ bGNApNG0kbGMi5trwcA9GArXh+FAfBAw5UexUDAQESkRsfhJPwaH4YsEGAAJGisRGAQY7UCC9
192
- @ ZAXBB+74LGCRxIEHwAHdWooDgGJcwpxDisQBQRjIgkDCVlfmZqbmiEAOw==" />
193
-
194
- @ <img class="intLink" title="Copy" data-format="copy"
195
- @ src="data:image/gif;base64,R0lGODlhFgAWAIQcAB1ChBFNsTRLYyJYwjljwl9vj1iE31
196
- @ iGzF6MnHWX9HOdz5GjuYCl2YKl8ZOt4qezxqK63aK/9KPD+7DI3b/I17LM/MrL1MLY9NHa7OP
197
- @ s++bx/Pv8/f///////////////yH5BAEAAB8ALAAAAAAWABYAAAWG4CeOZGmeaKqubOum1SQ/
198
- @ kPVOW749BeVSus2CgrCxHptLBbOQxCSNCCaF1GUqwQbBd0JGJAyGJJiobE+LnCaDcXAaEoxhQ
199
- @ ACgNw0FQx9kP+wmaRgYFBQNeAoGihCAJQsCkJAKOhgXEw8BLQYciooHf5o7EA+kC40qBKkAAA
200
- @ Grpy+wsbKzIiEAOw==" />
201
-
202
- @ <img class="intLink" title="Paste" data-format="paste"
203
- @ src="data:image/gif;base64,R0lGODlhFgAWAIQUAD04KTRLY2tXQF9vj414WZWIbXmOrp
204
- @ qbmpGjudClFaezxsa0cb/I1+3YitHa7PrkIPHvbuPs+/fvrvv8/f/////////////////////
205
- @ //////////////////////////yH5BAEAAB8ALAAAAAAWABYAAAWN4CeOZGmeaKqubGsusPvB
206
- @ SyFJjVDs6nJLB0khR4AkBCmfsCGBQAoCwjF5gwquVykSFbwZE+AwIBV0GhFog2EwIDchjwRiQ
207
- @ o9E2Fx4XD5R+B0DDAEnBXBhBhN2DgwDAQFjJYVhCQYRfgoIDGiQJAWTCQMRiwwMfgicnVcAAA
208
- @ MOaK+bLAOrtLUyt7i5uiUhADs=" />
209
-#endif
210
-
211
- @ </div>
212
- @ <div id="wysiwygBox"
213
- @ style="resize:both;overflow:auto;width:95%%;min-height:%d(h)em;"
214
- @ contenteditable="true">%s(zContent)</div>
215
- @ <script nonce="%h(style_nonce())">
216
- @ var oDoc;
217
- @
218
- @ /* Initialize the document editor */
219
- @ function initDoc() {
220
- @ initEventHandlers();
221
- @ oDoc = document.getElementById("wysiwygBox");
222
- @ if (!isWysiwyg()) { setDocMode(true); }
223
- @ }
224
- @
225
- @ function initEventHandlers() {
226
- @ document.querySelector('form').onsubmit = wysiwygSubmit;
227
- @ document.querySelector('#editMode').onchange = function() {
228
- @ setDocMode(this.selectedIndex)
229
- @ };
230
- @ var controls = document.querySelectorAll('select.format');
231
- @ for(var i = 0; i < controls.length; i++) {
232
- @ controls[i].onchange = handleDropDown;
233
- @ }
234
- @ controls = document.querySelectorAll('.intLink');
235
- @ for(i = 0; i < controls.length; i++) {
236
- @ controls[i].onclick = handleFormatButton;
237
- @ }
238
- @
239
- @ function handleDropDown() {
240
- @ formatDoc(this.dataset.format,this[this.selectedIndex].value);
241
- @ this.selectedIndex = 0;
242
- @ }
243
- @
244
- @ function handleFormatButton() {
245
- @ var extra;
246
- @ switch (this.dataset.format) {
247
- @ case 'createlink':
248
- @ var sLnk = prompt('Target URL:','');
249
- @ if(sLnk && sLnk != '')
250
- @ {
251
- @ extra = sLnk;
252
- @ }
253
- @ break;
254
- @ case 'formatblock':
255
- @ extra = 'blockquote';
256
- @ break;
257
- @ }
258
- @ formatDoc(this.dataset.format, extra);
259
- @ }
260
- @ }
261
- @
262
- @ /* Return true if the document editor is in WYSIWYG mode. Return
263
- @ ** false if it is in Markup mode */
264
- @ function isWysiwyg() {
265
- @ return document.getElementById("editMode").selectedIndex==0;
266
- @ }
267
- @
268
- @ /* Invoke this routine prior to submitting the HTML content back
269
- @ ** to the server */
270
- @ function wysiwygSubmit() {
271
- @ if(oDoc.style.whiteSpace=="pre-wrap"){setDocMode(0);}
272
- @ document.getElementById("wysiwygValue").value=oDoc.innerHTML;
273
- @ }
274
- @
275
- @ /* Run the editing command if in WYSIWYG mode */
276
- @ function formatDoc(sCmd, sValue) {
277
- @ if (isWysiwyg()){
278
- @ try {
279
- @ // First, try the W3C draft standard way, which has
280
- @ // been working on all non-IE browsers for a while.
281
- @ // It is also supported by IE11 and higher.
282
- @ document.execCommand("styleWithCSS", false, false);
283
- @ } catch (e) {
284
- @ try {
285
- @ // For IE9 or IE10, this should work.
286
- @ document.execCommand("useCSS", 0, true);
287
- @ } catch (e) {
288
- @ // OK, that apparently did not work, do nothing.
289
- @ }
290
- @ }
291
- @ document.execCommand(sCmd, false, sValue);
292
- @ oDoc.focus();
293
- @ }
294
- @ }
295
- @
296
- @ /* Change the editing mode. Convert to markup if the argument
297
- @ ** is true and wysiwyg if the argument is false. */
298
- @ function setDocMode(bToMarkup) {
299
- @ var oContent;
300
- @ if (bToMarkup) {
301
- @ /* WYSIWYG -> Markup */
302
- @ var linebreak = new RegExp("</p><p>","ig");
303
- @ oContent = document.createTextNode(
304
- @ oDoc.innerHTML.replace(linebreak,"</p>\n\n<p>"));
305
- @ oDoc.innerHTML = "";
306
- @ oDoc.style.whiteSpace = "pre-wrap";
307
- @ oDoc.appendChild(oContent);
308
- @ document.getElementById("toolBar1").style.visibility="hidden";
309
- @ document.getElementById("toolBar2").style.visibility="hidden";
310
- @ } else {
311
- @ /* Markup -> WYSIWYG */
312
- @ if (document.all) {
313
- @ oDoc.innerHTML = oDoc.innerText;
314
- @ } else {
315
- @ oContent = document.createRange();
316
- @ oContent.selectNodeContents(oDoc.firstChild);
317
- @ oDoc.innerHTML = oContent.toString();
318
- @ }
319
- @ oDoc.style.whiteSpace = "normal";
320
- @ document.getElementById("toolBar1").style.visibility="visible";
321
- @ document.getElementById("toolBar2").style.visibility="visible";
322
- @ }
323
- @ oDoc.focus();
324
- @ }
325
- @ initDoc();
326
- @ </script>
327
-
328
-}
--- a/src/wysiwyg.c
+++ b/src/wysiwyg.c
@@ -1,328 +0,0 @@
1 /*
2 ** Copyright (c) 2012 D. Richard Hipp
3 **
4 ** This program is free software; you can redistribute it and/or
5 ** modify it under the terms of the Simplified BSD License (also
6 ** known as the "2-Clause License" or "FreeBSD License".)
7 **
8 ** This program is distributed in the hope that it will be useful,
9 ** but without any warranty; without even the implied warranty of
10 ** merchantability or fitness for a particular purpose.
11 **
12 ** Author contact information:
13 ** [email protected]
14 ** http://www.hwaci.com/drh/
15 **
16 *******************************************************************************
17 **
18 ** This file contains code that generates WYSIWYG text editors on
19 ** web pages.
20 */
21 #include "config.h"
22 #include <assert.h>
23 #include <ctype.h>
24 #include "wysiwyg.h"
25
26
27 /*
28 ** Output code for a WYSIWYG editor. The caller must have already generated
29 ** the <form> that will contain the editor, and the call must generate the
30 ** corresponding </form> after this routine returns. The caller must include
31 ** an onsubmit= attribute on the <form> element that invokes the
32 ** wysiwygSubmit() function.
33 **
34 ** There can only be a single WYSIWYG editor per frame.
35 */
36 void wysiwygEditor(
37 const char *zId, /* ID for this editor */
38 const char *zContent, /* Initial content (HTML) */
39 int w, int h /* Initial width and height */
40 ){
41
42 @ <style type="text/css">
43 @ .intLink { cursor: pointer; }
44 @ img.intLink { border: 0; }
45 @ #wysiwygBox {
46 @ border: 1px #000000 solid;
47 @ padding: 12px;
48 @ }
49 @ #editMode label { cursor: pointer; }
50 @ </style>
51
52 @ <input id="wysiwygValue" type="hidden" name="%s(zId)">
53 @ <div id="editModeDiv">Edit mode:
54 @ <select id="editMode" size=1>
55 @ <option value="0">WYSIWYG</option>
56 @ <option value="1">Raw HTML</option>
57 @ </select></div>
58 @ <div id="toolBar1">
59 @ <select class="format" data-format="formatblock">
60 @ <option selected>- formatting -</option>
61 @ <option value="h1">Title 1 &lt;h1&gt;</option>
62 @ <option value="h2">Title 2 &lt;h2&gt;</option>
63 @ <option value="h3">Title 3 &lt;h3&gt;</option>
64 @ <option value="h4">Title 4 &lt;h4&gt;</option>
65 @ <option value="h5">Title 5 &lt;h5&gt;</option>
66 @ <option value="h6">Subtitle &lt;h6&gt;</option>
67 @ <option value="p">Paragraph &lt;p&gt;</option>
68 @ <option value="pre">Preformatted &lt;pre&gt;</option>
69 @ </select>
70 @ <select class="format" data-format="fontname">
71 @ <option class="heading" selected>- font -</option>
72 @ <option>Arial</option>
73 @ <option>Arial Black</option>
74 @ <option>Courier New</option>
75 @ <option>Times New Roman</option>
76 @ </select>
77 @ <select class="format" data-format="fontsize">
78 @ <option class="heading" selected>- size -</option>
79 @ <option value="1">Very small</option>
80 @ <option value="2">A bit small</option>
81 @ <option value="3">Normal</option>
82 @ <option value="4">Medium-large</option>
83 @ <option value="5">Big</option>
84 @ <option value="6">Very big</option>
85 @ <option value="7">Maximum</option>
86 @ </select>
87 @ <select class="format" data-format="forecolor">
88 @ <option class="heading" selected>- color -</option>
89 @ <option value="red">Red</option>
90 @ <option value="blue">Blue</option>
91 @ <option value="green">Green</option>
92 @ <option value="black">Black</option>
93 @ </select>
94 @ </div>
95 @ <div id="toolBar2">
96 @ <img class="intLink" title="Undo" data-format="undo"
97 @ src="data:image/gif;base64,R0lGODlhFgAWAOMKADljwliE33mOrpGjuYKl8aezxqPD+7
98 @ /I19DV3NHa7P///////////////////////yH5BAEKAA8ALAAAAAAWABYAAARR8MlJq704680
99 @ 7TkaYeJJBnES4EeUJvIGapWYAC0CsocQ7SDlWJkAkCA6ToMYWIARGQF3mRQVIEjkkSVLIbSfE
100 @ whdRIH4fh/DZMICe3/C4nBQBADs=">
101
102 @ <img class="intLink" title="Redo" data-format="redo"
103 @ src="data:image/gif;base64,R0lGODlhFgAWAMIHAB1ChDljwl9vj1iE34Kl8aPD+7/I1/
104 @ ///yH5BAEKAAcALAAAAAAWABYAAANKeLrc/jDKSesyphi7SiEgsVXZEATDICqBVJjpqWZt9Na
105 @ EDNbQK1wCQsxlYnxMAImhyDoFAElJasRRvAZVRqqQXUy7Cgx4TC6bswkAOw==">
106
107 @ <img class="intLink" title="Remove formatting" data-format="removeFormat"
108 @ src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AA
109 @ AABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAOxAAADsQBlSsOGwA
110 @ AAAd0SU1FB9oECQMCKPI8CIIAAAAIdEVYdENvbW1lbnQA9syWvwAAAuhJREFUOMtjYBgFxAB5
111 @ 01ZWBvVaL2nHnlmk6mXCJbF69zU+Hz/9fB5O1lx+bg45qhl8/fYr5it3XrP/YWTUvvvk3VeqG
112 @ Xz70TvbJy8+Wv39+2/Hz19/mGwjZzuTYjALuoBv9jImaXHeyD3H7kU8fPj2ICML8z92dlbtMz
113 @ deiG3fco7J08foH1kurkm3E9iw54YvKwuTuom+LPt/BgbWf3//sf37/1/c02cCG1lB8f//f95
114 @ DZx74MTMzshhoSm6szrQ/a6Ir/Z2RkfEjBxuLYFpDiDi6Af///2ckaHBp7+7wmavP5n76+P2C
115 @ lrLIYl8H9W36auJCbCxM4szMTJac7Kza////R3H1w2cfWAgafPbqs5g7D95++/P1B4+ECK8tA
116 @ wMDw/1H7159+/7r7ZcvPz4fOHbzEwMDwx8GBgaGnNatfHZx8zqrJ+4VJBh5CQEGOySEua/v3n
117 @ 7hXmqI8WUGBgYGL3vVG7fuPK3i5GD9/fja7ZsMDAzMG/Ze52mZeSj4yu1XEq/ff7W5dvfVAS1
118 @ lsXc4Db7z8C3r8p7Qjf///2dnZGxlqJuyr3rPqQd/Hhyu7oSpYWScylDQsd3kzvnH738wMDzj
119 @ 5GBN1VIWW4c3KDon7VOvm7S3paB9u5qsU5/x5KUnlY+eexQbkLNsErK61+++VnAJcfkyMTIwf
120 @ fj0QwZbJDKjcETs1Y8evyd48toz8y/ffzv//vPP4veffxpX77z6l5JewHPu8MqTDAwMDLzyrj
121 @ b/mZm0JcT5Lj+89+Ybm6zz95oMh7s4XbygN3Sluq4Mj5K8iKMgP4f0////fv77//8nLy+7MCc
122 @ XmyYDAwODS9jM9tcvPypd35pne3ljdjvj26+H2dhYpuENikgfvQeXNmSl3tqepxXsqhXPyc66
123 @ 6s+fv1fMdKR3TK72zpix8nTc7bdfhfkEeVbC9KhbK/9iYWHiErbu6MWbY/7//8/4//9/pgOnH
124 @ 6jGVazvFDRtq2VgiBIZrUTIBgCk+ivHvuEKwAAAAABJRU5ErkJggg==">
125
126 @ <img class="intLink" title="Bold" data-format="bold"
127 @ src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB
128 @ YAQAInhI+pa+H9mJy0LhdgtrxzDG5WGFVk6aXqyk6Y9kXvKKNuLbb6zgMFADs=" />
129
130 @ <img class="intLink" title="Italic" data-format="italic"
131 @ src="data:image/gif;base64,R0lGODlhFgAWAKEDAAAAAF9vj5WIbf///yH5BAEAAAMALA
132 @ AAAAAWABYAAAIjnI+py+0Po5x0gXvruEKHrF2BB1YiCWgbMFIYpsbyTNd2UwAAOw==" />
133
134 @ <img class="intLink" title="Underline" data-format="underline"
135 @ src="data:image/gif;base64,R0lGODlhFgAWAKECAAAAAF9vj////////yH5BAEAAAIALA
136 @ AAAAAWABYAAAIrlI+py+0Po5zUgAsEzvEeL4Ea15EiJJ5PSqJmuwKBEKgxVuXWtun+DwxCCgA
137 @ 7" />
138
139 @ <img class="intLink" title="Left align" data-format="justifyleft"
140 @ src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB
141 @ YAQAIghI+py+0Po5y02ouz3jL4D4JMGELkGYxo+qzl4nKyXAAAOw==" />
142
143 @ <img class="intLink" title="Center align" data-format="justifycenter"
144 @ src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB
145 @ YAQAIfhI+py+0Po5y02ouz3jL4D4JOGI7kaZ5Bqn4sycVbAQA7" />
146
147 @ <img class="intLink" title="Right align" data-format="justifyright"
148 @ src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB
149 @ YAQAIghI+py+0Po5y02ouz3jL4D4JQGDLkGYxouqzl43JyVgAAOw==" />
150 @ <img class="intLink" title="Numbered list"
151 @ data-format="insertorderedlist"
152 @ src="data:image/gif;base64,R0lGODlhFgAWAMIGAAAAADljwliE35GjuaezxtHa7P////
153 @ ///yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKSespwjoRFvggCBUBoTFBeq6QIAysQnRHaEO
154 @ zyaZ07Lu9lUBnC0UGQU1K52s6n5oEADs=" />
155
156 @ <img class="intLink" title="Dotted list"
157 @ data-format="insertunorderedlist"
158 @ src="data:image/gif;base64,R0lGODlhFgAWAMIGAAAAAB1ChF9vj1iE33mOrqezxv////
159 @ ///yH5BAEAAAcALAAAAAAWABYAAAMyeLrc/jDKSesppNhGRlBAKIZRERBbqm6YtnbfMY7lud6
160 @ 4UwiuKnigGQliQuWOyKQykgAAOw==" />
161
162 @ <img class="intLink" title="Quote" data-format="formatblock"
163 @ src="data:image/gif;base64,R0lGODlhFgAWAIQXAC1NqjFRjkBgmT9nqUJnsk9xrFJ7u2
164 @ R9qmKBt1iGzHmOrm6Sz4OXw3Odz4Cl2ZSnw6KxyqO306K63bG70bTB0rDI3bvI4P/////////
165 @ //////////////////////////yH5BAEKAB8ALAAAAAAWABYAAAVP4CeOZGmeaKqubEs2Cekk
166 @ ErvEI1zZuOgYFlakECEZFi0GgTGKEBATFmJAVXweVOoKEQgABB9IQDCmrLpjETrQQlhHjINrT
167 @ q/b7/i8fp8PAQA7" />
168
169 @ <img class="intLink" title="Delete indentation" data-format="outdent"
170 @ src="data:image/gif;base64,R0lGODlhFgAWAMIHAAAAADljwliE35GjuaezxtDV3NHa7P
171 @ ///yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKCQG9F2i7u8agQgyK1z2EIBil+TWqEMxhMcz
172 @ sYVJ3e4ahk+sFnAgtxSQDqWw6n5cEADs=" />
173
174 @ <img class="intLink" title="Add indentation" data-format="indent"
175 @ src="data:image/gif;base64,R0lGODlhFgAWAOMIAAAAADljwl9vj1iE35GjuaezxtDV3N
176 @ Ha7P///////////////////////////////yH5BAEAAAgALAAAAAAWABYAAAQ7EMlJq704650
177 @ B/x8gemMpgugwHJNZXodKsO5oqUOgo5KhBwWESyMQsCRDHu9VOyk5TM9zSpFSr9gsJwIAOw==">
178
179 @ <img class="intLink" title="Hyperlink" data-format="createlink"
180 @ src="data:image/gif;base64,R0lGODlhFgAWAOMKAB1ChDRLY19vj3mOrpGjuaezxrCztb
181 @ /I19Ha7Pv8/f///////////////////////yH5BAEKAA8ALAAAAAAWABYAAARY8MlJq704682
182 @ 7/2BYIQVhHg9pEgVGIklyDEUBy/RlE4FQF4dCj2AQXAiJQDCWQCAEBwIioEMQBgSAFhDAGghG
183 @ i9XgHAhMNoSZgJkJei33UESv2+/4vD4TAQA7" />
184
185 #if 0 /* Cut/Copy/Paste requires special browser permissions for security
186 ** reasons. So omit these buttons */
187 @ <img class="intLink" title="Cut" data-format="cut"
188 @ src="data:image/gif;base64,R0lGODlhFgAWAIQSAB1ChBFNsRJTySJYwjljwkxwl19vj1
189 @ dusYODhl6MnHmOrpqbmpGjuaezxrCztcDCxL/I18rL1P/////////////////////////////
190 @ //////////////////////////yH5BAEAAB8ALAAAAAAWABYAAAVu4CeOZGmeaKqubDs6TNnE
191 @ bGNApNG0kbGMi5trwcA9GArXh+FAfBAw5UexUDAQESkRsfhJPwaH4YsEGAAJGisRGAQY7UCC9
192 @ ZAXBB+74LGCRxIEHwAHdWooDgGJcwpxDisQBQRjIgkDCVlfmZqbmiEAOw==" />
193
194 @ <img class="intLink" title="Copy" data-format="copy"
195 @ src="data:image/gif;base64,R0lGODlhFgAWAIQcAB1ChBFNsTRLYyJYwjljwl9vj1iE31
196 @ iGzF6MnHWX9HOdz5GjuYCl2YKl8ZOt4qezxqK63aK/9KPD+7DI3b/I17LM/MrL1MLY9NHa7OP
197 @ s++bx/Pv8/f///////////////yH5BAEAAB8ALAAAAAAWABYAAAWG4CeOZGmeaKqubOum1SQ/
198 @ kPVOW749BeVSus2CgrCxHptLBbOQxCSNCCaF1GUqwQbBd0JGJAyGJJiobE+LnCaDcXAaEoxhQ
199 @ ACgNw0FQx9kP+wmaRgYFBQNeAoGihCAJQsCkJAKOhgXEw8BLQYciooHf5o7EA+kC40qBKkAAA
200 @ Grpy+wsbKzIiEAOw==" />
201
202 @ <img class="intLink" title="Paste" data-format="paste"
203 @ src="data:image/gif;base64,R0lGODlhFgAWAIQUAD04KTRLY2tXQF9vj414WZWIbXmOrp
204 @ qbmpGjudClFaezxsa0cb/I1+3YitHa7PrkIPHvbuPs+/fvrvv8/f/////////////////////
205 @ //////////////////////////yH5BAEAAB8ALAAAAAAWABYAAAWN4CeOZGmeaKqubGsusPvB
206 @ SyFJjVDs6nJLB0khR4AkBCmfsCGBQAoCwjF5gwquVykSFbwZE+AwIBV0GhFog2EwIDchjwRiQ
207 @ o9E2Fx4XD5R+B0DDAEnBXBhBhN2DgwDAQFjJYVhCQYRfgoIDGiQJAWTCQMRiwwMfgicnVcAAA
208 @ MOaK+bLAOrtLUyt7i5uiUhADs=" />
209 #endif
210
211 @ </div>
212 @ <div id="wysiwygBox"
213 @ style="resize:both;overflow:auto;width:95%%;min-height:%d(h)em;"
214 @ contenteditable="true">%s(zContent)</div>
215 @ <script nonce="%h(style_nonce())">
216 @ var oDoc;
217 @
218 @ /* Initialize the document editor */
219 @ function initDoc() {
220 @ initEventHandlers();
221 @ oDoc = document.getElementById("wysiwygBox");
222 @ if (!isWysiwyg()) { setDocMode(true); }
223 @ }
224 @
225 @ function initEventHandlers() {
226 @ document.querySelector('form').onsubmit = wysiwygSubmit;
227 @ document.querySelector('#editMode').onchange = function() {
228 @ setDocMode(this.selectedIndex)
229 @ };
230 @ var controls = document.querySelectorAll('select.format');
231 @ for(var i = 0; i < controls.length; i++) {
232 @ controls[i].onchange = handleDropDown;
233 @ }
234 @ controls = document.querySelectorAll('.intLink');
235 @ for(i = 0; i < controls.length; i++) {
236 @ controls[i].onclick = handleFormatButton;
237 @ }
238 @
239 @ function handleDropDown() {
240 @ formatDoc(this.dataset.format,this[this.selectedIndex].value);
241 @ this.selectedIndex = 0;
242 @ }
243 @
244 @ function handleFormatButton() {
245 @ var extra;
246 @ switch (this.dataset.format) {
247 @ case 'createlink':
248 @ var sLnk = prompt('Target URL:','');
249 @ if(sLnk && sLnk != '')
250 @ {
251 @ extra = sLnk;
252 @ }
253 @ break;
254 @ case 'formatblock':
255 @ extra = 'blockquote';
256 @ break;
257 @ }
258 @ formatDoc(this.dataset.format, extra);
259 @ }
260 @ }
261 @
262 @ /* Return true if the document editor is in WYSIWYG mode. Return
263 @ ** false if it is in Markup mode */
264 @ function isWysiwyg() {
265 @ return document.getElementById("editMode").selectedIndex==0;
266 @ }
267 @
268 @ /* Invoke this routine prior to submitting the HTML content back
269 @ ** to the server */
270 @ function wysiwygSubmit() {
271 @ if(oDoc.style.whiteSpace=="pre-wrap"){setDocMode(0);}
272 @ document.getElementById("wysiwygValue").value=oDoc.innerHTML;
273 @ }
274 @
275 @ /* Run the editing command if in WYSIWYG mode */
276 @ function formatDoc(sCmd, sValue) {
277 @ if (isWysiwyg()){
278 @ try {
279 @ // First, try the W3C draft standard way, which has
280 @ // been working on all non-IE browsers for a while.
281 @ // It is also supported by IE11 and higher.
282 @ document.execCommand("styleWithCSS", false, false);
283 @ } catch (e) {
284 @ try {
285 @ // For IE9 or IE10, this should work.
286 @ document.execCommand("useCSS", 0, true);
287 @ } catch (e) {
288 @ // OK, that apparently did not work, do nothing.
289 @ }
290 @ }
291 @ document.execCommand(sCmd, false, sValue);
292 @ oDoc.focus();
293 @ }
294 @ }
295 @
296 @ /* Change the editing mode. Convert to markup if the argument
297 @ ** is true and wysiwyg if the argument is false. */
298 @ function setDocMode(bToMarkup) {
299 @ var oContent;
300 @ if (bToMarkup) {
301 @ /* WYSIWYG -> Markup */
302 @ var linebreak = new RegExp("</p><p>","ig");
303 @ oContent = document.createTextNode(
304 @ oDoc.innerHTML.replace(linebreak,"</p>\n\n<p>"));
305 @ oDoc.innerHTML = "";
306 @ oDoc.style.whiteSpace = "pre-wrap";
307 @ oDoc.appendChild(oContent);
308 @ document.getElementById("toolBar1").style.visibility="hidden";
309 @ document.getElementById("toolBar2").style.visibility="hidden";
310 @ } else {
311 @ /* Markup -> WYSIWYG */
312 @ if (document.all) {
313 @ oDoc.innerHTML = oDoc.innerText;
314 @ } else {
315 @ oContent = document.createRange();
316 @ oContent.selectNodeContents(oDoc.firstChild);
317 @ oDoc.innerHTML = oContent.toString();
318 @ }
319 @ oDoc.style.whiteSpace = "normal";
320 @ document.getElementById("toolBar1").style.visibility="visible";
321 @ document.getElementById("toolBar2").style.visibility="visible";
322 @ }
323 @ oDoc.focus();
324 @ }
325 @ initDoc();
326 @ </script>
327
328 }
--- a/src/wysiwyg.c
+++ b/src/wysiwyg.c
@@ -1,328 +0,0 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
+4 -10
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -28,13 +28,13 @@
2828
2929
SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0
3030
3131
SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
3232
33
-SRC = add_.c ajax_.c alerts_.c allrepo_.c attach_.c backlink_.c backoffice_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c capabilities_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c deltafunc_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c extcgi_.c file_.c fileedit_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c fuzz_.c glob_.c graph_.c gzip_.c hname_.c hook_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c repolist_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c setupuser_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c smtp_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c terminal_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c webmail_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
33
+SRC = add_.c ajax_.c alerts_.c allrepo_.c attach_.c backlink_.c backoffice_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c capabilities_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c deltafunc_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c extcgi_.c file_.c fileedit_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c fuzz_.c glob_.c graph_.c gzip_.c hname_.c hook_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c repolist_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c setupuser_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c smtp_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c terminal_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c webmail_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c xfer_.c xfersetup_.c zip_.c
3434
35
-OBJ = $(OBJDIR)\add$O $(OBJDIR)\ajax$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backlink$O $(OBJDIR)\backoffice$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\capabilities$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\deltafunc$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\extcgi$O $(OBJDIR)\file$O $(OBJDIR)\fileedit$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\fuzz$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\hook$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\repolist$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\setupuser$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\smtp$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\terminal$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\webmail$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
35
+OBJ = $(OBJDIR)\add$O $(OBJDIR)\ajax$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backlink$O $(OBJDIR)\backoffice$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\capabilities$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\deltafunc$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\extcgi$O $(OBJDIR)\file$O $(OBJDIR)\fileedit$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\fuzz$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\hook$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\repolist$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\setupuser$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\smtp$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\terminal$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\webmail$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
3636
3737
3838
RC=$(DMDIR)\bin\rcc
3939
RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
4040
@@ -49,11 +49,11 @@
4949
5050
$(OBJDIR)\fossil.res: $B\win\fossil.rc
5151
$(RC) $(RCFLAGS) -o$@ $**
5252
5353
$(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
54
- +echo add ajax alerts allrepo attach backlink backoffice bag bisect blob branch browse builtin bundle cache capabilities captcha cgi checkin checkout clearsign clone comformat configure content cookies db delta deltacmd deltafunc descendants diff diffcmd dispatch doc encode etag event export extcgi file fileedit finfo foci forum fshell fusefs fuzz glob graph gzip hname hook http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path piechart pivot popen pqueue printf publish purge rebuild regexp repolist report rss schema search security_audit setup setupuser sha1 sha1hard sha3 shun sitemap skins smtp sqlcmd stash stat statrep style sync tag tar terminal th_main timeline tkt tktsetup undo unicode unversioned update url user utf8 util verify vfile webmail wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
54
+ +echo add ajax alerts allrepo attach backlink backoffice bag bisect blob branch browse builtin bundle cache capabilities captcha cgi checkin checkout clearsign clone comformat configure content cookies db delta deltacmd deltafunc descendants diff diffcmd dispatch doc encode etag event export extcgi file fileedit finfo foci forum fshell fusefs fuzz glob graph gzip hname hook http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path piechart pivot popen pqueue printf publish purge rebuild regexp repolist report rss schema search security_audit setup setupuser sha1 sha1hard sha3 shun sitemap skins smtp sqlcmd stash stat statrep style sync tag tar terminal th_main timeline tkt tktsetup undo unicode unversioned update url user utf8 util verify vfile webmail wiki wikiformat winfile winhttp xfer xfersetup zip shell sqlite3 th th_lang > $@
5555
+echo fossil >> $@
5656
+echo fossil >> $@
5757
+echo $(LIBS) >> $@
5858
+echo. >> $@
5959
+echo fossil >> $@
@@ -962,16 +962,10 @@
962962
$(TCC) -o$@ -c winhttp_.c
963963
964964
winhttp_.c : $(SRCDIR)\winhttp.c
965965
+translate$E $** > $@
966966
967
-$(OBJDIR)\wysiwyg$O : wysiwyg_.c wysiwyg.h
968
- $(TCC) -o$@ -c wysiwyg_.c
969
-
970
-wysiwyg_.c : $(SRCDIR)\wysiwyg.c
971
- +translate$E $** > $@
972
-
973967
$(OBJDIR)\xfer$O : xfer_.c xfer.h
974968
$(TCC) -o$@ -c xfer_.c
975969
976970
xfer_.c : $(SRCDIR)\xfer.c
977971
+translate$E $** > $@
@@ -987,7 +981,7 @@
987981
988982
zip_.c : $(SRCDIR)\zip.c
989983
+translate$E $** > $@
990984
991985
headers: makeheaders$E page_index.h builtin_data.h VERSION.h
992
- +makeheaders$E add_.c:add.h ajax_.c:ajax.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backlink_.c:backlink.h backoffice_.c:backoffice.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h capabilities_.c:capabilities.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h deltafunc_.c:deltafunc.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h extcgi_.c:extcgi.h file_.c:file.h fileedit_.c:fileedit.h finfo_.c:finfo.h foci_.c:foci.h forum_.c:forum.h fshell_.c:fshell.h fusefs_.c:fusefs.h fuzz_.c:fuzz.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h hook_.c:hook.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h piechart_.c:piechart.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h repolist_.c:repolist.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h setupuser_.c:setupuser.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h smtp_.c:smtp.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h terminal_.c:terminal.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h webmail_.c:webmail.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
986
+ +makeheaders$E add_.c:add.h ajax_.c:ajax.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backlink_.c:backlink.h backoffice_.c:backoffice.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h capabilities_.c:capabilities.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h deltafunc_.c:deltafunc.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h extcgi_.c:extcgi.h file_.c:file.h fileedit_.c:fileedit.h finfo_.c:finfo.h foci_.c:foci.h forum_.c:forum.h fshell_.c:fshell.h fusefs_.c:fusefs.h fuzz_.c:fuzz.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h hook_.c:hook.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h piechart_.c:piechart.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h repolist_.c:repolist.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h setupuser_.c:setupuser.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h smtp_.c:smtp.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h terminal_.c:terminal.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h webmail_.c:webmail.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
993987
@copy /Y nul: headers
994988
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -28,13 +28,13 @@
28
29 SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0
30
31 SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
32
33 SRC = add_.c ajax_.c alerts_.c allrepo_.c attach_.c backlink_.c backoffice_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c capabilities_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c deltafunc_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c extcgi_.c file_.c fileedit_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c fuzz_.c glob_.c graph_.c gzip_.c hname_.c hook_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c repolist_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c setupuser_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c smtp_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c terminal_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c webmail_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
34
35 OBJ = $(OBJDIR)\add$O $(OBJDIR)\ajax$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backlink$O $(OBJDIR)\backoffice$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\capabilities$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\deltafunc$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\extcgi$O $(OBJDIR)\file$O $(OBJDIR)\fileedit$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\fuzz$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\hook$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\repolist$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\setupuser$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\smtp$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\terminal$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\webmail$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
36
37
38 RC=$(DMDIR)\bin\rcc
39 RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
40
@@ -49,11 +49,11 @@
49
50 $(OBJDIR)\fossil.res: $B\win\fossil.rc
51 $(RC) $(RCFLAGS) -o$@ $**
52
53 $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
54 +echo add ajax alerts allrepo attach backlink backoffice bag bisect blob branch browse builtin bundle cache capabilities captcha cgi checkin checkout clearsign clone comformat configure content cookies db delta deltacmd deltafunc descendants diff diffcmd dispatch doc encode etag event export extcgi file fileedit finfo foci forum fshell fusefs fuzz glob graph gzip hname hook http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path piechart pivot popen pqueue printf publish purge rebuild regexp repolist report rss schema search security_audit setup setupuser sha1 sha1hard sha3 shun sitemap skins smtp sqlcmd stash stat statrep style sync tag tar terminal th_main timeline tkt tktsetup undo unicode unversioned update url user utf8 util verify vfile webmail wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
55 +echo fossil >> $@
56 +echo fossil >> $@
57 +echo $(LIBS) >> $@
58 +echo. >> $@
59 +echo fossil >> $@
@@ -962,16 +962,10 @@
962 $(TCC) -o$@ -c winhttp_.c
963
964 winhttp_.c : $(SRCDIR)\winhttp.c
965 +translate$E $** > $@
966
967 $(OBJDIR)\wysiwyg$O : wysiwyg_.c wysiwyg.h
968 $(TCC) -o$@ -c wysiwyg_.c
969
970 wysiwyg_.c : $(SRCDIR)\wysiwyg.c
971 +translate$E $** > $@
972
973 $(OBJDIR)\xfer$O : xfer_.c xfer.h
974 $(TCC) -o$@ -c xfer_.c
975
976 xfer_.c : $(SRCDIR)\xfer.c
977 +translate$E $** > $@
@@ -987,7 +981,7 @@
987
988 zip_.c : $(SRCDIR)\zip.c
989 +translate$E $** > $@
990
991 headers: makeheaders$E page_index.h builtin_data.h VERSION.h
992 +makeheaders$E add_.c:add.h ajax_.c:ajax.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backlink_.c:backlink.h backoffice_.c:backoffice.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h capabilities_.c:capabilities.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h deltafunc_.c:deltafunc.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h extcgi_.c:extcgi.h file_.c:file.h fileedit_.c:fileedit.h finfo_.c:finfo.h foci_.c:foci.h forum_.c:forum.h fshell_.c:fshell.h fusefs_.c:fusefs.h fuzz_.c:fuzz.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h hook_.c:hook.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h piechart_.c:piechart.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h repolist_.c:repolist.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h setupuser_.c:setupuser.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h smtp_.c:smtp.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h terminal_.c:terminal.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h webmail_.c:webmail.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
993 @copy /Y nul: headers
994
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -28,13 +28,13 @@
28
29 SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0
30
31 SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
32
33 SRC = add_.c ajax_.c alerts_.c allrepo_.c attach_.c backlink_.c backoffice_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c capabilities_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c deltafunc_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c extcgi_.c file_.c fileedit_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c fuzz_.c glob_.c graph_.c gzip_.c hname_.c hook_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c repolist_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c setupuser_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c smtp_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c terminal_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c webmail_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c xfer_.c xfersetup_.c zip_.c
34
35 OBJ = $(OBJDIR)\add$O $(OBJDIR)\ajax$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backlink$O $(OBJDIR)\backoffice$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\capabilities$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\deltafunc$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\extcgi$O $(OBJDIR)\file$O $(OBJDIR)\fileedit$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\fuzz$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\hook$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\repolist$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\setupuser$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\smtp$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\terminal$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\webmail$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
36
37
38 RC=$(DMDIR)\bin\rcc
39 RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
40
@@ -49,11 +49,11 @@
49
50 $(OBJDIR)\fossil.res: $B\win\fossil.rc
51 $(RC) $(RCFLAGS) -o$@ $**
52
53 $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
54 +echo add ajax alerts allrepo attach backlink backoffice bag bisect blob branch browse builtin bundle cache capabilities captcha cgi checkin checkout clearsign clone comformat configure content cookies db delta deltacmd deltafunc descendants diff diffcmd dispatch doc encode etag event export extcgi file fileedit finfo foci forum fshell fusefs fuzz glob graph gzip hname hook http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path piechart pivot popen pqueue printf publish purge rebuild regexp repolist report rss schema search security_audit setup setupuser sha1 sha1hard sha3 shun sitemap skins smtp sqlcmd stash stat statrep style sync tag tar terminal th_main timeline tkt tktsetup undo unicode unversioned update url user utf8 util verify vfile webmail wiki wikiformat winfile winhttp xfer xfersetup zip shell sqlite3 th th_lang > $@
55 +echo fossil >> $@
56 +echo fossil >> $@
57 +echo $(LIBS) >> $@
58 +echo. >> $@
59 +echo fossil >> $@
@@ -962,16 +962,10 @@
962 $(TCC) -o$@ -c winhttp_.c
963
964 winhttp_.c : $(SRCDIR)\winhttp.c
965 +translate$E $** > $@
966
 
 
 
 
 
 
967 $(OBJDIR)\xfer$O : xfer_.c xfer.h
968 $(TCC) -o$@ -c xfer_.c
969
970 xfer_.c : $(SRCDIR)\xfer.c
971 +translate$E $** > $@
@@ -987,7 +981,7 @@
981
982 zip_.c : $(SRCDIR)\zip.c
983 +translate$E $** > $@
984
985 headers: makeheaders$E page_index.h builtin_data.h VERSION.h
986 +makeheaders$E add_.c:add.h ajax_.c:ajax.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backlink_.c:backlink.h backoffice_.c:backoffice.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h capabilities_.c:capabilities.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h deltafunc_.c:deltafunc.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h extcgi_.c:extcgi.h file_.c:file.h fileedit_.c:fileedit.h finfo_.c:finfo.h foci_.c:foci.h forum_.c:forum.h fshell_.c:fshell.h fusefs_.c:fusefs.h fuzz_.c:fuzz.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h hook_.c:hook.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h piechart_.c:piechart.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h repolist_.c:repolist.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h setupuser_.c:setupuser.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h smtp_.c:smtp.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h terminal_.c:terminal.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h webmail_.c:webmail.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
987 @copy /Y nul: headers
988
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -566,11 +566,10 @@
566566
$(SRCDIR)/webmail.c \
567567
$(SRCDIR)/wiki.c \
568568
$(SRCDIR)/wikiformat.c \
569569
$(SRCDIR)/winfile.c \
570570
$(SRCDIR)/winhttp.c \
571
- $(SRCDIR)/wysiwyg.c \
572571
$(SRCDIR)/xfer.c \
573572
$(SRCDIR)/xfersetup.c \
574573
$(SRCDIR)/zip.c
575574
576575
EXTRA_FILES = \
@@ -640,10 +639,11 @@
640639
$(SRCDIR)/fossil.confirmer.js \
641640
$(SRCDIR)/fossil.dom.js \
642641
$(SRCDIR)/fossil.fetch.js \
643642
$(SRCDIR)/fossil.page.fileedit.js \
644643
$(SRCDIR)/fossil.page.forumpost.js \
644
+ $(SRCDIR)/fossil.page.wikiedit.js \
645645
$(SRCDIR)/fossil.storage.js \
646646
$(SRCDIR)/fossil.tabs.js \
647647
$(SRCDIR)/graph.js \
648648
$(SRCDIR)/href.js \
649649
$(SRCDIR)/login.js \
@@ -669,10 +669,11 @@
669669
$(SRCDIR)/sounds/d.wav \
670670
$(SRCDIR)/sounds/e.wav \
671671
$(SRCDIR)/sounds/f.wav \
672672
$(SRCDIR)/style.admin_log.css \
673673
$(SRCDIR)/style.fileedit.css \
674
+ $(SRCDIR)/style.wikiedit.css \
674675
$(SRCDIR)/tree.js \
675676
$(SRCDIR)/useredit.js \
676677
$(SRCDIR)/wiki.wiki
677678
678679
TRANS_SRC = \
@@ -814,11 +815,10 @@
814815
$(OBJDIR)/webmail_.c \
815816
$(OBJDIR)/wiki_.c \
816817
$(OBJDIR)/wikiformat_.c \
817818
$(OBJDIR)/winfile_.c \
818819
$(OBJDIR)/winhttp_.c \
819
- $(OBJDIR)/wysiwyg_.c \
820820
$(OBJDIR)/xfer_.c \
821821
$(OBJDIR)/xfersetup_.c \
822822
$(OBJDIR)/zip_.c
823823
824824
OBJ = \
@@ -960,11 +960,10 @@
960960
$(OBJDIR)/webmail.o \
961961
$(OBJDIR)/wiki.o \
962962
$(OBJDIR)/wikiformat.o \
963963
$(OBJDIR)/winfile.o \
964964
$(OBJDIR)/winhttp.o \
965
- $(OBJDIR)/wysiwyg.o \
966965
$(OBJDIR)/xfer.o \
967966
$(OBJDIR)/xfersetup.o \
968967
$(OBJDIR)/zip.o
969968
970969
APPNAME = fossil.exe
@@ -1321,11 +1320,10 @@
13211320
$(OBJDIR)/webmail_.c:$(OBJDIR)/webmail.h \
13221321
$(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h \
13231322
$(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h \
13241323
$(OBJDIR)/winfile_.c:$(OBJDIR)/winfile.h \
13251324
$(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h \
1326
- $(OBJDIR)/wysiwyg_.c:$(OBJDIR)/wysiwyg.h \
13271325
$(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h \
13281326
$(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h \
13291327
$(OBJDIR)/zip_.c:$(OBJDIR)/zip.h \
13301328
$(SRCDIR)/sqlite3.h \
13311329
$(SRCDIR)/th.h \
@@ -2454,18 +2452,10 @@
24542452
$(OBJDIR)/winhttp.o: $(OBJDIR)/winhttp_.c $(OBJDIR)/winhttp.h $(SRCDIR)/config.h
24552453
$(XTCC) -o $(OBJDIR)/winhttp.o -c $(OBJDIR)/winhttp_.c
24562454
24572455
$(OBJDIR)/winhttp.h: $(OBJDIR)/headers
24582456
2459
-$(OBJDIR)/wysiwyg_.c: $(SRCDIR)/wysiwyg.c $(TRANSLATE)
2460
- $(TRANSLATE) $(SRCDIR)/wysiwyg.c >$@
2461
-
2462
-$(OBJDIR)/wysiwyg.o: $(OBJDIR)/wysiwyg_.c $(OBJDIR)/wysiwyg.h $(SRCDIR)/config.h
2463
- $(XTCC) -o $(OBJDIR)/wysiwyg.o -c $(OBJDIR)/wysiwyg_.c
2464
-
2465
-$(OBJDIR)/wysiwyg.h: $(OBJDIR)/headers
2466
-
24672457
$(OBJDIR)/xfer_.c: $(SRCDIR)/xfer.c $(TRANSLATE)
24682458
$(TRANSLATE) $(SRCDIR)/xfer.c >$@
24692459
24702460
$(OBJDIR)/xfer.o: $(OBJDIR)/xfer_.c $(OBJDIR)/xfer.h $(SRCDIR)/config.h
24712461
$(XTCC) -o $(OBJDIR)/xfer.o -c $(OBJDIR)/xfer_.c
24722462
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -566,11 +566,10 @@
566 $(SRCDIR)/webmail.c \
567 $(SRCDIR)/wiki.c \
568 $(SRCDIR)/wikiformat.c \
569 $(SRCDIR)/winfile.c \
570 $(SRCDIR)/winhttp.c \
571 $(SRCDIR)/wysiwyg.c \
572 $(SRCDIR)/xfer.c \
573 $(SRCDIR)/xfersetup.c \
574 $(SRCDIR)/zip.c
575
576 EXTRA_FILES = \
@@ -640,10 +639,11 @@
640 $(SRCDIR)/fossil.confirmer.js \
641 $(SRCDIR)/fossil.dom.js \
642 $(SRCDIR)/fossil.fetch.js \
643 $(SRCDIR)/fossil.page.fileedit.js \
644 $(SRCDIR)/fossil.page.forumpost.js \
 
645 $(SRCDIR)/fossil.storage.js \
646 $(SRCDIR)/fossil.tabs.js \
647 $(SRCDIR)/graph.js \
648 $(SRCDIR)/href.js \
649 $(SRCDIR)/login.js \
@@ -669,10 +669,11 @@
669 $(SRCDIR)/sounds/d.wav \
670 $(SRCDIR)/sounds/e.wav \
671 $(SRCDIR)/sounds/f.wav \
672 $(SRCDIR)/style.admin_log.css \
673 $(SRCDIR)/style.fileedit.css \
 
674 $(SRCDIR)/tree.js \
675 $(SRCDIR)/useredit.js \
676 $(SRCDIR)/wiki.wiki
677
678 TRANS_SRC = \
@@ -814,11 +815,10 @@
814 $(OBJDIR)/webmail_.c \
815 $(OBJDIR)/wiki_.c \
816 $(OBJDIR)/wikiformat_.c \
817 $(OBJDIR)/winfile_.c \
818 $(OBJDIR)/winhttp_.c \
819 $(OBJDIR)/wysiwyg_.c \
820 $(OBJDIR)/xfer_.c \
821 $(OBJDIR)/xfersetup_.c \
822 $(OBJDIR)/zip_.c
823
824 OBJ = \
@@ -960,11 +960,10 @@
960 $(OBJDIR)/webmail.o \
961 $(OBJDIR)/wiki.o \
962 $(OBJDIR)/wikiformat.o \
963 $(OBJDIR)/winfile.o \
964 $(OBJDIR)/winhttp.o \
965 $(OBJDIR)/wysiwyg.o \
966 $(OBJDIR)/xfer.o \
967 $(OBJDIR)/xfersetup.o \
968 $(OBJDIR)/zip.o
969
970 APPNAME = fossil.exe
@@ -1321,11 +1320,10 @@
1321 $(OBJDIR)/webmail_.c:$(OBJDIR)/webmail.h \
1322 $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h \
1323 $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h \
1324 $(OBJDIR)/winfile_.c:$(OBJDIR)/winfile.h \
1325 $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h \
1326 $(OBJDIR)/wysiwyg_.c:$(OBJDIR)/wysiwyg.h \
1327 $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h \
1328 $(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h \
1329 $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h \
1330 $(SRCDIR)/sqlite3.h \
1331 $(SRCDIR)/th.h \
@@ -2454,18 +2452,10 @@
2454 $(OBJDIR)/winhttp.o: $(OBJDIR)/winhttp_.c $(OBJDIR)/winhttp.h $(SRCDIR)/config.h
2455 $(XTCC) -o $(OBJDIR)/winhttp.o -c $(OBJDIR)/winhttp_.c
2456
2457 $(OBJDIR)/winhttp.h: $(OBJDIR)/headers
2458
2459 $(OBJDIR)/wysiwyg_.c: $(SRCDIR)/wysiwyg.c $(TRANSLATE)
2460 $(TRANSLATE) $(SRCDIR)/wysiwyg.c >$@
2461
2462 $(OBJDIR)/wysiwyg.o: $(OBJDIR)/wysiwyg_.c $(OBJDIR)/wysiwyg.h $(SRCDIR)/config.h
2463 $(XTCC) -o $(OBJDIR)/wysiwyg.o -c $(OBJDIR)/wysiwyg_.c
2464
2465 $(OBJDIR)/wysiwyg.h: $(OBJDIR)/headers
2466
2467 $(OBJDIR)/xfer_.c: $(SRCDIR)/xfer.c $(TRANSLATE)
2468 $(TRANSLATE) $(SRCDIR)/xfer.c >$@
2469
2470 $(OBJDIR)/xfer.o: $(OBJDIR)/xfer_.c $(OBJDIR)/xfer.h $(SRCDIR)/config.h
2471 $(XTCC) -o $(OBJDIR)/xfer.o -c $(OBJDIR)/xfer_.c
2472
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -566,11 +566,10 @@
566 $(SRCDIR)/webmail.c \
567 $(SRCDIR)/wiki.c \
568 $(SRCDIR)/wikiformat.c \
569 $(SRCDIR)/winfile.c \
570 $(SRCDIR)/winhttp.c \
 
571 $(SRCDIR)/xfer.c \
572 $(SRCDIR)/xfersetup.c \
573 $(SRCDIR)/zip.c
574
575 EXTRA_FILES = \
@@ -640,10 +639,11 @@
639 $(SRCDIR)/fossil.confirmer.js \
640 $(SRCDIR)/fossil.dom.js \
641 $(SRCDIR)/fossil.fetch.js \
642 $(SRCDIR)/fossil.page.fileedit.js \
643 $(SRCDIR)/fossil.page.forumpost.js \
644 $(SRCDIR)/fossil.page.wikiedit.js \
645 $(SRCDIR)/fossil.storage.js \
646 $(SRCDIR)/fossil.tabs.js \
647 $(SRCDIR)/graph.js \
648 $(SRCDIR)/href.js \
649 $(SRCDIR)/login.js \
@@ -669,10 +669,11 @@
669 $(SRCDIR)/sounds/d.wav \
670 $(SRCDIR)/sounds/e.wav \
671 $(SRCDIR)/sounds/f.wav \
672 $(SRCDIR)/style.admin_log.css \
673 $(SRCDIR)/style.fileedit.css \
674 $(SRCDIR)/style.wikiedit.css \
675 $(SRCDIR)/tree.js \
676 $(SRCDIR)/useredit.js \
677 $(SRCDIR)/wiki.wiki
678
679 TRANS_SRC = \
@@ -814,11 +815,10 @@
815 $(OBJDIR)/webmail_.c \
816 $(OBJDIR)/wiki_.c \
817 $(OBJDIR)/wikiformat_.c \
818 $(OBJDIR)/winfile_.c \
819 $(OBJDIR)/winhttp_.c \
 
820 $(OBJDIR)/xfer_.c \
821 $(OBJDIR)/xfersetup_.c \
822 $(OBJDIR)/zip_.c
823
824 OBJ = \
@@ -960,11 +960,10 @@
960 $(OBJDIR)/webmail.o \
961 $(OBJDIR)/wiki.o \
962 $(OBJDIR)/wikiformat.o \
963 $(OBJDIR)/winfile.o \
964 $(OBJDIR)/winhttp.o \
 
965 $(OBJDIR)/xfer.o \
966 $(OBJDIR)/xfersetup.o \
967 $(OBJDIR)/zip.o
968
969 APPNAME = fossil.exe
@@ -1321,11 +1320,10 @@
1320 $(OBJDIR)/webmail_.c:$(OBJDIR)/webmail.h \
1321 $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h \
1322 $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h \
1323 $(OBJDIR)/winfile_.c:$(OBJDIR)/winfile.h \
1324 $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h \
 
1325 $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h \
1326 $(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h \
1327 $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h \
1328 $(SRCDIR)/sqlite3.h \
1329 $(SRCDIR)/th.h \
@@ -2454,18 +2452,10 @@
2452 $(OBJDIR)/winhttp.o: $(OBJDIR)/winhttp_.c $(OBJDIR)/winhttp.h $(SRCDIR)/config.h
2453 $(XTCC) -o $(OBJDIR)/winhttp.o -c $(OBJDIR)/winhttp_.c
2454
2455 $(OBJDIR)/winhttp.h: $(OBJDIR)/headers
2456
 
 
 
 
 
 
 
 
2457 $(OBJDIR)/xfer_.c: $(SRCDIR)/xfer.c $(TRANSLATE)
2458 $(TRANSLATE) $(SRCDIR)/xfer.c >$@
2459
2460 $(OBJDIR)/xfer.o: $(OBJDIR)/xfer_.c $(OBJDIR)/xfer.h $(SRCDIR)/config.h
2461 $(XTCC) -o $(OBJDIR)/xfer.o -c $(OBJDIR)/xfer_.c
2462
+4 -10
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -488,11 +488,10 @@
488488
"$(OX)\webmail_.c" \
489489
"$(OX)\wiki_.c" \
490490
"$(OX)\wikiformat_.c" \
491491
"$(OX)\winfile_.c" \
492492
"$(OX)\winhttp_.c" \
493
- "$(OX)\wysiwyg_.c" \
494493
"$(OX)\xfer_.c" \
495494
"$(OX)\xfersetup_.c" \
496495
"$(OX)\zip_.c"
497496
498497
EXTRA_FILES = "$(SRCDIR)\..\skins\aht\details.txt" \
@@ -561,10 +560,11 @@
561560
"$(SRCDIR)\fossil.confirmer.js" \
562561
"$(SRCDIR)\fossil.dom.js" \
563562
"$(SRCDIR)\fossil.fetch.js" \
564563
"$(SRCDIR)\fossil.page.fileedit.js" \
565564
"$(SRCDIR)\fossil.page.forumpost.js" \
565
+ "$(SRCDIR)\fossil.page.wikiedit.js" \
566566
"$(SRCDIR)\fossil.storage.js" \
567567
"$(SRCDIR)\fossil.tabs.js" \
568568
"$(SRCDIR)\graph.js" \
569569
"$(SRCDIR)\href.js" \
570570
"$(SRCDIR)\login.js" \
@@ -590,10 +590,11 @@
590590
"$(SRCDIR)\sounds\d.wav" \
591591
"$(SRCDIR)\sounds\e.wav" \
592592
"$(SRCDIR)\sounds\f.wav" \
593593
"$(SRCDIR)\style.admin_log.css" \
594594
"$(SRCDIR)\style.fileedit.css" \
595
+ "$(SRCDIR)\style.wikiedit.css" \
595596
"$(SRCDIR)\tree.js" \
596597
"$(SRCDIR)\useredit.js" \
597598
"$(SRCDIR)\wiki.wiki"
598599
599600
OBJ = "$(OX)\add$O" \
@@ -740,11 +741,10 @@
740741
"$(OX)\webmail$O" \
741742
"$(OX)\wiki$O" \
742743
"$(OX)\wikiformat$O" \
743744
"$(OX)\winfile$O" \
744745
"$(OX)\winhttp$O" \
745
- "$(OX)\wysiwyg$O" \
746746
"$(OX)\xfer$O" \
747747
"$(OX)\xfersetup$O" \
748748
"$(OX)\zip$O" \
749749
!if $(FOSSIL_ENABLE_MINIZ)!=0
750750
"$(OX)\miniz$O" \
@@ -967,11 +967,10 @@
967967
echo "$(OX)\webmail.obj" >> $@
968968
echo "$(OX)\wiki.obj" >> $@
969969
echo "$(OX)\wikiformat.obj" >> $@
970970
echo "$(OX)\winfile.obj" >> $@
971971
echo "$(OX)\winhttp.obj" >> $@
972
- echo "$(OX)\wysiwyg.obj" >> $@
973972
echo "$(OX)\xfer.obj" >> $@
974973
echo "$(OX)\xfersetup.obj" >> $@
975974
echo "$(OX)\zip.obj" >> $@
976975
!if $(FOSSIL_ENABLE_MINIZ)!=0
977976
echo "$(OX)\miniz.obj" >> $@
@@ -1155,10 +1154,11 @@
11551154
echo "$(SRCDIR)\fossil.confirmer.js" >> $@
11561155
echo "$(SRCDIR)\fossil.dom.js" >> $@
11571156
echo "$(SRCDIR)\fossil.fetch.js" >> $@
11581157
echo "$(SRCDIR)\fossil.page.fileedit.js" >> $@
11591158
echo "$(SRCDIR)\fossil.page.forumpost.js" >> $@
1159
+ echo "$(SRCDIR)\fossil.page.wikiedit.js" >> $@
11601160
echo "$(SRCDIR)\fossil.storage.js" >> $@
11611161
echo "$(SRCDIR)\fossil.tabs.js" >> $@
11621162
echo "$(SRCDIR)\graph.js" >> $@
11631163
echo "$(SRCDIR)\href.js" >> $@
11641164
echo "$(SRCDIR)\login.js" >> $@
@@ -1184,10 +1184,11 @@
11841184
echo "$(SRCDIR)\sounds/d.wav" >> $@
11851185
echo "$(SRCDIR)\sounds/e.wav" >> $@
11861186
echo "$(SRCDIR)\sounds/f.wav" >> $@
11871187
echo "$(SRCDIR)\style.admin_log.css" >> $@
11881188
echo "$(SRCDIR)\style.fileedit.css" >> $@
1189
+ echo "$(SRCDIR)\style.wikiedit.css" >> $@
11891190
echo "$(SRCDIR)\tree.js" >> $@
11901191
echo "$(SRCDIR)\useredit.js" >> $@
11911192
echo "$(SRCDIR)\wiki.wiki" >> $@
11921193
11931194
"$(OX)\add$O" : "$(OX)\add_.c" "$(OX)\add.h"
@@ -2028,16 +2029,10 @@
20282029
$(TCC) /Fo$@ /Fd$(@D)\ -c "$(OX)\winhttp_.c"
20292030
20302031
"$(OX)\winhttp_.c" : "$(SRCDIR)\winhttp.c"
20312032
"$(OBJDIR)\translate$E" $** > $@
20322033
2033
-"$(OX)\wysiwyg$O" : "$(OX)\wysiwyg_.c" "$(OX)\wysiwyg.h"
2034
- $(TCC) /Fo$@ /Fd$(@D)\ -c "$(OX)\wysiwyg_.c"
2035
-
2036
-"$(OX)\wysiwyg_.c" : "$(SRCDIR)\wysiwyg.c"
2037
- "$(OBJDIR)\translate$E" $** > $@
2038
-
20392034
"$(OX)\xfer$O" : "$(OX)\xfer_.c" "$(OX)\xfer.h"
20402035
$(TCC) /Fo$@ /Fd$(@D)\ -c "$(OX)\xfer_.c"
20412036
20422037
"$(OX)\xfer_.c" : "$(SRCDIR)\xfer.c"
20432038
"$(OBJDIR)\translate$E" $** > $@
@@ -2196,14 +2191,13 @@
21962191
"$(OX)\webmail_.c":"$(OX)\webmail.h" \
21972192
"$(OX)\wiki_.c":"$(OX)\wiki.h" \
21982193
"$(OX)\wikiformat_.c":"$(OX)\wikiformat.h" \
21992194
"$(OX)\winfile_.c":"$(OX)\winfile.h" \
22002195
"$(OX)\winhttp_.c":"$(OX)\winhttp.h" \
2201
- "$(OX)\wysiwyg_.c":"$(OX)\wysiwyg.h" \
22022196
"$(OX)\xfer_.c":"$(OX)\xfer.h" \
22032197
"$(OX)\xfersetup_.c":"$(OX)\xfersetup.h" \
22042198
"$(OX)\zip_.c":"$(OX)\zip.h" \
22052199
"$(SRCDIR)\sqlite3.h" \
22062200
"$(SRCDIR)\th.h" \
22072201
"$(OX)\VERSION.h" \
22082202
"$(SRCDIR)\cson_amalgamation.h"
22092203
@copy /Y nul: $@
22102204
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -488,11 +488,10 @@
488 "$(OX)\webmail_.c" \
489 "$(OX)\wiki_.c" \
490 "$(OX)\wikiformat_.c" \
491 "$(OX)\winfile_.c" \
492 "$(OX)\winhttp_.c" \
493 "$(OX)\wysiwyg_.c" \
494 "$(OX)\xfer_.c" \
495 "$(OX)\xfersetup_.c" \
496 "$(OX)\zip_.c"
497
498 EXTRA_FILES = "$(SRCDIR)\..\skins\aht\details.txt" \
@@ -561,10 +560,11 @@
561 "$(SRCDIR)\fossil.confirmer.js" \
562 "$(SRCDIR)\fossil.dom.js" \
563 "$(SRCDIR)\fossil.fetch.js" \
564 "$(SRCDIR)\fossil.page.fileedit.js" \
565 "$(SRCDIR)\fossil.page.forumpost.js" \
 
566 "$(SRCDIR)\fossil.storage.js" \
567 "$(SRCDIR)\fossil.tabs.js" \
568 "$(SRCDIR)\graph.js" \
569 "$(SRCDIR)\href.js" \
570 "$(SRCDIR)\login.js" \
@@ -590,10 +590,11 @@
590 "$(SRCDIR)\sounds\d.wav" \
591 "$(SRCDIR)\sounds\e.wav" \
592 "$(SRCDIR)\sounds\f.wav" \
593 "$(SRCDIR)\style.admin_log.css" \
594 "$(SRCDIR)\style.fileedit.css" \
 
595 "$(SRCDIR)\tree.js" \
596 "$(SRCDIR)\useredit.js" \
597 "$(SRCDIR)\wiki.wiki"
598
599 OBJ = "$(OX)\add$O" \
@@ -740,11 +741,10 @@
740 "$(OX)\webmail$O" \
741 "$(OX)\wiki$O" \
742 "$(OX)\wikiformat$O" \
743 "$(OX)\winfile$O" \
744 "$(OX)\winhttp$O" \
745 "$(OX)\wysiwyg$O" \
746 "$(OX)\xfer$O" \
747 "$(OX)\xfersetup$O" \
748 "$(OX)\zip$O" \
749 !if $(FOSSIL_ENABLE_MINIZ)!=0
750 "$(OX)\miniz$O" \
@@ -967,11 +967,10 @@
967 echo "$(OX)\webmail.obj" >> $@
968 echo "$(OX)\wiki.obj" >> $@
969 echo "$(OX)\wikiformat.obj" >> $@
970 echo "$(OX)\winfile.obj" >> $@
971 echo "$(OX)\winhttp.obj" >> $@
972 echo "$(OX)\wysiwyg.obj" >> $@
973 echo "$(OX)\xfer.obj" >> $@
974 echo "$(OX)\xfersetup.obj" >> $@
975 echo "$(OX)\zip.obj" >> $@
976 !if $(FOSSIL_ENABLE_MINIZ)!=0
977 echo "$(OX)\miniz.obj" >> $@
@@ -1155,10 +1154,11 @@
1155 echo "$(SRCDIR)\fossil.confirmer.js" >> $@
1156 echo "$(SRCDIR)\fossil.dom.js" >> $@
1157 echo "$(SRCDIR)\fossil.fetch.js" >> $@
1158 echo "$(SRCDIR)\fossil.page.fileedit.js" >> $@
1159 echo "$(SRCDIR)\fossil.page.forumpost.js" >> $@
 
1160 echo "$(SRCDIR)\fossil.storage.js" >> $@
1161 echo "$(SRCDIR)\fossil.tabs.js" >> $@
1162 echo "$(SRCDIR)\graph.js" >> $@
1163 echo "$(SRCDIR)\href.js" >> $@
1164 echo "$(SRCDIR)\login.js" >> $@
@@ -1184,10 +1184,11 @@
1184 echo "$(SRCDIR)\sounds/d.wav" >> $@
1185 echo "$(SRCDIR)\sounds/e.wav" >> $@
1186 echo "$(SRCDIR)\sounds/f.wav" >> $@
1187 echo "$(SRCDIR)\style.admin_log.css" >> $@
1188 echo "$(SRCDIR)\style.fileedit.css" >> $@
 
1189 echo "$(SRCDIR)\tree.js" >> $@
1190 echo "$(SRCDIR)\useredit.js" >> $@
1191 echo "$(SRCDIR)\wiki.wiki" >> $@
1192
1193 "$(OX)\add$O" : "$(OX)\add_.c" "$(OX)\add.h"
@@ -2028,16 +2029,10 @@
2028 $(TCC) /Fo$@ /Fd$(@D)\ -c "$(OX)\winhttp_.c"
2029
2030 "$(OX)\winhttp_.c" : "$(SRCDIR)\winhttp.c"
2031 "$(OBJDIR)\translate$E" $** > $@
2032
2033 "$(OX)\wysiwyg$O" : "$(OX)\wysiwyg_.c" "$(OX)\wysiwyg.h"
2034 $(TCC) /Fo$@ /Fd$(@D)\ -c "$(OX)\wysiwyg_.c"
2035
2036 "$(OX)\wysiwyg_.c" : "$(SRCDIR)\wysiwyg.c"
2037 "$(OBJDIR)\translate$E" $** > $@
2038
2039 "$(OX)\xfer$O" : "$(OX)\xfer_.c" "$(OX)\xfer.h"
2040 $(TCC) /Fo$@ /Fd$(@D)\ -c "$(OX)\xfer_.c"
2041
2042 "$(OX)\xfer_.c" : "$(SRCDIR)\xfer.c"
2043 "$(OBJDIR)\translate$E" $** > $@
@@ -2196,14 +2191,13 @@
2196 "$(OX)\webmail_.c":"$(OX)\webmail.h" \
2197 "$(OX)\wiki_.c":"$(OX)\wiki.h" \
2198 "$(OX)\wikiformat_.c":"$(OX)\wikiformat.h" \
2199 "$(OX)\winfile_.c":"$(OX)\winfile.h" \
2200 "$(OX)\winhttp_.c":"$(OX)\winhttp.h" \
2201 "$(OX)\wysiwyg_.c":"$(OX)\wysiwyg.h" \
2202 "$(OX)\xfer_.c":"$(OX)\xfer.h" \
2203 "$(OX)\xfersetup_.c":"$(OX)\xfersetup.h" \
2204 "$(OX)\zip_.c":"$(OX)\zip.h" \
2205 "$(SRCDIR)\sqlite3.h" \
2206 "$(SRCDIR)\th.h" \
2207 "$(OX)\VERSION.h" \
2208 "$(SRCDIR)\cson_amalgamation.h"
2209 @copy /Y nul: $@
2210
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -488,11 +488,10 @@
488 "$(OX)\webmail_.c" \
489 "$(OX)\wiki_.c" \
490 "$(OX)\wikiformat_.c" \
491 "$(OX)\winfile_.c" \
492 "$(OX)\winhttp_.c" \
 
493 "$(OX)\xfer_.c" \
494 "$(OX)\xfersetup_.c" \
495 "$(OX)\zip_.c"
496
497 EXTRA_FILES = "$(SRCDIR)\..\skins\aht\details.txt" \
@@ -561,10 +560,11 @@
560 "$(SRCDIR)\fossil.confirmer.js" \
561 "$(SRCDIR)\fossil.dom.js" \
562 "$(SRCDIR)\fossil.fetch.js" \
563 "$(SRCDIR)\fossil.page.fileedit.js" \
564 "$(SRCDIR)\fossil.page.forumpost.js" \
565 "$(SRCDIR)\fossil.page.wikiedit.js" \
566 "$(SRCDIR)\fossil.storage.js" \
567 "$(SRCDIR)\fossil.tabs.js" \
568 "$(SRCDIR)\graph.js" \
569 "$(SRCDIR)\href.js" \
570 "$(SRCDIR)\login.js" \
@@ -590,10 +590,11 @@
590 "$(SRCDIR)\sounds\d.wav" \
591 "$(SRCDIR)\sounds\e.wav" \
592 "$(SRCDIR)\sounds\f.wav" \
593 "$(SRCDIR)\style.admin_log.css" \
594 "$(SRCDIR)\style.fileedit.css" \
595 "$(SRCDIR)\style.wikiedit.css" \
596 "$(SRCDIR)\tree.js" \
597 "$(SRCDIR)\useredit.js" \
598 "$(SRCDIR)\wiki.wiki"
599
600 OBJ = "$(OX)\add$O" \
@@ -740,11 +741,10 @@
741 "$(OX)\webmail$O" \
742 "$(OX)\wiki$O" \
743 "$(OX)\wikiformat$O" \
744 "$(OX)\winfile$O" \
745 "$(OX)\winhttp$O" \
 
746 "$(OX)\xfer$O" \
747 "$(OX)\xfersetup$O" \
748 "$(OX)\zip$O" \
749 !if $(FOSSIL_ENABLE_MINIZ)!=0
750 "$(OX)\miniz$O" \
@@ -967,11 +967,10 @@
967 echo "$(OX)\webmail.obj" >> $@
968 echo "$(OX)\wiki.obj" >> $@
969 echo "$(OX)\wikiformat.obj" >> $@
970 echo "$(OX)\winfile.obj" >> $@
971 echo "$(OX)\winhttp.obj" >> $@
 
972 echo "$(OX)\xfer.obj" >> $@
973 echo "$(OX)\xfersetup.obj" >> $@
974 echo "$(OX)\zip.obj" >> $@
975 !if $(FOSSIL_ENABLE_MINIZ)!=0
976 echo "$(OX)\miniz.obj" >> $@
@@ -1155,10 +1154,11 @@
1154 echo "$(SRCDIR)\fossil.confirmer.js" >> $@
1155 echo "$(SRCDIR)\fossil.dom.js" >> $@
1156 echo "$(SRCDIR)\fossil.fetch.js" >> $@
1157 echo "$(SRCDIR)\fossil.page.fileedit.js" >> $@
1158 echo "$(SRCDIR)\fossil.page.forumpost.js" >> $@
1159 echo "$(SRCDIR)\fossil.page.wikiedit.js" >> $@
1160 echo "$(SRCDIR)\fossil.storage.js" >> $@
1161 echo "$(SRCDIR)\fossil.tabs.js" >> $@
1162 echo "$(SRCDIR)\graph.js" >> $@
1163 echo "$(SRCDIR)\href.js" >> $@
1164 echo "$(SRCDIR)\login.js" >> $@
@@ -1184,10 +1184,11 @@
1184 echo "$(SRCDIR)\sounds/d.wav" >> $@
1185 echo "$(SRCDIR)\sounds/e.wav" >> $@
1186 echo "$(SRCDIR)\sounds/f.wav" >> $@
1187 echo "$(SRCDIR)\style.admin_log.css" >> $@
1188 echo "$(SRCDIR)\style.fileedit.css" >> $@
1189 echo "$(SRCDIR)\style.wikiedit.css" >> $@
1190 echo "$(SRCDIR)\tree.js" >> $@
1191 echo "$(SRCDIR)\useredit.js" >> $@
1192 echo "$(SRCDIR)\wiki.wiki" >> $@
1193
1194 "$(OX)\add$O" : "$(OX)\add_.c" "$(OX)\add.h"
@@ -2028,16 +2029,10 @@
2029 $(TCC) /Fo$@ /Fd$(@D)\ -c "$(OX)\winhttp_.c"
2030
2031 "$(OX)\winhttp_.c" : "$(SRCDIR)\winhttp.c"
2032 "$(OBJDIR)\translate$E" $** > $@
2033
 
 
 
 
 
 
2034 "$(OX)\xfer$O" : "$(OX)\xfer_.c" "$(OX)\xfer.h"
2035 $(TCC) /Fo$@ /Fd$(@D)\ -c "$(OX)\xfer_.c"
2036
2037 "$(OX)\xfer_.c" : "$(SRCDIR)\xfer.c"
2038 "$(OBJDIR)\translate$E" $** > $@
@@ -2196,14 +2191,13 @@
2191 "$(OX)\webmail_.c":"$(OX)\webmail.h" \
2192 "$(OX)\wiki_.c":"$(OX)\wiki.h" \
2193 "$(OX)\wikiformat_.c":"$(OX)\wikiformat.h" \
2194 "$(OX)\winfile_.c":"$(OX)\winfile.h" \
2195 "$(OX)\winhttp_.c":"$(OX)\winhttp.h" \
 
2196 "$(OX)\xfer_.c":"$(OX)\xfer.h" \
2197 "$(OX)\xfersetup_.c":"$(OX)\xfersetup.h" \
2198 "$(OX)\zip_.c":"$(OX)\zip.h" \
2199 "$(SRCDIR)\sqlite3.h" \
2200 "$(SRCDIR)\th.h" \
2201 "$(OX)\VERSION.h" \
2202 "$(SRCDIR)\cson_amalgamation.h"
2203 @copy /Y nul: $@
2204
--- www/changes.wiki
+++ www/changes.wiki
@@ -58,10 +58,16 @@
5858
"[/help?cmd=sql|fossil sql]" command supports new output
5959
modes ".mode box" and ".mode json".
6060
* Add the "<tt>obscure()</tt>" SQL function to the
6161
"[/help?cmd=sql|fossil sql]" command.
6262
* [./delta_format.wiki|Delta compression] is now applied to forum edits.
63
+ * The [/help?cmd=/wikiedit|wiki editor] has been modernized and is
64
+ now Ajax-based. The WYSIWYG editing option for Fossil-format wiki
65
+ pages was removed. (Please let us know, via the site's Support menu,
66
+ if that removal unduly impacts you.) This also changes the semantics
67
+ of the wiki "Sandbox": that pseudo-page may be freely edited but
68
+ no longer saved via the UI.
6369
* Countless documentation enhancements.
6470
6571
<a name='v2_11'></a>
6672
<h2>Changes for Version 2.11 (2020-05-25)</h2>
6773
6874
--- www/changes.wiki
+++ www/changes.wiki
@@ -58,10 +58,16 @@
58 "[/help?cmd=sql|fossil sql]" command supports new output
59 modes ".mode box" and ".mode json".
60 * Add the "<tt>obscure()</tt>" SQL function to the
61 "[/help?cmd=sql|fossil sql]" command.
62 * [./delta_format.wiki|Delta compression] is now applied to forum edits.
 
 
 
 
 
 
63 * Countless documentation enhancements.
64
65 <a name='v2_11'></a>
66 <h2>Changes for Version 2.11 (2020-05-25)</h2>
67
68
--- www/changes.wiki
+++ www/changes.wiki
@@ -58,10 +58,16 @@
58 "[/help?cmd=sql|fossil sql]" command supports new output
59 modes ".mode box" and ".mode json".
60 * Add the "<tt>obscure()</tt>" SQL function to the
61 "[/help?cmd=sql|fossil sql]" command.
62 * [./delta_format.wiki|Delta compression] is now applied to forum edits.
63 * The [/help?cmd=/wikiedit|wiki editor] has been modernized and is
64 now Ajax-based. The WYSIWYG editing option for Fossil-format wiki
65 pages was removed. (Please let us know, via the site's Support menu,
66 if that removal unduly impacts you.) This also changes the semantics
67 of the wiki "Sandbox": that pseudo-page may be freely edited but
68 no longer saved via the UI.
69 * Countless documentation enhancements.
70
71 <a name='v2_11'></a>
72 <h2>Changes for Version 2.11 (2020-05-25)</h2>
73
74
--- www/changes.wiki
+++ www/changes.wiki
@@ -58,10 +58,16 @@
5858
"[/help?cmd=sql|fossil sql]" command supports new output
5959
modes ".mode box" and ".mode json".
6060
* Add the "<tt>obscure()</tt>" SQL function to the
6161
"[/help?cmd=sql|fossil sql]" command.
6262
* [./delta_format.wiki|Delta compression] is now applied to forum edits.
63
+ * The [/help?cmd=/wikiedit|wiki editor] has been modernized and is
64
+ now Ajax-based. The WYSIWYG editing option for Fossil-format wiki
65
+ pages was removed. (Please let us know, via the site's Support menu,
66
+ if that removal unduly impacts you.) This also changes the semantics
67
+ of the wiki "Sandbox": that pseudo-page may be freely edited but
68
+ no longer saved via the UI.
6369
* Countless documentation enhancements.
6470
6571
<a name='v2_11'></a>
6672
<h2>Changes for Version 2.11 (2020-05-25)</h2>
6773
6874
--- www/changes.wiki
+++ www/changes.wiki
@@ -58,10 +58,16 @@
58 "[/help?cmd=sql|fossil sql]" command supports new output
59 modes ".mode box" and ".mode json".
60 * Add the "<tt>obscure()</tt>" SQL function to the
61 "[/help?cmd=sql|fossil sql]" command.
62 * [./delta_format.wiki|Delta compression] is now applied to forum edits.
 
 
 
 
 
 
63 * Countless documentation enhancements.
64
65 <a name='v2_11'></a>
66 <h2>Changes for Version 2.11 (2020-05-25)</h2>
67
68
--- www/changes.wiki
+++ www/changes.wiki
@@ -58,10 +58,16 @@
58 "[/help?cmd=sql|fossil sql]" command supports new output
59 modes ".mode box" and ".mode json".
60 * Add the "<tt>obscure()</tt>" SQL function to the
61 "[/help?cmd=sql|fossil sql]" command.
62 * [./delta_format.wiki|Delta compression] is now applied to forum edits.
63 * The [/help?cmd=/wikiedit|wiki editor] has been modernized and is
64 now Ajax-based. The WYSIWYG editing option for Fossil-format wiki
65 pages was removed. (Please let us know, via the site's Support menu,
66 if that removal unduly impacts you.) This also changes the semantics
67 of the wiki "Sandbox": that pseudo-page may be freely edited but
68 no longer saved via the UI.
69 * Countless documentation enhancements.
70
71 <a name='v2_11'></a>
72 <h2>Changes for Version 2.11 (2020-05-25)</h2>
73
74

Keyboard Shortcuts

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