Skip to content

Commit

Permalink
feat: image menu - width 50% 100%
Browse files Browse the repository at this point in the history
  • Loading branch information
wangfupeng1988 committed Jun 30, 2021
1 parent 84be24e commit f9b4c68
Show file tree
Hide file tree
Showing 15 changed files with 282 additions and 125 deletions.
13 changes: 12 additions & 1 deletion examples/js/init-content.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,18 @@ window.initContent = [
},
{
type: 'paragraph',
children: [{ text: '一行文字' }],
children: [
{ text: '一行文字' },
{
type: 'image',
src: 'https://www.baidu.com/img/flexible/logo/pc/[email protected]',
alt: '百度',
url: 'https://www.baidu.com/',
style: { width: '101px', height: '33px' },
children: [{ text: '' }], // void node 要有一个空 text
},
{ text: '一行文字' },
],
},
{
type: 'blockquote',
Expand Down
61 changes: 33 additions & 28 deletions packages/basic-modules/src/assets/image.less
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
// 拖拽,修改图片尺寸
.w-e-selected-image-container {
position: relative;
display: inline-block;

.w-e-image-dragger {
width: 7px;
height: 7px;
background-color: #4290f7;
position: absolute;
}
.left-top {
top: -4px;
left: 0;
cursor: nwse-resize;
}
.right-top {
top: -4px;
right: 0;
cursor: nesw-resize;
.w-e-text-container [data-slate-editor] {
.w-e-image-container {
display: inline-block;
}
.left-bottom {
left: 0;
bottom: 0;
cursor: nesw-resize;
}
.right-bottom {
right: 0;
bottom: 0;
cursor: nwse-resize;
.w-e-selected-image-container {
position: relative;
overflow: hidden;

.w-e-image-dragger {
width: 7px;
height: 7px;
background-color: #4290f7;
position: absolute;
}
.left-top {
top: 0;
left: 0;
cursor: nwse-resize;
}
.right-top {
top: 0;
right: 0;
cursor: nesw-resize;
}
.left-bottom {
left: 0;
bottom: 0;
cursor: nesw-resize;
}
.right-bottom {
right: 0;
bottom: 0;
cursor: nwse-resize;
}
}
}
4 changes: 4 additions & 0 deletions packages/basic-modules/src/modules/image/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {
editImageMenuConf,
viewImageLinkMenuConf,
imageWidth30MenuConf,
imageWidth50MenuConf,
imageWidth100MenuConf,
} from './menu/index'

const image: IModuleConf = {
Expand All @@ -24,6 +26,8 @@ const image: IModuleConf = {
editImageMenuConf,
viewImageLinkMenuConf,
imageWidth30MenuConf,
imageWidth50MenuConf,
imageWidth100MenuConf,
],
editorPlugin: withImage,
}
Expand Down
13 changes: 13 additions & 0 deletions packages/basic-modules/src/modules/image/menu/Width100.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* @description image width 100%
* @author wangfupeng
*/

import ImageWidthBaseClass from './WidthBase'

class ImageWidth100 extends ImageWidthBaseClass {
title = '100%' // 菜单标题
value = '100%' // css width 的值
}

export default ImageWidth100
65 changes: 5 additions & 60 deletions packages/basic-modules/src/modules/image/menu/Width30.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,66 +3,11 @@
* @author wangfupeng
*/

import { Transforms, Node } from 'slate'
import { IButtonMenu, IDomEditor } from '@wangeditor/core'
import { checkNodeType, getSelectedNodeByType } from '../../_helpers/node'
import ImageWidthBaseClass from './WidthBase'

// TODO 宽度 30% 50% 100%
// 抽离一个 baseClass

class ImageWidth implements IButtonMenu {
title = '30%'
tag = 'button'
private value = '30%'

getValue(editor: IDomEditor): string | boolean {
// 无需获取 val
return ''
}

isActive(editor: IDomEditor): boolean {
// 无需 active
return false
}

private getSelectedNode(editor: IDomEditor): Node | null {
return getSelectedNodeByType(editor, 'image')
}

isDisabled(editor: IDomEditor): boolean {
if (editor.selection == null) return true

const imageNode = this.getSelectedNode(editor)
if (imageNode == null) {
// 选区未处于 image node ,则禁用
return true
}
return false
}

exec(editor: IDomEditor, value: string | boolean) {
if (this.isDisabled(editor)) return

const imageNode = this.getSelectedNode(editor)
if (imageNode == null) return

// @ts-ignore
const { style = {} } = imageNode
const newStyle = {
...style,
width: this.value, // 修改 width
height: '', // 清空 height
}

Transforms.setNodes(
editor,
// @ts-ignore
{ style: newStyle },
{
match: n => checkNodeType(n, 'image'),
}
)
}
class ImageWidth30 extends ImageWidthBaseClass {
title = '30%' // 菜单标题
value = '30%' // css width 的值
}

export default ImageWidth
export default ImageWidth30
13 changes: 13 additions & 0 deletions packages/basic-modules/src/modules/image/menu/Width50.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* @description image width 50%
* @author wangfupeng
*/

import ImageWidthBaseClass from './WidthBase'

class ImageWidth50 extends ImageWidthBaseClass {
title = '50%' // 菜单标题
value = '50%' // css width 的值
}

export default ImageWidth50
65 changes: 65 additions & 0 deletions packages/basic-modules/src/modules/image/menu/WidthBase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* @description image width base class
* @author wangfupeng
*/

import { Transforms, Node } from 'slate'
import { IButtonMenu, IDomEditor } from '@wangeditor/core'
import { checkNodeType, getSelectedNodeByType } from '../../_helpers/node'

abstract class ImageWidthBaseClass implements IButtonMenu {
abstract title: string // 菜单标题
tag = 'button'
abstract value: string // css width 的值

getValue(editor: IDomEditor): string | boolean {
// 无需获取 val
return ''
}

isActive(editor: IDomEditor): boolean {
// 无需 active
return false
}

private getSelectedNode(editor: IDomEditor): Node | null {
return getSelectedNodeByType(editor, 'image')
}

isDisabled(editor: IDomEditor): boolean {
if (editor.selection == null) return true

const imageNode = this.getSelectedNode(editor)
if (imageNode == null) {
// 选区未处于 image node ,则禁用
return true
}
return false
}

exec(editor: IDomEditor, value: string | boolean) {
if (this.isDisabled(editor)) return

const imageNode = this.getSelectedNode(editor)
if (imageNode == null) return

// @ts-ignore
const { style = {} } = imageNode
const newStyle = {
...style,
width: this.value, // 修改 width
height: '', // 清空 height
}

Transforms.setNodes(
editor,
// @ts-ignore
{ style: newStyle },
{
match: n => checkNodeType(n, 'image'),
}
)
}
}

export default ImageWidthBaseClass
2 changes: 1 addition & 1 deletion packages/basic-modules/src/modules/image/menu/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ export function genImageMenuConfig() {
/*自定义*/
},

// TODO onDeletedImage ??? 考虑所有删除的场景 —— 可以使用插件,劫持 e.apply 中的 `remove_node`
// TODO onDeletedImage - 参考 plugin.ts 中的 `newEditor.apply = `
}
}
16 changes: 16 additions & 0 deletions packages/basic-modules/src/modules/image/menu/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import DeleteImage from './DeleteImage'
import EditImage from './EditImage'
import ViewImageLink from './ViewImageLink'
import ImageWidth30 from './Width30'
import ImageWidth50 from './Width50'
import ImageWidth100 from './Width100'
import { genImageMenuConfig } from './config'

const config = genImageMenuConfig() // menu config
Expand Down Expand Up @@ -51,3 +53,17 @@ export const imageWidth30MenuConf = {
return new ImageWidth30()
},
}

export const imageWidth50MenuConf = {
key: 'imageWidth50',
factory() {
return new ImageWidth50()
},
}

export const imageWidth100MenuConf = {
key: 'imageWidth100',
factory() {
return new ImageWidth100()
},
}
20 changes: 19 additions & 1 deletion packages/basic-modules/src/modules/image/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
* @author wangfupeng
*/

import { Editor, Path, Operation } from 'slate'
import { IDomEditor } from '@wangeditor/core'

function withImage<T extends IDomEditor>(editor: T): T {
const { isInline, isVoid, insertData } = editor
const { isInline, isVoid /*, apply */ } = editor
const newEditor = editor

// 重写 isInline
Expand All @@ -33,6 +34,23 @@ function withImage<T extends IDomEditor>(editor: T): T {
return isVoid(elem)
}

// // 监听删除图片
// // 【注意】暂时不开放这个功能,因为图片删除还可能被撤销回来,所以无法通过 remove_node 这一个动作来处理删除图片
// // 要实现“获取用户删除的图片”还需要更多的支持,例如收集 remove_node 的图片,最后和所有图片进行对比
// // 还要考虑编辑图片
// newEditor.apply = (op: Operation) => {
// if (op.type === 'remove_node') {
// const { node } = op
// // @ts-ignore
// if (node.type === 'image') {
// console.log('removed image node', node)
// }
// }

// // 执行原本的 apply - 重要!!!
// apply(op)
// }

// 返回 editor ,重要!
return newEditor
}
Expand Down
Loading

0 comments on commit f9b4c68

Please sign in to comment.