@windoc/core 0.3.22 → 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.22";
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);
@@ -4422,6 +4407,7 @@ function mergeOption(options = {}) {
4422
4407
  wordBreak: "break-word" /* BREAK_WORD */,
4423
4408
  printPixelRatio: 3,
4424
4409
  maskMargin: [0, 0, 0, 0],
4410
+ scrollPaddingLines: 3,
4425
4411
  letterClass: [LETTER_CLASS.ENGLISH],
4426
4412
  contextMenuDisableKeys: [],
4427
4413
  shortcutDisableKeys: [],
@@ -4943,9 +4929,7 @@ function mergeSplitTableRowsForZip(trList) {
4943
4929
  for (let t = trList.length - 1; t >= 0; t--) {
4944
4930
  const splitTr = trList[t];
4945
4931
  if (!splitTr.splitParentId) continue;
4946
- const parentTrIdx = trList.findIndex(
4947
- (tr) => tr.id === splitTr.splitParentId
4948
- );
4932
+ const parentTrIdx = trList.findIndex((tr) => tr.id === splitTr.splitParentId);
4949
4933
  if (!~parentTrIdx) continue;
4950
4934
  const parentTr = trList[parentTrIdx];
4951
4935
  parentTr.height += splitTr.height;
@@ -5991,10 +5975,184 @@ ${ulListStyleText || `${listIndex + 1}.`}${buildText(
5991
5975
  return buildText(zipElementList(elementList));
5992
5976
  }
5993
5977
  function getSlimCloneElementList(elementList) {
5994
- return deepCloneOmitKeys(elementList, [
5995
- "metrics",
5996
- "style"
5997
- ]);
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;
5998
6156
  }
5999
6157
  function getIsBlockElement(element) {
6000
6158
  return !!element?.type && (BLOCK_ELEMENT_TYPE.includes(element.type) || element.imgDisplay === "inline" /* INLINE */);
@@ -6410,7 +6568,10 @@ var Cursor = class {
6410
6568
  const agentCursorDom = this.cursorAgent.getAgentCursorDom();
6411
6569
  if (document.activeElement !== agentCursorDom) {
6412
6570
  agentCursorDom.focus({ preventScroll: true });
6571
+ const scrollContainer = findScrollContainer(this.container);
6572
+ const { scrollLeft, scrollTop } = scrollContainer;
6413
6573
  agentCursorDom.setSelectionRange(0, 0);
6574
+ scrollContainer.scroll(scrollLeft, scrollTop);
6414
6575
  }
6415
6576
  }
6416
6577
  drawCursor(payload) {
@@ -6480,7 +6641,6 @@ var Cursor = class {
6480
6641
  this.recoveryCursor();
6481
6642
  return;
6482
6643
  }
6483
- const oldTop = this.cursorDom.style.top;
6484
6644
  const isReadonly = this.draw.isReadonly();
6485
6645
  this.cursorDom.style.width = `${width * scale}px`;
6486
6646
  this.cursorDom.style.backgroundColor = color;
@@ -6494,10 +6654,7 @@ var Cursor = class {
6494
6654
  this._clearBlinkTimeout();
6495
6655
  }
6496
6656
  nextTick2(() => {
6497
- this.moveCursorToVisible({
6498
- cursorPosition,
6499
- direction: parseInt(oldTop) > cursorTop ? "top" /* UP */ : "down" /* DOWN */
6500
- });
6657
+ this.moveCursorToVisible({ cursorPosition });
6501
6658
  });
6502
6659
  }
6503
6660
  recoveryCursor() {
@@ -6505,41 +6662,44 @@ var Cursor = class {
6505
6662
  this._clearBlinkTimeout();
6506
6663
  }
6507
6664
  moveCursorToVisible(payload) {
6508
- const { cursorPosition, direction } = payload;
6509
- if (!cursorPosition || !direction) return;
6665
+ const { cursorPosition } = payload;
6666
+ if (!cursorPosition) return;
6510
6667
  const {
6511
6668
  pageNo,
6512
- coordinate: { leftTop, leftBottom }
6669
+ coordinate: { leftTop },
6670
+ ascent,
6671
+ metrics: { boundingBoxAscent, boundingBoxDescent }
6513
6672
  } = cursorPosition;
6514
- const prePageY = pageNo * (this.draw.getHeight() + this.draw.getPageGap()) + this.container.getBoundingClientRect().top;
6515
- const isUp = direction === "top" /* UP */;
6516
- const x = leftBottom[0];
6517
- const cursorTop = leftTop[1] + cursorPosition.ascent - cursorPosition.metrics.boundingBoxAscent;
6518
- const cursorBottom = cursorTop + cursorPosition.metrics.boundingBoxAscent + cursorPosition.metrics.boundingBoxDescent;
6519
- const y = isUp ? cursorTop + prePageY : cursorBottom + prePageY;
6673
+ const containerRect = this.container.getBoundingClientRect();
6674
+ const pageOffset = pageNo * (this.draw.getHeight() + this.draw.getPageGap());
6675
+ const cursorTopViewport = containerRect.top + pageOffset + leftTop[1] + ascent - boundingBoxAscent;
6676
+ const cursorBottomViewport = cursorTopViewport + boundingBoxAscent + boundingBoxDescent;
6520
6677
  const scrollContainer = findScrollContainer(this.container);
6521
- const rect = {
6522
- left: 0,
6523
- right: 0,
6524
- top: 0,
6525
- bottom: 0
6526
- };
6678
+ let visibleTop;
6679
+ let visibleBottom;
6527
6680
  if (scrollContainer === document.documentElement) {
6528
- rect.right = window.innerWidth;
6529
- rect.bottom = window.innerHeight;
6681
+ visibleTop = 0;
6682
+ visibleBottom = window.innerHeight;
6530
6683
  } else {
6531
- const { left: left2, right: right2, top, bottom } = scrollContainer.getBoundingClientRect();
6532
- rect.left = left2;
6533
- rect.right = right2;
6534
- rect.top = top;
6535
- rect.bottom = bottom;
6536
- }
6537
- const { maskMargin } = this.options;
6538
- rect.top += maskMargin[0];
6539
- rect.bottom -= maskMargin[2];
6540
- if (!(x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom)) {
6541
- const { scrollLeft, scrollTop } = scrollContainer;
6542
- isUp ? scrollContainer.scroll(scrollLeft, scrollTop - (rect.top - y)) : scrollContainer.scroll(scrollLeft, scrollTop + y - rect.bottom);
6684
+ const scrollRect = scrollContainer.getBoundingClientRect();
6685
+ visibleTop = scrollRect.top;
6686
+ visibleBottom = scrollRect.bottom;
6687
+ }
6688
+ if (cursorTopViewport >= visibleTop && cursorBottomViewport <= visibleBottom) {
6689
+ return;
6690
+ }
6691
+ const scrollPadding = (boundingBoxAscent + boundingBoxDescent) * this.options.scrollPaddingLines;
6692
+ const { scrollLeft, scrollTop } = scrollContainer;
6693
+ if (cursorTopViewport < visibleTop) {
6694
+ scrollContainer.scroll(
6695
+ scrollLeft,
6696
+ scrollTop - (visibleTop - cursorTopViewport) - scrollPadding
6697
+ );
6698
+ } else {
6699
+ scrollContainer.scroll(
6700
+ scrollLeft,
6701
+ scrollTop + (cursorBottomViewport - visibleBottom) + scrollPadding
6702
+ );
6543
6703
  }
6544
6704
  }
6545
6705
  };
@@ -7665,7 +7825,8 @@ function backspace(evt, host) {
7665
7825
  } else {
7666
7826
  rangeManager.setRange(curIndex, curIndex);
7667
7827
  draw.render({
7668
- curIndex
7828
+ curIndex,
7829
+ dirtyStartIndex: curIndex + 1
7669
7830
  });
7670
7831
  }
7671
7832
  }
@@ -7807,7 +7968,8 @@ function del(evt, host) {
7807
7968
  } else {
7808
7969
  rangeManager.setRange(curIndex, curIndex);
7809
7970
  draw.render({
7810
- curIndex
7971
+ curIndex,
7972
+ dirtyStartIndex: curIndex + 1
7811
7973
  });
7812
7974
  }
7813
7975
  }
@@ -8511,8 +8673,7 @@ function updown(evt, host) {
8511
8673
  });
8512
8674
  if (!isCollapsed) {
8513
8675
  draw.getCursor().moveCursorToVisible({
8514
- cursorPosition: positionList[isUp ? anchorStartIndex : anchorEndIndex],
8515
- direction: isUp ? "top" /* UP */ : "down" /* DOWN */
8676
+ cursorPosition: positionList[isUp ? anchorStartIndex : anchorEndIndex]
8516
8677
  });
8517
8678
  }
8518
8679
  }
@@ -8650,10 +8811,12 @@ function input(data2, host) {
8650
8811
  if (~curIndex) {
8651
8812
  rangeManager.setRange(curIndex, curIndex);
8652
8813
  const isWordBoundary = !isComposing && /[\s\p{P}]/u.test(data2);
8814
+ const dirtyStartIndex = startIndex + 1;
8653
8815
  draw.render({
8654
8816
  curIndex,
8655
8817
  isSubmitHistory: !isComposing,
8656
- isInputHistory: !isComposing && !isWordBoundary
8818
+ isInputHistory: !isComposing && !isWordBoundary,
8819
+ dirtyStartIndex
8657
8820
  });
8658
8821
  }
8659
8822
  if (isComposing && ~curIndex) {
@@ -9337,7 +9500,7 @@ var HistoryManager = class {
9337
9500
  const pop = this.undoStack.pop();
9338
9501
  this.redoStack.push(pop);
9339
9502
  if (this.undoStack.length) {
9340
- this.undoStack[this.undoStack.length - 1]();
9503
+ this.undoStack[this.undoStack.length - 1].restore();
9341
9504
  }
9342
9505
  }
9343
9506
  }
@@ -9345,11 +9508,11 @@ var HistoryManager = class {
9345
9508
  if (this.redoStack.length) {
9346
9509
  const pop = this.redoStack.pop();
9347
9510
  this.undoStack.push(pop);
9348
- pop();
9511
+ pop.restore();
9349
9512
  }
9350
9513
  }
9351
- execute(fn) {
9352
- this.undoStack.push(fn);
9514
+ execute(entry) {
9515
+ this.undoStack.push(this._normalizeEntry(entry));
9353
9516
  if (this.redoStack.length) {
9354
9517
  this.redoStack = [];
9355
9518
  }
@@ -9357,11 +9520,12 @@ var HistoryManager = class {
9357
9520
  this.undoStack.shift();
9358
9521
  }
9359
9522
  }
9360
- replaceLatest(fn) {
9523
+ replaceLatest(entry) {
9524
+ const normalizedEntry = this._normalizeEntry(entry);
9361
9525
  if (this.undoStack.length > 0) {
9362
- this.undoStack[this.undoStack.length - 1] = fn;
9526
+ this.undoStack[this.undoStack.length - 1] = normalizedEntry;
9363
9527
  } else {
9364
- this.execute(fn);
9528
+ this.execute(normalizedEntry);
9365
9529
  }
9366
9530
  if (this.redoStack.length) {
9367
9531
  this.redoStack = [];
@@ -9392,6 +9556,14 @@ var HistoryManager = class {
9392
9556
  popUndo() {
9393
9557
  return this.undoStack.pop();
9394
9558
  }
9559
+ _normalizeEntry(entry) {
9560
+ if (typeof entry === "function") {
9561
+ return {
9562
+ restore: entry
9563
+ };
9564
+ }
9565
+ return entry;
9566
+ }
9395
9567
  };
9396
9568
 
9397
9569
  // src/core/position/Position.ts
@@ -11599,6 +11771,7 @@ var ScrollObserver = class {
11599
11771
  const { intersectionPageNo, visiblePageNoList } = this.getPageVisibleInfo();
11600
11772
  this.draw.setIntersectionPageNo(intersectionPageNo);
11601
11773
  this.draw.setVisiblePageNoList(visiblePageNoList);
11774
+ this.draw.renderVisiblePages(visiblePageNoList);
11602
11775
  }, 150);
11603
11776
  this.draw = draw;
11604
11777
  this.options = draw.getOptions();
@@ -20406,6 +20579,9 @@ var Area = class {
20406
20579
  getAreaInfo() {
20407
20580
  return this.areaInfoMap;
20408
20581
  }
20582
+ clear() {
20583
+ this.areaInfoMap.clear();
20584
+ }
20409
20585
  getActiveAreaId() {
20410
20586
  if (!this.areaInfoMap.size) return null;
20411
20587
  const { startIndex } = this.range.getRange();
@@ -20797,6 +20973,7 @@ var Draw = class {
20797
20973
  this.container = this._wrapContainer(rootContainer);
20798
20974
  this.pageList = [];
20799
20975
  this.ctxList = [];
20976
+ this.pageRenderVersionList = [];
20800
20977
  this.pageNo = 0;
20801
20978
  this.renderCount = 0;
20802
20979
  this.pagePixelRatio = null;
@@ -20809,6 +20986,7 @@ var Draw = class {
20809
20986
  this._formatContainer();
20810
20987
  this.pageContainer = this._createPageContainer();
20811
20988
  this._createPage(0);
20989
+ this.measureCtx = this._createMeasureContext();
20812
20990
  this.i18n = new I18n(options.locale);
20813
20991
  this.historyManager = new HistoryManager(this);
20814
20992
  this.position = new Position(this);
@@ -20873,6 +21051,8 @@ var Draw = class {
20873
21051
  this.pageRowList = [];
20874
21052
  this.painterStyle = null;
20875
21053
  this.painterOptions = null;
21054
+ this.elementFontCache = /* @__PURE__ */ new WeakMap();
21055
+ this.elementRowMarginCache = /* @__PURE__ */ new WeakMap();
20876
21056
  this.visiblePageNoList = [];
20877
21057
  this.intersectionPageNo = 0;
20878
21058
  this.lazyRenderIntersectionObserver = null;
@@ -21039,7 +21219,9 @@ var Draw = class {
21039
21219
  getContextInnerWidth() {
21040
21220
  const positionContext = this.position.getPositionContext();
21041
21221
  if (positionContext.isTable) {
21042
- const td = this.resolveTableCellContext(this.getOriginalElementList())?.td;
21222
+ const td = this.resolveTableCellContext(
21223
+ this.getOriginalElementList()
21224
+ )?.td;
21043
21225
  if (!td) return this.getColumnWidth() / this.options.scale;
21044
21226
  const tdPadding = this.getTdPadding();
21045
21227
  return td.width - tdPadding[1] - tdPadding[3];
@@ -21092,6 +21274,7 @@ var Draw = class {
21092
21274
  return this.visiblePageNoList;
21093
21275
  }
21094
21276
  setVisiblePageNoList(payload) {
21277
+ if (isArrayEqual(this.visiblePageNoList, payload)) return;
21095
21278
  this.visiblePageNoList = payload;
21096
21279
  if (this.listener.visiblePageNoListChange) {
21097
21280
  this.listener.visiblePageNoListChange(this.visiblePageNoList);
@@ -21104,6 +21287,7 @@ var Draw = class {
21104
21287
  return this.intersectionPageNo;
21105
21288
  }
21106
21289
  setIntersectionPageNo(payload) {
21290
+ if (this.intersectionPageNo === payload) return;
21107
21291
  this.intersectionPageNo = payload;
21108
21292
  if (this.listener.intersectionPageNoChange) {
21109
21293
  this.listener.intersectionPageNoChange(this.intersectionPageNo);
@@ -21131,7 +21315,9 @@ var Draw = class {
21131
21315
  candidateIndexes.push(context.index);
21132
21316
  }
21133
21317
  if (context.tableId) {
21134
- const tableIndex = sourceElementList.findIndex((el) => el.id === context.tableId);
21318
+ const tableIndex = sourceElementList.findIndex(
21319
+ (el) => el.id === context.tableId
21320
+ );
21135
21321
  if (~tableIndex && !candidateIndexes.includes(tableIndex)) {
21136
21322
  candidateIndexes.push(tableIndex);
21137
21323
  }
@@ -21240,9 +21426,7 @@ var Draw = class {
21240
21426
  return this.header.getElementList();
21241
21427
  }
21242
21428
  getTableElementList(sourceElementList) {
21243
- const splitCellSelectionContext = this.getSplitCellSelectionContext(
21244
- sourceElementList
21245
- );
21429
+ const splitCellSelectionContext = this.getSplitCellSelectionContext(sourceElementList);
21246
21430
  if (splitCellSelectionContext) {
21247
21431
  return splitCellSelectionContext.value;
21248
21432
  }
@@ -21366,10 +21550,7 @@ var Draw = class {
21366
21550
  positionContext.trId = continuationTr.id;
21367
21551
  positionContext.tableId = tableId;
21368
21552
  this.position.setPositionContext(positionContext);
21369
- this.range.setRange(
21370
- continuationCursorIndex,
21371
- continuationCursorIndex
21372
- );
21553
+ this.range.setRange(continuationCursorIndex, continuationCursorIndex);
21373
21554
  this.pendingTableCursorIndex = continuationCursorIndex;
21374
21555
  return true;
21375
21556
  }
@@ -21429,7 +21610,10 @@ var Draw = class {
21429
21610
  });
21430
21611
  const splitCellSelection = this.range.getSplitCellSelection();
21431
21612
  if (splitCellSelection) {
21432
- const curIndex2 = this.replaceSplitCellSelection(payload, splitCellSelection);
21613
+ const curIndex2 = this.replaceSplitCellSelection(
21614
+ payload,
21615
+ splitCellSelection
21616
+ );
21433
21617
  if (~curIndex2) {
21434
21618
  this.range.setRange(curIndex2, curIndex2);
21435
21619
  this.render({
@@ -21559,12 +21743,7 @@ var Draw = class {
21559
21743
  trId: rootCellContext.tr.id,
21560
21744
  tdId: rootTd.id
21561
21745
  });
21562
- this.spliceElementList(
21563
- rootTd.value,
21564
- 1,
21565
- rootTd.value.length - 1,
21566
- payload
21567
- );
21746
+ this.spliceElementList(rootTd.value, 1, rootTd.value.length - 1, payload);
21568
21747
  rootTd.rowList = void 0;
21569
21748
  rootTd.positionList = void 0;
21570
21749
  rootTd.mainHeight = void 0;
@@ -21984,6 +22163,15 @@ var Draw = class {
21984
22163
  this._initPageContext(ctx);
21985
22164
  this.pageList.push(canvas);
21986
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;
21987
22175
  }
21988
22176
  _initPageContext(ctx) {
21989
22177
  const dpr = this.getPagePixelRatio();
@@ -21996,8 +22184,22 @@ var Draw = class {
21996
22184
  const { defaultSize, defaultFont } = this.options;
21997
22185
  const font = el.font || defaultFont;
21998
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
+ }
21999
22191
  const sizePx = size * (96 / 72) * scale;
22000
- 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;
22001
22203
  }
22002
22204
  getElementSize(el) {
22003
22205
  return el.actualSize || el.size || this.options.defaultSize;
@@ -22010,13 +22212,25 @@ var Draw = class {
22010
22212
  scale
22011
22213
  } = this.options;
22012
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
+ }
22013
22220
  let ratio = 1;
22014
22221
  if (fontSize < 12) {
22015
22222
  ratio = fontSize / 12;
22016
22223
  } else if (fontSize > 30) {
22017
22224
  ratio = 1 + (fontSize - 30) / 30;
22018
22225
  }
22019
- 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;
22020
22234
  }
22021
22235
  createListStateSeed(initialListState) {
22022
22236
  const listLevelIndex = /* @__PURE__ */ new Map();
@@ -22095,7 +22309,12 @@ var Draw = class {
22095
22309
  pageHeight = 0,
22096
22310
  mainOuterHeight = 0,
22097
22311
  surroundElementList = [],
22098
- initialListState
22312
+ initialListState,
22313
+ hasListElement = true,
22314
+ fromIndex = 0,
22315
+ initialY = startY,
22316
+ initialPageNo = 0,
22317
+ initialRowIndex = 0
22099
22318
  } = payload;
22100
22319
  const {
22101
22320
  defaultSize,
@@ -22104,27 +22323,62 @@ var Draw = class {
22104
22323
  defaultTabWidth
22105
22324
  } = this.options;
22106
22325
  const defaultBasicRowMarginHeight = this.getDefaultBasicRowMarginHeight();
22107
- const canvas = document.createElement("canvas");
22108
- const ctx = canvas.getContext("2d");
22109
- 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
+ };
22110
22364
  const rowList = [];
22111
- if (elementList.length) {
22365
+ if (elementList.length && fromIndex < elementList.length) {
22112
22366
  rowList.push({
22113
22367
  width: 0,
22114
22368
  height: 0,
22115
22369
  ascent: 0,
22116
22370
  elementList: [],
22117
- startIndex: 0,
22118
- rowIndex: 0,
22119
- rowFlex: elementList?.[0]?.rowFlex || elementList?.[1]?.rowFlex
22371
+ startIndex: fromIndex,
22372
+ rowIndex: initialRowIndex,
22373
+ rowFlex: elementList?.[fromIndex]?.rowFlex || elementList?.[fromIndex + 1]?.rowFlex
22120
22374
  });
22121
22375
  }
22122
22376
  let x = startX;
22123
- let y = startY;
22124
- let pageNo = 0;
22377
+ let y = initialY;
22378
+ let pageNo = initialPageNo;
22125
22379
  const listState = this.createListStateSeed(initialListState);
22126
22380
  let controlRealWidth = 0;
22127
- for (let i = 0; i < elementList.length; i++) {
22381
+ for (let i = fromIndex; i < elementList.length; i++) {
22128
22382
  const curRow = rowList[rowList.length - 1];
22129
22383
  const element = elementList[i];
22130
22384
  const rowMargin = this.getElementRowMargin(element);
@@ -22170,9 +22424,7 @@ var Draw = class {
22170
22424
  } else if (element.type === "table" /* TABLE */) {
22171
22425
  let activeSplitRange;
22172
22426
  let mergedSplitFallback;
22173
- const logicalSplitCursor = this.getCollapsedSplitTableCursorContext(
22174
- element
22175
- );
22427
+ const logicalSplitCursor = this.getCollapsedSplitTableCursorContext(element);
22176
22428
  if (element.pagingId) {
22177
22429
  let tableIndex = i + 1;
22178
22430
  let combineCount = 0;
@@ -22777,16 +23029,14 @@ var Draw = class {
22777
23029
  element.actualSize = Math.ceil(size * 0.6);
22778
23030
  }
22779
23031
  metrics.height = (element.actualSize || size) * scale;
22780
- ctx.font = this.getElementFont(element);
23032
+ const elementFont = this.getElementFont(element);
23033
+ ctx.font = elementFont;
22781
23034
  const fontMetrics = this.textParticle.measureText(ctx, element);
22782
23035
  metrics.width = fontMetrics.width * scale;
22783
23036
  if (element.letterSpacing) {
22784
23037
  metrics.width += element.letterSpacing * scale;
22785
23038
  }
22786
- const basisMetrics = this.textParticle.measureBasisWord(
22787
- ctx,
22788
- element.font
22789
- );
23039
+ const basisMetrics = this.textParticle.measureBasisWord(ctx, elementFont);
22790
23040
  metrics.boundingBoxAscent = basisMetrics.fontBoundingBoxAscent * scale;
22791
23041
  metrics.boundingBoxDescent = basisMetrics.fontBoundingBoxDescent * scale;
22792
23042
  if (element.type === "superscript" /* SUPERSCRIPT */) {
@@ -22823,11 +23073,7 @@ var Draw = class {
22823
23073
  if ((!preElement?.type || preElement?.type === "text" /* TEXT */) && (!element.type || element.type === "text" /* TEXT */)) {
22824
23074
  const word = `${preElement?.value || ""}${element.value}`;
22825
23075
  if (this.WORD_LIKE_REG.test(word)) {
22826
- const { width, endElement } = this.textParticle.measureWord(
22827
- ctx,
22828
- elementList,
22829
- i
22830
- );
23076
+ const { width, endElement } = getWordMeasure(i, ctx.font);
22831
23077
  const wordWidth = width * scale;
22832
23078
  if (endElement && wordWidth <= availableWidth) {
22833
23079
  curRowWidth += wordWidth;
@@ -22960,6 +23206,7 @@ var Draw = class {
22960
23206
  x += metrics.width;
22961
23207
  }
22962
23208
  }
23209
+ ctx.restore();
22963
23210
  return rowList;
22964
23211
  }
22965
23212
  _applyRowSpacing() {
@@ -23552,30 +23799,11 @@ var Draw = class {
23552
23799
  if (this.isGraffitiMode()) {
23553
23800
  this.graffiti.render(ctx, pageNo);
23554
23801
  }
23802
+ this.pageRenderVersionList[pageNo] = this.renderCount;
23555
23803
  }
23556
23804
  _disconnectLazyRender() {
23557
23805
  this.lazyRenderIntersectionObserver?.disconnect();
23558
- }
23559
- _lazyRender() {
23560
- const positionList = this.position.getOriginalMainPositionList();
23561
- const elementList = this.getOriginalMainElementList();
23562
- this._disconnectLazyRender();
23563
- this.lazyRenderIntersectionObserver = new IntersectionObserver((entries) => {
23564
- entries.forEach((entry) => {
23565
- if (entry.isIntersecting) {
23566
- const index = Number(entry.target.dataset.index);
23567
- this._drawPage({
23568
- elementList,
23569
- positionList,
23570
- rowList: this.pageRowList[index],
23571
- pageNo: index
23572
- });
23573
- }
23574
- });
23575
- });
23576
- this.pageList.forEach((el) => {
23577
- this.lazyRenderIntersectionObserver.observe(el);
23578
- });
23806
+ this.lazyRenderIntersectionObserver = null;
23579
23807
  }
23580
23808
  _immediateRender() {
23581
23809
  const positionList = this.position.getOriginalMainPositionList();
@@ -23589,6 +23817,100 @@ var Draw = class {
23589
23817
  });
23590
23818
  }
23591
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
+ }
23592
23914
  render(payload) {
23593
23915
  this.renderCount++;
23594
23916
  const { header, footer } = this.options;
@@ -23600,15 +23922,19 @@ var Draw = class {
23600
23922
  isLazy = true,
23601
23923
  isInit = false,
23602
23924
  isSourceHistory = false,
23603
- isFirstRender = false
23925
+ isFirstRender = false,
23926
+ dirtyStartIndex
23604
23927
  } = payload || {};
23605
23928
  let { curIndex } = payload || {};
23606
23929
  this.pendingTableCursorIndex = void 0;
23607
23930
  const innerWidth = this.getInnerWidth();
23608
23931
  const columnWidth = this.getColumnWidth();
23609
23932
  const isPagingMode = this.getIsPagingMode();
23933
+ const columnCount = this.getColumnCount();
23610
23934
  const oldPageSize = this.pageRowList.length;
23611
23935
  if (isCompute) {
23936
+ const oldRowList = this.rowList;
23937
+ const oldPageRowList = this.pageRowList;
23612
23938
  this.position.setFloatPositionList([]);
23613
23939
  if (isPagingMode) {
23614
23940
  if (!header.disabled) {
@@ -23624,8 +23950,13 @@ var Draw = class {
23624
23950
  const mainOuterHeight = this.getMainOuterHeight();
23625
23951
  const startX = margins[3];
23626
23952
  const startY = margins[0] + extraHeight;
23627
- const surroundElementList = pickSurroundElementList(this.elementList);
23628
- this.rowList = this.computeRowList({
23953
+ const {
23954
+ hasAreaElement,
23955
+ hasListElement,
23956
+ hasStructuralElement,
23957
+ surroundElementList
23958
+ } = this._collectMainRenderMeta();
23959
+ const rowListPayload = {
23629
23960
  startX,
23630
23961
  startY,
23631
23962
  pageHeight,
@@ -23633,12 +23964,41 @@ var Draw = class {
23633
23964
  isPagingMode,
23634
23965
  innerWidth: columnWidth,
23635
23966
  surroundElementList,
23967
+ hasListElement,
23636
23968
  elementList: this.elementList
23637
- });
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
+ }
23638
23994
  this._applyRowSpacing();
23639
23995
  this.pageRowList = this._computePageList();
23640
23996
  this.position.computePositionList();
23641
- this.area.compute();
23997
+ if (hasAreaElement) {
23998
+ this.area.compute();
23999
+ } else {
24000
+ this.area.clear();
24001
+ }
23642
24002
  if (!this.isPrintMode()) {
23643
24003
  const searchKeyword = this.search.getSearchKeyword();
23644
24004
  if (searchKeyword) {
@@ -23662,10 +24022,26 @@ var Draw = class {
23662
24022
  if (prePageCount > curPageCount) {
23663
24023
  const deleteCount = prePageCount - curPageCount;
23664
24024
  this.ctxList.splice(curPageCount, deleteCount);
24025
+ this.pageRenderVersionList.splice(curPageCount, deleteCount);
23665
24026
  this.pageList.splice(curPageCount, deleteCount).forEach((page) => page.remove());
23666
24027
  }
23667
24028
  if (isLazy && isPagingMode) {
23668
- 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);
23669
24045
  } else {
23670
24046
  this._immediateRender();
23671
24047
  }
@@ -23714,7 +24090,9 @@ var Draw = class {
23714
24090
  const positionContext = this.position.getPositionContext();
23715
24091
  const positionList = this.position.getPositionList();
23716
24092
  if (positionContext.isTable) {
23717
- const tablePositionList = this.resolveTableCellContext(this.getOriginalElementList())?.td.positionList;
24093
+ const tablePositionList = this.resolveTableCellContext(
24094
+ this.getOriginalElementList()
24095
+ )?.td.positionList;
23718
24096
  if (curIndex === void 0 && tablePositionList) {
23719
24097
  curIndex = tablePositionList.length - 1;
23720
24098
  }
@@ -23741,36 +24119,51 @@ var Draw = class {
23741
24119
  return curIndex;
23742
24120
  }
23743
24121
  submitHistory(curIndex, isInput = false) {
23744
- const positionContext = this.position.getPositionContext();
23745
- const oldElementList = getSlimCloneElementList(this.elementList);
23746
- const oldHeaderElementList = getSlimCloneElementList(
23747
- this.header.getElementList()
23748
- );
23749
- const oldFooterElementList = getSlimCloneElementList(
23750
- this.footer.getElementList()
23751
- );
23752
- const oldRange = deepClone(this.range.getRange());
23753
- const pageNo = this.pageNo;
23754
- const oldPositionContext = deepClone(positionContext);
23755
- const zone = this.zone.getZone();
23756
- const fn = () => {
23757
- this.zone.setZone(zone);
23758
- this.setPageNo(pageNo);
23759
- this.position.setPositionContext(deepClone(oldPositionContext));
23760
- this.header.setElementList(deepClone(oldHeaderElementList));
23761
- this.footer.setElementList(deepClone(oldFooterElementList));
23762
- this.elementList = deepClone(oldElementList);
23763
- this.range.replaceRange(deepClone(oldRange));
23764
- this.render({
23765
- curIndex,
23766
- isSubmitHistory: false,
23767
- isSourceHistory: true
23768
- });
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
+ }
23769
24162
  };
23770
24163
  if (isInput && this.historyManager.isInputGroupable()) {
23771
- this.historyManager.replaceLatest(fn);
24164
+ this.historyManager.replaceLatest(entry);
23772
24165
  } else {
23773
- this.historyManager.execute(fn);
24166
+ this.historyManager.execute(entry);
23774
24167
  }
23775
24168
  if (isInput) {
23776
24169
  this.historyManager.recordInputTime();