Skip to content

Commit

Permalink
feat: 支持微前端 iframe 沙箱
Browse files Browse the repository at this point in the history
  • Loading branch information
Knight Chen committed Jun 10, 2023
1 parent f491c00 commit 2cdd1d3
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 12 deletions.
3 changes: 2 additions & 1 deletion packages/core/src/editor/dom-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import $, {
walkTextNodes,
} from '../utils/dom'
import { IS_CHROME, IS_FIREFOX } from '../utils/ua'
import { isDocument, isShadowRoot } from '../utils/check'

/**
* 自定义全局 command
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/editor/plugins/with-content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ export const withContent = <T extends Editor>(editor: T) => {
* 重置 HTML 内容
* @param html html string
*/
e.setHtml = (html: string = '') => {
e.setHtml = (html: string | null = '') => {
// 记录编辑器当前状态
const isEditorDisabled = e.isDisabled()
const isEditorFocused = e.isFocused()
Expand All @@ -384,7 +384,7 @@ export const withContent = <T extends Editor>(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)

// 恢复编辑器状态和选区
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/text-area/event-handlers/beforeInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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') {
Expand Down
21 changes: 21 additions & 0 deletions packages/core/src/utils/check.ts
Original file line number Diff line number Diff line change
@@ -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
}
12 changes: 4 additions & 8 deletions packages/core/src/utils/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -109,20 +110,15 @@ 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'
}

/**
* Check if a value is a DOM selection.
*/
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)
}

/**
Expand Down Expand Up @@ -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]
Expand Down

0 comments on commit 2cdd1d3

Please sign in to comment.