Fossil

Changes On Branch diff-keyboard-navigation
Login

Changes On Branch diff-keyboard-navigation

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

Changes In Branch diff-keyboard-navigation Excluding Merge-Ins

This is equivalent to a diff from f97a29dd to 75978253

2024-01-25
03:28
Make forum post hyperlinks more visible, with the conventional underline. ... (Closed-Leaf check-in: b9027e76 user: larrybr tags: visible-post-links)
03:00
Remove some vendor-prefixed CSS attributes, as modern browsers emit warnings for those. ... (check-in: a0850d54 user: stephan tags: trunk)
2024-01-23
06:46
Update the built-in zlib to version 1.3.1, released on January 22, 2024. According to check-ins [eea86cee3a] and [511ad59ae3], all files from the doc/ and contrib/ada/ subdirectories are excluded. ... (check-in: ff7fa23b user: florian tags: zlib-update)
2024-01-22
13:40
Sync with trunk. ... (Leaf check-in: 75978253 user: florian tags: diff-keyboard-navigation)
13:39
Sync with trunk. ... (Leaf check-in: f05b04a6 user: florian tags: timeline-keyboard-navigation)
13:37
Hide the timeline graph tooltip in the `pagehide' handler, as Chromium-based browsers (but not Firefox) are deprecating the `unload' handler. ... (check-in: f97a29dd user: florian tags: trunk)
2024-01-21
21:57
Typo fix and EOL whitespace cleanups. No functional changes. ... (check-in: e0576ea9 user: stephan tags: trunk)
2022-10-03
11:15
Check the meta key modifier (⊞|⌘|◆) when processing keyboard events. ... (check-in: 4811d5b2 user: florian tags: diff-keyboard-navigation)

Changes to src/fossil.diff.js.

14
15
16
17
18
19
20






21
22

















































































































23
24
25
26
27
28
29
    if(!sib) return;
    D.append(sib,btn);
    btn.addEventListener('click', function(){
      diffElem.classList.toggle('hidden');
    }, false);
  };
  document.querySelectorAll('table.diff').forEach(addToggle);






});


















































































































window.fossil.onPageLoad(function(){
  const F = window.fossil, D = F.dom;
  const Diff = F.diff = {
    e:{/*certain cached DOM elements*/},
    config: {
      chunkLoadLines: (
        F.config.diffContextLines * 3







>
>
>
>
>
>


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







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
    if(!sib) return;
    D.append(sib,btn);
    btn.addEventListener('click', function(){
      diffElem.classList.toggle('hidden');
    }, false);
  };
  document.querySelectorAll('table.diff').forEach(addToggle);
  function resetToggles(){
    var cb = document.querySelectorAll(
                        'input[type="checkbox"].diff-toggle:not(:checked)');
    for( var i=0; i<cb.length; i++ ) cb[i].checked = true;
  }
  setTimeout(resetToggles);
});

/*
** Diff keyboard navigation shortcuts:
**
** ### NOTE: The keyboard shortcuts are listed in the /vdiff help screen. ###
**
** Ideas and TODOs:
**
**  o The `timeline-keyboard-navigation' branch removes the unload handler from
**    pages containing timeline snippets, so it's no longer necessary to reset
**    the diff toggles on back/forward navigation in case the mentioned branch
**    is merged with `diff-keyboard-navigation'.
*/
(function(){
  window.addEventListener('load',function(){
    function btnScrollIntoView(e){
      e = e.parentElement;
      var rc = e.getBoundingClientRect();
      var y = 0;
      do{
        y += e.offsetTop;
      }while( e = e.offsetParent );
      window.scrollTo(0,y-6*rc.height);
    }
    document.addEventListener('keydown',function(evt){
      if( evt.target.tagName=='INPUT' || evt.target.tagName=='SELECT' ) return;
      var
        mSHIFT = 1<<13,
        kSHOW = mSHIFT | 73 /* SHIFT+I */,
        kHIDE = 73 /* I */,
        kNEXT = 80 /* P */,
        kPREV = 79 /* O */,
        kUNID = 85 /* U */,
        kSBSD = mSHIFT | 85 /* SHIFT+U */,
        mod = evt.altKey<<15|evt.ctrlKey<<14|evt.shiftKey<<13|evt.metaKey<<12,
        key = ( evt.which || evt.keyCode ) | mod;
      switch( key ){
        case kSHOW:
        case kHIDE:
        case kNEXT:
        case kPREV:
        case kUNID:
        case kSBSD: break;
        default: return;
      }
      evt.preventDefault();
      evt.stopPropagation();
      if( key==kSHOW || key==kHIDE ){
        var btn = document.getElementsByClassName('diff-toggle');
        if( btn.length>0 ){
          var chg = 0;
          for( var i=0; i<btn.length; i++ ){
            if( btn[i].checked && key==kHIDE ){
              btn[i].click();
              chg++;
            }
            else if( !btn[i].checked && key==kSHOW ){
              btn[i].click();
              chg++;
            }
          }
          if( chg>0 ) btnScrollIntoView(btn[0]);
        }
      }
      else if( key==kNEXT || key==kPREV ){
        var btn = document.getElementsByClassName('diff-toggle');
        if( btn.length>1 ){
          var nFolded = 0, n = -2;
          for( var i=0; i<btn.length; i++ ){
            if( !btn[i].checked ) nFolded++;
          }
          if( nFolded==0 ){
            n = ( key==kNEXT ? 0 : btn.length-1 );
            for( var i=0; i<btn.length; i++ ){
              if( n!=i ) btn[i].click();
            }
          }
          else{
            for( var i=0; i<btn.length; i++ ){
              if( btn[i].checked ){
                if( n==-2 ) n = ( key==kNEXT ? i+1 : i-1 );
                if( n!=i ) btn[i].click();
              }
            }
          }
          if( n==-2 ) n = ( key==kNEXT ? 0 : btn.length-1 );
          if( n in btn ){
            if( !btn[n].checked ) btn[n].click();
            btnScrollIntoView(btn[n]);
          }
        }
        else if( btn.length>0 ){
          btn[0].click();
          btnScrollIntoView(btn[0]);
        }
      }
      else if( key==kUNID || key==kSBSD ){
        var
          type = ( key==kUNID ? 'unified' : 'side-by-side' ),
          link = document.querySelector('.smb-'+type+'-diff')
                  || document.querySelector('.sml-'+type+'-diff'),
          href;
        if( link ){
          if( link.dataset.href ) href = link.dataset.href;   // anti-bot
          else href = link.href;
        }
        if( href && href!=location.href.slice(-href.length) ){
          location.href = href;
        }
      }
    }/*,true*/);
  },false);
}());

window.fossil.onPageLoad(function(){
  const F = window.fossil, D = F.dom;
  const Diff = F.diff = {
    e:{/*certain cached DOM elements*/},
    config: {
      chunkLoadLines: (
        F.config.diffContextLines * 3

Changes to src/info.c.

611
612
613
614
615
616
617



618
619
620
621
622
623
624
**
** Display information about a particular check-in.  The exact
** same information is shown on the /info page if the name query
** parameter to /info describes a check-in.
**
** The ARTIFACTID can be a unique prefix for the HASH of the check-in,
** or a tag or branch name that identifies the check-in.



*/
void ci_page(void){
  Stmt q1, q2, q3;
  int rid;
  int isLeaf;
  int diffType;        /* 0: no diff,  1: unified,  2: side-by-side */
  const char *zName;   /* Name of the check-in to be displayed */







>
>
>







611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
**
** Display information about a particular check-in.  The exact
** same information is shown on the /info page if the name query
** parameter to /info describes a check-in.
**
** The ARTIFACTID can be a unique prefix for the HASH of the check-in,
** or a tag or branch name that identifies the check-in.
**
** See the help screen for the /vdiff web page for a list of available
** keyboard shortcuts.
*/
void ci_page(void){
  Stmt q1, q2, q3;
  int rid;
  int isLeaf;
  int diffType;        /* 0: no diff,  1: unified,  2: side-by-side */
  const char *zName;   /* Name of the check-in to be displayed */
898
899
900
901
902
903
904


905
906
907
908


909
910
911
912
913
914
915
916
  DCfg.pRe = pRe;
  zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
  if( diffType!=0 ){
    @ %z(chref("button","%R/%s/%T?diff=0",zPageHide,zName))\
    @ Hide&nbsp;Diffs</a>
  }
  if( diffType!=1 ){


    @ %z(chref("button","%R/%s/%T?diff=1%s",zPage,zName,zW))\
    @ Unified&nbsp;Diffs</a>
  }
  if( diffType!=2 ){


    @ %z(chref("button","%R/%s/%T?diff=2%s",zPage,zName,zW))\
    @ Side-by-Side&nbsp;Diffs</a>
  }
  if( diffType!=0 ){
    if( *zW ){
      @ %z(chref("button","%R/%s/%T",zPage,zName))
      @ Show&nbsp;Whitespace&nbsp;Changes</a>
    }else{







>
>
|



>
>
|







901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
  DCfg.pRe = pRe;
  zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
  if( diffType!=0 ){
    @ %z(chref("button","%R/%s/%T?diff=0",zPageHide,zName))\
    @ Hide&nbsp;Diffs</a>
  }
  if( diffType!=1 ){
    /* Class "smb-unified-diff" required by the fossil.diff.js script. */
    const char *zBtnClass = "button smb-unified-diff";
    @ %z(chref(zBtnClass,"%R/%s/%T?diff=1%s",zPage,zName,zW))\
    @ Unified&nbsp;Diffs</a>
  }
  if( diffType!=2 ){
    /* Class "smb-side-by-side-diff" required by the fossil.diff.js script. */
    const char *zBtnClass = "button smb-side-by-side-diff";
    @ %z(chref(zBtnClass,"%R/%s/%T?diff=2%s",zPage,zName,zW))\
    @ Side-by-Side&nbsp;Diffs</a>
  }
  if( diffType!=0 ){
    if( *zW ){
      @ %z(chref("button","%R/%s/%T",zPage,zName))
      @ Show&nbsp;Whitespace&nbsp;Changes</a>
    }else{
1177
1178
1179
1180
1181
1182
1183












1184
1185
1186
1187
1188
1189
1190
**   dc=N            show N lines of context around each diff
**   w=BOOLEAN       ignore whitespace when computing diffs
**   nohdr           omit the description at the top of the page
**   nc              omit branch coloration from the header graph
**   inv             "Invert".  Exchange the roles of from= and to=
**
** Show all differences between two check-ins.












*/
void vdiff_page(void){
  int ridFrom, ridTo;
  int diffType = 0;        /* 0: none, 1: unified, 2: side-by-side */
  Manifest *pFrom, *pTo;
  ManifestFile *pFileFrom, *pFileTo;
  const char *zBranch;







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







1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
**   dc=N            show N lines of context around each diff
**   w=BOOLEAN       ignore whitespace when computing diffs
**   nohdr           omit the description at the top of the page
**   nc              omit branch coloration from the header graph
**   inv             "Invert".  Exchange the roles of from= and to=
**
** Show all differences between two check-ins.
**
** Keyboard navigation shortcuts:
**
**    I     Show all file changes.
**    i     Hide all file changes.
**    p     Show only next file change.
**    o     Show only previous file change.
**    u     Reload page in Unified Diff mode.
**    U     Reload page in Side-By-Side Diff mode.
**
** The keyboard shortcuts also apply to /vinfo, /ci and /fdiff pages,
** and to /info pages describing check-in information.
*/
void vdiff_page(void){
  int ridFrom, ridTo;
  int diffType = 0;        /* 0: none, 1: unified, 2: side-by-side */
  Manifest *pFrom, *pTo;
  ManifestFile *pFileFrom, *pFileTo;
  const char *zBranch;
1725
1726
1727
1728
1729
1730
1731



1732
1733
1734
1735
1736
1737
1738
**
**      dc=N             Show N lines of context around each diff
**      patch            Use the patch diff format
**      regex=REGEX      Only show differences that match REGEX
**      sbs=BOOLEAN      Turn side-by-side diffs on and off (default: on)
**      verbose=BOOLEAN  Show more detail when describing artifacts
**      w=BOOLEAN        Ignore whitespace



*/
void diff_page(void){
  int v1, v2;
  int isPatch = P("patch")!=0;
  int diffType;          /* 0: none, 1: unified,  2: side-by-side */
  char *zV1;
  char *zV2;







>
>
>







1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
**
**      dc=N             Show N lines of context around each diff
**      patch            Use the patch diff format
**      regex=REGEX      Only show differences that match REGEX
**      sbs=BOOLEAN      Turn side-by-side diffs on and off (default: on)
**      verbose=BOOLEAN  Show more detail when describing artifacts
**      w=BOOLEAN        Ignore whitespace
**
** See the help screen for the /vdiff web page for a list of available
** keyboard shortcuts.
*/
void diff_page(void){
  int v1, v2;
  int isPatch = P("patch")!=0;
  int diffType;          /* 0: none, 1: unified,  2: side-by-side */
  char *zV1;
  char *zV2;
2865
2866
2867
2868
2869
2870
2871



2872
2873
2874
2875
2876
2877
2878
**
** The NAME argument is any valid artifact name: an artifact hash,
** a timestamp, a tag name, etc.
**
** Because NAME can match so many different things (commit artifacts,
** wiki pages, ticket comments, forum posts...) the format of the output
** page depends on the type of artifact that NAME matches.



*/
void info_page(void){
  const char *zName;
  Blob uuid;
  int rid;
  int rc;
  int nLen;







>
>
>







2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
**
** The NAME argument is any valid artifact name: an artifact hash,
** a timestamp, a tag name, etc.
**
** Because NAME can match so many different things (commit artifacts,
** wiki pages, ticket comments, forum posts...) the format of the output
** page depends on the type of artifact that NAME matches.
**
** See the help screen for the /vdiff web page for a list of available
** keyboard shortcuts (if the NAME argument refers to a check-in).
*/
void info_page(void){
  const char *zName;
  Blob uuid;
  int rid;
  int rc;
  int nLen;