Fossil SCM

Inordinately much style/layout tweaking of the wysiwyg editor.

stephan 2020-08-30 15:58 wikiedit-wysiwyg-legacy
Commit a11abadd024d42d73ad75bd9d68105342b26f27dca9534399f1cfbca7787d4a1
--- src/fossil.page.wikiedit-wysiwyg-legacy.js
+++ src/fossil.page.wikiedit-wysiwyg-legacy.js
@@ -10,63 +10,78 @@
1010
'use strict';
1111
if(!F || !F.page || F.page.name!=='wikiedit') return;
1212
1313
const D = F.dom;
1414
15
+ ////////////////////////////////////////////////////////////////////////
16
+ // Install an app-specific stylesheet...
1517
(function(){
1618
const head = document.head || document.querySelector('head'),
1719
styleTag = document.createElement('style'),
1820
styleCSS = `
1921
.intLink { cursor: pointer; }
2022
img.intLink { border: 0; }
2123
#wysiwyg-container {
22
- max-width: calc(100% - 1em);
2324
display: flex;
2425
flex-direction: column;
26
+ max-width: 100% /* w/o this, toolbars don't wrap properly! */
2527
}
2628
#wysiwygBox {
2729
border: 1px #000000 solid;
2830
padding: 0 1em;
31
+ margin: 0;
2932
overflow: auto;
3033
min-height: 20em;
34
+}
35
+#wysiwygEditMode { /* wrapper for radio buttons */
36
+ border: 1px solid rgba(127,127,127,0.3);
37
+ border-radius: 0.25em;
38
+ padding: 0 0.35em 0 0.35em
39
+}
40
+#wysiwygEditMode > * {
41
+ vertical-align: text-top;
3142
}
3243
#wysiwygEditMode label { cursor: pointer; }
3344
#wysiwyg-toolbars {
3445
margin: 0 0 0.25em 0;
3546
display: flex;
3647
flex-wrap: wrap;
37
- flex-direction: row;
48
+ flex-direction: column;
3849
align-items: flex-start;
3950
}
4051
#wysiwyg-toolbars > * {
4152
margin: 0 0.5em 0.25em 0;
42
- align-self: center;
4353
}
4454
#wysiwyg-toolBar1, #wysiwyg-toolBar2 {
55
+ margin: 0 0.2em 0.2em 0;
56
+ display: flex;
57
+ flex-flow: row wrap;
4558
}
4659
#wysiwyg-toolBar1 > * { /* formatting buttons */
47
- margin: 0 0.2em 0.2em 0;
60
+ vertical-align: middle;
61
+ margin: 0 0.25em 0.25em 0;
4862
}
4963
#wysiwyg-toolBar2 > * { /* icons */
50
- margin: 0 0.2em 0.2em 0;
5164
border: 1px solid rgba(127,127,127,0.3);
52
- align-self: end;
65
+ vertical-align: baseline;
66
+ margin: 0.1em;
5367
}
5468
`;
5569
head.appendChild(styleTag);
5670
/* Adapted from https://stackoverflow.com/a/524721 */
5771
styleTag.type = 'text/css';
5872
D.append(styleTag, styleCSS);
5973
})();
6074
61
- const outerContainer = D.attr(D.div(), 'id', 'wysiwyg-container');
62
-
63
- const toolbars = D.attr(D.div(), 'id', 'wysiwyg-toolbars'),
75
+ const outerContainer = D.attr(D.div(), 'id', 'wysiwyg-container'),
76
+ toolbars = D.attr(D.div(), 'id', 'wysiwyg-toolbars'),
6477
toolbar1 = D.attr(D.div(), 'id', 'wysiwyg-toolBar1'),
65
- toolbar2 = D.attr(D.div(), 'id', 'wysiwyg-toolBar2');
66
- D.append(outerContainer,
67
- D.append(toolbars, toolbar1, toolbar2));
78
+ // ^^^ formatting options
79
+ toolbar2 = D.attr(D.div(), 'id', 'wysiwyg-toolBar2')
80
+ // ^^^^ action icon buttons
81
+ ;
82
+ D.append(outerContainer, D.append(toolbars, toolbar1, toolbar2));
6883
6984
/** Returns a function which simplifies adding a list of options
7085
to the given select element. See below for example usage. */
7186
const addOptions = function(select){
7287
return function ff(value, label){
@@ -74,26 +89,43 @@
7489
return ff;
7590
};
7691
};
7792
7893
////////////////////////////////////////////////////////////////////////
79
- // Edit mode selection button
80
- var select;
81
- const selectEditMode = select = D.attr(
82
- D.attr(D.select(), 'id', 'wysiwygEditMode'),
83
- 'size',
84
- 1
85
- );
86
- D.append(toolbar1, select);
87
- addOptions(select)(
88
- 0, "WYSIWYG")(
89
- 1, "Raw HTML");
90
- select.selectedIndex = 0;
94
+ // Edit mode selection (radio buttons).
95
+ const radio0 =
96
+ D.attr(
97
+ D.input('radio'),
98
+ 'name','wysiwyg-mode',
99
+ 'id', 'wysiwyg-mode-0',
100
+ 'value',0,
101
+ 'checked',true),
102
+ radio1 = D.attr(
103
+ D.input('radio'),
104
+ 'id','wysiwyg-mode-1',
105
+ 'name','wysiwyg-mode',
106
+ 'value',1),
107
+ radios = D.append(
108
+ D.attr(D.span(), 'id', 'wysiwygEditMode'),
109
+ radio0, D.append(
110
+ D.attr(D.label(), 'for', 'wysiwyg-mode-0'),
111
+ "WYSIWYG"
112
+ ),
113
+ radio1, D.append(
114
+ D.attr(D.label(), 'for', 'wysiwyg-mode-1'),
115
+ "Raw HTML"
116
+ )
117
+ );
118
+ D.append(toolbar1, radios);
119
+ const radioHandler = function(){setDocMode(+this.value)};
120
+ radio0.addEventListener('change',radioHandler, false);
121
+ radio1.addEventListener('change',radioHandler, false);
91122
92123
93124
////////////////////////////////////////////////////////////////////////
94125
// Text formatting options...
126
+ var select;
95127
select = D.addClass(D.select(), 'format');
96128
select.dataset.format = "formatblock";
97129
D.append(toolbar1, select);
98130
addOptions(select)(
99131
'', '- formatting -')(
@@ -163,11 +195,11 @@
163195
characters in the DOM element data attributes have been mangled
164196
to work around that: we simply use \u002f for every 2nd slash.
165197
*/
166198
(function f(title,format,src){
167199
const img = D.img();
168
- D.append(toolbar2, ' ', img);
200
+ D.append(toolbar2, img);
169201
D.addClass(img, 'intLink');
170202
D.attr(img, 'title', title);
171203
img.dataset.format = format;
172204
D.attr(img, 'src', 'string'===typeof src ? src : src.join(''));
173205
return f;
@@ -337,13 +369,10 @@
337369
break;
338370
}
339371
formatDoc(this.dataset.format, extra);
340372
};
341373
342
- selectEditMode.addEventListener('change',function() {
343
- setDocMode(this.selectedIndex)
344
- },false);
345374
var i, controls = outerContainer.querySelectorAll('select.format');
346375
for(i = 0; i < controls.length; i++) {
347376
controls[i].addEventListener('change', handleDropDown, false);;
348377
}
349378
controls = outerContainer.querySelectorAll('.intLink');
@@ -353,11 +382,11 @@
353382
}
354383
355384
/* Return true if the document editor is in WYSIWYG mode. Return
356385
** false if it is in Markup mode */
357386
function isWysiwyg() {
358
- return 0===selectEditMode.selectedIndex;
387
+ return radio0.checked;
359388
}
360389
361390
/* Invoke this routine prior to submitting the HTML content back
362391
** to the server */
363392
/*function wysiwygSubmit() {
@@ -434,20 +463,16 @@
434463
initDoc();
435464
const content = F.page.wikiContent() || '';
436465
var isDirty = false /* keep from stashing too often */;
437466
F.page.setContentMethods(
438467
function(){
439
- //selectEditMode.selectedIndex = 1;
440468
const rc = isWysiwyg() ? oDoc.innerHTML : oDoc.innerText;
441
- //setDocMode(selectEditMode.selectedIndex, rc);
442469
return rc;
443470
},
444471
function(content){
445
- //selectEditMode.selectedIndex = 1;
446
- //oDoc.innerText = content;
447472
isDirty = false;
448
- setDocMode(selectEditMode.selectedIndex, content);
473
+ setDocMode(radio0.checked ? 0 : 1, content);
449474
}
450475
);
451476
oDoc.addEventListener('blur', function(){
452477
if(isDirty) F.page.notifyOfChange();
453478
}, false);
454479
--- src/fossil.page.wikiedit-wysiwyg-legacy.js
+++ src/fossil.page.wikiedit-wysiwyg-legacy.js
@@ -10,63 +10,78 @@
10 'use strict';
11 if(!F || !F.page || F.page.name!=='wikiedit') return;
12
13 const D = F.dom;
14
 
 
15 (function(){
16 const head = document.head || document.querySelector('head'),
17 styleTag = document.createElement('style'),
18 styleCSS = `
19 .intLink { cursor: pointer; }
20 img.intLink { border: 0; }
21 #wysiwyg-container {
22 max-width: calc(100% - 1em);
23 display: flex;
24 flex-direction: column;
 
25 }
26 #wysiwygBox {
27 border: 1px #000000 solid;
28 padding: 0 1em;
 
29 overflow: auto;
30 min-height: 20em;
 
 
 
 
 
 
 
 
31 }
32 #wysiwygEditMode label { cursor: pointer; }
33 #wysiwyg-toolbars {
34 margin: 0 0 0.25em 0;
35 display: flex;
36 flex-wrap: wrap;
37 flex-direction: row;
38 align-items: flex-start;
39 }
40 #wysiwyg-toolbars > * {
41 margin: 0 0.5em 0.25em 0;
42 align-self: center;
43 }
44 #wysiwyg-toolBar1, #wysiwyg-toolBar2 {
 
 
 
45 }
46 #wysiwyg-toolBar1 > * { /* formatting buttons */
47 margin: 0 0.2em 0.2em 0;
 
48 }
49 #wysiwyg-toolBar2 > * { /* icons */
50 margin: 0 0.2em 0.2em 0;
51 border: 1px solid rgba(127,127,127,0.3);
52 align-self: end;
 
53 }
54 `;
55 head.appendChild(styleTag);
56 /* Adapted from https://stackoverflow.com/a/524721 */
57 styleTag.type = 'text/css';
58 D.append(styleTag, styleCSS);
59 })();
60
61 const outerContainer = D.attr(D.div(), 'id', 'wysiwyg-container');
62
63 const toolbars = D.attr(D.div(), 'id', 'wysiwyg-toolbars'),
64 toolbar1 = D.attr(D.div(), 'id', 'wysiwyg-toolBar1'),
65 toolbar2 = D.attr(D.div(), 'id', 'wysiwyg-toolBar2');
66 D.append(outerContainer,
67 D.append(toolbars, toolbar1, toolbar2));
 
 
68
69 /** Returns a function which simplifies adding a list of options
70 to the given select element. See below for example usage. */
71 const addOptions = function(select){
72 return function ff(value, label){
@@ -74,26 +89,43 @@
74 return ff;
75 };
76 };
77
78 ////////////////////////////////////////////////////////////////////////
79 // Edit mode selection button
80 var select;
81 const selectEditMode = select = D.attr(
82 D.attr(D.select(), 'id', 'wysiwygEditMode'),
83 'size',
84 1
85 );
86 D.append(toolbar1, select);
87 addOptions(select)(
88 0, "WYSIWYG")(
89 1, "Raw HTML");
90 select.selectedIndex = 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
92
93 ////////////////////////////////////////////////////////////////////////
94 // Text formatting options...
 
95 select = D.addClass(D.select(), 'format');
96 select.dataset.format = "formatblock";
97 D.append(toolbar1, select);
98 addOptions(select)(
99 '', '- formatting -')(
@@ -163,11 +195,11 @@
163 characters in the DOM element data attributes have been mangled
164 to work around that: we simply use \u002f for every 2nd slash.
165 */
166 (function f(title,format,src){
167 const img = D.img();
168 D.append(toolbar2, ' ', img);
169 D.addClass(img, 'intLink');
170 D.attr(img, 'title', title);
171 img.dataset.format = format;
172 D.attr(img, 'src', 'string'===typeof src ? src : src.join(''));
173 return f;
@@ -337,13 +369,10 @@
337 break;
338 }
339 formatDoc(this.dataset.format, extra);
340 };
341
342 selectEditMode.addEventListener('change',function() {
343 setDocMode(this.selectedIndex)
344 },false);
345 var i, controls = outerContainer.querySelectorAll('select.format');
346 for(i = 0; i < controls.length; i++) {
347 controls[i].addEventListener('change', handleDropDown, false);;
348 }
349 controls = outerContainer.querySelectorAll('.intLink');
@@ -353,11 +382,11 @@
353 }
354
355 /* Return true if the document editor is in WYSIWYG mode. Return
356 ** false if it is in Markup mode */
357 function isWysiwyg() {
358 return 0===selectEditMode.selectedIndex;
359 }
360
361 /* Invoke this routine prior to submitting the HTML content back
362 ** to the server */
363 /*function wysiwygSubmit() {
@@ -434,20 +463,16 @@
434 initDoc();
435 const content = F.page.wikiContent() || '';
436 var isDirty = false /* keep from stashing too often */;
437 F.page.setContentMethods(
438 function(){
439 //selectEditMode.selectedIndex = 1;
440 const rc = isWysiwyg() ? oDoc.innerHTML : oDoc.innerText;
441 //setDocMode(selectEditMode.selectedIndex, rc);
442 return rc;
443 },
444 function(content){
445 //selectEditMode.selectedIndex = 1;
446 //oDoc.innerText = content;
447 isDirty = false;
448 setDocMode(selectEditMode.selectedIndex, content);
449 }
450 );
451 oDoc.addEventListener('blur', function(){
452 if(isDirty) F.page.notifyOfChange();
453 }, false);
454
--- src/fossil.page.wikiedit-wysiwyg-legacy.js
+++ src/fossil.page.wikiedit-wysiwyg-legacy.js
@@ -10,63 +10,78 @@
10 'use strict';
11 if(!F || !F.page || F.page.name!=='wikiedit') return;
12
13 const D = F.dom;
14
15 ////////////////////////////////////////////////////////////////////////
16 // Install an app-specific stylesheet...
17 (function(){
18 const head = document.head || document.querySelector('head'),
19 styleTag = document.createElement('style'),
20 styleCSS = `
21 .intLink { cursor: pointer; }
22 img.intLink { border: 0; }
23 #wysiwyg-container {
 
24 display: flex;
25 flex-direction: column;
26 max-width: 100% /* w/o this, toolbars don't wrap properly! */
27 }
28 #wysiwygBox {
29 border: 1px #000000 solid;
30 padding: 0 1em;
31 margin: 0;
32 overflow: auto;
33 min-height: 20em;
34 }
35 #wysiwygEditMode { /* wrapper for radio buttons */
36 border: 1px solid rgba(127,127,127,0.3);
37 border-radius: 0.25em;
38 padding: 0 0.35em 0 0.35em
39 }
40 #wysiwygEditMode > * {
41 vertical-align: text-top;
42 }
43 #wysiwygEditMode label { cursor: pointer; }
44 #wysiwyg-toolbars {
45 margin: 0 0 0.25em 0;
46 display: flex;
47 flex-wrap: wrap;
48 flex-direction: column;
49 align-items: flex-start;
50 }
51 #wysiwyg-toolbars > * {
52 margin: 0 0.5em 0.25em 0;
 
53 }
54 #wysiwyg-toolBar1, #wysiwyg-toolBar2 {
55 margin: 0 0.2em 0.2em 0;
56 display: flex;
57 flex-flow: row wrap;
58 }
59 #wysiwyg-toolBar1 > * { /* formatting buttons */
60 vertical-align: middle;
61 margin: 0 0.25em 0.25em 0;
62 }
63 #wysiwyg-toolBar2 > * { /* icons */
 
64 border: 1px solid rgba(127,127,127,0.3);
65 vertical-align: baseline;
66 margin: 0.1em;
67 }
68 `;
69 head.appendChild(styleTag);
70 /* Adapted from https://stackoverflow.com/a/524721 */
71 styleTag.type = 'text/css';
72 D.append(styleTag, styleCSS);
73 })();
74
75 const outerContainer = D.attr(D.div(), 'id', 'wysiwyg-container'),
76 toolbars = D.attr(D.div(), 'id', 'wysiwyg-toolbars'),
 
77 toolbar1 = D.attr(D.div(), 'id', 'wysiwyg-toolBar1'),
78 // ^^^ formatting options
79 toolbar2 = D.attr(D.div(), 'id', 'wysiwyg-toolBar2')
80 // ^^^^ action icon buttons
81 ;
82 D.append(outerContainer, D.append(toolbars, toolbar1, toolbar2));
83
84 /** Returns a function which simplifies adding a list of options
85 to the given select element. See below for example usage. */
86 const addOptions = function(select){
87 return function ff(value, label){
@@ -74,26 +89,43 @@
89 return ff;
90 };
91 };
92
93 ////////////////////////////////////////////////////////////////////////
94 // Edit mode selection (radio buttons).
95 const radio0 =
96 D.attr(
97 D.input('radio'),
98 'name','wysiwyg-mode',
99 'id', 'wysiwyg-mode-0',
100 'value',0,
101 'checked',true),
102 radio1 = D.attr(
103 D.input('radio'),
104 'id','wysiwyg-mode-1',
105 'name','wysiwyg-mode',
106 'value',1),
107 radios = D.append(
108 D.attr(D.span(), 'id', 'wysiwygEditMode'),
109 radio0, D.append(
110 D.attr(D.label(), 'for', 'wysiwyg-mode-0'),
111 "WYSIWYG"
112 ),
113 radio1, D.append(
114 D.attr(D.label(), 'for', 'wysiwyg-mode-1'),
115 "Raw HTML"
116 )
117 );
118 D.append(toolbar1, radios);
119 const radioHandler = function(){setDocMode(+this.value)};
120 radio0.addEventListener('change',radioHandler, false);
121 radio1.addEventListener('change',radioHandler, false);
122
123
124 ////////////////////////////////////////////////////////////////////////
125 // Text formatting options...
126 var select;
127 select = D.addClass(D.select(), 'format');
128 select.dataset.format = "formatblock";
129 D.append(toolbar1, select);
130 addOptions(select)(
131 '', '- formatting -')(
@@ -163,11 +195,11 @@
195 characters in the DOM element data attributes have been mangled
196 to work around that: we simply use \u002f for every 2nd slash.
197 */
198 (function f(title,format,src){
199 const img = D.img();
200 D.append(toolbar2, img);
201 D.addClass(img, 'intLink');
202 D.attr(img, 'title', title);
203 img.dataset.format = format;
204 D.attr(img, 'src', 'string'===typeof src ? src : src.join(''));
205 return f;
@@ -337,13 +369,10 @@
369 break;
370 }
371 formatDoc(this.dataset.format, extra);
372 };
373
 
 
 
374 var i, controls = outerContainer.querySelectorAll('select.format');
375 for(i = 0; i < controls.length; i++) {
376 controls[i].addEventListener('change', handleDropDown, false);;
377 }
378 controls = outerContainer.querySelectorAll('.intLink');
@@ -353,11 +382,11 @@
382 }
383
384 /* Return true if the document editor is in WYSIWYG mode. Return
385 ** false if it is in Markup mode */
386 function isWysiwyg() {
387 return radio0.checked;
388 }
389
390 /* Invoke this routine prior to submitting the HTML content back
391 ** to the server */
392 /*function wysiwygSubmit() {
@@ -434,20 +463,16 @@
463 initDoc();
464 const content = F.page.wikiContent() || '';
465 var isDirty = false /* keep from stashing too often */;
466 F.page.setContentMethods(
467 function(){
 
468 const rc = isWysiwyg() ? oDoc.innerHTML : oDoc.innerText;
 
469 return rc;
470 },
471 function(content){
 
 
472 isDirty = false;
473 setDocMode(radio0.checked ? 0 : 1, content);
474 }
475 );
476 oDoc.addEventListener('blur', function(){
477 if(isDirty) F.page.notifyOfChange();
478 }, false);
479
--- src/style.wikiedit.css
+++ src/style.wikiedit.css
@@ -38,11 +38,11 @@
3838
vertical-align: middle;
3939
margin: 0.5em;
4040
}
4141
body.wikiedit .tab-container > .tabs > .tab-panel > .wikiedit-options > .input-with-label {
4242
vertical-align: middle;
43
- margin: 0.5em;
43
+ margin: 0 0.5em 0.25em 0.5em;
4444
}
4545
body.wikiedit label {
4646
display: inline; /* some skins set label display to block! */
4747
}
4848
body.wikiedit .wikiedit-options > div > * {
4949
--- src/style.wikiedit.css
+++ src/style.wikiedit.css
@@ -38,11 +38,11 @@
38 vertical-align: middle;
39 margin: 0.5em;
40 }
41 body.wikiedit .tab-container > .tabs > .tab-panel > .wikiedit-options > .input-with-label {
42 vertical-align: middle;
43 margin: 0.5em;
44 }
45 body.wikiedit label {
46 display: inline; /* some skins set label display to block! */
47 }
48 body.wikiedit .wikiedit-options > div > * {
49
--- src/style.wikiedit.css
+++ src/style.wikiedit.css
@@ -38,11 +38,11 @@
38 vertical-align: middle;
39 margin: 0.5em;
40 }
41 body.wikiedit .tab-container > .tabs > .tab-panel > .wikiedit-options > .input-with-label {
42 vertical-align: middle;
43 margin: 0 0.5em 0.25em 0.5em;
44 }
45 body.wikiedit label {
46 display: inline; /* some skins set label display to block! */
47 }
48 body.wikiedit .wikiedit-options > div > * {
49

Keyboard Shortcuts

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