diff --git a/.changeset/strange-rabbits-refuse.md b/.changeset/strange-rabbits-refuse.md new file mode 100644 index 000000000..56175fe32 --- /dev/null +++ b/.changeset/strange-rabbits-refuse.md @@ -0,0 +1,5 @@ +--- +'slate-react': patch +--- + +Fix copy-paste a slate fragment on android editable diff --git a/packages/slate-react/src/components/android/android-editable.tsx b/packages/slate-react/src/components/android/android-editable.tsx index 326a991ec..c51c8a45d 100644 --- a/packages/slate-react/src/components/android/android-editable.tsx +++ b/packages/slate-react/src/components/android/android-editable.tsx @@ -13,6 +13,7 @@ import { isDOMElement, isDOMNode, getDefaultView, + getClipboardData, isPlainTextOnlyPaste, } from '../../utils/dom' import { @@ -453,6 +454,7 @@ export const AndroidEditable = (props: EditableProps): JSX.Element => { onPaste={useCallback( (event: React.ClipboardEvent) => { // This unfortunately needs to be handled with paste events instead. + event.clipboardData = getClipboardData(event.clipboardData) if ( hasEditableTarget(editor, event.target) && !isEventHandled(event, attributes.onPaste) && diff --git a/packages/slate-react/src/utils/dom.ts b/packages/slate-react/src/utils/dom.ts index 7d4ae3a36..d8a27dc18 100644 --- a/packages/slate-react/src/utils/dom.ts +++ b/packages/slate-react/src/utils/dom.ts @@ -233,3 +233,20 @@ export const getPlainText = (domNode: DOMNode) => { return text } + +const catchSlateFragment = /data-slate-fragment="(.+?)"/m +export const getClipboardData = (dataTransfer: DataTransfer): DataTransfer => { + if (!dataTransfer.getData('application/x-slate-fragment')) { + const htmlData = dataTransfer.getData('text/html') + const [, fragment] = htmlData.match(catchSlateFragment) || [] + if (fragment) { + const clipboardData = new DataTransfer() + dataTransfer.types.forEach(type => { + clipboardData.setData(type, dataTransfer.getData(type)) + }) + clipboardData.setData('application/x-slate-fragment', fragment) + return clipboardData + } + } + return dataTransfer +}