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/lib/editify.es.js CHANGED
@@ -1498,6 +1498,7 @@ const initEditorNode = function(node) {
1498
1498
  if (typeof node == "string" && node) {
1499
1499
  node = document.body.querySelector(node);
1500
1500
  }
1501
+ node = node;
1501
1502
  if (!element$1.isElement(node)) {
1502
1503
  throw new Error("You must specify a dom container to initialize the editor");
1503
1504
  }
@@ -1666,7 +1667,7 @@ const _AlexElement = class _AlexElement2 {
1666
1667
  return this.isText() && !this.isEmpty() && isSpaceText(this.textContent);
1667
1668
  }
1668
1669
  /**
1669
- * 获取设置不可编辑的元素,如果是null,说明元素是可编辑的
1670
+ * 获取不可编辑的元素,如果是null,说明元素是可编辑的
1670
1671
  */
1671
1672
  getUneditableElement() {
1672
1673
  if (this.hasMarks() && this.marks["contenteditable"] == "false") {
@@ -2162,9 +2163,7 @@ class AlexHistory {
2162
2163
  if (this.current < this.records.length - 1) {
2163
2164
  this.records.length = this.current + 1;
2164
2165
  }
2165
- const newStack = stack.map((ele) => {
2166
- return ele.__fullClone();
2167
- });
2166
+ const newStack = stack.map((ele) => ele.__fullClone());
2168
2167
  const newRange = this.__cloneRange(newStack, range);
2169
2168
  this.records.push({
2170
2169
  stack: newStack,
@@ -2189,9 +2188,7 @@ class AlexHistory {
2189
2188
  current += 1;
2190
2189
  }
2191
2190
  const { stack, range } = this.records[current];
2192
- const newStack = stack.map((ele) => {
2193
- return ele.__fullClone();
2194
- });
2191
+ const newStack = stack.map((ele) => ele.__fullClone());
2195
2192
  const newRange = this.__cloneRange(newStack, range);
2196
2193
  return {
2197
2194
  current,
@@ -2983,24 +2980,25 @@ const handleSelectionChange = function() {
2983
2980
  }
2984
2981
  };
2985
2982
  const handleBeforeInput = function(e) {
2983
+ const event2 = e;
2986
2984
  if (this.disabled) {
2987
2985
  return;
2988
2986
  }
2989
- if (e.inputType == "deleteByCut" || e.inputType == "insertFromPaste" || e.inputType == "deleteByDrag" || e.inputType == "insertFromDrop") {
2987
+ if (event2.inputType == "deleteByCut" || event2.inputType == "insertFromPaste" || event2.inputType == "deleteByDrag" || event2.inputType == "insertFromDrop") {
2990
2988
  return;
2991
2989
  }
2992
- e.preventDefault();
2993
- if (e.inputType == "insertText" && e.data) {
2994
- this.insertText(e.data);
2990
+ event2.preventDefault();
2991
+ if (event2.inputType == "insertText" && event2.data) {
2992
+ this.insertText(event2.data);
2995
2993
  this.formatElementStack();
2996
2994
  this.domRender();
2997
2995
  this.rangeRender();
2998
- } else if (e.inputType == "insertParagraph" || e.inputType == "insertLineBreak") {
2996
+ } else if (event2.inputType == "insertParagraph" || event2.inputType == "insertLineBreak") {
2999
2997
  this.insertParagraph();
3000
2998
  this.formatElementStack();
3001
2999
  this.domRender();
3002
3000
  this.rangeRender();
3003
- } else if (e.inputType == "deleteContentBackward") {
3001
+ } else if (event2.inputType == "deleteContentBackward") {
3004
3002
  this.delete();
3005
3003
  this.formatElementStack();
3006
3004
  this.domRender();
@@ -3011,16 +3009,17 @@ const handleChineseInput = function(e) {
3011
3009
  if (this.disabled) {
3012
3010
  return;
3013
3011
  }
3014
- e.preventDefault();
3015
- if (e.type == "compositionstart") {
3012
+ const event2 = e;
3013
+ event2.preventDefault();
3014
+ if (event2.type == "compositionstart") {
3016
3015
  if (this.__chineseInputTimer) {
3017
3016
  clearTimeout(this.__chineseInputTimer);
3018
3017
  this.__chineseInputTimer = null;
3019
3018
  }
3020
3019
  this.__isInputChinese = true;
3021
- } else if (e.type == "compositionend") {
3022
- if (e.data) {
3023
- this.insertText(e.data);
3020
+ } else if (event2.type == "compositionend") {
3021
+ if (event2.data) {
3022
+ this.insertText(event2.data);
3024
3023
  this.formatElementStack();
3025
3024
  this.domRender();
3026
3025
  this.rangeRender();
@@ -3037,9 +3036,10 @@ const handleKeyboard = function(e) {
3037
3036
  if (this.__isInputChinese) {
3038
3037
  return;
3039
3038
  }
3040
- if (e.type == "keydown") {
3041
- if (isUndo(e)) {
3042
- e.preventDefault();
3039
+ const event2 = e;
3040
+ if (event2.type == "keydown") {
3041
+ if (isUndo(event2)) {
3042
+ event2.preventDefault();
3043
3043
  const historyRecord = this.history.get(-1);
3044
3044
  if (historyRecord) {
3045
3045
  this.history.current = historyRecord.current;
@@ -3049,8 +3049,8 @@ const handleKeyboard = function(e) {
3049
3049
  this.domRender(true);
3050
3050
  this.rangeRender();
3051
3051
  }
3052
- } else if (isRedo(e)) {
3053
- e.preventDefault();
3052
+ } else if (isRedo(event2)) {
3053
+ event2.preventDefault();
3054
3054
  const historyRecord = this.history.get(1);
3055
3055
  if (historyRecord) {
3056
3056
  this.history.current = historyRecord.current;
@@ -3061,20 +3061,20 @@ const handleKeyboard = function(e) {
3061
3061
  this.rangeRender();
3062
3062
  }
3063
3063
  }
3064
- this.emit("keydown", this.value, e);
3065
- } else if (e.type == "keyup") {
3066
- this.emit("keyup", this.value, e);
3064
+ this.emit("keydown", this.value, event2);
3065
+ } else if (event2.type == "keyup") {
3066
+ this.emit("keyup", this.value, event2);
3067
3067
  }
3068
3068
  };
3069
3069
  const handleCopy = async function(e) {
3070
- e.preventDefault();
3070
+ const event2 = e;
3071
+ event2.preventDefault();
3071
3072
  if (!this.range) {
3072
3073
  return;
3073
3074
  }
3074
3075
  if (!this.allowCopy) {
3075
3076
  return;
3076
3077
  }
3077
- const event2 = e;
3078
3078
  const result = this.getElementsByRange().list;
3079
3079
  if (event2.clipboardData && result.length) {
3080
3080
  const { text: text2, html } = setClipboardData.apply(this, [event2.clipboardData, result]);
@@ -3082,14 +3082,14 @@ const handleCopy = async function(e) {
3082
3082
  }
3083
3083
  };
3084
3084
  const handleCut = async function(e) {
3085
- e.preventDefault();
3085
+ const event2 = e;
3086
+ event2.preventDefault();
3086
3087
  if (!this.range) {
3087
3088
  return;
3088
3089
  }
3089
3090
  if (!this.allowCut) {
3090
3091
  return;
3091
3092
  }
3092
- const event2 = e;
3093
3093
  const result = this.getElementsByRange().list;
3094
3094
  if (event2.clipboardData && result.length) {
3095
3095
  const { text: text2, html } = setClipboardData.apply(this, [event2.clipboardData, result]);
@@ -3103,7 +3103,8 @@ const handleCut = async function(e) {
3103
3103
  }
3104
3104
  };
3105
3105
  const handlePaste = async function(e) {
3106
- e.preventDefault();
3106
+ const event2 = e;
3107
+ event2.preventDefault();
3107
3108
  if (this.disabled) {
3108
3109
  return;
3109
3110
  }
@@ -3113,7 +3114,6 @@ const handlePaste = async function(e) {
3113
3114
  if (!this.allowPaste) {
3114
3115
  return;
3115
3116
  }
3116
- const event2 = e;
3117
3117
  if (event2.clipboardData) {
3118
3118
  const html = event2.clipboardData.getData("text/html");
3119
3119
  const text2 = event2.clipboardData.getData("text/plain");
@@ -3876,48 +3876,50 @@ class AlexEditor {
3876
3876
  * 根据range来设置真实的光标
3877
3877
  */
3878
3878
  rangeRender() {
3879
- if (this.disabled) {
3880
- return;
3881
- }
3882
- if (this.range) {
3883
- const handler = (point) => {
3884
- let node = null;
3885
- let offset = null;
3886
- if (point.element.isText()) {
3887
- node = point.element.elm.childNodes[0];
3888
- offset = point.offset;
3889
- } else {
3890
- node = point.element.parent.elm;
3891
- const index = point.element.parent.children.findIndex((item) => {
3892
- return point.element.isEqual(item);
3893
- });
3894
- offset = point.offset + index;
3895
- }
3896
- return { node, offset };
3897
- };
3898
- this.__innerSelectionChange = true;
3899
- const anchorResult = handler(this.range.anchor);
3900
- const focusResult = handler(this.range.focus);
3901
- const selection = window.getSelection();
3902
- if (selection) {
3903
- selection.removeAllRanges();
3904
- const range = document.createRange();
3905
- range.setStart(anchorResult.node, anchorResult.offset);
3906
- range.setEnd(focusResult.node, focusResult.offset);
3907
- selection.addRange(range);
3879
+ return new Promise((resolve) => {
3880
+ if (this.disabled) {
3881
+ resolve();
3882
+ return;
3908
3883
  }
3909
- } else {
3910
- const selection = window.getSelection();
3911
- if (selection) {
3912
- selection.removeAllRanges();
3884
+ if (this.range) {
3885
+ const handler = (point) => {
3886
+ let node = null;
3887
+ let offset = null;
3888
+ if (point.element.isText()) {
3889
+ node = point.element.elm.childNodes[0];
3890
+ offset = point.offset;
3891
+ } else {
3892
+ node = point.element.parent.elm;
3893
+ const index = point.element.parent.children.findIndex((item) => point.element.isEqual(item));
3894
+ offset = point.offset + index;
3895
+ }
3896
+ return { node, offset };
3897
+ };
3898
+ this.__innerSelectionChange = true;
3899
+ const anchorResult = handler(this.range.anchor);
3900
+ const focusResult = handler(this.range.focus);
3901
+ const selection = window.getSelection();
3902
+ if (selection) {
3903
+ selection.removeAllRanges();
3904
+ const range = document.createRange();
3905
+ range.setStart(anchorResult.node, anchorResult.offset);
3906
+ range.setEnd(focusResult.node, focusResult.offset);
3907
+ selection.addRange(range);
3908
+ }
3909
+ } else {
3910
+ const selection = window.getSelection();
3911
+ if (selection) {
3912
+ selection.removeAllRanges();
3913
+ }
3913
3914
  }
3914
- }
3915
- setTimeout(() => {
3916
- setRangeInVisible.apply(this);
3917
- this.__innerSelectionChange = false;
3918
- this.history.updateCurrentRange(this.range);
3919
- this.emit("rangeUpdate", this.range);
3920
- }, 0);
3915
+ setTimeout(() => {
3916
+ setRangeInVisible.apply(this);
3917
+ this.__innerSelectionChange = false;
3918
+ this.history.updateCurrentRange(this.range);
3919
+ this.emit("rangeUpdate", this.range);
3920
+ resolve();
3921
+ }, 0);
3922
+ });
3921
3923
  }
3922
3924
  /**
3923
3925
  * 将html转为元素
@@ -3988,11 +3990,12 @@ class AlexEditor {
3988
3990
  if (inline.parse) {
3989
3991
  config.parsedom = AlexElement.TEXT_NODE;
3990
3992
  if (common$1.isObject(inline.parse)) {
3991
- for (let key in inline.parse) {
3992
- if (typeof inline.parse[key] == "function") {
3993
- config.styles[key] = inline.parse[key].apply(this, [node]);
3993
+ const inlineParse2 = inline.parse;
3994
+ for (let key in inlineParse2) {
3995
+ if (typeof inlineParse2[key] == "function") {
3996
+ config.styles[key] = inlineParse2[key].apply(this, [node]);
3994
3997
  } else {
3995
- config.styles[key] = inline.parse[key];
3998
+ config.styles[key] = inlineParse2[key];
3996
3999
  }
3997
4000
  }
3998
4001
  }
@@ -4549,7 +4552,7 @@ class AlexEditor {
4549
4552
  event$1.off(this.$el, "beforeinput.alex_editor compositionstart.alex_editor compositionupdate.alex_editor compositionend.alex_editor keydown.alex_editor cut.alex_editor paste.alex_editor copy.alex_editor dragstart.alex_editor drop.alex_editor focus.alex_editor blur.alex_editor");
4550
4553
  }
4551
4554
  }
4552
- const version$2 = "1.4.6";
4555
+ const version$2 = "1.4.7";
4553
4556
  console.log(`%c alex-editor %c v${version$2} `, "padding: 2px 1px; border-radius: 3px 0 0 3px; color: #fff; background: #606060; font-weight: bold;", "padding: 2px 1px; border-radius: 0 3px 3px 0; color: #fff; background: #42c02e; font-weight: bold;");
4554
4557
  const number = {
4555
4558
  /**
@@ -17875,7 +17878,7 @@ const languages = [
17875
17878
  value: "rust"
17876
17879
  }
17877
17880
  ];
17878
- const mergeObject = function(o1, o2) {
17881
+ const mergeObject = (o1, o2) => {
17879
17882
  if (!common.isObject(o1) && common.isObject(o2)) {
17880
17883
  return null;
17881
17884
  }
@@ -17888,7 +17891,7 @@ const mergeObject = function(o1, o2) {
17888
17891
  }
17889
17892
  return o1;
17890
17893
  };
17891
- const queryHasValue = function(obj, name, value) {
17894
+ const queryHasValue = (obj, name, value) => {
17892
17895
  if (value == null || value == void 0) {
17893
17896
  return obj.hasOwnProperty(name);
17894
17897
  }
@@ -17918,13 +17921,13 @@ const queryHasValue = function(obj, name, value) {
17918
17921
  }
17919
17922
  return ownValue == value;
17920
17923
  };
17921
- const cloneData = function(data2) {
17924
+ const cloneData = (data2) => {
17922
17925
  if (common.isObject(data2) || Array.isArray(data2)) {
17923
17926
  return JSON.parse(JSON.stringify(data2));
17924
17927
  }
17925
17928
  return data2;
17926
17929
  };
17927
- const getButtonOptionsConfig = function(editTrans) {
17930
+ const getButtonOptionsConfig = (editTrans) => {
17928
17931
  return {
17929
17932
  //标题配置
17930
17933
  heading: [
@@ -18118,7 +18121,7 @@ const getButtonOptionsConfig = function(editTrans) {
18118
18121
  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"]
18119
18122
  };
18120
18123
  };
18121
- const getToolbarConfig = function(editTrans, editLocale) {
18124
+ const getToolbarConfig = (editTrans, editLocale) => {
18122
18125
  return {
18123
18126
  //是否使用工具条
18124
18127
  use: true,
@@ -18361,7 +18364,7 @@ const getToolbarConfig = function(editTrans, editLocale) {
18361
18364
  extraDisabled: null
18362
18365
  };
18363
18366
  };
18364
- const getMenuConfig = function(editTrans, editLocale) {
18367
+ const getMenuConfig = (editTrans, editLocale) => {
18365
18368
  return {
18366
18369
  //是否使用菜单栏
18367
18370
  use: true,
@@ -18756,9 +18759,131 @@ const getMenuConfig = function(editTrans, editLocale) {
18756
18759
  extends: {}
18757
18760
  };
18758
18761
  };
18762
+ const setTableCellMerged = (cell) => {
18763
+ const breakEl = new AlexElement("closed", "br", null, null, null);
18764
+ cell.children = [breakEl];
18765
+ breakEl.parent = cell;
18766
+ if (cell.hasMarks()) {
18767
+ cell.marks["data-editify-merged"] = "true";
18768
+ } else {
18769
+ cell.marks = {
18770
+ "data-editify-merged": "true"
18771
+ };
18772
+ }
18773
+ };
18774
+ const getCellMergeElement = (editor, cell) => {
18775
+ const queryLeft = () => {
18776
+ let crossColumnElement = null;
18777
+ let el = editor.getPreviousElement(cell);
18778
+ let temIndex = 1;
18779
+ while (el) {
18780
+ const { colspan } = getCellSpanNumber(el);
18781
+ const isMergedCell = el.hasMarks() && el.marks["data-editify-merged"];
18782
+ if (!isMergedCell && colspan > temIndex) {
18783
+ crossColumnElement = el;
18784
+ break;
18785
+ } else {
18786
+ el = editor.getPreviousElement(el);
18787
+ temIndex++;
18788
+ }
18789
+ }
18790
+ return crossColumnElement;
18791
+ };
18792
+ const queryUp = () => {
18793
+ let crossRowElement = null;
18794
+ const index = cell.parent.children.findIndex((item) => item.isEqual(cell));
18795
+ let el = editor.getPreviousElement(cell.parent);
18796
+ let temIndex = 1;
18797
+ while (el) {
18798
+ const column = el.children[index];
18799
+ const { rowspan } = getCellSpanNumber(column);
18800
+ const isMergedCell = column.hasMarks() && column.marks["data-editify-merged"];
18801
+ if (!isMergedCell && rowspan > temIndex) {
18802
+ crossRowElement = column;
18803
+ break;
18804
+ } else {
18805
+ el = editor.getPreviousElement(el);
18806
+ temIndex++;
18807
+ }
18808
+ }
18809
+ return crossRowElement;
18810
+ };
18811
+ return {
18812
+ crossRowElement: queryUp(),
18813
+ crossColumnElement: queryLeft()
18814
+ };
18815
+ };
18816
+ const getCellSpanNumber = (cell) => {
18817
+ let rowspan = 1;
18818
+ let colspan = 1;
18819
+ if (cell.hasMarks()) {
18820
+ if (cell.marks["rowspan"]) {
18821
+ const num = Number(cell.marks["rowspan"]);
18822
+ rowspan = isNaN(num) ? 1 : num;
18823
+ }
18824
+ if (cell.marks["colspan"]) {
18825
+ const num = Number(cell.marks["colspan"]);
18826
+ colspan = isNaN(num) ? 1 : num;
18827
+ }
18828
+ }
18829
+ return {
18830
+ rowspan,
18831
+ colspan
18832
+ };
18833
+ };
18834
+ const getTableSize = (rowElements) => {
18835
+ const columns = [];
18836
+ const rows = [];
18837
+ rowElements.forEach((rowElement, rowIndex) => {
18838
+ rowElement.children.forEach((colElement, colIndex) => {
18839
+ if (Array.isArray(rows[rowIndex])) {
18840
+ rows[rowIndex].push(colElement);
18841
+ } else {
18842
+ rows[rowIndex] = [colElement];
18843
+ }
18844
+ if (Array.isArray(columns[colIndex])) {
18845
+ columns[colIndex].push(colElement);
18846
+ } else {
18847
+ columns[colIndex] = [colElement];
18848
+ }
18849
+ });
18850
+ });
18851
+ const rowNumbers = columns.map((item) => {
18852
+ return item.reduce((total, current) => {
18853
+ if (current.hasMarks()) {
18854
+ if (!!current.marks["data-editify-merged"]) {
18855
+ return total + 0;
18856
+ }
18857
+ if (!!current.marks["rowspan"]) {
18858
+ const num = Number(current.marks["rowspan"]);
18859
+ return total + (isNaN(num) ? 1 : num);
18860
+ }
18861
+ }
18862
+ return total + 1;
18863
+ }, 0);
18864
+ });
18865
+ const columnNumbers = rows.map((item) => {
18866
+ return item.reduce((total, current) => {
18867
+ if (current.hasMarks()) {
18868
+ if (!!current.marks["data-editify-merged"]) {
18869
+ return total + 0;
18870
+ }
18871
+ if (!!current.marks["colspan"]) {
18872
+ const num = Number(current.marks["colspan"]);
18873
+ return total + (isNaN(num) ? 1 : num);
18874
+ }
18875
+ }
18876
+ return total + 1;
18877
+ }, 0);
18878
+ });
18879
+ return {
18880
+ rowNumber: Math.max(...rowNumbers),
18881
+ columnNumber: Math.max(...columnNumbers)
18882
+ };
18883
+ };
18759
18884
  const elementIsMatch = (element2, config) => {
18760
18885
  let isMatch = true;
18761
- if (config.parsedom && element2.parsedom && config.parsedom != element2.parsedom) {
18886
+ if (config.parsedom && (element2.isText() || config.parsedom != element2.parsedom)) {
18762
18887
  isMatch = false;
18763
18888
  }
18764
18889
  if (config.marks) {
@@ -19723,6 +19848,139 @@ const insertSeparator = (editor) => {
19723
19848
  editor.range.anchor.moveToEnd(separator);
19724
19849
  editor.range.focus.moveToEnd(separator);
19725
19850
  };
19851
+ const autocompleteTableCells = (editor, rowElements, rowNumber, columnNumber) => {
19852
+ AlexElement.flatElements(rowElements).forEach((item) => {
19853
+ if (item.parsedom == "td" && item.hasMarks()) {
19854
+ if (item.marks["data-editify-merged"]) {
19855
+ delete item.marks["data-editify-merged"];
19856
+ }
19857
+ const colspan = isNaN(Number(item.marks["colspan"])) ? 1 : Number(item.marks["colspan"]);
19858
+ const rowspan = isNaN(Number(item.marks["rowspan"])) ? 1 : Number(item.marks["rowspan"]);
19859
+ if (colspan > 1) {
19860
+ let i = 1;
19861
+ while (i < colspan && item.parent.children.length < columnNumber) {
19862
+ const column = new AlexElement(
19863
+ "inblock",
19864
+ "td",
19865
+ {
19866
+ "data-editify-merged": "true"
19867
+ },
19868
+ null,
19869
+ null
19870
+ );
19871
+ const breakElement = new AlexElement("closed", "br", null, null, null);
19872
+ editor.addElementTo(breakElement, column);
19873
+ editor.addElementAfter(column, item);
19874
+ i++;
19875
+ }
19876
+ }
19877
+ if (rowspan > 1) {
19878
+ let el = item;
19879
+ let i = 1;
19880
+ while (i < rowspan && editor.getNextElement(el.parent) && editor.getNextElement(el.parent).children.length < columnNumber) {
19881
+ const nextRow = editor.getNextElement(el.parent);
19882
+ const index = el.parent.children.findIndex((item2) => item2.isEqual(el));
19883
+ const nextCell = nextRow.children[index];
19884
+ for (let j = 0; j < colspan; j++) {
19885
+ const column = new AlexElement(
19886
+ "inblock",
19887
+ "td",
19888
+ {
19889
+ "data-editify-merged": "true"
19890
+ },
19891
+ null,
19892
+ null
19893
+ );
19894
+ const breakElement = new AlexElement("closed", "br", null, null, null);
19895
+ editor.addElementTo(breakElement, column);
19896
+ if (nextCell) {
19897
+ editor.addElementBefore(column, nextCell);
19898
+ } else {
19899
+ editor.addElementTo(column, nextRow, nextRow.children.length);
19900
+ }
19901
+ }
19902
+ el = nextRow.children[index];
19903
+ i++;
19904
+ }
19905
+ }
19906
+ }
19907
+ });
19908
+ rowElements.forEach((rowElement) => {
19909
+ const number2 = rowElement.children.length;
19910
+ if (number2 < columnNumber) {
19911
+ for (let i = 0; i < columnNumber - number2; i++) {
19912
+ const column = new AlexElement("inblock", "td", null, null, null);
19913
+ const breakElement = new AlexElement("closed", "br", null, null, null);
19914
+ editor.addElementTo(breakElement, column);
19915
+ editor.addElementTo(column, rowElement, rowElement.children.length);
19916
+ }
19917
+ }
19918
+ });
19919
+ const length = rowElements.length;
19920
+ if (length < rowNumber) {
19921
+ for (let i = 0; i < rowNumber - length; i++) {
19922
+ const row = new AlexElement("inblock", "tr", null, null, null);
19923
+ for (let j = 0; j < columnNumber; j++) {
19924
+ const column = new AlexElement("inblock", "td", null, null, null);
19925
+ const breakElement = new AlexElement("closed", "br", null, null, null);
19926
+ editor.addElementTo(breakElement, column);
19927
+ editor.addElementTo(column, row);
19928
+ }
19929
+ rowElements.push(row);
19930
+ }
19931
+ }
19932
+ };
19933
+ const autoHideMergedTableCells = (editor, rowElements) => {
19934
+ const cells = AlexElement.flatElements(rowElements).filter((item) => item.parsedom == "td");
19935
+ cells.forEach((cell) => {
19936
+ if (cell.hasMarks() && !cell.marks["data-editify-merged"]) {
19937
+ const colspan = isNaN(Number(cell.marks["colspan"])) ? 1 : Number(cell.marks["colspan"]);
19938
+ const rowspan = isNaN(Number(cell.marks["rowspan"])) ? 1 : Number(cell.marks["rowspan"]);
19939
+ if (colspan > 1) {
19940
+ let el = cell;
19941
+ let i = 1;
19942
+ while (i < colspan) {
19943
+ const nextCell = editor.getNextElement(el);
19944
+ if (nextCell) {
19945
+ if (nextCell.hasMarks()) {
19946
+ nextCell.marks["data-editify-merged"] = "true";
19947
+ } else {
19948
+ nextCell.marks = {
19949
+ "data-editify-merged": "true"
19950
+ };
19951
+ }
19952
+ el = nextCell;
19953
+ i++;
19954
+ } else {
19955
+ break;
19956
+ }
19957
+ }
19958
+ }
19959
+ if (rowspan > 1) {
19960
+ const index = cell.parent.children.findIndex((item) => item.isEqual(cell));
19961
+ let el = cell;
19962
+ let i = 1;
19963
+ while (i < rowspan && el && editor.getNextElement(el.parent)) {
19964
+ const nextRow = editor.getNextElement(el.parent);
19965
+ for (let j = index; j < index + colspan; j++) {
19966
+ const current = nextRow.children[j];
19967
+ if (current) {
19968
+ if (current.hasMarks()) {
19969
+ current.marks["data-editify-merged"] = "true";
19970
+ } else {
19971
+ current.marks = {
19972
+ "data-editify-merged": "true"
19973
+ };
19974
+ }
19975
+ }
19976
+ }
19977
+ el = nextRow.children[index];
19978
+ i++;
19979
+ }
19980
+ }
19981
+ }
19982
+ });
19983
+ };
19726
19984
  const updateRangeInPre = (editor, element2, originalTextElements, newElements) => {
19727
19985
  if (!editor.range) {
19728
19986
  return;
@@ -19782,7 +20040,7 @@ const parseList = (editor, element2) => {
19782
20040
  element2.toEmpty();
19783
20041
  }
19784
20042
  };
19785
- const orderdListHandle = function(editor, element2) {
20043
+ const orderdListHandle = (editor, element2) => {
19786
20044
  if (isList(element2, true)) {
19787
20045
  const previousElement = editor.getPreviousElement(element2);
19788
20046
  if (previousElement && isList(previousElement, true)) {
@@ -19793,7 +20051,7 @@ const orderdListHandle = function(editor, element2) {
19793
20051
  }
19794
20052
  }
19795
20053
  };
19796
- const commonElementHandle = function(editor, element2) {
20054
+ const commonElementHandle = (editor, element2) => {
19797
20055
  if (element2.parsedom == "img" || element2.parsedom == "video" || element2.parsedom == "a") {
19798
20056
  const marks = {
19799
20057
  "data-editify-element": element2.key
@@ -19834,7 +20092,12 @@ const commonElementHandle = function(editor, element2) {
19834
20092
  }
19835
20093
  }
19836
20094
  };
19837
- const tableHandle = function(editor, element2) {
20095
+ const tableThTdHandle = (_editor, element2) => {
20096
+ if (element2.parsedom == "th") {
20097
+ element2.parsedom = "td";
20098
+ }
20099
+ };
20100
+ const tableFormatHandle = (editor, element2) => {
19838
20101
  if (element2.parsedom == "table") {
19839
20102
  const marks = {
19840
20103
  "data-editify-element": element2.key
@@ -19857,14 +20120,10 @@ const tableHandle = function(editor, element2) {
19857
20120
  const rows = elements.filter((el) => {
19858
20121
  return el.parsedom == "tr";
19859
20122
  });
20123
+ const { rowNumber, columnNumber } = getTableSize(rows);
19860
20124
  let colgroup = elements.find((el) => {
19861
20125
  return el.parsedom == "colgroup";
19862
20126
  });
19863
- const colNumber = Math.max(
19864
- ...rows.map((row) => {
19865
- return row.children.length;
19866
- })
19867
- );
19868
20127
  if (colgroup) {
19869
20128
  colgroup.children.forEach((col) => {
19870
20129
  if (!col.hasMarks()) {
@@ -19876,8 +20135,8 @@ const tableHandle = function(editor, element2) {
19876
20135
  }
19877
20136
  });
19878
20137
  const length = colgroup.children.length;
19879
- if (length < colNumber) {
19880
- for (let i = 0; i < colNumber - length; i++) {
20138
+ if (length < columnNumber) {
20139
+ for (let i = 0; i < columnNumber - length; i++) {
19881
20140
  const col = new AlexElement(
19882
20141
  "closed",
19883
20142
  "col",
@@ -19892,7 +20151,7 @@ const tableHandle = function(editor, element2) {
19892
20151
  }
19893
20152
  } else {
19894
20153
  colgroup = new AlexElement("inblock", "colgroup", null, null, null);
19895
- for (let i = colNumber - 1; i >= 0; i--) {
20154
+ for (let i = columnNumber - 1; i >= 0; i--) {
19896
20155
  const col = new AlexElement(
19897
20156
  "closed",
19898
20157
  "col",
@@ -19905,43 +20164,79 @@ const tableHandle = function(editor, element2) {
19905
20164
  editor.addElementTo(col, colgroup);
19906
20165
  }
19907
20166
  }
20167
+ autocompleteTableCells(editor, rows, rowNumber, columnNumber);
19908
20168
  element2.children = [];
19909
20169
  const tbody = new AlexElement("inblock", "tbody", null, null, null);
19910
- rows.reverse().forEach((row) => {
19911
- const length = row.children.length;
19912
- if (length < colNumber) {
19913
- for (let i = 0; i < colNumber - length; i++) {
19914
- const column = new AlexElement("inblock", "td", null, null, null);
19915
- const breakElement = new AlexElement("closed", "br", null, null, null);
19916
- editor.addElementTo(breakElement, column);
19917
- editor.addElementTo(column, row, row.children.length);
19918
- }
19919
- }
19920
- editor.addElementTo(row, tbody);
20170
+ rows.forEach((row) => {
20171
+ const index = tbody.hasChildren() ? tbody.children.length : 0;
20172
+ editor.addElementTo(row, tbody, index);
19921
20173
  });
19922
20174
  editor.addElementTo(tbody, element2);
19923
20175
  editor.addElementTo(colgroup, element2);
19924
- }
19925
- if (element2.parsedom == "th") {
19926
- element2.parsedom = "td";
19927
- }
19928
- if (element2.parsedom == "td") {
19929
- if (element2.hasMarks()) {
19930
- if (element2.marks["rowspan"]) {
19931
- delete element2.marks["rowspan"];
20176
+ autoHideMergedTableCells(editor, rows);
20177
+ }
20178
+ };
20179
+ const tableRangeMergedHandle = (editor, element2) => {
20180
+ if (element2.parsedom == "td" && element2.hasMarks() && element2.marks["data-editify-merged"] && editor.range) {
20181
+ const queryLeftSetRange = (_element, callback) => {
20182
+ let success = false;
20183
+ let el = editor.getPreviousElement(_element);
20184
+ let tempIndex = 1;
20185
+ while (el) {
20186
+ const { colspan } = getCellSpanNumber(el);
20187
+ if (el.hasMarks() && !el.marks["data-editify-merged"] && colspan > tempIndex) {
20188
+ success = true;
20189
+ callback(el);
20190
+ break;
20191
+ } else {
20192
+ el = editor.getPreviousElement(el);
20193
+ tempIndex++;
20194
+ }
20195
+ }
20196
+ return success;
20197
+ };
20198
+ const queryUpSetRange = (_element, callback) => {
20199
+ let success = false;
20200
+ const index = _element.parent.children.findIndex((item) => item.isEqual(_element));
20201
+ let el = editor.getPreviousElement(_element.parent);
20202
+ let tempIndex = 1;
20203
+ while (el) {
20204
+ const previousColumn = el.children[index];
20205
+ const { rowspan } = getCellSpanNumber(previousColumn);
20206
+ if (previousColumn.hasMarks() && !previousColumn.marks["data-editify-merged"] && rowspan > tempIndex) {
20207
+ success = true;
20208
+ callback(previousColumn);
20209
+ break;
20210
+ } else {
20211
+ el = editor.getPreviousElement(el);
20212
+ tempIndex++;
20213
+ }
19932
20214
  }
19933
- if (element2.marks["colspan"]) {
19934
- delete element2.marks["colspan"];
20215
+ return success;
20216
+ };
20217
+ if (element2.isContains(editor.range.anchor.element)) {
20218
+ const success = queryLeftSetRange(element2, (ele) => {
20219
+ editor.range.anchor.moveToEnd(ele);
20220
+ });
20221
+ if (!success) {
20222
+ queryUpSetRange(element2, (ele) => {
20223
+ editor.range.anchor.moveToEnd(ele);
20224
+ });
19935
20225
  }
19936
20226
  }
19937
- if (element2.hasStyles()) {
19938
- if (element2.styles["display"]) {
19939
- delete element2.styles["display"];
20227
+ if (element2.isContains(editor.range.focus.element)) {
20228
+ const success = queryLeftSetRange(element2, (ele) => {
20229
+ editor.range.focus.moveToEnd(ele);
20230
+ });
20231
+ if (!success) {
20232
+ queryUpSetRange(element2, (ele) => {
20233
+ editor.range.focus.moveToEnd(ele);
20234
+ });
19940
20235
  }
19941
20236
  }
19942
20237
  }
19943
20238
  };
19944
- const preHandle = function(editor, element2, highlight2, languages2) {
20239
+ const preHandle = (editor, element2, highlight2, languages2) => {
19945
20240
  if (element2.parsedom == "pre") {
19946
20241
  const marks = {
19947
20242
  "data-editify-element": element2.key
@@ -19988,7 +20283,7 @@ const preHandle = function(editor, element2, highlight2, languages2) {
19988
20283
  }
19989
20284
  }
19990
20285
  };
19991
- const specialInblockHandle = function(editor, element2) {
20286
+ const specialInblockHandle = (editor, element2) => {
19992
20287
  if (element2.hasChildren()) {
19993
20288
  element2.children.forEach((el) => {
19994
20289
  if (isList(el, true) || isList(el, false) || isTask(el) || ["blockquote", "pre", "table", "h1", "h2", "h3", "h4", "h5", "h6", "p"].includes(el.parsedom)) {
@@ -21595,6 +21890,100 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
21595
21890
  emits("update:modelValue", val);
21596
21891
  }
21597
21892
  });
21893
+ const canMergeCells = computed(() => {
21894
+ return (type) => {
21895
+ if (!editor.value.range) {
21896
+ return false;
21897
+ }
21898
+ const cell = getMatchElementByElement(editor.value.range.focus.element, {
21899
+ parsedom: "td"
21900
+ });
21901
+ if (!cell) {
21902
+ return false;
21903
+ }
21904
+ if (type == "left") {
21905
+ let flag = false;
21906
+ const cellSpanNum = getCellSpanNumber(cell);
21907
+ const previousColumn = editor.value.getPreviousElement(cell);
21908
+ if (previousColumn) {
21909
+ if (previousColumn.hasMarks() && previousColumn.marks["data-editify-merged"]) {
21910
+ const { crossColumnElement } = getCellMergeElement(editor.value, previousColumn);
21911
+ if (crossColumnElement) {
21912
+ const { rowspan } = getCellSpanNumber(crossColumnElement);
21913
+ flag = rowspan == cellSpanNum.rowspan;
21914
+ }
21915
+ } else {
21916
+ const { rowspan } = getCellSpanNumber(previousColumn);
21917
+ flag = rowspan == cellSpanNum.rowspan;
21918
+ }
21919
+ }
21920
+ return flag;
21921
+ }
21922
+ if (type == "right") {
21923
+ let flag = false;
21924
+ const cellSpanNum = getCellSpanNumber(cell);
21925
+ let nextColumn = editor.value.getNextElement(cell);
21926
+ while (nextColumn) {
21927
+ if (nextColumn.hasMarks() && nextColumn.marks["data-editify-merged"]) {
21928
+ const { crossColumnElement } = getCellMergeElement(editor.value, nextColumn);
21929
+ if (crossColumnElement) {
21930
+ nextColumn = editor.value.getNextElement(nextColumn);
21931
+ } else {
21932
+ break;
21933
+ }
21934
+ } else {
21935
+ const { rowspan } = getCellSpanNumber(nextColumn);
21936
+ flag = rowspan == cellSpanNum.rowspan;
21937
+ break;
21938
+ }
21939
+ }
21940
+ return flag;
21941
+ }
21942
+ if (type == "up") {
21943
+ let flag = false;
21944
+ const cellSpanNum = getCellSpanNumber(cell);
21945
+ const index = cell.parent.children.findIndex((item) => item.isEqual(cell));
21946
+ const previousRow = editor.value.getPreviousElement(cell.parent);
21947
+ if (previousRow) {
21948
+ const column = previousRow.children[index];
21949
+ if (column.hasMarks() && column.marks["data-editify-merged"]) {
21950
+ const { crossRowElement } = getCellMergeElement(editor.value, column);
21951
+ if (crossRowElement) {
21952
+ const { colspan } = getCellSpanNumber(crossRowElement);
21953
+ flag = colspan == cellSpanNum.colspan;
21954
+ }
21955
+ } else {
21956
+ const { colspan } = getCellSpanNumber(column);
21957
+ flag = colspan == cellSpanNum.colspan;
21958
+ }
21959
+ }
21960
+ return flag;
21961
+ }
21962
+ if (type == "down") {
21963
+ let flag = false;
21964
+ const cellSpanNum = getCellSpanNumber(cell);
21965
+ const index = cell.parent.children.findIndex((item) => item.isEqual(cell));
21966
+ let nextRow = editor.value.getNextElement(cell.parent);
21967
+ while (nextRow) {
21968
+ const column = nextRow.children[index];
21969
+ if (column.hasMarks() && column.marks["data-editify-merged"]) {
21970
+ const { crossRowElement } = getCellMergeElement(editor.value, column);
21971
+ if (crossRowElement) {
21972
+ nextRow = editor.value.getNextElement(nextRow);
21973
+ } else {
21974
+ break;
21975
+ }
21976
+ } else {
21977
+ const { colspan } = getCellSpanNumber(column);
21978
+ flag = colspan == cellSpanNum.colspan;
21979
+ break;
21980
+ }
21981
+ }
21982
+ return flag;
21983
+ }
21984
+ return false;
21985
+ };
21986
+ });
21598
21987
  const handleInputFocus = (e) => {
21599
21988
  if (props.color) {
21600
21989
  e.currentTarget.style.borderColor = props.color;
@@ -21855,25 +22244,26 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
21855
22244
  editor.value.range.anchor.element = editor.value.range.focus.element;
21856
22245
  editor.value.range.anchor.offset = editor.value.range.focus.offset;
21857
22246
  }
21858
- const tables = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: "table" });
21859
22247
  const columns = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: "td" });
21860
- const tbodys = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: "tbody" });
21861
- if (tables.length == 1 && tbodys.length == 1 && columns.length == 1) {
21862
- const rows = tbodys[0].children;
21863
- const index = columns[0].parent.children.findIndex((item) => {
22248
+ if (columns.length == 1) {
22249
+ const row = columns[0].parent;
22250
+ const tbody = row.parent;
22251
+ const table = tbody.parent;
22252
+ const rows = tbody.children;
22253
+ const index = row.children.findIndex((item) => {
21864
22254
  return item.isEqual(columns[0]);
21865
22255
  });
21866
- rows.forEach((row) => {
21867
- const newColumn = columns[0].clone(false);
22256
+ rows.forEach((item) => {
22257
+ const newColumn = new AlexElement("inblock", "td", null, null, null);
21868
22258
  const breakEl = new AlexElement("closed", "br", null, null, null);
21869
22259
  editor.value.addElementTo(breakEl, newColumn);
21870
22260
  if (type == "left") {
21871
- editor.value.addElementTo(newColumn, row, index);
22261
+ editor.value.addElementTo(newColumn, item, index);
21872
22262
  } else {
21873
- editor.value.addElementTo(newColumn, row, index + 1);
22263
+ editor.value.addElementTo(newColumn, item, index + 1);
21874
22264
  }
21875
22265
  });
21876
- const colgroup = tables[0].children.find((item) => {
22266
+ const colgroup = table.children.find((item) => {
21877
22267
  return item.parsedom == "colgroup";
21878
22268
  });
21879
22269
  const col = new AlexElement("closed", "col", null, null, null);
@@ -21882,7 +22272,6 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
21882
22272
  } else {
21883
22273
  editor.value.addElementTo(col, colgroup, index + 1);
21884
22274
  }
21885
- editor.value.formatElementStack();
21886
22275
  if (type == "left") {
21887
22276
  const previousColumn = editor.value.getPreviousElement(columns[0]);
21888
22277
  editor.value.range.anchor.moveToStart(previousColumn);
@@ -21892,6 +22281,7 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
21892
22281
  editor.value.range.anchor.moveToStart(nextColumn);
21893
22282
  editor.value.range.focus.moveToStart(nextColumn);
21894
22283
  }
22284
+ editor.value.formatElementStack();
21895
22285
  editor.value.domRender();
21896
22286
  editor.value.rangeRender();
21897
22287
  }
@@ -21901,23 +22291,25 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
21901
22291
  editor.value.range.anchor.element = editor.value.range.focus.element;
21902
22292
  editor.value.range.anchor.offset = editor.value.range.focus.offset;
21903
22293
  }
21904
- const tables = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: "table" });
21905
22294
  const rows = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: "tr" });
21906
- if (tables.length == 1 && rows.length == 1) {
21907
- const newRow = rows[0].clone();
21908
- newRow.children.forEach((column) => {
21909
- column.children = [];
22295
+ if (rows.length == 1) {
22296
+ const tbody = rows[0].parent;
22297
+ const { columnNumber } = getTableSize(tbody.children);
22298
+ const newRow = new AlexElement("inblock", "tr", null, null, null);
22299
+ for (let i = 0; i < columnNumber; i++) {
22300
+ const column = new AlexElement("inblock", "td", null, null, null);
21910
22301
  const breakEl = new AlexElement("closed", "br", null, null, null);
21911
22302
  editor.value.addElementTo(breakEl, column);
21912
- });
22303
+ editor.value.addElementTo(column, newRow);
22304
+ }
21913
22305
  if (type == "up") {
21914
22306
  editor.value.addElementBefore(newRow, rows[0]);
21915
22307
  } else {
21916
22308
  editor.value.addElementAfter(newRow, rows[0]);
21917
22309
  }
21918
- editor.value.formatElementStack();
21919
22310
  editor.value.range.anchor.moveToStart(newRow);
21920
22311
  editor.value.range.focus.moveToStart(newRow);
22312
+ editor.value.formatElementStack();
21921
22313
  editor.value.domRender();
21922
22314
  editor.value.rangeRender();
21923
22315
  setTimeout(() => {
@@ -21957,25 +22349,52 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
21957
22349
  editor.value.range.anchor.element = editor.value.range.focus.element;
21958
22350
  editor.value.range.anchor.offset = editor.value.range.focus.offset;
21959
22351
  }
21960
- const tables = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: "table" });
21961
- const rows = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: "tr" });
21962
- if (tables.length == 1 && rows.length == 1) {
21963
- const parent = rows[0].parent;
21964
- if (parent.children.length == 1) {
22352
+ const columns = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: "td" });
22353
+ if (columns.length == 1) {
22354
+ const row = columns[0].parent;
22355
+ if (row.parent.children.length == 1) {
21965
22356
  deleteElement("table");
21966
22357
  return;
21967
22358
  }
21968
- const previousRow = editor.value.getPreviousElement(rows[0]);
21969
- const nextRow = editor.value.getNextElement(rows[0]);
21970
- rows[0].toEmpty();
21971
- editor.value.formatElementStack();
22359
+ const index = row.children.findIndex((item) => {
22360
+ return item.isEqual(columns[0]);
22361
+ });
22362
+ const previousRow = editor.value.getPreviousElement(row);
22363
+ const nextRow = editor.value.getNextElement(row);
22364
+ row.children.forEach((item, i) => {
22365
+ const itemSpanNum = getCellSpanNumber(item);
22366
+ if (item.hasMarks() && item.marks["data-editify-merged"]) {
22367
+ const { crossRowElement } = getCellMergeElement(editor.value, item);
22368
+ if (crossRowElement) {
22369
+ const { rowspan } = getCellSpanNumber(crossRowElement);
22370
+ if (rowspan - 1 == 1) {
22371
+ delete crossRowElement.marks["rowspan"];
22372
+ } else {
22373
+ crossRowElement.marks["rowspan"] = rowspan - 1;
22374
+ }
22375
+ }
22376
+ } else if (itemSpanNum.rowspan > 1) {
22377
+ let el = editor.value.getNextElement(row);
22378
+ if (el && itemSpanNum.rowspan - 1 > 1) {
22379
+ if (el.children[i].hasMarks()) {
22380
+ el.children[i].marks["rowspan"] = itemSpanNum.rowspan - 1;
22381
+ } else {
22382
+ el.children[i].marks = {
22383
+ rowspan: itemSpanNum.rowspan - 1
22384
+ };
22385
+ }
22386
+ }
22387
+ }
22388
+ });
22389
+ row.toEmpty();
21972
22390
  if (previousRow) {
21973
- editor.value.range.anchor.moveToEnd(previousRow.children[0]);
21974
- editor.value.range.focus.moveToEnd(previousRow.children[0]);
22391
+ editor.value.range.anchor.moveToEnd(previousRow.children[index]);
22392
+ editor.value.range.focus.moveToEnd(previousRow.children[index]);
21975
22393
  } else {
21976
- editor.value.range.anchor.moveToEnd(nextRow.children[0]);
21977
- editor.value.range.focus.moveToEnd(nextRow.children[0]);
22394
+ editor.value.range.anchor.moveToEnd(nextRow.children[index]);
22395
+ editor.value.range.focus.moveToEnd(nextRow.children[index]);
21978
22396
  }
22397
+ editor.value.formatElementStack();
21979
22398
  editor.value.domRender();
21980
22399
  editor.value.rangeRender();
21981
22400
  setTimeout(() => {
@@ -21989,28 +22408,50 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
21989
22408
  editor.value.range.anchor.offset = editor.value.range.focus.offset;
21990
22409
  }
21991
22410
  const columns = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: "td" });
21992
- const tbodys = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: "tbody" });
21993
- const tables = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: "table" });
21994
- if (tables.length == 1 && tbodys.length == 1 && columns.length == 1) {
21995
- const rows = tbodys[0].children;
21996
- const parent = columns[0].parent;
21997
- if (parent.children.length == 1) {
22411
+ if (columns.length == 1) {
22412
+ const row = columns[0].parent;
22413
+ const rows = row.parent.children;
22414
+ const table = row.parent.parent;
22415
+ if (row.children.length == 1) {
21998
22416
  deleteElement("table");
21999
22417
  return;
22000
22418
  }
22001
- const previousColumn = editor.value.getPreviousElement(columns[0]);
22002
- const nextColumn = editor.value.getNextElement(columns[0]);
22003
- const index = columns[0].parent.children.findIndex((item) => {
22419
+ const index = row.children.findIndex((item) => {
22004
22420
  return item.isEqual(columns[0]);
22005
22421
  });
22006
- rows.forEach((row) => {
22007
- row.children[index].toEmpty();
22422
+ const previousColumn = editor.value.getPreviousElement(columns[0]);
22423
+ const nextColumn = editor.value.getNextElement(columns[0]);
22424
+ rows.forEach((item) => {
22425
+ const cell = item.children[index];
22426
+ const cellSpanNum = getCellSpanNumber(cell);
22427
+ if (cell.hasMarks() && cell.marks["data-editify-merged"]) {
22428
+ const { crossColumnElement } = getCellMergeElement(editor.value, cell);
22429
+ if (crossColumnElement) {
22430
+ const { colspan } = getCellSpanNumber(crossColumnElement);
22431
+ if (colspan - 1 == 1) {
22432
+ delete crossColumnElement.marks["colspan"];
22433
+ } else {
22434
+ crossColumnElement.marks["colspan"] = colspan - 1;
22435
+ }
22436
+ }
22437
+ } else if (cellSpanNum.colspan > 1) {
22438
+ let el = editor.value.getNextElement(cell);
22439
+ if (el && cellSpanNum.colspan - 1 > 1) {
22440
+ if (el.hasMarks()) {
22441
+ el.marks["colspan"] = cellSpanNum.colspan - 1;
22442
+ } else {
22443
+ el.marks = {
22444
+ colspan: cellSpanNum.colspan - 1
22445
+ };
22446
+ }
22447
+ }
22448
+ }
22449
+ cell.toEmpty();
22008
22450
  });
22009
- const colgroup = tables[0].children.find((item) => {
22451
+ const colgroup = table.children.find((item) => {
22010
22452
  return item.parsedom == "colgroup";
22011
22453
  });
22012
22454
  colgroup.children[index].toEmpty();
22013
- editor.value.formatElementStack();
22014
22455
  if (previousColumn) {
22015
22456
  editor.value.range.anchor.moveToEnd(previousColumn);
22016
22457
  editor.value.range.focus.moveToEnd(previousColumn);
@@ -22018,10 +22459,188 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
22018
22459
  editor.value.range.anchor.moveToEnd(nextColumn);
22019
22460
  editor.value.range.focus.moveToEnd(nextColumn);
22020
22461
  }
22462
+ editor.value.formatElementStack();
22021
22463
  editor.value.domRender();
22022
22464
  editor.value.rangeRender();
22023
22465
  }
22024
22466
  };
22467
+ const mergeCells = (type) => {
22468
+ if (!canMergeCells.value(type)) {
22469
+ return;
22470
+ }
22471
+ if (!editor.value.range.anchor.isEqual(editor.value.range.focus)) {
22472
+ editor.value.range.anchor.element = editor.value.range.focus.element;
22473
+ editor.value.range.anchor.offset = editor.value.range.focus.offset;
22474
+ }
22475
+ const columns = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: "td" });
22476
+ if (columns.length == 1) {
22477
+ if (type == "left") {
22478
+ const cellSpanNum = getCellSpanNumber(columns[0]);
22479
+ const previousColumn = editor.value.getPreviousElement(columns[0]);
22480
+ if (previousColumn) {
22481
+ if (previousColumn.hasMarks() && previousColumn.marks["data-editify-merged"]) {
22482
+ const { crossColumnElement } = getCellMergeElement(editor.value, previousColumn);
22483
+ if (crossColumnElement) {
22484
+ const { rowspan, colspan } = getCellSpanNumber(crossColumnElement);
22485
+ if (rowspan == cellSpanNum.rowspan) {
22486
+ crossColumnElement.marks["colspan"] = colspan + cellSpanNum.colspan;
22487
+ columns[0].children.forEach((item) => {
22488
+ crossColumnElement.children.push(item);
22489
+ item.parent = crossColumnElement;
22490
+ });
22491
+ setTableCellMerged(columns[0]);
22492
+ editor.value.range.anchor.moveToEnd(crossColumnElement);
22493
+ editor.value.range.focus.moveToEnd(crossColumnElement);
22494
+ editor.value.formatElementStack();
22495
+ editor.value.domRender();
22496
+ editor.value.rangeRender();
22497
+ }
22498
+ }
22499
+ } else {
22500
+ const { rowspan, colspan } = getCellSpanNumber(previousColumn);
22501
+ if (rowspan == cellSpanNum.rowspan) {
22502
+ if (previousColumn.hasMarks()) {
22503
+ previousColumn.marks["colspan"] = colspan + cellSpanNum.colspan;
22504
+ } else {
22505
+ previousColumn.marks = {
22506
+ colspan: colspan + cellSpanNum.colspan
22507
+ };
22508
+ }
22509
+ columns[0].children.forEach((item) => {
22510
+ previousColumn.children.push(item);
22511
+ item.parent = previousColumn;
22512
+ });
22513
+ setTableCellMerged(columns[0]);
22514
+ editor.value.range.anchor.moveToEnd(previousColumn);
22515
+ editor.value.range.focus.moveToEnd(previousColumn);
22516
+ editor.value.formatElementStack();
22517
+ editor.value.domRender();
22518
+ editor.value.rangeRender();
22519
+ }
22520
+ }
22521
+ }
22522
+ } else if (type == "right") {
22523
+ const cellSpanNum = getCellSpanNumber(columns[0]);
22524
+ let nextColumn = editor.value.getNextElement(columns[0]);
22525
+ while (nextColumn) {
22526
+ if (nextColumn.hasMarks() && nextColumn.marks["data-editify-merged"]) {
22527
+ const { crossColumnElement } = getCellMergeElement(editor.value, nextColumn);
22528
+ if (crossColumnElement) {
22529
+ nextColumn = editor.value.getNextElement(nextColumn);
22530
+ } else {
22531
+ break;
22532
+ }
22533
+ } else {
22534
+ const { rowspan, colspan } = getCellSpanNumber(nextColumn);
22535
+ if (rowspan == cellSpanNum.rowspan) {
22536
+ if (columns[0].hasMarks()) {
22537
+ columns[0].marks["colspan"] = cellSpanNum.colspan + colspan;
22538
+ } else {
22539
+ columns[0].marks = {
22540
+ colspan: cellSpanNum.colspan + colspan
22541
+ };
22542
+ }
22543
+ nextColumn.children.forEach((item) => {
22544
+ columns[0].children.push(item);
22545
+ item.parent = columns[0];
22546
+ });
22547
+ setTableCellMerged(nextColumn);
22548
+ editor.value.range.anchor.moveToEnd(columns[0]);
22549
+ editor.value.range.focus.moveToEnd(columns[0]);
22550
+ editor.value.formatElementStack();
22551
+ editor.value.domRender();
22552
+ editor.value.rangeRender();
22553
+ }
22554
+ break;
22555
+ }
22556
+ }
22557
+ } else if (type == "up") {
22558
+ const cellSpanNum = getCellSpanNumber(columns[0]);
22559
+ const index = columns[0].parent.children.findIndex((item) => item.isEqual(columns[0]));
22560
+ const previousRow = editor.value.getPreviousElement(columns[0].parent);
22561
+ if (previousRow) {
22562
+ const previousColumn = previousRow.children[index];
22563
+ if (previousColumn.hasMarks() && previousColumn.marks["data-editify-merged"]) {
22564
+ const { crossRowElement } = getCellMergeElement(editor.value, previousColumn);
22565
+ if (crossRowElement) {
22566
+ const { rowspan, colspan } = getCellSpanNumber(crossRowElement);
22567
+ if (colspan == cellSpanNum.colspan) {
22568
+ crossRowElement.marks["rowspan"] = rowspan + cellSpanNum.rowspan;
22569
+ columns[0].children.forEach((item) => {
22570
+ crossRowElement.children.push(item);
22571
+ item.parent = crossRowElement;
22572
+ });
22573
+ setTableCellMerged(columns[0]);
22574
+ editor.value.range.anchor.moveToEnd(crossRowElement);
22575
+ editor.value.range.focus.moveToEnd(crossRowElement);
22576
+ editor.value.formatElementStack();
22577
+ editor.value.domRender();
22578
+ editor.value.rangeRender();
22579
+ }
22580
+ }
22581
+ } else {
22582
+ const { rowspan, colspan } = getCellSpanNumber(previousColumn);
22583
+ if (colspan == cellSpanNum.colspan) {
22584
+ if (previousColumn.hasMarks()) {
22585
+ previousColumn.marks["rowspan"] = rowspan + cellSpanNum.rowspan;
22586
+ } else {
22587
+ previousColumn.marks = {
22588
+ rowspan: rowspan + cellSpanNum.rowspan
22589
+ };
22590
+ }
22591
+ columns[0].children.forEach((item) => {
22592
+ previousColumn.children.push(item);
22593
+ item.parent = previousColumn;
22594
+ });
22595
+ setTableCellMerged(columns[0]);
22596
+ editor.value.range.anchor.moveToEnd(previousColumn);
22597
+ editor.value.range.focus.moveToEnd(previousColumn);
22598
+ editor.value.formatElementStack();
22599
+ editor.value.domRender();
22600
+ editor.value.rangeRender();
22601
+ }
22602
+ }
22603
+ }
22604
+ } else if (type == "down") {
22605
+ const cellSpanNum = getCellSpanNumber(columns[0]);
22606
+ const index = columns[0].parent.children.findIndex((item) => item.isEqual(columns[0]));
22607
+ let nextRow = editor.value.getNextElement(columns[0].parent);
22608
+ while (nextRow) {
22609
+ const nextColumn = nextRow.children[index];
22610
+ if (nextColumn.hasMarks() && nextColumn.marks["data-editify-merged"]) {
22611
+ const { crossRowElement } = getCellMergeElement(editor.value, nextColumn);
22612
+ if (crossRowElement) {
22613
+ nextRow = editor.value.getNextElement(nextRow);
22614
+ } else {
22615
+ break;
22616
+ }
22617
+ } else {
22618
+ const { rowspan, colspan } = getCellSpanNumber(nextColumn);
22619
+ if (colspan == cellSpanNum.colspan) {
22620
+ if (columns[0].hasMarks()) {
22621
+ columns[0].marks["rowspan"] = cellSpanNum.rowspan + rowspan;
22622
+ } else {
22623
+ columns[0].marks = {
22624
+ rowspan: cellSpanNum.rowspan + rowspan
22625
+ };
22626
+ }
22627
+ nextColumn.children.forEach((item) => {
22628
+ columns[0].children.push(item);
22629
+ item.parent = columns[0];
22630
+ });
22631
+ setTableCellMerged(nextColumn);
22632
+ editor.value.range.anchor.moveToEnd(columns[0]);
22633
+ editor.value.range.focus.moveToEnd(columns[0]);
22634
+ editor.value.formatElementStack();
22635
+ editor.value.domRender();
22636
+ editor.value.rangeRender();
22637
+ }
22638
+ break;
22639
+ }
22640
+ }
22641
+ }
22642
+ }
22643
+ };
22025
22644
  const layerShow = () => {
22026
22645
  if (props.type == "link") {
22027
22646
  const links = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: "a" });
@@ -22143,7 +22762,7 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
22143
22762
  return (_ctx, _cache) => {
22144
22763
  return openBlock(), createBlock(Layer, {
22145
22764
  modelValue: show.value,
22146
- "onUpdate:modelValue": _cache[21] || (_cache[21] = ($event) => show.value = $event),
22765
+ "onUpdate:modelValue": _cache[25] || (_cache[25] = ($event) => show.value = $event),
22147
22766
  ref_key: "layerRef",
22148
22767
  ref: layerRef,
22149
22768
  node: _ctx.node,
@@ -22478,7 +23097,63 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
22478
23097
  _: 1
22479
23098
  }, 8, ["title", "tooltip", "color"]),
22480
23099
  createVNode(Button, {
22481
- onOperate: _cache[18] || (_cache[18] = ($event) => deleteElement("table")),
23100
+ disabled: !canMergeCells.value("left"),
23101
+ onOperate: _cache[18] || (_cache[18] = ($event) => mergeCells("left")),
23102
+ rightBorder: "",
23103
+ name: "mergeCellsLeft",
23104
+ title: unref($editTrans)("mergeCellsLeft"),
23105
+ tooltip: _ctx.config.tooltip,
23106
+ color: _ctx.color
23107
+ }, {
23108
+ default: withCtx(() => [
23109
+ createVNode(Icon, { value: "merge-cells-left" })
23110
+ ]),
23111
+ _: 1
23112
+ }, 8, ["disabled", "title", "tooltip", "color"]),
23113
+ createVNode(Button, {
23114
+ disabled: !canMergeCells.value("right"),
23115
+ onOperate: _cache[19] || (_cache[19] = ($event) => mergeCells("right")),
23116
+ rightBorder: "",
23117
+ name: "mergeCellsRight",
23118
+ title: unref($editTrans)("mergeCellsRight"),
23119
+ tooltip: _ctx.config.tooltip,
23120
+ color: _ctx.color
23121
+ }, {
23122
+ default: withCtx(() => [
23123
+ createVNode(Icon, { value: "merge-cells-right" })
23124
+ ]),
23125
+ _: 1
23126
+ }, 8, ["disabled", "title", "tooltip", "color"]),
23127
+ createVNode(Button, {
23128
+ disabled: !canMergeCells.value("up"),
23129
+ onOperate: _cache[20] || (_cache[20] = ($event) => mergeCells("up")),
23130
+ rightBorder: "",
23131
+ name: "mergeCellsUp",
23132
+ title: unref($editTrans)("mergeCellsUp"),
23133
+ tooltip: _ctx.config.tooltip,
23134
+ color: _ctx.color
23135
+ }, {
23136
+ default: withCtx(() => [
23137
+ createVNode(Icon, { value: "merge-cells-up" })
23138
+ ]),
23139
+ _: 1
23140
+ }, 8, ["disabled", "title", "tooltip", "color"]),
23141
+ createVNode(Button, {
23142
+ disabled: !canMergeCells.value("down"),
23143
+ onOperate: _cache[21] || (_cache[21] = ($event) => mergeCells("down")),
23144
+ rightBorder: "",
23145
+ name: "mergeCellsDown",
23146
+ title: unref($editTrans)("mergeCellsDown"),
23147
+ tooltip: _ctx.config.tooltip,
23148
+ color: _ctx.color
23149
+ }, {
23150
+ default: withCtx(() => [
23151
+ createVNode(Icon, { value: "merge-cells-down" })
23152
+ ]),
23153
+ _: 1
23154
+ }, 8, ["disabled", "title", "tooltip", "color"]),
23155
+ createVNode(Button, {
23156
+ onOperate: _cache[22] || (_cache[22] = ($event) => deleteElement("table")),
22482
23157
  leftBorder: "",
22483
23158
  name: "deleteTable",
22484
23159
  title: unref($editTrans)("deleteTable"),
@@ -22493,7 +23168,7 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
22493
23168
  ], 64)) : createCommentVNode("", true),
22494
23169
  _ctx.type == "codeBlock" ? (openBlock(), createElementBlock(Fragment, { key: 4 }, [
22495
23170
  createVNode(Button, {
22496
- onOperate: _cache[19] || (_cache[19] = ($event) => insertParagraphWithPre("up")),
23171
+ onOperate: _cache[23] || (_cache[23] = ($event) => insertParagraphWithPre("up")),
22497
23172
  name: "textWrapUp",
22498
23173
  title: unref($editTrans)("textWrapUp"),
22499
23174
  tooltip: _ctx.config.tooltip,
@@ -22508,7 +23183,7 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
22508
23183
  _: 1
22509
23184
  }, 8, ["title", "tooltip", "color"]),
22510
23185
  createVNode(Button, {
22511
- onOperate: _cache[20] || (_cache[20] = ($event) => insertParagraphWithPre("down")),
23186
+ onOperate: _cache[24] || (_cache[24] = ($event) => insertParagraphWithPre("down")),
22512
23187
  name: "textWrapDown",
22513
23188
  title: unref($editTrans)("textWrapDown"),
22514
23189
  tooltip: _ctx.config.tooltip,
@@ -22864,7 +23539,7 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
22864
23539
  };
22865
23540
  }
22866
23541
  });
22867
- const Toolbar = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["__scopeId", "data-v-f6219d4c"]]);
23542
+ const Toolbar = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["__scopeId", "data-v-c1aa741f"]]);
22868
23543
  const InsertLinkProps = {
22869
23544
  //主题色
22870
23545
  color: {
@@ -25058,6 +25733,10 @@ const en_US = {
25058
25733
  insertColumnRight: "Insert column backward",
25059
25734
  deleteRow: "Delete rows",
25060
25735
  deleteColumn: "Delete column",
25736
+ mergeCellsLeft: "Merge cells to the left",
25737
+ mergeCellsRight: "Merge cells to the right",
25738
+ mergeCellsUp: "Merge cells up",
25739
+ mergeCellsDown: "Merge cells down",
25061
25740
  deleteTable: "Delete table",
25062
25741
  selectLanguages: "Select language",
25063
25742
  autoRecognize: "Auto",
@@ -25158,6 +25837,10 @@ const zh_CN = {
25158
25837
  insertColumnRight: "向后插入列",
25159
25838
  deleteRow: "删除行",
25160
25839
  deleteColumn: "删除列",
25840
+ mergeCellsLeft: "向左合并单元格",
25841
+ mergeCellsRight: "向右合并单元格",
25842
+ mergeCellsUp: "向上合并单元格",
25843
+ mergeCellsDown: "向下合并单元格",
25161
25844
  deleteTable: "删除表格",
25162
25845
  selectLanguages: "选择语言",
25163
25846
  autoRecognize: "自动识别",
@@ -25470,7 +26153,13 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
25470
26153
  commonElementHandle(editor.value, el);
25471
26154
  },
25472
26155
  (el) => {
25473
- tableHandle(editor.value, el);
26156
+ tableThTdHandle(editor.value, el);
26157
+ },
26158
+ (el) => {
26159
+ tableFormatHandle(editor.value, el);
26160
+ },
26161
+ (el) => {
26162
+ tableRangeMergedHandle(editor.value, el);
25474
26163
  },
25475
26164
  (el) => {
25476
26165
  var _a, _b, _c, _d, _e, _f, _g;
@@ -25670,6 +26359,15 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
25670
26359
  if (el.parsedom == "div" && el.marks["data-editify-task"]) {
25671
26360
  marks["data-editify-task"] = el.marks["data-editify-task"];
25672
26361
  }
26362
+ if (["td", "th"].includes(el.parsedom) && el.marks["colspan"]) {
26363
+ marks["colspan"] = el.marks["colspan"];
26364
+ }
26365
+ if (["td", "th"].includes(el.parsedom) && el.marks["rowspan"]) {
26366
+ marks["rowspan"] = el.marks["rowspan"];
26367
+ }
26368
+ if (["td", "th"].includes(el.parsedom) && el.marks["data-editify-merged"]) {
26369
+ marks["data-editify-merged"] = el.marks["data-editify-merged"];
26370
+ }
25673
26371
  }
25674
26372
  if (el.hasStyles()) {
25675
26373
  if ((el.isBlock() || el.isInblock()) && el.styles["text-indent"]) {
@@ -26061,7 +26759,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
26061
26759
  };
26062
26760
  }
26063
26761
  });
26064
- const Editify = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-fcc910d9"]]);
26762
+ const Editify = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-57a3c1ea"]]);
26065
26763
  const InsertAttachmentProps = {
26066
26764
  //主题色
26067
26765
  color: {
@@ -41185,7 +41883,7 @@ const attachment = (options) => {
41185
41883
  const install = (app) => {
41186
41884
  app.component(Editify.name, Editify);
41187
41885
  };
41188
- const version = "0.1.42";
41886
+ const version = "0.1.44";
41189
41887
  console.log(`%c vue-editify %c v${version} `, "padding: 2px 1px; border-radius: 3px 0 0 3px; color: #fff; background: #606060; font-weight: bold;", "padding: 2px 1px; border-radius: 0 3px 3px 0; color: #fff; background: #42c02e; font-weight: bold;");
41190
41888
  export {
41191
41889
  AlexElement,
@@ -41213,6 +41911,7 @@ export {
41213
41911
  insertCodeBlock,
41214
41912
  insertImage,
41215
41913
  insertLink,
41914
+ insertSeparator,
41216
41915
  insertTable,
41217
41916
  insertVideo,
41218
41917
  install,