Fossil SCM
Add the new "script" element to skins, accessible as /script.js. The idea is to put the hamburger menu javascript from the js-hamburger-menu branch in this script element, rather than inlining it in the footer. But I am not certain that is the best way to go so this change is parked on a branch for now.
Commit
e5dbc6122d7b1c3aaa5c3fbf801bed6a00374fad266c138eb04b2c0419a1555b
Parent
ed84acb6d28398f…
2 files changed
+9
-4
+47
-21
+9
-4
| --- src/skins.c | ||
| +++ src/skins.c | ||
| @@ -55,13 +55,15 @@ | ||
| 55 | 55 | { "Khaki, No Logo", "khaki", 0 }, |
| 56 | 56 | { "Ardoise", "ardoise", 0 }, |
| 57 | 57 | }; |
| 58 | 58 | |
| 59 | 59 | /* |
| 60 | -** A skin consists of four "files" named here: | |
| 60 | +** A skin consists of five "files" named here: | |
| 61 | 61 | */ |
| 62 | -static const char *azSkinFile[] = { "css", "header", "footer", "details" }; | |
| 62 | +static const char *azSkinFile[] = { | |
| 63 | + "css", "header", "footer", "details", "js" | |
| 64 | +}; | |
| 63 | 65 | |
| 64 | 66 | /* |
| 65 | 67 | ** Alternative skins can be specified in the CGI script or by options |
| 66 | 68 | ** on the "http", "ui", and "server" commands. The alternative skin |
| 67 | 69 | ** name must be one of the aBuiltinSkin[].zLabel names. If there is |
| @@ -149,11 +151,11 @@ | ||
| 149 | 151 | |
| 150 | 152 | /* |
| 151 | 153 | ** The following routines return the various components of the skin |
| 152 | 154 | ** that should be used for the current run. |
| 153 | 155 | ** |
| 154 | -** zWhat is one of: "css", "header", "footer", "details". | |
| 156 | +** zWhat is one of: "css", "header", "footer", "details", "js" | |
| 155 | 157 | */ |
| 156 | 158 | const char *skin_get(const char *zWhat){ |
| 157 | 159 | const char *zOut; |
| 158 | 160 | char *z; |
| 159 | 161 | if( iDraftSkin ){ |
| @@ -691,11 +693,11 @@ | ||
| 691 | 693 | ** WEBPAGE: setup_skinedit |
| 692 | 694 | ** |
| 693 | 695 | ** Edit aspects of a skin determined by the w= query parameter. |
| 694 | 696 | ** Requires Setup privileges. |
| 695 | 697 | ** |
| 696 | -** w=NUM -- 0=CSS, 1=footer, 2=header, 3=details | |
| 698 | +** w=NUM -- 0=CSS, 1=footer, 2=header, 3=details, 4=js | |
| 697 | 699 | ** sk=NUM -- the draft skin number |
| 698 | 700 | */ |
| 699 | 701 | void setup_skinedit(void){ |
| 700 | 702 | static const struct sSkinAddr { |
| 701 | 703 | const char *zFile; |
| @@ -704,10 +706,11 @@ | ||
| 704 | 706 | } aSkinAttr[] = { |
| 705 | 707 | /* 0 */ { "css", "CSS", "CSS", }, |
| 706 | 708 | /* 1 */ { "footer", "Page Footer", "Footer", }, |
| 707 | 709 | /* 2 */ { "header", "Page Header", "Header", }, |
| 708 | 710 | /* 3 */ { "details", "Display Details", "Details", }, |
| 711 | + /* 4 */ { "js", "JavaScript", "Script", }, | |
| 709 | 712 | }; |
| 710 | 713 | const char *zBasis; /* The baseline file */ |
| 711 | 714 | const char *zOrig; /* Original content prior to editing */ |
| 712 | 715 | const char *zContent; /* Content after editing */ |
| 713 | 716 | const char *zDflt; /* Default content */ |
| @@ -1016,10 +1019,12 @@ | ||
| 1016 | 1019 | @ Header</a> |
| 1017 | 1020 | @ <li><a href='%R/setup_skinedit?w=1&sk=%d(iSkin)' target='_blank'>\ |
| 1018 | 1021 | @ Footer</a> |
| 1019 | 1022 | @ <li><a href='%R/setup_skinedit?w=3&sk=%d(iSkin)' target='_blank'>\ |
| 1020 | 1023 | @ Details</a> |
| 1024 | + @ <li><a href='%R/setup_skinedit?w=4&sk=%d(iSkin)' target='_blank'>\ | |
| 1025 | + @ Javascript</a> (optional) | |
| 1021 | 1026 | @ </ul> |
| 1022 | 1027 | } |
| 1023 | 1028 | @ |
| 1024 | 1029 | @ <a name='step5'></a> |
| 1025 | 1030 | @ <h1>Step 5: Verify The Draft Skin</h1> |
| 1026 | 1031 |
| --- src/skins.c | |
| +++ src/skins.c | |
| @@ -55,13 +55,15 @@ | |
| 55 | { "Khaki, No Logo", "khaki", 0 }, |
| 56 | { "Ardoise", "ardoise", 0 }, |
| 57 | }; |
| 58 | |
| 59 | /* |
| 60 | ** A skin consists of four "files" named here: |
| 61 | */ |
| 62 | static const char *azSkinFile[] = { "css", "header", "footer", "details" }; |
| 63 | |
| 64 | /* |
| 65 | ** Alternative skins can be specified in the CGI script or by options |
| 66 | ** on the "http", "ui", and "server" commands. The alternative skin |
| 67 | ** name must be one of the aBuiltinSkin[].zLabel names. If there is |
| @@ -149,11 +151,11 @@ | |
| 149 | |
| 150 | /* |
| 151 | ** The following routines return the various components of the skin |
| 152 | ** that should be used for the current run. |
| 153 | ** |
| 154 | ** zWhat is one of: "css", "header", "footer", "details". |
| 155 | */ |
| 156 | const char *skin_get(const char *zWhat){ |
| 157 | const char *zOut; |
| 158 | char *z; |
| 159 | if( iDraftSkin ){ |
| @@ -691,11 +693,11 @@ | |
| 691 | ** WEBPAGE: setup_skinedit |
| 692 | ** |
| 693 | ** Edit aspects of a skin determined by the w= query parameter. |
| 694 | ** Requires Setup privileges. |
| 695 | ** |
| 696 | ** w=NUM -- 0=CSS, 1=footer, 2=header, 3=details |
| 697 | ** sk=NUM -- the draft skin number |
| 698 | */ |
| 699 | void setup_skinedit(void){ |
| 700 | static const struct sSkinAddr { |
| 701 | const char *zFile; |
| @@ -704,10 +706,11 @@ | |
| 704 | } aSkinAttr[] = { |
| 705 | /* 0 */ { "css", "CSS", "CSS", }, |
| 706 | /* 1 */ { "footer", "Page Footer", "Footer", }, |
| 707 | /* 2 */ { "header", "Page Header", "Header", }, |
| 708 | /* 3 */ { "details", "Display Details", "Details", }, |
| 709 | }; |
| 710 | const char *zBasis; /* The baseline file */ |
| 711 | const char *zOrig; /* Original content prior to editing */ |
| 712 | const char *zContent; /* Content after editing */ |
| 713 | const char *zDflt; /* Default content */ |
| @@ -1016,10 +1019,12 @@ | |
| 1016 | @ Header</a> |
| 1017 | @ <li><a href='%R/setup_skinedit?w=1&sk=%d(iSkin)' target='_blank'>\ |
| 1018 | @ Footer</a> |
| 1019 | @ <li><a href='%R/setup_skinedit?w=3&sk=%d(iSkin)' target='_blank'>\ |
| 1020 | @ Details</a> |
| 1021 | @ </ul> |
| 1022 | } |
| 1023 | @ |
| 1024 | @ <a name='step5'></a> |
| 1025 | @ <h1>Step 5: Verify The Draft Skin</h1> |
| 1026 |
| --- src/skins.c | |
| +++ src/skins.c | |
| @@ -55,13 +55,15 @@ | |
| 55 | { "Khaki, No Logo", "khaki", 0 }, |
| 56 | { "Ardoise", "ardoise", 0 }, |
| 57 | }; |
| 58 | |
| 59 | /* |
| 60 | ** A skin consists of five "files" named here: |
| 61 | */ |
| 62 | static const char *azSkinFile[] = { |
| 63 | "css", "header", "footer", "details", "js" |
| 64 | }; |
| 65 | |
| 66 | /* |
| 67 | ** Alternative skins can be specified in the CGI script or by options |
| 68 | ** on the "http", "ui", and "server" commands. The alternative skin |
| 69 | ** name must be one of the aBuiltinSkin[].zLabel names. If there is |
| @@ -149,11 +151,11 @@ | |
| 151 | |
| 152 | /* |
| 153 | ** The following routines return the various components of the skin |
| 154 | ** that should be used for the current run. |
| 155 | ** |
| 156 | ** zWhat is one of: "css", "header", "footer", "details", "js" |
| 157 | */ |
| 158 | const char *skin_get(const char *zWhat){ |
| 159 | const char *zOut; |
| 160 | char *z; |
| 161 | if( iDraftSkin ){ |
| @@ -691,11 +693,11 @@ | |
| 693 | ** WEBPAGE: setup_skinedit |
| 694 | ** |
| 695 | ** Edit aspects of a skin determined by the w= query parameter. |
| 696 | ** Requires Setup privileges. |
| 697 | ** |
| 698 | ** w=NUM -- 0=CSS, 1=footer, 2=header, 3=details, 4=js |
| 699 | ** sk=NUM -- the draft skin number |
| 700 | */ |
| 701 | void setup_skinedit(void){ |
| 702 | static const struct sSkinAddr { |
| 703 | const char *zFile; |
| @@ -704,10 +706,11 @@ | |
| 706 | } aSkinAttr[] = { |
| 707 | /* 0 */ { "css", "CSS", "CSS", }, |
| 708 | /* 1 */ { "footer", "Page Footer", "Footer", }, |
| 709 | /* 2 */ { "header", "Page Header", "Header", }, |
| 710 | /* 3 */ { "details", "Display Details", "Details", }, |
| 711 | /* 4 */ { "js", "JavaScript", "Script", }, |
| 712 | }; |
| 713 | const char *zBasis; /* The baseline file */ |
| 714 | const char *zOrig; /* Original content prior to editing */ |
| 715 | const char *zContent; /* Content after editing */ |
| 716 | const char *zDflt; /* Default content */ |
| @@ -1016,10 +1019,12 @@ | |
| 1019 | @ Header</a> |
| 1020 | @ <li><a href='%R/setup_skinedit?w=1&sk=%d(iSkin)' target='_blank'>\ |
| 1021 | @ Footer</a> |
| 1022 | @ <li><a href='%R/setup_skinedit?w=3&sk=%d(iSkin)' target='_blank'>\ |
| 1023 | @ Details</a> |
| 1024 | @ <li><a href='%R/setup_skinedit?w=4&sk=%d(iSkin)' target='_blank'>\ |
| 1025 | @ Javascript</a> (optional) |
| 1026 | @ </ul> |
| 1027 | } |
| 1028 | @ |
| 1029 | @ <a name='step5'></a> |
| 1030 | @ <h1>Step 5: Verify The Draft Skin</h1> |
| 1031 |
+47
-21
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -402,10 +402,37 @@ | ||
| 402 | 402 | @ <link rel="stylesheet" href="$stylesheet_url" type="text/css" \ |
| 403 | 403 | @ media="screen" /> |
| 404 | 404 | @ </head> |
| 405 | 405 | @ <body> |
| 406 | 406 | ; |
| 407 | + | |
| 408 | +/* | |
| 409 | +** Initialize all the default TH1 variables | |
| 410 | +*/ | |
| 411 | +static void style_init_th1_vars(const char *zTitle){ | |
| 412 | + Th_Store("nonce", style_nonce()); | |
| 413 | + Th_Store("project_name", db_get("project-name","Unnamed Fossil Project")); | |
| 414 | + Th_Store("project_description", db_get("project-description","")); | |
| 415 | + if( zTitle ) Th_Store("title", zTitle); | |
| 416 | + Th_Store("baseurl", g.zBaseURL); | |
| 417 | + Th_Store("secureurl", login_wants_https_redirect()? g.zHttpsURL: g.zBaseURL); | |
| 418 | + Th_Store("home", g.zTop); | |
| 419 | + Th_Store("index_page", db_get("index-page","/home")); | |
| 420 | + if( local_zCurrentPage==0 ) style_set_current_page("%T", g.zPath); | |
| 421 | + Th_Store("current_page", local_zCurrentPage); | |
| 422 | + Th_Store("csrf_token", g.zCsrfToken); | |
| 423 | + Th_Store("release_version", RELEASE_VERSION); | |
| 424 | + Th_Store("manifest_version", MANIFEST_VERSION); | |
| 425 | + Th_Store("manifest_date", MANIFEST_DATE); | |
| 426 | + Th_Store("compiler_name", COMPILER_NAME); | |
| 427 | + url_var("stylesheet", "css", "style.css"); | |
| 428 | + image_url_var("logo"); | |
| 429 | + image_url_var("background"); | |
| 430 | + if( !login_is_nobody() ){ | |
| 431 | + Th_Store("login", g.zLogin); | |
| 432 | + } | |
| 433 | +} | |
| 407 | 434 | |
| 408 | 435 | /* |
| 409 | 436 | ** Draw the header. |
| 410 | 437 | */ |
| 411 | 438 | void style_header(const char *zTitleFormat, ...){ |
| @@ -423,31 +450,11 @@ | ||
| 423 | 450 | @ <!DOCTYPE html> |
| 424 | 451 | |
| 425 | 452 | if( g.thTrace ) Th_Trace("BEGIN_HEADER<br />\n", -1); |
| 426 | 453 | |
| 427 | 454 | /* Generate the header up through the main menu */ |
| 428 | - Th_Store("nonce", style_nonce()); | |
| 429 | - Th_Store("project_name", db_get("project-name","Unnamed Fossil Project")); | |
| 430 | - Th_Store("project_description", db_get("project-description","")); | |
| 431 | - Th_Store("title", zTitle); | |
| 432 | - Th_Store("baseurl", g.zBaseURL); | |
| 433 | - Th_Store("secureurl", login_wants_https_redirect()? g.zHttpsURL: g.zBaseURL); | |
| 434 | - Th_Store("home", g.zTop); | |
| 435 | - Th_Store("index_page", db_get("index-page","/home")); | |
| 436 | - if( local_zCurrentPage==0 ) style_set_current_page("%T", g.zPath); | |
| 437 | - Th_Store("current_page", local_zCurrentPage); | |
| 438 | - Th_Store("csrf_token", g.zCsrfToken); | |
| 439 | - Th_Store("release_version", RELEASE_VERSION); | |
| 440 | - Th_Store("manifest_version", MANIFEST_VERSION); | |
| 441 | - Th_Store("manifest_date", MANIFEST_DATE); | |
| 442 | - Th_Store("compiler_name", COMPILER_NAME); | |
| 443 | - url_var("stylesheet", "css", "style.css"); | |
| 444 | - image_url_var("logo"); | |
| 445 | - image_url_var("background"); | |
| 446 | - if( !login_is_nobody() ){ | |
| 447 | - Th_Store("login", g.zLogin); | |
| 448 | - } | |
| 455 | + style_init_th1_vars(zTitle); | |
| 449 | 456 | if( sqlite3_strlike("%<body%", zHeader, 0)!=0 ){ |
| 450 | 457 | Th_Render(zDfltHeader); |
| 451 | 458 | } |
| 452 | 459 | if( g.thTrace ) Th_Trace("BEGIN_HEADER_SCRIPT<br />\n", -1); |
| 453 | 460 | Th_Render(zHeader); |
| @@ -848,10 +855,29 @@ | ||
| 848 | 855 | zSelector = g.argv[3]; |
| 849 | 856 | found = containsSelector(blob_str(&css), zSelector); |
| 850 | 857 | fossil_print("%s %s\n", zSelector, found ? "found" : "not found"); |
| 851 | 858 | blob_reset(&css); |
| 852 | 859 | } |
| 860 | + | |
| 861 | +/* | |
| 862 | +** WEBPAGE: script.js | |
| 863 | +** | |
| 864 | +** Return the "Javascript" content for the current skin (if there is any) | |
| 865 | +*/ | |
| 866 | +void page_script_js(void){ | |
| 867 | + const char *zScript = skin_get("js"); | |
| 868 | + if( P("test") ){ | |
| 869 | + /* Render the script as plain-text for testing purposes, if the "test" | |
| 870 | + ** query parameter is present */ | |
| 871 | + cgi_set_content_type("text/plain"); | |
| 872 | + }else{ | |
| 873 | + /* Default behavior is to return javascript */ | |
| 874 | + cgi_set_content_type("application/javascript"); | |
| 875 | + } | |
| 876 | + style_init_th1_vars(0); | |
| 877 | + Th_Render(zScript?zScript:""); | |
| 878 | +} | |
| 853 | 879 | |
| 854 | 880 | |
| 855 | 881 | /* |
| 856 | 882 | ** WEBPAGE: style.css |
| 857 | 883 | ** |
| 858 | 884 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -402,10 +402,37 @@ | |
| 402 | @ <link rel="stylesheet" href="$stylesheet_url" type="text/css" \ |
| 403 | @ media="screen" /> |
| 404 | @ </head> |
| 405 | @ <body> |
| 406 | ; |
| 407 | |
| 408 | /* |
| 409 | ** Draw the header. |
| 410 | */ |
| 411 | void style_header(const char *zTitleFormat, ...){ |
| @@ -423,31 +450,11 @@ | |
| 423 | @ <!DOCTYPE html> |
| 424 | |
| 425 | if( g.thTrace ) Th_Trace("BEGIN_HEADER<br />\n", -1); |
| 426 | |
| 427 | /* Generate the header up through the main menu */ |
| 428 | Th_Store("nonce", style_nonce()); |
| 429 | Th_Store("project_name", db_get("project-name","Unnamed Fossil Project")); |
| 430 | Th_Store("project_description", db_get("project-description","")); |
| 431 | Th_Store("title", zTitle); |
| 432 | Th_Store("baseurl", g.zBaseURL); |
| 433 | Th_Store("secureurl", login_wants_https_redirect()? g.zHttpsURL: g.zBaseURL); |
| 434 | Th_Store("home", g.zTop); |
| 435 | Th_Store("index_page", db_get("index-page","/home")); |
| 436 | if( local_zCurrentPage==0 ) style_set_current_page("%T", g.zPath); |
| 437 | Th_Store("current_page", local_zCurrentPage); |
| 438 | Th_Store("csrf_token", g.zCsrfToken); |
| 439 | Th_Store("release_version", RELEASE_VERSION); |
| 440 | Th_Store("manifest_version", MANIFEST_VERSION); |
| 441 | Th_Store("manifest_date", MANIFEST_DATE); |
| 442 | Th_Store("compiler_name", COMPILER_NAME); |
| 443 | url_var("stylesheet", "css", "style.css"); |
| 444 | image_url_var("logo"); |
| 445 | image_url_var("background"); |
| 446 | if( !login_is_nobody() ){ |
| 447 | Th_Store("login", g.zLogin); |
| 448 | } |
| 449 | if( sqlite3_strlike("%<body%", zHeader, 0)!=0 ){ |
| 450 | Th_Render(zDfltHeader); |
| 451 | } |
| 452 | if( g.thTrace ) Th_Trace("BEGIN_HEADER_SCRIPT<br />\n", -1); |
| 453 | Th_Render(zHeader); |
| @@ -848,10 +855,29 @@ | |
| 848 | zSelector = g.argv[3]; |
| 849 | found = containsSelector(blob_str(&css), zSelector); |
| 850 | fossil_print("%s %s\n", zSelector, found ? "found" : "not found"); |
| 851 | blob_reset(&css); |
| 852 | } |
| 853 | |
| 854 | |
| 855 | /* |
| 856 | ** WEBPAGE: style.css |
| 857 | ** |
| 858 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -402,10 +402,37 @@ | |
| 402 | @ <link rel="stylesheet" href="$stylesheet_url" type="text/css" \ |
| 403 | @ media="screen" /> |
| 404 | @ </head> |
| 405 | @ <body> |
| 406 | ; |
| 407 | |
| 408 | /* |
| 409 | ** Initialize all the default TH1 variables |
| 410 | */ |
| 411 | static void style_init_th1_vars(const char *zTitle){ |
| 412 | Th_Store("nonce", style_nonce()); |
| 413 | Th_Store("project_name", db_get("project-name","Unnamed Fossil Project")); |
| 414 | Th_Store("project_description", db_get("project-description","")); |
| 415 | if( zTitle ) Th_Store("title", zTitle); |
| 416 | Th_Store("baseurl", g.zBaseURL); |
| 417 | Th_Store("secureurl", login_wants_https_redirect()? g.zHttpsURL: g.zBaseURL); |
| 418 | Th_Store("home", g.zTop); |
| 419 | Th_Store("index_page", db_get("index-page","/home")); |
| 420 | if( local_zCurrentPage==0 ) style_set_current_page("%T", g.zPath); |
| 421 | Th_Store("current_page", local_zCurrentPage); |
| 422 | Th_Store("csrf_token", g.zCsrfToken); |
| 423 | Th_Store("release_version", RELEASE_VERSION); |
| 424 | Th_Store("manifest_version", MANIFEST_VERSION); |
| 425 | Th_Store("manifest_date", MANIFEST_DATE); |
| 426 | Th_Store("compiler_name", COMPILER_NAME); |
| 427 | url_var("stylesheet", "css", "style.css"); |
| 428 | image_url_var("logo"); |
| 429 | image_url_var("background"); |
| 430 | if( !login_is_nobody() ){ |
| 431 | Th_Store("login", g.zLogin); |
| 432 | } |
| 433 | } |
| 434 | |
| 435 | /* |
| 436 | ** Draw the header. |
| 437 | */ |
| 438 | void style_header(const char *zTitleFormat, ...){ |
| @@ -423,31 +450,11 @@ | |
| 450 | @ <!DOCTYPE html> |
| 451 | |
| 452 | if( g.thTrace ) Th_Trace("BEGIN_HEADER<br />\n", -1); |
| 453 | |
| 454 | /* Generate the header up through the main menu */ |
| 455 | style_init_th1_vars(zTitle); |
| 456 | if( sqlite3_strlike("%<body%", zHeader, 0)!=0 ){ |
| 457 | Th_Render(zDfltHeader); |
| 458 | } |
| 459 | if( g.thTrace ) Th_Trace("BEGIN_HEADER_SCRIPT<br />\n", -1); |
| 460 | Th_Render(zHeader); |
| @@ -848,10 +855,29 @@ | |
| 855 | zSelector = g.argv[3]; |
| 856 | found = containsSelector(blob_str(&css), zSelector); |
| 857 | fossil_print("%s %s\n", zSelector, found ? "found" : "not found"); |
| 858 | blob_reset(&css); |
| 859 | } |
| 860 | |
| 861 | /* |
| 862 | ** WEBPAGE: script.js |
| 863 | ** |
| 864 | ** Return the "Javascript" content for the current skin (if there is any) |
| 865 | */ |
| 866 | void page_script_js(void){ |
| 867 | const char *zScript = skin_get("js"); |
| 868 | if( P("test") ){ |
| 869 | /* Render the script as plain-text for testing purposes, if the "test" |
| 870 | ** query parameter is present */ |
| 871 | cgi_set_content_type("text/plain"); |
| 872 | }else{ |
| 873 | /* Default behavior is to return javascript */ |
| 874 | cgi_set_content_type("application/javascript"); |
| 875 | } |
| 876 | style_init_th1_vars(0); |
| 877 | Th_Render(zScript?zScript:""); |
| 878 | } |
| 879 | |
| 880 | |
| 881 | /* |
| 882 | ** WEBPAGE: style.css |
| 883 | ** |
| 884 |