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