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].

stephan 2021-03-02 07:11 trunk
Commit 71a2d68a7a113e7cce3b33c2bc595f4d8b1e7b09b0e260860b3784475a1fe06c
--- src/branch.c
+++ src/branch.c
@@ -683,11 +683,10 @@
683683
style_set_current_feature("branch");
684684
style_header("Branches");
685685
style_submenu_element("List", "brlist");
686686
login_anonymous_available();
687687
timeline_ss_submenu();
688
- cookie_render();
689688
@ <h2>The initial check-in for each branch:</h2>
690689
blob_append(&sql, timeline_query_for_www(), -1);
691690
blob_append_sql(&sql,
692691
"AND blob.rid IN (SELECT rid FROM tagxref"
693692
" WHERE tagtype>0 AND tagid=%d AND srcid!=0)", TAG_BRANCH);
694693
--- 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 @@
11591159
#endif
11601160
z = (char*)P("HTTP_COOKIE");
11611161
if( z ){
11621162
z = fossil_strdup(z);
11631163
add_param_list(z, ';');
1164
+ z = (char*)cookie_value("skin",0);
1165
+ if(z){
1166
+ skin_use_alternative(z, 2);
1167
+ }
11641168
}
11651169
11661170
z = (char*)P("QUERY_STRING");
11671171
if( z ){
11681172
z = fossil_strdup(z);
11691173
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
+ }
11701182
}
11711183
11721184
z = (char*)P("REMOTE_ADDR");
11731185
if( z ){
11741186
g.zIpAddr = fossil_strdup(z);
11751187
--- 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 @@
173173
const char *zDflt /* Default value for the parameter */
174174
){
175175
cookie_readwrite(zQP, zPName, zDflt, COOKIE_READ|COOKIE_WRITE);
176176
}
177177
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.
180181
*/
181182
void cookie_render(void){
182
- if( cookies.bChanged && P("udc")!=0 ){
183
+ if( cookies.bChanged ){
183184
Blob new;
184185
int i;
185186
blob_init(&new, 0, 0);
186187
for(i=0;i<cookies.nParam;i++){
187188
if( i>0 ) blob_append(&new, ",", 1);
188189
--- 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
--- src/descendants.c
+++ src/descendants.c
@@ -565,11 +565,10 @@
565565
url_reset(&url);
566566
style_set_current_feature("leaves");
567567
style_header("Leaves");
568568
login_anonymous_available();
569569
timeline_ss_submenu();
570
- cookie_render();
571570
#if 0
572571
style_sidebox_begin("Nomenclature:", "33%");
573572
@ <ol>
574573
@ <li> A <div class="sideboxDescribed">leaf</div>
575574
@ is a check-in with no descendants in the same branch.</li>
576575
--- 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
--- src/finfo.c
+++ src/finfo.c
@@ -364,11 +364,10 @@
364364
url_initialize(&url, "finfo");
365365
if( brBg ) url_add_parameter(&url, "brbg", 0);
366366
if( uBg ) url_add_parameter(&url, "ubg", 0);
367367
ridFrom = name_to_rid_www("from");
368368
zPrevDate[0] = 0;
369
- cookie_render();
370369
if( fnid==0 ){
371370
@ No such file: %h(zFilename)
372371
style_finish_page();
373372
return;
374373
}
375374
--- 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 @@
939939
append_file_change_line(zUuid, zName, zOld, zNew, zOldName,
940940
diffFlags,pRe,mperm);
941941
}
942942
db_finalize(&q3);
943943
append_diff_javascript(diffType==2);
944
- cookie_render();
945944
style_finish_page();
946945
}
947946
948947
/*
949948
** WEBPAGE: winfo
@@ -1185,11 +1184,10 @@
11851184
login_check_credentials();
11861185
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
11871186
login_anonymous_available();
11881187
load_control();
11891188
diffType = preferred_diff_type();
1190
- cookie_render();
11911189
zRe = P("regex");
11921190
if( zRe ) re_compile(&pRe, zRe, 0);
11931191
zBranch = P("branch");
11941192
if( zBranch && zBranch[0]==0 ) zBranch = 0;
11951193
if( zBranch ){
@@ -1706,11 +1704,10 @@
17061704
int verbose = PB("verbose");
17071705
17081706
login_check_credentials();
17091707
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
17101708
diffType = preferred_diff_type();
1711
- cookie_render();
17121709
if( P("from") && P("to") ){
17131710
v1 = artifact_from_ci_and_filename("from");
17141711
v2 = artifact_from_ci_and_filename("to");
17151712
}else{
17161713
Stmt q;
17171714
--- 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 @@
18381838
zPathInfo += 7;
18391839
g.nExtraURL += 7;
18401840
cgi_replace_parameter("PATH_INFO", zPathInfo);
18411841
cgi_replace_parameter("SCRIPT_NAME", zNewScript);
18421842
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
+ }
18661844
18671845
/* If the content type is application/x-fossil or
18681846
** application/x-fossil-debug, then a sync/push/pull/clone is
18691847
** desired, so default the PATH_INFO to /xfer
18701848
*/
@@ -2378,11 +2356,11 @@
23782356
** Use one of the built-in skins defined by LABEL. LABEL is the
23792357
** name of the subdirectory under the skins/ directory that holds
23802358
** the elements of the built-in skin. If LABEL does not match,
23812359
** this directive is a silent no-op.
23822360
*/
2383
- skin_use_alternative(blob_str(&value));
2361
+ fossil_free(skin_use_alternative(blob_str(&value), 1));
23842362
blob_reset(&value);
23852363
continue;
23862364
}
23872365
if( blob_eq(&key, "jsmode:") && blob_token(&line, &value) ){
23882366
/* jsmode: MODE
23892367
--- 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 @@
104104
**
105105
** If the alternative skin name contains one or more '/' characters, then
106106
** it is assumed to be a directory on disk that holds override css.txt,
107107
** footer.txt, and header.txt. This mode can be used for interactive
108108
** 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.
109139
*/
110
-char *skin_use_alternative(const char *zName){
140
+char *skin_use_alternative(const char *zName, int rank){
141
+ static int currentRank = 5;
111142
int i;
112143
Blob err = BLOB_INITIALIZER;
113
- if( strchr(zName, '/')!=0 ){
144
+ if(rank > currentRank) return 0;
145
+ if( 1==rank && strchr(zName, '/')!=0 ){
114146
zAltSkinDir = fossil_strdup(zName);
115147
return 0;
116148
}
117149
if( sqlite3_strglob("draft[1-9]", zName)==0 ){
118150
skin_use_draft(zName[5] - '0');
@@ -137,11 +169,11 @@
137169
** call fossil_fatal() if an unknown skin is specified.
138170
*/
139171
void skin_override(void){
140172
const char *zSkin = find_option("skin",0,1);
141173
if( zSkin ){
142
- char *zErr = skin_use_alternative(zSkin);
174
+ char *zErr = skin_use_alternative(zSkin, 1);
143175
if( zErr ) fossil_fatal("%s", zErr);
144176
}
145177
}
146178
147179
/*
@@ -1154,24 +1186,27 @@
11541186
}
11551187
fossil_free(zPattern);
11561188
}
11571189
login_check_credentials();
11581190
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
+ }
11591199
@ <p>The following skins are available for this repository:</p>
11601200
@ <ul>
1161
- if( pAltSkin==0 && zAltSkinDir==0 && iDraftSkin==0 ){
1162
- @ <li> Standard skin for this repository &larr; <i>Currently in use</i>
1163
- }else{
1164
- @ <li> %z(href("%s/skins",zBase))Standard skin for this repository</a>
1165
- }
11661201
for(i=0; i<count(aBuiltinSkin); i++){
11671202
if( pAltSkin==&aBuiltinSkin[i] ){
11681203
@ <li> %h(aBuiltinSkin[i].zDesc) &larr; <i>Currently in use</i>
11691204
}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);
11711206
@ <li> %z(zUrl)%h(aBuiltinSkin[i].zDesc)</a>
11721207
}
11731208
}
11741209
@ </ul>
11751210
style_finish_page();
11761211
fossil_free(zBase);
11771212
}
11781213
--- 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 &larr; <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) &larr; <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) &larr; <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
--- src/style.c
+++ src/style.c
@@ -1011,10 +1011,14 @@
10111011
if( sqlite3_strlike("%</body>%", zFooter, 0)!=0 ){
10121012
style_load_all_js_files();
10131013
@ </body>
10141014
@ </html>
10151015
}
1016
+ /* Update the user display prefs cookie if it was modified during
1017
+ ** this request.
1018
+ */
1019
+ cookie_render();
10161020
}
10171021
10181022
/*
10191023
** Begin a side-box on the right-hand side of a page. The title and
10201024
** the width of the box are given as arguments. The width is usually
10211025
--- 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 @@
755755
756756
style_header("Tagged Check-ins");
757757
style_submenu_element("List", "taglist");
758758
login_anonymous_available();
759759
timeline_ss_submenu();
760
- cookie_render();
761760
@ <h2>Check-ins with non-propagating tags:</h2>
762761
blob_append(&sql, timeline_query_for_www(), -1);
763762
blob_append_sql(&sql,
764763
"AND blob.rid IN (SELECT rid FROM tagxref"
765764
" WHERE tagtype=1 AND srcid>0"
766765
--- 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
--- src/timeline.c
+++ src/timeline.c
@@ -1754,11 +1754,10 @@
17541754
cgi_set_parameter("y", zType);
17551755
}
17561756
if( zType[0]=='a' || zType[0]=='c' ){
17571757
cookie_write_parameter("y","y",zType);
17581758
}
1759
- cookie_render();
17601759
17611760
/* Convert the cf=FILEHASH query parameter into a c=CHECKINHASH value */
17621761
if( P("cf")!=0 ){
17631762
zCirca = db_text(0,
17641763
"SELECT (SELECT uuid FROM blob WHERE rid=mlink.mid)"
17651764
--- 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

Keyboard Shortcuts

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