Fossil SCM
Skin selection is now stored in the user display prefs cookie and can be modified from any page by passing the skin=xyz URL parameter. Gets trumped by /draftX URI or --skin CLI flag or skin: CGI config setting. Removed /skn_XYZ URI handling. /skins page now uses the new mechanism for skin selection. UDC is now rendered on every page if it was modified during that request, regardless of the 'udc' URL parameter. See discussion at [https://fossil-scm.org/forum/forumpost/4d3a10c72a|/forumpost/4d3a10c72a].
Commit
71a2d68a7a113e7cce3b33c2bc595f4d8b1e7b09b0e260860b3784475a1fe06c
Parent
4de677dcc3e6122…
11 files changed
-1
+12
+4
-3
-1
-1
-3
+2
-24
+44
-9
+4
-1
-1
-1
| --- src/branch.c | ||
| +++ src/branch.c | ||
| @@ -683,11 +683,10 @@ | ||
| 683 | 683 | style_set_current_feature("branch"); |
| 684 | 684 | style_header("Branches"); |
| 685 | 685 | style_submenu_element("List", "brlist"); |
| 686 | 686 | login_anonymous_available(); |
| 687 | 687 | timeline_ss_submenu(); |
| 688 | - cookie_render(); | |
| 689 | 688 | @ <h2>The initial check-in for each branch:</h2> |
| 690 | 689 | blob_append(&sql, timeline_query_for_www(), -1); |
| 691 | 690 | blob_append_sql(&sql, |
| 692 | 691 | "AND blob.rid IN (SELECT rid FROM tagxref" |
| 693 | 692 | " WHERE tagtype>0 AND tagid=%d AND srcid!=0)", TAG_BRANCH); |
| 694 | 693 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -683,11 +683,10 @@ | |
| 683 | style_set_current_feature("branch"); |
| 684 | style_header("Branches"); |
| 685 | style_submenu_element("List", "brlist"); |
| 686 | login_anonymous_available(); |
| 687 | timeline_ss_submenu(); |
| 688 | cookie_render(); |
| 689 | @ <h2>The initial check-in for each branch:</h2> |
| 690 | blob_append(&sql, timeline_query_for_www(), -1); |
| 691 | blob_append_sql(&sql, |
| 692 | "AND blob.rid IN (SELECT rid FROM tagxref" |
| 693 | " WHERE tagtype>0 AND tagid=%d AND srcid!=0)", TAG_BRANCH); |
| 694 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -683,11 +683,10 @@ | |
| 683 | style_set_current_feature("branch"); |
| 684 | style_header("Branches"); |
| 685 | style_submenu_element("List", "brlist"); |
| 686 | login_anonymous_available(); |
| 687 | timeline_ss_submenu(); |
| 688 | @ <h2>The initial check-in for each branch:</h2> |
| 689 | blob_append(&sql, timeline_query_for_www(), -1); |
| 690 | blob_append_sql(&sql, |
| 691 | "AND blob.rid IN (SELECT rid FROM tagxref" |
| 692 | " WHERE tagtype>0 AND tagid=%d AND srcid!=0)", TAG_BRANCH); |
| 693 |
+12
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -1159,16 +1159,28 @@ | ||
| 1159 | 1159 | #endif |
| 1160 | 1160 | z = (char*)P("HTTP_COOKIE"); |
| 1161 | 1161 | if( z ){ |
| 1162 | 1162 | z = fossil_strdup(z); |
| 1163 | 1163 | add_param_list(z, ';'); |
| 1164 | + z = (char*)cookie_value("skin",0); | |
| 1165 | + if(z){ | |
| 1166 | + skin_use_alternative(z, 2); | |
| 1167 | + } | |
| 1164 | 1168 | } |
| 1165 | 1169 | |
| 1166 | 1170 | z = (char*)P("QUERY_STRING"); |
| 1167 | 1171 | if( z ){ |
| 1168 | 1172 | z = fossil_strdup(z); |
| 1169 | 1173 | add_param_list(z, '&'); |
| 1174 | + z = (char*)P("skin"); | |
| 1175 | + if(z){ | |
| 1176 | + char *zErr = skin_use_alternative(z, 2); | |
| 1177 | + if(!zErr){ | |
| 1178 | + cookie_write_parameter("skin","skin",z); | |
| 1179 | + } | |
| 1180 | + fossil_free(zErr); | |
| 1181 | + } | |
| 1170 | 1182 | } |
| 1171 | 1183 | |
| 1172 | 1184 | z = (char*)P("REMOTE_ADDR"); |
| 1173 | 1185 | if( z ){ |
| 1174 | 1186 | g.zIpAddr = fossil_strdup(z); |
| 1175 | 1187 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -1159,16 +1159,28 @@ | |
| 1159 | #endif |
| 1160 | z = (char*)P("HTTP_COOKIE"); |
| 1161 | if( z ){ |
| 1162 | z = fossil_strdup(z); |
| 1163 | add_param_list(z, ';'); |
| 1164 | } |
| 1165 | |
| 1166 | z = (char*)P("QUERY_STRING"); |
| 1167 | if( z ){ |
| 1168 | z = fossil_strdup(z); |
| 1169 | add_param_list(z, '&'); |
| 1170 | } |
| 1171 | |
| 1172 | z = (char*)P("REMOTE_ADDR"); |
| 1173 | if( z ){ |
| 1174 | g.zIpAddr = fossil_strdup(z); |
| 1175 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -1159,16 +1159,28 @@ | |
| 1159 | #endif |
| 1160 | z = (char*)P("HTTP_COOKIE"); |
| 1161 | if( z ){ |
| 1162 | z = fossil_strdup(z); |
| 1163 | add_param_list(z, ';'); |
| 1164 | z = (char*)cookie_value("skin",0); |
| 1165 | if(z){ |
| 1166 | skin_use_alternative(z, 2); |
| 1167 | } |
| 1168 | } |
| 1169 | |
| 1170 | z = (char*)P("QUERY_STRING"); |
| 1171 | if( z ){ |
| 1172 | z = fossil_strdup(z); |
| 1173 | add_param_list(z, '&'); |
| 1174 | z = (char*)P("skin"); |
| 1175 | if(z){ |
| 1176 | char *zErr = skin_use_alternative(z, 2); |
| 1177 | if(!zErr){ |
| 1178 | cookie_write_parameter("skin","skin",z); |
| 1179 | } |
| 1180 | fossil_free(zErr); |
| 1181 | } |
| 1182 | } |
| 1183 | |
| 1184 | z = (char*)P("REMOTE_ADDR"); |
| 1185 | if( z ){ |
| 1186 | g.zIpAddr = fossil_strdup(z); |
| 1187 |
+4
-3
| --- src/cookies.c | ||
| +++ src/cookies.c | ||
| @@ -173,15 +173,16 @@ | ||
| 173 | 173 | const char *zDflt /* Default value for the parameter */ |
| 174 | 174 | ){ |
| 175 | 175 | cookie_readwrite(zQP, zPName, zDflt, COOKIE_READ|COOKIE_WRITE); |
| 176 | 176 | } |
| 177 | 177 | |
| 178 | -/* Update the user preferences cookie, if necessary, and shut down this | |
| 179 | -** module | |
| 178 | +/* Update the user preferences cookie, if necessary, and shut down | |
| 179 | +** this module. The cookie is only emitted if its value has actually | |
| 180 | +** changed since the request started. | |
| 180 | 181 | */ |
| 181 | 182 | void cookie_render(void){ |
| 182 | - if( cookies.bChanged && P("udc")!=0 ){ | |
| 183 | + if( cookies.bChanged ){ | |
| 183 | 184 | Blob new; |
| 184 | 185 | int i; |
| 185 | 186 | blob_init(&new, 0, 0); |
| 186 | 187 | for(i=0;i<cookies.nParam;i++){ |
| 187 | 188 | if( i>0 ) blob_append(&new, ",", 1); |
| 188 | 189 |
| --- src/cookies.c | |
| +++ src/cookies.c | |
| @@ -173,15 +173,16 @@ | |
| 173 | const char *zDflt /* Default value for the parameter */ |
| 174 | ){ |
| 175 | cookie_readwrite(zQP, zPName, zDflt, COOKIE_READ|COOKIE_WRITE); |
| 176 | } |
| 177 | |
| 178 | /* Update the user preferences cookie, if necessary, and shut down this |
| 179 | ** module |
| 180 | */ |
| 181 | void cookie_render(void){ |
| 182 | if( cookies.bChanged && P("udc")!=0 ){ |
| 183 | Blob new; |
| 184 | int i; |
| 185 | blob_init(&new, 0, 0); |
| 186 | for(i=0;i<cookies.nParam;i++){ |
| 187 | if( i>0 ) blob_append(&new, ",", 1); |
| 188 |
| --- src/cookies.c | |
| +++ src/cookies.c | |
| @@ -173,15 +173,16 @@ | |
| 173 | const char *zDflt /* Default value for the parameter */ |
| 174 | ){ |
| 175 | cookie_readwrite(zQP, zPName, zDflt, COOKIE_READ|COOKIE_WRITE); |
| 176 | } |
| 177 | |
| 178 | /* Update the user preferences cookie, if necessary, and shut down |
| 179 | ** this module. The cookie is only emitted if its value has actually |
| 180 | ** changed since the request started. |
| 181 | */ |
| 182 | void cookie_render(void){ |
| 183 | if( cookies.bChanged ){ |
| 184 | Blob new; |
| 185 | int i; |
| 186 | blob_init(&new, 0, 0); |
| 187 | for(i=0;i<cookies.nParam;i++){ |
| 188 | if( i>0 ) blob_append(&new, ",", 1); |
| 189 |
-1
| --- src/descendants.c | ||
| +++ src/descendants.c | ||
| @@ -565,11 +565,10 @@ | ||
| 565 | 565 | url_reset(&url); |
| 566 | 566 | style_set_current_feature("leaves"); |
| 567 | 567 | style_header("Leaves"); |
| 568 | 568 | login_anonymous_available(); |
| 569 | 569 | timeline_ss_submenu(); |
| 570 | - cookie_render(); | |
| 571 | 570 | #if 0 |
| 572 | 571 | style_sidebox_begin("Nomenclature:", "33%"); |
| 573 | 572 | @ <ol> |
| 574 | 573 | @ <li> A <div class="sideboxDescribed">leaf</div> |
| 575 | 574 | @ is a check-in with no descendants in the same branch.</li> |
| 576 | 575 |
| --- src/descendants.c | |
| +++ src/descendants.c | |
| @@ -565,11 +565,10 @@ | |
| 565 | url_reset(&url); |
| 566 | style_set_current_feature("leaves"); |
| 567 | style_header("Leaves"); |
| 568 | login_anonymous_available(); |
| 569 | timeline_ss_submenu(); |
| 570 | cookie_render(); |
| 571 | #if 0 |
| 572 | style_sidebox_begin("Nomenclature:", "33%"); |
| 573 | @ <ol> |
| 574 | @ <li> A <div class="sideboxDescribed">leaf</div> |
| 575 | @ is a check-in with no descendants in the same branch.</li> |
| 576 |
| --- src/descendants.c | |
| +++ src/descendants.c | |
| @@ -565,11 +565,10 @@ | |
| 565 | url_reset(&url); |
| 566 | style_set_current_feature("leaves"); |
| 567 | style_header("Leaves"); |
| 568 | login_anonymous_available(); |
| 569 | timeline_ss_submenu(); |
| 570 | #if 0 |
| 571 | style_sidebox_begin("Nomenclature:", "33%"); |
| 572 | @ <ol> |
| 573 | @ <li> A <div class="sideboxDescribed">leaf</div> |
| 574 | @ is a check-in with no descendants in the same branch.</li> |
| 575 |
-1
| --- src/finfo.c | ||
| +++ src/finfo.c | ||
| @@ -364,11 +364,10 @@ | ||
| 364 | 364 | url_initialize(&url, "finfo"); |
| 365 | 365 | if( brBg ) url_add_parameter(&url, "brbg", 0); |
| 366 | 366 | if( uBg ) url_add_parameter(&url, "ubg", 0); |
| 367 | 367 | ridFrom = name_to_rid_www("from"); |
| 368 | 368 | zPrevDate[0] = 0; |
| 369 | - cookie_render(); | |
| 370 | 369 | if( fnid==0 ){ |
| 371 | 370 | @ No such file: %h(zFilename) |
| 372 | 371 | style_finish_page(); |
| 373 | 372 | return; |
| 374 | 373 | } |
| 375 | 374 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -364,11 +364,10 @@ | |
| 364 | url_initialize(&url, "finfo"); |
| 365 | if( brBg ) url_add_parameter(&url, "brbg", 0); |
| 366 | if( uBg ) url_add_parameter(&url, "ubg", 0); |
| 367 | ridFrom = name_to_rid_www("from"); |
| 368 | zPrevDate[0] = 0; |
| 369 | cookie_render(); |
| 370 | if( fnid==0 ){ |
| 371 | @ No such file: %h(zFilename) |
| 372 | style_finish_page(); |
| 373 | return; |
| 374 | } |
| 375 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -364,11 +364,10 @@ | |
| 364 | url_initialize(&url, "finfo"); |
| 365 | if( brBg ) url_add_parameter(&url, "brbg", 0); |
| 366 | if( uBg ) url_add_parameter(&url, "ubg", 0); |
| 367 | ridFrom = name_to_rid_www("from"); |
| 368 | zPrevDate[0] = 0; |
| 369 | if( fnid==0 ){ |
| 370 | @ No such file: %h(zFilename) |
| 371 | style_finish_page(); |
| 372 | return; |
| 373 | } |
| 374 |
-3
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -939,11 +939,10 @@ | ||
| 939 | 939 | append_file_change_line(zUuid, zName, zOld, zNew, zOldName, |
| 940 | 940 | diffFlags,pRe,mperm); |
| 941 | 941 | } |
| 942 | 942 | db_finalize(&q3); |
| 943 | 943 | append_diff_javascript(diffType==2); |
| 944 | - cookie_render(); | |
| 945 | 944 | style_finish_page(); |
| 946 | 945 | } |
| 947 | 946 | |
| 948 | 947 | /* |
| 949 | 948 | ** WEBPAGE: winfo |
| @@ -1185,11 +1184,10 @@ | ||
| 1185 | 1184 | login_check_credentials(); |
| 1186 | 1185 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 1187 | 1186 | login_anonymous_available(); |
| 1188 | 1187 | load_control(); |
| 1189 | 1188 | diffType = preferred_diff_type(); |
| 1190 | - cookie_render(); | |
| 1191 | 1189 | zRe = P("regex"); |
| 1192 | 1190 | if( zRe ) re_compile(&pRe, zRe, 0); |
| 1193 | 1191 | zBranch = P("branch"); |
| 1194 | 1192 | if( zBranch && zBranch[0]==0 ) zBranch = 0; |
| 1195 | 1193 | if( zBranch ){ |
| @@ -1706,11 +1704,10 @@ | ||
| 1706 | 1704 | int verbose = PB("verbose"); |
| 1707 | 1705 | |
| 1708 | 1706 | login_check_credentials(); |
| 1709 | 1707 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 1710 | 1708 | diffType = preferred_diff_type(); |
| 1711 | - cookie_render(); | |
| 1712 | 1709 | if( P("from") && P("to") ){ |
| 1713 | 1710 | v1 = artifact_from_ci_and_filename("from"); |
| 1714 | 1711 | v2 = artifact_from_ci_and_filename("to"); |
| 1715 | 1712 | }else{ |
| 1716 | 1713 | Stmt q; |
| 1717 | 1714 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -939,11 +939,10 @@ | |
| 939 | append_file_change_line(zUuid, zName, zOld, zNew, zOldName, |
| 940 | diffFlags,pRe,mperm); |
| 941 | } |
| 942 | db_finalize(&q3); |
| 943 | append_diff_javascript(diffType==2); |
| 944 | cookie_render(); |
| 945 | style_finish_page(); |
| 946 | } |
| 947 | |
| 948 | /* |
| 949 | ** WEBPAGE: winfo |
| @@ -1185,11 +1184,10 @@ | |
| 1185 | login_check_credentials(); |
| 1186 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 1187 | login_anonymous_available(); |
| 1188 | load_control(); |
| 1189 | diffType = preferred_diff_type(); |
| 1190 | cookie_render(); |
| 1191 | zRe = P("regex"); |
| 1192 | if( zRe ) re_compile(&pRe, zRe, 0); |
| 1193 | zBranch = P("branch"); |
| 1194 | if( zBranch && zBranch[0]==0 ) zBranch = 0; |
| 1195 | if( zBranch ){ |
| @@ -1706,11 +1704,10 @@ | |
| 1706 | int verbose = PB("verbose"); |
| 1707 | |
| 1708 | login_check_credentials(); |
| 1709 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 1710 | diffType = preferred_diff_type(); |
| 1711 | cookie_render(); |
| 1712 | if( P("from") && P("to") ){ |
| 1713 | v1 = artifact_from_ci_and_filename("from"); |
| 1714 | v2 = artifact_from_ci_and_filename("to"); |
| 1715 | }else{ |
| 1716 | Stmt q; |
| 1717 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -939,11 +939,10 @@ | |
| 939 | append_file_change_line(zUuid, zName, zOld, zNew, zOldName, |
| 940 | diffFlags,pRe,mperm); |
| 941 | } |
| 942 | db_finalize(&q3); |
| 943 | append_diff_javascript(diffType==2); |
| 944 | style_finish_page(); |
| 945 | } |
| 946 | |
| 947 | /* |
| 948 | ** WEBPAGE: winfo |
| @@ -1185,11 +1184,10 @@ | |
| 1184 | login_check_credentials(); |
| 1185 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 1186 | login_anonymous_available(); |
| 1187 | load_control(); |
| 1188 | diffType = preferred_diff_type(); |
| 1189 | zRe = P("regex"); |
| 1190 | if( zRe ) re_compile(&pRe, zRe, 0); |
| 1191 | zBranch = P("branch"); |
| 1192 | if( zBranch && zBranch[0]==0 ) zBranch = 0; |
| 1193 | if( zBranch ){ |
| @@ -1706,11 +1704,10 @@ | |
| 1704 | int verbose = PB("verbose"); |
| 1705 | |
| 1706 | login_check_credentials(); |
| 1707 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 1708 | diffType = preferred_diff_type(); |
| 1709 | if( P("from") && P("to") ){ |
| 1710 | v1 = artifact_from_ci_and_filename("from"); |
| 1711 | v2 = artifact_from_ci_and_filename("to"); |
| 1712 | }else{ |
| 1713 | Stmt q; |
| 1714 |
+2
-24
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -1838,33 +1838,11 @@ | ||
| 1838 | 1838 | zPathInfo += 7; |
| 1839 | 1839 | g.nExtraURL += 7; |
| 1840 | 1840 | cgi_replace_parameter("PATH_INFO", zPathInfo); |
| 1841 | 1841 | cgi_replace_parameter("SCRIPT_NAME", zNewScript); |
| 1842 | 1842 | etag_cancel(); |
| 1843 | - }else if( zPathInfo && strncmp(zPathInfo, "/skn_", 5)==0 ){ | |
| 1844 | - int i; | |
| 1845 | - char *zAlt; | |
| 1846 | - char *zErr; | |
| 1847 | - char *z; | |
| 1848 | - while( (z = strstr(zPathInfo+1,"/skn_"))!=0 ) zPathInfo = z; | |
| 1849 | - for(i=5; zPathInfo[i] && zPathInfo[i]!='/'; i++){} | |
| 1850 | - zAlt = mprintf("%.*s", i-5, zPathInfo+5); | |
| 1851 | - zErr = skin_use_alternative(zAlt); | |
| 1852 | - if( zErr ){ | |
| 1853 | - fossil_free(zErr); | |
| 1854 | - }else{ | |
| 1855 | - char *zNewScript; | |
| 1856 | - zNewScript = mprintf("%T/skn_%s", P("SCRIPT_NAME"), zAlt); | |
| 1857 | - if( g.zTop ) g.zTop = mprintf("%R/skn_%s", zAlt); | |
| 1858 | - if( g.zBaseURL ) g.zBaseURL = mprintf("%s/skn_%s", g.zBaseURL, zAlt); | |
| 1859 | - zPathInfo += i; | |
| 1860 | - g.nExtraURL += i; | |
| 1861 | - cgi_replace_parameter("PATH_INFO", zPathInfo); | |
| 1862 | - cgi_replace_parameter("SCRIPT_NAME", zNewScript); | |
| 1863 | - } | |
| 1864 | - fossil_free(zAlt); | |
| 1865 | - } | |
| 1843 | + } | |
| 1866 | 1844 | |
| 1867 | 1845 | /* If the content type is application/x-fossil or |
| 1868 | 1846 | ** application/x-fossil-debug, then a sync/push/pull/clone is |
| 1869 | 1847 | ** desired, so default the PATH_INFO to /xfer |
| 1870 | 1848 | */ |
| @@ -2378,11 +2356,11 @@ | ||
| 2378 | 2356 | ** Use one of the built-in skins defined by LABEL. LABEL is the |
| 2379 | 2357 | ** name of the subdirectory under the skins/ directory that holds |
| 2380 | 2358 | ** the elements of the built-in skin. If LABEL does not match, |
| 2381 | 2359 | ** this directive is a silent no-op. |
| 2382 | 2360 | */ |
| 2383 | - skin_use_alternative(blob_str(&value)); | |
| 2361 | + fossil_free(skin_use_alternative(blob_str(&value), 1)); | |
| 2384 | 2362 | blob_reset(&value); |
| 2385 | 2363 | continue; |
| 2386 | 2364 | } |
| 2387 | 2365 | if( blob_eq(&key, "jsmode:") && blob_token(&line, &value) ){ |
| 2388 | 2366 | /* jsmode: MODE |
| 2389 | 2367 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -1838,33 +1838,11 @@ | |
| 1838 | zPathInfo += 7; |
| 1839 | g.nExtraURL += 7; |
| 1840 | cgi_replace_parameter("PATH_INFO", zPathInfo); |
| 1841 | cgi_replace_parameter("SCRIPT_NAME", zNewScript); |
| 1842 | etag_cancel(); |
| 1843 | }else if( zPathInfo && strncmp(zPathInfo, "/skn_", 5)==0 ){ |
| 1844 | int i; |
| 1845 | char *zAlt; |
| 1846 | char *zErr; |
| 1847 | char *z; |
| 1848 | while( (z = strstr(zPathInfo+1,"/skn_"))!=0 ) zPathInfo = z; |
| 1849 | for(i=5; zPathInfo[i] && zPathInfo[i]!='/'; i++){} |
| 1850 | zAlt = mprintf("%.*s", i-5, zPathInfo+5); |
| 1851 | zErr = skin_use_alternative(zAlt); |
| 1852 | if( zErr ){ |
| 1853 | fossil_free(zErr); |
| 1854 | }else{ |
| 1855 | char *zNewScript; |
| 1856 | zNewScript = mprintf("%T/skn_%s", P("SCRIPT_NAME"), zAlt); |
| 1857 | if( g.zTop ) g.zTop = mprintf("%R/skn_%s", zAlt); |
| 1858 | if( g.zBaseURL ) g.zBaseURL = mprintf("%s/skn_%s", g.zBaseURL, zAlt); |
| 1859 | zPathInfo += i; |
| 1860 | g.nExtraURL += i; |
| 1861 | cgi_replace_parameter("PATH_INFO", zPathInfo); |
| 1862 | cgi_replace_parameter("SCRIPT_NAME", zNewScript); |
| 1863 | } |
| 1864 | fossil_free(zAlt); |
| 1865 | } |
| 1866 | |
| 1867 | /* If the content type is application/x-fossil or |
| 1868 | ** application/x-fossil-debug, then a sync/push/pull/clone is |
| 1869 | ** desired, so default the PATH_INFO to /xfer |
| 1870 | */ |
| @@ -2378,11 +2356,11 @@ | |
| 2378 | ** Use one of the built-in skins defined by LABEL. LABEL is the |
| 2379 | ** name of the subdirectory under the skins/ directory that holds |
| 2380 | ** the elements of the built-in skin. If LABEL does not match, |
| 2381 | ** this directive is a silent no-op. |
| 2382 | */ |
| 2383 | skin_use_alternative(blob_str(&value)); |
| 2384 | blob_reset(&value); |
| 2385 | continue; |
| 2386 | } |
| 2387 | if( blob_eq(&key, "jsmode:") && blob_token(&line, &value) ){ |
| 2388 | /* jsmode: MODE |
| 2389 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -1838,33 +1838,11 @@ | |
| 1838 | zPathInfo += 7; |
| 1839 | g.nExtraURL += 7; |
| 1840 | cgi_replace_parameter("PATH_INFO", zPathInfo); |
| 1841 | cgi_replace_parameter("SCRIPT_NAME", zNewScript); |
| 1842 | etag_cancel(); |
| 1843 | } |
| 1844 | |
| 1845 | /* If the content type is application/x-fossil or |
| 1846 | ** application/x-fossil-debug, then a sync/push/pull/clone is |
| 1847 | ** desired, so default the PATH_INFO to /xfer |
| 1848 | */ |
| @@ -2378,11 +2356,11 @@ | |
| 2356 | ** Use one of the built-in skins defined by LABEL. LABEL is the |
| 2357 | ** name of the subdirectory under the skins/ directory that holds |
| 2358 | ** the elements of the built-in skin. If LABEL does not match, |
| 2359 | ** this directive is a silent no-op. |
| 2360 | */ |
| 2361 | fossil_free(skin_use_alternative(blob_str(&value), 1)); |
| 2362 | blob_reset(&value); |
| 2363 | continue; |
| 2364 | } |
| 2365 | if( blob_eq(&key, "jsmode:") && blob_token(&line, &value) ){ |
| 2366 | /* jsmode: MODE |
| 2367 |
+44
-9
| --- src/skins.c | ||
| +++ src/skins.c | ||
| @@ -104,15 +104,47 @@ | ||
| 104 | 104 | ** |
| 105 | 105 | ** If the alternative skin name contains one or more '/' characters, then |
| 106 | 106 | ** it is assumed to be a directory on disk that holds override css.txt, |
| 107 | 107 | ** footer.txt, and header.txt. This mode can be used for interactive |
| 108 | 108 | ** development of new skins. |
| 109 | +** | |
| 110 | +** The 2nd parameter is a ranking of how important this alternative | |
| 111 | +** skin declaration is, and lower values trump higher ones. If a call | |
| 112 | +** to this function passes a higher-valued rank than a previous call, | |
| 113 | +** the subsequent call becomes a no-op. Only calls with the same or | |
| 114 | +** lower rank (i.e. higher priority) will overwrite a previous | |
| 115 | +** setting. This approach is used because the CGI/server-time | |
| 116 | +** initialization happens in an order which is incompatible with our | |
| 117 | +** preferred ranking, making it otherwise more invasive to tell the | |
| 118 | +** internals "the --skin flag ranks higher than a URL parameter" (the | |
| 119 | +** former gets initialized before both URL parameters and the /draft | |
| 120 | +** path determination). | |
| 121 | +** | |
| 122 | +** The rankings were initially defined in | |
| 123 | +** https://fossil-scm.org/forum/forumpost/caf8c9a8bb | |
| 124 | +** and are: | |
| 125 | +** | |
| 126 | +** 0) A URI starting with /draft1-9, linked to via /setup_skin, trumps | |
| 127 | +** everything else. The rank argument is ignored if zName matches | |
| 128 | +** draft[1-9]. | |
| 129 | +** | |
| 130 | +** 1) The --skin flag or skin: CGI config setting. | |
| 131 | +** | |
| 132 | +** 2) The "skin" display setting cookie or URL argument, in that | |
| 133 | +** order. If the URL argument is provided and refers to a legal | |
| 134 | +** skin then that will update the display cookie. | |
| 135 | +** | |
| 136 | +** 3) Skin properties from the CONFIG db table | |
| 137 | +** | |
| 138 | +** 4) Default skin. | |
| 109 | 139 | */ |
| 110 | -char *skin_use_alternative(const char *zName){ | |
| 140 | +char *skin_use_alternative(const char *zName, int rank){ | |
| 141 | + static int currentRank = 5; | |
| 111 | 142 | int i; |
| 112 | 143 | Blob err = BLOB_INITIALIZER; |
| 113 | - if( strchr(zName, '/')!=0 ){ | |
| 144 | + if(rank > currentRank) return 0; | |
| 145 | + if( 1==rank && strchr(zName, '/')!=0 ){ | |
| 114 | 146 | zAltSkinDir = fossil_strdup(zName); |
| 115 | 147 | return 0; |
| 116 | 148 | } |
| 117 | 149 | if( sqlite3_strglob("draft[1-9]", zName)==0 ){ |
| 118 | 150 | skin_use_draft(zName[5] - '0'); |
| @@ -137,11 +169,11 @@ | ||
| 137 | 169 | ** call fossil_fatal() if an unknown skin is specified. |
| 138 | 170 | */ |
| 139 | 171 | void skin_override(void){ |
| 140 | 172 | const char *zSkin = find_option("skin",0,1); |
| 141 | 173 | if( zSkin ){ |
| 142 | - char *zErr = skin_use_alternative(zSkin); | |
| 174 | + char *zErr = skin_use_alternative(zSkin, 1); | |
| 143 | 175 | if( zErr ) fossil_fatal("%s", zErr); |
| 144 | 176 | } |
| 145 | 177 | } |
| 146 | 178 | |
| 147 | 179 | /* |
| @@ -1154,24 +1186,27 @@ | ||
| 1154 | 1186 | } |
| 1155 | 1187 | fossil_free(zPattern); |
| 1156 | 1188 | } |
| 1157 | 1189 | login_check_credentials(); |
| 1158 | 1190 | style_header("Skins"); |
| 1191 | + if(zAltSkinDir && zAltSkinDir[0]){ | |
| 1192 | + @ <p class="warning">Warning: this fossil instance was started with | |
| 1193 | + @ a hard-coded skin value which trumps any option selected below. | |
| 1194 | + @ A skins selected below will be recorded in your prefere cookie | |
| 1195 | + @ but will not be used until/unless the site administrator | |
| 1196 | + @ configures the site to run without a forced hard-coded skin. | |
| 1197 | + @ </p> | |
| 1198 | + } | |
| 1159 | 1199 | @ <p>The following skins are available for this repository:</p> |
| 1160 | 1200 | @ <ul> |
| 1161 | - if( pAltSkin==0 && zAltSkinDir==0 && iDraftSkin==0 ){ | |
| 1162 | - @ <li> Standard skin for this repository ← <i>Currently in use</i> | |
| 1163 | - }else{ | |
| 1164 | - @ <li> %z(href("%s/skins",zBase))Standard skin for this repository</a> | |
| 1165 | - } | |
| 1166 | 1201 | for(i=0; i<count(aBuiltinSkin); i++){ |
| 1167 | 1202 | if( pAltSkin==&aBuiltinSkin[i] ){ |
| 1168 | 1203 | @ <li> %h(aBuiltinSkin[i].zDesc) ← <i>Currently in use</i> |
| 1169 | 1204 | }else{ |
| 1170 | - char *zUrl = href("%s/skn_%s/skins", zBase, aBuiltinSkin[i].zLabel); | |
| 1205 | + char *zUrl = href("%s/skins?skin=%T", zBase, aBuiltinSkin[i].zLabel); | |
| 1171 | 1206 | @ <li> %z(zUrl)%h(aBuiltinSkin[i].zDesc)</a> |
| 1172 | 1207 | } |
| 1173 | 1208 | } |
| 1174 | 1209 | @ </ul> |
| 1175 | 1210 | style_finish_page(); |
| 1176 | 1211 | fossil_free(zBase); |
| 1177 | 1212 | } |
| 1178 | 1213 |
| --- src/skins.c | |
| +++ src/skins.c | |
| @@ -104,15 +104,47 @@ | |
| 104 | ** |
| 105 | ** If the alternative skin name contains one or more '/' characters, then |
| 106 | ** it is assumed to be a directory on disk that holds override css.txt, |
| 107 | ** footer.txt, and header.txt. This mode can be used for interactive |
| 108 | ** development of new skins. |
| 109 | */ |
| 110 | char *skin_use_alternative(const char *zName){ |
| 111 | int i; |
| 112 | Blob err = BLOB_INITIALIZER; |
| 113 | if( strchr(zName, '/')!=0 ){ |
| 114 | zAltSkinDir = fossil_strdup(zName); |
| 115 | return 0; |
| 116 | } |
| 117 | if( sqlite3_strglob("draft[1-9]", zName)==0 ){ |
| 118 | skin_use_draft(zName[5] - '0'); |
| @@ -137,11 +169,11 @@ | |
| 137 | ** call fossil_fatal() if an unknown skin is specified. |
| 138 | */ |
| 139 | void skin_override(void){ |
| 140 | const char *zSkin = find_option("skin",0,1); |
| 141 | if( zSkin ){ |
| 142 | char *zErr = skin_use_alternative(zSkin); |
| 143 | if( zErr ) fossil_fatal("%s", zErr); |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | /* |
| @@ -1154,24 +1186,27 @@ | |
| 1154 | } |
| 1155 | fossil_free(zPattern); |
| 1156 | } |
| 1157 | login_check_credentials(); |
| 1158 | style_header("Skins"); |
| 1159 | @ <p>The following skins are available for this repository:</p> |
| 1160 | @ <ul> |
| 1161 | if( pAltSkin==0 && zAltSkinDir==0 && iDraftSkin==0 ){ |
| 1162 | @ <li> Standard skin for this repository ← <i>Currently in use</i> |
| 1163 | }else{ |
| 1164 | @ <li> %z(href("%s/skins",zBase))Standard skin for this repository</a> |
| 1165 | } |
| 1166 | for(i=0; i<count(aBuiltinSkin); i++){ |
| 1167 | if( pAltSkin==&aBuiltinSkin[i] ){ |
| 1168 | @ <li> %h(aBuiltinSkin[i].zDesc) ← <i>Currently in use</i> |
| 1169 | }else{ |
| 1170 | char *zUrl = href("%s/skn_%s/skins", zBase, aBuiltinSkin[i].zLabel); |
| 1171 | @ <li> %z(zUrl)%h(aBuiltinSkin[i].zDesc)</a> |
| 1172 | } |
| 1173 | } |
| 1174 | @ </ul> |
| 1175 | style_finish_page(); |
| 1176 | fossil_free(zBase); |
| 1177 | } |
| 1178 |
| --- src/skins.c | |
| +++ src/skins.c | |
| @@ -104,15 +104,47 @@ | |
| 104 | ** |
| 105 | ** If the alternative skin name contains one or more '/' characters, then |
| 106 | ** it is assumed to be a directory on disk that holds override css.txt, |
| 107 | ** footer.txt, and header.txt. This mode can be used for interactive |
| 108 | ** development of new skins. |
| 109 | ** |
| 110 | ** The 2nd parameter is a ranking of how important this alternative |
| 111 | ** skin declaration is, and lower values trump higher ones. If a call |
| 112 | ** to this function passes a higher-valued rank than a previous call, |
| 113 | ** the subsequent call becomes a no-op. Only calls with the same or |
| 114 | ** lower rank (i.e. higher priority) will overwrite a previous |
| 115 | ** setting. This approach is used because the CGI/server-time |
| 116 | ** initialization happens in an order which is incompatible with our |
| 117 | ** preferred ranking, making it otherwise more invasive to tell the |
| 118 | ** internals "the --skin flag ranks higher than a URL parameter" (the |
| 119 | ** former gets initialized before both URL parameters and the /draft |
| 120 | ** path determination). |
| 121 | ** |
| 122 | ** The rankings were initially defined in |
| 123 | ** https://fossil-scm.org/forum/forumpost/caf8c9a8bb |
| 124 | ** and are: |
| 125 | ** |
| 126 | ** 0) A URI starting with /draft1-9, linked to via /setup_skin, trumps |
| 127 | ** everything else. The rank argument is ignored if zName matches |
| 128 | ** draft[1-9]. |
| 129 | ** |
| 130 | ** 1) The --skin flag or skin: CGI config setting. |
| 131 | ** |
| 132 | ** 2) The "skin" display setting cookie or URL argument, in that |
| 133 | ** order. If the URL argument is provided and refers to a legal |
| 134 | ** skin then that will update the display cookie. |
| 135 | ** |
| 136 | ** 3) Skin properties from the CONFIG db table |
| 137 | ** |
| 138 | ** 4) Default skin. |
| 139 | */ |
| 140 | char *skin_use_alternative(const char *zName, int rank){ |
| 141 | static int currentRank = 5; |
| 142 | int i; |
| 143 | Blob err = BLOB_INITIALIZER; |
| 144 | if(rank > currentRank) return 0; |
| 145 | if( 1==rank && strchr(zName, '/')!=0 ){ |
| 146 | zAltSkinDir = fossil_strdup(zName); |
| 147 | return 0; |
| 148 | } |
| 149 | if( sqlite3_strglob("draft[1-9]", zName)==0 ){ |
| 150 | skin_use_draft(zName[5] - '0'); |
| @@ -137,11 +169,11 @@ | |
| 169 | ** call fossil_fatal() if an unknown skin is specified. |
| 170 | */ |
| 171 | void skin_override(void){ |
| 172 | const char *zSkin = find_option("skin",0,1); |
| 173 | if( zSkin ){ |
| 174 | char *zErr = skin_use_alternative(zSkin, 1); |
| 175 | if( zErr ) fossil_fatal("%s", zErr); |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | /* |
| @@ -1154,24 +1186,27 @@ | |
| 1186 | } |
| 1187 | fossil_free(zPattern); |
| 1188 | } |
| 1189 | login_check_credentials(); |
| 1190 | style_header("Skins"); |
| 1191 | if(zAltSkinDir && zAltSkinDir[0]){ |
| 1192 | @ <p class="warning">Warning: this fossil instance was started with |
| 1193 | @ a hard-coded skin value which trumps any option selected below. |
| 1194 | @ A skins selected below will be recorded in your prefere cookie |
| 1195 | @ but will not be used until/unless the site administrator |
| 1196 | @ configures the site to run without a forced hard-coded skin. |
| 1197 | @ </p> |
| 1198 | } |
| 1199 | @ <p>The following skins are available for this repository:</p> |
| 1200 | @ <ul> |
| 1201 | for(i=0; i<count(aBuiltinSkin); i++){ |
| 1202 | if( pAltSkin==&aBuiltinSkin[i] ){ |
| 1203 | @ <li> %h(aBuiltinSkin[i].zDesc) ← <i>Currently in use</i> |
| 1204 | }else{ |
| 1205 | char *zUrl = href("%s/skins?skin=%T", zBase, aBuiltinSkin[i].zLabel); |
| 1206 | @ <li> %z(zUrl)%h(aBuiltinSkin[i].zDesc)</a> |
| 1207 | } |
| 1208 | } |
| 1209 | @ </ul> |
| 1210 | style_finish_page(); |
| 1211 | fossil_free(zBase); |
| 1212 | } |
| 1213 |
+4
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -1011,10 +1011,14 @@ | ||
| 1011 | 1011 | if( sqlite3_strlike("%</body>%", zFooter, 0)!=0 ){ |
| 1012 | 1012 | style_load_all_js_files(); |
| 1013 | 1013 | @ </body> |
| 1014 | 1014 | @ </html> |
| 1015 | 1015 | } |
| 1016 | + /* Update the user display prefs cookie if it was modified during | |
| 1017 | + ** this request. | |
| 1018 | + */ | |
| 1019 | + cookie_render(); | |
| 1016 | 1020 | } |
| 1017 | 1021 | |
| 1018 | 1022 | /* |
| 1019 | 1023 | ** Begin a side-box on the right-hand side of a page. The title and |
| 1020 | 1024 | ** the width of the box are given as arguments. The width is usually |
| 1021 | 1025 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -1011,10 +1011,14 @@ | |
| 1011 | if( sqlite3_strlike("%</body>%", zFooter, 0)!=0 ){ |
| 1012 | style_load_all_js_files(); |
| 1013 | @ </body> |
| 1014 | @ </html> |
| 1015 | } |
| 1016 | } |
| 1017 | |
| 1018 | /* |
| 1019 | ** Begin a side-box on the right-hand side of a page. The title and |
| 1020 | ** the width of the box are given as arguments. The width is usually |
| 1021 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -1011,10 +1011,14 @@ | |
| 1011 | if( sqlite3_strlike("%</body>%", zFooter, 0)!=0 ){ |
| 1012 | style_load_all_js_files(); |
| 1013 | @ </body> |
| 1014 | @ </html> |
| 1015 | } |
| 1016 | /* Update the user display prefs cookie if it was modified during |
| 1017 | ** this request. |
| 1018 | */ |
| 1019 | cookie_render(); |
| 1020 | } |
| 1021 | |
| 1022 | /* |
| 1023 | ** Begin a side-box on the right-hand side of a page. The title and |
| 1024 | ** the width of the box are given as arguments. The width is usually |
| 1025 |
-1
| --- src/tag.c | ||
| +++ src/tag.c | ||
| @@ -755,11 +755,10 @@ | ||
| 755 | 755 | |
| 756 | 756 | style_header("Tagged Check-ins"); |
| 757 | 757 | style_submenu_element("List", "taglist"); |
| 758 | 758 | login_anonymous_available(); |
| 759 | 759 | timeline_ss_submenu(); |
| 760 | - cookie_render(); | |
| 761 | 760 | @ <h2>Check-ins with non-propagating tags:</h2> |
| 762 | 761 | blob_append(&sql, timeline_query_for_www(), -1); |
| 763 | 762 | blob_append_sql(&sql, |
| 764 | 763 | "AND blob.rid IN (SELECT rid FROM tagxref" |
| 765 | 764 | " WHERE tagtype=1 AND srcid>0" |
| 766 | 765 |
| --- src/tag.c | |
| +++ src/tag.c | |
| @@ -755,11 +755,10 @@ | |
| 755 | |
| 756 | style_header("Tagged Check-ins"); |
| 757 | style_submenu_element("List", "taglist"); |
| 758 | login_anonymous_available(); |
| 759 | timeline_ss_submenu(); |
| 760 | cookie_render(); |
| 761 | @ <h2>Check-ins with non-propagating tags:</h2> |
| 762 | blob_append(&sql, timeline_query_for_www(), -1); |
| 763 | blob_append_sql(&sql, |
| 764 | "AND blob.rid IN (SELECT rid FROM tagxref" |
| 765 | " WHERE tagtype=1 AND srcid>0" |
| 766 |
| --- src/tag.c | |
| +++ src/tag.c | |
| @@ -755,11 +755,10 @@ | |
| 755 | |
| 756 | style_header("Tagged Check-ins"); |
| 757 | style_submenu_element("List", "taglist"); |
| 758 | login_anonymous_available(); |
| 759 | timeline_ss_submenu(); |
| 760 | @ <h2>Check-ins with non-propagating tags:</h2> |
| 761 | blob_append(&sql, timeline_query_for_www(), -1); |
| 762 | blob_append_sql(&sql, |
| 763 | "AND blob.rid IN (SELECT rid FROM tagxref" |
| 764 | " WHERE tagtype=1 AND srcid>0" |
| 765 |
-1
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -1754,11 +1754,10 @@ | ||
| 1754 | 1754 | cgi_set_parameter("y", zType); |
| 1755 | 1755 | } |
| 1756 | 1756 | if( zType[0]=='a' || zType[0]=='c' ){ |
| 1757 | 1757 | cookie_write_parameter("y","y",zType); |
| 1758 | 1758 | } |
| 1759 | - cookie_render(); | |
| 1760 | 1759 | |
| 1761 | 1760 | /* Convert the cf=FILEHASH query parameter into a c=CHECKINHASH value */ |
| 1762 | 1761 | if( P("cf")!=0 ){ |
| 1763 | 1762 | zCirca = db_text(0, |
| 1764 | 1763 | "SELECT (SELECT uuid FROM blob WHERE rid=mlink.mid)" |
| 1765 | 1764 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1754,11 +1754,10 @@ | |
| 1754 | cgi_set_parameter("y", zType); |
| 1755 | } |
| 1756 | if( zType[0]=='a' || zType[0]=='c' ){ |
| 1757 | cookie_write_parameter("y","y",zType); |
| 1758 | } |
| 1759 | cookie_render(); |
| 1760 | |
| 1761 | /* Convert the cf=FILEHASH query parameter into a c=CHECKINHASH value */ |
| 1762 | if( P("cf")!=0 ){ |
| 1763 | zCirca = db_text(0, |
| 1764 | "SELECT (SELECT uuid FROM blob WHERE rid=mlink.mid)" |
| 1765 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1754,11 +1754,10 @@ | |
| 1754 | cgi_set_parameter("y", zType); |
| 1755 | } |
| 1756 | if( zType[0]=='a' || zType[0]=='c' ){ |
| 1757 | cookie_write_parameter("y","y",zType); |
| 1758 | } |
| 1759 | |
| 1760 | /* Convert the cf=FILEHASH query parameter into a c=CHECKINHASH value */ |
| 1761 | if( P("cf")!=0 ){ |
| 1762 | zCirca = db_text(0, |
| 1763 | "SELECT (SELECT uuid FROM blob WHERE rid=mlink.mid)" |
| 1764 |