@hailin-zheng/editor-core 2.2.14 → 2.2.15

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/index-cjs.js CHANGED
@@ -53,8 +53,6 @@ class ElementEvent {
53
53
  * 当前所在的对象
54
54
  */
55
55
  currentElement;
56
- currentRenderObjectX;
57
- currentRenderObjectY;
58
56
  //是否取消向上冒泡
59
57
  isCancel;
60
58
  globalX;
@@ -770,8 +768,11 @@ class CommonUtil {
770
768
  const shouldCallNow = elapsed >= wait;
771
769
  clearTimeout(timeout);
772
770
  if (shouldCallNow) {
773
- fn.apply(context, args);
774
- lastExecTime = Date.now();
771
+ //延迟执行,微任务
772
+ Promise.resolve().then(() => {
773
+ fn.apply(context, args);
774
+ lastExecTime = Date.now();
775
+ });
775
776
  }
776
777
  else {
777
778
  timeout = setTimeout(() => {
@@ -1000,6 +1001,8 @@ function generatePatch(doc, clear = true) {
1000
1001
  }
1001
1002
  if ('insert' in op.ops) {
1002
1003
  insertOpsMap.set(ele, op);
1004
+ //对象复制出来,避免paintRenders等内存占用
1005
+ op.ops.insert = op.ops.insert.clone(true);
1003
1006
  }
1004
1007
  //当前为新插入的元素
1005
1008
  if ('insText' in op.ops) {
@@ -1254,7 +1257,7 @@ class Element {
1254
1257
  modifyFlag = exports.ModifyFlag.Modify;
1255
1258
  isMouseenter;
1256
1259
  _eventMap;
1257
- _refreshEvent = new Subject();
1260
+ //private _refreshEvent: Subject<void> = new Subject();
1258
1261
  _onChangeEvent = new Subject();
1259
1262
  observers = new WeakMap();
1260
1263
  paintRenders = [];
@@ -1359,14 +1362,15 @@ class Element {
1359
1362
  return 0;
1360
1363
  }
1361
1364
  }
1362
- get refreshSubject() {
1363
- return this._refreshEvent;
1364
- }
1365
+ // get refreshSubject(): Subject<void> {
1366
+ // return this._refreshEvent;
1367
+ // }
1365
1368
  get onChangeSubject() {
1366
1369
  return this._onChangeEvent;
1367
1370
  }
1368
1371
  refreshView() {
1369
- this._refreshEvent.next();
1372
+ //this._refreshEvent.next();
1373
+ //refreshEditor(this);
1370
1374
  }
1371
1375
  unsubscribe(element) {
1372
1376
  const subs = this.observers.get(element);
@@ -1448,13 +1452,13 @@ class BranchElement extends Element {
1448
1452
  child.parent = this;
1449
1453
  this.chilren.splice(index, 0, child);
1450
1454
  insertEle(child);
1451
- const refSub = child.refreshSubject.subscribe((data) => {
1452
- this.refreshSubject.next(data);
1453
- });
1455
+ //const refSub = child.refreshSubject.subscribe((data) => {
1456
+ //this.refreshSubject.next(data);
1457
+ // });
1454
1458
  const onChangeSub = child.onChangeSubject.subscribe((data) => {
1455
1459
  this.pubOnChange('tracker');
1456
1460
  });
1457
- this.addsubscribe(child, refSub, onChangeSub);
1461
+ this.addsubscribe(child, onChangeSub);
1458
1462
  this.pubOnChange('self');
1459
1463
  }
1460
1464
  removeChild(child) {
@@ -1734,9 +1738,9 @@ class ViewOptions {
1734
1738
  currentFontName = '宋体';
1735
1739
  //选区颜色
1736
1740
  selectionColor = 'rgb(131,175,155,0.5)';
1737
- dataDecoratorNormalColor = '#0050b3';
1738
- dataDecoratorMouseEnterColor = '#0050b3';
1739
- dataDecoratorFocusedColor = '#0050b3';
1741
+ dataEleDecoratorNormalColor = '#0050b3';
1742
+ dataEleDecoratorMouseEnterColor = '#0050b3';
1743
+ dataEleDecoratorFocusedColor = '#0050b3';
1740
1744
  //数据元修饰符宽度
1741
1745
  dataDecoratorWidth = 1;
1742
1746
  //是否显示数据元修饰符
@@ -1753,12 +1757,18 @@ class ViewOptions {
1753
1757
  dataEleNormalBgColor = '#fafafa';
1754
1758
  //数据元错误背景颜色
1755
1759
  dataEleErrorBgColor = '#ff4d4f';
1756
- //数据元正常背景颜色
1757
- dataGroupEleNormalBgColor = '';
1760
+ //数据组修饰符号颜色
1761
+ dataGroupDecoratorNormalColor = '#0050b3';
1762
+ dataGroupDecoratorMouseEnterColor = '#0050b3';
1763
+ dataGroupDecoratorFocusedColor = '#0050b3';
1764
+ //数据组正常背景颜色
1765
+ dataGroupNormalBgColor = '#fafafa';
1766
+ //数据元没有输入值时背景颜色
1767
+ dataGroupEmptyBgColor = '';
1758
1768
  //数据元鼠标悬浮颜色
1759
- dataGroupMouseEnterBgColor = '';
1760
- //数据元只读背景颜色
1761
- dataGroupFocusedBgColor = '';
1769
+ dataGroupMouseEnterBgColor = '#f5f5f5';
1770
+ //数据元焦点背景颜色
1771
+ dataGroupFocusedBgColor = '#f0f0f0';
1762
1772
  viewBackcolor = 'rgb(230,230,230)';
1763
1773
  paraSymbolColor = 'rgb(128,128,128)';
1764
1774
  dataGroupColor = 'rgb(0,80,179)';
@@ -1803,6 +1813,8 @@ class ViewOptions {
1803
1813
  showEnterSymbol = false;
1804
1814
  enableVisibleExpression = false;
1805
1815
  shapeRendering = 'auto';
1816
+ //是否开启快速测量
1817
+ enableFastMeasure = false;
1806
1818
  get fullPageView() {
1807
1819
  return this._fullPageView;
1808
1820
  }
@@ -2970,16 +2982,22 @@ class DataDecorateRenderObject extends LeafRenderObject {
2970
2982
  if (event.mode === 'print') {
2971
2983
  return null;
2972
2984
  }
2985
+ if (this.element.dataEle.type === 'data-group') {
2986
+ return this.exportDataGroupSVG(event);
2987
+ }
2973
2988
  // if(this.element.parent.parent.type==='data-group'){
2974
2989
  // return null;
2975
2990
  // }
2976
2991
  const options = event.options;
2977
- let color = options.dataDecoratorNormalColor;
2978
- if (this.element.dataEle.isMouseenter && options.dataDecoratorMouseEnterColor) {
2979
- color = options.dataDecoratorMouseEnterColor;
2992
+ let color = options.dataEleDecoratorNormalColor;
2993
+ if (this.element.dataEle.isMouseenter && options.dataEleDecoratorMouseEnterColor) {
2994
+ color = options.dataEleDecoratorMouseEnterColor;
2995
+ }
2996
+ if (this.element.dataEle.isFocused && options.dataEleDecoratorFocusedColor) {
2997
+ color = options.dataEleDecoratorFocusedColor;
2980
2998
  }
2981
- if (this.element.dataEle.isFocused && options.dataDecoratorFocusedColor) {
2982
- color = options.dataDecoratorFocusedColor;
2999
+ if (!color) {
3000
+ return null;
2983
3001
  }
2984
3002
  const element = this.element;
2985
3003
  const lineWidth = 3;
@@ -3000,6 +3018,37 @@ class DataDecorateRenderObject extends LeafRenderObject {
3000
3018
  d: path
3001
3019
  });
3002
3020
  }
3021
+ exportDataGroupSVG(event) {
3022
+ const options = event.options;
3023
+ let color = options.dataGroupDecoratorNormalColor;
3024
+ if (this.element.dataEle.isMouseenter && options.dataGroupDecoratorMouseEnterColor) {
3025
+ color = options.dataGroupDecoratorMouseEnterColor;
3026
+ }
3027
+ if (this.element.dataEle.isFocused && options.dataGroupDecoratorFocusedColor) {
3028
+ color = options.dataGroupDecoratorFocusedColor;
3029
+ }
3030
+ if (!color) {
3031
+ return null;
3032
+ }
3033
+ const element = this.element;
3034
+ const lineWidth = 4;
3035
+ let path = '';
3036
+ const height = this.parent.rect.height - 4;
3037
+ if (element.isPrefix) {
3038
+ const x = this.rect.x + this.rect.width / 2;
3039
+ path = `M ${x + lineWidth} 2 L ${x} 2 L ${x} ${height} L ${x + lineWidth} ${height}`;
3040
+ }
3041
+ else {
3042
+ const x = this.rect.x + this.rect.width / 2;
3043
+ path = `M ${x - lineWidth} 2 L ${x} 2 L ${x} ${height} L ${x - lineWidth} ${height}`;
3044
+ }
3045
+ return ElementUtil.createSvgPath({
3046
+ stroke: color,
3047
+ fill: "none",
3048
+ 'stroke-width': 2,
3049
+ d: path
3050
+ });
3051
+ }
3003
3052
  }
3004
3053
 
3005
3054
  function parser(code, objects) {
@@ -3481,6 +3530,7 @@ class DocumentElement extends BlockContainerElement {
3481
3530
  footerElement;
3482
3531
  //commentsContainerElement!: CommsContainerElement;
3483
3532
  headerEditState = false;
3533
+ editorContext = null;
3484
3534
  constructor() {
3485
3535
  super('doc');
3486
3536
  this.props = new DocumentProps();
@@ -3514,11 +3564,11 @@ class DocumentElement extends BlockContainerElement {
3514
3564
  }
3515
3565
  };
3516
3566
  }
3517
- clone() {
3567
+ clone(data) {
3518
3568
  const clone = new DocumentElement();
3519
3569
  this.props.clone(clone.props);
3520
3570
  cloneElementBase(this, clone);
3521
- cloneChildren(this, clone, true);
3571
+ cloneChildren(this, clone, data);
3522
3572
  return clone;
3523
3573
  }
3524
3574
  /**
@@ -3554,7 +3604,7 @@ class DocumentElement extends BlockContainerElement {
3554
3604
  this.headerEditState = false;
3555
3605
  }
3556
3606
  ss.clear();
3557
- this.refreshView();
3607
+ //this.refreshView();
3558
3608
  }
3559
3609
  markPairs = [];
3560
3610
  /**
@@ -3829,7 +3879,7 @@ class InlineGroupInputElement extends InlineGroupElement {
3829
3879
  this.addEvent('ElementKeyDown', (evt) => {
3830
3880
  const { selectionState, sourceEvent, source } = evt;
3831
3881
  const { startControl, startOffset } = selectionState;
3832
- if (IsInSideDataElement(startControl, startOffset)) {
3882
+ if (IsInSideInlineGroupInputElement(startControl, startOffset)) {
3833
3883
  if (sourceEvent.shiftKey && sourceEvent.keyCode === 13) ;
3834
3884
  else if (!sourceEvent.shiftKey && sourceEvent.keyCode === 13) {
3835
3885
  evt.isCancel = true;
@@ -3838,7 +3888,7 @@ class InlineGroupInputElement extends InlineGroupElement {
3838
3888
  }, true);
3839
3889
  this.addEvent('GotCursor', (evt) => {
3840
3890
  const { startControl, startOffset } = evt.selectionState;
3841
- if (IsInSideDataElement(startControl, startOffset)) {
3891
+ if (IsInSideInlineGroupInputElement(startControl, startOffset)) {
3842
3892
  this.isFocused = true;
3843
3893
  }
3844
3894
  });
@@ -3935,11 +3985,13 @@ class DataElementInlineGroup extends InlineGroupInputElement {
3935
3985
  });
3936
3986
  this.addEvent('ElementMousemove', (evt) => {
3937
3987
  this.isMouseenter = true;
3938
- this.refreshView();
3988
+ evt.ctx.refreshView();
3989
+ //this.refreshView();
3939
3990
  });
3940
3991
  this.addEvent('ElementMouseLeave', (evt) => {
3941
3992
  this.isMouseenter = false;
3942
- this.refreshView();
3993
+ evt.ctx.refreshView();
3994
+ //this.refreshView()
3943
3995
  });
3944
3996
  this.addEvent('GotCursor', (evt) => {
3945
3997
  this.onGotCursorEvent(evt);
@@ -4079,21 +4131,10 @@ function getCurrOptions(ele) {
4079
4131
  class DataElementRenderObject extends InlineGroupRenderObject {
4080
4132
  exportSVG(event) {
4081
4133
  const node = super.exportSVG(event);
4082
- exportDecoratorHTML(event, this);
4134
+ exportDataEleDecoratorSVG$1(event, this);
4135
+ //绘制下划线
4083
4136
  if (this.element.props.underline) {
4084
- const { x, y } = event.relativePagePos;
4085
- event.highlights.push({
4086
- sel: 'path',
4087
- data: {
4088
- ns: 'http://www.w3.org/2000/svg',
4089
- attrs: {
4090
- d: `M${x} ${y + this.rect.height} L${x + this.rect.width} ${y + this.rect.height}`,
4091
- stroke: '#000',
4092
- fill: 'none',
4093
- 'stroke-width': 1
4094
- }
4095
- }
4096
- });
4137
+ renderUnderline(event, this);
4097
4138
  }
4098
4139
  renderErrorTip(event, this);
4099
4140
  return node;
@@ -4156,7 +4197,7 @@ class DataElementBaseFactory extends ElementFactory {
4156
4197
  * @param event
4157
4198
  * @param r
4158
4199
  */
4159
- function exportDecoratorHTML(event, r) {
4200
+ function exportDataEleDecoratorSVG$1(event, r) {
4160
4201
  if (event.mode === 'print') {
4161
4202
  return;
4162
4203
  }
@@ -4172,6 +4213,9 @@ function exportDecoratorHTML(event, r) {
4172
4213
  if (r.element.isFocused && options.dataEleFocusedBgColor) {
4173
4214
  color = options.dataEleFocusedBgColor;
4174
4215
  }
4216
+ if (!color) {
4217
+ return;
4218
+ }
4175
4219
  //绘制背景
4176
4220
  const bgX = event.relativePagePos.x;
4177
4221
  const bgY = event.relativePagePos.y;
@@ -4340,6 +4384,21 @@ function renderUnderWavyLine(event, r, color) {
4340
4384
  d += Array(Math.ceil(width / 3)).fill("3,0").join(' t ');
4341
4385
  const path = ElementUtil.createSvgPath({ d, fill: 'none', stroke: color });
4342
4386
  event.highlights.push(path);
4387
+ }
4388
+ function renderUnderline(event, render) {
4389
+ const { x, y } = event.relativePagePos;
4390
+ event.highlights.push({
4391
+ sel: 'path',
4392
+ data: {
4393
+ ns: 'http://www.w3.org/2000/svg',
4394
+ attrs: {
4395
+ d: `M${x} ${y + render.rect.height} L${x + render.rect.width} ${y + render.rect.height}`,
4396
+ stroke: '#000',
4397
+ fill: 'none',
4398
+ 'stroke-width': 1
4399
+ }
4400
+ }
4401
+ });
4343
4402
  }
4344
4403
 
4345
4404
  class DocumentBodyElement extends BlockContainerElement {
@@ -5617,7 +5676,7 @@ class TableUtil {
5617
5676
  if (startCell) {
5618
5677
  this.restoreCellMerge(startCell);
5619
5678
  ss.resetRange(startCell, 0);
5620
- startCell.refreshView();
5679
+ //startCell.refreshView();
5621
5680
  }
5622
5681
  }
5623
5682
  static restoreCellMerge(cell) {
@@ -5715,7 +5774,7 @@ class TableUtil {
5715
5774
  tb.setCellWidth(insertColIndex === colsCount ? insertColIndex - 1 : insertColIndex, insertColWidth - newColWidth);
5716
5775
  tb.insertCol(insertColIndex, newColWidth);
5717
5776
  tb.pubOnChange('self');
5718
- tb.refreshView();
5777
+ //tb.refreshView();
5719
5778
  }
5720
5779
  /**
5721
5780
  * 在指定位置插入行
@@ -5744,7 +5803,7 @@ class TableUtil {
5744
5803
  //新行插在第一行或者最后一行
5745
5804
  if (insertRowIndex === 0 || insertRowIndex === tb.length) {
5746
5805
  tb.addChild(newRow, insertRowIndex);
5747
- tb.refreshView();
5806
+ //tb.refreshView();
5748
5807
  return newRow;
5749
5808
  }
5750
5809
  const destRow = tb.getChild(insertRowIndex);
@@ -5763,7 +5822,7 @@ class TableUtil {
5763
5822
  newCell.props.hMerge = destCell.props.hMerge;
5764
5823
  }
5765
5824
  tb.addChild(newRow, insertRowIndex);
5766
- tb.refreshView();
5825
+ //tb.refreshView();
5767
5826
  return newRow;
5768
5827
  }
5769
5828
  /**
@@ -5825,14 +5884,14 @@ class TableUtil {
5825
5884
  const nextCell = this.getNextCell(ss);
5826
5885
  if (nextCell) {
5827
5886
  ss.resetRange(nextCell, 0);
5828
- nextCell.refreshView();
5887
+ //nextCell.refreshView();
5829
5888
  return;
5830
5889
  }
5831
5890
  //新增行,并定位
5832
5891
  const tb = ElementUtil.getParentByType(startCell, TableElement);
5833
5892
  const newRow = this.insertNewRow(tb, rowIndex + 1);
5834
5893
  ss.resetRange(newRow, 0);
5835
- newRow.refreshView();
5894
+ //newRow.refreshView();
5836
5895
  }
5837
5896
  /**
5838
5897
  * 获取下一个可定位的单元格
@@ -5874,7 +5933,7 @@ class TableUtil {
5874
5933
  console.warn('当前位置不存在表格');
5875
5934
  return;
5876
5935
  }
5877
- tb.parent.refreshView();
5936
+ //tb.parent.refreshView();
5878
5937
  tb.remove();
5879
5938
  }
5880
5939
  /**
@@ -5895,7 +5954,7 @@ class TableUtil {
5895
5954
  else if (tc.props.diagonal === diagonal) {
5896
5955
  tc.props.diagonal = null;
5897
5956
  }
5898
- tc.refreshView();
5957
+ //tc.refreshView();
5899
5958
  }
5900
5959
  /**
5901
5960
  * 将当前表格截断成两个相邻的表格
@@ -6505,11 +6564,11 @@ class CommContentBaseElement extends BlockContainerElement {
6505
6564
  super(type);
6506
6565
  this.addEvent('GotCursor', () => {
6507
6566
  this.focus = true;
6508
- this.refreshView();
6567
+ //this.refreshView()
6509
6568
  });
6510
6569
  this.addEvent('LostCursor', () => {
6511
6570
  this.focus = false;
6512
- this.refreshView();
6571
+ //this.refreshView()
6513
6572
  });
6514
6573
  }
6515
6574
  }
@@ -8718,11 +8777,13 @@ class DataElementGroupElement extends InlineGroupInputElement {
8718
8777
  this.props = new DataElementGroupProps();
8719
8778
  this.addEvent('ElementMousemove', (evt) => {
8720
8779
  this.isMouseenter = true;
8721
- this.refreshView();
8780
+ //this.refreshView();
8781
+ evt.ctx.refreshView();
8722
8782
  });
8723
8783
  this.addEvent('ElementMouseLeave', (evt) => {
8724
8784
  this.isMouseenter = false;
8725
- this.refreshView();
8785
+ evt.ctx.refreshView();
8786
+ //this.refreshView();
8726
8787
  });
8727
8788
  }
8728
8789
  setValue(val) {
@@ -8783,6 +8844,15 @@ class DataElementGroupRenderObject extends InlineGroupRenderObject {
8783
8844
  }
8784
8845
  return cloneRender;
8785
8846
  }
8847
+ exportSVG(event) {
8848
+ const node = super.exportSVG(event);
8849
+ exportDataEleDecoratorSVG(event, this);
8850
+ //绘制下划线
8851
+ if (this.element.props.underline) {
8852
+ renderUnderline(event, this);
8853
+ }
8854
+ return node;
8855
+ }
8786
8856
  }
8787
8857
  class DataElementGroupFactory extends DataElementBaseFactory {
8788
8858
  match(type) {
@@ -8821,6 +8891,35 @@ function IsInSideDataGroup(control, offset) {
8821
8891
  }
8822
8892
  function validateDataGroup(control) {
8823
8893
  return control instanceof DataElementGroupElement;
8894
+ }
8895
+ /**
8896
+ * 渲染数据元背景修饰
8897
+ * @param event
8898
+ * @param r
8899
+ */
8900
+ function exportDataEleDecoratorSVG(event, r) {
8901
+ if (event.mode === 'print') {
8902
+ return;
8903
+ }
8904
+ const options = event.options;
8905
+ let color = options.dataGroupNormalBgColor;
8906
+ //空数据元填充颜色
8907
+ if (r.element.length === 2 && options.dataGroupEmptyBgColor) {
8908
+ color = options.dataGroupEmptyBgColor;
8909
+ }
8910
+ if (r.element.isMouseenter && options.dataGroupMouseEnterBgColor) {
8911
+ color = options.dataGroupMouseEnterBgColor;
8912
+ }
8913
+ if (r.element.isFocused && options.dataGroupFocusedBgColor) {
8914
+ color = options.dataGroupFocusedBgColor;
8915
+ }
8916
+ if (!color) {
8917
+ return;
8918
+ }
8919
+ //绘制背景
8920
+ const bgX = event.relativePagePos.x;
8921
+ const bgY = event.relativePagePos.y;
8922
+ event.highlights.push(ElementUtil.getFillSvgRect(bgX, bgY, r.rect.width, r.rect.height, color));
8824
8923
  }
8825
8924
 
8826
8925
  class DataElementImage extends DataElementLeaf {
@@ -9176,11 +9275,13 @@ class DataContainerElement extends BlockContainerElement {
9176
9275
  this.props = new DataContainerProps();
9177
9276
  this.addEvent('GotCursor', (evt) => {
9178
9277
  this.isFocused = true;
9179
- this.refreshView();
9278
+ evt.ctx.refreshView();
9279
+ //this.refreshView();
9180
9280
  });
9181
9281
  this.addEvent('LostCursor', (evt) => {
9182
9282
  this.isFocused = false;
9183
- this.refreshView();
9283
+ evt.ctx.refreshView();
9284
+ //this.refreshView();
9184
9285
  });
9185
9286
  }
9186
9287
  createRenderObject() {
@@ -9295,19 +9396,23 @@ class DocumentBodyPartElement extends BlockContainerElement {
9295
9396
  super('body-part');
9296
9397
  this.addEvent('ElementMousemove', (evt) => {
9297
9398
  this.isMouseenter = true;
9298
- this.refreshView();
9399
+ evt.ctx.refreshView();
9400
+ //this.refreshView();
9299
9401
  });
9300
9402
  this.addEvent('ElementMouseLeave', (evt) => {
9301
9403
  this.isMouseenter = false;
9302
- this.refreshView();
9404
+ evt.ctx.refreshView();
9405
+ //this.refreshView();
9303
9406
  });
9304
9407
  this.addEvent('GotCursor', (evt) => {
9305
9408
  this.isFocused = true;
9306
- this.refreshView();
9409
+ evt.ctx.refreshView();
9410
+ //this.refreshView();
9307
9411
  });
9308
9412
  this.addEvent('LostCursor', (evt) => {
9309
9413
  this.isFocused = false;
9310
- this.refreshView();
9414
+ evt.ctx.refreshView();
9415
+ //this.refreshView();
9311
9416
  });
9312
9417
  this.props = new BodyPartProps();
9313
9418
  }
@@ -10221,7 +10326,7 @@ class TableSplitCell {
10221
10326
  }
10222
10327
  }
10223
10328
  tb.pubOnChange('self');
10224
- tb.refreshView();
10329
+ //tb.refreshView();
10225
10330
  }
10226
10331
  /**
10227
10332
  * 拆分合并的单元格
@@ -10328,7 +10433,7 @@ class TableSplitCell {
10328
10433
  }
10329
10434
  }
10330
10435
  tb.pubOnChange('to-child');
10331
- tb.refreshView();
10436
+ //tb.refreshView();
10332
10437
  return {
10333
10438
  startColIndex: focusCellIndex,
10334
10439
  endColIndex: focusCellIndex + cols - 1
@@ -10358,7 +10463,7 @@ class TableSplitCell {
10358
10463
  TableUtil.restoreCell(ss);
10359
10464
  this.applyHorSplitColumnCurrPatchPacks(tb, focusRowIndex, focusCellIndex, rows, currPacks);
10360
10465
  tb.pubOnChange('to-child');
10361
- tb.refreshView();
10466
+ //tb.refreshView();
10362
10467
  return {
10363
10468
  startColIndex: focusCellIndex,
10364
10469
  endColIndex: this.getPrepareNewColCounts(otherPacks, hMergeCols)
@@ -10726,6 +10831,9 @@ class ElementSerialize {
10726
10831
  if (element instanceof PSymbolElement) {
10727
10832
  return '\n';
10728
10833
  }
10834
+ if (element instanceof BreakElement) {
10835
+ return '\n';
10836
+ }
10729
10837
  if (element instanceof BranchElement) {
10730
10838
  const items = [];
10731
10839
  for (let i = 0; i < element.length; i++) {
@@ -13274,6 +13382,7 @@ class EditorContext {
13274
13382
  //suggestionsList: Array<ISuggestionData> = [];
13275
13383
  //currentSuggestionsList: Array<ISuggestionData> = [];
13276
13384
  suggestions = new DocInputSuggestions();
13385
+ //editor->this->others
13277
13386
  onKeyDownEvent = new Subject();
13278
13387
  constructor(selectionState, viewOptions) {
13279
13388
  this.selectionState = selectionState;
@@ -13283,6 +13392,16 @@ class EditorContext {
13283
13392
  this.syncRefresh?.();
13284
13393
  });
13285
13394
  }
13395
+ /**
13396
+ * 刷新视图
13397
+ */
13398
+ refreshView() {
13399
+ this.syncRefresh?.();
13400
+ }
13401
+ /**
13402
+ * 编辑器文档刷新后回调(DOM渲染完成后回调)
13403
+ * @param cb
13404
+ */
13286
13405
  onNextView(cb) {
13287
13406
  if (!cb) {
13288
13407
  this.nextViewFns.length = 0;
@@ -13297,25 +13416,27 @@ class EditorContext {
13297
13416
  set document(value) {
13298
13417
  this.clearPrevDocCb?.();
13299
13418
  this._document = value;
13419
+ this._document['editorContext'] = this;
13300
13420
  // this.refSub = this._document.refreshSubject.subscribe((data) => {
13301
13421
  // data = data ?? 'content';
13302
13422
  // this.isDirty = this.isDirty || data === 'content';
13303
13423
  // this.syncRefresh?.(data);
13304
13424
  // });
13305
- const docRefreshSub = this._document.refreshSubject.subscribe(() => {
13306
- this.syncRefresh?.();
13307
- });
13425
+ // const docRefreshSub = this._document.refreshSubject.subscribe(() => {
13426
+ // this.syncRefresh?.();
13427
+ // });
13308
13428
  const docChangedSub = this._document.onChangeSubject.subscribe(() => {
13309
13429
  this.syncRefresh?.();
13310
13430
  });
13311
13431
  this.syncRefresh();
13312
13432
  this.clearPrevDocCb = () => {
13313
- docRefreshSub.unsubscribe();
13433
+ //docRefreshSub.unsubscribe();
13314
13434
  docChangedSub.unsubscribe();
13315
13435
  if (this._document) {
13316
13436
  this.selectionState?.renderContainer?.destroy();
13317
13437
  this.clear();
13318
13438
  this._document.destroy();
13439
+ this._document.editorContext = null;
13319
13440
  clearTraces(this._document);
13320
13441
  }
13321
13442
  this.clearPrevDocCb = null;
@@ -13326,6 +13447,7 @@ class EditorContext {
13326
13447
  this.selectionState.clear();
13327
13448
  this.isDirty = false;
13328
13449
  this.suggestions.clear();
13450
+ this.currentOpsLog.length = 0;
13329
13451
  //this.clearEleDepMaps();
13330
13452
  }
13331
13453
  get defaultCtx() {
@@ -13368,6 +13490,7 @@ class EditorContext {
13368
13490
  //this.ele_types_handlers.length = 0;
13369
13491
  //this.imageLoader.clear();
13370
13492
  this._document = null;
13493
+ this.currentOpsLog.length = 0;
13371
13494
  this.suggestions.destroy();
13372
13495
  }
13373
13496
  /**
@@ -13390,11 +13513,13 @@ class EditorContext {
13390
13513
  oldDataElement.remove();
13391
13514
  }
13392
13515
  currentRefreshType = null;
13516
+ //当前操作日志
13517
+ currentOpsLog = [];
13393
13518
  get refreshType() {
13394
- if (!this._document) {
13519
+ if (!this._document || this._document.modifyFlag === exports.ModifyFlag.None) {
13395
13520
  return null;
13396
13521
  }
13397
- return this._document.modifyFlag === exports.ModifyFlag.None ? 'appearance' : 'content';
13522
+ return this._document.modifyFlag === exports.ModifyFlag.Track ? 'appearance' : 'content';
13398
13523
  }
13399
13524
  adaptiveScale() {
13400
13525
  if (this.viewOptions.pageLayoutMode !== 'fit-page') {
@@ -13670,6 +13795,18 @@ class DocumentContext {
13670
13795
  }
13671
13796
  return arr;
13672
13797
  }
13798
+ }
13799
+ function refreshEditor(ele) {
13800
+ const doc = ElementUtil.getParent(ele, e => e.type === 'doc');
13801
+ if (doc) {
13802
+ const editorCtx = doc['editorContext'];
13803
+ if (editorCtx) {
13804
+ editorCtx.refreshView();
13805
+ }
13806
+ else {
13807
+ console.warn("doc.editorContext is null,不能刷新!");
13808
+ }
13809
+ }
13673
13810
  }
13674
13811
 
13675
13812
  class DynamicExecute {
@@ -15200,6 +15337,83 @@ class DocumentArrange {
15200
15337
  tmp.props.lineHeight = this.options.defaultLineHeight;
15201
15338
  return tmp;
15202
15339
  }
15340
+ patchParagraph() {
15341
+ if (!this.options.enableFastMeasure) {
15342
+ return false;
15343
+ }
15344
+ this.pMeasure = new ParagraphMeasure(this.options, this.renderCtx, this.execute);
15345
+ const ops = this.docCtx.currentOpsLog;
15346
+ if (!ops.length) {
15347
+ return false;
15348
+ }
15349
+ if (ops.every(op => 'delText' in op.ops || 'insText' in op.ops || ('insert' in op.ops && op.ops.insert.type === 'text'))) {
15350
+ const parentIndex = ops[0].parentIndex;
15351
+ //查找父容器
15352
+ const parentEle = ElementUtil.getControlByIndex(this.docCtx.document, { currIndex: -1, index: parentIndex }, true);
15353
+ const paraEle = ElementUtil.getParent(parentEle, item => item instanceof ParagraphElement);
15354
+ if (!paraEle) {
15355
+ return false;
15356
+ }
15357
+ const cacheRender = paraEle.cacheRender;
15358
+ if (!cacheRender) {
15359
+ return false;
15360
+ }
15361
+ //已经绘制的渲染对象
15362
+ const paintRenders = paraEle.paintRenders;
15363
+ const measureParaRenders = this.pMeasure.measureParagraph(paraEle, cacheRender.rect.width);
15364
+ if (measureParaRenders.length !== 1) {
15365
+ return false;
15366
+ }
15367
+ const measureParaRender = measureParaRenders[0];
15368
+ if (cacheRender.rect.width !== measureParaRender.rect.width || cacheRender.rect.height !== measureParaRender.rect.height) {
15369
+ return false;
15370
+ }
15371
+ //第一种情况,出现在页面或者页尾上
15372
+ const measureParaRenderLines = measureParaRender.length;
15373
+ const paintRendersLines = paintRenders.reduce((prev, curr) => {
15374
+ prev.push(...curr.getItems());
15375
+ return prev;
15376
+ }, []);
15377
+ if (paintRendersLines.length % measureParaRenderLines !== 0) {
15378
+ return false;
15379
+ }
15380
+ //完全一致,逐个替换
15381
+ if (paintRendersLines.length === measureParaRenderLines) {
15382
+ for (let i = 0; i < paintRendersLines.length; i++) {
15383
+ const line = paintRendersLines[i];
15384
+ const index = line.getIndex();
15385
+ const tempLine = measureParaRender.getChild(i).clone();
15386
+ tempLine.rect.width = line.rect.width;
15387
+ tempLine.rect.height = line.rect.height;
15388
+ tempLine.rect.x = line.rect.x;
15389
+ tempLine.rect.y = line.rect.y;
15390
+ line.parent.insertChild(tempLine, index);
15391
+ line.parent.removeChild(line);
15392
+ }
15393
+ return true;
15394
+ }
15395
+ }
15396
+ return false;
15397
+ }
15398
+ fastPatchReset(docRenders) {
15399
+ //测量阶段,对于空段落会插入段落符号,新表格会插入空段落,此时不需要记录节点的更改,以最大的节点进行记录
15400
+ return suppressTracking(() => {
15401
+ const doc = this.docCtx.document;
15402
+ this.execute = new DynamicExecute(doc, this.docCtx.selectionState);
15403
+ this.pMeasure = new ParagraphMeasure(this.options, this.renderCtx, this.execute);
15404
+ const data = {
15405
+ doc,
15406
+ options: this.options,
15407
+ execute: this.execute,
15408
+ renderCtx: this.renderCtx,
15409
+ createParaFn: () => this.createDefaultPara()
15410
+ };
15411
+ this.reset(data);
15412
+ this.setMeasureCompletedModifyFlag(doc);
15413
+ this.cacheDocRenders(docRenders);
15414
+ this.generateCommRange();
15415
+ });
15416
+ }
15203
15417
  }
15204
15418
 
15205
15419
  /**
@@ -15227,7 +15441,12 @@ class DocumentPaginator {
15227
15441
  this.docCtx.selectionState.renderContainer = this.docContainer;
15228
15442
  this.docContainer.rect.width = this.viewOptions.docPageSettings.width;
15229
15443
  const newMeasure = new DocumentArrange(this.docCtx, this.renderContext, this.seo);
15230
- this.docPages = newMeasure.measureDoc();
15444
+ if (newMeasure.patchParagraph()) {
15445
+ newMeasure.fastPatchReset(this.docPages);
15446
+ }
15447
+ else {
15448
+ this.docPages = newMeasure.measureDoc();
15449
+ }
15231
15450
  this.adjustTipLayoutWidth();
15232
15451
  this.layoutPages();
15233
15452
  }
@@ -20697,7 +20916,7 @@ class DocEditor {
20697
20916
  },
20698
20917
  on: {
20699
20918
  resize: () => {
20700
- console.log('resize');
20919
+ //console.log('resize')
20701
20920
  }
20702
20921
  }
20703
20922
  },
@@ -20715,10 +20934,13 @@ class DocEditor {
20715
20934
  const target = evt.target;
20716
20935
  this.viewOptions.pageOffset.x = target.scrollLeft;
20717
20936
  this.viewOptions.pageOffset.y = target.scrollTop;
20718
- this.onChange();
20937
+ //this.onChange();
20938
+ //滚动的时候,不需要重新计算元素
20939
+ //只需要重新渲染vnode即可
20940
+ this.onPatchVNodeSubject.next();
20719
20941
  },
20720
20942
  resize: () => {
20721
- console.log('resize');
20943
+ //console.log('resize')
20722
20944
  }
20723
20945
  },
20724
20946
  hook: {
@@ -20781,12 +21003,12 @@ class DocEditor {
20781
21003
  this.refreshDocument();
20782
21004
  this.flushTask = null;
20783
21005
  //回调
20784
- let cbs = [...this.docCtx.nextViewFns];
20785
- if (cbs.length) {
20786
- this.docCtx.onNextView(null);
20787
- cbs.forEach(cb => cb());
20788
- return;
20789
- }
21006
+ // let cbs = [...this.docCtx.nextViewFns];
21007
+ // if (cbs.length) {
21008
+ // this.docCtx.onNextView(null);
21009
+ // cbs.forEach(cb => cb());
21010
+ // return;
21011
+ // }
20790
21012
  this.historyMange.generateTrack();
20791
21013
  this.historyMange.generateSelectionLog();
20792
21014
  };
@@ -20836,9 +21058,9 @@ class DocEditor {
20836
21058
  * @returns
20837
21059
  */
20838
21060
  refreshDocument() {
20839
- if (this.docCtx.refreshType === null) {
20840
- return;
20841
- }
21061
+ // if (this.docCtx.refreshType === null) {
21062
+ // return;
21063
+ // }
20842
21064
  this.docCtx.currentRefreshType = this.docCtx.refreshType;
20843
21065
  if (this.docCtx.currentRefreshType) {
20844
21066
  this.onBeforeRefreshDocument.next();
@@ -21719,6 +21941,7 @@ class DocEditor {
21719
21941
  this.vNodeDocContent = this.nodePatch(this.svgContainer, vNode);
21720
21942
  }
21721
21943
  this.afterNodePatch.next();
21944
+ this.onNextView();
21722
21945
  //console.timeEnd('patch');
21723
21946
  };
21724
21947
  render();
@@ -21729,6 +21952,13 @@ class DocEditor {
21729
21952
  render();
21730
21953
  }, 32));
21731
21954
  }
21955
+ onNextView() {
21956
+ let cbs = [...this.docCtx.nextViewFns];
21957
+ if (cbs.length) {
21958
+ this.docCtx.onNextView();
21959
+ cbs.forEach(cb => cb());
21960
+ }
21961
+ }
21732
21962
  /**
21733
21963
  * 留痕提示的容器框,用于渲染后重新计算纵向位置
21734
21964
  * @private
@@ -22084,7 +22314,7 @@ class DocEditor {
22084
22314
  rule.setRuleOptions({ width: this.viewOptions.docPageSettings.width, pagePL, pagePR, docLeft });
22085
22315
  }
22086
22316
  version() {
22087
- return "2.2.14";
22317
+ return "2.2.15";
22088
22318
  }
22089
22319
  switchPageHeaderEditor() {
22090
22320
  this.docCtx.document.switchPageHeaderEditor(this.selectionState, null);
@@ -22167,6 +22397,7 @@ class DocEditor {
22167
22397
  readDocChangeLog() {
22168
22398
  //获取文档的变更日志
22169
22399
  const ops = generatePatch(this.docCtx.document, false);
22400
+ this.docCtx.currentOpsLog = [...ops];
22170
22401
  //1.处理批注删除不对称的问题
22171
22402
  for (let i = 0; i < ops.length; i++) {
22172
22403
  const op = ops[i];
@@ -22422,7 +22653,7 @@ class DocumentCombine {
22422
22653
  * 用于合并文档计算
22423
22654
  */
22424
22655
  load() {
22425
- const template = this.mainTemplate.clone();
22656
+ const template = this.mainTemplate.clone(true);
22426
22657
  const body = template.find((item) => item instanceof DocumentBodyElement);
22427
22658
  body.clearItems();
22428
22659
  for (let i = 0; i < this.docParts.length; i++) {
@@ -27784,13 +28015,13 @@ const onTableContextmenu = (evt) => {
27784
28015
  evt.menus.push({
27785
28016
  caption: '上方插入段落', click: () => {
27786
28017
  currentElement.parent.addChild(ParagraphElement.createElement(), currentElement.getIndex());
27787
- currentElement.refreshView();
28018
+ //currentElement.refreshView()
27788
28019
  }
27789
28020
  });
27790
28021
  evt.menus.push({
27791
28022
  caption: '下方插入段落', click: () => {
27792
28023
  currentElement.parent.addChild(ParagraphElement.createElement(), currentElement.getIndex() + 1);
27793
- currentElement.refreshView();
28024
+ //currentElement.refreshView()
27794
28025
  }
27795
28026
  });
27796
28027
  evt.menus = removeDuplicatesEvent(evt.menus);
@@ -28035,7 +28266,7 @@ exports.defaultParaHanging = defaultParaHanging;
28035
28266
  exports.deleteCurrentParagraph = deleteCurrentParagraph;
28036
28267
  exports.docOpsMap = docOpsMap;
28037
28268
  exports.elementTypeEventHandler = elementTypeEventHandler;
28038
- exports.exportDecoratorHTML = exportDecoratorHTML;
28269
+ exports.exportDataEleDecoratorSVG = exportDataEleDecoratorSVG$1;
28039
28270
  exports.falseChar = falseChar;
28040
28271
  exports.fontMapFunc = fontMapFunc;
28041
28272
  exports.formatEle = formatEle;
@@ -28053,10 +28284,12 @@ exports.onTableContextmenu = onTableContextmenu;
28053
28284
  exports.onceTask = onceTask;
28054
28285
  exports.parser = parser;
28055
28286
  exports.reactiveMap = reactiveMap;
28287
+ exports.refreshEditor = refreshEditor;
28056
28288
  exports.removeEle = removeEle;
28057
28289
  exports.removeText = removeText;
28058
28290
  exports.renderErrorTip = renderErrorTip;
28059
28291
  exports.renderUnderWavyLine = renderUnderWavyLine;
28292
+ exports.renderUnderline = renderUnderline;
28060
28293
  exports.runTextLineRender = runTextLineRender;
28061
28294
  exports.setChildrenModifyFlag = setChildrenModifyFlag;
28062
28295
  exports.setNotifyChangedCallback = setNotifyChangedCallback;