vue-editify 0.1.42 → 0.1.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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,