Skip to content

Commit

Permalink
Merge pull request #143 from wjw020206/master
Browse files Browse the repository at this point in the history
feat(format painter menu): add format painter menu

#141
  • Loading branch information
cycleccc authored Aug 18, 2024
2 parents e37a391 + a6acb5f commit 1ec9026
Show file tree
Hide file tree
Showing 11 changed files with 156 additions and 0 deletions.
4 changes: 4 additions & 0 deletions packages/basic-modules/src/constants/icon-svg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,7 @@ export const CHECK_BOX_SVG =
// 回车
export const ENTER_SVG =
'<svg viewBox="0 0 1255 1024"><path d="M1095.111111 731.477333h-625.777778V1024L0 658.318222 469.333333 292.408889v292.636444h625.777778V0h156.444445v731.477333z"></path></svg>'

// 格式刷
export const FORMAT_PAINTER =
'<svg viewBox="0 0 24 24"><path d="M8 19.997v-5h2v5h9v-7H5v7zm-4-9h16v-3h-6v-4h-4v4H4zm-1 10v-8H2v-6a1 1 0 0 1 1-1h5v-3a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v3h5a1 1 0 0 1 1 1v6h-1v8a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1"/></svg>'
2 changes: 2 additions & 0 deletions packages/basic-modules/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import wangEditorDividerModule from './modules/divider'
import wangEditorCodeBlockModule from './modules/code-block'
import wangEditorFullScreenModule from './modules/full-screen'
import wangEditorCommonModule from './modules/common'
import wangEditorFormatPainterModule from './modules/format-painter'

export default [
// text style
Expand Down Expand Up @@ -54,6 +55,7 @@ export default [
wangEditorTodoModule,

// command
wangEditorFormatPainterModule,
wangEditorUndoRedoModule,
wangEditorFullScreenModule,
wangEditorCommonModule,
Expand Down
3 changes: 3 additions & 0 deletions packages/basic-modules/src/locale/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,7 @@ export default {
todo: {
todo: 'Todo',
},
formatPainter: {
title: 'Format Painter',
},
}
3 changes: 3 additions & 0 deletions packages/basic-modules/src/locale/zh-CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,7 @@ export default {
todo: {
todo: '待办',
},
formatPainter: {
title: '格式刷',
},
}
13 changes: 13 additions & 0 deletions packages/basic-modules/src/modules/format-painter/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { IDomEditor } from '@wangeditor-next/core'
import { SlateEditor } from '@wangeditor-next/editor'

/** 清空所有标记(文本样式) */
export function clearAllMarks(editor: IDomEditor) {
const marks = SlateEditor.marks(editor)

if (marks) {
Object.keys(marks).forEach(mark => {
editor.removeMark(mark)
})
}
}
15 changes: 15 additions & 0 deletions packages/basic-modules/src/modules/format-painter/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* @description format painter
* @author CodePencil
*/

import { IModuleConf } from '@wangeditor-next/core'
import { formatPainterConf } from './menu/index'
import withFormatPainter from './plugin'

const formatPainter: Partial<IModuleConf> = {
menus: [formatPainterConf],
editorPlugin: withFormatPainter,
}

export default formatPainter
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* @description Format Painter
* @author CodePencil
*/

import { IButtonMenu, IDomEditor, t } from '@wangeditor-next/core'
import { SlateEditor } from '@wangeditor-next/editor'
import { FORMAT_PAINTER } from '../../../constants/icon-svg'
import { Text } from 'slate'
import { clearAllMarks } from '../helper'

interface FormatPaintAttributes {
isSelect: boolean
formatStyle: Omit<Text, 'text'> | null
}

class FormatPainter implements IButtonMenu {
title = t('formatPainter.title')
iconSvg = FORMAT_PAINTER
tag = 'button'
static attrs: FormatPaintAttributes = {
isSelect: false,
formatStyle: null,
}

getValue(editor: IDomEditor): string | boolean {
return ''
}

isActive(editor: IDomEditor): boolean {
return FormatPainter.attrs.isSelect
}

isDisabled(editor: IDomEditor): boolean {
return false
}

setFormatHtml(editor: IDomEditor) {
if (!editor.getSelectionText().length) return
if (FormatPainter.attrs.formatStyle) {
clearAllMarks(editor)
for (const [key, value] of Object.entries(FormatPainter.attrs.formatStyle)) {
editor.addMark(key, value)
}
}
FormatPainter.attrs.formatStyle = {}
FormatPainter.attrs.isSelect = false
}

exec(editor: IDomEditor, value: string | boolean) {
// 如果已经选中了格式刷则取消选中,反之保存已经选中文本的样式
if (FormatPainter.attrs.isSelect) {
FormatPainter.attrs.isSelect = false
} else {
// 判断是否选中文本
if (editor.getSelectionText().length) {
FormatPainter.attrs.formatStyle = SlateEditor.marks(editor)
FormatPainter.attrs.isSelect = true
}
}

editor.blur()
editor.focus()
}
}

export default FormatPainter
13 changes: 13 additions & 0 deletions packages/basic-modules/src/modules/format-painter/menu/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* @description menu entry
* @author CodePencil
*/

import FormatPainter from './FormatPainter'

export const formatPainterConf = {
key: 'formatPainter',
factory() {
return new FormatPainter()
},
}
34 changes: 34 additions & 0 deletions packages/basic-modules/src/modules/format-painter/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* @description editor 插件,重写 editor API
* @author CodePencil
*/

import { IDomEditor } from '@wangeditor-next/core'
import FormatPainter from './menu/FormatPainter'

function withFormatPainter<T extends IDomEditor>(editor: T): T {
const formatPainter = new FormatPainter()

const { onChange } = editor
const newEditor = editor

const handleMouseUp = () => {
formatPainter.setFormatHtml(newEditor)
document.removeEventListener('mouseup', handleMouseUp)
}

newEditor.onChange = () => {
onChange()

if (FormatPainter.attrs.isSelect) {
// 避免重复绑定 mouseup 事件
document.removeEventListener('mouseup', handleMouseUp)
document.addEventListener('mouseup', handleMouseUp)
}
}

// 返回 editor ,重要!
return newEditor
}

export default withFormatPainter
1 change: 1 addition & 0 deletions packages/editor/src/init-default-config/config/hoverbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export function genDefaultHoverbarKeys() {
// 也可以自定义 match 来匹配元素,此时 key 就随意了
text: {
menuKeys: [
'formatPainter',
'headerSelect',
'insertLink',
'bulletedList',
Expand Down
1 change: 1 addition & 0 deletions packages/editor/src/init-default-config/config/toolbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export function genDefaultToolbarKeys() {
'undo',
'redo',
'|',
'formatPainter',
'fullScreen',
]
}
Expand Down

0 comments on commit 1ec9026

Please sign in to comment.