mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-04-21 13:51:59 +02:00
Fix pasting content with newlines on Android (#5359)
* Improve InputEvent data type * Fix insertion of content with newlines on Android * Slice the trailing newline off of pasted text * Add changeset
This commit is contained in:
parent
4399935690
commit
9825d29b87
5
.changeset/rude-bikes-rule.md
Normal file
5
.changeset/rude-bikes-rule.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'slate-react': patch
|
||||
---
|
||||
|
||||
Fix an issue on Android where content containing a newline wouldn't be pasted properly
|
@ -36,6 +36,10 @@ const FLUSH_DELAY = 200
|
||||
// Replace with `const debug = console.log` to debug
|
||||
const debug = (..._: unknown[]) => {}
|
||||
|
||||
// Type guard to check if a value is a DataTransfer
|
||||
const isDataTransfer = (value: any): value is DataTransfer =>
|
||||
value?.constructor.name === 'DataTransfer'
|
||||
|
||||
export type CreateAndroidInputManagerOptions = {
|
||||
editor: ReactEditor
|
||||
|
||||
@ -343,7 +347,8 @@ export function createAndroidInputManager({
|
||||
|
||||
const { inputType: type } = event
|
||||
let targetRange: Range | null = null
|
||||
const data = (event as any).dataTransfer || event.data || undefined
|
||||
const data: DataTransfer | string | undefined =
|
||||
(event as any).dataTransfer || event.data || undefined
|
||||
|
||||
if (
|
||||
insertPositionHint !== false &&
|
||||
@ -577,18 +582,12 @@ export function createAndroidInputManager({
|
||||
case 'insertFromYank':
|
||||
case 'insertReplacementText':
|
||||
case 'insertText': {
|
||||
if (data?.constructor.name === 'DataTransfer') {
|
||||
if (isDataTransfer(data)) {
|
||||
return scheduleAction(() => ReactEditor.insertData(editor, data), {
|
||||
at: targetRange,
|
||||
})
|
||||
}
|
||||
|
||||
if (typeof data === 'string' && data.includes('\n')) {
|
||||
return scheduleAction(() => Editor.insertSoftBreak(editor), {
|
||||
at: Range.end(targetRange),
|
||||
})
|
||||
}
|
||||
|
||||
let text = data ?? ''
|
||||
|
||||
// COMPAT: If we are writing inside a placeholder, the ime inserts the text inside
|
||||
@ -597,6 +596,34 @@ export function createAndroidInputManager({
|
||||
text = text.replace('\uFEFF', '')
|
||||
}
|
||||
|
||||
// Pastes from the Android clipboard will generate `insertText` events.
|
||||
// If the copied text contains any newlines, Android will append an
|
||||
// extra newline to the end of the copied text.
|
||||
if (type === 'insertText' && /.*\n.*\n$/.test(text)) {
|
||||
text = text.slice(0, -1)
|
||||
}
|
||||
|
||||
// If the text includes a newline, split it at newlines and paste each component
|
||||
// string, with soft breaks in between each.
|
||||
if (text.includes('\n')) {
|
||||
return scheduleAction(
|
||||
() => {
|
||||
const parts = text.split('\n')
|
||||
parts.forEach((line, i) => {
|
||||
if (line) {
|
||||
Editor.insertText(editor, line)
|
||||
}
|
||||
if (i !== parts.length - 1) {
|
||||
Editor.insertSoftBreak(editor)
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
at: targetRange,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (Path.equals(targetRange.anchor.path, targetRange.focus.path)) {
|
||||
const [start, end] = Range.edges(targetRange)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user