aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2023-11-01 23:50:51 +0700
committerShulhan <ms@kilabit.info>2023-11-01 23:50:51 +0700
commitde34f96f48c69443b130d2e49a0dd5c1e26dba7f (patch)
treebcaaf7a55fed0de75eaf75d41279441a3081b74c
parent628e07e9d638abaf4987cd9233085a42a8a40d89 (diff)
downloadpakakeh.ts-de34f96f48c69443b130d2e49a0dd5c1e26dba7f.tar.xz
editor: handle DELETE on selection
If user select text and press delete key, the selected text should be deleted.
-rw-r--r--editor/editor.ts104
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) => {