vue-editify 0.1.43 → 0.1.45

Sign up to get free protection for your applications and to get access to all the features.
@@ -99,6 +99,22 @@
99
99
  <Button @operate="deleteTableColumn" rightBorder name="deleteColumn" :title="$editTrans('deleteColumn')" :tooltip="config.tooltip" :color="color">
100
100
  <Icon value="delete-column"></Icon>
101
101
  </Button>
102
+ <!-- 向左合并单元格 -->
103
+ <Button :disabled="!canMergeCells('left')" @operate="mergeCells('left')" rightBorder name="mergeCellsLeft" :title="$editTrans('mergeCellsLeft')" :tooltip="config.tooltip" :color="color">
104
+ <Icon value="merge-cells-left"></Icon>
105
+ </Button>
106
+ <!-- 向右合并单元格 -->
107
+ <Button :disabled="!canMergeCells('right')" @operate="mergeCells('right')" rightBorder name="mergeCellsRight" :title="$editTrans('mergeCellsRight')" :tooltip="config.tooltip" :color="color">
108
+ <Icon value="merge-cells-right"></Icon>
109
+ </Button>
110
+ <!-- 向上合并单元格 -->
111
+ <Button :disabled="!canMergeCells('up')" @operate="mergeCells('up')" rightBorder name="mergeCellsUp" :title="$editTrans('mergeCellsUp')" :tooltip="config.tooltip" :color="color">
112
+ <Icon value="merge-cells-up"></Icon>
113
+ </Button>
114
+ <!-- 向下合并单元格 -->
115
+ <Button :disabled="!canMergeCells('down')" @operate="mergeCells('down')" rightBorder name="mergeCellsDown" :title="$editTrans('mergeCellsDown')" :tooltip="config.tooltip" :color="color">
116
+ <Icon value="merge-cells-down"></Icon>
117
+ </Button>
102
118
  <!-- 删除表格 -->
103
119
  <Button @operate="deleteElement('table')" leftBorder name="deleteTable" :title="$editTrans('deleteTable')" :tooltip="config.tooltip" :color="color">
104
120
  <Icon value="delete-table"></Icon>
@@ -201,7 +217,7 @@ import Checkbox from '../checkbox/checkbox.vue'
201
217
  import Colors from '../colors/colors.vue'
202
218
  import { AlexEditor, AlexElement, AlexElementsRangeType } from 'alex-editor'
203
219
  import { common as DapCommon } from 'dap-util'
204
- import { getMatchElementsByRange, removeTextStyle, removeTextMark, setTextStyle, setLineHeight, setTextMark, setList, setTask, setHeading, setAlign, isRangeInList, isRangeInTask, queryTextStyle, queryTextMark } from '../../core/function'
220
+ import { getCellSpanNumber, getTableSize, getMatchElementsByRange, removeTextStyle, removeTextMark, setTextStyle, setLineHeight, setTextMark, setList, setTask, setHeading, setAlign, isRangeInList, isRangeInTask, queryTextStyle, queryTextMark, getMatchElementByElement, getCellMergeElement, setTableCellMerged } from '../../core/function'
205
221
  import { ToolbarProps } from './props'
206
222
  import { Ref, computed, inject, ref } from 'vue'
207
223
  import { ObjectType } from '../../core/tool'
@@ -453,6 +469,159 @@ const show = computed<boolean>({
453
469
  emits('update:modelValue', val)
454
470
  }
455
471
  })
472
+ //是否可以合并单元格
473
+ const canMergeCells = computed<(type: 'left' | 'right' | 'up' | 'down') => boolean>(() => {
474
+ return (type: 'left' | 'right' | 'up' | 'down') => {
475
+ if (!editor.value.range) {
476
+ return false
477
+ }
478
+ //光标所在单元格
479
+ const cell = getMatchElementByElement(editor.value.range.focus.element, {
480
+ parsedom: 'td'
481
+ })
482
+ //如果光标不在单元格内
483
+ if (!cell) {
484
+ return false
485
+ }
486
+ //判断是否可以向左合并
487
+ if (type == 'left') {
488
+ //是否可以向左合并
489
+ let flag = false
490
+ //当前单元格的rowspan
491
+ const cellSpanNum = getCellSpanNumber(cell)
492
+ //获取左侧单元格
493
+ const previousColumn = editor.value.getPreviousElement(cell)
494
+ //如果左侧单元格存在
495
+ if (previousColumn) {
496
+ //左侧单元格是隐藏的单元格
497
+ if (previousColumn.hasMarks() && previousColumn.marks!['data-editify-merged']) {
498
+ //获取合并该隐藏单元格的那个单元格
499
+ const { crossColumnElement } = getCellMergeElement(editor.value, previousColumn)
500
+ //如果是被跨列合并则判断跨列单元格占据的行数与当前单元格的行数是否一致
501
+ if (crossColumnElement) {
502
+ const { rowspan } = getCellSpanNumber(crossColumnElement)
503
+ flag = rowspan == cellSpanNum.rowspan
504
+ }
505
+ }
506
+ //左侧单元格不是隐藏的单元格
507
+ else {
508
+ //判断所占行数是否一致
509
+ const { rowspan } = getCellSpanNumber(previousColumn)
510
+ flag = rowspan == cellSpanNum.rowspan
511
+ }
512
+ }
513
+ return flag
514
+ }
515
+ //判断是否可以向右合并
516
+ if (type == 'right') {
517
+ //是否可以向右合并
518
+ let flag = false
519
+ //当前单元格的rowspan
520
+ const cellSpanNum = getCellSpanNumber(cell)
521
+ //获取右侧的单元格
522
+ let nextColumn = editor.value.getNextElement(cell)
523
+ //如果右侧单元格存在
524
+ while (nextColumn) {
525
+ //右侧单元格是隐藏的单元格
526
+ if (nextColumn.hasMarks() && nextColumn.marks!['data-editify-merged']) {
527
+ //获取合并该隐藏单元格的那个单元格
528
+ const { crossColumnElement } = getCellMergeElement(editor.value, nextColumn)
529
+ //如果是被跨列合并的表示属于当前单元格内,继续向右查询
530
+ if (crossColumnElement) {
531
+ nextColumn = editor.value.getNextElement(nextColumn)
532
+ }
533
+ //被跨行合并的直接结束,不能向右合并
534
+ else {
535
+ break
536
+ }
537
+ }
538
+ //右侧单元格不是隐藏的
539
+ else {
540
+ //判断行数是否与当前单元格一致
541
+ const { rowspan } = getCellSpanNumber(nextColumn)
542
+ //如果一致则可以合并
543
+ flag = rowspan == cellSpanNum.rowspan
544
+ //不管是否一致都直接结束
545
+ break
546
+ }
547
+ }
548
+ return flag
549
+ }
550
+ //判断是否可以向上合并
551
+ if (type == 'up') {
552
+ //是否可以向上合并
553
+ let flag = false
554
+ //当前单元格的colspan
555
+ const cellSpanNum = getCellSpanNumber(cell)
556
+ //获取单元格在行中的序列
557
+ const index = cell.parent!.children!.findIndex(item => item.isEqual(cell))
558
+ //获取上一行
559
+ const previousRow = editor.value.getPreviousElement(cell.parent!)
560
+ //如果上一行存在
561
+ if (previousRow) {
562
+ //获取上一行中对应序列的单元格
563
+ const column = previousRow.children![index]
564
+ //单元格是隐藏的单元格
565
+ if (column.hasMarks() && column.marks!['data-editify-merged']) {
566
+ //获取合并该隐藏单元格的那个单元格
567
+ const { crossRowElement } = getCellMergeElement(editor.value, column)
568
+ //如果是被跨行合并则判断跨列单元格占据的列数与当前单元格的列数是否一致
569
+ if (crossRowElement) {
570
+ const { colspan } = getCellSpanNumber(crossRowElement)
571
+ flag = colspan == cellSpanNum.colspan
572
+ }
573
+ }
574
+ //单元格不是隐藏的单元格
575
+ else {
576
+ //判断所占列数是否一致
577
+ const { colspan } = getCellSpanNumber(column)
578
+ flag = colspan == cellSpanNum.colspan
579
+ }
580
+ }
581
+ return flag
582
+ }
583
+ //判断是否可以向下合并
584
+ if (type == 'down') {
585
+ //是否可以向下合并
586
+ let flag = false
587
+ //当前单元格的colspan
588
+ const cellSpanNum = getCellSpanNumber(cell)
589
+ //获取单元格在行中的序列
590
+ const index = cell.parent!.children!.findIndex(item => item.isEqual(cell))
591
+ //获取下一行
592
+ let nextRow = editor.value.getNextElement(cell.parent!)
593
+ //如果下一行存在
594
+ while (nextRow) {
595
+ //获取下一行中对应序列的单元格
596
+ const column = nextRow.children![index]
597
+ //单元格是隐藏的单元格
598
+ if (column.hasMarks() && column.marks!['data-editify-merged']) {
599
+ //获取合并该隐藏单元格的那个单元格
600
+ const { crossRowElement } = getCellMergeElement(editor.value, column)
601
+ //如果是被跨行合并的表示属于当前单元格内,继续向下查询
602
+ if (crossRowElement) {
603
+ nextRow = editor.value.getNextElement(nextRow)
604
+ }
605
+ //被跨列合并的直接结束,不能向右合并
606
+ else {
607
+ break
608
+ }
609
+ }
610
+ //单元格不是隐藏的
611
+ else {
612
+ //判断列数是否与当前单元格一致
613
+ const { colspan } = getCellSpanNumber(column)
614
+ //如果一致则可以合并
615
+ flag = colspan == cellSpanNum.colspan
616
+ //不管是否一致都直接结束
617
+ break
618
+ }
619
+ }
620
+ return flag
621
+ }
622
+ return false
623
+ }
624
+ })
456
625
 
457
626
  //输入框获取焦点
458
627
  const handleInputFocus = (e: Event) => {
@@ -744,27 +913,28 @@ const insertTableColumn = (type: string | undefined = 'left') => {
744
913
  editor.value.range!.anchor.element = editor.value.range!.focus.element
745
914
  editor.value.range!.anchor.offset = editor.value.range!.focus.offset
746
915
  }
747
- const tables = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'table' })
748
916
  const columns = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'td' })
749
- const tbodys = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'tbody' })
750
- if (tables.length == 1 && tbodys.length == 1 && columns.length == 1) {
751
- const rows = tbodys[0].children
752
- const index = columns[0].parent!.children!.findIndex(item => {
917
+ if (columns.length == 1) {
918
+ const row = columns[0].parent!
919
+ const tbody = row.parent!
920
+ const table = tbody.parent!
921
+ const rows = tbody.children
922
+ const index = row.children!.findIndex(item => {
753
923
  return item.isEqual(columns[0])
754
924
  })
755
925
  //插入列
756
- rows!.forEach(row => {
757
- const newColumn = columns[0].clone(false)
926
+ rows!.forEach(item => {
927
+ const newColumn = new AlexElement('inblock', 'td', null, null, null)
758
928
  const breakEl = new AlexElement('closed', 'br', null, null, null)
759
929
  editor.value.addElementTo(breakEl, newColumn)
760
930
  if (type == 'left') {
761
- editor.value.addElementTo(newColumn, row, index)
931
+ editor.value.addElementTo(newColumn, item, index)
762
932
  } else {
763
- editor.value.addElementTo(newColumn, row, index + 1)
933
+ editor.value.addElementTo(newColumn, item, index + 1)
764
934
  }
765
935
  })
766
936
  //插入col
767
- const colgroup = tables[0].children!.find(item => {
937
+ const colgroup = table.children!.find(item => {
768
938
  return item.parsedom == 'colgroup'
769
939
  })!
770
940
  const col = new AlexElement('closed', 'col', null, null, null)
@@ -773,8 +943,6 @@ const insertTableColumn = (type: string | undefined = 'left') => {
773
943
  } else {
774
944
  editor.value.addElementTo(col, colgroup, index + 1)
775
945
  }
776
- //渲染
777
- editor.value.formatElementStack()
778
946
  if (type == 'left') {
779
947
  const previousColumn = editor.value.getPreviousElement(columns[0])!
780
948
  editor.value.range!.anchor.moveToStart(previousColumn)
@@ -784,6 +952,8 @@ const insertTableColumn = (type: string | undefined = 'left') => {
784
952
  editor.value.range!.anchor.moveToStart(nextColumn)
785
953
  editor.value.range!.focus.moveToStart(nextColumn)
786
954
  }
955
+ //渲染
956
+ editor.value.formatElementStack()
787
957
  editor.value.domRender()
788
958
  editor.value.rangeRender()
789
959
  }
@@ -794,23 +964,27 @@ const insertTableRow = (type: string | undefined = 'up') => {
794
964
  editor.value.range!.anchor.element = editor.value.range!.focus.element
795
965
  editor.value.range!.anchor.offset = editor.value.range!.focus.offset
796
966
  }
797
- const tables = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'table' })
798
967
  const rows = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'tr' })
799
- if (tables.length == 1 && rows.length == 1) {
800
- const newRow = rows[0].clone()
801
- newRow.children!.forEach(column => {
802
- column.children = []
968
+ if (rows.length == 1) {
969
+ const tbody = rows[0].parent!
970
+ const { columnNumber } = getTableSize(tbody.children!)
971
+ const newRow = new AlexElement('inblock', 'tr', null, null, null)
972
+ for (let i = 0; i < columnNumber; i++) {
973
+ const column = new AlexElement('inblock', 'td', null, null, null)
803
974
  const breakEl = new AlexElement('closed', 'br', null, null, null)
804
975
  editor.value.addElementTo(breakEl, column)
805
- })
976
+ editor.value.addElementTo(column, newRow)
977
+ }
806
978
  if (type == 'up') {
807
979
  editor.value.addElementBefore(newRow, rows[0])
808
980
  } else {
809
981
  editor.value.addElementAfter(newRow, rows[0])
810
982
  }
811
- editor.value.formatElementStack()
983
+ //重置光标
812
984
  editor.value.range!.anchor.moveToStart(newRow)
813
985
  editor.value.range!.focus.moveToStart(newRow)
986
+ //渲染
987
+ editor.value.formatElementStack()
814
988
  editor.value.domRender()
815
989
  editor.value.rangeRender()
816
990
  //更新工具条位置
@@ -854,25 +1028,67 @@ const deleteTableRow = () => {
854
1028
  editor.value.range!.anchor.element = editor.value.range!.focus.element
855
1029
  editor.value.range!.anchor.offset = editor.value.range!.focus.offset
856
1030
  }
857
- const tables = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'table' })
858
- const rows = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'tr' })
859
- if (tables.length == 1 && rows.length == 1) {
860
- const parent = rows[0].parent!
861
- if (parent.children!.length == 1) {
1031
+ const columns = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'td' })
1032
+ if (columns.length == 1) {
1033
+ //光标所在行
1034
+ const row = columns[0].parent!
1035
+ //如果只有一行则删除表格
1036
+ if (row.parent!.children!.length == 1) {
862
1037
  deleteElement('table')
863
1038
  return
864
1039
  }
865
- const previousRow = editor.value.getPreviousElement(rows[0])!
866
- const nextRow = editor.value.getNextElement(rows[0])!
867
- rows[0].toEmpty()
868
- editor.value.formatElementStack()
1040
+ //光标所在的单元格在行中的序列
1041
+ const index = row.children!.findIndex(item => {
1042
+ return item.isEqual(columns[0])
1043
+ })
1044
+ //上一行
1045
+ const previousRow = editor.value.getPreviousElement(row)
1046
+ //下一行
1047
+ const nextRow = editor.value.getNextElement(row)
1048
+ //遍历行中的每一个单元格
1049
+ row.children!.forEach((item, i) => {
1050
+ //获取单元格占的行数
1051
+ const itemSpanNum = getCellSpanNumber(item)
1052
+ //是隐藏的单元格
1053
+ if (item.hasMarks() && item.marks!['data-editify-merged']) {
1054
+ const { crossRowElement } = getCellMergeElement(editor.value, item)
1055
+ //如果是被跨行单元格合并的
1056
+ if (crossRowElement) {
1057
+ const { rowspan } = getCellSpanNumber(crossRowElement)
1058
+ if (rowspan - 1 == 1) {
1059
+ delete crossRowElement.marks!['rowspan']
1060
+ } else {
1061
+ crossRowElement.marks!['rowspan'] = rowspan - 1
1062
+ }
1063
+ }
1064
+ }
1065
+ //是跨行的单元格
1066
+ else if (itemSpanNum.rowspan > 1) {
1067
+ //获取下一行
1068
+ let el = editor.value.getNextElement(row)
1069
+ if (el && itemSpanNum.rowspan - 1 > 1) {
1070
+ if (el.children![i].hasMarks()) {
1071
+ el.children![i].marks!['rowspan'] = itemSpanNum.rowspan - 1
1072
+ } else {
1073
+ el.children![i].marks = {
1074
+ rowspan: itemSpanNum.rowspan - 1
1075
+ }
1076
+ }
1077
+ }
1078
+ }
1079
+ })
1080
+ //删除行
1081
+ row.toEmpty()
1082
+ //重置光标
869
1083
  if (previousRow) {
870
- editor.value.range!.anchor.moveToEnd(previousRow.children![0])
871
- editor.value.range!.focus.moveToEnd(previousRow.children![0])
1084
+ editor.value.range!.anchor.moveToEnd(previousRow.children![index])
1085
+ editor.value.range!.focus.moveToEnd(previousRow.children![index])
872
1086
  } else {
873
- editor.value.range!.anchor.moveToEnd(nextRow.children![0])
874
- editor.value.range!.focus.moveToEnd(nextRow.children![0])
1087
+ editor.value.range!.anchor.moveToEnd(nextRow!.children![index])
1088
+ editor.value.range!.focus.moveToEnd(nextRow!.children![index])
875
1089
  }
1090
+ //渲染
1091
+ editor.value.formatElementStack()
876
1092
  editor.value.domRender()
877
1093
  editor.value.rangeRender()
878
1094
  //更新工具条位置
@@ -888,42 +1104,315 @@ const deleteTableColumn = () => {
888
1104
  editor.value.range!.anchor.offset = editor.value.range!.focus.offset
889
1105
  }
890
1106
  const columns = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'td' })
891
- const tbodys = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'tbody' })
892
- const tables = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'table' })
893
- if (tables.length == 1 && tbodys.length == 1 && columns.length == 1) {
894
- const rows = tbodys[0].children!
895
- const parent = columns[0].parent!
896
- if (parent.children!.length == 1) {
1107
+ if (columns.length == 1) {
1108
+ //光标所在行
1109
+ const row = columns[0].parent!
1110
+ //所有的行元素
1111
+ const rows = row.parent!.children!
1112
+ //表格元素
1113
+ const table = row.parent!.parent!
1114
+ //如果光标所在行只有一个单元格则删除表格
1115
+ if (row.children!.length == 1) {
897
1116
  deleteElement('table')
898
1117
  return
899
1118
  }
900
- const previousColumn = editor.value.getPreviousElement(columns[0])!
901
- const nextColumn = editor.value.getNextElement(columns[0])!
902
- const index = columns[0].parent!.children!.findIndex(item => {
1119
+ //光标所在的单元格在行中的序列
1120
+ const index = row.children!.findIndex(item => {
903
1121
  return item.isEqual(columns[0])
904
1122
  })
905
- //删除列
906
- rows.forEach(row => {
907
- row.children![index].toEmpty()
1123
+ //前一个单元格
1124
+ const previousColumn = editor.value.getPreviousElement(columns[0])
1125
+ //后一个单元格
1126
+ const nextColumn = editor.value.getNextElement(columns[0])
1127
+ //遍历所有的行元素
1128
+ rows.forEach(item => {
1129
+ //对应序列的单元格
1130
+ const cell = item.children![index]
1131
+ const cellSpanNum = getCellSpanNumber(cell)
1132
+ //是隐藏的单元格
1133
+ if (cell.hasMarks() && cell.marks!['data-editify-merged']) {
1134
+ const { crossColumnElement } = getCellMergeElement(editor.value, cell)
1135
+ //如果是被跨列单元格合并的
1136
+ if (crossColumnElement) {
1137
+ const { colspan } = getCellSpanNumber(crossColumnElement)
1138
+ if (colspan - 1 == 1) {
1139
+ delete crossColumnElement.marks!['colspan']
1140
+ } else {
1141
+ crossColumnElement.marks!['colspan'] = colspan - 1
1142
+ }
1143
+ }
1144
+ }
1145
+ //跨列的单元格
1146
+ else if (cellSpanNum.colspan > 1) {
1147
+ //获取下一个单元格
1148
+ let el = editor.value.getNextElement(cell)
1149
+ if (el && cellSpanNum.colspan - 1 > 1) {
1150
+ if (el.hasMarks()) {
1151
+ el.marks!['colspan'] = cellSpanNum.colspan - 1
1152
+ } else {
1153
+ el.marks = {
1154
+ colspan: cellSpanNum.colspan - 1
1155
+ }
1156
+ }
1157
+ }
1158
+ }
1159
+ cell.toEmpty()
908
1160
  })
909
1161
  //删除col
910
- const colgroup = tables[0].children!.find(item => {
1162
+ const colgroup = table.children!.find(item => {
911
1163
  return item.parsedom == 'colgroup'
912
1164
  })!
913
1165
  colgroup.children![index].toEmpty()
914
- //渲染
915
- editor.value.formatElementStack()
916
1166
  if (previousColumn) {
917
1167
  editor.value.range!.anchor.moveToEnd(previousColumn)
918
1168
  editor.value.range!.focus.moveToEnd(previousColumn)
919
1169
  } else {
920
- editor.value.range!.anchor.moveToEnd(nextColumn)
921
- editor.value.range!.focus.moveToEnd(nextColumn)
1170
+ editor.value.range!.anchor.moveToEnd(nextColumn!)
1171
+ editor.value.range!.focus.moveToEnd(nextColumn!)
922
1172
  }
1173
+ //渲染
1174
+ editor.value.formatElementStack()
923
1175
  editor.value.domRender()
924
1176
  editor.value.rangeRender()
925
1177
  }
926
1178
  }
1179
+ //合并单元格
1180
+ const mergeCells = (type: 'left' | 'right' | 'up' | 'down') => {
1181
+ if (!canMergeCells.value(type)) {
1182
+ return
1183
+ }
1184
+ if (!editor.value.range!.anchor.isEqual(editor.value.range!.focus)) {
1185
+ editor.value.range!.anchor.element = editor.value.range!.focus.element
1186
+ editor.value.range!.anchor.offset = editor.value.range!.focus.offset
1187
+ }
1188
+ const columns = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'td' })
1189
+ if (columns.length == 1) {
1190
+ //向左合并单元格
1191
+ if (type == 'left') {
1192
+ //当前单元格所占行数和列数
1193
+ const cellSpanNum = getCellSpanNumber(columns[0])
1194
+ //获取左侧单元格
1195
+ const previousColumn = editor.value.getPreviousElement(columns[0])
1196
+ //如果左侧单元格存在
1197
+ if (previousColumn) {
1198
+ //左侧单元格是隐藏的单元格
1199
+ if (previousColumn.hasMarks() && previousColumn.marks!['data-editify-merged']) {
1200
+ //获取合并该隐藏单元格的那个单元格
1201
+ const { crossColumnElement } = getCellMergeElement(editor.value, previousColumn)
1202
+ //如果是被跨列合并则判断跨列单元格占据的行数与当前单元格的行数是否一致
1203
+ if (crossColumnElement) {
1204
+ const { rowspan, colspan } = getCellSpanNumber(crossColumnElement)
1205
+ //进行合并
1206
+ if (rowspan == cellSpanNum.rowspan) {
1207
+ crossColumnElement.marks!['colspan'] = colspan + cellSpanNum.colspan
1208
+ columns[0].children!.forEach(item => {
1209
+ crossColumnElement.children!.push(item)
1210
+ item.parent = crossColumnElement
1211
+ })
1212
+ setTableCellMerged(columns[0])
1213
+ editor.value.range!.anchor.moveToEnd(crossColumnElement)
1214
+ editor.value.range!.focus.moveToEnd(crossColumnElement)
1215
+ editor.value.formatElementStack()
1216
+ editor.value.domRender()
1217
+ editor.value.rangeRender()
1218
+ }
1219
+ }
1220
+ }
1221
+ //左侧单元格不是隐藏的单元格
1222
+ else {
1223
+ //判断所占行数是否一致
1224
+ const { rowspan, colspan } = getCellSpanNumber(previousColumn)
1225
+ //进行合并
1226
+ if (rowspan == cellSpanNum.rowspan) {
1227
+ if (previousColumn.hasMarks()) {
1228
+ previousColumn.marks!['colspan'] = colspan + cellSpanNum.colspan
1229
+ } else {
1230
+ previousColumn.marks = {
1231
+ colspan: colspan + cellSpanNum.colspan
1232
+ }
1233
+ }
1234
+ columns[0].children!.forEach(item => {
1235
+ previousColumn.children!.push(item)
1236
+ item.parent = previousColumn
1237
+ })
1238
+ setTableCellMerged(columns[0])
1239
+ editor.value.range!.anchor.moveToEnd(previousColumn)
1240
+ editor.value.range!.focus.moveToEnd(previousColumn)
1241
+ editor.value.formatElementStack()
1242
+ editor.value.domRender()
1243
+ editor.value.rangeRender()
1244
+ }
1245
+ }
1246
+ }
1247
+ }
1248
+ //向右合并单元格
1249
+ else if (type == 'right') {
1250
+ //当前单元格所占行数和列数
1251
+ const cellSpanNum = getCellSpanNumber(columns[0])
1252
+ //获取右侧的单元格
1253
+ let nextColumn = editor.value.getNextElement(columns[0])
1254
+ //如果右侧单元格存在
1255
+ while (nextColumn) {
1256
+ //右侧单元格是隐藏的单元格
1257
+ if (nextColumn.hasMarks() && nextColumn.marks!['data-editify-merged']) {
1258
+ //获取合并该隐藏单元格的那个单元格
1259
+ const { crossColumnElement } = getCellMergeElement(editor.value, nextColumn)
1260
+ //如果是被跨列合并的表示属于当前单元格内,继续向右查询
1261
+ if (crossColumnElement) {
1262
+ nextColumn = editor.value.getNextElement(nextColumn)
1263
+ }
1264
+ //被跨行合并的直接结束,不能向右合并
1265
+ else {
1266
+ break
1267
+ }
1268
+ }
1269
+ //右侧单元格不是隐藏的
1270
+ else {
1271
+ //判断行数是否与当前单元格一致
1272
+ const { rowspan, colspan } = getCellSpanNumber(nextColumn)
1273
+ //如果一致则可以合并
1274
+ if (rowspan == cellSpanNum.rowspan) {
1275
+ if (columns[0].hasMarks()) {
1276
+ columns[0].marks!['colspan'] = cellSpanNum.colspan + colspan
1277
+ } else {
1278
+ columns[0].marks = {
1279
+ colspan: cellSpanNum.colspan + colspan
1280
+ }
1281
+ }
1282
+ nextColumn.children!.forEach(item => {
1283
+ columns[0].children!.push(item)
1284
+ item.parent = columns[0]
1285
+ })
1286
+ setTableCellMerged(nextColumn)
1287
+ editor.value.range!.anchor.moveToEnd(columns[0])
1288
+ editor.value.range!.focus.moveToEnd(columns[0])
1289
+ editor.value.formatElementStack()
1290
+ editor.value.domRender()
1291
+ editor.value.rangeRender()
1292
+ }
1293
+ //不管是否一致都直接结束
1294
+ break
1295
+ }
1296
+ }
1297
+ }
1298
+ //向上合并单元格
1299
+ else if (type == 'up') {
1300
+ //当前单元格所占行数和列数
1301
+ const cellSpanNum = getCellSpanNumber(columns[0])
1302
+ //获取单元格在行中的序列
1303
+ const index = columns[0].parent!.children!.findIndex(item => item.isEqual(columns[0]))
1304
+ //获取上一行
1305
+ const previousRow = editor.value.getPreviousElement(columns[0].parent!)
1306
+ //如果上一行存在
1307
+ if (previousRow) {
1308
+ //获取上一行中对应序列的单元格
1309
+ const previousColumn = previousRow.children![index]
1310
+ //单元格是隐藏的单元格
1311
+ if (previousColumn.hasMarks() && previousColumn.marks!['data-editify-merged']) {
1312
+ //获取合并该隐藏单元格的那个单元格
1313
+ const { crossRowElement } = getCellMergeElement(editor.value, previousColumn)
1314
+ //如果是被跨行合并则判断跨列单元格占据的列数与当前单元格的列数是否一致
1315
+ if (crossRowElement) {
1316
+ const { rowspan, colspan } = getCellSpanNumber(crossRowElement)
1317
+ //进行合并
1318
+ if (colspan == cellSpanNum.colspan) {
1319
+ crossRowElement.marks!['rowspan'] = rowspan + cellSpanNum.rowspan
1320
+ columns[0].children!.forEach(item => {
1321
+ crossRowElement.children!.push(item)
1322
+ item.parent = crossRowElement
1323
+ })
1324
+ setTableCellMerged(columns[0])
1325
+ editor.value.range!.anchor.moveToEnd(crossRowElement)
1326
+ editor.value.range!.focus.moveToEnd(crossRowElement)
1327
+ editor.value.formatElementStack()
1328
+ editor.value.domRender()
1329
+ editor.value.rangeRender()
1330
+ }
1331
+ }
1332
+ }
1333
+ //单元格不是隐藏的单元格
1334
+ else {
1335
+ //判断所占列数是否一致
1336
+ const { rowspan, colspan } = getCellSpanNumber(previousColumn)
1337
+ //进行合并
1338
+ if (colspan == cellSpanNum.colspan) {
1339
+ if (previousColumn.hasMarks()) {
1340
+ previousColumn.marks!['rowspan'] = rowspan + cellSpanNum.rowspan
1341
+ } else {
1342
+ previousColumn.marks = {
1343
+ rowspan: rowspan + cellSpanNum.rowspan
1344
+ }
1345
+ }
1346
+ columns[0].children!.forEach(item => {
1347
+ previousColumn.children!.push(item)
1348
+ item.parent = previousColumn
1349
+ })
1350
+ setTableCellMerged(columns[0])
1351
+ editor.value.range!.anchor.moveToEnd(previousColumn)
1352
+ editor.value.range!.focus.moveToEnd(previousColumn)
1353
+ editor.value.formatElementStack()
1354
+ editor.value.domRender()
1355
+ editor.value.rangeRender()
1356
+ }
1357
+ }
1358
+ }
1359
+ }
1360
+ //向下合并单元格
1361
+ else if (type == 'down') {
1362
+ //当前单元格所占行数和列数
1363
+ const cellSpanNum = getCellSpanNumber(columns[0])
1364
+ //获取单元格在行中的序列
1365
+ const index = columns[0].parent!.children!.findIndex(item => item.isEqual(columns[0]))
1366
+ //获取下一行
1367
+ let nextRow = editor.value.getNextElement(columns[0].parent!)
1368
+ //如果下一行存在
1369
+ while (nextRow) {
1370
+ //获取下一行中对应序列的单元格
1371
+ const nextColumn = nextRow.children![index]
1372
+ //单元格是隐藏的单元格
1373
+ if (nextColumn.hasMarks() && nextColumn.marks!['data-editify-merged']) {
1374
+ //获取合并该隐藏单元格的那个单元格
1375
+ const { crossRowElement } = getCellMergeElement(editor.value, nextColumn)
1376
+ //如果是被跨行合并的表示属于当前单元格内,继续向下查询
1377
+ if (crossRowElement) {
1378
+ nextRow = editor.value.getNextElement(nextRow)
1379
+ }
1380
+ //被跨列合并的直接结束,不能向右合并
1381
+ else {
1382
+ break
1383
+ }
1384
+ }
1385
+ //单元格不是隐藏的
1386
+ else {
1387
+ //判断列数是否与当前单元格一致
1388
+ const { rowspan, colspan } = getCellSpanNumber(nextColumn)
1389
+ //如果一致则可以合并
1390
+ if (colspan == cellSpanNum.colspan) {
1391
+ if (columns[0].hasMarks()) {
1392
+ columns[0].marks!['rowspan'] = cellSpanNum.rowspan + rowspan
1393
+ } else {
1394
+ columns[0].marks = {
1395
+ rowspan: cellSpanNum.rowspan + rowspan
1396
+ }
1397
+ }
1398
+ nextColumn.children!.forEach(item => {
1399
+ columns[0].children!.push(item)
1400
+ item.parent = columns[0]
1401
+ })
1402
+ setTableCellMerged(nextColumn)
1403
+ editor.value.range!.anchor.moveToEnd(columns[0])
1404
+ editor.value.range!.focus.moveToEnd(columns[0])
1405
+ editor.value.formatElementStack()
1406
+ editor.value.domRender()
1407
+ editor.value.rangeRender()
1408
+ }
1409
+ //不管是否一致都直接结束
1410
+ break
1411
+ }
1412
+ }
1413
+ }
1414
+ }
1415
+ }
927
1416
  //浮层显示时
928
1417
  const layerShow = () => {
929
1418
  //链接初始化展示