Fossil SCM
Merged in the Ajax-based /wikiedit reimplementation.
Commit
19f275352230d801df693e344e1a70dd7e906f421b9a2d106351fb27f0d667be
Parent
bf1984428f6eb4c…
24 files changed
+13
-1
+173
+25
-18
+25
-18
+4
-8
+1
-1
+2
-17
+176
+176
-1
+27
-12
+2
-12
-1
+1
-11
+46
-11
+46
-11
-181
+6
+640
-202
-328
+4
-10
+2
-12
+4
-10
+6
+6
~
src/ajax.c
~
src/default.css
~
src/fileedit.c
~
src/fileedit.c
~
src/forum.c
~
src/forum.js
~
src/fossil.page.fileedit.js
+
src/fossil.page.wikiedit.js
~
src/fossil.page.wikiedit.js
~
src/main.c
~
src/main.mk
~
src/makemake.tcl
~
src/setup.c
~
src/style.c
~
src/style.c
~
src/style.fileedit.css
~
src/style.wikiedit.css
~
src/wiki.c
-
src/wysiwyg.c
~
win/Makefile.dmc
~
win/Makefile.mingw
~
win/Makefile.msc
~
www/changes.wiki
~
www/changes.wiki
+13
-1
| --- src/ajax.c | ||
| +++ src/ajax.c | ||
| @@ -163,10 +163,20 @@ | ||
| 163 | 163 | }else{ |
| 164 | 164 | CX("<pre class='udiff'>%b</pre>",&out); |
| 165 | 165 | } |
| 166 | 166 | blob_reset(&out); |
| 167 | 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 | +} | |
| 168 | 178 | |
| 169 | 179 | /* |
| 170 | 180 | ** Helper for /ajax routes. Clears the CGI content buffer, sets an |
| 171 | 181 | ** HTTP error status code, and queues up a JSON response in the form |
| 172 | 182 | ** of an object: |
| @@ -323,10 +333,11 @@ | ||
| 323 | 333 | if(zRenderMode!=0){ |
| 324 | 334 | cgi_printf_header("x-ajax-render-mode: %s\r\n", zRenderMode); |
| 325 | 335 | } |
| 326 | 336 | } |
| 327 | 337 | |
| 338 | +#if INTERFACE | |
| 328 | 339 | /* |
| 329 | 340 | ** Internal mapping of ajax sub-route names to various metadata. |
| 330 | 341 | */ |
| 331 | 342 | struct AjaxRoute { |
| 332 | 343 | const char *zName; /* Name part of the route after "ajax/" */ |
| @@ -334,16 +345,17 @@ | ||
| 334 | 345 | int bWriteMode; /* True if requires write mode */ |
| 335 | 346 | int bPost; /* True if requires POST (i.e. CSRF |
| 336 | 347 | ** verification) */ |
| 337 | 348 | }; |
| 338 | 349 | typedef struct AjaxRoute AjaxRoute; |
| 350 | +#endif /*INTERFACE*/ | |
| 339 | 351 | |
| 340 | 352 | /* |
| 341 | 353 | ** Comparison function for bsearch() for searching an AjaxRoute |
| 342 | 354 | ** list for a matching name. |
| 343 | 355 | */ |
| 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){ | |
| 345 | 357 | const AjaxRoute * rA = (const AjaxRoute*)a; |
| 346 | 358 | const AjaxRoute * rB = (const AjaxRoute*)b; |
| 347 | 359 | return fossil_strcmp(rA->zName, rB->zName); |
| 348 | 360 | } |
| 349 | 361 | |
| 350 | 362 |
| --- 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 |
+173
| --- src/default.css | ||
| +++ src/default.css | ||
| @@ -919,5 +919,178 @@ | ||
| 919 | 919 | } |
| 920 | 920 | img { |
| 921 | 921 | max-width: 100%; |
| 922 | 922 | height: auto; |
| 923 | 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 | +} | |
| 924 | 1097 |
| --- 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 @@ | ||
| 1630 | 1630 | /* will be moved into the tab container via JS */); |
| 1631 | 1631 | |
| 1632 | 1632 | /* Main tab container... */ |
| 1633 | 1633 | CX("<div id='fileedit-tabs' class='tab-container'></div>"); |
| 1634 | 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 | + | |
| 1635 | 1638 | /***** File/version info tab *****/ |
| 1636 | 1639 | { |
| 1637 | 1640 | CX("<div id='fileedit-tab-fileselect' " |
| 1638 | 1641 | "data-tab-parent='fileedit-tabs' " |
| 1639 | - "data-tab-label='File Info & Selection'" | |
| 1642 | + "data-tab-label='File Info & Selection' " | |
| 1643 | + "class='hidden'" | |
| 1640 | 1644 | ">"); |
| 1641 | 1645 | CX("<fieldset id='file-version-details'>" |
| 1642 | 1646 | "<legend>File/Version</legend>" |
| 1643 | 1647 | "<div>No file loaded.</div>" |
| 1644 | 1648 | "</fieldset>"); |
| @@ -1649,11 +1653,12 @@ | ||
| 1649 | 1653 | |
| 1650 | 1654 | /******* Content tab *******/ |
| 1651 | 1655 | { |
| 1652 | 1656 | CX("<div id='fileedit-tab-content' " |
| 1653 | 1657 | "data-tab-parent='fileedit-tabs' " |
| 1654 | - "data-tab-label='File Content'" | |
| 1658 | + "data-tab-label='File Content' " | |
| 1659 | + "class='hidden'" | |
| 1655 | 1660 | ">"); |
| 1656 | 1661 | CX("<div class='flex-container flex-row child-gap-small'>"); |
| 1657 | 1662 | CX("<button class='fileedit-content-reload confirmer' " |
| 1658 | 1663 | "title='Reload the file from the server, discarding " |
| 1659 | 1664 | "any local edits. To help avoid accidental loss of " |
| @@ -1679,11 +1684,12 @@ | ||
| 1679 | 1684 | |
| 1680 | 1685 | /****** Preview tab ******/ |
| 1681 | 1686 | { |
| 1682 | 1687 | CX("<div id='fileedit-tab-preview' " |
| 1683 | 1688 | "data-tab-parent='fileedit-tabs' " |
| 1684 | - "data-tab-label='Preview'" | |
| 1689 | + "data-tab-label='Preview' " | |
| 1690 | + "class='hidden'" | |
| 1685 | 1691 | ">"); |
| 1686 | 1692 | CX("<div class='fileedit-options flex-container flex-row'>"); |
| 1687 | 1693 | CX("<button id='btn-preview-refresh' " |
| 1688 | 1694 | "data-f-preview-from='fileContent' " |
| 1689 | 1695 | /* ^^^ fossil.page[methodName]() OR text source elem ID, |
| @@ -1741,11 +1747,12 @@ | ||
| 1741 | 1747 | |
| 1742 | 1748 | /****** Diff tab ******/ |
| 1743 | 1749 | { |
| 1744 | 1750 | CX("<div id='fileedit-tab-diff' " |
| 1745 | 1751 | "data-tab-parent='fileedit-tabs' " |
| 1746 | - "data-tab-label='Diff'" | |
| 1752 | + "data-tab-label='Diff' " | |
| 1753 | + "class='hidden'" | |
| 1747 | 1754 | ">"); |
| 1748 | 1755 | |
| 1749 | 1756 | CX("<div class='fileedit-options flex-container flex-row' " |
| 1750 | 1757 | "id='fileedit-tab-diff-buttons'>"); |
| 1751 | 1758 | CX("<button class='sbs'>Side-by-side</button>" |
| @@ -1773,11 +1780,12 @@ | ||
| 1773 | 1780 | } |
| 1774 | 1781 | |
| 1775 | 1782 | /****** Commit ******/ |
| 1776 | 1783 | CX("<div id='fileedit-tab-commit' " |
| 1777 | 1784 | "data-tab-parent='fileedit-tabs' " |
| 1778 | - "data-tab-label='Commit'" | |
| 1785 | + "data-tab-label='Commit' " | |
| 1786 | + "class='hidden'" | |
| 1779 | 1787 | ">"); |
| 1780 | 1788 | { |
| 1781 | 1789 | /******* Commit flags/options *******/ |
| 1782 | 1790 | CX("<div class='fileedit-options flex-container flex-row'>"); |
| 1783 | 1791 | style_labeled_checkbox("cb-dry-run", |
| @@ -1894,11 +1902,12 @@ | ||
| 1894 | 1902 | CX("</div>"/*#fileedit-tab-commit*/); |
| 1895 | 1903 | |
| 1896 | 1904 | /****** Help/Tips ******/ |
| 1897 | 1905 | CX("<div id='fileedit-tab-help' " |
| 1898 | 1906 | "data-tab-parent='fileedit-tabs' " |
| 1899 | - "data-tab-label='Help'" | |
| 1907 | + "data-tab-label='Help' " | |
| 1908 | + "class='hidden'" | |
| 1900 | 1909 | ">"); |
| 1901 | 1910 | { |
| 1902 | 1911 | CX("<h1>Help & Tips</h1>"); |
| 1903 | 1912 | CX("<ul>"); |
| 1904 | 1913 | CX("<li><strong>Only files matching the <code>fileedit-glob</code> " |
| @@ -1949,28 +1958,26 @@ | ||
| 1949 | 1958 | blob_appendf(&endScript,");\n"); |
| 1950 | 1959 | } |
| 1951 | 1960 | |
| 1952 | 1961 | blob_reset(&err); |
| 1953 | 1962 | 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(); | |
| 1962 | 1968 | /* |
| 1963 | 1969 | ** Set up a JS-side mapping of the AJAX_RENDER_xyz values. This is |
| 1964 | 1970 | ** 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. | |
| 1967 | 1975 | */ |
| 1968 | - builtin_fulfill_js_requests(); | |
| 1969 | 1976 | ajax_emit_js_preview_modes(1); |
| 1970 | - | |
| 1971 | 1977 | builtin_request_js("fossil.page.fileedit.js"); |
| 1978 | + builtin_fulfill_js_requests(); | |
| 1972 | 1979 | if(blob_size(&endScript)>0){ |
| 1973 | 1980 | style_emit_script_tag(0,0); |
| 1974 | 1981 | CX("\n(function(){\n"); |
| 1975 | 1982 | CX("try{\n%b}\n" |
| 1976 | 1983 | "catch(e){" |
| 1977 | 1984 |
| --- 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 & 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 & 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 & 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 & 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 @@ | ||
| 1630 | 1630 | /* will be moved into the tab container via JS */); |
| 1631 | 1631 | |
| 1632 | 1632 | /* Main tab container... */ |
| 1633 | 1633 | CX("<div id='fileedit-tabs' class='tab-container'></div>"); |
| 1634 | 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 | + | |
| 1635 | 1638 | /***** File/version info tab *****/ |
| 1636 | 1639 | { |
| 1637 | 1640 | CX("<div id='fileedit-tab-fileselect' " |
| 1638 | 1641 | "data-tab-parent='fileedit-tabs' " |
| 1639 | - "data-tab-label='File Info & Selection'" | |
| 1642 | + "data-tab-label='File Info & Selection' " | |
| 1643 | + "class='hidden'" | |
| 1640 | 1644 | ">"); |
| 1641 | 1645 | CX("<fieldset id='file-version-details'>" |
| 1642 | 1646 | "<legend>File/Version</legend>" |
| 1643 | 1647 | "<div>No file loaded.</div>" |
| 1644 | 1648 | "</fieldset>"); |
| @@ -1649,11 +1653,12 @@ | ||
| 1649 | 1653 | |
| 1650 | 1654 | /******* Content tab *******/ |
| 1651 | 1655 | { |
| 1652 | 1656 | CX("<div id='fileedit-tab-content' " |
| 1653 | 1657 | "data-tab-parent='fileedit-tabs' " |
| 1654 | - "data-tab-label='File Content'" | |
| 1658 | + "data-tab-label='File Content' " | |
| 1659 | + "class='hidden'" | |
| 1655 | 1660 | ">"); |
| 1656 | 1661 | CX("<div class='flex-container flex-row child-gap-small'>"); |
| 1657 | 1662 | CX("<button class='fileedit-content-reload confirmer' " |
| 1658 | 1663 | "title='Reload the file from the server, discarding " |
| 1659 | 1664 | "any local edits. To help avoid accidental loss of " |
| @@ -1679,11 +1684,12 @@ | ||
| 1679 | 1684 | |
| 1680 | 1685 | /****** Preview tab ******/ |
| 1681 | 1686 | { |
| 1682 | 1687 | CX("<div id='fileedit-tab-preview' " |
| 1683 | 1688 | "data-tab-parent='fileedit-tabs' " |
| 1684 | - "data-tab-label='Preview'" | |
| 1689 | + "data-tab-label='Preview' " | |
| 1690 | + "class='hidden'" | |
| 1685 | 1691 | ">"); |
| 1686 | 1692 | CX("<div class='fileedit-options flex-container flex-row'>"); |
| 1687 | 1693 | CX("<button id='btn-preview-refresh' " |
| 1688 | 1694 | "data-f-preview-from='fileContent' " |
| 1689 | 1695 | /* ^^^ fossil.page[methodName]() OR text source elem ID, |
| @@ -1741,11 +1747,12 @@ | ||
| 1741 | 1747 | |
| 1742 | 1748 | /****** Diff tab ******/ |
| 1743 | 1749 | { |
| 1744 | 1750 | CX("<div id='fileedit-tab-diff' " |
| 1745 | 1751 | "data-tab-parent='fileedit-tabs' " |
| 1746 | - "data-tab-label='Diff'" | |
| 1752 | + "data-tab-label='Diff' " | |
| 1753 | + "class='hidden'" | |
| 1747 | 1754 | ">"); |
| 1748 | 1755 | |
| 1749 | 1756 | CX("<div class='fileedit-options flex-container flex-row' " |
| 1750 | 1757 | "id='fileedit-tab-diff-buttons'>"); |
| 1751 | 1758 | CX("<button class='sbs'>Side-by-side</button>" |
| @@ -1773,11 +1780,12 @@ | ||
| 1773 | 1780 | } |
| 1774 | 1781 | |
| 1775 | 1782 | /****** Commit ******/ |
| 1776 | 1783 | CX("<div id='fileedit-tab-commit' " |
| 1777 | 1784 | "data-tab-parent='fileedit-tabs' " |
| 1778 | - "data-tab-label='Commit'" | |
| 1785 | + "data-tab-label='Commit' " | |
| 1786 | + "class='hidden'" | |
| 1779 | 1787 | ">"); |
| 1780 | 1788 | { |
| 1781 | 1789 | /******* Commit flags/options *******/ |
| 1782 | 1790 | CX("<div class='fileedit-options flex-container flex-row'>"); |
| 1783 | 1791 | style_labeled_checkbox("cb-dry-run", |
| @@ -1894,11 +1902,12 @@ | ||
| 1894 | 1902 | CX("</div>"/*#fileedit-tab-commit*/); |
| 1895 | 1903 | |
| 1896 | 1904 | /****** Help/Tips ******/ |
| 1897 | 1905 | CX("<div id='fileedit-tab-help' " |
| 1898 | 1906 | "data-tab-parent='fileedit-tabs' " |
| 1899 | - "data-tab-label='Help'" | |
| 1907 | + "data-tab-label='Help' " | |
| 1908 | + "class='hidden'" | |
| 1900 | 1909 | ">"); |
| 1901 | 1910 | { |
| 1902 | 1911 | CX("<h1>Help & Tips</h1>"); |
| 1903 | 1912 | CX("<ul>"); |
| 1904 | 1913 | CX("<li><strong>Only files matching the <code>fileedit-glob</code> " |
| @@ -1949,28 +1958,26 @@ | ||
| 1949 | 1958 | blob_appendf(&endScript,");\n"); |
| 1950 | 1959 | } |
| 1951 | 1960 | |
| 1952 | 1961 | blob_reset(&err); |
| 1953 | 1962 | 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(); | |
| 1962 | 1968 | /* |
| 1963 | 1969 | ** Set up a JS-side mapping of the AJAX_RENDER_xyz values. This is |
| 1964 | 1970 | ** 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. | |
| 1967 | 1975 | */ |
| 1968 | - builtin_fulfill_js_requests(); | |
| 1969 | 1976 | ajax_emit_js_preview_modes(1); |
| 1970 | - | |
| 1971 | 1977 | builtin_request_js("fossil.page.fileedit.js"); |
| 1978 | + builtin_fulfill_js_requests(); | |
| 1972 | 1979 | if(blob_size(&endScript)>0){ |
| 1973 | 1980 | style_emit_script_tag(0,0); |
| 1974 | 1981 | CX("\n(function(){\n"); |
| 1975 | 1982 | CX("try{\n%b}\n" |
| 1976 | 1983 | "catch(e){" |
| 1977 | 1984 |
| --- 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 & 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 & 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 & 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 & 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 @@ | ||
| 749 | 749 | forumthread_delete(pThread); |
| 750 | 750 | return target; |
| 751 | 751 | } |
| 752 | 752 | |
| 753 | 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. | |
| 754 | +** Emits all JS code required by /forumpost. | |
| 759 | 755 | */ |
| 760 | -static void forum_emit_page_js(){ | |
| 756 | +static void forumpost_emit_page_js(){ | |
| 761 | 757 | static int once = 0; |
| 762 | 758 | if(0==once){ |
| 763 | 759 | once = 1; |
| 760 | + style_emit_script_fossil_bootstrap(1); | |
| 764 | 761 | builtin_request_js("forum.js"); |
| 765 | - style_emit_script_fossil_bootstrap(0); | |
| 766 | 762 | builtin_request_js("fossil.dom.js"); |
| 767 | 763 | builtin_request_js("fossil.page.forumpost.js"); |
| 768 | 764 | } |
| 769 | 765 | } |
| 770 | 766 | |
| @@ -894,11 +890,11 @@ | ||
| 894 | 890 | }else{ |
| 895 | 891 | style_submenu_element("Chronological", "%R/%s/%s?t=c", g.zPath, zName); |
| 896 | 892 | style_submenu_element("Unformatted", "%R/%s/%s?t=r", g.zPath, zName); |
| 897 | 893 | forum_display_hierarchical(froot, fpid); |
| 898 | 894 | } |
| 899 | - forum_emit_page_js(); | |
| 895 | + forumpost_emit_page_js(); | |
| 900 | 896 | style_footer(); |
| 901 | 897 | } |
| 902 | 898 | |
| 903 | 899 | /* |
| 904 | 900 | ** Return true if a forum post should be moderated. |
| 905 | 901 |
| --- 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 @@ | ||
| 14 | 14 | var h = x[0].scrollHeight; |
| 15 | 15 | var y = absoluteY(x[0]); |
| 16 | 16 | if( w>h ) y = y + (h-w)/2; |
| 17 | 17 | if( y>0 ) window.scrollTo(0, y); |
| 18 | 18 | } |
| 19 | -})() | |
| 19 | +})(); | |
| 20 | 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/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 |
+2
-17
| --- src/fossil.page.fileedit.js | ||
| +++ src/fossil.page.fileedit.js | ||
| @@ -121,11 +121,11 @@ | ||
| 121 | 121 | and that would be horribly inefficient (meaning "battery-consuming" |
| 122 | 122 | on mobile devices). |
| 123 | 123 | */ |
| 124 | 124 | const $stash = { |
| 125 | 125 | keys: { |
| 126 | - index: F.page.name+'/index' | |
| 126 | + index: F.page.name+'.index' | |
| 127 | 127 | }, |
| 128 | 128 | /** |
| 129 | 129 | index: { |
| 130 | 130 | "CHECKIN_HASH:FILENAME": {file info w/o content} |
| 131 | 131 | ... |
| @@ -149,27 +149,12 @@ | ||
| 149 | 149 | /** Returns the index object, fetching it from the stash or creating |
| 150 | 150 | it anew on the first call. */ |
| 151 | 151 | getIndex: function(){ |
| 152 | 152 | if(!this.index){ |
| 153 | 153 | this.index = F.storage.getJSON( |
| 154 | - this.keys.index, undefined | |
| 154 | + this.keys.index, {} | |
| 155 | 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 | 156 | } |
| 172 | 157 | return this.index; |
| 173 | 158 | }, |
| 174 | 159 | _fireStashEvent: function(){ |
| 175 | 160 | if(this._disableNextEvent) delete this._disableNextEvent; |
| 176 | 161 | |
| 177 | 162 | 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 |
+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 | |
| @@ -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 |
+176
-1
| --- 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 @@ | ||
| 2095 | 2095 | ** REPO for a check-in or ticket that matches the |
| 2096 | 2096 | ** value of "name", then redirect to URL. There |
| 2097 | 2097 | ** can be multiple "redirect:" lines that are |
| 2098 | 2098 | ** processed in order. If the REPO is "*", then |
| 2099 | 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. | |
| 2100 | 2104 | ** |
| 2101 | 2105 | ** Most CGI files contain only a "repository:" line. It is uncommon to |
| 2102 | 2106 | ** use any other option. |
| 2103 | 2107 | ** |
| 2104 | 2108 | ** See also: http, server, winsrv |
| @@ -2274,15 +2278,17 @@ | ||
| 2274 | 2278 | continue; |
| 2275 | 2279 | } |
| 2276 | 2280 | if( blob_eq(&key, "jsmode:") && blob_token(&line, &value) ){ |
| 2277 | 2281 | /* jsmode: MODE |
| 2278 | 2282 | ** |
| 2279 | - ** Change how javascript resources are delivered with each HTML | |
| 2283 | + ** Change how JavaScript resources are delivered with each HTML | |
| 2280 | 2284 | ** page. MODE is "inline" to put all JS inline, or "separate" to |
| 2281 | 2285 | ** cause each JS file to be requested using a separate HTTP request, |
| 2282 | 2286 | ** 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. | |
| 2284 | 2290 | */ |
| 2285 | 2291 | builtin_set_js_delivery_mode(blob_str(&value),0); |
| 2286 | 2292 | blob_reset(&value); |
| 2287 | 2293 | continue; |
| 2288 | 2294 | } |
| @@ -2468,18 +2474,23 @@ | ||
| 2468 | 2474 | ** --files GLOB comma-separate glob patterns for static file to serve |
| 2469 | 2475 | ** --host NAME specify hostname of the server |
| 2470 | 2476 | ** --https signal a request coming in via https |
| 2471 | 2477 | ** --in FILE Take input from FILE instead of standard input |
| 2472 | 2478 | ** --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. | |
| 2474 | 2480 | ** 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. | |
| 2477 | 2483 | ** 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. | |
| 2481 | 2492 | ** --localauth enable automatic login for local connections |
| 2482 | 2493 | ** --nocompress do not compress HTTP replies |
| 2483 | 2494 | ** --nodelay omit backoffice processing if it would delay process exit |
| 2484 | 2495 | ** --nojail drop root privilege but do not enter the chroot jail |
| 2485 | 2496 | ** --nossl signal that no SSL connections are available |
| @@ -2736,18 +2747,22 @@ | ||
| 2736 | 2747 | ** --files GLOBLIST Comma-separated list of glob patterns for static files |
| 2737 | 2748 | ** --localauth enable automatic login for requests from localhost |
| 2738 | 2749 | ** --localhost listen on 127.0.0.1 only (always true for "ui") |
| 2739 | 2750 | ** --https Indicates that the input is coming through a reverse |
| 2740 | 2751 | ** 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. | |
| 2742 | 2753 | ** Mode can be one of: |
| 2743 | -** inline All javascript is inserted inline at | |
| 2754 | +** inline All JavaScript is inserted inline at | |
| 2744 | 2755 | ** the end of the HTML file. |
| 2745 | 2756 | ** separate Separate HTTP requests are made for |
| 2746 | -** each javascript file. | |
| 2757 | +** each JavaScript file. | |
| 2747 | 2758 | ** 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. | |
| 2749 | 2764 | ** --max-latency N Do not let any single HTTP request run for more than N |
| 2750 | 2765 | ** seconds (only works on unix) |
| 2751 | 2766 | ** --nocompress Do not compress HTTP replies |
| 2752 | 2767 | ** --nojail Drop root privileges but do not enter the chroot jail |
| 2753 | 2768 | ** --nossl signal that no SSL connections are available (Always |
| 2754 | 2769 |
| --- 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 @@ | ||
| 154 | 154 | $(SRCDIR)/webmail.c \ |
| 155 | 155 | $(SRCDIR)/wiki.c \ |
| 156 | 156 | $(SRCDIR)/wikiformat.c \ |
| 157 | 157 | $(SRCDIR)/winfile.c \ |
| 158 | 158 | $(SRCDIR)/winhttp.c \ |
| 159 | - $(SRCDIR)/wysiwyg.c \ | |
| 160 | 159 | $(SRCDIR)/xfer.c \ |
| 161 | 160 | $(SRCDIR)/xfersetup.c \ |
| 162 | 161 | $(SRCDIR)/zip.c |
| 163 | 162 | |
| 164 | 163 | EXTRA_FILES = \ |
| @@ -228,10 +227,11 @@ | ||
| 228 | 227 | $(SRCDIR)/fossil.confirmer.js \ |
| 229 | 228 | $(SRCDIR)/fossil.dom.js \ |
| 230 | 229 | $(SRCDIR)/fossil.fetch.js \ |
| 231 | 230 | $(SRCDIR)/fossil.page.fileedit.js \ |
| 232 | 231 | $(SRCDIR)/fossil.page.forumpost.js \ |
| 232 | + $(SRCDIR)/fossil.page.wikiedit.js \ | |
| 233 | 233 | $(SRCDIR)/fossil.storage.js \ |
| 234 | 234 | $(SRCDIR)/fossil.tabs.js \ |
| 235 | 235 | $(SRCDIR)/graph.js \ |
| 236 | 236 | $(SRCDIR)/href.js \ |
| 237 | 237 | $(SRCDIR)/login.js \ |
| @@ -257,10 +257,11 @@ | ||
| 257 | 257 | $(SRCDIR)/sounds/d.wav \ |
| 258 | 258 | $(SRCDIR)/sounds/e.wav \ |
| 259 | 259 | $(SRCDIR)/sounds/f.wav \ |
| 260 | 260 | $(SRCDIR)/style.admin_log.css \ |
| 261 | 261 | $(SRCDIR)/style.fileedit.css \ |
| 262 | + $(SRCDIR)/style.wikiedit.css \ | |
| 262 | 263 | $(SRCDIR)/tree.js \ |
| 263 | 264 | $(SRCDIR)/useredit.js \ |
| 264 | 265 | $(SRCDIR)/wiki.wiki |
| 265 | 266 | |
| 266 | 267 | TRANS_SRC = \ |
| @@ -402,11 +403,10 @@ | ||
| 402 | 403 | $(OBJDIR)/webmail_.c \ |
| 403 | 404 | $(OBJDIR)/wiki_.c \ |
| 404 | 405 | $(OBJDIR)/wikiformat_.c \ |
| 405 | 406 | $(OBJDIR)/winfile_.c \ |
| 406 | 407 | $(OBJDIR)/winhttp_.c \ |
| 407 | - $(OBJDIR)/wysiwyg_.c \ | |
| 408 | 408 | $(OBJDIR)/xfer_.c \ |
| 409 | 409 | $(OBJDIR)/xfersetup_.c \ |
| 410 | 410 | $(OBJDIR)/zip_.c |
| 411 | 411 | |
| 412 | 412 | OBJ = \ |
| @@ -548,11 +548,10 @@ | ||
| 548 | 548 | $(OBJDIR)/webmail.o \ |
| 549 | 549 | $(OBJDIR)/wiki.o \ |
| 550 | 550 | $(OBJDIR)/wikiformat.o \ |
| 551 | 551 | $(OBJDIR)/winfile.o \ |
| 552 | 552 | $(OBJDIR)/winhttp.o \ |
| 553 | - $(OBJDIR)/wysiwyg.o \ | |
| 554 | 553 | $(OBJDIR)/xfer.o \ |
| 555 | 554 | $(OBJDIR)/xfersetup.o \ |
| 556 | 555 | $(OBJDIR)/zip.o |
| 557 | 556 | all: $(OBJDIR) $(APPNAME) |
| 558 | 557 | |
| @@ -884,11 +883,10 @@ | ||
| 884 | 883 | $(OBJDIR)/webmail_.c:$(OBJDIR)/webmail.h \ |
| 885 | 884 | $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h \ |
| 886 | 885 | $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h \ |
| 887 | 886 | $(OBJDIR)/winfile_.c:$(OBJDIR)/winfile.h \ |
| 888 | 887 | $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h \ |
| 889 | - $(OBJDIR)/wysiwyg_.c:$(OBJDIR)/wysiwyg.h \ | |
| 890 | 888 | $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h \ |
| 891 | 889 | $(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h \ |
| 892 | 890 | $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h \ |
| 893 | 891 | $(SRCDIR)/sqlite3.h \ |
| 894 | 892 | $(SRCDIR)/th.h \ |
| @@ -2015,18 +2013,10 @@ | ||
| 2015 | 2013 | $(OBJDIR)/winhttp.o: $(OBJDIR)/winhttp_.c $(OBJDIR)/winhttp.h $(SRCDIR)/config.h |
| 2016 | 2014 | $(XTCC) -o $(OBJDIR)/winhttp.o -c $(OBJDIR)/winhttp_.c |
| 2017 | 2015 | |
| 2018 | 2016 | $(OBJDIR)/winhttp.h: $(OBJDIR)/headers |
| 2019 | 2017 | |
| 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 | 2018 | $(OBJDIR)/xfer_.c: $(SRCDIR)/xfer.c $(OBJDIR)/translate |
| 2029 | 2019 | $(OBJDIR)/translate $(SRCDIR)/xfer.c >$@ |
| 2030 | 2020 | |
| 2031 | 2021 | $(OBJDIR)/xfer.o: $(OBJDIR)/xfer_.c $(OBJDIR)/xfer.h $(SRCDIR)/config.h |
| 2032 | 2022 | $(XTCC) -o $(OBJDIR)/xfer.o -c $(OBJDIR)/xfer_.c |
| 2033 | 2023 |
| --- 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 |
-1
| --- src/makemake.tcl | ||
| +++ src/makemake.tcl | ||
| @@ -164,11 +164,10 @@ | ||
| 164 | 164 | webmail |
| 165 | 165 | wiki |
| 166 | 166 | wikiformat |
| 167 | 167 | winfile |
| 168 | 168 | winhttp |
| 169 | - wysiwyg | |
| 170 | 169 | xfer |
| 171 | 170 | xfersetup |
| 172 | 171 | zip |
| 173 | 172 | http_ssl |
| 174 | 173 | } |
| 175 | 174 |
| --- 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 @@ | ||
| 1077 | 1077 | @ in forum posts, make this setting be "<b>btw</b>". The default is an |
| 1078 | 1078 | @ empty string which means that Fossil never allows Markdown documents |
| 1079 | 1079 | @ to generate unsafe HTML. |
| 1080 | 1080 | @ (Property: "safe-html")</p> |
| 1081 | 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 | 1082 | onoff_attribute("Use HTML as wiki markup language", |
| 1091 | 1083 | "wiki-use-html", "wiki-use-html", 0, 0); |
| 1092 | 1084 | @ <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> | |
| 1096 | 1086 | @ <p><strong>CAUTION:</strong> when |
| 1097 | 1087 | @ enabling, <i>all</i> HTML tags and attributes are accepted in the wiki. |
| 1098 | 1088 | @ No sanitization is done. This means that it is very possible for malicious |
| 1099 | 1089 | @ users to inject dangerous HTML, CSS and JavaScript code into your wiki.</p> |
| 1100 | 1090 | @ <p>This should <strong>only</strong> be enabled when wiki editing is limited |
| 1101 | 1091 |
| --- 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 @@ | ||
| 1423 | 1423 | ** bootstrap the window.fossil object, using the built-in file |
| 1424 | 1424 | ** fossil.bootstrap.js (not to be confused with bootstrap.js). |
| 1425 | 1425 | ** |
| 1426 | 1426 | ** Subsequent calls are no-ops. |
| 1427 | 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. | |
| 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(). | |
| 1435 | 1436 | */ |
| 1436 | -void style_emit_script_fossil_bootstrap(int asInline){ | |
| 1437 | +void style_emit_script_fossil_bootstrap(int addScriptTag){ | |
| 1437 | 1438 | static int once = 0; |
| 1438 | 1439 | if(0==once++){ |
| 1439 | 1440 | /* Set up the generic/app-agnostic parts of window.fossil |
| 1440 | 1441 | ** which require C-level state... */ |
| 1441 | - style_emit_script_tag(0,0); | |
| 1442 | + if(addScriptTag!=0){ | |
| 1443 | + style_emit_script_tag(0,0); | |
| 1444 | + } | |
| 1442 | 1445 | CX("(function(){\n" |
| 1443 | 1446 | "if(!window.fossil) window.fossil={};\n" |
| 1444 | 1447 | "window.fossil.version = %!j;\n" |
| 1445 | 1448 | /* fossil.rootPath is the top-most CGI/server path, |
| 1446 | 1449 | ** including a trailing slash. */ |
| @@ -1465,13 +1468,15 @@ | ||
| 1465 | 1468 | */ |
| 1466 | 1469 | CX("window.fossil.page = {" |
| 1467 | 1470 | "name:\"%T\"" |
| 1468 | 1471 | "};\n", g.zPath); |
| 1469 | 1472 | 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 | |
| 1471 | 1477 | ** C-runtime state... */ |
| 1472 | - style_emit_script_tag(1,0); | |
| 1473 | 1478 | builtin_request_js("fossil.bootstrap.js"); |
| 1474 | 1479 | } |
| 1475 | 1480 | } |
| 1476 | 1481 | |
| 1477 | 1482 | /* |
| @@ -1501,5 +1506,35 @@ | ||
| 1501 | 1506 | } |
| 1502 | 1507 | }else{ |
| 1503 | 1508 | CX("</script>\n"); |
| 1504 | 1509 | } |
| 1505 | 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 | +} | |
| 1506 | 1541 |
| --- 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 @@ | ||
| 1423 | 1423 | ** bootstrap the window.fossil object, using the built-in file |
| 1424 | 1424 | ** fossil.bootstrap.js (not to be confused with bootstrap.js). |
| 1425 | 1425 | ** |
| 1426 | 1426 | ** Subsequent calls are no-ops. |
| 1427 | 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. | |
| 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(). | |
| 1435 | 1436 | */ |
| 1436 | -void style_emit_script_fossil_bootstrap(int asInline){ | |
| 1437 | +void style_emit_script_fossil_bootstrap(int addScriptTag){ | |
| 1437 | 1438 | static int once = 0; |
| 1438 | 1439 | if(0==once++){ |
| 1439 | 1440 | /* Set up the generic/app-agnostic parts of window.fossil |
| 1440 | 1441 | ** which require C-level state... */ |
| 1441 | - style_emit_script_tag(0,0); | |
| 1442 | + if(addScriptTag!=0){ | |
| 1443 | + style_emit_script_tag(0,0); | |
| 1444 | + } | |
| 1442 | 1445 | CX("(function(){\n" |
| 1443 | 1446 | "if(!window.fossil) window.fossil={};\n" |
| 1444 | 1447 | "window.fossil.version = %!j;\n" |
| 1445 | 1448 | /* fossil.rootPath is the top-most CGI/server path, |
| 1446 | 1449 | ** including a trailing slash. */ |
| @@ -1465,13 +1468,15 @@ | ||
| 1465 | 1468 | */ |
| 1466 | 1469 | CX("window.fossil.page = {" |
| 1467 | 1470 | "name:\"%T\"" |
| 1468 | 1471 | "};\n", g.zPath); |
| 1469 | 1472 | 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 | |
| 1471 | 1477 | ** C-runtime state... */ |
| 1472 | - style_emit_script_tag(1,0); | |
| 1473 | 1478 | builtin_request_js("fossil.bootstrap.js"); |
| 1474 | 1479 | } |
| 1475 | 1480 | } |
| 1476 | 1481 | |
| 1477 | 1482 | /* |
| @@ -1501,5 +1506,35 @@ | ||
| 1501 | 1506 | } |
| 1502 | 1507 | }else{ |
| 1503 | 1508 | CX("</script>\n"); |
| 1504 | 1509 | } |
| 1505 | 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 | +} | |
| 1506 | 1541 |
| --- 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 |
-181
| --- src/style.fileedit.css | ||
| +++ src/style.fileedit.css | ||
| @@ -183,186 +183,5 @@ | ||
| 183 | 183 | width: initial; |
| 184 | 184 | } |
| 185 | 185 | body.fileedit .sbsdiffcols div.difftxtcol pre { |
| 186 | 186 | max-width: 44em; |
| 187 | 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 | 188 | |
| 370 | 189 | 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 @@ | ||
| 102 | 102 | " WHERE tagid=%d AND mtime<%.16g" |
| 103 | 103 | " ORDER BY mtime DESC LIMIT 1", |
| 104 | 104 | tagid, mtime); |
| 105 | 105 | } |
| 106 | 106 | |
| 107 | - | |
| 108 | 107 | /* |
| 109 | 108 | ** WEBPAGE: home |
| 110 | 109 | ** WEBPAGE: index |
| 111 | 110 | ** WEBPAGE: not_found |
| 112 | 111 | ** |
| @@ -398,10 +397,24 @@ | ||
| 398 | 397 | if( sqlite3_strglob("tag/*", zPageName)==0 ){ |
| 399 | 398 | return WIKITYPE_TAG; |
| 400 | 399 | } |
| 401 | 400 | return WIKITYPE_NORMAL; |
| 402 | 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 | +} | |
| 403 | 416 | |
| 404 | 417 | /* |
| 405 | 418 | ** Add an appropriate style_header() for either the /wiki or /wikiedit page |
| 406 | 419 | ** for zPageName. zExtra is an empty string for /wiki but has the text |
| 407 | 420 | ** "Edit: " for /wikiedit. |
| @@ -541,16 +554,11 @@ | ||
| 541 | 554 | zMimetype = wiki_filter_mimetypes(zMimetype); |
| 542 | 555 | if( !g.isHome && !noSubmenu ){ |
| 543 | 556 | if( ((rid && g.perm.WrWiki) || (!rid && g.perm.NewWiki)) |
| 544 | 557 | && wiki_special_permission(zPageName) |
| 545 | 558 | ){ |
| 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); | |
| 552 | 560 | }else if( rid && g.perm.ApndWiki ){ |
| 553 | 561 | style_submenu_element("Edit", "%R/wikiappend?name=%T", zPageName); |
| 554 | 562 | } |
| 555 | 563 | if( g.perm.Hyperlink ){ |
| 556 | 564 | style_submenu_element("History", "%R/whistory?name=%T", zPageName); |
| @@ -620,220 +628,656 @@ | ||
| 620 | 628 | return azStyles[i+1]; |
| 621 | 629 | } |
| 622 | 630 | } |
| 623 | 631 | return azStyles[1]; |
| 624 | 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 | +} | |
| 625 | 1058 | |
| 626 | 1059 | /* |
| 627 | 1060 | ** 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. | |
| 629 | 1068 | ** |
| 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. | |
| 631 | 1072 | */ |
| 632 | 1073 | void wikiedit_page(void){ |
| 633 | - char *zTag; | |
| 634 | - int rid = 0; | |
| 1074 | + const char *zPageName; | |
| 1075 | + const char * zMimetype = P("mimetype"); | |
| 635 | 1076 | 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 | + | |
| 660 | 1079 | login_check_credentials(); |
| 661 | 1080 | zPageName = PD("name",""); |
| 662 | - if( check_name(zPageName) ) return; | |
| 1081 | + if(zPageName && *zPageName){ | |
| 1082 | + if( check_name(zPageName) ) return; | |
| 1083 | + } | |
| 663 | 1084 | isSandbox = is_sandbox(zPageName); |
| 664 | 1085 | if( isSandbox ){ |
| 665 | 1086 | if( !g.perm.WrWiki ){ |
| 666 | 1087 | login_needed(g.anon.WrWiki); |
| 667 | 1088 | return; |
| 668 | 1089 | } |
| 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; | |
| 681 | 1093 | if( !wiki_special_permission(zPageName) ){ |
| 682 | 1094 | login_needed(0); |
| 683 | 1095 | return; |
| 684 | 1096 | } |
| 1097 | + found = wiki_fetch_by_name(zPageName, 0, &rid, 0); | |
| 685 | 1098 | if( (rid && !g.perm.WrWiki) || (!rid && !g.perm.NewWiki) ){ |
| 686 | 1099 | login_needed(rid ? g.anon.WrWiki : g.anon.NewWiki); |
| 687 | 1100 | return; |
| 688 | 1101 | } |
| 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 & 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); | |
| 835 | 1279 | style_footer(); |
| 836 | 1280 | } |
| 837 | 1281 | |
| 838 | 1282 | /* |
| 839 | 1283 | ** WEBPAGE: wikinew |
| @@ -851,17 +1295,11 @@ | ||
| 851 | 1295 | return; |
| 852 | 1296 | } |
| 853 | 1297 | zName = PD("name",""); |
| 854 | 1298 | zMimetype = wiki_filter_mimetypes(P("mimetype")); |
| 855 | 1299 | 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); | |
| 863 | 1301 | } |
| 864 | 1302 | style_header("Create A New Wiki Page"); |
| 865 | 1303 | wiki_standard_submenu(W_ALL_BUT(W_NEW)); |
| 866 | 1304 | @ <p>Rules for wiki page names:</p> |
| 867 | 1305 | well_formed_wiki_name_rules(); |
| @@ -1441,11 +1879,11 @@ | ||
| 1441 | 1879 | ** -M|--mimetype TEXT-FORMAT The mime type of the update. |
| 1442 | 1880 | ** Defaults to the type used by |
| 1443 | 1881 | ** the previous version of the |
| 1444 | 1882 | ** page, or text/x-fossil-wiki. |
| 1445 | 1883 | ** Valid values are: text/x-fossil-wiki, |
| 1446 | -** text/markdown and text/plain. fossil, | |
| 1884 | +** text/x-markdown and text/plain. fossil, | |
| 1447 | 1885 | ** markdown or plain can be specified as |
| 1448 | 1886 | ** synonyms of these values. |
| 1449 | 1887 | ** -t|--technote DATETIME Specifies the timestamp of |
| 1450 | 1888 | ** the technote to be created or |
| 1451 | 1889 | ** updated. When updating a tech note |
| 1452 | 1890 | |
| 1453 | 1891 | 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 & 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 <h1></option> | |
| 62 | - @ <option value="h2">Title 2 <h2></option> | |
| 63 | - @ <option value="h3">Title 3 <h3></option> | |
| 64 | - @ <option value="h4">Title 4 <h4></option> | |
| 65 | - @ <option value="h5">Title 5 <h5></option> | |
| 66 | - @ <option value="h6">Subtitle <h6></option> | |
| 67 | - @ <option value="p">Paragraph <p></option> | |
| 68 | - @ <option value="pre">Preformatted <pre></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 <h1></option> |
| 62 | @ <option value="h2">Title 2 <h2></option> |
| 63 | @ <option value="h3">Title 3 <h3></option> |
| 64 | @ <option value="h4">Title 4 <h4></option> |
| 65 | @ <option value="h5">Title 5 <h5></option> |
| 66 | @ <option value="h6">Subtitle <h6></option> |
| 67 | @ <option value="p">Paragraph <p></option> |
| 68 | @ <option value="pre">Preformatted <pre></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 @@ | ||
| 28 | 28 | |
| 29 | 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 | 30 | |
| 31 | 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 | 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 | |
| 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 | 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 | |
| 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 | 36 | |
| 37 | 37 | |
| 38 | 38 | RC=$(DMDIR)\bin\rcc |
| 39 | 39 | RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__ |
| 40 | 40 | |
| @@ -49,11 +49,11 @@ | ||
| 49 | 49 | |
| 50 | 50 | $(OBJDIR)\fossil.res: $B\win\fossil.rc |
| 51 | 51 | $(RC) $(RCFLAGS) -o$@ $** |
| 52 | 52 | |
| 53 | 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 > $@ | |
| 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 | 55 | +echo fossil >> $@ |
| 56 | 56 | +echo fossil >> $@ |
| 57 | 57 | +echo $(LIBS) >> $@ |
| 58 | 58 | +echo. >> $@ |
| 59 | 59 | +echo fossil >> $@ |
| @@ -962,16 +962,10 @@ | ||
| 962 | 962 | $(TCC) -o$@ -c winhttp_.c |
| 963 | 963 | |
| 964 | 964 | winhttp_.c : $(SRCDIR)\winhttp.c |
| 965 | 965 | +translate$E $** > $@ |
| 966 | 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 | 967 | $(OBJDIR)\xfer$O : xfer_.c xfer.h |
| 974 | 968 | $(TCC) -o$@ -c xfer_.c |
| 975 | 969 | |
| 976 | 970 | xfer_.c : $(SRCDIR)\xfer.c |
| 977 | 971 | +translate$E $** > $@ |
| @@ -987,7 +981,7 @@ | ||
| 987 | 981 | |
| 988 | 982 | zip_.c : $(SRCDIR)\zip.c |
| 989 | 983 | +translate$E $** > $@ |
| 990 | 984 | |
| 991 | 985 | 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 | |
| 993 | 987 | @copy /Y nul: headers |
| 994 | 988 |
| --- 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 |
+2
-12
| --- win/Makefile.mingw | ||
| +++ win/Makefile.mingw | ||
| @@ -566,11 +566,10 @@ | ||
| 566 | 566 | $(SRCDIR)/webmail.c \ |
| 567 | 567 | $(SRCDIR)/wiki.c \ |
| 568 | 568 | $(SRCDIR)/wikiformat.c \ |
| 569 | 569 | $(SRCDIR)/winfile.c \ |
| 570 | 570 | $(SRCDIR)/winhttp.c \ |
| 571 | - $(SRCDIR)/wysiwyg.c \ | |
| 572 | 571 | $(SRCDIR)/xfer.c \ |
| 573 | 572 | $(SRCDIR)/xfersetup.c \ |
| 574 | 573 | $(SRCDIR)/zip.c |
| 575 | 574 | |
| 576 | 575 | EXTRA_FILES = \ |
| @@ -640,10 +639,11 @@ | ||
| 640 | 639 | $(SRCDIR)/fossil.confirmer.js \ |
| 641 | 640 | $(SRCDIR)/fossil.dom.js \ |
| 642 | 641 | $(SRCDIR)/fossil.fetch.js \ |
| 643 | 642 | $(SRCDIR)/fossil.page.fileedit.js \ |
| 644 | 643 | $(SRCDIR)/fossil.page.forumpost.js \ |
| 644 | + $(SRCDIR)/fossil.page.wikiedit.js \ | |
| 645 | 645 | $(SRCDIR)/fossil.storage.js \ |
| 646 | 646 | $(SRCDIR)/fossil.tabs.js \ |
| 647 | 647 | $(SRCDIR)/graph.js \ |
| 648 | 648 | $(SRCDIR)/href.js \ |
| 649 | 649 | $(SRCDIR)/login.js \ |
| @@ -669,10 +669,11 @@ | ||
| 669 | 669 | $(SRCDIR)/sounds/d.wav \ |
| 670 | 670 | $(SRCDIR)/sounds/e.wav \ |
| 671 | 671 | $(SRCDIR)/sounds/f.wav \ |
| 672 | 672 | $(SRCDIR)/style.admin_log.css \ |
| 673 | 673 | $(SRCDIR)/style.fileedit.css \ |
| 674 | + $(SRCDIR)/style.wikiedit.css \ | |
| 674 | 675 | $(SRCDIR)/tree.js \ |
| 675 | 676 | $(SRCDIR)/useredit.js \ |
| 676 | 677 | $(SRCDIR)/wiki.wiki |
| 677 | 678 | |
| 678 | 679 | TRANS_SRC = \ |
| @@ -814,11 +815,10 @@ | ||
| 814 | 815 | $(OBJDIR)/webmail_.c \ |
| 815 | 816 | $(OBJDIR)/wiki_.c \ |
| 816 | 817 | $(OBJDIR)/wikiformat_.c \ |
| 817 | 818 | $(OBJDIR)/winfile_.c \ |
| 818 | 819 | $(OBJDIR)/winhttp_.c \ |
| 819 | - $(OBJDIR)/wysiwyg_.c \ | |
| 820 | 820 | $(OBJDIR)/xfer_.c \ |
| 821 | 821 | $(OBJDIR)/xfersetup_.c \ |
| 822 | 822 | $(OBJDIR)/zip_.c |
| 823 | 823 | |
| 824 | 824 | OBJ = \ |
| @@ -960,11 +960,10 @@ | ||
| 960 | 960 | $(OBJDIR)/webmail.o \ |
| 961 | 961 | $(OBJDIR)/wiki.o \ |
| 962 | 962 | $(OBJDIR)/wikiformat.o \ |
| 963 | 963 | $(OBJDIR)/winfile.o \ |
| 964 | 964 | $(OBJDIR)/winhttp.o \ |
| 965 | - $(OBJDIR)/wysiwyg.o \ | |
| 966 | 965 | $(OBJDIR)/xfer.o \ |
| 967 | 966 | $(OBJDIR)/xfersetup.o \ |
| 968 | 967 | $(OBJDIR)/zip.o |
| 969 | 968 | |
| 970 | 969 | APPNAME = fossil.exe |
| @@ -1321,11 +1320,10 @@ | ||
| 1321 | 1320 | $(OBJDIR)/webmail_.c:$(OBJDIR)/webmail.h \ |
| 1322 | 1321 | $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h \ |
| 1323 | 1322 | $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h \ |
| 1324 | 1323 | $(OBJDIR)/winfile_.c:$(OBJDIR)/winfile.h \ |
| 1325 | 1324 | $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h \ |
| 1326 | - $(OBJDIR)/wysiwyg_.c:$(OBJDIR)/wysiwyg.h \ | |
| 1327 | 1325 | $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h \ |
| 1328 | 1326 | $(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h \ |
| 1329 | 1327 | $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h \ |
| 1330 | 1328 | $(SRCDIR)/sqlite3.h \ |
| 1331 | 1329 | $(SRCDIR)/th.h \ |
| @@ -2454,18 +2452,10 @@ | ||
| 2454 | 2452 | $(OBJDIR)/winhttp.o: $(OBJDIR)/winhttp_.c $(OBJDIR)/winhttp.h $(SRCDIR)/config.h |
| 2455 | 2453 | $(XTCC) -o $(OBJDIR)/winhttp.o -c $(OBJDIR)/winhttp_.c |
| 2456 | 2454 | |
| 2457 | 2455 | $(OBJDIR)/winhttp.h: $(OBJDIR)/headers |
| 2458 | 2456 | |
| 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 | 2457 | $(OBJDIR)/xfer_.c: $(SRCDIR)/xfer.c $(TRANSLATE) |
| 2468 | 2458 | $(TRANSLATE) $(SRCDIR)/xfer.c >$@ |
| 2469 | 2459 | |
| 2470 | 2460 | $(OBJDIR)/xfer.o: $(OBJDIR)/xfer_.c $(OBJDIR)/xfer.h $(SRCDIR)/config.h |
| 2471 | 2461 | $(XTCC) -o $(OBJDIR)/xfer.o -c $(OBJDIR)/xfer_.c |
| 2472 | 2462 |
| --- 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 @@ | ||
| 488 | 488 | "$(OX)\webmail_.c" \ |
| 489 | 489 | "$(OX)\wiki_.c" \ |
| 490 | 490 | "$(OX)\wikiformat_.c" \ |
| 491 | 491 | "$(OX)\winfile_.c" \ |
| 492 | 492 | "$(OX)\winhttp_.c" \ |
| 493 | - "$(OX)\wysiwyg_.c" \ | |
| 494 | 493 | "$(OX)\xfer_.c" \ |
| 495 | 494 | "$(OX)\xfersetup_.c" \ |
| 496 | 495 | "$(OX)\zip_.c" |
| 497 | 496 | |
| 498 | 497 | EXTRA_FILES = "$(SRCDIR)\..\skins\aht\details.txt" \ |
| @@ -561,10 +560,11 @@ | ||
| 561 | 560 | "$(SRCDIR)\fossil.confirmer.js" \ |
| 562 | 561 | "$(SRCDIR)\fossil.dom.js" \ |
| 563 | 562 | "$(SRCDIR)\fossil.fetch.js" \ |
| 564 | 563 | "$(SRCDIR)\fossil.page.fileedit.js" \ |
| 565 | 564 | "$(SRCDIR)\fossil.page.forumpost.js" \ |
| 565 | + "$(SRCDIR)\fossil.page.wikiedit.js" \ | |
| 566 | 566 | "$(SRCDIR)\fossil.storage.js" \ |
| 567 | 567 | "$(SRCDIR)\fossil.tabs.js" \ |
| 568 | 568 | "$(SRCDIR)\graph.js" \ |
| 569 | 569 | "$(SRCDIR)\href.js" \ |
| 570 | 570 | "$(SRCDIR)\login.js" \ |
| @@ -590,10 +590,11 @@ | ||
| 590 | 590 | "$(SRCDIR)\sounds\d.wav" \ |
| 591 | 591 | "$(SRCDIR)\sounds\e.wav" \ |
| 592 | 592 | "$(SRCDIR)\sounds\f.wav" \ |
| 593 | 593 | "$(SRCDIR)\style.admin_log.css" \ |
| 594 | 594 | "$(SRCDIR)\style.fileedit.css" \ |
| 595 | + "$(SRCDIR)\style.wikiedit.css" \ | |
| 595 | 596 | "$(SRCDIR)\tree.js" \ |
| 596 | 597 | "$(SRCDIR)\useredit.js" \ |
| 597 | 598 | "$(SRCDIR)\wiki.wiki" |
| 598 | 599 | |
| 599 | 600 | OBJ = "$(OX)\add$O" \ |
| @@ -740,11 +741,10 @@ | ||
| 740 | 741 | "$(OX)\webmail$O" \ |
| 741 | 742 | "$(OX)\wiki$O" \ |
| 742 | 743 | "$(OX)\wikiformat$O" \ |
| 743 | 744 | "$(OX)\winfile$O" \ |
| 744 | 745 | "$(OX)\winhttp$O" \ |
| 745 | - "$(OX)\wysiwyg$O" \ | |
| 746 | 746 | "$(OX)\xfer$O" \ |
| 747 | 747 | "$(OX)\xfersetup$O" \ |
| 748 | 748 | "$(OX)\zip$O" \ |
| 749 | 749 | !if $(FOSSIL_ENABLE_MINIZ)!=0 |
| 750 | 750 | "$(OX)\miniz$O" \ |
| @@ -967,11 +967,10 @@ | ||
| 967 | 967 | echo "$(OX)\webmail.obj" >> $@ |
| 968 | 968 | echo "$(OX)\wiki.obj" >> $@ |
| 969 | 969 | echo "$(OX)\wikiformat.obj" >> $@ |
| 970 | 970 | echo "$(OX)\winfile.obj" >> $@ |
| 971 | 971 | echo "$(OX)\winhttp.obj" >> $@ |
| 972 | - echo "$(OX)\wysiwyg.obj" >> $@ | |
| 973 | 972 | echo "$(OX)\xfer.obj" >> $@ |
| 974 | 973 | echo "$(OX)\xfersetup.obj" >> $@ |
| 975 | 974 | echo "$(OX)\zip.obj" >> $@ |
| 976 | 975 | !if $(FOSSIL_ENABLE_MINIZ)!=0 |
| 977 | 976 | echo "$(OX)\miniz.obj" >> $@ |
| @@ -1155,10 +1154,11 @@ | ||
| 1155 | 1154 | echo "$(SRCDIR)\fossil.confirmer.js" >> $@ |
| 1156 | 1155 | echo "$(SRCDIR)\fossil.dom.js" >> $@ |
| 1157 | 1156 | echo "$(SRCDIR)\fossil.fetch.js" >> $@ |
| 1158 | 1157 | echo "$(SRCDIR)\fossil.page.fileedit.js" >> $@ |
| 1159 | 1158 | echo "$(SRCDIR)\fossil.page.forumpost.js" >> $@ |
| 1159 | + echo "$(SRCDIR)\fossil.page.wikiedit.js" >> $@ | |
| 1160 | 1160 | echo "$(SRCDIR)\fossil.storage.js" >> $@ |
| 1161 | 1161 | echo "$(SRCDIR)\fossil.tabs.js" >> $@ |
| 1162 | 1162 | echo "$(SRCDIR)\graph.js" >> $@ |
| 1163 | 1163 | echo "$(SRCDIR)\href.js" >> $@ |
| 1164 | 1164 | echo "$(SRCDIR)\login.js" >> $@ |
| @@ -1184,10 +1184,11 @@ | ||
| 1184 | 1184 | echo "$(SRCDIR)\sounds/d.wav" >> $@ |
| 1185 | 1185 | echo "$(SRCDIR)\sounds/e.wav" >> $@ |
| 1186 | 1186 | echo "$(SRCDIR)\sounds/f.wav" >> $@ |
| 1187 | 1187 | echo "$(SRCDIR)\style.admin_log.css" >> $@ |
| 1188 | 1188 | echo "$(SRCDIR)\style.fileedit.css" >> $@ |
| 1189 | + echo "$(SRCDIR)\style.wikiedit.css" >> $@ | |
| 1189 | 1190 | echo "$(SRCDIR)\tree.js" >> $@ |
| 1190 | 1191 | echo "$(SRCDIR)\useredit.js" >> $@ |
| 1191 | 1192 | echo "$(SRCDIR)\wiki.wiki" >> $@ |
| 1192 | 1193 | |
| 1193 | 1194 | "$(OX)\add$O" : "$(OX)\add_.c" "$(OX)\add.h" |
| @@ -2028,16 +2029,10 @@ | ||
| 2028 | 2029 | $(TCC) /Fo$@ /Fd$(@D)\ -c "$(OX)\winhttp_.c" |
| 2029 | 2030 | |
| 2030 | 2031 | "$(OX)\winhttp_.c" : "$(SRCDIR)\winhttp.c" |
| 2031 | 2032 | "$(OBJDIR)\translate$E" $** > $@ |
| 2032 | 2033 | |
| 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 | 2034 | "$(OX)\xfer$O" : "$(OX)\xfer_.c" "$(OX)\xfer.h" |
| 2040 | 2035 | $(TCC) /Fo$@ /Fd$(@D)\ -c "$(OX)\xfer_.c" |
| 2041 | 2036 | |
| 2042 | 2037 | "$(OX)\xfer_.c" : "$(SRCDIR)\xfer.c" |
| 2043 | 2038 | "$(OBJDIR)\translate$E" $** > $@ |
| @@ -2196,14 +2191,13 @@ | ||
| 2196 | 2191 | "$(OX)\webmail_.c":"$(OX)\webmail.h" \ |
| 2197 | 2192 | "$(OX)\wiki_.c":"$(OX)\wiki.h" \ |
| 2198 | 2193 | "$(OX)\wikiformat_.c":"$(OX)\wikiformat.h" \ |
| 2199 | 2194 | "$(OX)\winfile_.c":"$(OX)\winfile.h" \ |
| 2200 | 2195 | "$(OX)\winhttp_.c":"$(OX)\winhttp.h" \ |
| 2201 | - "$(OX)\wysiwyg_.c":"$(OX)\wysiwyg.h" \ | |
| 2202 | 2196 | "$(OX)\xfer_.c":"$(OX)\xfer.h" \ |
| 2203 | 2197 | "$(OX)\xfersetup_.c":"$(OX)\xfersetup.h" \ |
| 2204 | 2198 | "$(OX)\zip_.c":"$(OX)\zip.h" \ |
| 2205 | 2199 | "$(SRCDIR)\sqlite3.h" \ |
| 2206 | 2200 | "$(SRCDIR)\th.h" \ |
| 2207 | 2201 | "$(OX)\VERSION.h" \ |
| 2208 | 2202 | "$(SRCDIR)\cson_amalgamation.h" |
| 2209 | 2203 | @copy /Y nul: $@ |
| 2210 | 2204 |
| --- 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 |
+6
| --- www/changes.wiki | ||
| +++ www/changes.wiki | ||
| @@ -58,10 +58,16 @@ | ||
| 58 | 58 | "[/help?cmd=sql|fossil sql]" command supports new output |
| 59 | 59 | modes ".mode box" and ".mode json". |
| 60 | 60 | * Add the "<tt>obscure()</tt>" SQL function to the |
| 61 | 61 | "[/help?cmd=sql|fossil sql]" command. |
| 62 | 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. | |
| 63 | 69 | * Countless documentation enhancements. |
| 64 | 70 | |
| 65 | 71 | <a name='v2_11'></a> |
| 66 | 72 | <h2>Changes for Version 2.11 (2020-05-25)</h2> |
| 67 | 73 | |
| 68 | 74 |
| --- 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 |
+6
| --- www/changes.wiki | ||
| +++ www/changes.wiki | ||
| @@ -58,10 +58,16 @@ | ||
| 58 | 58 | "[/help?cmd=sql|fossil sql]" command supports new output |
| 59 | 59 | modes ".mode box" and ".mode json". |
| 60 | 60 | * Add the "<tt>obscure()</tt>" SQL function to the |
| 61 | 61 | "[/help?cmd=sql|fossil sql]" command. |
| 62 | 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. | |
| 63 | 69 | * Countless documentation enhancements. |
| 64 | 70 | |
| 65 | 71 | <a name='v2_11'></a> |
| 66 | 72 | <h2>Changes for Version 2.11 (2020-05-25)</h2> |
| 67 | 73 | |
| 68 | 74 |
| --- 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 |