Fossil SCM

Sync with trunk.

florian 2024-12-13 17:01 diff-keyboard-navigation merge
Commit edda30c66d22cfab825c2ac32a10ec6a9b375d4acc88b4b3da5109ab87d5dffa
+1 -2
--- src/add.c
+++ src/add.c
@@ -753,12 +753,11 @@
753753
**
754754
** * All files in the repository but missing from the check-out (that is,
755755
** all files that show as MISSING with the "status" command) are
756756
** removed as if by the "[[rm]]" command.
757757
**
758
-** The command does not "[[commit]]". You must run the "[[commit]]" separately
759
-** as a separate step.
758
+** Note that this command does not "commit", as that is a separate step.
760759
**
761760
** Files and directories whose names begin with "." are ignored unless
762761
** the --dotfiles option is used.
763762
**
764763
** The --ignore option overrides the "ignore-glob" setting, as do the
765764
--- src/add.c
+++ src/add.c
@@ -753,12 +753,11 @@
753 **
754 ** * All files in the repository but missing from the check-out (that is,
755 ** all files that show as MISSING with the "status" command) are
756 ** removed as if by the "[[rm]]" command.
757 **
758 ** The command does not "[[commit]]". You must run the "[[commit]]" separately
759 ** as a separate step.
760 **
761 ** Files and directories whose names begin with "." are ignored unless
762 ** the --dotfiles option is used.
763 **
764 ** The --ignore option overrides the "ignore-glob" setting, as do the
765
--- src/add.c
+++ src/add.c
@@ -753,12 +753,11 @@
753 **
754 ** * All files in the repository but missing from the check-out (that is,
755 ** all files that show as MISSING with the "status" command) are
756 ** removed as if by the "[[rm]]" command.
757 **
758 ** Note that this command does not "commit", as that is a separate step.
 
759 **
760 ** Files and directories whose names begin with "." are ignored unless
761 ** the --dotfiles option is used.
762 **
763 ** The --ignore option overrides the "ignore-glob" setting, as do the
764
--- src/default.css
+++ src/default.css
@@ -748,10 +748,11 @@
748748
border-bottom: 3px solid gold;
749749
}
750750
body.tkt div.content ol.tkt-changes > li:target > ol {
751751
border-left: 1px solid gold;
752752
}
753
+body.cpage-ckout .file-change-line,
753754
body.cpage-info .file-change-line,
754755
body.cpage-vdiff .file-change-line {
755756
margin-top: 16px;
756757
margin-bottom: 16px;
757758
margin-right: 1em /* keep it from nudging right up against the scrollbar-reveal zone */;
758759
--- src/default.css
+++ src/default.css
@@ -748,10 +748,11 @@
748 border-bottom: 3px solid gold;
749 }
750 body.tkt div.content ol.tkt-changes > li:target > ol {
751 border-left: 1px solid gold;
752 }
 
753 body.cpage-info .file-change-line,
754 body.cpage-vdiff .file-change-line {
755 margin-top: 16px;
756 margin-bottom: 16px;
757 margin-right: 1em /* keep it from nudging right up against the scrollbar-reveal zone */;
758
--- src/default.css
+++ src/default.css
@@ -748,10 +748,11 @@
748 border-bottom: 3px solid gold;
749 }
750 body.tkt div.content ol.tkt-changes > li:target > ol {
751 border-left: 1px solid gold;
752 }
753 body.cpage-ckout .file-change-line,
754 body.cpage-info .file-change-line,
755 body.cpage-vdiff .file-change-line {
756 margin-top: 16px;
757 margin-bottom: 16px;
758 margin-right: 1em /* keep it from nudging right up against the scrollbar-reveal zone */;
759
+60 -33
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -1,43 +1,81 @@
11
/**
22
diff-related JS APIs for fossil.
33
*/
44
"use strict";
5
+/* Locate the UI element (if any) into which we can inject some diff-related
6
+ UI controls. */
7
+window.fossil.onPageLoad(function(){
8
+ const potentialParents = window.fossil.page.diffControlContainers = [
9
+ /* CSS selectors for possible parents for injected diff-related UI
10
+ controls. */
11
+ /* Put the most likely pages at the end, as array.pop() is more
12
+ efficient than array.shift() (see loop below). */
13
+ /* /filedit */ 'body.cpage-fileedit #fileedit-tab-diff-buttons',
14
+ /* /wikiedit */ 'body.cpage-wikiedit #wikiedit-tab-diff-buttons',
15
+ /* /fdiff */ 'body.fdiff form div.submenu',
16
+ /* /vdiff */ 'body.vdiff form div.submenu',
17
+ /* /info, /vinfo, /ckout */ 'body.vinfo div.sectionmenu.info-changes-menu'
18
+ ];
19
+ window.fossil.page.diffControlContainer = undefined;
20
+ while( potentialParents.length ){
21
+ if( (window.fossil.page.diffControlContainer
22
+ = document.querySelector(potentialParents.pop())) ){
23
+ break;
24
+ }
25
+ }
26
+});
27
+
528
window.fossil.onPageLoad(function(){
629
/**
730
Adds toggle checkboxes to each file entry in the diff views for
831
/info and similar pages.
932
*/
1033
const D = window.fossil.dom;
1134
const allToggles = [/*collection of all diff-toggle checkboxes */];
1235
const addToggle = function(diffElem){
1336
const sib = diffElem.previousElementSibling,
14
- btnOne = sib ? D.addClass(D.checkbox(true), 'diff-toggle') : 0;
37
+ ckbox = sib ? D.addClass(D.checkbox(true), 'diff-toggle') : 0;
1538
if(!sib) return;
16
- const lblToggle = D.append(D.label(null, " Toggle "), btnOne);
39
+ const lblToggle = D.label();
40
+ D.append(lblToggle, ckbox, D.text(" show/hide "));
1741
const wrapper = D.append(D.span(), lblToggle);
18
- const btnAll = D.button("all");
19
- btnAll.$cb = btnOne;
20
- allToggles.push(btnOne);
21
- D.append(sib, D.append(wrapper, lblToggle, D.text(" "), btnAll));
22
- btnOne.addEventListener('change', function(){
42
+ allToggles.push(ckbox);
43
+ D.append(sib, D.append(wrapper, lblToggle));
44
+ ckbox.addEventListener('change', function(){
2345
diffElem.classList[this.checked ? 'remove' : 'add']('hidden');
24
- }, false);
25
- btnAll.addEventListener('click', function(){
26
- /* Toggle all entries to match this line's new state. Note that
27
- we use click() instead of cb.checked=... so that the
28
- on-change event handler fires. */
29
- const checked = !this.$cb.checked;
30
- allToggles.forEach( (cb)=>{
31
- if(cb.checked!==checked) cb.click();
32
- });
3346
}, false);
3447
};
3548
if( !document.querySelector('body.fdiff') ){
3649
/* Don't show the diff toggle button for /fdiff because it only
3750
has a single file to show (and also a different DOM layout). */
3851
document.querySelectorAll('table.diff').forEach(addToggle);
52
+ }
53
+ const icm = allToggles.length>1 ? window.fossil.page.diffControlContainer : 0;
54
+ if(icm) {
55
+ const btnAll = D.addClass(D.a("#", "Show/Hide"), "button");
56
+ D.append( icm, btnAll );
57
+ btnAll.addEventListener('click', function(ev){
58
+ ev.preventDefault();
59
+ ev.stopPropagation();
60
+ /* Figure out whether we want to show all or hide all: if any diffs are
61
+ toggled off, show all, else hide all. */
62
+ let show = false;
63
+ let ckbox;
64
+ for( ckbox of allToggles ){
65
+ if( !ckbox.checked ){
66
+ show = true;
67
+ break;
68
+ }
69
+ }
70
+ for( ckbox of allToggles ){
71
+ /* Toggle all entries to match this new state. We use click()
72
+ instead of ckbox.checked=... so that the on-change event handler
73
+ fires. */
74
+ if(ckbox.checked!==show) ckbox.click();
75
+ }
76
+ }, false);
3977
}
4078
function resetToggles(){
4179
var cb = document.querySelectorAll(
4280
'input[type="checkbox"].diff-toggle:not(:checked)');
4381
for( var i=0; i<cb.length; i++ ) cb[i].checked = true;
@@ -781,26 +819,15 @@
781819
/* Look for a parent element to hold the sbs-sync-scroll toggle
782820
checkbox. This differs per page. If we don't find one, simply
783821
elide that toggle and use whatever preference the user last
784822
specified (defaulting to on). */
785823
let cbSync /* scroll-sync checkbox */;
786
- let eToggleParent /* element to put the sync-scroll checkbox in */;
787
- const potentialParents = [ /* possible parents for the checkbox */
788
- /* Put the most likely pages at the end, as array.pop() is more
789
- efficient than array.shift() (see loop below). */
790
- /* /filedit */ 'body.cpage-fileedit #fileedit-tab-diff-buttons',
791
- /* /wikiedit */ 'body.cpage-wikiedit #wikiedit-tab-diff-buttons',
792
- /* /fdiff */ 'body.fdiff form div.submenu',
793
- /* /vdiff */ 'body.vdiff form div.submenu',
794
- /* /info, /vinfo */ 'body.vinfo div.sectionmenu.info-changes-menu'
795
- ];
796
- while( potentialParents.length ){
797
- if( (eToggleParent = document.querySelector(potentialParents.pop())) ){
798
- break;
799
- }
800
- }
801
- const keySbsScroll = 'sync-diff-scroll' /* F.storage key */;
824
+ let eToggleParent = /* element to put the sync-scroll checkbox in */
825
+ document.querySelector('table.diff.splitdiff')
826
+ ? window.fossil.page.diffControlContainer
827
+ : undefined;
828
+ const keySbsScroll = 'sync-diff-scroll' /* F.storage key for persistent user preference */;
802829
if( eToggleParent ){
803830
/* Add a checkbox to toggle sbs scroll sync. Remember that in
804831
order to be UI-consistent in the /vdiff page we have to ensure
805832
that the checkbox is to the LEFT of of its label. We store the
806833
sync-scroll preference in F.storage (not a cookie) so that it
@@ -807,11 +834,11 @@
807834
persists across page loads and different apps. */
808835
cbSync = D.checkbox(keySbsScroll, F.storage.getBool(keySbsScroll,true));
809836
D.append(eToggleParent, D.append(
810837
D.addClass(D.create('span'), 'input-with-label'),
811838
D.append(D.create('label'),
812
- cbSync, "Sync side-by-side scrolling")
839
+ cbSync, "Scroll Sync")
813840
));
814841
cbSync.addEventListener('change', function(e){
815842
F.storage.set(keySbsScroll, e.target.checked);
816843
});
817844
}
818845
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -1,43 +1,81 @@
1 /**
2 diff-related JS APIs for fossil.
3 */
4 "use strict";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5 window.fossil.onPageLoad(function(){
6 /**
7 Adds toggle checkboxes to each file entry in the diff views for
8 /info and similar pages.
9 */
10 const D = window.fossil.dom;
11 const allToggles = [/*collection of all diff-toggle checkboxes */];
12 const addToggle = function(diffElem){
13 const sib = diffElem.previousElementSibling,
14 btnOne = sib ? D.addClass(D.checkbox(true), 'diff-toggle') : 0;
15 if(!sib) return;
16 const lblToggle = D.append(D.label(null, " Toggle "), btnOne);
 
17 const wrapper = D.append(D.span(), lblToggle);
18 const btnAll = D.button("all");
19 btnAll.$cb = btnOne;
20 allToggles.push(btnOne);
21 D.append(sib, D.append(wrapper, lblToggle, D.text(" "), btnAll));
22 btnOne.addEventListener('change', function(){
23 diffElem.classList[this.checked ? 'remove' : 'add']('hidden');
24 }, false);
25 btnAll.addEventListener('click', function(){
26 /* Toggle all entries to match this line's new state. Note that
27 we use click() instead of cb.checked=... so that the
28 on-change event handler fires. */
29 const checked = !this.$cb.checked;
30 allToggles.forEach( (cb)=>{
31 if(cb.checked!==checked) cb.click();
32 });
33 }, false);
34 };
35 if( !document.querySelector('body.fdiff') ){
36 /* Don't show the diff toggle button for /fdiff because it only
37 has a single file to show (and also a different DOM layout). */
38 document.querySelectorAll('table.diff').forEach(addToggle);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39 }
40 function resetToggles(){
41 var cb = document.querySelectorAll(
42 'input[type="checkbox"].diff-toggle:not(:checked)');
43 for( var i=0; i<cb.length; i++ ) cb[i].checked = true;
@@ -781,26 +819,15 @@
781 /* Look for a parent element to hold the sbs-sync-scroll toggle
782 checkbox. This differs per page. If we don't find one, simply
783 elide that toggle and use whatever preference the user last
784 specified (defaulting to on). */
785 let cbSync /* scroll-sync checkbox */;
786 let eToggleParent /* element to put the sync-scroll checkbox in */;
787 const potentialParents = [ /* possible parents for the checkbox */
788 /* Put the most likely pages at the end, as array.pop() is more
789 efficient than array.shift() (see loop below). */
790 /* /filedit */ 'body.cpage-fileedit #fileedit-tab-diff-buttons',
791 /* /wikiedit */ 'body.cpage-wikiedit #wikiedit-tab-diff-buttons',
792 /* /fdiff */ 'body.fdiff form div.submenu',
793 /* /vdiff */ 'body.vdiff form div.submenu',
794 /* /info, /vinfo */ 'body.vinfo div.sectionmenu.info-changes-menu'
795 ];
796 while( potentialParents.length ){
797 if( (eToggleParent = document.querySelector(potentialParents.pop())) ){
798 break;
799 }
800 }
801 const keySbsScroll = 'sync-diff-scroll' /* F.storage key */;
802 if( eToggleParent ){
803 /* Add a checkbox to toggle sbs scroll sync. Remember that in
804 order to be UI-consistent in the /vdiff page we have to ensure
805 that the checkbox is to the LEFT of of its label. We store the
806 sync-scroll preference in F.storage (not a cookie) so that it
@@ -807,11 +834,11 @@
807 persists across page loads and different apps. */
808 cbSync = D.checkbox(keySbsScroll, F.storage.getBool(keySbsScroll,true));
809 D.append(eToggleParent, D.append(
810 D.addClass(D.create('span'), 'input-with-label'),
811 D.append(D.create('label'),
812 cbSync, "Sync side-by-side scrolling")
813 ));
814 cbSync.addEventListener('change', function(e){
815 F.storage.set(keySbsScroll, e.target.checked);
816 });
817 }
818
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -1,43 +1,81 @@
1 /**
2 diff-related JS APIs for fossil.
3 */
4 "use strict";
5 /* Locate the UI element (if any) into which we can inject some diff-related
6 UI controls. */
7 window.fossil.onPageLoad(function(){
8 const potentialParents = window.fossil.page.diffControlContainers = [
9 /* CSS selectors for possible parents for injected diff-related UI
10 controls. */
11 /* Put the most likely pages at the end, as array.pop() is more
12 efficient than array.shift() (see loop below). */
13 /* /filedit */ 'body.cpage-fileedit #fileedit-tab-diff-buttons',
14 /* /wikiedit */ 'body.cpage-wikiedit #wikiedit-tab-diff-buttons',
15 /* /fdiff */ 'body.fdiff form div.submenu',
16 /* /vdiff */ 'body.vdiff form div.submenu',
17 /* /info, /vinfo, /ckout */ 'body.vinfo div.sectionmenu.info-changes-menu'
18 ];
19 window.fossil.page.diffControlContainer = undefined;
20 while( potentialParents.length ){
21 if( (window.fossil.page.diffControlContainer
22 = document.querySelector(potentialParents.pop())) ){
23 break;
24 }
25 }
26 });
27
28 window.fossil.onPageLoad(function(){
29 /**
30 Adds toggle checkboxes to each file entry in the diff views for
31 /info and similar pages.
32 */
33 const D = window.fossil.dom;
34 const allToggles = [/*collection of all diff-toggle checkboxes */];
35 const addToggle = function(diffElem){
36 const sib = diffElem.previousElementSibling,
37 ckbox = sib ? D.addClass(D.checkbox(true), 'diff-toggle') : 0;
38 if(!sib) return;
39 const lblToggle = D.label();
40 D.append(lblToggle, ckbox, D.text(" show/hide "));
41 const wrapper = D.append(D.span(), lblToggle);
42 allToggles.push(ckbox);
43 D.append(sib, D.append(wrapper, lblToggle));
44 ckbox.addEventListener('change', function(){
 
 
45 diffElem.classList[this.checked ? 'remove' : 'add']('hidden');
 
 
 
 
 
 
 
 
 
46 }, false);
47 };
48 if( !document.querySelector('body.fdiff') ){
49 /* Don't show the diff toggle button for /fdiff because it only
50 has a single file to show (and also a different DOM layout). */
51 document.querySelectorAll('table.diff').forEach(addToggle);
52 }
53 const icm = allToggles.length>1 ? window.fossil.page.diffControlContainer : 0;
54 if(icm) {
55 const btnAll = D.addClass(D.a("#", "Show/Hide"), "button");
56 D.append( icm, btnAll );
57 btnAll.addEventListener('click', function(ev){
58 ev.preventDefault();
59 ev.stopPropagation();
60 /* Figure out whether we want to show all or hide all: if any diffs are
61 toggled off, show all, else hide all. */
62 let show = false;
63 let ckbox;
64 for( ckbox of allToggles ){
65 if( !ckbox.checked ){
66 show = true;
67 break;
68 }
69 }
70 for( ckbox of allToggles ){
71 /* Toggle all entries to match this new state. We use click()
72 instead of ckbox.checked=... so that the on-change event handler
73 fires. */
74 if(ckbox.checked!==show) ckbox.click();
75 }
76 }, false);
77 }
78 function resetToggles(){
79 var cb = document.querySelectorAll(
80 'input[type="checkbox"].diff-toggle:not(:checked)');
81 for( var i=0; i<cb.length; i++ ) cb[i].checked = true;
@@ -781,26 +819,15 @@
819 /* Look for a parent element to hold the sbs-sync-scroll toggle
820 checkbox. This differs per page. If we don't find one, simply
821 elide that toggle and use whatever preference the user last
822 specified (defaulting to on). */
823 let cbSync /* scroll-sync checkbox */;
824 let eToggleParent = /* element to put the sync-scroll checkbox in */
825 document.querySelector('table.diff.splitdiff')
826 ? window.fossil.page.diffControlContainer
827 : undefined;
828 const keySbsScroll = 'sync-diff-scroll' /* F.storage key for persistent user preference */;
 
 
 
 
 
 
 
 
 
 
 
829 if( eToggleParent ){
830 /* Add a checkbox to toggle sbs scroll sync. Remember that in
831 order to be UI-consistent in the /vdiff page we have to ensure
832 that the checkbox is to the LEFT of of its label. We store the
833 sync-scroll preference in F.storage (not a cookie) so that it
@@ -807,11 +834,11 @@
834 persists across page loads and different apps. */
835 cbSync = D.checkbox(keySbsScroll, F.storage.getBool(keySbsScroll,true));
836 D.append(eToggleParent, D.append(
837 D.addClass(D.create('span'), 'input-with-label'),
838 D.append(D.create('label'),
839 cbSync, "Scroll Sync")
840 ));
841 cbSync.addEventListener('change', function(e){
842 F.storage.set(keySbsScroll, e.target.checked);
843 });
844 }
845
+60 -33
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -1,43 +1,81 @@
11
/**
22
diff-related JS APIs for fossil.
33
*/
44
"use strict";
5
+/* Locate the UI element (if any) into which we can inject some diff-related
6
+ UI controls. */
7
+window.fossil.onPageLoad(function(){
8
+ const potentialParents = window.fossil.page.diffControlContainers = [
9
+ /* CSS selectors for possible parents for injected diff-related UI
10
+ controls. */
11
+ /* Put the most likely pages at the end, as array.pop() is more
12
+ efficient than array.shift() (see loop below). */
13
+ /* /filedit */ 'body.cpage-fileedit #fileedit-tab-diff-buttons',
14
+ /* /wikiedit */ 'body.cpage-wikiedit #wikiedit-tab-diff-buttons',
15
+ /* /fdiff */ 'body.fdiff form div.submenu',
16
+ /* /vdiff */ 'body.vdiff form div.submenu',
17
+ /* /info, /vinfo, /ckout */ 'body.vinfo div.sectionmenu.info-changes-menu'
18
+ ];
19
+ window.fossil.page.diffControlContainer = undefined;
20
+ while( potentialParents.length ){
21
+ if( (window.fossil.page.diffControlContainer
22
+ = document.querySelector(potentialParents.pop())) ){
23
+ break;
24
+ }
25
+ }
26
+});
27
+
528
window.fossil.onPageLoad(function(){
629
/**
730
Adds toggle checkboxes to each file entry in the diff views for
831
/info and similar pages.
932
*/
1033
const D = window.fossil.dom;
1134
const allToggles = [/*collection of all diff-toggle checkboxes */];
1235
const addToggle = function(diffElem){
1336
const sib = diffElem.previousElementSibling,
14
- btnOne = sib ? D.addClass(D.checkbox(true), 'diff-toggle') : 0;
37
+ ckbox = sib ? D.addClass(D.checkbox(true), 'diff-toggle') : 0;
1538
if(!sib) return;
16
- const lblToggle = D.append(D.label(null, " Toggle "), btnOne);
39
+ const lblToggle = D.label();
40
+ D.append(lblToggle, ckbox, D.text(" show/hide "));
1741
const wrapper = D.append(D.span(), lblToggle);
18
- const btnAll = D.button("all");
19
- btnAll.$cb = btnOne;
20
- allToggles.push(btnOne);
21
- D.append(sib, D.append(wrapper, lblToggle, D.text(" "), btnAll));
22
- btnOne.addEventListener('change', function(){
42
+ allToggles.push(ckbox);
43
+ D.append(sib, D.append(wrapper, lblToggle));
44
+ ckbox.addEventListener('change', function(){
2345
diffElem.classList[this.checked ? 'remove' : 'add']('hidden');
24
- }, false);
25
- btnAll.addEventListener('click', function(){
26
- /* Toggle all entries to match this line's new state. Note that
27
- we use click() instead of cb.checked=... so that the
28
- on-change event handler fires. */
29
- const checked = !this.$cb.checked;
30
- allToggles.forEach( (cb)=>{
31
- if(cb.checked!==checked) cb.click();
32
- });
3346
}, false);
3447
};
3548
if( !document.querySelector('body.fdiff') ){
3649
/* Don't show the diff toggle button for /fdiff because it only
3750
has a single file to show (and also a different DOM layout). */
3851
document.querySelectorAll('table.diff').forEach(addToggle);
52
+ }
53
+ const icm = allToggles.length>1 ? window.fossil.page.diffControlContainer : 0;
54
+ if(icm) {
55
+ const btnAll = D.addClass(D.a("#", "Show/Hide"), "button");
56
+ D.append( icm, btnAll );
57
+ btnAll.addEventListener('click', function(ev){
58
+ ev.preventDefault();
59
+ ev.stopPropagation();
60
+ /* Figure out whether we want to show all or hide all: if any diffs are
61
+ toggled off, show all, else hide all. */
62
+ let show = false;
63
+ let ckbox;
64
+ for( ckbox of allToggles ){
65
+ if( !ckbox.checked ){
66
+ show = true;
67
+ break;
68
+ }
69
+ }
70
+ for( ckbox of allToggles ){
71
+ /* Toggle all entries to match this new state. We use click()
72
+ instead of ckbox.checked=... so that the on-change event handler
73
+ fires. */
74
+ if(ckbox.checked!==show) ckbox.click();
75
+ }
76
+ }, false);
3977
}
4078
function resetToggles(){
4179
var cb = document.querySelectorAll(
4280
'input[type="checkbox"].diff-toggle:not(:checked)');
4381
for( var i=0; i<cb.length; i++ ) cb[i].checked = true;
@@ -781,26 +819,15 @@
781819
/* Look for a parent element to hold the sbs-sync-scroll toggle
782820
checkbox. This differs per page. If we don't find one, simply
783821
elide that toggle and use whatever preference the user last
784822
specified (defaulting to on). */
785823
let cbSync /* scroll-sync checkbox */;
786
- let eToggleParent /* element to put the sync-scroll checkbox in */;
787
- const potentialParents = [ /* possible parents for the checkbox */
788
- /* Put the most likely pages at the end, as array.pop() is more
789
- efficient than array.shift() (see loop below). */
790
- /* /filedit */ 'body.cpage-fileedit #fileedit-tab-diff-buttons',
791
- /* /wikiedit */ 'body.cpage-wikiedit #wikiedit-tab-diff-buttons',
792
- /* /fdiff */ 'body.fdiff form div.submenu',
793
- /* /vdiff */ 'body.vdiff form div.submenu',
794
- /* /info, /vinfo */ 'body.vinfo div.sectionmenu.info-changes-menu'
795
- ];
796
- while( potentialParents.length ){
797
- if( (eToggleParent = document.querySelector(potentialParents.pop())) ){
798
- break;
799
- }
800
- }
801
- const keySbsScroll = 'sync-diff-scroll' /* F.storage key */;
824
+ let eToggleParent = /* element to put the sync-scroll checkbox in */
825
+ document.querySelector('table.diff.splitdiff')
826
+ ? window.fossil.page.diffControlContainer
827
+ : undefined;
828
+ const keySbsScroll = 'sync-diff-scroll' /* F.storage key for persistent user preference */;
802829
if( eToggleParent ){
803830
/* Add a checkbox to toggle sbs scroll sync. Remember that in
804831
order to be UI-consistent in the /vdiff page we have to ensure
805832
that the checkbox is to the LEFT of of its label. We store the
806833
sync-scroll preference in F.storage (not a cookie) so that it
@@ -807,11 +834,11 @@
807834
persists across page loads and different apps. */
808835
cbSync = D.checkbox(keySbsScroll, F.storage.getBool(keySbsScroll,true));
809836
D.append(eToggleParent, D.append(
810837
D.addClass(D.create('span'), 'input-with-label'),
811838
D.append(D.create('label'),
812
- cbSync, "Sync side-by-side scrolling")
839
+ cbSync, "Scroll Sync")
813840
));
814841
cbSync.addEventListener('change', function(e){
815842
F.storage.set(keySbsScroll, e.target.checked);
816843
});
817844
}
818845
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -1,43 +1,81 @@
1 /**
2 diff-related JS APIs for fossil.
3 */
4 "use strict";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5 window.fossil.onPageLoad(function(){
6 /**
7 Adds toggle checkboxes to each file entry in the diff views for
8 /info and similar pages.
9 */
10 const D = window.fossil.dom;
11 const allToggles = [/*collection of all diff-toggle checkboxes */];
12 const addToggle = function(diffElem){
13 const sib = diffElem.previousElementSibling,
14 btnOne = sib ? D.addClass(D.checkbox(true), 'diff-toggle') : 0;
15 if(!sib) return;
16 const lblToggle = D.append(D.label(null, " Toggle "), btnOne);
 
17 const wrapper = D.append(D.span(), lblToggle);
18 const btnAll = D.button("all");
19 btnAll.$cb = btnOne;
20 allToggles.push(btnOne);
21 D.append(sib, D.append(wrapper, lblToggle, D.text(" "), btnAll));
22 btnOne.addEventListener('change', function(){
23 diffElem.classList[this.checked ? 'remove' : 'add']('hidden');
24 }, false);
25 btnAll.addEventListener('click', function(){
26 /* Toggle all entries to match this line's new state. Note that
27 we use click() instead of cb.checked=... so that the
28 on-change event handler fires. */
29 const checked = !this.$cb.checked;
30 allToggles.forEach( (cb)=>{
31 if(cb.checked!==checked) cb.click();
32 });
33 }, false);
34 };
35 if( !document.querySelector('body.fdiff') ){
36 /* Don't show the diff toggle button for /fdiff because it only
37 has a single file to show (and also a different DOM layout). */
38 document.querySelectorAll('table.diff').forEach(addToggle);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39 }
40 function resetToggles(){
41 var cb = document.querySelectorAll(
42 'input[type="checkbox"].diff-toggle:not(:checked)');
43 for( var i=0; i<cb.length; i++ ) cb[i].checked = true;
@@ -781,26 +819,15 @@
781 /* Look for a parent element to hold the sbs-sync-scroll toggle
782 checkbox. This differs per page. If we don't find one, simply
783 elide that toggle and use whatever preference the user last
784 specified (defaulting to on). */
785 let cbSync /* scroll-sync checkbox */;
786 let eToggleParent /* element to put the sync-scroll checkbox in */;
787 const potentialParents = [ /* possible parents for the checkbox */
788 /* Put the most likely pages at the end, as array.pop() is more
789 efficient than array.shift() (see loop below). */
790 /* /filedit */ 'body.cpage-fileedit #fileedit-tab-diff-buttons',
791 /* /wikiedit */ 'body.cpage-wikiedit #wikiedit-tab-diff-buttons',
792 /* /fdiff */ 'body.fdiff form div.submenu',
793 /* /vdiff */ 'body.vdiff form div.submenu',
794 /* /info, /vinfo */ 'body.vinfo div.sectionmenu.info-changes-menu'
795 ];
796 while( potentialParents.length ){
797 if( (eToggleParent = document.querySelector(potentialParents.pop())) ){
798 break;
799 }
800 }
801 const keySbsScroll = 'sync-diff-scroll' /* F.storage key */;
802 if( eToggleParent ){
803 /* Add a checkbox to toggle sbs scroll sync. Remember that in
804 order to be UI-consistent in the /vdiff page we have to ensure
805 that the checkbox is to the LEFT of of its label. We store the
806 sync-scroll preference in F.storage (not a cookie) so that it
@@ -807,11 +834,11 @@
807 persists across page loads and different apps. */
808 cbSync = D.checkbox(keySbsScroll, F.storage.getBool(keySbsScroll,true));
809 D.append(eToggleParent, D.append(
810 D.addClass(D.create('span'), 'input-with-label'),
811 D.append(D.create('label'),
812 cbSync, "Sync side-by-side scrolling")
813 ));
814 cbSync.addEventListener('change', function(e){
815 F.storage.set(keySbsScroll, e.target.checked);
816 });
817 }
818
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -1,43 +1,81 @@
1 /**
2 diff-related JS APIs for fossil.
3 */
4 "use strict";
5 /* Locate the UI element (if any) into which we can inject some diff-related
6 UI controls. */
7 window.fossil.onPageLoad(function(){
8 const potentialParents = window.fossil.page.diffControlContainers = [
9 /* CSS selectors for possible parents for injected diff-related UI
10 controls. */
11 /* Put the most likely pages at the end, as array.pop() is more
12 efficient than array.shift() (see loop below). */
13 /* /filedit */ 'body.cpage-fileedit #fileedit-tab-diff-buttons',
14 /* /wikiedit */ 'body.cpage-wikiedit #wikiedit-tab-diff-buttons',
15 /* /fdiff */ 'body.fdiff form div.submenu',
16 /* /vdiff */ 'body.vdiff form div.submenu',
17 /* /info, /vinfo, /ckout */ 'body.vinfo div.sectionmenu.info-changes-menu'
18 ];
19 window.fossil.page.diffControlContainer = undefined;
20 while( potentialParents.length ){
21 if( (window.fossil.page.diffControlContainer
22 = document.querySelector(potentialParents.pop())) ){
23 break;
24 }
25 }
26 });
27
28 window.fossil.onPageLoad(function(){
29 /**
30 Adds toggle checkboxes to each file entry in the diff views for
31 /info and similar pages.
32 */
33 const D = window.fossil.dom;
34 const allToggles = [/*collection of all diff-toggle checkboxes */];
35 const addToggle = function(diffElem){
36 const sib = diffElem.previousElementSibling,
37 ckbox = sib ? D.addClass(D.checkbox(true), 'diff-toggle') : 0;
38 if(!sib) return;
39 const lblToggle = D.label();
40 D.append(lblToggle, ckbox, D.text(" show/hide "));
41 const wrapper = D.append(D.span(), lblToggle);
42 allToggles.push(ckbox);
43 D.append(sib, D.append(wrapper, lblToggle));
44 ckbox.addEventListener('change', function(){
 
 
45 diffElem.classList[this.checked ? 'remove' : 'add']('hidden');
 
 
 
 
 
 
 
 
 
46 }, false);
47 };
48 if( !document.querySelector('body.fdiff') ){
49 /* Don't show the diff toggle button for /fdiff because it only
50 has a single file to show (and also a different DOM layout). */
51 document.querySelectorAll('table.diff').forEach(addToggle);
52 }
53 const icm = allToggles.length>1 ? window.fossil.page.diffControlContainer : 0;
54 if(icm) {
55 const btnAll = D.addClass(D.a("#", "Show/Hide"), "button");
56 D.append( icm, btnAll );
57 btnAll.addEventListener('click', function(ev){
58 ev.preventDefault();
59 ev.stopPropagation();
60 /* Figure out whether we want to show all or hide all: if any diffs are
61 toggled off, show all, else hide all. */
62 let show = false;
63 let ckbox;
64 for( ckbox of allToggles ){
65 if( !ckbox.checked ){
66 show = true;
67 break;
68 }
69 }
70 for( ckbox of allToggles ){
71 /* Toggle all entries to match this new state. We use click()
72 instead of ckbox.checked=... so that the on-change event handler
73 fires. */
74 if(ckbox.checked!==show) ckbox.click();
75 }
76 }, false);
77 }
78 function resetToggles(){
79 var cb = document.querySelectorAll(
80 'input[type="checkbox"].diff-toggle:not(:checked)');
81 for( var i=0; i<cb.length; i++ ) cb[i].checked = true;
@@ -781,26 +819,15 @@
819 /* Look for a parent element to hold the sbs-sync-scroll toggle
820 checkbox. This differs per page. If we don't find one, simply
821 elide that toggle and use whatever preference the user last
822 specified (defaulting to on). */
823 let cbSync /* scroll-sync checkbox */;
824 let eToggleParent = /* element to put the sync-scroll checkbox in */
825 document.querySelector('table.diff.splitdiff')
826 ? window.fossil.page.diffControlContainer
827 : undefined;
828 const keySbsScroll = 'sync-diff-scroll' /* F.storage key for persistent user preference */;
 
 
 
 
 
 
 
 
 
 
 
829 if( eToggleParent ){
830 /* Add a checkbox to toggle sbs scroll sync. Remember that in
831 order to be UI-consistent in the /vdiff page we have to ensure
832 that the checkbox is to the LEFT of of its label. We store the
833 sync-scroll preference in F.storage (not a cookie) so that it
@@ -807,11 +834,11 @@
834 persists across page loads and different apps. */
835 cbSync = D.checkbox(keySbsScroll, F.storage.getBool(keySbsScroll,true));
836 D.append(eToggleParent, D.append(
837 D.addClass(D.create('span'), 'input-with-label'),
838 D.append(D.create('label'),
839 cbSync, "Scroll Sync")
840 ));
841 cbSync.addEventListener('change', function(e){
842 F.storage.set(keySbsScroll, e.target.checked);
843 });
844 }
845
+46 -29
--- src/info.c
+++ src/info.c
@@ -622,16 +622,19 @@
622622
char *zHostname;
623623
char *zCwd;
624624
int diffType; /* 0: no diff, 1: unified, 2: side-by-side */
625625
DiffConfig DCfg,*pCfg; /* Diff details */
626626
const char *zHome; /* Home directory */
627
+ const char *zW; /* The "w" query parameter */
628
+ int nChng; /* Number of changes */
627629
Stmt q;
628630
629631
if( !db_open_local(0) || !cgi_is_loopback(g.zIpAddr) ){
630
- cgi_redirect("%R/home");
632
+ cgi_redirectf("%R/home");
631633
return;
632634
}
635
+ file_chdir(g.zLocalRoot, 0);
633636
diffType = preferred_diff_type();
634637
pCfg = construct_diff_flags(diffType, &DCfg);
635638
vid = db_lget_int("checkout", 0);
636639
db_unprotect(PROTECT_ALL);
637640
vfile_check_signature(vid, CKSIG_ENOTFILE);
@@ -650,11 +653,14 @@
650653
style_header("Checkout Status: %h on %h", zCwd, zHostname);
651654
}else{
652655
style_header("Checkout Status: %h", zCwd);
653656
}
654657
render_checkin_context(vid, 0, 0, 0);
655
- if( pCfg==0 ){
658
+ nChng = db_int(0, "SELECT count(*) FROM vfile"
659
+ " WHERE vid=%d AND (deleted OR chnged OR rid==0)", vid);
660
+ if( nChng==0 ){
661
+ @ <p>No uncommitted changes</p>
656662
style_finish_page();
657663
return;
658664
}
659665
db_prepare(&q,
660666
/* 0 1 2 3 4 5 6 */
@@ -663,15 +669,33 @@
663669
" WHERE vid=%d"
664670
" AND (deleted OR chnged OR rid==0)"
665671
" ORDER BY pathname /*scan*/",
666672
vid
667673
);
668
- if( pCfg->diffFlags & DIFF_SIDEBYSIDE ){
669
- pCfg->diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
674
+ if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
675
+ DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
670676
}else{
671
- pCfg->diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
677
+ DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
672678
}
679
+ @ <hr>
680
+ @ <div class="sectionmenu info-changes-menu">
681
+ zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
682
+ if( diffType!=1 ){
683
+ @ %z(chref("button","%R?diff=1%s",zW))Unified&nbsp;Diff</a>
684
+ }
685
+ if( diffType!=2 ){
686
+ @ %z(chref("button","%R?diff=2%s",zW))Side-by-Side&nbsp;Diff</a>
687
+ }
688
+ if( diffType!=0 ){
689
+ if( *zW ){
690
+ @ %z(chref("button","%R?diff=%d",diffType))\
691
+ @ Show&nbsp;Whitespace&nbsp;Changes</a>
692
+ }else{
693
+ @ %z(chref("button","%R?diff=%d&w",diffType))Ignore&nbsp;Whitespace</a>
694
+ }
695
+ }
696
+ @ </div>
673697
while( db_step(&q)==SQLITE_ROW ){
674698
const char *zTreename = db_column_text(&q,0);
675699
int isDeleted = db_column_int(&q, 1);
676700
int isChnged = db_column_int(&q,2);
677701
int isNew = db_column_int(&q,3);
@@ -678,37 +702,39 @@
678702
int srcid = db_column_int(&q, 4);
679703
int isLink = db_column_int(&q, 5);
680704
const char *zUuid = db_column_text(&q, 6);
681705
int showDiff = 1;
682706
683
- pCfg->diffFlags &= (~DIFF_FILE_MASK);
707
+ DCfg.diffFlags &= (~DIFF_FILE_MASK);
708
+ @ <div class='file-change-line'><span>
684709
if( isDeleted ){
685
- @ <p>DELETED %h(zTreename)</p>
686
- pCfg->diffFlags |= DIFF_FILE_DELETED;
710
+ @ DELETED %h(zTreename)
711
+ DCfg.diffFlags |= DIFF_FILE_DELETED;
687712
showDiff = 0;
688713
}else if( file_access(zTreename, F_OK) ){
689
- @ <p>MISSING %h(zTreename)</p>
714
+ @ MISSING %h(zTreename)
690715
showDiff = 0;
691716
}else if( isNew ){
692
- @ <p>ADDED %h(zTreename)</p>
693
- pCfg->diffFlags |= DIFF_FILE_ADDED;
717
+ @ ADDED %h(zTreename)
718
+ DCfg.diffFlags |= DIFF_FILE_ADDED;
694719
srcid = 0;
695720
showDiff = 0;
696721
}else if( isChnged==3 ){
697
- @ <p>ADDED_BY_MERGE %h(zTreename)</p>
698
- pCfg->diffFlags |= DIFF_FILE_ADDED;
722
+ @ ADDED_BY_MERGE %h(zTreename)
723
+ DCfg.diffFlags |= DIFF_FILE_ADDED;
699724
srcid = 0;
700725
showDiff = 0;
701726
}else if( isChnged==5 ){
702
- @ <p>ADDED_BY_INTEGRATE %h(zTreename)</p>
703
- pCfg->diffFlags |= DIFF_FILE_ADDED;
727
+ @ ADDED_BY_INTEGRATE %h(zTreename)
728
+ DCfg.diffFlags |= DIFF_FILE_ADDED;
704729
srcid = 0;
705730
showDiff = 0;
706731
}else{
707
- @ <p>CHANGED %h(zTreename)</p>
732
+ @ CHANGED %h(zTreename)
708733
}
709
- if( showDiff ){
734
+ @ </span></div>
735
+ if( showDiff && pCfg ){
710736
Blob old, new;
711737
if( !isLink != !file_islink(zTreename) ){
712738
@ %s(DIFF_CANNOT_COMPUTE_SYMLINK)
713739
continue;
714740
}
@@ -724,10 +750,11 @@
724750
blob_reset(&old);
725751
blob_reset(&new);
726752
}
727753
}
728754
db_finalize(&q);
755
+ // @ </div> <!-- ap-002 -->
729756
append_diff_javascript(diffType);
730757
style_finish_page();
731758
}
732759
733760
/*
@@ -756,11 +783,10 @@
756783
const char *zParent; /* Hash of the parent check-in (if any) */
757784
const char *zRe; /* regex parameter */
758785
ReCompiled *pRe = 0; /* regex */
759786
const char *zW; /* URL param for ignoring whitespace */
760787
const char *zPage = "vinfo"; /* Page that shows diffs */
761
- const char *zPageHide = "ci"; /* Page that hides diffs */
762788
const char *zBrName; /* Branch name */
763789
DiffConfig DCfg,*pCfg; /* Type of diff */
764790
765791
login_check_credentials();
766792
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
@@ -1026,27 +1052,21 @@
10261052
@ <div class="sectionmenu info-changes-menu">
10271053
/* ^^^ .info-changes-menu is used by diff scroll sync */
10281054
pCfg = construct_diff_flags(diffType, &DCfg);
10291055
DCfg.pRe = pRe;
10301056
zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
1031
- if( diffType!=0 ){
1032
- /* Class "smb-hide-diff" required by the fossil.diff.js script. */
1033
- const char *zBtnClass = "button smb-hide-diff";
1034
- @ %z(chref(zBtnClass,"%R/%s/%T?diff=0",zPageHide,zName))\
1035
- @ Hide&nbsp;Diffs</a>
1036
- }
10371057
if( diffType!=1 ){
10381058
/* Class "smb-unified-diff" required by the fossil.diff.js script. */
10391059
const char *zBtnClass = "button smb-unified-diff";
10401060
@ %z(chref(zBtnClass,"%R/%s/%T?diff=1%s",zPage,zName,zW))\
1041
- @ Unified&nbsp;Diffs</a>
1061
+ @ Unified&nbsp;Diff</a>
10421062
}
10431063
if( diffType!=2 ){
10441064
/* Class "smb-side-by-side-diff" required by the fossil.diff.js script. */
10451065
const char *zBtnClass = "button smb-side-by-side-diff";
10461066
@ %z(chref(zBtnClass,"%R/%s/%T?diff=2%s",zPage,zName,zW))\
1047
- @ Side-by-Side&nbsp;Diffs</a>
1067
+ @ Side-by-Side&nbsp;Diff</a>
10481068
}
10491069
if( diffType!=0 ){
10501070
if( *zW ){
10511071
@ %z(chref("button","%R/%s/%T",zPage,zName))
10521072
@ Show&nbsp;Whitespace&nbsp;Changes</a>
@@ -1416,13 +1436,10 @@
14161436
cgi_check_for_malice();
14171437
style_set_current_feature("vdiff");
14181438
if( zBranch==0 ){
14191439
style_submenu_element("Path", "%R/timeline?me=%T&you=%T", zFrom, zTo);
14201440
}
1421
- if( diffType!=0 ){
1422
- style_submenu_element("Hide Diff", "%R/vdiff?diff=0&%b%b", &qp, &qpGlob);
1423
- }
14241441
if( diffType!=2 ){
14251442
style_submenu_element("Side-by-Side Diff", "%R/vdiff?diff=2&%b%b", &qp,
14261443
&qpGlob);
14271444
}
14281445
if( diffType!=1 ) {
14291446
--- src/info.c
+++ src/info.c
@@ -622,16 +622,19 @@
622 char *zHostname;
623 char *zCwd;
624 int diffType; /* 0: no diff, 1: unified, 2: side-by-side */
625 DiffConfig DCfg,*pCfg; /* Diff details */
626 const char *zHome; /* Home directory */
 
 
627 Stmt q;
628
629 if( !db_open_local(0) || !cgi_is_loopback(g.zIpAddr) ){
630 cgi_redirect("%R/home");
631 return;
632 }
 
633 diffType = preferred_diff_type();
634 pCfg = construct_diff_flags(diffType, &DCfg);
635 vid = db_lget_int("checkout", 0);
636 db_unprotect(PROTECT_ALL);
637 vfile_check_signature(vid, CKSIG_ENOTFILE);
@@ -650,11 +653,14 @@
650 style_header("Checkout Status: %h on %h", zCwd, zHostname);
651 }else{
652 style_header("Checkout Status: %h", zCwd);
653 }
654 render_checkin_context(vid, 0, 0, 0);
655 if( pCfg==0 ){
 
 
 
656 style_finish_page();
657 return;
658 }
659 db_prepare(&q,
660 /* 0 1 2 3 4 5 6 */
@@ -663,15 +669,33 @@
663 " WHERE vid=%d"
664 " AND (deleted OR chnged OR rid==0)"
665 " ORDER BY pathname /*scan*/",
666 vid
667 );
668 if( pCfg->diffFlags & DIFF_SIDEBYSIDE ){
669 pCfg->diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
670 }else{
671 pCfg->diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
672 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
673 while( db_step(&q)==SQLITE_ROW ){
674 const char *zTreename = db_column_text(&q,0);
675 int isDeleted = db_column_int(&q, 1);
676 int isChnged = db_column_int(&q,2);
677 int isNew = db_column_int(&q,3);
@@ -678,37 +702,39 @@
678 int srcid = db_column_int(&q, 4);
679 int isLink = db_column_int(&q, 5);
680 const char *zUuid = db_column_text(&q, 6);
681 int showDiff = 1;
682
683 pCfg->diffFlags &= (~DIFF_FILE_MASK);
 
684 if( isDeleted ){
685 @ <p>DELETED %h(zTreename)</p>
686 pCfg->diffFlags |= DIFF_FILE_DELETED;
687 showDiff = 0;
688 }else if( file_access(zTreename, F_OK) ){
689 @ <p>MISSING %h(zTreename)</p>
690 showDiff = 0;
691 }else if( isNew ){
692 @ <p>ADDED %h(zTreename)</p>
693 pCfg->diffFlags |= DIFF_FILE_ADDED;
694 srcid = 0;
695 showDiff = 0;
696 }else if( isChnged==3 ){
697 @ <p>ADDED_BY_MERGE %h(zTreename)</p>
698 pCfg->diffFlags |= DIFF_FILE_ADDED;
699 srcid = 0;
700 showDiff = 0;
701 }else if( isChnged==5 ){
702 @ <p>ADDED_BY_INTEGRATE %h(zTreename)</p>
703 pCfg->diffFlags |= DIFF_FILE_ADDED;
704 srcid = 0;
705 showDiff = 0;
706 }else{
707 @ <p>CHANGED %h(zTreename)</p>
708 }
709 if( showDiff ){
 
710 Blob old, new;
711 if( !isLink != !file_islink(zTreename) ){
712 @ %s(DIFF_CANNOT_COMPUTE_SYMLINK)
713 continue;
714 }
@@ -724,10 +750,11 @@
724 blob_reset(&old);
725 blob_reset(&new);
726 }
727 }
728 db_finalize(&q);
 
729 append_diff_javascript(diffType);
730 style_finish_page();
731 }
732
733 /*
@@ -756,11 +783,10 @@
756 const char *zParent; /* Hash of the parent check-in (if any) */
757 const char *zRe; /* regex parameter */
758 ReCompiled *pRe = 0; /* regex */
759 const char *zW; /* URL param for ignoring whitespace */
760 const char *zPage = "vinfo"; /* Page that shows diffs */
761 const char *zPageHide = "ci"; /* Page that hides diffs */
762 const char *zBrName; /* Branch name */
763 DiffConfig DCfg,*pCfg; /* Type of diff */
764
765 login_check_credentials();
766 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
@@ -1026,27 +1052,21 @@
1026 @ <div class="sectionmenu info-changes-menu">
1027 /* ^^^ .info-changes-menu is used by diff scroll sync */
1028 pCfg = construct_diff_flags(diffType, &DCfg);
1029 DCfg.pRe = pRe;
1030 zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
1031 if( diffType!=0 ){
1032 /* Class "smb-hide-diff" required by the fossil.diff.js script. */
1033 const char *zBtnClass = "button smb-hide-diff";
1034 @ %z(chref(zBtnClass,"%R/%s/%T?diff=0",zPageHide,zName))\
1035 @ Hide&nbsp;Diffs</a>
1036 }
1037 if( diffType!=1 ){
1038 /* Class "smb-unified-diff" required by the fossil.diff.js script. */
1039 const char *zBtnClass = "button smb-unified-diff";
1040 @ %z(chref(zBtnClass,"%R/%s/%T?diff=1%s",zPage,zName,zW))\
1041 @ Unified&nbsp;Diffs</a>
1042 }
1043 if( diffType!=2 ){
1044 /* Class "smb-side-by-side-diff" required by the fossil.diff.js script. */
1045 const char *zBtnClass = "button smb-side-by-side-diff";
1046 @ %z(chref(zBtnClass,"%R/%s/%T?diff=2%s",zPage,zName,zW))\
1047 @ Side-by-Side&nbsp;Diffs</a>
1048 }
1049 if( diffType!=0 ){
1050 if( *zW ){
1051 @ %z(chref("button","%R/%s/%T",zPage,zName))
1052 @ Show&nbsp;Whitespace&nbsp;Changes</a>
@@ -1416,13 +1436,10 @@
1416 cgi_check_for_malice();
1417 style_set_current_feature("vdiff");
1418 if( zBranch==0 ){
1419 style_submenu_element("Path", "%R/timeline?me=%T&you=%T", zFrom, zTo);
1420 }
1421 if( diffType!=0 ){
1422 style_submenu_element("Hide Diff", "%R/vdiff?diff=0&%b%b", &qp, &qpGlob);
1423 }
1424 if( diffType!=2 ){
1425 style_submenu_element("Side-by-Side Diff", "%R/vdiff?diff=2&%b%b", &qp,
1426 &qpGlob);
1427 }
1428 if( diffType!=1 ) {
1429
--- src/info.c
+++ src/info.c
@@ -622,16 +622,19 @@
622 char *zHostname;
623 char *zCwd;
624 int diffType; /* 0: no diff, 1: unified, 2: side-by-side */
625 DiffConfig DCfg,*pCfg; /* Diff details */
626 const char *zHome; /* Home directory */
627 const char *zW; /* The "w" query parameter */
628 int nChng; /* Number of changes */
629 Stmt q;
630
631 if( !db_open_local(0) || !cgi_is_loopback(g.zIpAddr) ){
632 cgi_redirectf("%R/home");
633 return;
634 }
635 file_chdir(g.zLocalRoot, 0);
636 diffType = preferred_diff_type();
637 pCfg = construct_diff_flags(diffType, &DCfg);
638 vid = db_lget_int("checkout", 0);
639 db_unprotect(PROTECT_ALL);
640 vfile_check_signature(vid, CKSIG_ENOTFILE);
@@ -650,11 +653,14 @@
653 style_header("Checkout Status: %h on %h", zCwd, zHostname);
654 }else{
655 style_header("Checkout Status: %h", zCwd);
656 }
657 render_checkin_context(vid, 0, 0, 0);
658 nChng = db_int(0, "SELECT count(*) FROM vfile"
659 " WHERE vid=%d AND (deleted OR chnged OR rid==0)", vid);
660 if( nChng==0 ){
661 @ <p>No uncommitted changes</p>
662 style_finish_page();
663 return;
664 }
665 db_prepare(&q,
666 /* 0 1 2 3 4 5 6 */
@@ -663,15 +669,33 @@
669 " WHERE vid=%d"
670 " AND (deleted OR chnged OR rid==0)"
671 " ORDER BY pathname /*scan*/",
672 vid
673 );
674 if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
675 DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
676 }else{
677 DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
678 }
679 @ <hr>
680 @ <div class="sectionmenu info-changes-menu">
681 zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
682 if( diffType!=1 ){
683 @ %z(chref("button","%R?diff=1%s",zW))Unified&nbsp;Diff</a>
684 }
685 if( diffType!=2 ){
686 @ %z(chref("button","%R?diff=2%s",zW))Side-by-Side&nbsp;Diff</a>
687 }
688 if( diffType!=0 ){
689 if( *zW ){
690 @ %z(chref("button","%R?diff=%d",diffType))\
691 @ Show&nbsp;Whitespace&nbsp;Changes</a>
692 }else{
693 @ %z(chref("button","%R?diff=%d&w",diffType))Ignore&nbsp;Whitespace</a>
694 }
695 }
696 @ </div>
697 while( db_step(&q)==SQLITE_ROW ){
698 const char *zTreename = db_column_text(&q,0);
699 int isDeleted = db_column_int(&q, 1);
700 int isChnged = db_column_int(&q,2);
701 int isNew = db_column_int(&q,3);
@@ -678,37 +702,39 @@
702 int srcid = db_column_int(&q, 4);
703 int isLink = db_column_int(&q, 5);
704 const char *zUuid = db_column_text(&q, 6);
705 int showDiff = 1;
706
707 DCfg.diffFlags &= (~DIFF_FILE_MASK);
708 @ <div class='file-change-line'><span>
709 if( isDeleted ){
710 @ DELETED %h(zTreename)
711 DCfg.diffFlags |= DIFF_FILE_DELETED;
712 showDiff = 0;
713 }else if( file_access(zTreename, F_OK) ){
714 @ MISSING %h(zTreename)
715 showDiff = 0;
716 }else if( isNew ){
717 @ ADDED %h(zTreename)
718 DCfg.diffFlags |= DIFF_FILE_ADDED;
719 srcid = 0;
720 showDiff = 0;
721 }else if( isChnged==3 ){
722 @ ADDED_BY_MERGE %h(zTreename)
723 DCfg.diffFlags |= DIFF_FILE_ADDED;
724 srcid = 0;
725 showDiff = 0;
726 }else if( isChnged==5 ){
727 @ ADDED_BY_INTEGRATE %h(zTreename)
728 DCfg.diffFlags |= DIFF_FILE_ADDED;
729 srcid = 0;
730 showDiff = 0;
731 }else{
732 @ CHANGED %h(zTreename)
733 }
734 @ </span></div>
735 if( showDiff && pCfg ){
736 Blob old, new;
737 if( !isLink != !file_islink(zTreename) ){
738 @ %s(DIFF_CANNOT_COMPUTE_SYMLINK)
739 continue;
740 }
@@ -724,10 +750,11 @@
750 blob_reset(&old);
751 blob_reset(&new);
752 }
753 }
754 db_finalize(&q);
755 // @ </div> <!-- ap-002 -->
756 append_diff_javascript(diffType);
757 style_finish_page();
758 }
759
760 /*
@@ -756,11 +783,10 @@
783 const char *zParent; /* Hash of the parent check-in (if any) */
784 const char *zRe; /* regex parameter */
785 ReCompiled *pRe = 0; /* regex */
786 const char *zW; /* URL param for ignoring whitespace */
787 const char *zPage = "vinfo"; /* Page that shows diffs */
 
788 const char *zBrName; /* Branch name */
789 DiffConfig DCfg,*pCfg; /* Type of diff */
790
791 login_check_credentials();
792 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
@@ -1026,27 +1052,21 @@
1052 @ <div class="sectionmenu info-changes-menu">
1053 /* ^^^ .info-changes-menu is used by diff scroll sync */
1054 pCfg = construct_diff_flags(diffType, &DCfg);
1055 DCfg.pRe = pRe;
1056 zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
 
 
 
 
 
 
1057 if( diffType!=1 ){
1058 /* Class "smb-unified-diff" required by the fossil.diff.js script. */
1059 const char *zBtnClass = "button smb-unified-diff";
1060 @ %z(chref(zBtnClass,"%R/%s/%T?diff=1%s",zPage,zName,zW))\
1061 @ Unified&nbsp;Diff</a>
1062 }
1063 if( diffType!=2 ){
1064 /* Class "smb-side-by-side-diff" required by the fossil.diff.js script. */
1065 const char *zBtnClass = "button smb-side-by-side-diff";
1066 @ %z(chref(zBtnClass,"%R/%s/%T?diff=2%s",zPage,zName,zW))\
1067 @ Side-by-Side&nbsp;Diff</a>
1068 }
1069 if( diffType!=0 ){
1070 if( *zW ){
1071 @ %z(chref("button","%R/%s/%T",zPage,zName))
1072 @ Show&nbsp;Whitespace&nbsp;Changes</a>
@@ -1416,13 +1436,10 @@
1436 cgi_check_for_malice();
1437 style_set_current_feature("vdiff");
1438 if( zBranch==0 ){
1439 style_submenu_element("Path", "%R/timeline?me=%T&you=%T", zFrom, zTo);
1440 }
 
 
 
1441 if( diffType!=2 ){
1442 style_submenu_element("Side-by-Side Diff", "%R/vdiff?diff=2&%b%b", &qp,
1443 &qpGlob);
1444 }
1445 if( diffType!=1 ) {
1446
+46 -29
--- src/info.c
+++ src/info.c
@@ -622,16 +622,19 @@
622622
char *zHostname;
623623
char *zCwd;
624624
int diffType; /* 0: no diff, 1: unified, 2: side-by-side */
625625
DiffConfig DCfg,*pCfg; /* Diff details */
626626
const char *zHome; /* Home directory */
627
+ const char *zW; /* The "w" query parameter */
628
+ int nChng; /* Number of changes */
627629
Stmt q;
628630
629631
if( !db_open_local(0) || !cgi_is_loopback(g.zIpAddr) ){
630
- cgi_redirect("%R/home");
632
+ cgi_redirectf("%R/home");
631633
return;
632634
}
635
+ file_chdir(g.zLocalRoot, 0);
633636
diffType = preferred_diff_type();
634637
pCfg = construct_diff_flags(diffType, &DCfg);
635638
vid = db_lget_int("checkout", 0);
636639
db_unprotect(PROTECT_ALL);
637640
vfile_check_signature(vid, CKSIG_ENOTFILE);
@@ -650,11 +653,14 @@
650653
style_header("Checkout Status: %h on %h", zCwd, zHostname);
651654
}else{
652655
style_header("Checkout Status: %h", zCwd);
653656
}
654657
render_checkin_context(vid, 0, 0, 0);
655
- if( pCfg==0 ){
658
+ nChng = db_int(0, "SELECT count(*) FROM vfile"
659
+ " WHERE vid=%d AND (deleted OR chnged OR rid==0)", vid);
660
+ if( nChng==0 ){
661
+ @ <p>No uncommitted changes</p>
656662
style_finish_page();
657663
return;
658664
}
659665
db_prepare(&q,
660666
/* 0 1 2 3 4 5 6 */
@@ -663,15 +669,33 @@
663669
" WHERE vid=%d"
664670
" AND (deleted OR chnged OR rid==0)"
665671
" ORDER BY pathname /*scan*/",
666672
vid
667673
);
668
- if( pCfg->diffFlags & DIFF_SIDEBYSIDE ){
669
- pCfg->diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
674
+ if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
675
+ DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
670676
}else{
671
- pCfg->diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
677
+ DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
672678
}
679
+ @ <hr>
680
+ @ <div class="sectionmenu info-changes-menu">
681
+ zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
682
+ if( diffType!=1 ){
683
+ @ %z(chref("button","%R?diff=1%s",zW))Unified&nbsp;Diff</a>
684
+ }
685
+ if( diffType!=2 ){
686
+ @ %z(chref("button","%R?diff=2%s",zW))Side-by-Side&nbsp;Diff</a>
687
+ }
688
+ if( diffType!=0 ){
689
+ if( *zW ){
690
+ @ %z(chref("button","%R?diff=%d",diffType))\
691
+ @ Show&nbsp;Whitespace&nbsp;Changes</a>
692
+ }else{
693
+ @ %z(chref("button","%R?diff=%d&w",diffType))Ignore&nbsp;Whitespace</a>
694
+ }
695
+ }
696
+ @ </div>
673697
while( db_step(&q)==SQLITE_ROW ){
674698
const char *zTreename = db_column_text(&q,0);
675699
int isDeleted = db_column_int(&q, 1);
676700
int isChnged = db_column_int(&q,2);
677701
int isNew = db_column_int(&q,3);
@@ -678,37 +702,39 @@
678702
int srcid = db_column_int(&q, 4);
679703
int isLink = db_column_int(&q, 5);
680704
const char *zUuid = db_column_text(&q, 6);
681705
int showDiff = 1;
682706
683
- pCfg->diffFlags &= (~DIFF_FILE_MASK);
707
+ DCfg.diffFlags &= (~DIFF_FILE_MASK);
708
+ @ <div class='file-change-line'><span>
684709
if( isDeleted ){
685
- @ <p>DELETED %h(zTreename)</p>
686
- pCfg->diffFlags |= DIFF_FILE_DELETED;
710
+ @ DELETED %h(zTreename)
711
+ DCfg.diffFlags |= DIFF_FILE_DELETED;
687712
showDiff = 0;
688713
}else if( file_access(zTreename, F_OK) ){
689
- @ <p>MISSING %h(zTreename)</p>
714
+ @ MISSING %h(zTreename)
690715
showDiff = 0;
691716
}else if( isNew ){
692
- @ <p>ADDED %h(zTreename)</p>
693
- pCfg->diffFlags |= DIFF_FILE_ADDED;
717
+ @ ADDED %h(zTreename)
718
+ DCfg.diffFlags |= DIFF_FILE_ADDED;
694719
srcid = 0;
695720
showDiff = 0;
696721
}else if( isChnged==3 ){
697
- @ <p>ADDED_BY_MERGE %h(zTreename)</p>
698
- pCfg->diffFlags |= DIFF_FILE_ADDED;
722
+ @ ADDED_BY_MERGE %h(zTreename)
723
+ DCfg.diffFlags |= DIFF_FILE_ADDED;
699724
srcid = 0;
700725
showDiff = 0;
701726
}else if( isChnged==5 ){
702
- @ <p>ADDED_BY_INTEGRATE %h(zTreename)</p>
703
- pCfg->diffFlags |= DIFF_FILE_ADDED;
727
+ @ ADDED_BY_INTEGRATE %h(zTreename)
728
+ DCfg.diffFlags |= DIFF_FILE_ADDED;
704729
srcid = 0;
705730
showDiff = 0;
706731
}else{
707
- @ <p>CHANGED %h(zTreename)</p>
732
+ @ CHANGED %h(zTreename)
708733
}
709
- if( showDiff ){
734
+ @ </span></div>
735
+ if( showDiff && pCfg ){
710736
Blob old, new;
711737
if( !isLink != !file_islink(zTreename) ){
712738
@ %s(DIFF_CANNOT_COMPUTE_SYMLINK)
713739
continue;
714740
}
@@ -724,10 +750,11 @@
724750
blob_reset(&old);
725751
blob_reset(&new);
726752
}
727753
}
728754
db_finalize(&q);
755
+ // @ </div> <!-- ap-002 -->
729756
append_diff_javascript(diffType);
730757
style_finish_page();
731758
}
732759
733760
/*
@@ -756,11 +783,10 @@
756783
const char *zParent; /* Hash of the parent check-in (if any) */
757784
const char *zRe; /* regex parameter */
758785
ReCompiled *pRe = 0; /* regex */
759786
const char *zW; /* URL param for ignoring whitespace */
760787
const char *zPage = "vinfo"; /* Page that shows diffs */
761
- const char *zPageHide = "ci"; /* Page that hides diffs */
762788
const char *zBrName; /* Branch name */
763789
DiffConfig DCfg,*pCfg; /* Type of diff */
764790
765791
login_check_credentials();
766792
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
@@ -1026,27 +1052,21 @@
10261052
@ <div class="sectionmenu info-changes-menu">
10271053
/* ^^^ .info-changes-menu is used by diff scroll sync */
10281054
pCfg = construct_diff_flags(diffType, &DCfg);
10291055
DCfg.pRe = pRe;
10301056
zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
1031
- if( diffType!=0 ){
1032
- /* Class "smb-hide-diff" required by the fossil.diff.js script. */
1033
- const char *zBtnClass = "button smb-hide-diff";
1034
- @ %z(chref(zBtnClass,"%R/%s/%T?diff=0",zPageHide,zName))\
1035
- @ Hide&nbsp;Diffs</a>
1036
- }
10371057
if( diffType!=1 ){
10381058
/* Class "smb-unified-diff" required by the fossil.diff.js script. */
10391059
const char *zBtnClass = "button smb-unified-diff";
10401060
@ %z(chref(zBtnClass,"%R/%s/%T?diff=1%s",zPage,zName,zW))\
1041
- @ Unified&nbsp;Diffs</a>
1061
+ @ Unified&nbsp;Diff</a>
10421062
}
10431063
if( diffType!=2 ){
10441064
/* Class "smb-side-by-side-diff" required by the fossil.diff.js script. */
10451065
const char *zBtnClass = "button smb-side-by-side-diff";
10461066
@ %z(chref(zBtnClass,"%R/%s/%T?diff=2%s",zPage,zName,zW))\
1047
- @ Side-by-Side&nbsp;Diffs</a>
1067
+ @ Side-by-Side&nbsp;Diff</a>
10481068
}
10491069
if( diffType!=0 ){
10501070
if( *zW ){
10511071
@ %z(chref("button","%R/%s/%T",zPage,zName))
10521072
@ Show&nbsp;Whitespace&nbsp;Changes</a>
@@ -1416,13 +1436,10 @@
14161436
cgi_check_for_malice();
14171437
style_set_current_feature("vdiff");
14181438
if( zBranch==0 ){
14191439
style_submenu_element("Path", "%R/timeline?me=%T&you=%T", zFrom, zTo);
14201440
}
1421
- if( diffType!=0 ){
1422
- style_submenu_element("Hide Diff", "%R/vdiff?diff=0&%b%b", &qp, &qpGlob);
1423
- }
14241441
if( diffType!=2 ){
14251442
style_submenu_element("Side-by-Side Diff", "%R/vdiff?diff=2&%b%b", &qp,
14261443
&qpGlob);
14271444
}
14281445
if( diffType!=1 ) {
14291446
--- src/info.c
+++ src/info.c
@@ -622,16 +622,19 @@
622 char *zHostname;
623 char *zCwd;
624 int diffType; /* 0: no diff, 1: unified, 2: side-by-side */
625 DiffConfig DCfg,*pCfg; /* Diff details */
626 const char *zHome; /* Home directory */
 
 
627 Stmt q;
628
629 if( !db_open_local(0) || !cgi_is_loopback(g.zIpAddr) ){
630 cgi_redirect("%R/home");
631 return;
632 }
 
633 diffType = preferred_diff_type();
634 pCfg = construct_diff_flags(diffType, &DCfg);
635 vid = db_lget_int("checkout", 0);
636 db_unprotect(PROTECT_ALL);
637 vfile_check_signature(vid, CKSIG_ENOTFILE);
@@ -650,11 +653,14 @@
650 style_header("Checkout Status: %h on %h", zCwd, zHostname);
651 }else{
652 style_header("Checkout Status: %h", zCwd);
653 }
654 render_checkin_context(vid, 0, 0, 0);
655 if( pCfg==0 ){
 
 
 
656 style_finish_page();
657 return;
658 }
659 db_prepare(&q,
660 /* 0 1 2 3 4 5 6 */
@@ -663,15 +669,33 @@
663 " WHERE vid=%d"
664 " AND (deleted OR chnged OR rid==0)"
665 " ORDER BY pathname /*scan*/",
666 vid
667 );
668 if( pCfg->diffFlags & DIFF_SIDEBYSIDE ){
669 pCfg->diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
670 }else{
671 pCfg->diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
672 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
673 while( db_step(&q)==SQLITE_ROW ){
674 const char *zTreename = db_column_text(&q,0);
675 int isDeleted = db_column_int(&q, 1);
676 int isChnged = db_column_int(&q,2);
677 int isNew = db_column_int(&q,3);
@@ -678,37 +702,39 @@
678 int srcid = db_column_int(&q, 4);
679 int isLink = db_column_int(&q, 5);
680 const char *zUuid = db_column_text(&q, 6);
681 int showDiff = 1;
682
683 pCfg->diffFlags &= (~DIFF_FILE_MASK);
 
684 if( isDeleted ){
685 @ <p>DELETED %h(zTreename)</p>
686 pCfg->diffFlags |= DIFF_FILE_DELETED;
687 showDiff = 0;
688 }else if( file_access(zTreename, F_OK) ){
689 @ <p>MISSING %h(zTreename)</p>
690 showDiff = 0;
691 }else if( isNew ){
692 @ <p>ADDED %h(zTreename)</p>
693 pCfg->diffFlags |= DIFF_FILE_ADDED;
694 srcid = 0;
695 showDiff = 0;
696 }else if( isChnged==3 ){
697 @ <p>ADDED_BY_MERGE %h(zTreename)</p>
698 pCfg->diffFlags |= DIFF_FILE_ADDED;
699 srcid = 0;
700 showDiff = 0;
701 }else if( isChnged==5 ){
702 @ <p>ADDED_BY_INTEGRATE %h(zTreename)</p>
703 pCfg->diffFlags |= DIFF_FILE_ADDED;
704 srcid = 0;
705 showDiff = 0;
706 }else{
707 @ <p>CHANGED %h(zTreename)</p>
708 }
709 if( showDiff ){
 
710 Blob old, new;
711 if( !isLink != !file_islink(zTreename) ){
712 @ %s(DIFF_CANNOT_COMPUTE_SYMLINK)
713 continue;
714 }
@@ -724,10 +750,11 @@
724 blob_reset(&old);
725 blob_reset(&new);
726 }
727 }
728 db_finalize(&q);
 
729 append_diff_javascript(diffType);
730 style_finish_page();
731 }
732
733 /*
@@ -756,11 +783,10 @@
756 const char *zParent; /* Hash of the parent check-in (if any) */
757 const char *zRe; /* regex parameter */
758 ReCompiled *pRe = 0; /* regex */
759 const char *zW; /* URL param for ignoring whitespace */
760 const char *zPage = "vinfo"; /* Page that shows diffs */
761 const char *zPageHide = "ci"; /* Page that hides diffs */
762 const char *zBrName; /* Branch name */
763 DiffConfig DCfg,*pCfg; /* Type of diff */
764
765 login_check_credentials();
766 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
@@ -1026,27 +1052,21 @@
1026 @ <div class="sectionmenu info-changes-menu">
1027 /* ^^^ .info-changes-menu is used by diff scroll sync */
1028 pCfg = construct_diff_flags(diffType, &DCfg);
1029 DCfg.pRe = pRe;
1030 zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
1031 if( diffType!=0 ){
1032 /* Class "smb-hide-diff" required by the fossil.diff.js script. */
1033 const char *zBtnClass = "button smb-hide-diff";
1034 @ %z(chref(zBtnClass,"%R/%s/%T?diff=0",zPageHide,zName))\
1035 @ Hide&nbsp;Diffs</a>
1036 }
1037 if( diffType!=1 ){
1038 /* Class "smb-unified-diff" required by the fossil.diff.js script. */
1039 const char *zBtnClass = "button smb-unified-diff";
1040 @ %z(chref(zBtnClass,"%R/%s/%T?diff=1%s",zPage,zName,zW))\
1041 @ Unified&nbsp;Diffs</a>
1042 }
1043 if( diffType!=2 ){
1044 /* Class "smb-side-by-side-diff" required by the fossil.diff.js script. */
1045 const char *zBtnClass = "button smb-side-by-side-diff";
1046 @ %z(chref(zBtnClass,"%R/%s/%T?diff=2%s",zPage,zName,zW))\
1047 @ Side-by-Side&nbsp;Diffs</a>
1048 }
1049 if( diffType!=0 ){
1050 if( *zW ){
1051 @ %z(chref("button","%R/%s/%T",zPage,zName))
1052 @ Show&nbsp;Whitespace&nbsp;Changes</a>
@@ -1416,13 +1436,10 @@
1416 cgi_check_for_malice();
1417 style_set_current_feature("vdiff");
1418 if( zBranch==0 ){
1419 style_submenu_element("Path", "%R/timeline?me=%T&you=%T", zFrom, zTo);
1420 }
1421 if( diffType!=0 ){
1422 style_submenu_element("Hide Diff", "%R/vdiff?diff=0&%b%b", &qp, &qpGlob);
1423 }
1424 if( diffType!=2 ){
1425 style_submenu_element("Side-by-Side Diff", "%R/vdiff?diff=2&%b%b", &qp,
1426 &qpGlob);
1427 }
1428 if( diffType!=1 ) {
1429
--- src/info.c
+++ src/info.c
@@ -622,16 +622,19 @@
622 char *zHostname;
623 char *zCwd;
624 int diffType; /* 0: no diff, 1: unified, 2: side-by-side */
625 DiffConfig DCfg,*pCfg; /* Diff details */
626 const char *zHome; /* Home directory */
627 const char *zW; /* The "w" query parameter */
628 int nChng; /* Number of changes */
629 Stmt q;
630
631 if( !db_open_local(0) || !cgi_is_loopback(g.zIpAddr) ){
632 cgi_redirectf("%R/home");
633 return;
634 }
635 file_chdir(g.zLocalRoot, 0);
636 diffType = preferred_diff_type();
637 pCfg = construct_diff_flags(diffType, &DCfg);
638 vid = db_lget_int("checkout", 0);
639 db_unprotect(PROTECT_ALL);
640 vfile_check_signature(vid, CKSIG_ENOTFILE);
@@ -650,11 +653,14 @@
653 style_header("Checkout Status: %h on %h", zCwd, zHostname);
654 }else{
655 style_header("Checkout Status: %h", zCwd);
656 }
657 render_checkin_context(vid, 0, 0, 0);
658 nChng = db_int(0, "SELECT count(*) FROM vfile"
659 " WHERE vid=%d AND (deleted OR chnged OR rid==0)", vid);
660 if( nChng==0 ){
661 @ <p>No uncommitted changes</p>
662 style_finish_page();
663 return;
664 }
665 db_prepare(&q,
666 /* 0 1 2 3 4 5 6 */
@@ -663,15 +669,33 @@
669 " WHERE vid=%d"
670 " AND (deleted OR chnged OR rid==0)"
671 " ORDER BY pathname /*scan*/",
672 vid
673 );
674 if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
675 DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
676 }else{
677 DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
678 }
679 @ <hr>
680 @ <div class="sectionmenu info-changes-menu">
681 zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
682 if( diffType!=1 ){
683 @ %z(chref("button","%R?diff=1%s",zW))Unified&nbsp;Diff</a>
684 }
685 if( diffType!=2 ){
686 @ %z(chref("button","%R?diff=2%s",zW))Side-by-Side&nbsp;Diff</a>
687 }
688 if( diffType!=0 ){
689 if( *zW ){
690 @ %z(chref("button","%R?diff=%d",diffType))\
691 @ Show&nbsp;Whitespace&nbsp;Changes</a>
692 }else{
693 @ %z(chref("button","%R?diff=%d&w",diffType))Ignore&nbsp;Whitespace</a>
694 }
695 }
696 @ </div>
697 while( db_step(&q)==SQLITE_ROW ){
698 const char *zTreename = db_column_text(&q,0);
699 int isDeleted = db_column_int(&q, 1);
700 int isChnged = db_column_int(&q,2);
701 int isNew = db_column_int(&q,3);
@@ -678,37 +702,39 @@
702 int srcid = db_column_int(&q, 4);
703 int isLink = db_column_int(&q, 5);
704 const char *zUuid = db_column_text(&q, 6);
705 int showDiff = 1;
706
707 DCfg.diffFlags &= (~DIFF_FILE_MASK);
708 @ <div class='file-change-line'><span>
709 if( isDeleted ){
710 @ DELETED %h(zTreename)
711 DCfg.diffFlags |= DIFF_FILE_DELETED;
712 showDiff = 0;
713 }else if( file_access(zTreename, F_OK) ){
714 @ MISSING %h(zTreename)
715 showDiff = 0;
716 }else if( isNew ){
717 @ ADDED %h(zTreename)
718 DCfg.diffFlags |= DIFF_FILE_ADDED;
719 srcid = 0;
720 showDiff = 0;
721 }else if( isChnged==3 ){
722 @ ADDED_BY_MERGE %h(zTreename)
723 DCfg.diffFlags |= DIFF_FILE_ADDED;
724 srcid = 0;
725 showDiff = 0;
726 }else if( isChnged==5 ){
727 @ ADDED_BY_INTEGRATE %h(zTreename)
728 DCfg.diffFlags |= DIFF_FILE_ADDED;
729 srcid = 0;
730 showDiff = 0;
731 }else{
732 @ CHANGED %h(zTreename)
733 }
734 @ </span></div>
735 if( showDiff && pCfg ){
736 Blob old, new;
737 if( !isLink != !file_islink(zTreename) ){
738 @ %s(DIFF_CANNOT_COMPUTE_SYMLINK)
739 continue;
740 }
@@ -724,10 +750,11 @@
750 blob_reset(&old);
751 blob_reset(&new);
752 }
753 }
754 db_finalize(&q);
755 // @ </div> <!-- ap-002 -->
756 append_diff_javascript(diffType);
757 style_finish_page();
758 }
759
760 /*
@@ -756,11 +783,10 @@
783 const char *zParent; /* Hash of the parent check-in (if any) */
784 const char *zRe; /* regex parameter */
785 ReCompiled *pRe = 0; /* regex */
786 const char *zW; /* URL param for ignoring whitespace */
787 const char *zPage = "vinfo"; /* Page that shows diffs */
 
788 const char *zBrName; /* Branch name */
789 DiffConfig DCfg,*pCfg; /* Type of diff */
790
791 login_check_credentials();
792 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
@@ -1026,27 +1052,21 @@
1052 @ <div class="sectionmenu info-changes-menu">
1053 /* ^^^ .info-changes-menu is used by diff scroll sync */
1054 pCfg = construct_diff_flags(diffType, &DCfg);
1055 DCfg.pRe = pRe;
1056 zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
 
 
 
 
 
 
1057 if( diffType!=1 ){
1058 /* Class "smb-unified-diff" required by the fossil.diff.js script. */
1059 const char *zBtnClass = "button smb-unified-diff";
1060 @ %z(chref(zBtnClass,"%R/%s/%T?diff=1%s",zPage,zName,zW))\
1061 @ Unified&nbsp;Diff</a>
1062 }
1063 if( diffType!=2 ){
1064 /* Class "smb-side-by-side-diff" required by the fossil.diff.js script. */
1065 const char *zBtnClass = "button smb-side-by-side-diff";
1066 @ %z(chref(zBtnClass,"%R/%s/%T?diff=2%s",zPage,zName,zW))\
1067 @ Side-by-Side&nbsp;Diff</a>
1068 }
1069 if( diffType!=0 ){
1070 if( *zW ){
1071 @ %z(chref("button","%R/%s/%T",zPage,zName))
1072 @ Show&nbsp;Whitespace&nbsp;Changes</a>
@@ -1416,13 +1436,10 @@
1436 cgi_check_for_malice();
1437 style_set_current_feature("vdiff");
1438 if( zBranch==0 ){
1439 style_submenu_element("Path", "%R/timeline?me=%T&you=%T", zFrom, zTo);
1440 }
 
 
 
1441 if( diffType!=2 ){
1442 style_submenu_element("Side-by-Side Diff", "%R/vdiff?diff=2&%b%b", &qp,
1443 &qpGlob);
1444 }
1445 if( diffType!=1 ) {
1446

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button