@hailin-zheng/editor-core 2.1.20 → 2.1.21

Sign up to get free protection for your applications and to get access to all the features.
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;