Public
HTTP (deprecated)
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Readme

Quill.js WYSIWYG

Basic WYSIWYG rich text editor, using quill.js.

Press the "Get HTML" button to show the HTML in an alert window.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import { blob } from "https://esm.town/v/std/blob?v=12";
import { thisWebURL } from "https://esm.town/v/stevekrouse/thisWebURL";
export default async function(req: Request) {
const url = new URL(req.url);
const name = url.pathname.slice(1);
if (!name) {
const generatedName = Math.random().toString(36).slice(2, 7);
return Response.redirect(`${thisWebURL()}/${generatedName}`);
}
if (req.method === "POST") {
await blob.setJSON(name, await req.text());
return Response.json("OK");
}
const startingData = await blob.getJSON(name)
?? `<p>Hello World!</p><p> Some initial <strong>bold</strong> text</p><p> <br /></p>`;
return new Response(
`<html>
<head>
<title>Quill Editor</title>
<style>{"html { font-family: sans-serif; }"}</style>
<script src="https://unpkg.com/htmx.org@1.9.9"></script>
<script>htmx.logAll()</script>
<link href="https://cdn.jsdelivr.net/npm/quill@2.0.0/dist/quill.snow.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/quill@2.0.0/dist/quill.js"></script>
</head>
<body style="display: flex; flex-direction: column; padding: 10px; align-items: center">
<div id="save-status" style="align-self: flex-end; padding: 5px; height: 20px"></div>
<div id="editor-view" style="width:90vw; height: 90vw">
<div id="editor">
${startingData}
</div>
</div>
<script type="module">
import {debounce} from "https://esm.sh/lodash-es";
const toolbarOptions = [
["bold", "italic", "underline", "strike"], // toggled buttons
["blockquote", "code-block"],
["link", "image", "video", "formula"],
[{ "header": 1 }, { "header": 2 }], // custom button values
[{ "list": "ordered" }, { "list": "bullet" }, { "list": "check" }],
[{ "script": "sub" }, { "script": "super" }], // superscript/subscript
[{ "indent": "-1" }, { "indent": "+1" }], // outdent/indent
[{ "size": ["small", false, "large", "huge"] }], // custom dropdown
[{ "header": [1, 2, 3, 4, 5, 6, false] }],
[{ "color": [] }, { "background": [] }], // dropdown with defaults from theme
[{ "font": [] }],
[{ "align": [] }],
["clean"], // remove formatting button
];
let options = {
debug: 'info',
modules: {
toolbar: toolbarOptions,
},
theme: 'snow',
};
let quill = new Quill('#editor', options)
function save() {
return fetch('${thisWebURL()}/${name}', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: quill.getSemanticHTML(),
})
}
// on debounced change, save the content
const saveStatus = document.getElementById('save-status');
quill.on('text-change', debounce(
async function(delta, oldDelta, source) {
saveStatus.innerHTML = 'Saving...';
await save();
saveStatus.innerHTML = 'Saved';
await new Promise(r => setTimeout(r, 1000));
saveStatus.innerHTML = '';
}, 1000
));
</script>
</body>
</html>`,
{
headers: {
"Content-Type": "text/html; charset=utf-8",
},
},
);
}
stevekrouse-quilleditor.web.val.run
May 24, 2024