some mobile improvements
This commit is contained in:
@@ -4,6 +4,8 @@
|
|||||||
<style>
|
<style>
|
||||||
#text {
|
#text {
|
||||||
white-space: pre;
|
white-space: pre;
|
||||||
|
outline: none;
|
||||||
|
caret-color: transparent;
|
||||||
}
|
}
|
||||||
.cursor {
|
.cursor {
|
||||||
border-left: 2px solid #000;
|
border-left: 2px solid #000;
|
||||||
|
|||||||
+76
-46
@@ -4,9 +4,11 @@ import { elementToPos } from "./mouse.js";
|
|||||||
|
|
||||||
export function setupInput(buffer, cursor, selection, onChange) {
|
export function setupInput(buffer, cursor, selection, onChange) {
|
||||||
let isMouseDown = false;
|
let isMouseDown = false;
|
||||||
|
const textEl = document.getElementById("text");
|
||||||
|
textEl.contentEditable = true;
|
||||||
|
|
||||||
function startDrag(e) {
|
function startDrag(e) {
|
||||||
if (!e.target.closest("#text")) return;
|
if (e.target !== textEl && !e.target.closest("#text")) return;
|
||||||
isMouseDown = true;
|
isMouseDown = true;
|
||||||
const pos = elementToPos(e.clientX, e.clientY, buffer);
|
const pos = elementToPos(e.clientX, e.clientY, buffer);
|
||||||
cursor.line = pos.line;
|
cursor.line = pos.line;
|
||||||
@@ -30,7 +32,7 @@ export function setupInput(buffer, cursor, selection, onChange) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function selectWord(e) {
|
function selectWord(e) {
|
||||||
if (!e.target.closest("#text")) return;
|
if (e.target !== textEl && !e.target.closest("#text")) return;
|
||||||
const pos = elementToPos(e.clientX, e.clientY, buffer);
|
const pos = elementToPos(e.clientX, e.clientY, buffer);
|
||||||
const line = buffer[pos.line];
|
const line = buffer[pos.line];
|
||||||
let start = pos.col;
|
let start = pos.col;
|
||||||
@@ -84,6 +86,22 @@ export function setupInput(buffer, cursor, selection, onChange) {
|
|||||||
clearSelection(selection);
|
clearSelection(selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deleteBackward() {
|
||||||
|
if (hasSelection(selection)) {
|
||||||
|
deleteSelection(buffer, cursor, selection);
|
||||||
|
} else if (cursor.col > 0) {
|
||||||
|
const line = buffer[cursor.line];
|
||||||
|
buffer[cursor.line] = line.slice(0, cursor.col - 1) + line.slice(cursor.col);
|
||||||
|
cursor.col--;
|
||||||
|
} else if (cursor.line > 0) {
|
||||||
|
cursor.col = buffer[cursor.line - 1].length;
|
||||||
|
buffer[cursor.line - 1] += buffer[cursor.line];
|
||||||
|
buffer.splice(cursor.line, 1);
|
||||||
|
cursor.line--;
|
||||||
|
}
|
||||||
|
clearSelection(selection);
|
||||||
|
}
|
||||||
|
|
||||||
function selectAll() {
|
function selectAll() {
|
||||||
selection.anchor = { line: 0, col: 0 };
|
selection.anchor = { line: 0, col: 0 };
|
||||||
selection.head = { line: buffer.length - 1, col: buffer[buffer.length - 1].length };
|
selection.head = { line: buffer.length - 1, col: buffer[buffer.length - 1].length };
|
||||||
@@ -91,12 +109,41 @@ export function setupInput(buffer, cursor, selection, onChange) {
|
|||||||
cursor.col = buffer[buffer.length - 1].length;
|
cursor.col = buffer[buffer.length - 1].length;
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener("mousedown", startDrag);
|
textEl.addEventListener("beforeinput", (e) => {
|
||||||
document.addEventListener("mousemove", drag);
|
e.preventDefault();
|
||||||
document.addEventListener("mouseup", endDrag);
|
|
||||||
document.addEventListener("dblclick", selectWord);
|
|
||||||
|
|
||||||
document.addEventListener("paste", (e) => {
|
if (e.inputType === "insertText") {
|
||||||
|
insertText(e.data);
|
||||||
|
onChange();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (e.inputType === "insertCompositionText") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (e.inputType === "deleteContentBackward") {
|
||||||
|
deleteBackward();
|
||||||
|
onChange();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (e.inputType === "deleteContentForward") {
|
||||||
|
if (hasSelection(selection)) {
|
||||||
|
deleteSelection(buffer, cursor, selection);
|
||||||
|
} else if (cursor.col < buffer[cursor.line].length) {
|
||||||
|
const line = buffer[cursor.line];
|
||||||
|
buffer[cursor.line] = line.slice(0, cursor.col) + line.slice(cursor.col + 1);
|
||||||
|
}
|
||||||
|
clearSelection(selection);
|
||||||
|
onChange();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (e.inputType === "insertFromPaste") {
|
||||||
|
insertText(e.clipboardData.getData("text"));
|
||||||
|
onChange();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
textEl.addEventListener("paste", (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const text = e.clipboardData.getData("text");
|
const text = e.clipboardData.getData("text");
|
||||||
if (!text) return;
|
if (!text) return;
|
||||||
@@ -104,28 +151,32 @@ export function setupInput(buffer, cursor, selection, onChange) {
|
|||||||
onChange();
|
onChange();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
textEl.addEventListener("copy", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const text = getSelectedText();
|
||||||
|
if (text) e.clipboardData.setData("text/plain", text);
|
||||||
|
});
|
||||||
|
|
||||||
|
textEl.addEventListener("cut", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const text = getSelectedText();
|
||||||
|
if (text) e.clipboardData.setData("text/plain", text);
|
||||||
|
deleteSelection(buffer, cursor, selection);
|
||||||
|
onChange();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener("mousedown", startDrag);
|
||||||
|
document.addEventListener("mousemove", drag);
|
||||||
|
document.addEventListener("mouseup", endDrag);
|
||||||
|
document.addEventListener("dblclick", selectWord);
|
||||||
|
|
||||||
|
textEl.focus();
|
||||||
|
|
||||||
document.addEventListener("keydown", (e) => {
|
document.addEventListener("keydown", (e) => {
|
||||||
const mod = e.ctrlKey || e.metaKey;
|
const mod = e.ctrlKey || e.metaKey;
|
||||||
const extending = e.shiftKey;
|
const extending = e.shiftKey;
|
||||||
|
|
||||||
if (mod) {
|
if (mod) {
|
||||||
if (e.key === "c") {
|
|
||||||
e.preventDefault();
|
|
||||||
const text = getSelectedText();
|
|
||||||
if (text) navigator.clipboard.writeText(text);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (e.key === "x") {
|
|
||||||
e.preventDefault();
|
|
||||||
const text = getSelectedText();
|
|
||||||
if (text) navigator.clipboard.writeText(text);
|
|
||||||
deleteSelection(buffer, cursor, selection);
|
|
||||||
onChange();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (e.key === "v") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (e.key === "a") {
|
if (e.key === "a") {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
selectAll();
|
selectAll();
|
||||||
@@ -173,19 +224,7 @@ export function setupInput(buffer, cursor, selection, onChange) {
|
|||||||
}
|
}
|
||||||
if (e.key === "Backspace") {
|
if (e.key === "Backspace") {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (hasSelection(selection)) {
|
deleteBackward();
|
||||||
deleteSelection(buffer, cursor, selection);
|
|
||||||
} else if (cursor.col > 0) {
|
|
||||||
const line = buffer[cursor.line];
|
|
||||||
buffer[cursor.line] = line.slice(0, cursor.col - 1) + line.slice(cursor.col);
|
|
||||||
cursor.col--;
|
|
||||||
} else if (cursor.line > 0) {
|
|
||||||
cursor.col = buffer[cursor.line - 1].length;
|
|
||||||
buffer[cursor.line - 1] += buffer[cursor.line];
|
|
||||||
buffer.splice(cursor.line, 1);
|
|
||||||
cursor.line--;
|
|
||||||
}
|
|
||||||
clearSelection(selection);
|
|
||||||
onChange();
|
onChange();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -202,14 +241,5 @@ export function setupInput(buffer, cursor, selection, onChange) {
|
|||||||
onChange();
|
onChange();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (e.key.length === 1) {
|
|
||||||
e.preventDefault();
|
|
||||||
if (hasSelection(selection)) deleteSelection(buffer, cursor, selection);
|
|
||||||
const line = buffer[cursor.line];
|
|
||||||
buffer[cursor.line] = line.slice(0, cursor.col) + e.key + line.slice(cursor.col);
|
|
||||||
cursor.col++;
|
|
||||||
clearSelection(selection);
|
|
||||||
onChange();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user