Fossil

Changes On Branch wcontent-subsets
Login

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

Changes In Branch wcontent-subsets Excluding Merge-Ins

This is equivalent to a diff from 96bf76a4b1 to 76844c35fc

2022-05-14
20:52
Handle a possible existence of the additional checkbox introduced in [29a24941ed9bf4]. ... (Leaf check-in: 76844c35fc user: george tags: wcontent-subsets)
2022-02-10
15:50
Update the built-in SQLite to the latest 3.38.0 beta that includes the performance enhancements on the datetime() function. ... (check-in: 740d655e55 user: drh tags: trunk)
00:29
Merge from trunk ... (Leaf check-in: 2b5f9b211c user: george tags: search-terms-highlighting)
00:22
Merge from trunk ... (Leaf check-in: a961a67ba7 user: george tags: rptview-submenu-paralink)
00:17
Merge from trunk ... (check-in: 88ff4e5dea user: george tags: wcontent-subsets)
00:12
Merge from trunk ... (Leaf check-in: 9b76469b38 user: george tags: th1-doc-vars)
00:05
Remove unused local variable from cgi_parse_POST_JSON() to fix a compiler warning. ... (check-in: 96bf76a4b1 user: george tags: trunk)
2022-02-09
20:23
Cherrypicked [92221aaa192e82] and [7283ae6e120c10] on behalf of George. ... (check-in: f902814db6 user: stephan tags: trunk)

Changes to src/db.c.
4398
4399
4400
4401
4402
4403
4404








































4405
4406
4407
4408
4409
4410
4411
/*
** SETTING: large-file-size     width=10 default=200000000
** Fossil considers any file whose size is greater than this value
** to be a "large file".  Fossil might issue warnings if you try to
** "add" or "commit" a "large file".  Set this value to 0 or less 
** to disable all such warnings.
*/









































/*
** Look up a control setting by its name.  Return a pointer to the Setting
** object, or NULL if there is no such setting.
**
** If allowPrefix is true, then the Setting returned is the first one for
** which zName is a prefix of the Setting name.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
/*
** SETTING: large-file-size     width=10 default=200000000
** Fossil considers any file whose size is greater than this value
** to be a "large file".  Fossil might issue warnings if you try to
** "add" or "commit" a "large file".  Set this value to 0 or less 
** to disable all such warnings.
*/
/*
** SETTING: wiki-classes     width=40 block-text
** Defines classes for wiki pages that are recognized by the list
** of available wiki pages (displayed by /wcontent web page).
**
** Each line defines a single rule for a class using a triplet:
** Visibility   Label   Pattern
**
** Visibility is one of the following letters:
**
**     s  show on load, may be toggled afterwards
**     h  hide on load, may be toggled afterwards
**     d  hide permanently, checkbox disabled
**     x  exclude completely, no control in the submenu
**
** Label is a spaces-free name of the class shown in the submenu.
** This very same string is used as a value for HTML's class=""
** atributes on the corresponding rows (thus beware of mangling).
**
** Pattern is a GLOB pattern against which wiki page names are
** matched to distinguish a class. Case-sensitive pattern matching
** is performed if the Visibility is specified by a lowercase letter,
** otherwise pattern matching is case-insensitive (in which case
** the syntax of SQLite's LIKE operator applies).
** Pattern that consists of just a single * is a special case for
** catching all wiki pages that do not fall into any other class
** (this fallback does not depend on the case of the Visibility letter).
**
** If several consequtive lines share the same Label then this defines
** a single class that spans accross several patterns. In that case
** all Visibilities must also be equal (modulus upper/lower cases).
**
** Patterns are matched in the order of their appearance in the list.
** If a repository manages thousands of wiki pages and the /wcontent
** page is requested very frequently then server's CPU load may become
** a concern. In that case an administrator is advised to rearrange
** classes in the list in such a way that more patterns are matched
** earlier. In all cases it is advised to keep a special "catch-all"
** class in the bottom of the list.
*/

/*
** Look up a control setting by its name.  Return a pointer to the Setting
** object, or NULL if there is no such setting.
**
** If allowPrefix is true, then the Setting returned is the first one for
** which zName is a prefix of the Setting name.
Added src/fossil.page.wcontent.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
/* This script implements interactivity of checkboxes that
 * toggle visibilitiy of user-defined classes of wikipage.
 *
 * 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() {

var tbody = document.querySelector(
            "body.wiki div.content table.sortable > tbody");
var prc = document.getElementById("page-reload-canary");
if( !tbody || !prc ) return;

var reloading = prc.checked;
// console.log("Reloading:",reloading);

var onChange = function(event){
  var display = event.target.checked ? "" : "none";
  var rows    = event.target.matchingRows;
  for(var i=0; i<rows.length; i++)
    rows[i].style.display = display;
}
var checkboxes = [];
document.querySelectorAll(
  "body.wiki .submenu > label.submenuckbox > input")
  .forEach(function(cbx){ checkboxes.push(cbx); });

for(var j=0; j<checkboxes.length; j++){
  var cbx = checkboxes[j];
  // see also https://caniuse.com/mdn-css_selectors_attribute
  var attr = cbx.getAttribute("data-ctrl");
  if( 'undefined' == typeof attr || !attr ) continue;
  var ctrl = attr.toString();
  var cname = cbx.parentElement.innerText.toString();
  var hidden = ( ctrl == 'h' || ctrl == 'd' );
  if( reloading )
    hidden = !cbx.checked;
  else
    cbx.checked = !hidden;
  cbx.matchingRows = [];
  tbody.querySelectorAll("tr."+cname).forEach(function (tr){
    tr.style.display = ( hidden ? "none" : "" );
    cbx.matchingRows.push(tr);
  });
  cbx.addEventListener("change", onChange ); 
  // console.log( cbx.matchingRows.length, cname, ctrl );
}

prc.checked = true;
}); // window.addEventListener( 'load' ...
Changes to src/main.mk.
229
230
231
232
233
234
235

236
237
238
239
240
241
242
  $(SRCDIR)/fossil.fetch.js \
  $(SRCDIR)/fossil.numbered-lines.js \
  $(SRCDIR)/fossil.page.brlist.js \
  $(SRCDIR)/fossil.page.chat.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 \







>







229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
  $(SRCDIR)/fossil.fetch.js \
  $(SRCDIR)/fossil.numbered-lines.js \
  $(SRCDIR)/fossil.page.brlist.js \
  $(SRCDIR)/fossil.page.chat.js \
  $(SRCDIR)/fossil.page.fileedit.js \
  $(SRCDIR)/fossil.page.forumpost.js \
  $(SRCDIR)/fossil.page.pikchrshow.js \
  $(SRCDIR)/fossil.page.wcontent.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 \
Changes to src/wiki.c.
19
20
21
22
23
24
25


















26
27
28
29
30
31
32
** This file contains code to do formatting of wiki text.
*/
#include "config.h"
#include <assert.h>
#include <ctype.h>
#include "wiki.h"



















/*
** Return true if the input string is a well-formed wiki page name.
**
** Well-formed wiki page names do not begin or end with whitespace,
** and do not contain tabs or other control characters and do not
** contain more than a single space character in a row.  Well-formed
** names must be between 1 and 100 characters in length, inclusive.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
** This file contains code to do formatting of wiki text.
*/
#include "config.h"
#include <assert.h>
#include <ctype.h>
#include "wiki.h"

#if INTERFACE

/*
** WikiClass struct holds information for matching a wiki page name.
** It is constructed by load_wiki_classes() function and represents a
** single well-formed line obtained from the 'wiki-classes' setting.
*/
struct WikiClass {
  const char * zPattern; /* pattern to match against                    */
  int   isCaseIns;       /* syntax flag: 0 for GLOB, 1 for LIKE         */
  short isAltPat;        /* indicates an additional pattern for a class */

  const char * zVisblty; /* visibility flag, one of: "s" "h" "d" "x"    */
  const char * zLabel;   /* user-visible class name, same in HTML attrs */
  const char * zParam;   /* checkbox attr, like in <input name="..." /> */
};
#endif

/*
** Return true if the input string is a well-formed wiki page name.
**
** Well-formed wiki page names do not begin or end with whitespace,
** and do not contain tabs or other control characters and do not
** contain more than a single space character in a row.  Well-formed
** names must be between 1 and 100 characters in length, inclusive.
437
438
439
440
441
442
443




















































































































444
445
446
447
448
449
450
    case WIKITYPE_CHECKIN: return "checkin";
    case WIKITYPE_BRANCH: return "branch";
    case WIKITYPE_TAG: return "tag";
    case WIKITYPE_NORMAL:
    default: return "normal";
  }
}





















































































































/*
** Add an appropriate style_header() for either the /wiki or /wikiedit page
** for zPageName.  zExtra is an empty string for /wiki but has the text
** "Edit: " for /wikiedit.
**
** If the page is /wiki and the page is one of the special times (check-in,







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
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
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
    case WIKITYPE_CHECKIN: return "checkin";
    case WIKITYPE_BRANCH: return "branch";
    case WIKITYPE_TAG: return "tag";
    case WIKITYPE_NORMAL:
    default: return "normal";
  }
}

/*
** load_wiki_classes() loads and parses the value of the 'wiki-classes'
** setting. Retrurns either NULL or a dynamically allocated array of
** WikiClasses (thus fossil_free() for the returned value is advised).
*/
WikiClass* load_wiki_classes(
  int *nWC,  /* number of well-formed elements in the returned array    */
  Blob *wcs  /* holds a buffer for strings in the returned WikiClass'es */
){

  static const char *zPN[] = { /* no malloc() for the common cases */
     "wc0", "wc1", "wc2", "wc3", "wc4", "wc5", "wc6", "wc7",
     "wc8", "wc9","wc10","wc11","wc12","wc13","wc14","wc15",
    "wc16","wc17","wc18","wc19","wc20","wc21","wc22","wc23"
  };
  WikiClass* aWC = 0;
  int n = 0;
  char *zWCS = db_get("wiki-classes",0);
  if( zWCS && strlen(zWCS) >= 5 ){
    Blob line  = empty_blob;
    int nAlloc = 0;
    blob_set_dynamic(wcs,zWCS);
    while( blob_line(wcs,&line) > 0 ){
      Blob vis = empty_blob;
      Blob lbl = empty_blob;
      Blob pat = empty_blob;
      WikiClass * wc;
      const char *z;
      int cins = 0;
      char v;
      if( blob_token(&line,&vis) != 1 ){
        continue;
      }
      v = vis.aData[0];
      switch( v ){
        case 'D':
        case 'H':
        case 'S':
        case 'X':
          cins = 1;
          vis.aData[0] = (char)tolower(v);
        case 'd':
        case 'h':
        case 's':
        case 'x':
          break;
        default:
          v = 0;
      }
      if( v == 0 ) continue;
      if( blob_token(&line,&lbl) <= 0 ){
        continue;
      }
      blob_tail(&line,&pat);
      /* blob_to_lf_only(&pre); <-- this is redundant, isn't it ? */
      blob_trim(&pat);
      z = blob_terminate(&pat);
      while(fossil_isspace(z[0])) z++;
      if( z[0] == 0 ){
        continue;
      }
      if( n >= nAlloc ){
        nAlloc += count(zPN);
        aWC = (WikiClass*)( aWC ?
             fossil_realloc(aWC,sizeof(WikiClass)*nAlloc)  :
             fossil_malloc_zero(sizeof(WikiClass)*nAlloc) );
      }
      wc = aWC + n;
      wc->zPattern  = z;
      wc->isCaseIns = cins;
      wc->zVisblty  = blob_terminate(&vis);
      wc->zLabel    = blob_terminate(&lbl);
      wc->zParam    = ( n < count(zPN) ? zPN[n] : mprintf("wc%d",n) );
      if( n > 0 && strcmp( wc->zLabel, wc[-1].zLabel ) == 0 ){
        if( wc->zVisblty[0] != wc[-1].zVisblty[0] ||
            strcmp( wc->zPattern, wc[-1].zPattern ) == 0 ){
          continue;
        }
        wc->isAltPat = 1;
      }else{
        wc->isAltPat = 0;
      }
      n++;
    }
  }
  if( nWC ) *nWC = n;
  return aWC;
}
/*
** Find and return a WikiClass that matches a name of a wiki page.
** Returns 0 if "fallback" pattern was not provisioned.
*/
const WikiClass* resolve_wiki_class(
  const char *zName,    /* name of a wiki page that should be classified */
  const WikiClass *aWC, /* pointer to the array of WikiClass'es          */
  int nWC               /* number of elements in the above array         */
){
  const WikiClass* fallback = 0;
  if( aWC && zName ){
    int i;
    for( i=0; i<nWC; i++ ){
      const WikiClass* wc = aWC + i;
      if( wc->zPattern[0] == '*' && wc->zPattern[1] == 0 ){
        if( !fallback ) fallback = wc;
      }else if( wc->isCaseIns ){
        if( sqlite3_strlike( wc->zPattern, zName, 0 ) == 0 )
          return wc;
      }else{
        if( sqlite3_strglob( wc->zPattern, zName ) == 0 )
          return wc;
      }
    }
  }
  return fallback;
}

/*
** Add an appropriate style_header() for either the /wiki or /wikiedit page
** for zPageName.  zExtra is an empty string for /wiki but has the text
** "Edit: " for /wikiedit.
**
** If the page is /wiki and the page is one of the special times (check-in,
1915
1916
1917
1918
1919
1920
1921



1922
1923
1924
1925
1926
1927
1928
1929
1930
1931







1932
1933

1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953



1954

1955
1956
1957
1958
1959

1960
1961





1962
1963
1964





1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979

1980
1981


1982
1983
1984
1985
1986
1987
1988
** List all available wiki pages with date created and last modified.
*/
void wcontent_page(void){
  Stmt q;
  double rNow;
  int showAll = P("all")!=0;
  int showRid = P("showid")!=0;




  login_check_credentials();
  if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
  style_set_current_feature("wiki");
  style_header("Available Wiki Pages");
  if( showAll ){
    style_submenu_element("Active", "%R/wcontent");
  }else{
    style_submenu_element("All", "%R/wcontent?all=1");
  }







  wiki_standard_submenu(W_ALL_BUT(W_LIST));
  db_prepare(&q, listAllWikiPages/*works-like:""*/);

  @ <div class="brlist">
  @ <table class='sortable' data-column-types='tKN' data-init-sort='1'>
  @ <thead><tr>
  @ <th>Name</th>
  @ <th>Last Change</th>
  @ <th>Versions</th>
  if( showRid ){
    @ <th>RID</th>
  }
  @ </tr></thead><tbody>
  rNow = db_double(0.0, "SELECT julianday('now')");
  while( db_step(&q)==SQLITE_ROW ){
    const char *zWName = db_column_text(&q, 0);
    const char *zSort = db_column_text(&q, 1);
    int wrid = db_column_int(&q, 2);
    double rWmtime = db_column_double(&q, 3);
    sqlite3_int64 iMtime = (sqlite3_int64)(rWmtime*86400.0);
    char *zAge;
    int wcnt = db_column_int(&q, 4);
    char *zWDisplayName;





    if( sqlite3_strglob("checkin/*", zWName)==0 ){
      zWDisplayName = mprintf("%.25s...", zWName);
    }else{
      zWDisplayName = mprintf("%s", zWName);
    }

    if( wrid==0 ){
      if( !showAll ) continue;





      @ <tr><td data-sortkey="%h(zSort)">\
      @ %z(href("%R/whistory?name=%T",zWName))<s>%h(zWDisplayName)</s></a></td>
    }else{





      @ <tr><td data-sortkey="%h(zSort)">\
      @ %z(href("%R/wiki?name=%T&p",zWName))%h(zWDisplayName)</a></td>
    }
    zAge = human_readable_age(rNow - rWmtime);
    @ <td data-sortkey="%016llx(iMtime)">%s(zAge)</td>
    fossil_free(zAge);
    @ <td>%z(href("%R/whistory?name=%T",zWName))%d(wcnt)</a></td>
    if( showRid ){
      @ <td>%d(wrid)</td>
    }
    @ </tr>
    fossil_free(zWDisplayName);
  }
  @ </tbody></table></div>
  db_finalize(&q);

  style_table_sorter();
  style_finish_page();


}

/*
** WEBPAGE: wfind
**
** URL: /wfind?title=TITLE
** List all wiki pages whose titles contain the search text







>
>
>










>
>
>
>
>
>
>


>




















>
>
>
|
>
|


|

>


>
>
>
>
>
|


>
>
>
>
>
|














>


>
>







2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
** List all available wiki pages with date created and last modified.
*/
void wcontent_page(void){
  Stmt q;
  double rNow;
  int showAll = P("all")!=0;
  int showRid = P("showid")!=0;
  Blob wcs = empty_blob;
  int i, nWC = 0;
  WikiClass* aWC;

  login_check_credentials();
  if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
  style_set_current_feature("wiki");
  style_header("Available Wiki Pages");
  if( showAll ){
    style_submenu_element("Active", "%R/wcontent");
  }else{
    style_submenu_element("All", "%R/wcontent?all=1");
  }
  aWC = load_wiki_classes(&nWC,&wcs);
  for( i=0; i<nWC; i++ ){
    const WikiClass * c = aWC + i;
    if( c->isAltPat || c->zVisblty[0] == 'x' ) continue;
    style_submenu_checkbox( c->zParam, c->zLabel,
      c->zVisblty[0]=='d' ? STYLE_DISABLED : STYLE_NORMAL, c->zVisblty);
  }
  wiki_standard_submenu(W_ALL_BUT(W_LIST));
  db_prepare(&q, listAllWikiPages/*works-like:""*/);
  @ <input hidden="hidden" id="page-reload-canary" type="checkbox"/>
  @ <div class="brlist">
  @ <table class='sortable' data-column-types='tKN' data-init-sort='1'>
  @ <thead><tr>
  @ <th>Name</th>
  @ <th>Last Change</th>
  @ <th>Versions</th>
  if( showRid ){
    @ <th>RID</th>
  }
  @ </tr></thead><tbody>
  rNow = db_double(0.0, "SELECT julianday('now')");
  while( db_step(&q)==SQLITE_ROW ){
    const char *zWName = db_column_text(&q, 0);
    const char *zSort = db_column_text(&q, 1);
    int wrid = db_column_int(&q, 2);
    double rWmtime = db_column_double(&q, 3);
    sqlite3_int64 iMtime = (sqlite3_int64)(rWmtime*86400.0);
    char *zAge;
    int wcnt = db_column_int(&q, 4);
    char *zWDisplayName;
    const WikiClass * wc = resolve_wiki_class(zWName,aWC,nWC);
    if( wc && (wc->zVisblty[0] == 'x' || wc->zVisblty[0] == 'd') ){
      continue;
    }

    if( sqlite3_strglob("checkin/*", zWName)==0 ){ /* --?--> strncmp() */
      zWDisplayName = mprintf("%.25s...", zWName);
    }else{
      zWDisplayName = mprintf("%s", zWName); /* --?--> fossil_strdup() */
    }

    if( wrid==0 ){
      if( !showAll ) continue;
      if(wc){
        @ <tr class="%h(wc->zLabel)">
      }else{
        @ <tr>
      }
      @ <td data-sortkey="%h(zSort)">\
      @ %z(href("%R/whistory?name=%T",zWName))<s>%h(zWDisplayName)</s></a></td>
    }else{
      if(wc){
        @ <tr class="%h(wc->zLabel)">
      }else{
        @ <tr>
      }
      @ <td data-sortkey="%h(zSort)">\
      @ %z(href("%R/wiki?name=%T&p",zWName))%h(zWDisplayName)</a></td>
    }
    zAge = human_readable_age(rNow - rWmtime);
    @ <td data-sortkey="%016llx(iMtime)">%s(zAge)</td>
    fossil_free(zAge);
    @ <td>%z(href("%R/whistory?name=%T",zWName))%d(wcnt)</a></td>
    if( showRid ){
      @ <td>%d(wrid)</td>
    }
    @ </tr>
    fossil_free(zWDisplayName);
  }
  @ </tbody></table></div>
  db_finalize(&q);
  builtin_request_js("fossil.page.wcontent.js");
  style_table_sorter();
  style_finish_page();
  if(aWC) fossil_free(aWC);
  blob_reset(&wcs); /* FIXME: it's an analog of fossil_free(), isn't it? */
}

/*
** WEBPAGE: wfind
**
** URL: /wfind?title=TITLE
** List all wiki pages whose titles contain the search text
Changes to www/javascript.md.
593
594
595
596
597
598
599









600
601
602
603
604
605
606
Clicking this hyperlink loads a `/timeline` page that shows
only these selected branches (and the related check-ins).

_Potential Workaround:_ A user can manually construct an appropriate
regular expession and put it into the "Tag Filter" entry of the
`/timeline` page (in its advanced mode).










----

## <a id="future"></a>Future Plans for JavaScript in Fossil

As of mid-2020, the informal provisional plan is to increase Fossil
UI's use of JavaScript considerably compared to its historically minimal
uses. To that end, a framework of Fossil-centric APIs is being developed







>
>
>
>
>
>
>
>
>







593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
Clicking this hyperlink loads a `/timeline` page that shows
only these selected branches (and the related check-ins).

_Potential Workaround:_ A user can manually construct an appropriate
regular expession and put it into the "Tag Filter" entry of the
`/timeline` page (in its advanced mode).

### <a id="wcontent"></a>Wiki content listing

[Since](/timeline?r=wcontent-subsets) version 2.18 it is possible to
add [configurable](/help?cmd=wiki-classes) checkbox controls to the
submenu of [available wiki pages](/wcontent) for the interactive
adjustment of a subset of wiki pages that are shown.
Client-side script is used to toggle visibility of the corresponding
rows according to the state of these checkboxes.

----

## <a id="future"></a>Future Plans for JavaScript in Fossil

As of mid-2020, the informal provisional plan is to increase Fossil
UI's use of JavaScript considerably compared to its historically minimal
uses. To that end, a framework of Fossil-centric APIs is being developed