@hailin-zheng/editor-core 2.1.20 → 2.1.21

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
@@ -658,10 +658,61 @@ class CommonUtil {
658
658
  return reg.test(str);
659
659
  }
660
660
  static cloneValue(val) {
661
- if (typeof val === 'object' && val) {
662
- return JSON.parse(JSON.stringify(val));
661
+ return CommonUtil.cloneDeep(val);
662
+ }
663
+ // @ts-ignore
664
+ static cloneDeep(source, visited = new WeakMap()) {
665
+ if (source === null || typeof source !== 'object') {
666
+ // 如果是基本类型或 null,则直接返回
667
+ return source;
668
+ }
669
+ // 处理循环引用
670
+ if (visited.has(source)) {
671
+ return visited.get(source);
672
+ }
673
+ if (Array.isArray(source)) {
674
+ // 如果是数组,则递归复制数组元素
675
+ const arrayClone = [];
676
+ visited.set(source, arrayClone);
677
+ source.forEach((item, index) => {
678
+ arrayClone[index] = CommonUtil.cloneDeep(item, visited);
679
+ });
680
+ return arrayClone;
681
+ }
682
+ if (source instanceof Date) {
683
+ // 如果是 Date 对象,则直接创建一个新的 Date 对象
684
+ return new Date(source.getTime());
685
+ }
686
+ if (source instanceof Map) {
687
+ // 如果是 Map 对象,则递归复制键值对
688
+ const mapClone = new Map();
689
+ visited.set(source, mapClone);
690
+ source.forEach((value, key) => {
691
+ mapClone.set(CommonUtil.cloneDeep(key, visited), CommonUtil.cloneDeep(value, visited));
692
+ });
693
+ return mapClone;
694
+ }
695
+ if (source instanceof Set) {
696
+ // 如果是 Set 对象,则递归复制元素
697
+ const setClone = new Set();
698
+ visited.set(source, setClone);
699
+ source.forEach(value => {
700
+ setClone.add(CommonUtil.cloneDeep(value, visited));
701
+ });
702
+ return setClone;
663
703
  }
664
- return val;
704
+ if (Object.prototype.toString.call(source) === '[object Object]') {
705
+ // 如果是普通对象,则递归复制对象属性
706
+ const objectClone = {};
707
+ visited.set(source, objectClone);
708
+ for (const key in source) {
709
+ if (source.hasOwnProperty(key)) {
710
+ objectClone[key] = CommonUtil.cloneDeep(source[key], visited);
711
+ }
712
+ }
713
+ return objectClone;
714
+ }
715
+ return source;
665
716
  }
666
717
  static isConstructor(f) {
667
718
  try {
@@ -741,6 +792,9 @@ class CommonUtil {
741
792
  return btoa(unescape(encodeURIComponent(str)));
742
793
  //return btoa(str.replace(/[\u00A0-\u2666]/g, c => `&#${c.charCodeAt(0)};`));
743
794
  }
795
+ static isEqual(a, b) {
796
+ return JSON.stringify(a) === JSON.stringify(b);
797
+ }
744
798
  }
745
799
 
746
800
  const docOpsMap = new Map();
@@ -1212,6 +1266,8 @@ class Element {
1212
1266
  disposed;
1213
1267
  //加载完毕
1214
1268
  loaded;
1269
+ visibleExpr;
1270
+ attribute;
1215
1271
  _parent;
1216
1272
  get parent() {
1217
1273
  return this._parent;
@@ -1284,7 +1340,6 @@ class Element {
1284
1340
  listeners.forEach(item => item(evt));
1285
1341
  }
1286
1342
  beginMeasure(data) {
1287
- this.paintRenders.length = 0;
1288
1343
  }
1289
1344
  endMeasure() {
1290
1345
  }
@@ -1700,6 +1755,7 @@ class ViewOptions {
1700
1755
  printHeaderFooterLine = false;
1701
1756
  //显示段落回车符号
1702
1757
  showEnterSymbol = false;
1758
+ enableVisibleExpression = false;
1703
1759
  get fullPageView() {
1704
1760
  return this._fullPageView;
1705
1761
  }
@@ -1813,6 +1869,30 @@ class BorderProps {
1813
1869
  return new BorderProps(this.width, this.color, this.style);
1814
1870
  }
1815
1871
  }
1872
+ /**
1873
+ * 克隆元素的基本属性
1874
+ * @param ele
1875
+ * @param target
1876
+ */
1877
+ function cloneElementBase(ele, target) {
1878
+ target.attribute = ele.attribute ? CommonUtil.cloneValue(ele.attribute) : undefined;
1879
+ }
1880
+ /**
1881
+ * 克隆元素的子元素
1882
+ * @param ele
1883
+ * @param target
1884
+ * @param data
1885
+ */
1886
+ function cloneChildren(ele, target, data) {
1887
+ if (!data) {
1888
+ return;
1889
+ }
1890
+ for (let i = 0; i < ele.length; i++) {
1891
+ const child = ele.getChild(i);
1892
+ const cloneChild = child.clone(true);
1893
+ target.addChild(cloneChild);
1894
+ }
1895
+ }
1816
1896
  class IDispose {
1817
1897
  }
1818
1898
  class ResizeLeafRenderObject extends LeafRenderObject {
@@ -2819,11 +2899,8 @@ class CommsContainerElement extends BlockContainerElement {
2819
2899
  }
2820
2900
  clone(data) {
2821
2901
  const clone = new CommsContainerElement();
2822
- if (data) {
2823
- for (let i = 0; i < this.length; i++) {
2824
- clone.addChild(this.getChild(i).clone(true));
2825
- }
2826
- }
2902
+ cloneElementBase(this, clone);
2903
+ cloneChildren(this, clone, data);
2827
2904
  return clone;
2828
2905
  }
2829
2906
  }
@@ -2906,7 +2983,7 @@ class DataDecorateElement extends LeafElement {
2906
2983
  clone() {
2907
2984
  const clone = new DataDecorateElement(this.dataEle, this.isPrefix);
2908
2985
  this.props.clone(clone.props);
2909
- //clone.renderCtx = this.renderCtx;
2986
+ cloneElementBase(this, clone);
2910
2987
  return clone;
2911
2988
  }
2912
2989
  }
@@ -2981,7 +3058,7 @@ class DataDecorateRenderObject extends LeafRenderObject {
2981
3058
  }
2982
3059
  }
2983
3060
 
2984
- function parser(code) {
3061
+ function parser(code, objects) {
2985
3062
  const node = acor__namespace.parse(code, { ecmaVersion: 'latest' });
2986
3063
  estraverse__default["default"].traverse(node, {
2987
3064
  enter: (child, parent) => {
@@ -2989,6 +3066,7 @@ function parser(code) {
2989
3066
  const identifierName = child['name'];
2990
3067
  if (identifierName.startsWith('$')) {
2991
3068
  child['name'] = `getObject('${identifierName.slice(1)}').value`;
3069
+ objects?.push(identifierName.slice(1));
2992
3070
  }
2993
3071
  }
2994
3072
  }
@@ -3015,6 +3093,28 @@ function parser(code) {
3015
3093
  });
3016
3094
  return astring.generate(node);
3017
3095
  }
3096
+ //判断代码的语句,如果最后一个语句不是return,那么加上return
3097
+ function addReturn(code) {
3098
+ const node = acor__namespace.parse(code, { ecmaVersion: 'latest' });
3099
+ estraverse__default["default"].replace(node, {
3100
+ leave: (child) => {
3101
+ //函数调用
3102
+ if (child.type == 'Program') {
3103
+ const body = child['body'];
3104
+ const lastNode = body[body.length - 1];
3105
+ if (lastNode.type !== 'ReturnStatement') {
3106
+ body[body.length - 1] = {
3107
+ type: 'ReturnStatement',
3108
+ start: -1, end: -1,
3109
+ argument: lastNode
3110
+ };
3111
+ }
3112
+ return child;
3113
+ }
3114
+ }
3115
+ });
3116
+ return astring.generate(node);
3117
+ }
3018
3118
  /**
3019
3119
  * 将参数转为函数调用arg => ()=>arg
3020
3120
  * @param nodes
@@ -3108,11 +3208,8 @@ class ParagraphElement extends BlockContentElement {
3108
3208
  clone(data) {
3109
3209
  const clone = new ParagraphElement();
3110
3210
  this.props.clone(clone.props);
3111
- if (data) {
3112
- for (let i = 0; i < this.length; i++) {
3113
- clone.addChild(this.getChild(i).clone(true));
3114
- }
3115
- }
3211
+ cloneElementBase(this, clone);
3212
+ cloneChildren(this, clone, data);
3116
3213
  return clone;
3117
3214
  }
3118
3215
  static createElement() {
@@ -3308,9 +3405,8 @@ class DocumentElement extends BlockContainerElement {
3308
3405
  clone() {
3309
3406
  const clone = new DocumentElement();
3310
3407
  this.props.clone(clone.props);
3311
- for (let i = 0; i < this.length; i++) {
3312
- clone.addChild(this.getChild(i).clone(true));
3313
- }
3408
+ cloneElementBase(this, clone);
3409
+ cloneChildren(this, clone, true);
3314
3410
  return clone;
3315
3411
  }
3316
3412
  /**
@@ -3687,6 +3783,7 @@ class InlineGroupInputElement extends InlineGroupElement {
3687
3783
  }
3688
3784
  cloneSelf(data, constr) {
3689
3785
  const clone = new constr();
3786
+ cloneElementBase(this, clone);
3690
3787
  this.props['clone'](clone.props);
3691
3788
  //cloneFunc.apply(this, clone.props);
3692
3789
  if (data) {
@@ -3809,7 +3906,7 @@ class DataElementInlineGroup extends InlineGroupInputElement {
3809
3906
  const code = parser(this.props.expression);
3810
3907
  this.expressFn = new Function(`with(this){ ${code} }`);
3811
3908
  }
3812
- this.expressFn.bind(data.parser)();
3909
+ this.expressFn.bind(data.execute)();
3813
3910
  //this.expressFn();
3814
3911
  }
3815
3912
  catch (e) {
@@ -4103,11 +4200,8 @@ class DocumentBodyElement extends BlockContainerElement {
4103
4200
  }
4104
4201
  clone(data) {
4105
4202
  const clone = new DocumentBodyElement();
4106
- if (data) {
4107
- for (let i = 0; i < this.length; i++) {
4108
- clone.addChild(this.getChild(i).clone(true));
4109
- }
4110
- }
4203
+ cloneElementBase(this, clone);
4204
+ cloneChildren(this, clone, data);
4111
4205
  return clone;
4112
4206
  }
4113
4207
  beginMeasure(data) {
@@ -4157,11 +4251,8 @@ class DocumentFooterElement extends BlockContainerElement {
4157
4251
  }
4158
4252
  clone(data) {
4159
4253
  const clone = new DocumentFooterElement();
4160
- if (data) {
4161
- for (let i = 0; i < this.length; i++) {
4162
- clone.addChild(this.getChild(i).clone(true));
4163
- }
4164
- }
4254
+ cloneElementBase(this, clone);
4255
+ cloneChildren(this, clone, data);
4165
4256
  return clone;
4166
4257
  }
4167
4258
  beginMeasure(data) {
@@ -4237,11 +4328,8 @@ class DocumentHeaderElement extends BlockContainerElement {
4237
4328
  }
4238
4329
  clone(data) {
4239
4330
  const clone = new DocumentHeaderElement();
4240
- if (data) {
4241
- for (let i = 0; i < this.length; i++) {
4242
- clone.addChild(this.getChild(i).clone(true));
4243
- }
4244
- }
4331
+ cloneElementBase(this, clone);
4332
+ cloneChildren(this, clone, data);
4245
4333
  return clone;
4246
4334
  }
4247
4335
  switchEditMode(evt) {
@@ -4339,6 +4427,7 @@ class PSymbolElement extends LeafElement {
4339
4427
  clone() {
4340
4428
  const clone = new PSymbolElement();
4341
4429
  clone.defaultHeight = this.defaultHeight;
4430
+ cloneElementBase(this, clone);
4342
4431
  return clone;
4343
4432
  }
4344
4433
  getSelfLength(pure) {
@@ -4420,11 +4509,8 @@ class TableCellElement extends BlockContainerElement {
4420
4509
  clone(data) {
4421
4510
  const clone = new TableCellElement();
4422
4511
  this.props.clone(clone.props);
4423
- if (data) {
4424
- for (let i = 0; i < this.length; i++) {
4425
- clone.addChild(this.getChild(i).clone(true));
4426
- }
4427
- }
4512
+ cloneElementBase(this, clone);
4513
+ cloneChildren(this, clone, data);
4428
4514
  return clone;
4429
4515
  }
4430
4516
  getCellWidth() {
@@ -4732,6 +4818,7 @@ class TextGroupElement extends LeafElement {
4732
4818
  const clone = new TextGroupElement();
4733
4819
  this.props.clone(clone.props);
4734
4820
  clone.text = this.text;
4821
+ cloneElementBase(this, clone);
4735
4822
  return clone;
4736
4823
  }
4737
4824
  destroy() {
@@ -6457,11 +6544,8 @@ class TableElement extends BlockContainerElement {
6457
6544
  clone(data) {
6458
6545
  const clone = new TableElement();
6459
6546
  this.props.clone(clone.props);
6460
- if (data) {
6461
- for (let i = 0; i < this.length; i++) {
6462
- clone.addChild(this.getChild(i).clone(true));
6463
- }
6464
- }
6547
+ cloneElementBase(this, clone);
6548
+ cloneChildren(this, clone, data);
6465
6549
  return clone;
6466
6550
  }
6467
6551
  createRenderObject() {
@@ -6750,6 +6834,7 @@ class CheckBoxElement extends LeafElement {
6750
6834
  }
6751
6835
  clone() {
6752
6836
  const clone = new CheckBoxElement();
6837
+ cloneElementBase(this, clone);
6753
6838
  this.props.clone(clone.props);
6754
6839
  return clone;
6755
6840
  }
@@ -6853,11 +6938,8 @@ class CommContentElement extends CommContentBaseElement {
6853
6938
  clone(data) {
6854
6939
  const clone = new CommContentElement();
6855
6940
  this.props.clone(clone.props);
6856
- if (data) {
6857
- for (let i = 0; i < this.length; i++) {
6858
- clone.addChild(this.getChild(i).clone(true));
6859
- }
6860
- }
6941
+ cloneElementBase(this, clone);
6942
+ cloneChildren(this, clone, data);
6861
6943
  return clone;
6862
6944
  }
6863
6945
  beginMeasure(data) {
@@ -7134,6 +7216,7 @@ class CommentElement extends LeafElement {
7134
7216
  clone() {
7135
7217
  const clone = new CommentElement();
7136
7218
  this.props.clone(clone.props);
7219
+ cloneElementBase(this, clone);
7137
7220
  return clone;
7138
7221
  }
7139
7222
  }
@@ -7283,11 +7366,8 @@ class ValidateElement extends CommContentBaseElement {
7283
7366
  clone(data) {
7284
7367
  const clone = new ValidateElement();
7285
7368
  this.props.clone(clone.props);
7286
- if (data) {
7287
- for (let i = 0; i < this.length; i++) {
7288
- clone.addChild(this.getChild(i).clone(true));
7289
- }
7290
- }
7369
+ cloneElementBase(this, clone);
7370
+ cloneChildren(this, clone, data);
7291
7371
  return clone;
7292
7372
  }
7293
7373
  setContent(content) {
@@ -8215,6 +8295,7 @@ class DataElementBarcode extends DataElementLeaf {
8215
8295
  clone(data) {
8216
8296
  const clone = new DataElementBarcode();
8217
8297
  this.props.clone(clone.props);
8298
+ cloneElementBase(this, clone);
8218
8299
  return clone;
8219
8300
  }
8220
8301
  setValue(val) {
@@ -8368,6 +8449,7 @@ class DataElementCheck extends DataElementLeaf {
8368
8449
  clone(data) {
8369
8450
  const clone = new DataElementCheck();
8370
8451
  this.props.clone(clone.props);
8452
+ cloneElementBase(this, clone);
8371
8453
  return clone;
8372
8454
  }
8373
8455
  setValue(val) {
@@ -8738,6 +8820,7 @@ class DataElementImage extends DataElementLeaf {
8738
8820
  clone(data) {
8739
8821
  const clone = new DataElementImage();
8740
8822
  this.props.clone(clone.props);
8823
+ cloneElementBase(this, clone);
8741
8824
  return clone;
8742
8825
  }
8743
8826
  destroy() {
@@ -8989,7 +9072,7 @@ class BreakElement extends LeafElement {
8989
9072
  }
8990
9073
  clone() {
8991
9074
  const clone = new BreakElement();
8992
- //clone.renderCtx = this.renderCtx;
9075
+ cloneElementBase(this, clone);
8993
9076
  return clone;
8994
9077
  }
8995
9078
  }
@@ -9210,11 +9293,8 @@ class DocumentBodyPartElement extends BlockContainerElement {
9210
9293
  clone(data) {
9211
9294
  const clone = new DocumentBodyPartElement();
9212
9295
  clone.props.partId = this.props.partId;
9213
- if (data) {
9214
- for (let i = 0; i < this.length; i++) {
9215
- clone.addChild(this.getChild(i).clone(true));
9216
- }
9217
- }
9296
+ cloneElementBase(this, clone);
9297
+ cloneChildren(this, clone, data);
9218
9298
  return clone;
9219
9299
  }
9220
9300
  }
@@ -9312,6 +9392,7 @@ class DataElementMH extends DataElementLeaf {
9312
9392
  clone(data) {
9313
9393
  const element = new DataElementMH();
9314
9394
  this.props.clone(element.props);
9395
+ cloneElementBase(this, element);
9315
9396
  return element;
9316
9397
  }
9317
9398
  getCurrentLayoutItem() {
@@ -9557,6 +9638,152 @@ function renderMHHTML(event, element, isPaint, nodes = []) {
9557
9638
  }
9558
9639
  }
9559
9640
 
9641
+ const fontSize = 12;
9642
+ const verPadding = 2;
9643
+ /**
9644
+ * 恒牙牙位图
9645
+ */
9646
+ class PermanentTeethElement extends DataElementLeaf {
9647
+ constructor() {
9648
+ super('permanent-teeth');
9649
+ this.props = new PermanentTeethProps();
9650
+ this.props.topLeft = '';
9651
+ this.props.topRight = '';
9652
+ this.props.bottomLeft = '';
9653
+ this.props.bottomRight = '';
9654
+ }
9655
+ setValue(val) {
9656
+ if (typeof val === 'string' && val) {
9657
+ const items = val.split(';');
9658
+ if (items.length >= 4) {
9659
+ this.props.topLeft = items[0];
9660
+ this.props.topRight = items[1];
9661
+ this.props.bottomLeft = items[2];
9662
+ this.props.bottomRight = items[3];
9663
+ }
9664
+ }
9665
+ else if (typeof val === 'object') {
9666
+ this.props.topLeft = val?.topLeft ?? '';
9667
+ this.props.topRight = val?.topRight ?? '';
9668
+ this.props.bottomLeft = val?.bottomLeft ?? '';
9669
+ this.props.bottomRight = val?.bottomRight ?? '';
9670
+ }
9671
+ }
9672
+ getValue() {
9673
+ const { topLeft, topRight, bottomLeft, bottomRight } = this.props;
9674
+ return `${topLeft};${topRight};${bottomLeft};${bottomRight}`;
9675
+ }
9676
+ clone(data) {
9677
+ const clone = new PermanentTeethElement();
9678
+ clone.props = this.props.clone();
9679
+ cloneElementBase(this, clone);
9680
+ return clone;
9681
+ }
9682
+ createRenderObject(data) {
9683
+ const clone = new PermanentTeethRenderObject(this);
9684
+ clone.rect.width = 150;
9685
+ //字体大小*2+上下间距2*2
9686
+ clone.rect.height = fontSize * 2 + verPadding * 2;
9687
+ //clone.rect= ElementUtil.cloneRect(this.rect);
9688
+ return clone;
9689
+ }
9690
+ serialize(viewOptions) {
9691
+ return {
9692
+ type: this.type,
9693
+ props: this.props.getSerializeProps(viewOptions)
9694
+ };
9695
+ }
9696
+ }
9697
+ class PermanentTeethRenderObject extends LeafRenderObject {
9698
+ clone() {
9699
+ const clone = new PermanentTeethRenderObject(this.element);
9700
+ clone.rect = ElementUtil.cloneRect(this.rect);
9701
+ return clone;
9702
+ }
9703
+ // measure(): { width: number, height: number } {
9704
+ // const ele = this.element;
9705
+ //
9706
+ // }
9707
+ exportHTML(event) {
9708
+ const ele = this.element;
9709
+ const g = super.exportHTML(event);
9710
+ const contentHorPadding = 4;
9711
+ g.children = [];
9712
+ // g.children.push(ElementUtil.getFillSvgPath(`M 0 ${this.rect.height / 2} h${this.rect.width}`, '#000', 1));
9713
+ // g.children.push(ElementUtil.getFillSvgPath(`M ${this.rect.width / 2} 0 v${this.rect.height}`, '#000', 1));
9714
+ //
9715
+ g.children.push(ElementUtil.getFillSvgRect(0, this.rect.height / 2, this.rect.width, 1, '#000'));
9716
+ g.children.push(ElementUtil.getFillSvgRect(this.rect.width / 2, 0, 1, this.rect.height, '#000'));
9717
+ const getSvgText = (text, x, y) => {
9718
+ return {
9719
+ sel: 'text',
9720
+ text: text,
9721
+ data: {
9722
+ ns: "http://www.w3.org/2000/svg",
9723
+ attrs: {
9724
+ 'dominant-baseline': 'hanging',
9725
+ 'font-family': 'Arial',
9726
+ 'font-size': fontSize,
9727
+ x,
9728
+ y,
9729
+ }
9730
+ },
9731
+ };
9732
+ };
9733
+ const topLeftWidth = event.renderCtx.mainContext.measureTextWidth(ele.props.topLeft, {
9734
+ fontSize: fontSize,
9735
+ fontName: 'Arial'
9736
+ });
9737
+ const bottomLeftWidth = event.renderCtx.mainContext.measureTextWidth(ele.props.bottomLeft, {
9738
+ fontSize: fontSize,
9739
+ fontName: 'Arial'
9740
+ });
9741
+ g.children.push(getSvgText(ele.props.topLeft, this.rect.width / 2 - topLeftWidth - contentHorPadding, verPadding));
9742
+ g.children.push(getSvgText(ele.props.topRight, this.rect.width / 2 + contentHorPadding, verPadding));
9743
+ g.children.push(getSvgText(ele.props.bottomLeft, this.rect.width / 2 - bottomLeftWidth - contentHorPadding, this.rect.height - fontSize + verPadding));
9744
+ g.children.push(getSvgText(ele.props.bottomRight, this.rect.width / 2 + contentHorPadding, this.rect.height - fontSize + verPadding));
9745
+ return g;
9746
+ }
9747
+ }
9748
+ class PermanentTeethFactory extends ElementFactory {
9749
+ match(type) {
9750
+ return type === 'permanent-teeth';
9751
+ }
9752
+ createElement(data) {
9753
+ const ele = new PermanentTeethElement();
9754
+ ele.props.bottomLeft = data.props?.bottomLeft ?? '';
9755
+ ele.props.bottomRight = data.props?.bottomRight ?? '';
9756
+ ele.props.topLeft = data.props?.topLeft ?? '';
9757
+ ele.props.topRight = data.props?.topRight ?? '';
9758
+ return ele;
9759
+ }
9760
+ }
9761
+ /**
9762
+ * 恒牙牙位图属性
9763
+ */
9764
+ class PermanentTeethProps extends INotifyPropertyChanged {
9765
+ topLeft;
9766
+ topRight;
9767
+ bottomLeft;
9768
+ bottomRight;
9769
+ getSerializeProps(viewOptions) {
9770
+ return {
9771
+ topLeft: this.topLeft,
9772
+ topRight: this.topRight,
9773
+ bottomLeft: this.bottomLeft,
9774
+ bottomRight: this.bottomRight,
9775
+ };
9776
+ }
9777
+ clone(dest) {
9778
+ dest = dest || new PermanentTeethProps();
9779
+ dest.topLeft = this.topLeft;
9780
+ dest.topRight = this.topRight;
9781
+ dest.bottomLeft = this.bottomLeft;
9782
+ dest.bottomRight = this.bottomRight;
9783
+ return dest;
9784
+ }
9785
+ }
9786
+
9560
9787
  class PictureElement extends LeafElement {
9561
9788
  //props: PictureProps;
9562
9789
  status = 'no';
@@ -9585,6 +9812,7 @@ class PictureElement extends LeafElement {
9585
9812
  clone(data) {
9586
9813
  const clone = new PictureElement();
9587
9814
  this.props.clone(clone.props);
9815
+ cloneElementBase(this, clone);
9588
9816
  return clone;
9589
9817
  }
9590
9818
  destroy() {
@@ -9710,6 +9938,7 @@ class RadioBoxElement extends LeafElement {
9710
9938
  clone() {
9711
9939
  const clone = new RadioBoxElement();
9712
9940
  this.props.clone(clone.props);
9941
+ cloneElementBase(this, clone);
9713
9942
  return clone;
9714
9943
  }
9715
9944
  }
@@ -9761,7 +9990,7 @@ class PageBreakElement extends LeafElement {
9761
9990
  }
9762
9991
  clone() {
9763
9992
  const clone = new PageBreakElement();
9764
- //clone.renderCtx = this.renderCtx;
9993
+ cloneElementBase(this, clone);
9765
9994
  return clone;
9766
9995
  }
9767
9996
  }
@@ -9798,7 +10027,9 @@ class TabElement extends LeafElement {
9798
10027
  };
9799
10028
  }
9800
10029
  clone() {
9801
- return new TabElement();
10030
+ const clone = new TabElement();
10031
+ cloneElementBase(this, clone);
10032
+ return clone;
9802
10033
  }
9803
10034
  }
9804
10035
  class TabRenderObject extends LeafRenderObject {
@@ -10393,6 +10624,7 @@ class SVGElement extends LeafElement {
10393
10624
  clone(data) {
10394
10625
  const clone = new SVGElement();
10395
10626
  this.props.clone(clone.props);
10627
+ cloneElementBase(this, clone);
10396
10628
  return clone;
10397
10629
  }
10398
10630
  destroy() {
@@ -10519,6 +10751,9 @@ class ElementSerialize {
10519
10751
  if (element.props && element.props['__attachedProperty'] && !result.props['__attachedProperty']) {
10520
10752
  result.props['__attachedProperty'] = CommonUtil.cloneValue(element.props['__attachedProperty']);
10521
10753
  }
10754
+ if (element.attribute) {
10755
+ result['attribute'] = this.serializeAttribute(element);
10756
+ }
10522
10757
  return result;
10523
10758
  }
10524
10759
  static serializeString(element, options = { all: false }) {
@@ -10541,6 +10776,21 @@ class ElementSerialize {
10541
10776
  }
10542
10777
  return "";
10543
10778
  }
10779
+ static serializeAttribute(element) {
10780
+ if (element.attribute) {
10781
+ const result = {};
10782
+ for (const key in element.attribute) {
10783
+ if (element.attribute[key] !== undefined && element.attribute[key] !== null) {
10784
+ result[key] = element.attribute[key];
10785
+ }
10786
+ }
10787
+ if (Object.keys(result).length === 0) {
10788
+ return null;
10789
+ }
10790
+ return CommonUtil.cloneValue(result);
10791
+ }
10792
+ return null;
10793
+ }
10544
10794
  /**
10545
10795
  * 获取选中的结构
10546
10796
  * @param ss
@@ -10639,12 +10889,8 @@ class TrackRunElement extends InlineGroupElement {
10639
10889
  clone(data) {
10640
10890
  const clone = new TrackRunElement(this.type);
10641
10891
  this.props.clone(clone.props);
10642
- if (data) {
10643
- const length = this.length;
10644
- for (let i = 0; i < length; i++) {
10645
- clone.addChild(this.getChild(i).clone(true));
10646
- }
10647
- }
10892
+ cloneElementBase(this, clone);
10893
+ cloneChildren(this, clone, data);
10648
10894
  return clone;
10649
10895
  }
10650
10896
  createRenderObject(data) {
@@ -12528,6 +12774,26 @@ class ElementUtil {
12528
12774
  ss.resetRange(ele.getChild(ele.length - 2), -1);
12529
12775
  }
12530
12776
  }
12777
+ static setEleAttribute(ele, attr, value) {
12778
+ if (!ele.attribute) {
12779
+ ele.attribute = {};
12780
+ }
12781
+ if (ele.attribute[attr] === value) {
12782
+ return;
12783
+ }
12784
+ ele.attribute[attr] = value;
12785
+ }
12786
+ static getEleAttribute(ele, attr) {
12787
+ if (ele.attribute) {
12788
+ return ele.attribute[attr];
12789
+ }
12790
+ return undefined;
12791
+ }
12792
+ static removeEleAttribute(ele, attr) {
12793
+ if (ele.attribute) {
12794
+ delete ele.attribute[attr];
12795
+ }
12796
+ }
12531
12797
  }
12532
12798
 
12533
12799
  class RenderContext {
@@ -13162,10 +13428,7 @@ class EditorContext {
13162
13428
  isDirty = false;
13163
13429
  cursorRect;
13164
13430
  _document;
13165
- //文档刷新的订阅事件
13166
- //refSub!: Subscription;
13167
13431
  syncRefresh;
13168
- //imageLoader: IImageLoader;
13169
13432
  dynamicFunc;
13170
13433
  docChange;
13171
13434
  clearPrevDocCb;
@@ -13219,6 +13482,7 @@ class EditorContext {
13219
13482
  //this.imageLoader.clear();
13220
13483
  this.dynamicFunc.destroyScripts();
13221
13484
  this.isDirty = false;
13485
+ //this.clearEleDepMaps();
13222
13486
  }
13223
13487
  get defaultCtx() {
13224
13488
  return new DocumentContext(this._document, this.selectionState);
@@ -13293,17 +13557,6 @@ class EditorContext {
13293
13557
  return this._document.modifyFlag === exports.ModifyFlag.None ? 'appearance' : 'content';
13294
13558
  }
13295
13559
  }
13296
- // export interface IImageLoader {
13297
- // clear(): void;
13298
- //
13299
- // loadImage(src: string, onCallback: (status: ImgLoadStatus) => void): void;
13300
- //
13301
- // getImage(src: string): HTMLImageElement | undefined;
13302
- //
13303
- // imagesLoadCompleted(): boolean;
13304
- //
13305
- // getLoadTasks(): Array<Promise<void>>;
13306
- // }
13307
13560
  /**
13308
13561
  * 文档上下文
13309
13562
  */
@@ -13566,13 +13819,23 @@ class DocumentContext {
13566
13819
  }
13567
13820
  }
13568
13821
 
13569
- class DynamicContextParser {
13822
+ class DynamicExecute {
13570
13823
  doc;
13571
13824
  ss;
13825
+ current;
13826
+ depItems;
13572
13827
  constructor(doc, ss) {
13573
13828
  this.doc = doc;
13574
13829
  this.ss = ss;
13575
13830
  }
13831
+ setCurrentCtx(ele, depItems) {
13832
+ this.current = ele;
13833
+ this.depItems = depItems;
13834
+ }
13835
+ clearCurrentCtx() {
13836
+ this.current = undefined;
13837
+ this.depItems = undefined;
13838
+ }
13576
13839
  cacheList;
13577
13840
  getControlById(id) {
13578
13841
  if (!this.cacheList) {
@@ -13584,6 +13847,10 @@ class DynamicContextParser {
13584
13847
  //return this.cacheList.find(item => item['props']['id'] === id);
13585
13848
  }
13586
13849
  getObject(id) {
13850
+ //如果当前存在编译缓存,则直接从缓存中获取
13851
+ if (this.depItems && this.depItems.has(id)) {
13852
+ return this.depItems.get(id);
13853
+ }
13587
13854
  new DocumentContext(this.doc, this.ss);
13588
13855
  if (id.startsWith('$')) {
13589
13856
  id = id.slice(1);
@@ -13602,6 +13869,9 @@ class DynamicContextParser {
13602
13869
  if (control) {
13603
13870
  control.setValue(val);
13604
13871
  }
13872
+ },
13873
+ get ref() {
13874
+ return control;
13605
13875
  }
13606
13876
  };
13607
13877
  }
@@ -13673,9 +13943,12 @@ class DynamicContextParser {
13673
13943
  class ParagraphMeasure {
13674
13944
  options;
13675
13945
  renderCtx;
13676
- constructor(options, renderCtx) {
13946
+ execute;
13947
+ constructor(options, renderCtx, execute) {
13677
13948
  this.options = options;
13678
13949
  this.renderCtx = renderCtx;
13950
+ this.execute = execute;
13951
+ this.execute = execute;
13679
13952
  }
13680
13953
  /**
13681
13954
  * 段落排版:
@@ -13771,7 +14044,10 @@ class ParagraphMeasure {
13771
14044
  const paraRenders = [];
13772
14045
  for (let i = 0; i < paraModels.length; i++) {
13773
14046
  const innerLineRects = paraModels[i].innerLine;
13774
- let render = p.createRenderObject();
14047
+ let render = this.createRenderObject(p);
14048
+ if (!render) {
14049
+ return [];
14050
+ }
13775
14051
  render.setRenderWidth(limitWidth);
13776
14052
  paraRenders.push(render);
13777
14053
  for (let j = 0; j < innerLineRects.length; j++) {
@@ -13912,7 +14188,7 @@ class ParagraphMeasure {
13912
14188
  }
13913
14189
  arrangeInlineGroupElement(parentLine, ele) {
13914
14190
  const { options, renderCtx } = this;
13915
- let render = ele.createRenderObject({ options, renderCtx });
14191
+ let render = this.createRenderObject(ele);
13916
14192
  //记录多行情况下的渲染对象,用于计算总长度,生成fill-null-space
13917
14193
  const inlineGroupRenders = [];
13918
14194
  ele.cacheRender = render;
@@ -13966,10 +14242,7 @@ class ParagraphMeasure {
13966
14242
  const baseTextProps = ele.props;
13967
14243
  nullText.text = baseTextProps.nullText;
13968
14244
  baseTextProps.nullTextProps.clone(nullText.props);
13969
- const nullTextRender = nullText.createRenderObject({
13970
- options: this.options,
13971
- renderCtx: this.renderCtx
13972
- });
14245
+ const nullTextRender = this.createRenderObject(nullText);
13973
14246
  //inlineGroupRender.insertChild(nullTextRender, 1);
13974
14247
  this.arrangeLeafRender(data, nullTextRender);
13975
14248
  }
@@ -13998,7 +14271,7 @@ class ParagraphMeasure {
13998
14271
  }
13999
14272
  }
14000
14273
  arrangeLeafElement(parentLine, ele) {
14001
- ele.cacheRender = ele.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
14274
+ ele.cacheRender = this.createRenderObject(ele);
14002
14275
  if (ele.cacheRender) {
14003
14276
  this.arrangeLeafRender(parentLine, ele.cacheRender);
14004
14277
  }
@@ -14195,11 +14468,85 @@ class ParagraphMeasure {
14195
14468
  }
14196
14469
  throw new Error('未到达计算位置');
14197
14470
  }
14198
- }
14199
-
14200
- /**
14201
- * 用于处理选区拖蓝
14202
- */
14471
+ /**
14472
+ * 解析可见性表达式
14473
+ * @param ele
14474
+ * @param execute
14475
+ * @private
14476
+ */
14477
+ parseVisibleExpression(ele, execute) {
14478
+ if (ele.visibleExpr)
14479
+ return;
14480
+ if (!ele.attribute?.visibleExpr)
14481
+ return;
14482
+ const reactiveMode = this.renderCtx.drawMode !== 'print';
14483
+ try {
14484
+ const depIdItems = [];
14485
+ const depEleMap = new Map();
14486
+ let compliedCode = parser(ele.attribute?.visibleExpr, depIdItems);
14487
+ compliedCode = addReturn(compliedCode);
14488
+ if (depIdItems.length) {
14489
+ depIdItems.forEach(dep => {
14490
+ const refCtx = execute.getObject(dep);
14491
+ if (refCtx.ref) {
14492
+ const refEle = refCtx.ref.item;
14493
+ depEleMap.set(dep, refCtx);
14494
+ //当前有可能是checkbox数组
14495
+ const refEles = Array.isArray(refEle) ? refEle : [refEle];
14496
+ reactiveMode && refEles.forEach(item => {
14497
+ //求值依赖元素更改的时候,发布当前元素重新计算的指令
14498
+ item.onChangeSubject.subscribe(() => {
14499
+ ele.pubOnChange('self');
14500
+ });
14501
+ });
14502
+ }
14503
+ });
14504
+ }
14505
+ ele.visibleExpr = { compliedCode, func: new Function(`with(this){ ${compliedCode} }`), depItems: depEleMap };
14506
+ }
14507
+ catch (e) {
14508
+ console.error('解析表达式出错', ele.attribute?.visibleExpr);
14509
+ }
14510
+ }
14511
+ /**
14512
+ * 元素可见行求值
14513
+ * @param ele
14514
+ * @param executeCtx
14515
+ * @private
14516
+ */
14517
+ evalVisibleExpr(ele, executeCtx) {
14518
+ if (ele.visibleExpr && ele.visibleExpr.func) {
14519
+ try {
14520
+ executeCtx.setCurrentCtx(ele, ele.visibleExpr.depItems);
14521
+ const func = ele.visibleExpr.func.bind(executeCtx);
14522
+ return func() === true;
14523
+ }
14524
+ catch (e) {
14525
+ console.error(e, "表达式执行出错", ele.visibleExpr.compliedCode);
14526
+ }
14527
+ finally {
14528
+ executeCtx.clearCurrentCtx();
14529
+ }
14530
+ }
14531
+ return true;
14532
+ }
14533
+ createRenderObject(element) {
14534
+ if (this.options.enableVisibleExpression) {
14535
+ this.parseVisibleExpression(element, this.execute);
14536
+ if (!this.evalVisibleExpr(element, this.execute)) {
14537
+ return null;
14538
+ }
14539
+ }
14540
+ return element.createRenderObject({
14541
+ options: this.options,
14542
+ renderCtx: this.renderCtx
14543
+ });
14544
+ }
14545
+ }
14546
+
14547
+ /**
14548
+ * 用于处理选区拖蓝
14549
+ */
14203
14550
  class SelectionOverlays {
14204
14551
  selectionState;
14205
14552
  selectionRange;
@@ -14326,6 +14673,8 @@ class DocumentArrange {
14326
14673
  renderCtx;
14327
14674
  seo;
14328
14675
  options;
14676
+ execute;
14677
+ pMeasure;
14329
14678
  constructor(docCtx, renderCtx, seo) {
14330
14679
  this.docCtx = docCtx;
14331
14680
  this.renderCtx = renderCtx;
@@ -14345,10 +14694,12 @@ class DocumentArrange {
14345
14694
  //测量阶段,对于空段落会插入段落符号,新表格会插入空段落,此时不需要记录节点的更改,以最大的节点进行记录
14346
14695
  return suppressTracking(() => {
14347
14696
  const doc = this.docCtx.document;
14697
+ this.execute = new DynamicExecute(doc, this.docCtx.selectionState);
14698
+ this.pMeasure = new ParagraphMeasure(this.options, this.renderCtx, this.execute);
14348
14699
  const data = {
14349
14700
  doc,
14350
14701
  viewOptions: this.options,
14351
- parser: new DynamicContextParser(doc, this.docCtx.selectionState),
14702
+ execute: this.execute,
14352
14703
  createParaFn: () => this.createDefaultPara()
14353
14704
  };
14354
14705
  doc.clearMarkItems();
@@ -14464,15 +14815,6 @@ class DocumentArrange {
14464
14815
  cloneFooterRender.rect.x = limitRect.x;
14465
14816
  cloneFooterRender.rect.y = documentRender.rect.height - bodyMarginBottom;
14466
14817
  currColumn === 0 && documentRender.addChild(cloneFooterRender);
14467
- // //审阅模式,添加审阅窗口
14468
- // if (this.options.showReviewWindow && commentsRender) {
14469
- // const commentsContainer = this.createRenderObject(commentsRender.element) as CommsContainerRenderObject;
14470
- // commentsContainer.padding.top = bodyMarginTop;
14471
- // commentsContainer.rect.height = documentRender.rect.height;
14472
- // documentRender.addChild(commentsContainer);
14473
- // commentsContainer.rect.x = documentRender.rect.x + documentRender.rect.width;
14474
- // documentRender.rect.width += this.options.reviewWindowWidth;
14475
- // }
14476
14818
  currColumn++;
14477
14819
  if (currColumn === docColumns) {
14478
14820
  currColumn = 0;
@@ -14483,7 +14825,7 @@ class DocumentArrange {
14483
14825
  return docPages;
14484
14826
  }
14485
14827
  createEmptyBodyRender(bodyRender, limitRect) {
14486
- const pageBodyRender = this.createRenderObject(bodyRender.element);
14828
+ const pageBodyRender = this.pMeasure.createRenderObject(bodyRender.element);
14487
14829
  pageBodyRender.rect.width = limitRect.width;
14488
14830
  const bodyInnerLimitRect = pageBodyRender.getInnerRect();
14489
14831
  if (this.options.fullPageView) {
@@ -14499,12 +14841,11 @@ class DocumentArrange {
14499
14841
  return element.cacheRender;
14500
14842
  }
14501
14843
  if (element instanceof BlockContentElement) {
14502
- const pRange = new ParagraphMeasure(this.options, this.renderCtx);
14503
- return pRange.measureParagraph(element, maxWidth);
14844
+ return this.pMeasure.measureParagraph(element, maxWidth);
14504
14845
  }
14505
14846
  else if (element instanceof BlockContainerElement) {
14506
14847
  const renders = [];
14507
- let render = this.createRenderObject(element);
14848
+ let render = this.pMeasure.createRenderObject(element);
14508
14849
  if (!render) {
14509
14850
  element.cacheRender = null;
14510
14851
  return null;
@@ -14517,8 +14858,8 @@ class DocumentArrange {
14517
14858
  const innerMaxWidth = render.getInnerMaxWidth();
14518
14859
  for (let i = 0; i < element.length; i++) {
14519
14860
  const child = element.getChild(i);
14520
- const blockContentELement = child;
14521
- const childRender = this.measureControl(blockContentELement, innerMaxWidth);
14861
+ const blockContentElement = child;
14862
+ const childRender = this.measureControl(blockContentElement, innerMaxWidth);
14522
14863
  if (!childRender) {
14523
14864
  continue;
14524
14865
  }
@@ -14528,7 +14869,7 @@ class DocumentArrange {
14528
14869
  }
14529
14870
  for (let j = 0; j < childRender.length; j++) {
14530
14871
  if (j > 0) {
14531
- render = this.createRenderObject(element);
14872
+ render = this.pMeasure.createRenderObject(element);
14532
14873
  if (!render.rect.width) {
14533
14874
  render.setRenderWidth(maxWidth);
14534
14875
  }
@@ -14556,12 +14897,6 @@ class DocumentArrange {
14556
14897
  textLineRenderMode(cacheRender, { options: this.options, renderCtx: this.renderCtx });
14557
14898
  }
14558
14899
  }
14559
- createRenderObject(element) {
14560
- return element.createRenderObject({
14561
- options: this.options,
14562
- renderCtx: this.renderCtx
14563
- });
14564
- }
14565
14900
  getDocInnerRect(documentRender) {
14566
14901
  const render = documentRender.element.createRenderObject();
14567
14902
  render.padding = documentRender.padding;
@@ -14580,7 +14915,7 @@ class DocumentArrange {
14580
14915
  if (render instanceof TableRenderObject) {
14581
14916
  return this.cutTable(render, limitHeight);
14582
14917
  }
14583
- const cloneRender = this.createRenderObject(render.element);
14918
+ const cloneRender = this.pMeasure.createRenderObject(render.element);
14584
14919
  cloneRender.setRenderWidth(render.rect.width);
14585
14920
  if (render instanceof MuiltBlockLineRenderObject) {
14586
14921
  let sumHeight = 0;
@@ -14757,7 +15092,7 @@ class DocumentArrange {
14757
15092
  for (let i = 0; i < cutCellRenders.length; i++) {
14758
15093
  let cellRender = cutCellRenders[i];
14759
15094
  if (!cellRender) {
14760
- cellRender = this.createRenderObject(cellRenders[i].element);
15095
+ cellRender = this.pMeasure.createRenderObject(cellRenders[i].element);
14761
15096
  cellRender.rect = ElementUtil.cloneRect(cellRenders[i].rect);
14762
15097
  cellRender.rect.height = 0;
14763
15098
  ElementUtil.remeasure(cellRender);
@@ -14873,647 +15208,18 @@ class DocumentArrange {
14873
15208
  return -1;
14874
15209
  }
14875
15210
  getHeaderRows(tb) {
14876
- const rows = [];
14877
- for (let i = 0; i < tb.length; i++) {
14878
- const rowRender = tb.getChild(i);
14879
- const rowEle = rowRender.element;
14880
- if (rowEle.props.headerRow) {
14881
- rows.push(rowRender);
14882
- }
14883
- else {
14884
- break;
14885
- }
14886
- }
14887
- return rows;
14888
- }
14889
- /**
14890
- * 修改测量完毕后的元素状态
14891
- * @param ele
14892
- */
14893
- setMeasureCompletedModifyFlag(ele) {
14894
- if (ele instanceof BranchElement) {
14895
- for (let i = 0; i < ele.length; i++) {
14896
- this.setMeasureCompletedModifyFlag(ele.getChild(i));
14897
- }
14898
- }
14899
- ele.modifyFlag = exports.ModifyFlag.None;
14900
- if (!ele.loaded) {
14901
- ele.loaded = true;
14902
- }
14903
- }
14904
- clearPaintCache(ele, data) {
14905
- ele.beginMeasure(data);
14906
- this.identifyComment(ele);
14907
- if (ele instanceof BranchElement) {
14908
- for (let i = 0; i < ele.length; i++) {
14909
- this.clearPaintCache(ele.getChild(i), data);
14910
- }
14911
- }
14912
- }
14913
- identifyComment(ele) {
14914
- if (ele instanceof CommentElement) {
14915
- this.docCtx.document.identifyCommMark(ele);
14916
- }
14917
- }
14918
- cacheDoc;
14919
- cacheDocRenders(docs) {
14920
- docs.forEach(doc => {
14921
- this.cacheDoc = doc;
14922
- this.cacheRenders(doc);
14923
- });
14924
- this.cacheDoc = null;
14925
- }
14926
- /**
14927
- * 生成批注区间信息
14928
- * @param renderTree
14929
- */
14930
- generateCommRange() {
14931
- this.seo.commRangeSets.clear();
14932
- const commMarks = this.docCtx.document.markPairs;
14933
- for (let i = 0; i < commMarks.length; i++) {
14934
- const commMark = commMarks[i];
14935
- if (commMark.start && commMark.end) {
14936
- const ancestor = DocumentSelection.getAncestorCommonControl(commMark.start, commMark.end);
14937
- const range = RangeUtil.getSectionRange(commMark.start, 0, commMark.end, 1, ancestor);
14938
- SelectionOverlays.addToCommentSets(range, this.seo.commRangeSets, commMark.start.color);
14939
- }
14940
- }
14941
- }
14942
- cacheRenders(renderTree) {
14943
- if (renderTree.element) {
14944
- renderTree.element.paintRenders.push(renderTree);
14945
- }
14946
- for (let i = 0; i < renderTree.length; i++) {
14947
- const currRender = renderTree.getChild(i);
14948
- if (currRender.element) {
14949
- this.cacheCommsRender(currRender);
14950
- }
14951
- if (currRender instanceof BranchRenderObject) {
14952
- this.cacheRenders(currRender);
14953
- }
14954
- else {
14955
- currRender.element && currRender.element.paintRenders.push(currRender);
14956
- }
14957
- }
14958
- }
14959
- /**
14960
- * 缓存批注标志
14961
- * @private
14962
- */
14963
- cacheCommsRender(render) {
14964
- if (render.element && render.element.type === 'comm') {
14965
- const commElement = render.element;
14966
- if (commElement.props.markType === 'start') {
14967
- const currDocRender = this.cacheDoc;
14968
- const docCommContainer = currDocRender.getItems().find(item => item instanceof CommsContainerRenderObject);
14969
- if (docCommContainer) {
14970
- docCommContainer.commsMarks.push(render);
14971
- }
14972
- }
14973
- }
14974
- if (render.element && render.element.type === 'comm-list') {
14975
- const commContainer = render;
14976
- CommentsUtil.createCommentsImage(commContainer);
14977
- }
14978
- }
14979
- endMeasures(ele) {
14980
- ele.endMeasure();
14981
- if (ele instanceof BranchElement) {
14982
- for (let i = 0; i < ele.length; i++) {
14983
- this.endMeasures(ele.getChild(i));
14984
- }
14985
- }
14986
- }
14987
- createDefaultPara() {
14988
- const tmp = new ParagraphElement();
14989
- tmp.props.lineHeight = this.options.defaultLineHeight;
14990
- return tmp;
14991
- }
14992
- }
14993
-
14994
- /**
14995
- * 文字行渲染模式
14996
- 用于医嘱打印模式
14997
- */
14998
- function runTextLineRender(ele, data) {
14999
- if (!data.options.textRowLineMode) {
15000
- return;
15001
- }
15002
- if (ele instanceof TableElement) {
15003
- // textLineRenderMode(ele, data);
15004
- // remeasureParentRenders(ele.cacheRender)
15005
- return;
15006
- }
15007
- if (ele instanceof BranchElement) {
15008
- for (let i = 0; i < ele.length; i++) {
15009
- runTextLineRender(ele.getChild(i), data);
15010
- }
15011
- }
15012
- }
15013
-
15014
- /**
15015
- * 测量阶段,生成Render-UI
15016
- */
15017
- class ElementMeasure {
15018
- docCtx;
15019
- renderCtx;
15020
- options;
15021
- constructor(docCtx, renderCtx) {
15022
- this.docCtx = docCtx;
15023
- this.renderCtx = renderCtx;
15024
- this.options = docCtx.viewOptions;
15025
- }
15026
- measureDocument(document) {
15027
- //测量阶段,对于空段落会插入段落符号,新表格会插入空段落,此时不需要记录节点的更改,以最大的节点进行记录
15028
- return suppressTracking(() => {
15029
- this.clearPaintCache(document, {
15030
- doc: document,
15031
- viewOptions: this.options,
15032
- parser: new DynamicContextParser(document, this.docCtx.selectionState),
15033
- createParaFn: () => new ParagraphElement()
15034
- });
15035
- const docRender = this.measureControl(document, this.options.docPageSettings.width);
15036
- this.setMeasureCompletedModifyFlag(document);
15037
- runTextLineRender(document, { options: this.options, renderCtx: this.renderCtx });
15038
- return docRender;
15039
- });
15040
- }
15041
- measureControl(element, maxWidth) {
15042
- if (element.modifyFlag === exports.ModifyFlag.None) {
15043
- return element.cacheRender;
15044
- }
15045
- if (element instanceof BlockContentElement) {
15046
- const render = element.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
15047
- element.cacheRender = render;
15048
- //测量阶段,只限制最大宽度即可
15049
- render.setRenderWidth(maxWidth);
15050
- if (element instanceof ParagraphElement) {
15051
- this.measureParagraph(element, render);
15052
- }
15053
- else {
15054
- throw new Error('未实现');
15055
- }
15056
- return render;
15057
- }
15058
- else if (element instanceof BlockContainerElement) {
15059
- //ElementUtil.fixBlockContainer(element);
15060
- let render = null;
15061
- if (element.modifyFlag === exports.ModifyFlag.Modify || element.modifyFlag === exports.ModifyFlag.Track) {
15062
- //ElementUtil.fixBlockContainer(element);
15063
- element.cacheRender = null;
15064
- render = element.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
15065
- if (!render) {
15066
- element.cacheRender = null;
15067
- return null;
15068
- }
15069
- if (!render.rect.width) {
15070
- render.setRenderWidth(maxWidth);
15071
- }
15072
- }
15073
- if (!render) {
15074
- throw new Error('render is null');
15075
- }
15076
- element.cacheRender = render;
15077
- const innerMaxWidth = render.getInnerMaxWidth();
15078
- for (let i = 0; i < element.length; i++) {
15079
- const child = element.getChild(i);
15080
- const blockContentELement = child;
15081
- const childRender = this.measureControl(blockContentELement, innerMaxWidth);
15082
- if (!childRender) {
15083
- continue;
15084
- }
15085
- render.addChild(childRender);
15086
- }
15087
- ElementUtil.remeasure(render);
15088
- return render;
15089
- }
15090
- else {
15091
- throw new Error('未实现');
15092
- }
15093
- }
15094
- /**
15095
- * 生成段落 UI 树
15096
- * @param para
15097
- * @param render
15098
- */
15099
- measureParagraph(para, render) {
15100
- ElementUtil.fixParagraphContent(para);
15101
- const renderObjects = [];
15102
- for (let i = 0; i < para.length; i++) {
15103
- const child = para.getChild(i);
15104
- if (child instanceof InlineGroupElement) {
15105
- child.cacheRender = this.getInlineGroupRenderItem(child);
15106
- if (child.cacheRender) {
15107
- renderObjects.push(child.cacheRender);
15108
- }
15109
- }
15110
- else if (child instanceof LeafElement) {
15111
- child.cacheRender = child.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
15112
- if (child.cacheRender) {
15113
- renderObjects.push(child.cacheRender);
15114
- }
15115
- }
15116
- }
15117
- this.measureInnerParagraph(render, para, renderObjects);
15118
- }
15119
- /**
15120
- * 根据段落UI元素,进行排列
15121
- * @param render
15122
- * @param paragraph
15123
- * @param renderObjects
15124
- */
15125
- measureInnerParagraph(render, paragraph, renderObjects) {
15126
- return;
15127
- // let lineRect = render.createLineRect();
15128
- // let maxLineWidth=render.rect.width;
15129
- // //行内框
15130
- // const innerLineRects: Array<ParagraphLineRectRenderObject> = [];
15131
- // const addInnerLineFunc = (lineRect: ParagraphLineRectRenderObject): void => {
15132
- // maxLineWidth=render.rect.width;
15133
- // innerLineRects.push(lineRect);
15134
- // if (innerLineRects.indexOf(lineRect) === 0) {
15135
- // if (paragraph.props.indent > 0) {
15136
- // maxLineWidth -= paragraph.props.indent;
15137
- // }
15138
- // } else {
15139
- // maxLineWidth -= paragraph.props.hanging;
15140
- // }
15141
- // };
15142
- // addInnerLineFunc(lineRect);
15143
- // let i = 0;
15144
- // let currItem = renderObjects[i++];
15145
- // const inCloseBody = paragraph.parent.type === 'body';
15146
- // while (currItem) {
15147
- // const maxWidth = maxLineWidth;
15148
- // const nextItem = renderObjects[i];
15149
- // const {
15150
- // firstItem,
15151
- // lastItem,
15152
- // br
15153
- // } = this.cutRenderItem(currItem, nextItem, maxWidth - lineRect.rect.width, lineRect.length === 0, inCloseBody);
15154
- // if (firstItem) {
15155
- // if (lastItem) {
15156
- // renderObjects.splice(i, 0, lastItem);
15157
- // }
15158
- // currItem = firstItem;
15159
- // } else {
15160
- // lineRect = render.createLineRect();
15161
- // addInnerLineFunc(lineRect);
15162
- // continue;
15163
- // }
15164
- // lineRect.addChild(currItem);
15165
- // currItem.rect.x = lineRect.rect.width;
15166
- // if (currItem.rect.height > lineRect.rect.height) {
15167
- // lineRect.rect.height = currItem.rect.height;
15168
- // }
15169
- // lineRect.rect.width += currItem.rect.width;
15170
- // if (br) {
15171
- // //lineRect.rect.maxWidth = lineRect.rect.width;
15172
- // lineRect = render.createLineRect();
15173
- // addInnerLineFunc(lineRect);
15174
- // }
15175
- // currItem = renderObjects[i++];
15176
- // }
15177
- // for (let i = 0; i < innerLineRects.length; i++) {
15178
- // const innerLineRect = innerLineRects[i] as ParagraphLineRectRenderObject;
15179
- // innerLineRect.rect.x = this.getParaLineRectStartX(innerLineRects.length, i, paragraph, render, innerLineRect);
15180
- // //限制最大行高
15181
- // const maxLineHeight = paragraph.props.lineHeight !== this.options.defaultLineHeight ? 100 : Math.floor(14 * 2);
15182
- // //fillLineHeight填充行高
15183
- // let fillLineHeight = Math.ceil(innerLineRect.rect.height * (paragraph.props.lineHeight - 1));
15184
- // fillLineHeight = fillLineHeight > maxLineHeight ? maxLineHeight : fillLineHeight;
15185
- // const lineHeight = innerLineRect.rect.height + fillLineHeight;
15186
- // const paddingBottom = Math.ceil(fillLineHeight / 2);
15187
- // innerLineRect.rect.height = lineHeight;
15188
- // for (let j = 0; j < innerLineRect.length; j++) {
15189
- // const leaf = innerLineRect.getChild(j);
15190
- // leaf.rect.y = innerLineRect.rect.height - paddingBottom - leaf.rect.height;
15191
- // }
15192
- // //render.rect.height += lineRect.rect.height;
15193
- // const outterLineRect = render.createLineRect();
15194
- // outterLineRect.rect.width = render.rect.width;
15195
- // outterLineRect.addChild(innerLineRect);
15196
- // ElementUtil.remeasure(outterLineRect, false);
15197
- // render.addChild(outterLineRect);
15198
- // }
15199
- // ElementUtil.remeasure(render);
15200
- }
15201
- /**
15202
- * 获取段落行布局横向坐标起始位置,被段落text-align影响
15203
- */
15204
- getParaLineRectStartX(counter, paraLineIndex, paraElement, paraRenderObject, paraLineRender) {
15205
- //左对齐,首行缩进
15206
- let indent = paraElement.props.indent;
15207
- //存在项目符号
15208
- if (paraLineIndex > 0) {
15209
- indent = paraElement.props.hanging;
15210
- }
15211
- if (paraElement.props.textAlign === 'center') {
15212
- const remainSpace = paraRenderObject.rect.width - paraLineRender.rect.width;
15213
- return Math.ceil(remainSpace / 2) + indent;
15214
- }
15215
- else if (paraElement.props.textAlign === 'right') {
15216
- const remainSpace = paraRenderObject.rect.width - paraLineRender.rect.width;
15217
- return remainSpace + indent;
15218
- }
15219
- else if (paraElement.props.textAlign === 'justify') {
15220
- const renderUnitCount = this.getRenderUnitLength(paraLineRender);
15221
- if (paraLineIndex === counter - 1 || renderUnitCount === 1) {
15222
- return indent;
15223
- }
15224
- const spaceWidth = (paraRenderObject.rect.width - paraLineRender.rect.width) / (renderUnitCount - 1);
15225
- this.setAlignJustify(paraLineRender, 0, spaceWidth);
15226
- return indent;
15227
- }
15228
- else {
15229
- return indent;
15230
- }
15231
- }
15232
- /**
15233
- * 设置两端对齐
15234
- * @param render
15235
- * @param count
15236
- * @param spaceWidth
15237
- */
15238
- setAlignJustify(render, count, spaceWidth) {
15239
- if (render instanceof BranchRenderObject) {
15240
- let width = 0;
15241
- for (let i = 0; i < render.length; i++) {
15242
- const currRender = render.getChild(i);
15243
- count += this.setAlignJustify(currRender, count, spaceWidth);
15244
- currRender.rect.x = width;
15245
- width += currRender.rect.width;
15246
- }
15247
- render.rect.width = width;
15248
- }
15249
- else if (render instanceof LeafRenderObject) {
15250
- if (render instanceof TextGroupRenderObject) {
15251
- let i = count === 0 ? 1 : 0;
15252
- for (; i < render.textMeasures.length; i++) {
15253
- render.textMeasures[i].actualSize = render.textMeasures[i].actualSize + spaceWidth;
15254
- }
15255
- render.measure();
15256
- count += render.textMeasures.length;
15257
- }
15258
- else {
15259
- if (count !== 0) {
15260
- render.rect.width += spaceWidth;
15261
- }
15262
- count += 1;
15263
- }
15264
- }
15265
- return count;
15266
- }
15267
- /**
15268
- * 获取段落行渲染单位个数,字符需要计算为字符长度
15269
- */
15270
- getRenderUnitLength(paraLine) {
15271
- if (paraLine instanceof LeafRenderObject) {
15272
- if (paraLine instanceof TextGroupRenderObject) {
15273
- return paraLine.textMeasures.length;
15274
- }
15275
- else {
15276
- return 1;
15277
- }
15278
- }
15279
- else if (paraLine instanceof BranchRenderObject) {
15280
- let count = 0;
15281
- for (let i = 0; i < paraLine.length; i++) {
15282
- count += this.getRenderUnitLength(paraLine.getChild(i));
15283
- }
15284
- return count;
15285
- }
15286
- throw new Error('未到达计算位置');
15287
- }
15288
- getInlineGroupRenderItem(item) {
15289
- const inlineGroupRender = item.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
15290
- if (!inlineGroupRender) {
15291
- return null;
15292
- }
15293
- for (let i = 0; i < item.length; i++) {
15294
- const child = item.getChild(i);
15295
- if (child instanceof LeafElement) {
15296
- child.cacheRender = child.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
15297
- if (child.cacheRender) {
15298
- inlineGroupRender.addChild(child.cacheRender);
15299
- }
15300
- }
15301
- else if (child instanceof InlineGroupElement) {
15302
- item.cacheRender = this.getInlineGroupRenderItem(child);
15303
- if (item.cacheRender) {
15304
- inlineGroupRender.addChild(item.cacheRender);
15305
- }
15306
- }
15307
- else {
15308
- throw new Error('未实现');
15309
- }
15310
- }
15311
- ElementUtil.remeasureInlineGroupRender(inlineGroupRender);
15312
- //限制最小长度
15313
- if (item instanceof DataElementInlineGroup) {
15314
- //需要填充null-text
15315
- if (item.length === 2) {
15316
- const nullText = new TextGroupElement();
15317
- nullText.isDecorate = true;
15318
- nullText.disableClick = true;
15319
- const baseTextProps = item.props;
15320
- nullText.text = baseTextProps.nullText;
15321
- baseTextProps.nullTextProps.clone(nullText.props);
15322
- const nullTextRender = nullText.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
15323
- inlineGroupRender.insertChild(nullTextRender, 1);
15324
- ElementUtil.remeasureInlineGroupRender(inlineGroupRender);
15325
- }
15326
- const props = item.props;
15327
- let minLength = props.minLength ?? 14;
15328
- minLength = minLength < 14 ? 14 : minLength;
15329
- if (item instanceof DataElementInlineGroup && inlineGroupRender.rect.width < minLength) {
15330
- const fillNullSpace = new FillNullSpaceRenderObject();
15331
- fillNullSpace.rect.width = minLength - inlineGroupRender.rect.width;
15332
- fillNullSpace.rect.height = inlineGroupRender.rect.height;
15333
- inlineGroupRender.insertChild(fillNullSpace, inlineGroupRender.length - 1);
15334
- }
15335
- ElementUtil.remeasureInlineGroupRender(inlineGroupRender);
15336
- }
15337
- return inlineGroupRender;
15338
- }
15339
- cutRenderItem(render, nextRender, limitWidth, lineEmpty, inCloseBody) {
15340
- if (render instanceof LeafRenderObject) {
15341
- if (render.rect.width > limitWidth && render instanceof TextGroupRenderObject) {
15342
- return this.cutTextRender(render, nextRender, limitWidth, lineEmpty, inCloseBody);
15343
- }
15344
- if (render instanceof FillNullSpaceRenderObject) {
15345
- return this.cutFillNullRender(render, limitWidth);
15346
- }
15347
- if (render.rect.width < limitWidth || lineEmpty || render.element.type === 'br' || render.element.type === 'psym') {
15348
- return { firstItem: render, lastItem: null, br: render.element.type === 'br' };
15349
- }
15350
- return { firstItem: null, lastItem: null };
15351
- }
15352
- else if (render instanceof InlineGroupRenderObject) {
15353
- return this.cutInlineGroupRenderItem(render, limitWidth, lineEmpty, inCloseBody);
15354
- }
15355
- throw new Error('到达计算边界');
15356
- }
15357
- cutTextRender(render, nextRender, limitWidth, lineEmpty, inCloseBody) {
15358
- let sumWidth = 0;
15359
- const cutRender = render.clone();
15360
- cutRender.textMeasures.length = 0;
15361
- let i = 0;
15362
- for (; i < render.textMeasures.length; i++) {
15363
- sumWidth += render.textMeasures[i].actualSize;
15364
- if (sumWidth > limitWidth) {
15365
- if (lineEmpty && i === 0) {
15366
- i = 1;
15367
- }
15368
- break;
15369
- }
15370
- }
15371
- //后置标点处理
15372
- i = this.patchHandlePostPunctuation(render, nextRender, i, inCloseBody, lineEmpty);
15373
- //前置标点处理
15374
- i = this.patchHandleLeadingPunctuation(render, i, lineEmpty);
15375
- if (i <= 0) {
15376
- return { firstItem: null, lastItem: null };
15377
- }
15378
- cutRender.textMeasures = render.textMeasures.splice(0, i);
15379
- render.measure();
15380
- cutRender.measure();
15381
- return { firstItem: cutRender, lastItem: render, br: true };
15382
- }
15383
- /**
15384
- * 处理前置标点,前置标点不能出现在末尾
15385
- * @param render
15386
- * @param i
15387
- */
15388
- patchHandleLeadingPunctuation(render, i, lineEmpty) {
15389
- if (i === 1 && lineEmpty) {
15390
- return i;
15391
- }
15392
- if (this.containLeadingPunctuation(render.textMeasures[i]?.char)) {
15393
- return i--;
15394
- }
15395
- return i;
15396
- }
15397
- /**
15398
- * 处理后置标点,后置标点不能出现在行首
15399
- * @param render
15400
- * @param i
15401
- * @param lineEmpty
15402
- */
15403
- patchHandlePostPunctuation(render, nextRender, i, inCloseBody, lineEmpty) {
15404
- if (i === render.textMeasures.length - 1) {
15405
- //紧跟着的字符包含后置标点
15406
- if (this.containerStartSymbolInTextStart(nextRender)) {
15407
- i--;
15408
- }
15409
- }
15410
- if (inCloseBody && this.containPostPunctuation(render.textMeasures[i]?.char)) {
15411
- if (this.containPostPunctuation(render.textMeasures[i + 1]?.char)) {
15412
- i--;
15413
- }
15414
- else {
15415
- i++;
15416
- }
15417
- }
15418
- else {
15419
- if (i > 1 && this.containPostPunctuation(render.textMeasures[i]?.char)) {
15420
- i--;
15421
- }
15422
- }
15423
- return i;
15424
- }
15425
- /**
15426
- * 是否包含后置标点
15427
- * @param str
15428
- * @returns
15429
- */
15430
- containPostPunctuation(str) {
15431
- return '!),.:;?]}¨·ˇˉ―‖’”…∶、。〃々〉》」』】〕〗!"'),.:;?]`|}~¢'.indexOf(str) > -1;
15432
- }
15433
- //是否包含前置标点
15434
- containLeadingPunctuation(str) {
15435
- return '‘“〈《「『【〔〖([{£'.indexOf(str) > -1;
15436
- }
15437
- /**
15438
- * 文本开头是否包含后置标点
15439
- * @param render
15440
- * @returns
15441
- */
15442
- containerStartSymbolInTextStart(render) {
15443
- //return false;
15444
- if (render instanceof TextGroupRenderObject) {
15445
- if (render.textMeasures.length > 0) {
15446
- return this.containPostPunctuation(render.textMeasures[0].char);
15447
- }
15448
- }
15449
- return false;
15450
- }
15451
- cutFillNullRender(render, limitWidth) {
15452
- if (limitWidth === 0) {
15453
- return { firstItem: null, lastItem: null };
15454
- }
15455
- if (render.rect.width > limitWidth) {
15456
- const cutRender = new FillNullSpaceRenderObject();
15457
- cutRender.rect.width = limitWidth;
15458
- cutRender.rect.height = render.rect.height;
15459
- render.rect.width = render.rect.width - limitWidth;
15460
- return { firstItem: cutRender, lastItem: render };
15461
- }
15462
- else {
15463
- return { firstItem: render, lastItem: null };
15464
- }
15465
- }
15466
- /**
15467
- * 行内编组元素超出行内可用空间,需要根据剩余空间长度进行截断
15468
- */
15469
- cutInlineGroupRenderItem(render, limitWidth, emptyLine, inCloseBody) {
15470
- const cutRender = render.element.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
15471
- let x = 0;
15472
- let br = false;
15473
- const items = [...render.getItems()];
15474
- for (let i = 0; i < items.length; i++) {
15475
- const child = items[i];
15476
- if (child instanceof LeafRenderObject) {
15477
- if (x + child.rect.width > limitWidth) {
15478
- const { firstItem, lastItem, br: childBr } = this.cutRenderItem(child, items[i + 1], limitWidth - x, emptyLine && cutRender.length === 0, inCloseBody);
15479
- if (firstItem) {
15480
- cutRender.addChild(firstItem);
15481
- }
15482
- br = childBr || br;
15483
- break;
15484
- }
15485
- else {
15486
- render.removeChild(child);
15487
- cutRender.addChild(child);
15488
- }
15489
- //软换行符
15490
- if (child.element && child.element.type === 'br') {
15491
- br = true;
15492
- break;
15493
- }
15211
+ const rows = [];
15212
+ for (let i = 0; i < tb.length; i++) {
15213
+ const rowRender = tb.getChild(i);
15214
+ const rowEle = rowRender.element;
15215
+ if (rowEle.props.headerRow) {
15216
+ rows.push(rowRender);
15494
15217
  }
15495
- else if (child instanceof InlineGroupRenderObject) {
15496
- if (x + child.rect.width > limitWidth) {
15497
- const { firstItem, br: childBr } = this.cutInlineGroupRenderItem(child, limitWidth - x, emptyLine && cutRender.length === 0, inCloseBody);
15498
- if (firstItem) {
15499
- cutRender.addChild(firstItem);
15500
- }
15501
- br = childBr || br;
15502
- break;
15503
- }
15504
- else {
15505
- render.removeChild(child);
15506
- cutRender.addChild(child);
15507
- }
15218
+ else {
15219
+ break;
15508
15220
  }
15509
- x += child.rect.width;
15510
- }
15511
- if (!cutRender.length) {
15512
- return { firstItem: null, lastItem: null };
15513
15221
  }
15514
- ElementUtil.remeasureInlineGroupRender(cutRender);
15515
- ElementUtil.remeasureInlineGroupRender(render);
15516
- return { firstItem: cutRender, lastItem: render.length ? render : null, br };
15222
+ return rows;
15517
15223
  }
15518
15224
  /**
15519
15225
  * 修改测量完毕后的元素状态
@@ -15526,29 +15232,105 @@ class ElementMeasure {
15526
15232
  }
15527
15233
  }
15528
15234
  ele.modifyFlag = exports.ModifyFlag.None;
15235
+ if (!ele.loaded) {
15236
+ ele.loaded = true;
15237
+ }
15529
15238
  }
15530
15239
  clearPaintCache(ele, data) {
15240
+ ele.paintRenders.length = 0;
15531
15241
  ele.beginMeasure(data);
15242
+ this.identifyComment(ele);
15532
15243
  if (ele instanceof BranchElement) {
15533
15244
  for (let i = 0; i < ele.length; i++) {
15534
15245
  this.clearPaintCache(ele.getChild(i), data);
15535
15246
  }
15536
15247
  }
15537
15248
  }
15249
+ identifyComment(ele) {
15250
+ if (ele instanceof CommentElement) {
15251
+ this.docCtx.document.identifyCommMark(ele);
15252
+ }
15253
+ }
15254
+ cacheDoc;
15255
+ cacheDocRenders(docs) {
15256
+ docs.forEach(doc => {
15257
+ this.cacheDoc = doc;
15258
+ this.cacheRenders(doc);
15259
+ });
15260
+ this.cacheDoc = null;
15261
+ }
15262
+ /**
15263
+ * 生成批注区间信息
15264
+ * @param renderTree
15265
+ */
15266
+ generateCommRange() {
15267
+ this.seo.commRangeSets.clear();
15268
+ const commMarks = this.docCtx.document.markPairs;
15269
+ for (let i = 0; i < commMarks.length; i++) {
15270
+ const commMark = commMarks[i];
15271
+ if (commMark.start && commMark.end) {
15272
+ const ancestor = DocumentSelection.getAncestorCommonControl(commMark.start, commMark.end);
15273
+ const range = RangeUtil.getSectionRange(commMark.start, 0, commMark.end, 1, ancestor);
15274
+ SelectionOverlays.addToCommentSets(range, this.seo.commRangeSets, commMark.start.color);
15275
+ }
15276
+ }
15277
+ }
15278
+ cacheRenders(renderTree) {
15279
+ if (renderTree.element) {
15280
+ renderTree.element.paintRenders.push(renderTree);
15281
+ }
15282
+ for (let i = 0; i < renderTree.length; i++) {
15283
+ const currRender = renderTree.getChild(i);
15284
+ if (currRender.element) {
15285
+ this.cacheCommsRender(currRender);
15286
+ }
15287
+ if (currRender instanceof BranchRenderObject) {
15288
+ this.cacheRenders(currRender);
15289
+ }
15290
+ else {
15291
+ currRender.element && currRender.element.paintRenders.push(currRender);
15292
+ }
15293
+ }
15294
+ }
15295
+ /**
15296
+ * 缓存批注标志
15297
+ * @private
15298
+ */
15299
+ cacheCommsRender(render) {
15300
+ if (render.element && render.element.type === 'comm') {
15301
+ const commElement = render.element;
15302
+ if (commElement.props.markType === 'start') {
15303
+ const currDocRender = this.cacheDoc;
15304
+ const docCommContainer = currDocRender.getItems().find(item => item instanceof CommsContainerRenderObject);
15305
+ if (docCommContainer) {
15306
+ docCommContainer.commsMarks.push(render);
15307
+ }
15308
+ }
15309
+ }
15310
+ if (render.element && render.element.type === 'comm-list') {
15311
+ const commContainer = render;
15312
+ CommentsUtil.createCommentsImage(commContainer);
15313
+ }
15314
+ }
15538
15315
  endMeasures(ele) {
15316
+ ele.endMeasure();
15539
15317
  if (ele instanceof BranchElement) {
15540
15318
  for (let i = 0; i < ele.length; i++) {
15541
15319
  this.endMeasures(ele.getChild(i));
15542
15320
  }
15543
15321
  }
15544
15322
  }
15323
+ createDefaultPara() {
15324
+ const tmp = new ParagraphElement();
15325
+ tmp.props.lineHeight = this.options.defaultLineHeight;
15326
+ return tmp;
15327
+ }
15545
15328
  }
15546
15329
 
15547
15330
  class DocumentPaint {
15548
15331
  renderContext;
15549
15332
  docCtx;
15550
15333
  seo;
15551
- elementMeasure;
15552
15334
  //elementRenderCut: ElementRenderCut;
15553
15335
  elementPaint;
15554
15336
  docPages;
@@ -15560,7 +15342,6 @@ class DocumentPaint {
15560
15342
  this.docCtx = docCtx;
15561
15343
  this.seo = seo;
15562
15344
  this.viewOptions = this.docCtx.viewOptions;
15563
- this.elementMeasure = new ElementMeasure(this.docCtx, this.renderContext);
15564
15345
  //this.elementRenderCut = new ElementRenderCut(this.viewOptions, this.renderContext);
15565
15346
  this.elementPaint = new ElementPaint(this.renderContext, this.docCtx);
15566
15347
  }
@@ -15720,130 +15501,6 @@ class DocumentPaint {
15720
15501
  }
15721
15502
  }
15722
15503
 
15723
- const fontSize = 12;
15724
- const verPadding = 2;
15725
- /**
15726
- * 恒牙牙位图
15727
- */
15728
- class PermanentTeethElement extends LeafElement {
15729
- constructor() {
15730
- super('permanent-teeth');
15731
- this.props = new PermanentTeethProps();
15732
- this.props.topLeft = '';
15733
- this.props.topRight = '';
15734
- this.props.bottomLeft = '';
15735
- this.props.bottomRight = '';
15736
- }
15737
- clone(data) {
15738
- const clone = new PermanentTeethElement();
15739
- clone.props = this.props.clone();
15740
- return clone;
15741
- }
15742
- createRenderObject(data) {
15743
- const clone = new PermanentTeethRenderObject(this);
15744
- clone.rect.width = 150;
15745
- //字体大小*2+上下间距2*2
15746
- clone.rect.height = fontSize * 2 + verPadding * 2;
15747
- //clone.rect= ElementUtil.cloneRect(this.rect);
15748
- return clone;
15749
- }
15750
- serialize(viewOptions) {
15751
- return {
15752
- type: this.type,
15753
- props: this.props.getSerializeProps(viewOptions)
15754
- };
15755
- }
15756
- }
15757
- class PermanentTeethRenderObject extends LeafRenderObject {
15758
- clone() {
15759
- const clone = new PermanentTeethRenderObject(this.element);
15760
- clone.rect = ElementUtil.cloneRect(this.rect);
15761
- return clone;
15762
- }
15763
- // measure(): { width: number, height: number } {
15764
- // const ele = this.element;
15765
- //
15766
- // }
15767
- exportHTML(event) {
15768
- const ele = this.element;
15769
- const g = super.exportHTML(event);
15770
- const contentHorPadding = 4;
15771
- g.children = [];
15772
- // g.children.push(ElementUtil.getFillSvgPath(`M 0 ${this.rect.height / 2} h${this.rect.width}`, '#000', 1));
15773
- // g.children.push(ElementUtil.getFillSvgPath(`M ${this.rect.width / 2} 0 v${this.rect.height}`, '#000', 1));
15774
- //
15775
- g.children.push(ElementUtil.getFillSvgRect(0, this.rect.height / 2, this.rect.width, 1, '#000'));
15776
- g.children.push(ElementUtil.getFillSvgRect(this.rect.width / 2, 0, 1, this.rect.height, '#000'));
15777
- const getSvgText = (text, x, y) => {
15778
- return {
15779
- sel: 'text',
15780
- text: text,
15781
- data: {
15782
- ns: "http://www.w3.org/2000/svg",
15783
- attrs: {
15784
- 'dominant-baseline': 'hanging',
15785
- 'font-family': 'Arial',
15786
- 'font-size': fontSize,
15787
- x,
15788
- y,
15789
- }
15790
- },
15791
- };
15792
- };
15793
- const topLeftWidth = event.renderCtx.mainContext.measureTextWidth(ele.props.topLeft, {
15794
- fontSize: fontSize,
15795
- fontName: 'Arial'
15796
- });
15797
- const bottomLeftWidth = event.renderCtx.mainContext.measureTextWidth(ele.props.bottomLeft, {
15798
- fontSize: fontSize,
15799
- fontName: 'Arial'
15800
- });
15801
- g.children.push(getSvgText(ele.props.topLeft, this.rect.width / 2 - topLeftWidth - contentHorPadding, verPadding));
15802
- g.children.push(getSvgText(ele.props.topRight, this.rect.width / 2 + contentHorPadding, verPadding));
15803
- g.children.push(getSvgText(ele.props.bottomLeft, this.rect.width / 2 - bottomLeftWidth - contentHorPadding, this.rect.height - fontSize + verPadding));
15804
- g.children.push(getSvgText(ele.props.bottomRight, this.rect.width / 2 + contentHorPadding, this.rect.height - fontSize + verPadding));
15805
- return g;
15806
- }
15807
- }
15808
- class PermanentTeethFactory extends ElementFactory {
15809
- match(type) {
15810
- return type === 'permanent-teeth';
15811
- }
15812
- createElement(data) {
15813
- const ele = new PermanentTeethElement();
15814
- ele.props.bottomLeft = data.props?.bottomLeft ?? '';
15815
- ele.props.bottomRight = data.props?.bottomRight ?? '';
15816
- ele.props.topLeft = data.props?.topLeft ?? '';
15817
- ele.props.topRight = data.props?.topRight ?? '';
15818
- return ele;
15819
- }
15820
- }
15821
- /**
15822
- * 恒牙牙位图属性
15823
- */
15824
- class PermanentTeethProps extends INotifyPropertyChanged {
15825
- topLeft;
15826
- topRight;
15827
- bottomLeft;
15828
- bottomRight;
15829
- getSerializeProps(viewOptions) {
15830
- return {
15831
- topLeft: this.topLeft,
15832
- topRight: this.topRight,
15833
- bottomLeft: this.bottomLeft,
15834
- bottomRight: this.bottomRight,
15835
- };
15836
- }
15837
- clone(dest) {
15838
- dest = dest || new PermanentTeethProps();
15839
- dest.topLeft = this.topLeft;
15840
- dest.topRight = this.topRight;
15841
- dest.bottomLeft = this.bottomLeft;
15842
- dest.bottomRight = this.bottomRight;
15843
- return dest;
15844
- }
15845
- }
15846
-
15847
15504
  class ElementReader {
15848
15505
  docCtx;
15849
15506
  constructor(docCtx) {
@@ -15907,29 +15564,18 @@ class ElementReader {
15907
15564
  this.setDocument(document);
15908
15565
  }
15909
15566
  setDocument(document) {
15910
- // if (this.docCtx.document) {
15911
- // this.docCtx.document.destroy();
15912
- // }
15913
- // this.document?.clearItems();
15914
- // document.docProps.clone(this.document.docProps);
15915
15567
  document.bodyElement = document.find((item) => item instanceof DocumentBodyElement);
15916
15568
  document.headerElement = document.find((item) => item instanceof DocumentHeaderElement);
15917
15569
  document.footerElement = document.find((item) => item instanceof DocumentFooterElement);
15918
- // document.commentsContainerElement = document.find((item) => item instanceof CommsContainerElement) as CommsContainerElement;
15919
- // if (!document.commentsContainerElement) {
15920
- // document.commentsContainerElement = new CommsContainerElement();
15921
- // }
15922
15570
  document.clearItems();
15923
15571
  document.addChild(document.headerElement);
15924
15572
  document.addChild(document.bodyElement);
15925
15573
  document.addChild(document.footerElement);
15926
- //document.addChild(document.commentsContainerElement);
15927
15574
  this.docCtx.document = document;
15928
15575
  document.viewOptions = this.docCtx.viewOptions;
15929
15576
  const width = Math.floor(document.props.width * this.docCtx.viewOptions.mmToPixelsRatio);
15930
15577
  const height = Math.floor(document.props.height * this.docCtx.viewOptions.mmToPixelsRatio);
15931
15578
  this.docCtx.viewOptions.docPageSettings = new PageOptions(width, height, document.props.orient);
15932
- //this.viewOptions.viewSettings.width = this.viewOptions.docPageSettings.width + 10;
15933
15579
  }
15934
15580
  readElement(data, strictMode = false) {
15935
15581
  if (typeof data === 'string') {
@@ -15951,6 +15597,7 @@ class ElementReader {
15951
15597
  }
15952
15598
  }
15953
15599
  factory.readCompleted(element, childArr);
15600
+ this.readAttribute(data, element);
15954
15601
  return element;
15955
15602
  }
15956
15603
  }
@@ -15962,6 +15609,11 @@ class ElementReader {
15962
15609
  return null;
15963
15610
  }
15964
15611
  }
15612
+ readAttribute(data, ele) {
15613
+ if (data.attribute) {
15614
+ ele.attribute = data.attribute;
15615
+ }
15616
+ }
15965
15617
  /**
15966
15618
  * 读取扩展属性
15967
15619
  * @param data
@@ -17215,7 +16867,6 @@ class DocumentEvent {
17215
16867
  startHitInfo: this.startHitInfo,
17216
16868
  endHitInfo: this.endHitInfo
17217
16869
  });
17218
- console.log(this.endHitInfo);
17219
16870
  }
17220
16871
  /**
17221
16872
  * 获取鼠标所在的渲染元素对象
@@ -20185,7 +19836,8 @@ class ElementTrackManage {
20185
19836
  * @private
20186
19837
  */
20187
19838
  mergeOps(ops) {
20188
- return false;
19839
+ return this.mergeFormatOps(ops);
19840
+ //return false;
20189
19841
  //问题在于:
20190
19842
  //1.新输入的字符串,selectState的startOffset、endOffset=1,后输入的字符串的endOffset进行累加
20191
19843
  //2.撤销后重做,选区范围在1-2,英国是0-2,因为之前在创建文本对象后,选区的结束位为1
@@ -20236,6 +19888,41 @@ class ElementTrackManage {
20236
19888
  // }
20237
19889
  // return false;
20238
19890
  }
19891
+ /**
19892
+ * 将对某个元素的最近两次的属性修改合并为一次,ops为当前记录的修改,比较上次的修改,如果为对同一个元素的修改,则合并
19893
+ * @private
19894
+ */
19895
+ mergeFormatOps(ops) {
19896
+ if (ops.length > 1) {
19897
+ return false;
19898
+ }
19899
+ const lastOps = this.actions[this.actions.length - 1];
19900
+ if (!lastOps || lastOps.ops.length > 1) {
19901
+ return false;
19902
+ }
19903
+ const prevOp = lastOps.ops[lastOps.ops.length - 1];
19904
+ const currOp = ops[0];
19905
+ //操作类型相同
19906
+ if ('format' in currOp.ops && 'format' in prevOp.ops && currOp.index === prevOp.index) {
19907
+ // const prevAfterSelection = lastOps.afterSelection;
19908
+ // if (!prevAfterSelection) {
19909
+ // return false;
19910
+ // }
19911
+ //前后是连续的操作
19912
+ const { format: currFormat } = currOp.ops;
19913
+ const { format: prevFormat } = prevOp.ops;
19914
+ Object.keys(currFormat).forEach(key => {
19915
+ const currValue = currFormat[key].newValue;
19916
+ const prevValue = prevFormat[key].newValue;
19917
+ if (CommonUtil.isEqual(currValue, prevValue)) {
19918
+ return;
19919
+ }
19920
+ prevFormat[key].newValue = currValue;
19921
+ });
19922
+ return true;
19923
+ }
19924
+ return false;
19925
+ }
20239
19926
  getSelection() {
20240
19927
  const { startControl, startOffset, endControl, endOffset, editable } = this.docCtx.selectionState;
20241
19928
  if (!startControl) {
@@ -28148,7 +27835,7 @@ class DocEditor {
28148
27835
  rule.setRuleOptions({ width: this.viewOptions.docPageSettings.width, pagePL, pagePR, docLeft });
28149
27836
  }
28150
27837
  version() {
28151
- return "2.1.20";
27838
+ return "2.1.21";
28152
27839
  }
28153
27840
  switchPageHeaderEditor() {
28154
27841
  this.docCtx.document.switchPageHeaderEditor(this.selectionState, null);
@@ -28201,6 +27888,26 @@ class DocumentCombine {
28201
27888
  }
28202
27889
  }
28203
27890
 
27891
+ /**
27892
+ * 文字行渲染模式
27893
+ 用于医嘱打印模式
27894
+ */
27895
+ function runTextLineRender(ele, data) {
27896
+ if (!data.options.textRowLineMode) {
27897
+ return;
27898
+ }
27899
+ if (ele instanceof TableElement) {
27900
+ // textLineRenderMode(ele, data);
27901
+ // remeasureParentRenders(ele.cacheRender)
27902
+ return;
27903
+ }
27904
+ if (ele instanceof BranchElement) {
27905
+ for (let i = 0; i < ele.length; i++) {
27906
+ runTextLineRender(ele.getChild(i), data);
27907
+ }
27908
+ }
27909
+ }
27910
+
28204
27911
  /**
28205
27912
  * 删除当前段落
28206
27913
  * @param evt
@@ -28489,6 +28196,10 @@ exports.ParagraphLineRectRenderObject = ParagraphLineRectRenderObject;
28489
28196
  exports.ParagraphProps = ParagraphProps;
28490
28197
  exports.ParagraphRenderObject = ParagraphRenderObject;
28491
28198
  exports.PasteElementEvent = PasteElementEvent;
28199
+ exports.PermanentTeethElement = PermanentTeethElement;
28200
+ exports.PermanentTeethFactory = PermanentTeethFactory;
28201
+ exports.PermanentTeethProps = PermanentTeethProps;
28202
+ exports.PermanentTeethRenderObject = PermanentTeethRenderObject;
28492
28203
  exports.PictureElement = PictureElement;
28493
28204
  exports.PictureFactory = PictureFactory;
28494
28205
  exports.PictureProps = PictureProps;
@@ -28542,8 +28253,11 @@ exports.ValidateElement = ValidateElement;
28542
28253
  exports.ValidateProps = ValidateProps;
28543
28254
  exports.ValidateRenderObject = ValidateRenderObject;
28544
28255
  exports.ViewOptions = ViewOptions;
28256
+ exports.addReturn = addReturn;
28545
28257
  exports.clearChildrenRenderCache = clearChildrenRenderCache;
28546
28258
  exports.clearTraces = clearTraces;
28259
+ exports.cloneChildren = cloneChildren;
28260
+ exports.cloneElementBase = cloneElementBase;
28547
28261
  exports.createPrintTemplate = createPrintTemplate;
28548
28262
  exports.defaultParaHanging = defaultParaHanging;
28549
28263
  exports.deleteCurrentParagraph = deleteCurrentParagraph;