I noticed this behavior that seems to have been introduced in iOS 14, but have only been able to reproduce it in our application-specific nodes, not in the basic ProseMirror schema’s nodes.
It seems like the selection gets updated in the browser differently than it used to, resulting in ProseMirror reading the selection change and emitting that transaction before detecting an enter being inserted (using custom iOS enter handling).
I’ve been working around it by ignoring the transaction that sets the selection too soon:
const shouldSkipIosEnterTransaction = (view, transaction) => {
if (!isIOS14OrLater) return false;
return view && transaction.selectionSet && !transaction.docChanged &&
// This matches the checks in prosemirror-view, where an lastIOSEnter is set along with a 200ms
// timer that fires the handleKeyDown (if nothing cancels it in the interim
(view.lastIOSEnter > Date.now() - 225);
};
The isIOS14OrLater check is webkit_version > 604, as iOS 14 appears to have shipped with webkit 605.
This patch to prosemirror-view should solve this. The problem was that the regular iOS enter hack wasn’t kicking in because the DOM structure created in this case caused ProseMirror to not treat the new block as a parseable node at all, returning from the DOM change code before even checking for the iOS enter hack.