Fossil

Changes On Branch wiki-history
Login

Changes On Branch wiki-history

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

Changes In Branch wiki-history Excluding Merge-Ins

This is equivalent to a diff from 8ec00b975b to 9ff7d9e5e3

2021-03-23
14:50
Implement selection of two arbitrary versions of a wiki for comparison (radio-button selects a baseline, anchor sign clears this selection). Also let several sequential edits by the same user be "recycled" into a single row. Effectively this backouts [cef8425cf4a482a3]. See also a [forum:4a67bd1c5d354e75|forum thread] ... (check-in: 6ebf5c7c9f user: george tags: trunk)
13:31
Merge changes from trunk ... (Closed-Leaf check-in: 9ff7d9e5e3 user: george tags: wiki-history)
2021-03-22
12:43
Update to SQLite 3.35.3 preview for testing. ... (check-in: 8ec00b975b user: drh tags: trunk)
03:03
Ported /chat from windows.fetch() to fossil.fetch() for XHR calls, as discussed in [forum:/forumpost/04b37ca5a5 | forum post 04b37ca5a5]. ... (check-in: e9ed315866 user: stephan tags: trunk)
2021-03-13
22:15
Avoid segfault while serving [/help?cmd=/wdiff|/wdiff] page with empty "pid" parameter in a query string. Segfault occurs due to dereferencing of a NULL pointer in pW2, which happens because both name_to_typed_rid("","w") and manifest_get(0,...) return 0. ... (check-in: 7b81aac17a user: george tags: wiki-history)

Added src/fossil.page.whistory.js.



































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
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
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/* This script adds interactivity for wiki-history webpages.
 *
 * The main code is within the 'on-click' handler of the "diff" links.
 * Instead of standard redirection it fills-in two hidden inputs with
 * the appropriate values and submits the corresponding form.
 * A special care should be taken if some intermediate edits are hidden.
 *
 * For the sake of compatibility with ascetic browsers the code tries
 * to avoid modern API and ECMAScript constructs. This makes it less
 * readable and may be reconsidered in the future.
*/
window.addEventListener( 'load', function() {

document.getElementById("wh-form").method = "GET";

var wh_id  = document.getElementById("wh-id" );
var wh_pid = document.getElementById("wh-pid");
var wh_cleaner = document.getElementById("wh-cleaner");
var wh_collapser = document.getElementById("wh-collapser");

var wh_radios   = [];  // user-visible controls for baseline selection
var wh_hidden   =  0;  // current number of hidden (collapsed) rows
var wh_selected = -1;  // index of the currently selected radio-button

var wh_onRadio = function( event ){

  var indx = event.target.indx;
  if( wh_selected == indx ){

    wh_selected  = -1;
    event.target.checked = false;
  }
  else wh_selected = indx;
}
var wh_onDifflink = function( event ){

  event.preventDefault();
  var indx = event.target.indx;
  wh_id.value = wh_radios[indx].value;

  if( wh_hidden > 0 ){

    var p = indx + 1;
    if( wh_selected >= 0 ){

       var tr = wh_radios[wh_selected].parentElement.parentElement;
       if( ! tr.hidden )
          p = wh_selected;
    }
    while( p < wh_radios.length ){

      if( ! wh_radios[p].parentElement.parentElement.hidden )
	     break;
      p++;
    }
    if( p < wh_radios.length ){

       wh_pid.value = wh_radios[p].value;
       wh_pid.checked = true;
    }
    else {  // just render the wiki for the case of the first major edit

      var path = document.location.pathname.split("/");
      path.pop();
      var newpath = path.join("/") + "/info/" + wh_radios[indx].value;
      document.location = document.location.origin + newpath;
      return;
    }
  }
  else if( wh_selected >= 0 ) {

     wh_pid.value = wh_radios[wh_selected].value;
     wh_pid.checked = true;
  }
  else wh_pid.checked = false;

  document.getElementById("wh-form").submit();
}
var wh_onCleaner = function() {

   if( wh_selected >= 0 ) {

      wh_radios[wh_selected].checked = false;
      wh_selected = -1;
   }
}
var wh_onCollapser = function( event ){

  var collapsing = ( wh_hidden == 0 );
  for( var k = 0; k < wh_radios.length; k++ ){

    var radio = wh_radios[k];
    var tr = radio.parentElement.parentElement;
    if( tr.className == "wh-intermediate" ){

	  if( tr.hidden = ! tr.hidden )
	    wh_hidden++;
	  else
	    wh_hidden--;

    } else if( radio.iterspan )
               radio.iterspan.hidden = ! collapsing;
  }
  if( wh_hidden > 0 ) {

    wh_collapser.title="Show intermediate edits";
    wh_collapser.innerHTML = "&emsp;&#9851; " + wh_hidden;
  }
  else {

    wh_collapser.title="Hide intermediate edits";
    wh_collapser.innerHTML = "&emsp;&#9842;"
  }
}

var inputs = document.getElementsByTagName("input");
for( var k = 0, indx = 0; k < inputs.length; k++ ) {

   var r = inputs[k];
   if( r.type == "radio" && r.name == "baseline" ) {

      wh_radios.push( r );
	  r.indx = indx++;
      r.addEventListener( "click", wh_onRadio );
      r.disabled = false;
      var td = r.parentElement.nextElementSibling;
      r.iterspan = td.getElementsByTagName("span")[0];
   }
}
for( var edits = 0, k = wh_radios.length - 1; k >= 0; k-- ) {

   var td = wh_radios[k].parentElement.nextElementSibling;
   if( td.parentElement.className == "wh-intermediate" )

      edits++;

   else if( edits > 0 ){

      var span = td.getElementsByTagName("span")[0];
      span.innerHTML = "&ensp;&#9842;" + edits;
      wh_radios[k].iterspan = span;
      edits = 0;
      //   also:  &#8746; (union)   &#931; (sigma)   &#215; (times)
   }
}
var links = document.getElementsByTagName("a");
for( var i = 0, indx = 0; i < links.length; i++ ) {

   var l = links[i];
   if( l.className == "wh-difflink" ){

      l.indx = indx++;
      l.addEventListener( "click", wh_onDifflink );
   }
}
wh_cleaner.addEventListener( "click", wh_onCleaner );
wh_collapser.addEventListener( "click", wh_onCollapser );
wh_collapser.title="Hide intermediate edits";
wh_collapser.hidden = false;

}); // window.addEventListener( 'load' ...

Changes to src/main.mk.

227
228
229
230
231
232
233

234
235
236
237
238
239
240
  $(SRCDIR)/fossil.dom.js \
  $(SRCDIR)/fossil.fetch.js \
  $(SRCDIR)/fossil.info-diff.js \
  $(SRCDIR)/fossil.numbered-lines.js \
  $(SRCDIR)/fossil.page.fileedit.js \
  $(SRCDIR)/fossil.page.forumpost.js \
  $(SRCDIR)/fossil.page.pikchrshow.js \

  $(SRCDIR)/fossil.page.wikiedit.js \
  $(SRCDIR)/fossil.pikchr.js \
  $(SRCDIR)/fossil.popupwidget.js \
  $(SRCDIR)/fossil.storage.js \
  $(SRCDIR)/fossil.tabs.js \
  $(SRCDIR)/fossil.wikiedit-wysiwyg.js \
  $(SRCDIR)/graph.js \







>







227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
  $(SRCDIR)/fossil.dom.js \
  $(SRCDIR)/fossil.fetch.js \
  $(SRCDIR)/fossil.info-diff.js \
  $(SRCDIR)/fossil.numbered-lines.js \
  $(SRCDIR)/fossil.page.fileedit.js \
  $(SRCDIR)/fossil.page.forumpost.js \
  $(SRCDIR)/fossil.page.pikchrshow.js \
  $(SRCDIR)/fossil.page.whistory.js \
  $(SRCDIR)/fossil.page.wikiedit.js \
  $(SRCDIR)/fossil.pikchr.js \
  $(SRCDIR)/fossil.popupwidget.js \
  $(SRCDIR)/fossil.storage.js \
  $(SRCDIR)/fossil.tabs.js \
  $(SRCDIR)/fossil.wikiedit-wysiwyg.js \
  $(SRCDIR)/graph.js \

Changes to src/wiki.c.

1577
1578
1579
1580
1581
1582
1583

1584
1585
1586
1587
1588
1589
1590
1591
1592
1593


1594

1595
1596

1597
1598
1599

1600
1601
1602























1603


1604
1605












1606










1607
1608

1609
1610
1611
1612
1613
1614
1615
** Additional parameters:
**
**     showid          Show RID values
**
** Show the complete change history for a single wiki page.
*/
void whistory_page(void){

  const char *zPageName;
  Blob sql;
  Stmt q;
  login_check_credentials();
  if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
  zPageName = PD("name","");
  style_set_current_feature("wiki");
  style_header("History Of %s", zPageName);
  blob_init(&sql, 0, 0);
  blob_append(&sql, timeline_query_for_www(), -1);


  blob_append_sql(&sql,

     "AND event.objid IN ("
     " SELECT tagxref.srcid"

     " FROM tagxref, tag"
     " WHERE tagxref.tagid=tag.tagid"
     " AND tag.tagname='wiki-%q')"

     " ORDER BY mtime DESC",
     zPageName
  );























  db_prepare(&q, "%s", blob_sql_text(&sql));


  www_print_timeline(&q,
    TIMELINE_DISJOINT|TIMELINE_GRAPH|TIMELINE_REFS,












    0, 0, 0, 0, 0, 0);










  db_finalize(&q);
  blob_reset(&sql);

  style_finish_page();
}

/*
** WEBPAGE: wdiff
**
** Show the changes to a wiki page.







>

|
|





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

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

|
>







1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599

1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634

1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
** Additional parameters:
**
**     showid          Show RID values
**
** Show the complete change history for a single wiki page.
*/
void whistory_page(void){
  Stmt q;
  const char *zPageName;
  double rNow;
  int showRid;
  login_check_credentials();
  if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
  zPageName = PD("name","");
  style_set_current_feature("wiki");
  style_header("History Of %s", zPageName);
  showRid = P("showid")!=0;
  db_prepare(&q,
    "SELECT"
    "  event.mtime,"
    "  blob.uuid,"
    "  coalesce(event.euser,event.user),"
    "  event.objid,"

    "  datetime(event.mtime)"
    " FROM event, blob, tag, tagxref"
    " WHERE event.type='w' AND blob.rid=event.objid"
    "   AND tag.tagname='wiki-%q'"
    "   AND tagxref.tagid=tag.tagid AND tagxref.srcid=event.objid"
    " ORDER BY event.mtime DESC",
    zPageName
  );
  @ <h2>History of <a href="%R/wiki?name=%T(zPageName)">%h(zPageName)</a></h2>
  form_begin( "id='wh-form'", "%R/wdiff" );
  @   <input id="wh-pid" name="pid" type="radio" hidden />
  @   <input id="wh-id"  name="id"  type="hidden" />
  @ </form>
  @ <style> .wh-clickable { cursor: pointer; } </style>
  @ <div class="brlist">
  @ <table>
  @ <thead><tr>
  @ <th>Age</th>
  @ <th>Hash</th>
  @ <th><span title="Baseline from which diffs are computed (click to unset)"
  @      id="wh-cleaner" class="wh-clickable">&#9875;</span></th>
  @ <th>User<span hidden class="wh-clickable"
  @                   id="wh-collapser">&emsp;&#9842;</span></th>
  if( showRid ){
    @ <th>RID</th>
  }
  @ <th>&nbsp;</th>
  @ </tr></thead><tbody>
  rNow = db_double(0.0, "SELECT julianday('now')");
  char zAuthor[64]; memset( zAuthor, 0, sizeof(zAuthor) );
  while( db_step(&q)==SQLITE_ROW ){
    double rMtime = db_column_double(&q, 0);
    const char *zUuid = db_column_text(&q, 1);
    const char *zUser = db_column_text(&q, 2);
    int wrid = db_column_int(&q, 3);

    const char *zWhen = db_column_text(&q, 4);
    /* sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0); */
    char *zAge = human_readable_age(rNow - rMtime);
    if( strncmp( zAuthor, zUser, sizeof(zAuthor) - 1 ) == 0 ) {
      @ <tr class="wh-intermediate" title="%s(zWhen)">
    }
    else {
      strncpy( zAuthor, zUser, sizeof(zAuthor) - 1 );
      @ <tr class="wh-major" title="%s(zWhen)">
    }
    /* @ <td data-sortkey="%016llx(iMtime)">%s(zAge)</td> */
    @ <td>%s(zAge)</td>
    fossil_free(zAge);
    @ <td>%z(href("%R/info/%s",zUuid))%S(zUuid)</a></td>
    @ <td><input disabled type="radio" name="baseline" value="%S(zUuid)"/></td>
    @ <td>%h(zUser)<span class="wh-iterations" hidden /></td>
    if( showRid ){
      @ <td>%z(href("%R/artifact/%S",zUuid))%d(wrid)</a></td>
    }
    @ <td>%z(chref("wh-difflink","%R/wdiff?id=%S",zUuid))diff</a></td>
    @ </tr>
  }
  @ </tbody></table></div>
  db_finalize(&q);
  builtin_request_js("fossil.page.whistory.js");
  /* style_table_sorter(); */
  style_finish_page();
}

/*
** WEBPAGE: wdiff
**
** Show the changes to a wiki page.
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
    rid1 = name_to_typed_rid(zId, "w");
  }
  zId = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid1);
  pW1 = manifest_get(rid1, CFTYPE_WIKI, 0);
  if( pW1==0 ) fossil_redirect_home();
  blob_init(&w1, pW1->zWiki, -1);
  zPid = P("pid");
  if( zPid==0 && pW1->nParent ){
    zPid = pW1->azParent[0];
  }
  if( zPid ){
    char *zDate;
    rid2 = name_to_typed_rid(zPid, "w");
    pW2 = manifest_get(rid2, CFTYPE_WIKI, 0);
    blob_init(&w2, pW2->zWiki, -1);
    @ <h2>Changes to \
    @ "%z(href("%R/whistory?name=%s",pW1->zWikiTitle))%h(pW1->zWikiTitle)</a>" \
    zDate = db_text(0, "SELECT datetime(%.16g)",pW2->rDate);







|


|







1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
    rid1 = name_to_typed_rid(zId, "w");
  }
  zId = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid1);
  pW1 = manifest_get(rid1, CFTYPE_WIKI, 0);
  if( pW1==0 ) fossil_redirect_home();
  blob_init(&w1, pW1->zWiki, -1);
  zPid = P("pid");
  if( ( zPid==0 || zPid[0] == 0 ) && pW1->nParent ){
    zPid = pW1->azParent[0];
  }
  if( zPid && zPid[0] != 0 ){
    char *zDate;
    rid2 = name_to_typed_rid(zPid, "w");
    pW2 = manifest_get(rid2, CFTYPE_WIKI, 0);
    blob_init(&w2, pW2->zWiki, -1);
    @ <h2>Changes to \
    @ "%z(href("%R/whistory?name=%s",pW1->zWikiTitle))%h(pW1->zWikiTitle)</a>" \
    zDate = db_text(0, "SELECT datetime(%.16g)",pW2->rDate);