Fossil

Check-in [92af2148]
Login

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

Overview
Comment:Fixes to the cookie handler. Simpler class structure on timelines.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sticky-timeline-style
Files: files | file ages | folders
SHA3-256: 92af2148fbfce50d75f5e9f9a724fa07e0e9693935a9a3504ea704ed3f4b2072
User & Date: drh 2017-11-29 02:20:36
Context
2017-11-29
02:29
Change the name of the "Detailed" mode on /timeline to "Verbose". check-in: c0a3a90b user: drh tags: sticky-timeline-style
02:20
Fixes to the cookie handler. Simpler class structure on timelines. check-in: 92af2148 user: drh tags: sticky-timeline-style
2017-11-28
22:16
Improvements to handling of the cookie for "sticky" display settings. check-in: 3ec84397 user: drh tags: sticky-timeline-style
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/cookies.c.

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
...
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
  z = (char*)P(zCookieName);
  if( z==0 ) z = "";
  cookies.zCookieValue = z = mprintf("%s", z);
  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;
      z++;
      cookies.aParam[cookies.nParam].zPValue = z;
      while( *z && *z!='&' ){ z++; }
      if( *z ){
        *z = 0;
        z++;
      }
      dehttpize(cookies.aParam[cookies.nParam].zPValue);
    }else{
      if( *z ){ *z++ = 0; }
................................................................................
void cookie_render(void){
  assert( cookies.zCookieName!=0 );
  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(cookies.zCookieName, blob_str(&new), 0, 31536000);
  }
  cookies.zCookieName = 0;
}








|




|







 







|
|







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
...
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
  z = (char*)P(zCookieName);
  if( z==0 ) z = "";
  cookies.zCookieValue = z = mprintf("%s", z);
  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;
      z++;
      cookies.aParam[cookies.nParam].zPValue = z;
      while( *z && *z!=',' ){ z++; }
      if( *z ){
        *z = 0;
        z++;
      }
      dehttpize(cookies.aParam[cookies.nParam].zPValue);
    }else{
      if( *z ){ *z++ = 0; }
................................................................................
void cookie_render(void){
  assert( cookies.zCookieName!=0 );
  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(cookies.zCookieName, blob_str(&new), 0, 31536000);
  }
  cookies.zCookieName = 0;
}

Changes to src/timeline.c.

250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273


274
275
276
277
278
279
280
...
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
...
462
463
464
465
466
467
468



469
470

471
472
473
474
475
476
477
...
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
...
587
588
589
590
591
592
593
594

595



596
597
598
599
600
601
602
....
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669

1670
1671
1672
1673
1674
1675
1676
  int fchngQueryInit = 0;     /* True if fchngQuery is initialized */
  Stmt fchngQuery;            /* Query for file changes on check-ins */
  static Stmt qbranch;
  int pendingEndTr = 0;       /* True if a </td></tr> is needed */
  int vid = 0;                /* Current checkout version */
  int dateFormat = 0;         /* 0: HH:MM (default) */
  int bCommentGitStyle = 0;   /* Only show comments through first blank line */
  const char *zTdClass;
  const char *zDateFmt;
  int iTableId = timeline_tableid();

  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_NORMAL ){
    zTdClass = "timelineStyleNormal";
  }else if( tmFlags & TIMELINE_COMPACT ){
    zTdClass = "timelineStyleCompact";
  }else if( tmFlags & TIMELINE_DETAILED ){
    zTdClass = "timelineStyleDetailed";


  }
  zDateFmt = P("datefmt");
  if( zDateFmt ) dateFormat = atoi(zDateFmt);
  if( tmFlags & TIMELINE_GRAPH ){
    pGraph = graph_init();
  }
  db_static_prepare(&qbranch,
................................................................................
      gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr,
                           zUuid, isLeaf);
      db_reset(&qbranch);
      @ <div id="m%d(gidx)" class="tl-nodemark"></div>
    }
    @</td>
    if( zBgClr && zBgClr[0] && rid!=selectedRid ){
      @ <td class="timelineTableCell %s(zTdClass)" \
      @  style="background-color: %h(zBgClr);">
    }else{
      @ <td class="timelineTableCell %s(zTdClass)">
    }
    if( pGraph && zType[0]!='c' ){
      @ &bull;
    }
    if( modPending ){
      @ <span class="modpending">(Awaiting Moderator Approval)</span>
    }
................................................................................
    if( zType[0]!='c' ){
      /* Comments for anything other than a check-in are generated by
      ** "fossil rebuild" and expect to be rendered as text/x-fossil-wiki */
      @ <span class='timelineComment' onclick='toggleDetail(%d(rid))'>
      wiki_convert(&comment, 0, WIKI_INLINE);
      @ </span>
    }else{



      @ <span class='timelineComment timelineCheckinComment' \
      @  onclick='toggleDetail(%d(rid))'>

      if( bCommentGitStyle ){
        /* Truncate comment at first blank line */
        int ii, jj;
        int n = blob_size(&comment);
        char *z = blob_str(&comment);
        for(ii=0; ii<n; ii++){
          if( z[ii]=='\n' ){
................................................................................
    */
    if( drawDetailEllipsis ){
      @ <span class='timelineEllipsis anticlutter' id='ellipsis-%d(rid)' \
      @  onclick='toggleDetail(%d(rid))'>...</span>
    }
    if( tmFlags & TIMELINE_COLUMNAR ){
      if( zBgClr && zBgClr[0] && rid!=selectedRid ){
        @ <td class="timelineTableCell timelineDetailCell"
        @  style="background-color: %h(zBgClr);">
      }else{
        @ <td class="timelineTableCell timelineDetailCell">
      }
    }
    if( tmFlags & TIMELINE_COMPACT ){
      cgi_printf("<span class='timelineDetailWrapper clutter' id='detail-%d'>",rid);
    }else{
      cgi_printf("<span class='timelineDetailWrapper'>");
    }
    if( zType[0]=='c' ){
      cgi_printf("<span class='timelineDetail timelineCheckinDetail'>");
    }else{
      cgi_printf("<span class='timelineDetail'>");
    }

    if( zType[0]=='c' ){
      if( isLeaf ){
        if( db_exists("SELECT 1 FROM tagxref"
                      " WHERE rid=%d AND tagid=%d AND tagtype>0",
                      rid, TAG_CLOSED) ){
          @ <span class='timelineLeaf'>Closed-Leaf</span>
................................................................................
        cgi_printf(" id:&nbsp;%d", rid);
      }
    }
    tag_private_status(rid);
    if( xExtra ){
      xExtra(rid);
    }
    /* End timelineDetail and timelineDetailWrapper */

    cgi_printf("</span></span>\n");




    /* Generate the file-change list if requested */
    if( (tmFlags & (TIMELINE_FCHANGES|TIMELINE_FRENAMES))!=0
     && zType[0]=='c' && g.perm.Hyperlink
    ){
      int inUl = 0;
      if( !fchngQueryInit ){
................................................................................
  if( z==0 ) z = db_get("timeline-default-length",0);
  if( z ){
    if( fossil_strcmp(z,"all")==0 ){
      nEntry = 0;
    }else{
      nEntry = atoi(z);
      if( nEntry<=0 ){
        cgi_replace_query_parameter("n","10");
        nEntry = 10;
      }
    }
  }else{
    cgi_replace_query_parameter("n","50");
    nEntry = 50;
  }

  cookie_write_parameter("n","n",0);
  cookie_link_parameter("ss","ss","n");
  cViewStyle = PD("ss","n")[0];
  style_submenu_multichoice("ss", 4, azViewStyles, 0);
  

  /* To view the timeline, must have permission to read project data.







|










|
|

|

|
>
>







 







<
|

|







 







>
>
>
|
<
>







 







<
|

|



<
<
|

<
<
<
|
<







 







|
>
|
>
>
>







 







|




|


>







250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
...
434
435
436
437
438
439
440

441
442
443
444
445
446
447
448
449
450
...
463
464
465
466
467
468
469
470
471
472
473

474
475
476
477
478
479
480
481
...
505
506
507
508
509
510
511

512
513
514
515
516
517


518
519



520

521
522
523
524
525
526
527
...
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
....
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
  int fchngQueryInit = 0;     /* True if fchngQuery is initialized */
  Stmt fchngQuery;            /* Query for file changes on check-ins */
  static Stmt qbranch;
  int pendingEndTr = 0;       /* True if a </td></tr> is needed */
  int vid = 0;                /* Current checkout version */
  int dateFormat = 0;         /* 0: HH:MM (default) */
  int bCommentGitStyle = 0;   /* Only show comments through first blank line */
  const char *zStyle;         /* Sub-name for classes for the style */
  const char *zDateFmt;
  int iTableId = timeline_tableid();

  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_DETAILED ){
    zStyle = "Detailed";
  }else{
    zStyle = "Normal";
  }
  zDateFmt = P("datefmt");
  if( zDateFmt ) dateFormat = atoi(zDateFmt);
  if( tmFlags & TIMELINE_GRAPH ){
    pGraph = graph_init();
  }
  db_static_prepare(&qbranch,
................................................................................
      gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr,
                           zUuid, isLeaf);
      db_reset(&qbranch);
      @ <div id="m%d(gidx)" class="tl-nodemark"></div>
    }
    @</td>
    if( zBgClr && zBgClr[0] && rid!=selectedRid ){

      @ <td class="timeline%s(zStyle)Cell" style="background-color: %h(zBgClr);">
    }else{
      @ <td class="timeline%s(zStyle)Cell">
    }
    if( pGraph && zType[0]!='c' ){
      @ &bull;
    }
    if( modPending ){
      @ <span class="modpending">(Awaiting Moderator Approval)</span>
    }
................................................................................
    if( zType[0]!='c' ){
      /* Comments for anything other than a check-in are generated by
      ** "fossil rebuild" and expect to be rendered as text/x-fossil-wiki */
      @ <span class='timelineComment' onclick='toggleDetail(%d(rid))'>
      wiki_convert(&comment, 0, WIKI_INLINE);
      @ </span>
    }else{
      if( tmFlags & TIMELINE_COMPACT ){
        @ <span class='timelineComment' onclick='toggleDetail(%d(rid))'>
      }else{
        @ <span class='timelineComment'>

      }
      if( bCommentGitStyle ){
        /* Truncate comment at first blank line */
        int ii, jj;
        int n = blob_size(&comment);
        char *z = blob_str(&comment);
        for(ii=0; ii<n; ii++){
          if( z[ii]=='\n' ){
................................................................................
    */
    if( drawDetailEllipsis ){
      @ <span class='timelineEllipsis anticlutter' id='ellipsis-%d(rid)' \
      @  onclick='toggleDetail(%d(rid))'>...</span>
    }
    if( tmFlags & TIMELINE_COLUMNAR ){
      if( zBgClr && zBgClr[0] && rid!=selectedRid ){

        @ <td class="timelineDetailCell" style="background-color: %h(zBgClr);">
      }else{
        @ <td class="timelineDetailCell">
      }
    }
    if( tmFlags & TIMELINE_COMPACT ){


      cgi_printf("<span class='clutter' id='detail-%d'>",rid);
    }



    cgi_printf("<span class='timeline%sDetail'>", zStyle);


    if( zType[0]=='c' ){
      if( isLeaf ){
        if( db_exists("SELECT 1 FROM tagxref"
                      " WHERE rid=%d AND tagid=%d AND tagtype>0",
                      rid, TAG_CLOSED) ){
          @ <span class='timelineLeaf'>Closed-Leaf</span>
................................................................................
        cgi_printf(" id:&nbsp;%d", rid);
      }
    }
    tag_private_status(rid);
    if( xExtra ){
      xExtra(rid);
    }
    /* End timelineDetail */
    if( tmFlags & TIMELINE_COMPACT ){
      @ </span></span>
    }else{
      @ </span>
    }

    /* Generate the file-change list if requested */
    if( (tmFlags & (TIMELINE_FCHANGES|TIMELINE_FRENAMES))!=0
     && zType[0]=='c' && g.perm.Hyperlink
    ){
      int inUl = 0;
      if( !fchngQueryInit ){
................................................................................
  if( z==0 ) z = db_get("timeline-default-length",0);
  if( z ){
    if( fossil_strcmp(z,"all")==0 ){
      nEntry = 0;
    }else{
      nEntry = atoi(z);
      if( nEntry<=0 ){
        z = "10";
        nEntry = 10;
      }
    }
  }else{
    z = "50";
    nEntry = 50;
  }
  cgi_replace_query_parameter("n",z);
  cookie_write_parameter("n","n",0);
  cookie_link_parameter("ss","ss","n");
  cViewStyle = PD("ss","n")[0];
  style_submenu_multichoice("ss", 4, azViewStyles, 0);
  

  /* To view the timeline, must have permission to read project data.