Skip to content

Commit dea1a5d

Browse files
author
Knight Chen
committed
feat: 支持微前端 iframe 沙箱
1 parent f491c00 commit dea1a5d

File tree

5 files changed

+31
-14
lines changed

5 files changed

+31
-14
lines changed

packages/core/src/editor/dom-editor.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ import $, {
2929
DOMRange,
3030
DOMSelection,
3131
DOMStaticRange,
32+
isDocument,
33+
isShadowRoot,
3234
isDOMElement,
3335
normalizeDOMPoint,
3436
isDOMSelection,
@@ -122,7 +124,7 @@ export const DomEditor = {
122124
const el = DomEditor.toDOMNode(editor, editor)
123125
const root = el.getRootNode()
124126

125-
if ((root instanceof Document || root instanceof ShadowRoot) && root.getSelection != null) {
127+
if ((isDocument(root) || isShadowRoot(root)) && Reflect.get(root, 'getSelection') != null) {
126128
return root
127129
}
128130
return el.ownerDocument

packages/core/src/editor/plugins/with-content.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ export const withContent = <T extends Editor>(editor: T) => {
370370
* 重置 HTML 内容
371371
* @param html html string
372372
*/
373-
e.setHtml = (html: string = '') => {
373+
e.setHtml = (html: string | null = '') => {
374374
// 记录编辑器当前状态
375375
const isEditorDisabled = e.isDisabled()
376376
const isEditorFocused = e.isFocused()
@@ -384,7 +384,7 @@ export const withContent = <T extends Editor>(editor: T) => {
384384
// https://github.com/wangeditor-team/wangEditor/issues/4754
385385
e.clear()
386386
// 设置新内容
387-
const newContent = htmlToContent(e, html)
387+
const newContent = htmlToContent(e, html == null ? '' : html)
388388
Transforms.insertFragment(e, newContent)
389389

390390
// 恢复编辑器状态和选区

packages/core/src/text-area/event-handlers/beforeInput.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { DomEditor } from '../../editor/dom-editor'
88
import { IDomEditor } from '../../editor/interface'
99
import TextArea from '../TextArea'
1010
import { hasEditableTarget } from '../helpers'
11-
import { DOMStaticRange } from '../../utils/dom'
11+
import { DOMStaticRange, isDataTransfer } from '../../utils/dom'
1212
import { HAS_BEFORE_INPUT_SUPPORT } from '../../utils/ua'
1313
import { EDITOR_TO_CAN_PASTE } from '../../utils/weak-maps'
1414

@@ -138,7 +138,7 @@ function handleBeforeInput(e: Event, textarea: TextArea, editor: IDomEditor) {
138138
if (!EDITOR_TO_CAN_PASTE.get(editor)) break // 不可默认粘贴
139139
}
140140

141-
if (data instanceof DataTransfer) {
141+
if (isDataTransfer(data)) {
142142
// 这里处理非纯文本(如 html 图片文件等)的粘贴。对于纯文本的粘贴,使用 paste 事件
143143
editor.insertData(data)
144144
} else if (typeof data === 'string') {

packages/core/src/utils/dom.ts

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,25 @@ if (empty) $.fn.empty = empty
6868

6969
export default $
7070

71+
import { toString } from './util'
72+
73+
export const isDocument = (value: any): value is Document => {
74+
return toString(value) === '[object HTMLDocument]'
75+
}
76+
77+
export const isShadowRoot = (value: any): value is ShadowRoot => {
78+
return toString(value) === '[object ShadowRoot]'
79+
}
80+
81+
export const isDataTransfer = (value: any): value is DataTransfer => {
82+
return toString(value) === '[object DataTransfer]'
83+
}
84+
85+
const HTML_ELEMENT_STR_REG_EXP = /\[object HTML([A-Z][a-z]*)*Element\]/
86+
export const isHTMLElememt = (value: any): value is HTMLElement => {
87+
return HTML_ELEMENT_STR_REG_EXP.test(toString(value))
88+
}
89+
7190
// ------------------------------- 分割线,以下内容参考 slate-react dom.ts -------------------------------
7291

7392
// COMPAT: This is required to prevent TypeScript aliases from doing some very
@@ -109,20 +128,14 @@ export const isDOMElement = (value: any): value is DOMElement => {
109128
* Check if a value is a DOM node.
110129
*/
111130
export const isDOMNode = (value: any): value is DOMNode => {
112-
const window = getDefaultView(value)
113-
return (
114-
!!window &&
115-
// @ts-ignore
116-
value instanceof window.Node
117-
)
131+
return value != null && typeof value.nodeType === 'number'
118132
}
119133

120134
/**
121135
* Check if a value is a DOM selection.
122136
*/
123137
export const isDOMSelection = (value: any): value is DOMSelection => {
124-
const window = value && value.anchorNode && getDefaultView(value.anchorNode)
125-
return !!window && value instanceof window.Selection
138+
return toString(value) === '[object Selection]'
126139
}
127140

128141
/**
@@ -343,7 +356,7 @@ export function walkTextNodes(
343356
handler: (textNode: DOMNode, parent: DOMElement) => void
344357
) {
345358
// void elem 内部的 text 不处理
346-
if (elem instanceof HTMLElement && elem.dataset.slateVoid === 'true') return
359+
if (isHTMLElememt(elem) && elem.dataset.slateVoid === 'true') return
347360

348361
for (let nodes = elem.childNodes, i = nodes.length; i--; ) {
349362
const node = nodes[i]

packages/core/src/utils/util.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,5 @@ export function deReplaceHtmlSpecialSymbols(str: string) {
8888
.replace(/&trade;/g, '™')
8989
.replace(/&quot;/g, '"')
9090
}
91+
92+
export const toString = (val: unknown): string => Object.prototype.toString.call(val)

0 commit comments

Comments
 (0)