diff options
Diffstat (limited to 'editor/editor.ts')
| -rw-r--r-- | editor/editor.ts | 93 |
1 files changed, 75 insertions, 18 deletions
diff --git a/editor/editor.ts b/editor/editor.ts index e95b858..962ebb5 100644 --- a/editor/editor.ts +++ b/editor/editor.ts @@ -23,8 +23,9 @@ export class WuiEditor { id: string; is_editable: boolean; lines: WuiEditorLine[] = []; + sel!: Selection; + selLineStart: number = 0; private el!: HTMLElement; - private sel!: Selection; private range_begin: number = -1; private range_end: number = -1; private raw_lines: string[] = []; @@ -61,6 +62,28 @@ export class WuiEditor { document.onkeyup = (ev: KeyboardEvent) => { this.onKeyupDocument(this, ev); }; + + // Handle system COPY event. + // For each selection range, add line-feed to the end of it, unless the + // line is empty, so when we paste it back we can iterate the lines and + // insert it as new line. + this.el.addEventListener("copy", (ev: ClipboardEvent) => { + ev.preventDefault(); + let text = ""; + let line = ""; + for (let i = 0; i < this.sel.rangeCount; i++) { + line = this.sel.getRangeAt(i)?.toString(); + if (!line) { + continue; + } + text += line; + + if (line != "\n") { + text += "\n"; + } + } + ev.clipboardData?.setData("text/plain", text); + }); } // getContent return content of file. @@ -82,13 +105,6 @@ export class WuiEditor { } as RangeInterface; } - onClickText() { - const sel = window.getSelection(); - if (sel) { - this.sel = sel; - } - } - // onKeyDelete handle key "DELETE" event on line. // // Case 1: DELETE on selection. @@ -101,10 +117,10 @@ export class WuiEditor { onKeyDelete(x: number, ev: KeyboardEvent) { ev.preventDefault(); - let elTextCurrent = this.lines[x]!.elText; - let textCurr = elTextCurrent.innerText; + const elTextCurrent = this.lines[x]!.elText; + const textCurr = elTextCurrent.innerText; - let selString = this.sel.toString(); + const selString = this.sel.toString(); if (selString.length > 0) { // Case 1: DELETE on selection. let textAfter = textCurr.slice(0, this.sel.anchorOffset); @@ -115,7 +131,7 @@ export class WuiEditor { } let textAfter = ""; - let off = this.sel.focusOffset; + const off = this.sel.focusOffset; if (off === textCurr.length) { // Case 2: DELETE on the end of line. @@ -505,7 +521,7 @@ export class WuiEditor { this.render(); } - private insertNewline(x: number, text: string) { + insertNewline(x: number, text: string) { const newline = new WuiEditorLine(x, text, this); for (let y = x; y < this.lines.length; y++) { this.lines[y]?.setNumber(y + 1); @@ -594,6 +610,10 @@ class WuiEditorLine { ed: WuiEditor, ) { this.lineNum = x; + if (text == "") { + // Add line feed to make all lines layout consistent. + text = "\n"; + } this.el = document.createElement("div"); this.el.classList.add(WUI_EDITOR_CLASS_LINE); @@ -613,10 +633,6 @@ class WuiEditorLine { this.elText.innerText = text; this.elText.contentEditable = "true"; - this.elText.onclick = () => { - ed.onClickText(); - }; - this.elText.onkeydown = (ev: KeyboardEvent) => { return ed.onKeydownOnLine(this.lineNum, ev); }; @@ -624,13 +640,54 @@ class WuiEditorLine { return ed.onKeyupOnLine(this.lineNum, ev); }; + // onmousedown get and store the current selection and current line + // number so we can do multiple selection later when mouse move up or + // down. + this.elText.onmousedown = () => { + ed.sel.removeAllRanges(); + + const sel = window.getSelection(); + if (!sel) { + return; + } + + ed.sel = sel; + ed.selLineStart = this.x; + }; + + this.elText.onmouseup = () => { + ed.selLineStart = 0; + }; + + // onmousemove if the current line not same when the mousedown started, + // add it to selection range. + this.elText.onmousemove = () => { + if (!ed.selLineStart) { + return; + } + if (ed.selLineStart == this.x) { + return; + } + + const range = document.createRange(); + range.selectNode(this.elText); + ed.sel.addRange(range); + }; + + // paste event we split the clipboard text into lines and it to editor + // line by line. this.elText.addEventListener("paste", (ev: ClipboardEvent) => { if (!ev.clipboardData) { return; } + ev.preventDefault(); + const text = ev.clipboardData.getData("text/plain"); - document.execCommand("insertHTML", false, text); + const lines = text.split("\n"); + lines.forEach((l: string, x: number) => { + ed.insertNewline(this.x + x, l); + }); }); this.el.appendChild(this.el_number); |
