Fossil SCM

Re-added the editor font size selector. Added a button to discard/reload edits, but it's too easy to activate by accident, so it's disabled until we have a common confirmation mechanism in place. Added timestamp to fossil.message() and fossil.error() output.

stephan 2020-05-05 23:54 fileedit-ajaxify
Commit 25dfd243a11e77f5be2eafc10acaeda790f8afb20d449ee985e8b64213364334
+21 -10
--- src/fileedit.c
+++ src/fileedit.c
@@ -1587,14 +1587,34 @@
15871587
{
15881588
CX("<div id='fileedit-tab-content' "
15891589
"data-tab-parent='fileedit-tabs' "
15901590
"data-tab-label='File Content'"
15911591
">");
1592
+ CX("<div class='fileedit-options flex-container row'>");
1593
+ if(0){
1594
+ /* Discard/reload button. Leave this out until we have a
1595
+ ** nice way of offering confirmation, e.g. like the old
1596
+ ** jQuery.confirmer plugin which required a 2nd click of the
1597
+ ** button within X seconds to confirm. Right now it's simply
1598
+ ** to easy to tap by accident. */
1599
+ CX("<button class='fileedit-content-reload'>Discard &amp; Reload"
1600
+ "</button>");
1601
+ }
1602
+ style_select_list_int("select-font-size",
1603
+ "editor_font_size", "Editor Font Size",
1604
+ NULL/*tooltip*/,
1605
+ 100,
1606
+ "100%", 100, "125%", 125,
1607
+ "150%", 150, "175%", 175,
1608
+ "200%", 200, NULL);
1609
+ CX("</div>");
1610
+ CX("<div class='flex-container row'>");
15921611
CX("<textarea name='content' id='fileedit-content-editor' "
15931612
"rows='20' cols='80'>");
15941613
CX("Loading...");
1595
- CX("</textarea>\n");
1614
+ CX("</textarea>");
1615
+ CX("</div>"/*textarea wrapper*/);
15961616
CX("</div>"/*#tab-file-content*/);
15971617
}
15981618
15991619
/****** Preview tab ******/
16001620
{
@@ -1732,19 +1752,10 @@
17321752
? 2 : 0),
17331753
"Inherit", 0,
17341754
"Unix", 1,
17351755
"Windows", 2,
17361756
NULL);
1737
-#if 0
1738
- style_select_list_int("select-font-size",
1739
- "editor_font_size", "Editor Font Size",
1740
- NULL/*tooltip*/,
1741
- 100,
1742
- "100%", 100, "125%", 125,
1743
- "150%", 150, "175%", 175,
1744
- "200%", 200, NULL);
1745
-#endif
17461757
CX("</div>"/*checkboxes*/);
17471758
}
17481759
17491760
{ /******* Comment *******/
17501761
CX("<fieldset class='fileedit-options'>"
17511762
--- src/fileedit.c
+++ src/fileedit.c
@@ -1587,14 +1587,34 @@
1587 {
1588 CX("<div id='fileedit-tab-content' "
1589 "data-tab-parent='fileedit-tabs' "
1590 "data-tab-label='File Content'"
1591 ">");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1592 CX("<textarea name='content' id='fileedit-content-editor' "
1593 "rows='20' cols='80'>");
1594 CX("Loading...");
1595 CX("</textarea>\n");
 
1596 CX("</div>"/*#tab-file-content*/);
1597 }
1598
1599 /****** Preview tab ******/
1600 {
@@ -1732,19 +1752,10 @@
1732 ? 2 : 0),
1733 "Inherit", 0,
1734 "Unix", 1,
1735 "Windows", 2,
1736 NULL);
1737 #if 0
1738 style_select_list_int("select-font-size",
1739 "editor_font_size", "Editor Font Size",
1740 NULL/*tooltip*/,
1741 100,
1742 "100%", 100, "125%", 125,
1743 "150%", 150, "175%", 175,
1744 "200%", 200, NULL);
1745 #endif
1746 CX("</div>"/*checkboxes*/);
1747 }
1748
1749 { /******* Comment *******/
1750 CX("<fieldset class='fileedit-options'>"
1751
--- src/fileedit.c
+++ src/fileedit.c
@@ -1587,14 +1587,34 @@
1587 {
1588 CX("<div id='fileedit-tab-content' "
1589 "data-tab-parent='fileedit-tabs' "
1590 "data-tab-label='File Content'"
1591 ">");
1592 CX("<div class='fileedit-options flex-container row'>");
1593 if(0){
1594 /* Discard/reload button. Leave this out until we have a
1595 ** nice way of offering confirmation, e.g. like the old
1596 ** jQuery.confirmer plugin which required a 2nd click of the
1597 ** button within X seconds to confirm. Right now it's simply
1598 ** to easy to tap by accident. */
1599 CX("<button class='fileedit-content-reload'>Discard &amp; Reload"
1600 "</button>");
1601 }
1602 style_select_list_int("select-font-size",
1603 "editor_font_size", "Editor Font Size",
1604 NULL/*tooltip*/,
1605 100,
1606 "100%", 100, "125%", 125,
1607 "150%", 150, "175%", 175,
1608 "200%", 200, NULL);
1609 CX("</div>");
1610 CX("<div class='flex-container row'>");
1611 CX("<textarea name='content' id='fileedit-content-editor' "
1612 "rows='20' cols='80'>");
1613 CX("Loading...");
1614 CX("</textarea>");
1615 CX("</div>"/*textarea wrapper*/);
1616 CX("</div>"/*#tab-file-content*/);
1617 }
1618
1619 /****** Preview tab ******/
1620 {
@@ -1732,19 +1752,10 @@
1752 ? 2 : 0),
1753 "Inherit", 0,
1754 "Unix", 1,
1755 "Windows", 2,
1756 NULL);
 
 
 
 
 
 
 
 
 
1757 CX("</div>"/*checkboxes*/);
1758 }
1759
1760 { /******* Comment *******/
1761 CX("<fieldset class='fileedit-options'>"
1762
--- src/fossil.bootstrap.js
+++ src/fossil.bootstrap.js
@@ -1,98 +1,111 @@
11
"use strict";
2
-/* Bootstrapping bits for the window.fossil object. Must be
3
- loaded after style.c:style_emit_script_tag() has initialized
4
- that object.
5
-*/
6
-
7
-/*
8
-** By default fossil.message() sends its arguments console.debug(). If
9
-** fossil.message.targetElement is set, it is assumed to be a DOM
10
-** element, its innerText gets assigned to the concatenation of all
11
-** arguments (with a space between each), and the CSS 'error' class is
12
-** removed from the object. Pass it a falsy value to clear the target
13
-** element.
14
-**
15
-** Returns this object.
16
-*/
17
-window.fossil.message = function f(msg){
18
- const args = Array.prototype.slice.call(arguments,0);
19
- const tgt = f.targetElement;
20
- if(tgt){
21
- tgt.classList.remove('error');
22
- tgt.innerText = args.join(' ');
23
- }
24
- else{
25
- args.unshift('Fossil status:');
26
- console.debug.apply(console,args);
27
- }
28
- return this;
29
-};
30
-/*
31
-** Set default message.targetElement to #fossil-status-bar, if found.
32
-*/
33
-window.fossil.message.targetElement =
34
- document.querySelector('#fossil-status-bar');
35
-/*
36
-** By default fossil.error() sends its first argument to
37
-** console.error(). If fossil.message.targetElement (yes,
38
-** fossil.message) is set, it adds the 'error' CSS class to
39
-** that element and sets its content as defined for message().
40
-**
41
-** Returns this object.
42
-*/
43
-window.fossil.error = function f(msg){
44
- const args = Array.prototype.slice.call(arguments,0);
45
- const tgt = window.fossil.message.targetElement;
46
- if(tgt){
47
- tgt.classList.add('error');
48
- tgt.innerText = args.join(' ');
49
- }
50
- else{
51
- args.unshift('Fossil error:');
52
- console.error.apply(console,args);
53
- }
54
- return this;
55
-};
56
-
57
-/**
58
- For each property in the given object, its key/value are encoded
59
- for use as URL parameters and the combined string is
60
- returned. e.g. {a:1,b:2} encodes to "a=1&b=2".
61
-
62
- If the 2nd argument is an array, each encoded element is appended
63
- to that array and tgtArray is returned. The above object would be
64
- appended as ['a','=','1','&','b','=','2']. This form is used for
65
- building up parameter lists before join('')ing the array to create
66
- the result string.
67
-*/
68
-window.fossil.encodeUrlArgs = function(obj,tgtArray){
69
- if(!obj) return '';
70
- const a = (tgtArray instanceof Array) ? tgtArray : [];
71
- let k, i = 0;
72
- for( k in obj ){
73
- if(i++) a.push('&');
74
- a.push(encodeURIComponent(k),
75
- '=',encodeURIComponent(obj[k]));
76
- }
77
- return a===tgtArray ? a : a.join('');
78
-};
79
-/**
80
- repoUrl( repoRelativePath [,urlParams] )
81
-
82
- Creates a URL by prepending this.rootPath to the given path
83
- (which must be relative from the top of the site, without a
84
- leading slash). If urlParams is a string, it must be
85
- paramters encoded in the form "key=val&key2=val2...", WITHOUT
86
- a leading '?'. If it's an object, all of its properties get
87
- appended to the URL in that form.
88
-*/
89
-window.fossil.repoUrl = function(path,urlParams){
90
- if(!urlParams) return this.rootPath+path;
91
- const url=[this.rootPath,path];
92
- url.push('?');
93
- if('string'===typeof urlParams) url.push(urlParams);
94
- else if('object'===typeof urlParams){
95
- this.encodeUrlArgs(urlParams, url);
96
- }
97
- return url.join('');
98
-};
2
+(function(global){
3
+ /* Bootstrapping bits for the global.fossil object. Must be
4
+ loaded after style.c:style_emit_script_tag() has initialized
5
+ that object.
6
+ */
7
+
8
+ const timestring = function f(){
9
+ if(!f.rx1){
10
+ f.rx1 = /\.\d+Z$/;
11
+ }
12
+ const d = new Date();
13
+ return d.toISOString().replace(f.rx1,'').split('T').join(' ');
14
+ };
15
+
16
+
17
+ /*
18
+ ** By default fossil.message() sends its arguments console.debug(). If
19
+ ** fossil.message.targetElement is set, it is assumed to be a DOM
20
+ ** element, its innerText gets assigned to the concatenation of all
21
+ ** arguments (with a space between each), and the CSS 'error' class is
22
+ ** removed from the object. Pass it a falsy value to clear the target
23
+ ** element.
24
+ **
25
+ ** Returns this object.
26
+ */
27
+ global.fossil.message = function f(msg){
28
+ const args = Array.prototype.slice.call(arguments,0);
29
+ const tgt = f.targetElement;
30
+ args.unshift(timestring()+' UTC:');
31
+ if(tgt){
32
+ tgt.classList.remove('error');
33
+ tgt.innerText = args.join(' ');
34
+ }
35
+ else{
36
+ args.unshift('Fossil status:');
37
+ console.debug.apply(console,args);
38
+ }
39
+ return this;
40
+ };
41
+ /*
42
+ ** Set default message.targetElement to #fossil-status-bar, if found.
43
+ */
44
+ global.fossil.message.targetElement =
45
+ document.querySelector('#fossil-status-bar');
46
+ /*
47
+ ** By default fossil.error() sends its first argument to
48
+ ** console.error(). If fossil.message.targetElement (yes,
49
+ ** fossil.message) is set, it adds the 'error' CSS class to
50
+ ** that element and sets its content as defined for message().
51
+ **
52
+ ** Returns this object.
53
+ */
54
+ global.fossil.error = function f(msg){
55
+ const args = Array.prototype.slice.call(arguments,0);
56
+ const tgt = global.fossil.message.targetElement;
57
+ args.unshift(timestring()+' UTC:');
58
+ if(tgt){
59
+ tgt.classList.add('error');
60
+ tgt.innerText = args.join(' ');
61
+ }
62
+ else{
63
+ args.unshift('Fossil error:');
64
+ console.error.apply(console,args);
65
+ }
66
+ return this;
67
+ };
68
+
69
+ /**
70
+ For each property in the given object, its key/value are encoded
71
+ for use as URL parameters and the combined string is
72
+ returned. e.g. {a:1,b:2} encodes to "a=1&b=2".
73
+
74
+ If the 2nd argument is an array, each encoded element is appended
75
+ to that array and tgtArray is returned. The above object would be
76
+ appended as ['a','=','1','&','b','=','2']. This form is used for
77
+ building up parameter lists before join('')ing the array to create
78
+ the result string.
79
+ */
80
+ global.fossil.encodeUrlArgs = function(obj,tgtArray){
81
+ if(!obj) return '';
82
+ const a = (tgtArray instanceof Array) ? tgtArray : [];
83
+ let k, i = 0;
84
+ for( k in obj ){
85
+ if(i++) a.push('&');
86
+ a.push(encodeURIComponent(k),
87
+ '=',encodeURIComponent(obj[k]));
88
+ }
89
+ return a===tgtArray ? a : a.join('');
90
+ };
91
+ /**
92
+ repoUrl( repoRelativePath [,urlParams] )
93
+
94
+ Creates a URL by prepending this.rootPath to the given path
95
+ (which must be relative from the top of the site, without a
96
+ leading slash). If urlParams is a string, it must be
97
+ paramters encoded in the form "key=val&key2=val2...", WITHOUT
98
+ a leading '?'. If it's an object, all of its properties get
99
+ appended to the URL in that form.
100
+ */
101
+ global.fossil.repoUrl = function(path,urlParams){
102
+ if(!urlParams) return this.rootPath+path;
103
+ const url=[this.rootPath,path];
104
+ url.push('?');
105
+ if('string'===typeof urlParams) url.push(urlParams);
106
+ else if('object'===typeof urlParams){
107
+ this.encodeUrlArgs(urlParams, url);
108
+ }
109
+ return url.join('');
110
+ };
111
+})(window);
99112
--- src/fossil.bootstrap.js
+++ src/fossil.bootstrap.js
@@ -1,98 +1,111 @@
1 "use strict";
2 /* Bootstrapping bits for the window.fossil object. Must be
3 loaded after style.c:style_emit_script_tag() has initialized
4 that object.
5 */
6
7 /*
8 ** By default fossil.message() sends its arguments console.debug(). If
9 ** fossil.message.targetElement is set, it is assumed to be a DOM
10 ** element, its innerText gets assigned to the concatenation of all
11 ** arguments (with a space between each), and the CSS 'error' class is
12 ** removed from the object. Pass it a falsy value to clear the target
13 ** element.
14 **
15 ** Returns this object.
16 */
17 window.fossil.message = function f(msg){
18 const args = Array.prototype.slice.call(arguments,0);
19 const tgt = f.targetElement;
20 if(tgt){
21 tgt.classList.remove('error');
22 tgt.innerText = args.join(' ');
23 }
24 else{
25 args.unshift('Fossil status:');
26 console.debug.apply(console,args);
27 }
28 return this;
29 };
30 /*
31 ** Set default message.targetElement to #fossil-status-bar, if found.
32 */
33 window.fossil.message.targetElement =
34 document.querySelector('#fossil-status-bar');
35 /*
36 ** By default fossil.error() sends its first argument to
37 ** console.error(). If fossil.message.targetElement (yes,
38 ** fossil.message) is set, it adds the 'error' CSS class to
39 ** that element and sets its content as defined for message().
40 **
41 ** Returns this object.
42 */
43 window.fossil.error = function f(msg){
44 const args = Array.prototype.slice.call(arguments,0);
45 const tgt = window.fossil.message.targetElement;
46 if(tgt){
47 tgt.classList.add('error');
48 tgt.innerText = args.join(' ');
49 }
50 else{
51 args.unshift('Fossil error:');
52 console.error.apply(console,args);
53 }
54 return this;
55 };
56
57 /**
58 For each property in the given object, its key/value are encoded
59 for use as URL parameters and the combined string is
60 returned. e.g. {a:1,b:2} encodes to "a=1&b=2".
61
62 If the 2nd argument is an array, each encoded element is appended
63 to that array and tgtArray is returned. The above object would be
64 appended as ['a','=','1','&','b','=','2']. This form is used for
65 building up parameter lists before join('')ing the array to create
66 the result string.
67 */
68 window.fossil.encodeUrlArgs = function(obj,tgtArray){
69 if(!obj) return '';
70 const a = (tgtArray instanceof Array) ? tgtArray : [];
71 let k, i = 0;
72 for( k in obj ){
73 if(i++) a.push('&');
74 a.push(encodeURIComponent(k),
75 '=',encodeURIComponent(obj[k]));
76 }
77 return a===tgtArray ? a : a.join('');
78 };
79 /**
80 repoUrl( repoRelativePath [,urlParams] )
81
82 Creates a URL by prepending this.rootPath to the given path
83 (which must be relative from the top of the site, without a
84 leading slash). If urlParams is a string, it must be
85 paramters encoded in the form "key=val&key2=val2...", WITHOUT
86 a leading '?'. If it's an object, all of its properties get
87 appended to the URL in that form.
88 */
89 window.fossil.repoUrl = function(path,urlParams){
90 if(!urlParams) return this.rootPath+path;
91 const url=[this.rootPath,path];
92 url.push('?');
93 if('string'===typeof urlParams) url.push(urlParams);
94 else if('object'===typeof urlParams){
95 this.encodeUrlArgs(urlParams, url);
96 }
97 return url.join('');
98 };
 
 
 
 
 
 
 
 
 
 
 
 
 
99
--- src/fossil.bootstrap.js
+++ src/fossil.bootstrap.js
@@ -1,98 +1,111 @@
1 "use strict";
2 (function(global){
3 /* Bootstrapping bits for the global.fossil object. Must be
4 loaded after style.c:style_emit_script_tag() has initialized
5 that object.
6 */
7
8 const timestring = function f(){
9 if(!f.rx1){
10 f.rx1 = /\.\d+Z$/;
11 }
12 const d = new Date();
13 return d.toISOString().replace(f.rx1,'').split('T').join(' ');
14 };
15
16
17 /*
18 ** By default fossil.message() sends its arguments console.debug(). If
19 ** fossil.message.targetElement is set, it is assumed to be a DOM
20 ** element, its innerText gets assigned to the concatenation of all
21 ** arguments (with a space between each), and the CSS 'error' class is
22 ** removed from the object. Pass it a falsy value to clear the target
23 ** element.
24 **
25 ** Returns this object.
26 */
27 global.fossil.message = function f(msg){
28 const args = Array.prototype.slice.call(arguments,0);
29 const tgt = f.targetElement;
30 args.unshift(timestring()+' UTC:');
31 if(tgt){
32 tgt.classList.remove('error');
33 tgt.innerText = args.join(' ');
34 }
35 else{
36 args.unshift('Fossil status:');
37 console.debug.apply(console,args);
38 }
39 return this;
40 };
41 /*
42 ** Set default message.targetElement to #fossil-status-bar, if found.
43 */
44 global.fossil.message.targetElement =
45 document.querySelector('#fossil-status-bar');
46 /*
47 ** By default fossil.error() sends its first argument to
48 ** console.error(). If fossil.message.targetElement (yes,
49 ** fossil.message) is set, it adds the 'error' CSS class to
50 ** that element and sets its content as defined for message().
51 **
52 ** Returns this object.
53 */
54 global.fossil.error = function f(msg){
55 const args = Array.prototype.slice.call(arguments,0);
56 const tgt = global.fossil.message.targetElement;
57 args.unshift(timestring()+' UTC:');
58 if(tgt){
59 tgt.classList.add('error');
60 tgt.innerText = args.join(' ');
61 }
62 else{
63 args.unshift('Fossil error:');
64 console.error.apply(console,args);
65 }
66 return this;
67 };
68
69 /**
70 For each property in the given object, its key/value are encoded
71 for use as URL parameters and the combined string is
72 returned. e.g. {a:1,b:2} encodes to "a=1&b=2".
73
74 If the 2nd argument is an array, each encoded element is appended
75 to that array and tgtArray is returned. The above object would be
76 appended as ['a','=','1','&','b','=','2']. This form is used for
77 building up parameter lists before join('')ing the array to create
78 the result string.
79 */
80 global.fossil.encodeUrlArgs = function(obj,tgtArray){
81 if(!obj) return '';
82 const a = (tgtArray instanceof Array) ? tgtArray : [];
83 let k, i = 0;
84 for( k in obj ){
85 if(i++) a.push('&');
86 a.push(encodeURIComponent(k),
87 '=',encodeURIComponent(obj[k]));
88 }
89 return a===tgtArray ? a : a.join('');
90 };
91 /**
92 repoUrl( repoRelativePath [,urlParams] )
93
94 Creates a URL by prepending this.rootPath to the given path
95 (which must be relative from the top of the site, without a
96 leading slash). If urlParams is a string, it must be
97 paramters encoded in the form "key=val&key2=val2...", WITHOUT
98 a leading '?'. If it's an object, all of its properties get
99 appended to the URL in that form.
100 */
101 global.fossil.repoUrl = function(path,urlParams){
102 if(!urlParams) return this.rootPath+path;
103 const url=[this.rootPath,path];
104 url.push('?');
105 if('string'===typeof urlParams) url.push(urlParams);
106 else if('object'===typeof urlParams){
107 this.encodeUrlArgs(urlParams, url);
108 }
109 return url.join('');
110 };
111 })(window);
112
--- src/fossil.page.fileedit.js
+++ src/fossil.page.fileedit.js
@@ -13,10 +13,12 @@
1313
taEditor: E('#fileedit-content-editor'),
1414
taComment: E('#fileedit-comment'),
1515
ajaxContentTarget: E('#ajax-target'),
1616
form: E('#fileedit-form'),
1717
btnCommit: E("#fileedit-btn-commit"),
18
+ btnReload: E("#fileedit-tab-content > .fileedit-options > "
19
+ +"button.fileedit-content-reload"),
1820
selectPreviewModeWrap: E('#select-preview-mode'),
1921
selectHtmlEmsWrap: E('#select-preview-html-ems'),
2022
selectEolWrap: E('#select-preview-html-ems'),
2123
cbLineNumbersWrap: E('#cb-line-numbers'),
2224
tabs:{
@@ -65,12 +67,17 @@
6567
);
6668
diffButtons.querySelector('button.unified').addEventListener(
6769
"click",(e)=>P.diff(false), false
6870
);
6971
P.e.btnCommit.addEventListener(
70
- "click",(e)=>stopEvent(e).commit(), false
72
+ "click",(e)=>P.commit(), false
7173
);
74
+ if(P.e.btnReload){
75
+ P.e.btnReload.addEventListener(
76
+ "click",(e)=>P.loadFile(), false
77
+ );
78
+ }
7279
/**
7380
Cosmetic: jump through some hoops to enable/disable
7481
certain preview options depending on the current
7582
preview mode...
7683
*/
@@ -149,12 +156,18 @@
149156
UI elements to reflect the loaded state.
150157
151158
Returns this object, noting that the load is async.
152159
*/
153160
F.page.loadFile = function(file,rev){
161
+ if(0===arguments.length){
162
+ if(!this.finfo) return this;
163
+ file = this.finfo.file;
164
+ rev = this.finfo.r;
165
+ }
154166
delete this.finfo;
155167
const self = this;
168
+ F.message("Loading content...");
156169
F.fetch('fileedit_content',{
157170
urlParams:{file:file,r:rev},
158171
onload:(r)=>{
159172
F.message('Loaded content.');
160173
self.e.taEditor.value = r;
161174
--- src/fossil.page.fileedit.js
+++ src/fossil.page.fileedit.js
@@ -13,10 +13,12 @@
13 taEditor: E('#fileedit-content-editor'),
14 taComment: E('#fileedit-comment'),
15 ajaxContentTarget: E('#ajax-target'),
16 form: E('#fileedit-form'),
17 btnCommit: E("#fileedit-btn-commit"),
 
 
18 selectPreviewModeWrap: E('#select-preview-mode'),
19 selectHtmlEmsWrap: E('#select-preview-html-ems'),
20 selectEolWrap: E('#select-preview-html-ems'),
21 cbLineNumbersWrap: E('#cb-line-numbers'),
22 tabs:{
@@ -65,12 +67,17 @@
65 );
66 diffButtons.querySelector('button.unified').addEventListener(
67 "click",(e)=>P.diff(false), false
68 );
69 P.e.btnCommit.addEventListener(
70 "click",(e)=>stopEvent(e).commit(), false
71 );
 
 
 
 
 
72 /**
73 Cosmetic: jump through some hoops to enable/disable
74 certain preview options depending on the current
75 preview mode...
76 */
@@ -149,12 +156,18 @@
149 UI elements to reflect the loaded state.
150
151 Returns this object, noting that the load is async.
152 */
153 F.page.loadFile = function(file,rev){
 
 
 
 
 
154 delete this.finfo;
155 const self = this;
 
156 F.fetch('fileedit_content',{
157 urlParams:{file:file,r:rev},
158 onload:(r)=>{
159 F.message('Loaded content.');
160 self.e.taEditor.value = r;
161
--- src/fossil.page.fileedit.js
+++ src/fossil.page.fileedit.js
@@ -13,10 +13,12 @@
13 taEditor: E('#fileedit-content-editor'),
14 taComment: E('#fileedit-comment'),
15 ajaxContentTarget: E('#ajax-target'),
16 form: E('#fileedit-form'),
17 btnCommit: E("#fileedit-btn-commit"),
18 btnReload: E("#fileedit-tab-content > .fileedit-options > "
19 +"button.fileedit-content-reload"),
20 selectPreviewModeWrap: E('#select-preview-mode'),
21 selectHtmlEmsWrap: E('#select-preview-html-ems'),
22 selectEolWrap: E('#select-preview-html-ems'),
23 cbLineNumbersWrap: E('#cb-line-numbers'),
24 tabs:{
@@ -65,12 +67,17 @@
67 );
68 diffButtons.querySelector('button.unified').addEventListener(
69 "click",(e)=>P.diff(false), false
70 );
71 P.e.btnCommit.addEventListener(
72 "click",(e)=>P.commit(), false
73 );
74 if(P.e.btnReload){
75 P.e.btnReload.addEventListener(
76 "click",(e)=>P.loadFile(), false
77 );
78 }
79 /**
80 Cosmetic: jump through some hoops to enable/disable
81 certain preview options depending on the current
82 preview mode...
83 */
@@ -149,12 +156,18 @@
156 UI elements to reflect the loaded state.
157
158 Returns this object, noting that the load is async.
159 */
160 F.page.loadFile = function(file,rev){
161 if(0===arguments.length){
162 if(!this.finfo) return this;
163 file = this.finfo.file;
164 rev = this.finfo.r;
165 }
166 delete this.finfo;
167 const self = this;
168 F.message("Loading content...");
169 F.fetch('fileedit_content',{
170 urlParams:{file:file,r:rev},
171 onload:(r)=>{
172 F.message('Loaded content.');
173 self.e.taEditor.value = r;
174

Keyboard Shortcuts

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