diff options
| author | Shulhan <ms@kilabit.info> | 2023-11-01 23:50:51 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2023-11-01 23:50:51 +0700 |
| commit | de34f96f48c69443b130d2e49a0dd5c1e26dba7f (patch) | |
| tree | bcaaf7a55fed0de75eaf75d41279441a3081b74c /editor/editor.ts | |
| parent | 628e07e9d638abaf4987cd9233085a42a8a40d89 (diff) | |
| download | pakakeh.ts-de34f96f48c69443b130d2e49a0dd5c1e26dba7f.tar.xz | |
editor: handle DELETE on selection
If user select text and press delete key, the selected text should be
deleted.
Diffstat (limited to 'editor/editor.ts')
| -rw-r--r-- | editor/editor.ts | 104 |
1 files changed, 61 insertions, 43 deletions
diff --git a/editor/editor.ts b/editor/editor.ts index 4ca0cce..e95b858 100644 --- a/editor/editor.ts +++ b/editor/editor.ts @@ -89,7 +89,65 @@ export class WuiEditor { } } - onKeyup(x: number, ev: KeyboardEvent) { + // onKeyDelete handle key "DELETE" event on line. + // + // Case 1: DELETE on selection. + // We "cut" the selected text and push it to undo-redo registry. + // + // Case 2: DELETE on the end of line. + // If the next line exist, join them with current line. + // + // Case 3: DELETE on beginning or middle of text. + onKeyDelete(x: number, ev: KeyboardEvent) { + ev.preventDefault(); + + let elTextCurrent = this.lines[x]!.elText; + let textCurr = elTextCurrent.innerText; + + let selString = this.sel.toString(); + if (selString.length > 0) { + // Case 1: DELETE on selection. + let textAfter = textCurr.slice(0, this.sel.anchorOffset); + textAfter += textCurr.slice(this.sel.focusOffset, textCurr.length); + this.unre.doUpdate(x, textCurr, textAfter); + this.sel.deleteFromDocument(); + return; + } + + let textAfter = ""; + let off = this.sel.focusOffset; + + if (off === textCurr.length) { + // Case 2: DELETE on the end of line. + if (x + 1 >= this.lines.length) { + // Current line is the last line, nothing to do. + return; + } + + const elTextAfter = this.lines[x + 1]!.elText; + textAfter = elTextAfter.innerText; + elTextAfter.innerText = ""; + + this.unre.doJoin(x, textCurr, textAfter); + this.deleteLine(x + 1); + + textAfter = textCurr + textAfter; + this.lines[x]!.elText.innerText = textAfter; + this.setCaret(elTextCurrent, off); + return; + } + + // Case 3: DELETE on beginning or middle of text. + textAfter = textCurr.slice(0, off); + textAfter += textCurr.slice(off + 1, textCurr.length); + + this.unre.doUpdate(x, textCurr, textAfter); + + this.lines[x]!.elText.innerText = textAfter; + this.setCaret(elTextCurrent, off); + } + + onKeyupOnLine(x: number, ev: KeyboardEvent) { let elTextCurr: HTMLElement; let elTextPrev: HTMLElement; let textBefore: string; @@ -169,9 +227,7 @@ export class WuiEditor { let textAfter: string; let off: number; let elText: HTMLElement | undefined; - let elTextCurrent: HTMLElement; let text: string; - let isJoinLineAfter: boolean; switch (ev.key) { case "ArrowUp": @@ -214,45 +270,7 @@ export class WuiEditor { return false; case "Delete": - ev.preventDefault(); - - isJoinLineAfter = false; - elTextCurrent = this.lines[x]!.elText; - - off = this.sel.focusOffset; - textBefore = elTextCurrent.innerText; - textAfter = ""; - - if (textBefore.length === 0 || off === textBefore.length) { - // Current line is empty, join the next line to current - // line; or - // Current offset is at the end of text, join the next - // line to current line. - isJoinLineAfter = true; - } - - if (isJoinLineAfter) { - if (x + 1 < this.lines.length) { - const elTextAfter = this.lines[x + 1]!.elText; - textAfter = elTextAfter.innerText; - elTextAfter.innerText = ""; - - this.unre.doJoin(x, textBefore, textAfter); - - this.deleteLine(x + 1); - textAfter = textBefore + textAfter; - } - } else { - textAfter = - textBefore.slice(0, off) + - textBefore.slice(off + 1, textBefore.length); - - this.unre.doUpdate(x, textBefore, textAfter); - } - - this.lines[x]!.elText.innerText = textAfter; - this.raw_lines[x] = textAfter; - this.setCaret(elTextCurrent, off); + this.onKeyDelete(x, ev); break; case "Enter": @@ -603,7 +621,7 @@ class WuiEditorLine { return ed.onKeydownOnLine(this.lineNum, ev); }; this.elText.onkeyup = (ev: KeyboardEvent) => { - return ed.onKeyup(this.lineNum, ev); + return ed.onKeyupOnLine(this.lineNum, ev); }; this.elText.addEventListener("paste", (ev: ClipboardEvent) => { |
