| | @@ -16,32 +16,29 @@ |
| 16 | 16 | ******************************************************************************* |
| 17 | 17 | ** |
| 18 | 18 | ** This file contains code used to manage a cookie that stores user-specific |
| 19 | 19 | ** display preferences for the web interface. |
| 20 | 20 | ** |
| 21 | | -** cookie_parse(zNameOfCookie); |
| 21 | +** cookie_parse(void); |
| 22 | 22 | ** |
| 23 | | -** Identify a cookie that will be used to remember display choices |
| 24 | | -** made by the user, so that those same choices are selected automatically |
| 25 | | -** the next time the page is presented. This routine must be invoked |
| 26 | | -** first, to initialize this module. |
| 23 | +** Read and parse the display preferences cookie. |
| 27 | 24 | ** |
| 28 | 25 | ** cookie_read_parameter(zQP, zPName); |
| 29 | 26 | ** |
| 30 | 27 | ** If query parameter zQP does not exist but zPName does exist in |
| 31 | 28 | ** the parsed cookie, then initialize zQP to hold the same value |
| 32 | 29 | ** as the zPName element in the parsed cookie. |
| 33 | 30 | ** |
| 34 | | -** cookie_write_parameter(zQP, zPName); |
| 31 | +** cookie_write_parameter(zQP, zPName, zDefault); |
| 35 | 32 | ** |
| 36 | 33 | ** If query parameter zQP exists and if it has a different value from |
| 37 | 34 | ** the zPName parameter in the parsed cookie, then replace the value of |
| 38 | 35 | ** zPName with the value of zQP. If zQP exists but zPName does not |
| 39 | 36 | ** exist, then zPName is created. If zQP does not exist or if it has |
| 40 | 37 | ** the same value as zPName, then this routine is a no-op. |
| 41 | 38 | ** |
| 42 | | -** cookie_link_parameter(zQP, zPName); |
| 39 | +** cookie_link_parameter(zQP, zPName, zDefault); |
| 43 | 40 | ** |
| 44 | 41 | ** This does both cookie_read_parameter() and cookie_write_parameter() |
| 45 | 42 | ** all at once. |
| 46 | 43 | ** |
| 47 | 44 | ** cookie_render(); |
| | @@ -49,10 +46,15 @@ |
| 49 | 46 | ** If any prior calls to cookie_write_parameter() have changed the |
| 50 | 47 | ** value of the user preferences cookie, this routine will cause the |
| 51 | 48 | ** new cookie value to be included in the HTTP header for the current |
| 52 | 49 | ** web page. This routine is a destructor for this module and should |
| 53 | 50 | ** be called once. |
| 51 | +** |
| 52 | +** char *cookie_value(zPName, zDefault); |
| 53 | +** |
| 54 | +** Look up the value of a cookie parameter zPName. Return zDefault if |
| 55 | +** there is no display preferences cookie or if zPName does not exist. |
| 54 | 56 | */ |
| 55 | 57 | #include "cookies.h" |
| 56 | 58 | #include <assert.h> |
| 57 | 59 | #include <string.h> |
| 58 | 60 | |
| | @@ -65,13 +67,13 @@ |
| 65 | 67 | /* |
| 66 | 68 | ** State information private to this module |
| 67 | 69 | */ |
| 68 | 70 | #define COOKIE_NPARAM 10 |
| 69 | 71 | static struct { |
| 70 | | - const char *zCookieName; /* name of the user preferences cookie */ |
| 71 | 72 | char *zCookieValue; /* Value of the user preferences cookie */ |
| 72 | 73 | int bChanged; /* True if any value has changed */ |
| 74 | + int bIsInit; /* True after initialization */ |
| 73 | 75 | int nParam; /* Number of parameters in the cookie */ |
| 74 | 76 | struct { |
| 75 | 77 | const char *zPName; /* Name of a parameter */ |
| 76 | 78 | char *zPValue; /* Value of that parameter */ |
| 77 | 79 | } aParam[COOKIE_NPARAM]; |
| | @@ -78,17 +80,17 @@ |
| 78 | 80 | } cookies; |
| 79 | 81 | |
| 80 | 82 | /* Initialize this module by parsing the content of the cookie named |
| 81 | 83 | ** by zCookieName |
| 82 | 84 | */ |
| 83 | | -void cookie_parse(const char *zCookieName){ |
| 85 | +void cookie_parse(void){ |
| 84 | 86 | char *z; |
| 85 | | - assert( cookies.zCookieName==0 ); |
| 86 | | - cookies.zCookieName = zCookieName; |
| 87 | | - z = (char*)P(zCookieName); |
| 87 | + if( cookies.bIsInit ) return; |
| 88 | + z = (char*)P(DISPLAY_SETTINGS_COOKIE); |
| 88 | 89 | if( z==0 ) z = ""; |
| 89 | 90 | cookies.zCookieValue = z = mprintf("%s", z); |
| 91 | + cookies.bIsInit = 1; |
| 90 | 92 | while( cookies.nParam<COOKIE_NPARAM ){ |
| 91 | 93 | while( fossil_isspace(z[0]) ) z++; |
| 92 | 94 | if( z[0]==0 ) break; |
| 93 | 95 | cookies.aParam[cookies.nParam].zPName = z; |
| 94 | 96 | while( *z && *z!='=' && *z!=',' ){ z++; } |
| | @@ -118,11 +120,11 @@ |
| 118 | 120 | const char *zDflt, /* Default value for the query parameter */ |
| 119 | 121 | int flags /* READ or WRITE or both */ |
| 120 | 122 | ){ |
| 121 | 123 | const char *zQVal = P(zQP); |
| 122 | 124 | int i; |
| 123 | | - assert( cookies.zCookieName!=0 ); |
| 125 | + cookie_parse(); |
| 124 | 126 | for(i=0; i<cookies.nParam && strcmp(zPName,cookies.aParam[i].zPName); i++){} |
| 125 | 127 | if( zQVal==0 && (flags & COOKIE_READ)!=0 && i<cookies.nParam ){ |
| 126 | 128 | cgi_set_parameter_nocopy(zQP, cookies.aParam[i].zPValue, 1); |
| 127 | 129 | return; |
| 128 | 130 | } |
| | @@ -171,23 +173,32 @@ |
| 171 | 173 | |
| 172 | 174 | /* Update the user preferences cookie, if necessary, and shut down this |
| 173 | 175 | ** module |
| 174 | 176 | */ |
| 175 | 177 | void cookie_render(void){ |
| 176 | | - assert( cookies.zCookieName!=0 ); |
| 177 | 178 | if( cookies.bChanged ){ |
| 178 | 179 | Blob new; |
| 179 | 180 | int i; |
| 180 | 181 | blob_init(&new, 0, 0); |
| 181 | 182 | for(i=0;i<cookies.nParam;i++){ |
| 182 | 183 | if( i>0 ) blob_append(&new, ",", 1); |
| 183 | 184 | blob_appendf(&new, "%s=%T", |
| 184 | 185 | cookies.aParam[i].zPName, cookies.aParam[i].zPValue); |
| 185 | 186 | } |
| 186 | | - cgi_set_cookie(cookies.zCookieName, blob_str(&new), 0, 31536000); |
| 187 | + cgi_set_cookie(DISPLAY_SETTINGS_COOKIE, blob_str(&new), 0, 31536000); |
| 187 | 188 | } |
| 188 | | - cookies.zCookieName = 0; |
| 189 | + cookies.bIsInit = 0; |
| 190 | +} |
| 191 | + |
| 192 | +/* Return the value of a preference cookie. |
| 193 | +*/ |
| 194 | +const char *cookie_value(const char *zPName, const char *zDefault){ |
| 195 | + int i; |
| 196 | + assert( zPName!=0 ); |
| 197 | + cookie_parse(); |
| 198 | + for(i=0; i<cookies.nParam && strcmp(zPName,cookies.aParam[i].zPName); i++){} |
| 199 | + return i<cookies.nParam ? cookies.aParam[i].zPValue : zDefault; |
| 189 | 200 | } |
| 190 | 201 | |
| 191 | 202 | /* |
| 192 | 203 | ** WEBPAGE: cookies |
| 193 | 204 | ** |
| | @@ -198,11 +209,11 @@ |
| 198 | 209 | int i; |
| 199 | 210 | if( PB("clear") ){ |
| 200 | 211 | cgi_set_cookie(DISPLAY_SETTINGS_COOKIE, "", 0, 1); |
| 201 | 212 | cgi_replace_parameter(DISPLAY_SETTINGS_COOKIE, ""); |
| 202 | 213 | } |
| 203 | | - cookie_parse(DISPLAY_SETTINGS_COOKIE); |
| 214 | + cookie_parse(); |
| 204 | 215 | style_header("User Preference Cookie Values"); |
| 205 | 216 | if( cookies.nParam ){ |
| 206 | 217 | style_submenu_element("Clear", "%R/cookies?clear"); |
| 207 | 218 | } |
| 208 | 219 | @ <p>The following are user preference settings held in the |
| 209 | 220 | |