Fossil SCM

Begin integrating the builtin_request_js() interface.

drh 2020-07-31 20:02 refactor-js-handling
Commit 13caa6e61e0a13c93ea47edc9ce33b3b92cd8292349de9af7e1b1e8e816a1e24
+1 -1
--- src/browse.c
+++ src/browse.c
@@ -911,11 +911,11 @@
911911
}
912912
}
913913
}
914914
@ </ul>
915915
@ </ul></div>
916
- style_load_one_js_file("tree.js");
916
+ builtin_request_js("tree.js");
917917
style_footer();
918918
919919
/* We could free memory used by sTree here if we needed to. But
920920
** the process is about to exit, so doing so would not really accomplish
921921
** anything useful. */
922922
--- src/browse.c
+++ src/browse.c
@@ -911,11 +911,11 @@
911 }
912 }
913 }
914 @ </ul>
915 @ </ul></div>
916 style_load_one_js_file("tree.js");
917 style_footer();
918
919 /* We could free memory used by sTree here if we needed to. But
920 ** the process is about to exit, so doing so would not really accomplish
921 ** anything useful. */
922
--- src/browse.c
+++ src/browse.c
@@ -911,11 +911,11 @@
911 }
912 }
913 }
914 @ </ul>
915 @ </ul></div>
916 builtin_request_js("tree.js");
917 style_footer();
918
919 /* We could free memory used by sTree here if we needed to. But
920 ** the process is about to exit, so doing so would not really accomplish
921 ** anything useful. */
922
+80 -8
--- src/builtin.c
+++ src/builtin.c
@@ -218,11 +218,52 @@
218218
*/
219219
static struct {
220220
int aReq[30]; /* Indexes of all requested built-in JS files */
221221
int nReq; /* Number of slots in aReq[] currently used */
222222
int nSent; /* Number of slots in aReq[] fulfilled */
223
+ int eDelivery; /* Delivery mechanism */
223224
} builtin;
225
+
226
+#if INTERFACE
227
+/* Various delivery mechanisms. The 0 option is the default.
228
+*/
229
+#define JS_INLINE_BATCH 0 /* inline, batched together */
230
+#define JS_INLINE_IMM 1 /* inline, as soon as requested */
231
+#define JS_SEP_BATCH 2 /* Separate resources, batched */
232
+#define JS_SEP_IMM 3 /* Separate resources, as requested */
233
+#define JS_BUNDLED 4 /* Single separate resource */
234
+#endif /* INTERFACE */
235
+
236
+/*
237
+** The argument is a request to change the javascript delivery mode.
238
+** The argument is a string which is a command-line option or CGI
239
+** parameter. Try to match it against one of the delivery options
240
+** and set things up accordingly. Throw an error if no match unless
241
+** bSilent is true.
242
+*/
243
+void builtin_set_js_delivery_mode(const char *zMode, int bSilent){
244
+ if( zMode==0 ) return;
245
+ if( strcmp(zMode, "inline")==0 ){
246
+ builtin.eDelivery = JS_INLINE_BATCH;
247
+ }else
248
+ if( strcmp(zMode, "inline-imm")==0 ){
249
+ builtin.eDelivery = JS_INLINE_IMM;
250
+ }else
251
+ if( strcmp(zMode, "sep")==0 ){
252
+ builtin.eDelivery = JS_SEP_BATCH;
253
+ }else
254
+ if( strcmp(zMode, "sep-imm")==0 ){
255
+ builtin.eDelivery = JS_SEP_IMM;
256
+ }else
257
+ if( strcmp(zMode, "bundled")==0 ){
258
+ builtin.eDelivery = JS_BUNDLED;
259
+ }else if( !bSilent ){
260
+ fossil_fatal("unknown javascript delivery mode \"%s\" - should be"
261
+ " one of: inline inline-immediate separate"
262
+ " separate-immediate bundled", zMode);
263
+ }
264
+}
224265
225266
/*
226267
** The caller wants the Javascript file named by zFilename to be
227268
** included in the generated page. Add the file to the queue of
228269
** requested javascript resources, if it is not there already.
@@ -253,10 +294,15 @@
253294
}
254295
if( builtin.nReq>=count(builtin.aReq) ){
255296
fossil_panic("too many javascript files requested");
256297
}
257298
builtin.aReq[builtin.nReq++] = i;
299
+ if( builtin.eDelivery==JS_INLINE_IMM
300
+ || builtin.eDelivery==JS_SEP_IMM
301
+ ){
302
+ builtin_fulfill_js_requests();
303
+ }
258304
}
259305
260306
/*
261307
** Fulfill all pending requests for javascript files.
262308
**
@@ -263,15 +309,41 @@
263309
** The current implementation delivers all javascript in-line. However,
264310
** the caller should not depend on this. Future changes to this routine
265311
** might choose to deliver javascript as separate resources.
266312
*/
267313
void builtin_fulfill_js_requests(void){
268
- if( builtin.nSent<builtin.nReq ){
269
- CX("<script nonce='%h'>\n",style_nonce);
270
- do{
271
- int i = builtin.aReq[builtin.nSent++];
272
- cgi_append_content((const char*)aBuiltinFiles[i].pData,
273
- aBuiltinFiles[i].nByte);
274
- }while( builtin.nSent<builtin.nReq );
275
- CX("</script>\n");
314
+ if( builtin.nSent>=builtin.nReq ) return; /* nothing to do */
315
+ switch( builtin.eDelivery ){
316
+ case JS_INLINE_BATCH:
317
+ case JS_INLINE_IMM: {
318
+ CX("<script nonce='%h'>\n",style_nonce());
319
+ do{
320
+ int i = builtin.aReq[builtin.nSent++];
321
+ CX("/* %s */\n", aBuiltinFiles[i].zName);
322
+ cgi_append_content((const char*)aBuiltinFiles[i].pData,
323
+ aBuiltinFiles[i].nByte);
324
+ }while( builtin.nSent<builtin.nReq );
325
+ CX("</script>\n");
326
+ break;
327
+ }
328
+ case JS_SEP_BATCH:
329
+ case JS_SEP_IMM: {
330
+ /* Each JS file as a separate resource */
331
+ while( builtin.nSent<builtin.nReq ){
332
+ int i = builtin.aReq[builtin.nSent++];
333
+ CX("<script src='/builtin?name=%t&id=%.8s'></script>\n",
334
+ aBuiltinFiles[i].zName, fossil_exe_id());
335
+ }
336
+ break;
337
+ }
338
+ case JS_BUNDLED: {
339
+ Blob aList;
340
+ blob_init(&aList,0,0);
341
+ while( builtin.nSent<builtin.nReq ){
342
+ blob_appendf(&aList, ",%d", builtin.aReq[builtin.nSent++]+1);
343
+ }
344
+ CX("<script src='/builtin?m=%s&id=%.8s'></script>\n",
345
+ blob_str(&aList)+1, fossil_exe_id());
346
+ blob_reset(&aList);
347
+ }
276348
}
277349
}
278350
--- src/builtin.c
+++ src/builtin.c
@@ -218,11 +218,52 @@
218 */
219 static struct {
220 int aReq[30]; /* Indexes of all requested built-in JS files */
221 int nReq; /* Number of slots in aReq[] currently used */
222 int nSent; /* Number of slots in aReq[] fulfilled */
 
223 } builtin;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
225 /*
226 ** The caller wants the Javascript file named by zFilename to be
227 ** included in the generated page. Add the file to the queue of
228 ** requested javascript resources, if it is not there already.
@@ -253,10 +294,15 @@
253 }
254 if( builtin.nReq>=count(builtin.aReq) ){
255 fossil_panic("too many javascript files requested");
256 }
257 builtin.aReq[builtin.nReq++] = i;
 
 
 
 
 
258 }
259
260 /*
261 ** Fulfill all pending requests for javascript files.
262 **
@@ -263,15 +309,41 @@
263 ** The current implementation delivers all javascript in-line. However,
264 ** the caller should not depend on this. Future changes to this routine
265 ** might choose to deliver javascript as separate resources.
266 */
267 void builtin_fulfill_js_requests(void){
268 if( builtin.nSent<builtin.nReq ){
269 CX("<script nonce='%h'>\n",style_nonce);
270 do{
271 int i = builtin.aReq[builtin.nSent++];
272 cgi_append_content((const char*)aBuiltinFiles[i].pData,
273 aBuiltinFiles[i].nByte);
274 }while( builtin.nSent<builtin.nReq );
275 CX("</script>\n");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
276 }
277 }
278
--- src/builtin.c
+++ src/builtin.c
@@ -218,11 +218,52 @@
218 */
219 static struct {
220 int aReq[30]; /* Indexes of all requested built-in JS files */
221 int nReq; /* Number of slots in aReq[] currently used */
222 int nSent; /* Number of slots in aReq[] fulfilled */
223 int eDelivery; /* Delivery mechanism */
224 } builtin;
225
226 #if INTERFACE
227 /* Various delivery mechanisms. The 0 option is the default.
228 */
229 #define JS_INLINE_BATCH 0 /* inline, batched together */
230 #define JS_INLINE_IMM 1 /* inline, as soon as requested */
231 #define JS_SEP_BATCH 2 /* Separate resources, batched */
232 #define JS_SEP_IMM 3 /* Separate resources, as requested */
233 #define JS_BUNDLED 4 /* Single separate resource */
234 #endif /* INTERFACE */
235
236 /*
237 ** The argument is a request to change the javascript delivery mode.
238 ** The argument is a string which is a command-line option or CGI
239 ** parameter. Try to match it against one of the delivery options
240 ** and set things up accordingly. Throw an error if no match unless
241 ** bSilent is true.
242 */
243 void builtin_set_js_delivery_mode(const char *zMode, int bSilent){
244 if( zMode==0 ) return;
245 if( strcmp(zMode, "inline")==0 ){
246 builtin.eDelivery = JS_INLINE_BATCH;
247 }else
248 if( strcmp(zMode, "inline-imm")==0 ){
249 builtin.eDelivery = JS_INLINE_IMM;
250 }else
251 if( strcmp(zMode, "sep")==0 ){
252 builtin.eDelivery = JS_SEP_BATCH;
253 }else
254 if( strcmp(zMode, "sep-imm")==0 ){
255 builtin.eDelivery = JS_SEP_IMM;
256 }else
257 if( strcmp(zMode, "bundled")==0 ){
258 builtin.eDelivery = JS_BUNDLED;
259 }else if( !bSilent ){
260 fossil_fatal("unknown javascript delivery mode \"%s\" - should be"
261 " one of: inline inline-immediate separate"
262 " separate-immediate bundled", zMode);
263 }
264 }
265
266 /*
267 ** The caller wants the Javascript file named by zFilename to be
268 ** included in the generated page. Add the file to the queue of
269 ** requested javascript resources, if it is not there already.
@@ -253,10 +294,15 @@
294 }
295 if( builtin.nReq>=count(builtin.aReq) ){
296 fossil_panic("too many javascript files requested");
297 }
298 builtin.aReq[builtin.nReq++] = i;
299 if( builtin.eDelivery==JS_INLINE_IMM
300 || builtin.eDelivery==JS_SEP_IMM
301 ){
302 builtin_fulfill_js_requests();
303 }
304 }
305
306 /*
307 ** Fulfill all pending requests for javascript files.
308 **
@@ -263,15 +309,41 @@
309 ** The current implementation delivers all javascript in-line. However,
310 ** the caller should not depend on this. Future changes to this routine
311 ** might choose to deliver javascript as separate resources.
312 */
313 void builtin_fulfill_js_requests(void){
314 if( builtin.nSent>=builtin.nReq ) return; /* nothing to do */
315 switch( builtin.eDelivery ){
316 case JS_INLINE_BATCH:
317 case JS_INLINE_IMM: {
318 CX("<script nonce='%h'>\n",style_nonce());
319 do{
320 int i = builtin.aReq[builtin.nSent++];
321 CX("/* %s */\n", aBuiltinFiles[i].zName);
322 cgi_append_content((const char*)aBuiltinFiles[i].pData,
323 aBuiltinFiles[i].nByte);
324 }while( builtin.nSent<builtin.nReq );
325 CX("</script>\n");
326 break;
327 }
328 case JS_SEP_BATCH:
329 case JS_SEP_IMM: {
330 /* Each JS file as a separate resource */
331 while( builtin.nSent<builtin.nReq ){
332 int i = builtin.aReq[builtin.nSent++];
333 CX("<script src='/builtin?name=%t&id=%.8s'></script>\n",
334 aBuiltinFiles[i].zName, fossil_exe_id());
335 }
336 break;
337 }
338 case JS_BUNDLED: {
339 Blob aList;
340 blob_init(&aList,0,0);
341 while( builtin.nSent<builtin.nReq ){
342 blob_appendf(&aList, ",%d", builtin.aReq[builtin.nSent++]+1);
343 }
344 CX("<script src='/builtin?m=%s&id=%.8s'></script>\n",
345 blob_str(&aList)+1, fossil_exe_id());
346 blob_reset(&aList);
347 }
348 }
349 }
350
+1 -1
--- src/forum.c
+++ src/forum.c
@@ -759,11 +759,11 @@
759759
*/
760760
static void forum_emit_page_js(){
761761
static int once = 0;
762762
if(0==once){
763763
once = 1;
764
- style_load_js("forum.js");
764
+ builtin_request_js("forum.js");
765765
style_emit_script_fossil_bootstrap(0);
766766
style_emit_script_dom(0);
767767
style_emit_script_builtin(0, "fossil.page.forumpost.js");
768768
}
769769
}
770770
--- src/forum.c
+++ src/forum.c
@@ -759,11 +759,11 @@
759 */
760 static void forum_emit_page_js(){
761 static int once = 0;
762 if(0==once){
763 once = 1;
764 style_load_js("forum.js");
765 style_emit_script_fossil_bootstrap(0);
766 style_emit_script_dom(0);
767 style_emit_script_builtin(0, "fossil.page.forumpost.js");
768 }
769 }
770
--- src/forum.c
+++ src/forum.c
@@ -759,11 +759,11 @@
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 style_emit_script_dom(0);
767 style_emit_script_builtin(0, "fossil.page.forumpost.js");
768 }
769 }
770
+3 -3
--- src/info.c
+++ src/info.c
@@ -441,11 +441,11 @@
441441
/*
442442
** Generate javascript to enhance HTML diffs.
443443
*/
444444
void append_diff_javascript(int sideBySide){
445445
if( !sideBySide ) return;
446
- style_load_one_js_file("sbsdiff.js");
446
+ builtin_request_js("sbsdiff.js");
447447
}
448448
449449
/*
450450
** Construct an appropriate diffFlag for text_diff() based on query
451451
** parameters and the to boolean arguments.
@@ -2089,11 +2089,11 @@
20892089
if( z[0]=='\n' ) z++;
20902090
}
20912091
if( n<iEnd ) cgi_printf("</div>");
20922092
@ </pre>
20932093
if( db_int(0, "SELECT EXISTS(SELECT 1 FROM lnos)") ){
2094
- style_load_one_js_file("scroll.js");
2094
+ builtin_request_js("scroll.js");
20952095
}
20962096
}
20972097
20982098
20992099
/*
@@ -3113,11 +3113,11 @@
31133113
@ <input type="submit" name="apply" value="Apply Changes" />
31143114
}
31153115
@ </td></tr>
31163116
@ </table>
31173117
@ </div></form>
3118
- style_load_one_js_file("ci_edit.js");
3118
+ builtin_request_js("ci_edit.js");
31193119
style_footer();
31203120
}
31213121
31223122
/*
31233123
** Prepare an ammended commit comment. Let the user modify it using the
31243124
--- src/info.c
+++ src/info.c
@@ -441,11 +441,11 @@
441 /*
442 ** Generate javascript to enhance HTML diffs.
443 */
444 void append_diff_javascript(int sideBySide){
445 if( !sideBySide ) return;
446 style_load_one_js_file("sbsdiff.js");
447 }
448
449 /*
450 ** Construct an appropriate diffFlag for text_diff() based on query
451 ** parameters and the to boolean arguments.
@@ -2089,11 +2089,11 @@
2089 if( z[0]=='\n' ) z++;
2090 }
2091 if( n<iEnd ) cgi_printf("</div>");
2092 @ </pre>
2093 if( db_int(0, "SELECT EXISTS(SELECT 1 FROM lnos)") ){
2094 style_load_one_js_file("scroll.js");
2095 }
2096 }
2097
2098
2099 /*
@@ -3113,11 +3113,11 @@
3113 @ <input type="submit" name="apply" value="Apply Changes" />
3114 }
3115 @ </td></tr>
3116 @ </table>
3117 @ </div></form>
3118 style_load_one_js_file("ci_edit.js");
3119 style_footer();
3120 }
3121
3122 /*
3123 ** Prepare an ammended commit comment. Let the user modify it using the
3124
--- src/info.c
+++ src/info.c
@@ -441,11 +441,11 @@
441 /*
442 ** Generate javascript to enhance HTML diffs.
443 */
444 void append_diff_javascript(int sideBySide){
445 if( !sideBySide ) return;
446 builtin_request_js("sbsdiff.js");
447 }
448
449 /*
450 ** Construct an appropriate diffFlag for text_diff() based on query
451 ** parameters and the to boolean arguments.
@@ -2089,11 +2089,11 @@
2089 if( z[0]=='\n' ) z++;
2090 }
2091 if( n<iEnd ) cgi_printf("</div>");
2092 @ </pre>
2093 if( db_int(0, "SELECT EXISTS(SELECT 1 FROM lnos)") ){
2094 builtin_request_js("scroll.js");
2095 }
2096 }
2097
2098
2099 /*
@@ -3113,11 +3113,11 @@
3113 @ <input type="submit" name="apply" value="Apply Changes" />
3114 }
3115 @ </td></tr>
3116 @ </table>
3117 @ </div></form>
3118 builtin_request_js("ci_edit.js");
3119 style_footer();
3120 }
3121
3122 /*
3123 ** Prepare an ammended commit comment. Let the user modify it using the
3124
+1 -1
--- src/login.c
+++ src/login.c
@@ -752,11 +752,11 @@
752752
@ %h(zCaptcha)
753753
@ </pre></td></tr></table>
754754
if( bAutoCaptcha ) {
755755
@ <input type="button" value="Fill out captcha" id='autofillButton' \
756756
@ data-af='%s(zDecoded)' />
757
- style_load_one_js_file("login.js");
757
+ builtin_request_js("login.js");
758758
}
759759
@ </div>
760760
free(zCaptcha);
761761
}
762762
@ </form>
763763
--- src/login.c
+++ src/login.c
@@ -752,11 +752,11 @@
752 @ %h(zCaptcha)
753 @ </pre></td></tr></table>
754 if( bAutoCaptcha ) {
755 @ <input type="button" value="Fill out captcha" id='autofillButton' \
756 @ data-af='%s(zDecoded)' />
757 style_load_one_js_file("login.js");
758 }
759 @ </div>
760 free(zCaptcha);
761 }
762 @ </form>
763
--- src/login.c
+++ src/login.c
@@ -752,11 +752,11 @@
752 @ %h(zCaptcha)
753 @ </pre></td></tr></table>
754 if( bAutoCaptcha ) {
755 @ <input type="button" value="Fill out captcha" id='autofillButton' \
756 @ data-af='%s(zDecoded)' />
757 builtin_request_js("login.js");
758 }
759 @ </div>
760 free(zCaptcha);
761 }
762 @ </form>
763
+10
--- src/main.c
+++ src/main.c
@@ -2714,10 +2714,19 @@
27142714
** --files GLOBLIST Comma-separated list of glob patterns for static files
27152715
** --localauth enable automatic login for requests from localhost
27162716
** --localhost listen on 127.0.0.1 only (always true for "ui")
27172717
** --https Indicates that the input is coming through a reverse
27182718
** proxy that has already translated HTTPS into HTTP.
2719
+** --jsmode MODE Determine how javascript is delivered with pages.
2720
+** Mode can be one of:
2721
+** inline JS inline at the end of the file
2722
+** inline-imm JS inline at point of need
2723
+** sep Separate HTTP requests for JS
2724
+** sep-imm Separate HTTP requests each issued
2725
+** at the need
2726
+** bundled One single separate HTTP for all
2727
+** JS resources
27192728
** --max-latency N Do not let any single HTTP request run for more than N
27202729
** seconds (only works on unix)
27212730
** --nocompress Do not compress HTTP replies
27222731
** --nojail Drop root privileges but do not enter the chroot jail
27232732
** --nossl signal that no SSL connections are available (Always
@@ -2760,10 +2769,11 @@
27602769
27612770
if( g.zErrlog==0 ){
27622771
g.zErrlog = "-";
27632772
}
27642773
g.zExtRoot = find_option("extroot",0,1);
2774
+ builtin_set_js_delivery_mode(find_option("jsmode",0,1),0);
27652775
zFileGlob = find_option("files-urlenc",0,1);
27662776
if( zFileGlob ){
27672777
char *z = mprintf("%s", zFileGlob);
27682778
dehttpize(z);
27692779
zFileGlob = z;
27702780
--- src/main.c
+++ src/main.c
@@ -2714,10 +2714,19 @@
2714 ** --files GLOBLIST Comma-separated list of glob patterns for static files
2715 ** --localauth enable automatic login for requests from localhost
2716 ** --localhost listen on 127.0.0.1 only (always true for "ui")
2717 ** --https Indicates that the input is coming through a reverse
2718 ** proxy that has already translated HTTPS into HTTP.
 
 
 
 
 
 
 
 
 
2719 ** --max-latency N Do not let any single HTTP request run for more than N
2720 ** seconds (only works on unix)
2721 ** --nocompress Do not compress HTTP replies
2722 ** --nojail Drop root privileges but do not enter the chroot jail
2723 ** --nossl signal that no SSL connections are available (Always
@@ -2760,10 +2769,11 @@
2760
2761 if( g.zErrlog==0 ){
2762 g.zErrlog = "-";
2763 }
2764 g.zExtRoot = find_option("extroot",0,1);
 
2765 zFileGlob = find_option("files-urlenc",0,1);
2766 if( zFileGlob ){
2767 char *z = mprintf("%s", zFileGlob);
2768 dehttpize(z);
2769 zFileGlob = z;
2770
--- src/main.c
+++ src/main.c
@@ -2714,10 +2714,19 @@
2714 ** --files GLOBLIST Comma-separated list of glob patterns for static files
2715 ** --localauth enable automatic login for requests from localhost
2716 ** --localhost listen on 127.0.0.1 only (always true for "ui")
2717 ** --https Indicates that the input is coming through a reverse
2718 ** proxy that has already translated HTTPS into HTTP.
2719 ** --jsmode MODE Determine how javascript is delivered with pages.
2720 ** Mode can be one of:
2721 ** inline JS inline at the end of the file
2722 ** inline-imm JS inline at point of need
2723 ** sep Separate HTTP requests for JS
2724 ** sep-imm Separate HTTP requests each issued
2725 ** at the need
2726 ** bundled One single separate HTTP for all
2727 ** JS resources
2728 ** --max-latency N Do not let any single HTTP request run for more than N
2729 ** seconds (only works on unix)
2730 ** --nocompress Do not compress HTTP replies
2731 ** --nojail Drop root privileges but do not enter the chroot jail
2732 ** --nossl signal that no SSL connections are available (Always
@@ -2760,10 +2769,11 @@
2769
2770 if( g.zErrlog==0 ){
2771 g.zErrlog = "-";
2772 }
2773 g.zExtRoot = find_option("extroot",0,1);
2774 builtin_set_js_delivery_mode(find_option("jsmode",0,1),0);
2775 zFileGlob = find_option("files-urlenc",0,1);
2776 if( zFileGlob ){
2777 char *z = mprintf("%s", zFileGlob);
2778 dehttpize(z);
2779 zFileGlob = z;
2780
--- src/mkbuiltin.c
+++ src/mkbuiltin.c
@@ -88,10 +88,11 @@
8888
i = k-1;
8989
continue;
9090
}
9191
}
9292
if( c=='\n' ){
93
+ if( j==0 ) continue;
9394
while( j>0 && isspace(z[j-1]) ) j--;
9495
z[j++] = '\n';
9596
while( i+1<n && isspace(z[i+1]) ) i++;
9697
continue;
9798
}
9899
--- src/mkbuiltin.c
+++ src/mkbuiltin.c
@@ -88,10 +88,11 @@
88 i = k-1;
89 continue;
90 }
91 }
92 if( c=='\n' ){
 
93 while( j>0 && isspace(z[j-1]) ) j--;
94 z[j++] = '\n';
95 while( i+1<n && isspace(z[i+1]) ) i++;
96 continue;
97 }
98
--- src/mkbuiltin.c
+++ src/mkbuiltin.c
@@ -88,10 +88,11 @@
88 i = k-1;
89 continue;
90 }
91 }
92 if( c=='\n' ){
93 if( j==0 ) continue;
94 while( j>0 && isspace(z[j-1]) ) j--;
95 z[j++] = '\n';
96 while( i+1<n && isspace(z[i+1]) ) i++;
97 continue;
98 }
99
+1 -1
--- src/setupuser.c
+++ src/setupuser.c
@@ -702,11 +702,11 @@
702702
@ </tr>
703703
}
704704
@ </table>
705705
@ </div></form>
706706
@ </div>
707
- style_load_one_js_file("useredit.js");
707
+ builtin_request_js("useredit.js");
708708
@ <hr>
709709
@ <h1>Notes On Privileges And Capabilities:</h1>
710710
@ <ul>
711711
if( higherUser ){
712712
@ <li><p class="missingPriv">
713713
--- src/setupuser.c
+++ src/setupuser.c
@@ -702,11 +702,11 @@
702 @ </tr>
703 }
704 @ </table>
705 @ </div></form>
706 @ </div>
707 style_load_one_js_file("useredit.js");
708 @ <hr>
709 @ <h1>Notes On Privileges And Capabilities:</h1>
710 @ <ul>
711 if( higherUser ){
712 @ <li><p class="missingPriv">
713
--- src/setupuser.c
+++ src/setupuser.c
@@ -702,11 +702,11 @@
702 @ </tr>
703 }
704 @ </table>
705 @ </div></form>
706 @ </div>
707 builtin_request_js("useredit.js");
708 @ <hr>
709 @ <h1>Notes On Privileges And Capabilities:</h1>
710 @ <ul>
711 if( higherUser ){
712 @ <li><p class="missingPriv">
713
+1 -1
--- src/skins.c
+++ src/skins.c
@@ -1101,8 +1101,8 @@
11011101
@ undo a prior publish.
11021102
}else{
11031103
@ <p>Visit the <a href='%R/setup_skin_admin'>Skin Admin</a> page
11041104
@ for cleanup and recovery actions.
11051105
}
1106
- style_load_one_js_file("skin.js");
1106
+ builtin_request_js("skin.js");
11071107
style_footer();
11081108
}
11091109
--- src/skins.c
+++ src/skins.c
@@ -1101,8 +1101,8 @@
1101 @ undo a prior publish.
1102 }else{
1103 @ <p>Visit the <a href='%R/setup_skin_admin'>Skin Admin</a> page
1104 @ for cleanup and recovery actions.
1105 }
1106 style_load_one_js_file("skin.js");
1107 style_footer();
1108 }
1109
--- src/skins.c
+++ src/skins.c
@@ -1101,8 +1101,8 @@
1101 @ undo a prior publish.
1102 }else{
1103 @ <p>Visit the <a href='%R/setup_skin_admin'>Skin Admin</a> page
1104 @ for cleanup and recovery actions.
1105 }
1106 builtin_request_js("skin.js");
1107 style_footer();
1108 }
1109
+5 -71
--- src/style.c
+++ src/style.c
@@ -88,14 +88,10 @@
8888
8989
/*
9090
** Flags for various javascript files needed prior to </body>
9191
*/
9292
static int needHrefJs = 0; /* href.js */
93
-static int needSortJs = 0; /* sorttable.js */
94
-static int needGraphJs = 0; /* graph.js */
95
-static int needCopyBtnJs = 0; /* copybtn.js */
96
-static int needAccordionJs = 0; /* accordion.js */
9793
9894
/*
9995
** Extra JS added to the end of the file.
10096
*/
10197
static Blob blobOnLoad = BLOB_INITIALIZER;
@@ -484,11 +480,11 @@
484480
zBtnFmt/*works-like:"%h%s%h%h%d"*/,
485481
zTargetId,zText,zTargetId,zTargetId,cchLength);
486482
}
487483
}
488484
free(zText);
489
- style_copybutton_control();
485
+ builtin_request_js("copybtn.js");
490486
return zResult;
491487
}
492488
493489
/*
494490
** Return a random nonce that is stored in static space. For a particular
@@ -694,66 +690,17 @@
694690
695691
/*
696692
** Indicate that the table-sorting javascript is needed.
697693
*/
698694
void style_table_sorter(void){
699
- needSortJs = 1;
700
-}
701
-
702
-/*
703
-** Indicate that the accordion javascript is needed.
704
-*/
705
-void style_accordion(void){
706
- needAccordionJs = 1;
707
-}
708
-
709
-/*
710
-** Indicate that the timeline graph javascript is needed.
711
-*/
712
-void style_graph_generator(void){
713
- needGraphJs = 1;
714
-}
715
-
716
-/*
717
-** Indicate that the copy button javascript is needed.
718
-*/
719
-void style_copybutton_control(void){
720
- needCopyBtnJs = 1;
721
-}
722
-
723
-/*
724
-** Generate code to load a single javascript file
725
-*/
726
-void style_load_one_js_file(const char *zFile){
727
- @ <script src='%R/builtin/%s(zFile)?id=%S(fossil_exe_id())'></script>
728
-}
729
-
730
-/*
731
-** All extra JS files to load.
732
-*/
733
-static const char *azJsToLoad[4];
734
-static int nJsToLoad = 0;
735
-
736
-/*
737
-** Register a new JS file to load at the end of the document.
738
-*/
739
-void style_load_js(const char *zName){
740
- int i;
741
- for(i=0; i<nJsToLoad; i++){
742
- if( fossil_strcmp(zName, azJsToLoad[i])==0 ) return;
743
- }
744
- if( nJsToLoad>=sizeof(azJsToLoad)/sizeof(azJsToLoad[0]) ){
745
- fossil_panic("too many JS files");
746
- }
747
- azJsToLoad[nJsToLoad++] = zName;
695
+ builtin_request_js("sorttable.js");
748696
}
749697
750698
/*
751699
** Generate code to load all required javascript files.
752700
*/
753701
static void style_load_all_js_files(void){
754
- int i;
755702
if( needHrefJs ){
756703
int nDelay = db_get_int("auto-hyperlink-delay",0);
757704
int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0);
758705
@ <script id='href-data' type='application/json'>\
759706
@ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
@@ -762,33 +709,20 @@
762709
@ function debugMsg(msg){
763710
@ var n = document.getElementById("debugMsg");
764711
@ if(n){n.textContent=msg;}
765712
@ }
766713
if( needHrefJs ){
714
+ @ /* href.js */
767715
cgi_append_content(builtin_text("href.js"),-1);
768716
}
769
- if( needSortJs ){
770
- cgi_append_content(builtin_text("sorttable.js"),-1);
771
- }
772
- if( needGraphJs ){
773
- cgi_append_content(builtin_text("graph.js"),-1);
774
- }
775
- if( needCopyBtnJs ){
776
- cgi_append_content(builtin_text("copybtn.js"),-1);
777
- }
778
- if( needAccordionJs ){
779
- cgi_append_content(builtin_text("accordion.js"),-1);
780
- }
781
- for(i=0; i<nJsToLoad; i++){
782
- cgi_append_content(builtin_text(azJsToLoad[i]),-1);
783
- }
784717
if( blob_size(&blobOnLoad)>0 ){
785718
@ window.onload = function(){
786719
cgi_append_content(blob_buffer(&blobOnLoad), blob_size(&blobOnLoad));
787720
cgi_append_content("\n}\n", -1);
788721
}
789722
@ </script>
723
+ builtin_fulfill_js_requests();
790724
}
791725
792726
/*
793727
** Extra JS to run after all content is loaded.
794728
*/
@@ -916,11 +850,11 @@
916850
@ </div>
917851
if( nSubmenuCtrl ){
918852
cgi_query_parameters_to_hidden();
919853
cgi_tag_query_parameter(0);
920854
@ </form>
921
- style_load_one_js_file("menu.js");
855
+ builtin_request_js("menu.js");
922856
}
923857
}
924858
925859
zAd = style_adunit_text(&mAdFlags);
926860
if( (mAdFlags & ADUNIT_RIGHT_OK)!=0 ){
927861
--- src/style.c
+++ src/style.c
@@ -88,14 +88,10 @@
88
89 /*
90 ** Flags for various javascript files needed prior to </body>
91 */
92 static int needHrefJs = 0; /* href.js */
93 static int needSortJs = 0; /* sorttable.js */
94 static int needGraphJs = 0; /* graph.js */
95 static int needCopyBtnJs = 0; /* copybtn.js */
96 static int needAccordionJs = 0; /* accordion.js */
97
98 /*
99 ** Extra JS added to the end of the file.
100 */
101 static Blob blobOnLoad = BLOB_INITIALIZER;
@@ -484,11 +480,11 @@
484 zBtnFmt/*works-like:"%h%s%h%h%d"*/,
485 zTargetId,zText,zTargetId,zTargetId,cchLength);
486 }
487 }
488 free(zText);
489 style_copybutton_control();
490 return zResult;
491 }
492
493 /*
494 ** Return a random nonce that is stored in static space. For a particular
@@ -694,66 +690,17 @@
694
695 /*
696 ** Indicate that the table-sorting javascript is needed.
697 */
698 void style_table_sorter(void){
699 needSortJs = 1;
700 }
701
702 /*
703 ** Indicate that the accordion javascript is needed.
704 */
705 void style_accordion(void){
706 needAccordionJs = 1;
707 }
708
709 /*
710 ** Indicate that the timeline graph javascript is needed.
711 */
712 void style_graph_generator(void){
713 needGraphJs = 1;
714 }
715
716 /*
717 ** Indicate that the copy button javascript is needed.
718 */
719 void style_copybutton_control(void){
720 needCopyBtnJs = 1;
721 }
722
723 /*
724 ** Generate code to load a single javascript file
725 */
726 void style_load_one_js_file(const char *zFile){
727 @ <script src='%R/builtin/%s(zFile)?id=%S(fossil_exe_id())'></script>
728 }
729
730 /*
731 ** All extra JS files to load.
732 */
733 static const char *azJsToLoad[4];
734 static int nJsToLoad = 0;
735
736 /*
737 ** Register a new JS file to load at the end of the document.
738 */
739 void style_load_js(const char *zName){
740 int i;
741 for(i=0; i<nJsToLoad; i++){
742 if( fossil_strcmp(zName, azJsToLoad[i])==0 ) return;
743 }
744 if( nJsToLoad>=sizeof(azJsToLoad)/sizeof(azJsToLoad[0]) ){
745 fossil_panic("too many JS files");
746 }
747 azJsToLoad[nJsToLoad++] = zName;
748 }
749
750 /*
751 ** Generate code to load all required javascript files.
752 */
753 static void style_load_all_js_files(void){
754 int i;
755 if( needHrefJs ){
756 int nDelay = db_get_int("auto-hyperlink-delay",0);
757 int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0);
758 @ <script id='href-data' type='application/json'>\
759 @ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
@@ -762,33 +709,20 @@
762 @ function debugMsg(msg){
763 @ var n = document.getElementById("debugMsg");
764 @ if(n){n.textContent=msg;}
765 @ }
766 if( needHrefJs ){
 
767 cgi_append_content(builtin_text("href.js"),-1);
768 }
769 if( needSortJs ){
770 cgi_append_content(builtin_text("sorttable.js"),-1);
771 }
772 if( needGraphJs ){
773 cgi_append_content(builtin_text("graph.js"),-1);
774 }
775 if( needCopyBtnJs ){
776 cgi_append_content(builtin_text("copybtn.js"),-1);
777 }
778 if( needAccordionJs ){
779 cgi_append_content(builtin_text("accordion.js"),-1);
780 }
781 for(i=0; i<nJsToLoad; i++){
782 cgi_append_content(builtin_text(azJsToLoad[i]),-1);
783 }
784 if( blob_size(&blobOnLoad)>0 ){
785 @ window.onload = function(){
786 cgi_append_content(blob_buffer(&blobOnLoad), blob_size(&blobOnLoad));
787 cgi_append_content("\n}\n", -1);
788 }
789 @ </script>
 
790 }
791
792 /*
793 ** Extra JS to run after all content is loaded.
794 */
@@ -916,11 +850,11 @@
916 @ </div>
917 if( nSubmenuCtrl ){
918 cgi_query_parameters_to_hidden();
919 cgi_tag_query_parameter(0);
920 @ </form>
921 style_load_one_js_file("menu.js");
922 }
923 }
924
925 zAd = style_adunit_text(&mAdFlags);
926 if( (mAdFlags & ADUNIT_RIGHT_OK)!=0 ){
927
--- src/style.c
+++ src/style.c
@@ -88,14 +88,10 @@
88
89 /*
90 ** Flags for various javascript files needed prior to </body>
91 */
92 static int needHrefJs = 0; /* href.js */
 
 
 
 
93
94 /*
95 ** Extra JS added to the end of the file.
96 */
97 static Blob blobOnLoad = BLOB_INITIALIZER;
@@ -484,11 +480,11 @@
480 zBtnFmt/*works-like:"%h%s%h%h%d"*/,
481 zTargetId,zText,zTargetId,zTargetId,cchLength);
482 }
483 }
484 free(zText);
485 builtin_request_js("copybtn.js");
486 return zResult;
487 }
488
489 /*
490 ** Return a random nonce that is stored in static space. For a particular
@@ -694,66 +690,17 @@
690
691 /*
692 ** Indicate that the table-sorting javascript is needed.
693 */
694 void style_table_sorter(void){
695 builtin_request_js("sorttable.js");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
696 }
697
698 /*
699 ** Generate code to load all required javascript files.
700 */
701 static void style_load_all_js_files(void){
 
702 if( needHrefJs ){
703 int nDelay = db_get_int("auto-hyperlink-delay",0);
704 int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0);
705 @ <script id='href-data' type='application/json'>\
706 @ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
@@ -762,33 +709,20 @@
709 @ function debugMsg(msg){
710 @ var n = document.getElementById("debugMsg");
711 @ if(n){n.textContent=msg;}
712 @ }
713 if( needHrefJs ){
714 @ /* href.js */
715 cgi_append_content(builtin_text("href.js"),-1);
716 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
717 if( blob_size(&blobOnLoad)>0 ){
718 @ window.onload = function(){
719 cgi_append_content(blob_buffer(&blobOnLoad), blob_size(&blobOnLoad));
720 cgi_append_content("\n}\n", -1);
721 }
722 @ </script>
723 builtin_fulfill_js_requests();
724 }
725
726 /*
727 ** Extra JS to run after all content is loaded.
728 */
@@ -916,11 +850,11 @@
850 @ </div>
851 if( nSubmenuCtrl ){
852 cgi_query_parameters_to_hidden();
853 cgi_tag_query_parameter(0);
854 @ </form>
855 builtin_request_js("menu.js");
856 }
857 }
858
859 zAd = style_adunit_text(&mAdFlags);
860 if( (mAdFlags & ADUNIT_RIGHT_OK)!=0 ){
861
+6 -2
--- src/timeline.c
+++ src/timeline.c
@@ -1083,12 +1083,12 @@
10831083
cgi_printf("\"br\":\"%j\",", pRow->zBranch ? pRow->zBranch : "");
10841084
cgi_printf("\"h\":\"%!S\"}%s",
10851085
pRow->zUuid, pRow->pNext ? ",\n" : "]\n");
10861086
}
10871087
@ }</script>
1088
- style_graph_generator();
1089
- style_copybutton_control(); /* Dependency: graph.js requires copybtn.js. */
1088
+ builtin_request_js("graph.js");
1089
+ builtin_request_js("copybtn.js"); /* Required by graph.js */
10901090
graph_free(pGraph);
10911091
}
10921092
}
10931093
10941094
/*
@@ -1741,10 +1741,14 @@
17411741
}
17421742
}else{
17431743
z = "50";
17441744
nEntry = 50;
17451745
}
1746
+
1747
+ /* Undocumented query parameter to set JS mode */
1748
+ builtin_set_js_delivery_mode(P("jsmode"),1);
1749
+
17461750
secondaryRid = name_to_typed_rid(P("sel2"),"ci");
17471751
selectedRid = name_to_typed_rid(P("sel1"),"ci");
17481752
cgi_replace_query_parameter("n",z);
17491753
cookie_write_parameter("n","n",0);
17501754
tmFlags |= timeline_ss_submenu();
17511755
--- src/timeline.c
+++ src/timeline.c
@@ -1083,12 +1083,12 @@
1083 cgi_printf("\"br\":\"%j\",", pRow->zBranch ? pRow->zBranch : "");
1084 cgi_printf("\"h\":\"%!S\"}%s",
1085 pRow->zUuid, pRow->pNext ? ",\n" : "]\n");
1086 }
1087 @ }</script>
1088 style_graph_generator();
1089 style_copybutton_control(); /* Dependency: graph.js requires copybtn.js. */
1090 graph_free(pGraph);
1091 }
1092 }
1093
1094 /*
@@ -1741,10 +1741,14 @@
1741 }
1742 }else{
1743 z = "50";
1744 nEntry = 50;
1745 }
 
 
 
 
1746 secondaryRid = name_to_typed_rid(P("sel2"),"ci");
1747 selectedRid = name_to_typed_rid(P("sel1"),"ci");
1748 cgi_replace_query_parameter("n",z);
1749 cookie_write_parameter("n","n",0);
1750 tmFlags |= timeline_ss_submenu();
1751
--- src/timeline.c
+++ src/timeline.c
@@ -1083,12 +1083,12 @@
1083 cgi_printf("\"br\":\"%j\",", pRow->zBranch ? pRow->zBranch : "");
1084 cgi_printf("\"h\":\"%!S\"}%s",
1085 pRow->zUuid, pRow->pNext ? ",\n" : "]\n");
1086 }
1087 @ }</script>
1088 builtin_request_js("graph.js");
1089 builtin_request_js("copybtn.js"); /* Required by graph.js */
1090 graph_free(pGraph);
1091 }
1092 }
1093
1094 /*
@@ -1741,10 +1741,14 @@
1741 }
1742 }else{
1743 z = "50";
1744 nEntry = 50;
1745 }
1746
1747 /* Undocumented query parameter to set JS mode */
1748 builtin_set_js_delivery_mode(P("jsmode"),1);
1749
1750 secondaryRid = name_to_typed_rid(P("sel2"),"ci");
1751 selectedRid = name_to_typed_rid(P("sel1"),"ci");
1752 cgi_replace_query_parameter("n",z);
1753 cookie_write_parameter("n","n",0);
1754 tmFlags |= timeline_ss_submenu();
1755
+1 -1
--- src/wiki.c
+++ src/wiki.c
@@ -1844,8 +1844,8 @@
18441844
blob_reset(&tail);
18451845
blob_reset(&title);
18461846
blob_reset(&wiki);
18471847
}
18481848
manifest_destroy(pWiki);
1849
- style_accordion();
1849
+ builtin_request_js("accordion.js");
18501850
return 1;
18511851
}
18521852
--- src/wiki.c
+++ src/wiki.c
@@ -1844,8 +1844,8 @@
1844 blob_reset(&tail);
1845 blob_reset(&title);
1846 blob_reset(&wiki);
1847 }
1848 manifest_destroy(pWiki);
1849 style_accordion();
1850 return 1;
1851 }
1852
--- src/wiki.c
+++ src/wiki.c
@@ -1844,8 +1844,8 @@
1844 blob_reset(&tail);
1845 blob_reset(&title);
1846 blob_reset(&wiki);
1847 }
1848 manifest_destroy(pWiki);
1849 builtin_request_js("accordion.js");
1850 return 1;
1851 }
1852

Keyboard Shortcuts

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