@windoc/core 0.3.23 → 0.3.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.
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var version = "0.3.23";
2
+ var version = "0.3.24";
3
3
 
4
4
  // src/dataset/enum/Common.ts
5
5
  var MaxHeightRatio = /* @__PURE__ */ ((MaxHeightRatio2) => {
@@ -106,21 +106,6 @@ function debounce(func, delay) {
106
106
  }, delay);
107
107
  };
108
108
  }
109
- function deepCloneOmitKeys(obj, omitKeys) {
110
- if (!obj || typeof obj !== "object") {
111
- return obj;
112
- }
113
- let newObj = {};
114
- if (Array.isArray(obj)) {
115
- newObj = obj.map((item) => deepCloneOmitKeys(item, omitKeys));
116
- } else {
117
- Object.keys(obj).forEach((key) => {
118
- if (omitKeys.includes(key)) return;
119
- newObj[key] = deepCloneOmitKeys(obj[key], omitKeys);
120
- });
121
- }
122
- return newObj;
123
- }
124
109
  function deepClone(obj) {
125
110
  if (typeof structuredClone === "function") {
126
111
  return structuredClone(obj);
@@ -4944,9 +4929,7 @@ function mergeSplitTableRowsForZip(trList) {
4944
4929
  for (let t = trList.length - 1; t >= 0; t--) {
4945
4930
  const splitTr = trList[t];
4946
4931
  if (!splitTr.splitParentId) continue;
4947
- const parentTrIdx = trList.findIndex(
4948
- (tr) => tr.id === splitTr.splitParentId
4949
- );
4932
+ const parentTrIdx = trList.findIndex((tr) => tr.id === splitTr.splitParentId);
4950
4933
  if (!~parentTrIdx) continue;
4951
4934
  const parentTr = trList[parentTrIdx];
4952
4935
  parentTr.height += splitTr.height;
@@ -5992,10 +5975,184 @@ ${ulListStyleText || `${listIndex + 1}.`}${buildText(
5992
5975
  return buildText(zipElementList(elementList));
5993
5976
  }
5994
5977
  function getSlimCloneElementList(elementList) {
5995
- return deepCloneOmitKeys(elementList, [
5996
- "metrics",
5997
- "style"
5998
- ]);
5978
+ const snapshotElementList = [];
5979
+ let preSourceElement = null;
5980
+ let preSnapshotElement = null;
5981
+ for (let i = 0; i < elementList.length; i++) {
5982
+ const element = elementList[i];
5983
+ if (preSourceElement && preSnapshotElement && isHistoryTextSnapshotMergeable(preSourceElement, element)) {
5984
+ preSnapshotElement.value += element.value;
5985
+ preSourceElement = element;
5986
+ continue;
5987
+ }
5988
+ const snapshotElement = cloneHistorySnapshotElement(element);
5989
+ snapshotElementList.push(snapshotElement);
5990
+ preSourceElement = element;
5991
+ preSnapshotElement = snapshotElement;
5992
+ }
5993
+ return snapshotElementList;
5994
+ }
5995
+ var HISTORY_SNAPSHOT_OMIT_ATTR = /* @__PURE__ */ new Set([
5996
+ "metrics",
5997
+ "style",
5998
+ "rowList",
5999
+ "positionList",
6000
+ "x",
6001
+ "y",
6002
+ "trIndex",
6003
+ "tdIndex",
6004
+ "isLastRowTd",
6005
+ "isLastColTd",
6006
+ "isLastTd",
6007
+ "rowIndex",
6008
+ "colIndex",
6009
+ "mainHeight",
6010
+ "realHeight",
6011
+ "realMinHeight",
6012
+ "splitBoundaryTop",
6013
+ "splitBoundaryBottom",
6014
+ "actualSize"
6015
+ ]);
6016
+ function cloneHistorySnapshotValue(payload) {
6017
+ if (!payload || typeof payload !== "object") {
6018
+ return payload;
6019
+ }
6020
+ if (Array.isArray(payload)) {
6021
+ return payload.map((item) => cloneHistorySnapshotValue(item));
6022
+ }
6023
+ const snapshot = {};
6024
+ for (const key of Object.keys(payload)) {
6025
+ if (HISTORY_SNAPSHOT_OMIT_ATTR.has(String(key))) continue;
6026
+ snapshot[String(key)] = cloneHistorySnapshotValue(
6027
+ payload[key]
6028
+ );
6029
+ }
6030
+ return snapshot;
6031
+ }
6032
+ function cloneHistorySnapshotTd(td) {
6033
+ const snapshot = {};
6034
+ for (const key of Object.keys(td)) {
6035
+ if (HISTORY_SNAPSHOT_OMIT_ATTR.has(String(key))) continue;
6036
+ const value = td[key];
6037
+ if (key === "value") {
6038
+ snapshot.value = getSlimCloneElementList(value);
6039
+ continue;
6040
+ }
6041
+ snapshot[String(key)] = cloneHistorySnapshotValue(value);
6042
+ }
6043
+ return snapshot;
6044
+ }
6045
+ function cloneHistorySnapshotTr(tr) {
6046
+ const snapshot = {};
6047
+ for (const key of Object.keys(tr)) {
6048
+ if (HISTORY_SNAPSHOT_OMIT_ATTR.has(String(key))) continue;
6049
+ const value = tr[key];
6050
+ if (key === "tdList") {
6051
+ snapshot.tdList = value.map((td) => cloneHistorySnapshotTd(td));
6052
+ continue;
6053
+ }
6054
+ snapshot[String(key)] = cloneHistorySnapshotValue(value);
6055
+ }
6056
+ return snapshot;
6057
+ }
6058
+ function cloneHistorySnapshotElement(element) {
6059
+ const snapshot = {};
6060
+ for (const key of Object.keys(element)) {
6061
+ if (HISTORY_SNAPSHOT_OMIT_ATTR.has(String(key))) continue;
6062
+ const value = element[key];
6063
+ if (key === "trList" && Array.isArray(value)) {
6064
+ snapshot.trList = value.map((tr) => cloneHistorySnapshotTr(tr));
6065
+ continue;
6066
+ }
6067
+ if (key === "valueList" && Array.isArray(value)) {
6068
+ snapshot.valueList = getSlimCloneElementList(value);
6069
+ continue;
6070
+ }
6071
+ if (key === "control" && value && typeof value === "object") {
6072
+ snapshot.control = cloneHistorySnapshotControl(
6073
+ value
6074
+ );
6075
+ continue;
6076
+ }
6077
+ snapshot[String(key)] = cloneHistorySnapshotValue(value);
6078
+ }
6079
+ return snapshot;
6080
+ }
6081
+ function cloneHistorySnapshotControl(control) {
6082
+ const snapshot = {};
6083
+ for (const key of Object.keys(control)) {
6084
+ const value = control[key];
6085
+ if (key === "value" && Array.isArray(value)) {
6086
+ snapshot.value = getSlimCloneElementList(value);
6087
+ continue;
6088
+ }
6089
+ snapshot[String(key)] = cloneHistorySnapshotValue(value);
6090
+ }
6091
+ return snapshot;
6092
+ }
6093
+ function isHistoryTextSnapshotElement(element) {
6094
+ return !element.type || TEXTLIKE_ELEMENT_TYPE.includes(element.type);
6095
+ }
6096
+ function isHistoryTextSnapshotMergeable(source, target) {
6097
+ if (!isHistoryTextSnapshotElement(source) || !isHistoryTextSnapshotElement(target)) {
6098
+ return false;
6099
+ }
6100
+ return isSameHistoryElementExceptValue(source, target);
6101
+ }
6102
+ function isSameHistoryElementExceptValue(source, target) {
6103
+ const sourceKeys = Object.keys(source).filter(
6104
+ (key) => !HISTORY_SNAPSHOT_OMIT_ATTR.has(key)
6105
+ );
6106
+ const targetKeys = Object.keys(target).filter(
6107
+ (key) => !HISTORY_SNAPSHOT_OMIT_ATTR.has(key)
6108
+ );
6109
+ if (sourceKeys.length !== targetKeys.length) return false;
6110
+ for (let s = 0; s < sourceKeys.length; s++) {
6111
+ const key = sourceKeys[s];
6112
+ if (key === "value") continue;
6113
+ if (key === "groupIds" && Array.isArray(source[key]) && Array.isArray(target[key]) && isArrayEqual(source[key], target[key])) {
6114
+ continue;
6115
+ }
6116
+ if (source[key] !== target[key]) {
6117
+ return false;
6118
+ }
6119
+ }
6120
+ return true;
6121
+ }
6122
+ function inflateElementList(elementList) {
6123
+ let i = 0;
6124
+ while (i < elementList.length) {
6125
+ const element = elementList[i];
6126
+ if (element.trList?.length) {
6127
+ for (let t = 0; t < element.trList.length; t++) {
6128
+ const tr = element.trList[t];
6129
+ for (let d = 0; d < tr.tdList.length; d++) {
6130
+ inflateElementList(tr.tdList[d].value);
6131
+ }
6132
+ }
6133
+ }
6134
+ if (element.valueList?.length) {
6135
+ inflateElementList(element.valueList);
6136
+ }
6137
+ if (element.control?.value?.length) {
6138
+ inflateElementList(element.control.value);
6139
+ }
6140
+ if (isHistoryTextSnapshotElement(element) && element.value?.length > 1) {
6141
+ const textList = splitText(element.value);
6142
+ elementList.splice(
6143
+ i,
6144
+ 1,
6145
+ ...textList.map((value) => ({
6146
+ ...element,
6147
+ value
6148
+ }))
6149
+ );
6150
+ i += textList.length;
6151
+ continue;
6152
+ }
6153
+ i++;
6154
+ }
6155
+ return elementList;
5999
6156
  }
6000
6157
  function getIsBlockElement(element) {
6001
6158
  return !!element?.type && (BLOCK_ELEMENT_TYPE.includes(element.type) || element.imgDisplay === "inline" /* INLINE */);
@@ -7668,7 +7825,8 @@ function backspace(evt, host) {
7668
7825
  } else {
7669
7826
  rangeManager.setRange(curIndex, curIndex);
7670
7827
  draw.render({
7671
- curIndex
7828
+ curIndex,
7829
+ dirtyStartIndex: curIndex + 1
7672
7830
  });
7673
7831
  }
7674
7832
  }
@@ -7810,7 +7968,8 @@ function del(evt, host) {
7810
7968
  } else {
7811
7969
  rangeManager.setRange(curIndex, curIndex);
7812
7970
  draw.render({
7813
- curIndex
7971
+ curIndex,
7972
+ dirtyStartIndex: curIndex + 1
7814
7973
  });
7815
7974
  }
7816
7975
  }
@@ -8652,10 +8811,12 @@ function input(data2, host) {
8652
8811
  if (~curIndex) {
8653
8812
  rangeManager.setRange(curIndex, curIndex);
8654
8813
  const isWordBoundary = !isComposing && /[\s\p{P}]/u.test(data2);
8814
+ const dirtyStartIndex = startIndex + 1;
8655
8815
  draw.render({
8656
8816
  curIndex,
8657
8817
  isSubmitHistory: !isComposing,
8658
- isInputHistory: !isComposing && !isWordBoundary
8818
+ isInputHistory: !isComposing && !isWordBoundary,
8819
+ dirtyStartIndex
8659
8820
  });
8660
8821
  }
8661
8822
  if (isComposing && ~curIndex) {
@@ -9339,7 +9500,7 @@ var HistoryManager = class {
9339
9500
  const pop = this.undoStack.pop();
9340
9501
  this.redoStack.push(pop);
9341
9502
  if (this.undoStack.length) {
9342
- this.undoStack[this.undoStack.length - 1]();
9503
+ this.undoStack[this.undoStack.length - 1].restore();
9343
9504
  }
9344
9505
  }
9345
9506
  }
@@ -9347,11 +9508,11 @@ var HistoryManager = class {
9347
9508
  if (this.redoStack.length) {
9348
9509
  const pop = this.redoStack.pop();
9349
9510
  this.undoStack.push(pop);
9350
- pop();
9511
+ pop.restore();
9351
9512
  }
9352
9513
  }
9353
- execute(fn) {
9354
- this.undoStack.push(fn);
9514
+ execute(entry) {
9515
+ this.undoStack.push(this._normalizeEntry(entry));
9355
9516
  if (this.redoStack.length) {
9356
9517
  this.redoStack = [];
9357
9518
  }
@@ -9359,11 +9520,12 @@ var HistoryManager = class {
9359
9520
  this.undoStack.shift();
9360
9521
  }
9361
9522
  }
9362
- replaceLatest(fn) {
9523
+ replaceLatest(entry) {
9524
+ const normalizedEntry = this._normalizeEntry(entry);
9363
9525
  if (this.undoStack.length > 0) {
9364
- this.undoStack[this.undoStack.length - 1] = fn;
9526
+ this.undoStack[this.undoStack.length - 1] = normalizedEntry;
9365
9527
  } else {
9366
- this.execute(fn);
9528
+ this.execute(normalizedEntry);
9367
9529
  }
9368
9530
  if (this.redoStack.length) {
9369
9531
  this.redoStack = [];
@@ -9394,6 +9556,14 @@ var HistoryManager = class {
9394
9556
  popUndo() {
9395
9557
  return this.undoStack.pop();
9396
9558
  }
9559
+ _normalizeEntry(entry) {
9560
+ if (typeof entry === "function") {
9561
+ return {
9562
+ restore: entry
9563
+ };
9564
+ }
9565
+ return entry;
9566
+ }
9397
9567
  };
9398
9568
 
9399
9569
  // src/core/position/Position.ts
@@ -11601,6 +11771,7 @@ var ScrollObserver = class {
11601
11771
  const { intersectionPageNo, visiblePageNoList } = this.getPageVisibleInfo();
11602
11772
  this.draw.setIntersectionPageNo(intersectionPageNo);
11603
11773
  this.draw.setVisiblePageNoList(visiblePageNoList);
11774
+ this.draw.renderVisiblePages(visiblePageNoList);
11604
11775
  }, 150);
11605
11776
  this.draw = draw;
11606
11777
  this.options = draw.getOptions();
@@ -20408,6 +20579,9 @@ var Area = class {
20408
20579
  getAreaInfo() {
20409
20580
  return this.areaInfoMap;
20410
20581
  }
20582
+ clear() {
20583
+ this.areaInfoMap.clear();
20584
+ }
20411
20585
  getActiveAreaId() {
20412
20586
  if (!this.areaInfoMap.size) return null;
20413
20587
  const { startIndex } = this.range.getRange();
@@ -20799,6 +20973,7 @@ var Draw = class {
20799
20973
  this.container = this._wrapContainer(rootContainer);
20800
20974
  this.pageList = [];
20801
20975
  this.ctxList = [];
20976
+ this.pageRenderVersionList = [];
20802
20977
  this.pageNo = 0;
20803
20978
  this.renderCount = 0;
20804
20979
  this.pagePixelRatio = null;
@@ -20811,6 +20986,7 @@ var Draw = class {
20811
20986
  this._formatContainer();
20812
20987
  this.pageContainer = this._createPageContainer();
20813
20988
  this._createPage(0);
20989
+ this.measureCtx = this._createMeasureContext();
20814
20990
  this.i18n = new I18n(options.locale);
20815
20991
  this.historyManager = new HistoryManager(this);
20816
20992
  this.position = new Position(this);
@@ -20875,6 +21051,8 @@ var Draw = class {
20875
21051
  this.pageRowList = [];
20876
21052
  this.painterStyle = null;
20877
21053
  this.painterOptions = null;
21054
+ this.elementFontCache = /* @__PURE__ */ new WeakMap();
21055
+ this.elementRowMarginCache = /* @__PURE__ */ new WeakMap();
20878
21056
  this.visiblePageNoList = [];
20879
21057
  this.intersectionPageNo = 0;
20880
21058
  this.lazyRenderIntersectionObserver = null;
@@ -21041,7 +21219,9 @@ var Draw = class {
21041
21219
  getContextInnerWidth() {
21042
21220
  const positionContext = this.position.getPositionContext();
21043
21221
  if (positionContext.isTable) {
21044
- const td = this.resolveTableCellContext(this.getOriginalElementList())?.td;
21222
+ const td = this.resolveTableCellContext(
21223
+ this.getOriginalElementList()
21224
+ )?.td;
21045
21225
  if (!td) return this.getColumnWidth() / this.options.scale;
21046
21226
  const tdPadding = this.getTdPadding();
21047
21227
  return td.width - tdPadding[1] - tdPadding[3];
@@ -21094,6 +21274,7 @@ var Draw = class {
21094
21274
  return this.visiblePageNoList;
21095
21275
  }
21096
21276
  setVisiblePageNoList(payload) {
21277
+ if (isArrayEqual(this.visiblePageNoList, payload)) return;
21097
21278
  this.visiblePageNoList = payload;
21098
21279
  if (this.listener.visiblePageNoListChange) {
21099
21280
  this.listener.visiblePageNoListChange(this.visiblePageNoList);
@@ -21106,6 +21287,7 @@ var Draw = class {
21106
21287
  return this.intersectionPageNo;
21107
21288
  }
21108
21289
  setIntersectionPageNo(payload) {
21290
+ if (this.intersectionPageNo === payload) return;
21109
21291
  this.intersectionPageNo = payload;
21110
21292
  if (this.listener.intersectionPageNoChange) {
21111
21293
  this.listener.intersectionPageNoChange(this.intersectionPageNo);
@@ -21133,7 +21315,9 @@ var Draw = class {
21133
21315
  candidateIndexes.push(context.index);
21134
21316
  }
21135
21317
  if (context.tableId) {
21136
- const tableIndex = sourceElementList.findIndex((el) => el.id === context.tableId);
21318
+ const tableIndex = sourceElementList.findIndex(
21319
+ (el) => el.id === context.tableId
21320
+ );
21137
21321
  if (~tableIndex && !candidateIndexes.includes(tableIndex)) {
21138
21322
  candidateIndexes.push(tableIndex);
21139
21323
  }
@@ -21242,9 +21426,7 @@ var Draw = class {
21242
21426
  return this.header.getElementList();
21243
21427
  }
21244
21428
  getTableElementList(sourceElementList) {
21245
- const splitCellSelectionContext = this.getSplitCellSelectionContext(
21246
- sourceElementList
21247
- );
21429
+ const splitCellSelectionContext = this.getSplitCellSelectionContext(sourceElementList);
21248
21430
  if (splitCellSelectionContext) {
21249
21431
  return splitCellSelectionContext.value;
21250
21432
  }
@@ -21368,10 +21550,7 @@ var Draw = class {
21368
21550
  positionContext.trId = continuationTr.id;
21369
21551
  positionContext.tableId = tableId;
21370
21552
  this.position.setPositionContext(positionContext);
21371
- this.range.setRange(
21372
- continuationCursorIndex,
21373
- continuationCursorIndex
21374
- );
21553
+ this.range.setRange(continuationCursorIndex, continuationCursorIndex);
21375
21554
  this.pendingTableCursorIndex = continuationCursorIndex;
21376
21555
  return true;
21377
21556
  }
@@ -21431,7 +21610,10 @@ var Draw = class {
21431
21610
  });
21432
21611
  const splitCellSelection = this.range.getSplitCellSelection();
21433
21612
  if (splitCellSelection) {
21434
- const curIndex2 = this.replaceSplitCellSelection(payload, splitCellSelection);
21613
+ const curIndex2 = this.replaceSplitCellSelection(
21614
+ payload,
21615
+ splitCellSelection
21616
+ );
21435
21617
  if (~curIndex2) {
21436
21618
  this.range.setRange(curIndex2, curIndex2);
21437
21619
  this.render({
@@ -21561,12 +21743,7 @@ var Draw = class {
21561
21743
  trId: rootCellContext.tr.id,
21562
21744
  tdId: rootTd.id
21563
21745
  });
21564
- this.spliceElementList(
21565
- rootTd.value,
21566
- 1,
21567
- rootTd.value.length - 1,
21568
- payload
21569
- );
21746
+ this.spliceElementList(rootTd.value, 1, rootTd.value.length - 1, payload);
21570
21747
  rootTd.rowList = void 0;
21571
21748
  rootTd.positionList = void 0;
21572
21749
  rootTd.mainHeight = void 0;
@@ -21986,6 +22163,15 @@ var Draw = class {
21986
22163
  this._initPageContext(ctx);
21987
22164
  this.pageList.push(canvas);
21988
22165
  this.ctxList.push(ctx);
22166
+ this.pageRenderVersionList.push(0);
22167
+ }
22168
+ _createMeasureContext() {
22169
+ const canvas = document.createElement("canvas");
22170
+ const ctx = canvas.getContext("2d");
22171
+ ctx.letterSpacing = "0px";
22172
+ ctx.wordSpacing = "0px";
22173
+ ctx.direction = "ltr";
22174
+ return ctx;
21989
22175
  }
21990
22176
  _initPageContext(ctx) {
21991
22177
  const dpr = this.getPagePixelRatio();
@@ -21998,8 +22184,22 @@ var Draw = class {
21998
22184
  const { defaultSize, defaultFont } = this.options;
21999
22185
  const font = el.font || defaultFont;
22000
22186
  const size = el.actualSize || el.size || defaultSize;
22187
+ const cache = this.elementFontCache.get(el);
22188
+ if (cache && cache.scale === scale && cache.font === font && cache.size === size && cache.actualSize === el.actualSize && cache.bold === el.bold && cache.italic === el.italic) {
22189
+ return cache.style;
22190
+ }
22001
22191
  const sizePx = size * (96 / 72) * scale;
22002
- return `${el.italic ? "italic " : ""}${el.bold ? "bold " : ""}${sizePx}px ${font}`;
22192
+ const style = `${el.italic ? "italic " : ""}${el.bold ? "bold " : ""}${sizePx}px ${font}`;
22193
+ this.elementFontCache.set(el, {
22194
+ scale,
22195
+ font,
22196
+ size,
22197
+ actualSize: el.actualSize,
22198
+ bold: el.bold,
22199
+ italic: el.italic,
22200
+ style
22201
+ });
22202
+ return style;
22003
22203
  }
22004
22204
  getElementSize(el) {
22005
22205
  return el.actualSize || el.size || this.options.defaultSize;
@@ -22012,13 +22212,25 @@ var Draw = class {
22012
22212
  scale
22013
22213
  } = this.options;
22014
22214
  const fontSize = el.size || defaultSize;
22215
+ const rowMarginValue = el.rowMargin ?? defaultRowMargin;
22216
+ const cache = this.elementRowMarginCache.get(el);
22217
+ if (cache && cache.scale === scale && cache.size === fontSize && cache.rowMargin === rowMarginValue) {
22218
+ return cache.value;
22219
+ }
22015
22220
  let ratio = 1;
22016
22221
  if (fontSize < 12) {
22017
22222
  ratio = fontSize / 12;
22018
22223
  } else if (fontSize > 30) {
22019
22224
  ratio = 1 + (fontSize - 30) / 30;
22020
22225
  }
22021
- return defaultBasicRowMarginHeight * ratio * (el.rowMargin ?? defaultRowMargin) * scale;
22226
+ const value = defaultBasicRowMarginHeight * ratio * rowMarginValue * scale;
22227
+ this.elementRowMarginCache.set(el, {
22228
+ scale,
22229
+ size: fontSize,
22230
+ rowMargin: rowMarginValue,
22231
+ value
22232
+ });
22233
+ return value;
22022
22234
  }
22023
22235
  createListStateSeed(initialListState) {
22024
22236
  const listLevelIndex = /* @__PURE__ */ new Map();
@@ -22097,7 +22309,12 @@ var Draw = class {
22097
22309
  pageHeight = 0,
22098
22310
  mainOuterHeight = 0,
22099
22311
  surroundElementList = [],
22100
- initialListState
22312
+ initialListState,
22313
+ hasListElement = true,
22314
+ fromIndex = 0,
22315
+ initialY = startY,
22316
+ initialPageNo = 0,
22317
+ initialRowIndex = 0
22101
22318
  } = payload;
22102
22319
  const {
22103
22320
  defaultSize,
@@ -22106,27 +22323,62 @@ var Draw = class {
22106
22323
  defaultTabWidth
22107
22324
  } = this.options;
22108
22325
  const defaultBasicRowMarginHeight = this.getDefaultBasicRowMarginHeight();
22109
- const canvas = document.createElement("canvas");
22110
- const ctx = canvas.getContext("2d");
22111
- const listStyleMap = this.listParticle.computeListStyle(ctx, elementList);
22326
+ const ctx = this.measureCtx;
22327
+ ctx.save();
22328
+ ctx.font = "10px sans-serif";
22329
+ ctx.textAlign = "start";
22330
+ ctx.textBaseline = "alphabetic";
22331
+ const listStyleMap = hasListElement ? this.listParticle.computeListStyle(ctx, elementList) : /* @__PURE__ */ new Map();
22332
+ const wordMeasureCache = /* @__PURE__ */ new Map();
22333
+ const getWordMeasure = (curIndex, elementFont) => {
22334
+ const cache = wordMeasureCache.get(curIndex);
22335
+ if (cache) return cache;
22336
+ let endIndex = curIndex;
22337
+ while (endIndex < elementList.length) {
22338
+ const measureElement = elementList[endIndex];
22339
+ if (measureElement.type && measureElement.type !== "text" /* TEXT */ || !this.LETTER_REG.test(measureElement.value)) {
22340
+ break;
22341
+ }
22342
+ if (this.getElementFont(measureElement) !== elementFont) {
22343
+ const fallbackWord = this.textParticle.measureWord(
22344
+ ctx,
22345
+ elementList,
22346
+ curIndex
22347
+ );
22348
+ wordMeasureCache.set(curIndex, fallbackWord);
22349
+ return fallbackWord;
22350
+ }
22351
+ endIndex++;
22352
+ }
22353
+ const endElement = elementList[endIndex] || null;
22354
+ let suffixWidth = 0;
22355
+ for (let i = endIndex - 1; i >= curIndex; i--) {
22356
+ suffixWidth += this.textParticle.measureText(ctx, elementList[i]).width;
22357
+ wordMeasureCache.set(i, {
22358
+ width: suffixWidth,
22359
+ endElement
22360
+ });
22361
+ }
22362
+ return wordMeasureCache.get(curIndex);
22363
+ };
22112
22364
  const rowList = [];
22113
- if (elementList.length) {
22365
+ if (elementList.length && fromIndex < elementList.length) {
22114
22366
  rowList.push({
22115
22367
  width: 0,
22116
22368
  height: 0,
22117
22369
  ascent: 0,
22118
22370
  elementList: [],
22119
- startIndex: 0,
22120
- rowIndex: 0,
22121
- rowFlex: elementList?.[0]?.rowFlex || elementList?.[1]?.rowFlex
22371
+ startIndex: fromIndex,
22372
+ rowIndex: initialRowIndex,
22373
+ rowFlex: elementList?.[fromIndex]?.rowFlex || elementList?.[fromIndex + 1]?.rowFlex
22122
22374
  });
22123
22375
  }
22124
22376
  let x = startX;
22125
- let y = startY;
22126
- let pageNo = 0;
22377
+ let y = initialY;
22378
+ let pageNo = initialPageNo;
22127
22379
  const listState = this.createListStateSeed(initialListState);
22128
22380
  let controlRealWidth = 0;
22129
- for (let i = 0; i < elementList.length; i++) {
22381
+ for (let i = fromIndex; i < elementList.length; i++) {
22130
22382
  const curRow = rowList[rowList.length - 1];
22131
22383
  const element = elementList[i];
22132
22384
  const rowMargin = this.getElementRowMargin(element);
@@ -22172,9 +22424,7 @@ var Draw = class {
22172
22424
  } else if (element.type === "table" /* TABLE */) {
22173
22425
  let activeSplitRange;
22174
22426
  let mergedSplitFallback;
22175
- const logicalSplitCursor = this.getCollapsedSplitTableCursorContext(
22176
- element
22177
- );
22427
+ const logicalSplitCursor = this.getCollapsedSplitTableCursorContext(element);
22178
22428
  if (element.pagingId) {
22179
22429
  let tableIndex = i + 1;
22180
22430
  let combineCount = 0;
@@ -22779,16 +23029,14 @@ var Draw = class {
22779
23029
  element.actualSize = Math.ceil(size * 0.6);
22780
23030
  }
22781
23031
  metrics.height = (element.actualSize || size) * scale;
22782
- ctx.font = this.getElementFont(element);
23032
+ const elementFont = this.getElementFont(element);
23033
+ ctx.font = elementFont;
22783
23034
  const fontMetrics = this.textParticle.measureText(ctx, element);
22784
23035
  metrics.width = fontMetrics.width * scale;
22785
23036
  if (element.letterSpacing) {
22786
23037
  metrics.width += element.letterSpacing * scale;
22787
23038
  }
22788
- const basisMetrics = this.textParticle.measureBasisWord(
22789
- ctx,
22790
- element.font
22791
- );
23039
+ const basisMetrics = this.textParticle.measureBasisWord(ctx, elementFont);
22792
23040
  metrics.boundingBoxAscent = basisMetrics.fontBoundingBoxAscent * scale;
22793
23041
  metrics.boundingBoxDescent = basisMetrics.fontBoundingBoxDescent * scale;
22794
23042
  if (element.type === "superscript" /* SUPERSCRIPT */) {
@@ -22825,11 +23073,7 @@ var Draw = class {
22825
23073
  if ((!preElement?.type || preElement?.type === "text" /* TEXT */) && (!element.type || element.type === "text" /* TEXT */)) {
22826
23074
  const word = `${preElement?.value || ""}${element.value}`;
22827
23075
  if (this.WORD_LIKE_REG.test(word)) {
22828
- const { width, endElement } = this.textParticle.measureWord(
22829
- ctx,
22830
- elementList,
22831
- i
22832
- );
23076
+ const { width, endElement } = getWordMeasure(i, ctx.font);
22833
23077
  const wordWidth = width * scale;
22834
23078
  if (endElement && wordWidth <= availableWidth) {
22835
23079
  curRowWidth += wordWidth;
@@ -22962,6 +23206,7 @@ var Draw = class {
22962
23206
  x += metrics.width;
22963
23207
  }
22964
23208
  }
23209
+ ctx.restore();
22965
23210
  return rowList;
22966
23211
  }
22967
23212
  _applyRowSpacing() {
@@ -23554,30 +23799,11 @@ var Draw = class {
23554
23799
  if (this.isGraffitiMode()) {
23555
23800
  this.graffiti.render(ctx, pageNo);
23556
23801
  }
23802
+ this.pageRenderVersionList[pageNo] = this.renderCount;
23557
23803
  }
23558
23804
  _disconnectLazyRender() {
23559
23805
  this.lazyRenderIntersectionObserver?.disconnect();
23560
- }
23561
- _lazyRender() {
23562
- const positionList = this.position.getOriginalMainPositionList();
23563
- const elementList = this.getOriginalMainElementList();
23564
- this._disconnectLazyRender();
23565
- this.lazyRenderIntersectionObserver = new IntersectionObserver((entries) => {
23566
- entries.forEach((entry) => {
23567
- if (entry.isIntersecting) {
23568
- const index = Number(entry.target.dataset.index);
23569
- this._drawPage({
23570
- elementList,
23571
- positionList,
23572
- rowList: this.pageRowList[index],
23573
- pageNo: index
23574
- });
23575
- }
23576
- });
23577
- });
23578
- this.pageList.forEach((el) => {
23579
- this.lazyRenderIntersectionObserver.observe(el);
23580
- });
23806
+ this.lazyRenderIntersectionObserver = null;
23581
23807
  }
23582
23808
  _immediateRender() {
23583
23809
  const positionList = this.position.getOriginalMainPositionList();
@@ -23591,6 +23817,100 @@ var Draw = class {
23591
23817
  });
23592
23818
  }
23593
23819
  }
23820
+ _collectMainRenderMeta() {
23821
+ const surroundElementList = [];
23822
+ let hasAreaElement = false;
23823
+ let hasListElement = false;
23824
+ let hasStructuralElement = false;
23825
+ for (let i = 0; i < this.elementList.length; i++) {
23826
+ const element = this.elementList[i];
23827
+ if (!hasAreaElement && element.areaId) {
23828
+ hasAreaElement = true;
23829
+ }
23830
+ if (!hasListElement && element.listId) {
23831
+ hasListElement = true;
23832
+ }
23833
+ if (!hasStructuralElement && (element.type === "table" /* TABLE */ || element.type === "block" /* BLOCK */ || element.type === "pageBreak" /* PAGE_BREAK */ || element.type === "columnBreak" /* COLUMN_BREAK */ || element.type === "image" /* IMAGE */ || element.type === "latex" /* LATEX */ || element.type === "separator" /* SEPARATOR */)) {
23834
+ hasStructuralElement = true;
23835
+ }
23836
+ if (element.imgDisplay === "surround" /* SURROUND */) {
23837
+ surroundElementList.push(element);
23838
+ }
23839
+ }
23840
+ return {
23841
+ hasAreaElement,
23842
+ hasListElement,
23843
+ hasStructuralElement,
23844
+ surroundElementList
23845
+ };
23846
+ }
23847
+ _getIncrementalRestartState(dirtyStartIndex, rowList, pageRowList, startY) {
23848
+ if (!rowList.length || !pageRowList.length) return null;
23849
+ const searchIndex = Math.max(dirtyStartIndex - 1, 0);
23850
+ let restartRowIndex = -1;
23851
+ for (let i = 0; i < rowList.length; i++) {
23852
+ if (rowList[i].startIndex <= searchIndex) {
23853
+ restartRowIndex = i;
23854
+ } else {
23855
+ break;
23856
+ }
23857
+ }
23858
+ if (restartRowIndex < 0) return null;
23859
+ if (restartRowIndex > 0 && this.elementList[rowList[restartRowIndex].startIndex]?.value === ZERO && !this.elementList[rowList[restartRowIndex].startIndex]?.listWrap) {
23860
+ restartRowIndex -= 1;
23861
+ }
23862
+ const restartRow = rowList[restartRowIndex];
23863
+ const fromIndex = Math.min(restartRow.startIndex, this.elementList.length);
23864
+ let initialPageNo = 0;
23865
+ let initialY = startY;
23866
+ let absoluteRowIndex = 0;
23867
+ let isFound = false;
23868
+ for (let pageNo = 0; pageNo < pageRowList.length; pageNo++) {
23869
+ const rows = pageRowList[pageNo];
23870
+ let y = startY;
23871
+ for (let rowNo = 0; rowNo < rows.length; rowNo++) {
23872
+ if (absoluteRowIndex === restartRowIndex) {
23873
+ initialPageNo = pageNo;
23874
+ initialY = y;
23875
+ isFound = true;
23876
+ break;
23877
+ }
23878
+ const row = rows[rowNo];
23879
+ y += (row.offsetY || 0) + (row.spaceAbove || 0) + row.height + (row.spaceBelow || 0);
23880
+ absoluteRowIndex++;
23881
+ }
23882
+ if (isFound) break;
23883
+ }
23884
+ if (!isFound) return null;
23885
+ return {
23886
+ fromIndex,
23887
+ initialY,
23888
+ initialPageNo,
23889
+ initialRowIndex: restartRow.rowIndex,
23890
+ initialListState: this.getListStateBeforeIndex(this.elementList, fromIndex),
23891
+ prefixRows: rowList.slice(0, restartRowIndex)
23892
+ };
23893
+ }
23894
+ renderVisiblePages(pageNoList) {
23895
+ const positionList = this.position.getOriginalMainPositionList();
23896
+ const elementList = this.getOriginalMainElementList();
23897
+ const targetPageNoList = pageNoList ?? this.visiblePageNoList;
23898
+ if (!targetPageNoList?.length) return;
23899
+ const renderedPageNoSet = /* @__PURE__ */ new Set();
23900
+ for (let i = 0; i < targetPageNoList.length; i++) {
23901
+ const pageNo = targetPageNoList[i];
23902
+ if (renderedPageNoSet.has(pageNo) || pageNo < 0 || pageNo >= this.pageRowList.length || this.pageRenderVersionList[pageNo] === this.renderCount) {
23903
+ continue;
23904
+ }
23905
+ renderedPageNoSet.add(pageNo);
23906
+ this._drawPage({
23907
+ elementList,
23908
+ positionList,
23909
+ rowList: this.pageRowList[pageNo],
23910
+ pageNo
23911
+ });
23912
+ }
23913
+ }
23594
23914
  render(payload) {
23595
23915
  this.renderCount++;
23596
23916
  const { header, footer } = this.options;
@@ -23602,15 +23922,19 @@ var Draw = class {
23602
23922
  isLazy = true,
23603
23923
  isInit = false,
23604
23924
  isSourceHistory = false,
23605
- isFirstRender = false
23925
+ isFirstRender = false,
23926
+ dirtyStartIndex
23606
23927
  } = payload || {};
23607
23928
  let { curIndex } = payload || {};
23608
23929
  this.pendingTableCursorIndex = void 0;
23609
23930
  const innerWidth = this.getInnerWidth();
23610
23931
  const columnWidth = this.getColumnWidth();
23611
23932
  const isPagingMode = this.getIsPagingMode();
23933
+ const columnCount = this.getColumnCount();
23612
23934
  const oldPageSize = this.pageRowList.length;
23613
23935
  if (isCompute) {
23936
+ const oldRowList = this.rowList;
23937
+ const oldPageRowList = this.pageRowList;
23614
23938
  this.position.setFloatPositionList([]);
23615
23939
  if (isPagingMode) {
23616
23940
  if (!header.disabled) {
@@ -23626,8 +23950,13 @@ var Draw = class {
23626
23950
  const mainOuterHeight = this.getMainOuterHeight();
23627
23951
  const startX = margins[3];
23628
23952
  const startY = margins[0] + extraHeight;
23629
- const surroundElementList = pickSurroundElementList(this.elementList);
23630
- this.rowList = this.computeRowList({
23953
+ const {
23954
+ hasAreaElement,
23955
+ hasListElement,
23956
+ hasStructuralElement,
23957
+ surroundElementList
23958
+ } = this._collectMainRenderMeta();
23959
+ const rowListPayload = {
23631
23960
  startX,
23632
23961
  startY,
23633
23962
  pageHeight,
@@ -23635,12 +23964,41 @@ var Draw = class {
23635
23964
  isPagingMode,
23636
23965
  innerWidth: columnWidth,
23637
23966
  surroundElementList,
23967
+ hasListElement,
23638
23968
  elementList: this.elementList
23639
- });
23969
+ };
23970
+ const canUseIncrementalMainRows = dirtyStartIndex !== void 0 && dirtyStartIndex >= 0 && !isInit && !isSourceHistory && isPagingMode && columnCount === 1 && !hasAreaElement && !hasStructuralElement && surroundElementList.length === 0 && oldRowList.length > 0 && oldPageRowList.length > 0;
23971
+ if (canUseIncrementalMainRows) {
23972
+ const restartState = this._getIncrementalRestartState(
23973
+ dirtyStartIndex,
23974
+ oldRowList,
23975
+ oldPageRowList,
23976
+ startY
23977
+ );
23978
+ if (restartState) {
23979
+ const suffixRows = this.computeRowList({
23980
+ ...rowListPayload,
23981
+ fromIndex: restartState.fromIndex,
23982
+ initialY: restartState.initialY,
23983
+ initialPageNo: restartState.initialPageNo,
23984
+ initialRowIndex: restartState.initialRowIndex,
23985
+ initialListState: restartState.initialListState
23986
+ });
23987
+ this.rowList = restartState.prefixRows.concat(suffixRows);
23988
+ } else {
23989
+ this.rowList = this.computeRowList(rowListPayload);
23990
+ }
23991
+ } else {
23992
+ this.rowList = this.computeRowList(rowListPayload);
23993
+ }
23640
23994
  this._applyRowSpacing();
23641
23995
  this.pageRowList = this._computePageList();
23642
23996
  this.position.computePositionList();
23643
- this.area.compute();
23997
+ if (hasAreaElement) {
23998
+ this.area.compute();
23999
+ } else {
24000
+ this.area.clear();
24001
+ }
23644
24002
  if (!this.isPrintMode()) {
23645
24003
  const searchKeyword = this.search.getSearchKeyword();
23646
24004
  if (searchKeyword) {
@@ -23664,10 +24022,26 @@ var Draw = class {
23664
24022
  if (prePageCount > curPageCount) {
23665
24023
  const deleteCount = prePageCount - curPageCount;
23666
24024
  this.ctxList.splice(curPageCount, deleteCount);
24025
+ this.pageRenderVersionList.splice(curPageCount, deleteCount);
23667
24026
  this.pageList.splice(curPageCount, deleteCount).forEach((page) => page.remove());
23668
24027
  }
23669
24028
  if (isLazy && isPagingMode) {
23670
- this._lazyRender();
24029
+ let visiblePageNoList = this.visiblePageNoList.filter(
24030
+ (pageNo) => pageNo >= 0 && pageNo < curPageCount
24031
+ );
24032
+ let intersectionPageNo = Math.min(
24033
+ this.intersectionPageNo,
24034
+ Math.max(curPageCount - 1, 0)
24035
+ );
24036
+ if (!visiblePageNoList.length || oldPageSize !== curPageCount || intersectionPageNo >= curPageCount) {
24037
+ const visibleInfo = this.scrollObserver.getPageVisibleInfo();
24038
+ intersectionPageNo = visibleInfo.intersectionPageNo;
24039
+ visiblePageNoList = visibleInfo.visiblePageNoList;
24040
+ this.setIntersectionPageNo(intersectionPageNo);
24041
+ this.setVisiblePageNoList(visiblePageNoList);
24042
+ }
24043
+ const renderPageNoList = visiblePageNoList.length ? visiblePageNoList : [intersectionPageNo];
24044
+ this.renderVisiblePages(renderPageNoList);
23671
24045
  } else {
23672
24046
  this._immediateRender();
23673
24047
  }
@@ -23716,7 +24090,9 @@ var Draw = class {
23716
24090
  const positionContext = this.position.getPositionContext();
23717
24091
  const positionList = this.position.getPositionList();
23718
24092
  if (positionContext.isTable) {
23719
- const tablePositionList = this.resolveTableCellContext(this.getOriginalElementList())?.td.positionList;
24093
+ const tablePositionList = this.resolveTableCellContext(
24094
+ this.getOriginalElementList()
24095
+ )?.td.positionList;
23720
24096
  if (curIndex === void 0 && tablePositionList) {
23721
24097
  curIndex = tablePositionList.length - 1;
23722
24098
  }
@@ -23743,36 +24119,51 @@ var Draw = class {
23743
24119
  return curIndex;
23744
24120
  }
23745
24121
  submitHistory(curIndex, isInput = false) {
23746
- const positionContext = this.position.getPositionContext();
23747
- const oldElementList = getSlimCloneElementList(this.elementList);
23748
- const oldHeaderElementList = getSlimCloneElementList(
23749
- this.header.getElementList()
23750
- );
23751
- const oldFooterElementList = getSlimCloneElementList(
23752
- this.footer.getElementList()
23753
- );
23754
- const oldRange = deepClone(this.range.getRange());
23755
- const pageNo = this.pageNo;
23756
- const oldPositionContext = deepClone(positionContext);
23757
- const zone = this.zone.getZone();
23758
- const fn = () => {
23759
- this.zone.setZone(zone);
23760
- this.setPageNo(pageNo);
23761
- this.position.setPositionContext(deepClone(oldPositionContext));
23762
- this.header.setElementList(deepClone(oldHeaderElementList));
23763
- this.footer.setElementList(deepClone(oldFooterElementList));
23764
- this.elementList = deepClone(oldElementList);
23765
- this.range.replaceRange(deepClone(oldRange));
23766
- this.render({
23767
- curIndex,
23768
- isSubmitHistory: false,
23769
- isSourceHistory: true
23770
- });
24122
+ const snapshot = {
24123
+ elementList: getSlimCloneElementList(this.elementList),
24124
+ headerElementList: getSlimCloneElementList(this.header.getElementList()),
24125
+ footerElementList: getSlimCloneElementList(this.footer.getElementList()),
24126
+ range: deepClone(this.range.getRange()),
24127
+ pageNo: this.pageNo,
24128
+ positionContext: deepClone(this.position.getPositionContext()),
24129
+ zone: this.zone.getZone()
24130
+ };
24131
+ const entry = {
24132
+ restore: () => {
24133
+ const {
24134
+ elementList,
24135
+ headerElementList,
24136
+ footerElementList,
24137
+ range,
24138
+ pageNo,
24139
+ positionContext,
24140
+ zone
24141
+ } = snapshot;
24142
+ const restoredHeaderElementList = inflateElementList(
24143
+ deepClone(headerElementList)
24144
+ );
24145
+ const restoredFooterElementList = inflateElementList(
24146
+ deepClone(footerElementList)
24147
+ );
24148
+ const restoredMainElementList = inflateElementList(deepClone(elementList));
24149
+ this.zone.setZone(zone);
24150
+ this.setPageNo(pageNo);
24151
+ this.position.setPositionContext(deepClone(positionContext));
24152
+ this.header.setElementList(restoredHeaderElementList);
24153
+ this.footer.setElementList(restoredFooterElementList);
24154
+ this.elementList = restoredMainElementList;
24155
+ this.range.replaceRange(deepClone(range));
24156
+ this.render({
24157
+ curIndex,
24158
+ isSubmitHistory: false,
24159
+ isSourceHistory: true
24160
+ });
24161
+ }
23771
24162
  };
23772
24163
  if (isInput && this.historyManager.isInputGroupable()) {
23773
- this.historyManager.replaceLatest(fn);
24164
+ this.historyManager.replaceLatest(entry);
23774
24165
  } else {
23775
- this.historyManager.execute(fn);
24166
+ this.historyManager.execute(entry);
23776
24167
  }
23777
24168
  if (isInput) {
23778
24169
  this.historyManager.recordInputTime();