@textbus/xnote 0.0.4 → 0.0.6

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.
Files changed (66) hide show
  1. package/bundles/components/button/button.d.ts +2 -3
  2. package/bundles/components/component-toolbar/component-toolbar.d.ts +1 -1
  3. package/bundles/components/divider/divider.d.ts +1 -1
  4. package/bundles/components/drag-resize/drag-resize.d.ts +1 -1
  5. package/bundles/components/dropdown/dropdown-menu.d.ts +1 -1
  6. package/bundles/components/dropdown/dropdown.d.ts +1 -1
  7. package/bundles/components/keymap/keymap.d.ts +2 -1
  8. package/bundles/components/menu-heading/menu-heading.d.ts +1 -1
  9. package/bundles/components/menu-item/menu-item.d.ts +1 -1
  10. package/bundles/components/popup/popup.d.ts +1 -1
  11. package/bundles/components/toolbar-item/toolbar-item.d.ts +1 -1
  12. package/bundles/fonts/textbus.svg +7 -1
  13. package/bundles/fonts/textbus.ttf +0 -0
  14. package/bundles/fonts/textbus.woff +0 -0
  15. package/bundles/index.css +1 -1
  16. package/bundles/index.esm.css +1 -1
  17. package/bundles/index.esm.js +904 -377
  18. package/bundles/index.js +908 -376
  19. package/bundles/plugins/_common/_api.d.ts +1 -0
  20. package/bundles/plugins/_common/attr.tool.d.ts +1 -1
  21. package/bundles/plugins/_common/block.tool.d.ts +1 -1
  22. package/bundles/plugins/_common/bold.tool.d.ts +1 -1
  23. package/bundles/plugins/_common/code.tool.d.ts +1 -1
  24. package/bundles/plugins/_common/color.tool.d.ts +1 -1
  25. package/bundles/plugins/_common/font-family.tool.d.ts +1 -1
  26. package/bundles/plugins/_common/font-size.tool.d.ts +1 -1
  27. package/bundles/plugins/_common/italic.tool.d.ts +1 -1
  28. package/bundles/plugins/_common/link.tool.d.ts +1 -1
  29. package/bundles/plugins/_common/strike-through.tool.d.ts +1 -1
  30. package/bundles/plugins/_common/table/_api.d.ts +4 -0
  31. package/bundles/plugins/_common/table/cell-align.tool.d.ts +1 -0
  32. package/bundles/plugins/_common/table/cell-background.tool.d.ts +1 -0
  33. package/bundles/plugins/_common/table/merge-cells.tool.d.ts +1 -0
  34. package/bundles/plugins/_common/table/split-cells.tool.d.ts +1 -0
  35. package/bundles/plugins/_common/underline.tool.d.ts +1 -1
  36. package/bundles/plugins/left-toolbar/insert-tool.d.ts +1 -1
  37. package/bundles/plugins/left-toolbar/left-toolbar.d.ts +1 -1
  38. package/bundles/plugins/link-jump/link-jump.d.ts +1 -1
  39. package/bundles/plugins/toolbar/toolbar.d.ts +1 -1
  40. package/bundles/textbus/attributes/_api.d.ts +1 -0
  41. package/bundles/textbus/attributes/cell-align.attr.d.ts +4 -0
  42. package/bundles/textbus/components/at/at-component.view.d.ts +1 -1
  43. package/bundles/textbus/components/blockqoute/blockquote.component.d.ts +1 -1
  44. package/bundles/textbus/components/highlight-box/highlight-box.component.d.ts +1 -1
  45. package/bundles/textbus/components/image/image.component.d.ts +1 -1
  46. package/bundles/textbus/components/katex/katex.component.d.ts +1 -1
  47. package/bundles/textbus/components/list/list.component.d.ts +1 -1
  48. package/bundles/textbus/components/paragraph/paragraph.component.d.ts +1 -1
  49. package/bundles/textbus/components/root/root.component.d.ts +1 -1
  50. package/bundles/textbus/components/source-code/source-code.component.d.ts +1 -1
  51. package/bundles/textbus/components/step/step-component.view.d.ts +1 -1
  52. package/bundles/textbus/components/table/components/left-bar.d.ts +1 -1
  53. package/bundles/textbus/components/table/components/resize-column.d.ts +1 -1
  54. package/bundles/textbus/components/table/components/resize-row.d.ts +1 -1
  55. package/bundles/textbus/components/table/components/scroll.d.ts +1 -1
  56. package/bundles/textbus/components/table/components/selection-mask.d.ts +1 -1
  57. package/bundles/textbus/components/table/components/top-bar.d.ts +1 -1
  58. package/bundles/textbus/components/table/table-component.view.d.ts +2 -3
  59. package/bundles/textbus/components/table/table.component.d.ts +30 -7
  60. package/bundles/textbus/components/table/table.service.d.ts +0 -8
  61. package/bundles/textbus/components/table/tools/complete.d.ts +19 -0
  62. package/bundles/textbus/components/table/tools/merge.d.ts +23 -0
  63. package/bundles/textbus/components/timeline/timeline-component.view.d.ts +1 -1
  64. package/bundles/textbus/components/todolist/todolist.component.d.ts +1 -1
  65. package/bundles/textbus/components/video/video.component.d.ts +1 -1
  66. package/package.json +14 -11
package/bundles/index.js CHANGED
@@ -8,6 +8,7 @@ var platformBrowser = require('@textbus/platform-browser');
8
8
  var platformBrowser$1 = require('@viewfly/platform-browser');
9
9
  var hooks = require('@viewfly/hooks');
10
10
  var highlightjs = require('highlight.js');
11
+ var uuid = require('uuid');
11
12
  var Katex = require('katex');
12
13
  var adapterViewfly = require('@textbus/adapter-viewfly');
13
14
  var color = require('@tanbo/color');
@@ -29,7 +30,7 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
29
30
  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
30
31
  PERFORMANCE OF THIS SOFTWARE.
31
32
  ***************************************************************************** */
32
- /* global Reflect, Promise, SuppressedError, Symbol */
33
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
33
34
 
34
35
 
35
36
  function __rest(s, e) {
@@ -482,7 +483,7 @@ var scopedId$h = "vf-c32a7b";
482
483
  function Keymap(props) {
483
484
  const arr = [];
484
485
  const keymap = props.keymap;
485
- if (keymap.ctrlKey) {
486
+ if (keymap.modKey) {
486
487
  arr.push(platformBrowser.isMac() ? jsxRuntime.jsx("span", { class: "xnote-icon-command" }) : jsxRuntime.jsx("span", { children: "Ctrl" }));
487
488
  }
488
489
  if (keymap.shiftKey) {
@@ -504,6 +505,9 @@ function Keymap(props) {
504
505
  if (Array.isArray(keymap.key)) {
505
506
  arr.push(jsxRuntime.jsx("span", { children: keymap.key.join('/') }));
506
507
  }
508
+ else if (typeof keymap.key === 'object') {
509
+ arr.push(jsxRuntime.jsx("span", { children: keymap.key.name }));
510
+ }
507
511
  else {
508
512
  arr.push(jsxRuntime.jsx("span", { children: keymap.key }));
509
513
  }
@@ -604,7 +608,7 @@ function registerTextAlignShortcut(textbus) {
604
608
  keyboard.addShortcut({
605
609
  keymap: {
606
610
  key: 'lrej'.split(''),
607
- ctrlKey: true
611
+ modKey: true
608
612
  },
609
613
  action(key) {
610
614
  const valueMap = {
@@ -662,7 +666,7 @@ function registerHeadingShortcut(textbus) {
662
666
  keyboard.addShortcut({
663
667
  keymap: {
664
668
  key: '0123456'.split(''),
665
- ctrlKey: true
669
+ modKey: true
666
670
  },
667
671
  action(key) {
668
672
  if (key === '0') {
@@ -823,7 +827,7 @@ function registerBlockquoteShortcut(textbus) {
823
827
  const keyboard = textbus.get(core$1.Keyboard);
824
828
  keyboard.addShortcut({
825
829
  keymap: {
826
- ctrlKey: true,
830
+ modKey: true,
827
831
  key: '\''
828
832
  },
829
833
  action() {
@@ -1770,16 +1774,16 @@ function AttrTool(props) {
1770
1774
  const states = checkStates();
1771
1775
  return (jsxRuntime.jsx(Dropdown, { width: 'auto', style: props.style, abreast: props.abreast, onCheck: updateAttr, trigger: 'hover', menu: [
1772
1776
  {
1773
- label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-paragraph-left" }), desc: jsxRuntime.jsx(Keymap, { keymap: { key: 'L', ctrlKey: true } }), checked: states.textAlign === 'left', children: "\u5DE6\u5BF9\u9F50" }),
1777
+ label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-paragraph-left" }), desc: jsxRuntime.jsx(Keymap, { keymap: { key: 'L', modKey: true } }), checked: states.textAlign === 'left', children: "\u5DE6\u5BF9\u9F50" }),
1774
1778
  value: 't-l'
1775
1779
  }, {
1776
- label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-paragraph-right" }), desc: jsxRuntime.jsx(Keymap, { keymap: { key: 'R', ctrlKey: true } }), checked: states.textAlign === 'right', children: "\u53F3\u5BF9\u9F50" }),
1780
+ label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-paragraph-right" }), desc: jsxRuntime.jsx(Keymap, { keymap: { key: 'R', modKey: true } }), checked: states.textAlign === 'right', children: "\u53F3\u5BF9\u9F50" }),
1777
1781
  value: 't-r'
1778
1782
  }, {
1779
- label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-paragraph-center" }), desc: jsxRuntime.jsx(Keymap, { keymap: { key: 'E', ctrlKey: true } }), checked: states.textAlign === 'center', children: "\u5C45\u4E2D\u5BF9\u9F50" }),
1783
+ label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-paragraph-center" }), desc: jsxRuntime.jsx(Keymap, { keymap: { key: 'E', modKey: true } }), checked: states.textAlign === 'center', children: "\u5C45\u4E2D\u5BF9\u9F50" }),
1780
1784
  value: 't-c'
1781
1785
  }, {
1782
- label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-paragraph-justify" }), desc: jsxRuntime.jsx(Keymap, { keymap: { key: 'J', ctrlKey: true } }), checked: states.textAlign === 'justify', children: "\u5206\u6563\u5BF9\u9F50" }),
1786
+ label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-paragraph-justify" }), desc: jsxRuntime.jsx(Keymap, { keymap: { key: 'J', modKey: true } }), checked: states.textAlign === 'justify', children: "\u5206\u6563\u5BF9\u9F50" }),
1783
1787
  value: 't-j'
1784
1788
  }, {
1785
1789
  label: jsxRuntime.jsx(Divider, {}),
@@ -1795,20 +1799,99 @@ function AttrTool(props) {
1795
1799
  });
1796
1800
  }
1797
1801
 
1802
+ class Rectangle {
1803
+ constructor(x1, y1, x2, y2) {
1804
+ this.x1 = x1;
1805
+ this.y1 = y1;
1806
+ this.x2 = x2;
1807
+ this.y2 = y2;
1808
+ }
1809
+ intersects(other) {
1810
+ return this.x1 < other.x2 && this.x2 > other.x1 && this.y1 < other.y2 && this.y2 > other.y1;
1811
+ }
1812
+ merge(other) {
1813
+ return new Rectangle(Math.min(this.x1, other.x1), Math.min(this.y1, other.y1), Math.max(this.x2, other.x2), Math.max(this.y2, other.y2));
1814
+ }
1815
+ }
1816
+ function findNonIntersectingRectangles(rectangles) {
1817
+ const merged = [];
1818
+ const remaining = [...rectangles];
1819
+ while (remaining.length > 0) {
1820
+ const current = remaining.shift();
1821
+ let mergedWithCurrent = false;
1822
+ for (let i = 0; i < merged.length; i++) {
1823
+ if (current.intersects(merged[i])) {
1824
+ merged[i] = current.merge(merged[i]);
1825
+ mergedWithCurrent = true;
1826
+ break;
1827
+ }
1828
+ }
1829
+ if (!mergedWithCurrent) {
1830
+ merged.push(current);
1831
+ }
1832
+ }
1833
+ return merged;
1834
+ }
1835
+ function getMaxRectangle(start, rectangles) {
1836
+ let merged = start;
1837
+ const remaining = [...rectangles];
1838
+ while (remaining.length > 0) {
1839
+ const current = remaining.shift();
1840
+ if (current.intersects(merged)) {
1841
+ merged = current.merge(merged);
1842
+ }
1843
+ }
1844
+ return merged;
1845
+ }
1846
+ function applyRectangles(rows, rectangles) {
1847
+ const table = rows.map(row => {
1848
+ return {
1849
+ row,
1850
+ cells: row.cells.map(cell => {
1851
+ return {
1852
+ rowspan: 1,
1853
+ colspan: 1,
1854
+ visible: true,
1855
+ raw: cell
1856
+ };
1857
+ })
1858
+ };
1859
+ });
1860
+ rectangles.forEach(rect => {
1861
+ const { x1, y1, x2, y2 } = rect;
1862
+ const rowspan = y2 - y1;
1863
+ const colspan = x2 - x1;
1864
+ for (let i = y1; i < y2; i++) {
1865
+ for (let j = x1; j < x2; j++) {
1866
+ const item = table[i].cells[j];
1867
+ if (i === y1 && j === x1) {
1868
+ item.visible = true;
1869
+ item.rowspan = rowspan;
1870
+ item.colspan = colspan;
1871
+ }
1872
+ else {
1873
+ item.visible = false;
1874
+ }
1875
+ }
1876
+ }
1877
+ });
1878
+ return table;
1879
+ }
1880
+
1798
1881
  const defaultRowHeight = 30;
1799
1882
  const defaultColumnWidth = 100;
1800
1883
  class TableComponent extends core$1.Component {
1801
1884
  static fromJSON(textbus, json) {
1802
1885
  const registry = textbus.get(core$1.Registry);
1803
1886
  return new TableComponent(textbus, {
1804
- layoutWidth: json.layoutWidth || [],
1887
+ columnsConfig: json.columnsConfig || [],
1888
+ mergeConfig: json.mergeConfig || [],
1805
1889
  rows: json.rows.map(row => {
1806
1890
  return {
1807
1891
  height: row.height,
1808
1892
  cells: row.cells.map(cell => {
1809
1893
  return {
1810
- colspan: cell.colspan,
1811
- rowspan: cell.rowspan,
1894
+ id: cell.id,
1812
1895
  slot: registry.createSlot(cell.slot)
1813
1896
  };
1814
1897
  })
@@ -1817,7 +1900,8 @@ class TableComponent extends core$1.Component {
1817
1900
  });
1818
1901
  }
1819
1902
  constructor(textbus, state = {
1820
- layoutWidth: Array.from({ length: 5 }).fill(100),
1903
+ columnsConfig: Array.from({ length: 5 }).fill(defaultColumnWidth),
1904
+ mergeConfig: {},
1821
1905
  rows: Array.from({ length: 3 }).map(() => {
1822
1906
  return {
1823
1907
  height: defaultRowHeight,
@@ -1826,9 +1910,8 @@ class TableComponent extends core$1.Component {
1826
1910
  const slot = new core$1.Slot([core$1.ContentType.BlockComponent]);
1827
1911
  slot.insert(p);
1828
1912
  return {
1829
- rowspan: 1,
1830
- colspan: 1,
1831
- slot
1913
+ slot,
1914
+ id: uuid.v4()
1832
1915
  };
1833
1916
  })
1834
1917
  };
@@ -1836,11 +1919,236 @@ class TableComponent extends core$1.Component {
1836
1919
  }) {
1837
1920
  super(textbus, state);
1838
1921
  this.selection = this.textbus.get(core$1.Selection);
1922
+ this.commander = this.textbus.get(core$1.Commander);
1839
1923
  this.focus = new core$1.Subject();
1840
1924
  this.tableSelection = core.createSignal(null);
1925
+ this.ignoreSelectionChanges = false;
1926
+ this.normalizedData = [];
1841
1927
  }
1842
1928
  getSlots() {
1843
- return this.state.rows.map(i => i.cells.map(j => j.slot)).flat();
1929
+ return this.normalizedData.map(item => {
1930
+ return item.cells.filter(i => i.visible).map(i => i.raw.slot);
1931
+ }).flat();
1932
+ }
1933
+ mergeCellBySelection() {
1934
+ var _a, _b, _c, _d;
1935
+ const slots = this.getSelectedNormalizedSlots();
1936
+ if (slots) {
1937
+ const start = (_b = (_a = slots.at(0)) === null || _a === void 0 ? void 0 : _a.cells.at(0)) === null || _b === void 0 ? void 0 : _b.raw;
1938
+ const end = (_d = (_c = slots.at(-1)) === null || _c === void 0 ? void 0 : _c.cells.at(-1)) === null || _d === void 0 ? void 0 : _d.raw;
1939
+ if (start && end) {
1940
+ slots.forEach(item => {
1941
+ item.cells.forEach(cell => {
1942
+ if (cell.raw.id === start.id) {
1943
+ return;
1944
+ }
1945
+ cell.raw.slot.cleanFormats();
1946
+ cell.raw.slot.cleanAttributes();
1947
+ cell.raw.slot.retain(0);
1948
+ cell.raw.slot.delete(cell.raw.slot.length);
1949
+ Reflect.deleteProperty(this.state.mergeConfig, cell.raw.id);
1950
+ });
1951
+ });
1952
+ this.state.mergeConfig[start.id] = end.id;
1953
+ }
1954
+ }
1955
+ this.selection.collapse(true);
1956
+ }
1957
+ splitCellsBySelection() {
1958
+ var _a, _b, _c, _d;
1959
+ const slots = this.getSelectedNormalizedSlots();
1960
+ if (slots) {
1961
+ slots.forEach(item => {
1962
+ item.cells.forEach(cell => {
1963
+ Reflect.deleteProperty(this.state.mergeConfig, cell.raw.id);
1964
+ });
1965
+ });
1966
+ const start = (_b = (_a = slots.at(0)) === null || _a === void 0 ? void 0 : _a.cells.at(0)) === null || _b === void 0 ? void 0 : _b.raw;
1967
+ const end = (_d = (_c = slots.at(-1)) === null || _c === void 0 ? void 0 : _c.cells.at(-1)) === null || _d === void 0 ? void 0 : _d.raw;
1968
+ if (start && end) {
1969
+ this.selection.setBaseAndExtent(start.slot, 0, end.slot, end.slot.length);
1970
+ }
1971
+ }
1972
+ }
1973
+ getMaxRectangle(startSlot, endSlot) {
1974
+ let index1 = -1;
1975
+ let index2 = -1;
1976
+ let x1 = -1;
1977
+ let x2 = -1;
1978
+ let y1 = -1;
1979
+ let y2 = -1;
1980
+ let index = 0;
1981
+ for (let i = 0; i < this.state.rows.length; i++) {
1982
+ const row = this.state.rows[i];
1983
+ for (let j = 0; j < row.cells.length; j++) {
1984
+ const item = row.cells[j];
1985
+ if (item.slot === startSlot) {
1986
+ index1 = index;
1987
+ x1 = j;
1988
+ y1 = i;
1989
+ }
1990
+ if (item.slot === endSlot) {
1991
+ index2 = index;
1992
+ x2 = j;
1993
+ y2 = i;
1994
+ }
1995
+ index++;
1996
+ }
1997
+ }
1998
+ if (index1 === -1 || index2 === -1) {
1999
+ return null;
2000
+ }
2001
+ if (x1 > x2) {
2002
+ [x1, x2] = [x2, x1];
2003
+ }
2004
+ if (y1 > y2) {
2005
+ [y1, y2] = [y2, y1];
2006
+ }
2007
+ return getMaxRectangle(new Rectangle(x1, y1, x2 + 1, y2 + 1), this.getMergedRectangles());
2008
+ }
2009
+ getSelectedNormalizedSlots() {
2010
+ const rect = this.getSelectedRect();
2011
+ if (rect) {
2012
+ return this.getSelectedNormalizedSlotsByRectangle(rect);
2013
+ }
2014
+ return null;
2015
+ }
2016
+ getSelectedRect() {
2017
+ const getSelfSlot = (slot) => {
2018
+ let cell = slot;
2019
+ while ((cell === null || cell === void 0 ? void 0 : cell.parent) && cell.parent !== this) {
2020
+ cell = cell.parentSlot;
2021
+ }
2022
+ return cell;
2023
+ };
2024
+ const start = getSelfSlot(this.selection.startSlot);
2025
+ const end = getSelfSlot(this.selection.endSlot);
2026
+ if (start && end) {
2027
+ return this.getMaxRectangle(start, end);
2028
+ }
2029
+ return null;
2030
+ }
2031
+ getSelectedNormalizedSlotsByRectangle(rectangle) {
2032
+ return this.normalizedData.slice(rectangle.y1, rectangle.y2).map(item => {
2033
+ return {
2034
+ row: item.row,
2035
+ cells: item.cells.slice(rectangle.x1, rectangle.x2)
2036
+ };
2037
+ });
2038
+ }
2039
+ getCellBySlot(slot) {
2040
+ for (const row of this.state.rows) {
2041
+ for (const cell of row.cells) {
2042
+ if (cell.slot === slot) {
2043
+ return cell;
2044
+ }
2045
+ }
2046
+ }
2047
+ return null;
2048
+ }
2049
+ getNormalizedData() {
2050
+ if (!this.changeMarker.dirty) {
2051
+ return this.normalizedData;
2052
+ }
2053
+ const nonIntersectingRectangles = this.getMergedRectangles();
2054
+ this.normalizedData = applyRectangles(this.state.rows, nonIntersectingRectangles);
2055
+ return this.normalizedData;
2056
+ }
2057
+ selectRow(startIndex, endIndex = startIndex + 1) {
2058
+ if (startIndex > endIndex) {
2059
+ [startIndex, endIndex] = [endIndex, startIndex];
2060
+ }
2061
+ if (startIndex === endIndex) {
2062
+ endIndex++;
2063
+ }
2064
+ const selectedSlots = [];
2065
+ const rows = this.getNormalizedData();
2066
+ rows.slice(startIndex, endIndex).forEach(row => {
2067
+ selectedSlots.push(...row.cells.filter(i => i.visible).map(i => i.raw.slot));
2068
+ });
2069
+ this.ignoreSelectionChanges = true;
2070
+ const slotRanges = selectedSlots.map(i => {
2071
+ return {
2072
+ slot: i,
2073
+ startIndex: 0,
2074
+ endIndex: i.length
2075
+ };
2076
+ });
2077
+ this.selection.setSelectedRanges(slotRanges);
2078
+ this.tableSelection.set({
2079
+ startColumn: 0,
2080
+ endColumn: this.state.columnsConfig.length,
2081
+ startRow: startIndex,
2082
+ endRow: endIndex,
2083
+ });
2084
+ this.focus.next(true);
2085
+ if (slotRanges.length) {
2086
+ setTimeout(() => {
2087
+ this.selection.restore();
2088
+ this.textbus.focus();
2089
+ });
2090
+ }
2091
+ }
2092
+ selectColumn(startIndex, endIndex = startIndex + 1) {
2093
+ if (startIndex > endIndex) {
2094
+ [startIndex, endIndex] = [endIndex, startIndex];
2095
+ }
2096
+ if (startIndex === endIndex) {
2097
+ endIndex++;
2098
+ }
2099
+ const selectedSlots = [];
2100
+ const rows = this.getNormalizedData();
2101
+ rows.forEach(row => {
2102
+ selectedSlots.push(...row.cells.slice(startIndex, endIndex).filter(i => i.visible).map(i => i.raw.slot));
2103
+ });
2104
+ this.ignoreSelectionChanges = true;
2105
+ const slotRanges = selectedSlots.map(i => {
2106
+ return {
2107
+ slot: i,
2108
+ startIndex: 0,
2109
+ endIndex: i.length
2110
+ };
2111
+ });
2112
+ this.selection.setSelectedRanges(slotRanges);
2113
+ this.tableSelection.set({
2114
+ startColumn: startIndex,
2115
+ endColumn: endIndex,
2116
+ startRow: 0,
2117
+ endRow: this.state.rows.length,
2118
+ });
2119
+ this.focus.next(true);
2120
+ this.selection.restore();
2121
+ this.textbus.focus();
2122
+ // if (slotRanges.length) {
2123
+ // setTimeout(() => {
2124
+ // this.selection.restore()
2125
+ // this.textbus.focus()
2126
+ // })
2127
+ // }
2128
+ }
2129
+ getMergedRectangles() {
2130
+ const rectangles = [];
2131
+ Object.entries(this.state.mergeConfig).forEach(([key, value]) => {
2132
+ const p1 = this.getCoordinateById(key);
2133
+ if (p1) {
2134
+ const p2 = this.getCoordinateById(value);
2135
+ if (p2) {
2136
+ rectangles.push(new Rectangle(p1[0], p1[1], p2[0] + 1, p2[1] + 1));
2137
+ }
2138
+ }
2139
+ });
2140
+ return findNonIntersectingRectangles(rectangles);
2141
+ }
2142
+ getCoordinateById(id) {
2143
+ const rows = this.state.rows;
2144
+ for (let i = 0; i < rows.length; i++) {
2145
+ const row = rows[i];
2146
+ const colIndex = row.cells.findIndex(i => i.id === id);
2147
+ if (colIndex > -1) {
2148
+ return [colIndex, i];
2149
+ }
2150
+ }
2151
+ return null;
1844
2152
  }
1845
2153
  setup() {
1846
2154
  const selection = core$1.useContext(core$1.Selection);
@@ -1854,6 +2162,9 @@ class TableComponent extends core$1.Component {
1854
2162
  return slot.parent === this;
1855
2163
  });
1856
2164
  const sub = selection.onChange.subscribe(() => {
2165
+ if (this.ignoreSelectionChanges) {
2166
+ return;
2167
+ }
1857
2168
  if (selection.commonAncestorComponent !== this || selection.isCollapsed) {
1858
2169
  this.tableSelection.set(null);
1859
2170
  }
@@ -1861,115 +2172,109 @@ class TableComponent extends core$1.Component {
1861
2172
  core$1.onDestroy(() => {
1862
2173
  sub.unsubscribe();
1863
2174
  });
1864
- const findPosition = (slot) => {
1865
- let cell = slot;
1866
- while ((cell === null || cell === void 0 ? void 0 : cell.parent) && cell.parent !== this) {
1867
- cell = cell.parentSlot;
2175
+ core$1.onGetRanges(ev => {
2176
+ if (this.selection.isCollapsed || this.ignoreSelectionChanges) {
2177
+ return;
1868
2178
  }
1869
- if (cell) {
1870
- const rows = this.state.rows;
1871
- for (let rowIndex = 0; rowIndex < rows.length; rowIndex++) {
1872
- const row = rows[rowIndex].cells;
1873
- for (let colIndex = 0; colIndex < row.length; colIndex++) {
1874
- const item = row[colIndex].slot;
1875
- if (item === cell) {
1876
- return {
1877
- rowIndex,
1878
- colIndex
1879
- };
1880
- }
1881
- }
2179
+ const rect = this.getSelectedRect();
2180
+ if (rect) {
2181
+ this.tableSelection.set({
2182
+ startColumn: rect.x1,
2183
+ endColumn: rect.x2,
2184
+ startRow: rect.y1,
2185
+ endRow: rect.y2
2186
+ });
2187
+ const selectedSlots = this.getSelectedNormalizedSlotsByRectangle(rect);
2188
+ const slotRanges = selectedSlots.map(item => {
2189
+ return item.cells.filter(i => {
2190
+ return i.visible;
2191
+ }).map(i => {
2192
+ return {
2193
+ startIndex: 0,
2194
+ endIndex: i.raw.slot.length,
2195
+ slot: i.raw.slot
2196
+ };
2197
+ });
2198
+ }).flat();
2199
+ if (slotRanges.length > 1) {
2200
+ ev.useRanges(slotRanges);
1882
2201
  }
1883
2202
  }
1884
- return null;
1885
- };
1886
- const select = (ev, selectPosition) => {
1887
- this.tableSelection.set(selectPosition);
1888
- if (selectPosition) {
1889
- const cells = [];
1890
- this.state.rows.slice(selectPosition.startRow, selectPosition.endRow).forEach(row => {
1891
- cells.push(...row.cells.slice(selectPosition.startColumn, selectPosition.endColumn).map(i => i.slot));
1892
- });
1893
- ev.useRanges(cells.map(i => {
1894
- return {
1895
- slot: i,
1896
- startIndex: 0,
1897
- endIndex: i.length
1898
- };
1899
- }));
1900
- ev.preventDefault();
2203
+ });
2204
+ }
2205
+ deleteColumns() {
2206
+ const selection = this.tableSelection();
2207
+ if (selection) {
2208
+ const { startColumn, endColumn } = selection;
2209
+ if (startColumn === 0 && endColumn === this.state.columnsConfig.length) {
2210
+ this.commander.removeComponent(this);
2211
+ return;
1901
2212
  }
1902
- };
1903
- core$1.onGetRanges(ev => {
1904
- var _a;
1905
- const startPosition = findPosition(selection.startSlot);
1906
- const endPosition = findPosition(selection.endSlot);
1907
- if (startPosition && endPosition) {
1908
- if (startPosition.rowIndex === endPosition.rowIndex && startPosition.colIndex === endPosition.colIndex) {
1909
- if (selection.startSlot === selection.endSlot && selection.startOffset === 0 && selection.endOffset === ((_a = selection.startSlot) === null || _a === void 0 ? void 0 : _a.length)) {
1910
- select(ev, {
1911
- startColumn: startPosition.colIndex,
1912
- startRow: startPosition.rowIndex,
1913
- endColumn: endPosition.colIndex + 1,
1914
- endRow: endPosition.rowIndex + 1
2213
+ this.state.columnsConfig.splice(startColumn, endColumn - startColumn);
2214
+ const mergeConfig = this.state.mergeConfig;
2215
+ const keys = Object.keys(mergeConfig);
2216
+ this.state.rows.forEach(row => {
2217
+ const before = row.cells.at(startColumn - 1);
2218
+ const after = row.cells.at(endColumn);
2219
+ const cells = row.cells.splice(startColumn, endColumn - startColumn);
2220
+ cells.forEach(cell => {
2221
+ if (keys.includes(cell.id)) {
2222
+ if (after) {
2223
+ mergeConfig[after.id] = mergeConfig[cell.id];
2224
+ }
2225
+ Reflect.deleteProperty(mergeConfig, cell.id);
2226
+ }
2227
+ if (before) {
2228
+ keys.forEach(key => {
2229
+ if (mergeConfig[key] === cell.id) {
2230
+ mergeConfig[key] = before.id;
2231
+ }
1915
2232
  });
1916
- return;
1917
2233
  }
1918
- select(ev, null);
1919
- return;
1920
- }
1921
- const [startColumn, endColumn] = [startPosition.colIndex, endPosition.colIndex].sort((a, b) => a - b);
1922
- const [startRow, endRow] = [startPosition.rowIndex, endPosition.rowIndex].sort((a, b) => a - b);
1923
- select(ev, {
1924
- startColumn,
1925
- startRow,
1926
- endColumn: endColumn + 1,
1927
- endRow: endRow + 1
1928
2234
  });
1929
- }
1930
- else {
1931
- select(ev, null);
1932
- }
1933
- });
1934
- }
1935
- // afterContentCheck() {
1936
- // const selection = this.selection
1937
- // const rows = this.state.rows
1938
- // rows.forEach(row => {
1939
- // row.cells.forEach(cell => {
1940
- // const slot = cell.slot
1941
- // if (slot.isEmpty) {
1942
- // const childSlot = new Slot([
1943
- // ContentType.Text,
1944
- // ContentType.InlineComponent
1945
- // ])
1946
- // const p = new ParagraphComponent(this.textbus, {
1947
- // slot: childSlot
1948
- // })
1949
- // slot.insert(p)
1950
- // if (slot === selection.anchorSlot) {
1951
- // selection.setAnchor(childSlot, 0)
1952
- // }
1953
- // if (slot === selection.focusSlot) {
1954
- // selection.setFocus(childSlot, 0)
1955
- // }
1956
- // }
1957
- // })
1958
- // })
1959
- // }
1960
- deleteColumn(index) {
1961
- this.state.layoutWidth.splice(index, 1);
1962
- this.state.rows.forEach(row => {
1963
- row.cells.splice(index, 1);
1964
- });
2235
+ });
2236
+ }
2237
+ this.tableSelection.set(null);
1965
2238
  this.selection.unSelect();
1966
2239
  }
1967
- deleteRow(index) {
1968
- this.state.rows.splice(index, 1);
2240
+ deleteRows() {
2241
+ const selection = this.tableSelection();
2242
+ if (selection) {
2243
+ const { startRow, endRow } = selection;
2244
+ if (startRow === 0 && endRow === this.state.rows.length) {
2245
+ this.commander.removeComponent(this);
2246
+ return;
2247
+ }
2248
+ const mergeConfig = this.state.mergeConfig;
2249
+ const keys = Object.keys(mergeConfig);
2250
+ const rows = this.state.rows;
2251
+ const deletedRows = rows.splice(startRow, endRow - startRow);
2252
+ deletedRows.forEach(row => {
2253
+ row.cells.forEach((cell, colIndex) => {
2254
+ var _a, _b;
2255
+ const before = (_a = rows.at(startRow - 1)) === null || _a === void 0 ? void 0 : _a.cells.at(colIndex);
2256
+ const after = (_b = rows.at(startRow)) === null || _b === void 0 ? void 0 : _b.cells.at(colIndex);
2257
+ if (keys.includes(cell.id)) {
2258
+ if (after) {
2259
+ mergeConfig[after.id] = mergeConfig[cell.id];
2260
+ }
2261
+ Reflect.deleteProperty(mergeConfig, cell.id);
2262
+ }
2263
+ if (before) {
2264
+ keys.forEach(key => {
2265
+ if (mergeConfig[key] === cell.id) {
2266
+ mergeConfig[key] = before.id;
2267
+ }
2268
+ });
2269
+ }
2270
+ });
2271
+ });
2272
+ }
2273
+ this.tableSelection.set(null);
1969
2274
  this.selection.unSelect();
1970
2275
  }
1971
2276
  insertColumn(index) {
1972
- this.state.layoutWidth.splice(index, 0, defaultColumnWidth);
2277
+ this.state.columnsConfig.splice(index, 0, defaultColumnWidth);
1973
2278
  this.state.rows.forEach(row => {
1974
2279
  const slot = new core$1.Slot([
1975
2280
  core$1.ContentType.BlockComponent,
@@ -1981,14 +2286,12 @@ class TableComponent extends core$1.Component {
1981
2286
  ])
1982
2287
  }));
1983
2288
  row.cells.splice(index, 0, {
1984
- rowspan: 1,
1985
- colspan: 1,
2289
+ id: uuid.v4(),
1986
2290
  slot
1987
2291
  });
1988
2292
  });
1989
2293
  this.textbus.nextTick(() => {
1990
- var _a;
1991
- const slot = (_a = this.state.rows[0].cells[index]) === null || _a === void 0 ? void 0 : _a.slot;
2294
+ const slot = this.state.rows[0].cells[index].slot;
1992
2295
  if (slot) {
1993
2296
  this.selection.selectFirstPosition(slot.getContentAtIndex(0));
1994
2297
  }
@@ -1997,7 +2300,7 @@ class TableComponent extends core$1.Component {
1997
2300
  insertRow(index) {
1998
2301
  this.state.rows.splice(index, 0, {
1999
2302
  height: defaultRowHeight,
2000
- cells: this.state.layoutWidth.map(() => {
2303
+ cells: this.state.columnsConfig.map(() => {
2001
2304
  const slot = new core$1.Slot([
2002
2305
  core$1.ContentType.BlockComponent,
2003
2306
  ]);
@@ -2008,15 +2311,13 @@ class TableComponent extends core$1.Component {
2008
2311
  ])
2009
2312
  }));
2010
2313
  return {
2011
- rowspan: 1,
2012
- colspan: 1,
2314
+ id: uuid.v4(),
2013
2315
  slot
2014
2316
  };
2015
2317
  })
2016
2318
  });
2017
2319
  this.textbus.nextTick(() => {
2018
- var _a;
2019
- const slot = (_a = this.state.rows[index].cells[0]) === null || _a === void 0 ? void 0 : _a.slot;
2320
+ const slot = this.state.rows[index].cells[0].slot;
2020
2321
  if (slot) {
2021
2322
  this.selection.selectFirstPosition(slot.getContentAtIndex(0));
2022
2323
  }
@@ -2051,7 +2352,7 @@ function registerStrikeThroughShortcut(textbus) {
2051
2352
  const keyboard = textbus.get(core$1.Keyboard);
2052
2353
  keyboard.addShortcut({
2053
2354
  keymap: {
2054
- ctrlKey: true,
2355
+ modKey: true,
2055
2356
  key: 'd'
2056
2357
  },
2057
2358
  action: () => {
@@ -2235,7 +2536,7 @@ function registerListShortcut(textbus) {
2235
2536
  keyboard.addShortcut({
2236
2537
  keymap: {
2237
2538
  key: ['o', 'u'],
2238
- ctrlKey: true,
2539
+ modKey: true,
2239
2540
  shiftKey: true
2240
2541
  },
2241
2542
  action(key) {
@@ -2767,43 +3068,43 @@ function BlockTool() {
2767
3068
  return (jsxRuntime.jsx(Dropdown, { width: 'auto', onCheck: transform, trigger: 'hover', menu: [
2768
3069
  {
2769
3070
  label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-pilcrow" }), desc: jsxRuntime.jsx(Keymap, { keymap: {
2770
- ctrlKey: true,
3071
+ modKey: true,
2771
3072
  key: '0'
2772
3073
  } }), checked: states.paragraph, children: "\u6B63\u6587" }),
2773
3074
  value: 'paragraph'
2774
3075
  }, {
2775
3076
  label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h1" }), desc: jsxRuntime.jsx(Keymap, { keymap: {
2776
- ctrlKey: true,
3077
+ modKey: true,
2777
3078
  key: '1'
2778
3079
  } }), checked: states.h1, children: "\u4E00\u7EA7\u6807\u9898" }),
2779
3080
  value: 'h1'
2780
3081
  }, {
2781
3082
  label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h2" }), desc: jsxRuntime.jsx(Keymap, { keymap: {
2782
- ctrlKey: true,
3083
+ modKey: true,
2783
3084
  key: '2'
2784
3085
  } }), checked: states.h2, children: "\u4E8C\u7EA7\u6807\u9898" }),
2785
3086
  value: 'h2'
2786
3087
  }, {
2787
3088
  label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h3" }), desc: jsxRuntime.jsx(Keymap, { keymap: {
2788
- ctrlKey: true,
3089
+ modKey: true,
2789
3090
  key: '3'
2790
3091
  } }), checked: states.h3, children: "\u4E09\u7EA7\u6807\u9898" }),
2791
3092
  value: 'h3'
2792
3093
  }, {
2793
3094
  label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h4" }), desc: jsxRuntime.jsx(Keymap, { keymap: {
2794
- ctrlKey: true,
3095
+ modKey: true,
2795
3096
  key: '4'
2796
3097
  } }), checked: states.h4, children: "\u56DB\u7EA7\u6807\u9898" }),
2797
3098
  value: 'h4'
2798
3099
  }, {
2799
3100
  label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h5" }), desc: jsxRuntime.jsx(Keymap, { keymap: {
2800
- ctrlKey: true,
3101
+ modKey: true,
2801
3102
  key: '5'
2802
3103
  } }), checked: states.h5, children: "\u4E94\u7EA7\u6807\u9898" }),
2803
3104
  value: 'h5'
2804
3105
  }, {
2805
3106
  label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h6" }), desc: jsxRuntime.jsx(Keymap, { keymap: {
2806
- ctrlKey: true,
3107
+ modKey: true,
2807
3108
  key: '6'
2808
3109
  } }), checked: states.h6, children: "\u516D\u7EA7\u6807\u9898" }),
2809
3110
  value: 'h6'
@@ -2814,13 +3115,13 @@ function BlockTool() {
2814
3115
  label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-checkbox-checked" }), checked: states.todolist, children: "\u5F85\u529E\u4E8B\u9879" }),
2815
3116
  value: 'todolist'
2816
3117
  }, {
2817
- label: jsxRuntime.jsx(MenuItem, { desc: jsxRuntime.jsx(Keymap, { keymap: { key: 'O', shiftKey: true, ctrlKey: true } }), icon: jsxRuntime.jsx("span", { class: "xnote-icon-list-numbered" }), checked: states.orderedList, children: "\u6709\u5E8F\u5217\u8868" }),
3118
+ label: jsxRuntime.jsx(MenuItem, { desc: jsxRuntime.jsx(Keymap, { keymap: { key: 'O', shiftKey: true, modKey: true } }), icon: jsxRuntime.jsx("span", { class: "xnote-icon-list-numbered" }), checked: states.orderedList, children: "\u6709\u5E8F\u5217\u8868" }),
2818
3119
  value: 'ol'
2819
3120
  }, {
2820
- label: jsxRuntime.jsx(MenuItem, { desc: jsxRuntime.jsx(Keymap, { keymap: { key: 'U', shiftKey: true, ctrlKey: true } }), icon: jsxRuntime.jsx("span", { class: "xnote-icon-list" }), checked: states.unorderedList, children: "\u65E0\u5E8F\u5217\u8868" }),
3121
+ label: jsxRuntime.jsx(MenuItem, { desc: jsxRuntime.jsx(Keymap, { keymap: { key: 'U', shiftKey: true, modKey: true } }), icon: jsxRuntime.jsx("span", { class: "xnote-icon-list" }), checked: states.unorderedList, children: "\u65E0\u5E8F\u5217\u8868" }),
2821
3122
  value: 'ul'
2822
3123
  }, {
2823
- label: jsxRuntime.jsx(MenuItem, { desc: jsxRuntime.jsx(Keymap, { keymap: { key: '\'', ctrlKey: true } }), icon: jsxRuntime.jsx("span", { class: "xnote-icon-quotes-right" }), checked: states.blockquote, children: "\u5F15\u7528" }),
3124
+ label: jsxRuntime.jsx(MenuItem, { desc: jsxRuntime.jsx(Keymap, { keymap: { key: '\'', modKey: true } }), icon: jsxRuntime.jsx("span", { class: "xnote-icon-quotes-right" }), checked: states.blockquote, children: "\u5F15\u7528" }),
2824
3125
  value: 'blockquote'
2825
3126
  }, {
2826
3127
  label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-source-code" }), checked: states.sourceCode, children: "\u4EE3\u7801\u5757" }),
@@ -2880,7 +3181,7 @@ function registerBoldShortcut(textbus) {
2880
3181
  const keyboard = textbus.get(core$1.Keyboard);
2881
3182
  keyboard.addShortcut({
2882
3183
  keymap: {
2883
- ctrlKey: true,
3184
+ modKey: true,
2884
3185
  key: 'b'
2885
3186
  },
2886
3187
  action: () => {
@@ -2927,7 +3228,7 @@ function registerCodeShortcut(textbus) {
2927
3228
  const keyboard = textbus.get(core$1.Keyboard);
2928
3229
  keyboard.addShortcut({
2929
3230
  keymap: {
2930
- ctrlKey: true,
3231
+ modKey: true,
2931
3232
  key: ','
2932
3233
  },
2933
3234
  action: () => {
@@ -3037,7 +3338,7 @@ function registerItalicShortcut(textbus) {
3037
3338
  const keyboard = textbus.get(core$1.Keyboard);
3038
3339
  keyboard.addShortcut({
3039
3340
  keymap: {
3040
- ctrlKey: true,
3341
+ modKey: true,
3041
3342
  key: 'i'
3042
3343
  },
3043
3344
  action: () => {
@@ -3120,7 +3421,7 @@ function registerUnderlineShortcut(textbus) {
3120
3421
  const keyboard = textbus.get(core$1.Keyboard);
3121
3422
  keyboard.addShortcut({
3122
3423
  keymap: {
3123
- ctrlKey: true,
3424
+ modKey: true,
3124
3425
  key: 'u'
3125
3426
  },
3126
3427
  action: () => {
@@ -3596,6 +3897,171 @@ function UnderlineTool() {
3596
3897
  };
3597
3898
  }
3598
3899
 
3900
+ const cellAlignAttr = new core$1.Attribute('cellAlign', {
3901
+ render(node, formatValue) {
3902
+ node.styles.set('verticalAlign', formatValue);
3903
+ }
3904
+ });
3905
+ const cellAlignAttrLoader = {
3906
+ match(element) {
3907
+ return element instanceof HTMLTableCellElement && !!element.style.verticalAlign;
3908
+ },
3909
+ read(element) {
3910
+ return {
3911
+ attribute: cellAlignAttr,
3912
+ value: element.style.verticalAlign
3913
+ };
3914
+ }
3915
+ };
3916
+
3917
+ function CellAlignTool() {
3918
+ const currentValue = core.createSignal('');
3919
+ const selection = core.inject(core$1.Selection);
3920
+ function check(v) {
3921
+ const commonAncestorComponent = selection.commonAncestorComponent;
3922
+ if (commonAncestorComponent instanceof TableComponent) {
3923
+ const slots = commonAncestorComponent.getSelectedNormalizedSlots();
3924
+ slots.forEach(item => {
3925
+ item.cells.forEach(cell => {
3926
+ if (cell.visible) {
3927
+ cell.raw.slot.setAttribute(cellAlignAttr, v);
3928
+ }
3929
+ });
3930
+ });
3931
+ }
3932
+ }
3933
+ const refreshService = core.inject(exports.RefreshService);
3934
+ const query = core.inject(core$1.Query);
3935
+ const highlight = core.createSignal(false);
3936
+ const subscription = refreshService.onRefresh.subscribe(() => {
3937
+ const result = query.queryAttribute(cellAlignAttr);
3938
+ const isHighlight = result.state === core$1.QueryStateType.Enabled;
3939
+ highlight.set(isHighlight);
3940
+ currentValue.set(isHighlight ? result.value : 'middle');
3941
+ });
3942
+ core.onUnmounted(() => {
3943
+ subscription.unsubscribe();
3944
+ });
3945
+ return () => {
3946
+ return (jsxRuntime.jsx(Dropdown, { onCheck: check, menu: [
3947
+ {
3948
+ label: jsxRuntime.jsx(MenuItem, { checked: currentValue() === 'top', icon: jsxRuntime.jsx("span", { class: "xnote-icon-align-top" }), children: "\u9876\u90E8\u5BF9\u9F50" }),
3949
+ value: 'top'
3950
+ },
3951
+ {
3952
+ label: jsxRuntime.jsx(MenuItem, { checked: currentValue() === 'middle', icon: jsxRuntime.jsx("span", { class: "xnote-icon-align-middle" }), children: "\u5782\u76F4\u5C45\u4E2D" }),
3953
+ value: 'middle'
3954
+ },
3955
+ {
3956
+ label: jsxRuntime.jsx(MenuItem, { checked: currentValue() === 'bottom', icon: jsxRuntime.jsx("span", { class: "xnote-icon-align-bottom" }), children: "\u5E95\u90E8\u5BF9\u9F50" }),
3957
+ value: 'bottom'
3958
+ }
3959
+ ], children: jsxRuntime.jsx(Button, { arrow: true, highlight: highlight(), children: jsxRuntime.jsx("span", { class: 'xnote-icon-align-' + (currentValue() || 'middle') }) }) }));
3960
+ };
3961
+ }
3962
+
3963
+ function CellBackgroundTool() {
3964
+ const refreshService = core.inject(exports.RefreshService);
3965
+ const selection = core.inject(core$1.Selection);
3966
+ const [viewModel, update] = hooks.useProduce({
3967
+ highlight: false,
3968
+ disabled: false,
3969
+ });
3970
+ function split() {
3971
+ // const commonAncestorComponent = selection.commonAncestorComponent
3972
+ // if (commonAncestorComponent instanceof TableComponent) {
3973
+ // const scopes = selection.getSelectedScopes()
3974
+ // if (scopes.length) {
3975
+ // const start = commonAncestorComponent.getCellBySlot(scopes.at(0)!.slot)
3976
+ // const end = commonAncestorComponent.getCellBySlot(scopes.at(-1)!.slot)
3977
+ // // Re
3978
+ // }
3979
+ // }
3980
+ }
3981
+ const sub = refreshService.onRefresh.subscribe(() => {
3982
+ const commonAncestorComponent = selection.commonAncestorComponent;
3983
+ update(draft => {
3984
+ draft.disabled = !(commonAncestorComponent instanceof TableComponent);
3985
+ });
3986
+ });
3987
+ core.onUnmounted(() => {
3988
+ sub.unsubscribe();
3989
+ });
3990
+ return () => {
3991
+ const vm = viewModel();
3992
+ return jsxRuntime.jsx(Button, { highlight: vm.highlight, disabled: vm.disabled, onClick: split, children: jsxRuntime.jsx("span", { class: "xnote-icon-palette" }) });
3993
+ };
3994
+ }
3995
+
3996
+ function MergeCellsTool() {
3997
+ const refreshService = core.inject(exports.RefreshService);
3998
+ const selection = core.inject(core$1.Selection);
3999
+ const [viewModel, update] = hooks.useProduce({
4000
+ highlight: false,
4001
+ disabled: false,
4002
+ });
4003
+ function merge() {
4004
+ const commonAncestorComponent = selection.commonAncestorComponent;
4005
+ if (commonAncestorComponent instanceof TableComponent) {
4006
+ commonAncestorComponent.mergeCellBySelection();
4007
+ }
4008
+ }
4009
+ const sub = refreshService.onRefresh.subscribe(() => {
4010
+ const commonAncestorComponent = selection.commonAncestorComponent;
4011
+ update(draft => {
4012
+ draft.disabled = !(commonAncestorComponent instanceof TableComponent);
4013
+ });
4014
+ });
4015
+ core.onUnmounted(() => {
4016
+ sub.unsubscribe();
4017
+ });
4018
+ return () => {
4019
+ const vm = viewModel();
4020
+ return jsxRuntime.jsx(Button, { highlight: vm.highlight, disabled: vm.disabled, onClick: merge, children: jsxRuntime.jsx("span", { class: "xnote-icon-merge-cells" }) });
4021
+ };
4022
+ }
4023
+
4024
+ function SplitCellsTool() {
4025
+ const refreshService = core.inject(exports.RefreshService);
4026
+ const selection = core.inject(core$1.Selection);
4027
+ const [viewModel, update] = hooks.useProduce({
4028
+ highlight: false,
4029
+ disabled: false,
4030
+ });
4031
+ function split() {
4032
+ const commonAncestorComponent = selection.commonAncestorComponent;
4033
+ if (commonAncestorComponent instanceof TableComponent) {
4034
+ commonAncestorComponent.splitCellsBySelection();
4035
+ }
4036
+ }
4037
+ const sub = refreshService.onRefresh.subscribe(() => {
4038
+ const commonAncestorComponent = selection.commonAncestorComponent;
4039
+ update(draft => {
4040
+ if (commonAncestorComponent instanceof TableComponent) {
4041
+ const slots = commonAncestorComponent.getSelectedNormalizedSlots();
4042
+ if (slots) {
4043
+ for (const item of slots) {
4044
+ for (const cell of item.cells) {
4045
+ if (cell.visible && cell.colspan > 1 || cell.colspan > 1) {
4046
+ draft.disabled = false;
4047
+ return;
4048
+ }
4049
+ }
4050
+ }
4051
+ }
4052
+ }
4053
+ draft.disabled = true;
4054
+ });
4055
+ });
4056
+ core.onUnmounted(() => {
4057
+ sub.unsubscribe();
4058
+ });
4059
+ return () => {
4060
+ const vm = viewModel();
4061
+ return jsxRuntime.jsx(Button, { highlight: vm.highlight, disabled: vm.disabled, onClick: split, children: jsxRuntime.jsx("span", { class: "xnote-icon-split-cells" }) });
4062
+ };
4063
+ }
4064
+
3599
4065
  var scopedId$9 = "vf-cf8e1c";
3600
4066
 
3601
4067
  class FileUploader {
@@ -4378,6 +4844,10 @@ function LinkJump() {
4378
4844
 
4379
4845
  var scopedId$6 = "vf-fee98b";
4380
4846
 
4847
+ function sum(numbers) {
4848
+ return numbers.reduce((a, b) => a + b, 0);
4849
+ }
4850
+
4381
4851
  const Toolbar = core.withAnnotation({
4382
4852
  providers: [exports.RefreshService]
4383
4853
  }, function Toolbar() {
@@ -4408,10 +4878,35 @@ const Toolbar = core.withAnnotation({
4408
4878
  const docRect = viewDocument.getBoundingClientRect();
4409
4879
  const toolbarHeight = 36;
4410
4880
  // const documentHeight = document.documentElement.clientHeight
4411
- const selectionFocusRect = bridge.getRect({
4412
- slot: selection.focusSlot,
4413
- offset: selection.focusOffset
4414
- });
4881
+ let selectionFocusRect = null;
4882
+ const commonAncestorComponent = selection.commonAncestorComponent;
4883
+ if (commonAncestorComponent instanceof TableComponent) {
4884
+ const slots = commonAncestorComponent.getSelectedNormalizedSlots().map(item => {
4885
+ return item.cells.filter(i => {
4886
+ return i.visible;
4887
+ }).map(cell => {
4888
+ return cell.raw.slot;
4889
+ });
4890
+ }).flat();
4891
+ const startSlot = slots.at(0);
4892
+ const endSlot = slots.at(-1);
4893
+ const rect = commonAncestorComponent.getSelectedRect();
4894
+ const startRect = adapter.getNativeNodeBySlot(startSlot).getBoundingClientRect();
4895
+ const endEle = adapter.getNativeNodeBySlot(endSlot).getBoundingClientRect();
4896
+ const width = sum(commonAncestorComponent.state.columnsConfig.slice(rect.x1, rect.x2));
4897
+ selectionFocusRect = {
4898
+ left: startRect.left + width / 2,
4899
+ top: startRect.top,
4900
+ height: endEle.bottom - startRect.top,
4901
+ width
4902
+ };
4903
+ }
4904
+ else {
4905
+ selectionFocusRect = bridge.getRect({
4906
+ slot: selection.focusSlot,
4907
+ offset: selection.focusOffset
4908
+ });
4909
+ }
4415
4910
  if (!selectionFocusRect) {
4416
4911
  return null;
4417
4912
  }
@@ -4442,7 +4937,13 @@ const Toolbar = core.withAnnotation({
4442
4937
  });
4443
4938
  function bindMouseup() {
4444
4939
  const docElement = adapter.getNativeNodeByComponent(rootComponentRef.component);
4445
- mouseupSubscription = core$1.fromEvent(docElement, 'mouseup').pipe(core$1.filter(ev => {
4940
+ mouseupSubscription = core$1.fromEvent(docElement, 'mouseup').pipe(core$1.delay(), core$1.filter(ev => {
4941
+ const c = selection.commonAncestorComponent;
4942
+ if (c instanceof TableComponent) {
4943
+ const b = !c.ignoreSelectionChanges;
4944
+ c.ignoreSelectionChanges = false;
4945
+ return b;
4946
+ }
4446
4947
  return !ev.composedPath().includes(toolbarRef.current);
4447
4948
  }), core$1.delay(100), core$1.filter(() => {
4448
4949
  return !selection.isCollapsed && !(selection.commonAncestorComponent instanceof SourceCodeComponent);
@@ -4486,7 +4987,7 @@ const Toolbar = core.withAnnotation({
4486
4987
  opacity: p.opacity,
4487
4988
  display: editorService.hideInlineToolbar ? 'none' : '',
4488
4989
  transitionDuration: p.transitionDuration + 's'
4489
- }, children: [jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(BlockTool, {}) }), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(AttrTool, {}) }), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(BoldTool, {}) }), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(ItalicTool, {}) }), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(StrikeThroughTool, {}) }), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(UnderlineTool, {}) }), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(FontSizeTool, {}) }), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(FontFamilyTool, {}) }), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(LinkTool, { hideToolbar: hideToolbar }) }), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(CodeTool, {}) }), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(ColorTool, {}) })] }));
4990
+ }, children: [selection.commonAncestorComponent instanceof TableComponent && jsxRuntime.jsxs(core.Fragment, { children: [jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(MergeCellsTool, {}) }), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(SplitCellsTool, {}) }), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(CellAlignTool, {}) })] }, "table"), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(BlockTool, {}) }), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(AttrTool, {}) }), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(BoldTool, {}) }), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(ItalicTool, {}) }), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(StrikeThroughTool, {}) }), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(UnderlineTool, {}) }), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(FontSizeTool, {}) }), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(FontFamilyTool, {}) }), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(LinkTool, { hideToolbar: hideToolbar }) }), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(CodeTool, {}) }), jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(ColorTool, {}) })] }));
4490
4991
  });
4491
4992
  });
4492
4993
 
@@ -4917,8 +5418,8 @@ let TableService = class TableService {
4917
5418
  constructor() {
4918
5419
  this.onInsertRowBefore = new core$1.Subject();
4919
5420
  this.onInsertColumnBefore = new core$1.Subject();
4920
- this.onSelectColumns = new core$1.Subject();
4921
- this.onSelectRows = new core$1.Subject();
5421
+ // onSelectColumns = new Subject<{ start: number, end: number } | null>()
5422
+ // onSelectRows = new Subject<{ start: number, end: number } | null>()
4922
5423
  this.onScroll = new core$1.Subject();
4923
5424
  }
4924
5425
  };
@@ -4938,7 +5439,11 @@ function ResizeColumn(props) {
4938
5439
  ignoreMove = true;
4939
5440
  }).add(core$1.fromEvent(document, 'mouseup').subscribe(() => {
4940
5441
  ignoreMove = false;
4941
- })).add(core$1.fromEvent(tableRef.current.parentNode, 'mousemove').subscribe(ev => {
5442
+ })).add(core$1.fromEvent(tableRef.current.parentNode, 'mouseleave').subscribe(() => {
5443
+ if (!isDrag) {
5444
+ dragLineRef.current.style.display = 'none';
5445
+ }
5446
+ }), core$1.fromEvent(tableRef.current.parentNode, 'mousemove').subscribe(ev => {
4942
5447
  if (isDrag || ignoreMove) {
4943
5448
  return;
4944
5449
  }
@@ -4946,7 +5451,7 @@ function ResizeColumn(props) {
4946
5451
  const leftDistance = ev.clientX - tableRect.x;
4947
5452
  const state = props.component.state;
4948
5453
  let x = 0;
4949
- for (let i = 0; i < state.layoutWidth.length + 1; i++) {
5454
+ for (let i = 0; i < state.columnsConfig.length + 1; i++) {
4950
5455
  const n = leftDistance - x;
4951
5456
  if (i > 0 && Math.abs(n) < 5) {
4952
5457
  Object.assign(dragLineRef.current.style, {
@@ -4958,14 +5463,14 @@ function ResizeColumn(props) {
4958
5463
  }
4959
5464
  activeCol = null;
4960
5465
  dragLineRef.current.style.display = 'none';
4961
- x += state.layoutWidth[i];
5466
+ x += state.columnsConfig[i] || 0;
4962
5467
  }
4963
5468
  })).add(core$1.fromEvent(dragLineRef.current, 'mousedown').subscribe(downEvent => {
4964
5469
  isDrag = true;
4965
5470
  editorService.changeLeftToolbarVisible(false);
4966
5471
  props.onActiveStateChange(true);
4967
5472
  const x = downEvent.clientX;
4968
- const layoutWidth = props.component.state.layoutWidth;
5473
+ const layoutWidth = props.component.state.columnsConfig;
4969
5474
  const initWidth = layoutWidth[activeCol - 1];
4970
5475
  const initLeft = layoutWidth.slice(0, activeCol).reduce((a, b) => a + b, 0);
4971
5476
  const minWidth = 30;
@@ -4982,8 +5487,8 @@ function ResizeColumn(props) {
4982
5487
  props.onActiveStateChange(false);
4983
5488
  moveEvent.unsubscribe();
4984
5489
  const distanceX = upEvent.clientX - x;
4985
- props.component.state.layoutWidth[activeCol - 1] = Math.max(initWidth + distanceX, minWidth);
4986
- props.layoutWidth.set(props.component.state.layoutWidth);
5490
+ props.component.state.columnsConfig[activeCol - 1] = Math.max(initWidth + distanceX, minWidth);
5491
+ props.layoutWidth.set(props.component.state.columnsConfig.slice());
4987
5492
  }));
4988
5493
  }));
4989
5494
  return () => {
@@ -4998,7 +5503,7 @@ function ResizeColumn(props) {
4998
5503
  return;
4999
5504
  }
5000
5505
  const state = props.component.state;
5001
- const left = state.layoutWidth.slice(0, n).reduce((a, b) => a + b, 0) - 0.5;
5506
+ const left = state.columnsConfig.slice(0, n).reduce((a, b) => a + b, 0) - 0.5;
5002
5507
  dragLineRef.current.style.display = 'block';
5003
5508
  dragLineRef.current.style.left = left + 'px';
5004
5509
  });
@@ -5013,9 +5518,7 @@ var scopedId$4 = "vf-39cb2c";
5013
5518
 
5014
5519
  function TopBar(props) {
5015
5520
  const editorService = core.inject(exports.EditorService);
5016
- const selection = core.inject(core$1.Selection);
5017
5521
  const tableService = core.inject(TableService);
5018
- const textbus = core.inject(core$1.Textbus);
5019
5522
  const selectedColumnRange = core.createSignal(null);
5020
5523
  function selectColumn(index, isMultiple) {
5021
5524
  editorService.hideInlineToolbar = true;
@@ -5031,24 +5534,11 @@ function TopBar(props) {
5031
5534
  startIndex: index, endIndex: index
5032
5535
  });
5033
5536
  }
5034
- const range = selectedColumnRange();
5035
- const [startIndex, endIndex] = [range.startIndex, range.endIndex].sort((a, b) => a - b);
5036
- const selectedSlots = [];
5037
- const rows = props.component.state.rows;
5038
- rows.forEach(row => {
5039
- selectedSlots.push(...row.cells.slice(startIndex, endIndex + 1).map(i => i.slot));
5040
- });
5041
- textbus.nextTick(() => {
5042
- selection.setSelectedRanges(selectedSlots.map(i => {
5043
- return {
5044
- slot: i,
5045
- startIndex: 0,
5046
- endIndex: i.length
5047
- };
5048
- }));
5049
- selection.restore();
5050
- textbus.focus();
5051
- });
5537
+ let { startIndex, endIndex } = selectedColumnRange();
5538
+ if (startIndex > endIndex) {
5539
+ [startIndex, endIndex] = [endIndex, startIndex];
5540
+ }
5541
+ props.component.selectColumn(startIndex, endIndex + 1);
5052
5542
  }
5053
5543
  let mouseDownFromToolbar = false;
5054
5544
  core.onMounted(() => {
@@ -5057,7 +5547,6 @@ function TopBar(props) {
5057
5547
  mouseDownFromToolbar = false;
5058
5548
  return;
5059
5549
  }
5060
- deleteIndex.set(null);
5061
5550
  selectedColumnRange.set(null);
5062
5551
  });
5063
5552
  return () => sub.unsubscribe();
@@ -5076,49 +5565,53 @@ function TopBar(props) {
5076
5565
  core.onUnmounted(() => {
5077
5566
  s.unsubscribe();
5078
5567
  });
5079
- const deleteIndex = core.createSignal(null);
5568
+ function refreshLayoutWidth() {
5569
+ props.layoutWidth.set(props.component.state.columnsConfig.slice());
5570
+ }
5080
5571
  return scopedCss.withScopedCSS(scopedId$4, () => {
5081
5572
  const { state, tableSelection } = props.component;
5082
5573
  const position = tableSelection();
5574
+ const range = selectedColumnRange();
5575
+ let left = 0;
5576
+ if (range) {
5577
+ left = sum(props.component.state.columnsConfig.slice(0, Math.min(range.startIndex, range.endIndex)));
5578
+ left += sum(props.component.state.columnsConfig.slice(Math.min(range.startIndex, range.endIndex), Math.max(range.startIndex, range.endIndex) + 1)) / 2;
5579
+ }
5083
5580
  return (jsxRuntime.jsx("div", { class: ['top-bar', {
5084
5581
  active: props.isFocus()
5085
- }], children: jsxRuntime.jsxs("div", { class: "toolbar-wrapper", children: [jsxRuntime.jsx("div", { class: "insert-bar", children: jsxRuntime.jsx("table", { style: {
5582
+ }], children: jsxRuntime.jsxs("div", { class: "toolbar-wrapper", children: [jsxRuntime.jsxs("div", { class: "insert-bar", children: [jsxRuntime.jsx(ComponentToolbar, { style: {
5583
+ left: left - leftDistance() + 'px',
5584
+ display: selectedColumnRange() ? 'inline-block' : 'none',
5585
+ }, innerStyle: {
5586
+ transform: 'translateX(-50%)'
5587
+ }, visible: !!selectedColumnRange(), children: jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(Button, { onClick: () => {
5588
+ props.component.deleteColumns();
5589
+ refreshLayoutWidth();
5590
+ }, children: jsxRuntime.jsx("span", { class: "xnote-icon-bin" }) }) }) }), jsxRuntime.jsx("table", { style: {
5591
+ transform: `translateX(${-leftDistance()}px)`
5592
+ }, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: props.layoutWidth().map((i, index) => {
5593
+ return (jsxRuntime.jsx("td", { style: { width: i + 'px', minWidth: i + 'px' }, children: jsxRuntime.jsxs("div", { class: "tool-container", children: [index === 0 && (jsxRuntime.jsx("span", { onMouseenter: () => {
5594
+ tableService.onInsertColumnBefore.next(0);
5595
+ }, onMouseleave: () => {
5596
+ tableService.onInsertColumnBefore.next(null);
5597
+ }, class: "insert-btn-wrap", style: {
5598
+ left: '-10px'
5599
+ }, onClick: () => {
5600
+ props.component.insertColumn(0);
5601
+ refreshLayoutWidth();
5602
+ }, children: jsxRuntime.jsx("button", { class: "insert-btn", type: "button", children: "+" }) })), jsxRuntime.jsx("span", { class: "insert-btn-wrap", onMouseenter: () => {
5603
+ tableService.onInsertColumnBefore.next(index + 1);
5604
+ }, onMouseleave: () => {
5605
+ tableService.onInsertColumnBefore.next(null);
5606
+ }, onClick: () => {
5607
+ props.component.insertColumn(index + 1);
5608
+ refreshLayoutWidth();
5609
+ }, children: jsxRuntime.jsx("button", { class: "insert-btn", type: "button", children: "+" }) })] }) }));
5610
+ }) }) }) })] }), jsxRuntime.jsx("div", { class: ['action-bar', { active: props.isFocus() }], children: jsxRuntime.jsx("table", { style: {
5086
5611
  transform: `translateX(${-leftDistance()}px)`
5087
5612
  }, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: props.layoutWidth().map((i, index) => {
5088
- return (jsxRuntime.jsx("td", { style: { width: i + 'px', minWidth: i + 'px' }, children: jsxRuntime.jsxs("div", { class: "tool-container", children: [index === 0 && (jsxRuntime.jsx("span", { onMouseenter: () => {
5089
- tableService.onInsertColumnBefore.next(0);
5090
- }, onMouseleave: () => {
5091
- tableService.onInsertColumnBefore.next(null);
5092
- }, class: "insert-btn-wrap", style: {
5093
- left: '-10px'
5094
- }, onClick: () => {
5095
- props.component.insertColumn(0);
5096
- }, children: jsxRuntime.jsx("button", { class: "insert-btn", type: "button", children: "+" }) })), jsxRuntime.jsx("span", { class: "insert-btn-wrap", onMouseenter: () => {
5097
- tableService.onInsertColumnBefore.next(index + 1);
5098
- }, onMouseleave: () => {
5099
- tableService.onInsertColumnBefore.next(null);
5100
- }, onClick: () => {
5101
- props.component.insertColumn(index + 1);
5102
- }, children: jsxRuntime.jsx("button", { class: "insert-btn", type: "button", children: "+" }) }), jsxRuntime.jsx(ComponentToolbar, { style: {
5103
- display: deleteIndex() === index ? 'inline-block' : 'none',
5104
- left: '50%',
5105
- }, innerStyle: {
5106
- transform: 'translateX(-50%)'
5107
- }, visible: deleteIndex() === index, children: jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(Button, { onClick: () => {
5108
- props.component.deleteColumn(index);
5109
- deleteIndex.set(null);
5110
- }, children: jsxRuntime.jsx("span", { class: "xnote-icon-bin" }) }) }) })] }) }));
5111
- }) }) }) }) }), jsxRuntime.jsx("div", { class: ['action-bar', { active: props.isFocus() }], children: jsxRuntime.jsx("table", { style: {
5112
- transform: `translateX(${-leftDistance()}px)`
5113
- }, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: props.layoutWidth().map((i, index) => {
5114
- return jsxRuntime.jsx("td", { onClick: ev => {
5613
+ return jsxRuntime.jsx("td", { onMousedown: ev => ev.preventDefault(), onClick: ev => {
5115
5614
  mouseDownFromToolbar = true;
5116
- if (!ev.shiftKey) {
5117
- deleteIndex.set(index);
5118
- }
5119
- else {
5120
- deleteIndex.set(null);
5121
- }
5122
5615
  selectColumn(index, ev.shiftKey);
5123
5616
  }, class: {
5124
5617
  active: !position ? false :
@@ -5180,10 +5673,8 @@ var scopedId$2 = "vf-aaece0";
5180
5673
 
5181
5674
  function LeftBar(props) {
5182
5675
  const editorService = core.inject(exports.EditorService);
5183
- const selection = core.inject(core$1.Selection);
5184
5676
  const actionBarRef = core.createRef();
5185
5677
  const insertBarRef = core.createRef();
5186
- const textbus = core.inject(core$1.Textbus);
5187
5678
  const tableService = core.inject(TableService);
5188
5679
  // 同步行高度
5189
5680
  core.onUpdated(() => {
@@ -5191,8 +5682,10 @@ function LeftBar(props) {
5191
5682
  const actionBarRows = actionBarRef.current.rows;
5192
5683
  setTimeout(() => {
5193
5684
  Array.from(props.tableRef.current.rows).forEach((tr, i) => {
5194
- insertBarRows.item(i).style.height = tr.getBoundingClientRect().height + 'px';
5195
- actionBarRows.item(i).style.height = tr.getBoundingClientRect().height + 'px';
5685
+ const height = tr.offsetHeight ||
5686
+ Math.min(...Array.from(tr.children).map(i => i.offsetHeight)) || 0;
5687
+ insertBarRows.item(i).style.height = height + 'px';
5688
+ actionBarRows.item(i).style.height = height + 'px';
5196
5689
  });
5197
5690
  });
5198
5691
  });
@@ -5231,30 +5724,27 @@ function LeftBar(props) {
5231
5724
  startIndex: index, endIndex: index
5232
5725
  });
5233
5726
  }
5234
- const range = selectedRowRange();
5235
- const [startIndex, endIndex] = [range.startIndex, range.endIndex].sort((a, b) => a - b);
5236
- const selectedSlots = [];
5237
- const rows = props.component.state.rows;
5238
- rows.slice(startIndex, endIndex + 1).forEach(row => {
5239
- selectedSlots.push(...row.cells.map(i => i.slot));
5240
- });
5241
- textbus.nextTick(() => {
5242
- selection.setSelectedRanges(selectedSlots.map(i => {
5243
- return {
5244
- slot: i,
5245
- startIndex: 0,
5246
- endIndex: i.length
5247
- };
5248
- }));
5249
- selection.restore();
5250
- textbus.focus();
5251
- });
5727
+ let { startIndex, endIndex } = selectedRowRange();
5728
+ if (startIndex > endIndex) {
5729
+ [startIndex, endIndex] = [endIndex, startIndex];
5730
+ }
5731
+ deleteIndex.set(startIndex);
5732
+ props.component.selectRow(startIndex, endIndex + 1);
5252
5733
  }
5253
5734
  return scopedCss.withScopedCSS(scopedId$2, () => {
5254
- const { state, tableSelection } = props.component;
5255
- const position = tableSelection();
5256
- return (jsxRuntime.jsxs("div", { class: ['left-bar', { active: props.isFocus() }], children: [jsxRuntime.jsx("div", { class: "insert-bar", children: jsxRuntime.jsx("table", { ref: insertBarRef, children: jsxRuntime.jsx("tbody", { children: state.rows.map((_, index) => {
5257
- return (jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: jsxRuntime.jsxs("div", { class: "toolbar-item", children: [index === 0 && (jsxRuntime.jsx("span", { onMouseenter: () => {
5735
+ const position = props.component.tableSelection();
5736
+ const normalizedData = props.component.getNormalizedData();
5737
+ return (jsxRuntime.jsxs("div", { class: ['left-bar', { active: props.isFocus() }], children: [jsxRuntime.jsx("div", { class: "insert-bar", children: jsxRuntime.jsx("table", { ref: insertBarRef, children: jsxRuntime.jsx("tbody", { children: normalizedData.map((row, index) => {
5738
+ let b = false;
5739
+ for (const item of row.cells) {
5740
+ if (item.visible) {
5741
+ b = true;
5742
+ break;
5743
+ }
5744
+ }
5745
+ return (jsxRuntime.jsx("tr", { style: {
5746
+ display: b ? '' : 'none'
5747
+ }, children: jsxRuntime.jsx("td", { children: jsxRuntime.jsxs("div", { class: "toolbar-item", children: [index === 0 && (jsxRuntime.jsx("span", { onMouseenter: () => {
5258
5748
  tableService.onInsertRowBefore.next(-1);
5259
5749
  }, onMouseleave: () => {
5260
5750
  tableService.onInsertRowBefore.next(null);
@@ -5267,6 +5757,11 @@ function LeftBar(props) {
5267
5757
  }, onMouseleave: () => {
5268
5758
  tableService.onInsertRowBefore.next(null);
5269
5759
  }, class: "insert-btn-wrap", onClick: () => {
5760
+ const cells = row.cells.filter(i => i.visible);
5761
+ if (cells.length < 2) {
5762
+ props.component.insertRow(index + row.cells.at(0).rowspan);
5763
+ return;
5764
+ }
5270
5765
  props.component.insertRow(index + 1);
5271
5766
  }, children: jsxRuntime.jsx("button", { class: "insert-btn", type: "button", children: "+" }) }), jsxRuntime.jsx(ComponentToolbar, { style: {
5272
5767
  display: deleteIndex() === index ? 'inline-block' : 'none',
@@ -5275,23 +5770,26 @@ function LeftBar(props) {
5275
5770
  top: 0,
5276
5771
  transform: 'translateY(-50%)'
5277
5772
  }, visible: deleteIndex() === index, children: jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(Button, { onClick: () => {
5278
- props.component.deleteRow(index);
5773
+ props.component.deleteRows();
5279
5774
  deleteIndex.set(null);
5280
5775
  }, children: jsxRuntime.jsx("span", { class: "xnote-icon-bin" }) }) }) })] }) }) }));
5281
- }) }) }) }), jsxRuntime.jsx("div", { class: "action-bar", children: jsxRuntime.jsx("table", { ref: actionBarRef, children: jsxRuntime.jsx("tbody", { children: props.component.state.rows.map((_, index) => {
5282
- return jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { onMousedown: (ev) => {
5776
+ }) }) }) }), jsxRuntime.jsx("div", { class: "action-bar", children: jsxRuntime.jsx("table", { ref: actionBarRef, children: jsxRuntime.jsx("tbody", { children: normalizedData.map((row, index) => {
5777
+ let b = false;
5778
+ for (const item of row.cells) {
5779
+ if (item.visible) {
5780
+ b = true;
5781
+ break;
5782
+ }
5783
+ }
5784
+ return jsxRuntime.jsx("tr", { style: {
5785
+ display: b ? '' : 'none'
5786
+ }, children: jsxRuntime.jsx("td", { onMousedown: ev => ev.preventDefault(), onClick: (ev) => {
5283
5787
  mouseDownFromToolbar = true;
5284
- if (!ev.shiftKey) {
5285
- deleteIndex.set(index);
5286
- }
5287
- else {
5288
- deleteIndex.set(null);
5289
- }
5290
5788
  selectRow(index, ev.shiftKey);
5291
5789
  }, class: {
5292
5790
  active: !position ? false :
5293
5791
  (position.startColumn === 0 &&
5294
- position.endColumn === state.layoutWidth.length &&
5792
+ position.endColumn === props.component.state.columnsConfig.length &&
5295
5793
  index >= position.startRow && index < position.endRow)
5296
5794
  } }) });
5297
5795
  }) }) }) })] }));
@@ -5300,10 +5798,6 @@ function LeftBar(props) {
5300
5798
 
5301
5799
  var scopedId$1 = "vf-d4c4a9";
5302
5800
 
5303
- function sum(numbers) {
5304
- return numbers.reduce((a, b) => a + b, 0);
5305
- }
5306
-
5307
5801
  function ResizeRow(props) {
5308
5802
  const dragLineRef = core.createRef();
5309
5803
  const tableService = core.inject(TableService);
@@ -5335,7 +5829,7 @@ function ResizeRow(props) {
5335
5829
  return jsxRuntime.jsx("div", { ref: dragLineRef, style: {
5336
5830
  display: styles().visible ? 'block' : 'none',
5337
5831
  top: styles().top + 'px',
5338
- width: sum(props.component.state.layoutWidth) + 'px'
5832
+ width: sum(props.component.state.columnsConfig) + 'px'
5339
5833
  }, class: 'drag-line' });
5340
5834
  });
5341
5835
  }
@@ -5369,16 +5863,19 @@ function SelectionMask(props) {
5369
5863
  if (selection.startRow > 0) {
5370
5864
  heightCompensation = -1;
5371
5865
  }
5372
- if (selection.endRow === state.rows.length) {
5866
+ if (selection.endRow + 1 === state.rows.length) {
5373
5867
  heightCompensation += 0.5;
5374
5868
  }
5375
5869
  const trs = Array.from(props.tableRef.current.rows);
5376
5870
  updateStyles(draft => {
5871
+ var _a;
5872
+ const height = trs[selection.endRow - 1].offsetHeight ||
5873
+ ((_a = trs[selection.endRow - 1].children[0]) === null || _a === void 0 ? void 0 : _a.offsetHeight) || 0;
5377
5874
  draft.visible = true;
5378
- draft.left = sum(state.layoutWidth.slice(0, selection.startColumn));
5875
+ draft.left = sum(state.columnsConfig.slice(0, selection.startColumn));
5379
5876
  draft.top = trs[selection.startRow].offsetTop + topCompensation;
5380
- draft.width = sum(state.layoutWidth.slice(selection.startColumn, selection.endColumn)) - 1 + 'px';
5381
- draft.height = trs[selection.endRow - 1].offsetTop + trs[selection.endRow - 1].offsetHeight + heightCompensation - draft.top + 'px';
5877
+ draft.width = sum(state.columnsConfig.slice(selection.startColumn, selection.endColumn)) - 1 + 'px';
5878
+ draft.height = trs[selection.endRow - 1].offsetTop + height + heightCompensation - draft.top + 'px';
5382
5879
  });
5383
5880
  }
5384
5881
  else {
@@ -5407,14 +5904,106 @@ function SelectionMask(props) {
5407
5904
  });
5408
5905
  }
5409
5906
 
5410
- // import { SlotRender } from '../SlotRender'
5907
+ /**
5908
+ * 修复不规范表格,并补全空位
5909
+ * @param table
5910
+ */
5911
+ function autoComplete(table) {
5912
+ const newTable = [];
5913
+ table.forEach((tr, rowIndex) => {
5914
+ let row = newTable[rowIndex];
5915
+ if (!row) {
5916
+ row = [];
5917
+ newTable[rowIndex] = row;
5918
+ }
5919
+ let startColumnIndex = 0;
5920
+ tr.forEach(td => {
5921
+ while (row[startColumnIndex]) {
5922
+ startColumnIndex++;
5923
+ }
5924
+ let maxColspan = 1;
5925
+ while (maxColspan < td.colspan) {
5926
+ if (!row[startColumnIndex + maxColspan]) {
5927
+ maxColspan++;
5928
+ }
5929
+ else {
5930
+ break;
5931
+ }
5932
+ }
5933
+ td.colspan = maxColspan;
5934
+ for (let i = rowIndex, len = td.rowspan + rowIndex; i < len; i++) {
5935
+ let row = newTable[i];
5936
+ if (!row) {
5937
+ row = [];
5938
+ newTable[i] = row;
5939
+ }
5940
+ for (let j = startColumnIndex, max = startColumnIndex + maxColspan; j < max; j++) {
5941
+ row[j] = td;
5942
+ }
5943
+ }
5944
+ startColumnIndex += maxColspan;
5945
+ });
5946
+ });
5947
+ const maxColumns = Math.max(...newTable.map(i => i.length));
5948
+ newTable.forEach(tr => {
5949
+ for (let i = 0; i < maxColumns; i++) {
5950
+ if (!tr[i]) {
5951
+ tr[i] = {
5952
+ id: uuid.v4(),
5953
+ rowspan: 1,
5954
+ colspan: 1,
5955
+ slot: new core$1.Slot([
5956
+ core$1.ContentType.BlockComponent
5957
+ ])
5958
+ };
5959
+ }
5960
+ }
5961
+ });
5962
+ const ids = [];
5963
+ const mergedConfig = {};
5964
+ const normalizedTable = newTable.map(tr => {
5965
+ return tr.map(td => {
5966
+ const is = ids.includes(td.id);
5967
+ if (is) {
5968
+ return {
5969
+ id: uuid.v4(),
5970
+ slot: new core$1.Slot([
5971
+ core$1.ContentType.BlockComponent,
5972
+ ])
5973
+ };
5974
+ }
5975
+ ids.push(td.id);
5976
+ return {
5977
+ id: td.id,
5978
+ slot: td.slot
5979
+ };
5980
+ });
5981
+ });
5982
+ ids.length = 0;
5983
+ newTable.forEach((tr, rowIndex) => {
5984
+ tr.forEach((td, colIndex) => {
5985
+ if (td.rowspan > 1 || td.colspan > 1) {
5986
+ if (ids.includes(td.id)) {
5987
+ return;
5988
+ }
5989
+ ids.push(td.id);
5990
+ mergedConfig[td.id] = normalizedTable[rowIndex + td.rowspan - 1][colIndex + td.colspan - 1].id;
5991
+ }
5992
+ });
5993
+ });
5994
+ return {
5995
+ mergedConfig,
5996
+ table: normalizedTable
5997
+ };
5998
+ }
5999
+
5411
6000
  const TableComponentView = core.withAnnotation({
5412
6001
  providers: [TableService]
5413
6002
  }, function TableComponentView(props) {
5414
6003
  const adapter = core.inject(platformBrowser.DomAdapter);
5415
6004
  const editorService = core.inject(exports.EditorService);
5416
6005
  const isFocus = core.createSignal(false);
5417
- const layoutWidth = core.createSignal(props.component.state.layoutWidth);
6006
+ const layoutWidth = core.createSignal(props.component.state.columnsConfig);
5418
6007
  const subscription = props.component.focus.subscribe(b => {
5419
6008
  isFocus.set(b);
5420
6009
  if (!b) {
@@ -5424,53 +6013,63 @@ const TableComponentView = core.withAnnotation({
5424
6013
  core.onUnmounted(() => {
5425
6014
  subscription.unsubscribe();
5426
6015
  });
6016
+ function resetIgnore() {
6017
+ props.component.ignoreSelectionChanges = false;
6018
+ }
5427
6019
  const tableRef = core.createRef();
5428
6020
  const isResizeColumn = core.createSignal(false);
5429
6021
  const rowMapping = new WeakMap();
5430
6022
  const readonly = useReadonly();
5431
6023
  const output = useOutput();
5432
6024
  return () => {
6025
+ const normalizedData = props.component.getNormalizedData();
5433
6026
  const state = props.component.state;
5434
- const rows = state.rows;
5435
- rows.forEach(row => {
5436
- if (rowMapping.has(row)) {
6027
+ // const rows = state.rows
6028
+ normalizedData.forEach(row => {
6029
+ if (rowMapping.has(row.row)) {
5437
6030
  return;
5438
6031
  }
5439
- rowMapping.set(row, Math.random());
6032
+ rowMapping.set(row.row, Math.random());
5440
6033
  });
5441
6034
  if (readonly() || output()) {
5442
- return (jsxRuntime.jsx("div", { class: "xnote-table", "data-component": props.component.name, "data-layout-width": state.layoutWidth, children: jsxRuntime.jsx("div", { class: "xnote-table-inner", ref: props.rootRef, children: jsxRuntime.jsx("div", { class: "xnote-table-container", children: jsxRuntime.jsxs("table", { class: [
6035
+ return (jsxRuntime.jsx("div", { class: "xnote-table", "data-component": props.component.name, "data-layout-width": `[${state.columnsConfig.join(',')}]`, children: jsxRuntime.jsx("div", { class: "xnote-table-inner", ref: props.rootRef, children: jsxRuntime.jsx("div", { class: "xnote-table-container", children: jsxRuntime.jsxs("table", { class: [
5443
6036
  'xnote-table-content',
5444
6037
  {
5445
6038
  'hide-selection': props.component.tableSelection()
5446
6039
  }
5447
- ], children: [jsxRuntime.jsx("colgroup", { children: layoutWidth().map(w => {
6040
+ ], children: [jsxRuntime.jsx("colgroup", { children: state.columnsConfig.map(w => {
5448
6041
  return jsxRuntime.jsx("col", { style: { width: w + 'px', minWidth: w + 'px' } });
5449
- }) }), jsxRuntime.jsx("tbody", { children: rows.map((row) => {
6042
+ }) }), jsxRuntime.jsx("tbody", { children: normalizedData.map((row) => {
5450
6043
  return (jsxRuntime.jsx("tr", { children: row.cells.map(cell => {
5451
- return adapter.slotRender(cell.slot, children => {
6044
+ return adapter.slotRender(cell.raw.slot, children => {
5452
6045
  return core$1.createVNode('td', {
5453
- key: cell.slot.id
6046
+ key: cell.raw.id,
6047
+ rowspan: cell.rowspan,
6048
+ colspan: cell.colspan
5454
6049
  }, children);
5455
6050
  }, readonly() || output());
5456
- }) }, rowMapping.get(row)));
6051
+ }) }, rowMapping.get(row.row)));
5457
6052
  }) })] }) }) }) }));
5458
6053
  }
5459
- return (jsxRuntime.jsx("div", { class: "xnote-table", "data-component": props.component.name, "data-layout-width": `[${state.layoutWidth.join(',')}]`, children: jsxRuntime.jsxs("div", { class: "xnote-table-inner", ref: props.rootRef, children: [jsxRuntime.jsx(TopBar, { isFocus: isFocus, layoutWidth: layoutWidth, component: props.component }), jsxRuntime.jsx(LeftBar, { tableRef: tableRef, isFocus: isFocus, component: props.component }), jsxRuntime.jsx(Scroll, { isFocus: isFocus, children: jsxRuntime.jsxs("div", { class: "xnote-table-container", children: [jsxRuntime.jsxs("table", { ref: tableRef, class: [
6054
+ return (jsxRuntime.jsx("div", { class: "xnote-table", "data-component": props.component.name, "data-layout-width": `[${state.columnsConfig.join(',')}]`, children: jsxRuntime.jsxs("div", { class: "xnote-table-inner", ref: props.rootRef, children: [jsxRuntime.jsx(TopBar, { isFocus: isFocus, layoutWidth: layoutWidth, component: props.component }), jsxRuntime.jsx(LeftBar, { tableRef: tableRef, isFocus: isFocus, component: props.component }), jsxRuntime.jsx(Scroll, { isFocus: isFocus, children: jsxRuntime.jsxs("div", { class: "xnote-table-container", children: [jsxRuntime.jsxs("table", { ref: tableRef, class: [
5460
6055
  'xnote-table-content',
5461
6056
  {
5462
6057
  'hide-selection': props.component.tableSelection()
5463
6058
  }
5464
6059
  ], children: [jsxRuntime.jsx("colgroup", { children: layoutWidth().map(w => {
5465
6060
  return jsxRuntime.jsx("col", { style: { width: w + 'px', minWidth: w + 'px' } });
5466
- }) }), jsxRuntime.jsx("tbody", { children: rows.map((row) => {
5467
- return (jsxRuntime.jsx("tr", { children: row.cells.map(cell => {
5468
- return adapter.slotRender(cell.slot, children => {
6061
+ }) }), jsxRuntime.jsx("tbody", { onMousedown: resetIgnore, children: normalizedData.map((row) => {
6062
+ return (jsxRuntime.jsx("tr", { children: row.cells.filter(i => {
6063
+ return i.visible;
6064
+ }).map(cell => {
6065
+ return adapter.slotRender(cell.raw.slot, children => {
5469
6066
  return core$1.createVNode('td', {
5470
- key: cell.slot.id
6067
+ key: cell.raw.id,
6068
+ rowspan: cell.rowspan,
6069
+ colspan: cell.colspan
5471
6070
  }, children);
5472
6071
  }, readonly() || output());
5473
- }) }, rowMapping.get(row)));
6072
+ }) }, rowMapping.get(row.row)));
5474
6073
  }) })] }), jsxRuntime.jsx(ResizeColumn, { tableRef: tableRef, component: props.component, layoutWidth: layoutWidth, onActiveStateChange: isActive => {
5475
6074
  isResizeColumn.set(isActive);
5476
6075
  } }), jsxRuntime.jsx(SelectionMask, { tableRef: tableRef, component: props.component })] }) }), jsxRuntime.jsx(ResizeRow, { component: props.component, tableRef: tableRef })] }) }));
@@ -5497,6 +6096,7 @@ const tableComponentLoader = {
5497
6096
  core$1.ContentType.BlockComponent,
5498
6097
  ]);
5499
6098
  arr.push({
6099
+ id: uuid.v4(),
5500
6100
  slot,
5501
6101
  rowspan: cell.rowSpan,
5502
6102
  colspan: cell.colSpan
@@ -5524,6 +6124,7 @@ const tableComponentLoader = {
5524
6124
  core$1.ContentType.BlockComponent,
5525
6125
  ]);
5526
6126
  arr.push({
6127
+ id: uuid.v4(),
5527
6128
  slot,
5528
6129
  rowspan: cell.rowSpan,
5529
6130
  colspan: cell.colSpan
@@ -5542,7 +6143,7 @@ const tableComponentLoader = {
5542
6143
  }
5543
6144
  bodies.unshift(...headers);
5544
6145
  const cells = autoComplete(bodies);
5545
- let layoutWidth = null;
6146
+ let layoutWidth = [];
5546
6147
  try {
5547
6148
  const columnWidth = JSON.parse(element.dataset.layoutWidth || '');
5548
6149
  if (Array.isArray(columnWidth)) {
@@ -5552,80 +6153,23 @@ const tableComponentLoader = {
5552
6153
  catch (e) {
5553
6154
  //
5554
6155
  }
5555
- if (!layoutWidth) {
5556
- layoutWidth = Array.from({ length: cells[0].length }).fill(100);
6156
+ const length = cells.table[0].length;
6157
+ for (let i = 0; i < length; i++) {
6158
+ layoutWidth[i] = layoutWidth[i] || 100;
5557
6159
  }
6160
+ layoutWidth.length = length;
5558
6161
  return new TableComponent(textbus, {
5559
- rows: cells.map(i => {
6162
+ columnsConfig: layoutWidth,
6163
+ mergeConfig: cells.mergedConfig,
6164
+ rows: cells.table.map(i => {
5560
6165
  return {
5561
6166
  height: 30,
5562
6167
  cells: i
5563
6168
  };
5564
- }),
5565
- layoutWidth
6169
+ })
5566
6170
  });
5567
6171
  }
5568
6172
  };
5569
- function autoComplete(table) {
5570
- const newTable = [];
5571
- table.forEach((tr, rowIndex) => {
5572
- if (!newTable[rowIndex]) {
5573
- newTable[rowIndex] = [];
5574
- }
5575
- const row = newTable[rowIndex];
5576
- let startColumnIndex = 0;
5577
- tr.forEach(td => {
5578
- while (row[startColumnIndex]) {
5579
- startColumnIndex++;
5580
- }
5581
- let maxColspan = 1;
5582
- while (maxColspan < td.colspan) {
5583
- if (!row[startColumnIndex + maxColspan]) {
5584
- maxColspan++;
5585
- }
5586
- else {
5587
- break;
5588
- }
5589
- }
5590
- td.colspan = maxColspan;
5591
- for (let i = rowIndex, len = td.rowspan + rowIndex; i < len; i++) {
5592
- if (!newTable[i]) {
5593
- newTable[i] = [];
5594
- }
5595
- const row = newTable[i];
5596
- for (let j = startColumnIndex, max = startColumnIndex + maxColspan; j < max; j++) {
5597
- row[j] = td;
5598
- }
5599
- }
5600
- startColumnIndex += maxColspan;
5601
- });
5602
- });
5603
- const maxColumns = Math.max(...newTable.map(i => i.length));
5604
- newTable.forEach(tr => {
5605
- for (let i = 0; i < maxColumns; i++) {
5606
- if (!tr[i]) {
5607
- tr[i] = {
5608
- rowspan: 1,
5609
- colspan: 1,
5610
- slot: new core$1.Slot([
5611
- core$1.ContentType.BlockComponent
5612
- ])
5613
- };
5614
- }
5615
- }
5616
- });
5617
- const recordCells = [];
5618
- return newTable.map(tr => {
5619
- return tr.filter(td => {
5620
- const is = recordCells.includes(td);
5621
- if (is) {
5622
- return false;
5623
- }
5624
- recordCells.push(td);
5625
- return true;
5626
- });
5627
- });
5628
- }
5629
6173
 
5630
6174
  function findFocusCell(table, slot) {
5631
6175
  var _a;
@@ -5662,18 +6206,25 @@ let TableSelectionAwarenessDelegate = class TableSelectionAwarenessDelegate exte
5662
6206
  if (!(commonAncestorComponent instanceof TableComponent)) {
5663
6207
  return false;
5664
6208
  }
5665
- const range = getSelectedRanges(commonAncestorComponent, findFocusCell(commonAncestorComponent, startSlot), findFocusCell(commonAncestorComponent, endSlot));
5666
- const rows = commonAncestorComponent.state.rows;
5667
- const startFocusSlot = rows[range.startRow].cells[range.startColumn].slot;
5668
- const endFocusSlot = rows[range.endRow].cells[range.endColumn].slot;
6209
+ const rect = commonAncestorComponent.getMaxRectangle(findFocusCell(commonAncestorComponent, startSlot), findFocusCell(commonAncestorComponent, endSlot));
5669
6210
  const renderer = this.domAdapter;
5670
- const startRect = renderer.getNativeNodeBySlot(startFocusSlot).getBoundingClientRect();
5671
- const endRect = renderer.getNativeNodeBySlot(endFocusSlot).getBoundingClientRect();
6211
+ if (!rect) {
6212
+ return false;
6213
+ }
6214
+ const normalizedSlots = commonAncestorComponent.getSelectedNormalizedSlotsByRectangle(rect);
6215
+ const rects = normalizedSlots.map(row => {
6216
+ return row.cells.filter(i => i.visible).map(i => {
6217
+ const td = renderer.getNativeNodeBySlot(i.raw.slot);
6218
+ return td.getBoundingClientRect();
6219
+ });
6220
+ }).flat();
6221
+ const left = Math.min(...rects.map(i => i.left));
6222
+ const top = Math.min(...rects.map(i => i.top));
5672
6223
  return [{
5673
- left: startRect.left,
5674
- top: startRect.top,
5675
- width: endRect.left + endRect.width - startRect.left,
5676
- height: endRect.top + endRect.height - startRect.top
6224
+ left,
6225
+ top,
6226
+ width: Math.max(...rects.map(i => i.right)) - left,
6227
+ height: Math.max(...rects.map(i => i.bottom)) - top
5677
6228
  }];
5678
6229
  }
5679
6230
  };
@@ -5682,32 +6233,6 @@ TableSelectionAwarenessDelegate = __decorate([
5682
6233
  __metadata("design:paramtypes", [platformBrowser.DomAdapter,
5683
6234
  core$1.Selection])
5684
6235
  ], TableSelectionAwarenessDelegate);
5685
- function getSelectedRanges(component, startSlot, endSlot) {
5686
- const p1 = finedPosition(component, startSlot);
5687
- const p2 = finedPosition(component, endSlot);
5688
- return {
5689
- startRow: Math.min(p1.rowIndex, p2.rowIndex),
5690
- endRow: Math.max(p1.rowIndex, p2.rowIndex),
5691
- startColumn: Math.min(p1.columnIndex, p2.columnIndex),
5692
- endColumn: Math.max(p1.columnIndex, p2.columnIndex)
5693
- };
5694
- }
5695
- function finedPosition(component, slot) {
5696
- const rows = component.state.rows;
5697
- for (let i = 0; i < rows.length; i++) {
5698
- const row = rows[i];
5699
- for (let j = 0; j < row.cells.length; j++) {
5700
- const cell = row.cells[j].slot;
5701
- if (cell === slot) {
5702
- return {
5703
- rowIndex: i,
5704
- columnIndex: j
5705
- };
5706
- }
5707
- }
5708
- }
5709
- return null;
5710
- }
5711
6236
 
5712
6237
  function TimelineComponentView(props) {
5713
6238
  const adapter = core.inject(platformBrowser.DomAdapter);
@@ -5872,6 +6397,7 @@ class Editor extends core$1.Textbus {
5872
6397
  strikeThroughFormatLoader,
5873
6398
  underlineFormatLoader
5874
6399
  ], attributeLoaders: [
6400
+ cellAlignAttrLoader,
5875
6401
  headingAttrLoader,
5876
6402
  textAlignAttrLoader,
5877
6403
  textIndentAttrLoader
@@ -5944,6 +6470,7 @@ class Editor extends core$1.Textbus {
5944
6470
  strikeThroughFormatter,
5945
6471
  underlineFormatter
5946
6472
  ], attributes: [
6473
+ cellAlignAttr,
5947
6474
  headingAttr,
5948
6475
  textAlignAttr,
5949
6476
  textIndentAttr
@@ -6023,6 +6550,8 @@ exports.BlockquoteComponent = BlockquoteComponent;
6023
6550
  exports.BlockquoteView = BlockquoteView;
6024
6551
  exports.BoldTool = BoldTool;
6025
6552
  exports.Button = Button;
6553
+ exports.CellAlignTool = CellAlignTool;
6554
+ exports.CellBackgroundTool = CellBackgroundTool;
6026
6555
  exports.CodeTool = CodeTool;
6027
6556
  exports.ColorTool = ColorTool;
6028
6557
  exports.ComponentToolbar = ComponentToolbar;
@@ -6052,6 +6581,7 @@ exports.ListComponentView = ListComponentView;
6052
6581
  exports.Matcher = Matcher;
6053
6582
  exports.MenuHeading = MenuHeading;
6054
6583
  exports.MenuItem = MenuItem;
6584
+ exports.MergeCellsTool = MergeCellsTool;
6055
6585
  exports.Organization = Organization;
6056
6586
  exports.OutputInjectionToken = OutputInjectionToken;
6057
6587
  exports.ParagraphComponent = ParagraphComponent;
@@ -6061,6 +6591,7 @@ exports.RootComponent = RootComponent;
6061
6591
  exports.RootView = RootView;
6062
6592
  exports.SourceCodeComponent = SourceCodeComponent;
6063
6593
  exports.SourceCodeView = SourceCodeView;
6594
+ exports.SplitCellsTool = SplitCellsTool;
6064
6595
  exports.StrikeThroughTool = StrikeThroughTool;
6065
6596
  exports.TableComponent = TableComponent;
6066
6597
  exports.TableComponentView = TableComponentView;
@@ -6073,12 +6604,13 @@ exports.UnderlineTool = UnderlineTool;
6073
6604
  exports.VideoComponent = VideoComponent;
6074
6605
  exports.VideoView = VideoView;
6075
6606
  exports.atComponentLoader = atComponentLoader;
6076
- exports.autoComplete = autoComplete;
6077
6607
  exports.backgroundColorFormatLoader = backgroundColorFormatLoader;
6078
6608
  exports.backgroundColorFormatter = backgroundColorFormatter;
6079
6609
  exports.blockquoteComponentLoader = blockquoteComponentLoader;
6080
6610
  exports.boldFormatLoader = boldFormatLoader;
6081
6611
  exports.boldFormatter = boldFormatter;
6612
+ exports.cellAlignAttr = cellAlignAttr;
6613
+ exports.cellAlignAttrLoader = cellAlignAttrLoader;
6082
6614
  exports.codeFormatLoader = codeFormatLoader;
6083
6615
  exports.codeFormatter = codeFormatter;
6084
6616
  exports.colorFormatLoader = colorFormatLoader;