Fossil

Check-in [62398459fb]
Login

Check-in [62398459fb]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add the ability to set a background image as part of the server configuration. Process the CSS using TH1 so that $baseurl can be inserted into the CSS.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 62398459fb904b129f94d0811f9bc70b9b3df20d
User & Date: drh 2012-03-31 15:18:03.708
Context
2012-03-31
16:24
Update the download page generator script to always include the <!DOCTYPE html> at the beginning. Otherwise, IE9 doesn't work. ... (check-in: 1bf77fa2da user: drh tags: trunk)
15:18
Add the ability to set a background image as part of the server configuration. Process the CSS using TH1 so that $baseurl can be inserted into the CSS. ... (check-in: 62398459fb user: drh tags: trunk)
14:35
Pulled in latest cson_amalgamation for cson_sqlite3_bind_value(). ... (check-in: 1eec62808d user: stephan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/configure.c.
76
77
78
79
80
81
82









83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

108

109

110

111
112

113
114
115
116
117
118
119
  int groupMask;       /* Which config groups is it part of */
} aConfig[] = {
  { "css",                    CONFIGSET_SKIN },
  { "header",                 CONFIGSET_SKIN },
  { "footer",                 CONFIGSET_SKIN },
  { "logo-mimetype",          CONFIGSET_SKIN },
  { "logo-image",             CONFIGSET_SKIN },









  { "project-name",           CONFIGSET_PROJ },
  { "project-description",    CONFIGSET_PROJ },
  { "manifest",               CONFIGSET_PROJ },
  { "ignore-glob",            CONFIGSET_PROJ },
  { "crnl-glob",              CONFIGSET_PROJ },
  { "empty-dirs",             CONFIGSET_PROJ },
  { "allow-symlinks",         CONFIGSET_PROJ },
  { "index-page",             CONFIGSET_SKIN },
#ifdef FOSSIL_ENABLE_TCL
  { "tcl",                    CONFIGSET_SKIN|CONFIGSET_TKT|CONFIGSET_XFER },
#endif
  { "timeline-block-markup",  CONFIGSET_SKIN },
  { "timeline-max-comment",   CONFIGSET_SKIN },
  { "ticket-table",           CONFIGSET_TKT  },
  { "ticket-common",          CONFIGSET_TKT  },
  { "ticket-change",          CONFIGSET_TKT  },
  { "ticket-newpage",         CONFIGSET_TKT  },
  { "ticket-viewpage",        CONFIGSET_TKT  },
  { "ticket-editpage",        CONFIGSET_TKT  },
  { "ticket-reportlist",      CONFIGSET_TKT  },
  { "ticket-report-template", CONFIGSET_TKT  },
  { "ticket-key-template",    CONFIGSET_TKT  },
  { "ticket-title-expr",      CONFIGSET_TKT  },
  { "ticket-closed-expr",     CONFIGSET_TKT  },
  { "@reportfmt",             CONFIGSET_TKT  },

  { "@user",                  CONFIGSET_USER },

  { "@concealed",             CONFIGSET_ADDR },

  { "@shun",                  CONFIGSET_SHUN },

  { "xfer-common-script",     CONFIGSET_XFER },
  { "xfer-push-script",       CONFIGSET_XFER },

};
static int iConfig = 0;

/*
** Return name of first configuration property matching the given mask.
*/
const char *configure_first_name(int iMask){







>
>
>
>
>
>
>
>
>







|
<
<
<
<
<












>

>

>

>


>







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99





100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
  int groupMask;       /* Which config groups is it part of */
} aConfig[] = {
  { "css",                    CONFIGSET_SKIN },
  { "header",                 CONFIGSET_SKIN },
  { "footer",                 CONFIGSET_SKIN },
  { "logo-mimetype",          CONFIGSET_SKIN },
  { "logo-image",             CONFIGSET_SKIN },
  { "background-mimetype",    CONFIGSET_SKIN },
  { "background-image",       CONFIGSET_SKIN },
  { "index-page",             CONFIGSET_SKIN },
  { "timeline-block-markup",  CONFIGSET_SKIN },
  { "timeline-max-comment",   CONFIGSET_SKIN },
#ifdef FOSSIL_ENABLE_TCL
  { "tcl",                    CONFIGSET_SKIN|CONFIGSET_TKT|CONFIGSET_XFER },
#endif

  { "project-name",           CONFIGSET_PROJ },
  { "project-description",    CONFIGSET_PROJ },
  { "manifest",               CONFIGSET_PROJ },
  { "ignore-glob",            CONFIGSET_PROJ },
  { "crnl-glob",              CONFIGSET_PROJ },
  { "empty-dirs",             CONFIGSET_PROJ },
  { "allow-symlinks",         CONFIGSET_PROJ },






  { "ticket-table",           CONFIGSET_TKT  },
  { "ticket-common",          CONFIGSET_TKT  },
  { "ticket-change",          CONFIGSET_TKT  },
  { "ticket-newpage",         CONFIGSET_TKT  },
  { "ticket-viewpage",        CONFIGSET_TKT  },
  { "ticket-editpage",        CONFIGSET_TKT  },
  { "ticket-reportlist",      CONFIGSET_TKT  },
  { "ticket-report-template", CONFIGSET_TKT  },
  { "ticket-key-template",    CONFIGSET_TKT  },
  { "ticket-title-expr",      CONFIGSET_TKT  },
  { "ticket-closed-expr",     CONFIGSET_TKT  },
  { "@reportfmt",             CONFIGSET_TKT  },

  { "@user",                  CONFIGSET_USER },

  { "@concealed",             CONFIGSET_ADDR },

  { "@shun",                  CONFIGSET_SHUN },

  { "xfer-common-script",     CONFIGSET_XFER },
  { "xfer-push-script",       CONFIGSET_XFER },

};
static int iConfig = 0;

/*
** Return name of first configuration property matching the given mask.
*/
const char *configure_first_name(int iMask){
Changes to src/doc.c.
602
603
604
605
606
607
608

































  if( blob_size(&logo)==0 ){
    blob_init(&logo, (char*)aLogo, sizeof(aLogo));
  }
  cgi_set_content_type(zMime);
  cgi_set_content(&logo);
  g.isConst = 1;
}








































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
  if( blob_size(&logo)==0 ){
    blob_init(&logo, (char*)aLogo, sizeof(aLogo));
  }
  cgi_set_content_type(zMime);
  cgi_set_content(&logo);
  g.isConst = 1;
}

/*
** The default background image:  a 16x16 white GIF
*/
static const unsigned char aBackground[] = {
    71,  73,  70,  56,  57,  97,  16,   0,  16,   0,
   240,   0,   0, 255, 255, 255,   0,   0,   0,  33,
   254,   4, 119, 105, 115, 104,   0,  44,   0,   0,
     0,   0,  16,   0,  16,   0,   0,   2,  14, 132,
   143, 169, 203, 237,  15, 163, 156, 180, 218, 139,
   179,  62,   5,   0,  59,
};


/*
** WEBPAGE: background
**
** Return the background image.
*/
void background_page(void){
  Blob bgimg;
  char *zMime;

  zMime = db_get("background-mimetype", "image/gif");
  blob_zero(&bgimg);
  db_blob(&bgimg, "SELECT value FROM config WHERE name='background-image'");
  if( blob_size(&bgimg)==0 ){
    blob_init(&bgimg, (char*)aBackground, sizeof(aBackground));
  }
  cgi_set_content_type(zMime);
  cgi_set_content(&bgimg);
  g.isConst = 1;
}
Changes to src/setup.c.
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
  setup_menu_entry("CSS", "setup_editcss",
    "Edit the Cascading Style Sheet used by all pages of this repository");
  setup_menu_entry("Header", "setup_header",
    "Edit HTML text inserted at the top of every page");
  setup_menu_entry("Footer", "setup_footer",
    "Edit HTML text inserted at the bottom of every page");
  setup_menu_entry("Logo", "setup_logo",
    "Change the logo image for the server");
  setup_menu_entry("Shunned", "shun",
    "Show artifacts that are shunned by this repository");
  setup_menu_entry("Log", "rcvfromlist",
    "A record of received artifacts and their sources");
  setup_menu_entry("User-Log", "access_log",
    "A record of login attempts");
  setup_menu_entry("Stats", "stat",







|







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
  setup_menu_entry("CSS", "setup_editcss",
    "Edit the Cascading Style Sheet used by all pages of this repository");
  setup_menu_entry("Header", "setup_header",
    "Edit HTML text inserted at the top of every page");
  setup_menu_entry("Footer", "setup_footer",
    "Edit HTML text inserted at the bottom of every page");
  setup_menu_entry("Logo", "setup_logo",
    "Change the logo and background images for the server");
  setup_menu_entry("Shunned", "shun",
    "Show artifacts that are shunned by this repository");
  setup_menu_entry("Log", "rcvfromlist",
    "A record of received artifacts and their sources");
  setup_menu_entry("User-Log", "access_log",
    "A record of login attempts");
  setup_menu_entry("Stats", "stat",
1317
1318
1319
1320
1321
1322
1323
1324



1325
1326



1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347

























1348
1349
1350
1351
1352
1353
1354

1355
1356
1357
1358
1359
1360
1361
1362

1363


1364
1365
1366
1367
1368









1369





1370
1371





1372
1373
1374
1375
1376

1377
1378
1379

1380
1381
1382
1383
1384
1385
1386
1387
  db_end_transaction(0);
}

/*
** WEBPAGE: setup_logo
*/
void setup_logo(void){
  const char *zMime = db_get("logo-mimetype","image/gif");



  const char *aImg = P("im");
  int szImg = atoi(PD("im:bytes","0"));



  if( szImg>0 ){
    zMime = PD("im:mimetype","image/gif");
  }
  login_check_credentials();
  if( !g.perm.Setup ){
    login_needed();
  }
  db_begin_transaction();
  if( P("set")!=0 && zMime && zMime[0] && szImg>0 ){
    Blob img;
    Stmt ins;
    blob_init(&img, aImg, szImg);
    db_prepare(&ins,
        "REPLACE INTO config(name,value,mtime)"
        " VALUES('logo-image',:bytes,now())"
    );
    db_bind_blob(&ins, ":bytes", &img);
    db_step(&ins);
    db_finalize(&ins);
    db_multi_exec(
       "REPLACE INTO config(name,value,mtime) VALUES('logo-mimetype',%Q,now())",

























       zMime
    );
    db_end_transaction(0);
    cgi_redirect("setup_logo");
  }else if( P("clr")!=0 ){
    db_multi_exec(
       "DELETE FROM config WHERE name GLOB 'logo-*'"

    );
    db_end_transaction(0);
    cgi_redirect("setup_logo");
  }
  style_header("Edit Project Logo");
  @ <p>The current project logo has a MIME-Type of <b>%h(zMime)</b> and looks
  @ like this:</p>
  @ <blockquote><p><img src="%s(g.zTop)/logo" alt="logo" /></p></blockquote>

  @


  @ <p>The logo is accessible to all users at this URL:
  @ <a href="%s(g.zBaseURL)/logo">%s(g.zBaseURL)/logo</a>.
  @ The logo may or may not appear on each
  @ page depending on the <a href="setup_editcss">CSS</a> and
  @ <a href="setup_header">header setup</a>.</p>









  @





  @ <form action="%s(g.zTop)/setup_logo" method="post"
  @  enctype="multipart/form-data"><div>





  @ <p>To set a new logo image, select a file to use as the logo using
  @ the entry box below and then press the "Change Logo" button.</p>
  login_insert_csrf_secret();
  @ Logo Image file:
  @ <input type="file" name="im" size="60" accept="image/*" /><br />

  @ <input type="submit" name="set" value="Change Logo" />
  @ <input type="submit" name="clr" value="Revert To Default" />
  @ </div></form>

  @
  @ <p><span class="note">Note:</span>  Your browser has probably cached the
  @ logo image, so you will probably need to press the Reload button on your
  @ browser after changing the logo to provoke your browser to reload the new
  @ logo image. </p>
  style_footer();
  db_end_transaction(0);
}







|
>
>
>
|
|
>
>
>
|
|






|


|









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|



|

|
>




|
|
|
|
>

>
>




|
>
>
>
>
>
>
>
>
>

>
>
>
>
>


>
>
>
>
>
|
<

|
|
>
|
|

>

|
|
<
|



1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426

1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437

1438
1439
1440
1441
  db_end_transaction(0);
}

/*
** WEBPAGE: setup_logo
*/
void setup_logo(void){
  const char *zLogoMime = db_get("logo-mimetype","image/gif");
  const char *aLogoImg = P("logoim");
  int szLogoImg = atoi(PD("logoim:bytes","0"));
  const char *zBgMime = db_get("background-mimetype","image/gif");
  const char *aBgImg = P("bgim");
  int szBgImg = atoi(PD("bgim:bytes","0"));
  if( szLogoImg>0 ){
    zLogoMime = PD("logoim:mimetype","image/gif");
  }
  if( szBgImg>0 ){
    zBgMime = PD("bgim:mimetype","image/gif");
  }
  login_check_credentials();
  if( !g.perm.Setup ){
    login_needed();
  }
  db_begin_transaction();
  if( P("setlogo")!=0 && zLogoMime && zLogoMime[0] && szLogoImg>0 ){
    Blob img;
    Stmt ins;
    blob_init(&img, aLogoImg, szLogoImg);
    db_prepare(&ins,
        "REPLACE INTO config(name,value,mtime)"
        " VALUES('logo-image',:bytes,now())"
    );
    db_bind_blob(&ins, ":bytes", &img);
    db_step(&ins);
    db_finalize(&ins);
    db_multi_exec(
       "REPLACE INTO config(name,value,mtime) VALUES('logo-mimetype',%Q,now())",
       zLogoMime
    );
    db_end_transaction(0);
    cgi_redirect("setup_logo");
  }else if( P("clrlogo")!=0 ){
    db_multi_exec(
       "DELETE FROM config WHERE name IN "
           "('logo-image','logo-mimetype')"
    );
    db_end_transaction(0);
    cgi_redirect("setup_logo");
  }else if( P("setbg")!=0 && zBgMime && zBgMime[0] && szBgImg>0 ){
    Blob img;
    Stmt ins;
    blob_init(&img, aBgImg, szBgImg);
    db_prepare(&ins,
        "REPLACE INTO config(name,value,mtime)"
        " VALUES('background-image',:bytes,now())"
    );
    db_bind_blob(&ins, ":bytes", &img);
    db_step(&ins);
    db_finalize(&ins);
    db_multi_exec(
       "REPLACE INTO config(name,value,mtime)"
       " VALUES('background-mimetype',%Q,now())",
       zBgMime
    );
    db_end_transaction(0);
    cgi_redirect("setup_logo");
  }else if( P("clrbg")!=0 ){
    db_multi_exec(
       "DELETE FROM config WHERE name IN "
           "('background-image','background-mimetype')"
    );
    db_end_transaction(0);
    cgi_redirect("setup_logo");
  }
  style_header("Edit Project Logo And Background");
  @ <p>The current project logo has a MIME-Type of <b>%h(zLogoMime)</b>
  @ and looks like this:</p>
  @ <blockquote><p><img src="%s(g.zTop)/logo" alt="logo" border="1" />
  @ </p></blockquote>
  @
  @ <form action="%s(g.zTop)/setup_logo" method="post"
  @  enctype="multipart/form-data"><div>
  @ <p>The logo is accessible to all users at this URL:
  @ <a href="%s(g.zBaseURL)/logo">%s(g.zBaseURL)/logo</a>.
  @ The logo may or may not appear on each
  @ page depending on the <a href="setup_editcss">CSS</a> and
  @ <a href="setup_header">header setup</a>.
  @ To change the logo image, use the following form:</p>
  login_insert_csrf_secret();
  @ Logo Image file:
  @ <input type="file" name="logoim" size="60" accept="image/*" />
  @ <p align="center">
  @ <input type="submit" name="setlogo" value="Change Logo" />
  @ <input type="submit" name="clrlogo" value="Revert To Default" /></p>
  @ </div></form>
  @ <hr />
  @
  @ <p>The current background image has a MIME-Type of <b>%h(zBgMime)</b>
  @ and looks like this:</p>
  @ <blockquote><p><img src="%s(g.zTop)/background" alt="background" border=1 />
  @ </p></blockquote>
  @
  @ <form action="%s(g.zTop)/setup_logo" method="post"
  @  enctype="multipart/form-data"><div>
  @ <p>The background image is accessible to all users at this URL:
  @ <a href="%s(g.zBaseURL)/background">%s(g.zBaseURL)/background</a>.
  @ The background image may or may not appear on each
  @ page depending on the <a href="setup_editcss">CSS</a> and
  @ <a href="setup_header">header setup</a>.
  @ To change the background image, use the following form:</p>

  login_insert_csrf_secret();
  @ Background image file:
  @ <input type="file" name="bgim" size="60" accept="image/*" />
  @ <p align="center">
  @ <input type="submit" name="setbg" value="Change Background" />
  @ <input type="submit" name="clrbg" value="Revert To Default" /></p>
  @ </div></form>
  @ <hr />
  @
  @ <p><span class="note">Note:</span>  Your browser has probably cached these
  @ images, so you may need to press the Reload button before changes will

  @ take effect. </p>
  style_footer();
  db_end_transaction(0);
}
Changes to src/style.c.
811
812
813
814
815
816
817

818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833


834






835

836
837
838
839
840
841
842
  }
}

/*
** WEBPAGE: style.css
*/
void page_style_css(void){

  const char *zCSS    = 0;
  int i;

  cgi_set_content_type("text/css");
  zCSS = db_get("css",(char*)zDefaultCSS);
  /* append user defined css */
  cgi_append_content(zCSS, -1);
  /* add special missing definitions */
  for (i=1;cssDefaultList[i].elementClass;i++)
    if (!strstr(zCSS,cssDefaultList[i].elementClass)) {
      cgi_append_content("/* ", -1);
      cgi_append_content(cssDefaultList[i].comment, -1);
      cgi_append_content(" */\n", -1);
      cgi_append_content(cssDefaultList[i].elementClass, -1);
      cgi_append_content(" {\n", -1);
      cgi_append_content(cssDefaultList[i].value, -1);


      cgi_append_content("}\n\n", -1);






    }

  g.isConst = 1;
}

/*
** WEBPAGE: test_env
*/
void page_test_env(void){







>




|
|
<

|
|
|
|
<
|
<
|
>
>
|
>
>
>
>
>
>
|
>







811
812
813
814
815
816
817
818
819
820
821
822
823
824

825
826
827
828
829

830

831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
  }
}

/*
** WEBPAGE: style.css
*/
void page_style_css(void){
  Blob css;
  const char *zCSS    = 0;
  int i;

  cgi_set_content_type("text/css");
  blob_init(&css, db_get("css",(char*)zDefaultCSS), -1);


  /* add special missing definitions */
  for(i=1; cssDefaultList[i].elementClass; i++){
    if( strstr(blob_str(&css), cssDefaultList[i].elementClass)==0 ){
      blob_appendf(&css, "/* %s */\n%s {\n%s}\n",
          cssDefaultList[i].comment,

          cssDefaultList[i].elementClass,

          cssDefaultList[i].value);
    }
  }

  /* Process through TH1 in order to give an opportunity to substitute
  ** variables such as $baseurl.
  */
  Th_Store("baseurl", g.zBaseURL);
  Th_Store("home", g.zTop);
  Th_Render(blob_str(&css));

  /* Tell CGI that the content returned by this page is considered cacheable */
  g.isConst = 1;
}

/*
** WEBPAGE: test_env
*/
void page_test_env(void){