@gct-paas/word 0.1.22 → 0.1.24

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 (47) hide show
  1. package/dist/capabilities/model-field-runtime/provider/FieldProviderRuntime.d.ts +4 -0
  2. package/dist/capabilities/model-field-runtime/service/FieldService.d.ts +2 -0
  3. package/dist/core/constants/index.d.ts +1 -0
  4. package/dist/core/cursor/types/cursor.d.ts +50 -0
  5. package/dist/core/index.d.ts +2 -0
  6. package/dist/core/layout/LayoutMapper.d.ts +2 -2
  7. package/dist/core/layout/handlers/{ImageHandler.d.ts → InlineImageLayoutHandler.d.ts} +2 -3
  8. package/dist/core/layout/handlers/fields/AttachmentHandler.d.ts +3 -2
  9. package/dist/core/layout/handlers/fields/{BaseHandler.d.ts → FieldBaseHandler.d.ts} +2 -5
  10. package/dist/core/layout/handlers/fields/FieldImageHandler.d.ts +7 -0
  11. package/dist/core/layout/handlers/fields/InputHandler.d.ts +3 -2
  12. package/dist/core/layout/handlers/fields/OptionHandler.d.ts +3 -2
  13. package/dist/core/layout/handlers/fields/SignatureHandler.d.ts +3 -2
  14. package/dist/core/layout/handlers/fields/index.d.ts +1 -2
  15. package/dist/core/layout/handlers/index.d.ts +1 -1
  16. package/dist/core/layout/handlers/pageWidgets/BarcodeHandler.d.ts +2 -2
  17. package/dist/core/layout/handlers/pageWidgets/DefaultHandler.d.ts +2 -2
  18. package/dist/core/layout/handlers/pageWidgets/DiagonalHandler.d.ts +2 -2
  19. package/dist/core/layout/handlers/pageWidgets/LineHandler.d.ts +2 -2
  20. package/dist/core/layout/handlers/pageWidgets/PageWidgetImageHandler.d.ts +5 -0
  21. package/dist/core/layout/handlers/pageWidgets/PaginationHandler.d.ts +2 -2
  22. package/dist/core/layout/handlers/pageWidgets/QrCodeHandler.d.ts +2 -2
  23. package/dist/core/layout/handlers/pageWidgets/SerialNumberHandler.d.ts +2 -2
  24. package/dist/core/layout/handlers/{base/BaseHandler.d.ts → pageWidgets/WidgetBaseHandler.d.ts} +2 -5
  25. package/dist/core/layout/handlers/pageWidgets/index.d.ts +1 -1
  26. package/dist/core/layout/logic/LayoutBuilder.d.ts +1 -1
  27. package/dist/core/layout/types/index.d.ts +23 -6
  28. package/dist/core/model/DocModel.d.ts +13 -1
  29. package/dist/core/model/types/index.d.ts +0 -1
  30. package/dist/core/view/Doc.d.ts +8 -1
  31. package/dist/core/view/base/LayoutNode.d.ts +4 -0
  32. package/dist/core/view/runs/TextRun.d.ts +4 -0
  33. package/dist/core/view/types/index.d.ts +2 -0
  34. package/dist/core/view/types/layout-node-by-component.d.ts +38 -0
  35. package/dist/core/view/utils/TextUtil.d.ts +89 -12
  36. package/dist/index.es.js +2145 -1805
  37. package/dist/runtime/_register_/runtime/SuiteRuntime.d.ts +4 -1
  38. package/dist/runtime/canvas/node/text-character.vue.d.ts +3 -1
  39. package/dist/runtime/interface/render.d.ts +1 -1
  40. package/dist/sdk/engine/index.d.ts +1 -1
  41. package/dist/sdk/types/field-model-query.d.ts +19 -0
  42. package/dist/sdk/types/index.d.ts +13 -0
  43. package/dist/utils/func/core.d.ts +15 -0
  44. package/package.json +1 -1
  45. package/dist/core/layout/handlers/fields/ImageHandler.d.ts +0 -5
  46. package/dist/core/layout/handlers/pageWidgets/ImageHandler.d.ts +0 -4
  47. package/dist/core/model/types/model.d.ts +0 -144
package/dist/index.es.js CHANGED
@@ -20617,6 +20617,20 @@ function getLastSegment(str, separator = ".") {
20617
20617
  const index2 = str.lastIndexOf(separator);
20618
20618
  return index2 === -1 ? str : str.slice(index2 + 1);
20619
20619
  }
20620
+ function parseLinkFieldExpression(str) {
20621
+ if (!str) {
20622
+ return {
20623
+ subFieldKey: "",
20624
+ linkFieldKey: ""
20625
+ };
20626
+ }
20627
+ const normalized = str.replace(/^\$\./, "");
20628
+ const [subFieldKey = "", linkFieldKey = ""] = normalized.split(":");
20629
+ return {
20630
+ subFieldKey,
20631
+ linkFieldKey
20632
+ };
20633
+ }
20620
20634
  function getBeforeBracket(str) {
20621
20635
  const reg = /\$\.[a-z_]+\[[^\]]+\]/i;
20622
20636
  return str.match(reg)?.[0] || "";
@@ -26214,437 +26228,1344 @@ function resolveCharHit(node, base, actualX) {
26214
26228
  side: localX < mid ? "before" : "after"
26215
26229
  };
26216
26230
  }
26217
- const AREA_ORDER = {
26218
- overlay: -1,
26219
- header: 0,
26220
- body: 1,
26221
- footer: 2
26222
- };
26223
- function computeCharOffsetsFromMetrics(metrics) {
26224
- const offsets = [0];
26225
- let acc = 0;
26226
- for (const m of metrics) {
26227
- acc += m.width;
26228
- offsets.push(acc);
26231
+ class LayoutNode {
26232
+ /** 唯一标识符 */
26233
+ id;
26234
+ /** 组件类型 */
26235
+ component;
26236
+ /** 所属文档 */
26237
+ doc;
26238
+ /** 父节点 */
26239
+ parent;
26240
+ /** 在父容器中的相对 X 坐标 */
26241
+ x = 0;
26242
+ /** 在父容器中的相对 Y 坐标 */
26243
+ y = 0;
26244
+ /** 布局后的绝对 X 坐标 */
26245
+ layoutX = 0;
26246
+ /** 布局后的绝对 Y 坐标 */
26247
+ layoutY = 0;
26248
+ modelRef;
26249
+ // valuePath?: string;
26250
+ /** 宽度 */
26251
+ _width = 0;
26252
+ /** 高度 */
26253
+ _height = 0;
26254
+ constructor(options) {
26255
+ this.id = options.id ?? uuid();
26256
+ this.doc = options.doc;
26257
+ if (options.x !== void 0) this.x = options.x;
26258
+ if (options.y !== void 0) this.y = options.y;
26259
+ if (options.width !== void 0) this._width = options.width;
26260
+ if (options.height !== void 0) this._height = options.height;
26261
+ this.modelRef = options.modelRef;
26262
+ this.modelRef && this.doc.layoutMapper.recordModelSplit(this.modelRef?.id, this.id);
26229
26263
  }
26230
- return offsets;
26231
- }
26232
- function buildTextMeta(node) {
26233
- const charMetrics = Array.isArray(node.charMetrics) ? node.charMetrics.slice() : [];
26234
- const charLength = Math.max(0, charMetrics.length);
26235
- return {
26236
- text: node.text ?? "",
26237
- charMetrics,
26238
- charLength,
26239
- charOffsets: charMetrics.length > 0 ? computeCharOffsetsFromMetrics(charMetrics) : void 0
26240
- };
26241
- }
26242
- function buildParagraphMeta(node) {
26243
- return {
26244
- lineTop: node.layoutY,
26245
- lineBottom: node.layoutY + node.height
26246
- };
26247
- }
26248
- function buildPosBox(node) {
26249
- const absLeft = node.layoutX ?? 0;
26250
- const absTop = node.layoutY ?? 0;
26251
- const relLeft = node.x ?? 0;
26252
- const relTop = node.y ?? 0;
26253
- const width = node.mergeFromId ? 0 : node.width ?? 0;
26254
- const height = node.mergeFromId ? 0 : node.height ?? 0;
26255
- return {
26256
- width,
26257
- height,
26258
- absbox: {
26259
- left: absLeft,
26260
- top: absTop,
26261
- right: absLeft + width,
26262
- bottom: absTop + height
26263
- },
26264
- relbox: {
26265
- left: relLeft,
26266
- top: relTop,
26267
- right: relLeft + width,
26268
- bottom: relTop + height
26269
- }
26270
- };
26271
- }
26272
- const lineUtils = {
26273
- resetLineCtx(ctx) {
26274
- ctx.lineId = void 0;
26275
- ctx.lineIndex = -1;
26276
- ctx.lineType = void 0;
26277
- },
26278
- resetTableCtx(ctx) {
26279
- ctx.tableId = void 0;
26280
- lineUtils.restTableRowCtx(ctx);
26281
- lineUtils.restTableCellCtx(ctx);
26282
- },
26283
- restTableRowCtx(ctx) {
26284
- ctx.tableRowId = void 0;
26285
- ctx.tableRowIndex = void 0;
26286
- ctx.__rowCounter = 0;
26287
- },
26288
- restTableCellCtx(ctx) {
26289
- ctx.tableCellId = void 0;
26290
- ctx.tableCellIndex = void 0;
26291
- ctx.__cellCounter = 0;
26292
- },
26293
- enterPaper(ctx, pageId) {
26294
- ctx.currentPageId = pageId;
26295
- ctx.area = "body";
26296
- lineUtils.resetLineCtx(ctx);
26297
- lineUtils.resetTableCtx(ctx);
26298
- },
26299
- enterHeader(ctx) {
26300
- ctx.area = "header";
26301
- lineUtils.resetLineCtx(ctx);
26302
- lineUtils.resetTableCtx(ctx);
26303
- },
26304
- enterFooter(ctx) {
26305
- ctx.area = "footer";
26306
- lineUtils.resetLineCtx(ctx);
26307
- lineUtils.resetTableCtx(ctx);
26308
- },
26309
- enterOverlay(ctx) {
26310
- ctx.area = "overlay";
26311
- lineUtils.resetLineCtx(ctx);
26312
- lineUtils.resetTableCtx(ctx);
26313
- },
26314
- enterTable(ctx, tableId) {
26315
- lineUtils.resetTableCtx(ctx);
26316
- ctx.tableId = tableId;
26317
- },
26318
- enterTableRow(ctx, rowId) {
26319
- ctx.lineIndex += 1;
26320
- ctx.lineId = rowId;
26321
- ctx.lineType = "tablerow";
26322
- ctx.tableRowId = rowId;
26323
- ctx.tableRowIndex = ctx.__rowCounter;
26324
- ctx.__rowCounter += 1;
26325
- lineUtils.restTableCellCtx(ctx);
26326
- },
26327
- enterTableCell(ctx, cellId) {
26328
- ctx.tableCellId = cellId;
26329
- ctx.tableCellIndex = ctx.__cellCounter;
26330
- ctx.__cellCounter += 1;
26331
- },
26332
- enterParagraph(ctx, nodeId) {
26333
- ctx.lineIndex += 1;
26334
- ctx.lineId = nodeId;
26335
- ctx.lineType = "paragraph";
26336
- lineUtils.resetTableCtx(ctx);
26264
+ get width() {
26265
+ return this._width;
26337
26266
  }
26338
- };
26339
- function walkPageDFS(pages, cb) {
26340
- pages.forEach((page, pi) => {
26341
- const visit = (node, idx, path2) => {
26342
- cb(node, idx, path2);
26343
- const children = node?.getChildren?.() ?? node.children;
26344
- if (Array.isArray(children)) {
26345
- children.forEach((c2, i) => visit(c2, idx.concat(i), path2.concat(c2.id)));
26346
- }
26347
- };
26348
- visit(page, [pi], [page.id]);
26349
- if (page.headerBand) {
26350
- visit(page.headerBand, [pi, -1], [page.id, page.headerBand.id]);
26351
- }
26352
- if (page.footerBand) {
26353
- visit(page.footerBand, [pi, -2], [page.id, page.footerBand.id]);
26354
- }
26355
- if (page.overlayBand) {
26356
- visit(page.overlayBand, [pi, -3], [page.id, page.overlayBand.id]);
26357
- }
26358
- });
26359
- }
26360
- function buildLayoutMeta(pages) {
26361
- const dataCenter = /* @__PURE__ */ new Map();
26362
- const lineCenter = /* @__PURE__ */ new Map();
26363
- const widgetMetaMap = /* @__PURE__ */ new Map();
26364
- const widgetIds = [];
26365
- const ctx = {
26366
- currentPageId: "",
26367
- lineIndex: -1,
26368
- __cellCounter: 0,
26369
- __rowCounter: 0,
26370
- area: "body"
26371
- };
26372
- let cursor = 0;
26373
- function collectLineInfo(node, type4, ctx2, pageId) {
26374
- const children = node.getChildren();
26375
- if (!children.length) return;
26376
- const childrenBoxes = children.map(buildPosBox);
26377
- const absBoxes = childrenBoxes.map((b2) => ({
26378
- ...b2.absbox,
26379
- lineTop: node.layoutY,
26380
- lineBottom: node.layoutY + node.height
26381
- }));
26382
- const areaOrder = AREA_ORDER[ctx2.area] ?? 1;
26383
- lineCenter.set(node.id, {
26384
- id: node.id,
26385
- type: type4,
26386
- pageId,
26387
- pageArea: ctx2.area,
26388
- sort: areaOrder * 1e5 + ctx2.lineIndex,
26389
- nextIds: children.map((c2) => c2.id),
26390
- size: absBoxes
26391
- });
26267
+ get height() {
26268
+ return this._height;
26392
26269
  }
26393
- walkPageDFS(pages, (node, pathIndex, path2) => {
26394
- if (!node?.id) return;
26395
- const component = node.component;
26396
- const page = pages[pathIndex[0]];
26397
- if (!page) return;
26398
- switch (component) {
26399
- case BuiltinComponentTypeConst.Paper:
26400
- lineUtils.enterPaper(ctx, page.id);
26401
- break;
26402
- case BuiltinComponentTypeConst.Header:
26403
- lineUtils.enterHeader(ctx);
26404
- break;
26405
- case BuiltinComponentTypeConst.Footer:
26406
- lineUtils.enterFooter(ctx);
26407
- break;
26408
- case BuiltinComponentTypeConst.OverlayContainer:
26409
- lineUtils.enterOverlay(ctx);
26410
- break;
26411
- case BuiltinComponentTypeConst.Table:
26412
- lineUtils.enterTable(ctx, node.id);
26413
- break;
26414
- case BuiltinComponentTypeConst.TableRow:
26415
- lineUtils.enterTableRow(ctx, node.id);
26416
- collectLineInfo(node, "tablerow", ctx, page.id);
26417
- break;
26418
- case BuiltinComponentTypeConst.TableCell:
26419
- lineUtils.enterTableCell(ctx, node.id);
26420
- break;
26421
- case BuiltinComponentTypeConst.Paragraph:
26422
- if (node.parent?.component === BuiltinComponentTypeConst.Paper || node.parent?.component === BuiltinComponentTypeConst.Header || node.parent?.component === BuiltinComponentTypeConst.Footer) {
26423
- lineUtils.enterParagraph(ctx, node.id);
26424
- collectLineInfo(node, "paragraph", ctx, page.id);
26425
- }
26426
- break;
26427
- }
26428
- const textMeta = component === BuiltinComponentTypeConst.Text ? buildTextMeta(node) : { charLength: 0 };
26429
- const paragraphMeta = component === BuiltinComponentTypeConst.Paragraph ? buildParagraphMeta(node) : {};
26430
- const pos = buildPosBox(node);
26431
- const fr = {
26432
- id: node.id,
26433
- component,
26434
- raw: node,
26435
- runIndex: dataCenter.size,
26436
- secRefId: page?.section.refId || "",
26437
- pageId: page?.id || "",
26438
- pageArea: ctx.area,
26439
- preId: node.parent?.id ?? "",
26440
- ...pos,
26441
- globalPosStart: cursor,
26442
- globalPosEnd: cursor + textMeta.charLength,
26443
- path: path2.slice(),
26444
- pathIndex: pathIndex.slice(),
26445
- line: isAtom(component) ? {
26446
- lineId: ctx.lineId,
26447
- lineIndex: ctx.lineIndex,
26448
- lineType: ctx.lineType,
26449
- tableId: ctx.tableId,
26450
- tableRowId: ctx.tableRowId,
26451
- tableRowIndex: ctx.tableRowIndex,
26452
- tableCellId: ctx.tableCellId,
26453
- tableCellIndex: ctx.tableCellIndex
26454
- } : void 0,
26455
- ...textMeta,
26456
- ...paragraphMeta
26457
- };
26458
- if (component === BuiltinComponentTypeConst.Text) {
26459
- const widgetMeta = node?.widgetMeta;
26460
- if (widgetMeta) {
26461
- if (!widgetMetaMap.has(widgetMeta.id)) {
26462
- widgetMetaMap.set(widgetMeta.id, []);
26463
- }
26464
- widgetMetaMap.get(widgetMeta.id).push(fr);
26270
+ set width(value) {
26271
+ this._width = value;
26272
+ }
26273
+ set height(value) {
26274
+ this._height = value;
26275
+ }
26276
+ get page() {
26277
+ return this.getPage();
26278
+ }
26279
+ get isWidgetRun() {
26280
+ return "widgetMeta" in this && Boolean(this.widgetMeta);
26281
+ }
26282
+ get isPageWidgetRun() {
26283
+ return "pageWidgetMeta" in this && Boolean(this.pageWidgetMeta);
26284
+ }
26285
+ get isSubRenderer() {
26286
+ return "subRenderer" in this && Boolean(this.subRenderer);
26287
+ }
26288
+ get isPlaceholderRun() {
26289
+ return "isPlaceholder" in this && this.isPlaceholder === true;
26290
+ }
26291
+ /**
26292
+ * 获取实例对应的 page
26293
+ * tips 表格第一次初始化无 page,target 可能为空
26294
+ * @returns
26295
+ */
26296
+ getPage() {
26297
+ let target = this;
26298
+ while (target) {
26299
+ if (target.component === BuiltinComponentTypeConst.Paper) {
26300
+ return target;
26465
26301
  }
26302
+ target = target.parent;
26466
26303
  }
26467
- dataCenter.set(node.id, fr);
26468
- widgetIds.push(node.id);
26469
- cursor += textMeta.charLength;
26470
- });
26471
- return { dataCenter, lineCenter, widgetIds, widgetMetaMap };
26472
- }
26473
- function isAtom(component) {
26474
- return component === BuiltinComponentTypeConst.Text || component === BuiltinComponentTypeConst.InlineImage;
26475
- }
26476
- function isPlaceholderNode(node) {
26477
- if (!node) return false;
26478
- if (node.component !== BuiltinComponentTypeConst.Text) return false;
26479
- const raw = node.raw;
26480
- return !!(raw && raw.isPlaceholder);
26481
- }
26482
- function isClickSelectAllNode(node, checkMarker = true) {
26483
- if (!node) return false;
26484
- if (node.component !== BuiltinComponentTypeConst.Text) return false;
26485
- const raw = node.raw;
26486
- return validateTextWidgetMarker(raw, checkMarker);
26487
- }
26488
- function validateTextWidgetMarker(raw, checkMarker) {
26489
- const baseValid = raw.isWidgetRun;
26490
- if (!checkMarker) {
26491
- return baseValid;
26304
+ return;
26492
26305
  }
26493
- return baseValid && !(raw.widgetFieldLeftMarker || raw.widgetFieldRightMarker);
26494
- }
26495
- function isClickPaperWidgetAllNode(node) {
26496
- if (!node) return false;
26497
- const raw = node.raw;
26498
- return raw.isPageWidgetRun;
26499
- }
26500
- class TextHitHandler {
26501
- handleHitDetection(doc, node, actualX, actualY) {
26502
- const base = getBaseMetaInfo(node);
26503
- if (doc.isInEditMode() && isClickSelectAllNode(node, false)) {
26504
- const raw = node.raw;
26505
- const modelId = raw.modelRef?.id;
26506
- if (raw.widgetFieldLeftMarker || raw.widgetFieldRightMarker) {
26507
- const side2 = raw.widgetFieldLeftMarker ? "before" : "after";
26508
- return {
26509
- ...base,
26510
- offset: 0,
26511
- side: side2
26512
- };
26513
- }
26514
- if (!modelId) return null;
26515
- const widgetIds = doc.layoutMapper.getModelSplitById(modelId);
26516
- const nodes = doc.layoutMapper.getBaseMetaNodeByIds(widgetIds);
26517
- if (!nodes?.length) return null;
26518
- const filterNodes = nodes.filter(
26519
- (node2) => !(node2.raw.widgetFieldLeftMarker || node2.raw.widgetFieldRightMarker)
26520
- );
26521
- const total = filterNodes.length;
26522
- const midIndex = Math.floor(total / 2);
26523
- const clickedIndex = filterNodes.findIndex((n) => n.id === node.id);
26524
- let side = "after";
26525
- if (clickedIndex < midIndex) {
26526
- side = "before";
26527
- } else if (clickedIndex > midIndex) {
26528
- side = "after";
26529
- } else {
26530
- side = resolveMiddleSide(filterNodes[midIndex], actualX);
26306
+ /**
26307
+ * 获取实例对应的 悬浮层
26308
+ * @returns
26309
+ */
26310
+ getOverlayLayout() {
26311
+ let target = this;
26312
+ while (target) {
26313
+ if (target.component === BuiltinComponentTypeConst.OverlayLayout) {
26314
+ return target;
26531
26315
  }
26532
- const targetNode = side === "after" ? filterNodes[total - 1] : filterNodes[0];
26533
- return {
26534
- ...getBaseMetaInfo(targetNode),
26535
- offset: 0,
26536
- side
26537
- };
26538
- }
26539
- if (doc.isInFillMode() && !isClickSelectAllNode(node)) {
26540
- return null;
26541
- }
26542
- if (Array.isArray(node.charOffsets) && node.charOffsets.length > 0) {
26543
- return resolveCharHit(node, base, actualX);
26316
+ target = target.parent;
26544
26317
  }
26545
- return {
26546
- ...base,
26547
- offset: 0,
26548
- side: "after"
26549
- };
26318
+ return;
26550
26319
  }
26551
- isClickSelectAll(doc, node) {
26552
- return {
26553
- type: "cursor"
26554
- };
26320
+ /**
26321
+ * 布局方法:计算并设置节点的绝对位置
26322
+ * @param x 绝对 X 坐标
26323
+ * @param y 绝对 Y 坐标
26324
+ */
26325
+ layout(x2 = 0, y2 = 0) {
26326
+ this.layoutX = x2;
26327
+ this.layoutY = y2;
26555
26328
  }
26556
- // todo 后续文本改成多文字一个节点可以处理
26557
- // resolveCursorIntent(doc: Doc, node: BaseMetaNode, cursor: ICursorPosition) {
26558
- // const base = getBaseMetaInfo(node);
26559
- // const isPlaceholder = !!((node.raw as any).isPlaceholder);
26560
- // if (isPlaceholder) {
26561
- // return { ...base, isPlaceholder: true, offset: 0, side: cursor.side || 'before', };
26562
- // }
26563
- // const offsets = Array.isArray(node.charOffsets) ? node.charOffsets as number[] : undefined;
26564
- // if (offsets && offsets.length > 0) {
26565
- // let off = Number.isFinite(Number(cursor.offset)) ? Math.floor(Number(cursor.offset)) : 0;
26566
- // off = Math.max(0, Math.min(off, offsets.length));
26567
- // const side = off >= offsets.length ? 'after' : (cursor.side || 'before');
26568
- // return { ...base, offset: off, side };
26569
- // }
26570
- // const off = Number.isFinite(Number(cursor.offset)) ? Math.max(0, Math.floor(Number(cursor.offset))) : 0;
26571
- // return { ...base, offset: off, side: cursor.side || 'before' };
26572
- // }
26573
- }
26574
- function toHorizontalIntervals(childMeta) {
26575
- return childMeta.map((i) => {
26576
- if (!i) return null;
26577
- const left = i.absbox.left ?? 0;
26578
- const right = i.absbox.right ?? left;
26579
- return [left, right];
26580
- }).filter(Boolean);
26581
- }
26582
- function toVerticalIntervalsAbs(doc, childMeta, pageId) {
26583
- return childMeta.map((c2) => {
26584
- if (!c2) return null;
26585
- const top = doc.layoutMapper.getAbsoluteCanvasPosition(
26586
- pageId,
26587
- 0,
26588
- c2.absbox.top,
26589
- true
26590
- ).y;
26591
- const bottom = doc.layoutMapper.getAbsoluteCanvasPosition(
26592
- pageId,
26593
- 0,
26594
- c2.absbox.bottom,
26595
- true
26596
- ).y;
26597
- return [top, bottom];
26598
- }).filter(Boolean);
26599
26329
  }
26600
- function findIntervalIndex(intervals, actualX) {
26601
- let left = 0;
26602
- let right = intervals.length - 1;
26603
- while (left <= right) {
26604
- const mid = Math.floor((left + right) / 2);
26605
- const [start, end] = intervals[mid];
26606
- if (actualX >= start && actualX < end) return mid;
26607
- if (actualX < start) right = mid - 1;
26608
- else left = mid + 1;
26330
+ class LayoutGroup extends LayoutNode {
26331
+ /** 子节点列表 */
26332
+ children = [];
26333
+ _padding = [0, 0, 0, 0];
26334
+ constructor(options) {
26335
+ super(options);
26609
26336
  }
26610
- return -1;
26611
- }
26612
- function getIntervalSide(intervals, actualX) {
26613
- if (!intervals || !intervals.length) return null;
26614
- const foundIndex = findIntervalIndex(intervals, actualX);
26615
- if (foundIndex !== -1) {
26616
- const [start, end] = intervals[foundIndex];
26617
- const midpoint = (start + end) / 2;
26618
- return {
26619
- index: foundIndex,
26620
- side: actualX < midpoint ? "before" : "after",
26621
- distance: Math.min(actualX - start, end - actualX)
26622
- };
26337
+ get padding() {
26338
+ return this._padding ?? [0, 0, 0, 0];
26623
26339
  }
26624
- let closestIndex = -1;
26625
- let closestDistance = Infinity;
26626
- let side = "before";
26627
- for (let i = 0; i < intervals.length; i++) {
26628
- const [start, end] = intervals[i];
26629
- const distToStart = Math.abs(actualX - start);
26630
- if (distToStart < closestDistance) {
26631
- closestDistance = distToStart;
26632
- closestIndex = i;
26633
- side = actualX < start ? "before" : "after";
26634
- }
26635
- const distToEnd = Math.abs(actualX - end);
26636
- if (distToEnd < closestDistance) {
26637
- closestDistance = distToEnd;
26638
- closestIndex = i;
26639
- side = actualX < end ? "before" : "after";
26640
- }
26340
+ get pt() {
26341
+ return this.padding[0];
26641
26342
  }
26642
- if (closestIndex !== -1) {
26643
- return {
26644
- index: closestIndex,
26645
- side,
26646
- distance: closestDistance
26647
- };
26343
+ get pr() {
26344
+ return this.padding[1];
26345
+ }
26346
+ get pb() {
26347
+ return this.padding[2];
26348
+ }
26349
+ get pl() {
26350
+ return this.padding[3];
26351
+ }
26352
+ /**
26353
+ * 添加子节点
26354
+ * @param child 要添加的子节点
26355
+ */
26356
+ addChild(child) {
26357
+ this.children.push(child);
26358
+ child.parent = this;
26359
+ }
26360
+ /**
26361
+ * 在指定位置插入子节点
26362
+ * @param index 插入位置
26363
+ * @param child 要插入的子节点
26364
+ */
26365
+ insertChild(index2, child) {
26366
+ this.children.splice(index2, 0, child);
26367
+ child.parent = this;
26368
+ }
26369
+ /**
26370
+ * 批量添加子节点
26371
+ * @param children 要添加的子节点数组
26372
+ */
26373
+ addChildren(children) {
26374
+ children.forEach((child) => {
26375
+ this.children.push(child);
26376
+ child.parent = this;
26377
+ });
26378
+ }
26379
+ /**
26380
+ * 在指定位置批量插入子节点
26381
+ * @param index 插入位置
26382
+ * @param children 要插入的子节点数组
26383
+ */
26384
+ insertChildren(index2, children) {
26385
+ this.children.splice(index2, 0, ...children);
26386
+ children.forEach((child) => {
26387
+ child.parent = this;
26388
+ });
26389
+ }
26390
+ /**
26391
+ * 移除子节点
26392
+ * @param child 要移除的子节点
26393
+ * @returns 是否成功移除
26394
+ */
26395
+ removeChild(child) {
26396
+ const index2 = this.children.indexOf(child);
26397
+ if (index2 !== -1) {
26398
+ this.children.splice(index2, 1);
26399
+ child.parent = void 0;
26400
+ return true;
26401
+ }
26402
+ return false;
26403
+ }
26404
+ /**
26405
+ * 根据索引移除子节点
26406
+ * @param index 子节点索引
26407
+ * @returns 被移除的子节点,如果索引无效则返回 undefined
26408
+ */
26409
+ removeChildAt(index2) {
26410
+ if (index2 >= 0 && index2 < this.children.length) {
26411
+ const child = this.children.splice(index2, 1)[0];
26412
+ if (child) {
26413
+ child.parent = void 0;
26414
+ }
26415
+ return child;
26416
+ }
26417
+ return void 0;
26418
+ }
26419
+ /**
26420
+ * 获取所有子节点(只读)
26421
+ */
26422
+ getChildren() {
26423
+ return this.children;
26424
+ }
26425
+ /**
26426
+ * 获取指定索引的子节点
26427
+ * @param index 子节点索引
26428
+ */
26429
+ getChildAt(index2) {
26430
+ return this.children[index2];
26431
+ }
26432
+ /**
26433
+ * 获取子节点数量
26434
+ */
26435
+ getChildCount() {
26436
+ return this.children.length;
26437
+ }
26438
+ /**
26439
+ * 获取第一个子节点
26440
+ */
26441
+ getFirstChild() {
26442
+ return this.children[0] ?? null;
26443
+ }
26444
+ /**
26445
+ * 获取最后一个子节点
26446
+ */
26447
+ getLastChild() {
26448
+ return this.children[this.children.length - 1] ?? null;
26449
+ }
26450
+ /**
26451
+ * 清空所有子节点
26452
+ */
26453
+ clearChildren() {
26454
+ this.children.forEach((child) => {
26455
+ child.parent = void 0;
26456
+ });
26457
+ this.children = [];
26458
+ }
26459
+ /**
26460
+ * 查找子节点索引
26461
+ * @param child 要查找的子节点
26462
+ * @returns 子节点索引,如果不存在则返回 -1
26463
+ */
26464
+ indexOfChild(child) {
26465
+ return this.children.indexOf(child);
26466
+ }
26467
+ /**
26468
+ * 检查是否包含子节点
26469
+ * @param child 要检查的子节点
26470
+ */
26471
+ hasChild(child) {
26472
+ return this.children.includes(child);
26473
+ }
26474
+ /**
26475
+ * 遍历所有子节点
26476
+ * @param callback 遍历回调函数
26477
+ */
26478
+ forEachChild(callback) {
26479
+ this.children.forEach(callback);
26480
+ }
26481
+ /**
26482
+ * 查找满足条件的子节点
26483
+ * @param predicate 查找条件
26484
+ * @returns 第一个满足条件的子节点,如果没有则返回 undefined
26485
+ */
26486
+ findChild(predicate) {
26487
+ return this.children.find(predicate);
26488
+ }
26489
+ /**
26490
+ * 过滤子节点
26491
+ * @param predicate 过滤条件
26492
+ * @returns 满足条件的子节点数组
26493
+ */
26494
+ filterChildren(predicate) {
26495
+ return this.children.filter(predicate);
26496
+ }
26497
+ }
26498
+ class BandContainer extends LayoutGroup {
26499
+ type;
26500
+ constructor(options) {
26501
+ super(options);
26502
+ this.type = options.type;
26503
+ if (options.type === "header") {
26504
+ this.component = BuiltinComponentTypeConst.Header;
26505
+ } else if (options.type === "footer") {
26506
+ this.component = BuiltinComponentTypeConst.Footer;
26507
+ }
26508
+ this.parent = options.page;
26509
+ }
26510
+ get page() {
26511
+ return this.parent;
26512
+ }
26513
+ /**
26514
+ * 宽度 = 页面正文宽度
26515
+ */
26516
+ get contentMaxWidth() {
26517
+ return this.page.contentMaxWidth;
26518
+ }
26519
+ /**
26520
+ * 页眉页脚不限制高度
26521
+ */
26522
+ get contentMaxHeight() {
26523
+ return Number.POSITIVE_INFINITY;
26524
+ }
26525
+ /** 获取页眉页脚内容高度 */
26526
+ getContentHeight() {
26527
+ return this.getChildren().reduce((sum, child) => sum + child.height, 0);
26528
+ }
26529
+ /** 当前真正推开正文的 inset 高度 */
26530
+ get actualInsetHeight() {
26531
+ return this.type === "header" ? this.page.pt : this.page.pb;
26532
+ }
26533
+ /** 获取剩余空间 */
26534
+ getRemainingSize() {
26535
+ return Number.POSITIVE_INFINITY;
26536
+ }
26537
+ layout(x2, y2) {
26538
+ this.layoutX = x2;
26539
+ this.layoutY = y2;
26540
+ this.forEachChild((child) => {
26541
+ child.layout(this.layoutX + child.x, this.layoutY + child.y);
26542
+ });
26543
+ }
26544
+ /** 距离页面边缘的安全间距(页眉/页脚与页面边缘的距离) */
26545
+ get spacingFromEdge() {
26546
+ return this.type === "header" ? this.page.section.headerSpacing : this.page.section.footerSpacing;
26547
+ }
26548
+ /** 页眉/页脚与正文的分界线 Y 坐标(相对整页) */
26549
+ get guideLineY() {
26550
+ return this.type === "header" ? this.page.pt : this.page.height - this.page.pb;
26551
+ }
26552
+ /** 页眉/页脚占位矩形(用于辅助线渲染),相对整页 */
26553
+ get guideRect() {
26554
+ const y2 = this.type === "header" ? this.spacingFromEdge : this.page.height - this.page.pb;
26555
+ const rawHeight = this.type === "header" ? this.page.pt - this.spacingFromEdge : this.page.pb - this.spacingFromEdge;
26556
+ const height = Math.max(0, rawHeight);
26557
+ return {
26558
+ x: this.page.pl,
26559
+ y: y2,
26560
+ width: this.contentMaxWidth,
26561
+ height
26562
+ };
26563
+ }
26564
+ /** 双击开启/关闭页眉页脚编辑的命中区域(相对整页) */
26565
+ get hitAreaRect() {
26566
+ const isHeader = this.type === "header";
26567
+ return {
26568
+ x: this.page.pl,
26569
+ y: isHeader ? 0 : this.page.height - this.page.pb,
26570
+ width: this.contentMaxWidth,
26571
+ height: isHeader ? this.page.pt : this.page.pb
26572
+ };
26573
+ }
26574
+ }
26575
+ class OverlayLayout extends LayoutGroup {
26576
+ component = BuiltinComponentTypeConst.OverlayLayout;
26577
+ constructor(options) {
26578
+ super(options);
26579
+ }
26580
+ /**
26581
+ * 获取可用宽度
26582
+ */
26583
+ get contentMaxWidth() {
26584
+ return this.width;
26585
+ }
26586
+ /**
26587
+ * 悬浮层不参与文档流布局,但是要设置 layoutX和 layoutY
26588
+ */
26589
+ layout() {
26590
+ this.layoutX = this.x;
26591
+ this.layoutY = this.y;
26592
+ }
26593
+ }
26594
+ class OverlayContainer extends LayoutGroup {
26595
+ component = BuiltinComponentTypeConst.OverlayContainer;
26596
+ parent;
26597
+ constructor(options) {
26598
+ super(options);
26599
+ this.parent = options.page;
26600
+ }
26601
+ get page() {
26602
+ return this.parent;
26603
+ }
26604
+ get width() {
26605
+ return this.page.width;
26606
+ }
26607
+ get height() {
26608
+ return this.page.height;
26609
+ }
26610
+ createOverlayLayout({
26611
+ x: x2,
26612
+ y: y2,
26613
+ width,
26614
+ height,
26615
+ modelRef
26616
+ }) {
26617
+ const newOverlayLayout = new OverlayLayout({
26618
+ doc: this.doc,
26619
+ x: x2,
26620
+ y: y2,
26621
+ width,
26622
+ height,
26623
+ modelRef
26624
+ });
26625
+ newOverlayLayout.layout();
26626
+ this.addChild(newOverlayLayout);
26627
+ return newOverlayLayout;
26628
+ }
26629
+ /**
26630
+ * 悬浮层不参与文档流布局
26631
+ */
26632
+ layout() {
26633
+ }
26634
+ }
26635
+ function normalizeColor(color, defaultColor = "#000000") {
26636
+ if (color === "auto" || !color) {
26637
+ return defaultColor;
26638
+ }
26639
+ if (color.startsWith("#")) {
26640
+ return color;
26641
+ }
26642
+ if (color.length === 8 && /^[0-9A-Fa-f]{8}$/.test(color)) {
26643
+ const alpha = color.substring(0, 2);
26644
+ const rgb = color.substring(2);
26645
+ return `#${rgb}${alpha}`;
26646
+ }
26647
+ if (color.length === 6 && /^[0-9A-Fa-f]{6}$/.test(color)) {
26648
+ return `#${color}`;
26649
+ }
26650
+ if (color.length === 3 && /^[0-9A-Fa-f]{3}$/.test(color)) {
26651
+ return `#${color}`;
26652
+ }
26653
+ return color;
26654
+ }
26655
+ function repeat(count, callback) {
26656
+ for (let i = 0; i < count; i++) {
26657
+ callback(i);
26658
+ }
26659
+ }
26660
+ function distributeInteger(total, count) {
26661
+ if (count <= 0) throw new Error("count must be > 0");
26662
+ if (total < 0) throw new Error("total must be >= 0");
26663
+ const base = Math.floor(total / count);
26664
+ const remainder = total % count;
26665
+ const result = [];
26666
+ for (let i = 0; i < count; i++) {
26667
+ result.push(i < count - remainder ? base : base + 1);
26668
+ }
26669
+ return result;
26670
+ }
26671
+ const mainData2WordData = (data) => {
26672
+ const entries = Object.entries(data).map(([key, value]) => {
26673
+ return [`$.${key}`, value];
26674
+ });
26675
+ return Object.fromEntries(entries);
26676
+ };
26677
+ class TextUtil {
26678
+ /** 字体度量缓存限制 */
26679
+ static FONT_METRICS_CACHE_LIMIT = 80;
26680
+ /** 布局大小缓存限制(按「样式 + 单段文本」键,长文档可提高命中率) */
26681
+ static LAYOUT_SIZE_CACHE_LIMIT = 500;
26682
+ /** 东亚常见全宽字符块 */
26683
+ static EAST_ASIAN_FULL_WIDTH_REGEX = /[\u3000-\u303F\u3040-\u30FF\u31F0-\u31FF\uFF01-\uFF60\uFFE0-\uFFE6]/u;
26684
+ /** 表单/文档中常见的几何符号 */
26685
+ static FULL_WIDTH_SYMBOL_REGEX = /[□■○●△▲▽▼◇◆◎※]/u;
26686
+ /**
26687
+ * 视觉间距系数
26688
+ * 值 = fontSize * ratio
26689
+ *
26690
+ * 解决:
26691
+ * - N·m
26692
+ * - N/A
26693
+ * - kg·m²
26694
+ * 等符号贴太近的问题
26695
+ */
26696
+ static VISUAL_SPACING_MAP = {
26697
+ "·": 0.24,
26698
+ "•": 0.24,
26699
+ "/": 0.16,
26700
+ "/": 0.16,
26701
+ "|": 0.12,
26702
+ ":": 0.06,
26703
+ ":": 0.08
26704
+ };
26705
+ static fontMetricsCache = /* @__PURE__ */ new Map();
26706
+ static layoutSizeCache = /* @__PURE__ */ new Map();
26707
+ /**
26708
+ * 等待文档字体就绪后再做 Canvas 度量,可减轻 Mac/Windows 因 Web 字体未加载导致的度量差异。
26709
+ * 无 Font Loading API 时立即 resolve。
26710
+ */
26711
+ static awaitDocumentFonts() {
26712
+ if (typeof document === "undefined") {
26713
+ return Promise.resolve();
26714
+ }
26715
+ const fonts = document.fonts;
26716
+ if (!fonts || typeof fonts.ready?.then !== "function") {
26717
+ return Promise.resolve();
26718
+ }
26719
+ return fonts.ready;
26720
+ }
26721
+ /**
26722
+ * 验证中文字符
26723
+ * @param char
26724
+ * @returns
26725
+ */
26726
+ static isHanChar(char) {
26727
+ return new RegExp("\\p{Script=Han}", "u").test(char);
26728
+ }
26729
+ /**
26730
+ * 验证是否为应按 1em 处理的全宽单字符
26731
+ * @param char
26732
+ * @returns
26733
+ */
26734
+ static isFullWidthChar(char) {
26735
+ if ([...char].length !== 1) {
26736
+ return false;
26737
+ }
26738
+ return this.isHanChar(char) || this.EAST_ASIAN_FULL_WIDTH_REGEX.test(char) || this.FULL_WIDTH_SYMBOL_REGEX.test(char);
26739
+ }
26740
+ /**
26741
+ * 获取字符视觉间距
26742
+ *
26743
+ * 注意:
26744
+ * 这里不是 glyph width
26745
+ * 而是用于排版推进的额外 advance width
26746
+ *
26747
+ * 例如:
26748
+ * - N·m
26749
+ * - N/A
26750
+ *
26751
+ * 中间符号真实宽度很小,
26752
+ * 但视觉上需要 breathing space
26753
+ *
26754
+ * @param char
26755
+ * @param fontSize
26756
+ * @returns
26757
+ */
26758
+ static getVisualSpacing(char, fontSize2) {
26759
+ const ratio = this.VISUAL_SPACING_MAP[char];
26760
+ if (!ratio) {
26761
+ return 0;
26762
+ }
26763
+ return fontSize2 * ratio;
26764
+ }
26765
+ /** 与度量路径一致:lineHeight 固定为 1 的样式副本 */
26766
+ static measureBase(payload) {
26767
+ return Object.assign({}, payload, { lineHeight: 1 });
26768
+ }
26769
+ /**
26770
+ * 字体级缓存键(不含 text),与 getFontMetrics 语义一致
26771
+ */
26772
+ static measureStyleKey(payload) {
26773
+ const c2 = this.measureBase(payload);
26774
+ return [
26775
+ c2.fontSize ?? "",
26776
+ c2.fontFamily ?? "",
26777
+ c2.fontStyle ?? "",
26778
+ c2.fontVariant ?? "",
26779
+ c2.lineHeight ?? "",
26780
+ c2.padding ?? "",
26781
+ c2.letterSpacing ?? ""
26782
+ ].join("");
26783
+ }
26784
+ /**
26785
+ * 布局缓存键:样式签名 + 编码后的文本
26786
+ */
26787
+ static layoutCacheKey(payload) {
26788
+ const c2 = this.measureBase(payload);
26789
+ return `${this.measureStyleKey(payload)}${encodeURIComponent(c2.text ?? "")}`;
26790
+ }
26791
+ static touchLru(map2, key, value) {
26792
+ map2.delete(key);
26793
+ map2.set(key, value);
26794
+ }
26795
+ static evictOldestIfFull(map2, limit) {
26796
+ if (map2.size >= limit) {
26797
+ const firstKey = map2.keys().next().value;
26798
+ map2.delete(firstKey);
26799
+ }
26800
+ }
26801
+ /**
26802
+ * 单次 Konva.Text 计算 width / height(advance width 含视觉间距)
26803
+ */
26804
+ static computeLayoutSizeUncached(payload) {
26805
+ const config = this.measureBase(payload);
26806
+ const text = new Konva.Text(config);
26807
+ const char = payload.text ?? "";
26808
+ const fontSize2 = payload.fontSize ?? 0;
26809
+ const width = this.isFullWidthChar(char) ? fontSize2 : text.width() + this.getVisualSpacing(char, fontSize2);
26810
+ return {
26811
+ width,
26812
+ height: text.height()
26813
+ };
26814
+ }
26815
+ /**
26816
+ * 一次度量:布局宽高 + 字体 ascent/descent(双缓存均未命中时只创建一个 Konva.Text)
26817
+ */
26818
+ static measureTextComplete(payload) {
26819
+ const layoutKey = this.layoutCacheKey(payload);
26820
+ const fontKey = this.measureStyleKey(payload);
26821
+ const layoutCached = this.layoutSizeCache.get(layoutKey);
26822
+ const fontCached = this.fontMetricsCache.get(fontKey);
26823
+ if (layoutCached && fontCached) {
26824
+ this.touchLru(this.layoutSizeCache, layoutKey, layoutCached);
26825
+ this.touchLru(this.fontMetricsCache, fontKey, fontCached);
26826
+ return {
26827
+ width: layoutCached.width,
26828
+ height: layoutCached.height,
26829
+ ascent: fontCached.ascent,
26830
+ descent: fontCached.descent
26831
+ };
26832
+ }
26833
+ if (layoutCached && !fontCached) {
26834
+ this.touchLru(this.layoutSizeCache, layoutKey, layoutCached);
26835
+ const { ascent: ascent2, descent: descent2 } = this.getFontMetrics(payload);
26836
+ return {
26837
+ width: layoutCached.width,
26838
+ height: layoutCached.height,
26839
+ ascent: ascent2,
26840
+ descent: descent2
26841
+ };
26842
+ }
26843
+ if (!layoutCached && fontCached) {
26844
+ const layout2 = this.computeLayoutSizeUncached(payload);
26845
+ this.evictOldestIfFull(this.layoutSizeCache, this.LAYOUT_SIZE_CACHE_LIMIT);
26846
+ this.layoutSizeCache.set(layoutKey, layout2);
26847
+ this.touchLru(this.fontMetricsCache, fontKey, fontCached);
26848
+ return {
26849
+ width: layout2.width,
26850
+ height: layout2.height,
26851
+ ascent: fontCached.ascent,
26852
+ descent: fontCached.descent
26853
+ };
26854
+ }
26855
+ const config = this.measureBase(payload);
26856
+ const text = new Konva.Text(config);
26857
+ const char = payload.text ?? "";
26858
+ const fontSize2 = payload.fontSize ?? 0;
26859
+ const width = this.isFullWidthChar(char) ? fontSize2 : text.width() + this.getVisualSpacing(char, fontSize2);
26860
+ const height = text.height();
26861
+ const sizeHg = text.measureSize("Hg");
26862
+ const ascent = sizeHg.actualBoundingBoxAscent;
26863
+ const descent = sizeHg.actualBoundingBoxDescent;
26864
+ const layout = { width, height };
26865
+ const font = { ascent, descent };
26866
+ this.evictOldestIfFull(this.layoutSizeCache, this.LAYOUT_SIZE_CACHE_LIMIT);
26867
+ this.evictOldestIfFull(this.fontMetricsCache, this.FONT_METRICS_CACHE_LIMIT);
26868
+ this.layoutSizeCache.set(layoutKey, layout);
26869
+ this.fontMetricsCache.set(fontKey, font);
26870
+ return { width, height, ascent, descent };
26871
+ }
26872
+ /**
26873
+ * 计算字体度量
26874
+ * ascent / descent
26875
+ *
26876
+ * @param payload
26877
+ * @returns
26878
+ */
26879
+ static getFontMetrics(payload) {
26880
+ const targetText = "Hg";
26881
+ const config = Object.assign({}, payload, {
26882
+ text: targetText,
26883
+ lineHeight: 1
26884
+ });
26885
+ const cacheKey = this.measureStyleKey(config);
26886
+ if (this.fontMetricsCache.has(cacheKey)) {
26887
+ const result2 = this.fontMetricsCache.get(cacheKey);
26888
+ this.touchLru(this.fontMetricsCache, cacheKey, result2);
26889
+ return result2;
26890
+ }
26891
+ const text = new Konva.Text(config);
26892
+ const size = text.measureSize(targetText);
26893
+ const result = {
26894
+ ascent: size.actualBoundingBoxAscent,
26895
+ descent: size.actualBoundingBoxDescent
26896
+ };
26897
+ this.evictOldestIfFull(this.fontMetricsCache, this.FONT_METRICS_CACHE_LIMIT);
26898
+ this.fontMetricsCache.set(cacheKey, result);
26899
+ return result;
26900
+ }
26901
+ /**
26902
+ * 获取字符排版推进宽度
26903
+ *
26904
+ * 注意:
26905
+ * 这里返回的是:
26906
+ * advance width
26907
+ *
26908
+ * 而不是:
26909
+ * glyph width
26910
+ *
26911
+ * 用于:
26912
+ * - 自动换行
26913
+ * - 光标推进
26914
+ * - 文本布局
26915
+ * - selection
26916
+ *
26917
+ * @param payload
26918
+ * @returns
26919
+ */
26920
+ static getAdvanceWidth(payload) {
26921
+ const char = payload.text ?? "";
26922
+ const fontSize2 = payload.fontSize ?? 0;
26923
+ if (this.isFullWidthChar(char)) {
26924
+ return fontSize2;
26925
+ }
26926
+ return this.getLayoutSize(payload).width;
26927
+ }
26928
+ /**
26929
+ * 计算单字符布局大小
26930
+ *
26931
+ * 注意:
26932
+ * width 使用 advance width
26933
+ *
26934
+ * @param payload
26935
+ * @returns
26936
+ */
26937
+ static getLayoutSize(payload) {
26938
+ const cacheKey = this.layoutCacheKey(payload);
26939
+ if (this.layoutSizeCache.has(cacheKey)) {
26940
+ const result2 = this.layoutSizeCache.get(cacheKey);
26941
+ this.touchLru(this.layoutSizeCache, cacheKey, result2);
26942
+ return { width: result2.width, height: result2.height };
26943
+ }
26944
+ const result = this.computeLayoutSizeUncached(payload);
26945
+ this.evictOldestIfFull(this.layoutSizeCache, this.LAYOUT_SIZE_CACHE_LIMIT);
26946
+ this.layoutSizeCache.set(cacheKey, result);
26947
+ return { width: result.width, height: result.height };
26948
+ }
26949
+ /**
26950
+ * 清除度量缓存
26951
+ */
26952
+ static clearMeasureCache() {
26953
+ this.fontMetricsCache.clear();
26954
+ this.layoutSizeCache.clear();
26955
+ }
26956
+ /**
26957
+ * 获取缓存大小
26958
+ * @returns
26959
+ */
26960
+ static getMeasureCacheSize() {
26961
+ return {
26962
+ fontMetrics: this.fontMetricsCache.size,
26963
+ layoutSize: this.layoutSizeCache.size
26964
+ };
26965
+ }
26966
+ }
26967
+ class TextRun extends LayoutNode {
26968
+ component = BuiltinComponentTypeConst.Text;
26969
+ /** 文本内容 */
26970
+ text = "";
26971
+ /** 字号 */
26972
+ fontSize = DEFAULT_FONT_SIZE;
26973
+ /** 字体 */
26974
+ fontFamily = DEFAULT_FONT_FAMILY;
26975
+ /** 高亮 */
26976
+ highlight = "none";
26977
+ /** 文字颜色 */
26978
+ color = DEFAULT_TEXT_COLOR;
26979
+ /** 加粗 */
26980
+ bold;
26981
+ /** 斜体 */
26982
+ italic;
26983
+ /** 下划线 */
26984
+ underline;
26985
+ /** 删除线 */
26986
+ strike;
26987
+ /** 字间距 */
26988
+ letterSpacing = 0;
26989
+ /** 文字对齐样式 */
26990
+ textAlign = "left";
26991
+ charMetrics = [];
26992
+ isPlaceholder = false;
26993
+ isComposition = false;
26994
+ lineHeight = 1.6;
26995
+ ascent;
26996
+ descent;
26997
+ style;
26998
+ constructor(options) {
26999
+ super(options);
27000
+ options.doc.increaseTextRunCount();
27001
+ const { text } = options;
27002
+ this.text = text;
27003
+ this.isPlaceholder = options.isPlaceholder || false;
27004
+ this.isComposition = options.isComposition || false;
27005
+ this.ascent = options.ascent ?? 0;
27006
+ this.descent = options.descent ?? 0;
27007
+ if (options.charMetrics) {
27008
+ this.charMetrics = options.charMetrics;
27009
+ } else {
27010
+ this.charMetrics.push({
27011
+ char: options.text,
27012
+ width: options.width,
27013
+ height: options.height
27014
+ });
27015
+ }
27016
+ if (options.style) {
27017
+ Object.assign(this, options.style);
27018
+ }
27019
+ }
27020
+ /**
27021
+ * 计算文字大小 度量
27022
+ * 优化版本
27023
+ * @param payload
27024
+ * @returns
27025
+ */
27026
+ static measureText(payload) {
27027
+ return TextUtil.measureTextComplete(payload);
27028
+ }
27029
+ /**
27030
+ * 计算文字大小 度量
27031
+ * @param payload
27032
+ * @returns
27033
+ */
27034
+ static __measureText(payload) {
27035
+ let config = {
27036
+ lineHeight: 1
27037
+ };
27038
+ Object.assign(config, payload);
27039
+ const text = new Konva.Text(config);
27040
+ const size = text.measureSize("Hg");
27041
+ const { actualBoundingBoxAscent: ascent, actualBoundingBoxDescent: descent } = size;
27042
+ return {
27043
+ width: text.width(),
27044
+ height: text.height(),
27045
+ ascent,
27046
+ descent
27047
+ };
27048
+ }
27049
+ static createEmptyRun(doc) {
27050
+ const fontSize2 = DEFAULT_FONT_SIZE;
27051
+ const { height, ascent, descent } = TextRun.measureText({
27052
+ text: "0",
27053
+ fontSize: fontSize2
27054
+ });
27055
+ const run = new TextRun({
27056
+ doc,
27057
+ width: 6,
27058
+ height,
27059
+ ascent,
27060
+ descent,
27061
+ text: "",
27062
+ isPlaceholder: true
27063
+ });
27064
+ return run;
27065
+ }
27066
+ /**TextStyle(样式体系的样式)转换为 Layout 层的样式
27067
+ * @param textStyle 经过继承计算的有效字符样式
27068
+ * @returns TextRun 的样式属性
27069
+ */
27070
+ static textStyle2LayoutStyle(textStyle) {
27071
+ if (!textStyle) return {};
27072
+ const layoutStyle = {};
27073
+ if (textStyle.sz !== void 0) {
27074
+ const fontSizeInPt = textStyle.sz / 2;
27075
+ layoutStyle.fontSize = fontSizeInPt * 96 / 72;
27076
+ }
27077
+ if (textStyle.rFonts?.ascii) {
27078
+ layoutStyle.fontFamily = textStyle.rFonts.ascii;
27079
+ }
27080
+ if (textStyle.highlight) {
27081
+ layoutStyle.highlight = normalizeColor(textStyle.highlight, "none");
27082
+ }
27083
+ if (textStyle.color) {
27084
+ layoutStyle.color = normalizeColor(textStyle.color, DEFAULT_TEXT_COLOR);
27085
+ }
27086
+ if (textStyle.b !== void 0) {
27087
+ layoutStyle.bold = textStyle.b;
27088
+ }
27089
+ if (textStyle.i !== void 0) {
27090
+ layoutStyle.italic = textStyle.i;
27091
+ }
27092
+ if (textStyle.u !== void 0 && textStyle.u !== "none") {
27093
+ layoutStyle.underline = true;
27094
+ }
27095
+ if (textStyle.strike !== void 0) {
27096
+ layoutStyle.strike = textStyle.strike;
27097
+ }
27098
+ if (textStyle.spacing !== void 0) {
27099
+ layoutStyle.letterSpacing = parseInt(textStyle.spacing) / 20;
27100
+ }
27101
+ if (textStyle.highlight !== void 0) ;
27102
+ return layoutStyle;
27103
+ }
27104
+ }
27105
+ class TextWidget extends TextRun {
27106
+ widgetMeta;
27107
+ valuePath;
27108
+ isEmptyPlaceholder = false;
27109
+ isIconPlaceholder = false;
27110
+ isSpacePlaceholder = false;
27111
+ widgetFieldLeftMarker;
27112
+ widgetFieldRightMarker;
27113
+ widgetOption;
27114
+ widgetFileItem;
27115
+ pageWidgetMeta;
27116
+ dataIndex;
27117
+ constructor(options) {
27118
+ super(options);
27119
+ this.widgetMeta = options.widgetMeta;
27120
+ this.valuePath = options.valuePath;
27121
+ this.isEmptyPlaceholder = options.isEmptyPlaceholder ?? false;
27122
+ this.isIconPlaceholder = options.isIconPlaceholder ?? false;
27123
+ this.isSpacePlaceholder = options.isSpacePlaceholder ?? false;
27124
+ this.widgetOption = options.widgetOption;
27125
+ this.widgetFileItem = options.widgetFileItem;
27126
+ this.widgetFieldLeftMarker = options.widgetFieldLeftMarker;
27127
+ this.widgetFieldRightMarker = options.widgetFieldRightMarker;
27128
+ this.pageWidgetMeta = options.pageWidgetMeta;
27129
+ this.dataIndex = options.dataIndex;
27130
+ }
27131
+ }
27132
+ function isLayoutTextRun(node) {
27133
+ return node != null && node.component === BuiltinComponentTypeConst.Text;
27134
+ }
27135
+ function isLayoutTextWidget(node) {
27136
+ return node instanceof TextWidget;
27137
+ }
27138
+ const AREA_ORDER = {
27139
+ overlay: -1,
27140
+ header: 0,
27141
+ body: 1,
27142
+ footer: 2
27143
+ };
27144
+ function computeCharOffsetsFromMetrics(metrics) {
27145
+ const offsets = [0];
27146
+ let acc = 0;
27147
+ for (const m of metrics) {
27148
+ acc += m.width;
27149
+ offsets.push(acc);
27150
+ }
27151
+ return offsets;
27152
+ }
27153
+ function buildTextMeta(node) {
27154
+ const charMetrics = Array.isArray(node.charMetrics) ? node.charMetrics.slice() : [];
27155
+ const charLength = Math.max(0, charMetrics.length);
27156
+ return {
27157
+ text: node.text ?? "",
27158
+ charMetrics,
27159
+ charLength,
27160
+ charOffsets: charMetrics.length > 0 ? computeCharOffsetsFromMetrics(charMetrics) : void 0
27161
+ };
27162
+ }
27163
+ function buildParagraphMeta(node) {
27164
+ return {
27165
+ lineTop: node.layoutY,
27166
+ lineBottom: node.layoutY + node.height
27167
+ };
27168
+ }
27169
+ function buildPosBox(node) {
27170
+ const absLeft = node.layoutX ?? 0;
27171
+ const absTop = node.layoutY ?? 0;
27172
+ const relLeft = node.x ?? 0;
27173
+ const relTop = node.y ?? 0;
27174
+ const width = node.mergeFromId ? 0 : node.width ?? 0;
27175
+ const height = node.mergeFromId ? 0 : node.height ?? 0;
27176
+ return {
27177
+ width,
27178
+ height,
27179
+ absbox: {
27180
+ left: absLeft,
27181
+ top: absTop,
27182
+ right: absLeft + width,
27183
+ bottom: absTop + height
27184
+ },
27185
+ relbox: {
27186
+ left: relLeft,
27187
+ top: relTop,
27188
+ right: relLeft + width,
27189
+ bottom: relTop + height
27190
+ }
27191
+ };
27192
+ }
27193
+ const lineUtils = {
27194
+ resetLineCtx(ctx) {
27195
+ ctx.lineId = void 0;
27196
+ ctx.lineIndex = -1;
27197
+ ctx.lineType = void 0;
27198
+ },
27199
+ resetTableCtx(ctx) {
27200
+ ctx.tableId = void 0;
27201
+ lineUtils.restTableRowCtx(ctx);
27202
+ lineUtils.restTableCellCtx(ctx);
27203
+ },
27204
+ restTableRowCtx(ctx) {
27205
+ ctx.tableRowId = void 0;
27206
+ ctx.tableRowIndex = void 0;
27207
+ ctx.__rowCounter = 0;
27208
+ },
27209
+ restTableCellCtx(ctx) {
27210
+ ctx.tableCellId = void 0;
27211
+ ctx.tableCellIndex = void 0;
27212
+ ctx.__cellCounter = 0;
27213
+ },
27214
+ enterPaper(ctx, pageId) {
27215
+ ctx.currentPageId = pageId;
27216
+ ctx.area = "body";
27217
+ lineUtils.resetLineCtx(ctx);
27218
+ lineUtils.resetTableCtx(ctx);
27219
+ },
27220
+ enterHeader(ctx) {
27221
+ ctx.area = "header";
27222
+ lineUtils.resetLineCtx(ctx);
27223
+ lineUtils.resetTableCtx(ctx);
27224
+ },
27225
+ enterFooter(ctx) {
27226
+ ctx.area = "footer";
27227
+ lineUtils.resetLineCtx(ctx);
27228
+ lineUtils.resetTableCtx(ctx);
27229
+ },
27230
+ enterOverlay(ctx) {
27231
+ ctx.area = "overlay";
27232
+ lineUtils.resetLineCtx(ctx);
27233
+ lineUtils.resetTableCtx(ctx);
27234
+ },
27235
+ enterTable(ctx, tableId) {
27236
+ lineUtils.resetTableCtx(ctx);
27237
+ ctx.tableId = tableId;
27238
+ },
27239
+ enterTableRow(ctx, rowId) {
27240
+ ctx.lineIndex += 1;
27241
+ ctx.lineId = rowId;
27242
+ ctx.lineType = "tablerow";
27243
+ ctx.tableRowId = rowId;
27244
+ ctx.tableRowIndex = ctx.__rowCounter;
27245
+ ctx.__rowCounter += 1;
27246
+ lineUtils.restTableCellCtx(ctx);
27247
+ },
27248
+ enterTableCell(ctx, cellId) {
27249
+ ctx.tableCellId = cellId;
27250
+ ctx.tableCellIndex = ctx.__cellCounter;
27251
+ ctx.__cellCounter += 1;
27252
+ },
27253
+ enterParagraph(ctx, nodeId) {
27254
+ ctx.lineIndex += 1;
27255
+ ctx.lineId = nodeId;
27256
+ ctx.lineType = "paragraph";
27257
+ lineUtils.resetTableCtx(ctx);
27258
+ }
27259
+ };
27260
+ function walkPageDFS(pages, cb) {
27261
+ pages.forEach((page, pi) => {
27262
+ const visit = (node, idx, path2) => {
27263
+ cb(node, idx, path2);
27264
+ const children = node?.getChildren?.() ?? node.children;
27265
+ if (Array.isArray(children)) {
27266
+ children.forEach((c2, i) => visit(c2, idx.concat(i), path2.concat(c2.id)));
27267
+ }
27268
+ };
27269
+ visit(page, [pi], [page.id]);
27270
+ if (page.headerBand) {
27271
+ visit(page.headerBand, [pi, -1], [page.id, page.headerBand.id]);
27272
+ }
27273
+ if (page.footerBand) {
27274
+ visit(page.footerBand, [pi, -2], [page.id, page.footerBand.id]);
27275
+ }
27276
+ if (page.overlayBand) {
27277
+ visit(page.overlayBand, [pi, -3], [page.id, page.overlayBand.id]);
27278
+ }
27279
+ });
27280
+ }
27281
+ function buildLayoutMeta(pages) {
27282
+ const dataCenter = /* @__PURE__ */ new Map();
27283
+ const lineCenter = /* @__PURE__ */ new Map();
27284
+ const widgetMetaMap = /* @__PURE__ */ new Map();
27285
+ const widgetIds = [];
27286
+ const ctx = {
27287
+ currentPageId: "",
27288
+ lineIndex: -1,
27289
+ __cellCounter: 0,
27290
+ __rowCounter: 0,
27291
+ area: "body"
27292
+ };
27293
+ let cursor = 0;
27294
+ function collectLineInfo(node, type4, ctx2, pageId) {
27295
+ const children = node.getChildren();
27296
+ if (!children.length) return;
27297
+ const childrenBoxes = children.map(buildPosBox);
27298
+ const absBoxes = childrenBoxes.map((b2) => ({
27299
+ ...b2.absbox,
27300
+ lineTop: node.layoutY,
27301
+ lineBottom: node.layoutY + node.height
27302
+ }));
27303
+ const areaOrder = AREA_ORDER[ctx2.area] ?? 1;
27304
+ lineCenter.set(node.id, {
27305
+ id: node.id,
27306
+ type: type4,
27307
+ pageId,
27308
+ pageArea: ctx2.area,
27309
+ sort: areaOrder * 1e5 + ctx2.lineIndex,
27310
+ nextIds: children.map((c2) => c2.id),
27311
+ size: absBoxes
27312
+ });
27313
+ }
27314
+ walkPageDFS(pages, (node, pathIndex, path2) => {
27315
+ if (!node?.id) return;
27316
+ const component = node.component;
27317
+ const page = pages[pathIndex[0]];
27318
+ if (!page) return;
27319
+ switch (component) {
27320
+ case BuiltinComponentTypeConst.Paper:
27321
+ lineUtils.enterPaper(ctx, page.id);
27322
+ break;
27323
+ case BuiltinComponentTypeConst.Header:
27324
+ lineUtils.enterHeader(ctx);
27325
+ break;
27326
+ case BuiltinComponentTypeConst.Footer:
27327
+ lineUtils.enterFooter(ctx);
27328
+ break;
27329
+ case BuiltinComponentTypeConst.OverlayContainer:
27330
+ lineUtils.enterOverlay(ctx);
27331
+ break;
27332
+ case BuiltinComponentTypeConst.Table:
27333
+ lineUtils.enterTable(ctx, node.id);
27334
+ break;
27335
+ case BuiltinComponentTypeConst.TableRow:
27336
+ lineUtils.enterTableRow(ctx, node.id);
27337
+ collectLineInfo(node, "tablerow", ctx, page.id);
27338
+ break;
27339
+ case BuiltinComponentTypeConst.TableCell:
27340
+ lineUtils.enterTableCell(ctx, node.id);
27341
+ break;
27342
+ case BuiltinComponentTypeConst.Paragraph:
27343
+ if (node.parent?.component === BuiltinComponentTypeConst.Paper || node.parent?.component === BuiltinComponentTypeConst.Header || node.parent?.component === BuiltinComponentTypeConst.Footer) {
27344
+ lineUtils.enterParagraph(ctx, node.id);
27345
+ collectLineInfo(node, "paragraph", ctx, page.id);
27346
+ }
27347
+ break;
27348
+ }
27349
+ const textMeta = component === BuiltinComponentTypeConst.Text ? buildTextMeta(node) : { charLength: 0 };
27350
+ const paragraphMeta = component === BuiltinComponentTypeConst.Paragraph ? buildParagraphMeta(node) : {};
27351
+ const pos = buildPosBox(node);
27352
+ const fr = {
27353
+ id: node.id,
27354
+ component,
27355
+ raw: node,
27356
+ runIndex: dataCenter.size,
27357
+ secRefId: page?.section.refId || "",
27358
+ pageId: page?.id || "",
27359
+ pageArea: ctx.area,
27360
+ preId: node.parent?.id ?? "",
27361
+ ...pos,
27362
+ globalPosStart: cursor,
27363
+ globalPosEnd: cursor + textMeta.charLength,
27364
+ path: path2.slice(),
27365
+ pathIndex: pathIndex.slice(),
27366
+ line: isAtom(component) ? {
27367
+ lineId: ctx.lineId,
27368
+ lineIndex: ctx.lineIndex,
27369
+ lineType: ctx.lineType,
27370
+ tableId: ctx.tableId,
27371
+ tableRowId: ctx.tableRowId,
27372
+ tableRowIndex: ctx.tableRowIndex,
27373
+ tableCellId: ctx.tableCellId,
27374
+ tableCellIndex: ctx.tableCellIndex
27375
+ } : void 0,
27376
+ ...textMeta,
27377
+ ...paragraphMeta
27378
+ };
27379
+ if (component === BuiltinComponentTypeConst.Text) {
27380
+ const widgetMeta = node?.widgetMeta;
27381
+ if (widgetMeta) {
27382
+ if (!widgetMetaMap.has(widgetMeta.id)) {
27383
+ widgetMetaMap.set(widgetMeta.id, []);
27384
+ }
27385
+ widgetMetaMap.get(widgetMeta.id).push(fr);
27386
+ }
27387
+ }
27388
+ dataCenter.set(node.id, fr);
27389
+ widgetIds.push(node.id);
27390
+ cursor += textMeta.charLength;
27391
+ });
27392
+ return { dataCenter, lineCenter, widgetIds, widgetMetaMap };
27393
+ }
27394
+ function isAtom(component) {
27395
+ return component === BuiltinComponentTypeConst.Text || component === BuiltinComponentTypeConst.InlineImage;
27396
+ }
27397
+ function isPlaceholderNode(node) {
27398
+ if (node.component !== BuiltinComponentTypeConst.Text) return false;
27399
+ const raw = node.raw;
27400
+ return !!(raw && "isPlaceholder" in raw && raw.isPlaceholder);
27401
+ }
27402
+ function isClickSelectAllNode(node, checkMarker = true) {
27403
+ if (!node) return false;
27404
+ if (node.component !== BuiltinComponentTypeConst.Text) return false;
27405
+ const raw = node.raw;
27406
+ if (!raw || !isLayoutTextWidget(raw)) return false;
27407
+ return validateTextWidgetMarker(raw, checkMarker);
27408
+ }
27409
+ function validateTextWidgetMarker(raw, checkMarker) {
27410
+ const baseValid = raw.isWidgetRun;
27411
+ if (!checkMarker) {
27412
+ return baseValid;
27413
+ }
27414
+ return baseValid && !(raw.widgetFieldLeftMarker || raw.widgetFieldRightMarker);
27415
+ }
27416
+ function isClickPaperWidgetAllNode(node) {
27417
+ if (!node) return false;
27418
+ const raw = node.raw;
27419
+ return raw.isPageWidgetRun;
27420
+ }
27421
+ class TextHitHandler {
27422
+ handleHitDetection(doc, node, actualX, actualY) {
27423
+ const base = getBaseMetaInfo(node);
27424
+ if (doc.isInEditMode() && isClickSelectAllNode(node, false)) {
27425
+ const raw = node.raw;
27426
+ const modelId = raw.modelRef?.id;
27427
+ if (raw.widgetFieldLeftMarker || raw.widgetFieldRightMarker) {
27428
+ const side2 = raw.widgetFieldLeftMarker ? "before" : "after";
27429
+ return {
27430
+ ...base,
27431
+ offset: 0,
27432
+ side: side2
27433
+ };
27434
+ }
27435
+ if (!modelId) return null;
27436
+ const widgetIds = doc.layoutMapper.getModelSplitById(modelId);
27437
+ const nodes = doc.layoutMapper.getBaseMetaNodeByIds(widgetIds);
27438
+ if (!nodes?.length) return null;
27439
+ const filterNodes = nodes.filter(
27440
+ (node2) => !(node2.raw.widgetFieldLeftMarker || node2.raw.widgetFieldRightMarker)
27441
+ );
27442
+ const total = filterNodes.length;
27443
+ const midIndex = Math.floor(total / 2);
27444
+ const clickedIndex = filterNodes.findIndex((n) => n.id === node.id);
27445
+ let side = "after";
27446
+ if (clickedIndex < midIndex) {
27447
+ side = "before";
27448
+ } else if (clickedIndex > midIndex) {
27449
+ side = "after";
27450
+ } else {
27451
+ side = resolveMiddleSide(filterNodes[midIndex], actualX);
27452
+ }
27453
+ const targetNode = side === "after" ? filterNodes[total - 1] : filterNodes[0];
27454
+ return {
27455
+ ...getBaseMetaInfo(targetNode),
27456
+ offset: 0,
27457
+ side
27458
+ };
27459
+ }
27460
+ if (doc.isInFillMode() && !isClickSelectAllNode(node)) {
27461
+ return null;
27462
+ }
27463
+ if (Array.isArray(node.charOffsets) && node.charOffsets.length > 0) {
27464
+ return resolveCharHit(node, base, actualX);
27465
+ }
27466
+ return {
27467
+ ...base,
27468
+ offset: 0,
27469
+ side: "after"
27470
+ };
27471
+ }
27472
+ isClickSelectAll(doc, node) {
27473
+ return {
27474
+ type: "cursor"
27475
+ };
27476
+ }
27477
+ // todo 后续文本改成多文字一个节点可以处理
27478
+ // resolveCursorIntent(doc: Doc, node: BaseMetaNode, cursor: ICursorPosition) {
27479
+ // const base = getBaseMetaInfo(node);
27480
+ // const isPlaceholder = !!((node.raw as any).isPlaceholder);
27481
+ // if (isPlaceholder) {
27482
+ // return { ...base, isPlaceholder: true, offset: 0, side: cursor.side || 'before', };
27483
+ // }
27484
+ // const offsets = Array.isArray(node.charOffsets) ? node.charOffsets as number[] : undefined;
27485
+ // if (offsets && offsets.length > 0) {
27486
+ // let off = Number.isFinite(Number(cursor.offset)) ? Math.floor(Number(cursor.offset)) : 0;
27487
+ // off = Math.max(0, Math.min(off, offsets.length));
27488
+ // const side = off >= offsets.length ? 'after' : (cursor.side || 'before');
27489
+ // return { ...base, offset: off, side };
27490
+ // }
27491
+ // const off = Number.isFinite(Number(cursor.offset)) ? Math.max(0, Math.floor(Number(cursor.offset))) : 0;
27492
+ // return { ...base, offset: off, side: cursor.side || 'before' };
27493
+ // }
27494
+ }
27495
+ function toHorizontalIntervals(childMeta) {
27496
+ return childMeta.map((i) => {
27497
+ if (!i) return null;
27498
+ const left = i.absbox.left ?? 0;
27499
+ const right = i.absbox.right ?? left;
27500
+ return [left, right];
27501
+ }).filter(Boolean);
27502
+ }
27503
+ function toVerticalIntervalsAbs(doc, childMeta, pageId) {
27504
+ return childMeta.map((c2) => {
27505
+ if (!c2) return null;
27506
+ const top = doc.layoutMapper.getAbsoluteCanvasPosition(
27507
+ pageId,
27508
+ 0,
27509
+ c2.absbox.top,
27510
+ true
27511
+ ).y;
27512
+ const bottom = doc.layoutMapper.getAbsoluteCanvasPosition(
27513
+ pageId,
27514
+ 0,
27515
+ c2.absbox.bottom,
27516
+ true
27517
+ ).y;
27518
+ return [top, bottom];
27519
+ }).filter(Boolean);
27520
+ }
27521
+ function findIntervalIndex(intervals, actualX) {
27522
+ let left = 0;
27523
+ let right = intervals.length - 1;
27524
+ while (left <= right) {
27525
+ const mid = Math.floor((left + right) / 2);
27526
+ const [start, end] = intervals[mid];
27527
+ if (actualX >= start && actualX < end) return mid;
27528
+ if (actualX < start) right = mid - 1;
27529
+ else left = mid + 1;
27530
+ }
27531
+ return -1;
27532
+ }
27533
+ function getIntervalSide(intervals, actualX) {
27534
+ if (!intervals || !intervals.length) return null;
27535
+ const foundIndex = findIntervalIndex(intervals, actualX);
27536
+ if (foundIndex !== -1) {
27537
+ const [start, end] = intervals[foundIndex];
27538
+ const midpoint = (start + end) / 2;
27539
+ return {
27540
+ index: foundIndex,
27541
+ side: actualX < midpoint ? "before" : "after",
27542
+ distance: Math.min(actualX - start, end - actualX)
27543
+ };
27544
+ }
27545
+ let closestIndex = -1;
27546
+ let closestDistance = Infinity;
27547
+ let side = "before";
27548
+ for (let i = 0; i < intervals.length; i++) {
27549
+ const [start, end] = intervals[i];
27550
+ const distToStart = Math.abs(actualX - start);
27551
+ if (distToStart < closestDistance) {
27552
+ closestDistance = distToStart;
27553
+ closestIndex = i;
27554
+ side = actualX < start ? "before" : "after";
27555
+ }
27556
+ const distToEnd = Math.abs(actualX - end);
27557
+ if (distToEnd < closestDistance) {
27558
+ closestDistance = distToEnd;
27559
+ closestIndex = i;
27560
+ side = actualX < end ? "before" : "after";
27561
+ }
27562
+ }
27563
+ if (closestIndex !== -1) {
27564
+ return {
27565
+ index: closestIndex,
27566
+ side,
27567
+ distance: closestDistance
27568
+ };
26648
27569
  }
26649
27570
  return null;
26650
27571
  }
@@ -30915,48 +31836,6 @@ const __vite_glob_0_13$3 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.
30915
31836
  __proto__: null,
30916
31837
  Enter
30917
31838
  }, Symbol.toStringTag, { value: "Module" }));
30918
- function normalizeColor(color, defaultColor = "#000000") {
30919
- if (color === "auto" || !color) {
30920
- return defaultColor;
30921
- }
30922
- if (color.startsWith("#")) {
30923
- return color;
30924
- }
30925
- if (color.length === 8 && /^[0-9A-Fa-f]{8}$/.test(color)) {
30926
- const alpha = color.substring(0, 2);
30927
- const rgb = color.substring(2);
30928
- return `#${rgb}${alpha}`;
30929
- }
30930
- if (color.length === 6 && /^[0-9A-Fa-f]{6}$/.test(color)) {
30931
- return `#${color}`;
30932
- }
30933
- if (color.length === 3 && /^[0-9A-Fa-f]{3}$/.test(color)) {
30934
- return `#${color}`;
30935
- }
30936
- return color;
30937
- }
30938
- function repeat(count, callback) {
30939
- for (let i = 0; i < count; i++) {
30940
- callback(i);
30941
- }
30942
- }
30943
- function distributeInteger(total, count) {
30944
- if (count <= 0) throw new Error("count must be > 0");
30945
- if (total < 0) throw new Error("total must be >= 0");
30946
- const base = Math.floor(total / count);
30947
- const remainder = total % count;
30948
- const result = [];
30949
- for (let i = 0; i < count; i++) {
30950
- result.push(i < count - remainder ? base : base + 1);
30951
- }
30952
- return result;
30953
- }
30954
- const mainData2WordData = (data) => {
30955
- const entries = Object.entries(data).map(([key, value]) => {
30956
- return [`$.${key}`, value];
30957
- });
30958
- return Object.fromEntries(entries);
30959
- };
30960
31839
  class InsertCol extends CommandBase {
30961
31840
  constructor(doc, payload) {
30962
31841
  super(doc, payload);
@@ -31111,10 +31990,11 @@ class InsertField extends CommandBase {
31111
31990
  */
31112
31991
  isConsecutivePath(parentPath, childPath) {
31113
31992
  if (!parentPath || !childPath) return false;
31114
- if (!childPath.startsWith(parentPath)) {
31993
+ const _parentPath = parentPath.includes(":") ? parentPath.split(":")[0] : parentPath;
31994
+ if (!childPath.startsWith(_parentPath)) {
31115
31995
  return false;
31116
31996
  }
31117
- const remainder = childPath.slice(parentPath.length);
31997
+ const remainder = childPath.slice(_parentPath.length);
31118
31998
  if (remainder === "") {
31119
31999
  return false;
31120
32000
  }
@@ -31759,10 +32639,10 @@ class InsertText extends CommandBase {
31759
32639
  side: "after"
31760
32640
  };
31761
32641
  }
31762
- if (validateTextWidgetMarker(run, false) || run.isPageWidgetRun) {
32642
+ if (isLayoutTextWidget(run) && validateTextWidgetMarker(run, false) || run.isPageWidgetRun) {
31763
32643
  const wr2 = mapper.getModelNodeById(run.modelRef.id);
31764
32644
  if (!wr2) return null;
31765
- const raw = run;
32645
+ const raw = isLayoutTextWidget(run) ? run : run;
31766
32646
  if (raw.widgetFieldLeftMarker || raw.widgetFieldRightMarker || run.isPageWidgetRun) {
31767
32647
  const newWr = new WrText({ text });
31768
32648
  if (raw.widgetFieldLeftMarker) {
@@ -31796,6 +32676,7 @@ class InsertText extends CommandBase {
31796
32676
  };
31797
32677
  }
31798
32678
  }
32679
+ if (!isLayoutTextRun(run)) return null;
31799
32680
  const wr = mapper.getModelNodeById(run.modelRef.id);
31800
32681
  if (!wr) return null;
31801
32682
  const oldText = String(run.text || "").trim();
@@ -32128,7 +33009,7 @@ class SetAlign extends CommandBase {
32128
33009
  }
32129
33010
  const paragraphs = [];
32130
33011
  for (const { model } of models) {
32131
- if (model.type === "paragraph") {
33012
+ if (model.name === "w:p") {
32132
33013
  paragraphs.push(model);
32133
33014
  }
32134
33015
  }
@@ -38206,472 +39087,75 @@ const _sfc_main$2$ = /* @__PURE__ */ defineComponent({
38206
39087
  "left-content": withCtx(() => [
38207
39088
  createElementVNode("span", {
38208
39089
  class: "color-icon read-only",
38209
- style: normalizeStyle({ backgroundColor: model.value })
38210
- }, null, 4)
38211
- ]),
38212
- _: 1
38213
- }, 8, ["tooltip"]);
38214
- };
38215
- }
38216
- });
38217
- const GctColorPicker = /* @__PURE__ */ _export_sfc(_sfc_main$2$, [["__scopeId", "data-v-a0f4e1cb"]]);
38218
- const DefaultAvatar = "data:image/png;base64,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";
38219
- let urlCacheMap = {};
38220
- function transformUrl(url2, { random = true } = {}) {
38221
- if (!url2) {
38222
- return "/404.png";
38223
- }
38224
- let basePath = "/minio";
38225
- const url22 = `${basePath}${url2.startsWith("/") ? "" : "/"}${url2}`;
38226
- if (!random) return url22;
38227
- if (urlCacheMap[url2] && Date.now() - urlCacheMap[url2].timestamp < 60 * 1e3) {
38228
- return `${url22}?${urlCacheMap[url2].random}`;
38229
- }
38230
- if (Object.keys(urlCacheMap).length > 100) urlCacheMap = {};
38231
- const r = Math.random();
38232
- urlCacheMap[url2] = {
38233
- random: r,
38234
- timestamp: Date.now()
38235
- };
38236
- return `${url22}?${r}`;
38237
- }
38238
- const _hoisted_1$1V = { class: "avatar__avatar" };
38239
- const _hoisted_2$1d = ["src"];
38240
- const _hoisted_3$U = {
38241
- key: 0,
38242
- class: "avatar__name"
38243
- };
38244
- const _sfc_main$2_ = /* @__PURE__ */ defineComponent({
38245
- __name: "Avatar",
38246
- props: {
38247
- avatar: {},
38248
- name: {},
38249
- direction: { default: "vertical" }
38250
- },
38251
- setup(__props) {
38252
- const props = __props;
38253
- const avatarUrl = computed(() => {
38254
- return props.avatar ? transformUrl(props.avatar) : DefaultAvatar;
38255
- });
38256
- return (_ctx, _cache) => {
38257
- return openBlock(), createElementBlock("div", {
38258
- class: normalizeClass(["avatar", `avatar--${__props.direction}`])
38259
- }, [
38260
- createElementVNode("div", _hoisted_1$1V, [
38261
- createElementVNode("img", {
38262
- class: "avatar__avatar-img",
38263
- src: avatarUrl.value
38264
- }, null, 8, _hoisted_2$1d)
38265
- ]),
38266
- __props.name ? (openBlock(), createElementBlock("div", _hoisted_3$U, toDisplayString(__props.name), 1)) : createCommentVNode("", true)
38267
- ], 2);
38268
- };
38269
- }
38270
- });
38271
- const GctAvatar = /* @__PURE__ */ _export_sfc(_sfc_main$2_, [["__scopeId", "data-v-b2773d93"]]);
38272
- class SetBoundedItem extends CommandBase {
38273
- constructor(doc, payload) {
38274
- super(doc, payload);
38275
- }
38276
- async execute() {
38277
- const cursor = this.doc.cursorManager;
38278
- if (cursor.isCollapsed()) return null;
38279
- const { mode, models } = CommandBase.getSelectionResult(this.doc, cursor.getSelection());
38280
- if (mode !== SelectionMode.Tds) return null;
38281
- if (models.length === 0) return null;
38282
- const startCell = models[0].model;
38283
- const endCell = models[models.length - 1].model;
38284
- const start = {
38285
- row: startCell.parent?.getCurrentIndex(),
38286
- col: startCell.getCurrentIndex()
38287
- };
38288
- const end = {
38289
- row: endCell.parent?.getCurrentIndex(),
38290
- col: endCell.getCurrentIndex()
38291
- };
38292
- const boundedRegion = this.getBoundedRegion(startCell, endCell);
38293
- if (!boundedRegion) {
38294
- GctMessage.warning("选区不在固定表范围内");
38295
- throw new Error("Cells are not in a bounded region");
38296
- }
38297
- this.output = boundedRegion.setItemRegion({
38298
- start,
38299
- end
38300
- });
38301
- return null;
38302
- }
38303
- /**
38304
- *
38305
- * @param startCell
38306
- * @param endCell
38307
- * @returns
38308
- */
38309
- getBoundedRegion(startCell, endCell) {
38310
- const region = this.getRegion(startCell, endCell);
38311
- if (!region) {
38312
- GctMessage.warning("选区超出子表范围");
38313
- throw new Error("Cells are not in the same region");
38314
- }
38315
- return region.type === "bounded" ? region : void 0;
38316
- }
38317
- /**
38318
- * 获取公共区域
38319
- * @param startCell
38320
- * @param endCell
38321
- * @returns
38322
- */
38323
- getRegion(startCell, endCell) {
38324
- if (startCell === endCell) {
38325
- return startCell.getRegion();
38326
- }
38327
- const startRegion = startCell.getRegion();
38328
- const endRegion = endCell.getRegion();
38329
- if (startRegion && endRegion && startRegion === endRegion) {
38330
- return startRegion;
38331
- }
38332
- return;
38333
- }
38334
- }
38335
- const __vite_glob_0_31$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
38336
- __proto__: null,
38337
- SetBoundedItem
38338
- }, Symbol.toStringTag, { value: "Module" }));
38339
- class SetCheckTable extends CommandBase {
38340
- constructor(doc, payload) {
38341
- super(doc, payload);
38342
- }
38343
- async execute() {
38344
- const cursor = this.doc.cursorManager;
38345
- if (cursor.isCollapsed()) return null;
38346
- const { mode, models } = CommandBase.getSelectionResult(this.doc, cursor.getSelection());
38347
- if (mode !== SelectionMode.Tds) return null;
38348
- if (models.length === 0) return null;
38349
- const startCell = models[0].model;
38350
- const endCell = models[models.length - 1].model;
38351
- const start = {
38352
- row: startCell.parent?.getCurrentIndex(),
38353
- col: startCell.getCurrentIndex()
38354
- };
38355
- const end = {
38356
- row: endCell.parent?.getCurrentIndex(),
38357
- col: endCell.getCurrentIndex()
38358
- };
38359
- this.output = startCell.table.setCheckTable({
38360
- start,
38361
- end,
38362
- name: this.payload.name,
38363
- valuePath: this.payload.valuePath
38364
- });
38365
- return null;
38366
- }
38367
- }
38368
- const __vite_glob_0_32$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
38369
- __proto__: null,
38370
- SetCheckTable
38371
- }, Symbol.toStringTag, { value: "Module" }));
38372
- class SetColor extends SetStyleBase {
38373
- constructor(doc, payload) {
38374
- super(doc, payload);
38375
- }
38376
- applyStyle(run) {
38377
- run.setColor(this.payload.color);
38378
- }
38379
- }
38380
- const __vite_glob_0_33$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
38381
- __proto__: null,
38382
- SetColor
38383
- }, Symbol.toStringTag, { value: "Module" }));
38384
- class SetDataGroup2D extends CommandBase {
38385
- constructor(doc, payload) {
38386
- super(doc, payload);
38387
- }
38388
- async execute() {
38389
- const cursor = this.doc.cursorManager;
38390
- if (cursor.isCollapsed()) return null;
38391
- const { mode, models } = CommandBase.getSelectionResult(this.doc, cursor.getSelection());
38392
- if (mode !== SelectionMode.Tds) return null;
38393
- if (models.length === 0) return null;
38394
- const startCell = models[0].model;
38395
- const endCell = models[models.length - 1].model;
38396
- const cellList = [...models.map((m) => m.model)];
38397
- const start = {
38398
- row: startCell.parent?.getCurrentIndex(),
38399
- col: startCell.getCurrentIndex()
38400
- };
38401
- const end = {
38402
- row: endCell.parent?.getCurrentIndex(),
38403
- col: endCell.getCurrentIndex()
38404
- };
38405
- const subTableRegion = this.getSubTableRegion(cellList);
38406
- if (!subTableRegion) {
38407
- throw new Error("Cells are not in a sub table region supporting data-group-2d");
38408
- }
38409
- this.output = subTableRegion.setItemRegion({
38410
- start,
38411
- end
38412
- });
38413
- return null;
38414
- }
38415
- /**
38416
- *
38417
- * @param cellList
38418
- * @returns
38419
- */
38420
- getSubTableRegion(cellList) {
38421
- let region;
38422
- cellList.some((cell) => {
38423
- const r = cell.getRegion();
38424
- if (r && ["check-table", "2d-table"].includes(r.type)) {
38425
- region = r;
38426
- return true;
38427
- }
38428
- });
38429
- if (!region) {
38430
- throw new Error("No region found");
38431
- }
38432
- return region;
38433
- }
38434
- }
38435
- const __vite_glob_0_34$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
38436
- __proto__: null,
38437
- SetDataGroup2D
38438
- }, Symbol.toStringTag, { value: "Module" }));
38439
- class SetFont extends SetStyleBase {
38440
- constructor(doc, payload) {
38441
- super(doc, payload);
38442
- }
38443
- applyStyle(run) {
38444
- run.setFont(this.payload.fontFamily);
38445
- }
38446
- }
38447
- const __vite_glob_0_35$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
38448
- __proto__: null,
38449
- SetFont
38450
- }, Symbol.toStringTag, { value: "Module" }));
38451
- class SetFontSize extends SetStyleBase {
38452
- constructor(doc, payload) {
38453
- super(doc, payload);
38454
- this.needsCalculatePostCommandContext = true;
38455
- }
38456
- applyStyle(run) {
38457
- run.setFontSize(this.payload.fontSize * 2);
38458
- }
38459
- }
38460
- const __vite_glob_0_36$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
38461
- __proto__: null,
38462
- SetFontSize
38463
- }, Symbol.toStringTag, { value: "Module" }));
38464
- class SetHeaderFooterConfig extends CommandBase {
38465
- constructor(doc, payload) {
38466
- super(doc, payload);
38467
- }
38468
- async execute() {
38469
- const { headerMargin, footerMargin, titlePg, evenAndOddHeaders } = this.payload;
38470
- this.doc?.eventManager.cursorController.clearCursor();
38471
- const sections = (this.doc.model?.document.body.children ?? []).filter(
38472
- (item) => item.name === "w:secPr"
38473
- );
38474
- if (sections.length === 0) {
38475
- this.isTerminated = true;
38476
- return null;
38477
- }
38478
- for (const section of sections) {
38479
- if (headerMargin !== void 0) {
38480
- section.setHeaderMargin(headerMargin);
38481
- }
38482
- if (footerMargin !== void 0) {
38483
- section.setFooterMargin(footerMargin);
38484
- }
38485
- if (titlePg !== void 0) {
38486
- section.setTitlePg(titlePg);
38487
- }
38488
- }
38489
- if (evenAndOddHeaders !== void 0) {
38490
- this.doc.model?.settings.setEvenAndOddHeaders(evenAndOddHeaders);
38491
- }
38492
- return null;
38493
- }
38494
- }
38495
- const __vite_glob_0_37$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
38496
- __proto__: null,
38497
- SetHeaderFooterConfig
38498
- }, Symbol.toStringTag, { value: "Module" }));
38499
- class SetHighlight extends SetStyleBase {
38500
- constructor(doc, payload) {
38501
- super(doc, payload);
38502
- }
38503
- applyStyle(run) {
38504
- run.setHighlight(this.payload.highlight);
38505
- }
38506
- }
38507
- const __vite_glob_0_38$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
38508
- __proto__: null,
38509
- SetHighlight
38510
- }, Symbol.toStringTag, { value: "Module" }));
38511
- class SetItalic extends SetStyleBase {
38512
- constructor(doc, payload) {
38513
- super(doc, payload);
38514
- }
38515
- applyStyle(run) {
38516
- run.setItalic(this.payload?.italic ?? true);
38517
- }
38518
- }
38519
- const __vite_glob_0_39$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
38520
- __proto__: null,
38521
- SetItalic
38522
- }, Symbol.toStringTag, { value: "Module" }));
38523
- class SetOrient extends CommandBase {
38524
- constructor(doc, payload) {
38525
- super(doc, payload);
38526
- }
38527
- async execute() {
38528
- const { orient, serRefId } = this.payload;
38529
- if (!["portrait", "landscape"].includes(orient)) {
38530
- throw new Error(`Invalid orientation: ${orient}`);
38531
- }
38532
- if (!serRefId) {
38533
- this.isTerminated = true;
38534
- return null;
38535
- }
38536
- const section = this.doc.model?.document.body.children.find(
38537
- (item) => item.id === serRefId
38538
- );
38539
- if (!section) {
38540
- this.isTerminated = true;
38541
- return null;
38542
- }
38543
- section.setOrient(orient);
38544
- return null;
38545
- }
38546
- }
38547
- const __vite_glob_0_40$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
38548
- __proto__: null,
38549
- SetOrient
38550
- }, Symbol.toStringTag, { value: "Module" }));
38551
- class SetPadding extends CommandBase {
38552
- constructor(doc, payload) {
38553
- super(doc, payload);
38554
- }
38555
- async execute() {
38556
- const { padding, serRefId } = this.payload;
38557
- if (!serRefId) {
38558
- this.isTerminated = true;
38559
- return null;
38560
- }
38561
- const section = this.doc.model?.document.body.children.find(
38562
- (item) => item.id === serRefId
38563
- );
38564
- if (!section) {
38565
- this.isTerminated = true;
38566
- return null;
38567
- }
38568
- const [top, right, bottom, left] = padding;
38569
- section.setMargins(top, bottom, left, right);
38570
- return null;
38571
- }
38572
- }
38573
- const __vite_glob_0_41$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
38574
- __proto__: null,
38575
- SetPadding
38576
- }, Symbol.toStringTag, { value: "Module" }));
38577
- class SetRepeating extends CommandBase {
38578
- constructor(doc, payload) {
38579
- super(doc, payload);
38580
- }
38581
- async execute() {
38582
- const cursor = this.doc.cursorManager;
38583
- if (cursor.isCollapsed()) return null;
38584
- const { mode, models } = CommandBase.getSelectionResult(this.doc, cursor.getSelection());
38585
- if (mode !== SelectionMode.Tds) return null;
38586
- if (models.length === 0) return null;
38587
- const startCell = models[0].model;
38588
- const endCell = models[models.length - 1].model;
38589
- const start = {
38590
- row: startCell.parent?.getCurrentIndex(),
38591
- col: startCell.getCurrentIndex()
38592
- };
38593
- const end = {
38594
- row: endCell.parent?.getCurrentIndex(),
38595
- col: endCell.getCurrentIndex()
38596
- };
38597
- this.output = startCell.table.setRepeating({
38598
- start,
38599
- end,
38600
- name: this.payload.name,
38601
- valuePath: this.payload.valuePath
38602
- });
38603
- return null;
39090
+ style: normalizeStyle({ backgroundColor: model.value })
39091
+ }, null, 4)
39092
+ ]),
39093
+ _: 1
39094
+ }, 8, ["tooltip"]);
39095
+ };
38604
39096
  }
38605
- }
38606
- const __vite_glob_0_42$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
38607
- __proto__: null,
38608
- SetRepeating
38609
- }, Symbol.toStringTag, { value: "Module" }));
38610
- class SetStrike extends SetStyleBase {
38611
- constructor(doc, payload) {
38612
- super(doc, payload);
39097
+ });
39098
+ const GctColorPicker = /* @__PURE__ */ _export_sfc(_sfc_main$2$, [["__scopeId", "data-v-a0f4e1cb"]]);
39099
+ const DefaultAvatar = "data:image/png;base64,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";
39100
+ let urlCacheMap = {};
39101
+ function transformUrl(url2, { random = true } = {}) {
39102
+ if (!url2) {
39103
+ return "/404.png";
38613
39104
  }
38614
- applyStyle(run) {
38615
- run.setStrike(this.payload.strike);
39105
+ let basePath = "/minio";
39106
+ const url22 = `${basePath}${url2.startsWith("/") ? "" : "/"}${url2}`;
39107
+ if (!random) return url22;
39108
+ if (urlCacheMap[url2] && Date.now() - urlCacheMap[url2].timestamp < 60 * 1e3) {
39109
+ return `${url22}?${urlCacheMap[url2].random}`;
38616
39110
  }
39111
+ if (Object.keys(urlCacheMap).length > 100) urlCacheMap = {};
39112
+ const r = Math.random();
39113
+ urlCacheMap[url2] = {
39114
+ random: r,
39115
+ timestamp: Date.now()
39116
+ };
39117
+ return `${url22}?${r}`;
38617
39118
  }
38618
- const __vite_glob_0_43 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
38619
- __proto__: null,
38620
- SetStrike
38621
- }, Symbol.toStringTag, { value: "Module" }));
38622
- class SetSubTableHeader extends CommandBase {
38623
- constructor(doc, payload) {
38624
- super(doc, payload);
38625
- }
38626
- async execute() {
38627
- const cursor = this.doc.cursorManager;
38628
- const { name } = this.payload;
38629
- if (cursor.isCollapsed()) return null;
38630
- const { mode, models } = CommandBase.getSelectionResult(this.doc, cursor.getSelection());
38631
- if (mode !== SelectionMode.Tds) return null;
38632
- if (models.length === 0) return null;
38633
- const startCell = models[0].model;
38634
- const endCell = models[models.length - 1].model;
38635
- const start = {
38636
- row: startCell.parent?.getCurrentIndex(),
38637
- col: startCell.getCurrentIndex()
38638
- };
38639
- const end = {
38640
- row: endCell.parent?.getCurrentIndex(),
38641
- col: endCell.getCurrentIndex()
38642
- };
38643
- const region = this.getSubTableRegion(endCell.table, end.row);
38644
- if (!region) {
38645
- GctMessage.warning("没有找到对应子表");
38646
- return null;
38647
- }
38648
- const crossRegion = startCell.table.findCrossRegion({ start, end });
38649
- crossRegion && startCell.table.deleteRegionById(crossRegion.id);
38650
- this.output = startCell.table.setSubTableHeader({
38651
- start,
38652
- end,
38653
- name,
38654
- subTableId: region.id
38655
- });
38656
- return null;
38657
- }
38658
- getSubTableRegion(table, rowIndex) {
38659
- return table.regions.find((region) => {
38660
- return region.start.row === rowIndex + 1 && ["repeating", "bounded", "check-table", "2d-table"].includes(region.type);
39119
+ const _hoisted_1$1V = { class: "avatar__avatar" };
39120
+ const _hoisted_2$1d = ["src"];
39121
+ const _hoisted_3$U = {
39122
+ key: 0,
39123
+ class: "avatar__name"
39124
+ };
39125
+ const _sfc_main$2_ = /* @__PURE__ */ defineComponent({
39126
+ __name: "Avatar",
39127
+ props: {
39128
+ avatar: {},
39129
+ name: {},
39130
+ direction: { default: "vertical" }
39131
+ },
39132
+ setup(__props) {
39133
+ const props = __props;
39134
+ const avatarUrl = computed(() => {
39135
+ return props.avatar ? transformUrl(props.avatar) : DefaultAvatar;
38661
39136
  });
39137
+ return (_ctx, _cache) => {
39138
+ return openBlock(), createElementBlock("div", {
39139
+ class: normalizeClass(["avatar", `avatar--${__props.direction}`])
39140
+ }, [
39141
+ createElementVNode("div", _hoisted_1$1V, [
39142
+ createElementVNode("img", {
39143
+ class: "avatar__avatar-img",
39144
+ src: avatarUrl.value
39145
+ }, null, 8, _hoisted_2$1d)
39146
+ ]),
39147
+ __props.name ? (openBlock(), createElementBlock("div", _hoisted_3$U, toDisplayString(__props.name), 1)) : createCommentVNode("", true)
39148
+ ], 2);
39149
+ };
38662
39150
  }
38663
- }
38664
- const __vite_glob_0_44 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
38665
- __proto__: null,
38666
- SetSubTableHeader
38667
- }, Symbol.toStringTag, { value: "Module" }));
38668
- class SetTableHeader extends CommandBase {
39151
+ });
39152
+ const GctAvatar = /* @__PURE__ */ _export_sfc(_sfc_main$2_, [["__scopeId", "data-v-b2773d93"]]);
39153
+ class SetBoundedItem extends CommandBase {
38669
39154
  constructor(doc, payload) {
38670
39155
  super(doc, payload);
38671
39156
  }
38672
39157
  async execute() {
38673
39158
  const cursor = this.doc.cursorManager;
38674
- const { name } = this.payload;
38675
39159
  if (cursor.isCollapsed()) return null;
38676
39160
  const { mode, models } = CommandBase.getSelectionResult(this.doc, cursor.getSelection());
38677
39161
  if (mode !== SelectionMode.Tds) return null;
@@ -38686,889 +39170,618 @@ class SetTableHeader extends CommandBase {
38686
39170
  row: endCell.parent?.getCurrentIndex(),
38687
39171
  col: endCell.getCurrentIndex()
38688
39172
  };
38689
- this.output = startCell.table.setTableHeader({
38690
- start,
38691
- end,
38692
- name
38693
- });
38694
- return null;
38695
- }
38696
- }
38697
- const __vite_glob_0_45 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
38698
- __proto__: null,
38699
- SetTableHeader
38700
- }, Symbol.toStringTag, { value: "Module" }));
38701
- class SetUnderline extends SetStyleBase {
38702
- constructor(doc, payload) {
38703
- super(doc, payload);
38704
- }
38705
- applyStyle(run) {
38706
- run.setUnderline(this.payload?.underline ?? "single");
38707
- }
38708
- }
38709
- const __vite_glob_0_46 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
38710
- __proto__: null,
38711
- SetUnderline
38712
- }, Symbol.toStringTag, { value: "Module" }));
38713
- class Snapshot extends CommandBase {
38714
- constructor(doc, payload) {
38715
- super(doc, payload);
38716
- }
38717
- async execute() {
38718
- return null;
38719
- }
38720
- }
38721
- const __vite_glob_0_47 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
38722
- __proto__: null,
38723
- Snapshot
38724
- }, Symbol.toStringTag, { value: "Module" }));
38725
- class UnmergeCells extends CommandBase {
38726
- constructor(doc, payload) {
38727
- super(doc, payload);
38728
- }
38729
- async execute() {
38730
- const cursor = this.doc.cursorManager;
38731
- if (cursor.isCollapsed()) return;
38732
- const { mode, models } = CommandBase.getSelectionResult(this.doc, cursor.getSelection());
38733
- if (mode !== SelectionMode.Tds) return;
38734
- if (models.length === 0) return;
38735
- const roots = models.map(({ model }) => model).filter((cell) => cell.id === cell.mergeId && !cell.mergeFromId);
38736
- if (roots.length === 0) return null;
38737
- const table = roots[0]?.table;
38738
- if (!table) return null;
38739
- table.runConsistencyMutation({
38740
- mutate: () => {
38741
- roots.forEach((cell) => {
38742
- cell.unmerge({ skipConsistency: true });
38743
- });
38744
- }
38745
- });
38746
- const mapper = this.doc.layoutMapper;
38747
- const normalized = this.doc.cursorManager.normalizeRange(cursor.getSelection());
38748
- const start = mapper.getLayoutNodeById(normalized.rangeStart.nodeId);
38749
- if (start?.isPlaceholderRun) {
38750
- const wp = mapper.getModelNodeById(start.parent.modelRef.id);
38751
- return {
38752
- wp,
38753
- pos: -1,
38754
- side: "after"
38755
- };
38756
- }
38757
- const wr = mapper.getModelNodeById(start.modelRef.id);
38758
- return {
38759
- wr,
38760
- pos: -1,
38761
- side: "after"
38762
- };
38763
- }
38764
- }
38765
- const __vite_glob_0_48 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
38766
- __proto__: null,
38767
- UnmergeCells
38768
- }, Symbol.toStringTag, { value: "Module" }));
38769
- const commandModules = /* @__PURE__ */ Object.assign({
38770
- "./commands/Backspace.ts": __vite_glob_0_0$4,
38771
- "./commands/CommitValidateNumber.ts": __vite_glob_0_1$4,
38772
- "./commands/Delete.ts": __vite_glob_0_2$4,
38773
- "./commands/Delete2DTable.ts": __vite_glob_0_3$4,
38774
- "./commands/DeleteBounded.ts": __vite_glob_0_4$4,
38775
- "./commands/DeleteBoundedItem.ts": __vite_glob_0_5$4,
38776
- "./commands/DeleteCheckTable.ts": __vite_glob_0_6$4,
38777
- "./commands/DeleteCol.ts": __vite_glob_0_7$3,
38778
- "./commands/DeleteDataGroup2D.ts": __vite_glob_0_8$3,
38779
- "./commands/DeleteRepeating.ts": __vite_glob_0_9$3,
38780
- "./commands/DeleteRow.ts": __vite_glob_0_10$3,
38781
- "./commands/DeleteTable.ts": __vite_glob_0_11$3,
38782
- "./commands/DeleteTableHeader.ts": __vite_glob_0_12$3,
38783
- "./commands/Enter.ts": __vite_glob_0_13$3,
38784
- "./commands/InsertCol.ts": __vite_glob_0_14$2,
38785
- "./commands/InsertField.ts": __vite_glob_0_15$2,
38786
- "./commands/InsertFloatingOverlay.ts": __vite_glob_0_16$1,
38787
- "./commands/InsertImage.ts": __vite_glob_0_17$1,
38788
- "./commands/InsertPaperWidget.ts": __vite_glob_0_18$1,
38789
- "./commands/InsertRow.ts": __vite_glob_0_19$1,
38790
- "./commands/InsertTable.ts": __vite_glob_0_20$1,
38791
- "./commands/InsertText.ts": __vite_glob_0_21$1,
38792
- "./commands/MergeCells.ts": __vite_glob_0_22$1,
38793
- "./commands/ResizeCol.ts": __vite_glob_0_23$1,
38794
- "./commands/ResizeImage.ts": __vite_glob_0_24$1,
38795
- "./commands/ResizeOverlayLayout.ts": __vite_glob_0_25$1,
38796
- "./commands/ResizeRow.ts": __vite_glob_0_26$1,
38797
- "./commands/Set2DTable.ts": __vite_glob_0_27$1,
38798
- "./commands/SetAlign.ts": __vite_glob_0_28$1,
38799
- "./commands/SetBold.ts": __vite_glob_0_29$1,
38800
- "./commands/SetBounded.ts": __vite_glob_0_30$1,
38801
- "./commands/SetBoundedItem.ts": __vite_glob_0_31$1,
38802
- "./commands/SetCheckTable.ts": __vite_glob_0_32$1,
38803
- "./commands/SetColor.ts": __vite_glob_0_33$1,
38804
- "./commands/SetDataGroup2D.ts": __vite_glob_0_34$1,
38805
- "./commands/SetFont.ts": __vite_glob_0_35$1,
38806
- "./commands/SetFontSize.ts": __vite_glob_0_36$1,
38807
- "./commands/SetHeaderFooterConfig.ts": __vite_glob_0_37$1,
38808
- "./commands/SetHighlight.ts": __vite_glob_0_38$1,
38809
- "./commands/SetItalic.ts": __vite_glob_0_39$1,
38810
- "./commands/SetOrient.ts": __vite_glob_0_40$1,
38811
- "./commands/SetPadding.ts": __vite_glob_0_41$1,
38812
- "./commands/SetRepeating.ts": __vite_glob_0_42$1,
38813
- "./commands/SetStrike.ts": __vite_glob_0_43,
38814
- "./commands/SetSubTableHeader.ts": __vite_glob_0_44,
38815
- "./commands/SetTableHeader.ts": __vite_glob_0_45,
38816
- "./commands/SetUnderline.ts": __vite_glob_0_46,
38817
- "./commands/Snapshot.ts": __vite_glob_0_47,
38818
- "./commands/UnmergeCells.ts": __vite_glob_0_48
38819
- });
38820
- function toCamelCase(pascalCase) {
38821
- return pascalCase.charAt(0).toLowerCase() + pascalCase.slice(1);
38822
- }
38823
- function getClassNameFromPath(path2) {
38824
- return path2.split("/").pop()?.replace(".ts", "") ?? "";
38825
- }
38826
- function buildCommandMap() {
38827
- const map2 = {};
38828
- Object.entries(commandModules).forEach(([path2, module2]) => {
38829
- const expectedClassName = getClassNameFromPath(path2);
38830
- const CommandClass = module2[expectedClassName];
38831
- if (CommandClass && typeof CommandClass === "function") {
38832
- const commandName = toCamelCase(expectedClassName);
38833
- map2[commandName] = CommandClass;
38834
- }
38835
- });
38836
- return map2;
38837
- }
38838
- class CommandManager {
38839
- registry = /* @__PURE__ */ new Map();
38840
- doc;
38841
- undoStack = [];
38842
- redoStack = [];
38843
- composition;
38844
- // 命令注册表 - 通过动态导入构建
38845
- static COMMAND_MAP = buildCommandMap();
38846
- constructor(doc) {
38847
- this.doc = doc;
38848
- Object.entries(CommandManager.COMMAND_MAP).forEach(([name, CommandClass]) => {
38849
- this.register(name, CommandClass);
38850
- });
38851
- }
38852
- register(name, CommandClass) {
38853
- this.registry.set(name, CommandClass);
38854
- }
38855
- async execute(name, payload) {
38856
- const CommandClass = this.registry.get(name);
38857
- if (!CommandClass) throw new Error(`Unknown command: ${name}`);
38858
- const cmd = new CommandClass(this.doc, payload);
38859
- const result = await cmd.do();
38860
- result && this.updateCursor(result);
38861
- payload?.doCallback && this.runCallback(payload.doCallback, result, cmd.output);
38862
- if (cmd.isTerminated) return;
38863
- this.undoStack.push(cmd);
38864
- this.redoStack.length = 0;
38865
- }
38866
- async undo() {
38867
- const cmd = this.undoStack.pop();
38868
- if (!cmd) return;
38869
- const result = await cmd.undo();
38870
- result && this.updateCursor(result);
38871
- cmd.payload?.undoCallback && this.runCallback(cmd.payload?.undoCallback, result);
38872
- this.redoStack.push(cmd);
38873
- }
38874
- async redo() {
38875
- const cmd = this.redoStack.pop();
38876
- if (!cmd) return;
38877
- const result = await cmd.do();
38878
- result && this.updateCursor(result);
38879
- cmd.payload?.doCallback && this.runCallback(cmd.payload?.doCallback, result);
38880
- this.undoStack.push(cmd);
38881
- }
38882
- compositionStart(text) {
38883
- }
38884
- compositionUpdate(text) {
38885
- }
38886
- compositionEnd(text) {
38887
- this.doc.commandManager.execute(CommandType.insertText, {
38888
- text
38889
- });
38890
- }
38891
- updateCursor(data) {
38892
- if (!data) return;
38893
- if (Array.isArray(data)) {
38894
- const [startData, endData] = data;
38895
- this.doc.eventManager.cursorController?.resolveCursorRange(startData, endData);
38896
- } else {
38897
- this.doc.eventManager.cursorController?.resolveCursorAtNode?.(data);
38898
- }
38899
- }
38900
- runCallback(callback, data, output) {
38901
- if (typeof callback === "function") {
38902
- callback(data, output);
38903
- }
38904
- }
38905
- }
38906
- class LayoutNode {
38907
- /** 唯一标识符 */
38908
- id;
38909
- /** 组件类型 */
38910
- component;
38911
- /** 所属文档 */
38912
- doc;
38913
- /** 父节点 */
38914
- parent;
38915
- /** 在父容器中的相对 X 坐标 */
38916
- x = 0;
38917
- /** 在父容器中的相对 Y 坐标 */
38918
- y = 0;
38919
- /** 布局后的绝对 X 坐标 */
38920
- layoutX = 0;
38921
- /** 布局后的绝对 Y 坐标 */
38922
- layoutY = 0;
38923
- modelRef;
38924
- // valuePath?: string;
38925
- /** 宽度 */
38926
- _width = 0;
38927
- /** 高度 */
38928
- _height = 0;
38929
- constructor(options) {
38930
- this.id = options.id ?? uuid();
38931
- this.doc = options.doc;
38932
- if (options.x !== void 0) this.x = options.x;
38933
- if (options.y !== void 0) this.y = options.y;
38934
- if (options.width !== void 0) this._width = options.width;
38935
- if (options.height !== void 0) this._height = options.height;
38936
- this.modelRef = options.modelRef;
38937
- this.modelRef && this.doc.layoutMapper.recordModelSplit(this.modelRef?.id, this.id);
38938
- }
38939
- get width() {
38940
- return this._width;
38941
- }
38942
- get height() {
38943
- return this._height;
38944
- }
38945
- set width(value) {
38946
- this._width = value;
38947
- }
38948
- set height(value) {
38949
- this._height = value;
38950
- }
38951
- get page() {
38952
- return this.getPage();
38953
- }
38954
- get isWidgetRun() {
38955
- return "widgetMeta" in this && !!this.widgetMeta;
38956
- }
38957
- get isPageWidgetRun() {
38958
- return "pageWidgetMeta" in this && !!this.pageWidgetMeta;
38959
- }
38960
- get isSubRenderer() {
38961
- return "subRenderer" in this && !!this.subRenderer;
38962
- }
38963
- get isPlaceholderRun() {
38964
- return "isPlaceholder" in this && this.isPlaceholder === true;
38965
- }
38966
- /**
38967
- * 获取实例对应的 page
38968
- * tips 表格第一次初始化无 page,target 可能为空
38969
- * @returns
38970
- */
38971
- getPage() {
38972
- let target = this;
38973
- while (target && target.constructor.name !== "Page") {
38974
- target = target.parent;
38975
- }
38976
- return target;
38977
- }
38978
- getOverlayLayout() {
38979
- let target = this;
38980
- while (target && target.constructor.name !== "OverlayLayout") {
38981
- target = target.parent;
39173
+ const boundedRegion = this.getBoundedRegion(startCell, endCell);
39174
+ if (!boundedRegion) {
39175
+ GctMessage.warning("选区不在固定表范围内");
39176
+ throw new Error("Cells are not in a bounded region");
38982
39177
  }
38983
- return target;
38984
- }
38985
- /**
38986
- * 布局方法:计算并设置节点的绝对位置
38987
- * @param x 绝对 X 坐标
38988
- * @param y 绝对 Y 坐标
38989
- */
38990
- layout(x2 = 0, y2 = 0) {
38991
- this.layoutX = x2;
38992
- this.layoutY = y2;
38993
- }
38994
- }
38995
- class LayoutGroup extends LayoutNode {
38996
- /** 子节点列表 */
38997
- children = [];
38998
- _padding = [0, 0, 0, 0];
38999
- constructor(options) {
39000
- super(options);
39001
- }
39002
- get padding() {
39003
- return this._padding ?? [0, 0, 0, 0];
39004
- }
39005
- get pt() {
39006
- return this.padding[0];
39007
- }
39008
- get pr() {
39009
- return this.padding[1];
39010
- }
39011
- get pb() {
39012
- return this.padding[2];
39013
- }
39014
- get pl() {
39015
- return this.padding[3];
39016
- }
39017
- /**
39018
- * 添加子节点
39019
- * @param child 要添加的子节点
39020
- */
39021
- addChild(child) {
39022
- this.children.push(child);
39023
- child.parent = this;
39024
- }
39025
- /**
39026
- * 在指定位置插入子节点
39027
- * @param index 插入位置
39028
- * @param child 要插入的子节点
39029
- */
39030
- insertChild(index2, child) {
39031
- this.children.splice(index2, 0, child);
39032
- child.parent = this;
39033
- }
39034
- /**
39035
- * 批量添加子节点
39036
- * @param children 要添加的子节点数组
39037
- */
39038
- addChildren(children) {
39039
- children.forEach((child) => {
39040
- this.children.push(child);
39041
- child.parent = this;
39042
- });
39043
- }
39044
- /**
39045
- * 在指定位置批量插入子节点
39046
- * @param index 插入位置
39047
- * @param children 要插入的子节点数组
39048
- */
39049
- insertChildren(index2, children) {
39050
- this.children.splice(index2, 0, ...children);
39051
- children.forEach((child) => {
39052
- child.parent = this;
39178
+ this.output = boundedRegion.setItemRegion({
39179
+ start,
39180
+ end
39053
39181
  });
39182
+ return null;
39054
39183
  }
39055
39184
  /**
39056
- * 移除子节点
39057
- * @param child 要移除的子节点
39058
- * @returns 是否成功移除
39059
- */
39060
- removeChild(child) {
39061
- const index2 = this.children.indexOf(child);
39062
- if (index2 !== -1) {
39063
- this.children.splice(index2, 1);
39064
- child.parent = void 0;
39065
- return true;
39066
- }
39067
- return false;
39068
- }
39069
- /**
39070
- * 根据索引移除子节点
39071
- * @param index 子节点索引
39072
- * @returns 被移除的子节点,如果索引无效则返回 undefined
39073
- */
39074
- removeChildAt(index2) {
39075
- if (index2 >= 0 && index2 < this.children.length) {
39076
- const child = this.children.splice(index2, 1)[0];
39077
- if (child) {
39078
- child.parent = void 0;
39079
- }
39080
- return child;
39081
- }
39082
- return void 0;
39083
- }
39084
- /**
39085
- * 获取所有子节点(只读)
39185
+ *
39186
+ * @param startCell
39187
+ * @param endCell
39188
+ * @returns
39086
39189
  */
39087
- getChildren() {
39088
- return this.children;
39190
+ getBoundedRegion(startCell, endCell) {
39191
+ const region = this.getRegion(startCell, endCell);
39192
+ if (!region) {
39193
+ GctMessage.warning("选区超出子表范围");
39194
+ throw new Error("Cells are not in the same region");
39195
+ }
39196
+ return region.type === "bounded" ? region : void 0;
39089
39197
  }
39090
39198
  /**
39091
- * 获取指定索引的子节点
39092
- * @param index 子节点索引
39199
+ * 获取公共区域
39200
+ * @param startCell
39201
+ * @param endCell
39202
+ * @returns
39093
39203
  */
39094
- getChildAt(index2) {
39095
- return this.children[index2];
39204
+ getRegion(startCell, endCell) {
39205
+ if (startCell === endCell) {
39206
+ return startCell.getRegion();
39207
+ }
39208
+ const startRegion = startCell.getRegion();
39209
+ const endRegion = endCell.getRegion();
39210
+ if (startRegion && endRegion && startRegion === endRegion) {
39211
+ return startRegion;
39212
+ }
39213
+ return;
39096
39214
  }
39097
- /**
39098
- * 获取子节点数量
39099
- */
39100
- getChildCount() {
39101
- return this.children.length;
39215
+ }
39216
+ const __vite_glob_0_31$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
39217
+ __proto__: null,
39218
+ SetBoundedItem
39219
+ }, Symbol.toStringTag, { value: "Module" }));
39220
+ class SetCheckTable extends CommandBase {
39221
+ constructor(doc, payload) {
39222
+ super(doc, payload);
39102
39223
  }
39103
- /**
39104
- * 获取第一个子节点
39105
- */
39106
- getFirstChild() {
39107
- return this.children[0] ?? null;
39224
+ async execute() {
39225
+ const cursor = this.doc.cursorManager;
39226
+ if (cursor.isCollapsed()) return null;
39227
+ const { mode, models } = CommandBase.getSelectionResult(this.doc, cursor.getSelection());
39228
+ if (mode !== SelectionMode.Tds) return null;
39229
+ if (models.length === 0) return null;
39230
+ const startCell = models[0].model;
39231
+ const endCell = models[models.length - 1].model;
39232
+ const start = {
39233
+ row: startCell.parent?.getCurrentIndex(),
39234
+ col: startCell.getCurrentIndex()
39235
+ };
39236
+ const end = {
39237
+ row: endCell.parent?.getCurrentIndex(),
39238
+ col: endCell.getCurrentIndex()
39239
+ };
39240
+ this.output = startCell.table.setCheckTable({
39241
+ start,
39242
+ end,
39243
+ name: this.payload.name,
39244
+ valuePath: this.payload.valuePath
39245
+ });
39246
+ return null;
39108
39247
  }
39109
- /**
39110
- * 获取最后一个子节点
39111
- */
39112
- getLastChild() {
39113
- return this.children[this.children.length - 1] ?? null;
39248
+ }
39249
+ const __vite_glob_0_32$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
39250
+ __proto__: null,
39251
+ SetCheckTable
39252
+ }, Symbol.toStringTag, { value: "Module" }));
39253
+ class SetColor extends SetStyleBase {
39254
+ constructor(doc, payload) {
39255
+ super(doc, payload);
39114
39256
  }
39115
- /**
39116
- * 清空所有子节点
39117
- */
39118
- clearChildren() {
39119
- this.children.forEach((child) => {
39120
- child.parent = void 0;
39257
+ applyStyle(run) {
39258
+ run.setColor(this.payload.color);
39259
+ }
39260
+ }
39261
+ const __vite_glob_0_33$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
39262
+ __proto__: null,
39263
+ SetColor
39264
+ }, Symbol.toStringTag, { value: "Module" }));
39265
+ class SetDataGroup2D extends CommandBase {
39266
+ constructor(doc, payload) {
39267
+ super(doc, payload);
39268
+ }
39269
+ async execute() {
39270
+ const cursor = this.doc.cursorManager;
39271
+ if (cursor.isCollapsed()) return null;
39272
+ const { mode, models } = CommandBase.getSelectionResult(this.doc, cursor.getSelection());
39273
+ if (mode !== SelectionMode.Tds) return null;
39274
+ if (models.length === 0) return null;
39275
+ const startCell = models[0].model;
39276
+ const endCell = models[models.length - 1].model;
39277
+ const cellList = [...models.map((m) => m.model)];
39278
+ const start = {
39279
+ row: startCell.parent?.getCurrentIndex(),
39280
+ col: startCell.getCurrentIndex()
39281
+ };
39282
+ const end = {
39283
+ row: endCell.parent?.getCurrentIndex(),
39284
+ col: endCell.getCurrentIndex()
39285
+ };
39286
+ const subTableRegion = this.getSubTableRegion(cellList);
39287
+ if (!subTableRegion) {
39288
+ throw new Error("Cells are not in a sub table region supporting data-group-2d");
39289
+ }
39290
+ this.output = subTableRegion.setItemRegion({
39291
+ start,
39292
+ end
39121
39293
  });
39122
- this.children = [];
39294
+ return null;
39123
39295
  }
39124
39296
  /**
39125
- * 查找子节点索引
39126
- * @param child 要查找的子节点
39127
- * @returns 子节点索引,如果不存在则返回 -1
39297
+ *
39298
+ * @param cellList
39299
+ * @returns
39128
39300
  */
39129
- indexOfChild(child) {
39130
- return this.children.indexOf(child);
39301
+ getSubTableRegion(cellList) {
39302
+ let region;
39303
+ cellList.some((cell) => {
39304
+ const r = cell.getRegion();
39305
+ if (r && ["check-table", "2d-table"].includes(r.type)) {
39306
+ region = r;
39307
+ return true;
39308
+ }
39309
+ });
39310
+ if (!region) {
39311
+ throw new Error("No region found");
39312
+ }
39313
+ return region;
39131
39314
  }
39132
- /**
39133
- * 检查是否包含子节点
39134
- * @param child 要检查的子节点
39135
- */
39136
- hasChild(child) {
39137
- return this.children.includes(child);
39315
+ }
39316
+ const __vite_glob_0_34$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
39317
+ __proto__: null,
39318
+ SetDataGroup2D
39319
+ }, Symbol.toStringTag, { value: "Module" }));
39320
+ class SetFont extends SetStyleBase {
39321
+ constructor(doc, payload) {
39322
+ super(doc, payload);
39138
39323
  }
39139
- /**
39140
- * 遍历所有子节点
39141
- * @param callback 遍历回调函数
39142
- */
39143
- forEachChild(callback) {
39144
- this.children.forEach(callback);
39324
+ applyStyle(run) {
39325
+ run.setFont(this.payload.fontFamily);
39145
39326
  }
39146
- /**
39147
- * 查找满足条件的子节点
39148
- * @param predicate 查找条件
39149
- * @returns 第一个满足条件的子节点,如果没有则返回 undefined
39150
- */
39151
- findChild(predicate) {
39152
- return this.children.find(predicate);
39327
+ }
39328
+ const __vite_glob_0_35$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
39329
+ __proto__: null,
39330
+ SetFont
39331
+ }, Symbol.toStringTag, { value: "Module" }));
39332
+ class SetFontSize extends SetStyleBase {
39333
+ constructor(doc, payload) {
39334
+ super(doc, payload);
39335
+ this.needsCalculatePostCommandContext = true;
39153
39336
  }
39154
- /**
39155
- * 过滤子节点
39156
- * @param predicate 过滤条件
39157
- * @returns 满足条件的子节点数组
39158
- */
39159
- filterChildren(predicate) {
39160
- return this.children.filter(predicate);
39337
+ applyStyle(run) {
39338
+ run.setFontSize(this.payload.fontSize * 2);
39161
39339
  }
39162
39340
  }
39163
- class BandContainer extends LayoutGroup {
39164
- type;
39165
- constructor(options) {
39166
- super(options);
39167
- this.type = options.type;
39168
- if (options.type === "header") {
39169
- this.component = BuiltinComponentTypeConst.Header;
39170
- } else if (options.type === "footer") {
39171
- this.component = BuiltinComponentTypeConst.Footer;
39341
+ const __vite_glob_0_36$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
39342
+ __proto__: null,
39343
+ SetFontSize
39344
+ }, Symbol.toStringTag, { value: "Module" }));
39345
+ class SetHeaderFooterConfig extends CommandBase {
39346
+ constructor(doc, payload) {
39347
+ super(doc, payload);
39348
+ }
39349
+ async execute() {
39350
+ const { headerMargin, footerMargin, titlePg, evenAndOddHeaders } = this.payload;
39351
+ this.doc?.eventManager.cursorController.clearCursor();
39352
+ const sections = (this.doc.model?.document.body.children ?? []).filter(
39353
+ (item) => item.name === "w:secPr"
39354
+ );
39355
+ if (sections.length === 0) {
39356
+ this.isTerminated = true;
39357
+ return null;
39172
39358
  }
39173
- this.parent = options.page;
39359
+ for (const section of sections) {
39360
+ if (headerMargin !== void 0) {
39361
+ section.setHeaderMargin(headerMargin);
39362
+ }
39363
+ if (footerMargin !== void 0) {
39364
+ section.setFooterMargin(footerMargin);
39365
+ }
39366
+ if (titlePg !== void 0) {
39367
+ section.setTitlePg(titlePg);
39368
+ }
39369
+ }
39370
+ if (evenAndOddHeaders !== void 0) {
39371
+ this.doc.model?.settings.setEvenAndOddHeaders(evenAndOddHeaders);
39372
+ }
39373
+ return null;
39174
39374
  }
39175
- get page() {
39176
- return this.parent;
39375
+ }
39376
+ const __vite_glob_0_37$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
39377
+ __proto__: null,
39378
+ SetHeaderFooterConfig
39379
+ }, Symbol.toStringTag, { value: "Module" }));
39380
+ class SetHighlight extends SetStyleBase {
39381
+ constructor(doc, payload) {
39382
+ super(doc, payload);
39177
39383
  }
39178
- /**
39179
- * 宽度 = 页面正文宽度
39180
- */
39181
- get contentMaxWidth() {
39182
- return this.page.contentMaxWidth;
39384
+ applyStyle(run) {
39385
+ run.setHighlight(this.payload.highlight);
39183
39386
  }
39184
- /**
39185
- * 页眉页脚不限制高度
39186
- */
39187
- get contentMaxHeight() {
39188
- return Number.POSITIVE_INFINITY;
39387
+ }
39388
+ const __vite_glob_0_38$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
39389
+ __proto__: null,
39390
+ SetHighlight
39391
+ }, Symbol.toStringTag, { value: "Module" }));
39392
+ class SetItalic extends SetStyleBase {
39393
+ constructor(doc, payload) {
39394
+ super(doc, payload);
39189
39395
  }
39190
- /** 获取页眉页脚内容高度 */
39191
- getContentHeight() {
39192
- return this.getChildren().reduce((sum, child) => sum + child.height, 0);
39396
+ applyStyle(run) {
39397
+ run.setItalic(this.payload?.italic ?? true);
39193
39398
  }
39194
- /** 当前真正推开正文的 inset 高度 */
39195
- get actualInsetHeight() {
39196
- return this.type === "header" ? this.page.pt : this.page.pb;
39399
+ }
39400
+ const __vite_glob_0_39$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
39401
+ __proto__: null,
39402
+ SetItalic
39403
+ }, Symbol.toStringTag, { value: "Module" }));
39404
+ class SetOrient extends CommandBase {
39405
+ constructor(doc, payload) {
39406
+ super(doc, payload);
39197
39407
  }
39198
- /** 获取剩余空间 */
39199
- getRemainingSize() {
39200
- return Number.POSITIVE_INFINITY;
39408
+ async execute() {
39409
+ const { orient, serRefId } = this.payload;
39410
+ if (!["portrait", "landscape"].includes(orient)) {
39411
+ throw new Error(`Invalid orientation: ${orient}`);
39412
+ }
39413
+ if (!serRefId) {
39414
+ this.isTerminated = true;
39415
+ return null;
39416
+ }
39417
+ const section = this.doc.model?.document.body.children.find(
39418
+ (item) => item.id === serRefId
39419
+ );
39420
+ if (!section) {
39421
+ this.isTerminated = true;
39422
+ return null;
39423
+ }
39424
+ section.setOrient(orient);
39425
+ return null;
39201
39426
  }
39202
- layout(x2, y2) {
39203
- this.layoutX = x2;
39204
- this.layoutY = y2;
39205
- this.forEachChild((child) => {
39206
- child.layout(this.layoutX + child.x, this.layoutY + child.y);
39207
- });
39427
+ }
39428
+ const __vite_glob_0_40$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
39429
+ __proto__: null,
39430
+ SetOrient
39431
+ }, Symbol.toStringTag, { value: "Module" }));
39432
+ class SetPadding extends CommandBase {
39433
+ constructor(doc, payload) {
39434
+ super(doc, payload);
39208
39435
  }
39209
- /** 距离页面边缘的安全间距(页眉/页脚与页面边缘的距离) */
39210
- get spacingFromEdge() {
39211
- return this.type === "header" ? this.page.section.headerSpacing : this.page.section.footerSpacing;
39436
+ async execute() {
39437
+ const { padding, serRefId } = this.payload;
39438
+ if (!serRefId) {
39439
+ this.isTerminated = true;
39440
+ return null;
39441
+ }
39442
+ const section = this.doc.model?.document.body.children.find(
39443
+ (item) => item.id === serRefId
39444
+ );
39445
+ if (!section) {
39446
+ this.isTerminated = true;
39447
+ return null;
39448
+ }
39449
+ const [top, right, bottom, left] = padding;
39450
+ section.setMargins(top, bottom, left, right);
39451
+ return null;
39212
39452
  }
39213
- /** 页眉/页脚与正文的分界线 Y 坐标(相对整页) */
39214
- get guideLineY() {
39215
- return this.type === "header" ? this.page.pt : this.page.height - this.page.pb;
39453
+ }
39454
+ const __vite_glob_0_41$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
39455
+ __proto__: null,
39456
+ SetPadding
39457
+ }, Symbol.toStringTag, { value: "Module" }));
39458
+ class SetRepeating extends CommandBase {
39459
+ constructor(doc, payload) {
39460
+ super(doc, payload);
39216
39461
  }
39217
- /** 页眉/页脚占位矩形(用于辅助线渲染),相对整页 */
39218
- get guideRect() {
39219
- const y2 = this.type === "header" ? this.spacingFromEdge : this.page.height - this.page.pb;
39220
- const rawHeight = this.type === "header" ? this.page.pt - this.spacingFromEdge : this.page.pb - this.spacingFromEdge;
39221
- const height = Math.max(0, rawHeight);
39222
- return {
39223
- x: this.page.pl,
39224
- y: y2,
39225
- width: this.contentMaxWidth,
39226
- height
39462
+ async execute() {
39463
+ const cursor = this.doc.cursorManager;
39464
+ if (cursor.isCollapsed()) return null;
39465
+ const { mode, models } = CommandBase.getSelectionResult(this.doc, cursor.getSelection());
39466
+ if (mode !== SelectionMode.Tds) return null;
39467
+ if (models.length === 0) return null;
39468
+ const startCell = models[0].model;
39469
+ const endCell = models[models.length - 1].model;
39470
+ const start = {
39471
+ row: startCell.parent?.getCurrentIndex(),
39472
+ col: startCell.getCurrentIndex()
39227
39473
  };
39228
- }
39229
- /** 双击开启/关闭页眉页脚编辑的命中区域(相对整页) */
39230
- get hitAreaRect() {
39231
- const isHeader = this.type === "header";
39232
- return {
39233
- x: this.page.pl,
39234
- y: isHeader ? 0 : this.page.height - this.page.pb,
39235
- width: this.contentMaxWidth,
39236
- height: isHeader ? this.page.pt : this.page.pb
39474
+ const end = {
39475
+ row: endCell.parent?.getCurrentIndex(),
39476
+ col: endCell.getCurrentIndex()
39237
39477
  };
39478
+ this.output = startCell.table.setRepeating({
39479
+ start,
39480
+ end,
39481
+ name: this.payload.name,
39482
+ valuePath: this.payload.valuePath
39483
+ });
39484
+ return null;
39238
39485
  }
39239
39486
  }
39240
- class OverlayLayout extends LayoutGroup {
39241
- component = BuiltinComponentTypeConst.OverlayLayout;
39242
- constructor(options) {
39243
- super(options);
39244
- }
39245
- /**
39246
- * 获取可用宽度
39247
- */
39248
- get contentMaxWidth() {
39249
- return this.width;
39487
+ const __vite_glob_0_42$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
39488
+ __proto__: null,
39489
+ SetRepeating
39490
+ }, Symbol.toStringTag, { value: "Module" }));
39491
+ class SetStrike extends SetStyleBase {
39492
+ constructor(doc, payload) {
39493
+ super(doc, payload);
39250
39494
  }
39251
- /**
39252
- * 悬浮层不参与文档流布局,但是要设置 layoutX和 layoutY
39253
- */
39254
- layout() {
39255
- this.layoutX = this.x;
39256
- this.layoutY = this.y;
39495
+ applyStyle(run) {
39496
+ run.setStrike(this.payload.strike);
39257
39497
  }
39258
39498
  }
39259
- class OverlayContainer extends LayoutGroup {
39260
- component = BuiltinComponentTypeConst.OverlayContainer;
39261
- parent;
39262
- constructor(options) {
39263
- super(options);
39264
- this.parent = options.page;
39499
+ const __vite_glob_0_43 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
39500
+ __proto__: null,
39501
+ SetStrike
39502
+ }, Symbol.toStringTag, { value: "Module" }));
39503
+ class SetSubTableHeader extends CommandBase {
39504
+ constructor(doc, payload) {
39505
+ super(doc, payload);
39265
39506
  }
39266
- get page() {
39267
- return this.parent;
39507
+ async execute() {
39508
+ const cursor = this.doc.cursorManager;
39509
+ const { name } = this.payload;
39510
+ if (cursor.isCollapsed()) return null;
39511
+ const { mode, models } = CommandBase.getSelectionResult(this.doc, cursor.getSelection());
39512
+ if (mode !== SelectionMode.Tds) return null;
39513
+ if (models.length === 0) return null;
39514
+ const startCell = models[0].model;
39515
+ const endCell = models[models.length - 1].model;
39516
+ const start = {
39517
+ row: startCell.parent?.getCurrentIndex(),
39518
+ col: startCell.getCurrentIndex()
39519
+ };
39520
+ const end = {
39521
+ row: endCell.parent?.getCurrentIndex(),
39522
+ col: endCell.getCurrentIndex()
39523
+ };
39524
+ const region = this.getSubTableRegion(endCell.table, end.row);
39525
+ if (!region) {
39526
+ GctMessage.warning("没有找到对应子表");
39527
+ return null;
39528
+ }
39529
+ const crossRegion = startCell.table.findCrossRegion({ start, end });
39530
+ crossRegion && startCell.table.deleteRegionById(crossRegion.id);
39531
+ this.output = startCell.table.setSubTableHeader({
39532
+ start,
39533
+ end,
39534
+ name,
39535
+ subTableId: region.id
39536
+ });
39537
+ return null;
39268
39538
  }
39269
- get width() {
39270
- return this.page.width;
39539
+ getSubTableRegion(table, rowIndex) {
39540
+ return table.regions.find((region) => {
39541
+ return region.start.row === rowIndex + 1 && ["repeating", "bounded", "check-table", "2d-table"].includes(region.type);
39542
+ });
39271
39543
  }
39272
- get height() {
39273
- return this.page.height;
39544
+ }
39545
+ const __vite_glob_0_44 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
39546
+ __proto__: null,
39547
+ SetSubTableHeader
39548
+ }, Symbol.toStringTag, { value: "Module" }));
39549
+ class SetTableHeader extends CommandBase {
39550
+ constructor(doc, payload) {
39551
+ super(doc, payload);
39274
39552
  }
39275
- createOverlayLayout({
39276
- x: x2,
39277
- y: y2,
39278
- width,
39279
- height,
39280
- modelRef
39281
- }) {
39282
- const newOverlayLayout = new OverlayLayout({
39283
- doc: this.doc,
39284
- x: x2,
39285
- y: y2,
39286
- width,
39287
- height,
39288
- modelRef
39553
+ async execute() {
39554
+ const cursor = this.doc.cursorManager;
39555
+ const { name } = this.payload;
39556
+ if (cursor.isCollapsed()) return null;
39557
+ const { mode, models } = CommandBase.getSelectionResult(this.doc, cursor.getSelection());
39558
+ if (mode !== SelectionMode.Tds) return null;
39559
+ if (models.length === 0) return null;
39560
+ const startCell = models[0].model;
39561
+ const endCell = models[models.length - 1].model;
39562
+ const start = {
39563
+ row: startCell.parent?.getCurrentIndex(),
39564
+ col: startCell.getCurrentIndex()
39565
+ };
39566
+ const end = {
39567
+ row: endCell.parent?.getCurrentIndex(),
39568
+ col: endCell.getCurrentIndex()
39569
+ };
39570
+ this.output = startCell.table.setTableHeader({
39571
+ start,
39572
+ end,
39573
+ name
39289
39574
  });
39290
- newOverlayLayout.layout();
39291
- this.addChild(newOverlayLayout);
39292
- return newOverlayLayout;
39575
+ return null;
39293
39576
  }
39294
- /**
39295
- * 悬浮层不参与文档流布局
39296
- */
39297
- layout() {
39577
+ }
39578
+ const __vite_glob_0_45 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
39579
+ __proto__: null,
39580
+ SetTableHeader
39581
+ }, Symbol.toStringTag, { value: "Module" }));
39582
+ class SetUnderline extends SetStyleBase {
39583
+ constructor(doc, payload) {
39584
+ super(doc, payload);
39585
+ }
39586
+ applyStyle(run) {
39587
+ run.setUnderline(this.payload?.underline ?? "single");
39298
39588
  }
39299
39589
  }
39300
- class TextUtil {
39301
- /** 字体度量缓存限制 */
39302
- static FONT_METRICS_CACHE_LIMIT = 50;
39303
- /** 布局大小缓存限制 */
39304
- static LAYOUT_SIZE_CACHE_LIMIT = 100;
39305
- /** 东亚常见全宽字符块 */
39306
- static EAST_ASIAN_FULL_WIDTH_REGEX = /[\u3000-\u303F\u3040-\u30FF\u31F0-\u31FF\uFF01-\uFF60\uFFE0-\uFFE6]/u;
39307
- /** 表单/文档中常见的几何符号 */
39308
- static FULL_WIDTH_SYMBOL_REGEX = /[□■○●△▲▽▼◇◆◎※]/u;
39309
- static fontMetricsCache = /* @__PURE__ */ new Map();
39310
- static layoutSizeCache = /* @__PURE__ */ new Map();
39311
- /**
39312
- * 验证中文字符
39313
- * @param char
39314
- * @returns
39315
- */
39316
- static isHanChar(char) {
39317
- return new RegExp("\\p{Script=Han}", "u").test(char);
39590
+ const __vite_glob_0_46 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
39591
+ __proto__: null,
39592
+ SetUnderline
39593
+ }, Symbol.toStringTag, { value: "Module" }));
39594
+ class Snapshot extends CommandBase {
39595
+ constructor(doc, payload) {
39596
+ super(doc, payload);
39318
39597
  }
39319
- /**
39320
- * 验证是否为应按 1em 处理的全宽单字符
39321
- * @param char
39322
- * @returns
39323
- */
39324
- static isFullWidthChar(char) {
39325
- if ([...char].length !== 1) {
39326
- return false;
39327
- }
39328
- return this.isHanChar(char) || this.EAST_ASIAN_FULL_WIDTH_REGEX.test(char) || this.FULL_WIDTH_SYMBOL_REGEX.test(char);
39598
+ async execute() {
39599
+ return null;
39329
39600
  }
39330
- /**
39331
- * 生成文本度量缓存键
39332
- * @param payload
39333
- * @param includeText
39334
- * @returns
39335
- */
39336
- static getMeasureCacheKey(payload, includeText = true) {
39337
- return JSON.stringify({
39338
- text: includeText ? payload.text ?? "" : "",
39339
- fontSize: payload.fontSize ?? "",
39340
- fontFamily: payload.fontFamily ?? "",
39341
- fontStyle: payload.fontStyle ?? "",
39342
- fontVariant: payload.fontVariant ?? "",
39343
- lineHeight: payload.lineHeight ?? "",
39344
- padding: payload.padding ?? "",
39345
- letterSpacing: payload.letterSpacing ?? ""
39346
- });
39601
+ }
39602
+ const __vite_glob_0_47 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
39603
+ __proto__: null,
39604
+ Snapshot
39605
+ }, Symbol.toStringTag, { value: "Module" }));
39606
+ class UnmergeCells extends CommandBase {
39607
+ constructor(doc, payload) {
39608
+ super(doc, payload);
39347
39609
  }
39348
- /**
39349
- * 计算度量 - 基于 JSON 序列化的缓存(LRU)
39350
- * 将最终的 config 序列化为缓存键,相同配置直接返回缓存结果
39351
- * 最近使用的项会被移到末尾,超限时删除最古老的项
39352
- * @param payload
39353
- * @returns
39354
- */
39355
- static getFontMetrics(payload) {
39356
- const targetText = "Hg";
39357
- const config = Object.assign({}, payload, {
39358
- text: targetText,
39359
- lineHeight: 1
39610
+ async execute() {
39611
+ const cursor = this.doc.cursorManager;
39612
+ if (cursor.isCollapsed()) return;
39613
+ const { mode, models } = CommandBase.getSelectionResult(this.doc, cursor.getSelection());
39614
+ if (mode !== SelectionMode.Tds) return;
39615
+ if (models.length === 0) return;
39616
+ const roots = models.map(({ model }) => model).filter((cell) => cell.id === cell.mergeId && !cell.mergeFromId);
39617
+ if (roots.length === 0) return null;
39618
+ const table = roots[0]?.table;
39619
+ if (!table) return null;
39620
+ table.runConsistencyMutation({
39621
+ mutate: () => {
39622
+ roots.forEach((cell) => {
39623
+ cell.unmerge({ skipConsistency: true });
39624
+ });
39625
+ }
39360
39626
  });
39361
- const cacheKey = this.getMeasureCacheKey(config, false);
39362
- if (this.fontMetricsCache.has(cacheKey)) {
39363
- const result2 = this.fontMetricsCache.get(cacheKey);
39364
- this.fontMetricsCache.delete(cacheKey);
39365
- this.fontMetricsCache.set(cacheKey, result2);
39366
- return result2;
39367
- }
39368
- const text = new Konva.Text(config);
39369
- const size = text.measureSize(targetText);
39370
- const result = {
39371
- ascent: size.actualBoundingBoxAscent,
39372
- descent: size.actualBoundingBoxDescent
39373
- };
39374
- if (this.fontMetricsCache.size >= this.FONT_METRICS_CACHE_LIMIT) {
39375
- const firstKey = this.fontMetricsCache.keys().next().value;
39376
- this.fontMetricsCache.delete(firstKey);
39377
- }
39378
- this.fontMetricsCache.set(cacheKey, result);
39379
- return result;
39380
- }
39381
- /**
39382
- * 计算单个字符布局大小 - 基于 JSON 序列化的缓存(LRU)
39383
- * @param payload
39384
- * @returns
39385
- */
39386
- static getLayoutSize(payload) {
39387
- if (this.isFullWidthChar(payload.text ?? "")) {
39388
- const fontSize2 = payload.fontSize ?? 0;
39627
+ const mapper = this.doc.layoutMapper;
39628
+ const normalized = this.doc.cursorManager.normalizeRange(cursor.getSelection());
39629
+ const start = mapper.getLayoutNodeById(normalized.rangeStart.nodeId);
39630
+ if (start?.isPlaceholderRun) {
39631
+ const wp = mapper.getModelNodeById(start.parent.modelRef.id);
39389
39632
  return {
39390
- width: fontSize2,
39391
- height: fontSize2
39633
+ wp,
39634
+ pos: -1,
39635
+ side: "after"
39392
39636
  };
39393
39637
  }
39394
- const config = Object.assign({}, payload, {
39395
- lineHeight: 1
39396
- });
39397
- const cacheKey = this.getMeasureCacheKey(config);
39398
- if (this.layoutSizeCache.has(cacheKey)) {
39399
- const result2 = this.layoutSizeCache.get(cacheKey);
39400
- this.layoutSizeCache.delete(cacheKey);
39401
- this.layoutSizeCache.set(cacheKey, result2);
39402
- return result2;
39403
- }
39404
- const text = new Konva.Text(config);
39405
- const result = {
39406
- width: text.width(),
39407
- height: text.height()
39408
- };
39409
- if (this.layoutSizeCache.size >= this.LAYOUT_SIZE_CACHE_LIMIT) {
39410
- const firstKey = this.layoutSizeCache.keys().next().value;
39411
- this.layoutSizeCache.delete(firstKey);
39412
- }
39413
- this.layoutSizeCache.set(cacheKey, result);
39414
- return result;
39415
- }
39416
- /**
39417
- * 清除度量结果缓存
39418
- */
39419
- static clearMeasureCache() {
39420
- this.fontMetricsCache.clear();
39421
- this.layoutSizeCache.clear();
39422
- }
39423
- /**
39424
- * 获取缓存大小信息
39425
- * @returns 返回测量缓存的大小 {fontMetrics, layoutSize}
39426
- */
39427
- static getMeasureCacheSize() {
39638
+ const wr = mapper.getModelNodeById(start.modelRef.id);
39428
39639
  return {
39429
- fontMetrics: this.fontMetricsCache.size,
39430
- layoutSize: this.layoutSizeCache.size
39640
+ wr,
39641
+ pos: -1,
39642
+ side: "after"
39431
39643
  };
39432
39644
  }
39433
39645
  }
39434
- class TextRun extends LayoutNode {
39435
- component = BuiltinComponentTypeConst.Text;
39436
- /** 文本内容 */
39437
- text = "";
39438
- /** 字号 */
39439
- fontSize = DEFAULT_FONT_SIZE;
39440
- /** 字体 */
39441
- fontFamily = DEFAULT_FONT_FAMILY;
39442
- /** 文字颜色 */
39443
- color = DEFAULT_TEXT_COLOR;
39444
- /** 加粗 */
39445
- bold;
39446
- /** 斜体 */
39447
- italic;
39448
- /** 下划线 */
39449
- underline;
39450
- /** 删除线 */
39451
- strike;
39452
- /** 字间距 */
39453
- letterSpacing = 0;
39454
- /** 文字对齐样式 */
39455
- textAlign = "left";
39456
- charMetrics = [];
39457
- isPlaceholder = false;
39458
- isComposition = false;
39459
- lineHeight = 1.6;
39460
- ascent;
39461
- descent;
39462
- style;
39463
- constructor(options) {
39464
- super(options);
39465
- options.doc.increaseTextRunCount();
39466
- const { text } = options;
39467
- this.text = text;
39468
- this.isPlaceholder = options.isPlaceholder || false;
39469
- this.isComposition = options.isComposition || false;
39470
- this.ascent = options.ascent ?? 0;
39471
- this.descent = options.descent ?? 0;
39472
- if (options.charMetrics) {
39473
- this.charMetrics = options.charMetrics;
39474
- } else {
39475
- this.charMetrics.push({
39476
- char: options.text,
39477
- width: options.width,
39478
- height: options.height
39479
- });
39480
- }
39481
- if (options.style) {
39482
- Object.assign(this, options.style);
39646
+ const __vite_glob_0_48 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
39647
+ __proto__: null,
39648
+ UnmergeCells
39649
+ }, Symbol.toStringTag, { value: "Module" }));
39650
+ const commandModules = /* @__PURE__ */ Object.assign({
39651
+ "./commands/Backspace.ts": __vite_glob_0_0$4,
39652
+ "./commands/CommitValidateNumber.ts": __vite_glob_0_1$4,
39653
+ "./commands/Delete.ts": __vite_glob_0_2$4,
39654
+ "./commands/Delete2DTable.ts": __vite_glob_0_3$4,
39655
+ "./commands/DeleteBounded.ts": __vite_glob_0_4$4,
39656
+ "./commands/DeleteBoundedItem.ts": __vite_glob_0_5$4,
39657
+ "./commands/DeleteCheckTable.ts": __vite_glob_0_6$4,
39658
+ "./commands/DeleteCol.ts": __vite_glob_0_7$3,
39659
+ "./commands/DeleteDataGroup2D.ts": __vite_glob_0_8$3,
39660
+ "./commands/DeleteRepeating.ts": __vite_glob_0_9$3,
39661
+ "./commands/DeleteRow.ts": __vite_glob_0_10$3,
39662
+ "./commands/DeleteTable.ts": __vite_glob_0_11$3,
39663
+ "./commands/DeleteTableHeader.ts": __vite_glob_0_12$3,
39664
+ "./commands/Enter.ts": __vite_glob_0_13$3,
39665
+ "./commands/InsertCol.ts": __vite_glob_0_14$2,
39666
+ "./commands/InsertField.ts": __vite_glob_0_15$2,
39667
+ "./commands/InsertFloatingOverlay.ts": __vite_glob_0_16$1,
39668
+ "./commands/InsertImage.ts": __vite_glob_0_17$1,
39669
+ "./commands/InsertPaperWidget.ts": __vite_glob_0_18$1,
39670
+ "./commands/InsertRow.ts": __vite_glob_0_19$1,
39671
+ "./commands/InsertTable.ts": __vite_glob_0_20$1,
39672
+ "./commands/InsertText.ts": __vite_glob_0_21$1,
39673
+ "./commands/MergeCells.ts": __vite_glob_0_22$1,
39674
+ "./commands/ResizeCol.ts": __vite_glob_0_23$1,
39675
+ "./commands/ResizeImage.ts": __vite_glob_0_24$1,
39676
+ "./commands/ResizeOverlayLayout.ts": __vite_glob_0_25$1,
39677
+ "./commands/ResizeRow.ts": __vite_glob_0_26$1,
39678
+ "./commands/Set2DTable.ts": __vite_glob_0_27$1,
39679
+ "./commands/SetAlign.ts": __vite_glob_0_28$1,
39680
+ "./commands/SetBold.ts": __vite_glob_0_29$1,
39681
+ "./commands/SetBounded.ts": __vite_glob_0_30$1,
39682
+ "./commands/SetBoundedItem.ts": __vite_glob_0_31$1,
39683
+ "./commands/SetCheckTable.ts": __vite_glob_0_32$1,
39684
+ "./commands/SetColor.ts": __vite_glob_0_33$1,
39685
+ "./commands/SetDataGroup2D.ts": __vite_glob_0_34$1,
39686
+ "./commands/SetFont.ts": __vite_glob_0_35$1,
39687
+ "./commands/SetFontSize.ts": __vite_glob_0_36$1,
39688
+ "./commands/SetHeaderFooterConfig.ts": __vite_glob_0_37$1,
39689
+ "./commands/SetHighlight.ts": __vite_glob_0_38$1,
39690
+ "./commands/SetItalic.ts": __vite_glob_0_39$1,
39691
+ "./commands/SetOrient.ts": __vite_glob_0_40$1,
39692
+ "./commands/SetPadding.ts": __vite_glob_0_41$1,
39693
+ "./commands/SetRepeating.ts": __vite_glob_0_42$1,
39694
+ "./commands/SetStrike.ts": __vite_glob_0_43,
39695
+ "./commands/SetSubTableHeader.ts": __vite_glob_0_44,
39696
+ "./commands/SetTableHeader.ts": __vite_glob_0_45,
39697
+ "./commands/SetUnderline.ts": __vite_glob_0_46,
39698
+ "./commands/Snapshot.ts": __vite_glob_0_47,
39699
+ "./commands/UnmergeCells.ts": __vite_glob_0_48
39700
+ });
39701
+ function toCamelCase(pascalCase) {
39702
+ return pascalCase.charAt(0).toLowerCase() + pascalCase.slice(1);
39703
+ }
39704
+ function getClassNameFromPath(path2) {
39705
+ return path2.split("/").pop()?.replace(".ts", "") ?? "";
39706
+ }
39707
+ function buildCommandMap() {
39708
+ const map2 = {};
39709
+ Object.entries(commandModules).forEach(([path2, module2]) => {
39710
+ const expectedClassName = getClassNameFromPath(path2);
39711
+ const CommandClass = module2[expectedClassName];
39712
+ if (CommandClass && typeof CommandClass === "function") {
39713
+ const commandName = toCamelCase(expectedClassName);
39714
+ map2[commandName] = CommandClass;
39483
39715
  }
39716
+ });
39717
+ return map2;
39718
+ }
39719
+ class CommandManager {
39720
+ registry = /* @__PURE__ */ new Map();
39721
+ doc;
39722
+ undoStack = [];
39723
+ redoStack = [];
39724
+ composition;
39725
+ // 命令注册表 - 通过动态导入构建
39726
+ static COMMAND_MAP = buildCommandMap();
39727
+ constructor(doc) {
39728
+ this.doc = doc;
39729
+ Object.entries(CommandManager.COMMAND_MAP).forEach(([name, CommandClass]) => {
39730
+ this.register(name, CommandClass);
39731
+ });
39484
39732
  }
39485
- /**
39486
- * 计算文字大小 度量
39487
- * 优化版本
39488
- * @param payload
39489
- * @returns
39490
- */
39491
- static measureText(payload) {
39492
- const { width, height } = TextUtil.getLayoutSize(payload);
39493
- const { ascent, descent } = TextUtil.getFontMetrics(payload);
39494
- return {
39495
- width,
39496
- height,
39497
- ascent,
39498
- descent
39499
- };
39733
+ register(name, CommandClass) {
39734
+ this.registry.set(name, CommandClass);
39500
39735
  }
39501
- /**
39502
- * 计算文字大小 度量
39503
- * @param payload
39504
- * @returns
39505
- */
39506
- static __measureText(payload) {
39507
- let config = {
39508
- lineHeight: 1
39509
- };
39510
- Object.assign(config, payload);
39511
- const text = new Konva.Text(config);
39512
- const size = text.measureSize("Hg");
39513
- const { actualBoundingBoxAscent: ascent, actualBoundingBoxDescent: descent } = size;
39514
- return {
39515
- width: text.width(),
39516
- height: text.height(),
39517
- ascent,
39518
- descent
39519
- };
39736
+ async execute(name, payload) {
39737
+ const CommandClass = this.registry.get(name);
39738
+ if (!CommandClass) throw new Error(`Unknown command: ${name}`);
39739
+ const cmd = new CommandClass(this.doc, payload);
39740
+ const result = await cmd.do();
39741
+ result && this.updateCursor(result);
39742
+ payload?.doCallback && this.runCallback(payload.doCallback, result, cmd.output);
39743
+ if (cmd.isTerminated) return;
39744
+ this.undoStack.push(cmd);
39745
+ this.redoStack.length = 0;
39520
39746
  }
39521
- static createEmptyRun(doc) {
39522
- const fontSize2 = DEFAULT_FONT_SIZE;
39523
- const { height, ascent, descent } = TextRun.measureText({
39524
- text: "0",
39525
- fontSize: fontSize2
39526
- });
39527
- const run = new TextRun({
39528
- doc,
39529
- width: 6,
39530
- height,
39531
- ascent,
39532
- descent,
39533
- text: "",
39534
- isPlaceholder: true
39747
+ async undo() {
39748
+ const cmd = this.undoStack.pop();
39749
+ if (!cmd) return;
39750
+ const result = await cmd.undo();
39751
+ result && this.updateCursor(result);
39752
+ cmd.payload?.undoCallback && this.runCallback(cmd.payload?.undoCallback, result);
39753
+ this.redoStack.push(cmd);
39754
+ }
39755
+ async redo() {
39756
+ const cmd = this.redoStack.pop();
39757
+ if (!cmd) return;
39758
+ const result = await cmd.do();
39759
+ result && this.updateCursor(result);
39760
+ cmd.payload?.doCallback && this.runCallback(cmd.payload?.doCallback, result);
39761
+ this.undoStack.push(cmd);
39762
+ }
39763
+ compositionStart(text) {
39764
+ }
39765
+ compositionUpdate(text) {
39766
+ }
39767
+ compositionEnd(text) {
39768
+ this.doc.commandManager.execute(CommandType.insertText, {
39769
+ text
39535
39770
  });
39536
- return run;
39537
39771
  }
39538
- /**TextStyle(样式体系的样式)转换为 Layout 层的样式
39539
- * @param textStyle 经过继承计算的有效字符样式
39540
- * @returns TextRun 的样式属性
39541
- */
39542
- static textStyle2LayoutStyle(textStyle) {
39543
- if (!textStyle) return {};
39544
- const layoutStyle = {};
39545
- if (textStyle.sz !== void 0) {
39546
- const fontSizeInPt = textStyle.sz / 2;
39547
- layoutStyle.fontSize = fontSizeInPt * 96 / 72;
39548
- }
39549
- if (textStyle.rFonts?.ascii) {
39550
- layoutStyle.fontFamily = textStyle.rFonts.ascii;
39551
- }
39552
- if (textStyle.color) {
39553
- layoutStyle.color = normalizeColor(textStyle.color, DEFAULT_TEXT_COLOR);
39554
- }
39555
- if (textStyle.b !== void 0) {
39556
- layoutStyle.bold = textStyle.b;
39557
- }
39558
- if (textStyle.i !== void 0) {
39559
- layoutStyle.italic = textStyle.i;
39560
- }
39561
- if (textStyle.u !== void 0 && textStyle.u !== "none") {
39562
- layoutStyle.underline = true;
39563
- }
39564
- if (textStyle.strike !== void 0) {
39565
- layoutStyle.strike = textStyle.strike;
39772
+ updateCursor(data) {
39773
+ if (!data) return;
39774
+ if (Array.isArray(data)) {
39775
+ const [startData, endData] = data;
39776
+ this.doc.eventManager.cursorController?.resolveCursorRange(startData, endData);
39777
+ } else {
39778
+ this.doc.eventManager.cursorController?.resolveCursorAtNode?.(data);
39566
39779
  }
39567
- if (textStyle.spacing !== void 0) {
39568
- layoutStyle.letterSpacing = parseInt(textStyle.spacing) / 20;
39780
+ }
39781
+ runCallback(callback, data, output) {
39782
+ if (typeof callback === "function") {
39783
+ callback(data, output);
39569
39784
  }
39570
- if (textStyle.highlight !== void 0) ;
39571
- return layoutStyle;
39572
39785
  }
39573
39786
  }
39574
39787
  class EventUtil {
@@ -40295,7 +40508,7 @@ class ImageRun extends LayoutNode {
40295
40508
  this.decorations = options.decorations;
40296
40509
  }
40297
40510
  }
40298
- let ImageHandler$2 = class ImageHandler {
40511
+ class InlineImageLayoutHandler {
40299
40512
  static emuToPixels(emu) {
40300
40513
  return UnitConverter.emuToPixel(emu);
40301
40514
  }
@@ -40306,9 +40519,10 @@ let ImageHandler$2 = class ImageHandler {
40306
40519
  return { imageId };
40307
40520
  }
40308
40521
  let current = wr.parent;
40309
- while (current) {
40310
- if (current.name === "w:hdr" || current.name === "w:ftr") {
40311
- const ownerRelId = current.relId;
40522
+ while (current && typeof current === "object") {
40523
+ const node = current;
40524
+ if (node.name === "w:hdr" || node.name === "w:ftr") {
40525
+ const ownerRelId = node.relId;
40312
40526
  if (!ownerRelId) break;
40313
40527
  return {
40314
40528
  imageId,
@@ -40316,7 +40530,7 @@ let ImageHandler$2 = class ImageHandler {
40316
40530
  ownerRelId
40317
40531
  };
40318
40532
  }
40319
- current = current.parent;
40533
+ current = node.parent;
40320
40534
  }
40321
40535
  return { imageId };
40322
40536
  }
@@ -40343,35 +40557,8 @@ let ImageHandler$2 = class ImageHandler {
40343
40557
  });
40344
40558
  context.addRun(run);
40345
40559
  }
40346
- };
40347
- class TextWidget extends TextRun {
40348
- widgetMeta;
40349
- valuePath;
40350
- isEmptyPlaceholder = false;
40351
- isIconPlaceholder = false;
40352
- isSpacePlaceholder = false;
40353
- widgetFieldLeftMarker;
40354
- widgetFieldRightMarker;
40355
- widgetOption;
40356
- widgetFileItem;
40357
- pageWidgetMeta;
40358
- dataIndex;
40359
- constructor(options) {
40360
- super(options);
40361
- this.widgetMeta = options.widgetMeta;
40362
- this.valuePath = options.valuePath;
40363
- this.isEmptyPlaceholder = options.isEmptyPlaceholder ?? false;
40364
- this.isIconPlaceholder = options.isIconPlaceholder ?? false;
40365
- this.isSpacePlaceholder = options.isSpacePlaceholder ?? false;
40366
- this.widgetOption = options.widgetOption;
40367
- this.widgetFileItem = options.widgetFileItem;
40368
- this.widgetFieldLeftMarker = options.widgetFieldLeftMarker;
40369
- this.widgetFieldRightMarker = options.widgetFieldRightMarker;
40370
- this.pageWidgetMeta = options.pageWidgetMeta;
40371
- this.dataIndex = options.dataIndex;
40372
- }
40373
40560
  }
40374
- let BaseHandler$1 = class BaseHandler {
40561
+ class FieldBaseHandler {
40375
40562
  static hasValue(value) {
40376
40563
  return value !== void 0 && value !== null;
40377
40564
  }
@@ -40696,8 +40883,8 @@ let BaseHandler$1 = class BaseHandler {
40696
40883
  run.x = context.getRunX();
40697
40884
  context.addRun(run);
40698
40885
  }
40699
- };
40700
- class OptionHandler extends BaseHandler$1 {
40886
+ }
40887
+ class OptionHandler extends FieldBaseHandler {
40701
40888
  static layout(ctx) {
40702
40889
  const { context } = ctx;
40703
40890
  if (context.doc.mode === DocModeTypeConst.Print) {
@@ -40807,7 +40994,7 @@ class ImageWidget extends ImageRun {
40807
40994
  this.dataIndex = options.dataIndex;
40808
40995
  }
40809
40996
  }
40810
- let ImageHandler$1 = class ImageHandler2 extends BaseHandler$1 {
40997
+ class FieldImageHandler extends FieldBaseHandler {
40811
40998
  static layout(ctx) {
40812
40999
  this.layoutField(ctx);
40813
41000
  }
@@ -40851,8 +41038,8 @@ let ImageHandler$1 = class ImageHandler2 extends BaseHandler$1 {
40851
41038
  this.layoutNoValueLabel(ctx);
40852
41039
  }
40853
41040
  }
40854
- };
40855
- class SignatureHandler extends BaseHandler$1 {
41041
+ }
41042
+ class SignatureHandler extends FieldBaseHandler {
40856
41043
  static layout(ctx) {
40857
41044
  this.layoutField(ctx);
40858
41045
  }
@@ -40938,7 +41125,7 @@ class SignatureHandler extends BaseHandler$1 {
40938
41125
  }
40939
41126
  }
40940
41127
  }
40941
- class InputHandler extends BaseHandler$1 {
41128
+ class InputHandler extends FieldBaseHandler {
40942
41129
  static layout(ctx) {
40943
41130
  const { context } = ctx;
40944
41131
  if (context.doc.mode === DocModeTypeConst.Print) {
@@ -40999,7 +41186,7 @@ class InputHandler extends BaseHandler$1 {
40999
41186
  });
41000
41187
  }
41001
41188
  }
41002
- class AttachmentHandler extends BaseHandler$1 {
41189
+ class AttachmentHandler extends FieldBaseHandler {
41003
41190
  static layout(ctx) {
41004
41191
  this.layoutField(ctx);
41005
41192
  }
@@ -41085,7 +41272,7 @@ class FieldHandler {
41085
41272
  } else if (wr.widgetMeta?.props?.renderComp === "radio") {
41086
41273
  OptionHandler.layout(ctx);
41087
41274
  } else if (wr.widgetMeta?.type === "fw:image") {
41088
- ImageHandler$1.layout(ctx);
41275
+ FieldImageHandler.layout(ctx);
41089
41276
  } else if (wr.widgetMeta?.type === "fw:signature") {
41090
41277
  SignatureHandler.layout(ctx);
41091
41278
  } else if (wr.widgetMeta?.type === "fw:file") {
@@ -41095,7 +41282,7 @@ class FieldHandler {
41095
41282
  }
41096
41283
  }
41097
41284
  }
41098
- class BaseHandler2 {
41285
+ class WidgetBaseHandler {
41099
41286
  context;
41100
41287
  wr;
41101
41288
  constructor(ctx) {
@@ -41115,11 +41302,7 @@ class BaseHandler2 {
41115
41302
  */
41116
41303
  getDataIndex(init2 = null) {
41117
41304
  const { context } = this;
41118
- const {
41119
- type: type4,
41120
- dataIndex,
41121
- xDataIndex
41122
- } = context.cell?.subRenderer || {};
41305
+ const { type: type4, dataIndex, xDataIndex } = context.cell?.subRenderer || {};
41123
41306
  return (type4 === "2d-table" ? xDataIndex : dataIndex) ?? init2;
41124
41307
  }
41125
41308
  getPaperIndex() {
@@ -41156,7 +41339,7 @@ class BaseHandler2 {
41156
41339
  return layoutStyle;
41157
41340
  }
41158
41341
  }
41159
- class SerialNumberHandler extends BaseHandler2 {
41342
+ class SerialNumberHandler extends WidgetBaseHandler {
41160
41343
  layout() {
41161
41344
  const { wr, context } = this;
41162
41345
  const layoutStyle = this.getLayoutStyle();
@@ -41195,7 +41378,7 @@ class SerialNumberHandler extends BaseHandler2 {
41195
41378
  });
41196
41379
  }
41197
41380
  }
41198
- class DefaultHandler extends BaseHandler2 {
41381
+ class DefaultHandler extends WidgetBaseHandler {
41199
41382
  layout() {
41200
41383
  const { wr, context } = this;
41201
41384
  const layoutStyle = this.getLayoutStyle();
@@ -41234,7 +41417,7 @@ class DefaultHandler extends BaseHandler2 {
41234
41417
  });
41235
41418
  }
41236
41419
  }
41237
- class QrCodeHandler extends BaseHandler2 {
41420
+ class QrCodeHandler extends WidgetBaseHandler {
41238
41421
  layout() {
41239
41422
  const { wr, context } = this;
41240
41423
  const { width = 80, height = 80 } = wr.pageWidgetMeta?.layout || {};
@@ -41256,7 +41439,7 @@ class QrCodeHandler extends BaseHandler2 {
41256
41439
  context.addRun(run);
41257
41440
  }
41258
41441
  }
41259
- class BarcodeHandler extends BaseHandler2 {
41442
+ class BarcodeHandler extends WidgetBaseHandler {
41260
41443
  getDecorationsInfo(width, height, label) {
41261
41444
  const { wr } = this;
41262
41445
  const { justifyContent, showValue } = wr.pageWidgetMeta?.props || {};
@@ -41318,7 +41501,7 @@ class BarcodeHandler extends BaseHandler2 {
41318
41501
  context.addRun(run);
41319
41502
  }
41320
41503
  }
41321
- class ImageHandler3 extends BaseHandler2 {
41504
+ class PageWidgetImageHandler extends WidgetBaseHandler {
41322
41505
  layout() {
41323
41506
  const { wr, context } = this;
41324
41507
  const { width = 120, height = 68 } = wr.pageWidgetMeta?.layout || {};
@@ -41340,7 +41523,7 @@ class ImageHandler3 extends BaseHandler2 {
41340
41523
  context.addRun(run);
41341
41524
  }
41342
41525
  }
41343
- class DiagonalHandler extends BaseHandler2 {
41526
+ class DiagonalHandler extends WidgetBaseHandler {
41344
41527
  layout() {
41345
41528
  const { wr, context } = this;
41346
41529
  const cell = this.getCell();
@@ -41379,7 +41562,7 @@ class DiagonalHandler extends BaseHandler2 {
41379
41562
  });
41380
41563
  }
41381
41564
  }
41382
- class PaginationHandler extends BaseHandler2 {
41565
+ class PaginationHandler extends WidgetBaseHandler {
41383
41566
  layout() {
41384
41567
  const { wr, context } = this;
41385
41568
  const layoutStyle = this.getLayoutStyle();
@@ -41458,7 +41641,7 @@ class PaginationHandler extends BaseHandler2 {
41458
41641
  return string3;
41459
41642
  }
41460
41643
  }
41461
- class LineHandler extends BaseHandler2 {
41644
+ class LineHandler extends WidgetBaseHandler {
41462
41645
  layout() {
41463
41646
  const { wr, context } = this;
41464
41647
  const { width = 120, height = 68 } = wr.pageWidgetMeta?.layout || {};
@@ -41489,7 +41672,7 @@ class PageWidgetHandler {
41489
41672
  } else if (wr.pageWidgetMeta?.type === "pw:barcode") {
41490
41673
  new BarcodeHandler(ctx).layout();
41491
41674
  } else if (wr.pageWidgetMeta?.type === "pw:image") {
41492
- new ImageHandler3(ctx).layout();
41675
+ new PageWidgetImageHandler(ctx).layout();
41493
41676
  } else if (wr.pageWidgetMeta?.type === "pw:diagonal") {
41494
41677
  new DiagonalHandler(ctx).layout();
41495
41678
  } else if (wr.pageWidgetMeta?.type === "pw:pagination") {
@@ -42727,7 +42910,7 @@ class LayoutManager {
42727
42910
  this.doc = doc;
42728
42911
  this.layoutHandlers = /* @__PURE__ */ new Map();
42729
42912
  this.layoutHandlers.set("text", TextHandler);
42730
- this.layoutHandlers.set("image", ImageHandler$2);
42913
+ this.layoutHandlers.set("image", InlineImageLayoutHandler);
42731
42914
  this.pageContext = new LayoutContext({
42732
42915
  type: "page",
42733
42916
  doc: this.doc,
@@ -45363,7 +45546,7 @@ class DataManager {
45363
45546
  values = [{ ...DEFAULT_EMPTY_ITEM }];
45364
45547
  }
45365
45548
  let arr = this.get(path2);
45366
- if (!Array.isArray(arr)) {
45549
+ if (!Array.isArray(arr) || arr.length === 0) {
45367
45550
  arr = [{ ...DEFAULT_EMPTY_ITEM }];
45368
45551
  this.set(path2, arr);
45369
45552
  }
@@ -45965,6 +46148,8 @@ class Doc {
45965
46148
  docRuntimeMeta;
45966
46149
  /** 外部的参数配置 */
45967
46150
  paramsConfig;
46151
+ /** 字段/模型查询(由上层注入 `SuiteRuntime` 等实现) */
46152
+ fieldModelQuery;
45968
46153
  /** 安全距离-上下 */
45969
46154
  SAFE_DIST_Y = 40;
45970
46155
  /** 安全距离-左右 */
@@ -45993,6 +46178,7 @@ class Doc {
45993
46178
  this.paramsConfig = options.paramsConfig;
45994
46179
  this.onLayoutChange = options.onLayoutChange;
45995
46180
  this.onSelectionChange = options.onSelectionChange;
46181
+ this.fieldModelQuery = options.fieldModelQuery;
45996
46182
  this.commandManager = new CommandManager(this);
45997
46183
  this.layoutManager = new LayoutManager(this);
45998
46184
  this.layoutMapper = new LayoutMapper(this);
@@ -47841,6 +48027,14 @@ class DocModel {
47841
48027
  }
47842
48028
  return result;
47843
48029
  }
48030
+ /** 获取所有 children */
48031
+ getAllChildren() {
48032
+ return this.document?.body?.children || [];
48033
+ }
48034
+ /** 获取所有表格 */
48035
+ getAllTables() {
48036
+ return this.getAllChildren().filter((w2) => w2.name === "w:tbl");
48037
+ }
47844
48038
  /**
47845
48039
  * 获取所有同时存在 widgetMeta 和 valuePath 的实例
47846
48040
  * @returns Wr 实例数组(包含 widgetMeta 和 valuePath 的文本或图片 run)
@@ -47856,11 +48050,72 @@ class DocModel {
47856
48050
  node.children.forEach((child) => collectWidgets(child));
47857
48051
  }
47858
48052
  };
47859
- if (this.document?.body?.children) {
47860
- this.document.body.children.forEach((child) => collectWidgets(child));
47861
- }
48053
+ this.getAllChildren().forEach((child) => collectWidgets(child));
47862
48054
  return instances;
47863
48055
  }
48056
+ /** 获取子表信息列表 */
48057
+ getSubTableInfoList() {
48058
+ const tables = this.getAllTables();
48059
+ const dynamicTableRegions = tables.filter((w2) => w2.hasRepeating).flatMap((w2) => w2.repeating).map((item) => {
48060
+ return {
48061
+ field: getLastSegment(item.valuePath),
48062
+ key: "dyn",
48063
+ name: "动态表",
48064
+ subType: "sub-table"
48065
+ };
48066
+ });
48067
+ const fixedTableRegions = tables.filter((w2) => w2.hasBounded).flatMap((w2) => w2.bounded).map((item) => {
48068
+ return {
48069
+ field: getLastSegment(item.valuePath),
48070
+ key: "newfixed",
48071
+ name: "固定表",
48072
+ subType: "fixed-table"
48073
+ };
48074
+ });
48075
+ const table2DRegions = tables.filter((w2) => w2.has2DTable).flatMap((w2) => w2._2DTable).map((item) => {
48076
+ const region = parseLinkFieldExpression(item.valuePath);
48077
+ const result = [];
48078
+ if (region.subFieldKey) {
48079
+ result.push({
48080
+ field: region.subFieldKey,
48081
+ key: "dyn",
48082
+ name: "二维表",
48083
+ subType: "sub-table-2d"
48084
+ });
48085
+ }
48086
+ if (region.linkFieldKey) {
48087
+ result.push({
48088
+ field: region.linkFieldKey,
48089
+ key: "newfixed",
48090
+ name: "二维表-关联",
48091
+ subType: "sub-table-2d-link"
48092
+ });
48093
+ }
48094
+ return result;
48095
+ }).flat();
48096
+ const checkTableRegions = tables.filter((w2) => w2.hasCheckTable).flatMap((w2) => w2.checkTable).map((item) => {
48097
+ const region = parseLinkFieldExpression(item.valuePath);
48098
+ const result = [];
48099
+ if (region.subFieldKey) {
48100
+ result.push({
48101
+ field: region.subFieldKey,
48102
+ key: "newfixed",
48103
+ name: "检验表-动态",
48104
+ subType: "check-table-2d"
48105
+ });
48106
+ }
48107
+ if (region.linkFieldKey) {
48108
+ result.push({
48109
+ field: region.linkFieldKey,
48110
+ key: "newfixed",
48111
+ name: "检验表-关联",
48112
+ subType: "check-table-2d-link"
48113
+ });
48114
+ }
48115
+ return result;
48116
+ }).flat();
48117
+ return [...dynamicTableRegions, ...fixedTableRegions, ...table2DRegions, ...checkTableRegions];
48118
+ }
47864
48119
  /** 根据 pageIndex 获取页眉实例 */
47865
48120
  getHeader(pageIndex, section) {
47866
48121
  const hasEvenOdd = this.settings?.isEvenAndOddEnabled();
@@ -50848,8 +51103,8 @@ const handleCustomDataSource = async (customDataSource, paramsConfig, subTableIn
50848
51103
  }
50849
51104
  return Promise.all(promises);
50850
51105
  };
50851
- const loadDataInitValues = async (designerJson, paramsConfig, subTableInfo, fieldPermission, instanceId) => {
50852
- const { document: document2 } = JSON.parse(designerJson || "{}");
51106
+ const loadDataInitValues = async (runtimeJson, paramsConfig, subTableInfo, fieldPermission, instanceId) => {
51107
+ const { document: document2 } = JSON.parse(runtimeJson || "{}");
50853
51108
  if (!document2?.config?.dataInit) return {};
50854
51109
  const {
50855
51110
  parameterMapping = [],
@@ -51046,12 +51301,11 @@ async function initializeDocumentEngine(props, payload, result) {
51046
51301
  );
51047
51302
  console.log("默认值集合 ===>", defaultDataMap);
51048
51303
  const dataInitMap = await loadDataInitValues(
51049
- requestInfo.designerJson || "",
51304
+ requestInfo.runtimeJson || "",
51050
51305
  paramsConfig,
51051
51306
  [],
51052
51307
  // JSW TODO: subTableInfo
51053
- [],
51054
- // JSW TODO: fieldPermission
51308
+ JSON.parse(requestInfo.processFieldPermission || "[]"),
51055
51309
  id
51056
51310
  );
51057
51311
  console.log("数据初始化集合 ===>", dataInitMap);
@@ -51078,6 +51332,8 @@ async function initializeDocumentEngine(props, payload, result) {
51078
51332
  initDocModelJson: JSON.stringify(docModel.toXmlJson())
51079
51333
  }
51080
51334
  };
51335
+ console.log("rawData", rawData);
51336
+ await TextUtil.awaitDocumentFonts();
51081
51337
  const doc = new Doc({
51082
51338
  model: docModel,
51083
51339
  mode: fillModeType,
@@ -51085,7 +51341,8 @@ async function initializeDocumentEngine(props, payload, result) {
51085
51341
  formType: requestInfo.formType || FormTypeConst.BASE,
51086
51342
  preview: payload.isPreview,
51087
51343
  paramsConfig: paramsConfig ?? {},
51088
- docRuntimeMeta
51344
+ docRuntimeMeta,
51345
+ fieldModelQuery: payload.ctx.runtime
51089
51346
  });
51090
51347
  doc.dataManager.setRawData(rawData, {
51091
51348
  ...defaultDataMap,
@@ -51276,6 +51533,16 @@ class FieldService {
51276
51533
  if (!runtime) return void 0;
51277
51534
  return runtime.getFieldById(id);
51278
51535
  }
51536
+ queryFieldByKeySync(modelKey, fieldKey) {
51537
+ const runtime = this.getRuntime(modelKey);
51538
+ if (!runtime) return void 0;
51539
+ return runtime.getFieldByKeySync(fieldKey);
51540
+ }
51541
+ queryFieldByIdSync(modelKey, id) {
51542
+ const runtime = this.getRuntime(modelKey);
51543
+ if (!runtime) return void 0;
51544
+ return runtime.getFieldByIdSync(id);
51545
+ }
51279
51546
  getFieldList(modelKey) {
51280
51547
  const rt2 = this.getRuntime(modelKey);
51281
51548
  if (!rt2) return [];
@@ -51591,6 +51858,12 @@ class SuiteRuntime {
51591
51858
  getFieldList(modelKey) {
51592
51859
  return this.fieldService.getFieldList(modelKey);
51593
51860
  }
51861
+ getFieldByKeyAsync(modelKey, key) {
51862
+ return this.fieldService.queryFieldByKeySync(modelKey, key);
51863
+ }
51864
+ getFieldByIdAsync(modelKey, id) {
51865
+ return this.fieldService.queryFieldByIdSync(modelKey, id);
51866
+ }
51594
51867
  getModel(modelKey) {
51595
51868
  return this.modelService.getModelSync(modelKey);
51596
51869
  }
@@ -53419,13 +53692,22 @@ const validateAllFields = async (doc) => {
53419
53692
  if (!showFormItem) {
53420
53693
  return;
53421
53694
  }
53695
+ const modelKey = getLastSegment(fieldMeta.modelLink);
53696
+ const fieldKey = getLastSegment(fieldMeta.fieldLink);
53697
+ const fieldInfo = doc.fieldModelQuery.getFieldByKeyAsync(modelKey, fieldKey);
53698
+ const modelInfo = doc.fieldModelQuery.getModel(modelKey);
53422
53699
  const ctx = createValidatorContext(doc, {
53423
53700
  ...widgetProps,
53424
53701
  showRequired: widgetState.required,
53425
53702
  validatorInfo: {
53426
53703
  modelId: widget.modelRef.id,
53427
53704
  runtimeValuePath,
53428
- widgetType: type4
53705
+ widgetType: type4,
53706
+ showModelName: modelInfo?.modelName,
53707
+ showModelKey: fieldInfo?.modelKey,
53708
+ showFieldName: fieldInfo?.name,
53709
+ subFieldKey: fieldMeta.subFieldKey,
53710
+ targetFieldId: fieldInfo?.key
53429
53711
  }
53430
53712
  });
53431
53713
  const rules2 = assembleRules(ctx);
@@ -54470,8 +54752,15 @@ const _sfc_main$2J = /* @__PURE__ */ defineComponent({
54470
54752
  },
54471
54753
  setup(__props) {
54472
54754
  const props = __props;
54755
+ const textRef = ref(null);
54756
+ const rectConfig = ref({
54757
+ width: 0,
54758
+ height: 0,
54759
+ fill: "#f00"
54760
+ });
54473
54761
  const textConfig = computed(() => {
54474
54762
  const widget = props.widget;
54763
+ const { highlight } = widget;
54475
54764
  const fontStyle = [widget.bold && "bold", widget.italic && "italic"].filter(Boolean).join(" ") || void 0;
54476
54765
  const textDecoration = [
54477
54766
  widget.isComposition && "underline",
@@ -54489,17 +54778,51 @@ const _sfc_main$2J = /* @__PURE__ */ defineComponent({
54489
54778
  align: widget.textAlign,
54490
54779
  letterSpacing: widget.letterSpacing,
54491
54780
  textDecoration,
54492
- wrap: "none"
54781
+ wrap: "none",
54782
+ _bgFill: highlight && highlight !== "none" ? highlight : void 0
54493
54783
  };
54494
54784
  });
54785
+ const updateRectSize = async (fill) => {
54786
+ if (!fill) return;
54787
+ await nextTick();
54788
+ if (textRef.value) {
54789
+ const textNode = textRef.value.getNode();
54790
+ const width = textNode.getTextWidth();
54791
+ const height = textNode.getHeight();
54792
+ rectConfig.value = {
54793
+ width,
54794
+ height,
54795
+ fill
54796
+ };
54797
+ }
54798
+ };
54799
+ watch(
54800
+ () => textConfig.value,
54801
+ async () => {
54802
+ await updateRectSize(textConfig.value._bgFill);
54803
+ },
54804
+ {
54805
+ immediate: true
54806
+ }
54807
+ );
54495
54808
  return (_ctx, _cache) => {
54809
+ const _component_v_rect = resolveComponent("v-rect");
54496
54810
  const _component_v_text = resolveComponent("v-text");
54497
54811
  const _component_v_group = resolveComponent("v-group");
54498
54812
  return openBlock(), createBlock(_component_v_group, {
54499
54813
  config: { x: __props.widget.x, y: __props.widget.y, id: __props.widget.id }
54500
54814
  }, {
54501
54815
  default: withCtx(() => [
54502
- createVNode(_component_v_text, { config: textConfig.value }, null, 8, ["config"])
54816
+ textConfig.value._bgFill ? (openBlock(), createBlock(_component_v_rect, {
54817
+ key: 0,
54818
+ config: rectConfig.value
54819
+ }, null, 8, ["config"])) : createCommentVNode("", true),
54820
+ createVNode(_component_v_text, {
54821
+ ref_key: "textRef",
54822
+ ref: textRef,
54823
+ config: textConfig.value,
54824
+ onConfigChange: updateRectSize
54825
+ }, null, 8, ["config"])
54503
54826
  ]),
54504
54827
  _: 1
54505
54828
  }, 8, ["config"]);
@@ -56748,6 +57071,15 @@ function useDocController(factory2, ops) {
56748
57071
  rawData() {
56749
57072
  return doc.dataManager.getRawData();
56750
57073
  },
57074
+ setRawData(data, defaultDataMap) {
57075
+ doc.dataManager.setRawData(data, defaultDataMap);
57076
+ },
57077
+ setMultiple(updates) {
57078
+ return doc.dataManager.setMultiple(updates);
57079
+ },
57080
+ getSubTableInfoList() {
57081
+ return doc.model?.getSubTableInfoList() ?? [];
57082
+ },
56751
57083
  // 业务操作 — 委托给 useDocOperations
56752
57084
  validate() {
56753
57085
  return ops.validate();
@@ -61532,6 +61864,14 @@ class FieldProviderRuntime {
61532
61864
  this.updateCache(res.data, res.total);
61533
61865
  return res;
61534
61866
  }
61867
+ /** 同步获取字段 */
61868
+ getFieldByKeySync(key) {
61869
+ return this.keyMap.get(key);
61870
+ }
61871
+ /** 同步获取字段 */
61872
+ getFieldByIdSync(id) {
61873
+ return this.idMap.get(id);
61874
+ }
61535
61875
  async getFieldByKey(key) {
61536
61876
  if (this.keyMap.has(key)) return this.keyMap.get(key);
61537
61877
  await this.fetchFields();