wangEditor
wangEditor copied to clipboard
自定义table表格插件回显到编辑器时执行了编辑器自身的表格parseElemHtml代码
问题描述
根据html回显到编辑器时没有执行我的parseElemHtml代码而是走了编辑器自身的表格parseElemHtml代码,该怎么处理? 源码中的parse-elem-html.ts代码中并没有对table、tr、th、td等元素进行精确匹配。
wangEditor 版本
"@wangeditor/editor": "^5.0.1", "@wangeditor/editor-for-react": "^1.0.2",
是否查阅了文档 ?
是
最小成本的复现步骤
(请告诉我们,如何最快的复现该问题?)
- 步骤一
render-elem.tsx
/*
* @Description:
* @Author: ldx
* @Date: 2022-05-13 15:22:43
* @LastEditors: ldx
* @LastEditTime: 2022-05-17 17:40:31
*/
import { DomEditor, IDomEditor, SlateElement } from '@wangeditor/editor'
import { Editor, Path, Point, Range } from 'slate'
import { h, VNode } from 'snabbdom'
import { editorData, genContainerId, getContainerElem } from '../utils'
import { TableCellElement, TableElement, TableRowElement } from './custom-types'
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name'
},
{
title: 'Age',
dataIndex: 'age',
key: 'age'
},
{
title: 'Address',
dataIndex: 'address',
key: 'address'
}
]
const dataSource = [
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park'
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park'
},
{
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park'
}
]
function renderTableHead(columns: any[] = []): VNode {
return h(
'tr',
{},
columns.map((column) => h('th', {}, column.title))
)
}
function renderTableEmpty(columns: any[] = []): VNode {
return h('tr', {}, [
h(
'td',
{
colSpan: columns.length
},
[
h(
'div',
{
style: {
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
color: '#0f0f0f4d'
}
},
[
h('i', {
className: 'iconfont icon-zanwushuju1',
style: { fontSize: '42px' }
}),
h('span', {}, '暂无数据')
]
)
]
)
])
}
function renderTableCell(dataSource: any[] = [], columns: any[] = []): VNode[] {
if (dataSource.length === 0) {
return [renderTableEmpty(columns)]
} else {
return dataSource.map((data) =>
h(
'tr',
{},
columns.map((column) =>
h('td', {}, [h('span', {}, data[column.dataIndex])])
)
)
)
}
}
function renderTable(
elemNode: SlateElement,
children: VNode[] | null,
editor: IDomEditor
): VNode {
const { fullWidth = false, id = '' } = elemNode as TableElement
const { editable = false } = elemNode as TableElement
// 当前节点是否选中
const selected = DomEditor.isNodeSelected(editor, elemNode)
const containerId = genContainerId(editor, elemNode)
if (selected && getContainerElem(containerId)) {
editor.emit('select:customElement', id)
}
console.log('editorData', editorData.get(id))
let data = editorData.get(id) as any
if (!data) {
// 请求接口
data = {
columns,
dataSource
}
editorData.set(id, data)
}
// 是否可编辑
// editable = editable || getContentEditable(editor, elemNode)
// 构建 table vnode
const tableVnode = h(
'table',
{
className: 'custom-table',
contentEditable: editable,
style: {
width: fullWidth ? '100%' : '',
margin: 'auto'
}
},
[
renderTableHead(data.columns),
...renderTableCell(data.dataSource, data.columns)
]
)
// 构建容器 vnode
const containerVnode = h(
'div',
{
props: {
id: containerId,
contentEditable: false // 不可编辑
},
style: {
display: 'flex', // inline
alignItems: 'center',
justifyContent: 'center'
}
},
[
h(
'span',
{
style: {
width: fullWidth ? '100%' : '',
display: 'block', // inline
marginLeft: '3px',
marginRight: '3px',
border: selected // 选中/不选中,样式不一样
? '2px solid var(--w-e-textarea-selected-border-color)' // wangEditor 提供了 css var https://www.wangeditor.com/v5/theme.html
: '2px solid transparent',
borderRadius: '3px',
padding: '3px 3px'
}
},
[tableVnode]
)
]
)
return containerVnode
}
const conf = {
type: 'customTable', // 节点 type ,重要!!!
renderElem: renderTable
}
export default conf
- 步骤二
/*
* @Description:
* @Author: ldx
* @Date: 2022-05-13 15:22:43
* @LastEditors: ldx
* @LastEditTime: 2022-05-17 18:16:42
*/
parse-elem-html.ts
import { IDomEditor, SlateDescendant, SlateElement } from '@wangeditor/editor'
import { TableElement } from './custom-types'
function parseTableHtml(
elem: Element,
children: SlateDescendant[],
editor: IDomEditor
): SlateElement {
const id = elem.getAttribute('data-id') || ''
const fullWidth = elem.getAttribute('data-fullWidth') || false
const editable = elem.getAttribute('data-editable') || false
console.log('================================================')
return {
type: 'customTable',
id,
fullWidth,
editable,
children: [{ text: '' }]
} as TableElement
}
const parseTableHtmlConf = {
selector: 'table[data-w-e-type="customTable"]',
parseElemHtml: parseTableHtml
}
export default parseTableHtmlConf
- 步骤三
index.ts
/*
* @Description:
* @Author: ldx
* @Date: 2022-05-17 11:17:36
* @LastEditors: ldx
* @LastEditTime: 2022-05-17 18:15:37
*/
import { IModuleConf } from '@wangeditor/core'
import { tableToHtmlConf } from './elem-to-html'
import parseTableHtmlConf from './parse-elem-html'
import withTable from './plugin'
import { preParseTableHtmlConf } from './pre-parse-html'
import renderElemConf from './render-elem'
export const module: Partial<IModuleConf> = {
renderElems: [renderElemConf],
elemsToHtml: [tableToHtmlConf],
}
export default module
- 步骤四 const node = { type: 'customTable', id, api: '', editable: false, children: [{ text: '' }] // children: rows } editor?.insertNode(node)
你一次性写的代码太多了。
你就把 renderTable
写的足够简单(先不管功能,先做测试),最好 5 行代码搞定,你看是否执行这个函数?
只管 render table ,其他的都不管,调试通这个再说。
二次开发嘛,要一步一步来,调通一步就往前走一步。
我进行了一个足够简单的demo测试,还是复现了这个问题。我认为是源码中表格的pre-parse-html文件中对table、tr、th、td等元素没有进行精确匹配导致的。
render-elem.tsx
import { h, VNode } from 'snabbdom'
function renderTable(): VNode {
// 构建 table vnode
const tableVnode = h(
'table',
{
className: 'custom-table'
},
[h('tr', {}, [h('th', {}, 'aaaa')]), h('tr', {}, [h('td', {}, 'bbbb')])]
)
return tableVnode
}
const conf = {
type: 'customTable', // 节点 type ,重要!!!
renderElem: renderTable
}
export default conf
parse-elem-html.ts
/*
* @Description:
* @Author: ldx
* @Date: 2022-05-13 15:22:43
* @LastEditors: ldx
* @LastEditTime: 2022-05-18 09:09:02
*/
import { SlateElement } from '@wangeditor/editor'
import { TableElement } from './custom-types'
function parseTableHtml(): SlateElement {
return {
type: 'customTable',
children: [{ text: '' }]
} as TableElement
}
const parseTableHtmlConf = {
selector: 'table[data-w-e-type="customTable"]',
parseElemHtml: parseTableHtml
}
export default parseTableHtmlConf
index.ts
/*
* @Description:
* @Author: ldx
* @Date: 2022-05-17 11:17:36
* @LastEditors: ldx
* @LastEditTime: 2022-05-18 09:12:38
*/
import { IModuleConf } from '@wangeditor/core'
import { tableToHtmlConf } from './elem-to-html'
import parseTableHtmlConf from './parse-elem-html'
export const module: Partial<IModuleConf> = {
elemsToHtml: [tableToHtmlConf],
parseElemsHtml: [parseTableHtmlConf]
}
export default module
// 使用
const node = {
type: 'customTable',
children: [{ text: '' }]
}
editor?.insertNode(node)
自定义table表格插件回显到编辑器时执行了编辑器自身的表格parseElemHtml代码
我认为是源码中表格的pre-parse-html文件中对table、tr、th、td等元素没有进行精确匹配导致的。
看当前现象,应该是你说的原因。我近期去排查一下。
近期我的项目需要上线,请问您什么时候修复这个问题。如果近期没有修复计划,我这边需要调整该功能。
---- 回复的原邮件 ---- | 发件人 | @.> | | 日期 | 2022年05月18日 10:20 | | 收件人 | @.> | | 抄送至 | @.@.> | | 主题 | Re: [wangeditor-team/wangEditor] 自定义table表格插件回显到编辑器时执行了编辑器自身的表格parseElemHtml代码 (Issue #4220) |
自定义table表格插件回显到编辑器时执行了编辑器自身的表格parseElemHtml代码
我认为是源码中表格的pre-parse-html文件中对table、tr、th、td等元素没有进行精确匹配导致的。
看当前现象,应该是你说的原因。我近期去排查一下。
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>
近期不行,没时间改。
这个问题修复了么
这个问题是否可以安排时间修复下,5月17号提出已经三个半月了,理解作者的开源不易,也经常刷到作者的抖音,明白开源是无私奉献,但确实这个问题影响到了项目开发,只能请求作者解决下了。
已修复。更新最新版 @wangeditor/editor
即可。
只要你的 HTML 中带有 data-w-e-type
属性(如 <table data-w-e-type="xxx">...</table>
),就不会走默认的 parseElemHtml
你需要自定义自己的 toHtml 和 parseHtml 逻辑(匹配好 data-w-e-type
的值),具体可参考“下载附件”插件的源码 https://github.com/wangeditor-team/wangEditor-plugin-upload-attachment