@gct-paas/word 0.1.74-beta.11 → 0.1.74-beta.12

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 (34) hide show
  1. package/dist/core/command/commands/InsertTable.d.ts +4 -0
  2. package/dist/core/constants/index.d.ts +1 -0
  3. package/dist/core/constants/table.d.ts +11 -0
  4. package/dist/core/cursor/logic/getSelectionRects.d.ts +15 -2
  5. package/dist/core/cursor/logic/index.d.ts +2 -1
  6. package/dist/core/cursor/logic/selectionAnalyzer.d.ts +31 -6
  7. package/dist/core/event/types.d.ts +1 -1
  8. package/dist/core/index.d.ts +1 -1
  9. package/dist/core/interaction/InteractionController.d.ts +11 -0
  10. package/dist/core/interaction/types.d.ts +8 -0
  11. package/dist/core/interaction/useInteraction.d.ts +6 -0
  12. package/dist/core/layout/LayoutManager.d.ts +5 -1
  13. package/dist/core/layout/providers/TableInfoProvider.d.ts +2 -2
  14. package/dist/core/layout/table/split-table.d.ts +10 -0
  15. package/dist/core/layout/types/index.d.ts +2 -0
  16. package/dist/core/model/document/Wbody.d.ts +4 -0
  17. package/dist/core/model/document/Wtbl/RowColumnOps.d.ts +9 -0
  18. package/dist/core/model/document/Wtbl/Serialization.d.ts +26 -1
  19. package/dist/core/model/document/Wtbl.d.ts +31 -3
  20. package/dist/core/model/document/Wtc.d.ts +13 -2
  21. package/dist/core/model/document/Wtr.d.ts +2 -1
  22. package/dist/core/model/document/index.d.ts +1 -0
  23. package/dist/core/model/document/utils/ensure-paragraphs-around-tables.d.ts +18 -0
  24. package/dist/core/model/templates/tableCell.template.d.ts +2 -0
  25. package/dist/core/view/Table.d.ts +13 -0
  26. package/dist/core/view/TableCell.d.ts +2 -1
  27. package/dist/domain/table/design/validate-nested-table-region.d.ts +31 -0
  28. package/dist/domain/table/design/validate-table-selection.d.ts +8 -0
  29. package/dist/domain/table/index.d.ts +1 -0
  30. package/dist/index.es.js +2323 -1350
  31. package/dist/runtime/canvas/table/table-design.vue.d.ts +1 -0
  32. package/dist/runtime/canvas/table/utils/useTableSelection.d.ts +6 -0
  33. package/dist/word.css +66 -66
  34. package/package.json +1 -1
@@ -5,5 +5,9 @@ import { Wtbl } from '../../model/document';
5
5
  export declare class InsertTable extends CommandBase<'insertTable'> {
6
6
  constructor(doc: Doc, payload?: CommandPayloadMap['insertTable']);
7
7
  protected createTable(width: number, rowCount?: number, colCount?: number): Wtbl;
8
+ private resolveBlockedTableLabel;
8
9
  protected execute(): Promise<PostCommandContext>;
10
+ private insertAtCursor;
11
+ private insertIntoBody;
12
+ private insertIntoCell;
9
13
  }
@@ -2,3 +2,4 @@ export * from './common';
2
2
  export * from './component';
3
3
  export * from './doc-mode';
4
4
  export * from './paper';
5
+ export * from './table';
@@ -0,0 +1,11 @@
1
+ /** 外表列/单元格最小宽度(像素),与手动拖列宽下限一致 */
2
+ export declare const MIN_TABLE_COL_WIDTH_PX = 30;
3
+ /** 外表列/单元格最小宽度(DXA) */
4
+ export declare const MIN_TABLE_COL_WIDTH_DXA: number;
5
+ /** 嵌套表内单列最小宽度(DXA,约 0.5") */
6
+ export declare const MIN_NESTED_TABLE_COL_WIDTH_DXA = 720;
7
+ /**
8
+ * 业务表 / 数据表 region 类型集合。
9
+ * 用于:嵌套表插入拦截、内外表业务数据标记互斥。
10
+ */
11
+ export declare const BUSINESS_DATA_REGION_TYPES: ReadonlySet<string>;
@@ -1,6 +1,19 @@
1
1
  import { Doc } from '../../view/Doc';
2
2
  import { ISelectionRange, Rect } from '../types/cursor';
3
3
  /**
4
- * 将 selection(逻辑选区)转换成一组视觉矩形(canvas 绝对坐标)
4
+ * 将 selection(逻辑选区)转换成一组视觉矩形(canvas 绝对坐标)和单元格 ID 集合。
5
+ *
6
+ * 高亮策略(按模式):
7
+ * - cell-range / cell-full / mixed(表格行部分)
8
+ * → cellRangeIds:由 table-cell.vue 在内容层渲染选中背景,
9
+ * 内表格单元格的白色背景会自然覆盖外格蓝色,无需额外处理。
10
+ * - cell-inner
11
+ * → rects:cursor 覆盖层渲染文字级别高亮;
12
+ * 只保留属于 selectionTableId 的原子节点(过滤掉内表格 atoms,解决 Q6 场景)。
13
+ * - mixed(段落部分) / 纯段落
14
+ * → rects:cursor 覆盖层渲染。
5
15
  */
6
- export declare function getSelectionRects(doc: Doc, selection: ISelectionRange, upgrade: boolean): Rect[];
16
+ export declare function getSelectionRects(doc: Doc, selection: ISelectionRange, upgrade: boolean): {
17
+ rects: Rect[];
18
+ cellRangeIds: string[];
19
+ };
@@ -5,7 +5,8 @@ export { computeRealignedCursorState, cursorMetaToInput, cursorPositionToInput,
5
5
  export { getCursorCoords } from './getCursorCoords';
6
6
  export { getCursorTextRawList } from './getCursorTextRawList';
7
7
  export { getSelectionRects } from './getSelectionRects';
8
- export { getSelectLinesInfo } from './selectionAnalyzer';
8
+ export { getSelectLinesInfo, resolveSelectionTableScope, resolveTableScopeFromCursor, resolveTableScopeFromModelNode, resolveWpFromCursor, } from './selectionAnalyzer';
9
+ export type { TableScope } from '../../model/document/Wtbl';
9
10
  export { getImmediateNeighborNode, findFirstAtomBeyond, isAtBoundaryOfNode, findTargetLineId, locateByX, } from './layoutNavigation';
10
11
  /**
11
12
  * 将命中结果转换为光标位置
@@ -1,12 +1,32 @@
1
- import { BaseMetaNode, LineInfo, TableSelectionMode } from '../../layout/types';
1
+ import { BaseMetaNode, LineInfo } from '../../layout/types';
2
2
  import { Doc } from '../../view/Doc';
3
3
  import { ISelectionRange } from '../types/cursor';
4
+ import { ModelNode } from '../../model/base';
5
+ import { TableScope } from '../../model/document/Wtbl';
6
+ import { Wp } from '../../model/document';
7
+ /** 从 model 节点向上解析当前表格作用域 */
8
+ export declare function resolveTableScopeFromModelNode(node: ModelNode): TableScope | undefined;
9
+ /** 从光标定位当前 Wtbl 作用域(含嵌套表内光标) */
10
+ export declare function resolveTableScopeFromCursor(doc: Doc): TableScope | undefined;
11
+ /** 从当前选区解析表格作用域(仅单表,跨内外表时返回 undefined) */
12
+ export declare function resolveSelectionTableScope(doc: Doc): TableScope | undefined;
13
+ /** 从光标向上解析所在段落的 Wp(兼容 placeholder 空行) */
14
+ export declare function resolveWpFromCursor(doc: Doc): Wp | undefined;
4
15
  /**
16
+ * 计算选区的行级信息(scopedSelectedLines、tableMode、rangeWidgetIds 等)。
5
17
  *
6
- * @param doc
7
- * @param selection
8
- * @param upgrade 单元格是否升级成单个单元格选中
9
- * @returns
18
+ * 过滤规则:
19
+ * - anchor 在嵌套表格内 → 严格夹紧在该嵌套表,不纳入外部行/段落
20
+ * - 其他情况 → 纳入所有顶层表格行 + 所有段落
21
+ *
22
+ * tableMode 决定策略:
23
+ * - mixed → 多张顶层表 OR (表格行 + 段落) → 选整行;段落单独生成 rect
24
+ * - cell-range → 单张表、多行或跨列
25
+ * - cell-inner → 单张表、单行、同一列(单格内文字选区)
26
+ * - cell-full → cell-inner 升级:选中整格(isCellUpgrade)
27
+ * - none → 纯段落 / 空
28
+ *
29
+ * @param upgrade 鼠标在 cellHitPoint 角上,允许 cell-inner → cell-full 升级
10
30
  */
11
31
  export declare function getSelectLinesInfo(doc: Doc, selection: ISelectionRange, upgrade: boolean): {
12
32
  normalized: import('../types/cursor').INormalizedRange;
@@ -16,8 +36,13 @@ export declare function getSelectLinesInfo(doc: Doc, selection: ISelectionRange,
16
36
  startPageIdx: number;
17
37
  endPageIdx: number;
18
38
  selectedLines: LineInfo[];
19
- tableMode: TableSelectionMode;
39
+ tableMode: "none" | "mixed" | "cell-range" | "cell-full" | "cell-inner";
20
40
  overlapIds: string[];
21
41
  widgetRunMap: Map<string, BaseMetaNode[]>;
22
42
  rangeWidgetIds: string[];
43
+ selectionTableId: string | undefined;
44
+ anchorCellIndex: number | undefined;
45
+ focusCellIndex: number | undefined;
46
+ /** focus 越界夹紧方向:true=夹末列,false=夹首列,undefined=已有精确值 */
47
+ focusClampToLast: boolean | undefined;
23
48
  } | undefined;
@@ -65,4 +65,4 @@ export type MoveOpts = Pick<KeydownOpts, 'dir' | 'shift' | 'ctrl'>;
65
65
  * 定义了系统中所有需要进行分发/调度的事件类型标识
66
66
  */
67
67
  export type DispatchEventType = 'ime:compositionstart' | 'ime:compositionupdate' | 'ime:compositionend' | 'ime:input' | 'ime:paste' | 'ime:focus' | 'ime:blur' | 'ime:keydown' | 'caret:locate' | 'konva:click' | 'konva:dragstart' | 'konva:dragmove' | 'konva:dragend' | 'konva:contextmenu' | 'inter:str' | 'inter:stc' | 'inter:stall' | 'inter:active' | 'inter:chg-hmid';
68
- export type EventBusType = 'autoScroll:start' | 'autoScroll:move' | 'autoScroll:stop' | 'caret:changed' | 'caret:requestScroll' | 'cursor:change' | 'cursor:changed' | 'tableSelection:change' | 'activeTableId:change' | 'dragHoverId:change' | 'hoverModelId:change' | 'focusModelId:change' | 'panelData:change';
68
+ export type EventBusType = 'autoScroll:start' | 'autoScroll:move' | 'autoScroll:stop' | 'caret:changed' | 'caret:requestScroll' | 'cursor:change' | 'cursor:changed' | 'tableSelection:change' | 'activeTableId:change' | 'activeTableScope:change' | 'dragHoverId:change' | 'hoverModelId:change' | 'focusModelId:change' | 'panelData:change';
@@ -29,7 +29,7 @@ export type { WrPageWidget } from './model/document';
29
29
  export type { Border, Paragraph } from './view/Paragraph';
30
30
  export type { OverlayLayout } from './view/base/OverlayLayout';
31
31
  export type { Table } from './view/Table';
32
- export type { SubRenderer } from './view/TableCell';
32
+ export type { SubRenderer, TableCellContent } from './view/TableCell';
33
33
  export type { Wtbl } from './model/document';
34
34
  export type { BoundedRegion, CheckTableRegion, _2DTableRegion } from './model/logic';
35
35
  export type { WidgetStateContext } from './widget/state';
@@ -1,6 +1,7 @@
1
1
  import { ActivePanelData, PanelType } from '../../domain/active/active-types';
2
2
  import { Doc } from '../view/Doc';
3
3
  import { ContextMenuParams } from '../../runtime/canvas/__common__/context-menu/index.type';
4
+ import { ActiveTableScopeState } from './types';
4
5
  export declare class InteractionController {
5
6
  doc: Doc;
6
7
  constructor(doc: Doc);
@@ -16,10 +17,20 @@ export declare class InteractionController {
16
17
  onSelectTableAll(payload: {
17
18
  id: string;
18
19
  }): void;
20
+ /**
21
+ * 根据行/列范围设置 cursor selection,驱动 cellRangeIds 内容层高亮。
22
+ *
23
+ * @param tableId 目标表格 layout ID
24
+ * @param options.rowRange [startRowIdx, endRowIdx](默认全表)
25
+ * @param options.colRange [startColIdx, endColIdx](默认全列)
26
+ */
27
+ private _setTableCursorSelection;
19
28
  clearTableSelection(): void;
20
29
  onChangeDragHoverId(hitId: string): void;
21
30
  onSetActiveTableId(tableId: string): void;
31
+ onSetActiveTableScope(scope: ActiveTableScopeState): void;
22
32
  clearActiveTableId(): void;
33
+ clearActiveTableScope(): void;
23
34
  /** 解析字段批注 key */
24
35
  private resolveFieldCommentKey;
25
36
  /**
@@ -1,16 +1,24 @@
1
1
  import { ActivePanelData } from '../../domain/active/active-types';
2
2
  import { AttachFieldTarget } from '../../domain/field/attach-field';
3
+ import { TableScope } from '../model/document/Wtbl';
3
4
  export type ITableSelection = {
4
5
  tableId: string;
5
6
  axis: 'row' | 'col' | 'all';
6
7
  index: number;
7
8
  realRowIndex?: number;
8
9
  } | null;
10
+ export type ActiveTableScopeState = Pick<TableScope, 'depth'> & {
11
+ wtblId: string;
12
+ rootWtblId: string;
13
+ hostCellId?: string;
14
+ };
9
15
  export type InteractionState = {
10
16
  /** 表格选择(行 / 列 / 全选) */
11
17
  tableSelection: ITableSelection | null;
12
18
  /** 当前激活表格 id(仅用于 table overlay 显示) */
13
19
  activeTableId: string;
20
+ /** 当前激活表格作用域(内外表隔离) */
21
+ activeTableScope: ActiveTableScopeState | null;
14
22
  /** 拖拽的id 用来进行处理单个单元格选中 */
15
23
  dragHoverId: string;
16
24
  /** hover 模型的模型 id */
@@ -8,6 +8,12 @@ export declare function useInteraction(docRef: Ref<Doc | null>): {
8
8
  readonly realRowIndex?: number | undefined;
9
9
  } | null | undefined;
10
10
  readonly activeTableId?: string | undefined;
11
+ readonly activeTableScope?: {
12
+ readonly depth: number;
13
+ readonly wtblId: string;
14
+ readonly rootWtblId: string;
15
+ readonly hostCellId?: string | undefined;
16
+ } | null | undefined;
11
17
  readonly dragHoverId?: string | undefined;
12
18
  readonly hoverModelId?: string | undefined;
13
19
  readonly focusModelId?: string | undefined;
@@ -25,7 +25,11 @@ export declare class LayoutManager {
25
25
  */
26
26
  private layoutTable;
27
27
  /**
28
- * 布局单元格内容
28
+ * 构建表格 layout 节点(不含分页)
29
+ */
30
+ private buildTableLayout;
31
+ /**
32
+ * 布局单元格内容(段落 + 嵌套表 block 混排)
29
33
  */
30
34
  private layoutCellContent;
31
35
  /**
@@ -1,4 +1,4 @@
1
- import { Wtbl, Wtc, Wtr } from '../../model/document';
1
+ import { Wtbl, Wtc, Wtr, Wp } from '../../model/document';
2
2
  import { TableExpander, CellFragment } from '../table/table-expand';
3
3
  import { SubRenderer } from '../../view/TableCell';
4
4
  export declare class TableInfoProvider {
@@ -10,7 +10,7 @@ export declare class TableInfoProvider {
10
10
  expandFromId: string;
11
11
  cells: CellFragment[];
12
12
  }[];
13
- getCellContent(cell: any): any[];
13
+ getCellContent(cell: CellFragment): Array<Wp | Wtbl>;
14
14
  getRowModelRef(row: any): {
15
15
  id: string;
16
16
  };
@@ -21,6 +21,16 @@ import { Table } from '../../view/Table';
21
21
  * 当前页: Row 0 原样 + Row 1 上半部分
22
22
  * 下一页: 新建 Cell A_next + Row 1 下半部分引用新源单元格
23
23
  */
24
+ /**
25
+ * 行内切分最小顶部剩余高度(像素)
26
+ *
27
+ * 仅约束「留在当前页的上半截」不能过薄:remainHeight < 此值时整行下移。
28
+ * 不再用几何 bottomHeight(rowH - remain)否决切分——那只是切分前的余量,
29
+ * 真正高度由 fillCells + redistribute 按内容重算;用它拦切分会导致
30
+ * 「差几像素超页却整行跳页」的悬崖效应。
31
+ */
32
+ declare const MIN_SPLIT_REMAINING_HEIGHT = 20;
33
+ export { MIN_SPLIT_REMAINING_HEIGHT };
24
34
  export declare class TableSplitter {
25
35
  private readonly table;
26
36
  private readonly maxHeight;
@@ -50,6 +50,8 @@ export interface LineInfo {
50
50
  /** 当前行的绝对位置 - 下边 */
51
51
  lineBottom: number;
52
52
  }>;
53
+ /** 所属表格的 layout id(仅 tablerow 类型有值) */
54
+ tableId?: string;
53
55
  }
54
56
  export interface Bounds {
55
57
  left: number;
@@ -26,6 +26,10 @@ export declare class Wbody extends ModelGroup<Child> {
26
26
  * @returns Wbody 实例
27
27
  */
28
28
  static fromXmlJson(json: RawElement): Wbody;
29
+ /**
30
+ * 规范化:确保 body 中每个 Wtbl 前后都紧跟一个 Wp。
31
+ */
32
+ ensureParagraphsAroundTables(): void;
29
33
  /**
30
34
  * 实例转换为原始 XML JSON
31
35
  *
@@ -4,6 +4,10 @@ import { Wtbl } from '../Wtbl';
4
4
  * 提供插入和删除行列的功能
5
5
  */
6
6
  export declare class WtblRowColumnOps {
7
+ /** 外表删除前,显式移除受影响单元格中的嵌套表,避免孤儿节点残留 */
8
+ private static detachNestedTablesFromCells;
9
+ /** 仅外表需要做「删除行/列/表时联动删除嵌套表」 */
10
+ private static detachNestedTablesFromOuterTable;
7
11
  /**
8
12
  * 新单元格同步引用信息
9
13
  * refCell: 参考单元格 (above | left)
@@ -55,6 +59,11 @@ export declare class WtblRowColumnOps {
55
59
  * 如果有右侧列,右侧列会相应调整以保持表格总宽度不变
56
60
  */
57
61
  static resizeCol(table: Wtbl, colIndex: number, width: number): void;
62
+ /**
63
+ * 从其他列借宽度给指定列跨度,保持表格总宽不变。
64
+ * 优先借右侧列,再借左侧;被借列不低于 minWidth。
65
+ */
66
+ static stealWidthToColumn(table: Wtbl, startCol: number, colSpan: number, extra: number, minWidth?: number): number;
58
67
  /**
59
68
  * 调整行高
60
69
  */
@@ -1,16 +1,41 @@
1
1
  import { RawElement } from '../../types/raw';
2
+ import { ModelNode } from '../../base';
2
3
  import { Wtr } from '../Wtr';
3
4
  import { Wtbl } from '../Wtbl';
4
5
  import { Wtc } from '../Wtc';
6
+ /** Wtc.fromXmlJson / Wtr.fromXmlJson 解析单元格内容时的上下文 */
7
+ export type WtcParseOptions = {
8
+ hostTableDepth: 0 | 1;
9
+ rootTableId: string;
10
+ grandchildWarned: {
11
+ value: number;
12
+ };
13
+ parseNestedTable: (json: RawElement) => ModelNode;
14
+ onGrandchildIgnored?: () => void;
15
+ };
16
+ /** WtblSerialization.fromXmlJson 解析上下文 */
17
+ export type WtblParseContext = {
18
+ depth: 0 | 1;
19
+ rootTableId?: string;
20
+ hostCellId?: string;
21
+ grandchildWarned?: {
22
+ value: number;
23
+ };
24
+ };
5
25
  /**
6
26
  * 表格序列化功能类
7
27
  * 提供 XML 转换、快照序列化等功能
8
28
  */
9
29
  export declare class WtblSerialization {
30
+ static resetImportGrandchildWarning(): void;
31
+ static consumeImportGrandchildWarning(): number;
32
+ static markGrandchildTableIgnored(warnedRef?: {
33
+ value: number;
34
+ }): void;
10
35
  /**
11
36
  * 从 XML JSON 创建表格实例
12
37
  */
13
- static fromXmlJson(json: RawElement): Wtbl;
38
+ static fromXmlJson(json: RawElement, context?: WtblParseContext): Wtbl;
14
39
  /**
15
40
  * 将表格实例转换为 XML JSON
16
41
  */
@@ -1,18 +1,32 @@
1
1
  import { RawElement } from '../types/raw';
2
2
  import { Wbody } from './Wbody';
3
- import { Wtr } from './Wtr';
4
3
  import { Wtc } from './Wtc';
4
+ import { Wtr } from './Wtr';
5
5
  import { ModelGroup, ModelGroupOptions } from '../base';
6
6
  import { TableRegion, BoundedRegionOptions, CheckTableRegionOptions, RepeatingRegionOptions, _2DTableRegionOptions, TableHeaderRegion, SubTableHeaderRegion, TableHeaderRegionOptions, SubTableHeaderRegionOptions, CheckTableRegion, MaterialConsumeTableRegion, MaterialConsumeTableRegionOptions, BoundedRegion, RepeatingRegion, _2DTableRegion } from '../logic';
7
+ import { WtblParseContext } from './Wtbl/Serialization';
7
8
  import { WtblPr } from './WtblPr';
9
+ /** 当前操作归属的表格作用域 */
10
+ export type TableScope = {
11
+ wtbl: Wtbl;
12
+ depth: number;
13
+ hostCell?: Wtc;
14
+ rootWtbl: Wtbl;
15
+ };
8
16
  export declare class Wtbl extends ModelGroup {
9
17
  name: 'w:tbl';
10
18
  type: "element";
11
19
  tblPr?: WtblPr;
12
20
  colWidths?: number[];
13
21
  regions: TableRegion[];
14
- parent?: Wbody;
22
+ parent?: Wbody | Wtc;
15
23
  children: Wtr[];
24
+ /** 嵌套表宿主单元格 id */
25
+ nestedInCellId?: string;
26
+ /** 最外层 Wtbl.id */
27
+ rootTableId?: string;
28
+ /** 嵌套深度:0(外表)或 1(嵌套表) */
29
+ depth: 0 | 1;
16
30
  private pendingRecalculate;
17
31
  private mutationDepth;
18
32
  private mutationNeedsRecalculate;
@@ -36,6 +50,17 @@ export declare class Wtbl extends ModelGroup {
36
50
  get checkTable(): CheckTableRegion[];
37
51
  getCheckTableById(id: string): CheckTableRegion | undefined;
38
52
  get hasCheckTable(): boolean;
53
+ /** 是否已标为业务表 / 数据表 */
54
+ get isBusinessOrDataTable(): boolean;
55
+ /** 沿 parent 链找到最外层 Wtbl */
56
+ getRootTable(): Wtbl;
57
+ getTableScope(): TableScope;
58
+ /** 收集本表单元格内的物理嵌套表 */
59
+ collectNestedTables(): Wtbl[];
60
+ /** 本表内是否存在已标业务/数据区的嵌套表 */
61
+ hasNestedBusinessOrDataTable(): boolean;
62
+ /** 作为物理嵌套表挂到宿主单元格 */
63
+ attachAsNested(hostCell: Wtc): void;
39
64
  get tableHeader(): Array<TableHeaderRegion | SubTableHeaderRegion>;
40
65
  getTableHeaderById(id: string): TableHeaderRegion | SubTableHeaderRegion | undefined;
41
66
  /**
@@ -49,7 +74,9 @@ export declare class Wtbl extends ModelGroup {
49
74
  syncRefs?: () => void;
50
75
  finalize?: () => void;
51
76
  }): void;
52
- static fromXmlJson(json: RawElement): Wtbl;
77
+ static fromXmlJson(json: RawElement, context?: WtblParseContext): Wtbl;
78
+ /** 是否为嵌套在单元格内的物理子表 */
79
+ get isNestedTable(): boolean;
53
80
  toXmlJson(): RawElement;
54
81
  /**
55
82
  * 在指定行索引处拆分表格
@@ -102,5 +129,6 @@ export declare class Wtbl extends ModelGroup {
102
129
  deleteColAt(index: number): void;
103
130
  deleteColRange(startIndex: number, endIndex: number): void;
104
131
  resizeCol(colIndex: number, width: number): void;
132
+ stealWidthToColumn(startCol: number, colSpan: number, extra: number, minWidth?: number): number;
105
133
  resizeRow(rowIndex: number, height: number): void;
106
134
  }
@@ -1,8 +1,9 @@
1
1
  import { RawElement } from '../types/raw';
2
2
  import { Wtr } from './Wtr';
3
3
  import { Wp } from './Wp';
4
+ import { Wtbl, TableScope } from './Wtbl';
4
5
  import { ModelGroup, ModelGroupOptions } from '../base';
5
- import { Wtbl } from './Wtbl';
6
+ import { WtcParseOptions } from './Wtbl/Serialization';
6
7
  import { SubTableRegionType, SubTableItemType, TableHeaderRegionType, WtcHeaderRef, WtcSubTableItemRef, WtcSubTableRef } from './wtcRegionRef';
7
8
  /** 单元格上需随行列复制同步的引用字段 */
8
9
  export declare const WTC_REF_KEYS: readonly ["mergeId", "subTable", "subTableItem", "header"];
@@ -46,6 +47,15 @@ export declare class Wtc extends ModelGroup {
46
47
  /** 是否是合并起始单元格 */
47
48
  get isMergeStart(): boolean;
48
49
  get contents(): Wp[];
50
+ getParagraphs(): Wp[];
51
+ getNestedTables(): Wtbl[];
52
+ getTableScope(): TableScope;
53
+ /** 单元格内容区宽度(DXA),用于嵌套表初始列宽(已扣除左右 padding) */
54
+ getContentWidthDxa(): number;
55
+ /** 是否允许在本单元格插入物理嵌套表 */
56
+ canInsertNestedTable(): boolean;
57
+ /** 在 block 子节点序列中插入嵌套表(纵向堆叠) */
58
+ insertNestedTableAt(index: number, wtbl: Wtbl): void;
49
59
  /** 单元格垂直对齐(w:tcPr/w:vAlign) */
50
60
  get vAlign(): 'top' | 'center' | 'bottom' | undefined;
51
61
  get firstContent(): Wp | undefined;
@@ -100,7 +110,7 @@ export declare class Wtc extends ModelGroup {
100
110
  /**
101
111
  * 从 XML JSON 创建单元格(返回数组,因为 colspan 会产生多个单元格)
102
112
  */
103
- static fromXmlJson(tcRaw: RawElement): Wtc[];
113
+ static fromXmlJson(tcRaw: RawElement, cellParseOptions?: WtcParseOptions): Wtc[];
104
114
  /**
105
115
  * 转换为 XML JSON
106
116
  * 结构:w:tc
@@ -109,6 +119,7 @@ export declare class Wtc extends ModelGroup {
109
119
  */
110
120
  toXmlJson(): RawElement | null;
111
121
  private buildTcPr;
122
+ private static parseNestedTableFromXml;
112
123
  private static normalizeWordColor;
113
124
  /**
114
125
  * 从模板创建单元格
@@ -1,6 +1,7 @@
1
1
  import { RawElement } from '../types/raw';
2
2
  import { Wtbl } from './Wtbl';
3
3
  import { Wtc } from './Wtc';
4
+ import { WtcParseOptions } from './Wtbl/Serialization';
4
5
  import { ModelGroup, ModelGroupOptions } from '../base';
5
6
  import { WtrPr, WtrHeightRule } from './WtrPr';
6
7
  type RowHeightRule = WtrHeightRule;
@@ -28,7 +29,7 @@ export declare class Wtr extends ModelGroup {
28
29
  /**
29
30
  * 从 XML JSON 创建表格行
30
31
  */
31
- static fromXmlJson(trRaw: RawElement): Wtr;
32
+ static fromXmlJson(trRaw: RawElement, cellParseOptions?: WtcParseOptions): Wtr;
32
33
  /**
33
34
  * 转换为 XML JSON
34
35
  * 结构:w:tr
@@ -8,6 +8,7 @@ export { WrImage } from './WrImage';
8
8
  export { WrField } from './WrField';
9
9
  export { WrPageWidget } from './WrPageWidget';
10
10
  export { Wtbl } from './Wtbl';
11
+ export type { TableScope } from './Wtbl';
11
12
  export { Wtr } from './Wtr';
12
13
  export { Wtc } from './Wtc';
13
14
  export { WsecPr } from './WsecPr';
@@ -0,0 +1,18 @@
1
+ import { Wtbl } from '../Wtbl';
2
+ import { ModelGroup } from '../../base';
3
+ type EnsureGroup = Pick<ModelGroup<any>, 'children' | 'insertBefore' | 'insertAfter'>;
4
+ /**
5
+ * 在数组中为每个表格补齐前后段落(就地修改,倒序遍历)。
6
+ * 适用于 fromXmlJson 等尚未挂到 ModelGroup 的构建阶段。
7
+ */
8
+ export declare function ensureParagraphsAroundTablesInList<T>(children: T[], isTable: (item: T | undefined) => boolean, isParagraph: (item: T | undefined) => boolean, createParagraph: () => T): void;
9
+ /** Wp / Wtbl 列表的便捷封装 */
10
+ export declare function ensureWpAroundWtblInList(children: unknown[]): void;
11
+ /**
12
+ * 确保单个表格在 ModelGroup 中前后都紧跟段落。
13
+ * 插入表格后调用即可(body / 单元格共用)。
14
+ */
15
+ export declare function ensureParagraphsAroundTable(group: EnsureGroup, table: Wtbl): void;
16
+ /** 确保 group 内每个表格前后都有段落 */
17
+ export declare function ensureParagraphsAroundAllTables(group: EnsureGroup): void;
18
+ export {};
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * 表格单元格模板 - TypeScript 版本
3
3
  * 保留变量占位符位置:{{width}}, {{paraId}}
4
+ *
5
+ * 单元格 block 子节点可为 w:p(段落)与 w:tbl(物理嵌套表)混合排列,仅纵向堆叠。
4
6
  */
5
7
  export declare const TABLE_CELL_TEMPLATE: {
6
8
  name: string;
@@ -3,14 +3,18 @@ import { TableRow } from './TableRow';
3
3
  import { Border } from './types';
4
4
  import { EventUtil } from './utils/EventUtil';
5
5
  import { TableCell } from './TableCell';
6
+ import { WtblPr } from '../model/document/WtblPr';
6
7
  export interface TableOptions extends LayoutGroupOptions {
7
8
  colWidths?: number[];
9
+ tblPr?: WtblPr;
8
10
  }
9
11
  export declare class Table extends LayoutGroup<TableRow> {
10
12
  type: 'table';
11
13
  component: "table";
12
14
  cellPadding: [number, number, number, number];
13
15
  colWidths?: number[];
16
+ /** 表格属性 */
17
+ tblPr?: WtblPr;
14
18
  /** redistribute 完成事件 */
15
19
  redistributeEvent: EventUtil;
16
20
  /** 表格边框 */
@@ -21,6 +25,15 @@ export declare class Table extends LayoutGroup<TableRow> {
21
25
  get width(): number;
22
26
  redistribute(): void;
23
27
  layout(x: number, y: number): void;
28
+ /**
29
+ * 相对正文区左边缘的水平偏移
30
+ * 对应 w:jc / w:tblInd;居中或右对齐且表格宽于正文区时可为负值
31
+ */
32
+ private resolveOffsetX;
33
+ /** 嵌套在单元格内的表格不使用页面级对齐 */
34
+ private isNestedInCell;
35
+ private getTableJc;
36
+ private getTblIndPx;
24
37
  updateCellOffsetInfo(): void;
25
38
  forEachCell(options: {
26
39
  startRowIdx: number;
@@ -27,7 +27,8 @@ export type SubRenderer = {
27
27
  /** 用来标记二维表的子类型 交叉 / 横向 / 纵向 */
28
28
  cellZone?: LinkSubTableCellZone;
29
29
  };
30
- export declare class TableCell extends LayoutGroup<Paragraph> implements IContainerMetrics {
30
+ export type TableCellContent = Paragraph | Table;
31
+ export declare class TableCell extends LayoutGroup<TableCellContent> implements IContainerMetrics {
31
32
  component: "tableCell";
32
33
  colspan: number;
33
34
  rowspan: number;
@@ -0,0 +1,31 @@
1
+ import { Wtbl, Wtc } from '../../../core/model/document';
2
+ import { TableCellSelectionBounds } from './validate-table-selection';
3
+ export type NestedTableMutexReason = 'cell-has-nested' | 'outer-has-region';
4
+ /**
5
+ * 业务表/数据表互斥校验(内外表)
6
+ *
7
+ * 规则 3:内表已标业务/数据区 → 外表该单元格不支持再标(被规则 4 涵盖)
8
+ * 规则 4:外表选中单元格含有内表 → 不支持标为业务/数据表
9
+ * 内表视角:外层宿主单元格已被外表标为业务/数据区 → 内表不支持再标
10
+ *
11
+ * @param table 当前操作的表格(外表或内表)
12
+ * @param bounds 当前光标选区对应的单元格范围(来自 resolveTableCellSelectionBounds)
13
+ */
14
+ export declare function validateNestedTableRegionMutex(table: Wtbl, bounds?: TableCellSelectionBounds | null): {
15
+ ok: boolean;
16
+ existingLabel?: string;
17
+ reason?: NestedTableMutexReason;
18
+ };
19
+ export declare function getNestedTableRegionMutexMessage(reason?: NestedTableMutexReason, existingLabel?: string): string;
20
+ /**
21
+ * 校验互斥并弹出警告。返回 true 表示可以继续标记。
22
+ */
23
+ export declare function assertNestedTableRegionMutex(table: Wtbl, bounds?: TableCellSelectionBounds | null): boolean;
24
+ /**
25
+ * 设置子表前的综合校验(嵌套互斥 + 同一行唯一子表)
26
+ */
27
+ export declare function assertSubTableRegionPlacement(table: Wtbl, bounds?: TableCellSelectionBounds | null): boolean;
28
+ /**
29
+ * 从起止单元格构造互斥校验所需的 bounds。
30
+ */
31
+ export declare function buildBoundsFromCellRange(startCell: Wtc, endCell: Wtc): TableCellSelectionBounds | null;
@@ -18,6 +18,14 @@ export type ValidateTableSelectionOptions = {
18
18
  /** 与这些类型区域重叠时不视为非法 */
19
19
  ignoreOverlapTypes?: string[];
20
20
  };
21
+ /**
22
+ * 同一行并排多个子表(列不重叠)时,布局展开只保留后设 region,需提前拦截。
23
+ * 若选区与已有 region 重叠,交由 findCrossRegion 处理,此处返回 undefined。
24
+ */
25
+ export declare function findSameRowSubTableConflict(table: Wtbl, bounds: TableCellSelectionBounds): TableRegion | undefined;
26
+ export declare function getSameRowSubTableConflictMessage(existing?: TableRegion): string;
27
+ /** 校验通过返回 true;冲突时弹出提示并返回 false */
28
+ export declare function assertSameRowSubTableAllowed(table: Wtbl, bounds: TableCellSelectionBounds): boolean;
21
29
  /** 解析已有逻辑区域的展示名称 */
22
30
  export declare function resolveTableRegionLabel(region: TableRegion): string;
23
31
  /** 从当前光标选区解析表格单元格范围 */
@@ -14,3 +14,4 @@ export * from './design/hooks/on-subtable-create';
14
14
  export * from './design/hooks/on-field-attach';
15
15
  export * from './design/hooks/on-repeating-default-props';
16
16
  export * from './design/validate-table-selection';
17
+ export * from './design/validate-nested-table-region';