From e094a9225fbbb31d54b1a1e25af498c86f6d25d0 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 6 Mar 2024 18:00:21 +0100 Subject: [PATCH] Work around iOS Enter+autocorrect behavior FIX: Avoid the editor getting confused when iOS autocorrects on pressing Enter and does the correction and the break insertion in two different events. Closes https://github.com/codemirror/dev/issues/1349 --- src/dom.ts | 1 + src/domchange.ts | 2 +- src/input.ts | 6 ++++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/dom.ts b/src/dom.ts index 3eda7651..afdd52e0 100644 --- a/src/dom.ts +++ b/src/dom.ts @@ -283,6 +283,7 @@ export function textRange(node: Text, from: number, to = from) { } export function dispatchKey(elt: HTMLElement, name: string, code: number): boolean { + console.log("dispatch", name) let options = {key: name, code: name, keyCode: code, which: code, cancelable: true} let down = new KeyboardEvent("keydown", options) ;(down as any).synthetic = true diff --git a/src/domchange.ts b/src/domchange.ts index 5ce7ca3f..1aa80bf0 100644 --- a/src/domchange.ts +++ b/src/domchange.ts @@ -116,7 +116,7 @@ export function applyDOMChange(view: EditorView, domChange: DOMChange): boolean } if (change) { - if (browser.ios && view.inputState.flushIOSKey()) return true + if (browser.ios && view.inputState.flushIOSKey(change)) return true // Android browsers don't fire reasonable key events for enter, // backspace, or delete. So this detects changes that look like // they're caused by those keys, and reinterprets them as key diff --git a/src/input.ts b/src/input.ts index c30d19c5..aa3f2f3a 100644 --- a/src/input.ts +++ b/src/input.ts @@ -1,4 +1,4 @@ -import {EditorSelection, EditorState, SelectionRange, RangeSet, Annotation} from "@codemirror/state" +import {EditorSelection, EditorState, SelectionRange, RangeSet, Annotation, Text} from "@codemirror/state" import {EditorView} from "./editorview" import {ContentView} from "./contentview" import {LineView} from "./blockview" @@ -142,9 +142,11 @@ export class InputState { return false } - flushIOSKey() { + flushIOSKey(change?: {from: number, to: number, insert: Text}) { let key = this.pendingIOSKey if (!key) return false + // This looks like an autocorrection before Enter + if (key.key == "Enter" && change && change.from < change.to && /^\S+$/.test(change.insert.toString())) return false this.pendingIOSKey = undefined return dispatchKey(this.view.contentDOM, key.key, key.keyCode) }