|
|
@@ -6,74 +6,173 @@
|
|
6
|
6
|
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
|
|
7
|
7
|
<style type="text/css">
|
|
8
|
8
|
/* Structural style */
|
|
|
9
|
+ :root, body {
|
|
|
10
|
+ width: 100%; height: 100%;
|
|
|
11
|
+ padding: 0;
|
|
|
12
|
+ margin: 0;
|
|
|
13
|
+ }
|
|
|
14
|
+ .pane-container {
|
|
|
15
|
+ position: absolute;
|
|
|
16
|
+ left: 0; top: 0;
|
|
|
17
|
+ width: 100%; height: 100%;
|
|
|
18
|
+ box-sizing: border-box;
|
|
|
19
|
+
|
|
|
20
|
+ display: grid;
|
|
|
21
|
+ grid-template-columns: auto 1fr;
|
|
|
22
|
+ }
|
|
|
23
|
+ .left-pane {
|
|
|
24
|
+ grid-row: 1; grid-column: 1;
|
|
|
25
|
+ resize: horizontal;
|
|
|
26
|
+ overflow-x: auto;
|
|
|
27
|
+ box-sizing: border-box;
|
|
|
28
|
+ min-width: 40vw;
|
|
|
29
|
+ max-width: 80vw;
|
|
|
30
|
+ border-right: 4px solid var(--color-ui-divider);
|
|
|
31
|
+
|
|
|
32
|
+ display: grid;
|
|
|
33
|
+ grid-template-rows: 32px 1fr;
|
|
|
34
|
+ grid-template-columns: 1fr;
|
|
|
35
|
+ }
|
|
|
36
|
+ .right-pane {
|
|
|
37
|
+ grid-row: 1; grid-column: 2;
|
|
|
38
|
+ overflow-x: auto;
|
|
|
39
|
+ overflow-y: scroll;
|
|
|
40
|
+ }
|
|
|
41
|
+ .toolbar-pane {
|
|
|
42
|
+ grid-row: 1; grid-column: 1;
|
|
|
43
|
+ box-sizing: border-box;
|
|
|
44
|
+ display: grid;
|
|
|
45
|
+ grid-template-columns: 1fr 1fr;
|
|
|
46
|
+ }
|
|
|
47
|
+ .toolbar-left {
|
|
|
48
|
+ grid-column: 1;
|
|
|
49
|
+ }
|
|
|
50
|
+ .toolbar-right {
|
|
|
51
|
+ grid-column: 2;
|
|
|
52
|
+ }
|
|
|
53
|
+ .editor-pane {
|
|
|
54
|
+ grid-row: 2; grid-column: 1;
|
|
|
55
|
+ }
|
|
|
56
|
+ #markdown-editor {
|
|
|
57
|
+ box-sizing: border-box;
|
|
|
58
|
+ position: relative;
|
|
|
59
|
+ width: 100%;
|
|
|
60
|
+ height: 100%;
|
|
|
61
|
+ resize: none;
|
|
|
62
|
+ }
|
|
|
63
|
+ @media screen and (max-width: 800px) {
|
|
|
64
|
+ .pane-container {
|
|
|
65
|
+ grid-template-columns: 1fr;
|
|
|
66
|
+ grid-template-rows: auto 1fr;
|
|
|
67
|
+ column-gap: 0;
|
|
|
68
|
+ }
|
|
|
69
|
+ .left-pane {
|
|
|
70
|
+ grid-row: 2; grid-column: 1;
|
|
|
71
|
+ resize: none;
|
|
|
72
|
+ overflow-x: hidden;
|
|
|
73
|
+ min-width: none;
|
|
|
74
|
+ max-width: none;
|
|
|
75
|
+ width: auto !important; /* undo wide mode resizing */
|
|
|
76
|
+ border-right: none;
|
|
|
77
|
+ border-top: 4px solid var(--color-ui-divider);
|
|
|
78
|
+ }
|
|
|
79
|
+ .right-pane {
|
|
|
80
|
+ grid-row: 1; grid-column: 1;
|
|
|
81
|
+ resize: vertical;
|
|
|
82
|
+ min-height: 40vw;
|
|
|
83
|
+ max-height: 80vw;
|
|
|
84
|
+ }
|
|
|
85
|
+ }
|
|
|
86
|
+ @media screen and (min-width: 801px) {
|
|
|
87
|
+ .right-pane {
|
|
|
88
|
+ height: auto !important; /* undo narrow mode resizing */
|
|
|
89
|
+ }
|
|
|
90
|
+ }
|
|
|
91
|
+
|
|
|
92
|
+ /* UI aesthetic */
|
|
|
93
|
+
|
|
9
|
94
|
:root {
|
|
10
|
95
|
--color-editor-background: #00a;
|
|
11
|
96
|
--color-editor-text: white;
|
|
12
|
|
- --toolbar-background: #ccc;
|
|
13
|
|
- --toolbar-text: #000;
|
|
|
97
|
+ --color-toolbar-background: #ccc;
|
|
|
98
|
+ --color-toolbar-text: #000;
|
|
|
99
|
+ --color-ui-divider: #000;
|
|
14
|
100
|
}
|
|
15
|
101
|
@media (prefers-color-scheme: dark) {
|
|
16
|
102
|
:root {
|
|
17
|
103
|
--toolbar-background: #aaa;
|
|
|
104
|
+ --color-ui-divider: #999;
|
|
18
|
105
|
}
|
|
19
|
106
|
}
|
|
20
|
|
- :root, body {
|
|
21
|
|
- width: 100%;
|
|
22
|
|
- height: 100%;
|
|
23
|
|
- padding: 0;
|
|
24
|
|
- margin: 0;
|
|
25
|
|
- background-color: var(--color-background);
|
|
26
|
|
- color: var(--color-text);
|
|
|
107
|
+ .toolbar-pane,
|
|
|
108
|
+ dialog {
|
|
|
109
|
+ font-family: sans-serif;
|
|
27
|
110
|
}
|
|
28
|
|
- .inputhalf {
|
|
29
|
|
- position: absolute;
|
|
30
|
|
- width: 50%;
|
|
31
|
|
- height: 100%;
|
|
32
|
|
- left: 0;
|
|
33
|
|
- top: 0;
|
|
|
111
|
+
|
|
|
112
|
+ .toolbar-pane {
|
|
|
113
|
+ background-color: var(--color-toolbar-background);
|
|
|
114
|
+ color: var(--color-toolbar-text);
|
|
|
115
|
+ border-bottom: 1px solid var(--color-ui-divider);
|
|
|
116
|
+ padding: 4px 20px;
|
|
|
117
|
+ }
|
|
|
118
|
+ .toolbar-left {
|
|
|
119
|
+ text-align: left;
|
|
|
120
|
+ }
|
|
|
121
|
+ .toolbar-right {
|
|
|
122
|
+ text-align: right;
|
|
|
123
|
+ }
|
|
|
124
|
+ #markdown-editor {
|
|
|
125
|
+ padding: 1em 2em;
|
|
|
126
|
+ border: none;
|
|
|
127
|
+ outline: none;
|
|
34
|
128
|
background-color: var(--color-editor-background);
|
|
35
|
129
|
color: var(--color-editor-text);
|
|
36
|
130
|
}
|
|
37
|
|
- .previewhalf {
|
|
38
|
|
- position: absolute;
|
|
39
|
|
- width: 50%;
|
|
40
|
|
- height: 100%;
|
|
41
|
|
- left: 50%;
|
|
42
|
|
- top: 0;
|
|
43
|
|
- overflow-y: auto;
|
|
44
|
|
- }
|
|
45
|
|
- #preview {
|
|
|
131
|
+ .preview-container {
|
|
46
|
132
|
padding: 1em;
|
|
47
|
133
|
margin: 0 auto;
|
|
48
|
134
|
max-width: 600px;
|
|
|
135
|
+ background-color: var(--color-background);
|
|
|
136
|
+ color: var(--color-text);
|
|
49
|
137
|
}
|
|
50
|
|
- .toolbar {
|
|
51
|
|
- position: absolute;
|
|
52
|
|
- z-index: 1;
|
|
53
|
|
- background-color: var(--toolbar-background);
|
|
54
|
|
- color: var(--toolbar-text);
|
|
55
|
|
- min-height: 32px;
|
|
56
|
|
- /* max-height: 300px; */
|
|
57
|
|
- width: 100%;
|
|
58
|
|
- border-bottom: 1px solid black;
|
|
59
|
|
- box-sizing: border-box;
|
|
60
|
|
- padding: 4px 20px;
|
|
61
|
|
- font-family: sans-serif;
|
|
|
138
|
+
|
|
|
139
|
+ dialog#readers-dialog {
|
|
|
140
|
+ max-width: 400px;
|
|
|
141
|
+ max-height: 400px;
|
|
62
|
142
|
}
|
|
63
|
|
- .codeswitch-cont {
|
|
64
|
|
- position: absolute;
|
|
65
|
|
- top: 0;
|
|
66
|
|
- right: 0;
|
|
67
|
|
- height: 31px;
|
|
68
|
|
- z-index: 2;
|
|
69
|
|
- background-color: var(--toolbar-background);
|
|
70
|
|
- color: var(--toolbar-text);
|
|
71
|
|
- padding: 3px 10px;
|
|
72
|
|
- box-sizing: border-box;
|
|
|
143
|
+ .dialog-layout {
|
|
|
144
|
+ position: relative;
|
|
|
145
|
+ width: 100%; height: 100%;
|
|
|
146
|
+
|
|
|
147
|
+ display: grid;
|
|
|
148
|
+ grid-template-rows: 32px 368px; /* can't get overflow to work without explicit height :( */
|
|
|
149
|
+ }
|
|
|
150
|
+ .dialog-titlebar {
|
|
|
151
|
+ grid-row: 1;
|
|
|
152
|
+
|
|
|
153
|
+ display: grid;
|
|
|
154
|
+ grid-template-columns: 1fr auto;
|
|
73
|
155
|
}
|
|
74
|
|
- #readercontainer {
|
|
|
156
|
+ .dialog-title {
|
|
|
157
|
+ grid-column: 1;
|
|
|
158
|
+ font-weight: bold;
|
|
|
159
|
+ }
|
|
|
160
|
+ .dialog-close {
|
|
|
161
|
+ grid-column: 2;
|
|
|
162
|
+ text-align: right;
|
|
|
163
|
+ }
|
|
|
164
|
+ .dialog-content {
|
|
|
165
|
+ grid-row: 2;
|
|
75
|
166
|
overflow-y: scroll;
|
|
76
|
167
|
}
|
|
|
168
|
+ .reader-list {
|
|
|
169
|
+ position: relative;
|
|
|
170
|
+ width: 100%; height: 100%;
|
|
|
171
|
+ }
|
|
|
172
|
+
|
|
|
173
|
+
|
|
|
174
|
+ /* --- old ----------------------------------------- */
|
|
|
175
|
+
|
|
77
|
176
|
.reader-header {
|
|
78
|
177
|
margin-top: 0.25em;
|
|
79
|
178
|
font-weight: bold;
|
|
|
@@ -82,20 +181,9 @@
|
|
82
|
181
|
display: inline-block;
|
|
83
|
182
|
padding: 4px 8px;
|
|
84
|
183
|
border: 1px dotted gray;
|
|
|
184
|
+ border-radius: 8px;
|
|
85
|
185
|
margin: 4px;
|
|
86
|
186
|
}
|
|
87
|
|
- #markdowninput {
|
|
88
|
|
- position: absolute;
|
|
89
|
|
- box-sizing: border-box;
|
|
90
|
|
- top: 32px;
|
|
91
|
|
- width: 100%;
|
|
92
|
|
- height: calc(100% - 32px);
|
|
93
|
|
- margin: 0;
|
|
94
|
|
- padding: 1em 2em;
|
|
95
|
|
- border: 0;
|
|
96
|
|
- background-color: var(--color-editor-background);
|
|
97
|
|
- color: var(--color-editor-text);
|
|
98
|
|
- }
|
|
99
|
187
|
.calculated {
|
|
100
|
188
|
background-color: var(--color-calculated-background);
|
|
101
|
189
|
font-style: italic;
|
|
|
@@ -112,36 +200,36 @@
|
|
112
|
200
|
:root {
|
|
113
|
201
|
--color-background: #fffff8;
|
|
114
|
202
|
--color-text: #111;
|
|
|
203
|
+ --color-text-secondary: #666;
|
|
115
|
204
|
--color-table-header: #ddd;
|
|
116
|
205
|
--color-table-border: black;
|
|
117
|
206
|
--color-calculated-background: #eee;
|
|
118
|
207
|
--color-highlight: #ff0;
|
|
119
|
208
|
--color-highlight-text: #111;
|
|
|
209
|
+ --color-rule: #111;
|
|
120
|
210
|
}
|
|
121
|
211
|
@media (prefers-color-scheme: dark) {
|
|
122
|
212
|
:root {
|
|
123
|
213
|
--color-background: #151515;
|
|
124
|
214
|
--color-text: #ddd;
|
|
|
215
|
+ --color-text-secondary: #999;
|
|
125
|
216
|
--color-table-header: #333;
|
|
126
|
217
|
--color-table-border: #ccc;
|
|
127
|
218
|
--color-calculated-background: #444;
|
|
128
|
219
|
--color-highlight: #88f;
|
|
129
|
220
|
--color-highlight-text: #ddd;
|
|
|
221
|
+ --color-rule: #ddd;
|
|
130
|
222
|
}
|
|
131
|
223
|
}
|
|
|
224
|
+
|
|
132
|
225
|
html {
|
|
133
|
226
|
font-size: 15px;
|
|
134
|
227
|
}
|
|
135
|
228
|
|
|
136
|
229
|
body {
|
|
137
|
|
- /* width: 87.5%;
|
|
138
|
|
- margin-left: auto;
|
|
139
|
|
- margin-right: auto;
|
|
140
|
|
- padding-left: 12.5%; */
|
|
141
|
230
|
font-family: et-book, Palatino, "Palatino Linotype", "Palatino LT STD", "Book Antiqua", Georgia, serif;
|
|
142
|
231
|
background-color: var(--color-background);
|
|
143
|
232
|
color: var(--color-text);
|
|
144
|
|
- /* max-width: 1400px; */
|
|
145
|
233
|
counter-reset: sidenote-counter;
|
|
146
|
234
|
}
|
|
147
|
235
|
|
|
|
@@ -170,7 +258,7 @@
|
|
170
|
258
|
}
|
|
171
|
259
|
.subtext {
|
|
172
|
260
|
font-size: 1rem;
|
|
173
|
|
- color: #888;
|
|
|
261
|
+ color: var(--color-text-secondary);
|
|
174
|
262
|
margin-top: 0.25em;
|
|
175
|
263
|
margin-bottom: 0.5em;
|
|
176
|
264
|
}
|
|
|
@@ -202,7 +290,7 @@
|
|
202
|
290
|
height: 1px;
|
|
203
|
291
|
width: 55%;
|
|
204
|
292
|
border: 0;
|
|
205
|
|
- border-top: 1px solid #ccc;
|
|
|
293
|
+ border-top: 1px solid var(--color-rule);
|
|
206
|
294
|
margin: 1em 0;
|
|
207
|
295
|
padding: 0;
|
|
208
|
296
|
}
|
|
|
@@ -268,7 +356,99 @@
|
|
268
|
356
|
<script src="js/markdown.js"></script>
|
|
269
|
357
|
<script src="js/spreadsheet.js"></script>
|
|
270
|
358
|
<script>
|
|
271
|
|
- var blockReaderClasses = {
|
|
|
359
|
+ const sampleMarkdown = `
|
|
|
360
|
+## Block Formats {#top}
|
|
|
361
|
+
|
|
|
362
|
+A regular paragraph.
|
|
|
363
|
+
|
|
|
364
|
+-# Sub text
|
|
|
365
|
+
|
|
|
366
|
+* Unordered
|
|
|
367
|
+* Lists
|
|
|
368
|
+ * Sub list
|
|
|
369
|
+
|
|
|
370
|
+1. Ordered
|
|
|
371
|
+2. Lists
|
|
|
372
|
+ 6. Sub list
|
|
|
373
|
+
|
|
|
374
|
+A blockquote:
|
|
|
375
|
+
|
|
|
376
|
+> "The only thing we have to fear is fear itself—nameless, unreasoning,
|
|
|
377
|
+> unjustified terror which paralyzes needed efforts to convert retreat into
|
|
|
378
|
+> advance." - Franklin D. Roosevelt's First Inaugural Address
|
|
|
379
|
+
|
|
|
380
|
+Some definitions:
|
|
|
381
|
+
|
|
|
382
|
+word
|
|
|
383
|
+: a unit of meaning in a sentence
|
|
|
384
|
+sentence
|
|
|
385
|
+: a collection of words
|
|
|
386
|
+
|
|
|
387
|
+Code:
|
|
|
388
|
+
|
|
|
389
|
+\`\`\`javascript
|
|
|
390
|
+function foo() {
|
|
|
391
|
+ return 'Hello world';
|
|
|
392
|
+}
|
|
|
393
|
+\`\`\`
|
|
|
394
|
+
|
|
|
395
|
+ function bar() {
|
|
|
396
|
+ return 'Indented code';
|
|
|
397
|
+ }
|
|
|
398
|
+
|
|
|
399
|
+### Heading, hash style
|
|
|
400
|
+
|
|
|
401
|
+Heading, underline style
|
|
|
402
|
+---
|
|
|
403
|
+
|
|
|
404
|
+### Modified Heading {style=color:red;}
|
|
|
405
|
+
|
|
|
406
|
+| Unit Price | Qty | Subtotal |
|
|
|
407
|
+| ---: | ---: | ---: |
|
|
|
408
|
+| $1.23 | 2 | =A*B FILL |
|
|
|
409
|
+| $4.99 | 6 | |
|
|
|
410
|
+| Total | | =SUM(C:C) |
|
|
|
411
|
+
|
|
|
412
|
+---
|
|
|
413
|
+
|
|
|
414
|
+## Inline Formats
|
|
|
415
|
+
|
|
|
416
|
+Normal, **double asterisk,** __double underscore,__ *asterisks,* _underscores,_
|
|
|
417
|
+~~double tildes,~~ ~single tildes,~ ^carets,^ ==double equals==, \`\`double backticks\`\`,
|
|
|
418
|
+\`single backticks\`.
|
|
|
419
|
+
|
|
|
420
|
+Lorem ipsum dolor sit amet,[^1] consectetur adipiscing elit.[^abc] Sed sodales
|
|
|
421
|
+in odio eget porta. Proin et erat sit amet erat semper mollis vitae ut
|
|
|
422
|
+turpis.[^foo] Ut ipsum dui, maximus sit amet suscipit at, dictum id nulla.[^bar]
|
|
|
423
|
+Aenean efficitur rhoncus nulla non fermentum.
|
|
|
424
|
+
|
|
|
425
|
+[^1]: Donec ut felis volutpat, gravida ipsum scelerisque, accumsan est.
|
|
|
426
|
+[^abc]: Cras dictum rutrum quam.
|
|
|
427
|
+[^foo]: Donec maximus bibendum lorem.
|
|
|
428
|
+[^bar]: Praesent consectetur tristique leo. Morbi nec nisi sit amet quam
|
|
|
429
|
+ imperdiet vehicula eu feugiat tortor.
|
|
|
430
|
+
|
|
|
431
|
+The HTML on the WWW is often full of JS and CSS.
|
|
|
432
|
+
|
|
|
433
|
+*[HTML]: Hypertext Markup Language
|
|
|
434
|
+*[WWW]: World Wide Web
|
|
|
435
|
+*[JS]: JavaScript
|
|
|
436
|
+*[CSS]: Cascading Style Sheets
|
|
|
437
|
+
|
|
|
438
|
+Click [here](#top) to return to the top. Referenced link to [Google][google].
|
|
|
439
|
+
|
|
|
440
|
+ 
|
|
|
441
|
+![][testimage]
|
|
|
442
|
+
|
|
|
443
|
+[testimage]: https://picsum.photos/102/75
|
|
|
444
|
+[google]: https://google.com "I prefer Duck Duck Go"
|
|
|
445
|
+
|
|
|
446
|
+Some verbatim <span style="color:green;">HTML</span>. A script tag
|
|
|
447
|
+will be ignored. <scr` + `ipt></sc` + `ript>
|
|
|
448
|
+ `.trim();
|
|
|
449
|
+ </script>
|
|
|
450
|
+ <script>
|
|
|
451
|
+ const blockReaderClasses = {
|
|
272
|
452
|
'Heading (underline)': MDUnderlinedHeadingReader,
|
|
273
|
453
|
'Heading (hash)': MDHashHeadingReader,
|
|
274
|
454
|
'Subtext': MDSubtextReader,
|
|
|
@@ -283,7 +463,7 @@
|
|
283
|
463
|
'Paragraph': MDParagraphReader,
|
|
284
|
464
|
'Spreadsheets': MDSpreadsheetReader,
|
|
285
|
465
|
};
|
|
286
|
|
- var inlineReaderClasses = {
|
|
|
466
|
+ const inlineReaderClasses = {
|
|
287
|
467
|
'Emphasis': MDEmphasisReader,
|
|
288
|
468
|
'Strong': MDStrongReader,
|
|
289
|
469
|
'Strikethrough': MDStrikethroughReader,
|
|
|
@@ -304,30 +484,36 @@
|
|
304
|
484
|
};
|
|
305
|
485
|
var activeReaders = [];
|
|
306
|
486
|
var parser = null;
|
|
|
487
|
+
|
|
|
488
|
+ function markdownEditorNode() { return document.getElementById('markdown-editor'); }
|
|
|
489
|
+ function previewNode() { return document.getElementById('preview-container'); }
|
|
|
490
|
+ function codeJSNode() { return document.getElementById('code-js'); }
|
|
|
491
|
+ function codePHPNode() { return document.getElementById('code-php'); }
|
|
|
492
|
+ function readersButtonNode() { return document.getElementById('readers-button'); }
|
|
|
493
|
+ function readersDialogNode() { return document.getElementById('readers-dialog'); }
|
|
|
494
|
+ function readerListNode() { return document.getElementById('reader-list'); }
|
|
|
495
|
+
|
|
307
|
496
|
function onDocumentLoad() {
|
|
|
497
|
+ if (markdownEditorNode().value === '') {
|
|
|
498
|
+ markdownEditorNode().value = sampleMarkdown;
|
|
|
499
|
+ }
|
|
308
|
500
|
activeReaders = [ ...Markdown.allReaders, new MDSpreadsheetReader() ];
|
|
309
|
501
|
parser = new Markdown(activeReaders);
|
|
310
|
|
- document.getElementById('markdowninput').addEventListener('input', onMarkdownChange);
|
|
|
502
|
+ markdownEditorNode().addEventListener('input', handleMarkdownChange);
|
|
311
|
503
|
populateReaderCheckboxes();
|
|
312
|
|
- document.getElementById('sendbutton').addEventListener('click', () => {
|
|
313
|
|
- handleSendClicked();
|
|
|
504
|
+ readersButtonNode().addEventListener('click', handleReadersButtonClicked);
|
|
|
505
|
+ codeJSNode().addEventListener('change', handleMarkdownChange);
|
|
|
506
|
+ codePHPNode().addEventListener('change', handleMarkdownChange);
|
|
|
507
|
+ readersDialogNode().getElementsByClassName("dialog-title")[0].innerHTML = "Readers";
|
|
|
508
|
+ readersDialogNode().getElementsByClassName("dialog-titlebar")[0].getElementsByTagName("button")[0].addEventListener('click', () => {
|
|
|
509
|
+ readersDialogNode().close();
|
|
314
|
510
|
});
|
|
315
|
|
- document.getElementById('code-js').addEventListener('change', onMarkdownChange);
|
|
316
|
|
- document.getElementById('code-php').addEventListener('change', onMarkdownChange);
|
|
317
|
|
- setTimeout(onMarkdownChange, 0);
|
|
318
|
|
- }
|
|
319
|
|
- function onMarkdownChange() {
|
|
320
|
|
- if (document.getElementById('code-php').checked) {
|
|
321
|
|
- debouncedSendPreviewRequest();
|
|
322
|
|
- } else if (document.getElementById('code-js').checked) {
|
|
323
|
|
- updatePreviewLocally();
|
|
324
|
|
- }
|
|
|
511
|
+ setTimeout(handleMarkdownChange, 0);
|
|
325
|
512
|
}
|
|
326
|
513
|
function updatePreviewLocally() {
|
|
327
|
|
- const textarea = document.getElementById('markdowninput');
|
|
328
|
|
- let markdown = textarea.value;
|
|
|
514
|
+ let markdown = markdownEditorNode().value;
|
|
329
|
515
|
let html = parser.toHTML(markdown, 'foo-');
|
|
330
|
|
- document.getElementById('preview').innerHTML = html;
|
|
|
516
|
+ previewNode().innerHTML = html;
|
|
331
|
517
|
}
|
|
332
|
518
|
var debounceTimer = null;
|
|
333
|
519
|
var needsUpdate = false;
|
|
|
@@ -348,7 +534,7 @@
|
|
348
|
534
|
}
|
|
349
|
535
|
}
|
|
350
|
536
|
function sendPreviewRequest() {
|
|
351
|
|
- const markdown = document.getElementById('markdowninput').value;
|
|
|
537
|
+ const markdown = markdownEditorNode().value;
|
|
352
|
538
|
const readers = activeReaders.map((r) => r.constructor.name);
|
|
353
|
539
|
const request = new XMLHttpRequest();
|
|
354
|
540
|
var formData = encodeForm({
|
|
|
@@ -359,7 +545,7 @@
|
|
359
|
545
|
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
|
360
|
546
|
request.onreadystatechange = () => {
|
|
361
|
547
|
if (request.readyState == 4 && request.status == 200) {
|
|
362
|
|
- document.getElementById('preview').innerHTML = request.responseText;
|
|
|
548
|
+ previewNode().innerHTML = request.responseText;
|
|
363
|
549
|
}
|
|
364
|
550
|
};
|
|
365
|
551
|
request.send(formData);
|
|
|
@@ -378,7 +564,7 @@
|
|
378
|
564
|
return pairs.join('&');
|
|
379
|
565
|
}
|
|
380
|
566
|
function populateReaderCheckboxes() {
|
|
381
|
|
- const container = document.getElementById('readercontainer');
|
|
|
567
|
+ const container = document.getElementById('reader-list');
|
|
382
|
568
|
var header = document.createElement('div');
|
|
383
|
569
|
header.classList.add('reader-header');
|
|
384
|
570
|
header.append(document.createTextNode('Block Readers'));
|
|
|
@@ -410,6 +596,8 @@
|
|
410
|
596
|
break;
|
|
411
|
597
|
}
|
|
412
|
598
|
}
|
|
|
599
|
+ const label = document.createElement('label');
|
|
|
600
|
+ label.classList.add('reader-check');
|
|
413
|
601
|
const check = document.createElement('input');
|
|
414
|
602
|
check.type = 'checkbox';
|
|
415
|
603
|
check.checked = isSelected;
|
|
|
@@ -417,14 +605,25 @@
|
|
417
|
605
|
handleCheckChanged(readerClass, check);
|
|
418
|
606
|
});
|
|
419
|
607
|
check.id = `reader-${readerClass.name}`;
|
|
420
|
|
- const label = document.createElement('label');
|
|
421
|
|
- label.htmlFor = check.id;
|
|
|
608
|
+ label.append(check);
|
|
422
|
609
|
label.append(document.createTextNode(name));
|
|
423
|
|
- const div = document.createElement('div');
|
|
424
|
|
- div.classList.add('reader-check');
|
|
425
|
|
- div.append(check);
|
|
426
|
|
- div.append(label);
|
|
427
|
|
- return div;
|
|
|
610
|
+ return label;
|
|
|
611
|
+ }
|
|
|
612
|
+
|
|
|
613
|
+ function handleMarkdownChange() {
|
|
|
614
|
+ if (codePHPNode().checked) {
|
|
|
615
|
+ debouncedSendPreviewRequest();
|
|
|
616
|
+ } else if (codeJSNode().checked) {
|
|
|
617
|
+ updatePreviewLocally();
|
|
|
618
|
+ }
|
|
|
619
|
+ }
|
|
|
620
|
+ function handleReadersButtonClicked() {
|
|
|
621
|
+ const dlg = readersDialogNode();
|
|
|
622
|
+ if (dlg.open) {
|
|
|
623
|
+ dlg.close();
|
|
|
624
|
+ } else {
|
|
|
625
|
+ dlg.showModal();
|
|
|
626
|
+ }
|
|
428
|
627
|
}
|
|
429
|
628
|
function handleCheckChanged(readerClass, check) {
|
|
430
|
629
|
if (check.checked) {
|
|
|
@@ -433,124 +632,56 @@
|
|
433
|
632
|
activeReaders = activeReaders.filter((reader) => reader.constructor.name !== readerClass.name);
|
|
434
|
633
|
}
|
|
435
|
634
|
parser = new Markdown(activeReaders);
|
|
436
|
|
- onMarkdownChange();
|
|
437
|
|
- }
|
|
438
|
|
- function handleSendClicked() {
|
|
439
|
|
- sendPreviewRequest();
|
|
|
635
|
+ handleMarkdownChange();
|
|
440
|
636
|
}
|
|
441
|
637
|
document.addEventListener('DOMContentLoaded', onDocumentLoad);
|
|
442
|
638
|
</script>
|
|
443
|
639
|
</head>
|
|
444
|
640
|
|
|
445
|
641
|
<body>
|
|
446
|
|
- <div class="inputhalf half">
|
|
447
|
|
- <div class="toolbar">
|
|
448
|
|
- <details>
|
|
449
|
|
- <summary>Readers</summary>
|
|
450
|
|
-
|
|
451
|
|
- <div id="readercontainer"></div>
|
|
452
|
|
- </details>
|
|
|
642
|
+ <div class="pane-container">
|
|
|
643
|
+ <div class="left-pane pane">
|
|
|
644
|
+ <div class="toolbar-pane">
|
|
|
645
|
+ <div class="toolbar-left">
|
|
|
646
|
+ <button id="readers-button">Readers</button>
|
|
|
647
|
+ </div>
|
|
|
648
|
+ <div class="toolbar-right">
|
|
|
649
|
+ <label>
|
|
|
650
|
+ <input type="radio" id="code-js" name="code" value="js" checked>
|
|
|
651
|
+ Javascript
|
|
|
652
|
+ </label>
|
|
|
653
|
+ <label>
|
|
|
654
|
+ <input type="radio" id="code-php" name="code" value="php">
|
|
|
655
|
+ PHP
|
|
|
656
|
+ </label>
|
|
|
657
|
+ </div>
|
|
|
658
|
+ </div>
|
|
|
659
|
+ <div class="editor-pane">
|
|
|
660
|
+ <textarea id="markdown-editor"></textarea>
|
|
|
661
|
+ </div>
|
|
453
|
662
|
</div>
|
|
454
|
|
- <div class="codeswitch-cont">
|
|
455
|
|
- <input type="radio" id="code-js" name="code" value="js" checked>
|
|
456
|
|
- <label for="code-js">Javascript</label>
|
|
457
|
|
- <input type="radio" id="code-php" name="code" value="php">
|
|
458
|
|
- <label for="code-php">PHP</label>
|
|
|
663
|
+ <div class="right-pane pane">
|
|
|
664
|
+ <div class="preview-container" id="preview-container">
|
|
|
665
|
+ <h1>Preview Here</h1>
|
|
|
666
|
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed turpis. Integer tincidunt eu nibh.</p>
|
|
|
667
|
+ <p>Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies velit. Nam eget dui et libero pharetra dapibus.</p>
|
|
|
668
|
+ <p>Vestibulum in vulputate velit. Cras egestas, urna quis dignissim convallis, arcu felis sagittis diam, non fermentum massa justo ac neque. In ornare do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
|
|
|
669
|
+ <p>Duis phasellus maecenas vestibulum mollis facilisis. Nulla sit amet erat. Suspendisse in justo eu odio suscipit rhoncus. Praesent id massa for ante varius ultrices. Cras sed leo at felis sagittis cursus. Integer turpis est, vulputate ut, elementum ac, condimentum eget, diam.</p>
|
|
|
670
|
+ <p>Aliquam nec enim. Nulla tempus sem et risus. Proin mi. Etiam sit amet orci eget eros faucibus tincidunt. Duis volutpat nunc vel velit. Suspendisse potenti. Integer sollicitudin dictum est. Donec ut dolor. Nam malesuada magna.</p>
|
|
|
671
|
+ <p>Sed non lectus. Vivamus consectetuer purus vitae massa. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies velit. Nam eget dui et libero pharetra dapibus</p>
|
|
|
672
|
+ </div>
|
|
459
|
673
|
</div>
|
|
460
|
|
- <div id="sendbuttoncont"><button id="sendbutton">Send</button></div>
|
|
461
|
|
- <textarea id="markdowninput">## Block Formats {#top}
|
|
462
|
|
-
|
|
463
|
|
-A regular paragraph.
|
|
464
|
|
-
|
|
465
|
|
--# Sub text
|
|
466
|
|
-
|
|
467
|
|
-* Unordered
|
|
468
|
|
-* Lists
|
|
469
|
|
- * Sub list
|
|
470
|
|
-
|
|
471
|
|
-1. Ordered
|
|
472
|
|
-2. Lists
|
|
473
|
|
- 6. Sub list
|
|
474
|
|
-
|
|
475
|
|
-A blockquote:
|
|
476
|
|
-
|
|
477
|
|
-> "The only thing we have to fear is fear itself—nameless, unreasoning,
|
|
478
|
|
-> unjustified terror which paralyzes needed efforts to convert retreat into
|
|
479
|
|
-> advance." - Franklin D. Roosevelt's First Inaugural Address
|
|
480
|
|
-
|
|
481
|
|
-Some definitions:
|
|
482
|
|
-
|
|
483
|
|
-word
|
|
484
|
|
-: a unit of meaning in a sentence
|
|
485
|
|
-sentence
|
|
486
|
|
-: a collection of words
|
|
487
|
|
-
|
|
488
|
|
-Code:
|
|
489
|
|
-
|
|
490
|
|
-```javascript
|
|
491
|
|
-function foo() {
|
|
492
|
|
- return 'Hello world';
|
|
493
|
|
-}
|
|
494
|
|
-```
|
|
495
|
|
-
|
|
496
|
|
- function bar() {
|
|
497
|
|
- return 'Indented code';
|
|
498
|
|
- }
|
|
499
|
|
-
|
|
500
|
|
-### Heading, hash style
|
|
501
|
|
-
|
|
502
|
|
-Heading, underline style
|
|
503
|
|
----
|
|
504
|
|
-
|
|
505
|
|
-### Modified Heading {style=color:red;}
|
|
506
|
|
-
|
|
507
|
|
-| Unit Price | Qty | Subtotal |
|
|
508
|
|
-| ---: | ---: | ---: |
|
|
509
|
|
-| $1.23 | 2 | =A*B FILL |
|
|
510
|
|
-| $4.99 | 6 | |
|
|
511
|
|
-| Total | | =SUM(C:C) |
|
|
512
|
|
-
|
|
513
|
|
----
|
|
514
|
|
-
|
|
515
|
|
-## Inline Formats
|
|
516
|
|
-
|
|
517
|
|
-Normal, **double asterisk,** __double underscore,__ *asterisks,* _underscores,_
|
|
518
|
|
-~~double tildes,~~ ~single tildes,~ ^carets,^ ==double equals==, ``double backticks``,
|
|
519
|
|
-`single backticks`.
|
|
520
|
|
-
|
|
521
|
|
-Lorem ipsum dolor sit amet,[^1] consectetur adipiscing elit.[^abc] Sed sodales
|
|
522
|
|
-in odio eget porta. Proin et erat sit amet erat semper mollis vitae ut
|
|
523
|
|
-turpis.[^foo] Ut ipsum dui, maximus sit amet suscipit at, dictum id nulla.[^bar]
|
|
524
|
|
-Aenean efficitur rhoncus nulla non fermentum.
|
|
525
|
|
-
|
|
526
|
|
-[^1]: Donec ut felis volutpat, gravida ipsum scelerisque, accumsan est.
|
|
527
|
|
-[^abc]: Cras dictum rutrum quam.
|
|
528
|
|
-[^foo]: Donec maximus bibendum lorem.
|
|
529
|
|
-[^bar]: Praesent consectetur tristique leo. Morbi nec nisi sit amet quam
|
|
530
|
|
- imperdiet vehicula eu feugiat tortor.
|
|
531
|
|
-
|
|
532
|
|
-The HTML on the WWW is often full of JS and CSS.
|
|
533
|
|
-
|
|
534
|
|
-*[HTML]: Hypertext Markup Language
|
|
535
|
|
-*[WWW]: World Wide Web
|
|
536
|
|
-*[JS]: JavaScript
|
|
537
|
|
-*[CSS]: Cascading Style Sheets
|
|
538
|
|
-
|
|
539
|
|
-Click [here](#top) to return to the top. Referenced link to [Google][google].
|
|
540
|
|
-
|
|
541
|
|
- 
|
|
542
|
|
-![][testimage]
|
|
543
|
|
-
|
|
544
|
|
-[testimage]: https://picsum.photos/102/75
|
|
545
|
|
-[google]: https://google.com "I prefer Duck Duck Go"
|
|
546
|
|
-
|
|
547
|
|
-Some verbatim <span style="color:green;">HTML</span>. A script tag
|
|
548
|
|
-will be ignored. <script></script></textarea>
|
|
549
|
674
|
</div>
|
|
550
|
|
- <div class="previewhalf half">
|
|
551
|
|
- <div id="preview">
|
|
552
|
|
- <p>Preview here</p>
|
|
|
675
|
+ <dialog id="readers-dialog">
|
|
|
676
|
+ <div class="dialog-layout">
|
|
|
677
|
+ <div class="dialog-titlebar">
|
|
|
678
|
+ <div class="dialog-title"></div>
|
|
|
679
|
+ <div class="dialog-close"><button>✕</button></div>
|
|
|
680
|
+ </div>
|
|
|
681
|
+ <div class="dialog-content">
|
|
|
682
|
+ <div class="reader-list" id="reader-list"></div>
|
|
|
683
|
+ </div>
|
|
553
|
684
|
</div>
|
|
554
|
|
- </div>
|
|
|
685
|
+ </dialog>
|
|
555
|
686
|
</body>
|
|
556
|
687
|
</html>
|