From d06706c9e15bbbdd7cdd9a1bbb38c87d37c85ea1 Mon Sep 17 00:00:00 2001 From: I Made Budi Surya Darma Date: Sat, 14 Aug 2021 01:54:58 +0800 Subject: [PATCH] Read data-slate-fragment when application/x-slate-fragment is missing (#4454) * fix missing slate-fragment onpaste ion safari * add changeset --- .changeset/nervous-planes-wonder.md | 5 +++++ .../components/android/android-editable.tsx | 3 ++- packages/slate-react/src/plugin/with-react.ts | 13 +++++++++++-- packages/slate-react/src/utils/dom.ts | 18 ++++++++++++++++-- 4 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 .changeset/nervous-planes-wonder.md diff --git a/.changeset/nervous-planes-wonder.md b/.changeset/nervous-planes-wonder.md new file mode 100644 index 0000000000..3728d59c87 --- /dev/null +++ b/.changeset/nervous-planes-wonder.md @@ -0,0 +1,5 @@ +--- +'slate-react': patch +--- + +Fix to read fragment from data-slate-fragment when application/x-slate-fragment is missing diff --git a/packages/slate-react/src/components/android/android-editable.tsx b/packages/slate-react/src/components/android/android-editable.tsx index c51c8a45d3..32c9a6a46a 100644 --- a/packages/slate-react/src/components/android/android-editable.tsx +++ b/packages/slate-react/src/components/android/android-editable.tsx @@ -453,8 +453,9 @@ export const AndroidEditable = (props: EditableProps): JSX.Element => { )} onPaste={useCallback( (event: React.ClipboardEvent) => { - // This unfortunately needs to be handled with paste events instead. + // this will make application/x-slate-fragment exist when onPaste attributes is passed event.clipboardData = getClipboardData(event.clipboardData) + // This unfortunately needs to be handled with paste events instead. if ( hasEditableTarget(editor, event.target) && !isEventHandled(event, attributes.onPaste) && diff --git a/packages/slate-react/src/plugin/with-react.ts b/packages/slate-react/src/plugin/with-react.ts index bf30018ecc..ebc40643b7 100644 --- a/packages/slate-react/src/plugin/with-react.ts +++ b/packages/slate-react/src/plugin/with-react.ts @@ -9,7 +9,11 @@ import { NATIVE_OPERATIONS, flushNativeEvents, } from '../utils/native' -import { isDOMText, getPlainText } from '../utils/dom' +import { + isDOMText, + getPlainText, + getSlateFragmentAttribute, +} from '../utils/dom' import { findCurrentLineRange } from '../utils/lines' /** @@ -213,7 +217,12 @@ export const withReact = (editor: T) => { } e.insertData = (data: DataTransfer) => { - const fragment = data.getData('application/x-slate-fragment') + /** + * Checking copied fragment from application/x-slate-fragment or data-slate-fragment + */ + const fragment = + data.getData('application/x-slate-fragment') || + getSlateFragmentAttribute(data) if (fragment) { const decoded = decodeURIComponent(window.atob(fragment)) diff --git a/packages/slate-react/src/utils/dom.ts b/packages/slate-react/src/utils/dom.ts index d8a27dc18e..368c6a905a 100644 --- a/packages/slate-react/src/utils/dom.ts +++ b/packages/slate-react/src/utils/dom.ts @@ -234,11 +234,25 @@ export const getPlainText = (domNode: DOMNode) => { return text } +/** + * Get x-slate-fragment attribute from data-slate-fragment + */ const catchSlateFragment = /data-slate-fragment="(.+?)"/m +export const getSlateFragmentAttribute = ( + dataTransfer: DataTransfer +): string | void => { + const htmlData = dataTransfer.getData('text/html') + const [, fragment] = htmlData.match(catchSlateFragment) || [] + return fragment +} + +/** + * Get the x-slate-fragment attribute that exist in text/html data + * and append it to the DataTransfer object + */ export const getClipboardData = (dataTransfer: DataTransfer): DataTransfer => { if (!dataTransfer.getData('application/x-slate-fragment')) { - const htmlData = dataTransfer.getData('text/html') - const [, fragment] = htmlData.match(catchSlateFragment) || [] + const fragment = getSlateFragmentAttribute(dataTransfer) if (fragment) { const clipboardData = new DataTransfer() dataTransfer.types.forEach(type => {