Skip to content

Commit

Permalink
feat: modal appendTo body
Browse files Browse the repository at this point in the history
  • Loading branch information
wangfupeng1988 committed Nov 13, 2021
1 parent 9f062be commit fc0ab06
Show file tree
Hide file tree
Showing 13 changed files with 150 additions and 8 deletions.
9 changes: 9 additions & 0 deletions packages/core/src/assets/modal.less
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,12 @@
width: 100%;
}
}

// modal 有可能直接 append 到 <body> 下面
body .w-e-modal {
box-sizing: border-box;

* {
box-sizing: border-box;
}
}
1 change: 1 addition & 0 deletions packages/core/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export function genToolbarConfig(userConfig?: Partial<IToolbarConfig>): IToolbar
toolbarKeys: [],
excludeKeys: [],
insertKeys: { index: 0, keys: [] },
modalAppendToBody: false,

// 合并用户配置
...(userConfig || {}),
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/config/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,5 @@ export interface IToolbarConfig {
toolbarKeys: Array<string | IMenuGroup>
insertKeys: { index: number; keys: string | Array<string | IMenuGroup> }
excludeKeys: Array<string> // 排除哪些菜单
modalAppendToBody: boolean // modal append 到 body ,而非 $textAreaContainer 内
}
2 changes: 1 addition & 1 deletion packages/core/src/editor/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export interface IDomEditor extends Editor {
on: (type: string, listener: ee.EventListener) => void
off: (type: string, listener: ee.EventListener) => void
once: (type: string, listener: ee.EventListener) => void
emit: (type: string) => void
emit: (type: string, ...args: any[]) => void

// undo redo - 不用自己实现,使用 slate-history 扩展
undo?: () => void
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/editor/plugins/with-emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ export const withEmitter = <T extends Editor>(editor: T) => {
const emitter = getEmitter(e)
emitter.off(type, listener)
}
e.emit = type => {
e.emit = (type, ...args: any[]) => {
const emitter = getEmitter(e)
emitter.emit(type)
emitter.emit(type, ...args)

// editor 销毁时,off 掉 destroyed listeners
if (type === 'destroyed') {
Expand Down
26 changes: 22 additions & 4 deletions packages/core/src/menus/bar-item/ModalButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import Modal from '../panel-and-modal/Modal'
import { getEditorInstance } from './index'
import { getPositionBySelection, getPositionByNode, correctPosition } from '../helpers/position'
import { DomEditor } from '../../editor/dom-editor'
import $ from '../../utils/dom'

class ModalButton extends BaseButton {
private $body = $('body')
private modal: Modal | null = null
menu: IModalMenu

Expand Down Expand Up @@ -78,19 +80,35 @@ class ModalButton extends BaseButton {
if (menu.getModalContentElem == null) return

const textarea = DomEditor.getTextarea(editor)
const toolbar = DomEditor.getToolbar(editor)
const { modalAppendToBody } = toolbar?.getConfig() || {}

const $content = menu.getModalContentElem(editor)
modal.renderContent($content)
const positionStyle = this.getPosition() // 获取 modal position
modal.setStyle(positionStyle)

if (modalAppendToBody) {
// appendTo body 时,用户自己设置 modal 定位
modal.setStyle({ left: '0', right: '0' })
} else {
// 计算并设置 modal position
const positionStyle = this.getPosition()
modal.setStyle(positionStyle)
}

if (firstTime) {
modal.appendTo(textarea.$textAreaContainer)
if (modalAppendToBody) {
modal.appendTo(this.$body)
} else {
modal.appendTo(textarea.$textAreaContainer)
}
}

modal.show()

correctPosition(editor, modal.$elem) // 修正 modal 定位,避免超出 textContainer 边界
if (!modalAppendToBody) {
// 修正 modal 定位,避免超出 textContainer 边界( appendTo body 则不用设置,用户自己设置 )
correctPosition(editor, modal.$elem)
}
}
}

Expand Down
13 changes: 12 additions & 1 deletion packages/core/src/menus/panel-and-modal/BaseClass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@

import { IDomEditor } from '../../editor/interface'
import { Dom7Array } from '../../utils/dom'
import { EDITOR_TO_PANEL_AND_MODAL } from '../../utils/weak-maps'
import { EDITOR_TO_PANEL_AND_MODAL, PANEL_OR_MODAL_TO_EDITOR } from '../../utils/weak-maps'

abstract class PanelAndModal {
abstract readonly type: string
abstract readonly $elem: Dom7Array
isShow: boolean = false
private showTime: number = 0 // 显示时的时间戳
Expand All @@ -26,6 +27,8 @@ abstract class PanelAndModal {
EDITOR_TO_PANEL_AND_MODAL.set(editor, set)
}
set.add(this)

PANEL_OR_MODAL_TO_EDITOR.set(this, editor)
}

/**
Expand Down Expand Up @@ -57,6 +60,10 @@ abstract class PanelAndModal {
const { $elem } = this
$elem.show()
this.isShow = true

// 触发事件
const editor = PANEL_OR_MODAL_TO_EDITOR.get(this)
if (editor) editor.emit('modalOrPanelShow', this)
}

hide() {
Expand All @@ -71,6 +78,10 @@ abstract class PanelAndModal {
const { $elem } = this
$elem.hide()
this.isShow = false

// 触发事件
const editor = PANEL_OR_MODAL_TO_EDITOR.get(this)
if (editor) editor.emit('modalOrPanelHide')
}
}

Expand Down
1 change: 1 addition & 0 deletions packages/core/src/menus/panel-and-modal/DropPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import $, { Dom7Array } from '../../utils/dom'
import PanelAndModal from './BaseClass'

class DropPanel extends PanelAndModal {
type = 'dropPanel'
readonly $elem: Dom7Array = $(`<div class="w-e-drop-panel"></div>`)

constructor(editor: IDomEditor) {
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/menus/panel-and-modal/Modal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { DomEditor } from '../../editor/dom-editor'
import { SVG_CLOSE } from '../../constants/svg'

class Modal extends PanelAndModal {
type = 'modal'
readonly $elem: Dom7Array = $(`<div class="w-e-modal"></div>`)
private width: number = 0

Expand Down
1 change: 1 addition & 0 deletions packages/core/src/menus/panel-and-modal/SelectList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ function gen$SelectedIcon() {
}

class SelectList extends PanelAndModal {
type = 'selectList'
readonly $elem: Dom7Array = $(`<div class="w-e-select-list"></div>`)

constructor(editor: IDomEditor, width?: number) {
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/utils/weak-maps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const HOVER_BAR_TO_EDITOR = new WeakMap<HoverBar, IDomEditor>()
export const EDITOR_TO_HOVER_BAR = new WeakMap<IDomEditor, HoverBar>()
export const BAR_ITEM_TO_EDITOR = new WeakMap<IBarItem, IDomEditor>()
export const EDITOR_TO_PANEL_AND_MODAL = new WeakMap<IDomEditor, Set<PanelAndModal>>()
export const PANEL_OR_MODAL_TO_EDITOR = new WeakMap<PanelAndModal, IDomEditor>()

// config
export const EDITOR_TO_CONFIG = new WeakMap<IDomEditor, IEditorConfig>()
Expand Down
1 change: 1 addition & 0 deletions packages/editor/examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ <h1>wangEditor examples</h1>
<li><a href="./multi-editors.html">Multi editors 多个编辑器</a></li>
<li><a href="./headers.html">Get headers and scroll 获取标题/滚动到标题</a></li>
<li><a href="./huge-doc.html">Huge doc 大文件(几万个字)</a></li>
<li><a href="./modal-appendTo-body.html">Modal appendTo body</a></li>
<li><a href="./i18n.html">i18n 国际化</a></li>
<li><a href="./code-highlight.html">Code highlight 代码高亮</a></li>
<li><a href="./shadow-dom.html">Shadow DOM</a></li>
Expand Down
97 changes: 97 additions & 0 deletions packages/editor/examples/modal-appendTo-body.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>modal appendTo body - demo</title>
<link href="https://cdn.bootcdn.net/ajax/libs/normalize/8.0.1/normalize.min.css" rel="stylesheet">
<link href="./css/view.css" rel="stylesheet">
<link href="./css/editor.css" rel="stylesheet">
<link href="../dist/css/style.css" rel="stylesheet">

<style>
#mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 999;
background-color: #00000073;
display: none;
}
</style>
</head>

<body>
<p>
modal appendTo body
</p>

<div>
<div id="editor-toolbar" class="editor-toolbar"></div>
<div id="editor-text-area" class="editor-text-area"></div>
</div>

<!-- mask div 蒙层 -->
<div id="mask"></div>

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="js/init-content.js"></script>
<script src="../dist/index.js"></script>
<script>
const E = window.wangEditor

const editorConfig = { MENU_CONF: {} }

const toolbarConfig = {
modalAppendToBody: true
}

const editor = E.createEditor({
selector: '#editor-text-area',
content: window.content1,
config: editorConfig
})

const toolbar = E.createToolbar({
editor,
selector: '#editor-toolbar',
config: toolbarConfig
})

editor.on('modalOrPanelShow', modalOrPanel => {
if (modalOrPanel.type !== 'modal') return

const { $elem } = modalOrPanel // modal element
const width = $elem.width()
const height = $elem.height()

// set modal position z-index
$elem.css({
left: '50%',
top: '50%',
marginLeft: `-${width / 2}px`,
marginTop: `-${height / 2}px`,
zIndex: 1000
})

// show mask div
document.getElementById('mask').style.display = 'block'
})
editor.on('modalOrPanelHide', () => {
console.log('hide')

// hide mask div
document.getElementById('mask').style.display = 'none'
})
// click mask div to hide modal
document.getElementById('mask').addEventListener('click', () => {
editor.hidePanelOrModal()
})
</script>
</body>

</html>

0 comments on commit fc0ab06

Please sign in to comment.