Fossil SCM

Minor improvements in fossil.dom and touchups in code which can make use of them. Found a way around using innerHTML assignment for rendering pikchr content. (TODO: genericize that and apply it to wikiedit/fileedit previews.)

stephan 2020-09-12 09:47 trunk
Commit 74791f8873a98ec4b024edbc7257f78211bbf189f7ab4802c31685dd999282b9
+70 -22
--- src/fossil.dom.js
+++ src/fossil.dom.js
@@ -83,29 +83,33 @@
8383
*/
8484
dom.label = function(forElem, text){
8585
const rc = document.createElement('label');
8686
if(forElem){
8787
if(forElem instanceof HTMLElement){
88
- forElem = dom.attr(forElem, 'id');
88
+ forElem = this.attr(forElem, 'id');
8989
}
9090
dom.attr(rc, 'for', forElem);
9191
}
92
- if(text) dom.append(rc, text);
92
+ if(text) this.append(rc, text);
9393
return rc;
9494
};
95
+ /**
96
+ Returns an IMG element with an optional src
97
+ attribute value.
98
+ */
9599
dom.img = function(src){
96
- const e = dom.create('img');
100
+ const e = this.create('img');
97101
if(src) e.setAttribute('src',src);
98102
return e;
99103
};
100104
/**
101105
Creates and returns a new anchor element with the given
102106
optional href and label. If label===true then href is used
103107
as the label.
104108
*/
105109
dom.a = function(href,label){
106
- const e = dom.create('a');
110
+ const e = this.create('a');
107111
if(href) e.setAttribute('href',href);
108112
if(label) e.appendChild(dom.text(true===label ? href : label));
109113
return e;
110114
};
111115
dom.hr = dom.createElemFactory('hr');
@@ -114,23 +118,65 @@
114118
dom.button = function(label){
115119
const b = this.create('button');
116120
if(label) b.appendChild(this.text(label));
117121
return b;
118122
};
119
- dom.textarea = dom.createElemFactory('textarea');
123
+ /**
124
+ Returns a TEXTAREA element.
125
+
126
+ Usages:
127
+
128
+ ([boolean readonly = false])
129
+ (non-boolean rows[,cols[,readonly=false]])
130
+
131
+ Each of the rows/cols/readonly attributes is only set if it is
132
+ truthy.
133
+ */
134
+ dom.textarea = function(){
135
+ const rc = this.create('textarea');
136
+ let rows, cols, readonly;
137
+ if(1===arguments.length){
138
+ if('boolean'===typeof arguments[0]){
139
+ readonly = !!arguments[0];
140
+ }else{
141
+ rows = arguments[0];
142
+ }
143
+ }else if(arguments.length){
144
+ rows = arguments[0];
145
+ cols = arguments[1];
146
+ readonly = arguments[2];
147
+ }
148
+ if(rows) rc.setAttribute('rows',rows);
149
+ if(cols) rc.setAttribute('cols', cols);
150
+ if(readonly) rc.setAttribute('readonly', true);
151
+ return rc;
152
+ };
153
+
154
+ /**
155
+ Returns a new SELECT element.
156
+ */
120157
dom.select = dom.createElemFactory('select');
158
+
121159
/**
122
- Returns an OPTION element with the given value and label
123
- text (which defaults to the value).
124
-
125
- May be called as (value), (selectElement), (selectElement,
126
- value), (value, label) or (selectElement, value,
127
- label). The latter appends the new element to the given
128
- SELECT element.
129
-
130
- If the value has the undefined value then it is NOT
131
- assigned as the option element's value.
160
+ Returns an OPTION element with the given value and label text
161
+ (which defaults to the value).
162
+
163
+ Usage:
164
+
165
+ (value[, label])
166
+ (selectElement [,value [,label = value]])
167
+
168
+ Any forms taking a SELECT element append the new element to the
169
+ given SELECT element.
170
+
171
+ If any label is falsy and the value is not then the value is used
172
+ as the label. A non-falsy label value may have any type suitable
173
+ for passing as the 2nd argument to dom.append().
174
+
175
+ If the value has the undefined value then it is NOT assigned as
176
+ the option element's value and no label is set unless it has a
177
+ non-undefined value.
132178
*/
133179
dom.option = function(value,label){
134180
const a = arguments;
135181
var sel;
136182
if(1==a.length){
@@ -155,10 +201,12 @@
155201
}
156202
const o = this.create('option');
157203
if(undefined !== value){
158204
o.value = value;
159205
this.append(o, this.text(label || value));
206
+ }else if(undefined !== label){
207
+ this.append(o, label);
160208
}
161209
if(sel) this.append(sel, o);
162210
return o;
163211
};
164212
dom.h = function(level){
@@ -196,24 +244,24 @@
196244
dom.tfoot = dom.createElemFactoryWithOptionalParent('tfoot');
197245
dom.tr = dom.createElemFactoryWithOptionalParent('tr');
198246
dom.td = dom.createElemFactoryWithOptionalParent('td');
199247
dom.th = dom.createElemFactoryWithOptionalParent('th');
200248
201
-
202249
/**
203
- Creates and returns a FIELDSET element, optionaly with a
204
- LEGEND element added to it.
250
+ Creates and returns a FIELDSET element, optionaly with a LEGEND
251
+ element added to it. If legendText is an HTMLElement then it is
252
+ appended as-is, else it is assume (if truthy) to be a value
253
+ suitable for passing to dom.append(aLegendElement,...).
205254
*/
206255
dom.fieldset = function(legendText){
207256
const fs = this.create('fieldset');
208257
if(legendText){
209258
this.append(
210259
fs,
211
- this.append(
212
- this.create('legend'),
213
- legendText
214
- )
260
+ (legendText instanceof HTMLElement)
261
+ ? legendText
262
+ : this.append(this.create('legend'),legendText)
215263
);
216264
}
217265
return fs;
218266
};
219267
220268
--- src/fossil.dom.js
+++ src/fossil.dom.js
@@ -83,29 +83,33 @@
83 */
84 dom.label = function(forElem, text){
85 const rc = document.createElement('label');
86 if(forElem){
87 if(forElem instanceof HTMLElement){
88 forElem = dom.attr(forElem, 'id');
89 }
90 dom.attr(rc, 'for', forElem);
91 }
92 if(text) dom.append(rc, text);
93 return rc;
94 };
 
 
 
 
95 dom.img = function(src){
96 const e = dom.create('img');
97 if(src) e.setAttribute('src',src);
98 return e;
99 };
100 /**
101 Creates and returns a new anchor element with the given
102 optional href and label. If label===true then href is used
103 as the label.
104 */
105 dom.a = function(href,label){
106 const e = dom.create('a');
107 if(href) e.setAttribute('href',href);
108 if(label) e.appendChild(dom.text(true===label ? href : label));
109 return e;
110 };
111 dom.hr = dom.createElemFactory('hr');
@@ -114,23 +118,65 @@
114 dom.button = function(label){
115 const b = this.create('button');
116 if(label) b.appendChild(this.text(label));
117 return b;
118 };
119 dom.textarea = dom.createElemFactory('textarea');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120 dom.select = dom.createElemFactory('select');
 
121 /**
122 Returns an OPTION element with the given value and label
123 text (which defaults to the value).
124
125 May be called as (value), (selectElement), (selectElement,
126 value), (value, label) or (selectElement, value,
127 label). The latter appends the new element to the given
128 SELECT element.
129
130 If the value has the undefined value then it is NOT
131 assigned as the option element's value.
 
 
 
 
 
 
 
 
132 */
133 dom.option = function(value,label){
134 const a = arguments;
135 var sel;
136 if(1==a.length){
@@ -155,10 +201,12 @@
155 }
156 const o = this.create('option');
157 if(undefined !== value){
158 o.value = value;
159 this.append(o, this.text(label || value));
 
 
160 }
161 if(sel) this.append(sel, o);
162 return o;
163 };
164 dom.h = function(level){
@@ -196,24 +244,24 @@
196 dom.tfoot = dom.createElemFactoryWithOptionalParent('tfoot');
197 dom.tr = dom.createElemFactoryWithOptionalParent('tr');
198 dom.td = dom.createElemFactoryWithOptionalParent('td');
199 dom.th = dom.createElemFactoryWithOptionalParent('th');
200
201
202 /**
203 Creates and returns a FIELDSET element, optionaly with a
204 LEGEND element added to it.
 
 
205 */
206 dom.fieldset = function(legendText){
207 const fs = this.create('fieldset');
208 if(legendText){
209 this.append(
210 fs,
211 this.append(
212 this.create('legend'),
213 legendText
214 )
215 );
216 }
217 return fs;
218 };
219
220
--- src/fossil.dom.js
+++ src/fossil.dom.js
@@ -83,29 +83,33 @@
83 */
84 dom.label = function(forElem, text){
85 const rc = document.createElement('label');
86 if(forElem){
87 if(forElem instanceof HTMLElement){
88 forElem = this.attr(forElem, 'id');
89 }
90 dom.attr(rc, 'for', forElem);
91 }
92 if(text) this.append(rc, text);
93 return rc;
94 };
95 /**
96 Returns an IMG element with an optional src
97 attribute value.
98 */
99 dom.img = function(src){
100 const e = this.create('img');
101 if(src) e.setAttribute('src',src);
102 return e;
103 };
104 /**
105 Creates and returns a new anchor element with the given
106 optional href and label. If label===true then href is used
107 as the label.
108 */
109 dom.a = function(href,label){
110 const e = this.create('a');
111 if(href) e.setAttribute('href',href);
112 if(label) e.appendChild(dom.text(true===label ? href : label));
113 return e;
114 };
115 dom.hr = dom.createElemFactory('hr');
@@ -114,23 +118,65 @@
118 dom.button = function(label){
119 const b = this.create('button');
120 if(label) b.appendChild(this.text(label));
121 return b;
122 };
123 /**
124 Returns a TEXTAREA element.
125
126 Usages:
127
128 ([boolean readonly = false])
129 (non-boolean rows[,cols[,readonly=false]])
130
131 Each of the rows/cols/readonly attributes is only set if it is
132 truthy.
133 */
134 dom.textarea = function(){
135 const rc = this.create('textarea');
136 let rows, cols, readonly;
137 if(1===arguments.length){
138 if('boolean'===typeof arguments[0]){
139 readonly = !!arguments[0];
140 }else{
141 rows = arguments[0];
142 }
143 }else if(arguments.length){
144 rows = arguments[0];
145 cols = arguments[1];
146 readonly = arguments[2];
147 }
148 if(rows) rc.setAttribute('rows',rows);
149 if(cols) rc.setAttribute('cols', cols);
150 if(readonly) rc.setAttribute('readonly', true);
151 return rc;
152 };
153
154 /**
155 Returns a new SELECT element.
156 */
157 dom.select = dom.createElemFactory('select');
158
159 /**
160 Returns an OPTION element with the given value and label text
161 (which defaults to the value).
162
163 Usage:
164
165 (value[, label])
166 (selectElement [,value [,label = value]])
167
168 Any forms taking a SELECT element append the new element to the
169 given SELECT element.
170
171 If any label is falsy and the value is not then the value is used
172 as the label. A non-falsy label value may have any type suitable
173 for passing as the 2nd argument to dom.append().
174
175 If the value has the undefined value then it is NOT assigned as
176 the option element's value and no label is set unless it has a
177 non-undefined value.
178 */
179 dom.option = function(value,label){
180 const a = arguments;
181 var sel;
182 if(1==a.length){
@@ -155,10 +201,12 @@
201 }
202 const o = this.create('option');
203 if(undefined !== value){
204 o.value = value;
205 this.append(o, this.text(label || value));
206 }else if(undefined !== label){
207 this.append(o, label);
208 }
209 if(sel) this.append(sel, o);
210 return o;
211 };
212 dom.h = function(level){
@@ -196,24 +244,24 @@
244 dom.tfoot = dom.createElemFactoryWithOptionalParent('tfoot');
245 dom.tr = dom.createElemFactoryWithOptionalParent('tr');
246 dom.td = dom.createElemFactoryWithOptionalParent('td');
247 dom.th = dom.createElemFactoryWithOptionalParent('th');
248
 
249 /**
250 Creates and returns a FIELDSET element, optionaly with a LEGEND
251 element added to it. If legendText is an HTMLElement then it is
252 appended as-is, else it is assume (if truthy) to be a value
253 suitable for passing to dom.append(aLegendElement,...).
254 */
255 dom.fieldset = function(legendText){
256 const fs = this.create('fieldset');
257 if(legendText){
258 this.append(
259 fs,
260 (legendText instanceof HTMLElement)
261 ? legendText
262 : this.append(this.create('legend'),legendText)
 
263 );
264 }
265 return fs;
266 };
267
268
--- src/fossil.page.fileedit.js
+++ src/fossil.page.fileedit.js
@@ -480,11 +480,11 @@
480480
D.append(D.code(),
481481
F.storage.storageImplName()),
482482
"):",
483483
btnHelp, sel, btnClear);
484484
F.helpButtonlets.setup(btnHelp);
485
- D.option(D.disable(sel), "(empty)");
485
+ D.option(D.disable(sel), undefined, "(empty)");
486486
F.page.addEventListener('fileedit-stash-updated',(e)=>this.updateList(e.detail));
487487
F.page.addEventListener('fileedit-file-loaded',(e)=>this.updateList($stash, e.detail));
488488
sel.addEventListener('change',function(e){
489489
const opt = this.selectedOptions[0];
490490
if(opt && opt._finfo) P.loadFile(opt._finfo);
@@ -543,11 +543,11 @@
543543
});
544544
const self = this;
545545
D.clearElement(this.e.select);
546546
if(0===ilist.length){
547547
D.addClass(this.e.btnClear, 'hidden');
548
- D.option(D.disable(this.e.select),"No local edits");
548
+ D.option(D.disable(this.e.select),undefined,"No local edits");
549549
return;
550550
}
551551
D.enable(this.e.select);
552552
D.removeClass(this.e.btnClear, 'hidden');
553553
D.disable(D.option(this.e.select,0,"Select a local edit..."));
554554
--- src/fossil.page.fileedit.js
+++ src/fossil.page.fileedit.js
@@ -480,11 +480,11 @@
480 D.append(D.code(),
481 F.storage.storageImplName()),
482 "):",
483 btnHelp, sel, btnClear);
484 F.helpButtonlets.setup(btnHelp);
485 D.option(D.disable(sel), "(empty)");
486 F.page.addEventListener('fileedit-stash-updated',(e)=>this.updateList(e.detail));
487 F.page.addEventListener('fileedit-file-loaded',(e)=>this.updateList($stash, e.detail));
488 sel.addEventListener('change',function(e){
489 const opt = this.selectedOptions[0];
490 if(opt && opt._finfo) P.loadFile(opt._finfo);
@@ -543,11 +543,11 @@
543 });
544 const self = this;
545 D.clearElement(this.e.select);
546 if(0===ilist.length){
547 D.addClass(this.e.btnClear, 'hidden');
548 D.option(D.disable(this.e.select),"No local edits");
549 return;
550 }
551 D.enable(this.e.select);
552 D.removeClass(this.e.btnClear, 'hidden');
553 D.disable(D.option(this.e.select,0,"Select a local edit..."));
554
--- src/fossil.page.fileedit.js
+++ src/fossil.page.fileedit.js
@@ -480,11 +480,11 @@
480 D.append(D.code(),
481 F.storage.storageImplName()),
482 "):",
483 btnHelp, sel, btnClear);
484 F.helpButtonlets.setup(btnHelp);
485 D.option(D.disable(sel), undefined, "(empty)");
486 F.page.addEventListener('fileedit-stash-updated',(e)=>this.updateList(e.detail));
487 F.page.addEventListener('fileedit-file-loaded',(e)=>this.updateList($stash, e.detail));
488 sel.addEventListener('change',function(e){
489 const opt = this.selectedOptions[0];
490 if(opt && opt._finfo) P.loadFile(opt._finfo);
@@ -543,11 +543,11 @@
543 });
544 const self = this;
545 D.clearElement(this.e.select);
546 if(0===ilist.length){
547 D.addClass(this.e.btnClear, 'hidden');
548 D.option(D.disable(this.e.select),undefined,"No local edits");
549 return;
550 }
551 D.enable(this.e.select);
552 D.removeClass(this.e.btnClear, 'hidden');
553 D.disable(D.option(this.e.select,0,"Select a local edit..."));
554
--- src/fossil.page.pikchrshow.js
+++ src/fossil.page.pikchrshow.js
@@ -28,12 +28,11 @@
2828
),
2929
previewModeLabel: D.label('preview-copy-button'),
3030
btnSubmit: E('#pikchr-submit-preview'),
3131
cbDarkMode: E('#flipcolors-wrapper > input[type=checkbox]'),
3232
taContent: E('#content'),
33
- taPreviewText: D.attr(D.textarea(), 'rows', 20, 'cols', 60,
34
- 'readonly', true),
33
+ taPreviewText: D.textarea(20,0,true),
3534
uiControls: E('#pikchrshow-controls'),
3635
previewModeToggle: D.button("Preview mode"),
3736
markupAlignDefault: D.attr(D.radio('markup-align','',true),
3837
'id','markup-align-default'),
3938
markupAlignCenter: D.attr(D.radio('markup-align','center'),
@@ -257,14 +256,25 @@
257256
f.getMarkupAlignmentClass = function(){
258257
if(P.e.markupAlignCenter.checked) return ' center';
259258
else if(P.e.markupAlignIndent.checked) return ' indent';
260259
return '';
261260
};
261
+ /* Parses P.response.raw as HTML without using innerHTML. */
262
+ f.parseResponse = function(tgt){
263
+ let childs;
264
+ if(P.response.raw){
265
+ const newNode = new DOMParser().parseFromString(P.response.raw, 'text/html');
266
+ childs = newNode.documentElement.querySelectorAll('body > *');
267
+ }else{
268
+ childs = [];
269
+ }
270
+ D.append(D.clearElement(tgt), childs);
271
+ };
262272
}
263273
const preTgt = this.e.previewTarget;
264274
if(this.response.isError){
265
- preTgt.innerHTML = this.response.raw;
275
+ f.parseResponse(preTgt);
266276
D.addClass(preTgt, 'error');
267277
this.e.previewModeLabel.innerText = "Error";
268278
return;
269279
}
270280
D.removeClass(preTgt, 'error');
@@ -274,30 +284,30 @@
274284
let label;
275285
switch(this.previewMode){
276286
case 0:
277287
label = "SVG";
278288
f.showMarkupAlignment(false);
279
- preTgt.innerHTML = this.response.raw;
289
+ f.parseResponse(preTgt);
280290
this.e.taPreviewText.value =
281291
this.response.raw.replace(f.rxNonce, '')/*for copy button*/;
282292
break;
283293
case 1:
284294
label = "Markdown";
285295
f.showMarkupAlignment(true);
286296
this.e.taPreviewText.value = [
287297
'```pikchr'+f.getMarkupAlignmentClass(),
288
- this.response.inputText, '```'
298
+ this.response.inputText.trim(), '```'
289299
].join('\n');
290300
D.append(D.clearElement(preTgt), this.e.taPreviewText);
291301
break;
292302
case 2:
293303
label = "Fossil wiki";
294304
f.showMarkupAlignment(true);
295305
this.e.taPreviewText.value = [
296306
'<verbatim type="pikchr',
297307
f.getMarkupAlignmentClass(),
298
- '">', this.response.inputText, '</verbatim>'
308
+ '">', this.response.inputText.trim(), '</verbatim>'
299309
].join('');
300310
D.append(D.clearElement(preTgt), this.e.taPreviewText);
301311
break;
302312
case 3:
303313
label = "Raw SVG";
304314
--- src/fossil.page.pikchrshow.js
+++ src/fossil.page.pikchrshow.js
@@ -28,12 +28,11 @@
28 ),
29 previewModeLabel: D.label('preview-copy-button'),
30 btnSubmit: E('#pikchr-submit-preview'),
31 cbDarkMode: E('#flipcolors-wrapper > input[type=checkbox]'),
32 taContent: E('#content'),
33 taPreviewText: D.attr(D.textarea(), 'rows', 20, 'cols', 60,
34 'readonly', true),
35 uiControls: E('#pikchrshow-controls'),
36 previewModeToggle: D.button("Preview mode"),
37 markupAlignDefault: D.attr(D.radio('markup-align','',true),
38 'id','markup-align-default'),
39 markupAlignCenter: D.attr(D.radio('markup-align','center'),
@@ -257,14 +256,25 @@
257 f.getMarkupAlignmentClass = function(){
258 if(P.e.markupAlignCenter.checked) return ' center';
259 else if(P.e.markupAlignIndent.checked) return ' indent';
260 return '';
261 };
 
 
 
 
 
 
 
 
 
 
 
262 }
263 const preTgt = this.e.previewTarget;
264 if(this.response.isError){
265 preTgt.innerHTML = this.response.raw;
266 D.addClass(preTgt, 'error');
267 this.e.previewModeLabel.innerText = "Error";
268 return;
269 }
270 D.removeClass(preTgt, 'error');
@@ -274,30 +284,30 @@
274 let label;
275 switch(this.previewMode){
276 case 0:
277 label = "SVG";
278 f.showMarkupAlignment(false);
279 preTgt.innerHTML = this.response.raw;
280 this.e.taPreviewText.value =
281 this.response.raw.replace(f.rxNonce, '')/*for copy button*/;
282 break;
283 case 1:
284 label = "Markdown";
285 f.showMarkupAlignment(true);
286 this.e.taPreviewText.value = [
287 '```pikchr'+f.getMarkupAlignmentClass(),
288 this.response.inputText, '```'
289 ].join('\n');
290 D.append(D.clearElement(preTgt), this.e.taPreviewText);
291 break;
292 case 2:
293 label = "Fossil wiki";
294 f.showMarkupAlignment(true);
295 this.e.taPreviewText.value = [
296 '<verbatim type="pikchr',
297 f.getMarkupAlignmentClass(),
298 '">', this.response.inputText, '</verbatim>'
299 ].join('');
300 D.append(D.clearElement(preTgt), this.e.taPreviewText);
301 break;
302 case 3:
303 label = "Raw SVG";
304
--- src/fossil.page.pikchrshow.js
+++ src/fossil.page.pikchrshow.js
@@ -28,12 +28,11 @@
28 ),
29 previewModeLabel: D.label('preview-copy-button'),
30 btnSubmit: E('#pikchr-submit-preview'),
31 cbDarkMode: E('#flipcolors-wrapper > input[type=checkbox]'),
32 taContent: E('#content'),
33 taPreviewText: D.textarea(20,0,true),
 
34 uiControls: E('#pikchrshow-controls'),
35 previewModeToggle: D.button("Preview mode"),
36 markupAlignDefault: D.attr(D.radio('markup-align','',true),
37 'id','markup-align-default'),
38 markupAlignCenter: D.attr(D.radio('markup-align','center'),
@@ -257,14 +256,25 @@
256 f.getMarkupAlignmentClass = function(){
257 if(P.e.markupAlignCenter.checked) return ' center';
258 else if(P.e.markupAlignIndent.checked) return ' indent';
259 return '';
260 };
261 /* Parses P.response.raw as HTML without using innerHTML. */
262 f.parseResponse = function(tgt){
263 let childs;
264 if(P.response.raw){
265 const newNode = new DOMParser().parseFromString(P.response.raw, 'text/html');
266 childs = newNode.documentElement.querySelectorAll('body > *');
267 }else{
268 childs = [];
269 }
270 D.append(D.clearElement(tgt), childs);
271 };
272 }
273 const preTgt = this.e.previewTarget;
274 if(this.response.isError){
275 f.parseResponse(preTgt);
276 D.addClass(preTgt, 'error');
277 this.e.previewModeLabel.innerText = "Error";
278 return;
279 }
280 D.removeClass(preTgt, 'error');
@@ -274,30 +284,30 @@
284 let label;
285 switch(this.previewMode){
286 case 0:
287 label = "SVG";
288 f.showMarkupAlignment(false);
289 f.parseResponse(preTgt);
290 this.e.taPreviewText.value =
291 this.response.raw.replace(f.rxNonce, '')/*for copy button*/;
292 break;
293 case 1:
294 label = "Markdown";
295 f.showMarkupAlignment(true);
296 this.e.taPreviewText.value = [
297 '```pikchr'+f.getMarkupAlignmentClass(),
298 this.response.inputText.trim(), '```'
299 ].join('\n');
300 D.append(D.clearElement(preTgt), this.e.taPreviewText);
301 break;
302 case 2:
303 label = "Fossil wiki";
304 f.showMarkupAlignment(true);
305 this.e.taPreviewText.value = [
306 '<verbatim type="pikchr',
307 f.getMarkupAlignmentClass(),
308 '">', this.response.inputText.trim(), '</verbatim>'
309 ].join('');
310 D.append(D.clearElement(preTgt), this.e.taPreviewText);
311 break;
312 case 3:
313 label = "Raw SVG";
314
--- src/fossil.page.wikiedit.js
+++ src/fossil.page.wikiedit.js
@@ -553,11 +553,11 @@
553553
parentElem,
554554
D.append(D.fieldset("Select a page to edit"),
555555
sel)
556556
);
557557
D.attr(sel, 'size', 12);
558
- D.option(D.disable(D.clearElement(sel)), "Loading...");
558
+ D.option(D.disable(D.clearElement(sel)), undefined, "Loading...");
559559
560560
/** Set up filter checkboxes for the various types
561561
of wiki pages... */
562562
const fsFilter = D.addClass(D.fieldset("Page types"),"page-types-list"),
563563
fsFilterBody = D.div(),
@@ -703,11 +703,11 @@
703703
D.append(D.code(),
704704
F.storage.storageImplName()),
705705
"):",
706706
btnHelp, sel, btnClear);
707707
F.helpButtonlets.setup(btnHelp);
708
- D.option(D.disable(sel), "(empty)");
708
+ D.option(D.disable(sel), undefined, "(empty)");
709709
P.addEventListener('wiki-stash-updated',(e)=>this.updateList(e.detail));
710710
P.addEventListener('wiki-page-loaded',(e)=>this.updateList($stash, e.detail));
711711
sel.addEventListener('change',function(e){
712712
const opt = this.selectedOptions[0];
713713
if(opt && opt._winfo) P.loadPage(opt._winfo);
@@ -758,11 +758,11 @@
758758
});
759759
const self = this;
760760
D.clearElement(this.e.select);
761761
if(0===ilist.length){
762762
D.addClass(this.e.btnClear, 'hidden');
763
- D.option(D.disable(this.e.select),"No local edits");
763
+ D.option(D.disable(this.e.select),undefined,"No local edits");
764764
return;
765765
}
766766
D.enable(this.e.select);
767767
if(true){
768768
/* The problem with this Clear button is that it allows the
@@ -769,11 +769,11 @@
769769
user to nuke a non-empty newly-added page without the
770770
failsafe confirmation we have if they use
771771
P.e.btnReload. Not yet sure how best to resolve that. */
772772
D.removeClass(this.e.btnClear, 'hidden');
773773
}
774
- D.disable(D.option(this.e.select,0,"Select a local edit..."));
774
+ D.disable(D.option(this.e.select,undefined,"Select a local edit..."));
775775
const currentWinfo = theWinfo || P.winfo || {name:''};
776776
ilist.sort(f.compare).forEach(function(winfo,n){
777777
const key = stasher.indexKey(winfo),
778778
rev = winfo.version || '';
779779
const opt = D.option(
780780
--- src/fossil.page.wikiedit.js
+++ src/fossil.page.wikiedit.js
@@ -553,11 +553,11 @@
553 parentElem,
554 D.append(D.fieldset("Select a page to edit"),
555 sel)
556 );
557 D.attr(sel, 'size', 12);
558 D.option(D.disable(D.clearElement(sel)), "Loading...");
559
560 /** Set up filter checkboxes for the various types
561 of wiki pages... */
562 const fsFilter = D.addClass(D.fieldset("Page types"),"page-types-list"),
563 fsFilterBody = D.div(),
@@ -703,11 +703,11 @@
703 D.append(D.code(),
704 F.storage.storageImplName()),
705 "):",
706 btnHelp, sel, btnClear);
707 F.helpButtonlets.setup(btnHelp);
708 D.option(D.disable(sel), "(empty)");
709 P.addEventListener('wiki-stash-updated',(e)=>this.updateList(e.detail));
710 P.addEventListener('wiki-page-loaded',(e)=>this.updateList($stash, e.detail));
711 sel.addEventListener('change',function(e){
712 const opt = this.selectedOptions[0];
713 if(opt && opt._winfo) P.loadPage(opt._winfo);
@@ -758,11 +758,11 @@
758 });
759 const self = this;
760 D.clearElement(this.e.select);
761 if(0===ilist.length){
762 D.addClass(this.e.btnClear, 'hidden');
763 D.option(D.disable(this.e.select),"No local edits");
764 return;
765 }
766 D.enable(this.e.select);
767 if(true){
768 /* The problem with this Clear button is that it allows the
@@ -769,11 +769,11 @@
769 user to nuke a non-empty newly-added page without the
770 failsafe confirmation we have if they use
771 P.e.btnReload. Not yet sure how best to resolve that. */
772 D.removeClass(this.e.btnClear, 'hidden');
773 }
774 D.disable(D.option(this.e.select,0,"Select a local edit..."));
775 const currentWinfo = theWinfo || P.winfo || {name:''};
776 ilist.sort(f.compare).forEach(function(winfo,n){
777 const key = stasher.indexKey(winfo),
778 rev = winfo.version || '';
779 const opt = D.option(
780
--- src/fossil.page.wikiedit.js
+++ src/fossil.page.wikiedit.js
@@ -553,11 +553,11 @@
553 parentElem,
554 D.append(D.fieldset("Select a page to edit"),
555 sel)
556 );
557 D.attr(sel, 'size', 12);
558 D.option(D.disable(D.clearElement(sel)), undefined, "Loading...");
559
560 /** Set up filter checkboxes for the various types
561 of wiki pages... */
562 const fsFilter = D.addClass(D.fieldset("Page types"),"page-types-list"),
563 fsFilterBody = D.div(),
@@ -703,11 +703,11 @@
703 D.append(D.code(),
704 F.storage.storageImplName()),
705 "):",
706 btnHelp, sel, btnClear);
707 F.helpButtonlets.setup(btnHelp);
708 D.option(D.disable(sel), undefined, "(empty)");
709 P.addEventListener('wiki-stash-updated',(e)=>this.updateList(e.detail));
710 P.addEventListener('wiki-page-loaded',(e)=>this.updateList($stash, e.detail));
711 sel.addEventListener('change',function(e){
712 const opt = this.selectedOptions[0];
713 if(opt && opt._winfo) P.loadPage(opt._winfo);
@@ -758,11 +758,11 @@
758 });
759 const self = this;
760 D.clearElement(this.e.select);
761 if(0===ilist.length){
762 D.addClass(this.e.btnClear, 'hidden');
763 D.option(D.disable(this.e.select),undefined,"No local edits");
764 return;
765 }
766 D.enable(this.e.select);
767 if(true){
768 /* The problem with this Clear button is that it allows the
@@ -769,11 +769,11 @@
769 user to nuke a non-empty newly-added page without the
770 failsafe confirmation we have if they use
771 P.e.btnReload. Not yet sure how best to resolve that. */
772 D.removeClass(this.e.btnClear, 'hidden');
773 }
774 D.disable(D.option(this.e.select,undefined,"Select a local edit..."));
775 const currentWinfo = theWinfo || P.winfo || {name:''};
776 ilist.sort(f.compare).forEach(function(winfo,n){
777 const key = stasher.indexKey(winfo),
778 rev = winfo.version || '';
779 const opt = D.option(
780

Keyboard Shortcuts

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