fix: handle Gboard clipboard strip multi-line paste via beforeinput (#21265)
Gboard's clipboard suggestion strip sends multi-line pastes as 'insertText' in beforeinput rather than a standard paste event, causing ProseMirror to drop the text content and insert only a newline. Add a beforeinput handler that intercepts multi-line insertText events on Android and manually inserts with hard breaks to preserve the formatting.
This commit is contained in:
@@ -897,6 +897,34 @@
|
|||||||
oncompositionend(event);
|
oncompositionend(event);
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
beforeinput: (view, event) => {
|
||||||
|
// Workaround for Gboard's clipboard suggestion strip which sends
|
||||||
|
// multi-line pastes as 'insertText' rather than a standard paste event.
|
||||||
|
// Manually insert with hard breaks to preserve multi-line formatting.
|
||||||
|
const isAndroid = /Android/i.test(navigator.userAgent);
|
||||||
|
if (isAndroid && event.inputType === 'insertText' && event.data?.includes('\n')) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const { state, dispatch } = view;
|
||||||
|
const { from, to } = state.selection;
|
||||||
|
const lines = event.data.split('\n');
|
||||||
|
const nodes = [];
|
||||||
|
|
||||||
|
lines.forEach((line, index) => {
|
||||||
|
if (index > 0) {
|
||||||
|
nodes.push(state.schema.nodes.hardBreak.create());
|
||||||
|
}
|
||||||
|
if (line.length > 0) {
|
||||||
|
nodes.push(state.schema.text(line));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const fragment = Fragment.fromArray(nodes);
|
||||||
|
dispatch(state.tr.replaceWith(from, to, fragment).scrollIntoView());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
focus: (view, event) => {
|
focus: (view, event) => {
|
||||||
eventDispatch('focus', { event });
|
eventDispatch('focus', { event });
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user