@textbus/xnote 0.0.5 → 0.0.7

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 (68) 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/editor.d.ts +8 -1
  13. package/bundles/fonts/textbus.svg +7 -1
  14. package/bundles/fonts/textbus.ttf +0 -0
  15. package/bundles/fonts/textbus.woff +0 -0
  16. package/bundles/index.css +1 -1
  17. package/bundles/index.esm.css +1 -1
  18. package/bundles/index.esm.js +947 -396
  19. package/bundles/index.js +950 -394
  20. package/bundles/plugins/_common/_api.d.ts +1 -0
  21. package/bundles/plugins/_common/attr.tool.d.ts +1 -1
  22. package/bundles/plugins/_common/block.tool.d.ts +1 -1
  23. package/bundles/plugins/_common/bold.tool.d.ts +1 -1
  24. package/bundles/plugins/_common/code.tool.d.ts +1 -1
  25. package/bundles/plugins/_common/color.tool.d.ts +1 -1
  26. package/bundles/plugins/_common/font-family.tool.d.ts +1 -1
  27. package/bundles/plugins/_common/font-size.tool.d.ts +1 -1
  28. package/bundles/plugins/_common/italic.tool.d.ts +1 -1
  29. package/bundles/plugins/_common/link.tool.d.ts +1 -1
  30. package/bundles/plugins/_common/strike-through.tool.d.ts +1 -1
  31. package/bundles/plugins/_common/table/_api.d.ts +4 -0
  32. package/bundles/plugins/_common/table/cell-align.tool.d.ts +1 -0
  33. package/bundles/plugins/_common/table/cell-background.tool.d.ts +1 -0
  34. package/bundles/plugins/_common/table/merge-cells.tool.d.ts +1 -0
  35. package/bundles/plugins/_common/table/split-cells.tool.d.ts +1 -0
  36. package/bundles/plugins/_common/underline.tool.d.ts +1 -1
  37. package/bundles/plugins/left-toolbar/insert-tool.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-selection-awareness-delegate.d.ts +2 -2
  60. package/bundles/textbus/components/table/table.component.d.ts +30 -7
  61. package/bundles/textbus/components/table/table.service.d.ts +0 -8
  62. package/bundles/textbus/components/table/tools/complete.d.ts +19 -0
  63. package/bundles/textbus/components/table/tools/merge.d.ts +23 -0
  64. package/bundles/textbus/components/timeline/timeline-component.view.d.ts +1 -1
  65. package/bundles/textbus/components/todolist/todolist.component.d.ts +1 -1
  66. package/bundles/textbus/components/video/video.component.d.ts +1 -1
  67. package/bundles/xnote-message-bus.d.ts +21 -0
  68. package/package.json +13 -10
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() {
@@ -989,7 +993,8 @@ function ParagraphView(props) {
989
993
  }
990
994
  const paragraphComponentLoader = {
991
995
  match(element, returnableContentTypes) {
992
- return returnableContentTypes.includes(core$1.ContentType.BlockComponent) && (element.dataset.component === ParagraphComponent.componentName || /^P|H[1-6]$/.test(element.tagName));
996
+ return returnableContentTypes.includes(core$1.ContentType.BlockComponent) &&
997
+ (element.dataset.component === ParagraphComponent.componentName || /^P|H[1-6]$/.test(element.tagName));
993
998
  },
994
999
  read(element, textbus, slotParser) {
995
1000
  let content;
@@ -1770,16 +1775,16 @@ function AttrTool(props) {
1770
1775
  const states = checkStates();
1771
1776
  return (jsxRuntime.jsx(Dropdown, { width: 'auto', style: props.style, abreast: props.abreast, onCheck: updateAttr, trigger: 'hover', menu: [
1772
1777
  {
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" }),
1778
+ 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
1779
  value: 't-l'
1775
1780
  }, {
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" }),
1781
+ 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
1782
  value: 't-r'
1778
1783
  }, {
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" }),
1784
+ 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
1785
  value: 't-c'
1781
1786
  }, {
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" }),
1787
+ 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
1788
  value: 't-j'
1784
1789
  }, {
1785
1790
  label: jsxRuntime.jsx(Divider, {}),
@@ -1795,20 +1800,99 @@ function AttrTool(props) {
1795
1800
  });
1796
1801
  }
1797
1802
 
1803
+ class Rectangle {
1804
+ constructor(x1, y1, x2, y2) {
1805
+ this.x1 = x1;
1806
+ this.y1 = y1;
1807
+ this.x2 = x2;
1808
+ this.y2 = y2;
1809
+ }
1810
+ intersects(other) {
1811
+ return this.x1 < other.x2 && this.x2 > other.x1 && this.y1 < other.y2 && this.y2 > other.y1;
1812
+ }
1813
+ merge(other) {
1814
+ 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));
1815
+ }
1816
+ }
1817
+ function findNonIntersectingRectangles(rectangles) {
1818
+ const merged = [];
1819
+ const remaining = [...rectangles];
1820
+ while (remaining.length > 0) {
1821
+ const current = remaining.shift();
1822
+ let mergedWithCurrent = false;
1823
+ for (let i = 0; i < merged.length; i++) {
1824
+ if (current.intersects(merged[i])) {
1825
+ merged[i] = current.merge(merged[i]);
1826
+ mergedWithCurrent = true;
1827
+ break;
1828
+ }
1829
+ }
1830
+ if (!mergedWithCurrent) {
1831
+ merged.push(current);
1832
+ }
1833
+ }
1834
+ return merged;
1835
+ }
1836
+ function getMaxRectangle(start, rectangles) {
1837
+ let merged = start;
1838
+ const remaining = [...rectangles];
1839
+ while (remaining.length > 0) {
1840
+ const current = remaining.shift();
1841
+ if (current.intersects(merged)) {
1842
+ merged = current.merge(merged);
1843
+ }
1844
+ }
1845
+ return merged;
1846
+ }
1847
+ function applyRectangles(rows, rectangles) {
1848
+ const table = rows.map(row => {
1849
+ return {
1850
+ row,
1851
+ cells: row.cells.map(cell => {
1852
+ return {
1853
+ rowspan: 1,
1854
+ colspan: 1,
1855
+ visible: true,
1856
+ raw: cell
1857
+ };
1858
+ })
1859
+ };
1860
+ });
1861
+ rectangles.forEach(rect => {
1862
+ const { x1, y1, x2, y2 } = rect;
1863
+ const rowspan = y2 - y1;
1864
+ const colspan = x2 - x1;
1865
+ for (let i = y1; i < y2; i++) {
1866
+ for (let j = x1; j < x2; j++) {
1867
+ const item = table[i].cells[j];
1868
+ if (i === y1 && j === x1) {
1869
+ item.visible = true;
1870
+ item.rowspan = rowspan;
1871
+ item.colspan = colspan;
1872
+ }
1873
+ else {
1874
+ item.visible = false;
1875
+ }
1876
+ }
1877
+ }
1878
+ });
1879
+ return table;
1880
+ }
1881
+
1798
1882
  const defaultRowHeight = 30;
1799
1883
  const defaultColumnWidth = 100;
1800
1884
  class TableComponent extends core$1.Component {
1801
1885
  static fromJSON(textbus, json) {
1802
1886
  const registry = textbus.get(core$1.Registry);
1803
1887
  return new TableComponent(textbus, {
1804
- layoutWidth: json.layoutWidth || [],
1888
+ columnsConfig: json.columnsConfig || [],
1889
+ mergeConfig: json.mergeConfig || [],
1805
1890
  rows: json.rows.map(row => {
1806
1891
  return {
1807
1892
  height: row.height,
1808
1893
  cells: row.cells.map(cell => {
1809
1894
  return {
1810
- colspan: cell.colspan,
1811
- rowspan: cell.rowspan,
1895
+ id: cell.id,
1812
1896
  slot: registry.createSlot(cell.slot)
1813
1897
  };
1814
1898
  })
@@ -1817,7 +1901,8 @@ class TableComponent extends core$1.Component {
1817
1901
  });
1818
1902
  }
1819
1903
  constructor(textbus, state = {
1820
- layoutWidth: Array.from({ length: 5 }).fill(100),
1904
+ columnsConfig: Array.from({ length: 5 }).fill(defaultColumnWidth),
1905
+ mergeConfig: {},
1821
1906
  rows: Array.from({ length: 3 }).map(() => {
1822
1907
  return {
1823
1908
  height: defaultRowHeight,
@@ -1826,9 +1911,8 @@ class TableComponent extends core$1.Component {
1826
1911
  const slot = new core$1.Slot([core$1.ContentType.BlockComponent]);
1827
1912
  slot.insert(p);
1828
1913
  return {
1829
- rowspan: 1,
1830
- colspan: 1,
1831
- slot
1914
+ slot,
1915
+ id: uuid.v4()
1832
1916
  };
1833
1917
  })
1834
1918
  };
@@ -1836,11 +1920,236 @@ class TableComponent extends core$1.Component {
1836
1920
  }) {
1837
1921
  super(textbus, state);
1838
1922
  this.selection = this.textbus.get(core$1.Selection);
1923
+ this.commander = this.textbus.get(core$1.Commander);
1839
1924
  this.focus = new core$1.Subject();
1840
1925
  this.tableSelection = core.createSignal(null);
1926
+ this.ignoreSelectionChanges = false;
1927
+ this.normalizedData = [];
1841
1928
  }
1842
1929
  getSlots() {
1843
- return this.state.rows.map(i => i.cells.map(j => j.slot)).flat();
1930
+ return this.normalizedData.map(item => {
1931
+ return item.cells.filter(i => i.visible).map(i => i.raw.slot);
1932
+ }).flat();
1933
+ }
1934
+ mergeCellBySelection() {
1935
+ var _a, _b, _c, _d;
1936
+ const slots = this.getSelectedNormalizedSlots();
1937
+ if (slots) {
1938
+ 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;
1939
+ 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;
1940
+ if (start && end) {
1941
+ slots.forEach(item => {
1942
+ item.cells.forEach(cell => {
1943
+ if (cell.raw.id === start.id) {
1944
+ return;
1945
+ }
1946
+ cell.raw.slot.cleanFormats();
1947
+ cell.raw.slot.cleanAttributes();
1948
+ cell.raw.slot.retain(0);
1949
+ cell.raw.slot.delete(cell.raw.slot.length);
1950
+ Reflect.deleteProperty(this.state.mergeConfig, cell.raw.id);
1951
+ });
1952
+ });
1953
+ this.state.mergeConfig[start.id] = end.id;
1954
+ }
1955
+ }
1956
+ this.selection.collapse(true);
1957
+ }
1958
+ splitCellsBySelection() {
1959
+ var _a, _b, _c, _d;
1960
+ const slots = this.getSelectedNormalizedSlots();
1961
+ if (slots) {
1962
+ slots.forEach(item => {
1963
+ item.cells.forEach(cell => {
1964
+ Reflect.deleteProperty(this.state.mergeConfig, cell.raw.id);
1965
+ });
1966
+ });
1967
+ 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;
1968
+ 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;
1969
+ if (start && end) {
1970
+ this.selection.setBaseAndExtent(start.slot, 0, end.slot, end.slot.length);
1971
+ }
1972
+ }
1973
+ }
1974
+ getMaxRectangle(startSlot, endSlot) {
1975
+ let index1 = -1;
1976
+ let index2 = -1;
1977
+ let x1 = -1;
1978
+ let x2 = -1;
1979
+ let y1 = -1;
1980
+ let y2 = -1;
1981
+ let index = 0;
1982
+ for (let i = 0; i < this.state.rows.length; i++) {
1983
+ const row = this.state.rows[i];
1984
+ for (let j = 0; j < row.cells.length; j++) {
1985
+ const item = row.cells[j];
1986
+ if (item.slot === startSlot) {
1987
+ index1 = index;
1988
+ x1 = j;
1989
+ y1 = i;
1990
+ }
1991
+ if (item.slot === endSlot) {
1992
+ index2 = index;
1993
+ x2 = j;
1994
+ y2 = i;
1995
+ }
1996
+ index++;
1997
+ }
1998
+ }
1999
+ if (index1 === -1 || index2 === -1) {
2000
+ return null;
2001
+ }
2002
+ if (x1 > x2) {
2003
+ [x1, x2] = [x2, x1];
2004
+ }
2005
+ if (y1 > y2) {
2006
+ [y1, y2] = [y2, y1];
2007
+ }
2008
+ return getMaxRectangle(new Rectangle(x1, y1, x2 + 1, y2 + 1), this.getMergedRectangles());
2009
+ }
2010
+ getSelectedNormalizedSlots() {
2011
+ const rect = this.getSelectedRect();
2012
+ if (rect) {
2013
+ return this.getSelectedNormalizedSlotsByRectangle(rect);
2014
+ }
2015
+ return null;
2016
+ }
2017
+ getSelectedRect() {
2018
+ const getSelfSlot = (slot) => {
2019
+ let cell = slot;
2020
+ while ((cell === null || cell === void 0 ? void 0 : cell.parent) && cell.parent !== this) {
2021
+ cell = cell.parentSlot;
2022
+ }
2023
+ return cell;
2024
+ };
2025
+ const start = getSelfSlot(this.selection.startSlot);
2026
+ const end = getSelfSlot(this.selection.endSlot);
2027
+ if (start && end) {
2028
+ return this.getMaxRectangle(start, end);
2029
+ }
2030
+ return null;
2031
+ }
2032
+ getSelectedNormalizedSlotsByRectangle(rectangle) {
2033
+ return this.normalizedData.slice(rectangle.y1, rectangle.y2).map(item => {
2034
+ return {
2035
+ row: item.row,
2036
+ cells: item.cells.slice(rectangle.x1, rectangle.x2)
2037
+ };
2038
+ });
2039
+ }
2040
+ getCellBySlot(slot) {
2041
+ for (const row of this.state.rows) {
2042
+ for (const cell of row.cells) {
2043
+ if (cell.slot === slot) {
2044
+ return cell;
2045
+ }
2046
+ }
2047
+ }
2048
+ return null;
2049
+ }
2050
+ getNormalizedData() {
2051
+ if (!this.changeMarker.dirty) {
2052
+ return this.normalizedData;
2053
+ }
2054
+ const nonIntersectingRectangles = this.getMergedRectangles();
2055
+ this.normalizedData = applyRectangles(this.state.rows, nonIntersectingRectangles);
2056
+ return this.normalizedData;
2057
+ }
2058
+ selectRow(startIndex, endIndex = startIndex + 1) {
2059
+ if (startIndex > endIndex) {
2060
+ [startIndex, endIndex] = [endIndex, startIndex];
2061
+ }
2062
+ if (startIndex === endIndex) {
2063
+ endIndex++;
2064
+ }
2065
+ const selectedSlots = [];
2066
+ const rows = this.getNormalizedData();
2067
+ rows.slice(startIndex, endIndex).forEach(row => {
2068
+ selectedSlots.push(...row.cells.filter(i => i.visible).map(i => i.raw.slot));
2069
+ });
2070
+ this.ignoreSelectionChanges = true;
2071
+ const slotRanges = selectedSlots.map(i => {
2072
+ return {
2073
+ slot: i,
2074
+ startIndex: 0,
2075
+ endIndex: i.length
2076
+ };
2077
+ });
2078
+ this.selection.setSelectedRanges(slotRanges);
2079
+ this.tableSelection.set({
2080
+ startColumn: 0,
2081
+ endColumn: this.state.columnsConfig.length,
2082
+ startRow: startIndex,
2083
+ endRow: endIndex,
2084
+ });
2085
+ this.focus.next(true);
2086
+ if (slotRanges.length) {
2087
+ setTimeout(() => {
2088
+ this.selection.restore();
2089
+ this.textbus.focus();
2090
+ });
2091
+ }
2092
+ }
2093
+ selectColumn(startIndex, endIndex = startIndex + 1) {
2094
+ if (startIndex > endIndex) {
2095
+ [startIndex, endIndex] = [endIndex, startIndex];
2096
+ }
2097
+ if (startIndex === endIndex) {
2098
+ endIndex++;
2099
+ }
2100
+ const selectedSlots = [];
2101
+ const rows = this.getNormalizedData();
2102
+ rows.forEach(row => {
2103
+ selectedSlots.push(...row.cells.slice(startIndex, endIndex).filter(i => i.visible).map(i => i.raw.slot));
2104
+ });
2105
+ this.ignoreSelectionChanges = true;
2106
+ const slotRanges = selectedSlots.map(i => {
2107
+ return {
2108
+ slot: i,
2109
+ startIndex: 0,
2110
+ endIndex: i.length
2111
+ };
2112
+ });
2113
+ this.selection.setSelectedRanges(slotRanges);
2114
+ this.tableSelection.set({
2115
+ startColumn: startIndex,
2116
+ endColumn: endIndex,
2117
+ startRow: 0,
2118
+ endRow: this.state.rows.length,
2119
+ });
2120
+ this.focus.next(true);
2121
+ this.selection.restore();
2122
+ this.textbus.focus();
2123
+ // if (slotRanges.length) {
2124
+ // setTimeout(() => {
2125
+ // this.selection.restore()
2126
+ // this.textbus.focus()
2127
+ // })
2128
+ // }
2129
+ }
2130
+ getMergedRectangles() {
2131
+ const rectangles = [];
2132
+ Object.entries(this.state.mergeConfig).forEach(([key, value]) => {
2133
+ const p1 = this.getCoordinateById(key);
2134
+ if (p1) {
2135
+ const p2 = this.getCoordinateById(value);
2136
+ if (p2) {
2137
+ rectangles.push(new Rectangle(p1[0], p1[1], p2[0] + 1, p2[1] + 1));
2138
+ }
2139
+ }
2140
+ });
2141
+ return findNonIntersectingRectangles(rectangles);
2142
+ }
2143
+ getCoordinateById(id) {
2144
+ const rows = this.state.rows;
2145
+ for (let i = 0; i < rows.length; i++) {
2146
+ const row = rows[i];
2147
+ const colIndex = row.cells.findIndex(i => i.id === id);
2148
+ if (colIndex > -1) {
2149
+ return [colIndex, i];
2150
+ }
2151
+ }
2152
+ return null;
1844
2153
  }
1845
2154
  setup() {
1846
2155
  const selection = core$1.useContext(core$1.Selection);
@@ -1854,6 +2163,9 @@ class TableComponent extends core$1.Component {
1854
2163
  return slot.parent === this;
1855
2164
  });
1856
2165
  const sub = selection.onChange.subscribe(() => {
2166
+ if (this.ignoreSelectionChanges) {
2167
+ return;
2168
+ }
1857
2169
  if (selection.commonAncestorComponent !== this || selection.isCollapsed) {
1858
2170
  this.tableSelection.set(null);
1859
2171
  }
@@ -1861,115 +2173,109 @@ class TableComponent extends core$1.Component {
1861
2173
  core$1.onDestroy(() => {
1862
2174
  sub.unsubscribe();
1863
2175
  });
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;
2176
+ core$1.onGetRanges(ev => {
2177
+ if (this.selection.isCollapsed || this.ignoreSelectionChanges) {
2178
+ return;
1868
2179
  }
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
- }
2180
+ const rect = this.getSelectedRect();
2181
+ if (rect) {
2182
+ this.tableSelection.set({
2183
+ startColumn: rect.x1,
2184
+ endColumn: rect.x2,
2185
+ startRow: rect.y1,
2186
+ endRow: rect.y2
2187
+ });
2188
+ const selectedSlots = this.getSelectedNormalizedSlotsByRectangle(rect);
2189
+ const slotRanges = selectedSlots.map(item => {
2190
+ return item.cells.filter(i => {
2191
+ return i.visible;
2192
+ }).map(i => {
2193
+ return {
2194
+ startIndex: 0,
2195
+ endIndex: i.raw.slot.length,
2196
+ slot: i.raw.slot
2197
+ };
2198
+ });
2199
+ }).flat();
2200
+ if (slotRanges.length > 1) {
2201
+ ev.useRanges(slotRanges);
1882
2202
  }
1883
2203
  }
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();
2204
+ });
2205
+ }
2206
+ deleteColumns() {
2207
+ const selection = this.tableSelection();
2208
+ if (selection) {
2209
+ const { startColumn, endColumn } = selection;
2210
+ if (startColumn === 0 && endColumn === this.state.columnsConfig.length) {
2211
+ this.commander.removeComponent(this);
2212
+ return;
1901
2213
  }
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
2214
+ this.state.columnsConfig.splice(startColumn, endColumn - startColumn);
2215
+ const mergeConfig = this.state.mergeConfig;
2216
+ const keys = Object.keys(mergeConfig);
2217
+ this.state.rows.forEach(row => {
2218
+ const before = row.cells.at(startColumn - 1);
2219
+ const after = row.cells.at(endColumn);
2220
+ const cells = row.cells.splice(startColumn, endColumn - startColumn);
2221
+ cells.forEach(cell => {
2222
+ if (keys.includes(cell.id)) {
2223
+ if (after) {
2224
+ mergeConfig[after.id] = mergeConfig[cell.id];
2225
+ }
2226
+ Reflect.deleteProperty(mergeConfig, cell.id);
2227
+ }
2228
+ if (before) {
2229
+ keys.forEach(key => {
2230
+ if (mergeConfig[key] === cell.id) {
2231
+ mergeConfig[key] = before.id;
2232
+ }
1915
2233
  });
1916
- return;
1917
2234
  }
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
2235
  });
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
- });
2236
+ });
2237
+ }
2238
+ this.tableSelection.set(null);
1965
2239
  this.selection.unSelect();
1966
2240
  }
1967
- deleteRow(index) {
1968
- this.state.rows.splice(index, 1);
2241
+ deleteRows() {
2242
+ const selection = this.tableSelection();
2243
+ if (selection) {
2244
+ const { startRow, endRow } = selection;
2245
+ if (startRow === 0 && endRow === this.state.rows.length) {
2246
+ this.commander.removeComponent(this);
2247
+ return;
2248
+ }
2249
+ const mergeConfig = this.state.mergeConfig;
2250
+ const keys = Object.keys(mergeConfig);
2251
+ const rows = this.state.rows;
2252
+ const deletedRows = rows.splice(startRow, endRow - startRow);
2253
+ deletedRows.forEach(row => {
2254
+ row.cells.forEach((cell, colIndex) => {
2255
+ var _a, _b;
2256
+ const before = (_a = rows.at(startRow - 1)) === null || _a === void 0 ? void 0 : _a.cells.at(colIndex);
2257
+ const after = (_b = rows.at(startRow)) === null || _b === void 0 ? void 0 : _b.cells.at(colIndex);
2258
+ if (keys.includes(cell.id)) {
2259
+ if (after) {
2260
+ mergeConfig[after.id] = mergeConfig[cell.id];
2261
+ }
2262
+ Reflect.deleteProperty(mergeConfig, cell.id);
2263
+ }
2264
+ if (before) {
2265
+ keys.forEach(key => {
2266
+ if (mergeConfig[key] === cell.id) {
2267
+ mergeConfig[key] = before.id;
2268
+ }
2269
+ });
2270
+ }
2271
+ });
2272
+ });
2273
+ }
2274
+ this.tableSelection.set(null);
1969
2275
  this.selection.unSelect();
1970
2276
  }
1971
2277
  insertColumn(index) {
1972
- this.state.layoutWidth.splice(index, 0, defaultColumnWidth);
2278
+ this.state.columnsConfig.splice(index, 0, defaultColumnWidth);
1973
2279
  this.state.rows.forEach(row => {
1974
2280
  const slot = new core$1.Slot([
1975
2281
  core$1.ContentType.BlockComponent,
@@ -1981,14 +2287,12 @@ class TableComponent extends core$1.Component {
1981
2287
  ])
1982
2288
  }));
1983
2289
  row.cells.splice(index, 0, {
1984
- rowspan: 1,
1985
- colspan: 1,
2290
+ id: uuid.v4(),
1986
2291
  slot
1987
2292
  });
1988
2293
  });
1989
2294
  this.textbus.nextTick(() => {
1990
- var _a;
1991
- const slot = (_a = this.state.rows[0].cells[index]) === null || _a === void 0 ? void 0 : _a.slot;
2295
+ const slot = this.state.rows[0].cells[index].slot;
1992
2296
  if (slot) {
1993
2297
  this.selection.selectFirstPosition(slot.getContentAtIndex(0));
1994
2298
  }
@@ -1997,7 +2301,7 @@ class TableComponent extends core$1.Component {
1997
2301
  insertRow(index) {
1998
2302
  this.state.rows.splice(index, 0, {
1999
2303
  height: defaultRowHeight,
2000
- cells: this.state.layoutWidth.map(() => {
2304
+ cells: this.state.columnsConfig.map(() => {
2001
2305
  const slot = new core$1.Slot([
2002
2306
  core$1.ContentType.BlockComponent,
2003
2307
  ]);
@@ -2008,15 +2312,13 @@ class TableComponent extends core$1.Component {
2008
2312
  ])
2009
2313
  }));
2010
2314
  return {
2011
- rowspan: 1,
2012
- colspan: 1,
2315
+ id: uuid.v4(),
2013
2316
  slot
2014
2317
  };
2015
2318
  })
2016
2319
  });
2017
2320
  this.textbus.nextTick(() => {
2018
- var _a;
2019
- const slot = (_a = this.state.rows[index].cells[0]) === null || _a === void 0 ? void 0 : _a.slot;
2321
+ const slot = this.state.rows[index].cells[0].slot;
2020
2322
  if (slot) {
2021
2323
  this.selection.selectFirstPosition(slot.getContentAtIndex(0));
2022
2324
  }
@@ -2051,7 +2353,7 @@ function registerStrikeThroughShortcut(textbus) {
2051
2353
  const keyboard = textbus.get(core$1.Keyboard);
2052
2354
  keyboard.addShortcut({
2053
2355
  keymap: {
2054
- ctrlKey: true,
2356
+ modKey: true,
2055
2357
  key: 'd'
2056
2358
  },
2057
2359
  action: () => {
@@ -2235,7 +2537,7 @@ function registerListShortcut(textbus) {
2235
2537
  keyboard.addShortcut({
2236
2538
  keymap: {
2237
2539
  key: ['o', 'u'],
2238
- ctrlKey: true,
2540
+ modKey: true,
2239
2541
  shiftKey: true
2240
2542
  },
2241
2543
  action(key) {
@@ -2767,43 +3069,43 @@ function BlockTool() {
2767
3069
  return (jsxRuntime.jsx(Dropdown, { width: 'auto', onCheck: transform, trigger: 'hover', menu: [
2768
3070
  {
2769
3071
  label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-pilcrow" }), desc: jsxRuntime.jsx(Keymap, { keymap: {
2770
- ctrlKey: true,
3072
+ modKey: true,
2771
3073
  key: '0'
2772
3074
  } }), checked: states.paragraph, children: "\u6B63\u6587" }),
2773
3075
  value: 'paragraph'
2774
3076
  }, {
2775
3077
  label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h1" }), desc: jsxRuntime.jsx(Keymap, { keymap: {
2776
- ctrlKey: true,
3078
+ modKey: true,
2777
3079
  key: '1'
2778
3080
  } }), checked: states.h1, children: "\u4E00\u7EA7\u6807\u9898" }),
2779
3081
  value: 'h1'
2780
3082
  }, {
2781
3083
  label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h2" }), desc: jsxRuntime.jsx(Keymap, { keymap: {
2782
- ctrlKey: true,
3084
+ modKey: true,
2783
3085
  key: '2'
2784
3086
  } }), checked: states.h2, children: "\u4E8C\u7EA7\u6807\u9898" }),
2785
3087
  value: 'h2'
2786
3088
  }, {
2787
3089
  label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h3" }), desc: jsxRuntime.jsx(Keymap, { keymap: {
2788
- ctrlKey: true,
3090
+ modKey: true,
2789
3091
  key: '3'
2790
3092
  } }), checked: states.h3, children: "\u4E09\u7EA7\u6807\u9898" }),
2791
3093
  value: 'h3'
2792
3094
  }, {
2793
3095
  label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h4" }), desc: jsxRuntime.jsx(Keymap, { keymap: {
2794
- ctrlKey: true,
3096
+ modKey: true,
2795
3097
  key: '4'
2796
3098
  } }), checked: states.h4, children: "\u56DB\u7EA7\u6807\u9898" }),
2797
3099
  value: 'h4'
2798
3100
  }, {
2799
3101
  label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h5" }), desc: jsxRuntime.jsx(Keymap, { keymap: {
2800
- ctrlKey: true,
3102
+ modKey: true,
2801
3103
  key: '5'
2802
3104
  } }), checked: states.h5, children: "\u4E94\u7EA7\u6807\u9898" }),
2803
3105
  value: 'h5'
2804
3106
  }, {
2805
3107
  label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h6" }), desc: jsxRuntime.jsx(Keymap, { keymap: {
2806
- ctrlKey: true,
3108
+ modKey: true,
2807
3109
  key: '6'
2808
3110
  } }), checked: states.h6, children: "\u516D\u7EA7\u6807\u9898" }),
2809
3111
  value: 'h6'
@@ -2814,13 +3116,13 @@ function BlockTool() {
2814
3116
  label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-checkbox-checked" }), checked: states.todolist, children: "\u5F85\u529E\u4E8B\u9879" }),
2815
3117
  value: 'todolist'
2816
3118
  }, {
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" }),
3119
+ 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
3120
  value: 'ol'
2819
3121
  }, {
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" }),
3122
+ 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
3123
  value: 'ul'
2822
3124
  }, {
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" }),
3125
+ 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
3126
  value: 'blockquote'
2825
3127
  }, {
2826
3128
  label: jsxRuntime.jsx(MenuItem, { icon: jsxRuntime.jsx("span", { class: "xnote-icon-source-code" }), checked: states.sourceCode, children: "\u4EE3\u7801\u5757" }),
@@ -2880,7 +3182,7 @@ function registerBoldShortcut(textbus) {
2880
3182
  const keyboard = textbus.get(core$1.Keyboard);
2881
3183
  keyboard.addShortcut({
2882
3184
  keymap: {
2883
- ctrlKey: true,
3185
+ modKey: true,
2884
3186
  key: 'b'
2885
3187
  },
2886
3188
  action: () => {
@@ -2927,7 +3229,7 @@ function registerCodeShortcut(textbus) {
2927
3229
  const keyboard = textbus.get(core$1.Keyboard);
2928
3230
  keyboard.addShortcut({
2929
3231
  keymap: {
2930
- ctrlKey: true,
3232
+ modKey: true,
2931
3233
  key: ','
2932
3234
  },
2933
3235
  action: () => {
@@ -3037,7 +3339,7 @@ function registerItalicShortcut(textbus) {
3037
3339
  const keyboard = textbus.get(core$1.Keyboard);
3038
3340
  keyboard.addShortcut({
3039
3341
  keymap: {
3040
- ctrlKey: true,
3342
+ modKey: true,
3041
3343
  key: 'i'
3042
3344
  },
3043
3345
  action: () => {
@@ -3120,7 +3422,7 @@ function registerUnderlineShortcut(textbus) {
3120
3422
  const keyboard = textbus.get(core$1.Keyboard);
3121
3423
  keyboard.addShortcut({
3122
3424
  keymap: {
3123
- ctrlKey: true,
3425
+ modKey: true,
3124
3426
  key: 'u'
3125
3427
  },
3126
3428
  action: () => {
@@ -3596,6 +3898,171 @@ function UnderlineTool() {
3596
3898
  };
3597
3899
  }
3598
3900
 
3901
+ const cellAlignAttr = new core$1.Attribute('cellAlign', {
3902
+ render(node, formatValue) {
3903
+ node.styles.set('verticalAlign', formatValue);
3904
+ }
3905
+ });
3906
+ const cellAlignAttrLoader = {
3907
+ match(element) {
3908
+ return element instanceof HTMLTableCellElement && !!element.style.verticalAlign;
3909
+ },
3910
+ read(element) {
3911
+ return {
3912
+ attribute: cellAlignAttr,
3913
+ value: element.style.verticalAlign
3914
+ };
3915
+ }
3916
+ };
3917
+
3918
+ function CellAlignTool() {
3919
+ const currentValue = core.createSignal('');
3920
+ const selection = core.inject(core$1.Selection);
3921
+ function check(v) {
3922
+ const commonAncestorComponent = selection.commonAncestorComponent;
3923
+ if (commonAncestorComponent instanceof TableComponent) {
3924
+ const slots = commonAncestorComponent.getSelectedNormalizedSlots();
3925
+ slots.forEach(item => {
3926
+ item.cells.forEach(cell => {
3927
+ if (cell.visible) {
3928
+ cell.raw.slot.setAttribute(cellAlignAttr, v);
3929
+ }
3930
+ });
3931
+ });
3932
+ }
3933
+ }
3934
+ const refreshService = core.inject(exports.RefreshService);
3935
+ const query = core.inject(core$1.Query);
3936
+ const highlight = core.createSignal(false);
3937
+ const subscription = refreshService.onRefresh.subscribe(() => {
3938
+ const result = query.queryAttribute(cellAlignAttr);
3939
+ const isHighlight = result.state === core$1.QueryStateType.Enabled;
3940
+ highlight.set(isHighlight);
3941
+ currentValue.set(isHighlight ? result.value : 'middle');
3942
+ });
3943
+ core.onUnmounted(() => {
3944
+ subscription.unsubscribe();
3945
+ });
3946
+ return () => {
3947
+ return (jsxRuntime.jsx(Dropdown, { onCheck: check, menu: [
3948
+ {
3949
+ label: jsxRuntime.jsx(MenuItem, { checked: currentValue() === 'top', icon: jsxRuntime.jsx("span", { class: "xnote-icon-align-top" }), children: "\u9876\u90E8\u5BF9\u9F50" }),
3950
+ value: 'top'
3951
+ },
3952
+ {
3953
+ label: jsxRuntime.jsx(MenuItem, { checked: currentValue() === 'middle', icon: jsxRuntime.jsx("span", { class: "xnote-icon-align-middle" }), children: "\u5782\u76F4\u5C45\u4E2D" }),
3954
+ value: 'middle'
3955
+ },
3956
+ {
3957
+ label: jsxRuntime.jsx(MenuItem, { checked: currentValue() === 'bottom', icon: jsxRuntime.jsx("span", { class: "xnote-icon-align-bottom" }), children: "\u5E95\u90E8\u5BF9\u9F50" }),
3958
+ value: 'bottom'
3959
+ }
3960
+ ], children: jsxRuntime.jsx(Button, { arrow: true, highlight: highlight(), children: jsxRuntime.jsx("span", { class: 'xnote-icon-align-' + (currentValue() || 'middle') }) }) }));
3961
+ };
3962
+ }
3963
+
3964
+ function CellBackgroundTool() {
3965
+ const refreshService = core.inject(exports.RefreshService);
3966
+ const selection = core.inject(core$1.Selection);
3967
+ const [viewModel, update] = hooks.useProduce({
3968
+ highlight: false,
3969
+ disabled: false,
3970
+ });
3971
+ function split() {
3972
+ // const commonAncestorComponent = selection.commonAncestorComponent
3973
+ // if (commonAncestorComponent instanceof TableComponent) {
3974
+ // const scopes = selection.getSelectedScopes()
3975
+ // if (scopes.length) {
3976
+ // const start = commonAncestorComponent.getCellBySlot(scopes.at(0)!.slot)
3977
+ // const end = commonAncestorComponent.getCellBySlot(scopes.at(-1)!.slot)
3978
+ // // Re
3979
+ // }
3980
+ // }
3981
+ }
3982
+ const sub = refreshService.onRefresh.subscribe(() => {
3983
+ const commonAncestorComponent = selection.commonAncestorComponent;
3984
+ update(draft => {
3985
+ draft.disabled = !(commonAncestorComponent instanceof TableComponent);
3986
+ });
3987
+ });
3988
+ core.onUnmounted(() => {
3989
+ sub.unsubscribe();
3990
+ });
3991
+ return () => {
3992
+ const vm = viewModel();
3993
+ return jsxRuntime.jsx(Button, { highlight: vm.highlight, disabled: vm.disabled, onClick: split, children: jsxRuntime.jsx("span", { class: "xnote-icon-palette" }) });
3994
+ };
3995
+ }
3996
+
3997
+ function MergeCellsTool() {
3998
+ const refreshService = core.inject(exports.RefreshService);
3999
+ const selection = core.inject(core$1.Selection);
4000
+ const [viewModel, update] = hooks.useProduce({
4001
+ highlight: false,
4002
+ disabled: false,
4003
+ });
4004
+ function merge() {
4005
+ const commonAncestorComponent = selection.commonAncestorComponent;
4006
+ if (commonAncestorComponent instanceof TableComponent) {
4007
+ commonAncestorComponent.mergeCellBySelection();
4008
+ }
4009
+ }
4010
+ const sub = refreshService.onRefresh.subscribe(() => {
4011
+ const commonAncestorComponent = selection.commonAncestorComponent;
4012
+ update(draft => {
4013
+ draft.disabled = !(commonAncestorComponent instanceof TableComponent);
4014
+ });
4015
+ });
4016
+ core.onUnmounted(() => {
4017
+ sub.unsubscribe();
4018
+ });
4019
+ return () => {
4020
+ const vm = viewModel();
4021
+ return jsxRuntime.jsx(Button, { highlight: vm.highlight, disabled: vm.disabled, onClick: merge, children: jsxRuntime.jsx("span", { class: "xnote-icon-merge-cells" }) });
4022
+ };
4023
+ }
4024
+
4025
+ function SplitCellsTool() {
4026
+ const refreshService = core.inject(exports.RefreshService);
4027
+ const selection = core.inject(core$1.Selection);
4028
+ const [viewModel, update] = hooks.useProduce({
4029
+ highlight: false,
4030
+ disabled: false,
4031
+ });
4032
+ function split() {
4033
+ const commonAncestorComponent = selection.commonAncestorComponent;
4034
+ if (commonAncestorComponent instanceof TableComponent) {
4035
+ commonAncestorComponent.splitCellsBySelection();
4036
+ }
4037
+ }
4038
+ const sub = refreshService.onRefresh.subscribe(() => {
4039
+ const commonAncestorComponent = selection.commonAncestorComponent;
4040
+ update(draft => {
4041
+ if (commonAncestorComponent instanceof TableComponent) {
4042
+ const slots = commonAncestorComponent.getSelectedNormalizedSlots();
4043
+ if (slots) {
4044
+ for (const item of slots) {
4045
+ for (const cell of item.cells) {
4046
+ if (cell.visible && cell.colspan > 1 || cell.colspan > 1) {
4047
+ draft.disabled = false;
4048
+ return;
4049
+ }
4050
+ }
4051
+ }
4052
+ }
4053
+ }
4054
+ draft.disabled = true;
4055
+ });
4056
+ });
4057
+ core.onUnmounted(() => {
4058
+ sub.unsubscribe();
4059
+ });
4060
+ return () => {
4061
+ const vm = viewModel();
4062
+ return jsxRuntime.jsx(Button, { highlight: vm.highlight, disabled: vm.disabled, onClick: split, children: jsxRuntime.jsx("span", { class: "xnote-icon-split-cells" }) });
4063
+ };
4064
+ }
4065
+
3599
4066
  var scopedId$9 = "vf-cf8e1c";
3600
4067
 
3601
4068
  class FileUploader {
@@ -4378,6 +4845,10 @@ function LinkJump() {
4378
4845
 
4379
4846
  var scopedId$6 = "vf-fee98b";
4380
4847
 
4848
+ function sum(numbers) {
4849
+ return numbers.reduce((a, b) => a + b, 0);
4850
+ }
4851
+
4381
4852
  const Toolbar = core.withAnnotation({
4382
4853
  providers: [exports.RefreshService]
4383
4854
  }, function Toolbar() {
@@ -4408,10 +4879,35 @@ const Toolbar = core.withAnnotation({
4408
4879
  const docRect = viewDocument.getBoundingClientRect();
4409
4880
  const toolbarHeight = 36;
4410
4881
  // const documentHeight = document.documentElement.clientHeight
4411
- const selectionFocusRect = bridge.getRect({
4412
- slot: selection.focusSlot,
4413
- offset: selection.focusOffset
4414
- });
4882
+ let selectionFocusRect = null;
4883
+ const commonAncestorComponent = selection.commonAncestorComponent;
4884
+ if (commonAncestorComponent instanceof TableComponent) {
4885
+ const slots = commonAncestorComponent.getSelectedNormalizedSlots().map(item => {
4886
+ return item.cells.filter(i => {
4887
+ return i.visible;
4888
+ }).map(cell => {
4889
+ return cell.raw.slot;
4890
+ });
4891
+ }).flat();
4892
+ const startSlot = slots.at(0);
4893
+ const endSlot = slots.at(-1);
4894
+ const rect = commonAncestorComponent.getSelectedRect();
4895
+ const startRect = adapter.getNativeNodeBySlot(startSlot).getBoundingClientRect();
4896
+ const endEle = adapter.getNativeNodeBySlot(endSlot).getBoundingClientRect();
4897
+ const width = sum(commonAncestorComponent.state.columnsConfig.slice(rect.x1, rect.x2));
4898
+ selectionFocusRect = {
4899
+ left: startRect.left + width / 2,
4900
+ top: startRect.top,
4901
+ height: endEle.bottom - startRect.top,
4902
+ width
4903
+ };
4904
+ }
4905
+ else {
4906
+ selectionFocusRect = bridge.getRect({
4907
+ slot: selection.focusSlot,
4908
+ offset: selection.focusOffset
4909
+ });
4910
+ }
4415
4911
  if (!selectionFocusRect) {
4416
4912
  return null;
4417
4913
  }
@@ -4442,7 +4938,13 @@ const Toolbar = core.withAnnotation({
4442
4938
  });
4443
4939
  function bindMouseup() {
4444
4940
  const docElement = adapter.getNativeNodeByComponent(rootComponentRef.component);
4445
- mouseupSubscription = core$1.fromEvent(docElement, 'mouseup').pipe(core$1.filter(ev => {
4941
+ mouseupSubscription = core$1.fromEvent(docElement, 'mouseup').pipe(core$1.delay(), core$1.filter(ev => {
4942
+ const c = selection.commonAncestorComponent;
4943
+ if (c instanceof TableComponent) {
4944
+ const b = !c.ignoreSelectionChanges;
4945
+ c.ignoreSelectionChanges = false;
4946
+ return b;
4947
+ }
4446
4948
  return !ev.composedPath().includes(toolbarRef.current);
4447
4949
  }), core$1.delay(100), core$1.filter(() => {
4448
4950
  return !selection.isCollapsed && !(selection.commonAncestorComponent instanceof SourceCodeComponent);
@@ -4486,7 +4988,7 @@ const Toolbar = core.withAnnotation({
4486
4988
  opacity: p.opacity,
4487
4989
  display: editorService.hideInlineToolbar ? 'none' : '',
4488
4990
  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, {}) })] }));
4991
+ }, 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
4992
  });
4491
4993
  });
4492
4994
 
@@ -4917,8 +5419,8 @@ let TableService = class TableService {
4917
5419
  constructor() {
4918
5420
  this.onInsertRowBefore = new core$1.Subject();
4919
5421
  this.onInsertColumnBefore = new core$1.Subject();
4920
- this.onSelectColumns = new core$1.Subject();
4921
- this.onSelectRows = new core$1.Subject();
5422
+ // onSelectColumns = new Subject<{ start: number, end: number } | null>()
5423
+ // onSelectRows = new Subject<{ start: number, end: number } | null>()
4922
5424
  this.onScroll = new core$1.Subject();
4923
5425
  }
4924
5426
  };
@@ -4938,7 +5440,11 @@ function ResizeColumn(props) {
4938
5440
  ignoreMove = true;
4939
5441
  }).add(core$1.fromEvent(document, 'mouseup').subscribe(() => {
4940
5442
  ignoreMove = false;
4941
- })).add(core$1.fromEvent(tableRef.current.parentNode, 'mousemove').subscribe(ev => {
5443
+ })).add(core$1.fromEvent(tableRef.current.parentNode, 'mouseleave').subscribe(() => {
5444
+ if (!isDrag) {
5445
+ dragLineRef.current.style.display = 'none';
5446
+ }
5447
+ }), core$1.fromEvent(tableRef.current.parentNode, 'mousemove').subscribe(ev => {
4942
5448
  if (isDrag || ignoreMove) {
4943
5449
  return;
4944
5450
  }
@@ -4946,7 +5452,7 @@ function ResizeColumn(props) {
4946
5452
  const leftDistance = ev.clientX - tableRect.x;
4947
5453
  const state = props.component.state;
4948
5454
  let x = 0;
4949
- for (let i = 0; i < state.layoutWidth.length + 1; i++) {
5455
+ for (let i = 0; i < state.columnsConfig.length + 1; i++) {
4950
5456
  const n = leftDistance - x;
4951
5457
  if (i > 0 && Math.abs(n) < 5) {
4952
5458
  Object.assign(dragLineRef.current.style, {
@@ -4958,14 +5464,14 @@ function ResizeColumn(props) {
4958
5464
  }
4959
5465
  activeCol = null;
4960
5466
  dragLineRef.current.style.display = 'none';
4961
- x += state.layoutWidth[i];
5467
+ x += state.columnsConfig[i] || 0;
4962
5468
  }
4963
5469
  })).add(core$1.fromEvent(dragLineRef.current, 'mousedown').subscribe(downEvent => {
4964
5470
  isDrag = true;
4965
5471
  editorService.changeLeftToolbarVisible(false);
4966
5472
  props.onActiveStateChange(true);
4967
5473
  const x = downEvent.clientX;
4968
- const layoutWidth = props.component.state.layoutWidth;
5474
+ const layoutWidth = props.component.state.columnsConfig;
4969
5475
  const initWidth = layoutWidth[activeCol - 1];
4970
5476
  const initLeft = layoutWidth.slice(0, activeCol).reduce((a, b) => a + b, 0);
4971
5477
  const minWidth = 30;
@@ -4982,8 +5488,8 @@ function ResizeColumn(props) {
4982
5488
  props.onActiveStateChange(false);
4983
5489
  moveEvent.unsubscribe();
4984
5490
  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);
5491
+ props.component.state.columnsConfig[activeCol - 1] = Math.max(initWidth + distanceX, minWidth);
5492
+ props.layoutWidth.set(props.component.state.columnsConfig.slice());
4987
5493
  }));
4988
5494
  }));
4989
5495
  return () => {
@@ -4998,7 +5504,7 @@ function ResizeColumn(props) {
4998
5504
  return;
4999
5505
  }
5000
5506
  const state = props.component.state;
5001
- const left = state.layoutWidth.slice(0, n).reduce((a, b) => a + b, 0) - 0.5;
5507
+ const left = state.columnsConfig.slice(0, n).reduce((a, b) => a + b, 0) - 0.5;
5002
5508
  dragLineRef.current.style.display = 'block';
5003
5509
  dragLineRef.current.style.left = left + 'px';
5004
5510
  });
@@ -5013,9 +5519,7 @@ var scopedId$4 = "vf-39cb2c";
5013
5519
 
5014
5520
  function TopBar(props) {
5015
5521
  const editorService = core.inject(exports.EditorService);
5016
- const selection = core.inject(core$1.Selection);
5017
5522
  const tableService = core.inject(TableService);
5018
- const textbus = core.inject(core$1.Textbus);
5019
5523
  const selectedColumnRange = core.createSignal(null);
5020
5524
  function selectColumn(index, isMultiple) {
5021
5525
  editorService.hideInlineToolbar = true;
@@ -5031,24 +5535,11 @@ function TopBar(props) {
5031
5535
  startIndex: index, endIndex: index
5032
5536
  });
5033
5537
  }
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
- });
5538
+ let { startIndex, endIndex } = selectedColumnRange();
5539
+ if (startIndex > endIndex) {
5540
+ [startIndex, endIndex] = [endIndex, startIndex];
5541
+ }
5542
+ props.component.selectColumn(startIndex, endIndex + 1);
5052
5543
  }
5053
5544
  let mouseDownFromToolbar = false;
5054
5545
  core.onMounted(() => {
@@ -5057,7 +5548,6 @@ function TopBar(props) {
5057
5548
  mouseDownFromToolbar = false;
5058
5549
  return;
5059
5550
  }
5060
- deleteIndex.set(null);
5061
5551
  selectedColumnRange.set(null);
5062
5552
  });
5063
5553
  return () => sub.unsubscribe();
@@ -5076,49 +5566,53 @@ function TopBar(props) {
5076
5566
  core.onUnmounted(() => {
5077
5567
  s.unsubscribe();
5078
5568
  });
5079
- const deleteIndex = core.createSignal(null);
5569
+ function refreshLayoutWidth() {
5570
+ props.layoutWidth.set(props.component.state.columnsConfig.slice());
5571
+ }
5080
5572
  return scopedCss.withScopedCSS(scopedId$4, () => {
5081
5573
  const { state, tableSelection } = props.component;
5082
5574
  const position = tableSelection();
5575
+ const range = selectedColumnRange();
5576
+ let left = 0;
5577
+ if (range) {
5578
+ left = sum(props.component.state.columnsConfig.slice(0, Math.min(range.startIndex, range.endIndex)));
5579
+ left += sum(props.component.state.columnsConfig.slice(Math.min(range.startIndex, range.endIndex), Math.max(range.startIndex, range.endIndex) + 1)) / 2;
5580
+ }
5083
5581
  return (jsxRuntime.jsx("div", { class: ['top-bar', {
5084
5582
  active: props.isFocus()
5085
- }], children: jsxRuntime.jsxs("div", { class: "toolbar-wrapper", children: [jsxRuntime.jsx("div", { class: "insert-bar", children: jsxRuntime.jsx("table", { style: {
5086
- transform: `translateX(${-leftDistance()}px)`
5087
- }, 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: {
5583
+ }], children: jsxRuntime.jsxs("div", { class: "toolbar-wrapper", children: [jsxRuntime.jsxs("div", { class: "insert-bar", children: [jsxRuntime.jsx(ComponentToolbar, { style: {
5584
+ left: left - leftDistance() + 'px',
5585
+ display: selectedColumnRange() ? 'inline-block' : 'none',
5586
+ }, innerStyle: {
5587
+ transform: 'translateX(-50%)'
5588
+ }, visible: !!selectedColumnRange(), children: jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(Button, { onClick: () => {
5589
+ props.component.deleteColumns();
5590
+ refreshLayoutWidth();
5591
+ }, children: jsxRuntime.jsx("span", { class: "xnote-icon-bin" }) }) }) }), jsxRuntime.jsx("table", { style: {
5592
+ transform: `translateX(${-leftDistance()}px)`
5593
+ }, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: props.layoutWidth().map((i, index) => {
5594
+ 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: () => {
5595
+ tableService.onInsertColumnBefore.next(0);
5596
+ }, onMouseleave: () => {
5597
+ tableService.onInsertColumnBefore.next(null);
5598
+ }, class: "insert-btn-wrap", style: {
5599
+ left: '-10px'
5600
+ }, onClick: () => {
5601
+ props.component.insertColumn(0);
5602
+ refreshLayoutWidth();
5603
+ }, children: jsxRuntime.jsx("button", { class: "insert-btn", type: "button", children: "+" }) })), jsxRuntime.jsx("span", { class: "insert-btn-wrap", onMouseenter: () => {
5604
+ tableService.onInsertColumnBefore.next(index + 1);
5605
+ }, onMouseleave: () => {
5606
+ tableService.onInsertColumnBefore.next(null);
5607
+ }, onClick: () => {
5608
+ props.component.insertColumn(index + 1);
5609
+ refreshLayoutWidth();
5610
+ }, children: jsxRuntime.jsx("button", { class: "insert-btn", type: "button", children: "+" }) })] }) }));
5611
+ }) }) }) })] }), jsxRuntime.jsx("div", { class: ['action-bar', { active: props.isFocus() }], children: jsxRuntime.jsx("table", { style: {
5112
5612
  transform: `translateX(${-leftDistance()}px)`
5113
5613
  }, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: props.layoutWidth().map((i, index) => {
5114
- return jsxRuntime.jsx("td", { onClick: ev => {
5614
+ return jsxRuntime.jsx("td", { onMousedown: ev => ev.preventDefault(), onClick: ev => {
5115
5615
  mouseDownFromToolbar = true;
5116
- if (!ev.shiftKey) {
5117
- deleteIndex.set(index);
5118
- }
5119
- else {
5120
- deleteIndex.set(null);
5121
- }
5122
5616
  selectColumn(index, ev.shiftKey);
5123
5617
  }, class: {
5124
5618
  active: !position ? false :
@@ -5180,10 +5674,8 @@ var scopedId$2 = "vf-aaece0";
5180
5674
 
5181
5675
  function LeftBar(props) {
5182
5676
  const editorService = core.inject(exports.EditorService);
5183
- const selection = core.inject(core$1.Selection);
5184
5677
  const actionBarRef = core.createRef();
5185
5678
  const insertBarRef = core.createRef();
5186
- const textbus = core.inject(core$1.Textbus);
5187
5679
  const tableService = core.inject(TableService);
5188
5680
  // 同步行高度
5189
5681
  core.onUpdated(() => {
@@ -5191,8 +5683,10 @@ function LeftBar(props) {
5191
5683
  const actionBarRows = actionBarRef.current.rows;
5192
5684
  setTimeout(() => {
5193
5685
  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';
5686
+ const height = tr.offsetHeight ||
5687
+ Math.min(...Array.from(tr.children).map(i => i.offsetHeight)) || 0;
5688
+ insertBarRows.item(i).style.height = height + 'px';
5689
+ actionBarRows.item(i).style.height = height + 'px';
5196
5690
  });
5197
5691
  });
5198
5692
  });
@@ -5231,30 +5725,27 @@ function LeftBar(props) {
5231
5725
  startIndex: index, endIndex: index
5232
5726
  });
5233
5727
  }
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
- });
5728
+ let { startIndex, endIndex } = selectedRowRange();
5729
+ if (startIndex > endIndex) {
5730
+ [startIndex, endIndex] = [endIndex, startIndex];
5731
+ }
5732
+ deleteIndex.set(startIndex);
5733
+ props.component.selectRow(startIndex, endIndex + 1);
5252
5734
  }
5253
5735
  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: () => {
5736
+ const position = props.component.tableSelection();
5737
+ const normalizedData = props.component.getNormalizedData();
5738
+ 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) => {
5739
+ let b = false;
5740
+ for (const item of row.cells) {
5741
+ if (item.visible) {
5742
+ b = true;
5743
+ break;
5744
+ }
5745
+ }
5746
+ return (jsxRuntime.jsx("tr", { style: {
5747
+ display: b ? '' : 'none'
5748
+ }, children: jsxRuntime.jsx("td", { children: jsxRuntime.jsxs("div", { class: "toolbar-item", children: [index === 0 && (jsxRuntime.jsx("span", { onMouseenter: () => {
5258
5749
  tableService.onInsertRowBefore.next(-1);
5259
5750
  }, onMouseleave: () => {
5260
5751
  tableService.onInsertRowBefore.next(null);
@@ -5267,6 +5758,11 @@ function LeftBar(props) {
5267
5758
  }, onMouseleave: () => {
5268
5759
  tableService.onInsertRowBefore.next(null);
5269
5760
  }, class: "insert-btn-wrap", onClick: () => {
5761
+ const cells = row.cells.filter(i => i.visible);
5762
+ if (cells.length < 2) {
5763
+ props.component.insertRow(index + row.cells.at(0).rowspan);
5764
+ return;
5765
+ }
5270
5766
  props.component.insertRow(index + 1);
5271
5767
  }, children: jsxRuntime.jsx("button", { class: "insert-btn", type: "button", children: "+" }) }), jsxRuntime.jsx(ComponentToolbar, { style: {
5272
5768
  display: deleteIndex() === index ? 'inline-block' : 'none',
@@ -5275,23 +5771,26 @@ function LeftBar(props) {
5275
5771
  top: 0,
5276
5772
  transform: 'translateY(-50%)'
5277
5773
  }, visible: deleteIndex() === index, children: jsxRuntime.jsx(ToolbarItem, { children: jsxRuntime.jsx(Button, { onClick: () => {
5278
- props.component.deleteRow(index);
5774
+ props.component.deleteRows();
5279
5775
  deleteIndex.set(null);
5280
5776
  }, 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) => {
5777
+ }) }) }) }), jsxRuntime.jsx("div", { class: "action-bar", children: jsxRuntime.jsx("table", { ref: actionBarRef, children: jsxRuntime.jsx("tbody", { children: normalizedData.map((row, index) => {
5778
+ let b = false;
5779
+ for (const item of row.cells) {
5780
+ if (item.visible) {
5781
+ b = true;
5782
+ break;
5783
+ }
5784
+ }
5785
+ return jsxRuntime.jsx("tr", { style: {
5786
+ display: b ? '' : 'none'
5787
+ }, children: jsxRuntime.jsx("td", { onMousedown: ev => ev.preventDefault(), onClick: (ev) => {
5283
5788
  mouseDownFromToolbar = true;
5284
- if (!ev.shiftKey) {
5285
- deleteIndex.set(index);
5286
- }
5287
- else {
5288
- deleteIndex.set(null);
5289
- }
5290
5789
  selectRow(index, ev.shiftKey);
5291
5790
  }, class: {
5292
5791
  active: !position ? false :
5293
5792
  (position.startColumn === 0 &&
5294
- position.endColumn === state.layoutWidth.length &&
5793
+ position.endColumn === props.component.state.columnsConfig.length &&
5295
5794
  index >= position.startRow && index < position.endRow)
5296
5795
  } }) });
5297
5796
  }) }) }) })] }));
@@ -5300,10 +5799,6 @@ function LeftBar(props) {
5300
5799
 
5301
5800
  var scopedId$1 = "vf-d4c4a9";
5302
5801
 
5303
- function sum(numbers) {
5304
- return numbers.reduce((a, b) => a + b, 0);
5305
- }
5306
-
5307
5802
  function ResizeRow(props) {
5308
5803
  const dragLineRef = core.createRef();
5309
5804
  const tableService = core.inject(TableService);
@@ -5335,7 +5830,7 @@ function ResizeRow(props) {
5335
5830
  return jsxRuntime.jsx("div", { ref: dragLineRef, style: {
5336
5831
  display: styles().visible ? 'block' : 'none',
5337
5832
  top: styles().top + 'px',
5338
- width: sum(props.component.state.layoutWidth) + 'px'
5833
+ width: sum(props.component.state.columnsConfig) + 'px'
5339
5834
  }, class: 'drag-line' });
5340
5835
  });
5341
5836
  }
@@ -5369,16 +5864,19 @@ function SelectionMask(props) {
5369
5864
  if (selection.startRow > 0) {
5370
5865
  heightCompensation = -1;
5371
5866
  }
5372
- if (selection.endRow === state.rows.length) {
5867
+ if (selection.endRow + 1 === state.rows.length) {
5373
5868
  heightCompensation += 0.5;
5374
5869
  }
5375
5870
  const trs = Array.from(props.tableRef.current.rows);
5376
5871
  updateStyles(draft => {
5872
+ var _a;
5873
+ const height = trs[selection.endRow - 1].offsetHeight ||
5874
+ ((_a = trs[selection.endRow - 1].children[0]) === null || _a === void 0 ? void 0 : _a.offsetHeight) || 0;
5377
5875
  draft.visible = true;
5378
- draft.left = sum(state.layoutWidth.slice(0, selection.startColumn));
5876
+ draft.left = sum(state.columnsConfig.slice(0, selection.startColumn));
5379
5877
  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';
5878
+ draft.width = sum(state.columnsConfig.slice(selection.startColumn, selection.endColumn)) - 1 + 'px';
5879
+ draft.height = trs[selection.endRow - 1].offsetTop + height + heightCompensation - draft.top + 'px';
5382
5880
  });
5383
5881
  }
5384
5882
  else {
@@ -5407,14 +5905,106 @@ function SelectionMask(props) {
5407
5905
  });
5408
5906
  }
5409
5907
 
5410
- // import { SlotRender } from '../SlotRender'
5908
+ /**
5909
+ * 修复不规范表格,并补全空位
5910
+ * @param table
5911
+ */
5912
+ function autoComplete(table) {
5913
+ const newTable = [];
5914
+ table.forEach((tr, rowIndex) => {
5915
+ let row = newTable[rowIndex];
5916
+ if (!row) {
5917
+ row = [];
5918
+ newTable[rowIndex] = row;
5919
+ }
5920
+ let startColumnIndex = 0;
5921
+ tr.forEach(td => {
5922
+ while (row[startColumnIndex]) {
5923
+ startColumnIndex++;
5924
+ }
5925
+ let maxColspan = 1;
5926
+ while (maxColspan < td.colspan) {
5927
+ if (!row[startColumnIndex + maxColspan]) {
5928
+ maxColspan++;
5929
+ }
5930
+ else {
5931
+ break;
5932
+ }
5933
+ }
5934
+ td.colspan = maxColspan;
5935
+ for (let i = rowIndex, len = td.rowspan + rowIndex; i < len; i++) {
5936
+ let row = newTable[i];
5937
+ if (!row) {
5938
+ row = [];
5939
+ newTable[i] = row;
5940
+ }
5941
+ for (let j = startColumnIndex, max = startColumnIndex + maxColspan; j < max; j++) {
5942
+ row[j] = td;
5943
+ }
5944
+ }
5945
+ startColumnIndex += maxColspan;
5946
+ });
5947
+ });
5948
+ const maxColumns = Math.max(...newTable.map(i => i.length));
5949
+ newTable.forEach(tr => {
5950
+ for (let i = 0; i < maxColumns; i++) {
5951
+ if (!tr[i]) {
5952
+ tr[i] = {
5953
+ id: uuid.v4(),
5954
+ rowspan: 1,
5955
+ colspan: 1,
5956
+ slot: new core$1.Slot([
5957
+ core$1.ContentType.BlockComponent
5958
+ ])
5959
+ };
5960
+ }
5961
+ }
5962
+ });
5963
+ const ids = [];
5964
+ const mergedConfig = {};
5965
+ const normalizedTable = newTable.map(tr => {
5966
+ return tr.map(td => {
5967
+ const is = ids.includes(td.id);
5968
+ if (is) {
5969
+ return {
5970
+ id: uuid.v4(),
5971
+ slot: new core$1.Slot([
5972
+ core$1.ContentType.BlockComponent,
5973
+ ])
5974
+ };
5975
+ }
5976
+ ids.push(td.id);
5977
+ return {
5978
+ id: td.id,
5979
+ slot: td.slot
5980
+ };
5981
+ });
5982
+ });
5983
+ ids.length = 0;
5984
+ newTable.forEach((tr, rowIndex) => {
5985
+ tr.forEach((td, colIndex) => {
5986
+ if (td.rowspan > 1 || td.colspan > 1) {
5987
+ if (ids.includes(td.id)) {
5988
+ return;
5989
+ }
5990
+ ids.push(td.id);
5991
+ mergedConfig[td.id] = normalizedTable[rowIndex + td.rowspan - 1][colIndex + td.colspan - 1].id;
5992
+ }
5993
+ });
5994
+ });
5995
+ return {
5996
+ mergedConfig,
5997
+ table: normalizedTable
5998
+ };
5999
+ }
6000
+
5411
6001
  const TableComponentView = core.withAnnotation({
5412
6002
  providers: [TableService]
5413
6003
  }, function TableComponentView(props) {
5414
6004
  const adapter = core.inject(platformBrowser.DomAdapter);
5415
6005
  const editorService = core.inject(exports.EditorService);
5416
6006
  const isFocus = core.createSignal(false);
5417
- const layoutWidth = core.createSignal(props.component.state.layoutWidth);
6007
+ const layoutWidth = core.createSignal(props.component.state.columnsConfig);
5418
6008
  const subscription = props.component.focus.subscribe(b => {
5419
6009
  isFocus.set(b);
5420
6010
  if (!b) {
@@ -5424,53 +6014,63 @@ const TableComponentView = core.withAnnotation({
5424
6014
  core.onUnmounted(() => {
5425
6015
  subscription.unsubscribe();
5426
6016
  });
6017
+ function resetIgnore() {
6018
+ props.component.ignoreSelectionChanges = false;
6019
+ }
5427
6020
  const tableRef = core.createRef();
5428
6021
  const isResizeColumn = core.createSignal(false);
5429
6022
  const rowMapping = new WeakMap();
5430
6023
  const readonly = useReadonly();
5431
6024
  const output = useOutput();
5432
6025
  return () => {
6026
+ const normalizedData = props.component.getNormalizedData();
5433
6027
  const state = props.component.state;
5434
- const rows = state.rows;
5435
- rows.forEach(row => {
5436
- if (rowMapping.has(row)) {
6028
+ // const rows = state.rows
6029
+ normalizedData.forEach(row => {
6030
+ if (rowMapping.has(row.row)) {
5437
6031
  return;
5438
6032
  }
5439
- rowMapping.set(row, Math.random());
6033
+ rowMapping.set(row.row, Math.random());
5440
6034
  });
5441
6035
  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: [
6036
+ 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
6037
  'xnote-table-content',
5444
6038
  {
5445
6039
  'hide-selection': props.component.tableSelection()
5446
6040
  }
5447
- ], children: [jsxRuntime.jsx("colgroup", { children: layoutWidth().map(w => {
6041
+ ], children: [jsxRuntime.jsx("colgroup", { children: state.columnsConfig.map(w => {
5448
6042
  return jsxRuntime.jsx("col", { style: { width: w + 'px', minWidth: w + 'px' } });
5449
- }) }), jsxRuntime.jsx("tbody", { children: rows.map((row) => {
6043
+ }) }), jsxRuntime.jsx("tbody", { children: normalizedData.map((row) => {
5450
6044
  return (jsxRuntime.jsx("tr", { children: row.cells.map(cell => {
5451
- return adapter.slotRender(cell.slot, children => {
6045
+ return adapter.slotRender(cell.raw.slot, children => {
5452
6046
  return core$1.createVNode('td', {
5453
- key: cell.slot.id
6047
+ key: cell.raw.id,
6048
+ rowspan: cell.rowspan,
6049
+ colspan: cell.colspan
5454
6050
  }, children);
5455
6051
  }, readonly() || output());
5456
- }) }, rowMapping.get(row)));
6052
+ }) }, rowMapping.get(row.row)));
5457
6053
  }) })] }) }) }) }));
5458
6054
  }
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: [
6055
+ 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
6056
  'xnote-table-content',
5461
6057
  {
5462
6058
  'hide-selection': props.component.tableSelection()
5463
6059
  }
5464
6060
  ], children: [jsxRuntime.jsx("colgroup", { children: layoutWidth().map(w => {
5465
6061
  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 => {
6062
+ }) }), jsxRuntime.jsx("tbody", { onMousedown: resetIgnore, children: normalizedData.map((row) => {
6063
+ return (jsxRuntime.jsx("tr", { children: row.cells.filter(i => {
6064
+ return i.visible;
6065
+ }).map(cell => {
6066
+ return adapter.slotRender(cell.raw.slot, children => {
5469
6067
  return core$1.createVNode('td', {
5470
- key: cell.slot.id
6068
+ key: cell.raw.id,
6069
+ rowspan: cell.rowspan,
6070
+ colspan: cell.colspan
5471
6071
  }, children);
5472
6072
  }, readonly() || output());
5473
- }) }, rowMapping.get(row)));
6073
+ }) }, rowMapping.get(row.row)));
5474
6074
  }) })] }), jsxRuntime.jsx(ResizeColumn, { tableRef: tableRef, component: props.component, layoutWidth: layoutWidth, onActiveStateChange: isActive => {
5475
6075
  isResizeColumn.set(isActive);
5476
6076
  } }), jsxRuntime.jsx(SelectionMask, { tableRef: tableRef, component: props.component })] }) }), jsxRuntime.jsx(ResizeRow, { component: props.component, tableRef: tableRef })] }) }));
@@ -5497,6 +6097,7 @@ const tableComponentLoader = {
5497
6097
  core$1.ContentType.BlockComponent,
5498
6098
  ]);
5499
6099
  arr.push({
6100
+ id: uuid.v4(),
5500
6101
  slot,
5501
6102
  rowspan: cell.rowSpan,
5502
6103
  colspan: cell.colSpan
@@ -5524,6 +6125,7 @@ const tableComponentLoader = {
5524
6125
  core$1.ContentType.BlockComponent,
5525
6126
  ]);
5526
6127
  arr.push({
6128
+ id: uuid.v4(),
5527
6129
  slot,
5528
6130
  rowspan: cell.rowSpan,
5529
6131
  colspan: cell.colSpan
@@ -5542,7 +6144,7 @@ const tableComponentLoader = {
5542
6144
  }
5543
6145
  bodies.unshift(...headers);
5544
6146
  const cells = autoComplete(bodies);
5545
- let layoutWidth = null;
6147
+ let layoutWidth = [];
5546
6148
  try {
5547
6149
  const columnWidth = JSON.parse(element.dataset.layoutWidth || '');
5548
6150
  if (Array.isArray(columnWidth)) {
@@ -5552,80 +6154,23 @@ const tableComponentLoader = {
5552
6154
  catch (e) {
5553
6155
  //
5554
6156
  }
5555
- if (!layoutWidth) {
5556
- layoutWidth = Array.from({ length: cells[0].length }).fill(100);
6157
+ const length = cells.table[0].length;
6158
+ for (let i = 0; i < length; i++) {
6159
+ layoutWidth[i] = layoutWidth[i] || 100;
5557
6160
  }
6161
+ layoutWidth.length = length;
5558
6162
  return new TableComponent(textbus, {
5559
- rows: cells.map(i => {
6163
+ columnsConfig: layoutWidth,
6164
+ mergeConfig: cells.mergedConfig,
6165
+ rows: cells.table.map(i => {
5560
6166
  return {
5561
6167
  height: 30,
5562
6168
  cells: i
5563
6169
  };
5564
- }),
5565
- layoutWidth
6170
+ })
5566
6171
  });
5567
6172
  }
5568
6173
  };
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
6174
 
5630
6175
  function findFocusCell(table, slot) {
5631
6176
  var _a;
@@ -5643,7 +6188,7 @@ let TableSelectionAwarenessDelegate = class TableSelectionAwarenessDelegate exte
5643
6188
  this.domAdapter = domAdapter;
5644
6189
  this.selection = selection;
5645
6190
  }
5646
- getRects(abstractSelection) {
6191
+ getRects(abstractSelection, _, data) {
5647
6192
  const { focusSlot, anchorSlot } = abstractSelection;
5648
6193
  const focusPaths = this.selection.getPathsBySlot(focusSlot);
5649
6194
  const anchorPaths = this.selection.getPathsBySlot(anchorSlot);
@@ -5662,18 +6207,25 @@ let TableSelectionAwarenessDelegate = class TableSelectionAwarenessDelegate exte
5662
6207
  if (!(commonAncestorComponent instanceof TableComponent)) {
5663
6208
  return false;
5664
6209
  }
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;
6210
+ const rect = data.data || commonAncestorComponent.getMaxRectangle(findFocusCell(commonAncestorComponent, startSlot), findFocusCell(commonAncestorComponent, endSlot));
5669
6211
  const renderer = this.domAdapter;
5670
- const startRect = renderer.getNativeNodeBySlot(startFocusSlot).getBoundingClientRect();
5671
- const endRect = renderer.getNativeNodeBySlot(endFocusSlot).getBoundingClientRect();
6212
+ if (!rect) {
6213
+ return false;
6214
+ }
6215
+ const normalizedSlots = commonAncestorComponent.getSelectedNormalizedSlotsByRectangle(rect);
6216
+ const rects = normalizedSlots.map(row => {
6217
+ return row.cells.filter(i => i.visible).map(i => {
6218
+ const td = renderer.getNativeNodeBySlot(i.raw.slot);
6219
+ return td.getBoundingClientRect();
6220
+ });
6221
+ }).flat();
6222
+ const left = Math.min(...rects.map(i => i.left));
6223
+ const top = Math.min(...rects.map(i => i.top));
5672
6224
  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
6225
+ left,
6226
+ top,
6227
+ width: Math.max(...rects.map(i => i.right)) - left,
6228
+ height: Math.max(...rects.map(i => i.bottom)) - top
5677
6229
  }];
5678
6230
  }
5679
6231
  };
@@ -5682,32 +6234,6 @@ TableSelectionAwarenessDelegate = __decorate([
5682
6234
  __metadata("design:paramtypes", [platformBrowser.DomAdapter,
5683
6235
  core$1.Selection])
5684
6236
  ], 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
6237
 
5712
6238
  function TimelineComponentView(props) {
5713
6239
  const adapter = core.inject(platformBrowser.DomAdapter);
@@ -5815,6 +6341,30 @@ const stepComponentLoader = {
5815
6341
  }
5816
6342
  };
5817
6343
 
6344
+ class XNoteMessageBug extends collaborate.MessageBus {
6345
+ constructor(selection, collaborateCursor, userinfo) {
6346
+ super();
6347
+ this.selection = selection;
6348
+ this.collaborateCursor = collaborateCursor;
6349
+ this.userinfo = userinfo;
6350
+ this.messageChangeEvent = new core$1.Subject();
6351
+ this.onMessageChange = this.messageChangeEvent.asObservable();
6352
+ }
6353
+ get() {
6354
+ const selection = this.selection;
6355
+ const c = selection.commonAncestorComponent;
6356
+ return Object.assign(Object.assign({}, this.userinfo), { selection: selection.getPaths(), data: (!selection.isCollapsed && c instanceof TableComponent) ? c.getSelectedRect() : null });
6357
+ }
6358
+ consume(message) {
6359
+ this.messageChangeEvent.next([...message]);
6360
+ this.collaborateCursor.draw(message.filter(item => {
6361
+ return item.message.id !== this.userinfo.id;
6362
+ }).map(item => {
6363
+ return item.message;
6364
+ }));
6365
+ }
6366
+ }
6367
+
5818
6368
  class Editor extends core$1.Textbus {
5819
6369
  constructor(editorConfig = {}) {
5820
6370
  const adapter = new adapterViewfly.ViewflyAdapter({
@@ -5872,6 +6422,7 @@ class Editor extends core$1.Textbus {
5872
6422
  strikeThroughFormatLoader,
5873
6423
  underlineFormatLoader
5874
6424
  ], attributeLoaders: [
6425
+ cellAlignAttrLoader,
5875
6426
  headingAttrLoader,
5876
6427
  textAlignAttrLoader,
5877
6428
  textIndentAttrLoader
@@ -5879,9 +6430,20 @@ class Editor extends core$1.Textbus {
5879
6430
  const modules = [browserModule];
5880
6431
  if (editorConfig.collaborateConfig) {
5881
6432
  modules.push(new collaborate.CollaborateModule(editorConfig.collaborateConfig));
5882
- browserModule.providers.push({
5883
- provide: platformBrowser.CollaborateSelectionAwarenessDelegate,
5884
- useClass: TableSelectionAwarenessDelegate
6433
+ modules.push({
6434
+ providers: [{
6435
+ provide: platformBrowser.CollaborateSelectionAwarenessDelegate,
6436
+ useClass: TableSelectionAwarenessDelegate
6437
+ }, {
6438
+ provide: collaborate.MessageBus,
6439
+ useFactory: (selection, collaborateCursor) => {
6440
+ return new XNoteMessageBug(selection, collaborateCursor, editorConfig.collaborateConfig.userinfo);
6441
+ },
6442
+ deps: [
6443
+ core$1.Selection,
6444
+ platformBrowser.CollaborateCursor
6445
+ ]
6446
+ }]
5885
6447
  });
5886
6448
  }
5887
6449
  const vDomAdapter = new adapterViewfly.ViewflyVDomAdapter({
@@ -5944,25 +6506,14 @@ class Editor extends core$1.Textbus {
5944
6506
  strikeThroughFormatter,
5945
6507
  underlineFormatter
5946
6508
  ], attributes: [
6509
+ cellAlignAttr,
5947
6510
  headingAttr,
5948
6511
  textAlignAttr,
5949
6512
  textIndentAttr
5950
6513
  ], plugins: [
5951
6514
  new LeftToolbarPlugin(),
5952
6515
  new ToolbarPlugin(),
5953
- ], setup(textbus) {
5954
- if (editorConfig.collaborateConfig) {
5955
- const activity = textbus.get(collaborate.UserActivity);
5956
- const collabCursor = textbus.get(platformBrowser.CollaborateCursor);
5957
- const sub = activity.onStateChange.subscribe(ev => {
5958
- collabCursor.draw(ev);
5959
- });
5960
- return () => {
5961
- sub.unsubscribe();
5962
- };
5963
- }
5964
- },
5965
- onAfterStartup(textbus) {
6516
+ ], onAfterStartup(textbus) {
5966
6517
  registerBoldShortcut(textbus);
5967
6518
  registerCodeShortcut(textbus);
5968
6519
  registerItalicShortcut(textbus);
@@ -6023,6 +6574,8 @@ exports.BlockquoteComponent = BlockquoteComponent;
6023
6574
  exports.BlockquoteView = BlockquoteView;
6024
6575
  exports.BoldTool = BoldTool;
6025
6576
  exports.Button = Button;
6577
+ exports.CellAlignTool = CellAlignTool;
6578
+ exports.CellBackgroundTool = CellBackgroundTool;
6026
6579
  exports.CodeTool = CodeTool;
6027
6580
  exports.ColorTool = ColorTool;
6028
6581
  exports.ComponentToolbar = ComponentToolbar;
@@ -6052,6 +6605,7 @@ exports.ListComponentView = ListComponentView;
6052
6605
  exports.Matcher = Matcher;
6053
6606
  exports.MenuHeading = MenuHeading;
6054
6607
  exports.MenuItem = MenuItem;
6608
+ exports.MergeCellsTool = MergeCellsTool;
6055
6609
  exports.Organization = Organization;
6056
6610
  exports.OutputInjectionToken = OutputInjectionToken;
6057
6611
  exports.ParagraphComponent = ParagraphComponent;
@@ -6061,6 +6615,7 @@ exports.RootComponent = RootComponent;
6061
6615
  exports.RootView = RootView;
6062
6616
  exports.SourceCodeComponent = SourceCodeComponent;
6063
6617
  exports.SourceCodeView = SourceCodeView;
6618
+ exports.SplitCellsTool = SplitCellsTool;
6064
6619
  exports.StrikeThroughTool = StrikeThroughTool;
6065
6620
  exports.TableComponent = TableComponent;
6066
6621
  exports.TableComponentView = TableComponentView;
@@ -6073,12 +6628,13 @@ exports.UnderlineTool = UnderlineTool;
6073
6628
  exports.VideoComponent = VideoComponent;
6074
6629
  exports.VideoView = VideoView;
6075
6630
  exports.atComponentLoader = atComponentLoader;
6076
- exports.autoComplete = autoComplete;
6077
6631
  exports.backgroundColorFormatLoader = backgroundColorFormatLoader;
6078
6632
  exports.backgroundColorFormatter = backgroundColorFormatter;
6079
6633
  exports.blockquoteComponentLoader = blockquoteComponentLoader;
6080
6634
  exports.boldFormatLoader = boldFormatLoader;
6081
6635
  exports.boldFormatter = boldFormatter;
6636
+ exports.cellAlignAttr = cellAlignAttr;
6637
+ exports.cellAlignAttrLoader = cellAlignAttrLoader;
6082
6638
  exports.codeFormatLoader = codeFormatLoader;
6083
6639
  exports.codeFormatter = codeFormatter;
6084
6640
  exports.colorFormatLoader = colorFormatLoader;