vue-editify 0.0.27 → 0.0.29

Sign up to get free protection for your applications and to get access to all the features.
package/src/core/index.js CHANGED
@@ -1,1263 +1,1263 @@
1
- import { AlexElement } from 'alex-editor'
2
- import { getHljsHtml, languages } from '../hljs'
3
- import Dap from 'dap-util'
4
-
5
- //粘贴html时保留的数据
6
- export const pasteKeepData = {
7
- //粘贴html时元素保留的样式(全部元素)
8
- marks: {
9
- 'data-editify-list': ['div'],
10
- 'data-editify-value': ['div'],
11
- 'data-editify-code': ['span'],
12
- 'data-editify-task': ['div'],
13
- contenteditable: '*',
14
- src: ['img', 'video'],
15
- autoplay: ['video'],
16
- loop: ['video'],
17
- muted: ['video'],
18
- href: ['a'],
19
- target: ['a'],
20
- alt: ['img'],
21
- controls: ['video'],
22
- name: '*',
23
- disabled: '*',
24
- colspan: ['td']
25
- },
26
- //粘贴html时非文本元素保留的样式
27
- styles: {
28
- 'text-indent': '*',
29
- 'text-align': '*'
30
- }
31
- }
32
-
33
- //编辑器props属性
34
- export const editorProps = {
35
- //编辑器内容
36
- modelValue: {
37
- type: String,
38
- default: '<p><br></p>'
39
- },
40
- //占位符
41
- placeholder: {
42
- type: String,
43
- default: ''
44
- },
45
- //是否自动获取焦点
46
- autofocus: {
47
- type: Boolean,
48
- default: false
49
- },
50
- //是否禁用编辑器
51
- disabled: {
52
- type: Boolean,
53
- default: false
54
- },
55
- //是否允许复制
56
- allowCopy: {
57
- type: Boolean,
58
- default: true
59
- },
60
- //是否允许粘贴
61
- allowPaste: {
62
- type: Boolean,
63
- default: true
64
- },
65
- //是否允许剪切
66
- allowCut: {
67
- type: Boolean,
68
- default: true
69
- },
70
- //是否允许粘贴html
71
- allowPasteHtml: {
72
- type: Boolean,
73
- default: false
74
- },
75
- //编辑内容高度
76
- height: {
77
- type: String,
78
- default: '600px'
79
- },
80
- //是否自适应高度
81
- autoheight: {
82
- type: Boolean,
83
- default: false
84
- },
85
- //是否显示边框
86
- border: {
87
- type: Boolean,
88
- default: false
89
- },
90
- //主题色
91
- color: {
92
- type: String,
93
- default: '#03a8f3',
94
- validator(value) {
95
- return Dap.common.matchingText(value, 'hex')
96
- }
97
- },
98
- //视频宽高比
99
- videoRatio: {
100
- type: Number,
101
- default: 16 / 9
102
- },
103
- //工具条按钮设置
104
- toolbar: {
105
- type: Object,
106
- default: null
107
- },
108
- //是否显示字数统计
109
- showWordLength: {
110
- type: Boolean,
111
- default: false
112
- },
113
- //自定义粘贴图片
114
- customImagePaste: {
115
- type: Function,
116
- default: null
117
- },
118
- //自定义粘贴视频
119
- customVideoPaste: {
120
- type: Function,
121
- default: null
122
- },
123
- //菜单栏配置
124
- menu: {
125
- type: Object,
126
- default: null
127
- }
128
- }
129
-
130
- //获取colgroup的col数量
131
- export const getColNumbers = row => {
132
- const children = row?.children || []
133
- let num = 0
134
- children.forEach(td => {
135
- if (td.hasMarks() && td.marks.hasOwnProperty('colspan')) {
136
- const span = Number(td.marks.colspan)
137
- if (!isNaN(span)) {
138
- num += span
139
- }
140
- } else {
141
- num += 1
142
- }
143
- })
144
- return num
145
- }
146
-
147
- //对象平替值方法
148
- export const mergeObject = (o1, o2) => {
149
- if (!Dap.common.isObject(o1) && Dap.common.isObject(o2)) {
150
- return null
151
- }
152
- for (let key in o2) {
153
- //如果o1和o2的相同属性都是对象并且不是数组,则继续merge
154
- if (Dap.common.isObject(o2[key]) && !Array.isArray(o2[key]) && Dap.common.isObject(o1[key]) && !Array.isArray(o1[key])) {
155
- o1[key] = mergeObject(o1[key], o2[key])
156
- }
157
- //否则直接将o2的值给o1
158
- else {
159
- o1[key] = o2[key]
160
- }
161
- }
162
- return o1
163
- }
164
-
165
- //判断是否列表
166
- export const blockIsList = (element, ordered = false) => {
167
- return element.type == 'block' && element.parsedom == 'div' && element.hasMarks() && element.marks['data-editify-list'] == (ordered ? 'ol' : 'ul')
168
- }
169
-
170
- //判断是否任务列表
171
- export const blockIsTask = element => {
172
- return element.type == 'block' && element.parsedom == 'div' && element.hasMarks() && element.marks.hasOwnProperty('data-editify-task')
173
- }
174
-
175
- //将某个块元素转为段落
176
- export const blockToParagraph = element => {
177
- element.marks = null
178
- element.styles = null
179
- element.parsedom = AlexElement.BLOCK_NODE
180
- }
181
-
182
- //其他元素转为列表
183
- export const blockToList = (element, ordered = false) => {
184
- //如果是列表则返回
185
- if (blockIsList(element, ordered)) {
186
- return
187
- }
188
- //先转为段落
189
- blockToParagraph(element)
190
- //然后转为列表
191
- element.parsedom = 'div'
192
- if (!element.hasMarks()) {
193
- element.marks = {}
194
- }
195
- element.marks['data-editify-list'] = ordered ? 'ol' : 'ul'
196
- }
197
-
198
- //其他元素转为任务列表
199
- export const blockToTask = element => {
200
- //如果是任务列表则返回
201
- if (blockIsTask(element)) {
202
- return
203
- }
204
- //先转为段落
205
- blockToParagraph(element)
206
- //然后转为任务列表
207
- element.parsedom = 'div'
208
- if (!element.hasMarks()) {
209
- element.marks = {}
210
- }
211
- element.marks['data-editify-task'] = 'uncheck'
212
- }
213
-
214
- //元素格式化时转换ol和li标签
215
- export const parseList = function (element) {
216
- //ol标签和ul标签转为div
217
- if (element.parsedom == 'ol' || element.parsedom == 'ul') {
218
- if (element.hasChildren()) {
219
- element.children.forEach((el, index) => {
220
- const newEl = el.clone()
221
- newEl.parsedom = 'div'
222
- newEl.type = 'block'
223
- if (!newEl.hasMarks()) {
224
- newEl.marks = {}
225
- }
226
- newEl.marks['data-editify-list'] = element.parsedom
227
- if (element.parsedom == 'ol') {
228
- newEl.marks['data-editify-value'] = index + 1
229
- }
230
- //插入到该元素之后
231
- this.addElementAfter(newEl, element)
232
- })
233
- }
234
- element.toEmpty()
235
- }
236
- //有序列表的序号处理
237
- if (element.type == 'block' && element.hasMarks() && element.marks['data-editify-list'] == 'ol') {
238
- //获取前一个元素
239
- const previousElement = this.getPreviousElement(element)
240
- //如果前一个元素存在并且也是有序列表
241
- if (previousElement && previousElement.hasMarks() && previousElement.marks['data-editify-list'] == 'ol') {
242
- const previousValue = Number(previousElement.marks['data-editify-value'])
243
- element.marks['data-editify-value'] = previousValue + 1
244
- }
245
- //前一个元素不是有序列表,则从0开始
246
- else {
247
- element.marks['data-editify-value'] = 1
248
- }
249
- }
250
- }
251
-
252
- //元素格式化时转换code标签
253
- export const parseCode = function (element) {
254
- if (element.parsedom == 'code') {
255
- element.parsedom = 'span'
256
- const marks = {
257
- 'data-editify-code': true
258
- }
259
- if (element.hasMarks()) {
260
- Object.assign(element.marks, marks)
261
- } else {
262
- element.marks = marks
263
- }
264
- }
265
- }
266
-
267
- //元素格式化时处理媒体元素和链接
268
- export const mediaHandle = function (element) {
269
- //图片、视频和链接设置marks
270
- if (element.parsedom == 'img' || element.parsedom == 'video' || element.parsedom == 'a') {
271
- const marks = {
272
- 'data-editify-element': element.key
273
- }
274
- if (element.hasMarks()) {
275
- Object.assign(element.marks, marks)
276
- } else {
277
- element.marks = marks
278
- }
279
- }
280
-
281
- //视频的特殊处理,两侧无元素时在两侧加上空白文本
282
- if (element.parsedom == 'video') {
283
- const previousElement = this.getPreviousElement(element)
284
- const newTextElement = this.getNextElement(element)
285
- //如果不存在前一个元素
286
- if (!previousElement || previousElement.isEmpty()) {
287
- const spaceText = AlexElement.getSpaceElement()
288
- this.addElementBefore(spaceText, element)
289
- }
290
- //如果不存在后一个元素
291
- if (!newTextElement || newTextElement.isEmpty()) {
292
- const spaceText = AlexElement.getSpaceElement()
293
- this.addElementAfter(spaceText, element)
294
- }
295
- }
296
- }
297
-
298
- //元素格式化时处理表格
299
- export const tableHandle = function (element) {
300
- if (element.parsedom == 'table') {
301
- const marks = {
302
- 'data-editify-element': element.key
303
- }
304
- if (element.hasMarks()) {
305
- Object.assign(element.marks, marks)
306
- } else {
307
- element.marks = marks
308
- }
309
- const elements = AlexElement.flatElements(element.children)
310
- const rows = elements.filter(el => {
311
- return el.parsedom == 'tr'
312
- })
313
- let colgroup = elements.find(el => {
314
- return el.parsedom == 'colgroup'
315
- })
316
- if (colgroup) {
317
- colgroup.children.forEach(col => {
318
- if (!col.hasMarks()) {
319
- col.marks = {
320
- width: 'auto'
321
- }
322
- } else if (!col.marks['width']) {
323
- col.marks['width'] = 'auto'
324
- }
325
- })
326
- } else {
327
- colgroup = new AlexElement('inblock', 'colgroup', null, null, null)
328
- const colNumber = getColNumbers(rows[0])
329
- for (let i = colNumber - 1; i >= 0; i--) {
330
- const col = new AlexElement(
331
- 'closed',
332
- 'col',
333
- {
334
- width: 'auto'
335
- },
336
- null,
337
- null
338
- )
339
- this.addElementTo(col, colgroup)
340
- }
341
- }
342
- element.children = []
343
- const tbody = new AlexElement('inblock', 'tbody', null, null, null)
344
- rows.reverse().forEach(row => {
345
- this.addElementTo(row, tbody)
346
- })
347
- this.addElementTo(tbody, element)
348
- this.addElementTo(colgroup, element)
349
- } else if (element.parsedom == 'th') {
350
- element.parsedom = 'td'
351
- }
352
- }
353
-
354
- //更新代码块内的光标位置
355
- const updateRangeInPre = function (element, originalTextElements, newElements) {
356
- if (!this.range) {
357
- return
358
- }
359
- //如果虚拟光标的起点在代码块内对虚拟光标的起点进行重新定位
360
- if (this.range.anchor.element.getBlock().isEqual(element)) {
361
- //获取起点所在文本元素的在所有文本元素中的序列
362
- const elIndex = originalTextElements.findIndex(el => this.range.anchor.element.isEqual(el))
363
- //起点在整个代码内容中的位置
364
- const offset = originalTextElements.filter((el, i) => i < elIndex).reduce((total, item, i) => total + item.textContent.length, 0) + this.range.anchor.offset
365
- //获取pre下新的子孙元素中全部的文本元素
366
- const newTextElements = AlexElement.flatElements(newElements).filter(el => el.isText() && !el.isEmpty())
367
- let i = 0
368
- let index = 0
369
- //遍历
370
- while (i < newTextElements.length) {
371
- let newIndex = index + newTextElements[i].textContent.length
372
- if (offset >= index && offset <= newIndex) {
373
- this.range.anchor.element = newTextElements[i]
374
- this.range.anchor.offset = offset - index
375
- break
376
- }
377
- i++
378
- index = newIndex
379
- }
380
- }
381
- //如果虚拟光标的终点在代码块内需要对虚拟光标的终点进行重新定位
382
- if (this.range.focus.element.getBlock().isEqual(element)) {
383
- //获取终点所在文本元素的在所有文本元素中的序列
384
- const elIndex = originalTextElements.findIndex(el => this.range.focus.element.isEqual(el))
385
- //终点在整个代码内容中的位置
386
- const offset = originalTextElements.filter((el, i) => i < elIndex).reduce((total, item, i) => total + item.textContent.length, 0) + this.range.focus.offset
387
- //获取全部的新文本元素
388
- const newTextElements = AlexElement.flatElements(newElements).filter(el => el.isText() && !el.isEmpty())
389
- let i = 0
390
- let index = 0
391
- //遍历
392
- while (i < newTextElements.length) {
393
- let newIndex = index + newTextElements[i].textContent.length
394
- if (offset >= index && offset <= newIndex) {
395
- this.range.focus.element = newTextElements[i]
396
- this.range.focus.offset = offset - index
397
- break
398
- }
399
- i++
400
- index = newIndex
401
- }
402
- }
403
- }
404
-
405
- //元素格式化时处理pre,将pre的内容根据语言进行样式处理
406
- export const preHandle = function (element, highlight, languages) {
407
- //如果是代码块进行处理
408
- if ((element.isBlock() || element.isInblock()) && element.isPreStyle()) {
409
- const marks = {
410
- 'data-editify-element': element.key
411
- }
412
- if (element.hasMarks()) {
413
- Object.assign(element.marks, marks)
414
- } else {
415
- element.marks = marks
416
- }
417
- //高亮处理
418
- if (highlight && element.hasChildren()) {
419
- //获取语言类型
420
- let language = element.marks['data-editify-hljs'] || ''
421
- if (language && languages && !languages.includes(language)) {
422
- language = ''
423
- }
424
- //获取pre标签下所有的文本元素
425
- const originalTextElements = AlexElement.flatElements(element.children).filter(el => el.isText() && !el.isEmpty())
426
- //获取pre下的代码文本值
427
- const textContent = originalTextElements.reduce((val, item) => {
428
- return val + item.textContent
429
- }, '')
430
- //将文本元素的内容转为经过hljs处理的内容
431
- const html = getHljsHtml(textContent, language)
432
- if (html) {
433
- //将经过hljs处理的内容转为元素数组
434
- const newElements = this.parseHtml(html)
435
- //处理光标位置
436
- updateRangeInPre.apply(this, [element, originalTextElements, newElements])
437
- //将新文本元素全部加入到pre子元素数组中
438
- element.children = newElements
439
- newElements.forEach(newEl => {
440
- newEl.parent = element
441
- })
442
- }
443
- }
444
- }
445
- }
446
-
447
- //获取菜单按钮列表数据配置
448
- export const getButtonOptionsConfig = function (editTrans, editLocale) {
449
- return {
450
- //标题配置
451
- heading: [
452
- {
453
- label: editTrans('text'),
454
- value: 'p'
455
- },
456
- {
457
- label: editTrans('h1'),
458
- value: 'h1',
459
- style: {
460
- fontSize: '26px',
461
- fontWeight: 'bold'
462
- }
463
- },
464
- {
465
- label: editTrans('h2'),
466
- value: 'h2',
467
- style: {
468
- fontSize: '24px',
469
- fontWeight: 'bold'
470
- }
471
- },
472
- {
473
- label: editTrans('h3'),
474
- value: 'h3',
475
- style: {
476
- fontSize: '22px',
477
- fontWeight: 'bold'
478
- }
479
- },
480
- {
481
- label: editTrans('h4'),
482
- value: 'h4',
483
- style: {
484
- fontSize: '20px',
485
- fontWeight: 'bold'
486
- }
487
- },
488
- {
489
- label: editTrans('h5'),
490
- value: 'h5',
491
- style: {
492
- fontSize: '18px',
493
- fontWeight: 'bold'
494
- }
495
- },
496
- {
497
- label: editTrans('h6'),
498
- value: 'h6',
499
- style: {
500
- fontSize: '16px',
501
- fontWeight: 'bold'
502
- }
503
- }
504
- ],
505
- //缩进配置
506
- indent: [
507
- {
508
- label: editTrans('indentIncrease'),
509
- value: 'indent-increase',
510
- icon: 'indent-increase'
511
- },
512
- {
513
- label: editTrans('indentDecrease'),
514
- value: 'indent-decrease',
515
- icon: 'indent-decrease'
516
- }
517
- ],
518
- //对齐方式
519
- align: [
520
- {
521
- label: editTrans('alignLeft'),
522
- value: 'left',
523
- icon: 'align-left'
524
- },
525
- {
526
- label: editTrans('alignRight'),
527
- value: 'right',
528
- icon: 'align-right'
529
- },
530
- {
531
- label: editTrans('alignCenter'),
532
- value: 'center',
533
- icon: 'align-center'
534
- },
535
- {
536
- label: editTrans('alignJustify'),
537
- value: 'justify',
538
- icon: 'align-justify'
539
- }
540
- ],
541
- //字号配置
542
- fontSize: [
543
- {
544
- label: editTrans('defaultSize'),
545
- value: ''
546
- },
547
- {
548
- label: '12px',
549
- value: '12px'
550
- },
551
- {
552
- label: '14px',
553
- value: '14px'
554
- },
555
- {
556
- label: '16px',
557
- value: '16px'
558
- },
559
- {
560
- label: '18px',
561
- value: '18px'
562
- },
563
- {
564
- label: '20px',
565
- value: '20px'
566
- },
567
- {
568
- label: '24px',
569
- value: '24px'
570
- },
571
- {
572
- label: '28px',
573
- value: '28px'
574
- },
575
- {
576
- label: '32px',
577
- value: '32px'
578
- },
579
- {
580
- label: '36px',
581
- value: '36px'
582
- },
583
- {
584
- label: '40px',
585
- value: '40px'
586
- }
587
- ],
588
- //字体配置
589
- fontFamily: [
590
- {
591
- label: editTrans('defaultFontFamily'),
592
- value: ''
593
- },
594
- {
595
- label: '黑体',
596
- value: '黑体,黑体-简'
597
- },
598
- {
599
- label: '华文仿宋',
600
- value: '华文仿宋'
601
- },
602
- {
603
- label: '楷体',
604
- value: '楷体,楷体-简'
605
- },
606
- {
607
- label: '华文楷体',
608
- value: '华文楷体'
609
- },
610
- {
611
- label: '宋体',
612
- value: '宋体,宋体-简'
613
- },
614
- {
615
- label: 'Arial',
616
- value: 'Arial'
617
- },
618
- {
619
- label: 'Consolas',
620
- value: 'Consolas,monospace'
621
- }
622
- ],
623
- //行高配置
624
- lineHeight: [
625
- {
626
- label: editTrans('defaultLineHeight'),
627
- value: ''
628
- },
629
- 1,
630
- 1.15,
631
- 1.5,
632
- 2,
633
- 2.5,
634
- 3
635
- ],
636
- //前景色配置
637
- foreColor: ['#000000', '#505050', '#808080', '#BBBBBB', '#CCCCCC', '#EEEEEE', '#F7F7F7', '#FFFFFF', '#EC1A0A', '#FF9900', '#FFFF00', '#07C160', '#00FFFF', '#0B73DE', '#9C00FF', '#FF00FF', '#F7C6CE', '#FFE7CE', '#FFEFC6', '#D6EFD6', '#CEDEE7', '#CEE7F7', '#D6D6E7', '#E7D6DE', '#E79C9C', '#FFC69C', '#FFE79C', '#B5D6A5', '#A5C6CE', '#9CC6EF', '#B5A5D6', '#D6A5BD', '#e45649', '#F7AD6B', '#FFD663', '#94BD7B', '#73A5AD', '#6BADDE', '#8C7BC6', '#C67BA5', '#CE0000', '#E79439', '#EFC631', '#50a14f', '#4A7B8C', '#03A8F3', '#634AA5', '#A54A7B', '#9C0000', '#B56308', '#BD9400', '#397B21', '#104A5A', '#085294', '#311873', '#731842', '#630000', '#7B3900', '#986801', '#295218', '#083139', '#003163', '#21104A', '#4A1031'],
638
- //背景色配置
639
- backColor: ['#000000', '#505050', '#808080', '#BBBBBB', '#CCCCCC', '#EEEEEE', '#F7F7F7', '#FFFFFF', '#EC1A0A', '#FF9900', '#FFFF00', '#07C160', '#00FFFF', '#0B73DE', '#9C00FF', '#FF00FF', '#F7C6CE', '#FFE7CE', '#FFEFC6', '#D6EFD6', '#CEDEE7', '#CEE7F7', '#D6D6E7', '#E7D6DE', '#E79C9C', '#FFC69C', '#FFE79C', '#B5D6A5', '#A5C6CE', '#9CC6EF', '#B5A5D6', '#D6A5BD', '#e45649', '#F7AD6B', '#FFD663', '#94BD7B', '#73A5AD', '#6BADDE', '#8C7BC6', '#C67BA5', '#CE0000', '#E79439', '#EFC631', '#50a14f', '#4A7B8C', '#03A8F3', '#634AA5', '#A54A7B', '#9C0000', '#B56308', '#BD9400', '#397B21', '#104A5A', '#085294', '#311873', '#731842', '#630000', '#7B3900', '#986801', '#295218', '#083139', '#003163', '#21104A', '#4A1031']
640
- }
641
- }
642
-
643
- //工具条全量配置
644
- export const getToolbarConfig = function (editTrans, editLocale) {
645
- return {
646
- //是否使用工具条
647
- use: true,
648
- // 工具条的样式设置
649
- style: null,
650
- // 是否使用工具提示
651
- tooltip: true,
652
- // 代码块工具条配置
653
- codeBlock: {
654
- //语言列表
655
- languages: {
656
- //是否显示此工具
657
- show: true,
658
- //列表配置
659
- options: [
660
- {
661
- label: editTrans('autoRecognize'),
662
- value: ''
663
- },
664
- ...languages
665
- ],
666
- //浮层宽度
667
- width: 100,
668
- //浮层最大高度
669
- maxHeight: 180,
670
- //左侧边框是否显示
671
- leftBorder: true,
672
- //右侧边框是否显示
673
- rightBorder: false
674
- }
675
- },
676
- //文本工具条配置
677
- text: {
678
- //标题
679
- heading: {
680
- //是否显示此工具
681
- show: true,
682
- //列表配置
683
- options: getButtonOptionsConfig(editTrans, editLocale).heading,
684
- //按钮默认显示的值
685
- defaultValue: 'p',
686
- //浮层宽度
687
- width: editLocale == 'en_US' ? 150 : 130,
688
- //浮层最大高度
689
- maxHeight: '',
690
- //左侧边框是否显示
691
- leftBorder: false,
692
- //右侧边框是否显示
693
- rightBorder: true
694
- },
695
- //对齐方式
696
- align: {
697
- //是否显示此工具
698
- show: false,
699
- //列表配置
700
- options: getButtonOptionsConfig(editTrans, editLocale).align,
701
- //浮层宽度
702
- width: editLocale == 'zh_CN' ? 100 : 130,
703
- //浮层最大高度
704
- maxHeight: '',
705
- //左侧边框是否显示
706
- leftBorder: false,
707
- //右侧边框是否显示
708
- rightBorder: false
709
- },
710
- //有序列表
711
- orderList: {
712
- //是否显示此工具
713
- show: false,
714
- //左侧边框是否显示
715
- leftBorder: false,
716
- //右侧边框是否显示
717
- rightBorder: false
718
- },
719
- //无序列表
720
- unorderList: {
721
- //是否显示此工具
722
- show: false,
723
- //左侧边框是否显示
724
- leftBorder: false,
725
- //右侧边框是否显示
726
- rightBorder: false
727
- },
728
- //任务列表
729
- task: {
730
- //是否显示此工具
731
- show: false,
732
- //左侧边框是否显示
733
- leftBorder: false,
734
- //右侧边框是否显示
735
- rightBorder: false
736
- },
737
- //粗体
738
- bold: {
739
- //是否显示此工具
740
- show: true,
741
- //左侧边框是否显示
742
- leftBorder: false,
743
- //右侧边框是否显示
744
- rightBorder: false
745
- },
746
- //斜体
747
- italic: {
748
- //是否显示此工具
749
- show: true,
750
- //左侧边框是否显示
751
- leftBorder: false,
752
- //右侧边框是否显示
753
- rightBorder: false
754
- },
755
- //删除线
756
- strikethrough: {
757
- //是否显示此工具
758
- show: true,
759
- //左侧边框是否显示
760
- leftBorder: false,
761
- //右侧边框是否显示
762
- rightBorder: false
763
- },
764
- //下划线
765
- underline: {
766
- //是否显示此工具
767
- show: false,
768
- //左侧边框是否显示
769
- leftBorder: false,
770
- //右侧边框是否显示
771
- rightBorder: false
772
- },
773
- //行内代码
774
- code: {
775
- //是否显示此工具
776
- show: true,
777
- //左侧边框是否显示
778
- leftBorder: false,
779
- //右侧边框是否显示
780
- rightBorder: false
781
- },
782
- //上标
783
- super: {
784
- //是否显示此工具
785
- show: false,
786
- //左侧边框是否显示
787
- leftBorder: false,
788
- //右侧边框是否显示
789
- rightBorder: false
790
- },
791
- //下标
792
- sub: {
793
- //是否显示此工具
794
- show: false,
795
- //左侧边框是否显示
796
- leftBorder: false,
797
- //右侧边框是否显示
798
- rightBorder: false
799
- },
800
- //字号
801
- fontSize: {
802
- //是否显示此工具
803
- show: true,
804
- //列表配置
805
- options: getButtonOptionsConfig(editTrans, editLocale).fontSize,
806
- //按钮默认显示的值
807
- defaultValue: '',
808
- //浮层宽度
809
- width: 90,
810
- //浮层最大高度
811
- maxHeight: 200,
812
- //左侧边框是否显示
813
- leftBorder: true,
814
- //右侧边框是否显示
815
- rightBorder: false
816
- },
817
- //字体
818
- fontFamily: {
819
- //是否显示此工具
820
- show: false,
821
- //列表配置
822
- options: getButtonOptionsConfig(editTrans, editLocale).fontFamily,
823
- //按钮默认显示的值
824
- defaultValue: '',
825
- //浮层宽度
826
- width: 100,
827
- //浮层最大高度
828
- maxHeight: 200,
829
- //左侧边框是否显示
830
- leftBorder: false,
831
- //右侧边框是否显示
832
- rightBorder: false
833
- },
834
- //行高
835
- lineHeight: {
836
- //是否显示此工具
837
- show: false,
838
- //列表配置
839
- options: getButtonOptionsConfig(editTrans, editLocale).lineHeight,
840
- //按钮默认显示的值
841
- defaultValue: '',
842
- //浮层宽度
843
- width: 90,
844
- //浮层最大高度
845
- maxHeight: '',
846
- //左侧边框是否显示
847
- leftBorder: false,
848
- //右侧边框是否显示
849
- rightBorder: false
850
- },
851
- //前景色
852
- foreColor: {
853
- //是否显示此工具
854
- show: true,
855
- //列表配置
856
- options: getButtonOptionsConfig(editTrans, editLocale).foreColor,
857
- //左侧边框是否显示
858
- leftBorder: false,
859
- //右侧边框是否显示
860
- rightBorder: false
861
- },
862
- //背景色
863
- backColor: {
864
- //是否显示此工具
865
- show: true,
866
- //列表配置
867
- options: getButtonOptionsConfig(editTrans, editLocale).backColor,
868
- //左侧边框是否显示
869
- leftBorder: false,
870
- //右侧边框是否显示
871
- rightBorder: false
872
- },
873
- //清除格式
874
- formatClear: {
875
- //是否显示此工具
876
- show: true,
877
- //左侧边框是否显示
878
- leftBorder: true,
879
- //右侧边框是否显示
880
- rightBorder: false
881
- }
882
- },
883
- //(只对文本工具条中的按钮生效)添加额外的按钮禁用判定,回调参数为name,this指向组件实例
884
- extraDisabled: null
885
- }
886
- }
887
-
888
- //菜单栏全量配置
889
- export const getMenuConfig = function (editTrans, editLocale) {
890
- return {
891
- //是否使用菜单栏
892
- use: true,
893
- //是否使用工具提示
894
- tooltip: true,
895
- //菜单栏显示模式,支持default/inner/fixed
896
- mode: 'default',
897
- //添加额外的按钮禁用判定,回调参数为name,this指向组件实例
898
- extraDisabled: null,
899
- //菜单栏的样式自定义
900
- style: null,
901
- //菜单排序
902
- sequence: {
903
- undo: 0,
904
- redo: 1,
905
- heading: 2,
906
- indent: 3,
907
- quote: 4,
908
- align: 5,
909
- orderList: 6,
910
- unorderList: 7,
911
- task: 8,
912
- bold: 9,
913
- underline: 10,
914
- italic: 11,
915
- strikethrough: 12,
916
- code: 13,
917
- super: 14,
918
- sub: 15,
919
- formatClear: 16,
920
- fontSize: 17,
921
- fontFamily: 18,
922
- lineHeight: 19,
923
- foreColor: 20,
924
- backColor: 21,
925
- link: 22,
926
- image: 23,
927
- video: 24,
928
- table: 25,
929
- codeBlock: 26,
930
- sourceView: 27
931
- },
932
- //撤销按钮配置
933
- undo: {
934
- //是否显示此按钮
935
- show: true,
936
- //左侧边框是否显示
937
- leftBorder: false,
938
- //右侧边框是否显示
939
- rightBorder: false
940
- },
941
- //重做按钮配置
942
- redo: {
943
- //是否显示此按钮
944
- show: true,
945
- //左侧边框是否显示
946
- leftBorder: false,
947
- //右侧边框是否显示
948
- rightBorder: false
949
- },
950
- //标题
951
- heading: {
952
- //是否显示此按钮
953
- show: true,
954
- //列表配置
955
- options: getButtonOptionsConfig(editTrans, editLocale).heading,
956
- //按钮默认显示的值
957
- defaultValue: 'p',
958
- //浮层宽度
959
- width: editLocale == 'en_US' ? 150 : 130,
960
- //浮层最大高度
961
- maxHeight: '',
962
- //左侧边框是否显示
963
- leftBorder: true,
964
- //右侧边框是否显示
965
- rightBorder: false
966
- },
967
- //缩进
968
- indent: {
969
- //是否显示此工具
970
- show: true,
971
- //列表配置
972
- options: getButtonOptionsConfig(editTrans, editLocale).indent,
973
- //浮层宽度
974
- width: editLocale == 'en_US' ? 150 : 110,
975
- //浮层最大高度
976
- maxHeight: '',
977
- //左侧边框是否显示
978
- leftBorder: false,
979
- //右侧边框是否显示
980
- rightBorder: false
981
- },
982
- //引用按钮配置
983
- quote: {
984
- //是否显示此按钮
985
- show: true,
986
- //左侧边框是否显示
987
- leftBorder: false,
988
- //右侧边框是否显示
989
- rightBorder: false
990
- },
991
- //对齐方式
992
- align: {
993
- //是否显示此工具
994
- show: true,
995
- //列表配置
996
- options: getButtonOptionsConfig(editTrans, editLocale).align,
997
- //浮层宽度
998
- width: editLocale == 'zh_CN' ? 100 : 130,
999
- //浮层最大高度
1000
- maxHeight: '',
1001
- //左侧边框是否显示
1002
- leftBorder: true,
1003
- //右侧边框是否显示
1004
- rightBorder: false
1005
- },
1006
- //有序列表按钮配置
1007
- orderList: {
1008
- //是否显示此按钮
1009
- show: true,
1010
- //左侧边框是否显示
1011
- leftBorder: false,
1012
- //右侧边框是否显示
1013
- rightBorder: false
1014
- },
1015
- //无序列表按钮配置
1016
- unorderList: {
1017
- //是否显示此按钮
1018
- show: true,
1019
- //左侧边框是否显示
1020
- leftBorder: false,
1021
- //右侧边框是否显示
1022
- rightBorder: false
1023
- },
1024
- //任务列表按钮配置
1025
- task: {
1026
- //是否显示此按钮
1027
- show: true,
1028
- //左侧边框是否显示
1029
- leftBorder: false,
1030
- //右侧边框是否显示
1031
- rightBorder: false
1032
- },
1033
- //粗体按钮配置
1034
- bold: {
1035
- //是否显示此按钮
1036
- show: true,
1037
- //左侧边框是否显示
1038
- leftBorder: true,
1039
- //右侧边框是否显示
1040
- rightBorder: false
1041
- },
1042
- //下划线按钮配置
1043
- underline: {
1044
- //是否显示此按钮
1045
- show: true,
1046
- //左侧边框是否显示
1047
- leftBorder: false,
1048
- //右侧边框是否显示
1049
- rightBorder: false
1050
- },
1051
- //斜体按钮配置
1052
- italic: {
1053
- //是否显示此按钮
1054
- show: true,
1055
- //左侧边框是否显示
1056
- leftBorder: false,
1057
- //右侧边框是否显示
1058
- rightBorder: false
1059
- },
1060
- //删除线按钮配置
1061
- strikethrough: {
1062
- //是否显示此按钮
1063
- show: true,
1064
- //左侧边框是否显示
1065
- leftBorder: false,
1066
- //右侧边框是否显示
1067
- rightBorder: false
1068
- },
1069
- //行内代码按钮配置
1070
- code: {
1071
- //是否显示此按钮
1072
- show: true,
1073
- //左侧边框是否显示
1074
- leftBorder: false,
1075
- //右侧边框是否显示
1076
- rightBorder: false
1077
- },
1078
- //上标
1079
- super: {
1080
- //是否显示此工具
1081
- show: true,
1082
- //左侧边框是否显示
1083
- leftBorder: false,
1084
- //右侧边框是否显示
1085
- rightBorder: false
1086
- },
1087
- //下标
1088
- sub: {
1089
- //是否显示此工具
1090
- show: true,
1091
- //左侧边框是否显示
1092
- leftBorder: false,
1093
- //右侧边框是否显示
1094
- rightBorder: false
1095
- },
1096
- //清除格式
1097
- formatClear: {
1098
- //是否显示此工具
1099
- show: true,
1100
- //左侧边框是否显示
1101
- leftBorder: false,
1102
- //右侧边框是否显示
1103
- rightBorder: false
1104
- },
1105
- //字号
1106
- fontSize: {
1107
- //是否显示此工具
1108
- show: true,
1109
- //列表配置
1110
- options: getButtonOptionsConfig(editTrans, editLocale).fontSize,
1111
- //按钮默认显示的值
1112
- defaultValue: '',
1113
- //浮层宽度
1114
- width: 90,
1115
- //浮层最大高度
1116
- maxHeight: 200,
1117
- //左侧边框是否显示
1118
- leftBorder: true,
1119
- //右侧边框是否显示
1120
- rightBorder: false
1121
- },
1122
- //字体
1123
- fontFamily: {
1124
- //是否显示此工具
1125
- show: true,
1126
- //列表配置
1127
- options: getButtonOptionsConfig(editTrans, editLocale).fontFamily,
1128
- //按钮默认显示的值
1129
- defaultValue: '',
1130
- //浮层宽度
1131
- width: 100,
1132
- //浮层最大高度
1133
- maxHeight: 200,
1134
- //左侧边框是否显示
1135
- leftBorder: false,
1136
- //右侧边框是否显示
1137
- rightBorder: false
1138
- },
1139
- //行高
1140
- lineHeight: {
1141
- //是否显示此工具
1142
- show: true,
1143
- //列表配置
1144
- options: getButtonOptionsConfig(editTrans, editLocale).lineHeight,
1145
- //按钮默认显示的值
1146
- defaultValue: '',
1147
- //浮层宽度
1148
- width: 90,
1149
- //浮层最大高度
1150
- maxHeight: '',
1151
- //左侧边框是否显示
1152
- leftBorder: false,
1153
- //右侧边框是否显示
1154
- rightBorder: false
1155
- },
1156
- //前景色
1157
- foreColor: {
1158
- //是否显示此工具
1159
- show: true,
1160
- //列表配置
1161
- options: getButtonOptionsConfig(editTrans, editLocale).foreColor,
1162
- //左侧边框是否显示
1163
- leftBorder: true,
1164
- //右侧边框是否显示
1165
- rightBorder: false
1166
- },
1167
- //背景色
1168
- backColor: {
1169
- //是否显示此工具
1170
- show: true,
1171
- //列表配置
1172
- options: getButtonOptionsConfig(editTrans, editLocale).backColor,
1173
- //左侧边框是否显示
1174
- leftBorder: false,
1175
- //右侧边框是否显示
1176
- rightBorder: false
1177
- },
1178
- //链接
1179
- link: {
1180
- //是否显示此工具
1181
- show: true,
1182
- //左侧边框是否显示
1183
- leftBorder: true,
1184
- //右侧边框是否显示
1185
- rightBorder: false
1186
- },
1187
- //图片
1188
- image: {
1189
- //是否显示此工具
1190
- show: true,
1191
- //左侧边框是否显示
1192
- leftBorder: false,
1193
- //右侧边框是否显示
1194
- rightBorder: false,
1195
- //图片支持上传的类型,不区分大小写
1196
- accept: ['jpg', 'png', 'jpeg', 'webp', 'jfif', 'ico', 'gif', 'svg', 'psd'],
1197
- //是否多选图片
1198
- multiple: false,
1199
- //单张图片的最大值,单位kb
1200
- maxSize: null,
1201
- //单张图片的最小值,单位kb
1202
- minSize: null,
1203
- //自定义上传图片
1204
- customUpload: null,
1205
- //异常处理函数
1206
- handleError: null
1207
- },
1208
- //视频
1209
- video: {
1210
- //是否显示此工具
1211
- show: true,
1212
- //左侧边框是否显示
1213
- leftBorder: false,
1214
- //右侧边框是否显示
1215
- rightBorder: false,
1216
- //视频支持上传的类型,不区分大小写
1217
- accept: ['mp4', 'avi', 'mpg', 'wmv', 'mov', 'rm', 'swf', 'flv'],
1218
- //是否多选视频
1219
- multiple: false,
1220
- //单个视频的的最大值,单位kb
1221
- maxSize: null,
1222
- //单个视频的最小值,单位kb
1223
- minSize: null,
1224
- //自定义上传视频
1225
- customUpload: null,
1226
- //异常处理函数
1227
- handleError: null
1228
- },
1229
- //表格
1230
- table: {
1231
- //是否显示此工具
1232
- show: true,
1233
- //左侧边框是否显示
1234
- leftBorder: false,
1235
- //右侧边框是否显示
1236
- rightBorder: false,
1237
- //创建时表格的最大行数
1238
- maxRows: 10,
1239
- //创建时表格的最大列数
1240
- maxColumns: 10
1241
- },
1242
- //代码块
1243
- codeBlock: {
1244
- //是否显示此工具
1245
- show: true,
1246
- //左侧边框是否显示
1247
- leftBorder: false,
1248
- //右侧边框是否显示
1249
- rightBorder: false
1250
- },
1251
- //代码视图
1252
- sourceView: {
1253
- //是否显示此工具
1254
- show: false,
1255
- //左侧边框是否显示
1256
- leftBorder: false,
1257
- //右侧边框是否显示
1258
- rightBorder: false
1259
- },
1260
- //拓展菜单,每个key表示拓展菜单的唯一名称,value是对象,包含type/title/rightBorder/leftBorder/disabled/active/width/maxHeight/options/value/hideScroll/onLayerShow/onLayerShown/onLayerHidden/onOperate/default/layer/option属性
1261
- extends: {}
1262
- }
1263
- }
1
+ import { AlexElement } from 'alex-editor'
2
+ import { getHljsHtml, languages } from '../hljs'
3
+ import Dap from 'dap-util'
4
+
5
+ //粘贴html时保留的数据
6
+ export const pasteKeepData = {
7
+ //粘贴html时元素保留的样式(全部元素)
8
+ marks: {
9
+ 'data-editify-list': ['div'],
10
+ 'data-editify-value': ['div'],
11
+ 'data-editify-code': ['span'],
12
+ 'data-editify-task': ['div'],
13
+ contenteditable: '*',
14
+ src: ['img', 'video'],
15
+ autoplay: ['video'],
16
+ loop: ['video'],
17
+ muted: ['video'],
18
+ href: ['a'],
19
+ target: ['a'],
20
+ alt: ['img'],
21
+ controls: ['video'],
22
+ name: '*',
23
+ disabled: '*',
24
+ colspan: ['td']
25
+ },
26
+ //粘贴html时非文本元素保留的样式
27
+ styles: {
28
+ 'text-indent': '*',
29
+ 'text-align': '*'
30
+ }
31
+ }
32
+
33
+ //编辑器props属性
34
+ export const editorProps = {
35
+ //编辑器内容
36
+ modelValue: {
37
+ type: String,
38
+ default: '<p><br></p>'
39
+ },
40
+ //占位符
41
+ placeholder: {
42
+ type: String,
43
+ default: ''
44
+ },
45
+ //是否自动获取焦点
46
+ autofocus: {
47
+ type: Boolean,
48
+ default: false
49
+ },
50
+ //是否禁用编辑器
51
+ disabled: {
52
+ type: Boolean,
53
+ default: false
54
+ },
55
+ //是否允许复制
56
+ allowCopy: {
57
+ type: Boolean,
58
+ default: true
59
+ },
60
+ //是否允许粘贴
61
+ allowPaste: {
62
+ type: Boolean,
63
+ default: true
64
+ },
65
+ //是否允许剪切
66
+ allowCut: {
67
+ type: Boolean,
68
+ default: true
69
+ },
70
+ //是否允许粘贴html
71
+ allowPasteHtml: {
72
+ type: Boolean,
73
+ default: false
74
+ },
75
+ //编辑内容高度
76
+ height: {
77
+ type: String,
78
+ default: '600px'
79
+ },
80
+ //是否自适应高度
81
+ autoheight: {
82
+ type: Boolean,
83
+ default: false
84
+ },
85
+ //是否显示边框
86
+ border: {
87
+ type: Boolean,
88
+ default: false
89
+ },
90
+ //主题色
91
+ color: {
92
+ type: String,
93
+ default: '#03a8f3',
94
+ validator(value) {
95
+ return Dap.common.matchingText(value, 'hex')
96
+ }
97
+ },
98
+ //视频宽高比
99
+ videoRatio: {
100
+ type: Number,
101
+ default: 16 / 9
102
+ },
103
+ //工具条按钮设置
104
+ toolbar: {
105
+ type: Object,
106
+ default: null
107
+ },
108
+ //是否显示字数统计
109
+ showWordLength: {
110
+ type: Boolean,
111
+ default: false
112
+ },
113
+ //自定义粘贴图片
114
+ customImagePaste: {
115
+ type: Function,
116
+ default: null
117
+ },
118
+ //自定义粘贴视频
119
+ customVideoPaste: {
120
+ type: Function,
121
+ default: null
122
+ },
123
+ //菜单栏配置
124
+ menu: {
125
+ type: Object,
126
+ default: null
127
+ }
128
+ }
129
+
130
+ //获取colgroup的col数量
131
+ export const getColNumbers = row => {
132
+ const children = row?.children || []
133
+ let num = 0
134
+ children.forEach(td => {
135
+ if (td.hasMarks() && td.marks.hasOwnProperty('colspan')) {
136
+ const span = Number(td.marks.colspan)
137
+ if (!isNaN(span)) {
138
+ num += span
139
+ }
140
+ } else {
141
+ num += 1
142
+ }
143
+ })
144
+ return num
145
+ }
146
+
147
+ //对象平替值方法
148
+ export const mergeObject = (o1, o2) => {
149
+ if (!Dap.common.isObject(o1) && Dap.common.isObject(o2)) {
150
+ return null
151
+ }
152
+ for (let key in o2) {
153
+ //如果o1和o2的相同属性都是对象并且不是数组,则继续merge
154
+ if (Dap.common.isObject(o2[key]) && !Array.isArray(o2[key]) && Dap.common.isObject(o1[key]) && !Array.isArray(o1[key])) {
155
+ o1[key] = mergeObject(o1[key], o2[key])
156
+ }
157
+ //否则直接将o2的值给o1
158
+ else {
159
+ o1[key] = o2[key]
160
+ }
161
+ }
162
+ return o1
163
+ }
164
+
165
+ //判断是否列表
166
+ export const blockIsList = (element, ordered = false) => {
167
+ return element.type == 'block' && element.parsedom == 'div' && element.hasMarks() && element.marks['data-editify-list'] == (ordered ? 'ol' : 'ul')
168
+ }
169
+
170
+ //判断是否任务列表
171
+ export const blockIsTask = element => {
172
+ return element.type == 'block' && element.parsedom == 'div' && element.hasMarks() && element.marks.hasOwnProperty('data-editify-task')
173
+ }
174
+
175
+ //将某个块元素转为段落
176
+ export const blockToParagraph = element => {
177
+ element.marks = null
178
+ element.styles = null
179
+ element.parsedom = AlexElement.BLOCK_NODE
180
+ }
181
+
182
+ //其他元素转为列表
183
+ export const blockToList = (element, ordered = false) => {
184
+ //如果是列表则返回
185
+ if (blockIsList(element, ordered)) {
186
+ return
187
+ }
188
+ //先转为段落
189
+ blockToParagraph(element)
190
+ //然后转为列表
191
+ element.parsedom = 'div'
192
+ if (!element.hasMarks()) {
193
+ element.marks = {}
194
+ }
195
+ element.marks['data-editify-list'] = ordered ? 'ol' : 'ul'
196
+ }
197
+
198
+ //其他元素转为任务列表
199
+ export const blockToTask = element => {
200
+ //如果是任务列表则返回
201
+ if (blockIsTask(element)) {
202
+ return
203
+ }
204
+ //先转为段落
205
+ blockToParagraph(element)
206
+ //然后转为任务列表
207
+ element.parsedom = 'div'
208
+ if (!element.hasMarks()) {
209
+ element.marks = {}
210
+ }
211
+ element.marks['data-editify-task'] = 'uncheck'
212
+ }
213
+
214
+ //元素格式化时转换ol和li标签
215
+ export const parseList = function (element) {
216
+ //ol标签和ul标签转为div
217
+ if (element.parsedom == 'ol' || element.parsedom == 'ul') {
218
+ if (element.hasChildren()) {
219
+ element.children.forEach((el, index) => {
220
+ const newEl = el.clone()
221
+ newEl.parsedom = 'div'
222
+ newEl.type = 'block'
223
+ if (!newEl.hasMarks()) {
224
+ newEl.marks = {}
225
+ }
226
+ newEl.marks['data-editify-list'] = element.parsedom
227
+ if (element.parsedom == 'ol') {
228
+ newEl.marks['data-editify-value'] = index + 1
229
+ }
230
+ //插入到该元素之后
231
+ this.addElementAfter(newEl, element)
232
+ })
233
+ }
234
+ element.toEmpty()
235
+ }
236
+ //有序列表的序号处理
237
+ if (element.type == 'block' && element.hasMarks() && element.marks['data-editify-list'] == 'ol') {
238
+ //获取前一个元素
239
+ const previousElement = this.getPreviousElement(element)
240
+ //如果前一个元素存在并且也是有序列表
241
+ if (previousElement && previousElement.hasMarks() && previousElement.marks['data-editify-list'] == 'ol') {
242
+ const previousValue = Number(previousElement.marks['data-editify-value'])
243
+ element.marks['data-editify-value'] = previousValue + 1
244
+ }
245
+ //前一个元素不是有序列表,则从0开始
246
+ else {
247
+ element.marks['data-editify-value'] = 1
248
+ }
249
+ }
250
+ }
251
+
252
+ //元素格式化时转换code标签
253
+ export const parseCode = function (element) {
254
+ if (element.parsedom == 'code') {
255
+ element.parsedom = 'span'
256
+ const marks = {
257
+ 'data-editify-code': true
258
+ }
259
+ if (element.hasMarks()) {
260
+ Object.assign(element.marks, marks)
261
+ } else {
262
+ element.marks = marks
263
+ }
264
+ }
265
+ }
266
+
267
+ //元素格式化时处理媒体元素和链接
268
+ export const mediaHandle = function (element) {
269
+ //图片、视频和链接设置marks
270
+ if (element.parsedom == 'img' || element.parsedom == 'video' || element.parsedom == 'a') {
271
+ const marks = {
272
+ 'data-editify-element': element.key
273
+ }
274
+ if (element.hasMarks()) {
275
+ Object.assign(element.marks, marks)
276
+ } else {
277
+ element.marks = marks
278
+ }
279
+ }
280
+
281
+ //视频的特殊处理,两侧无元素时在两侧加上空白文本
282
+ if (element.parsedom == 'video') {
283
+ const previousElement = this.getPreviousElement(element)
284
+ const newTextElement = this.getNextElement(element)
285
+ //如果不存在前一个元素
286
+ if (!previousElement || previousElement.isEmpty()) {
287
+ const spaceText = AlexElement.getSpaceElement()
288
+ this.addElementBefore(spaceText, element)
289
+ }
290
+ //如果不存在后一个元素
291
+ if (!newTextElement || newTextElement.isEmpty()) {
292
+ const spaceText = AlexElement.getSpaceElement()
293
+ this.addElementAfter(spaceText, element)
294
+ }
295
+ }
296
+ }
297
+
298
+ //元素格式化时处理表格
299
+ export const tableHandle = function (element) {
300
+ if (element.parsedom == 'table') {
301
+ const marks = {
302
+ 'data-editify-element': element.key
303
+ }
304
+ if (element.hasMarks()) {
305
+ Object.assign(element.marks, marks)
306
+ } else {
307
+ element.marks = marks
308
+ }
309
+ const elements = AlexElement.flatElements(element.children)
310
+ const rows = elements.filter(el => {
311
+ return el.parsedom == 'tr'
312
+ })
313
+ let colgroup = elements.find(el => {
314
+ return el.parsedom == 'colgroup'
315
+ })
316
+ if (colgroup) {
317
+ colgroup.children.forEach(col => {
318
+ if (!col.hasMarks()) {
319
+ col.marks = {
320
+ width: 'auto'
321
+ }
322
+ } else if (!col.marks['width']) {
323
+ col.marks['width'] = 'auto'
324
+ }
325
+ })
326
+ } else {
327
+ colgroup = new AlexElement('inblock', 'colgroup', null, null, null)
328
+ const colNumber = getColNumbers(rows[0])
329
+ for (let i = colNumber - 1; i >= 0; i--) {
330
+ const col = new AlexElement(
331
+ 'closed',
332
+ 'col',
333
+ {
334
+ width: 'auto'
335
+ },
336
+ null,
337
+ null
338
+ )
339
+ this.addElementTo(col, colgroup)
340
+ }
341
+ }
342
+ element.children = []
343
+ const tbody = new AlexElement('inblock', 'tbody', null, null, null)
344
+ rows.reverse().forEach(row => {
345
+ this.addElementTo(row, tbody)
346
+ })
347
+ this.addElementTo(tbody, element)
348
+ this.addElementTo(colgroup, element)
349
+ } else if (element.parsedom == 'th') {
350
+ element.parsedom = 'td'
351
+ }
352
+ }
353
+
354
+ //更新代码块内的光标位置
355
+ const updateRangeInPre = function (element, originalTextElements, newElements) {
356
+ if (!this.range) {
357
+ return
358
+ }
359
+ //如果虚拟光标的起点在代码块内对虚拟光标的起点进行重新定位
360
+ if (this.range.anchor.element.getBlock().isEqual(element)) {
361
+ //获取起点所在文本元素的在所有文本元素中的序列
362
+ const elIndex = originalTextElements.findIndex(el => this.range.anchor.element.isEqual(el))
363
+ //起点在整个代码内容中的位置
364
+ const offset = originalTextElements.filter((el, i) => i < elIndex).reduce((total, item, i) => total + item.textContent.length, 0) + this.range.anchor.offset
365
+ //获取pre下新的子孙元素中全部的文本元素
366
+ const newTextElements = AlexElement.flatElements(newElements).filter(el => el.isText() && !el.isEmpty())
367
+ let i = 0
368
+ let index = 0
369
+ //遍历
370
+ while (i < newTextElements.length) {
371
+ let newIndex = index + newTextElements[i].textContent.length
372
+ if (offset >= index && offset <= newIndex) {
373
+ this.range.anchor.element = newTextElements[i]
374
+ this.range.anchor.offset = offset - index
375
+ break
376
+ }
377
+ i++
378
+ index = newIndex
379
+ }
380
+ }
381
+ //如果虚拟光标的终点在代码块内需要对虚拟光标的终点进行重新定位
382
+ if (this.range.focus.element.getBlock().isEqual(element)) {
383
+ //获取终点所在文本元素的在所有文本元素中的序列
384
+ const elIndex = originalTextElements.findIndex(el => this.range.focus.element.isEqual(el))
385
+ //终点在整个代码内容中的位置
386
+ const offset = originalTextElements.filter((el, i) => i < elIndex).reduce((total, item, i) => total + item.textContent.length, 0) + this.range.focus.offset
387
+ //获取全部的新文本元素
388
+ const newTextElements = AlexElement.flatElements(newElements).filter(el => el.isText() && !el.isEmpty())
389
+ let i = 0
390
+ let index = 0
391
+ //遍历
392
+ while (i < newTextElements.length) {
393
+ let newIndex = index + newTextElements[i].textContent.length
394
+ if (offset >= index && offset <= newIndex) {
395
+ this.range.focus.element = newTextElements[i]
396
+ this.range.focus.offset = offset - index
397
+ break
398
+ }
399
+ i++
400
+ index = newIndex
401
+ }
402
+ }
403
+ }
404
+
405
+ //元素格式化时处理pre,将pre的内容根据语言进行样式处理
406
+ export const preHandle = function (element, highlight, languages) {
407
+ //如果是代码块进行处理
408
+ if ((element.isBlock() || element.isInblock()) && element.isPreStyle()) {
409
+ const marks = {
410
+ 'data-editify-element': element.key
411
+ }
412
+ if (element.hasMarks()) {
413
+ Object.assign(element.marks, marks)
414
+ } else {
415
+ element.marks = marks
416
+ }
417
+ //高亮处理
418
+ if (highlight && element.hasChildren()) {
419
+ //获取语言类型
420
+ let language = element.marks['data-editify-hljs'] || ''
421
+ if (language && languages && !languages.includes(language)) {
422
+ language = ''
423
+ }
424
+ //获取pre标签下所有的文本元素
425
+ const originalTextElements = AlexElement.flatElements(element.children).filter(el => el.isText() && !el.isEmpty())
426
+ //获取pre下的代码文本值
427
+ const textContent = originalTextElements.reduce((val, item) => {
428
+ return val + item.textContent
429
+ }, '')
430
+ //将文本元素的内容转为经过hljs处理的内容
431
+ const html = getHljsHtml(textContent, language)
432
+ if (html) {
433
+ //将经过hljs处理的内容转为元素数组
434
+ const newElements = this.parseHtml(html)
435
+ //处理光标位置
436
+ updateRangeInPre.apply(this, [element, originalTextElements, newElements])
437
+ //将新文本元素全部加入到pre子元素数组中
438
+ element.children = newElements
439
+ newElements.forEach(newEl => {
440
+ newEl.parent = element
441
+ })
442
+ }
443
+ }
444
+ }
445
+ }
446
+
447
+ //获取菜单按钮列表数据配置
448
+ export const getButtonOptionsConfig = function (editTrans, editLocale) {
449
+ return {
450
+ //标题配置
451
+ heading: [
452
+ {
453
+ label: editTrans('text'),
454
+ value: 'p'
455
+ },
456
+ {
457
+ label: editTrans('h1'),
458
+ value: 'h1',
459
+ style: {
460
+ fontSize: '26px',
461
+ fontWeight: 'bold'
462
+ }
463
+ },
464
+ {
465
+ label: editTrans('h2'),
466
+ value: 'h2',
467
+ style: {
468
+ fontSize: '24px',
469
+ fontWeight: 'bold'
470
+ }
471
+ },
472
+ {
473
+ label: editTrans('h3'),
474
+ value: 'h3',
475
+ style: {
476
+ fontSize: '22px',
477
+ fontWeight: 'bold'
478
+ }
479
+ },
480
+ {
481
+ label: editTrans('h4'),
482
+ value: 'h4',
483
+ style: {
484
+ fontSize: '20px',
485
+ fontWeight: 'bold'
486
+ }
487
+ },
488
+ {
489
+ label: editTrans('h5'),
490
+ value: 'h5',
491
+ style: {
492
+ fontSize: '18px',
493
+ fontWeight: 'bold'
494
+ }
495
+ },
496
+ {
497
+ label: editTrans('h6'),
498
+ value: 'h6',
499
+ style: {
500
+ fontSize: '16px',
501
+ fontWeight: 'bold'
502
+ }
503
+ }
504
+ ],
505
+ //缩进配置
506
+ indent: [
507
+ {
508
+ label: editTrans('indentIncrease'),
509
+ value: 'indent-increase',
510
+ icon: 'indent-increase'
511
+ },
512
+ {
513
+ label: editTrans('indentDecrease'),
514
+ value: 'indent-decrease',
515
+ icon: 'indent-decrease'
516
+ }
517
+ ],
518
+ //对齐方式
519
+ align: [
520
+ {
521
+ label: editTrans('alignLeft'),
522
+ value: 'left',
523
+ icon: 'align-left'
524
+ },
525
+ {
526
+ label: editTrans('alignRight'),
527
+ value: 'right',
528
+ icon: 'align-right'
529
+ },
530
+ {
531
+ label: editTrans('alignCenter'),
532
+ value: 'center',
533
+ icon: 'align-center'
534
+ },
535
+ {
536
+ label: editTrans('alignJustify'),
537
+ value: 'justify',
538
+ icon: 'align-justify'
539
+ }
540
+ ],
541
+ //字号配置
542
+ fontSize: [
543
+ {
544
+ label: editTrans('defaultSize'),
545
+ value: ''
546
+ },
547
+ {
548
+ label: '12px',
549
+ value: '12px'
550
+ },
551
+ {
552
+ label: '14px',
553
+ value: '14px'
554
+ },
555
+ {
556
+ label: '16px',
557
+ value: '16px'
558
+ },
559
+ {
560
+ label: '18px',
561
+ value: '18px'
562
+ },
563
+ {
564
+ label: '20px',
565
+ value: '20px'
566
+ },
567
+ {
568
+ label: '24px',
569
+ value: '24px'
570
+ },
571
+ {
572
+ label: '28px',
573
+ value: '28px'
574
+ },
575
+ {
576
+ label: '32px',
577
+ value: '32px'
578
+ },
579
+ {
580
+ label: '36px',
581
+ value: '36px'
582
+ },
583
+ {
584
+ label: '40px',
585
+ value: '40px'
586
+ }
587
+ ],
588
+ //字体配置
589
+ fontFamily: [
590
+ {
591
+ label: editTrans('defaultFontFamily'),
592
+ value: ''
593
+ },
594
+ {
595
+ label: '黑体',
596
+ value: '黑体,黑体-简'
597
+ },
598
+ {
599
+ label: '华文仿宋',
600
+ value: '华文仿宋'
601
+ },
602
+ {
603
+ label: '楷体',
604
+ value: '楷体,楷体-简'
605
+ },
606
+ {
607
+ label: '华文楷体',
608
+ value: '华文楷体'
609
+ },
610
+ {
611
+ label: '宋体',
612
+ value: '宋体,宋体-简'
613
+ },
614
+ {
615
+ label: 'Arial',
616
+ value: 'Arial'
617
+ },
618
+ {
619
+ label: 'Consolas',
620
+ value: 'Consolas,monospace'
621
+ }
622
+ ],
623
+ //行高配置
624
+ lineHeight: [
625
+ {
626
+ label: editTrans('defaultLineHeight'),
627
+ value: ''
628
+ },
629
+ 1,
630
+ 1.15,
631
+ 1.5,
632
+ 2,
633
+ 2.5,
634
+ 3
635
+ ],
636
+ //前景色配置
637
+ foreColor: ['#000000', '#505050', '#808080', '#BBBBBB', '#CCCCCC', '#EEEEEE', '#F7F7F7', '#FFFFFF', '#EC1A0A', '#FF9900', '#FFFF00', '#07C160', '#00FFFF', '#0B73DE', '#9C00FF', '#FF00FF', '#F7C6CE', '#FFE7CE', '#FFEFC6', '#D6EFD6', '#CEDEE7', '#CEE7F7', '#D6D6E7', '#E7D6DE', '#E79C9C', '#FFC69C', '#FFE79C', '#B5D6A5', '#A5C6CE', '#9CC6EF', '#B5A5D6', '#D6A5BD', '#e45649', '#F7AD6B', '#FFD663', '#94BD7B', '#73A5AD', '#6BADDE', '#8C7BC6', '#C67BA5', '#CE0000', '#E79439', '#EFC631', '#50a14f', '#4A7B8C', '#03A8F3', '#634AA5', '#A54A7B', '#9C0000', '#B56308', '#BD9400', '#397B21', '#104A5A', '#085294', '#311873', '#731842', '#630000', '#7B3900', '#986801', '#295218', '#083139', '#003163', '#21104A', '#4A1031'],
638
+ //背景色配置
639
+ backColor: ['#000000', '#505050', '#808080', '#BBBBBB', '#CCCCCC', '#EEEEEE', '#F7F7F7', '#FFFFFF', '#EC1A0A', '#FF9900', '#FFFF00', '#07C160', '#00FFFF', '#0B73DE', '#9C00FF', '#FF00FF', '#F7C6CE', '#FFE7CE', '#FFEFC6', '#D6EFD6', '#CEDEE7', '#CEE7F7', '#D6D6E7', '#E7D6DE', '#E79C9C', '#FFC69C', '#FFE79C', '#B5D6A5', '#A5C6CE', '#9CC6EF', '#B5A5D6', '#D6A5BD', '#e45649', '#F7AD6B', '#FFD663', '#94BD7B', '#73A5AD', '#6BADDE', '#8C7BC6', '#C67BA5', '#CE0000', '#E79439', '#EFC631', '#50a14f', '#4A7B8C', '#03A8F3', '#634AA5', '#A54A7B', '#9C0000', '#B56308', '#BD9400', '#397B21', '#104A5A', '#085294', '#311873', '#731842', '#630000', '#7B3900', '#986801', '#295218', '#083139', '#003163', '#21104A', '#4A1031']
640
+ }
641
+ }
642
+
643
+ //工具条全量配置
644
+ export const getToolbarConfig = function (editTrans, editLocale) {
645
+ return {
646
+ //是否使用工具条
647
+ use: true,
648
+ // 工具条的样式设置
649
+ style: null,
650
+ // 是否使用工具提示
651
+ tooltip: true,
652
+ // 代码块工具条配置
653
+ codeBlock: {
654
+ //语言列表
655
+ languages: {
656
+ //是否显示此工具
657
+ show: true,
658
+ //列表配置
659
+ options: [
660
+ {
661
+ label: editTrans('autoRecognize'),
662
+ value: ''
663
+ },
664
+ ...languages
665
+ ],
666
+ //浮层宽度
667
+ width: 100,
668
+ //浮层最大高度
669
+ maxHeight: 180,
670
+ //左侧边框是否显示
671
+ leftBorder: true,
672
+ //右侧边框是否显示
673
+ rightBorder: false
674
+ }
675
+ },
676
+ //文本工具条配置
677
+ text: {
678
+ //标题
679
+ heading: {
680
+ //是否显示此工具
681
+ show: true,
682
+ //列表配置
683
+ options: getButtonOptionsConfig(editTrans, editLocale).heading,
684
+ //按钮默认显示的值
685
+ defaultValue: 'p',
686
+ //浮层宽度
687
+ width: editLocale == 'en_US' ? 150 : 130,
688
+ //浮层最大高度
689
+ maxHeight: '',
690
+ //左侧边框是否显示
691
+ leftBorder: false,
692
+ //右侧边框是否显示
693
+ rightBorder: true
694
+ },
695
+ //对齐方式
696
+ align: {
697
+ //是否显示此工具
698
+ show: false,
699
+ //列表配置
700
+ options: getButtonOptionsConfig(editTrans, editLocale).align,
701
+ //浮层宽度
702
+ width: editLocale == 'zh_CN' ? 100 : 130,
703
+ //浮层最大高度
704
+ maxHeight: '',
705
+ //左侧边框是否显示
706
+ leftBorder: false,
707
+ //右侧边框是否显示
708
+ rightBorder: false
709
+ },
710
+ //有序列表
711
+ orderList: {
712
+ //是否显示此工具
713
+ show: false,
714
+ //左侧边框是否显示
715
+ leftBorder: false,
716
+ //右侧边框是否显示
717
+ rightBorder: false
718
+ },
719
+ //无序列表
720
+ unorderList: {
721
+ //是否显示此工具
722
+ show: false,
723
+ //左侧边框是否显示
724
+ leftBorder: false,
725
+ //右侧边框是否显示
726
+ rightBorder: false
727
+ },
728
+ //任务列表
729
+ task: {
730
+ //是否显示此工具
731
+ show: false,
732
+ //左侧边框是否显示
733
+ leftBorder: false,
734
+ //右侧边框是否显示
735
+ rightBorder: false
736
+ },
737
+ //粗体
738
+ bold: {
739
+ //是否显示此工具
740
+ show: true,
741
+ //左侧边框是否显示
742
+ leftBorder: false,
743
+ //右侧边框是否显示
744
+ rightBorder: false
745
+ },
746
+ //斜体
747
+ italic: {
748
+ //是否显示此工具
749
+ show: true,
750
+ //左侧边框是否显示
751
+ leftBorder: false,
752
+ //右侧边框是否显示
753
+ rightBorder: false
754
+ },
755
+ //删除线
756
+ strikethrough: {
757
+ //是否显示此工具
758
+ show: true,
759
+ //左侧边框是否显示
760
+ leftBorder: false,
761
+ //右侧边框是否显示
762
+ rightBorder: false
763
+ },
764
+ //下划线
765
+ underline: {
766
+ //是否显示此工具
767
+ show: false,
768
+ //左侧边框是否显示
769
+ leftBorder: false,
770
+ //右侧边框是否显示
771
+ rightBorder: false
772
+ },
773
+ //行内代码
774
+ code: {
775
+ //是否显示此工具
776
+ show: true,
777
+ //左侧边框是否显示
778
+ leftBorder: false,
779
+ //右侧边框是否显示
780
+ rightBorder: false
781
+ },
782
+ //上标
783
+ super: {
784
+ //是否显示此工具
785
+ show: false,
786
+ //左侧边框是否显示
787
+ leftBorder: false,
788
+ //右侧边框是否显示
789
+ rightBorder: false
790
+ },
791
+ //下标
792
+ sub: {
793
+ //是否显示此工具
794
+ show: false,
795
+ //左侧边框是否显示
796
+ leftBorder: false,
797
+ //右侧边框是否显示
798
+ rightBorder: false
799
+ },
800
+ //字号
801
+ fontSize: {
802
+ //是否显示此工具
803
+ show: true,
804
+ //列表配置
805
+ options: getButtonOptionsConfig(editTrans, editLocale).fontSize,
806
+ //按钮默认显示的值
807
+ defaultValue: '',
808
+ //浮层宽度
809
+ width: 90,
810
+ //浮层最大高度
811
+ maxHeight: 200,
812
+ //左侧边框是否显示
813
+ leftBorder: true,
814
+ //右侧边框是否显示
815
+ rightBorder: false
816
+ },
817
+ //字体
818
+ fontFamily: {
819
+ //是否显示此工具
820
+ show: false,
821
+ //列表配置
822
+ options: getButtonOptionsConfig(editTrans, editLocale).fontFamily,
823
+ //按钮默认显示的值
824
+ defaultValue: '',
825
+ //浮层宽度
826
+ width: 100,
827
+ //浮层最大高度
828
+ maxHeight: 200,
829
+ //左侧边框是否显示
830
+ leftBorder: false,
831
+ //右侧边框是否显示
832
+ rightBorder: false
833
+ },
834
+ //行高
835
+ lineHeight: {
836
+ //是否显示此工具
837
+ show: false,
838
+ //列表配置
839
+ options: getButtonOptionsConfig(editTrans, editLocale).lineHeight,
840
+ //按钮默认显示的值
841
+ defaultValue: '',
842
+ //浮层宽度
843
+ width: 90,
844
+ //浮层最大高度
845
+ maxHeight: '',
846
+ //左侧边框是否显示
847
+ leftBorder: false,
848
+ //右侧边框是否显示
849
+ rightBorder: false
850
+ },
851
+ //前景色
852
+ foreColor: {
853
+ //是否显示此工具
854
+ show: true,
855
+ //列表配置
856
+ options: getButtonOptionsConfig(editTrans, editLocale).foreColor,
857
+ //左侧边框是否显示
858
+ leftBorder: false,
859
+ //右侧边框是否显示
860
+ rightBorder: false
861
+ },
862
+ //背景色
863
+ backColor: {
864
+ //是否显示此工具
865
+ show: true,
866
+ //列表配置
867
+ options: getButtonOptionsConfig(editTrans, editLocale).backColor,
868
+ //左侧边框是否显示
869
+ leftBorder: false,
870
+ //右侧边框是否显示
871
+ rightBorder: false
872
+ },
873
+ //清除格式
874
+ formatClear: {
875
+ //是否显示此工具
876
+ show: true,
877
+ //左侧边框是否显示
878
+ leftBorder: true,
879
+ //右侧边框是否显示
880
+ rightBorder: false
881
+ }
882
+ },
883
+ //(只对文本工具条中的按钮生效)添加额外的按钮禁用判定,回调参数为name,this指向组件实例
884
+ extraDisabled: null
885
+ }
886
+ }
887
+
888
+ //菜单栏全量配置
889
+ export const getMenuConfig = function (editTrans, editLocale) {
890
+ return {
891
+ //是否使用菜单栏
892
+ use: true,
893
+ //是否使用工具提示
894
+ tooltip: true,
895
+ //菜单栏显示模式,支持default/inner/fixed
896
+ mode: 'default',
897
+ //添加额外的按钮禁用判定,回调参数为name,this指向组件实例
898
+ extraDisabled: null,
899
+ //菜单栏的样式自定义
900
+ style: null,
901
+ //菜单排序
902
+ sequence: {
903
+ undo: 0,
904
+ redo: 1,
905
+ heading: 2,
906
+ indent: 3,
907
+ quote: 4,
908
+ align: 5,
909
+ orderList: 6,
910
+ unorderList: 7,
911
+ task: 8,
912
+ bold: 9,
913
+ underline: 10,
914
+ italic: 11,
915
+ strikethrough: 12,
916
+ code: 13,
917
+ super: 14,
918
+ sub: 15,
919
+ formatClear: 16,
920
+ fontSize: 17,
921
+ fontFamily: 18,
922
+ lineHeight: 19,
923
+ foreColor: 20,
924
+ backColor: 21,
925
+ link: 22,
926
+ image: 23,
927
+ video: 24,
928
+ table: 25,
929
+ codeBlock: 26,
930
+ sourceView: 27
931
+ },
932
+ //撤销按钮配置
933
+ undo: {
934
+ //是否显示此按钮
935
+ show: true,
936
+ //左侧边框是否显示
937
+ leftBorder: false,
938
+ //右侧边框是否显示
939
+ rightBorder: false
940
+ },
941
+ //重做按钮配置
942
+ redo: {
943
+ //是否显示此按钮
944
+ show: true,
945
+ //左侧边框是否显示
946
+ leftBorder: false,
947
+ //右侧边框是否显示
948
+ rightBorder: false
949
+ },
950
+ //标题
951
+ heading: {
952
+ //是否显示此按钮
953
+ show: true,
954
+ //列表配置
955
+ options: getButtonOptionsConfig(editTrans, editLocale).heading,
956
+ //按钮默认显示的值
957
+ defaultValue: 'p',
958
+ //浮层宽度
959
+ width: editLocale == 'en_US' ? 150 : 130,
960
+ //浮层最大高度
961
+ maxHeight: '',
962
+ //左侧边框是否显示
963
+ leftBorder: true,
964
+ //右侧边框是否显示
965
+ rightBorder: false
966
+ },
967
+ //缩进
968
+ indent: {
969
+ //是否显示此工具
970
+ show: true,
971
+ //列表配置
972
+ options: getButtonOptionsConfig(editTrans, editLocale).indent,
973
+ //浮层宽度
974
+ width: editLocale == 'en_US' ? 150 : 110,
975
+ //浮层最大高度
976
+ maxHeight: '',
977
+ //左侧边框是否显示
978
+ leftBorder: false,
979
+ //右侧边框是否显示
980
+ rightBorder: false
981
+ },
982
+ //引用按钮配置
983
+ quote: {
984
+ //是否显示此按钮
985
+ show: true,
986
+ //左侧边框是否显示
987
+ leftBorder: false,
988
+ //右侧边框是否显示
989
+ rightBorder: false
990
+ },
991
+ //对齐方式
992
+ align: {
993
+ //是否显示此工具
994
+ show: true,
995
+ //列表配置
996
+ options: getButtonOptionsConfig(editTrans, editLocale).align,
997
+ //浮层宽度
998
+ width: editLocale == 'zh_CN' ? 100 : 130,
999
+ //浮层最大高度
1000
+ maxHeight: '',
1001
+ //左侧边框是否显示
1002
+ leftBorder: true,
1003
+ //右侧边框是否显示
1004
+ rightBorder: false
1005
+ },
1006
+ //有序列表按钮配置
1007
+ orderList: {
1008
+ //是否显示此按钮
1009
+ show: true,
1010
+ //左侧边框是否显示
1011
+ leftBorder: false,
1012
+ //右侧边框是否显示
1013
+ rightBorder: false
1014
+ },
1015
+ //无序列表按钮配置
1016
+ unorderList: {
1017
+ //是否显示此按钮
1018
+ show: true,
1019
+ //左侧边框是否显示
1020
+ leftBorder: false,
1021
+ //右侧边框是否显示
1022
+ rightBorder: false
1023
+ },
1024
+ //任务列表按钮配置
1025
+ task: {
1026
+ //是否显示此按钮
1027
+ show: true,
1028
+ //左侧边框是否显示
1029
+ leftBorder: false,
1030
+ //右侧边框是否显示
1031
+ rightBorder: false
1032
+ },
1033
+ //粗体按钮配置
1034
+ bold: {
1035
+ //是否显示此按钮
1036
+ show: true,
1037
+ //左侧边框是否显示
1038
+ leftBorder: true,
1039
+ //右侧边框是否显示
1040
+ rightBorder: false
1041
+ },
1042
+ //下划线按钮配置
1043
+ underline: {
1044
+ //是否显示此按钮
1045
+ show: true,
1046
+ //左侧边框是否显示
1047
+ leftBorder: false,
1048
+ //右侧边框是否显示
1049
+ rightBorder: false
1050
+ },
1051
+ //斜体按钮配置
1052
+ italic: {
1053
+ //是否显示此按钮
1054
+ show: true,
1055
+ //左侧边框是否显示
1056
+ leftBorder: false,
1057
+ //右侧边框是否显示
1058
+ rightBorder: false
1059
+ },
1060
+ //删除线按钮配置
1061
+ strikethrough: {
1062
+ //是否显示此按钮
1063
+ show: true,
1064
+ //左侧边框是否显示
1065
+ leftBorder: false,
1066
+ //右侧边框是否显示
1067
+ rightBorder: false
1068
+ },
1069
+ //行内代码按钮配置
1070
+ code: {
1071
+ //是否显示此按钮
1072
+ show: true,
1073
+ //左侧边框是否显示
1074
+ leftBorder: false,
1075
+ //右侧边框是否显示
1076
+ rightBorder: false
1077
+ },
1078
+ //上标
1079
+ super: {
1080
+ //是否显示此工具
1081
+ show: true,
1082
+ //左侧边框是否显示
1083
+ leftBorder: false,
1084
+ //右侧边框是否显示
1085
+ rightBorder: false
1086
+ },
1087
+ //下标
1088
+ sub: {
1089
+ //是否显示此工具
1090
+ show: true,
1091
+ //左侧边框是否显示
1092
+ leftBorder: false,
1093
+ //右侧边框是否显示
1094
+ rightBorder: false
1095
+ },
1096
+ //清除格式
1097
+ formatClear: {
1098
+ //是否显示此工具
1099
+ show: true,
1100
+ //左侧边框是否显示
1101
+ leftBorder: false,
1102
+ //右侧边框是否显示
1103
+ rightBorder: false
1104
+ },
1105
+ //字号
1106
+ fontSize: {
1107
+ //是否显示此工具
1108
+ show: true,
1109
+ //列表配置
1110
+ options: getButtonOptionsConfig(editTrans, editLocale).fontSize,
1111
+ //按钮默认显示的值
1112
+ defaultValue: '',
1113
+ //浮层宽度
1114
+ width: 90,
1115
+ //浮层最大高度
1116
+ maxHeight: 200,
1117
+ //左侧边框是否显示
1118
+ leftBorder: true,
1119
+ //右侧边框是否显示
1120
+ rightBorder: false
1121
+ },
1122
+ //字体
1123
+ fontFamily: {
1124
+ //是否显示此工具
1125
+ show: true,
1126
+ //列表配置
1127
+ options: getButtonOptionsConfig(editTrans, editLocale).fontFamily,
1128
+ //按钮默认显示的值
1129
+ defaultValue: '',
1130
+ //浮层宽度
1131
+ width: 100,
1132
+ //浮层最大高度
1133
+ maxHeight: 200,
1134
+ //左侧边框是否显示
1135
+ leftBorder: false,
1136
+ //右侧边框是否显示
1137
+ rightBorder: false
1138
+ },
1139
+ //行高
1140
+ lineHeight: {
1141
+ //是否显示此工具
1142
+ show: true,
1143
+ //列表配置
1144
+ options: getButtonOptionsConfig(editTrans, editLocale).lineHeight,
1145
+ //按钮默认显示的值
1146
+ defaultValue: '',
1147
+ //浮层宽度
1148
+ width: 90,
1149
+ //浮层最大高度
1150
+ maxHeight: '',
1151
+ //左侧边框是否显示
1152
+ leftBorder: false,
1153
+ //右侧边框是否显示
1154
+ rightBorder: false
1155
+ },
1156
+ //前景色
1157
+ foreColor: {
1158
+ //是否显示此工具
1159
+ show: true,
1160
+ //列表配置
1161
+ options: getButtonOptionsConfig(editTrans, editLocale).foreColor,
1162
+ //左侧边框是否显示
1163
+ leftBorder: true,
1164
+ //右侧边框是否显示
1165
+ rightBorder: false
1166
+ },
1167
+ //背景色
1168
+ backColor: {
1169
+ //是否显示此工具
1170
+ show: true,
1171
+ //列表配置
1172
+ options: getButtonOptionsConfig(editTrans, editLocale).backColor,
1173
+ //左侧边框是否显示
1174
+ leftBorder: false,
1175
+ //右侧边框是否显示
1176
+ rightBorder: false
1177
+ },
1178
+ //链接
1179
+ link: {
1180
+ //是否显示此工具
1181
+ show: true,
1182
+ //左侧边框是否显示
1183
+ leftBorder: true,
1184
+ //右侧边框是否显示
1185
+ rightBorder: false
1186
+ },
1187
+ //图片
1188
+ image: {
1189
+ //是否显示此工具
1190
+ show: true,
1191
+ //左侧边框是否显示
1192
+ leftBorder: false,
1193
+ //右侧边框是否显示
1194
+ rightBorder: false,
1195
+ //图片支持上传的类型,不区分大小写
1196
+ accept: ['jpg', 'png', 'jpeg', 'webp', 'jfif', 'ico', 'gif', 'svg', 'psd'],
1197
+ //是否多选图片
1198
+ multiple: false,
1199
+ //单张图片的最大值,单位kb
1200
+ maxSize: null,
1201
+ //单张图片的最小值,单位kb
1202
+ minSize: null,
1203
+ //自定义上传图片
1204
+ customUpload: null,
1205
+ //异常处理函数
1206
+ handleError: null
1207
+ },
1208
+ //视频
1209
+ video: {
1210
+ //是否显示此工具
1211
+ show: true,
1212
+ //左侧边框是否显示
1213
+ leftBorder: false,
1214
+ //右侧边框是否显示
1215
+ rightBorder: false,
1216
+ //视频支持上传的类型,不区分大小写
1217
+ accept: ['mp4', 'avi', 'mpg', 'wmv', 'mov', 'rm', 'swf', 'flv'],
1218
+ //是否多选视频
1219
+ multiple: false,
1220
+ //单个视频的的最大值,单位kb
1221
+ maxSize: null,
1222
+ //单个视频的最小值,单位kb
1223
+ minSize: null,
1224
+ //自定义上传视频
1225
+ customUpload: null,
1226
+ //异常处理函数
1227
+ handleError: null
1228
+ },
1229
+ //表格
1230
+ table: {
1231
+ //是否显示此工具
1232
+ show: true,
1233
+ //左侧边框是否显示
1234
+ leftBorder: false,
1235
+ //右侧边框是否显示
1236
+ rightBorder: false,
1237
+ //创建时表格的最大行数
1238
+ maxRows: 10,
1239
+ //创建时表格的最大列数
1240
+ maxColumns: 10
1241
+ },
1242
+ //代码块
1243
+ codeBlock: {
1244
+ //是否显示此工具
1245
+ show: true,
1246
+ //左侧边框是否显示
1247
+ leftBorder: false,
1248
+ //右侧边框是否显示
1249
+ rightBorder: false
1250
+ },
1251
+ //代码视图
1252
+ sourceView: {
1253
+ //是否显示此工具
1254
+ show: false,
1255
+ //左侧边框是否显示
1256
+ leftBorder: false,
1257
+ //右侧边框是否显示
1258
+ rightBorder: false
1259
+ },
1260
+ //拓展菜单,每个key表示拓展菜单的唯一名称,value是对象,包含type/title/rightBorder/leftBorder/disabled/active/width/maxHeight/options/value/hideScroll/onLayerShow/onLayerShown/onLayerHidden/onOperate/default/layer/option属性
1261
+ extends: {}
1262
+ }
1263
+ }