@hufe921/canvas-editor 1.0.3 → 1.0.5

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.
@@ -5,6 +5,7 @@ import { IMarkElementListDeletedOption } from '../../interface/Trace';
5
5
  import { IRow } from '../../interface/Row';
6
6
  import { IColumnLayout, IColumnOption } from '../../interface/Column';
7
7
  import { ColumnManager } from './column/ColumnManager';
8
+ import { IncrementalRowComputer } from './IncrementalRowComputer';
8
9
  import { Cursor } from '../cursor/Cursor';
9
10
  import { CanvasEvent } from '../event/CanvasEvent';
10
11
  import { GlobalEvent } from '../event/GlobalEvent';
@@ -131,6 +132,9 @@ export declare class Draw {
131
132
  private LETTER_REG;
132
133
  private WORD_LIKE_REG;
133
134
  private rowList;
135
+ private rawRowList;
136
+ private incrementalRowComputer;
137
+ private isElementListTruncated;
134
138
  private pageRowList;
135
139
  private pageDirectionList;
136
140
  private painterStyle;
@@ -232,12 +236,18 @@ export declare class Draw {
232
236
  getTableElementList(sourceElementList: IElement[]): IElement[];
233
237
  getElementList(): IElement[];
234
238
  getMainElementList(): IElement[];
239
+ getRawRowList(): IRow[];
240
+ getIncrementalRowComputer(): IncrementalRowComputer;
241
+ getIsElementListTruncated(): boolean;
242
+ getIsControlMinWidthPlaceholder(): boolean;
235
243
  getOriginalElementList(): IElement[];
236
244
  getOriginalMainElementList(): IElement[];
237
245
  getFooterElementList(): IElement[];
238
246
  getTd(): ITd | null;
239
247
  insertElementList(payload: IElement[], options?: IInsertElementListOption): void;
240
248
  appendElementList(elementList: IElement[], options?: IAppendElementListOption): void;
249
+ setElementProperty(elementList: IElement | IElement[], properties: Partial<IElement>): void;
250
+ deleteElementProperty(elementList: IElement | IElement[], keys: (keyof IElement)[]): void;
241
251
  spliceElementList(elementList: IElement[], start: number, deleteCount: number, items?: IElement[], options?: ISpliceElementListOption): void;
242
252
  getCanvasEvent(): CanvasEvent;
243
253
  getGlobalEvent(): GlobalEvent;
@@ -0,0 +1,43 @@
1
+ import type { IComputeRange, IComputeRowListPayload, IIncrementalRowListResult } from '../../interface/Draw';
2
+ import type { IElement } from '../../interface/Element';
3
+ import type { IRow, IRowComputeState } from '../../interface/Row';
4
+ import type { Draw } from './Draw';
5
+ /**
6
+ * 行级增量行计算器。
7
+ *
8
+ * 行边界是断行依赖链的重置点(行首 x 由容器状态决定),因此编辑只需从受影响行
9
+ * 断点续算,与某个旧行结构状态收敛即停(通常 1~3 行),其后旧行原样复用。
10
+ * y/pageNo 等位置状态不影响行内容,过期快照依然安全。
11
+ *
12
+ * 门控不满足时返回 null,调用方退回全量,行为与未开启时一致。
13
+ */
14
+ export declare class IncrementalRowComputer {
15
+ private draw;
16
+ private readonly snapshotMap;
17
+ private lastLayoutSignature;
18
+ private dirtyElementList;
19
+ private dirtyStartIndex;
20
+ private dirtyEndIndex;
21
+ private isLayoutDirty;
22
+ constructor(draw: Draw);
23
+ recordSnapshot(row: IRow, snapshot: IRowComputeState, firstElement?: IElement): void;
24
+ /**
25
+ * 记录主文档元素列表的一次修改区间(脏区间,增量续算提示)。
26
+ * splice/delete 助手自动记录;少数直接 splice 的场景需显式调用。
27
+ */
28
+ markRangeDirty(elementList: IElement[], start: number, deleteCount: number, insertCount: number): void;
29
+ markFullDirty(): void;
30
+ consumeDirtyRange(): IComputeRange | undefined;
31
+ findPageNoOfRow(row: IRow): number | undefined;
32
+ /**
33
+ * 尝试增量计算。成功返回合并后的行列表与首个变动行
34
+ * (拆分跨页表格前的原始行列表),失败返回 null(调用方走全量)。
35
+ */
36
+ tryCompute(range: IComputeRange | undefined, payload: IComputeRowListPayload): IIncrementalRowListResult | null;
37
+ observeLayout(): void;
38
+ private getLayoutSignature;
39
+ private _findRowIndexOfElement;
40
+ private _isComplexElement;
41
+ private _isStructuralEqual;
42
+ private static readonly MAX_CASCADE_ELEMENT;
43
+ }
@@ -70,6 +70,7 @@ export declare class DatePicker {
70
70
  private _updateMonthView;
71
71
  private _switchView;
72
72
  private _toggleDateTimePicker;
73
+ private _createDate;
73
74
  private _setDatePick;
74
75
  private _setTimePick;
75
76
  private _preMonth;
@@ -1,4 +1,4 @@
1
- import { IComputePageRowPositionPayload, IComputePageRowPositionResult, IComputeRowPositionPayload, IFloatPosition, IGetFloatPositionByXYPayload, ISetSurroundPositionPayload } from '../../interface/Position';
1
+ import { IComputePageRowPositionPayload, IComputePageRowPositionResult, IComputePositionListPayload, IComputeRowPositionPayload, IFloatPosition, IGetFloatPositionByXYPayload, ISetSurroundPositionPayload } from '../../interface/Position';
2
2
  import { IElement, IElementPosition } from '../../interface/Element';
3
3
  import { ITd } from '../../interface/table/Td';
4
4
  import { ICurrentPosition, IGetPositionByXYPayload, IPositionContext } from '../../interface/Position';
@@ -10,6 +10,7 @@ export declare class Position {
10
10
  private tablePagingPositionList;
11
11
  private tablePagingPositionMap;
12
12
  private floatPositionList;
13
+ private pagePositionCacheList;
13
14
  private draw;
14
15
  private eventBus;
15
16
  private options;
@@ -37,7 +38,7 @@ export declare class Position {
37
38
  };
38
39
  computePageRowPosition(payload: IComputePageRowPositionPayload): IComputePageRowPositionResult;
39
40
  private _offsetTdPositionByVerticalAlign;
40
- computePositionList(): void;
41
+ computePositionList(payload?: IComputePositionListPayload): void;
41
42
  computeRowPosition(payload: IComputeRowPositionPayload): IElementPosition[];
42
43
  setCursorPosition(position: IElementPosition | null): void;
43
44
  getCursorPosition(): IElementPosition | null;
@@ -77,6 +77,10 @@ export interface IControlBasic {
77
77
  cascade?: IControlCascadeRule[];
78
78
  validation?: IControlValidation;
79
79
  compute?: string;
80
+ activeBackgroundColor?: string;
81
+ disabledBackgroundColor?: string;
82
+ existValueBackgroundColor?: string;
83
+ noValueBackgroundColor?: string;
80
84
  }
81
85
  export interface IControlStyle {
82
86
  font?: string;
@@ -1,7 +1,7 @@
1
1
  import { ImageDisplay } from '../dataset/enum/Common';
2
2
  import { EditorMode, EditorZone } from '../dataset/enum/Editor';
3
3
  import { IElement, IElementPosition } from './Element';
4
- import { IRow } from './Row';
4
+ import { IRow, IRowComputeState, IRowElement } from './Row';
5
5
  export interface IDrawOption {
6
6
  curIndex?: number;
7
7
  isSetCursor?: boolean;
@@ -12,6 +12,10 @@ export interface IDrawOption {
12
12
  isSourceHistory?: boolean;
13
13
  isFirstRender?: boolean;
14
14
  }
15
+ export interface IComputeRange {
16
+ startIndex: number;
17
+ endIndex: number;
18
+ }
15
19
  export interface IForceUpdateOption {
16
20
  isSubmitHistory?: boolean;
17
21
  }
@@ -72,4 +76,21 @@ export interface IComputeRowListPayload {
72
76
  isPagingMode?: boolean;
73
77
  pageHeight?: number;
74
78
  surroundElementList?: IElement[];
79
+ /**
80
+ * 断点续算:从 state 对应的行首元素(startIndex)重新参与断行,
81
+ * 到与某个旧行状态收敛(converge 返回 true)或文档末尾即止,
82
+ * 收敛点之后的旧行对象可原样复用。
83
+ */
84
+ resume?: IComputeRowListResume;
85
+ }
86
+ export interface IComputeRowListResume {
87
+ startIndex: number;
88
+ state: IRowComputeState;
89
+ preRowLastElement?: IRowElement;
90
+ shouldAbort?: (element: IElement, index: number) => boolean;
91
+ converge?: (state: IRowComputeState, firstElement: IElement, startIndex: number) => boolean;
92
+ }
93
+ export interface IIncrementalRowListResult {
94
+ rowList: IRow[];
95
+ firstChangedRow: IRow;
75
96
  }
@@ -34,6 +34,14 @@ import { ITraceOption } from './Trace';
34
34
  import { IRulerOption } from './Ruler';
35
35
  import { IHintOption } from './Hint';
36
36
  import type { ISpellcheckOption } from './Spellcheck';
37
+ export interface ILabOption {
38
+ /**
39
+ * 行级增量行计算:编辑时仅从受影响行断点续算,区间外行复用。
40
+ * 复杂结构(表格/控件/浮动图/分栏/minWidth 控件占位等)自动退化全量。
41
+ * 默认:false
42
+ */
43
+ incrementalCompute?: boolean;
44
+ }
37
45
  export interface IEditorData {
38
46
  header?: IElement[];
39
47
  main: IElement[];
@@ -86,6 +94,7 @@ export interface IEditorOption {
86
94
  scrollContainerSelector?: string;
87
95
  pageOuterSelectionDisable?: boolean;
88
96
  wordBreak?: WordBreak;
97
+ lab?: ILabOption;
89
98
  table?: ITableOption;
90
99
  header?: IHeader;
91
100
  footer?: IFooter;
@@ -88,6 +88,9 @@ export interface IComputePageRowPositionResult {
88
88
  y: number;
89
89
  index: number;
90
90
  }
91
+ export interface IComputePositionListPayload {
92
+ fromPageNo?: number;
93
+ }
91
94
  export interface IFloatPosition {
92
95
  pageNo: number;
93
96
  element: IElement;
@@ -1,6 +1,7 @@
1
1
  import { PaperDirection } from '../dataset/enum/Editor';
2
2
  import { RowFlex } from '../dataset/enum/Row';
3
3
  import { IElement, IElementMetrics, IElementPosition, ITableRowFragment } from './Element';
4
+ import { IMargin } from './Margin';
4
5
  import { ITd } from './table/Td';
5
6
  export type IRowElement = IElement & {
6
7
  metrics: IElementMetrics;
@@ -31,3 +32,18 @@ export interface IRow {
31
32
  positionList: IElementPosition[];
32
33
  }[];
33
34
  }
35
+ export interface IRowComputeState {
36
+ rowIndex: number;
37
+ x: number;
38
+ y: number;
39
+ pageNo: number;
40
+ pageStartY: number;
41
+ direction: PaperDirection;
42
+ margins: IMargin;
43
+ innerWidth: number;
44
+ startX: number;
45
+ pageHeight: number;
46
+ column: number;
47
+ controlRealWidth: number;
48
+ listIndexMap: Map<string, number>;
49
+ }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@hufe921/canvas-editor",
3
3
  "author": "Hufe",
4
4
  "license": "MIT",
5
- "version": "1.0.3",
5
+ "version": "1.0.5",
6
6
  "description": "A Canvas/SVG-based rich text editor",
7
7
  "publishConfig": {
8
8
  "registry": "https://registry.npmjs.org/",
@@ -51,26 +51,26 @@
51
51
  "@eslint/js": "^10.0.1",
52
52
  "@rollup/plugin-typescript": "^12.3.0",
53
53
  "@types/jsdom": "^28.0.3",
54
- "@types/node": "^24.12.4",
54
+ "@types/node": "^24.19.1",
55
55
  "@types/prismjs": "^1.26.6",
56
- "@typescript-eslint/eslint-plugin": "^8.69.0",
57
- "@typescript-eslint/parser": "^8.69.0",
56
+ "@typescript-eslint/eslint-plugin": "^8.71.1",
57
+ "@typescript-eslint/parser": "^8.71.1",
58
58
  "@vitest/coverage-v8": "^4.1.11",
59
59
  "cypress": "^15.21.1",
60
60
  "cypress-file-upload": "^5.0.8",
61
- "eslint": "^10.9.1",
62
- "globals": "^17.12.0",
61
+ "eslint": "^10.12.0",
62
+ "globals": "^17.13.0",
63
63
  "jsdom": "^29.1.1",
64
64
  "simple-git-hooks": "^2.14.0",
65
65
  "tslib": "^2.8.1",
66
66
  "typescript": "^6.0.3",
67
- "typescript-eslint": "^8.69.0",
68
- "vite": "^8.2.2",
67
+ "typescript-eslint": "^8.71.1",
68
+ "vite": "^8.3.3",
69
69
  "vite-plugin-css-injected-by-js": "^5.0.1",
70
70
  "vitepress": "^1.6.4",
71
71
  "vitest": "^4.1.11",
72
- "vitest-canvas-mock": "^1.1.5",
73
- "vue": "^3.5.42"
72
+ "vitest-canvas-mock": "^1.2.0",
73
+ "vue": "^3.5.43"
74
74
  },
75
75
  "simple-git-hooks": {
76
76
  "pre-commit": "npm run lint && npm run type:check",