From ddb540da0a80b7ecad1ebb62f51e76d252f771f3 Mon Sep 17 00:00:00 2001 From: Shulhan Date: Thu, 3 Oct 2024 17:29:07 +0700 Subject: editor: allow inserting tab on editor Previously pressing tab on editor will move focus to the next component on page or browser. Now, pressing tab will insert "\t" on the current cursor. --- editor/editor.js | 27 +++++++++++++++++++++++++++ editor/editor.ts | 31 +++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/editor/editor.js b/editor/editor.js index e80e147..090b7fe 100644 --- a/editor/editor.js +++ b/editor/editor.js @@ -11,6 +11,7 @@ export class WuiEditor { this.elLineNumber = document.createElement("div"); this.elContent = document.createElement("div"); this.isKeyControl = false; + this.isKeyShift = false; this.id = opts.id; this.isEditable = opts.isEditable; const el = document.getElementById(opts.id); @@ -102,6 +103,7 @@ export class WuiEditor { }; this.elContent.addEventListener("blur", () => { this.isKeyControl = false; + this.isKeyShift = false; }); } this.elContent.classList.add(WUI_EDITOR_CLASS_CONTENT); @@ -146,6 +148,16 @@ export class WuiEditor { `; document.head.appendChild(style); } + insert(text) { + const selection = window.getSelection(); + if (!selection || !selection.rangeCount) { + console.error(`insert: failed to get selection`); + return; + } + selection.deleteFromDocument(); + selection.getRangeAt(0).insertNode(document.createTextNode(text)); + selection.collapseToEnd(); + } onKeydownDocument(ed, ev) { switch (ev.key) { case "Control": @@ -164,6 +176,18 @@ export class WuiEditor { } this.addNewLine(); return false; + case "Shift": + ed.isKeyShift = true; + break; + case "Tab": + if (ed.isKeyShift) { + // Pressing Shift+Tab should move focus out of editor, + // which focus to the previous component on the page or browser. + return true; + } + ev.preventDefault(); + this.insert("\t"); + return false; } return true; } @@ -172,6 +196,9 @@ export class WuiEditor { case "Control": ed.isKeyControl = false; return true; + case "Shift": + ed.isKeyShift = false; + break; } return true; } diff --git a/editor/editor.ts b/editor/editor.ts index a036311..d524a52 100644 --- a/editor/editor.ts +++ b/editor/editor.ts @@ -24,6 +24,7 @@ export class WuiEditor { private elLineNumber: HTMLElement = document.createElement("div"); private elContent: HTMLElement = document.createElement("div"); private isKeyControl: boolean = false; + private isKeyShift: boolean = false; constructor(public opts: WuiEditorOptions) { this.id = opts.id; @@ -133,6 +134,7 @@ export class WuiEditor { }; this.elContent.addEventListener("blur", () => { this.isKeyControl = false; + this.isKeyShift = false; }); } this.elContent.classList.add(WUI_EDITOR_CLASS_CONTENT); @@ -179,6 +181,17 @@ export class WuiEditor { document.head.appendChild(style); } + private insert(text: string) { + const selection = window.getSelection(); + if (!selection || !selection.rangeCount) { + console.error(`insert: failed to get selection`); + return; + } + selection.deleteFromDocument(); + selection.getRangeAt(0).insertNode(document.createTextNode(text)); + selection.collapseToEnd(); + } + private onKeydownDocument(ed: WuiEditor, ev: KeyboardEvent) { switch (ev.key) { case "Control": @@ -199,6 +212,20 @@ export class WuiEditor { this.addNewLine(); return false; + + case "Shift": + ed.isKeyShift = true; + break; + + case "Tab": + if (ed.isKeyShift) { + // Pressing Shift+Tab should move focus out of editor, + // which focus to the previous component on the page or browser. + return true; + } + ev.preventDefault(); + this.insert("\t"); + return false; } return true; } @@ -208,6 +235,10 @@ export class WuiEditor { case "Control": ed.isKeyControl = false; return true; + + case "Shift": + ed.isKeyShift = false; + break; } return true; } -- cgit v1.3