vue-editify 0.1.42 → 0.1.44
Sign up to get free protection for your applications and to get access to all the features.
- package/examples/App.vue +57 -3
- package/lib/core/function.d.ts +83 -43
- package/lib/core/rule.d.ts +14 -2
- package/lib/editify/editify.vue.d.ts +1 -1
- package/lib/editify.es.js +872 -173
- package/lib/editify.umd.js +1 -1
- package/lib/index.d.ts +3 -3
- package/lib/style.css +1 -1
- package/package.json +2 -2
- package/src/components/toolbar/toolbar.vue +539 -50
- package/src/core/function.ts +220 -44
- package/src/core/rule.ts +281 -42
- package/src/core/tool.ts +6 -6
- package/src/editify/editify.less +4 -0
- package/src/editify/editify.vue +20 -2
- package/src/icon/iconfont.css +16 -0
- package/src/icon/iconfont.ttf +0 -0
- package/src/icon/iconfont.woff +0 -0
- package/src/index.ts +3 -3
- package/src/locale/en_US.ts +4 -0
- package/src/locale/zh_CN.ts +4 -0
package/src/core/rule.ts
CHANGED
@@ -1,8 +1,175 @@
|
|
1
1
|
import { AlexEditor, AlexElement } from 'alex-editor'
|
2
2
|
import { LanguagesItemType, getHljsHtml } from '../hljs'
|
3
|
-
import { isList, isTask } from './function'
|
3
|
+
import { isList, isTask, getTableSize, getCellSpanNumber } from './function'
|
4
4
|
import { common as DapCommon } from 'dap-util'
|
5
5
|
|
6
|
+
/**
|
7
|
+
* 自动补全表格行和列
|
8
|
+
* @param editor
|
9
|
+
* @param rowElements
|
10
|
+
* @param rowNumber
|
11
|
+
* @param columnNumber
|
12
|
+
*/
|
13
|
+
const autocompleteTableCells = (editor: AlexEditor, rowElements: AlexElement[], rowNumber: number, columnNumber: number) => {
|
14
|
+
//遍历所有的单元格
|
15
|
+
AlexElement.flatElements(rowElements).forEach(item => {
|
16
|
+
if (item.parsedom == 'td' && item.hasMarks()) {
|
17
|
+
//删除被合并的标识
|
18
|
+
if (item.marks!['data-editify-merged']) {
|
19
|
+
delete item.marks!['data-editify-merged']
|
20
|
+
}
|
21
|
+
//获取colspan
|
22
|
+
const colspan = isNaN(Number(item.marks!['colspan'])) ? 1 : Number(item.marks!['colspan'])
|
23
|
+
//获取rowspan
|
24
|
+
const rowspan = isNaN(Number(item.marks!['rowspan'])) ? 1 : Number(item.marks!['rowspan'])
|
25
|
+
//针对colspan>1的单元格在后面补全隐藏的单元格
|
26
|
+
if (colspan > 1) {
|
27
|
+
let i = 1
|
28
|
+
//补全的数量小于需要补全的数量并且列总数量小于理论数量
|
29
|
+
while (i < colspan && item.parent!.children!.length < columnNumber) {
|
30
|
+
const column = new AlexElement(
|
31
|
+
'inblock',
|
32
|
+
'td',
|
33
|
+
{
|
34
|
+
'data-editify-merged': 'true'
|
35
|
+
},
|
36
|
+
null,
|
37
|
+
null
|
38
|
+
)
|
39
|
+
const breakElement = new AlexElement('closed', 'br', null, null, null)
|
40
|
+
editor.addElementTo(breakElement, column)
|
41
|
+
editor.addElementAfter(column, item)
|
42
|
+
i++
|
43
|
+
}
|
44
|
+
}
|
45
|
+
//针对rowspan>1的单元格在后面的行中对应位置补全隐藏的单元格
|
46
|
+
if (rowspan > 1) {
|
47
|
+
let el = item
|
48
|
+
let i = 1
|
49
|
+
while (i < rowspan && editor.getNextElement(el.parent!) && editor.getNextElement(el.parent!)!.children!.length < columnNumber) {
|
50
|
+
//下一行
|
51
|
+
const nextRow = editor.getNextElement(el.parent!)!
|
52
|
+
//单元格在行中的序列
|
53
|
+
const index = el.parent!.children!.findIndex(item => item.isEqual(el))
|
54
|
+
//下一行对应的单元格
|
55
|
+
const nextCell = nextRow.children![index]
|
56
|
+
//根据当前单元格的跨列数补充符合跨列数的隐藏单元格
|
57
|
+
for (let j = 0; j < colspan; j++) {
|
58
|
+
const column = new AlexElement(
|
59
|
+
'inblock',
|
60
|
+
'td',
|
61
|
+
{
|
62
|
+
'data-editify-merged': 'true'
|
63
|
+
},
|
64
|
+
null,
|
65
|
+
null
|
66
|
+
)
|
67
|
+
const breakElement = new AlexElement('closed', 'br', null, null, null)
|
68
|
+
editor.addElementTo(breakElement, column)
|
69
|
+
if (nextCell) {
|
70
|
+
editor.addElementBefore(column, nextCell)
|
71
|
+
} else {
|
72
|
+
editor.addElementTo(column, nextRow, nextRow.children!.length)
|
73
|
+
}
|
74
|
+
}
|
75
|
+
el = nextRow.children![index]
|
76
|
+
i++
|
77
|
+
}
|
78
|
+
}
|
79
|
+
}
|
80
|
+
})
|
81
|
+
//遍历每一行,如果还缺少列则在后面补全列
|
82
|
+
rowElements.forEach(rowElement => {
|
83
|
+
//遍历该行的单元格获取总列数
|
84
|
+
const number = rowElement.children!.length
|
85
|
+
if (number < columnNumber) {
|
86
|
+
for (let i = 0; i < columnNumber - number; i++) {
|
87
|
+
const column = new AlexElement('inblock', 'td', null, null, null)
|
88
|
+
const breakElement = new AlexElement('closed', 'br', null, null, null)
|
89
|
+
editor.addElementTo(breakElement, column)
|
90
|
+
editor.addElementTo(column, rowElement, rowElement.children!.length)
|
91
|
+
}
|
92
|
+
}
|
93
|
+
})
|
94
|
+
//获取总行数
|
95
|
+
const length = rowElements.length
|
96
|
+
//判断总行数是否小于实际行数则补全行
|
97
|
+
if (length < rowNumber) {
|
98
|
+
for (let i = 0; i < rowNumber - length; i++) {
|
99
|
+
const row = new AlexElement('inblock', 'tr', null, null, null)
|
100
|
+
for (let j = 0; j < columnNumber; j++) {
|
101
|
+
const column = new AlexElement('inblock', 'td', null, null, null)
|
102
|
+
const breakElement = new AlexElement('closed', 'br', null, null, null)
|
103
|
+
editor.addElementTo(breakElement, column)
|
104
|
+
editor.addElementTo(column, row)
|
105
|
+
}
|
106
|
+
rowElements.push(row)
|
107
|
+
}
|
108
|
+
}
|
109
|
+
}
|
110
|
+
|
111
|
+
/**
|
112
|
+
* 自动隐藏被合并的单元格
|
113
|
+
* @param editor
|
114
|
+
* @param rowElements
|
115
|
+
*/
|
116
|
+
const autoHideMergedTableCells = (editor: AlexEditor, rowElements: AlexElement[]) => {
|
117
|
+
const cells = AlexElement.flatElements(rowElements).filter(item => item.parsedom == 'td')
|
118
|
+
cells.forEach(cell => {
|
119
|
+
if (cell.hasMarks() && !cell.marks!['data-editify-merged']) {
|
120
|
+
//获取colspan
|
121
|
+
const colspan = isNaN(Number(cell.marks!['colspan'])) ? 1 : Number(cell.marks!['colspan'])
|
122
|
+
//获取rowspan
|
123
|
+
const rowspan = isNaN(Number(cell.marks!['rowspan'])) ? 1 : Number(cell.marks!['rowspan'])
|
124
|
+
//如果是跨列单元格,隐藏该单元格同行后的colspan-1个单元格
|
125
|
+
if (colspan > 1) {
|
126
|
+
let el = cell
|
127
|
+
let i = 1
|
128
|
+
while (i < colspan) {
|
129
|
+
const nextCell = editor.getNextElement(el)!
|
130
|
+
if (nextCell) {
|
131
|
+
if (nextCell.hasMarks()) {
|
132
|
+
nextCell.marks!['data-editify-merged'] = 'true'
|
133
|
+
} else {
|
134
|
+
nextCell.marks = {
|
135
|
+
'data-editify-merged': 'true'
|
136
|
+
}
|
137
|
+
}
|
138
|
+
el = nextCell
|
139
|
+
i++
|
140
|
+
} else {
|
141
|
+
break
|
142
|
+
}
|
143
|
+
}
|
144
|
+
}
|
145
|
+
//如果是跨行单元格,隐藏该单元格同列后的rowspan-1行单元格
|
146
|
+
if (rowspan > 1) {
|
147
|
+
const index = cell.parent!.children!.findIndex(item => item.isEqual(cell))
|
148
|
+
let el = cell
|
149
|
+
let i = 1
|
150
|
+
while (i < rowspan && el && editor.getNextElement(el.parent!)) {
|
151
|
+
const nextRow = editor.getNextElement(el.parent!)!
|
152
|
+
//根据跨行单元格占据的列数,在后的rowspan-1行中隐藏colspan个单元格
|
153
|
+
for (let j = index; j < index + colspan; j++) {
|
154
|
+
const current = nextRow.children![j]
|
155
|
+
if (current) {
|
156
|
+
if (current.hasMarks()) {
|
157
|
+
current.marks!['data-editify-merged'] = 'true'
|
158
|
+
} else {
|
159
|
+
current.marks = {
|
160
|
+
'data-editify-merged': 'true'
|
161
|
+
}
|
162
|
+
}
|
163
|
+
}
|
164
|
+
}
|
165
|
+
el = nextRow.children![index]
|
166
|
+
i++
|
167
|
+
}
|
168
|
+
}
|
169
|
+
}
|
170
|
+
})
|
171
|
+
}
|
172
|
+
|
6
173
|
/**
|
7
174
|
* 更新代码块内的光标位置
|
8
175
|
* @param editor
|
@@ -94,7 +261,7 @@ export const parseList = (editor: AlexEditor, element: AlexElement) => {
|
|
94
261
|
* @param editor
|
95
262
|
* @param element
|
96
263
|
*/
|
97
|
-
export const orderdListHandle =
|
264
|
+
export const orderdListHandle = (editor: AlexEditor, element: AlexElement) => {
|
98
265
|
//有序列表的序号处理
|
99
266
|
if (isList(element, true)) {
|
100
267
|
//获取前一个元素
|
@@ -116,7 +283,7 @@ export const orderdListHandle = function (editor: AlexEditor, element: AlexEleme
|
|
116
283
|
* @param editor
|
117
284
|
* @param element
|
118
285
|
*/
|
119
|
-
export const commonElementHandle =
|
286
|
+
export const commonElementHandle = (editor: AlexEditor, element: AlexElement) => {
|
120
287
|
//图片、视频和链接设置marks
|
121
288
|
if (element.parsedom == 'img' || element.parsedom == 'video' || element.parsedom == 'a') {
|
122
289
|
const marks = {
|
@@ -167,11 +334,22 @@ export const commonElementHandle = function (editor: AlexEditor, element: AlexEl
|
|
167
334
|
}
|
168
335
|
|
169
336
|
/**
|
170
|
-
*
|
337
|
+
* 元素格式化时处理表格:th转为td
|
338
|
+
* @param editor
|
339
|
+
* @param element
|
340
|
+
*/
|
341
|
+
export const tableThTdHandle = (_editor: AlexEditor, element: AlexElement) => {
|
342
|
+
if (element.parsedom == 'th') {
|
343
|
+
element.parsedom = 'td'
|
344
|
+
}
|
345
|
+
}
|
346
|
+
|
347
|
+
/**
|
348
|
+
* 元素格式化时处理表格:格式化表格
|
171
349
|
* @param editor
|
172
350
|
* @param element
|
173
351
|
*/
|
174
|
-
export const
|
352
|
+
export const tableFormatHandle = (editor: AlexEditor, element: AlexElement) => {
|
175
353
|
if (element.parsedom == 'table') {
|
176
354
|
const marks = {
|
177
355
|
'data-editify-element': element.key
|
@@ -195,16 +373,12 @@ export const tableHandle = function (editor: AlexEditor, element: AlexElement) {
|
|
195
373
|
const rows = elements.filter(el => {
|
196
374
|
return el.parsedom == 'tr'
|
197
375
|
})
|
376
|
+
//获取表格实际应该的规格
|
377
|
+
const { rowNumber, columnNumber } = getTableSize(rows)
|
198
378
|
//colgroup元素
|
199
379
|
let colgroup = elements.find(el => {
|
200
380
|
return el.parsedom == 'colgroup'
|
201
381
|
})
|
202
|
-
//理论上的col的数量:取最多列数
|
203
|
-
const colNumber = Math.max(
|
204
|
-
...rows.map(row => {
|
205
|
-
return row.children!.length
|
206
|
-
})
|
207
|
-
)
|
208
382
|
//如果colgroup元素存在
|
209
383
|
if (colgroup) {
|
210
384
|
//遍历每个col元素设置默认的width:'auto
|
@@ -222,8 +396,8 @@ export const tableHandle = function (editor: AlexEditor, element: AlexElement) {
|
|
222
396
|
})
|
223
397
|
//对缺少的col元素进行补全
|
224
398
|
const length = colgroup.children!.length
|
225
|
-
if (length <
|
226
|
-
for (let i = 0; i <
|
399
|
+
if (length < columnNumber) {
|
400
|
+
for (let i = 0; i < columnNumber - length; i++) {
|
227
401
|
const col = new AlexElement(
|
228
402
|
'closed',
|
229
403
|
'col',
|
@@ -240,7 +414,7 @@ export const tableHandle = function (editor: AlexEditor, element: AlexElement) {
|
|
240
414
|
//如果colgroup元素不存在则新建
|
241
415
|
else {
|
242
416
|
colgroup = new AlexElement('inblock', 'colgroup', null, null, null)
|
243
|
-
for (let i =
|
417
|
+
for (let i = columnNumber - 1; i >= 0; i--) {
|
244
418
|
const col = new AlexElement(
|
245
419
|
'closed',
|
246
420
|
'col',
|
@@ -253,41 +427,106 @@ export const tableHandle = function (editor: AlexEditor, element: AlexElement) {
|
|
253
427
|
editor.addElementTo(col, colgroup)
|
254
428
|
}
|
255
429
|
}
|
430
|
+
//自动补全表格的单元格
|
431
|
+
autocompleteTableCells(editor, rows, rowNumber, columnNumber)
|
432
|
+
//清空表格
|
256
433
|
element.children = []
|
434
|
+
//创建tbody元素
|
257
435
|
const tbody = new AlexElement('inblock', 'tbody', null, null, null)
|
258
|
-
rows
|
259
|
-
|
260
|
-
const
|
261
|
-
|
262
|
-
for (let i = 0; i < colNumber - length; i++) {
|
263
|
-
const column = new AlexElement('inblock', 'td', null, null, null)
|
264
|
-
const breakElement = new AlexElement('closed', 'br', null, null, null)
|
265
|
-
editor.addElementTo(breakElement, column)
|
266
|
-
editor.addElementTo(column, row, row.children!.length)
|
267
|
-
}
|
268
|
-
}
|
269
|
-
editor.addElementTo(row, tbody)
|
436
|
+
//将rows全部加入表格中
|
437
|
+
rows.forEach(row => {
|
438
|
+
const index = tbody.hasChildren() ? tbody.children!.length : 0
|
439
|
+
editor.addElementTo(row, tbody, index)
|
270
440
|
})
|
271
441
|
editor.addElementTo(tbody, element)
|
272
442
|
editor.addElementTo(colgroup, element)
|
443
|
+
//对表格单元格合并状态进行处理
|
444
|
+
autoHideMergedTableCells(editor, rows)
|
273
445
|
}
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
446
|
+
}
|
447
|
+
|
448
|
+
/**
|
449
|
+
* 元素格式化时处理表格:处理光标在表格隐藏单元格内的情况
|
450
|
+
* @param editor
|
451
|
+
* @param element
|
452
|
+
*/
|
453
|
+
export const tableRangeMergedHandle = (editor: AlexEditor, element: AlexElement) => {
|
454
|
+
//如果元素是被隐藏的单元格,并且光标在该单元格内
|
455
|
+
if (element.parsedom == 'td' && element.hasMarks() && element.marks!['data-editify-merged'] && editor.range) {
|
456
|
+
//单元格向左查找设置焦点
|
457
|
+
const queryLeftSetRange = (_element: AlexElement, callback: (ele: AlexElement) => void) => {
|
458
|
+
//是否已查找到
|
459
|
+
let success = false
|
460
|
+
//获取前一个单元格
|
461
|
+
let el = editor.getPreviousElement(_element)
|
462
|
+
let tempIndex = 1
|
463
|
+
//如果前一个单元格存在则循环
|
464
|
+
while (el) {
|
465
|
+
//获取单元格的colspan
|
466
|
+
const { colspan } = getCellSpanNumber(el)
|
467
|
+
//如果单元格是跨列的并且是跨当前单元格的
|
468
|
+
if (el.hasMarks() && !el.marks!['data-editify-merged'] && colspan > tempIndex) {
|
469
|
+
success = true
|
470
|
+
callback(el)
|
471
|
+
break
|
472
|
+
}
|
473
|
+
//不是则继续向上查找
|
474
|
+
else {
|
475
|
+
el = editor.getPreviousElement(el)
|
476
|
+
tempIndex++
|
477
|
+
}
|
478
|
+
}
|
479
|
+
return success
|
480
|
+
}
|
481
|
+
//单元格向上查找设置焦点
|
482
|
+
const queryUpSetRange = (_element: AlexElement, callback: (ele: AlexElement) => void) => {
|
483
|
+
//是否已查找到
|
484
|
+
let success = false
|
485
|
+
//单元格在行中的序列
|
486
|
+
const index = _element.parent!.children!.findIndex(item => item.isEqual(_element))
|
487
|
+
//获取前一行元素
|
488
|
+
let el = editor.getPreviousElement(_element.parent!)
|
489
|
+
let tempIndex = 1
|
490
|
+
//如果前一行元素存在则循环
|
491
|
+
while (el) {
|
492
|
+
//获取前一行中同列的单元格
|
493
|
+
const previousColumn = el.children![index]
|
494
|
+
//获取单元格的rowspan
|
495
|
+
const { rowspan } = getCellSpanNumber(previousColumn)
|
496
|
+
//如果单元格是跨行的并且是跨当前单元格的
|
497
|
+
if (previousColumn.hasMarks() && !previousColumn.marks!['data-editify-merged'] && rowspan > tempIndex) {
|
498
|
+
success = true
|
499
|
+
callback(previousColumn)
|
500
|
+
break
|
501
|
+
}
|
502
|
+
//不是则继续向上查找
|
503
|
+
else {
|
504
|
+
el = editor.getPreviousElement(el)
|
505
|
+
tempIndex++
|
506
|
+
}
|
282
507
|
}
|
283
|
-
|
284
|
-
|
508
|
+
return success
|
509
|
+
}
|
510
|
+
//起点在该单元格下
|
511
|
+
if (element.isContains(editor.range.anchor.element)) {
|
512
|
+
const success = queryLeftSetRange(element, ele => {
|
513
|
+
editor.range!.anchor.moveToEnd(ele)
|
514
|
+
})
|
515
|
+
if (!success) {
|
516
|
+
queryUpSetRange(element, ele => {
|
517
|
+
editor.range!.anchor.moveToEnd(ele)
|
518
|
+
})
|
285
519
|
}
|
286
520
|
}
|
287
|
-
|
288
|
-
if (element.
|
289
|
-
|
290
|
-
|
521
|
+
//终点在该单元格下
|
522
|
+
if (element.isContains(editor.range.focus.element)) {
|
523
|
+
const success = queryLeftSetRange(element, ele => {
|
524
|
+
editor.range!.focus.moveToEnd(ele)
|
525
|
+
})
|
526
|
+
if (!success) {
|
527
|
+
queryUpSetRange(element, ele => {
|
528
|
+
editor.range!.focus.moveToEnd(ele)
|
529
|
+
})
|
291
530
|
}
|
292
531
|
}
|
293
532
|
}
|
@@ -300,7 +539,7 @@ export const tableHandle = function (editor: AlexEditor, element: AlexElement) {
|
|
300
539
|
* @param highlight
|
301
540
|
* @param languages
|
302
541
|
*/
|
303
|
-
export const preHandle =
|
542
|
+
export const preHandle = (editor: AlexEditor, element: AlexElement, highlight: boolean, languages: (string | LanguagesItemType)[]) => {
|
304
543
|
//如果是代码块进行处理
|
305
544
|
if (element.parsedom == 'pre') {
|
306
545
|
const marks = {
|
@@ -365,7 +604,7 @@ export const preHandle = function (editor: AlexEditor, element: AlexElement, hig
|
|
365
604
|
* @param editor
|
366
605
|
* @param element
|
367
606
|
*/
|
368
|
-
export const specialInblockHandle =
|
607
|
+
export const specialInblockHandle = (editor: AlexEditor, element: AlexElement) => {
|
369
608
|
if (element.hasChildren()) {
|
370
609
|
element.children!.forEach(el => {
|
371
610
|
if (isList(el, true) || isList(el, false) || isTask(el) || ['blockquote', 'pre', 'table', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'].includes(el.parsedom!)) {
|
package/src/core/tool.ts
CHANGED
@@ -224,7 +224,7 @@ export type PluginType = (editifyInstance: ComponentInternalInstance, editTrans:
|
|
224
224
|
* @param o2
|
225
225
|
* @returns
|
226
226
|
*/
|
227
|
-
export const mergeObject =
|
227
|
+
export const mergeObject = (o1: ObjectType, o2: ObjectType) => {
|
228
228
|
if (!DapCommon.isObject(o1) && DapCommon.isObject(o2)) {
|
229
229
|
return null
|
230
230
|
}
|
@@ -248,7 +248,7 @@ export const mergeObject = function (o1: ObjectType, o2: ObjectType) {
|
|
248
248
|
* @param value
|
249
249
|
* @returns
|
250
250
|
*/
|
251
|
-
export const queryHasValue =
|
251
|
+
export const queryHasValue = (obj: ObjectType, name: string, value?: string | number) => {
|
252
252
|
//如果value不存在则判断是否拥有属性name
|
253
253
|
if (value == null || value == undefined) {
|
254
254
|
return obj.hasOwnProperty(name)
|
@@ -293,7 +293,7 @@ export const queryHasValue = function (obj: ObjectType, name: string, value?: st
|
|
293
293
|
* @param data
|
294
294
|
* @returns
|
295
295
|
*/
|
296
|
-
export const cloneData =
|
296
|
+
export const cloneData = (data: any) => {
|
297
297
|
if (DapCommon.isObject(data) || Array.isArray(data)) {
|
298
298
|
return JSON.parse(JSON.stringify(data))
|
299
299
|
}
|
@@ -305,7 +305,7 @@ export const cloneData = function (data: any) {
|
|
305
305
|
* @param editTrans
|
306
306
|
* @returns
|
307
307
|
*/
|
308
|
-
export const getButtonOptionsConfig =
|
308
|
+
export const getButtonOptionsConfig = (editTrans: (key: string) => any): ButtonOptionsConfigType => {
|
309
309
|
return {
|
310
310
|
//标题配置
|
311
311
|
heading: [
|
@@ -506,7 +506,7 @@ export const getButtonOptionsConfig = function (editTrans: (key: string) => any)
|
|
506
506
|
* @param editLocale
|
507
507
|
* @returns
|
508
508
|
*/
|
509
|
-
export const getToolbarConfig =
|
509
|
+
export const getToolbarConfig = (editTrans: (key: string) => any, editLocale: LocaleType): ToolbarConfigType => {
|
510
510
|
return {
|
511
511
|
//是否使用工具条
|
512
512
|
use: true,
|
@@ -756,7 +756,7 @@ export const getToolbarConfig = function (editTrans: (key: string) => any, editL
|
|
756
756
|
* @param editLocale
|
757
757
|
* @returns
|
758
758
|
*/
|
759
|
-
export const getMenuConfig =
|
759
|
+
export const getMenuConfig = (editTrans: (key: string) => any, editLocale: LocaleType): MenuConfigType => {
|
760
760
|
return {
|
761
761
|
//是否使用菜单栏
|
762
762
|
use: true,
|
package/src/editify/editify.less
CHANGED
package/src/editify/editify.vue
CHANGED
@@ -23,7 +23,7 @@ import { computed, getCurrentInstance, nextTick, onBeforeUnmount, onMounted, pro
|
|
23
23
|
import { AlexEditor, AlexElement, AlexElementRangeType, AlexElementsRangeType } from 'alex-editor'
|
24
24
|
import { element as DapElement, event as DapEvent, data as DapData, number as DapNumber, color as DapColor } from 'dap-util'
|
25
25
|
import { mergeObject, getToolbarConfig, getMenuConfig, MenuConfigType, ObjectType, ToolbarConfigType, PluginResultType } from '../core/tool'
|
26
|
-
import { parseList, orderdListHandle, commonElementHandle,
|
26
|
+
import { parseList, orderdListHandle, commonElementHandle, tableThTdHandle, tableFormatHandle, tableRangeMergedHandle, preHandle, specialInblockHandle } from '../core/rule'
|
27
27
|
import { isTask, elementToParagraph, getMatchElementsByRange, hasTableInRange, hasLinkInRange, hasPreInRange, hasImageInRange, hasVideoInRange } from '../core/function'
|
28
28
|
import Toolbar from '../components/toolbar/toolbar.vue'
|
29
29
|
import Menu from '../components/menu/menu.vue'
|
@@ -287,7 +287,13 @@ const createEditor = () => {
|
|
287
287
|
commonElementHandle(editor.value!, el)
|
288
288
|
},
|
289
289
|
el => {
|
290
|
-
|
290
|
+
tableThTdHandle(editor.value!, el)
|
291
|
+
},
|
292
|
+
el => {
|
293
|
+
tableFormatHandle(editor.value!, el)
|
294
|
+
},
|
295
|
+
el => {
|
296
|
+
tableRangeMergedHandle(editor.value!, el)
|
291
297
|
},
|
292
298
|
el => {
|
293
299
|
preHandle(editor.value!, el, !!(toolbarConfig.value?.use && toolbarConfig.value?.codeBlock?.languages?.show), <(string | LanguagesItemType)[]>toolbarConfig.value?.codeBlock?.languages?.options)
|
@@ -521,6 +527,18 @@ const handleCustomHtmlPaste = async (elements: AlexElement[]) => {
|
|
521
527
|
if (el.parsedom == 'div' && el.marks!['data-editify-task']) {
|
522
528
|
marks['data-editify-task'] = el.marks!['data-editify-task']
|
523
529
|
}
|
530
|
+
//表格单元格colspan属性保留
|
531
|
+
if (['td', 'th'].includes(el.parsedom!) && el.marks!['colspan']) {
|
532
|
+
marks['colspan'] = el.marks!['colspan']
|
533
|
+
}
|
534
|
+
//表格单元格rowspan属性保留
|
535
|
+
if (['td', 'th'].includes(el.parsedom!) && el.marks!['rowspan']) {
|
536
|
+
marks['rowspan'] = el.marks!['rowspan']
|
537
|
+
}
|
538
|
+
//表格单元格被合并属性保留
|
539
|
+
if (['td', 'th'].includes(el.parsedom!) && el.marks!['data-editify-merged']) {
|
540
|
+
marks['data-editify-merged'] = el.marks!['data-editify-merged']
|
541
|
+
}
|
524
542
|
}
|
525
543
|
//处理需要保留的样式
|
526
544
|
if (el.hasStyles()) {
|
package/src/icon/iconfont.css
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
.editify-icon-merge-cells-up:before {
|
2
|
+
content: '\e73e';
|
3
|
+
}
|
4
|
+
|
5
|
+
.editify-icon-merge-cells-left:before {
|
6
|
+
content: '\e741';
|
7
|
+
}
|
8
|
+
|
9
|
+
.editify-icon-merge-cells-right:before {
|
10
|
+
content: '\e73f';
|
11
|
+
}
|
12
|
+
|
13
|
+
.editify-icon-merge-cells-down:before {
|
14
|
+
content: '\e740';
|
15
|
+
}
|
16
|
+
|
1
17
|
.editify-icon-mathformula:before {
|
2
18
|
content: '\e616';
|
3
19
|
}
|
package/src/icon/iconfont.ttf
CHANGED
Binary file
|
package/src/icon/iconfont.woff
CHANGED
Binary file
|
package/src/index.ts
CHANGED
@@ -9,17 +9,17 @@ export type { ButtonTypeType, ButtonOptionsItemType, ButtonSelectConfigType, But
|
|
9
9
|
export type { InsertImageUploadErrorType } from './components/insertImage/props'
|
10
10
|
export type { InsertVideoUploadErrorType } from './components/insertVideo/props'
|
11
11
|
export type { MenuButtonType, MenuSelectButtonType, MenuDisplayButtonType, MenuImageButtonType, MenuVideoButtonType, MenuTableButtonType, MenuCustomButtonType, CodeBlockToolbarType, TextToolbarType, ToolbarConfigType, MenuSequenceType, MenuModeType, MenuExtendType, MenuConfigType, PluginType, PluginResultType } from './core/tool'
|
12
|
-
export type {
|
12
|
+
export type { ElementMatchConfigType } from './core/function'
|
13
13
|
|
14
14
|
//导出编辑器操作方法
|
15
|
-
export { elementIsMatch, getMatchElementByElement, getMatchElementsByRange, elementIsInList, elementIsInTask, isList, isTask, hasPreInRange, isRangeInPre, hasQuoteInRange, isRangeInQuote, hasListInRange, isRangeInList, hasTaskInRange, isRangeInTask, hasLinkInRange, hasTableInRange, hasImageInRange, hasVideoInRange, queryTextStyle, queryTextMark, getRangeText, setIndentIncrease, setIndentDecrease, setQuote, setAlign, setList, setTask, setTextStyle, setTextMark, removeTextStyle, removeTextMark, setLineHeight, insertLink, insertImage, insertVideo, insertTable, insertCodeBlock } from './core/function'
|
15
|
+
export { elementIsMatch, getMatchElementByElement, getMatchElementsByRange, elementIsInList, elementIsInTask, isList, isTask, hasPreInRange, isRangeInPre, hasQuoteInRange, isRangeInQuote, hasListInRange, isRangeInList, hasTaskInRange, isRangeInTask, hasLinkInRange, hasTableInRange, hasImageInRange, hasVideoInRange, queryTextStyle, queryTextMark, getRangeText, setIndentIncrease, setIndentDecrease, setQuote, setAlign, setList, setTask, setTextStyle, setTextMark, removeTextStyle, removeTextMark, setLineHeight, insertLink, insertImage, insertVideo, insertTable, insertCodeBlock, insertSeparator } from './core/function'
|
16
16
|
|
17
17
|
//安装函数
|
18
18
|
const install: FunctionPlugin = (app: App) => {
|
19
19
|
app.component(Editify.name!, Editify)
|
20
20
|
}
|
21
21
|
//版本号
|
22
|
-
const version = '0.1.
|
22
|
+
const version = '0.1.44'
|
23
23
|
|
24
24
|
//导出AlexElement元素
|
25
25
|
export { AlexElement } from 'alex-editor'
|
package/src/locale/en_US.ts
CHANGED
@@ -9,6 +9,10 @@ export const en_US: ObjectType = {
|
|
9
9
|
insertColumnRight: 'Insert column backward',
|
10
10
|
deleteRow: 'Delete rows',
|
11
11
|
deleteColumn: 'Delete column',
|
12
|
+
mergeCellsLeft: 'Merge cells to the left',
|
13
|
+
mergeCellsRight: 'Merge cells to the right',
|
14
|
+
mergeCellsUp: 'Merge cells up',
|
15
|
+
mergeCellsDown: 'Merge cells down',
|
12
16
|
deleteTable: 'Delete table',
|
13
17
|
selectLanguages: 'Select language',
|
14
18
|
autoRecognize: 'Auto',
|
package/src/locale/zh_CN.ts
CHANGED
@@ -9,6 +9,10 @@ export const zh_CN: ObjectType = {
|
|
9
9
|
insertColumnRight: '向后插入列',
|
10
10
|
deleteRow: '删除行',
|
11
11
|
deleteColumn: '删除列',
|
12
|
+
mergeCellsLeft: '向左合并单元格',
|
13
|
+
mergeCellsRight: '向右合并单元格',
|
14
|
+
mergeCellsUp: '向上合并单元格',
|
15
|
+
mergeCellsDown: '向下合并单元格',
|
12
16
|
deleteTable: '删除表格',
|
13
17
|
selectLanguages: '选择语言',
|
14
18
|
autoRecognize: '自动识别',
|