Fossil SCM

Implemented the first version of the JavaScript tutorial chooser in www/server/index.html, complete with fallbacks for the noscript case, optional display of the static document matrix, and pretty CSS transitions between the states.

wyoung 2019-08-18 08:52 server-docs
Commit 0cbdbc725c36744f50ca02e4ae211aa43aa5f279c36af7a95f690ca8a6bb8eac
1 file changed +127 -6
--- www/server/index.html
+++ www/server/index.html
@@ -1,8 +1,8 @@
11
<div class='fossil-doc' data-title="How To Configure A Fossil Server">
22
3
-<style>
3
+<style type="text/css" nonce="$NONCE">
44
p {
55
margin-left: 4em;
66
margin-right: 3em;
77
}
88
@@ -15,10 +15,24 @@
1515
}
1616
1717
ol, ul {
1818
margin-left: 3em;
1919
}
20
+
21
+ a#all {
22
+ font-size: 90%;
23
+ margin-left: 1em;
24
+ }
25
+
26
+ div#tutpick.show {
27
+ max-height: 99em;
28
+ transition: max-height 1000ms ease-in;
29
+ }
30
+ div#tutpick {
31
+ max-height: 0;
32
+ overflow: hidden;
33
+ }
2034
2135
th.fep {
2236
background-color: #e8e8e8;
2337
min-width: 3em;
2438
padding: 0.4em;
@@ -115,10 +129,15 @@
115129
116130
<p>We've broken the configuration for each method out into a series of
117131
sub-articles. Some of these are generic, while others depend on
118132
particular operating systems or front-end software:</p>
119133
134
+<div id="tutpick"></div>
135
+
136
+<!-- Define alternative to JS tutorial picker below. When updating this
137
+ table, update "matrix" in the JS code below to match! -->
138
+<noscript id="tutmatrix">
120139
<table style="margin-left: 6em;">
121140
<tr>
122141
<th class="host">⇩ OS / Method ⇨</th>
123142
<th class="fep">none</th>
124143
<th class="fep">inetd</th>
@@ -183,19 +202,121 @@
183202
documents linked above: Apple’s <tt>launchd</tt>, Linux’s
184203
<tt>systemd</tt>, Solaris’ SMF, etc. We would welcome <a
185204
href="contribute.wiki">contributions</a> to cover these as well. We also
186205
welcome contributions to fill gaps (<font size="-2">❌</font>) in the table
187206
above. </p>
207
+</noscript>
188208
189209
190210
<h2 id="more">Further Details</h2>
191211
192212
<ul>
193
- <li> <a id="chroot" href="../chroot.md">The Server Chroot Jail</a>
194
- <li><a id="loadmgmt" href="../loadmgmt.md">Managing Server Load</a>
195
- <li><a id="tls" href="../ssl.wiki">Securing a Repository with TLS</a>
213
+ <li><a id="chroot" href="../chroot.md" >The Server Chroot Jail</a>
214
+ <li><a id="loadmgmt" href="../loadmgmt.md" >Managing Server Load</a>
215
+ <li><a id="tls" href="../ssl.wiki" >Securing a Repository with TLS</a>
196216
<li><a id="ext" href="../serverext.wiki">CGI Server Extensions</a>
197
- <li><a id="about" href="../aboutcgi.wiki">How CGI Works In Fossil</a>
198
- <li><a id="sync" href="../sync.wiki">The Fossil Sync Protocol</a>
217
+ <li><a id="about" href="../aboutcgi.wiki" >How CGI Works In Fossil</a>
218
+ <li><a id="sync" href="../sync.wiki" >The Fossil Sync Protocol</a>
199219
</ul>
200220
201221
</div>
222
+
223
+<script type="text/javascript" nonce="$NONCE">
224
+ (function() {
225
+ // Define data structure analog to <table> above. Matrix elements
226
+ // can have one of these constant values or a string for a one-off
227
+ // custom value. Values outside the <table> above go at the end of
228
+ // the rows we define here.
229
+ const YES = 1; // host-specific doc provided
230
+ const IFA = 2; // inherit doc from "any"
231
+ const NO = 3; // method invalid or undocumented for this host OS
232
+ const methods = [
233
+ "none", "inetd", "stunnel", "CGI", "SCGI", "althttpd", "proxy", "service"
234
+ ];
235
+ const matrix = {
236
+ "any OS": [ YES, YES, YES, YES, YES, YES, NO, NO ],
237
+ "Debian or Ubuntu": [ IFA, IFA, IFA, IFA, IFA, IFA, "nginx", NO ],
238
+ "Windows": [ NO, NO, YES, YES, NO, NO, "IIS", NO ],
239
+ }
240
+ const osNames = Object.keys(matrix).sort((e) => {
241
+ return e.toLowerCase()
242
+ }).map((longName, i) => {
243
+ var shortName = longName.toLowerCase().split(' ')[0];
244
+ return [ longName, shortName ];
245
+ });
246
+ const osNameMap = Object.fromEntries(osNames);
247
+ //console.log("OS name map: " + JSON.stringify(osNameMap));
248
+
249
+ // Build initial tutorial chooser HTML, and insert it into doc where
250
+ // the static HTML <table> matrix normally goes.
251
+ var html = '<p><b>I want to run Fossil on</b> <select id="os">';
252
+ for (var os of osNames) {
253
+ const longName = os[0];
254
+ const shortName = os[1];
255
+ html += '<option name="' + shortName + '">' + longName + '</option>';
256
+ }
257
+ html += '</select> <b>underneath</b> <select id="fep"></select>'
258
+ html += '<a id="all">SHOW ALL</a></p>';
259
+ const picker = document.querySelector('div#tutpick');
260
+ picker.innerHTML = html;
261
+ picker.classList.add('show');
262
+
263
+ // Slide noscript <table> in place of JS tutorial chooser on
264
+ // "SHOW ALL" click.
265
+ document.querySelector('a#all').addEventListener('click', () => {
266
+ picker.classList.remove('show');
267
+ picker.innerHTML = document.querySelector('#tutmatrix').innerHTML;
268
+ setTimeout(() => {
269
+ // Let doc update to set new height, so transition happens.
270
+ picker.classList.add('show');
271
+ }, 10);
272
+ });
273
+
274
+ // Attach event handlers to drop-downs. Have to wait until the page
275
+ // loads, else we'll get null back from querySelector(('select#foo')).
276
+ window.addEventListener('load', () => {
277
+ // Set up the FEP choice drop-down on initial page load and
278
+ // update it when the OS choice drop-down changes.
279
+ const osSel = document.querySelector('select#os');
280
+ const fepSel = document.querySelector('select#fep');
281
+ function osClickHandler() {
282
+ var osLong = osSel.value;
283
+ var osShort = osNameMap[osLong];
284
+
285
+ var html = '<option>---</option>';
286
+ matrix[osLong].forEach((choice, i) => {
287
+ var mu;
288
+ if (typeof(choice) === 'string') {
289
+ mu = choice;
290
+ choice = YES;
291
+ }
292
+ else {
293
+ mu = methods[i];
294
+ }
295
+ const ml = mu.toLowerCase();
296
+
297
+ if (choice != NO) {
298
+ if (choice == YES) {
299
+ html += '<option value="' + osShort + '/' + ml + '.md">';
300
+ }
301
+ else if (choice == IFA) {
302
+ html += '<option value="any/' + ml + '.md">';
303
+ }
304
+ html += mu + '</option>';
305
+ }
306
+ });
307
+
308
+ fepSel.innerHTML = html;
309
+ }
310
+ osSel.addEventListener('change', osClickHandler);
311
+ osClickHandler(); // load fepSel initial content
312
+
313
+ // Go to selected document when user changes FEP drop-down
314
+ fepSel.addEventListener('change', () => {
315
+ var doc = fepSel.value;
316
+ if (doc) location.href = doc;
317
+ // else it's the --- entry, either because we just reloaded the
318
+ // <option> set or because the user re-selected it.
319
+ });
320
+ });
321
+ })();
322
+</script>
202323
--- www/server/index.html
+++ www/server/index.html
@@ -1,8 +1,8 @@
1 <div class='fossil-doc' data-title="How To Configure A Fossil Server">
2
3 <style>
4 p {
5 margin-left: 4em;
6 margin-right: 3em;
7 }
8
@@ -15,10 +15,24 @@
15 }
16
17 ol, ul {
18 margin-left: 3em;
19 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
21 th.fep {
22 background-color: #e8e8e8;
23 min-width: 3em;
24 padding: 0.4em;
@@ -115,10 +129,15 @@
115
116 <p>We've broken the configuration for each method out into a series of
117 sub-articles. Some of these are generic, while others depend on
118 particular operating systems or front-end software:</p>
119
 
 
 
 
 
120 <table style="margin-left: 6em;">
121 <tr>
122 <th class="host">⇩ OS / Method ⇨</th>
123 <th class="fep">none</th>
124 <th class="fep">inetd</th>
@@ -183,19 +202,121 @@
183 documents linked above: Apple’s <tt>launchd</tt>, Linux’s
184 <tt>systemd</tt>, Solaris’ SMF, etc. We would welcome <a
185 href="contribute.wiki">contributions</a> to cover these as well. We also
186 welcome contributions to fill gaps (<font size="-2">❌</font>) in the table
187 above. </p>
 
188
189
190 <h2 id="more">Further Details</h2>
191
192 <ul>
193 <li> <a id="chroot" href="../chroot.md">The Server Chroot Jail</a>
194 <li><a id="loadmgmt" href="../loadmgmt.md">Managing Server Load</a>
195 <li><a id="tls" href="../ssl.wiki">Securing a Repository with TLS</a>
196 <li><a id="ext" href="../serverext.wiki">CGI Server Extensions</a>
197 <li><a id="about" href="../aboutcgi.wiki">How CGI Works In Fossil</a>
198 <li><a id="sync" href="../sync.wiki">The Fossil Sync Protocol</a>
199 </ul>
200
201 </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
--- www/server/index.html
+++ www/server/index.html
@@ -1,8 +1,8 @@
1 <div class='fossil-doc' data-title="How To Configure A Fossil Server">
2
3 <style type="text/css" nonce="$NONCE">
4 p {
5 margin-left: 4em;
6 margin-right: 3em;
7 }
8
@@ -15,10 +15,24 @@
15 }
16
17 ol, ul {
18 margin-left: 3em;
19 }
20
21 a#all {
22 font-size: 90%;
23 margin-left: 1em;
24 }
25
26 div#tutpick.show {
27 max-height: 99em;
28 transition: max-height 1000ms ease-in;
29 }
30 div#tutpick {
31 max-height: 0;
32 overflow: hidden;
33 }
34
35 th.fep {
36 background-color: #e8e8e8;
37 min-width: 3em;
38 padding: 0.4em;
@@ -115,10 +129,15 @@
129
130 <p>We've broken the configuration for each method out into a series of
131 sub-articles. Some of these are generic, while others depend on
132 particular operating systems or front-end software:</p>
133
134 <div id="tutpick"></div>
135
136 <!-- Define alternative to JS tutorial picker below. When updating this
137 table, update "matrix" in the JS code below to match! -->
138 <noscript id="tutmatrix">
139 <table style="margin-left: 6em;">
140 <tr>
141 <th class="host">⇩ OS / Method ⇨</th>
142 <th class="fep">none</th>
143 <th class="fep">inetd</th>
@@ -183,19 +202,121 @@
202 documents linked above: Apple’s <tt>launchd</tt>, Linux’s
203 <tt>systemd</tt>, Solaris’ SMF, etc. We would welcome <a
204 href="contribute.wiki">contributions</a> to cover these as well. We also
205 welcome contributions to fill gaps (<font size="-2">❌</font>) in the table
206 above. </p>
207 </noscript>
208
209
210 <h2 id="more">Further Details</h2>
211
212 <ul>
213 <li><a id="chroot" href="../chroot.md" >The Server Chroot Jail</a>
214 <li><a id="loadmgmt" href="../loadmgmt.md" >Managing Server Load</a>
215 <li><a id="tls" href="../ssl.wiki" >Securing a Repository with TLS</a>
216 <li><a id="ext" href="../serverext.wiki">CGI Server Extensions</a>
217 <li><a id="about" href="../aboutcgi.wiki" >How CGI Works In Fossil</a>
218 <li><a id="sync" href="../sync.wiki" >The Fossil Sync Protocol</a>
219 </ul>
220
221 </div>
222
223 <script type="text/javascript" nonce="$NONCE">
224 (function() {
225 // Define data structure analog to <table> above. Matrix elements
226 // can have one of these constant values or a string for a one-off
227 // custom value. Values outside the <table> above go at the end of
228 // the rows we define here.
229 const YES = 1; // host-specific doc provided
230 const IFA = 2; // inherit doc from "any"
231 const NO = 3; // method invalid or undocumented for this host OS
232 const methods = [
233 "none", "inetd", "stunnel", "CGI", "SCGI", "althttpd", "proxy", "service"
234 ];
235 const matrix = {
236 "any OS": [ YES, YES, YES, YES, YES, YES, NO, NO ],
237 "Debian or Ubuntu": [ IFA, IFA, IFA, IFA, IFA, IFA, "nginx", NO ],
238 "Windows": [ NO, NO, YES, YES, NO, NO, "IIS", NO ],
239 }
240 const osNames = Object.keys(matrix).sort((e) => {
241 return e.toLowerCase()
242 }).map((longName, i) => {
243 var shortName = longName.toLowerCase().split(' ')[0];
244 return [ longName, shortName ];
245 });
246 const osNameMap = Object.fromEntries(osNames);
247 //console.log("OS name map: " + JSON.stringify(osNameMap));
248
249 // Build initial tutorial chooser HTML, and insert it into doc where
250 // the static HTML <table> matrix normally goes.
251 var html = '<p><b>I want to run Fossil on</b> <select id="os">';
252 for (var os of osNames) {
253 const longName = os[0];
254 const shortName = os[1];
255 html += '<option name="' + shortName + '">' + longName + '</option>';
256 }
257 html += '</select> <b>underneath</b> <select id="fep"></select>'
258 html += '<a id="all">SHOW ALL</a></p>';
259 const picker = document.querySelector('div#tutpick');
260 picker.innerHTML = html;
261 picker.classList.add('show');
262
263 // Slide noscript <table> in place of JS tutorial chooser on
264 // "SHOW ALL" click.
265 document.querySelector('a#all').addEventListener('click', () => {
266 picker.classList.remove('show');
267 picker.innerHTML = document.querySelector('#tutmatrix').innerHTML;
268 setTimeout(() => {
269 // Let doc update to set new height, so transition happens.
270 picker.classList.add('show');
271 }, 10);
272 });
273
274 // Attach event handlers to drop-downs. Have to wait until the page
275 // loads, else we'll get null back from querySelector(('select#foo')).
276 window.addEventListener('load', () => {
277 // Set up the FEP choice drop-down on initial page load and
278 // update it when the OS choice drop-down changes.
279 const osSel = document.querySelector('select#os');
280 const fepSel = document.querySelector('select#fep');
281 function osClickHandler() {
282 var osLong = osSel.value;
283 var osShort = osNameMap[osLong];
284
285 var html = '<option>---</option>';
286 matrix[osLong].forEach((choice, i) => {
287 var mu;
288 if (typeof(choice) === 'string') {
289 mu = choice;
290 choice = YES;
291 }
292 else {
293 mu = methods[i];
294 }
295 const ml = mu.toLowerCase();
296
297 if (choice != NO) {
298 if (choice == YES) {
299 html += '<option value="' + osShort + '/' + ml + '.md">';
300 }
301 else if (choice == IFA) {
302 html += '<option value="any/' + ml + '.md">';
303 }
304 html += mu + '</option>';
305 }
306 });
307
308 fepSel.innerHTML = html;
309 }
310 osSel.addEventListener('change', osClickHandler);
311 osClickHandler(); // load fepSel initial content
312
313 // Go to selected document when user changes FEP drop-down
314 fepSel.addEventListener('change', () => {
315 var doc = fepSel.value;
316 if (doc) location.href = doc;
317 // else it's the --- entry, either because we just reloaded the
318 // <option> set or because the user re-selected it.
319 });
320 });
321 })();
322 </script>
323

Keyboard Shortcuts

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