@sy-common/wang-editor 1.0.0-beta.22 → 1.0.0-beta.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/customHrMenu.js +231 -0
- package/src/index.vue +12 -164
package/package.json
CHANGED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { Transforms, Element } from 'slate'
|
|
2
|
+
import { h } from 'snabbdom'
|
|
3
|
+
|
|
4
|
+
class CustomHrMenu {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.title = '彩色分割线'
|
|
7
|
+
this.tag = 'button'
|
|
8
|
+
this.showDropPanel = true // ✅ 关键:必须设置为 true 才能弹出面板
|
|
9
|
+
this.iconSvg = '<svg viewBox="0 0 1092 1024"><path d="M0 51.2m51.2 0l989.866667 0q51.2 0 51.2 51.2l0 0q0 51.2-51.2 51.2l-989.866667 0q-51.2 0-51.2-51.2l0 0q0 51.2 51.2-51.2Z" fill="#999"/><path d="M0 460.8m51.2 0l170.666667 0q51.2 0 51.2 51.2l0 0q0 51.2-51.2 51.2l-170.666667 0q-51.2 0-51.2-51.2l0 0q0 51.2 51.2-51.2Z" fill="#ff4d4f"/><path d="M273 460.8m51.2 0l170.666667 0q51.2 0 51.2 51.2l0 0q0 51.2-51.2 51.2l-170.666667 0q-51.2 0-51.2-51.2l0 0q0 51.2 51.2-51.2Z" fill="#faad14"/><path d="M546 460.8m51.2 0l170.666667 0q51.2 0 51.2 51.2l0 0q0 51.2-51.2 51.2l-170.666667 0q-51.2 0-51.2-51.2l0 0q0 51.2 51.2-51.2Z" fill="#52c41a"/><path d="M819 460.8m51.2 0l170.666667 0q51.2 0 51.2 51.2l0 0q0 51.2-51.2 51.2l-170.666667 0q-51.2 0-51.2-51.2l0 0q0 51.2 51.2-51.2Z" fill="#1890ff"/><path d="M0 870.4m51.2 0l989.866667 0q51.2 0 51.2 51.2l0 0q0 51.2-51.2 51.2l-989.866667 0q-51.2 0-51.2-51.2l0 0q0 51.2 51.2-51.2Z" fill="#999"/></svg>' // 可选,设置菜单图标
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// 判断菜单是否禁用
|
|
13
|
+
isDisabled(editor) {
|
|
14
|
+
return false
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// 判断菜单是否激活
|
|
18
|
+
isActive(editor) {
|
|
19
|
+
return false
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// 获取当前值
|
|
23
|
+
getValue(editor) {
|
|
24
|
+
return ''
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// 点击菜单时执行(当没有下拉面板时才会调用此方法)
|
|
28
|
+
exec(editor, value) {
|
|
29
|
+
if (value) {
|
|
30
|
+
this.insertColoredHr(editor, value)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// ✅ 关键:创建下拉面板内容(颜色选择器)
|
|
35
|
+
getPanelContentElem(editor) {
|
|
36
|
+
const panel = document.createElement('div')
|
|
37
|
+
panel.style.cssText = `
|
|
38
|
+
display: grid;
|
|
39
|
+
grid-template-columns: repeat(5, 1fr);
|
|
40
|
+
gap: 8px;
|
|
41
|
+
padding: 12px;
|
|
42
|
+
background: white;
|
|
43
|
+
border-radius: 4px;
|
|
44
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
|
45
|
+
`
|
|
46
|
+
|
|
47
|
+
// 预设颜色列表
|
|
48
|
+
const colors = [
|
|
49
|
+
'#000000', '#333333', '#666666', '#999999', '#cccccc',
|
|
50
|
+
'#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff',
|
|
51
|
+
'#ff6600', '#00ccff', '#ff0066', '#9933ff', '#33ff99'
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
colors.forEach(color => {
|
|
55
|
+
const btn = document.createElement('button')
|
|
56
|
+
btn.setAttribute('data-color', color)
|
|
57
|
+
btn.style.cssText = `
|
|
58
|
+
width: 32px;
|
|
59
|
+
height: 32px;
|
|
60
|
+
background-color: ${color};
|
|
61
|
+
border: 1px solid #ddd;
|
|
62
|
+
border-radius: 4px;
|
|
63
|
+
cursor: pointer;
|
|
64
|
+
transition: transform 0.2s;
|
|
65
|
+
`
|
|
66
|
+
btn.addEventListener('mouseenter', () => {
|
|
67
|
+
btn.style.transform = 'scale(1.1)'
|
|
68
|
+
})
|
|
69
|
+
btn.addEventListener('mouseleave', () => {
|
|
70
|
+
btn.style.transform = 'scale(1)'
|
|
71
|
+
})
|
|
72
|
+
btn.addEventListener('click', () => {
|
|
73
|
+
// 点击颜色时插入彩色分割线
|
|
74
|
+
this.insertColoredHr(editor, color)
|
|
75
|
+
// 关闭下拉面板
|
|
76
|
+
editor.hidePanelOrModal()
|
|
77
|
+
})
|
|
78
|
+
panel.appendChild(btn)
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
return panel
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// 插入彩色分割线的公共方法
|
|
85
|
+
insertColoredHr(editor, color) {
|
|
86
|
+
// 插入自定义节点
|
|
87
|
+
editor.insertNode({
|
|
88
|
+
type: 'colored-hr',
|
|
89
|
+
color: color,
|
|
90
|
+
children: [{ text: '' }]
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
// 插入换行段落,方便继续编辑
|
|
94
|
+
editor.insertNode({
|
|
95
|
+
type: 'paragraph',
|
|
96
|
+
children: [{ text: '' }]
|
|
97
|
+
})
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const renderColoredHr = (elem, children, editor) => {
|
|
102
|
+
const color = elem.color || '#cccccc'
|
|
103
|
+
|
|
104
|
+
// 使用 snabbdom 的 h() 函数创建 VNode
|
|
105
|
+
return h('hr', {
|
|
106
|
+
attrs: {
|
|
107
|
+
'data-color': color,
|
|
108
|
+
'data-w-e-type': 'colored-hr'
|
|
109
|
+
},
|
|
110
|
+
style: {
|
|
111
|
+
border: 'none',
|
|
112
|
+
borderTop: `2px solid ${color}`,
|
|
113
|
+
margin: '16px 0'
|
|
114
|
+
}
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// 2. HTML 转换函数:保存时把自定义节点转成 HTML
|
|
119
|
+
const hrToHtml = (elem, childrenHtml) => {
|
|
120
|
+
// 调试:打印 elem 看看是什么
|
|
121
|
+
|
|
122
|
+
const color = elem.color || '#cccccc'
|
|
123
|
+
const html = `<hr style="border: none; border-top: 2px solid ${color}; margin: 16px 0;" data-color="${color}" data-w-e-type="colored-hr">`
|
|
124
|
+
return html
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// 3. HTML 解析函数:加载时把 HTML 转回自定义节点
|
|
128
|
+
const parseHrHtml = (domElem, children, editor) => {
|
|
129
|
+
console.log('parseHrHtml received domElem:', domElem)
|
|
130
|
+
const color = domElem.getAttribute('data-color') || '#cccccc'
|
|
131
|
+
console.log('parseHrHtml color:', color)
|
|
132
|
+
return {
|
|
133
|
+
type: 'colored-hr',
|
|
134
|
+
color: color,
|
|
135
|
+
children: [{ text: '' }]
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function withColoredHr(editor) {
|
|
140
|
+
const { isVoid, normalizeNode } = editor
|
|
141
|
+
|
|
142
|
+
// 标记 colored-hr 为 void 元素(不能输入文字)
|
|
143
|
+
editor.isVoid = (elem) => {
|
|
144
|
+
if (Element.isElement(elem) && elem.type === 'colored-hr') {
|
|
145
|
+
return true
|
|
146
|
+
}
|
|
147
|
+
return isVoid(elem)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// 可选:规范化节点,确保结构正确
|
|
151
|
+
editor.normalizeNode = ([node, path]) => {
|
|
152
|
+
if (Element.isElement(node) && node.type === 'colored-hr') {
|
|
153
|
+
// 确保 colored-hr 有 color 属性
|
|
154
|
+
if (node.color == null) {
|
|
155
|
+
Transforms.setNodes(editor, { color: '#cccccc' }, { at: path })
|
|
156
|
+
return
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
normalizeNode([node, path])
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return editor
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// 4. 组装模块并注册
|
|
166
|
+
const coloredHrModule = {
|
|
167
|
+
elemsToHtml: [{
|
|
168
|
+
type: 'colored-hr',
|
|
169
|
+
elemToHtml: hrToHtml
|
|
170
|
+
}],
|
|
171
|
+
renderElems: [{
|
|
172
|
+
type: 'colored-hr',
|
|
173
|
+
renderElem: renderColoredHr
|
|
174
|
+
}],
|
|
175
|
+
parseElemsHtml: [{
|
|
176
|
+
selector: 'hr[data-w-e-type="colored-hr"]',
|
|
177
|
+
parseElemHtml: parseHrHtml
|
|
178
|
+
}],
|
|
179
|
+
|
|
180
|
+
editorPlugin: withColoredHr,
|
|
181
|
+
|
|
182
|
+
menus: [{
|
|
183
|
+
key: 'customHrMenu',
|
|
184
|
+
factory() {
|
|
185
|
+
return new CustomHrMenu()
|
|
186
|
+
}
|
|
187
|
+
}]
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
export function registerMenu(Boot) {
|
|
193
|
+
try {
|
|
194
|
+
// 1. 注册菜单(你确认这个可以)
|
|
195
|
+
Boot.registerMenu({
|
|
196
|
+
key: 'customHrMenu',
|
|
197
|
+
factory: () => new CustomHrMenu()
|
|
198
|
+
})
|
|
199
|
+
console.log('✅ 菜单注册成功')
|
|
200
|
+
|
|
201
|
+
// 2. 注册渲染
|
|
202
|
+
Boot.registerRenderElem({
|
|
203
|
+
type: 'colored-hr',
|
|
204
|
+
renderElem: renderColoredHr
|
|
205
|
+
})
|
|
206
|
+
console.log('✅ 渲染注册成功')
|
|
207
|
+
|
|
208
|
+
// 3. 注册 HTML 导出
|
|
209
|
+
Boot.registerElemToHtml({
|
|
210
|
+
type: 'colored-hr',
|
|
211
|
+
elemToHtml: hrToHtml
|
|
212
|
+
})
|
|
213
|
+
console.log('✅ HTML导出注册成功')
|
|
214
|
+
|
|
215
|
+
// 4. 注册 HTML 解析
|
|
216
|
+
Boot.registerParseElemHtml({
|
|
217
|
+
selector: 'hr[data-color]',
|
|
218
|
+
parseElemHtml: parseHrHtml
|
|
219
|
+
})
|
|
220
|
+
console.log('✅ HTML解析注册成功')
|
|
221
|
+
|
|
222
|
+
// 5. 注册插件
|
|
223
|
+
Boot.registerPlugin(withColoredHr)
|
|
224
|
+
console.log('✅ 插件注册成功')
|
|
225
|
+
} catch (e) {
|
|
226
|
+
if (!e.message.includes('already') && !e.message.includes('duplicate')) {
|
|
227
|
+
console.warn('注册失败:', e)
|
|
228
|
+
throw e
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
package/src/index.vue
CHANGED
|
@@ -21,10 +21,9 @@ import '@wangeditor-next/editor/dist/css/style.css'
|
|
|
21
21
|
import {oneOf} from '@lambo-design/shared/utils/platform';
|
|
22
22
|
import {Editor, Toolbar} from '@wangeditor-next/editor-for-vue2'
|
|
23
23
|
import {Boot} from '@wangeditor-next/editor'
|
|
24
|
-
import {
|
|
25
|
-
|
|
24
|
+
import {registerMenu} from './customHrMenu'
|
|
26
25
|
// 注册分割线颜色菜单(模块级别,只执行一次)
|
|
27
|
-
|
|
26
|
+
registerMenu(Boot)
|
|
28
27
|
|
|
29
28
|
export default {
|
|
30
29
|
name: 'WangEditor',
|
|
@@ -99,8 +98,8 @@ export default {
|
|
|
99
98
|
default: false
|
|
100
99
|
},
|
|
101
100
|
/**
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
* @description: 隐藏菜单
|
|
102
|
+
*/
|
|
104
103
|
hideMenu: {
|
|
105
104
|
type: Array,
|
|
106
105
|
default: () => []
|
|
@@ -119,7 +118,7 @@ export default {
|
|
|
119
118
|
toolbarConfig: {
|
|
120
119
|
insertKeys: {
|
|
121
120
|
index: 24, // 在分割线菜单后面插入
|
|
122
|
-
keys: [
|
|
121
|
+
keys: ['customHrMenu']
|
|
123
122
|
}
|
|
124
123
|
},
|
|
125
124
|
editorConfig: {
|
|
@@ -245,53 +244,8 @@ export default {
|
|
|
245
244
|
|
|
246
245
|
if (!isEmpty && wasEmpty) {
|
|
247
246
|
if (this.valueType === 'html') {
|
|
248
|
-
let html = newVal
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
// 【关键修复】在 setHtml 之前,先从 HTML 字符串计算 hr 数量
|
|
252
|
-
// 这样 setHtml 触发 onChange 时,hrCount 已经是正确的
|
|
253
|
-
const tempDivForCount = document.createElement('div')
|
|
254
|
-
tempDivForCount.innerHTML = html
|
|
255
|
-
this.hrCount = tempDivForCount.querySelectorAll('hr').length
|
|
256
|
-
|
|
257
|
-
// 表格处理...
|
|
258
|
-
const tableRegex = /(<table)([\s\S]*?)(<\/table>)/gi;
|
|
259
|
-
html = html.replace(tableRegex, (match, startTag, content, endTag) => {
|
|
260
|
-
const updatedContent = content.replace(/border-width:\s*(\d+)px;/g, 'border-width: $1;');
|
|
261
|
-
return `${startTag}${updatedContent}${endTag}`;
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
const tempDiv = document.createElement('div');
|
|
265
|
-
tempDiv.innerHTML = html;
|
|
266
|
-
const tables = tempDiv.querySelectorAll('table');
|
|
267
|
-
tables.forEach(table => {
|
|
268
|
-
table.setAttribute('data-processed', 'true');
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
this.editor.setHtml(tempDiv.innerHTML)
|
|
272
|
-
|
|
273
|
-
// setHtml 后异步设置 hr 颜色样式到 DOM
|
|
274
|
-
if (hrColors.length > 0) {
|
|
275
|
-
setTimeout(() => {
|
|
276
|
-
try {
|
|
277
|
-
const container = this.editor.getEditableContainer()
|
|
278
|
-
if (!container) return
|
|
279
|
-
const hrs = container.querySelectorAll('hr')
|
|
280
|
-
hrs.forEach((hr, index) => {
|
|
281
|
-
const color = hrColors[index] || ''
|
|
282
|
-
if (color) {
|
|
283
|
-
hr.style.border = 'none'
|
|
284
|
-
hr.style.borderTop = '2px solid ' + color
|
|
285
|
-
hr.style.margin = '10px 0'
|
|
286
|
-
hr.setAttribute('data-divider-color', color)
|
|
287
|
-
}
|
|
288
|
-
})
|
|
289
|
-
this.hrCount = hrs.length
|
|
290
|
-
} catch (e) {
|
|
291
|
-
console.warn('设置 hr 颜色失败:', e)
|
|
292
|
-
}
|
|
293
|
-
}, 100)
|
|
294
|
-
}
|
|
247
|
+
let html = newVal
|
|
248
|
+
this.editor.setHtml(html)
|
|
295
249
|
} else {
|
|
296
250
|
this.editor.insertText(newVal)
|
|
297
251
|
}
|
|
@@ -334,124 +288,18 @@ export default {
|
|
|
334
288
|
methods: {
|
|
335
289
|
|
|
336
290
|
onCreated(editor) {
|
|
337
|
-
this.editor = Object.seal(editor)
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
if (html) {
|
|
341
|
-
this.editor.setHtml(html)
|
|
342
|
-
// 处理已有颜色的 hr 元素,从 style 中提取颜色
|
|
343
|
-
this.$nextTick(() => {
|
|
344
|
-
try {
|
|
345
|
-
const container = this.editor.getEditableContainer()
|
|
346
|
-
if (!container) return
|
|
347
|
-
const hrs = container.querySelectorAll('hr')
|
|
348
|
-
// 初始化 hrCount,记录已有分割线数量
|
|
349
|
-
this.hrCount = hrs.length
|
|
350
|
-
hrs.forEach(hr => {
|
|
351
|
-
const style = hr.getAttribute('style') || ''
|
|
352
|
-
// 匹配 border 中的颜色
|
|
353
|
-
const colorMatch = style.match(/border\s*:[^;]*solid\s+(rgb\([^)]+\)|#[a-fA-F0-9]+)/i)
|
|
354
|
-
if (colorMatch) {
|
|
355
|
-
hr.setAttribute('data-divider-color', colorMatch[1])
|
|
356
|
-
}
|
|
357
|
-
})
|
|
358
|
-
} catch (e) {
|
|
359
|
-
console.warn('处理已存在 hr 颜色失败:', e)
|
|
360
|
-
}
|
|
361
|
-
})
|
|
291
|
+
this.editor = Object.seal(editor)
|
|
292
|
+
if (this.value) {
|
|
293
|
+
this.editor.setHtml(this.value)
|
|
362
294
|
}
|
|
363
295
|
},
|
|
364
296
|
onChange(editor) {
|
|
365
|
-
let
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
// 创建一个临时的 div 容器来解析 HTML
|
|
369
|
-
const tempDiv = document.createElement('div');
|
|
370
|
-
tempDiv.innerHTML = html;
|
|
371
|
-
|
|
372
|
-
// 从编辑器 DOM 获取所有 hr 的颜色,写入输出 HTML
|
|
373
|
-
const editorContainer = this.editor.getEditableContainer()
|
|
374
|
-
const editorHrs = editorContainer ? editorContainer.querySelectorAll('hr') : []
|
|
375
|
-
const outputHrs = tempDiv.querySelectorAll('hr')
|
|
376
|
-
|
|
377
|
-
// 检测新增的分割线,设置默认颜色
|
|
378
|
-
const DEFAULT_HR_COLOR = 'rgb(250, 64, 6)'
|
|
379
|
-
if (editorHrs.length > this.hrCount) {
|
|
380
|
-
// 有新增的分割线:只给没有颜色的 hr 设置默认色
|
|
381
|
-
for (let i = this.hrCount; i < editorHrs.length; i++) {
|
|
382
|
-
const hr = editorHrs[i]
|
|
383
|
-
// 【关键】如果 hr 已经有颜色(回显的),不要覆盖
|
|
384
|
-
if (!hr.getAttribute('data-divider-color')) {
|
|
385
|
-
hr.style.border = 'none'
|
|
386
|
-
hr.style.borderTop = '2px solid ' + DEFAULT_HR_COLOR
|
|
387
|
-
hr.style.margin = '10px 0'
|
|
388
|
-
hr.setAttribute('data-divider-color', DEFAULT_HR_COLOR)
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
this.hrCount = editorHrs.length
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
editorHrs.forEach((hr, index) => {
|
|
395
|
-
const color = hr.getAttribute('data-divider-color') || ''
|
|
396
|
-
if (color && outputHrs[index]) {
|
|
397
|
-
outputHrs[index].setAttribute('style', 'border: none; border-top: 2px solid ' + color + '; margin: 10px 0;')
|
|
398
|
-
}
|
|
399
|
-
})
|
|
400
|
-
|
|
401
|
-
// 处理 table 元素 -- 查找新增的表格并添加默认样式
|
|
402
|
-
const tables = tempDiv.querySelectorAll('table:not([data-processed])');
|
|
403
|
-
tables.forEach(table => {
|
|
404
|
-
const currentStyle = table.getAttribute('style') || '';
|
|
405
|
-
const newStyle = `border-collapse: collapse;border-style: solid; border-color: rgb(204, 204, 204);border-width: 1;${currentStyle}`.trim();
|
|
406
|
-
table.setAttribute('class', 'wangeditor-styled-table');
|
|
407
|
-
table.setAttribute('style', newStyle);
|
|
408
|
-
|
|
409
|
-
// 处理表头
|
|
410
|
-
const thCells = table.querySelectorAll('th');
|
|
411
|
-
thCells.forEach(cell => {
|
|
412
|
-
const cellCurrentStyle = cell.getAttribute('style') || '';
|
|
413
|
-
const cellNewStyle = `background-color: rgb(245, 242, 240);border-style: solid; border-color: rgb(204, 204, 204);border-width: 1;padding: 3px 5px;${cellCurrentStyle}`.trim();
|
|
414
|
-
cell.setAttribute('style', cellNewStyle);
|
|
415
|
-
});
|
|
416
|
-
|
|
417
|
-
// 处理单元格
|
|
418
|
-
const tdCells = table.querySelectorAll('td');
|
|
419
|
-
tdCells.forEach(cell => {
|
|
420
|
-
const cellCurrentStyle = cell.getAttribute('style') || '';
|
|
421
|
-
const cellNewStyle = `border-style: solid; border-color: rgb(204, 204, 204);border-width: 1;padding: 3px 5px;${cellCurrentStyle}`.trim();
|
|
422
|
-
cell.setAttribute('style', cellNewStyle);
|
|
423
|
-
});
|
|
424
|
-
|
|
425
|
-
// 标记已处理
|
|
426
|
-
table.setAttribute('data-processed', 'true');
|
|
427
|
-
});
|
|
428
|
-
|
|
429
|
-
// 更新处理后的 HTML
|
|
430
|
-
html = tempDiv.innerHTML;
|
|
431
|
-
this.$emit('input', self.valueType === 'html' ? html : editor.getText())
|
|
297
|
+
let html = editor.getHtml()
|
|
298
|
+
this.$emit('input', this.valueType === 'html' ? html : editor.getText())
|
|
432
299
|
this.$emit('on-change', html, editor.getText())
|
|
433
300
|
},
|
|
434
|
-
customPaste(editor, event, callback) {
|
|
435
|
-
//console.log('ClipboardEvent 粘贴事件对象', event)
|
|
436
|
-
const html = event.clipboardData.getData('text/html') // 获取粘贴的 html
|
|
437
|
-
const text = event.clipboardData.getData('text/plain') // 获取粘贴的纯文本
|
|
438
|
-
const rtf = event.clipboardData.getData('text/rtf') // 获取 rtf 数据(如从 word wsp 复制粘贴)
|
|
439
|
-
|
|
440
|
-
//console.log("customPaste-html",rtf)
|
|
441
|
-
// 自定义插入内容
|
|
442
|
-
editor.setHtml(html)
|
|
443
|
-
|
|
444
|
-
// 返回 false ,阻止默认粘贴行为
|
|
445
|
-
event.preventDefault()
|
|
446
|
-
callback(false) // 返回值(注意,vue 事件的返回值,不能用 return)
|
|
447
|
-
|
|
448
|
-
// 返回 true ,继续默认的粘贴行为
|
|
449
|
-
// callback(true)
|
|
450
|
-
},
|
|
451
301
|
},
|
|
452
|
-
mounted() {
|
|
453
302
|
|
|
454
|
-
},
|
|
455
303
|
beforeDestroy() {
|
|
456
304
|
const editor = this.editor
|
|
457
305
|
if (editor == null) return
|