@textbus/xnote 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/bundles/components/button/button.d.ts +2 -3
  2. package/bundles/components/component-toolbar/component-toolbar.d.ts +1 -1
  3. package/bundles/components/divider/divider.d.ts +1 -1
  4. package/bundles/components/drag-resize/drag-resize.d.ts +1 -1
  5. package/bundles/components/dropdown/dropdown-menu.d.ts +1 -1
  6. package/bundles/components/dropdown/dropdown.d.ts +1 -1
  7. package/bundles/components/keymap/keymap.d.ts +2 -1
  8. package/bundles/components/menu-heading/menu-heading.d.ts +1 -1
  9. package/bundles/components/menu-item/menu-item.d.ts +1 -1
  10. package/bundles/components/popup/popup.d.ts +1 -1
  11. package/bundles/components/toolbar-item/toolbar-item.d.ts +1 -1
  12. package/bundles/fonts/textbus.svg +7 -1
  13. package/bundles/fonts/textbus.ttf +0 -0
  14. package/bundles/fonts/textbus.woff +0 -0
  15. package/bundles/index.css +1 -1
  16. package/bundles/index.esm.css +1 -1
  17. package/bundles/index.esm.js +904 -377
  18. package/bundles/index.js +908 -376
  19. package/bundles/plugins/_common/_api.d.ts +1 -0
  20. package/bundles/plugins/_common/attr.tool.d.ts +1 -1
  21. package/bundles/plugins/_common/block.tool.d.ts +1 -1
  22. package/bundles/plugins/_common/bold.tool.d.ts +1 -1
  23. package/bundles/plugins/_common/code.tool.d.ts +1 -1
  24. package/bundles/plugins/_common/color.tool.d.ts +1 -1
  25. package/bundles/plugins/_common/font-family.tool.d.ts +1 -1
  26. package/bundles/plugins/_common/font-size.tool.d.ts +1 -1
  27. package/bundles/plugins/_common/italic.tool.d.ts +1 -1
  28. package/bundles/plugins/_common/link.tool.d.ts +1 -1
  29. package/bundles/plugins/_common/strike-through.tool.d.ts +1 -1
  30. package/bundles/plugins/_common/table/_api.d.ts +4 -0
  31. package/bundles/plugins/_common/table/cell-align.tool.d.ts +1 -0
  32. package/bundles/plugins/_common/table/cell-background.tool.d.ts +1 -0
  33. package/bundles/plugins/_common/table/merge-cells.tool.d.ts +1 -0
  34. package/bundles/plugins/_common/table/split-cells.tool.d.ts +1 -0
  35. package/bundles/plugins/_common/underline.tool.d.ts +1 -1
  36. package/bundles/plugins/left-toolbar/insert-tool.d.ts +1 -1
  37. package/bundles/plugins/left-toolbar/left-toolbar.d.ts +1 -1
  38. package/bundles/plugins/link-jump/link-jump.d.ts +1 -1
  39. package/bundles/plugins/toolbar/toolbar.d.ts +1 -1
  40. package/bundles/textbus/attributes/_api.d.ts +1 -0
  41. package/bundles/textbus/attributes/cell-align.attr.d.ts +4 -0
  42. package/bundles/textbus/components/at/at-component.view.d.ts +1 -1
  43. package/bundles/textbus/components/blockqoute/blockquote.component.d.ts +1 -1
  44. package/bundles/textbus/components/highlight-box/highlight-box.component.d.ts +1 -1
  45. package/bundles/textbus/components/image/image.component.d.ts +1 -1
  46. package/bundles/textbus/components/katex/katex.component.d.ts +1 -1
  47. package/bundles/textbus/components/list/list.component.d.ts +1 -1
  48. package/bundles/textbus/components/paragraph/paragraph.component.d.ts +1 -1
  49. package/bundles/textbus/components/root/root.component.d.ts +1 -1
  50. package/bundles/textbus/components/source-code/source-code.component.d.ts +1 -1
  51. package/bundles/textbus/components/step/step-component.view.d.ts +1 -1
  52. package/bundles/textbus/components/table/components/left-bar.d.ts +1 -1
  53. package/bundles/textbus/components/table/components/resize-column.d.ts +1 -1
  54. package/bundles/textbus/components/table/components/resize-row.d.ts +1 -1
  55. package/bundles/textbus/components/table/components/scroll.d.ts +1 -1
  56. package/bundles/textbus/components/table/components/selection-mask.d.ts +1 -1
  57. package/bundles/textbus/components/table/components/top-bar.d.ts +1 -1
  58. package/bundles/textbus/components/table/table-component.view.d.ts +2 -3
  59. package/bundles/textbus/components/table/table.component.d.ts +30 -7
  60. package/bundles/textbus/components/table/table.service.d.ts +0 -8
  61. package/bundles/textbus/components/table/tools/complete.d.ts +19 -0
  62. package/bundles/textbus/components/table/tools/merge.d.ts +23 -0
  63. package/bundles/textbus/components/timeline/timeline-component.view.d.ts +1 -1
  64. package/bundles/textbus/components/todolist/todolist.component.d.ts +1 -1
  65. package/bundles/textbus/components/video/video.component.d.ts +1 -1
  66. package/package.json +14 -11
@@ -1,11 +1,12 @@
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';
@@ -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() {
@@ -1768,16 +1772,16 @@ function AttrTool(props) {
1768
1772
  const states = checkStates();
1769
1773
  return (jsx(Dropdown, { width: 'auto', style: props.style, abreast: props.abreast, onCheck: updateAttr, trigger: 'hover', menu: [
1770
1774
  {
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" }),
1775
+ 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
1776
  value: 't-l'
1773
1777
  }, {
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" }),
1778
+ 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
1779
  value: 't-r'
1776
1780
  }, {
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" }),
1781
+ 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
1782
  value: 't-c'
1779
1783
  }, {
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" }),
1784
+ 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
1785
  value: 't-j'
1782
1786
  }, {
1783
1787
  label: jsx(Divider, {}),
@@ -1793,20 +1797,99 @@ function AttrTool(props) {
1793
1797
  });
1794
1798
  }
1795
1799
 
1800
+ class Rectangle {
1801
+ constructor(x1, y1, x2, y2) {
1802
+ this.x1 = x1;
1803
+ this.y1 = y1;
1804
+ this.x2 = x2;
1805
+ this.y2 = y2;
1806
+ }
1807
+ intersects(other) {
1808
+ return this.x1 < other.x2 && this.x2 > other.x1 && this.y1 < other.y2 && this.y2 > other.y1;
1809
+ }
1810
+ merge(other) {
1811
+ 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));
1812
+ }
1813
+ }
1814
+ function findNonIntersectingRectangles(rectangles) {
1815
+ const merged = [];
1816
+ const remaining = [...rectangles];
1817
+ while (remaining.length > 0) {
1818
+ const current = remaining.shift();
1819
+ let mergedWithCurrent = false;
1820
+ for (let i = 0; i < merged.length; i++) {
1821
+ if (current.intersects(merged[i])) {
1822
+ merged[i] = current.merge(merged[i]);
1823
+ mergedWithCurrent = true;
1824
+ break;
1825
+ }
1826
+ }
1827
+ if (!mergedWithCurrent) {
1828
+ merged.push(current);
1829
+ }
1830
+ }
1831
+ return merged;
1832
+ }
1833
+ function getMaxRectangle(start, rectangles) {
1834
+ let merged = start;
1835
+ const remaining = [...rectangles];
1836
+ while (remaining.length > 0) {
1837
+ const current = remaining.shift();
1838
+ if (current.intersects(merged)) {
1839
+ merged = current.merge(merged);
1840
+ }
1841
+ }
1842
+ return merged;
1843
+ }
1844
+ function applyRectangles(rows, rectangles) {
1845
+ const table = rows.map(row => {
1846
+ return {
1847
+ row,
1848
+ cells: row.cells.map(cell => {
1849
+ return {
1850
+ rowspan: 1,
1851
+ colspan: 1,
1852
+ visible: true,
1853
+ raw: cell
1854
+ };
1855
+ })
1856
+ };
1857
+ });
1858
+ rectangles.forEach(rect => {
1859
+ const { x1, y1, x2, y2 } = rect;
1860
+ const rowspan = y2 - y1;
1861
+ const colspan = x2 - x1;
1862
+ for (let i = y1; i < y2; i++) {
1863
+ for (let j = x1; j < x2; j++) {
1864
+ const item = table[i].cells[j];
1865
+ if (i === y1 && j === x1) {
1866
+ item.visible = true;
1867
+ item.rowspan = rowspan;
1868
+ item.colspan = colspan;
1869
+ }
1870
+ else {
1871
+ item.visible = false;
1872
+ }
1873
+ }
1874
+ }
1875
+ });
1876
+ return table;
1877
+ }
1878
+
1796
1879
  const defaultRowHeight = 30;
1797
1880
  const defaultColumnWidth = 100;
1798
1881
  class TableComponent extends Component {
1799
1882
  static fromJSON(textbus, json) {
1800
1883
  const registry = textbus.get(Registry);
1801
1884
  return new TableComponent(textbus, {
1802
- layoutWidth: json.layoutWidth || [],
1885
+ columnsConfig: json.columnsConfig || [],
1886
+ mergeConfig: json.mergeConfig || [],
1803
1887
  rows: json.rows.map(row => {
1804
1888
  return {
1805
1889
  height: row.height,
1806
1890
  cells: row.cells.map(cell => {
1807
1891
  return {
1808
- colspan: cell.colspan,
1809
- rowspan: cell.rowspan,
1892
+ id: cell.id,
1810
1893
  slot: registry.createSlot(cell.slot)
1811
1894
  };
1812
1895
  })
@@ -1815,7 +1898,8 @@ class TableComponent extends Component {
1815
1898
  });
1816
1899
  }
1817
1900
  constructor(textbus, state = {
1818
- layoutWidth: Array.from({ length: 5 }).fill(100),
1901
+ columnsConfig: Array.from({ length: 5 }).fill(defaultColumnWidth),
1902
+ mergeConfig: {},
1819
1903
  rows: Array.from({ length: 3 }).map(() => {
1820
1904
  return {
1821
1905
  height: defaultRowHeight,
@@ -1824,9 +1908,8 @@ class TableComponent extends Component {
1824
1908
  const slot = new Slot([ContentType.BlockComponent]);
1825
1909
  slot.insert(p);
1826
1910
  return {
1827
- rowspan: 1,
1828
- colspan: 1,
1829
- slot
1911
+ slot,
1912
+ id: v4()
1830
1913
  };
1831
1914
  })
1832
1915
  };
@@ -1834,11 +1917,236 @@ class TableComponent extends Component {
1834
1917
  }) {
1835
1918
  super(textbus, state);
1836
1919
  this.selection = this.textbus.get(Selection);
1920
+ this.commander = this.textbus.get(Commander);
1837
1921
  this.focus = new Subject();
1838
1922
  this.tableSelection = createSignal(null);
1923
+ this.ignoreSelectionChanges = false;
1924
+ this.normalizedData = [];
1839
1925
  }
1840
1926
  getSlots() {
1841
- return this.state.rows.map(i => i.cells.map(j => j.slot)).flat();
1927
+ return this.normalizedData.map(item => {
1928
+ return item.cells.filter(i => i.visible).map(i => i.raw.slot);
1929
+ }).flat();
1930
+ }
1931
+ mergeCellBySelection() {
1932
+ var _a, _b, _c, _d;
1933
+ const slots = this.getSelectedNormalizedSlots();
1934
+ if (slots) {
1935
+ 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;
1936
+ 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;
1937
+ if (start && end) {
1938
+ slots.forEach(item => {
1939
+ item.cells.forEach(cell => {
1940
+ if (cell.raw.id === start.id) {
1941
+ return;
1942
+ }
1943
+ cell.raw.slot.cleanFormats();
1944
+ cell.raw.slot.cleanAttributes();
1945
+ cell.raw.slot.retain(0);
1946
+ cell.raw.slot.delete(cell.raw.slot.length);
1947
+ Reflect.deleteProperty(this.state.mergeConfig, cell.raw.id);
1948
+ });
1949
+ });
1950
+ this.state.mergeConfig[start.id] = end.id;
1951
+ }
1952
+ }
1953
+ this.selection.collapse(true);
1954
+ }
1955
+ splitCellsBySelection() {
1956
+ var _a, _b, _c, _d;
1957
+ const slots = this.getSelectedNormalizedSlots();
1958
+ if (slots) {
1959
+ slots.forEach(item => {
1960
+ item.cells.forEach(cell => {
1961
+ Reflect.deleteProperty(this.state.mergeConfig, cell.raw.id);
1962
+ });
1963
+ });
1964
+ 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;
1965
+ 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;
1966
+ if (start && end) {
1967
+ this.selection.setBaseAndExtent(start.slot, 0, end.slot, end.slot.length);
1968
+ }
1969
+ }
1970
+ }
1971
+ getMaxRectangle(startSlot, endSlot) {
1972
+ let index1 = -1;
1973
+ let index2 = -1;
1974
+ let x1 = -1;
1975
+ let x2 = -1;
1976
+ let y1 = -1;
1977
+ let y2 = -1;
1978
+ let index = 0;
1979
+ for (let i = 0; i < this.state.rows.length; i++) {
1980
+ const row = this.state.rows[i];
1981
+ for (let j = 0; j < row.cells.length; j++) {
1982
+ const item = row.cells[j];
1983
+ if (item.slot === startSlot) {
1984
+ index1 = index;
1985
+ x1 = j;
1986
+ y1 = i;
1987
+ }
1988
+ if (item.slot === endSlot) {
1989
+ index2 = index;
1990
+ x2 = j;
1991
+ y2 = i;
1992
+ }
1993
+ index++;
1994
+ }
1995
+ }
1996
+ if (index1 === -1 || index2 === -1) {
1997
+ return null;
1998
+ }
1999
+ if (x1 > x2) {
2000
+ [x1, x2] = [x2, x1];
2001
+ }
2002
+ if (y1 > y2) {
2003
+ [y1, y2] = [y2, y1];
2004
+ }
2005
+ return getMaxRectangle(new Rectangle(x1, y1, x2 + 1, y2 + 1), this.getMergedRectangles());
2006
+ }
2007
+ getSelectedNormalizedSlots() {
2008
+ const rect = this.getSelectedRect();
2009
+ if (rect) {
2010
+ return this.getSelectedNormalizedSlotsByRectangle(rect);
2011
+ }
2012
+ return null;
2013
+ }
2014
+ getSelectedRect() {
2015
+ const getSelfSlot = (slot) => {
2016
+ let cell = slot;
2017
+ while ((cell === null || cell === void 0 ? void 0 : cell.parent) && cell.parent !== this) {
2018
+ cell = cell.parentSlot;
2019
+ }
2020
+ return cell;
2021
+ };
2022
+ const start = getSelfSlot(this.selection.startSlot);
2023
+ const end = getSelfSlot(this.selection.endSlot);
2024
+ if (start && end) {
2025
+ return this.getMaxRectangle(start, end);
2026
+ }
2027
+ return null;
2028
+ }
2029
+ getSelectedNormalizedSlotsByRectangle(rectangle) {
2030
+ return this.normalizedData.slice(rectangle.y1, rectangle.y2).map(item => {
2031
+ return {
2032
+ row: item.row,
2033
+ cells: item.cells.slice(rectangle.x1, rectangle.x2)
2034
+ };
2035
+ });
2036
+ }
2037
+ getCellBySlot(slot) {
2038
+ for (const row of this.state.rows) {
2039
+ for (const cell of row.cells) {
2040
+ if (cell.slot === slot) {
2041
+ return cell;
2042
+ }
2043
+ }
2044
+ }
2045
+ return null;
2046
+ }
2047
+ getNormalizedData() {
2048
+ if (!this.changeMarker.dirty) {
2049
+ return this.normalizedData;
2050
+ }
2051
+ const nonIntersectingRectangles = this.getMergedRectangles();
2052
+ this.normalizedData = applyRectangles(this.state.rows, nonIntersectingRectangles);
2053
+ return this.normalizedData;
2054
+ }
2055
+ selectRow(startIndex, endIndex = startIndex + 1) {
2056
+ if (startIndex > endIndex) {
2057
+ [startIndex, endIndex] = [endIndex, startIndex];
2058
+ }
2059
+ if (startIndex === endIndex) {
2060
+ endIndex++;
2061
+ }
2062
+ const selectedSlots = [];
2063
+ const rows = this.getNormalizedData();
2064
+ rows.slice(startIndex, endIndex).forEach(row => {
2065
+ selectedSlots.push(...row.cells.filter(i => i.visible).map(i => i.raw.slot));
2066
+ });
2067
+ this.ignoreSelectionChanges = true;
2068
+ const slotRanges = selectedSlots.map(i => {
2069
+ return {
2070
+ slot: i,
2071
+ startIndex: 0,
2072
+ endIndex: i.length
2073
+ };
2074
+ });
2075
+ this.selection.setSelectedRanges(slotRanges);
2076
+ this.tableSelection.set({
2077
+ startColumn: 0,
2078
+ endColumn: this.state.columnsConfig.length,
2079
+ startRow: startIndex,
2080
+ endRow: endIndex,
2081
+ });
2082
+ this.focus.next(true);
2083
+ if (slotRanges.length) {
2084
+ setTimeout(() => {
2085
+ this.selection.restore();
2086
+ this.textbus.focus();
2087
+ });
2088
+ }
2089
+ }
2090
+ selectColumn(startIndex, endIndex = startIndex + 1) {
2091
+ if (startIndex > endIndex) {
2092
+ [startIndex, endIndex] = [endIndex, startIndex];
2093
+ }
2094
+ if (startIndex === endIndex) {
2095
+ endIndex++;
2096
+ }
2097
+ const selectedSlots = [];
2098
+ const rows = this.getNormalizedData();
2099
+ rows.forEach(row => {
2100
+ selectedSlots.push(...row.cells.slice(startIndex, endIndex).filter(i => i.visible).map(i => i.raw.slot));
2101
+ });
2102
+ this.ignoreSelectionChanges = true;
2103
+ const slotRanges = selectedSlots.map(i => {
2104
+ return {
2105
+ slot: i,
2106
+ startIndex: 0,
2107
+ endIndex: i.length
2108
+ };
2109
+ });
2110
+ this.selection.setSelectedRanges(slotRanges);
2111
+ this.tableSelection.set({
2112
+ startColumn: startIndex,
2113
+ endColumn: endIndex,
2114
+ startRow: 0,
2115
+ endRow: this.state.rows.length,
2116
+ });
2117
+ this.focus.next(true);
2118
+ this.selection.restore();
2119
+ this.textbus.focus();
2120
+ // if (slotRanges.length) {
2121
+ // setTimeout(() => {
2122
+ // this.selection.restore()
2123
+ // this.textbus.focus()
2124
+ // })
2125
+ // }
2126
+ }
2127
+ getMergedRectangles() {
2128
+ const rectangles = [];
2129
+ Object.entries(this.state.mergeConfig).forEach(([key, value]) => {
2130
+ const p1 = this.getCoordinateById(key);
2131
+ if (p1) {
2132
+ const p2 = this.getCoordinateById(value);
2133
+ if (p2) {
2134
+ rectangles.push(new Rectangle(p1[0], p1[1], p2[0] + 1, p2[1] + 1));
2135
+ }
2136
+ }
2137
+ });
2138
+ return findNonIntersectingRectangles(rectangles);
2139
+ }
2140
+ getCoordinateById(id) {
2141
+ const rows = this.state.rows;
2142
+ for (let i = 0; i < rows.length; i++) {
2143
+ const row = rows[i];
2144
+ const colIndex = row.cells.findIndex(i => i.id === id);
2145
+ if (colIndex > -1) {
2146
+ return [colIndex, i];
2147
+ }
2148
+ }
2149
+ return null;
1842
2150
  }
1843
2151
  setup() {
1844
2152
  const selection = useContext(Selection);
@@ -1852,6 +2160,9 @@ class TableComponent extends Component {
1852
2160
  return slot.parent === this;
1853
2161
  });
1854
2162
  const sub = selection.onChange.subscribe(() => {
2163
+ if (this.ignoreSelectionChanges) {
2164
+ return;
2165
+ }
1855
2166
  if (selection.commonAncestorComponent !== this || selection.isCollapsed) {
1856
2167
  this.tableSelection.set(null);
1857
2168
  }
@@ -1859,115 +2170,109 @@ class TableComponent extends Component {
1859
2170
  onDestroy(() => {
1860
2171
  sub.unsubscribe();
1861
2172
  });
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;
2173
+ onGetRanges(ev => {
2174
+ if (this.selection.isCollapsed || this.ignoreSelectionChanges) {
2175
+ return;
1866
2176
  }
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
- }
2177
+ const rect = this.getSelectedRect();
2178
+ if (rect) {
2179
+ this.tableSelection.set({
2180
+ startColumn: rect.x1,
2181
+ endColumn: rect.x2,
2182
+ startRow: rect.y1,
2183
+ endRow: rect.y2
2184
+ });
2185
+ const selectedSlots = this.getSelectedNormalizedSlotsByRectangle(rect);
2186
+ const slotRanges = selectedSlots.map(item => {
2187
+ return item.cells.filter(i => {
2188
+ return i.visible;
2189
+ }).map(i => {
2190
+ return {
2191
+ startIndex: 0,
2192
+ endIndex: i.raw.slot.length,
2193
+ slot: i.raw.slot
2194
+ };
2195
+ });
2196
+ }).flat();
2197
+ if (slotRanges.length > 1) {
2198
+ ev.useRanges(slotRanges);
1880
2199
  }
1881
2200
  }
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();
2201
+ });
2202
+ }
2203
+ deleteColumns() {
2204
+ const selection = this.tableSelection();
2205
+ if (selection) {
2206
+ const { startColumn, endColumn } = selection;
2207
+ if (startColumn === 0 && endColumn === this.state.columnsConfig.length) {
2208
+ this.commander.removeComponent(this);
2209
+ return;
1899
2210
  }
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
2211
+ this.state.columnsConfig.splice(startColumn, endColumn - startColumn);
2212
+ const mergeConfig = this.state.mergeConfig;
2213
+ const keys = Object.keys(mergeConfig);
2214
+ this.state.rows.forEach(row => {
2215
+ const before = row.cells.at(startColumn - 1);
2216
+ const after = row.cells.at(endColumn);
2217
+ const cells = row.cells.splice(startColumn, endColumn - startColumn);
2218
+ cells.forEach(cell => {
2219
+ if (keys.includes(cell.id)) {
2220
+ if (after) {
2221
+ mergeConfig[after.id] = mergeConfig[cell.id];
2222
+ }
2223
+ Reflect.deleteProperty(mergeConfig, cell.id);
2224
+ }
2225
+ if (before) {
2226
+ keys.forEach(key => {
2227
+ if (mergeConfig[key] === cell.id) {
2228
+ mergeConfig[key] = before.id;
2229
+ }
1913
2230
  });
1914
- return;
1915
2231
  }
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
2232
  });
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
- });
2233
+ });
2234
+ }
2235
+ this.tableSelection.set(null);
1963
2236
  this.selection.unSelect();
1964
2237
  }
1965
- deleteRow(index) {
1966
- this.state.rows.splice(index, 1);
2238
+ deleteRows() {
2239
+ const selection = this.tableSelection();
2240
+ if (selection) {
2241
+ const { startRow, endRow } = selection;
2242
+ if (startRow === 0 && endRow === this.state.rows.length) {
2243
+ this.commander.removeComponent(this);
2244
+ return;
2245
+ }
2246
+ const mergeConfig = this.state.mergeConfig;
2247
+ const keys = Object.keys(mergeConfig);
2248
+ const rows = this.state.rows;
2249
+ const deletedRows = rows.splice(startRow, endRow - startRow);
2250
+ deletedRows.forEach(row => {
2251
+ row.cells.forEach((cell, colIndex) => {
2252
+ var _a, _b;
2253
+ const before = (_a = rows.at(startRow - 1)) === null || _a === void 0 ? void 0 : _a.cells.at(colIndex);
2254
+ const after = (_b = rows.at(startRow)) === null || _b === void 0 ? void 0 : _b.cells.at(colIndex);
2255
+ if (keys.includes(cell.id)) {
2256
+ if (after) {
2257
+ mergeConfig[after.id] = mergeConfig[cell.id];
2258
+ }
2259
+ Reflect.deleteProperty(mergeConfig, cell.id);
2260
+ }
2261
+ if (before) {
2262
+ keys.forEach(key => {
2263
+ if (mergeConfig[key] === cell.id) {
2264
+ mergeConfig[key] = before.id;
2265
+ }
2266
+ });
2267
+ }
2268
+ });
2269
+ });
2270
+ }
2271
+ this.tableSelection.set(null);
1967
2272
  this.selection.unSelect();
1968
2273
  }
1969
2274
  insertColumn(index) {
1970
- this.state.layoutWidth.splice(index, 0, defaultColumnWidth);
2275
+ this.state.columnsConfig.splice(index, 0, defaultColumnWidth);
1971
2276
  this.state.rows.forEach(row => {
1972
2277
  const slot = new Slot([
1973
2278
  ContentType.BlockComponent,
@@ -1979,14 +2284,12 @@ class TableComponent extends Component {
1979
2284
  ])
1980
2285
  }));
1981
2286
  row.cells.splice(index, 0, {
1982
- rowspan: 1,
1983
- colspan: 1,
2287
+ id: v4(),
1984
2288
  slot
1985
2289
  });
1986
2290
  });
1987
2291
  this.textbus.nextTick(() => {
1988
- var _a;
1989
- const slot = (_a = this.state.rows[0].cells[index]) === null || _a === void 0 ? void 0 : _a.slot;
2292
+ const slot = this.state.rows[0].cells[index].slot;
1990
2293
  if (slot) {
1991
2294
  this.selection.selectFirstPosition(slot.getContentAtIndex(0));
1992
2295
  }
@@ -1995,7 +2298,7 @@ class TableComponent extends Component {
1995
2298
  insertRow(index) {
1996
2299
  this.state.rows.splice(index, 0, {
1997
2300
  height: defaultRowHeight,
1998
- cells: this.state.layoutWidth.map(() => {
2301
+ cells: this.state.columnsConfig.map(() => {
1999
2302
  const slot = new Slot([
2000
2303
  ContentType.BlockComponent,
2001
2304
  ]);
@@ -2006,15 +2309,13 @@ class TableComponent extends Component {
2006
2309
  ])
2007
2310
  }));
2008
2311
  return {
2009
- rowspan: 1,
2010
- colspan: 1,
2312
+ id: v4(),
2011
2313
  slot
2012
2314
  };
2013
2315
  })
2014
2316
  });
2015
2317
  this.textbus.nextTick(() => {
2016
- var _a;
2017
- const slot = (_a = this.state.rows[index].cells[0]) === null || _a === void 0 ? void 0 : _a.slot;
2318
+ const slot = this.state.rows[index].cells[0].slot;
2018
2319
  if (slot) {
2019
2320
  this.selection.selectFirstPosition(slot.getContentAtIndex(0));
2020
2321
  }
@@ -2049,7 +2350,7 @@ function registerStrikeThroughShortcut(textbus) {
2049
2350
  const keyboard = textbus.get(Keyboard);
2050
2351
  keyboard.addShortcut({
2051
2352
  keymap: {
2052
- ctrlKey: true,
2353
+ modKey: true,
2053
2354
  key: 'd'
2054
2355
  },
2055
2356
  action: () => {
@@ -2233,7 +2534,7 @@ function registerListShortcut(textbus) {
2233
2534
  keyboard.addShortcut({
2234
2535
  keymap: {
2235
2536
  key: ['o', 'u'],
2236
- ctrlKey: true,
2537
+ modKey: true,
2237
2538
  shiftKey: true
2238
2539
  },
2239
2540
  action(key) {
@@ -2765,43 +3066,43 @@ function BlockTool() {
2765
3066
  return (jsx(Dropdown, { width: 'auto', onCheck: transform, trigger: 'hover', menu: [
2766
3067
  {
2767
3068
  label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-pilcrow" }), desc: jsx(Keymap, { keymap: {
2768
- ctrlKey: true,
3069
+ modKey: true,
2769
3070
  key: '0'
2770
3071
  } }), checked: states.paragraph, children: "\u6B63\u6587" }),
2771
3072
  value: 'paragraph'
2772
3073
  }, {
2773
3074
  label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-heading-h1" }), desc: jsx(Keymap, { keymap: {
2774
- ctrlKey: true,
3075
+ modKey: true,
2775
3076
  key: '1'
2776
3077
  } }), checked: states.h1, children: "\u4E00\u7EA7\u6807\u9898" }),
2777
3078
  value: 'h1'
2778
3079
  }, {
2779
3080
  label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-heading-h2" }), desc: jsx(Keymap, { keymap: {
2780
- ctrlKey: true,
3081
+ modKey: true,
2781
3082
  key: '2'
2782
3083
  } }), checked: states.h2, children: "\u4E8C\u7EA7\u6807\u9898" }),
2783
3084
  value: 'h2'
2784
3085
  }, {
2785
3086
  label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-heading-h3" }), desc: jsx(Keymap, { keymap: {
2786
- ctrlKey: true,
3087
+ modKey: true,
2787
3088
  key: '3'
2788
3089
  } }), checked: states.h3, children: "\u4E09\u7EA7\u6807\u9898" }),
2789
3090
  value: 'h3'
2790
3091
  }, {
2791
3092
  label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-heading-h4" }), desc: jsx(Keymap, { keymap: {
2792
- ctrlKey: true,
3093
+ modKey: true,
2793
3094
  key: '4'
2794
3095
  } }), checked: states.h4, children: "\u56DB\u7EA7\u6807\u9898" }),
2795
3096
  value: 'h4'
2796
3097
  }, {
2797
3098
  label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-heading-h5" }), desc: jsx(Keymap, { keymap: {
2798
- ctrlKey: true,
3099
+ modKey: true,
2799
3100
  key: '5'
2800
3101
  } }), checked: states.h5, children: "\u4E94\u7EA7\u6807\u9898" }),
2801
3102
  value: 'h5'
2802
3103
  }, {
2803
3104
  label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-heading-h6" }), desc: jsx(Keymap, { keymap: {
2804
- ctrlKey: true,
3105
+ modKey: true,
2805
3106
  key: '6'
2806
3107
  } }), checked: states.h6, children: "\u516D\u7EA7\u6807\u9898" }),
2807
3108
  value: 'h6'
@@ -2812,13 +3113,13 @@ function BlockTool() {
2812
3113
  label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-checkbox-checked" }), checked: states.todolist, children: "\u5F85\u529E\u4E8B\u9879" }),
2813
3114
  value: 'todolist'
2814
3115
  }, {
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" }),
3116
+ 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
3117
  value: 'ol'
2817
3118
  }, {
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" }),
3119
+ 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
3120
  value: 'ul'
2820
3121
  }, {
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" }),
3122
+ 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
3123
  value: 'blockquote'
2823
3124
  }, {
2824
3125
  label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-source-code" }), checked: states.sourceCode, children: "\u4EE3\u7801\u5757" }),
@@ -2878,7 +3179,7 @@ function registerBoldShortcut(textbus) {
2878
3179
  const keyboard = textbus.get(Keyboard);
2879
3180
  keyboard.addShortcut({
2880
3181
  keymap: {
2881
- ctrlKey: true,
3182
+ modKey: true,
2882
3183
  key: 'b'
2883
3184
  },
2884
3185
  action: () => {
@@ -2925,7 +3226,7 @@ function registerCodeShortcut(textbus) {
2925
3226
  const keyboard = textbus.get(Keyboard);
2926
3227
  keyboard.addShortcut({
2927
3228
  keymap: {
2928
- ctrlKey: true,
3229
+ modKey: true,
2929
3230
  key: ','
2930
3231
  },
2931
3232
  action: () => {
@@ -3035,7 +3336,7 @@ function registerItalicShortcut(textbus) {
3035
3336
  const keyboard = textbus.get(Keyboard);
3036
3337
  keyboard.addShortcut({
3037
3338
  keymap: {
3038
- ctrlKey: true,
3339
+ modKey: true,
3039
3340
  key: 'i'
3040
3341
  },
3041
3342
  action: () => {
@@ -3118,7 +3419,7 @@ function registerUnderlineShortcut(textbus) {
3118
3419
  const keyboard = textbus.get(Keyboard);
3119
3420
  keyboard.addShortcut({
3120
3421
  keymap: {
3121
- ctrlKey: true,
3422
+ modKey: true,
3122
3423
  key: 'u'
3123
3424
  },
3124
3425
  action: () => {
@@ -3594,6 +3895,171 @@ function UnderlineTool() {
3594
3895
  };
3595
3896
  }
3596
3897
 
3898
+ const cellAlignAttr = new Attribute('cellAlign', {
3899
+ render(node, formatValue) {
3900
+ node.styles.set('verticalAlign', formatValue);
3901
+ }
3902
+ });
3903
+ const cellAlignAttrLoader = {
3904
+ match(element) {
3905
+ return element instanceof HTMLTableCellElement && !!element.style.verticalAlign;
3906
+ },
3907
+ read(element) {
3908
+ return {
3909
+ attribute: cellAlignAttr,
3910
+ value: element.style.verticalAlign
3911
+ };
3912
+ }
3913
+ };
3914
+
3915
+ function CellAlignTool() {
3916
+ const currentValue = createSignal('');
3917
+ const selection = inject(Selection);
3918
+ function check(v) {
3919
+ const commonAncestorComponent = selection.commonAncestorComponent;
3920
+ if (commonAncestorComponent instanceof TableComponent) {
3921
+ const slots = commonAncestorComponent.getSelectedNormalizedSlots();
3922
+ slots.forEach(item => {
3923
+ item.cells.forEach(cell => {
3924
+ if (cell.visible) {
3925
+ cell.raw.slot.setAttribute(cellAlignAttr, v);
3926
+ }
3927
+ });
3928
+ });
3929
+ }
3930
+ }
3931
+ const refreshService = inject(RefreshService);
3932
+ const query = inject(Query);
3933
+ const highlight = createSignal(false);
3934
+ const subscription = refreshService.onRefresh.subscribe(() => {
3935
+ const result = query.queryAttribute(cellAlignAttr);
3936
+ const isHighlight = result.state === QueryStateType.Enabled;
3937
+ highlight.set(isHighlight);
3938
+ currentValue.set(isHighlight ? result.value : 'middle');
3939
+ });
3940
+ onUnmounted(() => {
3941
+ subscription.unsubscribe();
3942
+ });
3943
+ return () => {
3944
+ return (jsx(Dropdown, { onCheck: check, menu: [
3945
+ {
3946
+ label: jsx(MenuItem, { checked: currentValue() === 'top', icon: jsx("span", { class: "xnote-icon-align-top" }), children: "\u9876\u90E8\u5BF9\u9F50" }),
3947
+ value: 'top'
3948
+ },
3949
+ {
3950
+ label: jsx(MenuItem, { checked: currentValue() === 'middle', icon: jsx("span", { class: "xnote-icon-align-middle" }), children: "\u5782\u76F4\u5C45\u4E2D" }),
3951
+ value: 'middle'
3952
+ },
3953
+ {
3954
+ label: jsx(MenuItem, { checked: currentValue() === 'bottom', icon: jsx("span", { class: "xnote-icon-align-bottom" }), children: "\u5E95\u90E8\u5BF9\u9F50" }),
3955
+ value: 'bottom'
3956
+ }
3957
+ ], children: jsx(Button, { arrow: true, highlight: highlight(), children: jsx("span", { class: 'xnote-icon-align-' + (currentValue() || 'middle') }) }) }));
3958
+ };
3959
+ }
3960
+
3961
+ function CellBackgroundTool() {
3962
+ const refreshService = inject(RefreshService);
3963
+ const selection = inject(Selection);
3964
+ const [viewModel, update] = useProduce({
3965
+ highlight: false,
3966
+ disabled: false,
3967
+ });
3968
+ function split() {
3969
+ // const commonAncestorComponent = selection.commonAncestorComponent
3970
+ // if (commonAncestorComponent instanceof TableComponent) {
3971
+ // const scopes = selection.getSelectedScopes()
3972
+ // if (scopes.length) {
3973
+ // const start = commonAncestorComponent.getCellBySlot(scopes.at(0)!.slot)
3974
+ // const end = commonAncestorComponent.getCellBySlot(scopes.at(-1)!.slot)
3975
+ // // Re
3976
+ // }
3977
+ // }
3978
+ }
3979
+ const sub = refreshService.onRefresh.subscribe(() => {
3980
+ const commonAncestorComponent = selection.commonAncestorComponent;
3981
+ update(draft => {
3982
+ draft.disabled = !(commonAncestorComponent instanceof TableComponent);
3983
+ });
3984
+ });
3985
+ onUnmounted(() => {
3986
+ sub.unsubscribe();
3987
+ });
3988
+ return () => {
3989
+ const vm = viewModel();
3990
+ return jsx(Button, { highlight: vm.highlight, disabled: vm.disabled, onClick: split, children: jsx("span", { class: "xnote-icon-palette" }) });
3991
+ };
3992
+ }
3993
+
3994
+ function MergeCellsTool() {
3995
+ const refreshService = inject(RefreshService);
3996
+ const selection = inject(Selection);
3997
+ const [viewModel, update] = useProduce({
3998
+ highlight: false,
3999
+ disabled: false,
4000
+ });
4001
+ function merge() {
4002
+ const commonAncestorComponent = selection.commonAncestorComponent;
4003
+ if (commonAncestorComponent instanceof TableComponent) {
4004
+ commonAncestorComponent.mergeCellBySelection();
4005
+ }
4006
+ }
4007
+ const sub = refreshService.onRefresh.subscribe(() => {
4008
+ const commonAncestorComponent = selection.commonAncestorComponent;
4009
+ update(draft => {
4010
+ draft.disabled = !(commonAncestorComponent instanceof TableComponent);
4011
+ });
4012
+ });
4013
+ onUnmounted(() => {
4014
+ sub.unsubscribe();
4015
+ });
4016
+ return () => {
4017
+ const vm = viewModel();
4018
+ return jsx(Button, { highlight: vm.highlight, disabled: vm.disabled, onClick: merge, children: jsx("span", { class: "xnote-icon-merge-cells" }) });
4019
+ };
4020
+ }
4021
+
4022
+ function SplitCellsTool() {
4023
+ const refreshService = inject(RefreshService);
4024
+ const selection = inject(Selection);
4025
+ const [viewModel, update] = useProduce({
4026
+ highlight: false,
4027
+ disabled: false,
4028
+ });
4029
+ function split() {
4030
+ const commonAncestorComponent = selection.commonAncestorComponent;
4031
+ if (commonAncestorComponent instanceof TableComponent) {
4032
+ commonAncestorComponent.splitCellsBySelection();
4033
+ }
4034
+ }
4035
+ const sub = refreshService.onRefresh.subscribe(() => {
4036
+ const commonAncestorComponent = selection.commonAncestorComponent;
4037
+ update(draft => {
4038
+ if (commonAncestorComponent instanceof TableComponent) {
4039
+ const slots = commonAncestorComponent.getSelectedNormalizedSlots();
4040
+ if (slots) {
4041
+ for (const item of slots) {
4042
+ for (const cell of item.cells) {
4043
+ if (cell.visible && cell.colspan > 1 || cell.colspan > 1) {
4044
+ draft.disabled = false;
4045
+ return;
4046
+ }
4047
+ }
4048
+ }
4049
+ }
4050
+ }
4051
+ draft.disabled = true;
4052
+ });
4053
+ });
4054
+ onUnmounted(() => {
4055
+ sub.unsubscribe();
4056
+ });
4057
+ return () => {
4058
+ const vm = viewModel();
4059
+ return jsx(Button, { highlight: vm.highlight, disabled: vm.disabled, onClick: split, children: jsx("span", { class: "xnote-icon-split-cells" }) });
4060
+ };
4061
+ }
4062
+
3597
4063
  var scopedId$9 = "vf-cf8e1c";
3598
4064
 
3599
4065
  class FileUploader {
@@ -4376,6 +4842,10 @@ function LinkJump() {
4376
4842
 
4377
4843
  var scopedId$6 = "vf-fee98b";
4378
4844
 
4845
+ function sum(numbers) {
4846
+ return numbers.reduce((a, b) => a + b, 0);
4847
+ }
4848
+
4379
4849
  const Toolbar = withAnnotation({
4380
4850
  providers: [RefreshService]
4381
4851
  }, function Toolbar() {
@@ -4406,10 +4876,35 @@ const Toolbar = withAnnotation({
4406
4876
  const docRect = viewDocument.getBoundingClientRect();
4407
4877
  const toolbarHeight = 36;
4408
4878
  // const documentHeight = document.documentElement.clientHeight
4409
- const selectionFocusRect = bridge.getRect({
4410
- slot: selection.focusSlot,
4411
- offset: selection.focusOffset
4412
- });
4879
+ let selectionFocusRect = null;
4880
+ const commonAncestorComponent = selection.commonAncestorComponent;
4881
+ if (commonAncestorComponent instanceof TableComponent) {
4882
+ const slots = commonAncestorComponent.getSelectedNormalizedSlots().map(item => {
4883
+ return item.cells.filter(i => {
4884
+ return i.visible;
4885
+ }).map(cell => {
4886
+ return cell.raw.slot;
4887
+ });
4888
+ }).flat();
4889
+ const startSlot = slots.at(0);
4890
+ const endSlot = slots.at(-1);
4891
+ const rect = commonAncestorComponent.getSelectedRect();
4892
+ const startRect = adapter.getNativeNodeBySlot(startSlot).getBoundingClientRect();
4893
+ const endEle = adapter.getNativeNodeBySlot(endSlot).getBoundingClientRect();
4894
+ const width = sum(commonAncestorComponent.state.columnsConfig.slice(rect.x1, rect.x2));
4895
+ selectionFocusRect = {
4896
+ left: startRect.left + width / 2,
4897
+ top: startRect.top,
4898
+ height: endEle.bottom - startRect.top,
4899
+ width
4900
+ };
4901
+ }
4902
+ else {
4903
+ selectionFocusRect = bridge.getRect({
4904
+ slot: selection.focusSlot,
4905
+ offset: selection.focusOffset
4906
+ });
4907
+ }
4413
4908
  if (!selectionFocusRect) {
4414
4909
  return null;
4415
4910
  }
@@ -4440,7 +4935,13 @@ const Toolbar = withAnnotation({
4440
4935
  });
4441
4936
  function bindMouseup() {
4442
4937
  const docElement = adapter.getNativeNodeByComponent(rootComponentRef.component);
4443
- mouseupSubscription = fromEvent(docElement, 'mouseup').pipe(filter(ev => {
4938
+ mouseupSubscription = fromEvent(docElement, 'mouseup').pipe(delay(), filter(ev => {
4939
+ const c = selection.commonAncestorComponent;
4940
+ if (c instanceof TableComponent) {
4941
+ const b = !c.ignoreSelectionChanges;
4942
+ c.ignoreSelectionChanges = false;
4943
+ return b;
4944
+ }
4444
4945
  return !ev.composedPath().includes(toolbarRef.current);
4445
4946
  }), delay(100), filter(() => {
4446
4947
  return !selection.isCollapsed && !(selection.commonAncestorComponent instanceof SourceCodeComponent);
@@ -4484,7 +4985,7 @@ const Toolbar = withAnnotation({
4484
4985
  opacity: p.opacity,
4485
4986
  display: editorService.hideInlineToolbar ? 'none' : '',
4486
4987
  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, {}) })] }));
4988
+ }, 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
4989
  });
4489
4990
  });
4490
4991
 
@@ -4915,8 +5416,8 @@ let TableService = class TableService {
4915
5416
  constructor() {
4916
5417
  this.onInsertRowBefore = new Subject();
4917
5418
  this.onInsertColumnBefore = new Subject();
4918
- this.onSelectColumns = new Subject();
4919
- this.onSelectRows = new Subject();
5419
+ // onSelectColumns = new Subject<{ start: number, end: number } | null>()
5420
+ // onSelectRows = new Subject<{ start: number, end: number } | null>()
4920
5421
  this.onScroll = new Subject();
4921
5422
  }
4922
5423
  };
@@ -4936,7 +5437,11 @@ function ResizeColumn(props) {
4936
5437
  ignoreMove = true;
4937
5438
  }).add(fromEvent(document, 'mouseup').subscribe(() => {
4938
5439
  ignoreMove = false;
4939
- })).add(fromEvent(tableRef.current.parentNode, 'mousemove').subscribe(ev => {
5440
+ })).add(fromEvent(tableRef.current.parentNode, 'mouseleave').subscribe(() => {
5441
+ if (!isDrag) {
5442
+ dragLineRef.current.style.display = 'none';
5443
+ }
5444
+ }), fromEvent(tableRef.current.parentNode, 'mousemove').subscribe(ev => {
4940
5445
  if (isDrag || ignoreMove) {
4941
5446
  return;
4942
5447
  }
@@ -4944,7 +5449,7 @@ function ResizeColumn(props) {
4944
5449
  const leftDistance = ev.clientX - tableRect.x;
4945
5450
  const state = props.component.state;
4946
5451
  let x = 0;
4947
- for (let i = 0; i < state.layoutWidth.length + 1; i++) {
5452
+ for (let i = 0; i < state.columnsConfig.length + 1; i++) {
4948
5453
  const n = leftDistance - x;
4949
5454
  if (i > 0 && Math.abs(n) < 5) {
4950
5455
  Object.assign(dragLineRef.current.style, {
@@ -4956,14 +5461,14 @@ function ResizeColumn(props) {
4956
5461
  }
4957
5462
  activeCol = null;
4958
5463
  dragLineRef.current.style.display = 'none';
4959
- x += state.layoutWidth[i];
5464
+ x += state.columnsConfig[i] || 0;
4960
5465
  }
4961
5466
  })).add(fromEvent(dragLineRef.current, 'mousedown').subscribe(downEvent => {
4962
5467
  isDrag = true;
4963
5468
  editorService.changeLeftToolbarVisible(false);
4964
5469
  props.onActiveStateChange(true);
4965
5470
  const x = downEvent.clientX;
4966
- const layoutWidth = props.component.state.layoutWidth;
5471
+ const layoutWidth = props.component.state.columnsConfig;
4967
5472
  const initWidth = layoutWidth[activeCol - 1];
4968
5473
  const initLeft = layoutWidth.slice(0, activeCol).reduce((a, b) => a + b, 0);
4969
5474
  const minWidth = 30;
@@ -4980,8 +5485,8 @@ function ResizeColumn(props) {
4980
5485
  props.onActiveStateChange(false);
4981
5486
  moveEvent.unsubscribe();
4982
5487
  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);
5488
+ props.component.state.columnsConfig[activeCol - 1] = Math.max(initWidth + distanceX, minWidth);
5489
+ props.layoutWidth.set(props.component.state.columnsConfig.slice());
4985
5490
  }));
4986
5491
  }));
4987
5492
  return () => {
@@ -4996,7 +5501,7 @@ function ResizeColumn(props) {
4996
5501
  return;
4997
5502
  }
4998
5503
  const state = props.component.state;
4999
- const left = state.layoutWidth.slice(0, n).reduce((a, b) => a + b, 0) - 0.5;
5504
+ const left = state.columnsConfig.slice(0, n).reduce((a, b) => a + b, 0) - 0.5;
5000
5505
  dragLineRef.current.style.display = 'block';
5001
5506
  dragLineRef.current.style.left = left + 'px';
5002
5507
  });
@@ -5011,9 +5516,7 @@ var scopedId$4 = "vf-39cb2c";
5011
5516
 
5012
5517
  function TopBar(props) {
5013
5518
  const editorService = inject(EditorService);
5014
- const selection = inject(Selection);
5015
5519
  const tableService = inject(TableService);
5016
- const textbus = inject(Textbus);
5017
5520
  const selectedColumnRange = createSignal(null);
5018
5521
  function selectColumn(index, isMultiple) {
5019
5522
  editorService.hideInlineToolbar = true;
@@ -5029,24 +5532,11 @@ function TopBar(props) {
5029
5532
  startIndex: index, endIndex: index
5030
5533
  });
5031
5534
  }
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
- });
5535
+ let { startIndex, endIndex } = selectedColumnRange();
5536
+ if (startIndex > endIndex) {
5537
+ [startIndex, endIndex] = [endIndex, startIndex];
5538
+ }
5539
+ props.component.selectColumn(startIndex, endIndex + 1);
5050
5540
  }
5051
5541
  let mouseDownFromToolbar = false;
5052
5542
  onMounted(() => {
@@ -5055,7 +5545,6 @@ function TopBar(props) {
5055
5545
  mouseDownFromToolbar = false;
5056
5546
  return;
5057
5547
  }
5058
- deleteIndex.set(null);
5059
5548
  selectedColumnRange.set(null);
5060
5549
  });
5061
5550
  return () => sub.unsubscribe();
@@ -5074,49 +5563,53 @@ function TopBar(props) {
5074
5563
  onUnmounted(() => {
5075
5564
  s.unsubscribe();
5076
5565
  });
5077
- const deleteIndex = createSignal(null);
5566
+ function refreshLayoutWidth() {
5567
+ props.layoutWidth.set(props.component.state.columnsConfig.slice());
5568
+ }
5078
5569
  return withScopedCSS(scopedId$4, () => {
5079
5570
  const { state, tableSelection } = props.component;
5080
5571
  const position = tableSelection();
5572
+ const range = selectedColumnRange();
5573
+ let left = 0;
5574
+ if (range) {
5575
+ left = sum(props.component.state.columnsConfig.slice(0, Math.min(range.startIndex, range.endIndex)));
5576
+ left += sum(props.component.state.columnsConfig.slice(Math.min(range.startIndex, range.endIndex), Math.max(range.startIndex, range.endIndex) + 1)) / 2;
5577
+ }
5081
5578
  return (jsx("div", { class: ['top-bar', {
5082
5579
  active: props.isFocus()
5083
- }], children: jsxs("div", { class: "toolbar-wrapper", children: [jsx("div", { class: "insert-bar", children: jsx("table", { style: {
5580
+ }], children: jsxs("div", { class: "toolbar-wrapper", children: [jsxs("div", { class: "insert-bar", children: [jsx(ComponentToolbar, { style: {
5581
+ left: left - leftDistance() + 'px',
5582
+ display: selectedColumnRange() ? 'inline-block' : 'none',
5583
+ }, innerStyle: {
5584
+ transform: 'translateX(-50%)'
5585
+ }, visible: !!selectedColumnRange(), children: jsx(ToolbarItem, { children: jsx(Button, { onClick: () => {
5586
+ props.component.deleteColumns();
5587
+ refreshLayoutWidth();
5588
+ }, children: jsx("span", { class: "xnote-icon-bin" }) }) }) }), jsx("table", { style: {
5589
+ transform: `translateX(${-leftDistance()}px)`
5590
+ }, children: jsx("tbody", { children: jsx("tr", { children: props.layoutWidth().map((i, index) => {
5591
+ return (jsx("td", { style: { width: i + 'px', minWidth: i + 'px' }, children: jsxs("div", { class: "tool-container", children: [index === 0 && (jsx("span", { onMouseenter: () => {
5592
+ tableService.onInsertColumnBefore.next(0);
5593
+ }, onMouseleave: () => {
5594
+ tableService.onInsertColumnBefore.next(null);
5595
+ }, class: "insert-btn-wrap", style: {
5596
+ left: '-10px'
5597
+ }, onClick: () => {
5598
+ props.component.insertColumn(0);
5599
+ refreshLayoutWidth();
5600
+ }, children: jsx("button", { class: "insert-btn", type: "button", children: "+" }) })), jsx("span", { class: "insert-btn-wrap", onMouseenter: () => {
5601
+ tableService.onInsertColumnBefore.next(index + 1);
5602
+ }, onMouseleave: () => {
5603
+ tableService.onInsertColumnBefore.next(null);
5604
+ }, onClick: () => {
5605
+ props.component.insertColumn(index + 1);
5606
+ refreshLayoutWidth();
5607
+ }, children: jsx("button", { class: "insert-btn", type: "button", children: "+" }) })] }) }));
5608
+ }) }) }) })] }), jsx("div", { class: ['action-bar', { active: props.isFocus() }], children: jsx("table", { style: {
5084
5609
  transform: `translateX(${-leftDistance()}px)`
5085
5610
  }, 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: {
5110
- transform: `translateX(${-leftDistance()}px)`
5111
- }, children: jsx("tbody", { children: jsx("tr", { children: props.layoutWidth().map((i, index) => {
5112
- return jsx("td", { onClick: ev => {
5611
+ return jsx("td", { onMousedown: ev => ev.preventDefault(), onClick: ev => {
5113
5612
  mouseDownFromToolbar = true;
5114
- if (!ev.shiftKey) {
5115
- deleteIndex.set(index);
5116
- }
5117
- else {
5118
- deleteIndex.set(null);
5119
- }
5120
5613
  selectColumn(index, ev.shiftKey);
5121
5614
  }, class: {
5122
5615
  active: !position ? false :
@@ -5178,10 +5671,8 @@ var scopedId$2 = "vf-aaece0";
5178
5671
 
5179
5672
  function LeftBar(props) {
5180
5673
  const editorService = inject(EditorService);
5181
- const selection = inject(Selection);
5182
5674
  const actionBarRef = createRef();
5183
5675
  const insertBarRef = createRef();
5184
- const textbus = inject(Textbus);
5185
5676
  const tableService = inject(TableService);
5186
5677
  // 同步行高度
5187
5678
  onUpdated(() => {
@@ -5189,8 +5680,10 @@ function LeftBar(props) {
5189
5680
  const actionBarRows = actionBarRef.current.rows;
5190
5681
  setTimeout(() => {
5191
5682
  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';
5683
+ const height = tr.offsetHeight ||
5684
+ Math.min(...Array.from(tr.children).map(i => i.offsetHeight)) || 0;
5685
+ insertBarRows.item(i).style.height = height + 'px';
5686
+ actionBarRows.item(i).style.height = height + 'px';
5194
5687
  });
5195
5688
  });
5196
5689
  });
@@ -5229,30 +5722,27 @@ function LeftBar(props) {
5229
5722
  startIndex: index, endIndex: index
5230
5723
  });
5231
5724
  }
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
- });
5725
+ let { startIndex, endIndex } = selectedRowRange();
5726
+ if (startIndex > endIndex) {
5727
+ [startIndex, endIndex] = [endIndex, startIndex];
5728
+ }
5729
+ deleteIndex.set(startIndex);
5730
+ props.component.selectRow(startIndex, endIndex + 1);
5250
5731
  }
5251
5732
  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: () => {
5733
+ const position = props.component.tableSelection();
5734
+ const normalizedData = props.component.getNormalizedData();
5735
+ 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) => {
5736
+ let b = false;
5737
+ for (const item of row.cells) {
5738
+ if (item.visible) {
5739
+ b = true;
5740
+ break;
5741
+ }
5742
+ }
5743
+ return (jsx("tr", { style: {
5744
+ display: b ? '' : 'none'
5745
+ }, children: jsx("td", { children: jsxs("div", { class: "toolbar-item", children: [index === 0 && (jsx("span", { onMouseenter: () => {
5256
5746
  tableService.onInsertRowBefore.next(-1);
5257
5747
  }, onMouseleave: () => {
5258
5748
  tableService.onInsertRowBefore.next(null);
@@ -5265,6 +5755,11 @@ function LeftBar(props) {
5265
5755
  }, onMouseleave: () => {
5266
5756
  tableService.onInsertRowBefore.next(null);
5267
5757
  }, class: "insert-btn-wrap", onClick: () => {
5758
+ const cells = row.cells.filter(i => i.visible);
5759
+ if (cells.length < 2) {
5760
+ props.component.insertRow(index + row.cells.at(0).rowspan);
5761
+ return;
5762
+ }
5268
5763
  props.component.insertRow(index + 1);
5269
5764
  }, children: jsx("button", { class: "insert-btn", type: "button", children: "+" }) }), jsx(ComponentToolbar, { style: {
5270
5765
  display: deleteIndex() === index ? 'inline-block' : 'none',
@@ -5273,23 +5768,26 @@ function LeftBar(props) {
5273
5768
  top: 0,
5274
5769
  transform: 'translateY(-50%)'
5275
5770
  }, visible: deleteIndex() === index, children: jsx(ToolbarItem, { children: jsx(Button, { onClick: () => {
5276
- props.component.deleteRow(index);
5771
+ props.component.deleteRows();
5277
5772
  deleteIndex.set(null);
5278
5773
  }, 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) => {
5774
+ }) }) }) }), jsx("div", { class: "action-bar", children: jsx("table", { ref: actionBarRef, children: jsx("tbody", { children: normalizedData.map((row, index) => {
5775
+ let b = false;
5776
+ for (const item of row.cells) {
5777
+ if (item.visible) {
5778
+ b = true;
5779
+ break;
5780
+ }
5781
+ }
5782
+ return jsx("tr", { style: {
5783
+ display: b ? '' : 'none'
5784
+ }, children: jsx("td", { onMousedown: ev => ev.preventDefault(), onClick: (ev) => {
5281
5785
  mouseDownFromToolbar = true;
5282
- if (!ev.shiftKey) {
5283
- deleteIndex.set(index);
5284
- }
5285
- else {
5286
- deleteIndex.set(null);
5287
- }
5288
5786
  selectRow(index, ev.shiftKey);
5289
5787
  }, class: {
5290
5788
  active: !position ? false :
5291
5789
  (position.startColumn === 0 &&
5292
- position.endColumn === state.layoutWidth.length &&
5790
+ position.endColumn === props.component.state.columnsConfig.length &&
5293
5791
  index >= position.startRow && index < position.endRow)
5294
5792
  } }) });
5295
5793
  }) }) }) })] }));
@@ -5298,10 +5796,6 @@ function LeftBar(props) {
5298
5796
 
5299
5797
  var scopedId$1 = "vf-d4c4a9";
5300
5798
 
5301
- function sum(numbers) {
5302
- return numbers.reduce((a, b) => a + b, 0);
5303
- }
5304
-
5305
5799
  function ResizeRow(props) {
5306
5800
  const dragLineRef = createRef();
5307
5801
  const tableService = inject(TableService);
@@ -5333,7 +5827,7 @@ function ResizeRow(props) {
5333
5827
  return jsx("div", { ref: dragLineRef, style: {
5334
5828
  display: styles().visible ? 'block' : 'none',
5335
5829
  top: styles().top + 'px',
5336
- width: sum(props.component.state.layoutWidth) + 'px'
5830
+ width: sum(props.component.state.columnsConfig) + 'px'
5337
5831
  }, class: 'drag-line' });
5338
5832
  });
5339
5833
  }
@@ -5367,16 +5861,19 @@ function SelectionMask(props) {
5367
5861
  if (selection.startRow > 0) {
5368
5862
  heightCompensation = -1;
5369
5863
  }
5370
- if (selection.endRow === state.rows.length) {
5864
+ if (selection.endRow + 1 === state.rows.length) {
5371
5865
  heightCompensation += 0.5;
5372
5866
  }
5373
5867
  const trs = Array.from(props.tableRef.current.rows);
5374
5868
  updateStyles(draft => {
5869
+ var _a;
5870
+ const height = trs[selection.endRow - 1].offsetHeight ||
5871
+ ((_a = trs[selection.endRow - 1].children[0]) === null || _a === void 0 ? void 0 : _a.offsetHeight) || 0;
5375
5872
  draft.visible = true;
5376
- draft.left = sum(state.layoutWidth.slice(0, selection.startColumn));
5873
+ draft.left = sum(state.columnsConfig.slice(0, selection.startColumn));
5377
5874
  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';
5875
+ draft.width = sum(state.columnsConfig.slice(selection.startColumn, selection.endColumn)) - 1 + 'px';
5876
+ draft.height = trs[selection.endRow - 1].offsetTop + height + heightCompensation - draft.top + 'px';
5380
5877
  });
5381
5878
  }
5382
5879
  else {
@@ -5405,14 +5902,106 @@ function SelectionMask(props) {
5405
5902
  });
5406
5903
  }
5407
5904
 
5408
- // import { SlotRender } from '../SlotRender'
5905
+ /**
5906
+ * 修复不规范表格,并补全空位
5907
+ * @param table
5908
+ */
5909
+ function autoComplete(table) {
5910
+ const newTable = [];
5911
+ table.forEach((tr, rowIndex) => {
5912
+ let row = newTable[rowIndex];
5913
+ if (!row) {
5914
+ row = [];
5915
+ newTable[rowIndex] = row;
5916
+ }
5917
+ let startColumnIndex = 0;
5918
+ tr.forEach(td => {
5919
+ while (row[startColumnIndex]) {
5920
+ startColumnIndex++;
5921
+ }
5922
+ let maxColspan = 1;
5923
+ while (maxColspan < td.colspan) {
5924
+ if (!row[startColumnIndex + maxColspan]) {
5925
+ maxColspan++;
5926
+ }
5927
+ else {
5928
+ break;
5929
+ }
5930
+ }
5931
+ td.colspan = maxColspan;
5932
+ for (let i = rowIndex, len = td.rowspan + rowIndex; i < len; i++) {
5933
+ let row = newTable[i];
5934
+ if (!row) {
5935
+ row = [];
5936
+ newTable[i] = row;
5937
+ }
5938
+ for (let j = startColumnIndex, max = startColumnIndex + maxColspan; j < max; j++) {
5939
+ row[j] = td;
5940
+ }
5941
+ }
5942
+ startColumnIndex += maxColspan;
5943
+ });
5944
+ });
5945
+ const maxColumns = Math.max(...newTable.map(i => i.length));
5946
+ newTable.forEach(tr => {
5947
+ for (let i = 0; i < maxColumns; i++) {
5948
+ if (!tr[i]) {
5949
+ tr[i] = {
5950
+ id: v4(),
5951
+ rowspan: 1,
5952
+ colspan: 1,
5953
+ slot: new Slot([
5954
+ ContentType.BlockComponent
5955
+ ])
5956
+ };
5957
+ }
5958
+ }
5959
+ });
5960
+ const ids = [];
5961
+ const mergedConfig = {};
5962
+ const normalizedTable = newTable.map(tr => {
5963
+ return tr.map(td => {
5964
+ const is = ids.includes(td.id);
5965
+ if (is) {
5966
+ return {
5967
+ id: v4(),
5968
+ slot: new Slot([
5969
+ ContentType.BlockComponent,
5970
+ ])
5971
+ };
5972
+ }
5973
+ ids.push(td.id);
5974
+ return {
5975
+ id: td.id,
5976
+ slot: td.slot
5977
+ };
5978
+ });
5979
+ });
5980
+ ids.length = 0;
5981
+ newTable.forEach((tr, rowIndex) => {
5982
+ tr.forEach((td, colIndex) => {
5983
+ if (td.rowspan > 1 || td.colspan > 1) {
5984
+ if (ids.includes(td.id)) {
5985
+ return;
5986
+ }
5987
+ ids.push(td.id);
5988
+ mergedConfig[td.id] = normalizedTable[rowIndex + td.rowspan - 1][colIndex + td.colspan - 1].id;
5989
+ }
5990
+ });
5991
+ });
5992
+ return {
5993
+ mergedConfig,
5994
+ table: normalizedTable
5995
+ };
5996
+ }
5997
+
5409
5998
  const TableComponentView = withAnnotation({
5410
5999
  providers: [TableService]
5411
6000
  }, function TableComponentView(props) {
5412
6001
  const adapter = inject(DomAdapter);
5413
6002
  const editorService = inject(EditorService);
5414
6003
  const isFocus = createSignal(false);
5415
- const layoutWidth = createSignal(props.component.state.layoutWidth);
6004
+ const layoutWidth = createSignal(props.component.state.columnsConfig);
5416
6005
  const subscription = props.component.focus.subscribe(b => {
5417
6006
  isFocus.set(b);
5418
6007
  if (!b) {
@@ -5422,53 +6011,63 @@ const TableComponentView = withAnnotation({
5422
6011
  onUnmounted(() => {
5423
6012
  subscription.unsubscribe();
5424
6013
  });
6014
+ function resetIgnore() {
6015
+ props.component.ignoreSelectionChanges = false;
6016
+ }
5425
6017
  const tableRef = createRef();
5426
6018
  const isResizeColumn = createSignal(false);
5427
6019
  const rowMapping = new WeakMap();
5428
6020
  const readonly = useReadonly();
5429
6021
  const output = useOutput();
5430
6022
  return () => {
6023
+ const normalizedData = props.component.getNormalizedData();
5431
6024
  const state = props.component.state;
5432
- const rows = state.rows;
5433
- rows.forEach(row => {
5434
- if (rowMapping.has(row)) {
6025
+ // const rows = state.rows
6026
+ normalizedData.forEach(row => {
6027
+ if (rowMapping.has(row.row)) {
5435
6028
  return;
5436
6029
  }
5437
- rowMapping.set(row, Math.random());
6030
+ rowMapping.set(row.row, Math.random());
5438
6031
  });
5439
6032
  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: [
6033
+ 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
6034
  'xnote-table-content',
5442
6035
  {
5443
6036
  'hide-selection': props.component.tableSelection()
5444
6037
  }
5445
- ], children: [jsx("colgroup", { children: layoutWidth().map(w => {
6038
+ ], children: [jsx("colgroup", { children: state.columnsConfig.map(w => {
5446
6039
  return jsx("col", { style: { width: w + 'px', minWidth: w + 'px' } });
5447
- }) }), jsx("tbody", { children: rows.map((row) => {
6040
+ }) }), jsx("tbody", { children: normalizedData.map((row) => {
5448
6041
  return (jsx("tr", { children: row.cells.map(cell => {
5449
- return adapter.slotRender(cell.slot, children => {
6042
+ return adapter.slotRender(cell.raw.slot, children => {
5450
6043
  return createVNode('td', {
5451
- key: cell.slot.id
6044
+ key: cell.raw.id,
6045
+ rowspan: cell.rowspan,
6046
+ colspan: cell.colspan
5452
6047
  }, children);
5453
6048
  }, readonly() || output());
5454
- }) }, rowMapping.get(row)));
6049
+ }) }, rowMapping.get(row.row)));
5455
6050
  }) })] }) }) }) }));
5456
6051
  }
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: [
6052
+ 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
6053
  'xnote-table-content',
5459
6054
  {
5460
6055
  'hide-selection': props.component.tableSelection()
5461
6056
  }
5462
6057
  ], children: [jsx("colgroup", { children: layoutWidth().map(w => {
5463
6058
  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 => {
6059
+ }) }), jsx("tbody", { onMousedown: resetIgnore, children: normalizedData.map((row) => {
6060
+ return (jsx("tr", { children: row.cells.filter(i => {
6061
+ return i.visible;
6062
+ }).map(cell => {
6063
+ return adapter.slotRender(cell.raw.slot, children => {
5467
6064
  return createVNode('td', {
5468
- key: cell.slot.id
6065
+ key: cell.raw.id,
6066
+ rowspan: cell.rowspan,
6067
+ colspan: cell.colspan
5469
6068
  }, children);
5470
6069
  }, readonly() || output());
5471
- }) }, rowMapping.get(row)));
6070
+ }) }, rowMapping.get(row.row)));
5472
6071
  }) })] }), jsx(ResizeColumn, { tableRef: tableRef, component: props.component, layoutWidth: layoutWidth, onActiveStateChange: isActive => {
5473
6072
  isResizeColumn.set(isActive);
5474
6073
  } }), jsx(SelectionMask, { tableRef: tableRef, component: props.component })] }) }), jsx(ResizeRow, { component: props.component, tableRef: tableRef })] }) }));
@@ -5495,6 +6094,7 @@ const tableComponentLoader = {
5495
6094
  ContentType.BlockComponent,
5496
6095
  ]);
5497
6096
  arr.push({
6097
+ id: v4(),
5498
6098
  slot,
5499
6099
  rowspan: cell.rowSpan,
5500
6100
  colspan: cell.colSpan
@@ -5522,6 +6122,7 @@ const tableComponentLoader = {
5522
6122
  ContentType.BlockComponent,
5523
6123
  ]);
5524
6124
  arr.push({
6125
+ id: v4(),
5525
6126
  slot,
5526
6127
  rowspan: cell.rowSpan,
5527
6128
  colspan: cell.colSpan
@@ -5540,7 +6141,7 @@ const tableComponentLoader = {
5540
6141
  }
5541
6142
  bodies.unshift(...headers);
5542
6143
  const cells = autoComplete(bodies);
5543
- let layoutWidth = null;
6144
+ let layoutWidth = [];
5544
6145
  try {
5545
6146
  const columnWidth = JSON.parse(element.dataset.layoutWidth || '');
5546
6147
  if (Array.isArray(columnWidth)) {
@@ -5550,80 +6151,23 @@ const tableComponentLoader = {
5550
6151
  catch (e) {
5551
6152
  //
5552
6153
  }
5553
- if (!layoutWidth) {
5554
- layoutWidth = Array.from({ length: cells[0].length }).fill(100);
6154
+ const length = cells.table[0].length;
6155
+ for (let i = 0; i < length; i++) {
6156
+ layoutWidth[i] = layoutWidth[i] || 100;
5555
6157
  }
6158
+ layoutWidth.length = length;
5556
6159
  return new TableComponent(textbus, {
5557
- rows: cells.map(i => {
6160
+ columnsConfig: layoutWidth,
6161
+ mergeConfig: cells.mergedConfig,
6162
+ rows: cells.table.map(i => {
5558
6163
  return {
5559
6164
  height: 30,
5560
6165
  cells: i
5561
6166
  };
5562
- }),
5563
- layoutWidth
6167
+ })
5564
6168
  });
5565
6169
  }
5566
6170
  };
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
6171
 
5628
6172
  function findFocusCell(table, slot) {
5629
6173
  var _a;
@@ -5660,18 +6204,25 @@ let TableSelectionAwarenessDelegate = class TableSelectionAwarenessDelegate exte
5660
6204
  if (!(commonAncestorComponent instanceof TableComponent)) {
5661
6205
  return false;
5662
6206
  }
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;
6207
+ const rect = commonAncestorComponent.getMaxRectangle(findFocusCell(commonAncestorComponent, startSlot), findFocusCell(commonAncestorComponent, endSlot));
5667
6208
  const renderer = this.domAdapter;
5668
- const startRect = renderer.getNativeNodeBySlot(startFocusSlot).getBoundingClientRect();
5669
- const endRect = renderer.getNativeNodeBySlot(endFocusSlot).getBoundingClientRect();
6209
+ if (!rect) {
6210
+ return false;
6211
+ }
6212
+ const normalizedSlots = commonAncestorComponent.getSelectedNormalizedSlotsByRectangle(rect);
6213
+ const rects = normalizedSlots.map(row => {
6214
+ return row.cells.filter(i => i.visible).map(i => {
6215
+ const td = renderer.getNativeNodeBySlot(i.raw.slot);
6216
+ return td.getBoundingClientRect();
6217
+ });
6218
+ }).flat();
6219
+ const left = Math.min(...rects.map(i => i.left));
6220
+ const top = Math.min(...rects.map(i => i.top));
5670
6221
  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
6222
+ left,
6223
+ top,
6224
+ width: Math.max(...rects.map(i => i.right)) - left,
6225
+ height: Math.max(...rects.map(i => i.bottom)) - top
5675
6226
  }];
5676
6227
  }
5677
6228
  };
@@ -5680,32 +6231,6 @@ TableSelectionAwarenessDelegate = __decorate([
5680
6231
  __metadata("design:paramtypes", [DomAdapter,
5681
6232
  Selection])
5682
6233
  ], 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
6234
 
5710
6235
  function TimelineComponentView(props) {
5711
6236
  const adapter = inject(DomAdapter);
@@ -5870,6 +6395,7 @@ class Editor extends Textbus {
5870
6395
  strikeThroughFormatLoader,
5871
6396
  underlineFormatLoader
5872
6397
  ], attributeLoaders: [
6398
+ cellAlignAttrLoader,
5873
6399
  headingAttrLoader,
5874
6400
  textAlignAttrLoader,
5875
6401
  textIndentAttrLoader
@@ -5942,6 +6468,7 @@ class Editor extends Textbus {
5942
6468
  strikeThroughFormatter,
5943
6469
  underlineFormatter
5944
6470
  ], attributes: [
6471
+ cellAlignAttr,
5945
6472
  headingAttr,
5946
6473
  textAlignAttr,
5947
6474
  textIndentAttr
@@ -6013,4 +6540,4 @@ class Editor extends Textbus {
6013
6540
  }
6014
6541
  }
6015
6542
 
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 };
6543
+ 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 };