diff options
| author | Shulhan <ms@kilabit.info> | 2021-08-27 08:40:25 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2021-08-27 23:47:17 +0700 |
| commit | 58cfb51717241721b8e66bdbf4ea4bb9a41b5ca1 (patch) | |
| tree | be8d487163024cccd7daf32980f1a3da5cacfa6e /editor/editor.ts | |
| parent | 6857ce06167038eb5980a9b2bfc2af2c6c0a87ae (diff) | |
| download | pakakeh.ts-58cfb51717241721b8e66bdbf4ea4bb9a41b5ca1.tar.xz | |
editor: add handler to save the content
When user press CTRL+S on the editor, it will trigger the OnSave handler.
While at it,
* auto scroll when pressing arrow up or down
* auto scroll to bottom when pressing Enter at the end of file
* fix tab key not inserting tab characters
Diffstat (limited to 'editor/editor.ts')
| -rw-r--r-- | editor/editor.ts | 182 |
1 files changed, 111 insertions, 71 deletions
diff --git a/editor/editor.ts b/editor/editor.ts index 15107da..b227f3c 100644 --- a/editor/editor.ts +++ b/editor/editor.ts @@ -12,6 +12,9 @@ export interface IEditor { // Handler that will be called when user select lines. OnSelection(begin: number, end: number): void + + // Handler that will be callend when user press CTRL+S. + OnSave(content: string): void } export class Editor { @@ -137,34 +140,34 @@ export class Editor { .wui-editor { background-color: cornsilk; font-family: monospace; + overflow-y: auto; width: 100%; - overflow-y: scroll; } .wui-editor-line { - display: table; + display: block; + width: 100%; } .wui-line-number { - -moz-user-select: none; - -ms-user-select: none; - -webkit-user-select: none; color: dimgrey; cursor: pointer; - display: table-cell; - padding: 4px 1em 4px 4px; + display: inline-block; + padding: 4px 10px 4px 4px; text-align: right; user-select: none; - width: 3em; + vertical-align: top; + width: 30px; } .wui-line-number:hover { background-color: lightsalmon; } .wui-line-text { - display: table-cell; + display: inline-block; padding: 4px; border-color: lightblue; border-width: 0px; border-style: solid; white-space: pre-wrap; + width: calc(100% - 60px); } ` document.head.appendChild(style) @@ -251,11 +254,14 @@ export class Editor { onKeyup(x: number, text: HTMLElement, ev: KeyboardEvent) { let textBefore: string let textAfter: string + let off: number switch (ev.key) { case "Alt": + case "ArrowDown": case "ArrowLeft": case "ArrowRight": + case "ArrowUp": case "CapsLock": case "ContextMenu": case "Delete": @@ -271,58 +277,23 @@ export class Editor { case "Shift": break - case "ArrowUp": - if (x == 0) { - return false - } - if (!this.sel) { - return false - } - ev.preventDefault() - let elText = this.lines[x - 1].elText - let off = this.sel.focusOffset - if (off > elText.innerText.length) { - off = elText.innerText.length - } - this.setCaret(elText, off) - break - - case "ArrowDown": - if (x == this.lines.length - 1) { - return false - } - if (!this.sel) { - return false - } - ev.preventDefault() - elText = this.lines[x + 1].elText - off = this.sel.focusOffset - if (off > elText.innerText.length) { - off = elText.innerText.length - } - this.setCaret(elText, off) - break - case "Backspace": if (!this.sel) { - return + return false } ev.preventDefault() + textBefore = this.rawLines[x] let elTextCurr = this.lines[x].elText - textBefore = elTextCurr.innerText + textAfter = elTextCurr.innerText off = this.sel.focusOffset if (off > 0) { - textAfter = - textBefore.slice(0, off - 1) + textBefore.slice(off, textBefore.length) - this.unre.DoUpdate(x, textBefore, textAfter) - elTextCurr.innerText = textAfter this.rawLines[x] = textAfter - this.setCaret(elTextCurr, off - 1) - return + this.setCaret(elTextCurr, off) + return false } // Join current line with previous. @@ -337,34 +308,16 @@ export class Editor { // Remove the current line this.deleteLine(x) this.setCaret(elTextPrev, off) - break + return false - case "Enter": - ev.preventDefault() + case "Control": + this.isKeyControl = false break - case "Tab": - if (!this.sel) { - return false - } - - elText = this.lines[x].elText - off = this.sel.focusOffset - textBefore = elText.innerText - textAfter = textBefore.slice(0, off) + "\t" + textBefore.slice(off, textBefore.length) - - this.unre.DoUpdate(x, textBefore, textAfter) - elText.innerText = textAfter - this.rawLines[x] = textAfter - - this.setCaret(elText, off + 1) + case "Enter": ev.preventDefault() break - case "Control": - this.isKeyControl = false - break - case "r": if (this.isKeyControl) { ev.preventDefault() @@ -395,11 +348,65 @@ export class Editor { let off: number switch (ev.key) { + case "ArrowUp": + if (x == 0) { + return false + } + if (!this.el) { + return false + } + if (!this.sel) { + return false + } + ev.preventDefault() + + let elText = this.lines[x - 1].elText + let off = this.sel.focusOffset + if (off > elText.innerText.length) { + off = elText.innerText.length + } + this.setCaret(elText, off) + + if (x == 1) { + this.el.scrollTop = 0 + } else if (x * 23 < this.el.scrollTop) { + this.el.scrollTop -= 25 + } + return false + + case "ArrowDown": + if (x == this.lines.length - 1) { + return false + } + if (!this.el) { + return false + } + if (!this.sel) { + return false + } + ev.preventDefault() + + elText = this.lines[x + 1].elText + off = this.sel.focusOffset + if (off > elText.innerText.length) { + off = elText.innerText.length + } + this.setCaret(elText, off) + + x += 2 + if (x * 25 >= this.el.clientHeight + this.el.scrollTop) { + this.el.scrollTop += 25 + } + return false + case "Control": this.isKeyControl = true break case "Enter": + if (!this.el) { + return + } if (!this.sel) { return } @@ -416,6 +423,10 @@ export class Editor { this.rawLines[x] = textBefore this.insertNewline(x + 1, textAfter) + console.log("scroll", x, this.rawLines.length) + if (x + 3 >= this.rawLines.length) { + this.el.scrollTop = this.el.scrollHeight + } break case "Escape": @@ -423,6 +434,24 @@ export class Editor { this.clearSelection() break + case "Tab": + if (!this.sel) { + return false + } + ev.preventDefault() + + elText = this.lines[x].elText + off = this.sel.focusOffset + textBefore = elText.innerText + textAfter = textBefore.slice(0, off) + "\t" + textBefore.slice(off, textBefore.length) + + this.unre.DoUpdate(x, textBefore, textAfter) + elText.innerText = textAfter + this.rawLines[x] = textAfter + + this.setCaret(elText, off + 1) + break + case "r": if (this.isKeyControl) { ev.preventDefault() @@ -431,6 +460,17 @@ export class Editor { } break + case "s": + if (this.isKeyControl) { + ev.preventDefault() + ev.stopPropagation() + if (this.opts.OnSave) { + this.opts.OnSave(this.GetContent()) + } + return false + } + break + case "z": if (this.isKeyControl) { ev.preventDefault() |
