@hailin-zheng/editor-core 2.1.20 → 2.1.22

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,60 @@ 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
+ static cloneDeep(source, visited = new WeakMap()) {
664
+ if (source === null || typeof source !== 'object') {
665
+ // 如果是基本类型或 null,则直接返回
666
+ return source;
667
+ }
668
+ // 处理循环引用
669
+ if (visited.has(source)) {
670
+ return visited.get(source);
671
+ }
672
+ if (Array.isArray(source)) {
673
+ // 如果是数组,则递归复制数组元素
674
+ const arrayClone = [];
675
+ visited.set(source, arrayClone);
676
+ source.forEach((item, index) => {
677
+ arrayClone[index] = CommonUtil.cloneDeep(item, visited);
678
+ });
679
+ return arrayClone;
680
+ }
681
+ if (source instanceof Date) {
682
+ // 如果是 Date 对象,则直接创建一个新的 Date 对象
683
+ return new Date(source.getTime());
684
+ }
685
+ if (source instanceof Map) {
686
+ // 如果是 Map 对象,则递归复制键值对
687
+ const mapClone = new Map();
688
+ visited.set(source, mapClone);
689
+ source.forEach((value, key) => {
690
+ mapClone.set(CommonUtil.cloneDeep(key, visited), CommonUtil.cloneDeep(value, visited));
691
+ });
692
+ return mapClone;
693
+ }
694
+ if (source instanceof Set) {
695
+ // 如果是 Set 对象,则递归复制元素
696
+ const setClone = new Set();
697
+ visited.set(source, setClone);
698
+ source.forEach(value => {
699
+ setClone.add(CommonUtil.cloneDeep(value, visited));
700
+ });
701
+ return setClone;
663
702
  }
664
- return val;
703
+ if (Object.prototype.toString.call(source) === '[object Object]') {
704
+ // 如果是普通对象,则递归复制对象属性
705
+ const objectClone = {};
706
+ visited.set(source, objectClone);
707
+ for (const key in source) {
708
+ if (source.hasOwnProperty(key)) {
709
+ objectClone[key] = CommonUtil.cloneDeep(source[key], visited);
710
+ }
711
+ }
712
+ return objectClone;
713
+ }
714
+ return source;
665
715
  }
666
716
  static isConstructor(f) {
667
717
  try {
@@ -741,6 +791,9 @@ class CommonUtil {
741
791
  return btoa(unescape(encodeURIComponent(str)));
742
792
  //return btoa(str.replace(/[\u00A0-\u2666]/g, c => `&#${c.charCodeAt(0)};`));
743
793
  }
794
+ static isEqual(a, b) {
795
+ return JSON.stringify(a) === JSON.stringify(b);
796
+ }
744
797
  }
745
798
 
746
799
  const docOpsMap = new Map();
@@ -1212,6 +1265,8 @@ class Element {
1212
1265
  disposed;
1213
1266
  //加载完毕
1214
1267
  loaded;
1268
+ visibleExpr;
1269
+ attribute;
1215
1270
  _parent;
1216
1271
  get parent() {
1217
1272
  return this._parent;
@@ -1284,7 +1339,6 @@ class Element {
1284
1339
  listeners.forEach(item => item(evt));
1285
1340
  }
1286
1341
  beginMeasure(data) {
1287
- this.paintRenders.length = 0;
1288
1342
  }
1289
1343
  endMeasure() {
1290
1344
  }
@@ -1700,6 +1754,7 @@ class ViewOptions {
1700
1754
  printHeaderFooterLine = false;
1701
1755
  //显示段落回车符号
1702
1756
  showEnterSymbol = false;
1757
+ enableVisibleExpression = false;
1703
1758
  get fullPageView() {
1704
1759
  return this._fullPageView;
1705
1760
  }
@@ -1813,6 +1868,30 @@ class BorderProps {
1813
1868
  return new BorderProps(this.width, this.color, this.style);
1814
1869
  }
1815
1870
  }
1871
+ /**
1872
+ * 克隆元素的基本属性
1873
+ * @param ele
1874
+ * @param target
1875
+ */
1876
+ function cloneElementBase(ele, target) {
1877
+ target.attribute = ele.attribute ? CommonUtil.cloneValue(ele.attribute) : undefined;
1878
+ }
1879
+ /**
1880
+ * 克隆元素的子元素
1881
+ * @param ele
1882
+ * @param target
1883
+ * @param data
1884
+ */
1885
+ function cloneChildren(ele, target, data) {
1886
+ if (!data) {
1887
+ return;
1888
+ }
1889
+ for (let i = 0; i < ele.length; i++) {
1890
+ const child = ele.getChild(i);
1891
+ const cloneChild = child.clone(true);
1892
+ target.addChild(cloneChild);
1893
+ }
1894
+ }
1816
1895
  class IDispose {
1817
1896
  }
1818
1897
  class ResizeLeafRenderObject extends LeafRenderObject {
@@ -2819,11 +2898,8 @@ class CommsContainerElement extends BlockContainerElement {
2819
2898
  }
2820
2899
  clone(data) {
2821
2900
  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
- }
2901
+ cloneElementBase(this, clone);
2902
+ cloneChildren(this, clone, data);
2827
2903
  return clone;
2828
2904
  }
2829
2905
  }
@@ -2906,7 +2982,7 @@ class DataDecorateElement extends LeafElement {
2906
2982
  clone() {
2907
2983
  const clone = new DataDecorateElement(this.dataEle, this.isPrefix);
2908
2984
  this.props.clone(clone.props);
2909
- //clone.renderCtx = this.renderCtx;
2985
+ cloneElementBase(this, clone);
2910
2986
  return clone;
2911
2987
  }
2912
2988
  }
@@ -2981,7 +3057,7 @@ class DataDecorateRenderObject extends LeafRenderObject {
2981
3057
  }
2982
3058
  }
2983
3059
 
2984
- function parser(code) {
3060
+ function parser(code, objects) {
2985
3061
  const node = acor__namespace.parse(code, { ecmaVersion: 'latest' });
2986
3062
  estraverse__default["default"].traverse(node, {
2987
3063
  enter: (child, parent) => {
@@ -2989,6 +3065,7 @@ function parser(code) {
2989
3065
  const identifierName = child['name'];
2990
3066
  if (identifierName.startsWith('$')) {
2991
3067
  child['name'] = `getObject('${identifierName.slice(1)}').value`;
3068
+ objects?.push(identifierName.slice(1));
2992
3069
  }
2993
3070
  }
2994
3071
  }
@@ -3015,6 +3092,28 @@ function parser(code) {
3015
3092
  });
3016
3093
  return astring.generate(node);
3017
3094
  }
3095
+ //判断代码的语句,如果最后一个语句不是return,那么加上return
3096
+ function addReturn(code) {
3097
+ const node = acor__namespace.parse(code, { ecmaVersion: 'latest' });
3098
+ estraverse__default["default"].replace(node, {
3099
+ leave: (child) => {
3100
+ //函数调用
3101
+ if (child.type == 'Program') {
3102
+ const body = child['body'];
3103
+ const lastNode = body[body.length - 1];
3104
+ if (lastNode.type !== 'ReturnStatement') {
3105
+ body[body.length - 1] = {
3106
+ type: 'ReturnStatement',
3107
+ start: -1, end: -1,
3108
+ argument: lastNode
3109
+ };
3110
+ }
3111
+ return child;
3112
+ }
3113
+ }
3114
+ });
3115
+ return astring.generate(node);
3116
+ }
3018
3117
  /**
3019
3118
  * 将参数转为函数调用arg => ()=>arg
3020
3119
  * @param nodes
@@ -3108,11 +3207,8 @@ class ParagraphElement extends BlockContentElement {
3108
3207
  clone(data) {
3109
3208
  const clone = new ParagraphElement();
3110
3209
  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
- }
3210
+ cloneElementBase(this, clone);
3211
+ cloneChildren(this, clone, data);
3116
3212
  return clone;
3117
3213
  }
3118
3214
  static createElement() {
@@ -3308,9 +3404,8 @@ class DocumentElement extends BlockContainerElement {
3308
3404
  clone() {
3309
3405
  const clone = new DocumentElement();
3310
3406
  this.props.clone(clone.props);
3311
- for (let i = 0; i < this.length; i++) {
3312
- clone.addChild(this.getChild(i).clone(true));
3313
- }
3407
+ cloneElementBase(this, clone);
3408
+ cloneChildren(this, clone, true);
3314
3409
  return clone;
3315
3410
  }
3316
3411
  /**
@@ -3687,6 +3782,7 @@ class InlineGroupInputElement extends InlineGroupElement {
3687
3782
  }
3688
3783
  cloneSelf(data, constr) {
3689
3784
  const clone = new constr();
3785
+ cloneElementBase(this, clone);
3690
3786
  this.props['clone'](clone.props);
3691
3787
  //cloneFunc.apply(this, clone.props);
3692
3788
  if (data) {
@@ -3809,7 +3905,7 @@ class DataElementInlineGroup extends InlineGroupInputElement {
3809
3905
  const code = parser(this.props.expression);
3810
3906
  this.expressFn = new Function(`with(this){ ${code} }`);
3811
3907
  }
3812
- this.expressFn.bind(data.parser)();
3908
+ this.expressFn.bind(data.execute)();
3813
3909
  //this.expressFn();
3814
3910
  }
3815
3911
  catch (e) {
@@ -4103,11 +4199,8 @@ class DocumentBodyElement extends BlockContainerElement {
4103
4199
  }
4104
4200
  clone(data) {
4105
4201
  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
- }
4202
+ cloneElementBase(this, clone);
4203
+ cloneChildren(this, clone, data);
4111
4204
  return clone;
4112
4205
  }
4113
4206
  beginMeasure(data) {
@@ -4157,11 +4250,8 @@ class DocumentFooterElement extends BlockContainerElement {
4157
4250
  }
4158
4251
  clone(data) {
4159
4252
  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
- }
4253
+ cloneElementBase(this, clone);
4254
+ cloneChildren(this, clone, data);
4165
4255
  return clone;
4166
4256
  }
4167
4257
  beginMeasure(data) {
@@ -4237,11 +4327,8 @@ class DocumentHeaderElement extends BlockContainerElement {
4237
4327
  }
4238
4328
  clone(data) {
4239
4329
  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
- }
4330
+ cloneElementBase(this, clone);
4331
+ cloneChildren(this, clone, data);
4245
4332
  return clone;
4246
4333
  }
4247
4334
  switchEditMode(evt) {
@@ -4339,6 +4426,7 @@ class PSymbolElement extends LeafElement {
4339
4426
  clone() {
4340
4427
  const clone = new PSymbolElement();
4341
4428
  clone.defaultHeight = this.defaultHeight;
4429
+ cloneElementBase(this, clone);
4342
4430
  return clone;
4343
4431
  }
4344
4432
  getSelfLength(pure) {
@@ -4420,11 +4508,8 @@ class TableCellElement extends BlockContainerElement {
4420
4508
  clone(data) {
4421
4509
  const clone = new TableCellElement();
4422
4510
  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
- }
4511
+ cloneElementBase(this, clone);
4512
+ cloneChildren(this, clone, data);
4428
4513
  return clone;
4429
4514
  }
4430
4515
  getCellWidth() {
@@ -4732,6 +4817,7 @@ class TextGroupElement extends LeafElement {
4732
4817
  const clone = new TextGroupElement();
4733
4818
  this.props.clone(clone.props);
4734
4819
  clone.text = this.text;
4820
+ cloneElementBase(this, clone);
4735
4821
  return clone;
4736
4822
  }
4737
4823
  destroy() {
@@ -4796,6 +4882,8 @@ class TextGroupRenderObject extends LeafRenderObject {
4796
4882
  return;
4797
4883
  }
4798
4884
  const props = this.element.props;
4885
+ //基线位置到top的距离
4886
+ const actualFontBoundingBoxAscent = event.renderCtx.mainContext.getActualFontBoundingBoxAscent(props.getFont());
4799
4887
  let { width, height } = this.rect;
4800
4888
  let vertHeight = 0; //baseLine;
4801
4889
  if (props.vertAlign === 'subscript') {
@@ -4814,10 +4902,11 @@ class TextGroupRenderObject extends LeafRenderObject {
4814
4902
  return curr.actualSize + prev;
4815
4903
  }, this.rect.x);
4816
4904
  const x = arr.join(' ');
4817
- const y = this.rect.y + vertHeight; //this.textMeasures.map(item => this.rect.y + vertHeight).join(' ');
4818
- // const text = this.textMeasures.map(item => {
4819
- // return item.char
4820
- // }).join('');
4905
+ let y = this.rect.y + vertHeight;
4906
+ //基线处理
4907
+ y += actualFontBoundingBoxAscent ?? 0;
4908
+ //行高处理
4909
+ y += (height - props.fontSize) / 2;
4821
4910
  const t = {
4822
4911
  sel: 'text',
4823
4912
  text: text,
@@ -4825,8 +4914,6 @@ class TextGroupRenderObject extends LeafRenderObject {
4825
4914
  ns: "http://www.w3.org/2000/svg",
4826
4915
  attrs: {
4827
4916
  //"transform": `translate(0,${(height - props.fontSize) / 2})`,
4828
- "translate": { x: 0, y: (height - props.fontSize) / 2 },
4829
- 'dominant-baseline': 'hanging',
4830
4917
  'font-family': this.element.props.fontName,
4831
4918
  'font-size': fontSize,
4832
4919
  x,
@@ -4834,6 +4921,9 @@ class TextGroupRenderObject extends LeafRenderObject {
4834
4921
  }
4835
4922
  },
4836
4923
  };
4924
+ if (actualFontBoundingBoxAscent === undefined) {
4925
+ t.data.attrs['dominant-baseline'] = 'hanging';
4926
+ }
4837
4927
  if (this.element.props.fontWeight !== 'normal') {
4838
4928
  t.data.attrs['font-weight'] = this.element.props.fontWeight;
4839
4929
  }
@@ -6457,11 +6547,8 @@ class TableElement extends BlockContainerElement {
6457
6547
  clone(data) {
6458
6548
  const clone = new TableElement();
6459
6549
  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
- }
6550
+ cloneElementBase(this, clone);
6551
+ cloneChildren(this, clone, data);
6465
6552
  return clone;
6466
6553
  }
6467
6554
  createRenderObject() {
@@ -6750,6 +6837,7 @@ class CheckBoxElement extends LeafElement {
6750
6837
  }
6751
6838
  clone() {
6752
6839
  const clone = new CheckBoxElement();
6840
+ cloneElementBase(this, clone);
6753
6841
  this.props.clone(clone.props);
6754
6842
  return clone;
6755
6843
  }
@@ -6853,11 +6941,8 @@ class CommContentElement extends CommContentBaseElement {
6853
6941
  clone(data) {
6854
6942
  const clone = new CommContentElement();
6855
6943
  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
- }
6944
+ cloneElementBase(this, clone);
6945
+ cloneChildren(this, clone, data);
6861
6946
  return clone;
6862
6947
  }
6863
6948
  beginMeasure(data) {
@@ -7134,6 +7219,7 @@ class CommentElement extends LeafElement {
7134
7219
  clone() {
7135
7220
  const clone = new CommentElement();
7136
7221
  this.props.clone(clone.props);
7222
+ cloneElementBase(this, clone);
7137
7223
  return clone;
7138
7224
  }
7139
7225
  }
@@ -7283,11 +7369,8 @@ class ValidateElement extends CommContentBaseElement {
7283
7369
  clone(data) {
7284
7370
  const clone = new ValidateElement();
7285
7371
  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
- }
7372
+ cloneElementBase(this, clone);
7373
+ cloneChildren(this, clone, data);
7291
7374
  return clone;
7292
7375
  }
7293
7376
  setContent(content) {
@@ -8215,6 +8298,7 @@ class DataElementBarcode extends DataElementLeaf {
8215
8298
  clone(data) {
8216
8299
  const clone = new DataElementBarcode();
8217
8300
  this.props.clone(clone.props);
8301
+ cloneElementBase(this, clone);
8218
8302
  return clone;
8219
8303
  }
8220
8304
  setValue(val) {
@@ -8368,6 +8452,7 @@ class DataElementCheck extends DataElementLeaf {
8368
8452
  clone(data) {
8369
8453
  const clone = new DataElementCheck();
8370
8454
  this.props.clone(clone.props);
8455
+ cloneElementBase(this, clone);
8371
8456
  return clone;
8372
8457
  }
8373
8458
  setValue(val) {
@@ -8738,6 +8823,7 @@ class DataElementImage extends DataElementLeaf {
8738
8823
  clone(data) {
8739
8824
  const clone = new DataElementImage();
8740
8825
  this.props.clone(clone.props);
8826
+ cloneElementBase(this, clone);
8741
8827
  return clone;
8742
8828
  }
8743
8829
  destroy() {
@@ -8989,7 +9075,7 @@ class BreakElement extends LeafElement {
8989
9075
  }
8990
9076
  clone() {
8991
9077
  const clone = new BreakElement();
8992
- //clone.renderCtx = this.renderCtx;
9078
+ cloneElementBase(this, clone);
8993
9079
  return clone;
8994
9080
  }
8995
9081
  }
@@ -9210,11 +9296,8 @@ class DocumentBodyPartElement extends BlockContainerElement {
9210
9296
  clone(data) {
9211
9297
  const clone = new DocumentBodyPartElement();
9212
9298
  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
- }
9299
+ cloneElementBase(this, clone);
9300
+ cloneChildren(this, clone, data);
9218
9301
  return clone;
9219
9302
  }
9220
9303
  }
@@ -9312,6 +9395,7 @@ class DataElementMH extends DataElementLeaf {
9312
9395
  clone(data) {
9313
9396
  const element = new DataElementMH();
9314
9397
  this.props.clone(element.props);
9398
+ cloneElementBase(this, element);
9315
9399
  return element;
9316
9400
  }
9317
9401
  getCurrentLayoutItem() {
@@ -9557,6 +9641,152 @@ function renderMHHTML(event, element, isPaint, nodes = []) {
9557
9641
  }
9558
9642
  }
9559
9643
 
9644
+ const fontSize = 12;
9645
+ const verPadding = 2;
9646
+ /**
9647
+ * 恒牙牙位图
9648
+ */
9649
+ class PermanentTeethElement extends DataElementLeaf {
9650
+ constructor() {
9651
+ super('permanent-teeth');
9652
+ this.props = new PermanentTeethProps();
9653
+ this.props.topLeft = '';
9654
+ this.props.topRight = '';
9655
+ this.props.bottomLeft = '';
9656
+ this.props.bottomRight = '';
9657
+ }
9658
+ setValue(val) {
9659
+ if (typeof val === 'string' && val) {
9660
+ const items = val.split(';');
9661
+ if (items.length >= 4) {
9662
+ this.props.topLeft = items[0];
9663
+ this.props.topRight = items[1];
9664
+ this.props.bottomLeft = items[2];
9665
+ this.props.bottomRight = items[3];
9666
+ }
9667
+ }
9668
+ else if (typeof val === 'object') {
9669
+ this.props.topLeft = val?.topLeft ?? '';
9670
+ this.props.topRight = val?.topRight ?? '';
9671
+ this.props.bottomLeft = val?.bottomLeft ?? '';
9672
+ this.props.bottomRight = val?.bottomRight ?? '';
9673
+ }
9674
+ }
9675
+ getValue() {
9676
+ const { topLeft, topRight, bottomLeft, bottomRight } = this.props;
9677
+ return `${topLeft};${topRight};${bottomLeft};${bottomRight}`;
9678
+ }
9679
+ clone(data) {
9680
+ const clone = new PermanentTeethElement();
9681
+ clone.props = this.props.clone();
9682
+ cloneElementBase(this, clone);
9683
+ return clone;
9684
+ }
9685
+ createRenderObject(data) {
9686
+ const clone = new PermanentTeethRenderObject(this);
9687
+ clone.rect.width = 150;
9688
+ //字体大小*2+上下间距2*2
9689
+ clone.rect.height = fontSize * 2 + verPadding * 2;
9690
+ //clone.rect= ElementUtil.cloneRect(this.rect);
9691
+ return clone;
9692
+ }
9693
+ serialize(viewOptions) {
9694
+ return {
9695
+ type: this.type,
9696
+ props: this.props.getSerializeProps(viewOptions)
9697
+ };
9698
+ }
9699
+ }
9700
+ class PermanentTeethRenderObject extends LeafRenderObject {
9701
+ clone() {
9702
+ const clone = new PermanentTeethRenderObject(this.element);
9703
+ clone.rect = ElementUtil.cloneRect(this.rect);
9704
+ return clone;
9705
+ }
9706
+ // measure(): { width: number, height: number } {
9707
+ // const ele = this.element;
9708
+ //
9709
+ // }
9710
+ exportHTML(event) {
9711
+ const ele = this.element;
9712
+ const g = super.exportHTML(event);
9713
+ const contentHorPadding = 4;
9714
+ g.children = [];
9715
+ // g.children.push(ElementUtil.getFillSvgPath(`M 0 ${this.rect.height / 2} h${this.rect.width}`, '#000', 1));
9716
+ // g.children.push(ElementUtil.getFillSvgPath(`M ${this.rect.width / 2} 0 v${this.rect.height}`, '#000', 1));
9717
+ //
9718
+ g.children.push(ElementUtil.getFillSvgRect(0, this.rect.height / 2, this.rect.width, 1, '#000'));
9719
+ g.children.push(ElementUtil.getFillSvgRect(this.rect.width / 2, 0, 1, this.rect.height, '#000'));
9720
+ const getSvgText = (text, x, y) => {
9721
+ return {
9722
+ sel: 'text',
9723
+ text: text,
9724
+ data: {
9725
+ ns: "http://www.w3.org/2000/svg",
9726
+ attrs: {
9727
+ 'dominant-baseline': 'hanging',
9728
+ 'font-family': 'Arial',
9729
+ 'font-size': fontSize,
9730
+ x,
9731
+ y,
9732
+ }
9733
+ },
9734
+ };
9735
+ };
9736
+ const topLeftWidth = event.renderCtx.mainContext.measureTextWidth(ele.props.topLeft, {
9737
+ fontSize: fontSize,
9738
+ fontName: 'Arial'
9739
+ });
9740
+ const bottomLeftWidth = event.renderCtx.mainContext.measureTextWidth(ele.props.bottomLeft, {
9741
+ fontSize: fontSize,
9742
+ fontName: 'Arial'
9743
+ });
9744
+ g.children.push(getSvgText(ele.props.topLeft, this.rect.width / 2 - topLeftWidth - contentHorPadding, verPadding));
9745
+ g.children.push(getSvgText(ele.props.topRight, this.rect.width / 2 + contentHorPadding, verPadding));
9746
+ g.children.push(getSvgText(ele.props.bottomLeft, this.rect.width / 2 - bottomLeftWidth - contentHorPadding, this.rect.height - fontSize + verPadding));
9747
+ g.children.push(getSvgText(ele.props.bottomRight, this.rect.width / 2 + contentHorPadding, this.rect.height - fontSize + verPadding));
9748
+ return g;
9749
+ }
9750
+ }
9751
+ class PermanentTeethFactory extends ElementFactory {
9752
+ match(type) {
9753
+ return type === 'permanent-teeth';
9754
+ }
9755
+ createElement(data) {
9756
+ const ele = new PermanentTeethElement();
9757
+ ele.props.bottomLeft = data.props?.bottomLeft ?? '';
9758
+ ele.props.bottomRight = data.props?.bottomRight ?? '';
9759
+ ele.props.topLeft = data.props?.topLeft ?? '';
9760
+ ele.props.topRight = data.props?.topRight ?? '';
9761
+ return ele;
9762
+ }
9763
+ }
9764
+ /**
9765
+ * 恒牙牙位图属性
9766
+ */
9767
+ class PermanentTeethProps extends INotifyPropertyChanged {
9768
+ topLeft;
9769
+ topRight;
9770
+ bottomLeft;
9771
+ bottomRight;
9772
+ getSerializeProps(viewOptions) {
9773
+ return {
9774
+ topLeft: this.topLeft,
9775
+ topRight: this.topRight,
9776
+ bottomLeft: this.bottomLeft,
9777
+ bottomRight: this.bottomRight,
9778
+ };
9779
+ }
9780
+ clone(dest) {
9781
+ dest = dest || new PermanentTeethProps();
9782
+ dest.topLeft = this.topLeft;
9783
+ dest.topRight = this.topRight;
9784
+ dest.bottomLeft = this.bottomLeft;
9785
+ dest.bottomRight = this.bottomRight;
9786
+ return dest;
9787
+ }
9788
+ }
9789
+
9560
9790
  class PictureElement extends LeafElement {
9561
9791
  //props: PictureProps;
9562
9792
  status = 'no';
@@ -9585,6 +9815,7 @@ class PictureElement extends LeafElement {
9585
9815
  clone(data) {
9586
9816
  const clone = new PictureElement();
9587
9817
  this.props.clone(clone.props);
9818
+ cloneElementBase(this, clone);
9588
9819
  return clone;
9589
9820
  }
9590
9821
  destroy() {
@@ -9710,6 +9941,7 @@ class RadioBoxElement extends LeafElement {
9710
9941
  clone() {
9711
9942
  const clone = new RadioBoxElement();
9712
9943
  this.props.clone(clone.props);
9944
+ cloneElementBase(this, clone);
9713
9945
  return clone;
9714
9946
  }
9715
9947
  }
@@ -9761,7 +9993,7 @@ class PageBreakElement extends LeafElement {
9761
9993
  }
9762
9994
  clone() {
9763
9995
  const clone = new PageBreakElement();
9764
- //clone.renderCtx = this.renderCtx;
9996
+ cloneElementBase(this, clone);
9765
9997
  return clone;
9766
9998
  }
9767
9999
  }
@@ -9798,7 +10030,9 @@ class TabElement extends LeafElement {
9798
10030
  };
9799
10031
  }
9800
10032
  clone() {
9801
- return new TabElement();
10033
+ const clone = new TabElement();
10034
+ cloneElementBase(this, clone);
10035
+ return clone;
9802
10036
  }
9803
10037
  }
9804
10038
  class TabRenderObject extends LeafRenderObject {
@@ -10393,6 +10627,7 @@ class SVGElement extends LeafElement {
10393
10627
  clone(data) {
10394
10628
  const clone = new SVGElement();
10395
10629
  this.props.clone(clone.props);
10630
+ cloneElementBase(this, clone);
10396
10631
  return clone;
10397
10632
  }
10398
10633
  destroy() {
@@ -10519,6 +10754,9 @@ class ElementSerialize {
10519
10754
  if (element.props && element.props['__attachedProperty'] && !result.props['__attachedProperty']) {
10520
10755
  result.props['__attachedProperty'] = CommonUtil.cloneValue(element.props['__attachedProperty']);
10521
10756
  }
10757
+ if (element.attribute) {
10758
+ result['attribute'] = this.serializeAttribute(element);
10759
+ }
10522
10760
  return result;
10523
10761
  }
10524
10762
  static serializeString(element, options = { all: false }) {
@@ -10541,6 +10779,21 @@ class ElementSerialize {
10541
10779
  }
10542
10780
  return "";
10543
10781
  }
10782
+ static serializeAttribute(element) {
10783
+ if (element.attribute) {
10784
+ const result = {};
10785
+ for (const key in element.attribute) {
10786
+ if (element.attribute[key] !== undefined && element.attribute[key] !== null) {
10787
+ result[key] = element.attribute[key];
10788
+ }
10789
+ }
10790
+ if (Object.keys(result).length === 0) {
10791
+ return null;
10792
+ }
10793
+ return CommonUtil.cloneValue(result);
10794
+ }
10795
+ return null;
10796
+ }
10544
10797
  /**
10545
10798
  * 获取选中的结构
10546
10799
  * @param ss
@@ -10639,12 +10892,8 @@ class TrackRunElement extends InlineGroupElement {
10639
10892
  clone(data) {
10640
10893
  const clone = new TrackRunElement(this.type);
10641
10894
  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
- }
10895
+ cloneElementBase(this, clone);
10896
+ cloneChildren(this, clone, data);
10648
10897
  return clone;
10649
10898
  }
10650
10899
  createRenderObject(data) {
@@ -12528,6 +12777,26 @@ class ElementUtil {
12528
12777
  ss.resetRange(ele.getChild(ele.length - 2), -1);
12529
12778
  }
12530
12779
  }
12780
+ static setEleAttribute(ele, attr, value) {
12781
+ if (!ele.attribute) {
12782
+ ele.attribute = {};
12783
+ }
12784
+ if (ele.attribute[attr] === value) {
12785
+ return;
12786
+ }
12787
+ ele.attribute[attr] = value;
12788
+ }
12789
+ static getEleAttribute(ele, attr) {
12790
+ if (ele.attribute) {
12791
+ return ele.attribute[attr];
12792
+ }
12793
+ return undefined;
12794
+ }
12795
+ static removeEleAttribute(ele, attr) {
12796
+ if (ele.attribute) {
12797
+ delete ele.attribute[attr];
12798
+ }
12799
+ }
12531
12800
  }
12532
12801
 
12533
12802
  class RenderContext {
@@ -12602,7 +12871,18 @@ class PaintContent {
12602
12871
  this.init();
12603
12872
  }
12604
12873
  init() {
12605
- this.ctx.textBaseline = 'top';
12874
+ //this.ctx.textBaseline = 'top';
12875
+ }
12876
+ cacheFontBoundingBoxAscentMap = new Map();
12877
+ getActualFontBoundingBoxAscent(font) {
12878
+ if (this.cacheFontBoundingBoxAscentMap.has(font)) {
12879
+ return this.cacheFontBoundingBoxAscentMap.get(font);
12880
+ }
12881
+ this.ctx.font = font;
12882
+ const textMetrics = this.ctx.measureText('正');
12883
+ const value = textMetrics.actualBoundingBoxAscent;
12884
+ this.cacheFontBoundingBoxAscentMap.set(font, value);
12885
+ return value;
12606
12886
  }
12607
12887
  setGlobalAlpha(alpha) {
12608
12888
  this.ctx.globalAlpha = alpha;
@@ -13162,10 +13442,7 @@ class EditorContext {
13162
13442
  isDirty = false;
13163
13443
  cursorRect;
13164
13444
  _document;
13165
- //文档刷新的订阅事件
13166
- //refSub!: Subscription;
13167
13445
  syncRefresh;
13168
- //imageLoader: IImageLoader;
13169
13446
  dynamicFunc;
13170
13447
  docChange;
13171
13448
  clearPrevDocCb;
@@ -13219,6 +13496,7 @@ class EditorContext {
13219
13496
  //this.imageLoader.clear();
13220
13497
  this.dynamicFunc.destroyScripts();
13221
13498
  this.isDirty = false;
13499
+ //this.clearEleDepMaps();
13222
13500
  }
13223
13501
  get defaultCtx() {
13224
13502
  return new DocumentContext(this._document, this.selectionState);
@@ -13293,17 +13571,6 @@ class EditorContext {
13293
13571
  return this._document.modifyFlag === exports.ModifyFlag.None ? 'appearance' : 'content';
13294
13572
  }
13295
13573
  }
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
13574
  /**
13308
13575
  * 文档上下文
13309
13576
  */
@@ -13566,13 +13833,23 @@ class DocumentContext {
13566
13833
  }
13567
13834
  }
13568
13835
 
13569
- class DynamicContextParser {
13836
+ class DynamicExecute {
13570
13837
  doc;
13571
13838
  ss;
13839
+ current;
13840
+ depItems;
13572
13841
  constructor(doc, ss) {
13573
13842
  this.doc = doc;
13574
13843
  this.ss = ss;
13575
13844
  }
13845
+ setCurrentCtx(ele, depItems) {
13846
+ this.current = ele;
13847
+ this.depItems = depItems;
13848
+ }
13849
+ clearCurrentCtx() {
13850
+ this.current = undefined;
13851
+ this.depItems = undefined;
13852
+ }
13576
13853
  cacheList;
13577
13854
  getControlById(id) {
13578
13855
  if (!this.cacheList) {
@@ -13584,6 +13861,10 @@ class DynamicContextParser {
13584
13861
  //return this.cacheList.find(item => item['props']['id'] === id);
13585
13862
  }
13586
13863
  getObject(id) {
13864
+ //如果当前存在编译缓存,则直接从缓存中获取
13865
+ if (this.depItems && this.depItems.has(id)) {
13866
+ return this.depItems.get(id);
13867
+ }
13587
13868
  new DocumentContext(this.doc, this.ss);
13588
13869
  if (id.startsWith('$')) {
13589
13870
  id = id.slice(1);
@@ -13602,6 +13883,9 @@ class DynamicContextParser {
13602
13883
  if (control) {
13603
13884
  control.setValue(val);
13604
13885
  }
13886
+ },
13887
+ get ref() {
13888
+ return control;
13605
13889
  }
13606
13890
  };
13607
13891
  }
@@ -13673,9 +13957,12 @@ class DynamicContextParser {
13673
13957
  class ParagraphMeasure {
13674
13958
  options;
13675
13959
  renderCtx;
13676
- constructor(options, renderCtx) {
13960
+ execute;
13961
+ constructor(options, renderCtx, execute) {
13677
13962
  this.options = options;
13678
13963
  this.renderCtx = renderCtx;
13964
+ this.execute = execute;
13965
+ this.execute = execute;
13679
13966
  }
13680
13967
  /**
13681
13968
  * 段落排版:
@@ -13771,7 +14058,10 @@ class ParagraphMeasure {
13771
14058
  const paraRenders = [];
13772
14059
  for (let i = 0; i < paraModels.length; i++) {
13773
14060
  const innerLineRects = paraModels[i].innerLine;
13774
- let render = p.createRenderObject();
14061
+ let render = this.createRenderObject(p);
14062
+ if (!render) {
14063
+ return [];
14064
+ }
13775
14065
  render.setRenderWidth(limitWidth);
13776
14066
  paraRenders.push(render);
13777
14067
  for (let j = 0; j < innerLineRects.length; j++) {
@@ -13912,7 +14202,7 @@ class ParagraphMeasure {
13912
14202
  }
13913
14203
  arrangeInlineGroupElement(parentLine, ele) {
13914
14204
  const { options, renderCtx } = this;
13915
- let render = ele.createRenderObject({ options, renderCtx });
14205
+ let render = this.createRenderObject(ele);
13916
14206
  //记录多行情况下的渲染对象,用于计算总长度,生成fill-null-space
13917
14207
  const inlineGroupRenders = [];
13918
14208
  ele.cacheRender = render;
@@ -13966,10 +14256,7 @@ class ParagraphMeasure {
13966
14256
  const baseTextProps = ele.props;
13967
14257
  nullText.text = baseTextProps.nullText;
13968
14258
  baseTextProps.nullTextProps.clone(nullText.props);
13969
- const nullTextRender = nullText.createRenderObject({
13970
- options: this.options,
13971
- renderCtx: this.renderCtx
13972
- });
14259
+ const nullTextRender = this.createRenderObject(nullText);
13973
14260
  //inlineGroupRender.insertChild(nullTextRender, 1);
13974
14261
  this.arrangeLeafRender(data, nullTextRender);
13975
14262
  }
@@ -13998,7 +14285,7 @@ class ParagraphMeasure {
13998
14285
  }
13999
14286
  }
14000
14287
  arrangeLeafElement(parentLine, ele) {
14001
- ele.cacheRender = ele.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
14288
+ ele.cacheRender = this.createRenderObject(ele);
14002
14289
  if (ele.cacheRender) {
14003
14290
  this.arrangeLeafRender(parentLine, ele.cacheRender);
14004
14291
  }
@@ -14195,6 +14482,80 @@ class ParagraphMeasure {
14195
14482
  }
14196
14483
  throw new Error('未到达计算位置');
14197
14484
  }
14485
+ /**
14486
+ * 解析可见性表达式
14487
+ * @param ele
14488
+ * @param execute
14489
+ * @private
14490
+ */
14491
+ parseVisibleExpression(ele, execute) {
14492
+ if (ele.visibleExpr)
14493
+ return;
14494
+ if (!ele.attribute?.visibleExpr)
14495
+ return;
14496
+ const reactiveMode = this.renderCtx.drawMode !== 'print';
14497
+ try {
14498
+ const depIdItems = [];
14499
+ const depEleMap = new Map();
14500
+ let compliedCode = parser(ele.attribute?.visibleExpr, depIdItems);
14501
+ compliedCode = addReturn(compliedCode);
14502
+ if (depIdItems.length) {
14503
+ depIdItems.forEach(dep => {
14504
+ const refCtx = execute.getObject(dep);
14505
+ if (refCtx.ref) {
14506
+ const refEle = refCtx.ref.item;
14507
+ depEleMap.set(dep, refCtx);
14508
+ //当前有可能是checkbox数组
14509
+ const refEles = Array.isArray(refEle) ? refEle : [refEle];
14510
+ reactiveMode && refEles.forEach(item => {
14511
+ //求值依赖元素更改的时候,发布当前元素重新计算的指令
14512
+ item.onChangeSubject.subscribe(() => {
14513
+ ele.pubOnChange('self');
14514
+ });
14515
+ });
14516
+ }
14517
+ });
14518
+ }
14519
+ ele.visibleExpr = { compliedCode, func: new Function(`with(this){ ${compliedCode} }`), depItems: depEleMap };
14520
+ }
14521
+ catch (e) {
14522
+ console.error('解析表达式出错', ele.attribute?.visibleExpr);
14523
+ }
14524
+ }
14525
+ /**
14526
+ * 元素可见行求值
14527
+ * @param ele
14528
+ * @param executeCtx
14529
+ * @private
14530
+ */
14531
+ evalVisibleExpr(ele, executeCtx) {
14532
+ if (ele.visibleExpr && ele.visibleExpr.func) {
14533
+ try {
14534
+ executeCtx.setCurrentCtx(ele, ele.visibleExpr.depItems);
14535
+ const func = ele.visibleExpr.func.bind(executeCtx);
14536
+ return func() === true;
14537
+ }
14538
+ catch (e) {
14539
+ console.error(e, "表达式执行出错", ele.visibleExpr.compliedCode);
14540
+ }
14541
+ finally {
14542
+ executeCtx.clearCurrentCtx();
14543
+ }
14544
+ }
14545
+ return true;
14546
+ }
14547
+ createRenderObject(element) {
14548
+ if (this.options.enableVisibleExpression) {
14549
+ this.parseVisibleExpression(element, this.execute);
14550
+ if (!this.evalVisibleExpr(element, this.execute)) {
14551
+ return null;
14552
+ }
14553
+ }
14554
+ return element.createRenderObject({
14555
+ options: this.options,
14556
+ renderCtx: this.renderCtx
14557
+ });
14558
+ }
14198
14559
  }
14199
14560
 
14200
14561
  /**
@@ -14326,6 +14687,8 @@ class DocumentArrange {
14326
14687
  renderCtx;
14327
14688
  seo;
14328
14689
  options;
14690
+ execute;
14691
+ pMeasure;
14329
14692
  constructor(docCtx, renderCtx, seo) {
14330
14693
  this.docCtx = docCtx;
14331
14694
  this.renderCtx = renderCtx;
@@ -14345,10 +14708,12 @@ class DocumentArrange {
14345
14708
  //测量阶段,对于空段落会插入段落符号,新表格会插入空段落,此时不需要记录节点的更改,以最大的节点进行记录
14346
14709
  return suppressTracking(() => {
14347
14710
  const doc = this.docCtx.document;
14711
+ this.execute = new DynamicExecute(doc, this.docCtx.selectionState);
14712
+ this.pMeasure = new ParagraphMeasure(this.options, this.renderCtx, this.execute);
14348
14713
  const data = {
14349
14714
  doc,
14350
14715
  viewOptions: this.options,
14351
- parser: new DynamicContextParser(doc, this.docCtx.selectionState),
14716
+ execute: this.execute,
14352
14717
  createParaFn: () => this.createDefaultPara()
14353
14718
  };
14354
14719
  doc.clearMarkItems();
@@ -14464,15 +14829,6 @@ class DocumentArrange {
14464
14829
  cloneFooterRender.rect.x = limitRect.x;
14465
14830
  cloneFooterRender.rect.y = documentRender.rect.height - bodyMarginBottom;
14466
14831
  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
14832
  currColumn++;
14477
14833
  if (currColumn === docColumns) {
14478
14834
  currColumn = 0;
@@ -14483,7 +14839,7 @@ class DocumentArrange {
14483
14839
  return docPages;
14484
14840
  }
14485
14841
  createEmptyBodyRender(bodyRender, limitRect) {
14486
- const pageBodyRender = this.createRenderObject(bodyRender.element);
14842
+ const pageBodyRender = this.pMeasure.createRenderObject(bodyRender.element);
14487
14843
  pageBodyRender.rect.width = limitRect.width;
14488
14844
  const bodyInnerLimitRect = pageBodyRender.getInnerRect();
14489
14845
  if (this.options.fullPageView) {
@@ -14499,12 +14855,11 @@ class DocumentArrange {
14499
14855
  return element.cacheRender;
14500
14856
  }
14501
14857
  if (element instanceof BlockContentElement) {
14502
- const pRange = new ParagraphMeasure(this.options, this.renderCtx);
14503
- return pRange.measureParagraph(element, maxWidth);
14858
+ return this.pMeasure.measureParagraph(element, maxWidth);
14504
14859
  }
14505
14860
  else if (element instanceof BlockContainerElement) {
14506
14861
  const renders = [];
14507
- let render = this.createRenderObject(element);
14862
+ let render = this.pMeasure.createRenderObject(element);
14508
14863
  if (!render) {
14509
14864
  element.cacheRender = null;
14510
14865
  return null;
@@ -14517,8 +14872,8 @@ class DocumentArrange {
14517
14872
  const innerMaxWidth = render.getInnerMaxWidth();
14518
14873
  for (let i = 0; i < element.length; i++) {
14519
14874
  const child = element.getChild(i);
14520
- const blockContentELement = child;
14521
- const childRender = this.measureControl(blockContentELement, innerMaxWidth);
14875
+ const blockContentElement = child;
14876
+ const childRender = this.measureControl(blockContentElement, innerMaxWidth);
14522
14877
  if (!childRender) {
14523
14878
  continue;
14524
14879
  }
@@ -14528,7 +14883,7 @@ class DocumentArrange {
14528
14883
  }
14529
14884
  for (let j = 0; j < childRender.length; j++) {
14530
14885
  if (j > 0) {
14531
- render = this.createRenderObject(element);
14886
+ render = this.pMeasure.createRenderObject(element);
14532
14887
  if (!render.rect.width) {
14533
14888
  render.setRenderWidth(maxWidth);
14534
14889
  }
@@ -14556,12 +14911,6 @@ class DocumentArrange {
14556
14911
  textLineRenderMode(cacheRender, { options: this.options, renderCtx: this.renderCtx });
14557
14912
  }
14558
14913
  }
14559
- createRenderObject(element) {
14560
- return element.createRenderObject({
14561
- options: this.options,
14562
- renderCtx: this.renderCtx
14563
- });
14564
- }
14565
14914
  getDocInnerRect(documentRender) {
14566
14915
  const render = documentRender.element.createRenderObject();
14567
14916
  render.padding = documentRender.padding;
@@ -14580,7 +14929,7 @@ class DocumentArrange {
14580
14929
  if (render instanceof TableRenderObject) {
14581
14930
  return this.cutTable(render, limitHeight);
14582
14931
  }
14583
- const cloneRender = this.createRenderObject(render.element);
14932
+ const cloneRender = this.pMeasure.createRenderObject(render.element);
14584
14933
  cloneRender.setRenderWidth(render.rect.width);
14585
14934
  if (render instanceof MuiltBlockLineRenderObject) {
14586
14935
  let sumHeight = 0;
@@ -14757,7 +15106,7 @@ class DocumentArrange {
14757
15106
  for (let i = 0; i < cutCellRenders.length; i++) {
14758
15107
  let cellRender = cutCellRenders[i];
14759
15108
  if (!cellRender) {
14760
- cellRender = this.createRenderObject(cellRenders[i].element);
15109
+ cellRender = this.pMeasure.createRenderObject(cellRenders[i].element);
14761
15110
  cellRender.rect = ElementUtil.cloneRect(cellRenders[i].rect);
14762
15111
  cellRender.rect.height = 0;
14763
15112
  ElementUtil.remeasure(cellRender);
@@ -14873,647 +15222,18 @@ class DocumentArrange {
14873
15222
  return -1;
14874
15223
  }
14875
15224
  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
- }
15225
+ const rows = [];
15226
+ for (let i = 0; i < tb.length; i++) {
15227
+ const rowRender = tb.getChild(i);
15228
+ const rowEle = rowRender.element;
15229
+ if (rowEle.props.headerRow) {
15230
+ rows.push(rowRender);
15494
15231
  }
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
- }
15232
+ else {
15233
+ break;
15508
15234
  }
15509
- x += child.rect.width;
15510
- }
15511
- if (!cutRender.length) {
15512
- return { firstItem: null, lastItem: null };
15513
15235
  }
15514
- ElementUtil.remeasureInlineGroupRender(cutRender);
15515
- ElementUtil.remeasureInlineGroupRender(render);
15516
- return { firstItem: cutRender, lastItem: render.length ? render : null, br };
15236
+ return rows;
15517
15237
  }
15518
15238
  /**
15519
15239
  * 修改测量完毕后的元素状态
@@ -15526,29 +15246,105 @@ class ElementMeasure {
15526
15246
  }
15527
15247
  }
15528
15248
  ele.modifyFlag = exports.ModifyFlag.None;
15249
+ if (!ele.loaded) {
15250
+ ele.loaded = true;
15251
+ }
15529
15252
  }
15530
15253
  clearPaintCache(ele, data) {
15254
+ ele.paintRenders.length = 0;
15531
15255
  ele.beginMeasure(data);
15256
+ this.identifyComment(ele);
15532
15257
  if (ele instanceof BranchElement) {
15533
15258
  for (let i = 0; i < ele.length; i++) {
15534
15259
  this.clearPaintCache(ele.getChild(i), data);
15535
15260
  }
15536
15261
  }
15537
15262
  }
15263
+ identifyComment(ele) {
15264
+ if (ele instanceof CommentElement) {
15265
+ this.docCtx.document.identifyCommMark(ele);
15266
+ }
15267
+ }
15268
+ cacheDoc;
15269
+ cacheDocRenders(docs) {
15270
+ docs.forEach(doc => {
15271
+ this.cacheDoc = doc;
15272
+ this.cacheRenders(doc);
15273
+ });
15274
+ this.cacheDoc = null;
15275
+ }
15276
+ /**
15277
+ * 生成批注区间信息
15278
+ * @param renderTree
15279
+ */
15280
+ generateCommRange() {
15281
+ this.seo.commRangeSets.clear();
15282
+ const commMarks = this.docCtx.document.markPairs;
15283
+ for (let i = 0; i < commMarks.length; i++) {
15284
+ const commMark = commMarks[i];
15285
+ if (commMark.start && commMark.end) {
15286
+ const ancestor = DocumentSelection.getAncestorCommonControl(commMark.start, commMark.end);
15287
+ const range = RangeUtil.getSectionRange(commMark.start, 0, commMark.end, 1, ancestor);
15288
+ SelectionOverlays.addToCommentSets(range, this.seo.commRangeSets, commMark.start.color);
15289
+ }
15290
+ }
15291
+ }
15292
+ cacheRenders(renderTree) {
15293
+ if (renderTree.element) {
15294
+ renderTree.element.paintRenders.push(renderTree);
15295
+ }
15296
+ for (let i = 0; i < renderTree.length; i++) {
15297
+ const currRender = renderTree.getChild(i);
15298
+ if (currRender.element) {
15299
+ this.cacheCommsRender(currRender);
15300
+ }
15301
+ if (currRender instanceof BranchRenderObject) {
15302
+ this.cacheRenders(currRender);
15303
+ }
15304
+ else {
15305
+ currRender.element && currRender.element.paintRenders.push(currRender);
15306
+ }
15307
+ }
15308
+ }
15309
+ /**
15310
+ * 缓存批注标志
15311
+ * @private
15312
+ */
15313
+ cacheCommsRender(render) {
15314
+ if (render.element && render.element.type === 'comm') {
15315
+ const commElement = render.element;
15316
+ if (commElement.props.markType === 'start') {
15317
+ const currDocRender = this.cacheDoc;
15318
+ const docCommContainer = currDocRender.getItems().find(item => item instanceof CommsContainerRenderObject);
15319
+ if (docCommContainer) {
15320
+ docCommContainer.commsMarks.push(render);
15321
+ }
15322
+ }
15323
+ }
15324
+ if (render.element && render.element.type === 'comm-list') {
15325
+ const commContainer = render;
15326
+ CommentsUtil.createCommentsImage(commContainer);
15327
+ }
15328
+ }
15538
15329
  endMeasures(ele) {
15330
+ ele.endMeasure();
15539
15331
  if (ele instanceof BranchElement) {
15540
15332
  for (let i = 0; i < ele.length; i++) {
15541
15333
  this.endMeasures(ele.getChild(i));
15542
15334
  }
15543
15335
  }
15544
15336
  }
15337
+ createDefaultPara() {
15338
+ const tmp = new ParagraphElement();
15339
+ tmp.props.lineHeight = this.options.defaultLineHeight;
15340
+ return tmp;
15341
+ }
15545
15342
  }
15546
15343
 
15547
15344
  class DocumentPaint {
15548
15345
  renderContext;
15549
15346
  docCtx;
15550
15347
  seo;
15551
- elementMeasure;
15552
15348
  //elementRenderCut: ElementRenderCut;
15553
15349
  elementPaint;
15554
15350
  docPages;
@@ -15560,7 +15356,6 @@ class DocumentPaint {
15560
15356
  this.docCtx = docCtx;
15561
15357
  this.seo = seo;
15562
15358
  this.viewOptions = this.docCtx.viewOptions;
15563
- this.elementMeasure = new ElementMeasure(this.docCtx, this.renderContext);
15564
15359
  //this.elementRenderCut = new ElementRenderCut(this.viewOptions, this.renderContext);
15565
15360
  this.elementPaint = new ElementPaint(this.renderContext, this.docCtx);
15566
15361
  }
@@ -15720,130 +15515,6 @@ class DocumentPaint {
15720
15515
  }
15721
15516
  }
15722
15517
 
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
15518
  class ElementReader {
15848
15519
  docCtx;
15849
15520
  constructor(docCtx) {
@@ -15907,29 +15578,18 @@ class ElementReader {
15907
15578
  this.setDocument(document);
15908
15579
  }
15909
15580
  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
15581
  document.bodyElement = document.find((item) => item instanceof DocumentBodyElement);
15916
15582
  document.headerElement = document.find((item) => item instanceof DocumentHeaderElement);
15917
15583
  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
15584
  document.clearItems();
15923
15585
  document.addChild(document.headerElement);
15924
15586
  document.addChild(document.bodyElement);
15925
15587
  document.addChild(document.footerElement);
15926
- //document.addChild(document.commentsContainerElement);
15927
15588
  this.docCtx.document = document;
15928
15589
  document.viewOptions = this.docCtx.viewOptions;
15929
15590
  const width = Math.floor(document.props.width * this.docCtx.viewOptions.mmToPixelsRatio);
15930
15591
  const height = Math.floor(document.props.height * this.docCtx.viewOptions.mmToPixelsRatio);
15931
15592
  this.docCtx.viewOptions.docPageSettings = new PageOptions(width, height, document.props.orient);
15932
- //this.viewOptions.viewSettings.width = this.viewOptions.docPageSettings.width + 10;
15933
15593
  }
15934
15594
  readElement(data, strictMode = false) {
15935
15595
  if (typeof data === 'string') {
@@ -15951,6 +15611,7 @@ class ElementReader {
15951
15611
  }
15952
15612
  }
15953
15613
  factory.readCompleted(element, childArr);
15614
+ this.readAttribute(data, element);
15954
15615
  return element;
15955
15616
  }
15956
15617
  }
@@ -15962,6 +15623,11 @@ class ElementReader {
15962
15623
  return null;
15963
15624
  }
15964
15625
  }
15626
+ readAttribute(data, ele) {
15627
+ if (data.attribute) {
15628
+ ele.attribute = data.attribute;
15629
+ }
15630
+ }
15965
15631
  /**
15966
15632
  * 读取扩展属性
15967
15633
  * @param data
@@ -17215,7 +16881,6 @@ class DocumentEvent {
17215
16881
  startHitInfo: this.startHitInfo,
17216
16882
  endHitInfo: this.endHitInfo
17217
16883
  });
17218
- console.log(this.endHitInfo);
17219
16884
  }
17220
16885
  /**
17221
16886
  * 获取鼠标所在的渲染元素对象
@@ -20185,7 +19850,8 @@ class ElementTrackManage {
20185
19850
  * @private
20186
19851
  */
20187
19852
  mergeOps(ops) {
20188
- return false;
19853
+ return this.mergeFormatOps(ops);
19854
+ //return false;
20189
19855
  //问题在于:
20190
19856
  //1.新输入的字符串,selectState的startOffset、endOffset=1,后输入的字符串的endOffset进行累加
20191
19857
  //2.撤销后重做,选区范围在1-2,英国是0-2,因为之前在创建文本对象后,选区的结束位为1
@@ -20236,6 +19902,41 @@ class ElementTrackManage {
20236
19902
  // }
20237
19903
  // return false;
20238
19904
  }
19905
+ /**
19906
+ * 将对某个元素的最近两次的属性修改合并为一次,ops为当前记录的修改,比较上次的修改,如果为对同一个元素的修改,则合并
19907
+ * @private
19908
+ */
19909
+ mergeFormatOps(ops) {
19910
+ if (ops.length > 1) {
19911
+ return false;
19912
+ }
19913
+ const lastOps = this.actions[this.actions.length - 1];
19914
+ if (!lastOps || lastOps.ops.length > 1) {
19915
+ return false;
19916
+ }
19917
+ const prevOp = lastOps.ops[lastOps.ops.length - 1];
19918
+ const currOp = ops[0];
19919
+ //操作类型相同
19920
+ if ('format' in currOp.ops && 'format' in prevOp.ops && currOp.index === prevOp.index) {
19921
+ // const prevAfterSelection = lastOps.afterSelection;
19922
+ // if (!prevAfterSelection) {
19923
+ // return false;
19924
+ // }
19925
+ //前后是连续的操作
19926
+ const { format: currFormat } = currOp.ops;
19927
+ const { format: prevFormat } = prevOp.ops;
19928
+ Object.keys(currFormat).forEach(key => {
19929
+ const currValue = currFormat[key].newValue;
19930
+ const prevValue = prevFormat[key].newValue;
19931
+ if (CommonUtil.isEqual(currValue, prevValue)) {
19932
+ return;
19933
+ }
19934
+ prevFormat[key].newValue = currValue;
19935
+ });
19936
+ return true;
19937
+ }
19938
+ return false;
19939
+ }
20239
19940
  getSelection() {
20240
19941
  const { startControl, startOffset, endControl, endOffset, editable } = this.docCtx.selectionState;
20241
19942
  if (!startControl) {
@@ -28148,7 +27849,7 @@ class DocEditor {
28148
27849
  rule.setRuleOptions({ width: this.viewOptions.docPageSettings.width, pagePL, pagePR, docLeft });
28149
27850
  }
28150
27851
  version() {
28151
- return "2.1.20";
27852
+ return "2.1.22";
28152
27853
  }
28153
27854
  switchPageHeaderEditor() {
28154
27855
  this.docCtx.document.switchPageHeaderEditor(this.selectionState, null);
@@ -28201,6 +27902,26 @@ class DocumentCombine {
28201
27902
  }
28202
27903
  }
28203
27904
 
27905
+ /**
27906
+ * 文字行渲染模式
27907
+ 用于医嘱打印模式
27908
+ */
27909
+ function runTextLineRender(ele, data) {
27910
+ if (!data.options.textRowLineMode) {
27911
+ return;
27912
+ }
27913
+ if (ele instanceof TableElement) {
27914
+ // textLineRenderMode(ele, data);
27915
+ // remeasureParentRenders(ele.cacheRender)
27916
+ return;
27917
+ }
27918
+ if (ele instanceof BranchElement) {
27919
+ for (let i = 0; i < ele.length; i++) {
27920
+ runTextLineRender(ele.getChild(i), data);
27921
+ }
27922
+ }
27923
+ }
27924
+
28204
27925
  /**
28205
27926
  * 删除当前段落
28206
27927
  * @param evt
@@ -28489,6 +28210,10 @@ exports.ParagraphLineRectRenderObject = ParagraphLineRectRenderObject;
28489
28210
  exports.ParagraphProps = ParagraphProps;
28490
28211
  exports.ParagraphRenderObject = ParagraphRenderObject;
28491
28212
  exports.PasteElementEvent = PasteElementEvent;
28213
+ exports.PermanentTeethElement = PermanentTeethElement;
28214
+ exports.PermanentTeethFactory = PermanentTeethFactory;
28215
+ exports.PermanentTeethProps = PermanentTeethProps;
28216
+ exports.PermanentTeethRenderObject = PermanentTeethRenderObject;
28492
28217
  exports.PictureElement = PictureElement;
28493
28218
  exports.PictureFactory = PictureFactory;
28494
28219
  exports.PictureProps = PictureProps;
@@ -28542,8 +28267,11 @@ exports.ValidateElement = ValidateElement;
28542
28267
  exports.ValidateProps = ValidateProps;
28543
28268
  exports.ValidateRenderObject = ValidateRenderObject;
28544
28269
  exports.ViewOptions = ViewOptions;
28270
+ exports.addReturn = addReturn;
28545
28271
  exports.clearChildrenRenderCache = clearChildrenRenderCache;
28546
28272
  exports.clearTraces = clearTraces;
28273
+ exports.cloneChildren = cloneChildren;
28274
+ exports.cloneElementBase = cloneElementBase;
28547
28275
  exports.createPrintTemplate = createPrintTemplate;
28548
28276
  exports.defaultParaHanging = defaultParaHanging;
28549
28277
  exports.deleteCurrentParagraph = deleteCurrentParagraph;