diff options
| -rw-r--r-- | editor/editor.d.ts | 27 | ||||
| -rw-r--r-- | editor/editor.js | 152 | ||||
| -rw-r--r-- | editor/editor.ts | 180 | ||||
| -rw-r--r-- | editor/example.html | 104 |
4 files changed, 463 insertions, 0 deletions
diff --git a/editor/editor.d.ts b/editor/editor.d.ts new file mode 100644 index 0000000..ff1c307 --- /dev/null +++ b/editor/editor.d.ts @@ -0,0 +1,27 @@ +import { IVfsNode, Response } from "../vfs/vfs"; +export interface IEditor { + id: string; + is_editable: boolean; + OpenFile(path: string): Response; + SaveFile(node: IVfsNode): Response; +} +export declare class Editor implements IEditor { + opts: IEditor; + id: string; + is_editable: boolean; + private el; + private activeFile; + private activeText; + private rangeBegin; + private rangeEnd; + private lines; + constructor(opts: IEditor); + OpenFile(path: string): Response; + SaveFile(node: IVfsNode): Response; + insertNewline(x: number): void; + onClickText(text: HTMLElement): void; + onKeydownText(x: number, text: HTMLElement, ev: KeyboardEvent): boolean; + onMouseDownAtLine(x: number): void; + onMouseUpAtLine(x: number): void; + render(): void; +} diff --git a/editor/editor.js b/editor/editor.js new file mode 100644 index 0000000..540b42c --- /dev/null +++ b/editor/editor.js @@ -0,0 +1,152 @@ +"use strict"; +exports.__esModule = true; +exports.Editor = void 0; +var Editor = /** @class */ (function () { + function Editor(opts) { + this.opts = opts; + this.activeFile = null; + this.activeText = null; + this.rangeBegin = 0; + this.rangeEnd = 0; + this.lines = []; + this.id = opts.id; + this.is_editable = opts.is_editable; + this.el = document.getElementById(opts.id); + if (!this.el) { + console.error("Editor: element ID not found:", opts.id); + return; + } + this.el.classList.add("wui-editor"); + } + Editor.prototype.OpenFile = function (path) { + var res = { + code: 500 + }; + if (!this.el) { + return res; + } + res = this.opts.OpenFile(path); + if (res.code != 200) { + return res; + } + if (!res.data) { + return res; + } + this.activeFile = res.data; + var content = this.activeFile.content; + content = content.replace("\r\n", "\n"); + var lines = content.split("\n"); + for (var x = 0; x < lines.length; x++) { + var line = new EditorLine(x, lines[x], this); + this.lines.push(line); + } + this.render(); + return res; + }; + Editor.prototype.SaveFile = function (node) { + var res = this.opts.SaveFile(node); + return res; + }; + Editor.prototype.insertNewline = function (x) { + console.log("enter new line:", x); + var newline = new EditorLine(x, "", this); + for (var y = x; y < this.lines.length; y++) { + this.lines[y].setNumber(y + 2); + } + this.lines.splice(x, 0, newline); + this.render(); + }; + Editor.prototype.onClickText = function (text) { + if (this.activeText) { + this.activeText.contentEditable = "false"; + this.activeText.style.borderWidth = "0"; + } + text.contentEditable = "true"; + text.style.borderWidth = "2px"; + this.activeText = text; + text.focus(); + }; + Editor.prototype.onKeydownText = function (x, text, ev) { + if (ev.key === "Escape") { + text.contentEditable = "false"; + text.style.borderWidth = "0"; + this.activeText = null; + return false; + } + if (ev.key === "Enter") { + this.insertNewline(x + 1); + ev.preventDefault(); + return false; + } + return true; + }; + Editor.prototype.onMouseDownAtLine = function (x) { + this.rangeBegin = x; + }; + Editor.prototype.onMouseUpAtLine = function (x) { + this.rangeEnd = x; + console.log("range: ", this.rangeBegin, " - ", this.rangeEnd); + if (this.rangeEnd < this.rangeBegin) { + return; + } + if (!this.el) { + return; + } + var y = 0; + for (; y < this.rangeBegin; y++) { + this.el.children[y].setAttribute("style", ""); + } + for (; y <= this.rangeEnd; y++) { + this.el.children[y].setAttribute("style", "background-color:lightsalmon"); + } + for (; y < this.el.children.length; y++) { + this.el.children[y].setAttribute("style", ""); + } + }; + Editor.prototype.render = function () { + if (!this.el) { + return; + } + this.el.innerHTML = ""; + for (var _i = 0, _a = this.lines; _i < _a.length; _i++) { + var line = _a[_i]; + this.el.appendChild(line.el); + } + }; + return Editor; +}()); +exports.Editor = Editor; +var EditorLine = /** @class */ (function () { + function EditorLine(x, text, ed) { + var _this = this; + this.x = x; + this.text = text; + this.el = document.createElement("div"); + this.el.classList.add("wui-editor-line"); + this.elNumber = document.createElement("span"); + this.elNumber.classList.add("wui-line-number"); + this.elNumber.innerText = x + 1 + ""; + this.elNumber.onmousedown = function (ev) { + ed.onMouseDownAtLine(x); + }; + this.elNumber.onmouseup = function (ev) { + ed.onMouseUpAtLine(x); + }; + this.elText = document.createElement("span"); + this.elText.classList.add("wui-line-text"); + this.elText.innerText = text; + this.elText.onclick = function (ev) { + ed.onClickText(_this.elText); + }; + this.elText.onkeydown = function (ev) { + return ed.onKeydownText(x, _this.elText, ev); + }; + this.el.appendChild(this.elNumber); + this.el.appendChild(this.elText); + } + EditorLine.prototype.setNumber = function (x) { + this.elNumber.innerText = x + ""; + }; + return EditorLine; +}()); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZWRpdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQVVBO0lBVUMsZ0JBQW1CLElBQWE7UUFBYixTQUFJLEdBQUosSUFBSSxDQUFTO1FBTnhCLGVBQVUsR0FBb0IsSUFBSSxDQUFBO1FBQ2xDLGVBQVUsR0FBdUIsSUFBSSxDQUFBO1FBQ3JDLGVBQVUsR0FBVyxDQUFDLENBQUE7UUFDdEIsYUFBUSxHQUFXLENBQUMsQ0FBQTtRQUNwQixVQUFLLEdBQWlCLEVBQUUsQ0FBQTtRQUcvQixJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUE7UUFDakIsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFBO1FBRW5DLElBQUksQ0FBQyxFQUFFLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7UUFDMUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUU7WUFDYixPQUFPLENBQUMsS0FBSyxDQUFDLCtCQUErQixFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtZQUN2RCxPQUFNO1NBQ047UUFDRCxJQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUE7SUFDcEMsQ0FBQztJQUVELHlCQUFRLEdBQVIsVUFBUyxJQUFZO1FBQ3BCLElBQUksR0FBRyxHQUFhO1lBQ25CLElBQUksRUFBRSxHQUFHO1NBQ1QsQ0FBQTtRQUNELElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFO1lBQ2IsT0FBTyxHQUFHLENBQUE7U0FDVjtRQUVELEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUM5QixJQUFJLEdBQUcsQ0FBQyxJQUFJLElBQUksR0FBRyxFQUFFO1lBQ3BCLE9BQU8sR0FBRyxDQUFBO1NBQ1Y7UUFDRCxJQUFJ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
\ No newline at end of file diff --git a/editor/editor.ts b/editor/editor.ts new file mode 100644 index 0000000..f021db0 --- /dev/null +++ b/editor/editor.ts @@ -0,0 +1,180 @@ +import { IVfsNode, Response } from "../vfs/vfs" + +export interface IEditor { + id: string + is_editable: boolean + + OpenFile(path: string): Response + SaveFile(node: IVfsNode): Response +} + +export class Editor implements IEditor { + id: string + is_editable: boolean + private el: HTMLElement | null + private activeFile: IVfsNode | null = null + private activeText: HTMLElement | null = null + private rangeBegin: number = 0 + private rangeEnd: number = 0 + private lines: EditorLine[] = [] + + constructor(public opts: IEditor) { + this.id = opts.id + this.is_editable = opts.is_editable + + this.el = document.getElementById(opts.id) + if (!this.el) { + console.error("Editor: element ID not found:", opts.id) + return + } + this.el.classList.add("wui-editor") + } + + OpenFile(path: string): Response { + let res: Response = { + code: 500, + } + if (!this.el) { + return res + } + + res = this.opts.OpenFile(path) + if (res.code != 200) { + return res + } + if (!res.data) { + return res + } + + this.activeFile = res.data as IVfsNode + + let content = this.activeFile.content as string + content = content.replace("\r\n", "\n") + let lines = content.split("\n") + + for (let x = 0; x < lines.length; x++) { + let line = new EditorLine(x, lines[x], this) + this.lines.push(line) + } + + this.render() + + return res + } + + SaveFile(node: IVfsNode): Response { + let res = this.opts.SaveFile(node) + return res + } + + insertNewline(x: number) { + console.log("enter new line:", x) + let newline = new EditorLine(x, "", this) + for (let y = x; y < this.lines.length; y++) { + this.lines[y].setNumber(y + 2) + } + this.lines.splice(x, 0, newline) + this.render() + } + + onClickText(text: HTMLElement) { + if (this.activeText) { + this.activeText.contentEditable = "false" + this.activeText.style.borderWidth = "0" + } + text.contentEditable = "true" + text.style.borderWidth = "2px" + this.activeText = text + text.focus() + } + + onKeydownText(x: number, text: HTMLElement, ev: KeyboardEvent) { + if (ev.key === "Escape") { + text.contentEditable = "false" + text.style.borderWidth = "0" + this.activeText = null + return false + } + if (ev.key === "Enter") { + this.insertNewline(x + 1) + ev.preventDefault() + return false + } + return true + } + + onMouseDownAtLine(x: number) { + this.rangeBegin = x + } + + onMouseUpAtLine(x: number) { + this.rangeEnd = x + console.log("range: ", this.rangeBegin, " - ", this.rangeEnd) + if (this.rangeEnd < this.rangeBegin) { + return + } + if (!this.el) { + return + } + let y = 0 + for (; y < this.rangeBegin; y++) { + this.el.children[y].setAttribute("style", "") + } + for (; y <= this.rangeEnd; y++) { + this.el.children[y].setAttribute("style", "background-color:lightsalmon") + } + for (; y < this.el.children.length; y++) { + this.el.children[y].setAttribute("style", "") + } + } + + render() { + if (!this.el) { + return + } + this.el.innerHTML = "" + for (const line of this.lines) { + this.el.appendChild(line.el) + } + } +} + +class EditorLine { + el!: HTMLElement + elNumber!: HTMLElement + elText!: HTMLElement + + constructor(public x: number, public text: string, ed: Editor) { + this.el = document.createElement("div") + this.el.classList.add("wui-editor-line") + + this.elNumber = document.createElement("span") + this.elNumber.classList.add("wui-line-number") + this.elNumber.innerText = x + 1 + "" + + this.elNumber.onmousedown = (ev: MouseEvent) => { + ed.onMouseDownAtLine(x) + } + this.elNumber.onmouseup = (ev: MouseEvent) => { + ed.onMouseUpAtLine(x) + } + + this.elText = document.createElement("span") + this.elText.classList.add("wui-line-text") + this.elText.innerText = text + + this.elText.onclick = (ev: MouseEvent) => { + ed.onClickText(this.elText) + } + this.elText.onkeydown = (ev: KeyboardEvent) => { + return ed.onKeydownText(x, this.elText, ev) + } + + this.el.appendChild(this.elNumber) + this.el.appendChild(this.elText) + } + + setNumber(x: number) { + this.elNumber.innerText = x + "" + } +} diff --git a/editor/example.html b/editor/example.html new file mode 100644 index 0000000..ac45e60 --- /dev/null +++ b/editor/example.html @@ -0,0 +1,104 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="UTF-8" /> + <title>WUI - editor</title> + <style> + [contenteditable] { + outline: 0px solid transparent; + } + .wui-editor { + background-color: cornsilk; + font-family: monospace; + width: 100%; + } + .wui-editor-line { + display: table; + } + .wui-line-number:hover { + background-color: lightsalmon; + } + .wui-line-number { + display: table-cell; + padding: 4px 1em 4px 4px; + text-align: right; + width: 3em; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + } + .wui-line-text { + display: table-cell; + padding: 4px; + border-color: lightblue; + border-width: 0px; + border-style: solid; + } + </style> + </head> + <body onload="main()"> + <div id="editor"></div> + + <script> + var exports = {} + </script> + <script src="editor.js"></script> + <script> + function main() { + let opts = { + id: "editor", + is_editable: true, + OpenFile: doOpenFile, + } + + let editor = new Editor(opts) + + editor.OpenFile("/test.aww") + } + + function doOpenFile(path) { + let res = { + code: 200, + data: { + name: "Test", + path: path, + content: `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 +`, + }, + } + return res + } + </script> + </body> +</html> |
