|
a759842…
|
stephan
|
1 |
/** |
|
a759842…
|
stephan
|
2 |
A slight adaptation of fossil's legacy wysiwyg wiki editor which |
|
a759842…
|
stephan
|
3 |
makes it usable with the newer editor's edit widget replacement |
|
a759842…
|
stephan
|
4 |
API. |
|
a759842…
|
stephan
|
5 |
|
|
a759842…
|
stephan
|
6 |
Requires: window.fossil, fossil.dom, and that the current page is |
|
a759842…
|
stephan
|
7 |
/wikiedit. If called from another page it returns without effect. |
|
a759842…
|
stephan
|
8 |
|
|
a759842…
|
stephan
|
9 |
Caveat: this is an all-or-nothing solution. That is, once plugged |
|
a759842…
|
stephan
|
10 |
in to /wikiedit, it cannot be removed without reloading the page. |
|
a759842…
|
stephan
|
11 |
That is a limitation of the current editor-widget-swapping API. |
|
a759842…
|
stephan
|
12 |
*/ |
|
a759842…
|
stephan
|
13 |
(function(F/*fossil object*/){ |
|
a759842…
|
stephan
|
14 |
'use strict'; |
|
a759842…
|
stephan
|
15 |
if(!F || !F.page || F.page.name!=='wikiedit') return; |
|
a759842…
|
stephan
|
16 |
|
|
a759842…
|
stephan
|
17 |
const D = F.dom; |
|
a759842…
|
stephan
|
18 |
|
|
a759842…
|
stephan
|
19 |
//////////////////////////////////////////////////////////////////////// |
|
a759842…
|
stephan
|
20 |
// Install an app-specific stylesheet... |
|
a759842…
|
stephan
|
21 |
(function(){ |
|
a759842…
|
stephan
|
22 |
const head = document.head || document.querySelector('head'), |
|
a759842…
|
stephan
|
23 |
styleTag = document.createElement('style'), |
|
a759842…
|
stephan
|
24 |
styleCSS = ` |
|
a759842…
|
stephan
|
25 |
.intLink { cursor: pointer; } |
|
a759842…
|
stephan
|
26 |
img.intLink { border: 0; } |
|
a759842…
|
stephan
|
27 |
#wysiwyg-container { |
|
a759842…
|
stephan
|
28 |
display: flex; |
|
a759842…
|
stephan
|
29 |
flex-direction: column; |
|
a759842…
|
stephan
|
30 |
max-width: 100% /* w/o this, toolbars don't wrap properly! */ |
|
a759842…
|
stephan
|
31 |
} |
|
a759842…
|
stephan
|
32 |
#wysiwygBox { |
|
a759842…
|
stephan
|
33 |
border: 1px solid rgba(127,127,127,0.3); |
|
a759842…
|
stephan
|
34 |
border-radius: 0.25em; |
|
a759842…
|
stephan
|
35 |
padding: 0.25em 1em; |
|
a759842…
|
stephan
|
36 |
margin: 0; |
|
a759842…
|
stephan
|
37 |
overflow: auto; |
|
a759842…
|
stephan
|
38 |
min-height: 20em; |
|
a759842…
|
stephan
|
39 |
resize: vertical; |
|
a759842…
|
stephan
|
40 |
} |
|
a759842…
|
stephan
|
41 |
#wysiwygEditMode { /* wrapper for radio buttons */ |
|
a759842…
|
stephan
|
42 |
border: 1px solid rgba(127,127,127,0.3); |
|
a759842…
|
stephan
|
43 |
border-radius: 0.25em; |
|
a759842…
|
stephan
|
44 |
padding: 0 0.35em 0 0.35em |
|
a759842…
|
stephan
|
45 |
} |
|
a759842…
|
stephan
|
46 |
#wysiwygEditMode > * { |
|
a759842…
|
stephan
|
47 |
vertical-align: text-top; |
|
a759842…
|
stephan
|
48 |
} |
|
a759842…
|
stephan
|
49 |
#wysiwygEditMode label { cursor: pointer; } |
|
a759842…
|
stephan
|
50 |
#wysiwyg-toolbars { |
|
a759842…
|
stephan
|
51 |
margin: 0 0 0.25em 0; |
|
a759842…
|
stephan
|
52 |
display: flex; |
|
a759842…
|
stephan
|
53 |
flex-wrap: wrap; |
|
a759842…
|
stephan
|
54 |
flex-direction: column; |
|
a759842…
|
stephan
|
55 |
align-items: flex-start; |
|
a759842…
|
stephan
|
56 |
} |
|
a759842…
|
stephan
|
57 |
#wysiwyg-toolbars > * { |
|
a759842…
|
stephan
|
58 |
margin: 0 0.5em 0.25em 0; |
|
a759842…
|
stephan
|
59 |
} |
|
a759842…
|
stephan
|
60 |
#wysiwyg-toolBar1, #wysiwyg-toolBar2 { |
|
a759842…
|
stephan
|
61 |
margin: 0 0.2em 0.2em 0; |
|
a759842…
|
stephan
|
62 |
display: flex; |
|
a759842…
|
stephan
|
63 |
flex-flow: row wrap; |
|
a759842…
|
stephan
|
64 |
} |
|
a759842…
|
stephan
|
65 |
#wysiwyg-toolBar1 > * { /* formatting buttons */ |
|
a759842…
|
stephan
|
66 |
vertical-align: middle; |
|
a759842…
|
stephan
|
67 |
margin: 0 0.25em 0.25em 0; |
|
a759842…
|
stephan
|
68 |
} |
|
a759842…
|
stephan
|
69 |
#wysiwyg-toolBar2 > * { /* icons */ |
|
a759842…
|
stephan
|
70 |
border: 1px solid rgba(127,127,127,0.3); |
|
a759842…
|
stephan
|
71 |
vertical-align: baseline; |
|
a759842…
|
stephan
|
72 |
margin: 0.1em; |
|
a759842…
|
stephan
|
73 |
} |
|
a759842…
|
stephan
|
74 |
`; |
|
a759842…
|
stephan
|
75 |
head.appendChild(styleTag); |
|
a759842…
|
stephan
|
76 |
styleTag.type = 'text/css'; |
|
a759842…
|
stephan
|
77 |
D.append(styleTag, styleCSS); |
|
a759842…
|
stephan
|
78 |
})(); |
|
a759842…
|
stephan
|
79 |
|
|
a759842…
|
stephan
|
80 |
const outerContainer = D.attr(D.div(), 'id', 'wysiwyg-container'), |
|
a759842…
|
stephan
|
81 |
toolbars = D.attr(D.div(), 'id', 'wysiwyg-toolbars'), |
|
a759842…
|
stephan
|
82 |
toolbar1 = D.attr(D.div(), 'id', 'wysiwyg-toolBar1'), |
|
a759842…
|
stephan
|
83 |
// ^^^ formatting options |
|
a759842…
|
stephan
|
84 |
toolbar2 = D.attr(D.div(), 'id', 'wysiwyg-toolBar2') |
|
a759842…
|
stephan
|
85 |
// ^^^^ action icon buttons |
|
a759842…
|
stephan
|
86 |
; |
|
a759842…
|
stephan
|
87 |
D.append(outerContainer, D.append(toolbars, toolbar1, toolbar2)); |
|
a759842…
|
stephan
|
88 |
|
|
a759842…
|
stephan
|
89 |
/** Returns a function which simplifies adding a list of options |
|
a759842…
|
stephan
|
90 |
to the given select element. See below for example usage. */ |
|
a759842…
|
stephan
|
91 |
const addOptions = function(select){ |
|
a759842…
|
stephan
|
92 |
return function ff(value, label){ |
|
a759842…
|
stephan
|
93 |
D.option(select, value, label || value); |
|
a759842…
|
stephan
|
94 |
return ff; |
|
a759842…
|
stephan
|
95 |
}; |
|
a759842…
|
stephan
|
96 |
}; |
|
a759842…
|
stephan
|
97 |
|
|
a759842…
|
stephan
|
98 |
//////////////////////////////////////////////////////////////////////// |
|
a759842…
|
stephan
|
99 |
// Edit mode selection (radio buttons). |
|
a759842…
|
stephan
|
100 |
const radio0 = |
|
a759842…
|
stephan
|
101 |
D.attr( |
|
a759842…
|
stephan
|
102 |
D.input('radio'), |
|
a759842…
|
stephan
|
103 |
'name','wysiwyg-mode', |
|
a759842…
|
stephan
|
104 |
'id', 'wysiwyg-mode-0', |
|
a759842…
|
stephan
|
105 |
'value',0, |
|
a759842…
|
stephan
|
106 |
'checked',true), |
|
a759842…
|
stephan
|
107 |
radio1 = D.attr( |
|
a759842…
|
stephan
|
108 |
D.input('radio'), |
|
a759842…
|
stephan
|
109 |
'id','wysiwyg-mode-1', |
|
a759842…
|
stephan
|
110 |
'name','wysiwyg-mode', |
|
a759842…
|
stephan
|
111 |
'value',1), |
|
a759842…
|
stephan
|
112 |
radios = D.append( |
|
a759842…
|
stephan
|
113 |
D.attr(D.span(), 'id', 'wysiwygEditMode'), |
|
a759842…
|
stephan
|
114 |
radio0, D.append( |
|
a759842…
|
stephan
|
115 |
D.attr(D.label(), 'for', 'wysiwyg-mode-0'), |
|
a759842…
|
stephan
|
116 |
"WYSIWYG" |
|
a759842…
|
stephan
|
117 |
), |
|
a759842…
|
stephan
|
118 |
radio1, D.append( |
|
a759842…
|
stephan
|
119 |
D.attr(D.label(), 'for', 'wysiwyg-mode-1'), |
|
a759842…
|
stephan
|
120 |
"Raw HTML" |
|
a759842…
|
stephan
|
121 |
) |
|
a759842…
|
stephan
|
122 |
); |
|
a759842…
|
stephan
|
123 |
D.append(toolbar1, radios); |
|
a759842…
|
stephan
|
124 |
const radioHandler = function(){setDocMode(+this.value)}; |
|
a759842…
|
stephan
|
125 |
radio0.addEventListener('change',radioHandler, false); |
|
a759842…
|
stephan
|
126 |
radio1.addEventListener('change',radioHandler, false); |
|
a759842…
|
stephan
|
127 |
|
|
a759842…
|
stephan
|
128 |
|
|
a759842…
|
stephan
|
129 |
//////////////////////////////////////////////////////////////////////// |
|
a759842…
|
stephan
|
130 |
// Text formatting options... |
|
a759842…
|
stephan
|
131 |
var select; |
|
a759842…
|
stephan
|
132 |
select = D.addClass(D.select(), 'format'); |
|
a759842…
|
stephan
|
133 |
select.dataset.format = "formatblock"; |
|
a759842…
|
stephan
|
134 |
D.append(toolbar1, select); |
|
a759842…
|
stephan
|
135 |
addOptions(select)( |
|
a759842…
|
stephan
|
136 |
'', '- formatting -')( |
|
a759842…
|
stephan
|
137 |
"h1", "Title 1 <h1>")( |
|
a759842…
|
stephan
|
138 |
"h2", "Title 2 <h2>")( |
|
a759842…
|
stephan
|
139 |
"h3", "Title 3 <h3>")( |
|
a759842…
|
stephan
|
140 |
"h4", "Title 4 <h4>")( |
|
a759842…
|
stephan
|
141 |
"h5", "Title 5 <h5>")( |
|
a759842…
|
stephan
|
142 |
"h6", "Subtitle <h6>")( |
|
a759842…
|
stephan
|
143 |
"p", "Paragraph <p>")( |
|
a759842…
|
stephan
|
144 |
"pre", "Preformatted <pre>"); |
|
a759842…
|
stephan
|
145 |
|
|
a759842…
|
stephan
|
146 |
select = D.addClass(D.select(), 'format'); |
|
a759842…
|
stephan
|
147 |
select.dataset.format = "fontname"; |
|
a759842…
|
stephan
|
148 |
D.append(toolbar1, select); |
|
a759842…
|
stephan
|
149 |
D.addClass( |
|
a759842…
|
stephan
|
150 |
D.option(select, '', '- font -'), |
|
a759842…
|
stephan
|
151 |
"heading" |
|
a759842…
|
stephan
|
152 |
); |
|
a759842…
|
stephan
|
153 |
addOptions(select)( |
|
a759842…
|
stephan
|
154 |
'Arial')( |
|
a759842…
|
stephan
|
155 |
'Arial Black')( |
|
a759842…
|
stephan
|
156 |
'Courier New')( |
|
a759842…
|
stephan
|
157 |
'Times New Roman'); |
|
a759842…
|
stephan
|
158 |
|
|
a759842…
|
stephan
|
159 |
select = D.addClass(D.select(), 'format'); |
|
a759842…
|
stephan
|
160 |
D.append(toolbar1, select); |
|
a759842…
|
stephan
|
161 |
select.dataset.format = "fontsize"; |
|
a759842…
|
stephan
|
162 |
D.addClass( |
|
a759842…
|
stephan
|
163 |
D.option(select, '', '- size -'), |
|
a759842…
|
stephan
|
164 |
"heading" |
|
a759842…
|
stephan
|
165 |
); |
|
a759842…
|
stephan
|
166 |
addOptions(select)( |
|
a759842…
|
stephan
|
167 |
"1", "Very small")( |
|
a759842…
|
stephan
|
168 |
"2", "A bit small")( |
|
a759842…
|
stephan
|
169 |
"3", "Normal")( |
|
a759842…
|
stephan
|
170 |
"4", "Medium-large")( |
|
a759842…
|
stephan
|
171 |
"5", "Big")( |
|
a759842…
|
stephan
|
172 |
"6", "Very big")( |
|
a759842…
|
stephan
|
173 |
"7", "Maximum"); |
|
a759842…
|
stephan
|
174 |
|
|
a759842…
|
stephan
|
175 |
select = D.addClass(D.select(), 'format'); |
|
a759842…
|
stephan
|
176 |
D.append(toolbar1, select); |
|
a759842…
|
stephan
|
177 |
select.dataset.format = 'forecolor'; |
|
a759842…
|
stephan
|
178 |
D.addClass( |
|
a759842…
|
stephan
|
179 |
D.option(select, '', '- color -'), |
|
a759842…
|
stephan
|
180 |
"heading" |
|
a759842…
|
stephan
|
181 |
); |
|
a759842…
|
stephan
|
182 |
addOptions(select)( |
|
a759842…
|
stephan
|
183 |
"red", "Red")( |
|
a759842…
|
stephan
|
184 |
"blue", "Blue")( |
|
a759842…
|
stephan
|
185 |
"green", "Green")( |
|
a759842…
|
stephan
|
186 |
"black", "Black")( |
|
a759842…
|
stephan
|
187 |
"grey", "Grey")( |
|
a759842…
|
stephan
|
188 |
"yellow", "Yellow")( |
|
a759842…
|
stephan
|
189 |
"cyan", "Cyan")( |
|
a759842…
|
stephan
|
190 |
"magenta", "Magenta"); |
|
a759842…
|
stephan
|
191 |
|
|
a759842…
|
stephan
|
192 |
|
|
a759842…
|
stephan
|
193 |
//////////////////////////////////////////////////////////////////////// |
|
a759842…
|
stephan
|
194 |
// Icon-based toolbar... |
|
a759842…
|
stephan
|
195 |
/** |
|
a759842…
|
stephan
|
196 |
Inject the icons... |
|
a759842…
|
stephan
|
197 |
|
|
a759842…
|
stephan
|
198 |
mkbuiltins strips anything which looks like a C++-style comment, |
|
a759842…
|
stephan
|
199 |
even if it's in a string literal, and thus the runs of "/" |
|
a759842…
|
stephan
|
200 |
characters in the DOM element data attributes have been mangled |
|
a759842…
|
stephan
|
201 |
to work around that: we simply use \x2f for every 2nd slash. |
|
a759842…
|
stephan
|
202 |
*/ |
|
a759842…
|
stephan
|
203 |
(function f(title,format,src){ |
|
a759842…
|
stephan
|
204 |
const img = D.img(); |
|
a759842…
|
stephan
|
205 |
D.append(toolbar2, img); |
|
a759842…
|
stephan
|
206 |
D.addClass(img, 'intLink'); |
|
a759842…
|
stephan
|
207 |
D.attr(img, 'title', title); |
|
a759842…
|
stephan
|
208 |
img.dataset.format = format; |
|
a759842…
|
stephan
|
209 |
D.attr(img, 'src', 'string'===typeof src ? src : src.join('')); |
|
a759842…
|
stephan
|
210 |
return f; |
|
a759842…
|
stephan
|
211 |
})( |
|
a759842…
|
stephan
|
212 |
'Undo', 'undo', |
|
a759842…
|
stephan
|
213 |
["data:image/gif;base64,R0lGODlhFgAWAOMKADljwliE33mOrpGjuYKl8aezxqPD+7", |
|
a759842…
|
stephan
|
214 |
"/I19DV3NHa7P/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f", |
|
a759842…
|
stephan
|
215 |
"/\x2f/\x2f/\x2f/yH5BAEKAA8ALAAAAAAWABYAAARR8MlJq704680", |
|
a759842…
|
stephan
|
216 |
"7TkaYeJJBnES4EeUJvIGapWYAC0CsocQ7SDlWJkAkCA6ToMYWIARGQF3mRQVIEjkkSVLIbSfE", |
|
a759842…
|
stephan
|
217 |
"whdRIH4fh/DZMICe3/C4nBQBADs="] |
|
a759842…
|
stephan
|
218 |
)( |
|
a759842…
|
stephan
|
219 |
'Redo','redo', |
|
a759842…
|
stephan
|
220 |
["data:image/gif;base64,R0lGODlhFgAWAMIHAB1ChDljwl9vj1iE34Kl8aPD+7/I1/", |
|
a759842…
|
stephan
|
221 |
"/\x2f/yH5BAEKAAcALAAAAAAWABYAAANKeLrc/jDKSesyphi7SiEgsVXZEATDICqBVJjpqWZt9Na", |
|
a759842…
|
stephan
|
222 |
"EDNbQK1wCQsxlYnxMAImhyDoFAElJasRRvAZVRqqQXUy7Cgx4TC6bswkAOw=="] |
|
a759842…
|
stephan
|
223 |
)( |
|
a759842…
|
stephan
|
224 |
"Remove formatting", |
|
a759842…
|
stephan
|
225 |
"removeFormat", |
|
a759842…
|
stephan
|
226 |
["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AA", |
|
a759842…
|
stephan
|
227 |
"AABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAOxAAADsQBlSsOGwA", |
|
a759842…
|
stephan
|
228 |
"AAAd0SU1FB9oECQMCKPI8CIIAAAAIdEVYdENvbW1lbnQA9syWvwAAAuhJREFUOMtjYBgFxAB5", |
|
a759842…
|
stephan
|
229 |
"01ZWBvVaL2nHnlmk6mXCJbF69zU+Hz/9fB5O1lx+bg45qhl8/fYr5it3XrP/YWTUvvvk3VeqG", |
|
a759842…
|
stephan
|
230 |
"Xz70TvbJy8+Wv39+2/Hz19/mGwjZzuTYjALuoBv9jImaXHeyD3H7kU8fPj2ICML8z92dlbtMz", |
|
a759842…
|
stephan
|
231 |
"deiG3fco7J08foH1kurkm3E9iw54YvKwuTuom+LPt/BgbWf3/\x2fsf37/1/c02cCG1lB8f/\x2ff95", |
|
a759842…
|
stephan
|
232 |
"DZx74MTMzshhoSm6szrQ/a6Ir/Z2RkfEjBxuLYFpDiDi6Af/\x2f/2ckaHBp7+7wmavP5n76+P2C", |
|
a759842…
|
stephan
|
233 |
"lrLIYl8H9W36auJCbCxM4szMTJac7Kza/\x2f/\x2fR3H1w2cfWAgafPbqs5g7D95++/P1B4+ECK8tA", |
|
a759842…
|
stephan
|
234 |
"wMDw/1H7159+/7r7ZcvPz4fOHbzEwMDwx8GBgaGnNatfHZx8zqrJ+4VJBh5CQEGOySEua/v3n", |
|
a759842…
|
stephan
|
235 |
"7hXmqI8WUGBgYGL3vVG7fuPK3i5GD9/fja7ZsMDAzMG/Ze52mZeSj4yu1XEq/ff7W5dvfVAS1", |
|
a759842…
|
stephan
|
236 |
"lsXc4Db7z8C3r8p7Qjf/\x2f/2dnZGxlqJuyr3rPqQd/Hhyu7oSpYWScylDQsd3kzvnH738wMDzj", |
|
a759842…
|
stephan
|
237 |
"5GBN1VIWW4c3KDon7VOvm7S3paB9u5qsU5/x5KUnlY+eexQbkLNsErK61+++VnAJcfkyMTIwf", |
|
a759842…
|
stephan
|
238 |
"fj0QwZbJDKjcETs1Y8evyd48toz8y/ffzv/\x2fvPP4veffxpX77z6l5JewHPu8MqTDAwMDLzyrj", |
|
a759842…
|
stephan
|
239 |
"b/mZm0JcT5Lj+89+Ybm6zz95oMh7s4XbygN3Sluq4Mj5K8iKMgP4f0/\x2f/\x2ffv77/\x2f8nLy+7MCc", |
|
a759842…
|
stephan
|
240 |
"XmyYDAwODS9jM9tcvPypd35pne3ljdjvj26+H2dhYpuENikgfvQeXNmSl3tqepxXsqhXPyc66", |
|
a759842…
|
stephan
|
241 |
"6s+fv1fMdKR3TK72zpix8nTc7bdfhfkEeVbC9KhbK/9iYWHiErbu6MWbY/7/\x2f8/4/\x2f9/pgOnH", |
|
a759842…
|
stephan
|
242 |
"6jGVazvFDRtq2VgiBIZrUTIBgCk+ivHvuEKwAAAAABJRU5ErkJggg=="] |
|
a759842…
|
stephan
|
243 |
)( |
|
a759842…
|
stephan
|
244 |
"Bold", |
|
a759842…
|
stephan
|
245 |
"bold", |
|
a759842…
|
stephan
|
246 |
["data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB", |
|
a759842…
|
stephan
|
247 |
"YAQAInhI+pa+H9mJy0LhdgtrxzDG5WGFVk6aXqyk6Y9kXvKKNuLbb6zgMFADs="] |
|
a759842…
|
stephan
|
248 |
)( |
|
a759842…
|
stephan
|
249 |
"Italic", |
|
a759842…
|
stephan
|
250 |
"italic", |
|
a759842…
|
stephan
|
251 |
["data:image/gif;base64,R0lGODlhFgAWAKEDAAAAAF9vj5WIbf/\x2f/yH5BAEAAAMALA", |
|
a759842…
|
stephan
|
252 |
"AAAAAWABYAAAIjnI+py+0Po5x0gXvruEKHrF2BB1YiCWgbMFIYpsbyTNd2UwAAOw=="] |
|
a759842…
|
stephan
|
253 |
)( |
|
a759842…
|
stephan
|
254 |
"Underline", |
|
a759842…
|
stephan
|
255 |
"underline", |
|
a759842…
|
stephan
|
256 |
["data:image/gif;base64,R0lGODlhFgAWAKECAAAAAF9vj/\x2f/\x2f/\x2f/\x2fyH5BAEAAAIALA", |
|
a759842…
|
stephan
|
257 |
"AAAAAWABYAAAIrlI+py+0Po5zUgAsEzvEeL4Ea15EiJJ5PSqJmuwKBEKgxVuXWtun+DwxCCgA", |
|
a759842…
|
stephan
|
258 |
"7"] |
|
a759842…
|
stephan
|
259 |
)( |
|
a759842…
|
stephan
|
260 |
"Left align", |
|
a759842…
|
stephan
|
261 |
"justifyleft", |
|
a759842…
|
stephan
|
262 |
["data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB", |
|
a759842…
|
stephan
|
263 |
"YAQAIghI+py+0Po5y02ouz3jL4D4JMGELkGYxo+qzl4nKyXAAAOw=="] |
|
a759842…
|
stephan
|
264 |
)( |
|
a759842…
|
stephan
|
265 |
"Center align", |
|
a759842…
|
stephan
|
266 |
"justifycenter", |
|
a759842…
|
stephan
|
267 |
["data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB", |
|
a759842…
|
stephan
|
268 |
"YAQAIfhI+py+0Po5y02ouz3jL4D4JOGI7kaZ5Bqn4sycVbAQA7"] |
|
a759842…
|
stephan
|
269 |
)( |
|
a759842…
|
stephan
|
270 |
"Right align", |
|
a759842…
|
stephan
|
271 |
"justifyright", |
|
a759842…
|
stephan
|
272 |
["data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB", |
|
a759842…
|
stephan
|
273 |
"YAQAIghI+py+0Po5y02ouz3jL4D4JQGDLkGYxouqzl43JyVgAAOw=="] |
|
a759842…
|
stephan
|
274 |
)( |
|
a759842…
|
stephan
|
275 |
"Numbered list", |
|
a759842…
|
stephan
|
276 |
"insertorderedlist", |
|
a759842…
|
stephan
|
277 |
["data:image/gif;base64,R0lGODlhFgAWAMIGAAAAADljwliE35GjuaezxtHa7P/\x2f/\x2f", |
|
a759842…
|
stephan
|
278 |
"/\x2f/yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKSespwjoRFvggCBUBoTFBeq6QIAysQnRHaEO", |
|
a759842…
|
stephan
|
279 |
"zyaZ07Lu9lUBnC0UGQU1K52s6n5oEADs="] |
|
a759842…
|
stephan
|
280 |
)( |
|
a759842…
|
stephan
|
281 |
"Dotted list", |
|
a759842…
|
stephan
|
282 |
"insertunorderedlist", |
|
a759842…
|
stephan
|
283 |
["data:image/gif;base64,R0lGODlhFgAWAMIGAAAAAB1ChF9vj1iE33mOrqezxv/\x2f/\x2f", |
|
a759842…
|
stephan
|
284 |
"/\x2f/yH5BAEAAAcALAAAAAAWABYAAAMyeLrc/jDKSesppNhGRlBAKIZRERBbqm6YtnbfMY7lud6", |
|
a759842…
|
stephan
|
285 |
"4UwiuKnigGQliQuWOyKQykgAAOw=="] |
|
a759842…
|
stephan
|
286 |
)( |
|
a759842…
|
stephan
|
287 |
"Quote", |
|
a759842…
|
stephan
|
288 |
"formatblock", |
|
a759842…
|
stephan
|
289 |
["data:image/gif;base64,R0lGODlhFgAWAIQXAC1NqjFRjkBgmT9nqUJnsk9xrFJ7u2", |
|
a759842…
|
stephan
|
290 |
"R9qmKBt1iGzHmOrm6Sz4OXw3Odz4Cl2ZSnw6KxyqO306K63bG70bTB0rDI3bvI4P", |
|
a759842…
|
stephan
|
291 |
"/\x2f/\x2f/\x2f/\x2f/", |
|
a759842…
|
stephan
|
292 |
"/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f", |
|
a759842…
|
stephan
|
293 |
"/\x2f/\x2f/\x2fyH5BAEKAB8ALAAAAAAWABYAAAVP4CeOZGmeaKqubEs2Cekk", |
|
a759842…
|
stephan
|
294 |
"ErvEI1zZuOgYFlakECEZFi0GgTGKEBATFmJAVXweVOoKEQgABB9IQDCmrLpjETrQQlhHjINrT", |
|
a759842…
|
stephan
|
295 |
"q/b7/i8fp8PAQA7"] |
|
a759842…
|
stephan
|
296 |
)( |
|
a759842…
|
stephan
|
297 |
"Delete indentation", |
|
a759842…
|
stephan
|
298 |
"outdent", |
|
a759842…
|
stephan
|
299 |
["data:image/gif;base64,R0lGODlhFgAWAMIHAAAAADljwliE35GjuaezxtDV3NHa7P", |
|
a759842…
|
stephan
|
300 |
"/\x2f/yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKCQG9F2i7u8agQgyK1z2EIBil+TWqEMxhMcz", |
|
a759842…
|
stephan
|
301 |
"sYVJ3e4ahk+sFnAgtxSQDqWw6n5cEADs="] |
|
a759842…
|
stephan
|
302 |
)( |
|
a759842…
|
stephan
|
303 |
"Add indentation", |
|
a759842…
|
stephan
|
304 |
"indent", |
|
a759842…
|
stephan
|
305 |
["data:image/gif;base64,R0lGODlhFgAWAOMIAAAAADljwl9vj1iE35GjuaezxtDV3N", |
|
a759842…
|
stephan
|
306 |
"Ha7P/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f", |
|
a759842…
|
stephan
|
307 |
"/\x2f/\x2f/yH5BAEAAAgALAAAAAAWABYAAAQ7EMlJq704650", |
|
a759842…
|
stephan
|
308 |
"B/x8gemMpgugwHJNZXodKsO5oqUOgo5KhBwWESyMQsCRDHu9VOyk5TM9zSpFSr9gsJwIAOw==" |
|
a759842…
|
stephan
|
309 |
] |
|
a759842…
|
stephan
|
310 |
)( |
|
a759842…
|
stephan
|
311 |
"Hyperlink", |
|
a759842…
|
stephan
|
312 |
"createlink", |
|
a759842…
|
stephan
|
313 |
["data:image/gif;base64,R0lGODlhFgAWAOMKAB1ChDRLY19vj3mOrpGjuaezxrCztb", |
|
a759842…
|
stephan
|
314 |
"/I19Ha7Pv8/f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f", |
|
a759842…
|
stephan
|
315 |
"/yH5BAEKAA8ALAAAAAAWABYAAARY8MlJq704682", |
|
a759842…
|
stephan
|
316 |
"7/2BYIQVhHg9pEgVGIklyDEUBy/RlE4FQF4dCj2AQXAiJQDCWQCAEBwIioEMQBgSAFhDAGghG", |
|
a759842…
|
stephan
|
317 |
"i9XgHAhMNoSZgJkJei33UESv2+/4vD4TAQA7"] |
|
a759842…
|
stephan
|
318 |
)( |
|
a759842…
|
stephan
|
319 |
"Cut", |
|
a759842…
|
stephan
|
320 |
"cut", |
|
a759842…
|
stephan
|
321 |
["data:image/gif;base64,R0lGODlhFgAWAIQSAB1ChBFNsRJTySJYwjljwkxwl19vj1", |
|
a759842…
|
stephan
|
322 |
"dusYODhl6MnHmOrpqbmpGjuaezxrCztcDCxL/I18rL1P/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f", |
|
a759842…
|
stephan
|
323 |
"/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/", |
|
a759842…
|
stephan
|
324 |
"/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f", |
|
a759842…
|
stephan
|
325 |
"yH5BAEAAB8ALAAAAAAWABYAAAVu4CeOZGmeaKqubDs6TNnE", |
|
a759842…
|
stephan
|
326 |
"bGNApNG0kbGMi5trwcA9GArXh+FAfBAw5UexUDAQESkRsfhJPwaH4YsEGAAJGisRGAQY7UCC9", |
|
a759842…
|
stephan
|
327 |
"ZAXBB+74LGCRxIEHwAHdWooDgGJcwpxDisQBQRjIgkDCVlfmZqbmiEAOw=="] |
|
a759842…
|
stephan
|
328 |
)( |
|
a759842…
|
stephan
|
329 |
"Copy", |
|
a759842…
|
stephan
|
330 |
"copy", |
|
a759842…
|
stephan
|
331 |
["data:image/gif;base64,R0lGODlhFgAWAIQcAB1ChBFNsTRLYyJYwjljwl9vj1iE31", |
|
a759842…
|
stephan
|
332 |
"iGzF6MnHWX9HOdz5GjuYCl2YKl8ZOt4qezxqK63aK/9KPD+7DI3b/I17LM/MrL1MLY9NHa7OP", |
|
a759842…
|
stephan
|
333 |
"s++bx/Pv8/f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f", |
|
a759842…
|
stephan
|
334 |
"/yH5BAEAAB8ALAAAAAAWABYAAAWG4CeOZGmeaKqubOum1SQ/", |
|
a759842…
|
stephan
|
335 |
"kPVOW749BeVSus2CgrCxHptLBbOQxCSNCCaF1GUqwQbBd0JGJAyGJJiobE+LnCaDcXAaEoxhQ", |
|
a759842…
|
stephan
|
336 |
"ACgNw0FQx9kP+wmaRgYFBQNeAoGihCAJQsCkJAKOhgXEw8BLQYciooHf5o7EA+kC40qBKkAAA", |
|
a759842…
|
stephan
|
337 |
"Grpy+wsbKzIiEAOw=="] |
|
a759842…
|
stephan
|
338 |
)( |
|
a759842…
|
stephan
|
339 |
/* Paste, when activated via JS, has no effect in some (maybe all) |
|
a759842…
|
stephan
|
340 |
environments. Activated externally, e.g. keyboard, it works. */ |
|
a759842…
|
stephan
|
341 |
"Paste (does not work in all environments)", |
|
a759842…
|
stephan
|
342 |
"paste", |
|
a759842…
|
stephan
|
343 |
["data:image/gif;base64,R0lGODlhFgAWAIQUAD04KTRLY2tXQF9vj414WZWIbXmOrp", |
|
a759842…
|
stephan
|
344 |
"qbmpGjudClFaezxsa0cb/I1+3YitHa7PrkIPHvbuPs+/fvrvv8/f/\x2f/\x2f/\x2f", |
|
a759842…
|
stephan
|
345 |
"/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/", |
|
a759842…
|
stephan
|
346 |
"/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f/\x2f", |
|
a759842…
|
stephan
|
347 |
"yH5BAEAAB8ALAAAAAAWABYAAAWN4CeOZGmeaKqubGsusPvB", |
|
a759842…
|
stephan
|
348 |
"SyFJjVDs6nJLB0khR4AkBCmfsCGBQAoCwjF5gwquVykSFbwZE+AwIBV0GhFog2EwIDchjwRiQ", |
|
a759842…
|
stephan
|
349 |
"o9E2Fx4XD5R+B0DDAEnBXBhBhN2DgwDAQFjJYVhCQYRfgoIDGiQJAWTCQMRiwwMfgicnVcAAA", |
|
a759842…
|
stephan
|
350 |
"MOaK+bLAOrtLUyt7i5uiUhADs="] |
|
a759842…
|
stephan
|
351 |
); |
|
a759842…
|
stephan
|
352 |
|
|
a759842…
|
stephan
|
353 |
//////////////////////////////////////////////////////////////////////// |
|
a759842…
|
stephan
|
354 |
// The main editor area... |
|
a759842…
|
stephan
|
355 |
const oDoc = D.attr(D.div(), 'id', "wysiwygBox"); |
|
a759842…
|
stephan
|
356 |
D.attr(oDoc, 'contenteditable', 'true'); |
|
a759842…
|
stephan
|
357 |
D.append(outerContainer, oDoc); |
|
a759842…
|
stephan
|
358 |
|
|
a759842…
|
stephan
|
359 |
/* Initialize the document editor */ |
|
a759842…
|
stephan
|
360 |
function initDoc() { |
|
a759842…
|
stephan
|
361 |
initEventHandlers(); |
|
a759842…
|
stephan
|
362 |
if (!isWysiwyg()) { setDocMode(true); } |
|
a759842…
|
stephan
|
363 |
} |
|
a759842…
|
stephan
|
364 |
|
|
a759842…
|
stephan
|
365 |
function initEventHandlers() { |
|
a759842…
|
stephan
|
366 |
//console.debug("initEventHandlers()"); |
|
a759842…
|
stephan
|
367 |
const handleDropDown = function() { |
|
a759842…
|
stephan
|
368 |
formatDoc(this.dataset.format,this[this.selectedIndex].value); |
|
a759842…
|
stephan
|
369 |
this.selectedIndex = 0; |
|
a759842…
|
stephan
|
370 |
}; |
|
a759842…
|
stephan
|
371 |
|
|
a759842…
|
stephan
|
372 |
const handleFormatButton = function() { |
|
a759842…
|
stephan
|
373 |
var extra; |
|
a759842…
|
stephan
|
374 |
switch (this.dataset.format) { |
|
a759842…
|
stephan
|
375 |
case 'createlink': |
|
a759842…
|
stephan
|
376 |
const sLnk = prompt('Target URL:',''); |
|
a759842…
|
stephan
|
377 |
if(sLnk) extra = sLnk; |
|
a759842…
|
stephan
|
378 |
break; |
|
a759842…
|
stephan
|
379 |
case 'formatblock': |
|
a759842…
|
stephan
|
380 |
extra = 'blockquote'; |
|
a759842…
|
stephan
|
381 |
break; |
|
a759842…
|
stephan
|
382 |
} |
|
a759842…
|
stephan
|
383 |
formatDoc(this.dataset.format, extra); |
|
a759842…
|
stephan
|
384 |
}; |
|
a759842…
|
stephan
|
385 |
|
|
a759842…
|
stephan
|
386 |
var i, controls = outerContainer.querySelectorAll('select.format'); |
|
a759842…
|
stephan
|
387 |
for(i = 0; i < controls.length; i++) { |
|
a759842…
|
stephan
|
388 |
controls[i].addEventListener('change', handleDropDown, false);; |
|
a759842…
|
stephan
|
389 |
} |
|
a759842…
|
stephan
|
390 |
controls = outerContainer.querySelectorAll('.intLink'); |
|
a759842…
|
stephan
|
391 |
for(i = 0; i < controls.length; i++) { |
|
a759842…
|
stephan
|
392 |
controls[i].addEventListener('click', handleFormatButton, false); |
|
a759842…
|
stephan
|
393 |
} |
|
a759842…
|
stephan
|
394 |
} |
|
a759842…
|
stephan
|
395 |
|
|
a759842…
|
stephan
|
396 |
/* Return true if the document editor is in WYSIWYG mode. Return |
|
a759842…
|
stephan
|
397 |
** false if it is in Markup mode */ |
|
a759842…
|
stephan
|
398 |
function isWysiwyg() { |
|
a759842…
|
stephan
|
399 |
return radio0.checked; |
|
a759842…
|
stephan
|
400 |
} |
|
a759842…
|
stephan
|
401 |
|
|
a759842…
|
stephan
|
402 |
/* Run the editing command if in WYSIWYG mode */ |
|
a759842…
|
stephan
|
403 |
function formatDoc(sCmd, sValue) { |
|
a759842…
|
stephan
|
404 |
if (isWysiwyg()){ |
|
a759842…
|
stephan
|
405 |
try { |
|
a759842…
|
stephan
|
406 |
// First, try the W3C draft standard way, which has |
|
a759842…
|
stephan
|
407 |
// been working on all non-IE browsers for a while. |
|
a759842…
|
stephan
|
408 |
// It is also supported by IE11 and higher. |
|
a759842…
|
stephan
|
409 |
document.execCommand("styleWithCSS", false, false); |
|
a759842…
|
stephan
|
410 |
} catch (e) { |
|
a759842…
|
stephan
|
411 |
try { |
|
a759842…
|
stephan
|
412 |
// For IE9 or IE10, this should work. |
|
a759842…
|
stephan
|
413 |
document.execCommand("useCSS", 0, true); |
|
a759842…
|
stephan
|
414 |
} catch (e) { |
|
a759842…
|
stephan
|
415 |
// OK, that apparently did not work, do nothing. |
|
a759842…
|
stephan
|
416 |
} |
|
a759842…
|
stephan
|
417 |
} |
|
a759842…
|
stephan
|
418 |
document.execCommand(sCmd, false, sValue); |
|
a759842…
|
stephan
|
419 |
oDoc.focus(); |
|
a759842…
|
stephan
|
420 |
} |
|
a759842…
|
stephan
|
421 |
} |
|
a759842…
|
stephan
|
422 |
|
|
a759842…
|
stephan
|
423 |
/* Change the editing mode. Convert to markup if the argument |
|
a759842…
|
stephan
|
424 |
** is true and wysiwyg if the argument is false. */ |
|
a759842…
|
stephan
|
425 |
function setDocMode(bToMarkup, content) { |
|
a759842…
|
stephan
|
426 |
if(undefined===content){ |
|
a759842…
|
stephan
|
427 |
content = bToMarkup ? oDoc.innerHTML : oDoc.innerText; |
|
a759842…
|
stephan
|
428 |
} |
|
a759842…
|
stephan
|
429 |
if(!setDocMode.linebreak){ |
|
a759842…
|
stephan
|
430 |
setDocMode.linebreak = new RegExp("</p><p>","ig"); |
|
a759842…
|
stephan
|
431 |
} |
|
a759842…
|
stephan
|
432 |
if(!setDocMode.toHide){ |
|
a759842…
|
stephan
|
433 |
setDocMode.toHide = toolbars.querySelectorAll( |
|
a759842…
|
stephan
|
434 |
'#wysiwyg-toolBar1 > *:not(#wysiwygEditMode), ' |
|
a759842…
|
stephan
|
435 |
+'#wysiwyg-toolBar2'); |
|
a759842…
|
stephan
|
436 |
} |
|
a759842…
|
stephan
|
437 |
if (bToMarkup) { |
|
a759842…
|
stephan
|
438 |
/* WYSIWYG -> Markup */ |
|
a759842…
|
stephan
|
439 |
// Legacy did this: content=content.replace(setDocMode.linebreak,"</p>\n\n<p>") |
|
a759842…
|
stephan
|
440 |
D.append(D.clearElement(oDoc), content) |
|
a759842…
|
stephan
|
441 |
oDoc.style.whiteSpace = "pre-wrap"; |
|
a759842…
|
stephan
|
442 |
D.addClass(setDocMode.toHide, 'hidden'); |
|
a759842…
|
stephan
|
443 |
} else { |
|
a759842…
|
stephan
|
444 |
/* Markup -> WYSIWYG */ |
|
a759842…
|
stephan
|
445 |
D.parseHtml(D.clearElement(oDoc), content); |
|
a759842…
|
stephan
|
446 |
oDoc.style.whiteSpace = "normal"; |
|
a759842…
|
stephan
|
447 |
D.removeClass(setDocMode.toHide, 'hidden'); |
|
a759842…
|
stephan
|
448 |
} |
|
a759842…
|
stephan
|
449 |
oDoc.focus(); |
|
a759842…
|
stephan
|
450 |
} |
|
a759842…
|
stephan
|
451 |
|
|
a759842…
|
stephan
|
452 |
//////////////////////////////////////////////////////////////////////// |
|
a759842…
|
stephan
|
453 |
// A hook which can be activated via a site skin to plug this editor |
|
e2bdc10…
|
danield
|
454 |
// into the wikiedit page. |
|
a759842…
|
stephan
|
455 |
F.page.wysiwyg = { |
|
a759842…
|
stephan
|
456 |
// only for debugging: oDoc: oDoc, |
|
a759842…
|
stephan
|
457 |
/* |
|
a759842…
|
stephan
|
458 |
Replaces wikiedit's default editor widget with this wysiwyg |
|
a759842…
|
stephan
|
459 |
editor. |
|
a759842…
|
stephan
|
460 |
|
|
a759842…
|
stephan
|
461 |
Must either be called via an onPageLoad handler via the site |
|
a759842…
|
stephan
|
462 |
skin's footer or else it can be called manually from the dev |
|
a759842…
|
stephan
|
463 |
tools console. Calling it too early (e.g. in the page footer |
|
d83638e…
|
danield
|
464 |
outside of an onPageLoad handler) will crash because wikiedit |
|
a759842…
|
stephan
|
465 |
has not been initialized. |
|
a759842…
|
stephan
|
466 |
*/ |
|
a759842…
|
stephan
|
467 |
init: function(){ |
|
a759842…
|
stephan
|
468 |
initDoc(); |
|
a759842…
|
stephan
|
469 |
const content = F.page.wikiContent() || ''; |
|
a759842…
|
stephan
|
470 |
var isDirty = false /* keep from stashing too often */; |
|
a759842…
|
stephan
|
471 |
F.page.setContentMethods( |
|
a759842…
|
stephan
|
472 |
function(){ |
|
a759842…
|
stephan
|
473 |
const rc = isWysiwyg() ? oDoc.innerHTML : oDoc.innerText; |
|
a759842…
|
stephan
|
474 |
return rc; |
|
a759842…
|
stephan
|
475 |
}, |
|
a759842…
|
stephan
|
476 |
function(content){ |
|
a759842…
|
stephan
|
477 |
isDirty = false; |
|
a759842…
|
stephan
|
478 |
setDocMode(radio0.checked ? 0 : 1, content); |
|
a759842…
|
stephan
|
479 |
} |
|
a759842…
|
stephan
|
480 |
); |
|
a759842…
|
stephan
|
481 |
oDoc.addEventListener('blur', function(){ |
|
a759842…
|
stephan
|
482 |
if(isDirty) F.page.notifyOfChange(); |
|
a759842…
|
stephan
|
483 |
}, false); |
|
a759842…
|
stephan
|
484 |
oDoc.addEventListener('input', function(){isDirty = true}, false); |
|
a759842…
|
stephan
|
485 |
F.page.wikiContent(content)/*feed it back in to our widget*/; |
|
a759842…
|
stephan
|
486 |
F.page.replaceEditorElement(outerContainer); |
|
a759842…
|
stephan
|
487 |
F.message("Replaced wiki editor widget with legacy wysiwyg editor."); |
|
a759842…
|
stephan
|
488 |
} |
|
a759842…
|
stephan
|
489 |
}; |
|
a759842…
|
stephan
|
490 |
})(window.fossil); |