From 68800af579625d76d5abb183fb5251d62df52565 Mon Sep 17 00:00:00 2001 From: CodePencil Date: Sat, 25 Jan 2025 13:41:03 +0800 Subject: [PATCH] fix: Safari paste image base64 and blob (#524) * fix: fixed the issue with upload image urls in the Safari browser * revert: delete async --------- Co-authored-by: cycleccc <2991205548@qq.com> --- packages/core/src/editor/helper.ts | 42 ------------------- .../src/editor/plugins/with-event-data.ts | 20 +-------- .../src/text-area/event-handlers/paste.ts | 18 ++++---- 3 files changed, 12 insertions(+), 68 deletions(-) delete mode 100644 packages/core/src/editor/helper.ts diff --git a/packages/core/src/editor/helper.ts b/packages/core/src/editor/helper.ts deleted file mode 100644 index 4e9b1ced2..000000000 --- a/packages/core/src/editor/helper.ts +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @description Processing blob url - * @author CodePencil - */ - -/** 提取 blob URL */ -export function extractBlobUrlFromImg(html: string) { - const regex = /]*src=["'](blob:[^"']+)["'][^>]*>/i - const match = html.match(regex) - - return match ? match[1] : null -} - -/** 将 blob URL 转换为 base64 */ -export async function convertBlobUrlToBase64(blobUrl: string) { - try { - const response = await fetch(blobUrl) - - if (!response.ok) { - throw new Error('Failed to fetch blob URL') - } - - const blob = await response.blob() - - return new Promise((resolve, reject) => { - const reader = new FileReader() - - reader.onloadend = () => { - resolve(reader.result as string) - } - - reader.onerror = () => { - reject(new Error('Failed to read blob as data URL')) - } - - reader.readAsDataURL(blob) - }) - } catch (error) { - console.error(error) - return null - } -} diff --git a/packages/core/src/editor/plugins/with-event-data.ts b/packages/core/src/editor/plugins/with-event-data.ts index 82c803649..08bfd47de 100644 --- a/packages/core/src/editor/plugins/with-event-data.ts +++ b/packages/core/src/editor/plugins/with-event-data.ts @@ -9,9 +9,7 @@ import { import { IDomEditor } from '../..' import { getPlainText, isDOMText } from '../../utils/dom' -import { IS_SAFARI } from '../../utils/ua' import { DomEditor } from '../dom-editor' -import { convertBlobUrlToBase64, extractBlobUrlFromImg } from '../helper' export const withEventData = (editor: T) => { const e = editor as T & IDomEditor @@ -108,7 +106,7 @@ export const withEventData = (editor: T) => { return data } - e.insertData = async (data: DataTransfer) => { + e.insertData = (data: DataTransfer) => { const fragment = data.getData('application/x-slate-fragment') // 只有从编辑器中内复制的内容,才会获取 fragment,从其他地方粘贴到编辑器中,不会获取 fragment @@ -121,23 +119,9 @@ export const withEventData = (editor: T) => { } const text = data.getData('text/plain') - let html = data.getData('text/html') + const html = data.getData('text/html') // const rtf = data.getData('text/rtf') - if (IS_SAFARI) { - const blobUrl = extractBlobUrlFromImg(html) - - if (blobUrl) { - const base64Data = await convertBlobUrlToBase64(blobUrl) - - if (base64Data) { - html = `image.png` - - URL.revokeObjectURL(blobUrl) - } - } - } - if (html) { e.dangerouslyInsertHtml(html) return diff --git a/packages/core/src/text-area/event-handlers/paste.ts b/packages/core/src/text-area/event-handlers/paste.ts index 128bda27c..9336953a9 100644 --- a/packages/core/src/text-area/event-handlers/paste.ts +++ b/packages/core/src/text-area/event-handlers/paste.ts @@ -4,12 +4,11 @@ */ import { IDomEditor } from '../../editor/interface' -import { DomEditor } from '../../editor/dom-editor' -import TextArea from '../TextArea' -import { hasEditableTarget } from '../helpers' import { isPlainTextOnlyPaste } from '../../utils/dom' -import { HAS_BEFORE_INPUT_SUPPORT } from '../../utils/ua' +import { HAS_BEFORE_INPUT_SUPPORT, IS_SAFARI } from '../../utils/ua' import { EDITOR_TO_CAN_PASTE } from '../../utils/weak-maps' +import { hasEditableTarget } from '../helpers' +import TextArea from '../TextArea' function handleOnPaste(e: Event, textarea: TextArea, editor: IDomEditor) { EDITOR_TO_CAN_PASTE.set(editor, true) // 标记为:可执行默认粘贴 @@ -17,12 +16,14 @@ function handleOnPaste(e: Event, textarea: TextArea, editor: IDomEditor) { const event = e as ClipboardEvent const { readOnly } = editor.getConfig() - if (readOnly) return - if (!hasEditableTarget(editor, event.target)) return + if (readOnly) { return } + if (!hasEditableTarget(editor, event.target)) { return } const { customPaste } = editor.getConfig() + if (customPaste) { const res = customPaste(editor, event) + if (res === false) { // 自行实现粘贴,不执行默认粘贴 EDITOR_TO_CAN_PASTE.set(editor, false) // 标记为:不可执行默认粘贴 @@ -32,12 +33,13 @@ function handleOnPaste(e: Event, textarea: TextArea, editor: IDomEditor) { // 如果支持 beforeInput 且不是纯粘贴文本(如 html、图片文件),则使用 beforeInput 来实现 // 这里只处理:不支持 beforeInput 或者 粘贴纯文本 - if (HAS_BEFORE_INPUT_SUPPORT && !isPlainTextOnlyPaste(event)) return + if (!IS_SAFARI && HAS_BEFORE_INPUT_SUPPORT && !isPlainTextOnlyPaste(event)) { return } event.preventDefault() const data = event.clipboardData - if (data == null) return + + if (data == null) { return } editor.insertData(data) }