diff --git a/packages/core/src/editor/dom-editor.ts b/packages/core/src/editor/dom-editor.ts index f7a32f80e..c8f275471 100644 --- a/packages/core/src/editor/dom-editor.ts +++ b/packages/core/src/editor/dom-editor.ts @@ -36,6 +36,7 @@ import $, { walkTextNodes, } from '../utils/dom' import { IS_CHROME, IS_FIREFOX } from '../utils/ua' +import { isDocument, isShadowRoot } from '../utils/check' /** * 自定义全局 command @@ -122,7 +123,7 @@ export const DomEditor = { const el = DomEditor.toDOMNode(editor, editor) const root = el.getRootNode() - if ((root instanceof Document || root instanceof ShadowRoot) && root.getSelection != null) { + if ((isDocument(root) || isShadowRoot(root)) && Reflect.get(root, 'getSelection') != null) { return root } return el.ownerDocument diff --git a/packages/core/src/editor/plugins/with-content.ts b/packages/core/src/editor/plugins/with-content.ts index 1af7d7444..a5daf175f 100644 --- a/packages/core/src/editor/plugins/with-content.ts +++ b/packages/core/src/editor/plugins/with-content.ts @@ -370,7 +370,7 @@ export const withContent = (editor: T) => { * 重置 HTML 内容 * @param html html string */ - e.setHtml = (html: string = '') => { + e.setHtml = (html: string | null = '') => { // 记录编辑器当前状态 const isEditorDisabled = e.isDisabled() const isEditorFocused = e.isFocused() @@ -384,7 +384,7 @@ export const withContent = (editor: T) => { // https://github.com/wangeditor-team/wangEditor/issues/4754 e.clear() // 设置新内容 - const newContent = htmlToContent(e, html) + const newContent = htmlToContent(e, html == null ? '' : html) Transforms.insertFragment(e, newContent) // 恢复编辑器状态和选区 diff --git a/packages/core/src/text-area/event-handlers/beforeInput.ts b/packages/core/src/text-area/event-handlers/beforeInput.ts index 86a4c2be4..993725fa8 100644 --- a/packages/core/src/text-area/event-handlers/beforeInput.ts +++ b/packages/core/src/text-area/event-handlers/beforeInput.ts @@ -11,6 +11,7 @@ import { hasEditableTarget } from '../helpers' import { DOMStaticRange } from '../../utils/dom' import { HAS_BEFORE_INPUT_SUPPORT } from '../../utils/ua' import { EDITOR_TO_CAN_PASTE } from '../../utils/weak-maps' +import { isDataTransfer } from '../../utils/check' // 补充 beforeInput event 的属性 interface BeforeInputEventType { @@ -138,7 +139,7 @@ function handleBeforeInput(e: Event, textarea: TextArea, editor: IDomEditor) { if (!EDITOR_TO_CAN_PASTE.get(editor)) break // 不可默认粘贴 } - if (data instanceof DataTransfer) { + if (isDataTransfer(data)) { // 这里处理非纯文本(如 html 图片文件等)的粘贴。对于纯文本的粘贴,使用 paste 事件 editor.insertData(data) } else if (typeof data === 'string') { diff --git a/packages/core/src/utils/check.ts b/packages/core/src/utils/check.ts new file mode 100644 index 000000000..c41c75347 --- /dev/null +++ b/packages/core/src/utils/check.ts @@ -0,0 +1,21 @@ +const toString = (val: unknown): string => Object.prototype.toString.call(val) + +export function isDocument(val: unknown): val is Document { + return toString(val) === '[object HTMLDocument]' +} + +export function isShadowRoot(val: any): val is ShadowRoot { + return toString(val) === '[object ShadowRoot]' +} + +export function isDataTransfer(val: any): val is DataTransfer { + return toString(val) === '[object DataTransfer]' +} + +export function isSelection(val: any): val is Selection { + return toString(val) === '[object Selection]' +} + +export function isHTMLElement(val: any): val is HTMLElement { + return !!val && Reflect.get(val, 'nodeType') === Node.ELEMENT_NODE +} diff --git a/packages/core/src/utils/dom.ts b/packages/core/src/utils/dom.ts index 0402d65b3..a90fe4077 100644 --- a/packages/core/src/utils/dom.ts +++ b/packages/core/src/utils/dom.ts @@ -80,6 +80,7 @@ import DOMText = globalThis.Text import DOMRange = globalThis.Range import DOMSelection = globalThis.Selection import DOMStaticRange = globalThis.StaticRange +import { isHTMLElement, isSelection } from './check' export { DOMNode, DOMComment, DOMElement, DOMText, DOMRange, DOMSelection, DOMStaticRange } export type DOMPoint = [Node, number] @@ -109,12 +110,7 @@ export const isDOMElement = (value: any): value is DOMElement => { * Check if a value is a DOM node. */ export const isDOMNode = (value: any): value is DOMNode => { - const window = getDefaultView(value) - return ( - !!window && - // @ts-ignore - value instanceof window.Node - ) + return value != null && typeof value.nodeType === 'number' } /** @@ -122,7 +118,7 @@ export const isDOMNode = (value: any): value is DOMNode => { */ export const isDOMSelection = (value: any): value is DOMSelection => { const window = value && value.anchorNode && getDefaultView(value.anchorNode) - return !!window && value instanceof window.Selection + return !!window && isSelection(value) } /** @@ -343,7 +339,7 @@ export function walkTextNodes( handler: (textNode: DOMNode, parent: DOMElement) => void ) { // void elem 内部的 text 不处理 - if (elem instanceof HTMLElement && elem.dataset.slateVoid === 'true') return + if (isHTMLElement(elem) && elem.dataset.slateVoid === 'true') return for (let nodes = elem.childNodes, i = nodes.length; i--; ) { const node = nodes[i]