Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | All timelines use the "ss" display preferences cookie. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | sticky-timeline-style |
| Files: | files | file ages | folders |
| SHA3-256: |
6314b4ed94380d0e8982206808d0916a |
| User & Date: | drh 2017-11-29 14:02:01.055 |
Context
|
2017-11-29
| ||
| 14:05 | The /timeline supports 4 sticky viewing modes: Modern, Verbose, Compact, and Columnar. The new cookie.c module supports sticky user viewing preferences. check-in: c94f608548 user: drh tags: trunk | |
| 14:02 | All timelines use the "ss" display preferences cookie. Closed-Leaf check-in: 6314b4ed94 user: drh tags: sticky-timeline-style | |
| 13:25 | Add the "View" selector to the /finfo page. check-in: e36f693f7a user: drh tags: sticky-timeline-style | |
Changes
Changes to src/cookies.c.
| ︙ | ︙ | |||
14 15 16 17 18 19 20 | ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** This file contains code used to manage a cookie that stores user-specific ** display preferences for the web interface. ** | | < < < | | | > > > > > < > | | < | > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
** http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This file contains code used to manage a cookie that stores user-specific
** display preferences for the web interface.
**
** cookie_parse(void);
**
** Read and parse the display preferences cookie.
**
** cookie_read_parameter(zQP, zPName);
**
** If query parameter zQP does not exist but zPName does exist in
** the parsed cookie, then initialize zQP to hold the same value
** as the zPName element in the parsed cookie.
**
** cookie_write_parameter(zQP, zPName, zDefault);
**
** If query parameter zQP exists and if it has a different value from
** the zPName parameter in the parsed cookie, then replace the value of
** zPName with the value of zQP. If zQP exists but zPName does not
** exist, then zPName is created. If zQP does not exist or if it has
** the same value as zPName, then this routine is a no-op.
**
** cookie_link_parameter(zQP, zPName, zDefault);
**
** This does both cookie_read_parameter() and cookie_write_parameter()
** all at once.
**
** cookie_render();
**
** If any prior calls to cookie_write_parameter() have changed the
** value of the user preferences cookie, this routine will cause the
** new cookie value to be included in the HTTP header for the current
** web page. This routine is a destructor for this module and should
** be called once.
**
** char *cookie_value(zPName, zDefault);
**
** Look up the value of a cookie parameter zPName. Return zDefault if
** there is no display preferences cookie or if zPName does not exist.
*/
#include "cookies.h"
#include <assert.h>
#include <string.h>
#if INTERFACE
/* the standard name of the display settings cookie for fossil */
# define DISPLAY_SETTINGS_COOKIE "fossil_display_settings"
#endif
/*
** State information private to this module
*/
#define COOKIE_NPARAM 10
static struct {
char *zCookieValue; /* Value of the user preferences cookie */
int bChanged; /* True if any value has changed */
int bIsInit; /* True after initialization */
int nParam; /* Number of parameters in the cookie */
struct {
const char *zPName; /* Name of a parameter */
char *zPValue; /* Value of that parameter */
} aParam[COOKIE_NPARAM];
} cookies;
/* Initialize this module by parsing the content of the cookie named
** by zCookieName
*/
void cookie_parse(void){
char *z;
if( cookies.bIsInit ) return;
z = (char*)P(DISPLAY_SETTINGS_COOKIE);
if( z==0 ) z = "";
cookies.zCookieValue = z = mprintf("%s", z);
cookies.bIsInit = 1;
while( cookies.nParam<COOKIE_NPARAM ){
while( fossil_isspace(z[0]) ) z++;
if( z[0]==0 ) break;
cookies.aParam[cookies.nParam].zPName = z;
while( *z && *z!='=' && *z!=',' ){ z++; }
if( *z=='=' ){
*z = 0;
|
| ︙ | ︙ | |||
116 117 118 119 120 121 122 |
const char *zQP, /* Name of the query parameter */
const char *zPName, /* Name of the cooking setting */
const char *zDflt, /* Default value for the query parameter */
int flags /* READ or WRITE or both */
){
const char *zQVal = P(zQP);
int i;
| | | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
const char *zQP, /* Name of the query parameter */
const char *zPName, /* Name of the cooking setting */
const char *zDflt, /* Default value for the query parameter */
int flags /* READ or WRITE or both */
){
const char *zQVal = P(zQP);
int i;
cookie_parse();
for(i=0; i<cookies.nParam && strcmp(zPName,cookies.aParam[i].zPName); i++){}
if( zQVal==0 && (flags & COOKIE_READ)!=0 && i<cookies.nParam ){
cgi_set_parameter_nocopy(zQP, cookies.aParam[i].zPValue, 1);
return;
}
if( zQVal==0 ) zQVal = zDflt;
if( (flags & COOKIE_WRITE)!=0
|
| ︙ | ︙ | |||
169 170 171 172 173 174 175 |
cookie_readwrite(zQP, zPName, zDflt, COOKIE_READ|COOKIE_WRITE);
}
/* Update the user preferences cookie, if necessary, and shut down this
** module
*/
void cookie_render(void){
| < | | > > > > > > > > > > | | 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
cookie_readwrite(zQP, zPName, zDflt, COOKIE_READ|COOKIE_WRITE);
}
/* Update the user preferences cookie, if necessary, and shut down this
** module
*/
void cookie_render(void){
if( cookies.bChanged ){
Blob new;
int i;
blob_init(&new, 0, 0);
for(i=0;i<cookies.nParam;i++){
if( i>0 ) blob_append(&new, ",", 1);
blob_appendf(&new, "%s=%T",
cookies.aParam[i].zPName, cookies.aParam[i].zPValue);
}
cgi_set_cookie(DISPLAY_SETTINGS_COOKIE, blob_str(&new), 0, 31536000);
}
cookies.bIsInit = 0;
}
/* Return the value of a preference cookie.
*/
const char *cookie_value(const char *zPName, const char *zDefault){
int i;
assert( zPName!=0 );
cookie_parse();
for(i=0; i<cookies.nParam && strcmp(zPName,cookies.aParam[i].zPName); i++){}
return i<cookies.nParam ? cookies.aParam[i].zPValue : zDefault;
}
/*
** WEBPAGE: cookies
**
** Show the current display settings contained in the
** "fossil_display_settings" cookie.
*/
void cookie_page(void){
int i;
if( PB("clear") ){
cgi_set_cookie(DISPLAY_SETTINGS_COOKIE, "", 0, 1);
cgi_replace_parameter(DISPLAY_SETTINGS_COOKIE, "");
}
cookie_parse();
style_header("User Preference Cookie Values");
if( cookies.nParam ){
style_submenu_element("Clear", "%R/cookies?clear");
}
@ <p>The following are user preference settings held in the
@ "fossil_display_settings" cookie.
@ <ul>
|
| ︙ | ︙ |
Changes to src/finfo.c.
| ︙ | ︙ | |||
323 324 325 326 327 328 329 |
int tmFlags = 0; /* Viewing mode */
const char *zStyle; /* Viewing mode name */
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
style_header("File History");
login_anonymous_available();
| < | 323 324 325 326 327 328 329 330 331 332 333 334 335 336 |
int tmFlags = 0; /* Viewing mode */
const char *zStyle; /* Viewing mode name */
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
style_header("File History");
login_anonymous_available();
tmFlags = timeline_ss_submenu();
if( tmFlags & TIMELINE_COLUMNAR ){
zStyle = "Columnar";
}else if( tmFlags & TIMELINE_COMPACT ){
zStyle = "Compact";
}else if( tmFlags & TIMELINE_VERBOSE ){
zStyle = "Verbose";
|
| ︙ | ︙ |
Changes to src/timeline.c.
| ︙ | ︙ | |||
103 104 105 106 107 108 109 | #define TIMELINE_UCOLOR 0x0080 /* Background color by user */ #define TIMELINE_FRENAMES 0x0100 /* Detail only file name changes */ #define TIMELINE_UNHIDE 0x0200 /* Unhide check-ins with "hidden" tag */ #define TIMELINE_SHOWRID 0x0400 /* Show RID values in addition to UUIDs */ #define TIMELINE_BISECT 0x0800 /* Show supplimental bisect information */ #define TIMELINE_COMPACT 0x1000 /* Use the "compact" view style */ #define TIMELINE_VERBOSE 0x2000 /* Use the "detailed" view style */ | | > | 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
#define TIMELINE_UCOLOR 0x0080 /* Background color by user */
#define TIMELINE_FRENAMES 0x0100 /* Detail only file name changes */
#define TIMELINE_UNHIDE 0x0200 /* Unhide check-ins with "hidden" tag */
#define TIMELINE_SHOWRID 0x0400 /* Show RID values in addition to UUIDs */
#define TIMELINE_BISECT 0x0800 /* Show supplimental bisect information */
#define TIMELINE_COMPACT 0x1000 /* Use the "compact" view style */
#define TIMELINE_VERBOSE 0x2000 /* Use the "detailed" view style */
#define TIMELINE_MODERN 0x4000 /* Use the "modern" view style */
#define TIMELINE_COLUMNAR 0x8000 /* Use the "columns view style */
#define TIMELINE_VIEWS 0xf000 /* Mask for all of the view styles */
#endif
/*
** Hash a string and use the hash to determine a background color.
*/
char *hash_color(const char *z){
int i; /* Loop counter */
|
| ︙ | ︙ | |||
261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
if( fossil_strcmp(g.zIpAddr, "127.0.0.1")==0 && db_open_local(0) ){
vid = db_lget_int("checkout", 0);
}
zPrevDate[0] = 0;
mxWikiLen = db_get_int("timeline-max-comment", 0);
dateFormat = db_get_int("timeline-date-format", 0);
bCommentGitStyle = db_get_int("timeline-truncate-at-blank", 0);
if( tmFlags & TIMELINE_COLUMNAR ){
zStyle = "Columnar";
}else if( tmFlags & TIMELINE_COMPACT ){
zStyle = "Compact";
}else if( tmFlags & TIMELINE_VERBOSE ){
zStyle = "Verbose";
}else{
| > > > | 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
if( fossil_strcmp(g.zIpAddr, "127.0.0.1")==0 && db_open_local(0) ){
vid = db_lget_int("checkout", 0);
}
zPrevDate[0] = 0;
mxWikiLen = db_get_int("timeline-max-comment", 0);
dateFormat = db_get_int("timeline-date-format", 0);
bCommentGitStyle = db_get_int("timeline-truncate-at-blank", 0);
if( (tmFlags & TIMELINE_VIEWS)==0 ){
tmFlags |= timeline_ss_cookie();
}
if( tmFlags & TIMELINE_COLUMNAR ){
zStyle = "Columnar";
}else if( tmFlags & TIMELINE_COMPACT ){
zStyle = "Compact";
}else if( tmFlags & TIMELINE_VERBOSE ){
zStyle = "Verbose";
}else{
|
| ︙ | ︙ | |||
1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 |
}
assert( i<=count(az) );
}
if( i>2 ){
style_submenu_multichoice("y", i/2, az, isDisabled);
}
}
/*
** Add the select/option box to the timeline submenu that is used to
** set the ss= parameter that determines the viewing mode.
**
** Return the TIMELINE_* value appropriate for the view-style.
*/
int timeline_ss_submenu(void){
static const char *azViewStyles[] = {
"m", "Modern View",
"c", "Compact View",
"v", "Verbose View",
"j", "Columnar View",
};
| > > > > > > > > > > > > > > < < < < < < < | | 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 |
}
assert( i<=count(az) );
}
if( i>2 ){
style_submenu_multichoice("y", i/2, az, isDisabled);
}
}
/*
** Convert the current "ss" display preferences cookie into an appropriate TIMELINE_* flag
*/
int timeline_ss_cookie(void){
int tmFlags;
switch( cookie_value("ss","m")[0] ){
case 'c': tmFlags = TIMELINE_COMPACT; break;
case 'v': tmFlags = TIMELINE_VERBOSE; break;
case 'j': tmFlags = TIMELINE_COLUMNAR; break;
default: tmFlags = TIMELINE_MODERN; break;
}
return tmFlags;
}
/*
** Add the select/option box to the timeline submenu that is used to
** set the ss= parameter that determines the viewing mode.
**
** Return the TIMELINE_* value appropriate for the view-style.
*/
int timeline_ss_submenu(void){
static const char *azViewStyles[] = {
"m", "Modern View",
"c", "Compact View",
"v", "Verbose View",
"j", "Columnar View",
};
cookie_link_parameter("ss","ss","m");
style_submenu_multichoice("ss", 4, azViewStyles, 0);
return timeline_ss_cookie();
}
/*
** If the zChng string is not NULL, then it should be a comma-separated
** list of glob patterns for filenames. Add an term to the WHERE clause
** for the SQL statement under construction that excludes any check-in that
** does not modify one or more files matching the globs.
|
| ︙ | ︙ | |||
1690 1691 1692 1693 1694 1695 1696 | const char *z; char *zOlderButton = 0; /* URL for Older button at the bottom */ char *zNewerButton = 0; /* URL for Newer button at the top */ int selectedRid = -9999999; /* Show a highlight on this RID */ int disableY = 0; /* Disable type selector on submenu */ /* Set number of rows to display */ | < | 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 |
const char *z;
char *zOlderButton = 0; /* URL for Older button at the bottom */
char *zNewerButton = 0; /* URL for Newer button at the top */
int selectedRid = -9999999; /* Show a highlight on this RID */
int disableY = 0; /* Disable type selector on submenu */
/* Set number of rows to display */
cookie_read_parameter("n","n");
z = P("n");
if( z==0 ) z = db_get("timeline-default-length",0);
if( z ){
if( fossil_strcmp(z,"all")==0 ){
nEntry = 0;
}else{
|
| ︙ | ︙ |