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 dea1a5d
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 14 deletions.
4 changes: 3 additions & 1 deletion packages/core/src/editor/dom-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import $, {
DOMRange,
DOMSelection,
DOMStaticRange,
isDocument,
isShadowRoot,
isDOMElement,
normalizeDOMPoint,
isDOMSelection,
Expand Down Expand Up @@ -122,7 +124,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
4 changes: 2 additions & 2 deletions packages/core/src/text-area/event-handlers/beforeInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { DomEditor } from '../../editor/dom-editor'
import { IDomEditor } from '../../editor/interface'
import TextArea from '../TextArea'
import { hasEditableTarget } from '../helpers'
import { DOMStaticRange } from '../../utils/dom'
import { DOMStaticRange, isDataTransfer } from '../../utils/dom'
import { HAS_BEFORE_INPUT_SUPPORT } from '../../utils/ua'
import { EDITOR_TO_CAN_PASTE } from '../../utils/weak-maps'

Expand Down Expand Up @@ -138,7 +138,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
31 changes: 22 additions & 9 deletions packages/core/src/utils/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,25 @@ if (empty) $.fn.empty = empty

export default $

import { toString } from './util'

export const isDocument = (value: any): value is Document => {
return toString(value) === '[object HTMLDocument]'
}

export const isShadowRoot = (value: any): value is ShadowRoot => {
return toString(value) === '[object ShadowRoot]'
}

export const isDataTransfer = (value: any): value is DataTransfer => {
return toString(value) === '[object DataTransfer]'
}

const HTML_ELEMENT_STR_REG_EXP = /\[object HTML([A-Z][a-z]*)*Element\]/
export const isHTMLElememt = (value: any): value is HTMLElement => {
return HTML_ELEMENT_STR_REG_EXP.test(toString(value))
}

// ------------------------------- 分割线,以下内容参考 slate-react dom.ts -------------------------------

// COMPAT: This is required to prevent TypeScript aliases from doing some very
Expand Down Expand Up @@ -109,20 +128,14 @@ 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 toString(value) === '[object Selection]'
}

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

for (let nodes = elem.childNodes, i = nodes.length; i--; ) {
const node = nodes[i]
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/utils/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,5 @@ export function deReplaceHtmlSpecialSymbols(str: string) {
.replace(/&trade;/g, '™')
.replace(/&quot;/g, '"')
}

export const toString = (val: unknown): string => Object.prototype.toString.call(val)

0 comments on commit dea1a5d

Please sign in to comment.