Fossil SCM

Extended style.css to optionally be able to load page-specific CSS if the 'page' URL param is provided and a builtin file named style.{{page}}.css is found. The stylesheet_url TH1 var now adds URL param page=g.zPath if builtin file style.{{g.zPath}}.css is available.

stephan 2020-05-17 03:19 fileedit-ajaxify
Commit d661c12cbadef066fcd747c7526cd64d5f27fa340021f3a3fa4d98e0af3970e7
1 file changed +58 -6
+58 -6
--- src/style.c
+++ src/style.c
@@ -370,15 +370,31 @@
370370
const char *zVarPrefix,
371371
const char *zConfigName,
372372
const char *zPageName
373373
){
374374
char *zVarName = mprintf("%s_url", zVarPrefix);
375
- char *zUrl = mprintf("%R/%s?id=%x", zPageName,
376
- skin_id(zConfigName));
375
+ char *zExtra = 0;
376
+ char *zUrl = 0;
377
+ if(0==strcmp("css",zConfigName)){
378
+ /* Account for page-specific CSS, appending a page=NAME url flag
379
+ ** only if we have a corresponding built-in page-specific CSS
380
+ ** file. Do not append it to all pages because we would
381
+ ** effectively cache-bust all pages which do not have
382
+ ** page-specific CSS. */
383
+ char * zBuiltin = mprintf("style.%s.css", g.zPath);
384
+ if(builtin_file(zBuiltin,0)!=0){
385
+ zExtra = mprintf("&page=%s", g.zPath);
386
+ }
387
+ fossil_free(zBuiltin);
388
+ }
389
+ zUrl = mprintf("%R/%s?id=%x%s", zPageName,
390
+ skin_id(zConfigName),
391
+ zExtra ? zExtra : "");
377392
Th_Store(zVarName, zUrl);
378
- free(zUrl);
379
- free(zVarName);
393
+ fossil_free(zExtra);
394
+ fossil_free(zUrl);
395
+ fossil_free(zVarName);
380396
}
381397
382398
/*
383399
** Create a TH1 variable containing the URL for the specified config image.
384400
** The resulting variable name will be of the form $[zImageName]_image_url.
@@ -1063,16 +1079,52 @@
10631079
** WEBPAGE: style.css
10641080
**
10651081
** Return the style sheet.
10661082
*/
10671083
void page_style_css(void){
1068
- Blob css;
1084
+ Blob css = empty_blob;
10691085
int i;
10701086
int isInit = 0;
1087
+ const char * zPage = P("page");
10711088
10721089
cgi_set_content_type("text/css");
1073
- blob_init(&css,skin_get("css"),-1);
1090
+ if(zPage!=0 && zPage[0]!=0
1091
+ && strlen(zPage)<30/*marginal safety measure vs malicious input*/){
1092
+ /* Check for page-specific CSS. The placement of this CSS is kinda
1093
+ ** tricky. It "very probably needs" to come before any
1094
+ ** skin-supplied CSS, but if it does then a system-level skin
1095
+ ** which does silly things like set *all* textareas to the same
1096
+ ** 32px tall (Ardoise) can effectively ruin page-specific
1097
+ ** layout. If the page-specific CSS is emitted after the skin,
1098
+ ** then the page-specific CSS will potentially override any user
1099
+ ** edits made to the skin, leaving the user with no way to
1100
+ ** override them except to import a separate CSS file from their
1101
+ ** custom skin, after this one. Thus the page CSS needs to come
1102
+ ** first, but it also needs "unusually specific"
1103
+ ** (i.e. strongly-binding) CSS classes for any style which "needs"
1104
+ ** to override the *default* skin CSS, but which is nonetheless
1105
+ ** overridable by client-side edits by using CSS selectors of
1106
+ ** equal or higher specificity.
1107
+ **
1108
+ ** The alternative to this approach is that we pack all
1109
+ ** page-specific CSS into default_css.txt, which can explode it
1110
+ ** tremendously. e.g. /fileedit itself includes 330-ish lines of
1111
+ ** CSS.
1112
+ */
1113
+ int nLen = 0;
1114
+ char * zPageCss = mprintf("style.%s.css",zPage);
1115
+ const char * zBuiltin = (const char *)builtin_file(zPageCss, &nLen);
1116
+ fossil_free(zPageCss);
1117
+ if(nLen>0){
1118
+ blob_append(&css, zBuiltin, nLen);
1119
+ }
1120
+ }
1121
+ if(blob_size(&css)>0){
1122
+ blob_append(&css,skin_get("css"),-1);
1123
+ }else{
1124
+ blob_init(&css,skin_get("css"),-1);
1125
+ }
10741126
10751127
/* add special missing definitions */
10761128
for(i=1; cssDefaultList[i].elementClass; i++){
10771129
char *z = blob_str(&css);
10781130
if( !containsSelector(z, cssDefaultList[i].elementClass) ){
10791131
--- src/style.c
+++ src/style.c
@@ -370,15 +370,31 @@
370 const char *zVarPrefix,
371 const char *zConfigName,
372 const char *zPageName
373 ){
374 char *zVarName = mprintf("%s_url", zVarPrefix);
375 char *zUrl = mprintf("%R/%s?id=%x", zPageName,
376 skin_id(zConfigName));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
377 Th_Store(zVarName, zUrl);
378 free(zUrl);
379 free(zVarName);
 
380 }
381
382 /*
383 ** Create a TH1 variable containing the URL for the specified config image.
384 ** The resulting variable name will be of the form $[zImageName]_image_url.
@@ -1063,16 +1079,52 @@
1063 ** WEBPAGE: style.css
1064 **
1065 ** Return the style sheet.
1066 */
1067 void page_style_css(void){
1068 Blob css;
1069 int i;
1070 int isInit = 0;
 
1071
1072 cgi_set_content_type("text/css");
1073 blob_init(&css,skin_get("css"),-1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1074
1075 /* add special missing definitions */
1076 for(i=1; cssDefaultList[i].elementClass; i++){
1077 char *z = blob_str(&css);
1078 if( !containsSelector(z, cssDefaultList[i].elementClass) ){
1079
--- src/style.c
+++ src/style.c
@@ -370,15 +370,31 @@
370 const char *zVarPrefix,
371 const char *zConfigName,
372 const char *zPageName
373 ){
374 char *zVarName = mprintf("%s_url", zVarPrefix);
375 char *zExtra = 0;
376 char *zUrl = 0;
377 if(0==strcmp("css",zConfigName)){
378 /* Account for page-specific CSS, appending a page=NAME url flag
379 ** only if we have a corresponding built-in page-specific CSS
380 ** file. Do not append it to all pages because we would
381 ** effectively cache-bust all pages which do not have
382 ** page-specific CSS. */
383 char * zBuiltin = mprintf("style.%s.css", g.zPath);
384 if(builtin_file(zBuiltin,0)!=0){
385 zExtra = mprintf("&page=%s", g.zPath);
386 }
387 fossil_free(zBuiltin);
388 }
389 zUrl = mprintf("%R/%s?id=%x%s", zPageName,
390 skin_id(zConfigName),
391 zExtra ? zExtra : "");
392 Th_Store(zVarName, zUrl);
393 fossil_free(zExtra);
394 fossil_free(zUrl);
395 fossil_free(zVarName);
396 }
397
398 /*
399 ** Create a TH1 variable containing the URL for the specified config image.
400 ** The resulting variable name will be of the form $[zImageName]_image_url.
@@ -1063,16 +1079,52 @@
1079 ** WEBPAGE: style.css
1080 **
1081 ** Return the style sheet.
1082 */
1083 void page_style_css(void){
1084 Blob css = empty_blob;
1085 int i;
1086 int isInit = 0;
1087 const char * zPage = P("page");
1088
1089 cgi_set_content_type("text/css");
1090 if(zPage!=0 && zPage[0]!=0
1091 && strlen(zPage)<30/*marginal safety measure vs malicious input*/){
1092 /* Check for page-specific CSS. The placement of this CSS is kinda
1093 ** tricky. It "very probably needs" to come before any
1094 ** skin-supplied CSS, but if it does then a system-level skin
1095 ** which does silly things like set *all* textareas to the same
1096 ** 32px tall (Ardoise) can effectively ruin page-specific
1097 ** layout. If the page-specific CSS is emitted after the skin,
1098 ** then the page-specific CSS will potentially override any user
1099 ** edits made to the skin, leaving the user with no way to
1100 ** override them except to import a separate CSS file from their
1101 ** custom skin, after this one. Thus the page CSS needs to come
1102 ** first, but it also needs "unusually specific"
1103 ** (i.e. strongly-binding) CSS classes for any style which "needs"
1104 ** to override the *default* skin CSS, but which is nonetheless
1105 ** overridable by client-side edits by using CSS selectors of
1106 ** equal or higher specificity.
1107 **
1108 ** The alternative to this approach is that we pack all
1109 ** page-specific CSS into default_css.txt, which can explode it
1110 ** tremendously. e.g. /fileedit itself includes 330-ish lines of
1111 ** CSS.
1112 */
1113 int nLen = 0;
1114 char * zPageCss = mprintf("style.%s.css",zPage);
1115 const char * zBuiltin = (const char *)builtin_file(zPageCss, &nLen);
1116 fossil_free(zPageCss);
1117 if(nLen>0){
1118 blob_append(&css, zBuiltin, nLen);
1119 }
1120 }
1121 if(blob_size(&css)>0){
1122 blob_append(&css,skin_get("css"),-1);
1123 }else{
1124 blob_init(&css,skin_get("css"),-1);
1125 }
1126
1127 /* add special missing definitions */
1128 for(i=1; cssDefaultList[i].elementClass; i++){
1129 char *z = blob_str(&css);
1130 if( !containsSelector(z, cssDefaultList[i].elementClass) ){
1131

Keyboard Shortcuts

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