diff options
Diffstat (limited to 'editor')
| -rw-r--r-- | editor/editor.js | 205 | ||||
| -rw-r--r-- | editor/example.js | 65 |
2 files changed, 270 insertions, 0 deletions
diff --git a/editor/editor.js b/editor/editor.js new file mode 100644 index 0000000..e80e147 --- /dev/null +++ b/editor/editor.js @@ -0,0 +1,205 @@ +// SPDX-FileCopyrightText: 2021 M. Shulhan <ms@kilabit.info> +// SPDX-License-Identifier: GPL-3.0-or-later +const WUI_EDITOR_CLASS = "wui_editor"; +const WUI_EDITOR_CLASS_LINE_NUMBER = "wui_editor_line_number"; +const WUI_EDITOR_CLASS_CONTENT = "wui_editor_content"; +export class WuiEditor { + constructor(opts) { + this.opts = opts; + this.content = ""; + this.totalLine = 0; + this.elLineNumber = document.createElement("div"); + this.elContent = document.createElement("div"); + this.isKeyControl = false; + this.id = opts.id; + this.isEditable = opts.isEditable; + const el = document.getElementById(opts.id); + if (!el) { + console.error("WuiEditor: element ID not found:", opts.id); + return; + } + this.el = el; + this.initStyle(); + this.initLineNumber(); + this.initContent(); + this.el.classList.add(WUI_EDITOR_CLASS); + } + // getContent return content of file. + getContent() { + let content = ""; + let el; + let line; + this.elContent.childNodes.forEach((node) => { + switch (node.nodeType) { + case Node.ELEMENT_NODE: + el = node; + line = el.innerText; + break; + case Node.TEXT_NODE: + line = node.nodeValue || ""; + break; + } + line = line.trimEnd(); + content += line + "\n"; + }); + content = content.trim(); + return content; + } + // open the node for editing. + // The content MUST be encoded in base64. + open(node) { + this.content = atob(node.content); + this.content = this.content.replace("\r\n", "\n"); + this.render(this.content); + } + setEditable(yes) { + this.isEditable = yes; + if (yes) { + this.elContent.setAttribute("contenteditable", "true"); + } + else { + this.elContent.setAttribute("contenteditable", "false"); + } + } + addNewLine() { + this.totalLine++; + const elLine = document.createElement("div"); + elLine.innerText = `${this.totalLine}`; + this.elLineNumber.appendChild(elLine); + } + initLineNumber() { + this.elLineNumber.classList.add(WUI_EDITOR_CLASS_LINE_NUMBER); + this.el.appendChild(this.elLineNumber); + } + initContent() { + if (this.opts.isEditable) { + this.elContent.setAttribute("contenteditable", "true"); + this.elContent.setAttribute("spellcheck", "false"); + this.elContent.addEventListener("paste", (ev) => { + var _a; + ev.preventDefault(); + let text = ((_a = ev.clipboardData) === null || _a === void 0 ? void 0 : _a.getData("text/plain")) || ""; + if (!text) { + console.error(`on paste: text is ${text}`); + return; + } + const selection = window.getSelection(); + if (!selection || !selection.rangeCount) { + console.error(`on paste: failed to get selection`); + return; + } + text = text.trimEnd(); + selection.deleteFromDocument(); + selection.getRangeAt(0).insertNode(document.createTextNode(text)); + selection.collapseToEnd(); + this.renderLineNumber(this.getContent()); + }); + this.elContent.onkeydown = (ev) => { + this.onKeydownDocument(this, ev); + }; + this.elContent.onkeyup = (ev) => { + this.onKeyupDocument(this, ev); + }; + this.elContent.addEventListener("blur", () => { + this.isKeyControl = false; + }); + } + this.elContent.classList.add(WUI_EDITOR_CLASS_CONTENT); + this.el.appendChild(this.elContent); + } + initStyle() { + const style = document.createElement("style"); + style.type = "text/css"; + style.innerText = ` + [contenteditable] { + outline: 0px solid transparent; + } + .${WUI_EDITOR_CLASS} { + background-color: cornsilk; + border: 1px solid brown; + font-family: monospace; + line-height: 1.6em; + overflow-y: scroll; + width: 100%; + } + .${WUI_EDITOR_CLASS_LINE_NUMBER} { + background-color: bisque; + border-right: 1px dashed brown; + color: dimgrey; + display: inline-block; + font-family: monospace; + margin-right: 4px; + padding: 0px 8px; + position: sticky; + text-align: right; + width: 3em; + } + .${WUI_EDITOR_CLASS_CONTENT} { + caret-color: red; + display: inline-block; + padding: 0px 8px 0 0; + vertical-align: top; + white-space: pre; + width: calc(100% - 10em); + word-wrap: normal; + } + `; + document.head.appendChild(style); + } + onKeydownDocument(ed, ev) { + switch (ev.key) { + case "Control": + ed.isKeyControl = true; + break; + case "Enter": + if (ed.isKeyControl) { + ev.preventDefault(); + ev.stopPropagation(); + if (ed.opts.onSave) { + const content = ed.getContent(); + ed.opts.onSave(content); + ed.render(content); + } + return false; + } + this.addNewLine(); + return false; + } + return true; + } + onKeyupDocument(ed, ev) { + switch (ev.key) { + case "Control": + ed.isKeyControl = false; + return true; + } + return true; + } + render(content) { + const lines = content.split("\n"); + this.elContent.innerText = ""; + this.elLineNumber.innerText = ""; + lines.forEach((line, x) => { + const el = document.createElement("div"); + el.innerText = `${x + 1}`; + this.elLineNumber.appendChild(el); + const div = document.createElement("div"); + div.innerText = line; + if (line == "") { + div.appendChild(document.createElement("br")); + } + this.elContent.appendChild(div); + }); + this.totalLine = lines.length; + } + renderLineNumber(content) { + const lines = content.split("\n"); + this.elLineNumber.innerText = ""; + lines.forEach((_, x) => { + const el = document.createElement("div"); + el.innerText = `${x + 1}`; + this.elLineNumber.appendChild(el); + }); + this.totalLine = lines.length; + } +} diff --git a/editor/example.js b/editor/example.js new file mode 100644 index 0000000..cbda425 --- /dev/null +++ b/editor/example.js @@ -0,0 +1,65 @@ +// SPDX-FileCopyrightText: 2019 M. Shulhan <ms@kilabit.info> +// SPDX-License-Identifier: GPL-3.0-or-later +import { WuiEditor } from "./editor.js"; +const nodeFile = { + name: "Test", + path: "/test", + is_dir: false, + content_type: "text/plain", + mod_time: 0, + size: 0, + mode: "", + childs: [], + content: btoa(`mkdir -p \${HOME}/aur/stackdriver-collectd + +git -C \${HOME}/aur/stackdriver-collectd clone \\ + ssh://aur@aur.archlinux.org/stackdriver-collectd.git . + +sh -c "cd \${HOME}/aur/stackdriver-collectd; \\ + makepkg --force --install --noconfirm" +pacman -Ql stackdriver-collectd + +sudo systemctl enable stackdriver-collectd + +#put! {{.BaseDir}}/_template/etc/collectd-influxdb.conf /opt/collectd/etc/collectd.conf + +sudo systemctl restart stackdriver-collectd +sudo systemctl status stackdriver-collectd + +##---- Connect telegraf with collectd + +{{.Val "influxdb::dir"}}/bin/influx bucket create \\ + --name stackdriver_collectd \\ + --description "stackdriver collectd" \\ + --org {{.Val "influxdb::org"}} \\ + --token {{.Val "influxdb:telegraf:token"}} \\ + --retention "3d" + +#put: {{.BaseDir}}/_template/etc/telegraf/telegraf.d/stackdriver-collectd.conf \\ + {{.Val "influxdb::dir"}}/etc/telegraf/telegraf.d/stackdriver-collectd.conf + +sudo systemctl restart telegraf +sudo systemctl status telegraf +`), +}; +const opts = { + id: "editor", + isEditable: true, + onSave: (content) => { + const lines = content.split("\n"); + lines.forEach((line, x) => { + console.log(`${x}: ${line}`); + }); + }, +}; +const wuiEditor = new WuiEditor(opts); +wuiEditor.open(nodeFile); +const optsro = { + id: "editor-readonly", + isEditable: false, + onSave: (content) => { + console.log("OnSave: ", content); + }, +}; +const edro = new WuiEditor(optsro); +edro.open(nodeFile); |
