@hailin-zheng/editor-core 2.1.19 → 2.1.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/index-cjs.js +752 -1842
  2. package/index-cjs.js.map +1 -1
  3. package/index.js +742 -1843
  4. package/index.js.map +1 -1
  5. package/med_editor/framework/ast-parser.d.ts +2 -1
  6. package/med_editor/framework/common-util.d.ts +2 -0
  7. package/med_editor/framework/document-arrange.d.ts +4 -1
  8. package/med_editor/framework/document-paint.d.ts +0 -4
  9. package/med_editor/framework/{dynamic-executer.d.ts → dynamic-execute.d.ts} +6 -7
  10. package/med_editor/framework/element-define.d.ts +36 -2
  11. package/med_editor/framework/element-props.d.ts +8 -0
  12. package/med_editor/framework/element-reader.d.ts +1 -0
  13. package/med_editor/framework/element-serialize.d.ts +1 -0
  14. package/med_editor/framework/element-trace-manage.d.ts +5 -0
  15. package/med_editor/framework/element-util.d.ts +3 -0
  16. package/med_editor/framework/impl/checkbox/checkbox-impl.d.ts +2 -3
  17. package/med_editor/framework/impl/comments/comment-content-impl.d.ts +1 -2
  18. package/med_editor/framework/impl/comments/comment-element-impl.d.ts +1 -2
  19. package/med_editor/framework/impl/comments/comments-container-impl.d.ts +2 -6
  20. package/med_editor/framework/impl/comments/validate-msg-impl.d.ts +1 -2
  21. package/med_editor/framework/impl/data-element/data-decorate-impl.d.ts +1 -2
  22. package/med_editor/framework/impl/data-element/data-element-barcode.d.ts +2 -5
  23. package/med_editor/framework/impl/data-element/data-element-base-impl.d.ts +0 -1
  24. package/med_editor/framework/impl/data-element/data-element-check-impl.d.ts +1 -2
  25. package/med_editor/framework/impl/data-element/data-element-group-impl.d.ts +1 -2
  26. package/med_editor/framework/impl/data-element/data-element-image-impl.d.ts +2 -5
  27. package/med_editor/framework/impl/decorate/fill-null-space-imple.d.ts +1 -2
  28. package/med_editor/framework/impl/document/doc-body-impl.d.ts +1 -2
  29. package/med_editor/framework/impl/document/doc-body-part-impl.d.ts +1 -2
  30. package/med_editor/framework/impl/document/doc-container-impl.d.ts +1 -2
  31. package/med_editor/framework/impl/document/doc-footer-impl.d.ts +1 -2
  32. package/med_editor/framework/impl/document/doc-header-impl.d.ts +1 -2
  33. package/med_editor/framework/impl/document/doc-impl.d.ts +1 -2
  34. package/med_editor/framework/impl/index.d.ts +2 -0
  35. package/med_editor/framework/impl/media-formula/menstrual-history.d.ts +1 -2
  36. package/med_editor/framework/impl/media-formula/permanent-teeth.d.ts +6 -4
  37. package/med_editor/framework/impl/paragraph/p-impl.d.ts +0 -2
  38. package/med_editor/framework/impl/picture/RectEle.d.ts +1 -6
  39. package/med_editor/framework/impl/picture/image-impl.d.ts +2 -5
  40. package/med_editor/framework/impl/radio/radio-impl.d.ts +1 -2
  41. package/med_editor/framework/impl/svg/svg-impl.d.ts +20 -0
  42. package/med_editor/framework/impl/symbol/br-symbol-impl.d.ts +1 -2
  43. package/med_editor/framework/impl/symbol/p-symbol-impl.d.ts +1 -2
  44. package/med_editor/framework/impl/symbol/page-br-symbol-impl.d.ts +1 -2
  45. package/med_editor/framework/impl/symbol/tab-symbol-impl.d.ts +1 -2
  46. package/med_editor/framework/impl/table/table-cell-impl.d.ts +1 -2
  47. package/med_editor/framework/impl/table/table-impl.d.ts +1 -2
  48. package/med_editor/framework/impl/table/table-row-impl.d.ts +1 -2
  49. package/med_editor/framework/impl/text/text-impl.d.ts +1 -2
  50. package/med_editor/framework/impl/text/track-run-impl.d.ts +1 -2
  51. package/med_editor/framework/paragraph-arrange.d.ts +18 -1
  52. package/med_editor/framework/render-define.d.ts +0 -2
  53. package/package.json +1 -1
  54. package/med_editor/framework/element-measure.d.ts +0 -94
  55. package/med_editor/framework/element-render-cut.d.ts +0 -59
package/index.js CHANGED
@@ -246,8 +246,6 @@ class RenderObject {
246
246
  this.margin = new MarginProps();
247
247
  this.padding = new PaddingProps();
248
248
  }
249
- pagePaintCompleted(e) {
250
- }
251
249
  destroy() {
252
250
  //this.parent = null;
253
251
  //this.margin = null;
@@ -631,10 +629,61 @@ class CommonUtil {
631
629
  return reg.test(str);
632
630
  }
633
631
  static cloneValue(val) {
634
- if (typeof val === 'object' && val) {
635
- return JSON.parse(JSON.stringify(val));
632
+ return CommonUtil.cloneDeep(val);
633
+ }
634
+ // @ts-ignore
635
+ static cloneDeep(source, visited = new WeakMap()) {
636
+ if (source === null || typeof source !== 'object') {
637
+ // 如果是基本类型或 null,则直接返回
638
+ return source;
639
+ }
640
+ // 处理循环引用
641
+ if (visited.has(source)) {
642
+ return visited.get(source);
643
+ }
644
+ if (Array.isArray(source)) {
645
+ // 如果是数组,则递归复制数组元素
646
+ const arrayClone = [];
647
+ visited.set(source, arrayClone);
648
+ source.forEach((item, index) => {
649
+ arrayClone[index] = CommonUtil.cloneDeep(item, visited);
650
+ });
651
+ return arrayClone;
652
+ }
653
+ if (source instanceof Date) {
654
+ // 如果是 Date 对象,则直接创建一个新的 Date 对象
655
+ return new Date(source.getTime());
656
+ }
657
+ if (source instanceof Map) {
658
+ // 如果是 Map 对象,则递归复制键值对
659
+ const mapClone = new Map();
660
+ visited.set(source, mapClone);
661
+ source.forEach((value, key) => {
662
+ mapClone.set(CommonUtil.cloneDeep(key, visited), CommonUtil.cloneDeep(value, visited));
663
+ });
664
+ return mapClone;
665
+ }
666
+ if (source instanceof Set) {
667
+ // 如果是 Set 对象,则递归复制元素
668
+ const setClone = new Set();
669
+ visited.set(source, setClone);
670
+ source.forEach(value => {
671
+ setClone.add(CommonUtil.cloneDeep(value, visited));
672
+ });
673
+ return setClone;
636
674
  }
637
- return val;
675
+ if (Object.prototype.toString.call(source) === '[object Object]') {
676
+ // 如果是普通对象,则递归复制对象属性
677
+ const objectClone = {};
678
+ visited.set(source, objectClone);
679
+ for (const key in source) {
680
+ if (source.hasOwnProperty(key)) {
681
+ objectClone[key] = CommonUtil.cloneDeep(source[key], visited);
682
+ }
683
+ }
684
+ return objectClone;
685
+ }
686
+ return source;
638
687
  }
639
688
  static isConstructor(f) {
640
689
  try {
@@ -714,6 +763,9 @@ class CommonUtil {
714
763
  return btoa(unescape(encodeURIComponent(str)));
715
764
  //return btoa(str.replace(/[\u00A0-\u2666]/g, c => `&#${c.charCodeAt(0)};`));
716
765
  }
766
+ static isEqual(a, b) {
767
+ return JSON.stringify(a) === JSON.stringify(b);
768
+ }
717
769
  }
718
770
 
719
771
  const docOpsMap = new Map();
@@ -1185,6 +1237,8 @@ class Element {
1185
1237
  disposed;
1186
1238
  //加载完毕
1187
1239
  loaded;
1240
+ visibleExpr;
1241
+ attribute;
1188
1242
  _parent;
1189
1243
  get parent() {
1190
1244
  return this._parent;
@@ -1257,7 +1311,6 @@ class Element {
1257
1311
  listeners.forEach(item => item(evt));
1258
1312
  }
1259
1313
  beginMeasure(data) {
1260
- this.paintRenders.length = 0;
1261
1314
  }
1262
1315
  endMeasure() {
1263
1316
  }
@@ -1673,6 +1726,7 @@ class ViewOptions {
1673
1726
  printHeaderFooterLine = false;
1674
1727
  //显示段落回车符号
1675
1728
  showEnterSymbol = false;
1729
+ enableVisibleExpression = false;
1676
1730
  get fullPageView() {
1677
1731
  return this._fullPageView;
1678
1732
  }
@@ -1786,6 +1840,30 @@ class BorderProps {
1786
1840
  return new BorderProps(this.width, this.color, this.style);
1787
1841
  }
1788
1842
  }
1843
+ /**
1844
+ * 克隆元素的基本属性
1845
+ * @param ele
1846
+ * @param target
1847
+ */
1848
+ function cloneElementBase(ele, target) {
1849
+ target.attribute = ele.attribute ? CommonUtil.cloneValue(ele.attribute) : undefined;
1850
+ }
1851
+ /**
1852
+ * 克隆元素的子元素
1853
+ * @param ele
1854
+ * @param target
1855
+ * @param data
1856
+ */
1857
+ function cloneChildren(ele, target, data) {
1858
+ if (!data) {
1859
+ return;
1860
+ }
1861
+ for (let i = 0; i < ele.length; i++) {
1862
+ const child = ele.getChild(i);
1863
+ const cloneChild = child.clone(true);
1864
+ target.addChild(cloneChild);
1865
+ }
1866
+ }
1789
1867
  class IDispose {
1790
1868
  }
1791
1869
  class ResizeLeafRenderObject extends LeafRenderObject {
@@ -2223,6 +2301,32 @@ class PictureProps extends INotifyPropertyChanged {
2223
2301
  return props;
2224
2302
  }
2225
2303
  }
2304
+ class SVGProps extends INotifyPropertyChanged {
2305
+ title;
2306
+ width = 5;
2307
+ height = 5;
2308
+ value;
2309
+ clone(dest) {
2310
+ const clone = dest ?? new SVGProps();
2311
+ super.cloneAttachedProperty(clone);
2312
+ clone.width = this.width;
2313
+ clone.height = this.height;
2314
+ clone.value = this.value;
2315
+ clone.title = this.title;
2316
+ return clone;
2317
+ }
2318
+ getSerializeProps(viewOptions) {
2319
+ const props = {
2320
+ width: this.width,
2321
+ height: this.height,
2322
+ value: this.value,
2323
+ };
2324
+ if (this.title) {
2325
+ props['title'] = this.title;
2326
+ }
2327
+ return props;
2328
+ }
2329
+ }
2226
2330
  class DataDecorateProps extends INotifyPropertyChanged {
2227
2331
  content;
2228
2332
  size;
@@ -2766,26 +2870,15 @@ class CommsContainerElement extends BlockContainerElement {
2766
2870
  }
2767
2871
  clone(data) {
2768
2872
  const clone = new CommsContainerElement();
2769
- if (data) {
2770
- for (let i = 0; i < this.length; i++) {
2771
- clone.addChild(this.getChild(i).clone(true));
2772
- }
2773
- }
2873
+ cloneElementBase(this, clone);
2874
+ cloneChildren(this, clone, data);
2774
2875
  return clone;
2775
2876
  }
2776
2877
  }
2777
2878
  class CommsContainerRenderObject extends BlockContainerRenderObject {
2778
2879
  //批注内容是否已经重组,只要重新绘制的时候组合一次即可
2779
2880
  isMeasureComm;
2780
- selectedSet;
2781
- commentRangeStatus = [];
2782
2881
  commsMarks = [];
2783
- render(e) {
2784
- if (this.rect.height === 0) {
2785
- return;
2786
- }
2787
- e.render.contentContext.strokeRect(e.position.x, e.position.y, this.rect.width, this.rect.height, 'black', 0.5);
2788
- }
2789
2882
  clone() {
2790
2883
  const clone = new CommsContainerRenderObject(this.element);
2791
2884
  clone.rect = ElementUtil.cloneRect(this.rect);
@@ -2861,14 +2954,11 @@ class DataDecorateElement extends LeafElement {
2861
2954
  clone() {
2862
2955
  const clone = new DataDecorateElement(this.dataEle, this.isPrefix);
2863
2956
  this.props.clone(clone.props);
2864
- //clone.renderCtx = this.renderCtx;
2957
+ cloneElementBase(this, clone);
2865
2958
  return clone;
2866
2959
  }
2867
2960
  }
2868
2961
  class DataDecorateRenderObject extends LeafRenderObject {
2869
- render(e) {
2870
- this.renderDecorRect(e.render, e.position);
2871
- }
2872
2962
  renderDecorRect(ctx, position) {
2873
2963
  if (ctx.drawMode === 'print') {
2874
2964
  return;
@@ -2939,7 +3029,7 @@ class DataDecorateRenderObject extends LeafRenderObject {
2939
3029
  }
2940
3030
  }
2941
3031
 
2942
- function parser(code) {
3032
+ function parser(code, objects) {
2943
3033
  const node = acor.parse(code, { ecmaVersion: 'latest' });
2944
3034
  estraverse.traverse(node, {
2945
3035
  enter: (child, parent) => {
@@ -2947,6 +3037,7 @@ function parser(code) {
2947
3037
  const identifierName = child['name'];
2948
3038
  if (identifierName.startsWith('$')) {
2949
3039
  child['name'] = `getObject('${identifierName.slice(1)}').value`;
3040
+ objects?.push(identifierName.slice(1));
2950
3041
  }
2951
3042
  }
2952
3043
  }
@@ -2973,6 +3064,28 @@ function parser(code) {
2973
3064
  });
2974
3065
  return generate(node);
2975
3066
  }
3067
+ //判断代码的语句,如果最后一个语句不是return,那么加上return
3068
+ function addReturn(code) {
3069
+ const node = acor.parse(code, { ecmaVersion: 'latest' });
3070
+ estraverse.replace(node, {
3071
+ leave: (child) => {
3072
+ //函数调用
3073
+ if (child.type == 'Program') {
3074
+ const body = child['body'];
3075
+ const lastNode = body[body.length - 1];
3076
+ if (lastNode.type !== 'ReturnStatement') {
3077
+ body[body.length - 1] = {
3078
+ type: 'ReturnStatement',
3079
+ start: -1, end: -1,
3080
+ argument: lastNode
3081
+ };
3082
+ }
3083
+ return child;
3084
+ }
3085
+ }
3086
+ });
3087
+ return generate(node);
3088
+ }
2976
3089
  /**
2977
3090
  * 将参数转为函数调用arg => ()=>arg
2978
3091
  * @param nodes
@@ -3066,11 +3179,8 @@ class ParagraphElement extends BlockContentElement {
3066
3179
  clone(data) {
3067
3180
  const clone = new ParagraphElement();
3068
3181
  this.props.clone(clone.props);
3069
- if (data) {
3070
- for (let i = 0; i < this.length; i++) {
3071
- clone.addChild(this.getChild(i).clone(true));
3072
- }
3073
- }
3182
+ cloneElementBase(this, clone);
3183
+ cloneChildren(this, clone, data);
3074
3184
  return clone;
3075
3185
  }
3076
3186
  static createElement() {
@@ -3078,10 +3188,6 @@ class ParagraphElement extends BlockContentElement {
3078
3188
  }
3079
3189
  }
3080
3190
  class ParagraphRenderObject extends MuiltBlockLineRenderObject {
3081
- render(e) {
3082
- e.nextRender();
3083
- this.drawProjectNumber(e.render, e.docCtx.viewOptions, e);
3084
- }
3085
3191
  /**
3086
3192
  * 绘制项目符号
3087
3193
  */
@@ -3159,8 +3265,6 @@ class ParagraphLineRectRenderObject extends BlockLineRectRenderObject {
3159
3265
  baseTopLine = 0;
3160
3266
  baseBottomLine = 0;
3161
3267
  startX = 0;
3162
- render(e) {
3163
- }
3164
3268
  clone() {
3165
3269
  const cloneRender = new ParagraphLineRectRenderObject(this.element);
3166
3270
  cloneRender.rect = ElementUtil.cloneRect(this.rect);
@@ -3272,9 +3376,8 @@ class DocumentElement extends BlockContainerElement {
3272
3376
  clone() {
3273
3377
  const clone = new DocumentElement();
3274
3378
  this.props.clone(clone.props);
3275
- for (let i = 0; i < this.length; i++) {
3276
- clone.addChild(this.getChild(i).clone(true));
3277
- }
3379
+ cloneElementBase(this, clone);
3380
+ cloneChildren(this, clone, true);
3278
3381
  return clone;
3279
3382
  }
3280
3383
  /**
@@ -3362,21 +3465,6 @@ class DocumentRenderObject extends BlockContainerRenderObject {
3362
3465
  }
3363
3466
  headerLine;
3364
3467
  footerLine;
3365
- render(e) {
3366
- const { render, position, docCtx: { viewOptions } } = e;
3367
- const { width: docWidth, height: docHeight } = viewOptions.docPageSettings;
3368
- render.overlaysContext.fillRect(position.x, position.y, docWidth, this.rect.height, 'white', 5, 'black');
3369
- e.render.tran(() => {
3370
- e.render.contentContext.ctx.fillStyle = e.docCtx.viewOptions.defaultColor;
3371
- this.checkPrintMode(e);
3372
- e.nextRender();
3373
- this.drawCopyRight(viewOptions, render, position);
3374
- this.drawDocPageNum(render, viewOptions, position);
3375
- //绘制文档边距线
3376
- this.drawMarginLine(position, render, docWidth, docHeight);
3377
- this.drawWatermark(render, viewOptions, position);
3378
- });
3379
- }
3380
3468
  /**
3381
3469
  * 打印模式检查
3382
3470
  * 如果是续打模式,需要进行裁剪打印范围,页眉页脚都不需要打印
@@ -3666,6 +3754,7 @@ class InlineGroupInputElement extends InlineGroupElement {
3666
3754
  }
3667
3755
  cloneSelf(data, constr) {
3668
3756
  const clone = new constr();
3757
+ cloneElementBase(this, clone);
3669
3758
  this.props['clone'](clone.props);
3670
3759
  //cloneFunc.apply(this, clone.props);
3671
3760
  if (data) {
@@ -3788,7 +3877,7 @@ class DataElementInlineGroup extends InlineGroupInputElement {
3788
3877
  const code = parser(this.props.expression);
3789
3878
  this.expressFn = new Function(`with(this){ ${code} }`);
3790
3879
  }
3791
- this.expressFn.bind(data.parser)();
3880
+ this.expressFn.bind(data.execute)();
3792
3881
  //this.expressFn();
3793
3882
  }
3794
3883
  catch (e) {
@@ -3812,45 +3901,6 @@ function getCurrOptions(ele) {
3812
3901
  return doc?.viewOptions;
3813
3902
  }
3814
3903
  class DataElementRenderObject extends InlineGroupRenderObject {
3815
- render(e) {
3816
- const { render, position, docCtx: { viewOptions } } = e;
3817
- this.paintPos = e.position;
3818
- //数据元不打印
3819
- if (!this.element.props.printable && render.drawMode === 'print') {
3820
- return;
3821
- }
3822
- render.contentContext.tran(() => {
3823
- //绘制数据元区域底色
3824
- let bgColor = '';
3825
- if (this.element.isMouseenter) {
3826
- bgColor = this.element.props.editable ? viewOptions.dataEleOverlaysColor : viewOptions.dataEleReadOnlyOverlayColor;
3827
- }
3828
- if (this.element.isFocused) {
3829
- bgColor = e.docCtx.viewOptions.dataEleFocusedBgColor;
3830
- }
3831
- if (this.element.errorTip) {
3832
- bgColor = viewOptions.dataEleErrorBgColor;
3833
- }
3834
- if (bgColor) {
3835
- render.contentContext.fillRect(position.x, position.y, this.rect.width, this.rect.height, bgColor);
3836
- }
3837
- if (this.element.props.secretBrowse && viewOptions.secretBrowse) {
3838
- render.contentContext.ctx.filter = "blur(10px)";
3839
- }
3840
- if (this.element.props.underline) {
3841
- const y = position.y + 2 + this.rect.height;
3842
- render.contentContext.strokeLines([{ x: position.x, y }, {
3843
- x: position.x + this.rect.width,
3844
- y
3845
- }], 1, '#595959');
3846
- }
3847
- e.nextRender();
3848
- this.drawCaption(e);
3849
- });
3850
- e.render.onRenderCompleted.subscribe(() => {
3851
- drawDecorator(e, this);
3852
- });
3853
- }
3854
3904
  exportHTML(event) {
3855
3905
  const node = super.exportHTML(event);
3856
3906
  exportDecoratorHTML(event, this);
@@ -4121,11 +4171,8 @@ class DocumentBodyElement extends BlockContainerElement {
4121
4171
  }
4122
4172
  clone(data) {
4123
4173
  const clone = new DocumentBodyElement();
4124
- if (data) {
4125
- for (let i = 0; i < this.length; i++) {
4126
- clone.addChild(this.getChild(i).clone(true));
4127
- }
4128
- }
4174
+ cloneElementBase(this, clone);
4175
+ cloneChildren(this, clone, data);
4129
4176
  return clone;
4130
4177
  }
4131
4178
  beginMeasure(data) {
@@ -4136,15 +4183,6 @@ class DocumentBodyElement extends BlockContainerElement {
4136
4183
  }
4137
4184
  }
4138
4185
  class DocumentBodyRenderObject extends MuiltBlockLineRenderObject {
4139
- render(e) {
4140
- const { render, position } = e;
4141
- render.tran(() => {
4142
- if (this.element.disableClick && render.drawMode === 'view') {
4143
- render.contentContext.setGlobalAlpha(0.5);
4144
- }
4145
- e.nextRender();
4146
- });
4147
- }
4148
4186
  clone(cloneData = true) {
4149
4187
  const cloneRender = new DocumentBodyRenderObject(this.element);
4150
4188
  cloneRender.rect = ElementUtil.cloneRect(this.rect);
@@ -4184,11 +4222,8 @@ class DocumentFooterElement extends BlockContainerElement {
4184
4222
  }
4185
4223
  clone(data) {
4186
4224
  const clone = new DocumentFooterElement();
4187
- if (data) {
4188
- for (let i = 0; i < this.length; i++) {
4189
- clone.addChild(this.getChild(i).clone(true));
4190
- }
4191
- }
4225
+ cloneElementBase(this, clone);
4226
+ cloneChildren(this, clone, data);
4192
4227
  return clone;
4193
4228
  }
4194
4229
  beginMeasure(data) {
@@ -4214,22 +4249,6 @@ class DocumentFooterElement extends BlockContainerElement {
4214
4249
  }
4215
4250
  }
4216
4251
  class DocumentFooterRenderObject extends BlockContainerRenderObject {
4217
- render(e) {
4218
- const { render, position } = e;
4219
- render.tran(() => {
4220
- //判断页眉是否为输入内容
4221
- const isFooterEmpty = ElementUtil.checkEmptyRenderContent(this);
4222
- if (this.element.disableClick && render.drawMode === 'view') {
4223
- if (isFooterEmpty) {
4224
- render.contentContext.setGlobalAlpha(0);
4225
- }
4226
- else {
4227
- render.contentContext.setGlobalAlpha(0.5);
4228
- }
4229
- }
4230
- e.nextRender();
4231
- });
4232
- }
4233
4252
  clone() {
4234
4253
  const cloneRender = new DocumentFooterRenderObject(this.element);
4235
4254
  cloneRender.rect = ElementUtil.cloneRect(this.rect);
@@ -4280,11 +4299,8 @@ class DocumentHeaderElement extends BlockContainerElement {
4280
4299
  }
4281
4300
  clone(data) {
4282
4301
  const clone = new DocumentHeaderElement();
4283
- if (data) {
4284
- for (let i = 0; i < this.length; i++) {
4285
- clone.addChild(this.getChild(i).clone(true));
4286
- }
4287
- }
4302
+ cloneElementBase(this, clone);
4303
+ cloneChildren(this, clone, data);
4288
4304
  return clone;
4289
4305
  }
4290
4306
  switchEditMode(evt) {
@@ -4310,27 +4326,6 @@ class DocumentHeaderElement extends BlockContainerElement {
4310
4326
  }
4311
4327
  }
4312
4328
  class DocumentHeaderRenderObject extends BlockContainerRenderObject {
4313
- render(e) {
4314
- const { render, position } = e;
4315
- render.tran(() => {
4316
- //判断页眉是否为输入内容
4317
- const isHeaderEmpty = ElementUtil.checkEmptyRenderContent(this);
4318
- //存在输入内容时,绘制页眉-页体分割线
4319
- if (!isHeaderEmpty || !this.element.disableClick) {
4320
- const headerLineY = this.rect.height;
4321
- render.contentContext.drawHoriLine(position.x, position.y + headerLineY, this.rect.width, 'black', 0.5);
4322
- }
4323
- if (this.element.disableClick && render.drawMode === 'view') {
4324
- if (isHeaderEmpty) {
4325
- render.contentContext.setGlobalAlpha(0);
4326
- }
4327
- else {
4328
- render.contentContext.setGlobalAlpha(0.5);
4329
- }
4330
- }
4331
- e.nextRender();
4332
- });
4333
- }
4334
4329
  clone() {
4335
4330
  const cloneRender = new DocumentHeaderRenderObject(this.element);
4336
4331
  cloneRender.rect = ElementUtil.cloneRect(this.rect);
@@ -4403,6 +4398,7 @@ class PSymbolElement extends LeafElement {
4403
4398
  clone() {
4404
4399
  const clone = new PSymbolElement();
4405
4400
  clone.defaultHeight = this.defaultHeight;
4401
+ cloneElementBase(this, clone);
4406
4402
  return clone;
4407
4403
  }
4408
4404
  getSelfLength(pure) {
@@ -4410,13 +4406,6 @@ class PSymbolElement extends LeafElement {
4410
4406
  }
4411
4407
  }
4412
4408
  class PSymbolRenderObject extends LeafRenderObject {
4413
- render(e) {
4414
- const { render, position } = e;
4415
- if (render.drawMode === 'print' || !e.docCtx.viewOptions.showParaSymbol) {
4416
- return;
4417
- }
4418
- render.contentContext.drawText('↩', this.element.textProps, position.x, position.y, 20, this.rect.height);
4419
- }
4420
4409
  exportHTML(event) {
4421
4410
  if (!event.options.showEnterSymbol || event.mode === 'print') {
4422
4411
  return null;
@@ -4491,11 +4480,8 @@ class TableCellElement extends BlockContainerElement {
4491
4480
  clone(data) {
4492
4481
  const clone = new TableCellElement();
4493
4482
  this.props.clone(clone.props);
4494
- if (data) {
4495
- for (let i = 0; i < this.length; i++) {
4496
- clone.addChild(this.getChild(i).clone(true));
4497
- }
4498
- }
4483
+ cloneElementBase(this, clone);
4484
+ cloneChildren(this, clone, data);
4499
4485
  return clone;
4500
4486
  }
4501
4487
  getCellWidth() {
@@ -4529,22 +4515,6 @@ class TableCellElement extends BlockContainerElement {
4529
4515
  }
4530
4516
  }
4531
4517
  class TableCellRenderObject extends InlineMuiltBlockLineRenderObject {
4532
- render(e) {
4533
- const { render, position } = e;
4534
- render.tran(() => {
4535
- render.contentContext.clip(position.x, position.y, this.rect.width, this.rect.height);
4536
- const { hMerge, vMerge, backgroundColor, diagonal } = this.element.props;
4537
- if (hMerge === 'continue' || vMerge === 'continue') {
4538
- render.contentContext.setGlobalAlpha(0);
4539
- render.overlaysContext.setGlobalAlpha(0);
4540
- }
4541
- if (backgroundColor && this.rect.width && this.rect.height) {
4542
- render.contentContext.fillRect(position.x, position.y, this.rect.width, this.rect.height, backgroundColor);
4543
- }
4544
- this.renderDiagonal(render, diagonal, position);
4545
- e.nextRender();
4546
- });
4547
- }
4548
4518
  /**
4549
4519
  * 绘制对角线
4550
4520
  * @private
@@ -4713,8 +4683,6 @@ class TableRowRenderObject extends MuiltBlockLineRenderObject {
4713
4683
  remeasureState = true;
4714
4684
  //当前行是否存在合并单元格
4715
4685
  hasMergeCells = undefined;
4716
- render(e) {
4717
- }
4718
4686
  clone() {
4719
4687
  const cloneRender = new TableRowRenderObject(this.element);
4720
4688
  cloneRender.remeasureState = this.remeasureState;
@@ -4743,17 +4711,6 @@ class DocumentContainerRender extends BlockContainerRenderObject {
4743
4711
  constructor() {
4744
4712
  super(null);
4745
4713
  }
4746
- render(e) {
4747
- const { render, nextRender, docCtx: { viewOptions } } = e;
4748
- const { viewSettings, docPageSettings, viewBackcolor, scale } = viewOptions;
4749
- render.clear();
4750
- //render.overlaysContext.fillRect(0, 0, viewSettings.width, viewSettings.height, viewBackcolor);
4751
- render.tran(() => {
4752
- render.overlaysContext.ctx.scale(scale, scale);
4753
- render.contentContext.ctx.scale(scale, scale);
4754
- nextRender();
4755
- });
4756
- }
4757
4714
  clone() {
4758
4715
  throw new Error("Method not implemented.");
4759
4716
  }
@@ -4832,6 +4789,7 @@ class TextGroupElement extends LeafElement {
4832
4789
  const clone = new TextGroupElement();
4833
4790
  this.props.clone(clone.props);
4834
4791
  clone.text = this.text;
4792
+ cloneElementBase(this, clone);
4835
4793
  return clone;
4836
4794
  }
4837
4795
  destroy() {
@@ -4870,17 +4828,6 @@ class TextGroupElement extends LeafElement {
4870
4828
  }
4871
4829
  class TextGroupRenderObject extends LeafRenderObject {
4872
4830
  textMeasures;
4873
- render(e) {
4874
- const { render, position } = e;
4875
- //null-text不打印
4876
- if (render.drawMode === 'print' && this.element.isDecorate) {
4877
- return;
4878
- }
4879
- if (this.element.props.border) {
4880
- render.contentContext.strokeRect(position.x, position.y, this.rect.width, this.rect.height);
4881
- }
4882
- render.contentContext.drawTextUnits(this, position.x, position.y + (this.rect.height - this.element.props.fontSize) / 2);
4883
- }
4884
4831
  constructor(element) {
4885
4832
  super(element);
4886
4833
  }
@@ -6568,11 +6515,8 @@ class TableElement extends BlockContainerElement {
6568
6515
  clone(data) {
6569
6516
  const clone = new TableElement();
6570
6517
  this.props.clone(clone.props);
6571
- if (data) {
6572
- for (let i = 0; i < this.length; i++) {
6573
- clone.addChild(this.getChild(i).clone(true));
6574
- }
6575
- }
6518
+ cloneElementBase(this, clone);
6519
+ cloneChildren(this, clone, data);
6576
6520
  return clone;
6577
6521
  }
6578
6522
  createRenderObject() {
@@ -6596,56 +6540,6 @@ class TableRenderObject extends MuiltBlockLineRenderObject {
6596
6540
  setRenderWidth(maxWidth) {
6597
6541
  super.setRenderWidth(maxWidth);
6598
6542
  }
6599
- render(e) {
6600
- const { render, position } = e;
6601
- //绘制表格线
6602
- const border = this.element.props.border;
6603
- if (border === 'none') {
6604
- return;
6605
- }
6606
- const lineDash = border === 'dashed' ? [2, 2] : [];
6607
- for (let i = 0; i < this.length; i++) {
6608
- const rowRender = this.getChild(i);
6609
- const rowPos = { x: rowRender.rect.x + position.x, y: rowRender.rect.y + position.y };
6610
- for (let j = 0; j < rowRender.length; j++) {
6611
- const cellRender = rowRender.getChild(j);
6612
- const cellPos = { x: cellRender.rect.x + rowPos.x, y: cellRender.rect.y + rowPos.y };
6613
- //绘制单元格上边框
6614
- if (i === 0) {
6615
- //ctx.contentContext.fillRect(cellPos.x, cellPos.y, cellRender.rect.width, 1);
6616
- render.contentContext.fillLines([{ x: cellPos.x, y: cellPos.y }, {
6617
- x: cellPos.x + cellRender.rect.width,
6618
- y: cellPos.y
6619
- }], 1, '#000', lineDash);
6620
- //this.drawLine(ctx, { x: cellPos.x, y: cellPos.y }, { x: cellPos.x + cellRender.rect.width, y: cellPos.y });
6621
- }
6622
- //绘制左边框
6623
- if (j === 0) {
6624
- //ctx.contentContext.fillRect(cellPos.x, cellPos.y, 1, cellRender.rect.height);
6625
- render.contentContext.fillLines([{ x: cellPos.x, y: cellPos.y }, {
6626
- x: cellPos.x,
6627
- y: cellPos.y + cellRender.rect.height
6628
- }], 1, '#000', lineDash);
6629
- //this.drawLine(ctx, { x: cellPos.x, y: cellPos.y }, { x: cellPos.x, y: cellPos.y + cellRender.rect.height });
6630
- }
6631
- //绘制右边框
6632
- //ctx.contentContext.fillRect(cellPos.x + cellRender.rect.width, cellPos.y, 1, cellRender.rect.height);
6633
- render.contentContext.fillLines([{
6634
- x: cellPos.x + cellRender.rect.width,
6635
- y: cellPos.y
6636
- }, { x: cellPos.x + cellRender.rect.width, y: cellPos.y + cellRender.rect.height }], 1, '#000', lineDash);
6637
- //this.drawLine(ctx, { x: cellPos.x + cellRender.rect.width, y: cellPos.y }, { x: cellPos.x + cellRender.rect.width, y: cellPos.y + cellRender.rect.height });
6638
- //绘制下边框
6639
- //ctx.contentContext.fillRect(cellPos.x, cellPos.y + cellRender.rect.height, cellRender.rect.width, 1);
6640
- render.contentContext.fillLines([{
6641
- x: cellPos.x,
6642
- y: cellPos.y + cellRender.rect.height
6643
- }, { x: cellPos.x + cellRender.rect.width, y: cellPos.y + cellRender.rect.height }], 1, '#000', lineDash);
6644
- //this.drawLine(ctx, { x: cellPos.x, y: cellPos.y + cellRender.rect.height }, { x: cellPos.x + cellRender.rect.width, y: cellPos.y + cellRender.rect.height });
6645
- //cellRender.beginRender(ctx, { x: position.x + cellRender.offsetX, y: position.y + cellRender.offsetY });
6646
- }
6647
- }
6648
- }
6649
6543
  exportTableBorder() {
6650
6544
  //绘制表格线
6651
6545
  const border = this.element.props.border;
@@ -6911,6 +6805,7 @@ class CheckBoxElement extends LeafElement {
6911
6805
  }
6912
6806
  clone() {
6913
6807
  const clone = new CheckBoxElement();
6808
+ cloneElementBase(this, clone);
6914
6809
  this.props.clone(clone.props);
6915
6810
  return clone;
6916
6811
  }
@@ -6930,10 +6825,7 @@ class CheckBoxFactory extends ElementFactory {
6930
6825
  }
6931
6826
  }
6932
6827
  class CheckBoxRenderObject extends LeafRenderObject {
6933
- render(e) {
6934
- e.render.contentContext.drawCheckBox(e.position.x + 2, e.position.y, this.element.props.size, this.element.props.size, this.element.props.isChecked);
6935
- }
6936
- clone(cloneData = true) {
6828
+ clone() {
6937
6829
  const clone = new CheckBoxRenderObject(this.element);
6938
6830
  clone.rect = ElementUtil.cloneRect(this.rect);
6939
6831
  return clone;
@@ -7017,11 +6909,8 @@ class CommContentElement extends CommContentBaseElement {
7017
6909
  clone(data) {
7018
6910
  const clone = new CommContentElement();
7019
6911
  this.props.clone(clone.props);
7020
- if (data) {
7021
- for (let i = 0; i < this.length; i++) {
7022
- clone.addChild(this.getChild(i).clone(true));
7023
- }
7024
- }
6912
+ cloneElementBase(this, clone);
6913
+ cloneChildren(this, clone, data);
7025
6914
  return clone;
7026
6915
  }
7027
6916
  beginMeasure(data) {
@@ -7032,34 +6921,6 @@ class CommContentElement extends CommContentBaseElement {
7032
6921
  }
7033
6922
  }
7034
6923
  class CommContentRenderObject extends CommContentBaseRenderObject {
7035
- render(e) {
7036
- let borderColor = this.element.focus ? '#fa8c16' : '#ffd591';
7037
- e.render.contentContext.strokeRect(e.position.x, e.position.y, this.rect.width, this.rect.height, borderColor);
7038
- e.render.contentContext.fillRect(e.position.x, e.position.y, 8, this.rect.height, '#871400');
7039
- const docRender = ElementUtil.getParentRender(this.commMarkRender.render, DocumentRenderObject);
7040
- //获取审阅标记的绘制坐标
7041
- let commMarkPos = ElementUtil.getRenderAbsolutePaintPos(this.commMarkRender.render, {
7042
- x: 0,
7043
- y: -e.docCtx.viewOptions.pageOffset.y
7044
- });
7045
- const commMarkLinePos = ElementUtil.getParaLinePos(this.commMarkRender.render, commMarkPos);
7046
- commMarkPos.y = commMarkLinePos.y + 2;
7047
- const docRenderPos = ElementUtil.getRenderAbsolutePaintPos(docRender, {
7048
- x: 0,
7049
- y: -e.docCtx.viewOptions.pageOffset.y
7050
- });
7051
- const marginLeft = commMarkPos.x - docRenderPos.x - docRender.padding.left;
7052
- const marginRight = e.docCtx.viewOptions.docPageSettings.width - marginLeft - docRender.padding.right * 2;
7053
- e.render.overlaysContext.drawDashLine([commMarkPos, {
7054
- x: commMarkPos.x + marginRight,
7055
- y: commMarkPos.y
7056
- }], [1, 1], 'red');
7057
- e.render.overlaysContext.drawDashLine([{
7058
- x: commMarkPos.x + marginRight,
7059
- y: commMarkPos.y
7060
- }, e.position], [1, 1], 'red');
7061
- this.renderTitle(e.render, e.position);
7062
- }
7063
6924
  exportHTML(event) {
7064
6925
  const t = super.exportHTML(event);
7065
6926
  t.children = [];
@@ -7326,20 +7187,11 @@ class CommentElement extends LeafElement {
7326
7187
  clone() {
7327
7188
  const clone = new CommentElement();
7328
7189
  this.props.clone(clone.props);
7190
+ cloneElementBase(this, clone);
7329
7191
  return clone;
7330
7192
  }
7331
7193
  }
7332
7194
  class CommentRenderObject extends LeafRenderObject {
7333
- //renderPos!: Position;
7334
- render(e) {
7335
- // if (!e.docCtx.viewOptions.showReviewWindow) {
7336
- // return;
7337
- // }
7338
- // this.renderPos = e.position;
7339
- // const paraLinePos = ElementUtil.getParaLinePos(this, {x: e.position.x, y: e.position.y});
7340
- // const color = '#ff4d4f';
7341
- // e.render.contentContext.fillRect(e.position.x - 1, paraLinePos.y, 2, paraLinePos.height, color)
7342
- }
7343
7195
  exportHTML(event) {
7344
7196
  const renderPos = { ...event.relativePagePos };
7345
7197
  const paraLinePos = ElementUtil.getParaLinePos(this, { x: renderPos.x, y: renderPos.y });
@@ -7485,11 +7337,8 @@ class ValidateElement extends CommContentBaseElement {
7485
7337
  clone(data) {
7486
7338
  const clone = new ValidateElement();
7487
7339
  this.props.clone(clone.props);
7488
- if (data) {
7489
- for (let i = 0; i < this.length; i++) {
7490
- clone.addChild(this.getChild(i).clone(true));
7491
- }
7492
- }
7340
+ cloneElementBase(this, clone);
7341
+ cloneChildren(this, clone, data);
7493
7342
  return clone;
7494
7343
  }
7495
7344
  setContent(content) {
@@ -7505,31 +7354,6 @@ class ValidateElement extends CommContentBaseElement {
7505
7354
  }
7506
7355
  }
7507
7356
  class ValidateRenderObject extends CommContentBaseRenderObject {
7508
- render(e) {
7509
- let borderColor = this.element.focus ? '#fa8c16' : '#ffd591';
7510
- e.render.contentContext.strokeRect(e.position.x, e.position.y, this.rect.width, this.rect.height, borderColor);
7511
- e.render.contentContext.fillRect(e.position.x, e.position.y, 8, this.rect.height, '#871400');
7512
- const docRender = ElementUtil.getParentRender(this.commMarkRender.render, DocumentRenderObject);
7513
- //获取审阅标记的绘制坐标
7514
- let commMarkPos = ElementUtil.getRenderAbsolutePaintPos(this.commMarkRender.render, {
7515
- x: 0,
7516
- y: -e.docCtx.viewOptions.pageOffset.y
7517
- });
7518
- const commMarkLinePos = ElementUtil.getParaLinePos(this.commMarkRender.render, commMarkPos);
7519
- commMarkPos.y = commMarkLinePos.y + 2;
7520
- const docRenderPos = ElementUtil.getRenderAbsolutePaintPos(docRender, { x: 0, y: -e.docCtx.viewOptions.pageOffset.y });
7521
- const marginLeft = commMarkPos.x - docRenderPos.x - docRender.padding.left;
7522
- const marginRight = e.docCtx.viewOptions.docPageSettings.width - marginLeft - docRender.padding.right * 2;
7523
- e.render.overlaysContext.drawDashLine([commMarkPos, {
7524
- x: commMarkPos.x + marginRight,
7525
- y: commMarkPos.y
7526
- }], [1, 1], 'red');
7527
- e.render.overlaysContext.drawDashLine([{
7528
- x: commMarkPos.x + marginRight,
7529
- y: commMarkPos.y
7530
- }, e.position], [1, 1], 'red');
7531
- this.renderTitle(e.render, e.position);
7532
- }
7533
7357
  renderTitle(ctx, position) {
7534
7358
  const topPadding = 24;
7535
7359
  const textProps = new TextProps();
@@ -8442,6 +8266,7 @@ class DataElementBarcode extends DataElementLeaf {
8442
8266
  clone(data) {
8443
8267
  const clone = new DataElementBarcode();
8444
8268
  this.props.clone(clone.props);
8269
+ cloneElementBase(this, clone);
8445
8270
  return clone;
8446
8271
  }
8447
8272
  setValue(val) {
@@ -8455,40 +8280,11 @@ class DataElementBarcode extends DataElementLeaf {
8455
8280
  }
8456
8281
  }
8457
8282
  class DataElementBarcodeRenderObject extends ResizeLeafRenderObject {
8458
- render(e) {
8459
- // const barcodeEle = this.element as DataElementBarcode;
8460
- // barcodeEle.drawBarcode(e.render, e.position);
8461
- }
8462
8283
  clone() {
8463
8284
  const clone = new DataElementBarcodeRenderObject(this.element);
8464
8285
  clone.rect = ElementUtil.cloneRect(this.rect);
8465
8286
  return clone;
8466
8287
  }
8467
- pagePaintCompleted(e) {
8468
- if (this.element.isFocused) {
8469
- const { render, position: pos } = e;
8470
- const { width, height } = this.rect;
8471
- render.contentContext.strokeRect(pos.x, pos.y, this.rect.width, this.rect.height, '#1890ff', 0.5);
8472
- this.drawResizeCircle(render, pos.x, pos.y);
8473
- this.drawResizeCircle(render, pos.x + width, pos.y);
8474
- this.drawResizeCircle(render, pos.x, pos.y + height);
8475
- this.drawResizeCircle(render, pos.x + width, pos.y + height);
8476
- this.drawResizeCircle(render, pos.x + (Math.floor(width / 2)), pos.y);
8477
- this.drawResizeCircle(render, pos.x + (Math.floor(width / 2)), pos.y + height);
8478
- this.drawResizeCircle(render, pos.x, pos.y + (Math.floor(height / 2)));
8479
- this.drawResizeCircle(render, pos.x + width, pos.y + (Math.floor(height / 2)));
8480
- }
8481
- }
8482
- drawResizeCircle(ctx, x, y) {
8483
- const ctxNative = ctx.contentContext.ctx;
8484
- ctxNative.save();
8485
- ctxNative.fillStyle = '#69c0ff';
8486
- ctxNative.beginPath();
8487
- ctxNative.arc(x, y, Math.floor(4 / 5 * 4), 0, 2 * Math.PI);
8488
- ctxNative.closePath();
8489
- ctxNative.fill();
8490
- ctxNative.restore();
8491
- }
8492
8288
  exportHTML(event) {
8493
8289
  const t = super.exportHTML(event);
8494
8290
  if (this.element.props.type === 'qrcode') {
@@ -8624,6 +8420,7 @@ class DataElementCheck extends DataElementLeaf {
8624
8420
  clone(data) {
8625
8421
  const clone = new DataElementCheck();
8626
8422
  this.props.clone(clone.props);
8423
+ cloneElementBase(this, clone);
8627
8424
  return clone;
8628
8425
  }
8629
8426
  setValue(val) {
@@ -8653,27 +8450,6 @@ class DataElementCheckRenderObject extends LeafRenderObject {
8653
8450
  cloneRender.rect = ElementUtil.cloneRect(this.rect);
8654
8451
  return cloneRender;
8655
8452
  }
8656
- render(e) {
8657
- const { render, position } = e;
8658
- const element = this.element;
8659
- if (element.props.drawStateChar) {
8660
- const font = `${element.props.size - 2}px 微软雅黑`;
8661
- const str = element.props.checked ? element.props.trueChar : element.props.falseChar;
8662
- const color = element.props.checked ? element.props.trueStateColor : element.props.falseStateColor;
8663
- e.render.contentContext.drawText2(str, font, color, position.x, position.y, element.props.size, element.props.size);
8664
- if (element.props.border) {
8665
- e.render.contentContext.strokeRect(position.x + 2, position.y, element.props.size, element.props.size);
8666
- }
8667
- }
8668
- else {
8669
- if (element.props.multiSelect) {
8670
- render.contentContext.drawCheckBox(position.x + 2, position.y, element.props.size, element.props.size, element.props.checked);
8671
- }
8672
- else {
8673
- render.contentContext.drawRadioBox(position.x + 2, position.y, element.props.size, element.props.size, element.props.checked);
8674
- }
8675
- }
8676
- }
8677
8453
  exportHTML(event) {
8678
8454
  const t = super.exportHTML(event);
8679
8455
  const props = this.element.props;
@@ -8964,12 +8740,6 @@ class DataElementGroupElement extends InlineGroupInputElement {
8964
8740
  }
8965
8741
  }
8966
8742
  class DataElementGroupRenderObject extends InlineGroupRenderObject {
8967
- render(e) {
8968
- this.paintPos = e.position;
8969
- e.render.onRenderCompleted.subscribe(() => {
8970
- drawDecorator(e, this);
8971
- });
8972
- }
8973
8743
  clone() {
8974
8744
  const cloneRender = new DataElementGroupRenderObject(this.element);
8975
8745
  cloneRender.rect = ElementUtil.cloneRect(this.rect);
@@ -9021,6 +8791,7 @@ class DataElementImage extends DataElementLeaf {
9021
8791
  clone(data) {
9022
8792
  const clone = new DataElementImage();
9023
8793
  this.props.clone(clone.props);
8794
+ cloneElementBase(this, clone);
9024
8795
  return clone;
9025
8796
  }
9026
8797
  destroy() {
@@ -9037,38 +8808,11 @@ class DataElementImage extends DataElementLeaf {
9037
8808
  }
9038
8809
  }
9039
8810
  class DataImageRenderObject extends ResizeLeafRenderObject {
9040
- render(e) {
9041
- }
9042
8811
  clone() {
9043
8812
  const clone = new DataImageRenderObject(this.element);
9044
8813
  clone.rect = ElementUtil.cloneRect(this.rect);
9045
8814
  return clone;
9046
8815
  }
9047
- pagePaintCompleted(e) {
9048
- if (this.element.isFocused) {
9049
- const { render, position: pos } = e;
9050
- const { width, height } = this.rect;
9051
- render.contentContext.strokeRect(pos.x, pos.y, this.rect.width, this.rect.height, '#1890ff', 0.5);
9052
- this.drawResizeCircle(render, pos.x, pos.y);
9053
- this.drawResizeCircle(render, pos.x + width, pos.y);
9054
- this.drawResizeCircle(render, pos.x, pos.y + height);
9055
- this.drawResizeCircle(render, pos.x + width, pos.y + height);
9056
- this.drawResizeCircle(render, pos.x + (Math.floor(width / 2)), pos.y);
9057
- this.drawResizeCircle(render, pos.x + (Math.floor(width / 2)), pos.y + height);
9058
- this.drawResizeCircle(render, pos.x, pos.y + (Math.floor(height / 2)));
9059
- this.drawResizeCircle(render, pos.x + width, pos.y + (Math.floor(height / 2)));
9060
- }
9061
- }
9062
- drawResizeCircle(ctx, x, y) {
9063
- const ctxNative = ctx.contentContext.ctx;
9064
- ctxNative.save();
9065
- ctxNative.fillStyle = '#69c0ff';
9066
- ctxNative.beginPath();
9067
- ctxNative.arc(x, y, Math.floor(4 / 5 * 4), 0, 2 * Math.PI);
9068
- ctxNative.closePath();
9069
- ctxNative.fill();
9070
- ctxNative.restore();
9071
- }
9072
8816
  exportHTML(event) {
9073
8817
  const t = super.exportHTML(event);
9074
8818
  t.children = [{
@@ -9299,18 +9043,11 @@ class BreakElement extends LeafElement {
9299
9043
  }
9300
9044
  clone() {
9301
9045
  const clone = new BreakElement();
9302
- //clone.renderCtx = this.renderCtx;
9046
+ cloneElementBase(this, clone);
9303
9047
  return clone;
9304
9048
  }
9305
9049
  }
9306
9050
  class BreakRenderObject extends LeafRenderObject {
9307
- render(e) {
9308
- const { render, position } = e;
9309
- if (render.drawMode === 'print') {
9310
- return;
9311
- }
9312
- render.contentContext.drawText('↓', this.element.textProps, position.x, position.y, 20, this.rect.height);
9313
- }
9314
9051
  exportHTML(event) {
9315
9052
  if (!event.options.showEnterSymbol || event.mode === 'print') {
9316
9053
  return null;
@@ -9476,8 +9213,6 @@ class FillNullSpaceRenderObject extends LeafRenderObject {
9476
9213
  super(null);
9477
9214
  this.disableClick = true;
9478
9215
  }
9479
- render(e) {
9480
- }
9481
9216
  clone() {
9482
9217
  const clone = new FillNullSpaceRenderObject();
9483
9218
  clone.rect = ElementUtil.cloneRect(this.rect);
@@ -9529,20 +9264,12 @@ class DocumentBodyPartElement extends BlockContainerElement {
9529
9264
  clone(data) {
9530
9265
  const clone = new DocumentBodyPartElement();
9531
9266
  clone.props.partId = this.props.partId;
9532
- if (data) {
9533
- for (let i = 0; i < this.length; i++) {
9534
- clone.addChild(this.getChild(i).clone(true));
9535
- }
9536
- }
9267
+ cloneElementBase(this, clone);
9268
+ cloneChildren(this, clone, data);
9537
9269
  return clone;
9538
9270
  }
9539
9271
  }
9540
9272
  class DocumentBodyPartRenderObject extends MuiltBlockLineRenderObject {
9541
- render(e) {
9542
- const { render, position } = e;
9543
- const bgColor = (this.element.isFocused || this.element.isMouseenter) ? '#d9d9d9' : '#ffffff';
9544
- render.overlaysContext.fillRect(position.x - 2, position.y - 2, this.rect.width + 4, this.rect.height + 4, bgColor, 5, 'black');
9545
- }
9546
9273
  clone(cloneData = true) {
9547
9274
  const cloneRender = new DocumentBodyPartRenderObject(this.element);
9548
9275
  cloneRender.rect = ElementUtil.cloneRect(this.rect);
@@ -9636,6 +9363,7 @@ class DataElementMH extends DataElementLeaf {
9636
9363
  clone(data) {
9637
9364
  const element = new DataElementMH();
9638
9365
  this.props.clone(element.props);
9366
+ cloneElementBase(this, element);
9639
9367
  return element;
9640
9368
  }
9641
9369
  getCurrentLayoutItem() {
@@ -9682,9 +9410,6 @@ function getMHItem(kind) {
9682
9410
  return mhLayoutItems[kindIndex];
9683
9411
  }
9684
9412
  class DataRenderMH extends LeafRenderObject {
9685
- render(e) {
9686
- renderMH(this.element, e.render, e.position, true);
9687
- }
9688
9413
  exportHTML(event) {
9689
9414
  const t = super.exportHTML(event);
9690
9415
  const children = [];
@@ -9884,6 +9609,152 @@ function renderMHHTML(event, element, isPaint, nodes = []) {
9884
9609
  }
9885
9610
  }
9886
9611
 
9612
+ const fontSize = 12;
9613
+ const verPadding = 2;
9614
+ /**
9615
+ * 恒牙牙位图
9616
+ */
9617
+ class PermanentTeethElement extends DataElementLeaf {
9618
+ constructor() {
9619
+ super('permanent-teeth');
9620
+ this.props = new PermanentTeethProps();
9621
+ this.props.topLeft = '';
9622
+ this.props.topRight = '';
9623
+ this.props.bottomLeft = '';
9624
+ this.props.bottomRight = '';
9625
+ }
9626
+ setValue(val) {
9627
+ if (typeof val === 'string' && val) {
9628
+ const items = val.split(';');
9629
+ if (items.length >= 4) {
9630
+ this.props.topLeft = items[0];
9631
+ this.props.topRight = items[1];
9632
+ this.props.bottomLeft = items[2];
9633
+ this.props.bottomRight = items[3];
9634
+ }
9635
+ }
9636
+ else if (typeof val === 'object') {
9637
+ this.props.topLeft = val?.topLeft ?? '';
9638
+ this.props.topRight = val?.topRight ?? '';
9639
+ this.props.bottomLeft = val?.bottomLeft ?? '';
9640
+ this.props.bottomRight = val?.bottomRight ?? '';
9641
+ }
9642
+ }
9643
+ getValue() {
9644
+ const { topLeft, topRight, bottomLeft, bottomRight } = this.props;
9645
+ return `${topLeft};${topRight};${bottomLeft};${bottomRight}`;
9646
+ }
9647
+ clone(data) {
9648
+ const clone = new PermanentTeethElement();
9649
+ clone.props = this.props.clone();
9650
+ cloneElementBase(this, clone);
9651
+ return clone;
9652
+ }
9653
+ createRenderObject(data) {
9654
+ const clone = new PermanentTeethRenderObject(this);
9655
+ clone.rect.width = 150;
9656
+ //字体大小*2+上下间距2*2
9657
+ clone.rect.height = fontSize * 2 + verPadding * 2;
9658
+ //clone.rect= ElementUtil.cloneRect(this.rect);
9659
+ return clone;
9660
+ }
9661
+ serialize(viewOptions) {
9662
+ return {
9663
+ type: this.type,
9664
+ props: this.props.getSerializeProps(viewOptions)
9665
+ };
9666
+ }
9667
+ }
9668
+ class PermanentTeethRenderObject extends LeafRenderObject {
9669
+ clone() {
9670
+ const clone = new PermanentTeethRenderObject(this.element);
9671
+ clone.rect = ElementUtil.cloneRect(this.rect);
9672
+ return clone;
9673
+ }
9674
+ // measure(): { width: number, height: number } {
9675
+ // const ele = this.element;
9676
+ //
9677
+ // }
9678
+ exportHTML(event) {
9679
+ const ele = this.element;
9680
+ const g = super.exportHTML(event);
9681
+ const contentHorPadding = 4;
9682
+ g.children = [];
9683
+ // g.children.push(ElementUtil.getFillSvgPath(`M 0 ${this.rect.height / 2} h${this.rect.width}`, '#000', 1));
9684
+ // g.children.push(ElementUtil.getFillSvgPath(`M ${this.rect.width / 2} 0 v${this.rect.height}`, '#000', 1));
9685
+ //
9686
+ g.children.push(ElementUtil.getFillSvgRect(0, this.rect.height / 2, this.rect.width, 1, '#000'));
9687
+ g.children.push(ElementUtil.getFillSvgRect(this.rect.width / 2, 0, 1, this.rect.height, '#000'));
9688
+ const getSvgText = (text, x, y) => {
9689
+ return {
9690
+ sel: 'text',
9691
+ text: text,
9692
+ data: {
9693
+ ns: "http://www.w3.org/2000/svg",
9694
+ attrs: {
9695
+ 'dominant-baseline': 'hanging',
9696
+ 'font-family': 'Arial',
9697
+ 'font-size': fontSize,
9698
+ x,
9699
+ y,
9700
+ }
9701
+ },
9702
+ };
9703
+ };
9704
+ const topLeftWidth = event.renderCtx.mainContext.measureTextWidth(ele.props.topLeft, {
9705
+ fontSize: fontSize,
9706
+ fontName: 'Arial'
9707
+ });
9708
+ const bottomLeftWidth = event.renderCtx.mainContext.measureTextWidth(ele.props.bottomLeft, {
9709
+ fontSize: fontSize,
9710
+ fontName: 'Arial'
9711
+ });
9712
+ g.children.push(getSvgText(ele.props.topLeft, this.rect.width / 2 - topLeftWidth - contentHorPadding, verPadding));
9713
+ g.children.push(getSvgText(ele.props.topRight, this.rect.width / 2 + contentHorPadding, verPadding));
9714
+ g.children.push(getSvgText(ele.props.bottomLeft, this.rect.width / 2 - bottomLeftWidth - contentHorPadding, this.rect.height - fontSize + verPadding));
9715
+ g.children.push(getSvgText(ele.props.bottomRight, this.rect.width / 2 + contentHorPadding, this.rect.height - fontSize + verPadding));
9716
+ return g;
9717
+ }
9718
+ }
9719
+ class PermanentTeethFactory extends ElementFactory {
9720
+ match(type) {
9721
+ return type === 'permanent-teeth';
9722
+ }
9723
+ createElement(data) {
9724
+ const ele = new PermanentTeethElement();
9725
+ ele.props.bottomLeft = data.props?.bottomLeft ?? '';
9726
+ ele.props.bottomRight = data.props?.bottomRight ?? '';
9727
+ ele.props.topLeft = data.props?.topLeft ?? '';
9728
+ ele.props.topRight = data.props?.topRight ?? '';
9729
+ return ele;
9730
+ }
9731
+ }
9732
+ /**
9733
+ * 恒牙牙位图属性
9734
+ */
9735
+ class PermanentTeethProps extends INotifyPropertyChanged {
9736
+ topLeft;
9737
+ topRight;
9738
+ bottomLeft;
9739
+ bottomRight;
9740
+ getSerializeProps(viewOptions) {
9741
+ return {
9742
+ topLeft: this.topLeft,
9743
+ topRight: this.topRight,
9744
+ bottomLeft: this.bottomLeft,
9745
+ bottomRight: this.bottomRight,
9746
+ };
9747
+ }
9748
+ clone(dest) {
9749
+ dest = dest || new PermanentTeethProps();
9750
+ dest.topLeft = this.topLeft;
9751
+ dest.topRight = this.topRight;
9752
+ dest.bottomLeft = this.bottomLeft;
9753
+ dest.bottomRight = this.bottomRight;
9754
+ return dest;
9755
+ }
9756
+ }
9757
+
9887
9758
  class PictureElement extends LeafElement {
9888
9759
  //props: PictureProps;
9889
9760
  status = 'no';
@@ -9912,6 +9783,7 @@ class PictureElement extends LeafElement {
9912
9783
  clone(data) {
9913
9784
  const clone = new PictureElement();
9914
9785
  this.props.clone(clone.props);
9786
+ cloneElementBase(this, clone);
9915
9787
  return clone;
9916
9788
  }
9917
9789
  destroy() {
@@ -9919,36 +9791,11 @@ class PictureElement extends LeafElement {
9919
9791
  }
9920
9792
  }
9921
9793
  class PictureRenderObject extends ResizeLeafRenderObject {
9922
- render(e) {
9923
- }
9924
9794
  clone() {
9925
9795
  const clone = new PictureRenderObject(this.element);
9926
9796
  clone.rect = ElementUtil.cloneRect(this.rect);
9927
9797
  return clone;
9928
9798
  }
9929
- pagePaintCompleted(e) {
9930
- if (this.element.isFocused) {
9931
- const { render, position: pos } = e;
9932
- const { width, height } = this.rect;
9933
- render.contentContext.strokeRect(pos.x, pos.y, width, height, '#1890ff', 0.5);
9934
- this.drawResizeCircle(render, pos.x, pos.y);
9935
- this.drawResizeCircle(render, pos.x + width, pos.y);
9936
- this.drawResizeCircle(render, pos.x, pos.y + height);
9937
- this.drawResizeCircle(render, pos.x + width, pos.y + height);
9938
- this.drawResizeCircle(render, pos.x + (Math.floor(width / 2)), pos.y);
9939
- this.drawResizeCircle(render, pos.x + (Math.floor(width / 2)), pos.y + height);
9940
- this.drawResizeCircle(render, pos.x, pos.y + (Math.floor(height / 2)));
9941
- this.drawResizeCircle(render, pos.x + width, pos.y + (Math.floor(height / 2)));
9942
- }
9943
- }
9944
- drawResizeCircle(ctx, x, y) {
9945
- const ctxNative = ctx.contentContext.ctx;
9946
- ctxNative.fillStyle = '#69c0ff';
9947
- ctxNative.beginPath();
9948
- ctxNative.arc(x, y, Math.floor(4 / 5 * 4), 0, 2 * Math.PI);
9949
- ctxNative.closePath();
9950
- ctxNative.fill();
9951
- }
9952
9799
  exportHTML(event) {
9953
9800
  const picElement = this.element;
9954
9801
  const picProps = picElement.props;
@@ -10062,6 +9909,7 @@ class RadioBoxElement extends LeafElement {
10062
9909
  clone() {
10063
9910
  const clone = new RadioBoxElement();
10064
9911
  this.props.clone(clone.props);
9912
+ cloneElementBase(this, clone);
10065
9913
  return clone;
10066
9914
  }
10067
9915
  }
@@ -10080,10 +9928,6 @@ class RadioBoxFactory extends ElementFactory {
10080
9928
  }
10081
9929
  }
10082
9930
  class RadioBoxRenderObject extends LeafRenderObject {
10083
- render(e) {
10084
- const { render, position } = e;
10085
- render.contentContext.drawRadioBox(position.x + 2, position.y, this.element.props.size, this.element.props.size, this.element.props.isChecked);
10086
- }
10087
9931
  clone(cloneData = true) {
10088
9932
  const clone = new RadioBoxRenderObject(this.element);
10089
9933
  clone.rect = ElementUtil.cloneRect(this.rect);
@@ -10117,18 +9961,11 @@ class PageBreakElement extends LeafElement {
10117
9961
  }
10118
9962
  clone() {
10119
9963
  const clone = new PageBreakElement();
10120
- //clone.renderCtx = this.renderCtx;
9964
+ cloneElementBase(this, clone);
10121
9965
  return clone;
10122
9966
  }
10123
9967
  }
10124
9968
  class PageBreakRenderObject extends LeafRenderObject {
10125
- render(e) {
10126
- const { render, position } = e;
10127
- if (render.drawMode === 'print') {
10128
- return;
10129
- }
10130
- render.contentContext.drawText('↩', this.element.textProps, position.x, position.y, 20, this.rect.height);
10131
- }
10132
9969
  clone() {
10133
9970
  const render = new PageBreakRenderObject(this.element);
10134
9971
  render.rect = ElementUtil.cloneRect(this.rect);
@@ -10161,17 +9998,12 @@ class TabElement extends LeafElement {
10161
9998
  };
10162
9999
  }
10163
10000
  clone() {
10164
- return new TabElement();
10001
+ const clone = new TabElement();
10002
+ cloneElementBase(this, clone);
10003
+ return clone;
10165
10004
  }
10166
10005
  }
10167
10006
  class TabRenderObject extends LeafRenderObject {
10168
- render(e) {
10169
- const { render, position } = e;
10170
- if (render.drawMode === 'print') {
10171
- return;
10172
- }
10173
- //render.contentContext.fillRect(position.x,position.y,this.rect.width,this.rect.height,'red');
10174
- }
10175
10007
  clone() {
10176
10008
  const render = new TabRenderObject(this.element);
10177
10009
  render.rect = ElementUtil.cloneRect(this.rect);
@@ -10737,6 +10569,116 @@ class TableSplitCell {
10737
10569
  }
10738
10570
  }
10739
10571
 
10572
+ class SVGElement extends LeafElement {
10573
+ resizeable = true;
10574
+ constructor() {
10575
+ super('svg');
10576
+ this.props = new SVGProps();
10577
+ //this.addPropValueChangedSub(this.props);
10578
+ this.cursorType = 'move';
10579
+ this.focusable = true;
10580
+ }
10581
+ createRenderObject() {
10582
+ const render = new SVGRenderObject(this);
10583
+ render.rect.width = this.props.width;
10584
+ render.rect.height = this.props.height;
10585
+ return render;
10586
+ }
10587
+ serialize(options) {
10588
+ return {
10589
+ type: 'svg',
10590
+ props: {
10591
+ ...this.props.getSerializeProps(options)
10592
+ }
10593
+ };
10594
+ }
10595
+ clone(data) {
10596
+ const clone = new SVGElement();
10597
+ this.props.clone(clone.props);
10598
+ cloneElementBase(this, clone);
10599
+ return clone;
10600
+ }
10601
+ destroy() {
10602
+ super.destroy();
10603
+ }
10604
+ }
10605
+ class SVGRenderObject extends ResizeLeafRenderObject {
10606
+ clone() {
10607
+ const clone = new SVGRenderObject(this.element);
10608
+ clone.rect = ElementUtil.cloneRect(this.rect);
10609
+ return clone;
10610
+ }
10611
+ drawResizeCircle(ctx, x, y) {
10612
+ const ctxNative = ctx.contentContext.ctx;
10613
+ ctxNative.fillStyle = '#69c0ff';
10614
+ ctxNative.beginPath();
10615
+ ctxNative.arc(x, y, Math.floor(4 / 5 * 4), 0, 2 * Math.PI);
10616
+ ctxNative.closePath();
10617
+ ctxNative.fill();
10618
+ }
10619
+ exportHTML(event) {
10620
+ const props = this.element.props;
10621
+ const t = super.exportHTML(event);
10622
+ t.children = [{
10623
+ sel: 'svg',
10624
+ data: {
10625
+ ns: "http://www.w3.org/2000/svg",
10626
+ attrs: {
10627
+ width: this.rect.width,
10628
+ height: this.rect.height
10629
+ }
10630
+ },
10631
+ children: [{
10632
+ sel: 'image',
10633
+ data: {
10634
+ ns: "http://www.w3.org/2000/svg",
10635
+ attrs: {
10636
+ "xlink:href": props.value,
10637
+ width: Math.min(this.rect.width, this.rect.height),
10638
+ height: Math.min(this.rect.width, this.rect.height)
10639
+ }
10640
+ }
10641
+ }]
10642
+ }];
10643
+ //绘制拖动圆圈
10644
+ if (this.element.isFocused) {
10645
+ const { width, height } = this.rect;
10646
+ const circlePoints = [{ x: 0, y: 0 }, { x: width, y: 0 }, { x: 0, y: height }, { x: width, y: height }, { x: Math.floor(width / 2), y: 0 }, { x: Math.floor(width / 2), y: height }, { x: 0, y: Math.floor(height / 2) }, { x: width, y: Math.floor(height / 2) }];
10647
+ circlePoints.forEach((p) => {
10648
+ t.children.push({
10649
+ sel: 'circle',
10650
+ data: {
10651
+ ns: "http://www.w3.org/2000/svg",
10652
+ attrs: {
10653
+ cx: p.x,
10654
+ cy: p.y,
10655
+ r: Math.floor(4 / 5 * 4),
10656
+ fill: '#69c0ff'
10657
+ }
10658
+ }
10659
+ });
10660
+ });
10661
+ }
10662
+ return t;
10663
+ }
10664
+ }
10665
+ class SVGFactory extends ElementFactory {
10666
+ match(type) {
10667
+ return type === 'svg';
10668
+ }
10669
+ createElement(data) {
10670
+ const props = data.props;
10671
+ const pic = new SVGElement();
10672
+ const picProps = pic.props;
10673
+ picProps.width = props.width;
10674
+ picProps.height = props.height;
10675
+ picProps.value = props.value;
10676
+ picProps.title = props.title;
10677
+ pic.props = picProps;
10678
+ return pic;
10679
+ }
10680
+ }
10681
+
10740
10682
  class ElementSerialize {
10741
10683
  /**
10742
10684
  * 将当前文档对象构建并输出到标准的JSON对象
@@ -10780,6 +10722,9 @@ class ElementSerialize {
10780
10722
  if (element.props && element.props['__attachedProperty'] && !result.props['__attachedProperty']) {
10781
10723
  result.props['__attachedProperty'] = CommonUtil.cloneValue(element.props['__attachedProperty']);
10782
10724
  }
10725
+ if (element.attribute) {
10726
+ result['attribute'] = this.serializeAttribute(element);
10727
+ }
10783
10728
  return result;
10784
10729
  }
10785
10730
  static serializeString(element, options = { all: false }) {
@@ -10789,6 +10734,9 @@ class ElementSerialize {
10789
10734
  if (element instanceof TextGroupElement && !element.isDecorate) {
10790
10735
  return element.text;
10791
10736
  }
10737
+ if (element instanceof PSymbolElement) {
10738
+ return '\n';
10739
+ }
10792
10740
  if (element instanceof BranchElement) {
10793
10741
  const items = [];
10794
10742
  for (let i = 0; i < element.length; i++) {
@@ -10799,6 +10747,21 @@ class ElementSerialize {
10799
10747
  }
10800
10748
  return "";
10801
10749
  }
10750
+ static serializeAttribute(element) {
10751
+ if (element.attribute) {
10752
+ const result = {};
10753
+ for (const key in element.attribute) {
10754
+ if (element.attribute[key] !== undefined && element.attribute[key] !== null) {
10755
+ result[key] = element.attribute[key];
10756
+ }
10757
+ }
10758
+ if (Object.keys(result).length === 0) {
10759
+ return null;
10760
+ }
10761
+ return CommonUtil.cloneValue(result);
10762
+ }
10763
+ return null;
10764
+ }
10802
10765
  /**
10803
10766
  * 获取选中的结构
10804
10767
  * @param ss
@@ -10897,12 +10860,8 @@ class TrackRunElement extends InlineGroupElement {
10897
10860
  clone(data) {
10898
10861
  const clone = new TrackRunElement(this.type);
10899
10862
  this.props.clone(clone.props);
10900
- if (data) {
10901
- const length = this.length;
10902
- for (let i = 0; i < length; i++) {
10903
- clone.addChild(this.getChild(i).clone(true));
10904
- }
10905
- }
10863
+ cloneElementBase(this, clone);
10864
+ cloneChildren(this, clone, data);
10906
10865
  return clone;
10907
10866
  }
10908
10867
  createRenderObject(data) {
@@ -10939,32 +10898,6 @@ class TrackRunRenderObject extends InlineGroupRenderObject {
10939
10898
  constructor(ele) {
10940
10899
  super(ele);
10941
10900
  }
10942
- render(e) {
10943
- const { render, position, docCtx: { viewOptions } } = e;
10944
- render.tran(() => {
10945
- let fillColor = viewOptions.showTrackChanges ? this.element.type === 'ins-run' ? viewOptions.trackInsColor : viewOptions.trackDelColor : '';
10946
- if (fillColor) {
10947
- render.contentContext.ctx.fillStyle = fillColor;
10948
- }
10949
- e.nextRender();
10950
- });
10951
- const { x, y } = position;
10952
- //不显示痕迹
10953
- if (!viewOptions.showTrackChanges) {
10954
- return;
10955
- }
10956
- const color = this.element.type === 'ins-run' ? 'green' : 'red';
10957
- for (let i = 0; i < this.length; i++) {
10958
- const childRender = this.getChild(i);
10959
- const { rect } = childRender;
10960
- if (childRender.element && childRender.element.type === 'del-run') {
10961
- continue;
10962
- }
10963
- let lineY = y + rect.y + rect.height;
10964
- lineY = this.element.type === 'ins-run' ? lineY : lineY - rect.height / 2;
10965
- render.contentContext.drawHoriLine(x + rect.x, lineY, rect.width, color, 1);
10966
- }
10967
- }
10968
10901
  exportHTML(event) {
10969
10902
  const { options } = event;
10970
10903
  const t = super.exportHTML(event);
@@ -12527,9 +12460,9 @@ class ElementUtil {
12527
12460
  return this.getTextRenderOffset(render, x);
12528
12461
  }
12529
12462
  else {
12530
- if (render.element && render.element.type === 'psym') {
12531
- return 0;
12532
- }
12463
+ // if (render.element && render.element.type === 'psym') {
12464
+ // return 0;
12465
+ // }
12533
12466
  return (render.rect.width / 2) >= x ? 0 : 1;
12534
12467
  }
12535
12468
  }
@@ -12812,6 +12745,26 @@ class ElementUtil {
12812
12745
  ss.resetRange(ele.getChild(ele.length - 2), -1);
12813
12746
  }
12814
12747
  }
12748
+ static setEleAttribute(ele, attr, value) {
12749
+ if (!ele.attribute) {
12750
+ ele.attribute = {};
12751
+ }
12752
+ if (ele.attribute[attr] === value) {
12753
+ return;
12754
+ }
12755
+ ele.attribute[attr] = value;
12756
+ }
12757
+ static getEleAttribute(ele, attr) {
12758
+ if (ele.attribute) {
12759
+ return ele.attribute[attr];
12760
+ }
12761
+ return undefined;
12762
+ }
12763
+ static removeEleAttribute(ele, attr) {
12764
+ if (ele.attribute) {
12765
+ delete ele.attribute[attr];
12766
+ }
12767
+ }
12815
12768
  }
12816
12769
 
12817
12770
  class RenderContext {
@@ -13259,12 +13212,12 @@ class ElementPaint {
13259
13212
  }
13260
13213
  }
13261
13214
  });
13262
- docContainer.render({
13263
- render: this.renderCtx,
13264
- position: { x: docContainer.rect.x, y: docContainer.rect.y },
13265
- nextRender: nextRenderFn,
13266
- docCtx: this.docCtx
13267
- });
13215
+ // docContainer.render({
13216
+ // render: this.renderCtx,
13217
+ // position: { x: docContainer.rect.x, y: docContainer.rect.y },
13218
+ // nextRender: nextRenderFn,
13219
+ // docCtx: this.docCtx
13220
+ // })
13268
13221
  nextRenderFn();
13269
13222
  const { scale, viewSettings: { width, height } } = this.viewOptions;
13270
13223
  while (this.renderCtx.onRenderCompleted.subs.length > 0) {
@@ -13293,25 +13246,25 @@ class ElementPaint {
13293
13246
  this.drawRenderObject(child, currPosition, inViewPort);
13294
13247
  }
13295
13248
  });
13296
- const renderData = {
13249
+ ({
13297
13250
  position: currPosition,
13298
13251
  nextRender: nextRenderFn,
13299
13252
  render: this.renderCtx,
13300
13253
  docCtx: this.docCtx
13301
- };
13302
- renderObject.render(renderData);
13254
+ });
13255
+ //renderObject.render(renderData);
13303
13256
  nextRenderFn();
13304
13257
  }
13305
13258
  }
13306
13259
  else if (renderObject instanceof LeafRenderObject) {
13307
13260
  if (inViewPort) {
13308
- const renderData = {
13261
+ ({
13309
13262
  position: currPosition,
13310
13263
  nextRender: () => { },
13311
13264
  render: this.renderCtx,
13312
13265
  docCtx: this.docCtx
13313
- };
13314
- renderObject.render(renderData);
13266
+ });
13267
+ //renderObject.render(renderData);
13315
13268
  }
13316
13269
  }
13317
13270
  //处理选中拖蓝
@@ -13364,14 +13317,14 @@ class ElementPaint {
13364
13317
  * 触发页面绘制结束事件
13365
13318
  */
13366
13319
  invokedPagePaintCompleted(renderObject, parent) {
13367
- const { x: rx, y: ry, width: rw, height: rh } = renderObject.rect;
13368
- const currPosition = { x: rx + parent.x, y: ry + parent.y };
13369
- renderObject.pagePaintCompleted({ render: this.renderCtx, position: currPosition, docCtx: this.docCtx });
13370
- if (renderObject instanceof BranchRenderObject) {
13371
- for (let i = 0; i < renderObject.length; i++) {
13372
- this.invokedPagePaintCompleted(renderObject.getChild(i), currPosition);
13373
- }
13374
- }
13320
+ // const { x: rx, y: ry, width: rw, height: rh } = renderObject.rect;
13321
+ // const currPosition = { x: rx + parent.x, y: ry + parent.y };
13322
+ // renderObject.pagePaintCompleted({ render: this.renderCtx, position: currPosition, docCtx: this.docCtx })
13323
+ // if (renderObject instanceof BranchRenderObject) {
13324
+ // for (let i = 0; i < renderObject.length; i++) {
13325
+ // this.invokedPagePaintCompleted(renderObject.getChild(i), currPosition);
13326
+ // }
13327
+ // }
13375
13328
  }
13376
13329
  static drawPage(renderCtx, docCtx, renderObject, parent) {
13377
13330
  const { x: rx, y: ry } = renderObject.rect;
@@ -13383,24 +13336,9 @@ class ElementPaint {
13383
13336
  this.drawPage(renderCtx, docCtx, child, currPosition);
13384
13337
  }
13385
13338
  });
13386
- const renderData = {
13387
- position: currPosition,
13388
- nextRender: nextRenderFn,
13389
- render: renderCtx,
13390
- docCtx
13391
- };
13392
- renderObject.render(renderData);
13339
+ //renderObject.render(renderData);
13393
13340
  nextRenderFn();
13394
13341
  }
13395
- else if (renderObject instanceof LeafRenderObject) {
13396
- const renderData = {
13397
- position: currPosition,
13398
- nextRender: () => { },
13399
- render: renderCtx,
13400
- docCtx: docCtx
13401
- };
13402
- renderObject.render(renderData);
13403
- }
13404
13342
  }
13405
13343
  }
13406
13344
 
@@ -13461,10 +13399,7 @@ class EditorContext {
13461
13399
  isDirty = false;
13462
13400
  cursorRect;
13463
13401
  _document;
13464
- //文档刷新的订阅事件
13465
- //refSub!: Subscription;
13466
13402
  syncRefresh;
13467
- //imageLoader: IImageLoader;
13468
13403
  dynamicFunc;
13469
13404
  docChange;
13470
13405
  clearPrevDocCb;
@@ -13518,6 +13453,7 @@ class EditorContext {
13518
13453
  //this.imageLoader.clear();
13519
13454
  this.dynamicFunc.destroyScripts();
13520
13455
  this.isDirty = false;
13456
+ //this.clearEleDepMaps();
13521
13457
  }
13522
13458
  get defaultCtx() {
13523
13459
  return new DocumentContext(this._document, this.selectionState);
@@ -13592,17 +13528,6 @@ class EditorContext {
13592
13528
  return this._document.modifyFlag === ModifyFlag$1.None ? 'appearance' : 'content';
13593
13529
  }
13594
13530
  }
13595
- // export interface IImageLoader {
13596
- // clear(): void;
13597
- //
13598
- // loadImage(src: string, onCallback: (status: ImgLoadStatus) => void): void;
13599
- //
13600
- // getImage(src: string): HTMLImageElement | undefined;
13601
- //
13602
- // imagesLoadCompleted(): boolean;
13603
- //
13604
- // getLoadTasks(): Array<Promise<void>>;
13605
- // }
13606
13531
  /**
13607
13532
  * 文档上下文
13608
13533
  */
@@ -13865,13 +13790,23 @@ class DocumentContext {
13865
13790
  }
13866
13791
  }
13867
13792
 
13868
- class DynamicContextParser {
13793
+ class DynamicExecute {
13869
13794
  doc;
13870
13795
  ss;
13796
+ current;
13797
+ depItems;
13871
13798
  constructor(doc, ss) {
13872
13799
  this.doc = doc;
13873
13800
  this.ss = ss;
13874
13801
  }
13802
+ setCurrentCtx(ele, depItems) {
13803
+ this.current = ele;
13804
+ this.depItems = depItems;
13805
+ }
13806
+ clearCurrentCtx() {
13807
+ this.current = undefined;
13808
+ this.depItems = undefined;
13809
+ }
13875
13810
  cacheList;
13876
13811
  getControlById(id) {
13877
13812
  if (!this.cacheList) {
@@ -13883,6 +13818,10 @@ class DynamicContextParser {
13883
13818
  //return this.cacheList.find(item => item['props']['id'] === id);
13884
13819
  }
13885
13820
  getObject(id) {
13821
+ //如果当前存在编译缓存,则直接从缓存中获取
13822
+ if (this.depItems && this.depItems.has(id)) {
13823
+ return this.depItems.get(id);
13824
+ }
13886
13825
  new DocumentContext(this.doc, this.ss);
13887
13826
  if (id.startsWith('$')) {
13888
13827
  id = id.slice(1);
@@ -13901,6 +13840,9 @@ class DynamicContextParser {
13901
13840
  if (control) {
13902
13841
  control.setValue(val);
13903
13842
  }
13843
+ },
13844
+ get ref() {
13845
+ return control;
13904
13846
  }
13905
13847
  };
13906
13848
  }
@@ -13972,9 +13914,12 @@ class DynamicContextParser {
13972
13914
  class ParagraphMeasure {
13973
13915
  options;
13974
13916
  renderCtx;
13975
- constructor(options, renderCtx) {
13917
+ execute;
13918
+ constructor(options, renderCtx, execute) {
13976
13919
  this.options = options;
13977
13920
  this.renderCtx = renderCtx;
13921
+ this.execute = execute;
13922
+ this.execute = execute;
13978
13923
  }
13979
13924
  /**
13980
13925
  * 段落排版:
@@ -14070,7 +14015,10 @@ class ParagraphMeasure {
14070
14015
  const paraRenders = [];
14071
14016
  for (let i = 0; i < paraModels.length; i++) {
14072
14017
  const innerLineRects = paraModels[i].innerLine;
14073
- let render = p.createRenderObject();
14018
+ let render = this.createRenderObject(p);
14019
+ if (!render) {
14020
+ return [];
14021
+ }
14074
14022
  render.setRenderWidth(limitWidth);
14075
14023
  paraRenders.push(render);
14076
14024
  for (let j = 0; j < innerLineRects.length; j++) {
@@ -14211,7 +14159,7 @@ class ParagraphMeasure {
14211
14159
  }
14212
14160
  arrangeInlineGroupElement(parentLine, ele) {
14213
14161
  const { options, renderCtx } = this;
14214
- let render = ele.createRenderObject({ options, renderCtx });
14162
+ let render = this.createRenderObject(ele);
14215
14163
  //记录多行情况下的渲染对象,用于计算总长度,生成fill-null-space
14216
14164
  const inlineGroupRenders = [];
14217
14165
  ele.cacheRender = render;
@@ -14265,10 +14213,7 @@ class ParagraphMeasure {
14265
14213
  const baseTextProps = ele.props;
14266
14214
  nullText.text = baseTextProps.nullText;
14267
14215
  baseTextProps.nullTextProps.clone(nullText.props);
14268
- const nullTextRender = nullText.createRenderObject({
14269
- options: this.options,
14270
- renderCtx: this.renderCtx
14271
- });
14216
+ const nullTextRender = this.createRenderObject(nullText);
14272
14217
  //inlineGroupRender.insertChild(nullTextRender, 1);
14273
14218
  this.arrangeLeafRender(data, nullTextRender);
14274
14219
  }
@@ -14297,7 +14242,7 @@ class ParagraphMeasure {
14297
14242
  }
14298
14243
  }
14299
14244
  arrangeLeafElement(parentLine, ele) {
14300
- ele.cacheRender = ele.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
14245
+ ele.cacheRender = this.createRenderObject(ele);
14301
14246
  if (ele.cacheRender) {
14302
14247
  this.arrangeLeafRender(parentLine, ele.cacheRender);
14303
14248
  }
@@ -14494,6 +14439,80 @@ class ParagraphMeasure {
14494
14439
  }
14495
14440
  throw new Error('未到达计算位置');
14496
14441
  }
14442
+ /**
14443
+ * 解析可见性表达式
14444
+ * @param ele
14445
+ * @param execute
14446
+ * @private
14447
+ */
14448
+ parseVisibleExpression(ele, execute) {
14449
+ if (ele.visibleExpr)
14450
+ return;
14451
+ if (!ele.attribute?.visibleExpr)
14452
+ return;
14453
+ const reactiveMode = this.renderCtx.drawMode !== 'print';
14454
+ try {
14455
+ const depIdItems = [];
14456
+ const depEleMap = new Map();
14457
+ let compliedCode = parser(ele.attribute?.visibleExpr, depIdItems);
14458
+ compliedCode = addReturn(compliedCode);
14459
+ if (depIdItems.length) {
14460
+ depIdItems.forEach(dep => {
14461
+ const refCtx = execute.getObject(dep);
14462
+ if (refCtx.ref) {
14463
+ const refEle = refCtx.ref.item;
14464
+ depEleMap.set(dep, refCtx);
14465
+ //当前有可能是checkbox数组
14466
+ const refEles = Array.isArray(refEle) ? refEle : [refEle];
14467
+ reactiveMode && refEles.forEach(item => {
14468
+ //求值依赖元素更改的时候,发布当前元素重新计算的指令
14469
+ item.onChangeSubject.subscribe(() => {
14470
+ ele.pubOnChange('self');
14471
+ });
14472
+ });
14473
+ }
14474
+ });
14475
+ }
14476
+ ele.visibleExpr = { compliedCode, func: new Function(`with(this){ ${compliedCode} }`), depItems: depEleMap };
14477
+ }
14478
+ catch (e) {
14479
+ console.error('解析表达式出错', ele.attribute?.visibleExpr);
14480
+ }
14481
+ }
14482
+ /**
14483
+ * 元素可见行求值
14484
+ * @param ele
14485
+ * @param executeCtx
14486
+ * @private
14487
+ */
14488
+ evalVisibleExpr(ele, executeCtx) {
14489
+ if (ele.visibleExpr && ele.visibleExpr.func) {
14490
+ try {
14491
+ executeCtx.setCurrentCtx(ele, ele.visibleExpr.depItems);
14492
+ const func = ele.visibleExpr.func.bind(executeCtx);
14493
+ return func() === true;
14494
+ }
14495
+ catch (e) {
14496
+ console.error(e, "表达式执行出错", ele.visibleExpr.compliedCode);
14497
+ }
14498
+ finally {
14499
+ executeCtx.clearCurrentCtx();
14500
+ }
14501
+ }
14502
+ return true;
14503
+ }
14504
+ createRenderObject(element) {
14505
+ if (this.options.enableVisibleExpression) {
14506
+ this.parseVisibleExpression(element, this.execute);
14507
+ if (!this.evalVisibleExpr(element, this.execute)) {
14508
+ return null;
14509
+ }
14510
+ }
14511
+ return element.createRenderObject({
14512
+ options: this.options,
14513
+ renderCtx: this.renderCtx
14514
+ });
14515
+ }
14497
14516
  }
14498
14517
 
14499
14518
  /**
@@ -14625,6 +14644,8 @@ class DocumentArrange {
14625
14644
  renderCtx;
14626
14645
  seo;
14627
14646
  options;
14647
+ execute;
14648
+ pMeasure;
14628
14649
  constructor(docCtx, renderCtx, seo) {
14629
14650
  this.docCtx = docCtx;
14630
14651
  this.renderCtx = renderCtx;
@@ -14644,10 +14665,12 @@ class DocumentArrange {
14644
14665
  //测量阶段,对于空段落会插入段落符号,新表格会插入空段落,此时不需要记录节点的更改,以最大的节点进行记录
14645
14666
  return suppressTracking(() => {
14646
14667
  const doc = this.docCtx.document;
14668
+ this.execute = new DynamicExecute(doc, this.docCtx.selectionState);
14669
+ this.pMeasure = new ParagraphMeasure(this.options, this.renderCtx, this.execute);
14647
14670
  const data = {
14648
14671
  doc,
14649
14672
  viewOptions: this.options,
14650
- parser: new DynamicContextParser(doc, this.docCtx.selectionState),
14673
+ execute: this.execute,
14651
14674
  createParaFn: () => this.createDefaultPara()
14652
14675
  };
14653
14676
  doc.clearMarkItems();
@@ -14763,15 +14786,6 @@ class DocumentArrange {
14763
14786
  cloneFooterRender.rect.x = limitRect.x;
14764
14787
  cloneFooterRender.rect.y = documentRender.rect.height - bodyMarginBottom;
14765
14788
  currColumn === 0 && documentRender.addChild(cloneFooterRender);
14766
- // //审阅模式,添加审阅窗口
14767
- // if (this.options.showReviewWindow && commentsRender) {
14768
- // const commentsContainer = this.createRenderObject(commentsRender.element) as CommsContainerRenderObject;
14769
- // commentsContainer.padding.top = bodyMarginTop;
14770
- // commentsContainer.rect.height = documentRender.rect.height;
14771
- // documentRender.addChild(commentsContainer);
14772
- // commentsContainer.rect.x = documentRender.rect.x + documentRender.rect.width;
14773
- // documentRender.rect.width += this.options.reviewWindowWidth;
14774
- // }
14775
14789
  currColumn++;
14776
14790
  if (currColumn === docColumns) {
14777
14791
  currColumn = 0;
@@ -14782,7 +14796,7 @@ class DocumentArrange {
14782
14796
  return docPages;
14783
14797
  }
14784
14798
  createEmptyBodyRender(bodyRender, limitRect) {
14785
- const pageBodyRender = this.createRenderObject(bodyRender.element);
14799
+ const pageBodyRender = this.pMeasure.createRenderObject(bodyRender.element);
14786
14800
  pageBodyRender.rect.width = limitRect.width;
14787
14801
  const bodyInnerLimitRect = pageBodyRender.getInnerRect();
14788
14802
  if (this.options.fullPageView) {
@@ -14798,12 +14812,11 @@ class DocumentArrange {
14798
14812
  return element.cacheRender;
14799
14813
  }
14800
14814
  if (element instanceof BlockContentElement) {
14801
- const pRange = new ParagraphMeasure(this.options, this.renderCtx);
14802
- return pRange.measureParagraph(element, maxWidth);
14815
+ return this.pMeasure.measureParagraph(element, maxWidth);
14803
14816
  }
14804
14817
  else if (element instanceof BlockContainerElement) {
14805
14818
  const renders = [];
14806
- let render = this.createRenderObject(element);
14819
+ let render = this.pMeasure.createRenderObject(element);
14807
14820
  if (!render) {
14808
14821
  element.cacheRender = null;
14809
14822
  return null;
@@ -14816,8 +14829,8 @@ class DocumentArrange {
14816
14829
  const innerMaxWidth = render.getInnerMaxWidth();
14817
14830
  for (let i = 0; i < element.length; i++) {
14818
14831
  const child = element.getChild(i);
14819
- const blockContentELement = child;
14820
- const childRender = this.measureControl(blockContentELement, innerMaxWidth);
14832
+ const blockContentElement = child;
14833
+ const childRender = this.measureControl(blockContentElement, innerMaxWidth);
14821
14834
  if (!childRender) {
14822
14835
  continue;
14823
14836
  }
@@ -14827,7 +14840,7 @@ class DocumentArrange {
14827
14840
  }
14828
14841
  for (let j = 0; j < childRender.length; j++) {
14829
14842
  if (j > 0) {
14830
- render = this.createRenderObject(element);
14843
+ render = this.pMeasure.createRenderObject(element);
14831
14844
  if (!render.rect.width) {
14832
14845
  render.setRenderWidth(maxWidth);
14833
14846
  }
@@ -14855,12 +14868,6 @@ class DocumentArrange {
14855
14868
  textLineRenderMode(cacheRender, { options: this.options, renderCtx: this.renderCtx });
14856
14869
  }
14857
14870
  }
14858
- createRenderObject(element) {
14859
- return element.createRenderObject({
14860
- options: this.options,
14861
- renderCtx: this.renderCtx
14862
- });
14863
- }
14864
14871
  getDocInnerRect(documentRender) {
14865
14872
  const render = documentRender.element.createRenderObject();
14866
14873
  render.padding = documentRender.padding;
@@ -14879,7 +14886,7 @@ class DocumentArrange {
14879
14886
  if (render instanceof TableRenderObject) {
14880
14887
  return this.cutTable(render, limitHeight);
14881
14888
  }
14882
- const cloneRender = this.createRenderObject(render.element);
14889
+ const cloneRender = this.pMeasure.createRenderObject(render.element);
14883
14890
  cloneRender.setRenderWidth(render.rect.width);
14884
14891
  if (render instanceof MuiltBlockLineRenderObject) {
14885
14892
  let sumHeight = 0;
@@ -14964,10 +14971,11 @@ class DocumentArrange {
14964
14971
  let currRow = rows[j];
14965
14972
  const cutRows = [];
14966
14973
  while (currRow) {
14974
+ const minHeight = currRow.element.props.minHeight;
14967
14975
  const rowContentHeight = this.getBlockLineHeight(currRow);
14968
14976
  if (rowContentHeight + sumHeight > limitHeight) {
14969
- //行存在最小高度,且当前行跨页的情况下,不截断该行
14970
- if (currRow.element.props.minHeight) {
14977
+ //行存在最小高度,且当前行内容的高度小于最小高度,且当前行跨页的情况下,不截断该行
14978
+ if (minHeight > 0 && minHeight > rowContentHeight) {
14971
14979
  break;
14972
14980
  }
14973
14981
  //限制的外框尺寸
@@ -15055,7 +15063,7 @@ class DocumentArrange {
15055
15063
  for (let i = 0; i < cutCellRenders.length; i++) {
15056
15064
  let cellRender = cutCellRenders[i];
15057
15065
  if (!cellRender) {
15058
- cellRender = this.createRenderObject(cellRenders[i].element);
15066
+ cellRender = this.pMeasure.createRenderObject(cellRenders[i].element);
15059
15067
  cellRender.rect = ElementUtil.cloneRect(cellRenders[i].rect);
15060
15068
  cellRender.rect.height = 0;
15061
15069
  ElementUtil.remeasure(cellRender);
@@ -15200,6 +15208,7 @@ class DocumentArrange {
15200
15208
  }
15201
15209
  }
15202
15210
  clearPaintCache(ele, data) {
15211
+ ele.paintRenders.length = 0;
15203
15212
  ele.beginMeasure(data);
15204
15213
  this.identifyComment(ele);
15205
15214
  if (ele instanceof BranchElement) {
@@ -15227,1105 +15236,65 @@ class DocumentArrange {
15227
15236
  */
15228
15237
  generateCommRange() {
15229
15238
  this.seo.commRangeSets.clear();
15230
- const commMarks = this.docCtx.document.markPairs;
15231
- for (let i = 0; i < commMarks.length; i++) {
15232
- const commMark = commMarks[i];
15233
- if (commMark.start && commMark.end) {
15234
- const ancestor = DocumentSelection.getAncestorCommonControl(commMark.start, commMark.end);
15235
- const range = RangeUtil.getSectionRange(commMark.start, 0, commMark.end, 1, ancestor);
15236
- SelectionOverlays.addToCommentSets(range, this.seo.commRangeSets, commMark.start.color);
15237
- }
15238
- }
15239
- }
15240
- cacheRenders(renderTree) {
15241
- if (renderTree.element) {
15242
- renderTree.element.paintRenders.push(renderTree);
15243
- }
15244
- for (let i = 0; i < renderTree.length; i++) {
15245
- const currRender = renderTree.getChild(i);
15246
- if (currRender.element) {
15247
- this.cacheCommsRender(currRender);
15248
- }
15249
- if (currRender instanceof BranchRenderObject) {
15250
- this.cacheRenders(currRender);
15251
- }
15252
- else {
15253
- currRender.element && currRender.element.paintRenders.push(currRender);
15254
- }
15255
- }
15256
- }
15257
- /**
15258
- * 缓存批注标志
15259
- * @private
15260
- */
15261
- cacheCommsRender(render) {
15262
- if (render.element && render.element.type === 'comm') {
15263
- const commElement = render.element;
15264
- if (commElement.props.markType === 'start') {
15265
- const currDocRender = this.cacheDoc;
15266
- const docCommContainer = currDocRender.getItems().find(item => item instanceof CommsContainerRenderObject);
15267
- if (docCommContainer) {
15268
- docCommContainer.commsMarks.push(render);
15269
- }
15270
- }
15271
- }
15272
- if (render.element && render.element.type === 'comm-list') {
15273
- const commContainer = render;
15274
- CommentsUtil.createCommentsImage(commContainer);
15275
- }
15276
- }
15277
- endMeasures(ele) {
15278
- ele.endMeasure();
15279
- if (ele instanceof BranchElement) {
15280
- for (let i = 0; i < ele.length; i++) {
15281
- this.endMeasures(ele.getChild(i));
15282
- }
15283
- }
15284
- }
15285
- createDefaultPara() {
15286
- const tmp = new ParagraphElement();
15287
- tmp.props.lineHeight = this.options.defaultLineHeight;
15288
- return tmp;
15289
- }
15290
- }
15291
-
15292
- /**
15293
- * 文字行渲染模式
15294
- 用于医嘱打印模式
15295
- */
15296
- function runTextLineRender(ele, data) {
15297
- if (!data.options.textRowLineMode) {
15298
- return;
15299
- }
15300
- if (ele instanceof TableElement) {
15301
- // textLineRenderMode(ele, data);
15302
- // remeasureParentRenders(ele.cacheRender)
15303
- return;
15304
- }
15305
- if (ele instanceof BranchElement) {
15306
- for (let i = 0; i < ele.length; i++) {
15307
- runTextLineRender(ele.getChild(i), data);
15308
- }
15309
- }
15310
- }
15311
-
15312
- /**
15313
- * 测量阶段,生成Render-UI
15314
- */
15315
- class ElementMeasure {
15316
- docCtx;
15317
- renderCtx;
15318
- options;
15319
- constructor(docCtx, renderCtx) {
15320
- this.docCtx = docCtx;
15321
- this.renderCtx = renderCtx;
15322
- this.options = docCtx.viewOptions;
15323
- }
15324
- measureDocument(document) {
15325
- //测量阶段,对于空段落会插入段落符号,新表格会插入空段落,此时不需要记录节点的更改,以最大的节点进行记录
15326
- return suppressTracking(() => {
15327
- this.clearPaintCache(document, {
15328
- doc: document,
15329
- viewOptions: this.options,
15330
- parser: new DynamicContextParser(document, this.docCtx.selectionState),
15331
- createParaFn: () => new ParagraphElement()
15332
- });
15333
- const docRender = this.measureControl(document, this.options.docPageSettings.width);
15334
- this.setMeasureCompletedModifyFlag(document);
15335
- runTextLineRender(document, { options: this.options, renderCtx: this.renderCtx });
15336
- return docRender;
15337
- });
15338
- }
15339
- measureControl(element, maxWidth) {
15340
- if (element.modifyFlag === ModifyFlag$1.None) {
15341
- return element.cacheRender;
15342
- }
15343
- if (element instanceof BlockContentElement) {
15344
- const render = element.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
15345
- element.cacheRender = render;
15346
- //测量阶段,只限制最大宽度即可
15347
- render.setRenderWidth(maxWidth);
15348
- if (element instanceof ParagraphElement) {
15349
- this.measureParagraph(element, render);
15350
- }
15351
- else {
15352
- throw new Error('未实现');
15353
- }
15354
- return render;
15355
- }
15356
- else if (element instanceof BlockContainerElement) {
15357
- //ElementUtil.fixBlockContainer(element);
15358
- let render = null;
15359
- if (element.modifyFlag === ModifyFlag$1.Modify || element.modifyFlag === ModifyFlag$1.Track) {
15360
- //ElementUtil.fixBlockContainer(element);
15361
- element.cacheRender = null;
15362
- render = element.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
15363
- if (!render) {
15364
- element.cacheRender = null;
15365
- return null;
15366
- }
15367
- if (!render.rect.width) {
15368
- render.setRenderWidth(maxWidth);
15369
- }
15370
- }
15371
- if (!render) {
15372
- throw new Error('render is null');
15373
- }
15374
- element.cacheRender = render;
15375
- const innerMaxWidth = render.getInnerMaxWidth();
15376
- for (let i = 0; i < element.length; i++) {
15377
- const child = element.getChild(i);
15378
- const blockContentELement = child;
15379
- const childRender = this.measureControl(blockContentELement, innerMaxWidth);
15380
- if (!childRender) {
15381
- continue;
15382
- }
15383
- render.addChild(childRender);
15384
- }
15385
- ElementUtil.remeasure(render);
15386
- return render;
15387
- }
15388
- else {
15389
- throw new Error('未实现');
15390
- }
15391
- }
15392
- /**
15393
- * 生成段落 UI 树
15394
- * @param para
15395
- * @param render
15396
- */
15397
- measureParagraph(para, render) {
15398
- ElementUtil.fixParagraphContent(para);
15399
- const renderObjects = [];
15400
- for (let i = 0; i < para.length; i++) {
15401
- const child = para.getChild(i);
15402
- if (child instanceof InlineGroupElement) {
15403
- child.cacheRender = this.getInlineGroupRenderItem(child);
15404
- if (child.cacheRender) {
15405
- renderObjects.push(child.cacheRender);
15406
- }
15407
- }
15408
- else if (child instanceof LeafElement) {
15409
- child.cacheRender = child.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
15410
- if (child.cacheRender) {
15411
- renderObjects.push(child.cacheRender);
15412
- }
15413
- }
15414
- }
15415
- this.measureInnerParagraph(render, para, renderObjects);
15416
- }
15417
- /**
15418
- * 根据段落UI元素,进行排列
15419
- * @param render
15420
- * @param paragraph
15421
- * @param renderObjects
15422
- */
15423
- measureInnerParagraph(render, paragraph, renderObjects) {
15424
- return;
15425
- // let lineRect = render.createLineRect();
15426
- // let maxLineWidth=render.rect.width;
15427
- // //行内框
15428
- // const innerLineRects: Array<ParagraphLineRectRenderObject> = [];
15429
- // const addInnerLineFunc = (lineRect: ParagraphLineRectRenderObject): void => {
15430
- // maxLineWidth=render.rect.width;
15431
- // innerLineRects.push(lineRect);
15432
- // if (innerLineRects.indexOf(lineRect) === 0) {
15433
- // if (paragraph.props.indent > 0) {
15434
- // maxLineWidth -= paragraph.props.indent;
15435
- // }
15436
- // } else {
15437
- // maxLineWidth -= paragraph.props.hanging;
15438
- // }
15439
- // };
15440
- // addInnerLineFunc(lineRect);
15441
- // let i = 0;
15442
- // let currItem = renderObjects[i++];
15443
- // const inCloseBody = paragraph.parent.type === 'body';
15444
- // while (currItem) {
15445
- // const maxWidth = maxLineWidth;
15446
- // const nextItem = renderObjects[i];
15447
- // const {
15448
- // firstItem,
15449
- // lastItem,
15450
- // br
15451
- // } = this.cutRenderItem(currItem, nextItem, maxWidth - lineRect.rect.width, lineRect.length === 0, inCloseBody);
15452
- // if (firstItem) {
15453
- // if (lastItem) {
15454
- // renderObjects.splice(i, 0, lastItem);
15455
- // }
15456
- // currItem = firstItem;
15457
- // } else {
15458
- // lineRect = render.createLineRect();
15459
- // addInnerLineFunc(lineRect);
15460
- // continue;
15461
- // }
15462
- // lineRect.addChild(currItem);
15463
- // currItem.rect.x = lineRect.rect.width;
15464
- // if (currItem.rect.height > lineRect.rect.height) {
15465
- // lineRect.rect.height = currItem.rect.height;
15466
- // }
15467
- // lineRect.rect.width += currItem.rect.width;
15468
- // if (br) {
15469
- // //lineRect.rect.maxWidth = lineRect.rect.width;
15470
- // lineRect = render.createLineRect();
15471
- // addInnerLineFunc(lineRect);
15472
- // }
15473
- // currItem = renderObjects[i++];
15474
- // }
15475
- // for (let i = 0; i < innerLineRects.length; i++) {
15476
- // const innerLineRect = innerLineRects[i] as ParagraphLineRectRenderObject;
15477
- // innerLineRect.rect.x = this.getParaLineRectStartX(innerLineRects.length, i, paragraph, render, innerLineRect);
15478
- // //限制最大行高
15479
- // const maxLineHeight = paragraph.props.lineHeight !== this.options.defaultLineHeight ? 100 : Math.floor(14 * 2);
15480
- // //fillLineHeight填充行高
15481
- // let fillLineHeight = Math.ceil(innerLineRect.rect.height * (paragraph.props.lineHeight - 1));
15482
- // fillLineHeight = fillLineHeight > maxLineHeight ? maxLineHeight : fillLineHeight;
15483
- // const lineHeight = innerLineRect.rect.height + fillLineHeight;
15484
- // const paddingBottom = Math.ceil(fillLineHeight / 2);
15485
- // innerLineRect.rect.height = lineHeight;
15486
- // for (let j = 0; j < innerLineRect.length; j++) {
15487
- // const leaf = innerLineRect.getChild(j);
15488
- // leaf.rect.y = innerLineRect.rect.height - paddingBottom - leaf.rect.height;
15489
- // }
15490
- // //render.rect.height += lineRect.rect.height;
15491
- // const outterLineRect = render.createLineRect();
15492
- // outterLineRect.rect.width = render.rect.width;
15493
- // outterLineRect.addChild(innerLineRect);
15494
- // ElementUtil.remeasure(outterLineRect, false);
15495
- // render.addChild(outterLineRect);
15496
- // }
15497
- // ElementUtil.remeasure(render);
15498
- }
15499
- /**
15500
- * 获取段落行布局横向坐标起始位置,被段落text-align影响
15501
- */
15502
- getParaLineRectStartX(counter, paraLineIndex, paraElement, paraRenderObject, paraLineRender) {
15503
- //左对齐,首行缩进
15504
- let indent = paraElement.props.indent;
15505
- //存在项目符号
15506
- if (paraLineIndex > 0) {
15507
- indent = paraElement.props.hanging;
15508
- }
15509
- if (paraElement.props.textAlign === 'center') {
15510
- const remainSpace = paraRenderObject.rect.width - paraLineRender.rect.width;
15511
- return Math.ceil(remainSpace / 2) + indent;
15512
- }
15513
- else if (paraElement.props.textAlign === 'right') {
15514
- const remainSpace = paraRenderObject.rect.width - paraLineRender.rect.width;
15515
- return remainSpace + indent;
15516
- }
15517
- else if (paraElement.props.textAlign === 'justify') {
15518
- const renderUnitCount = this.getRenderUnitLength(paraLineRender);
15519
- if (paraLineIndex === counter - 1 || renderUnitCount === 1) {
15520
- return indent;
15521
- }
15522
- const spaceWidth = (paraRenderObject.rect.width - paraLineRender.rect.width) / (renderUnitCount - 1);
15523
- this.setAlignJustify(paraLineRender, 0, spaceWidth);
15524
- return indent;
15525
- }
15526
- else {
15527
- return indent;
15528
- }
15529
- }
15530
- /**
15531
- * 设置两端对齐
15532
- * @param render
15533
- * @param count
15534
- * @param spaceWidth
15535
- */
15536
- setAlignJustify(render, count, spaceWidth) {
15537
- if (render instanceof BranchRenderObject) {
15538
- let width = 0;
15539
- for (let i = 0; i < render.length; i++) {
15540
- const currRender = render.getChild(i);
15541
- count += this.setAlignJustify(currRender, count, spaceWidth);
15542
- currRender.rect.x = width;
15543
- width += currRender.rect.width;
15544
- }
15545
- render.rect.width = width;
15546
- }
15547
- else if (render instanceof LeafRenderObject) {
15548
- if (render instanceof TextGroupRenderObject) {
15549
- let i = count === 0 ? 1 : 0;
15550
- for (; i < render.textMeasures.length; i++) {
15551
- render.textMeasures[i].actualSize = render.textMeasures[i].actualSize + spaceWidth;
15552
- }
15553
- render.measure();
15554
- count += render.textMeasures.length;
15555
- }
15556
- else {
15557
- if (count !== 0) {
15558
- render.rect.width += spaceWidth;
15559
- }
15560
- count += 1;
15561
- }
15562
- }
15563
- return count;
15564
- }
15565
- /**
15566
- * 获取段落行渲染单位个数,字符需要计算为字符长度
15567
- */
15568
- getRenderUnitLength(paraLine) {
15569
- if (paraLine instanceof LeafRenderObject) {
15570
- if (paraLine instanceof TextGroupRenderObject) {
15571
- return paraLine.textMeasures.length;
15572
- }
15573
- else {
15574
- return 1;
15575
- }
15576
- }
15577
- else if (paraLine instanceof BranchRenderObject) {
15578
- let count = 0;
15579
- for (let i = 0; i < paraLine.length; i++) {
15580
- count += this.getRenderUnitLength(paraLine.getChild(i));
15581
- }
15582
- return count;
15583
- }
15584
- throw new Error('未到达计算位置');
15585
- }
15586
- getInlineGroupRenderItem(item) {
15587
- const inlineGroupRender = item.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
15588
- if (!inlineGroupRender) {
15589
- return null;
15590
- }
15591
- for (let i = 0; i < item.length; i++) {
15592
- const child = item.getChild(i);
15593
- if (child instanceof LeafElement) {
15594
- child.cacheRender = child.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
15595
- if (child.cacheRender) {
15596
- inlineGroupRender.addChild(child.cacheRender);
15597
- }
15598
- }
15599
- else if (child instanceof InlineGroupElement) {
15600
- item.cacheRender = this.getInlineGroupRenderItem(child);
15601
- if (item.cacheRender) {
15602
- inlineGroupRender.addChild(item.cacheRender);
15603
- }
15604
- }
15605
- else {
15606
- throw new Error('未实现');
15607
- }
15608
- }
15609
- ElementUtil.remeasureInlineGroupRender(inlineGroupRender);
15610
- //限制最小长度
15611
- if (item instanceof DataElementInlineGroup) {
15612
- //需要填充null-text
15613
- if (item.length === 2) {
15614
- const nullText = new TextGroupElement();
15615
- nullText.isDecorate = true;
15616
- nullText.disableClick = true;
15617
- const baseTextProps = item.props;
15618
- nullText.text = baseTextProps.nullText;
15619
- baseTextProps.nullTextProps.clone(nullText.props);
15620
- const nullTextRender = nullText.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
15621
- inlineGroupRender.insertChild(nullTextRender, 1);
15622
- ElementUtil.remeasureInlineGroupRender(inlineGroupRender);
15623
- }
15624
- const props = item.props;
15625
- let minLength = props.minLength ?? 14;
15626
- minLength = minLength < 14 ? 14 : minLength;
15627
- if (item instanceof DataElementInlineGroup && inlineGroupRender.rect.width < minLength) {
15628
- const fillNullSpace = new FillNullSpaceRenderObject();
15629
- fillNullSpace.rect.width = minLength - inlineGroupRender.rect.width;
15630
- fillNullSpace.rect.height = inlineGroupRender.rect.height;
15631
- inlineGroupRender.insertChild(fillNullSpace, inlineGroupRender.length - 1);
15632
- }
15633
- ElementUtil.remeasureInlineGroupRender(inlineGroupRender);
15634
- }
15635
- return inlineGroupRender;
15636
- }
15637
- cutRenderItem(render, nextRender, limitWidth, lineEmpty, inCloseBody) {
15638
- if (render instanceof LeafRenderObject) {
15639
- if (render.rect.width > limitWidth && render instanceof TextGroupRenderObject) {
15640
- return this.cutTextRender(render, nextRender, limitWidth, lineEmpty, inCloseBody);
15641
- }
15642
- if (render instanceof FillNullSpaceRenderObject) {
15643
- return this.cutFillNullRender(render, limitWidth);
15644
- }
15645
- if (render.rect.width < limitWidth || lineEmpty || render.element.type === 'br' || render.element.type === 'psym') {
15646
- return { firstItem: render, lastItem: null, br: render.element.type === 'br' };
15647
- }
15648
- return { firstItem: null, lastItem: null };
15649
- }
15650
- else if (render instanceof InlineGroupRenderObject) {
15651
- return this.cutInlineGroupRenderItem(render, limitWidth, lineEmpty, inCloseBody);
15652
- }
15653
- throw new Error('到达计算边界');
15654
- }
15655
- cutTextRender(render, nextRender, limitWidth, lineEmpty, inCloseBody) {
15656
- let sumWidth = 0;
15657
- const cutRender = render.clone();
15658
- cutRender.textMeasures.length = 0;
15659
- let i = 0;
15660
- for (; i < render.textMeasures.length; i++) {
15661
- sumWidth += render.textMeasures[i].actualSize;
15662
- if (sumWidth > limitWidth) {
15663
- if (lineEmpty && i === 0) {
15664
- i = 1;
15665
- }
15666
- break;
15667
- }
15668
- }
15669
- //后置标点处理
15670
- i = this.patchHandlePostPunctuation(render, nextRender, i, inCloseBody, lineEmpty);
15671
- //前置标点处理
15672
- i = this.patchHandleLeadingPunctuation(render, i, lineEmpty);
15673
- if (i <= 0) {
15674
- return { firstItem: null, lastItem: null };
15675
- }
15676
- cutRender.textMeasures = render.textMeasures.splice(0, i);
15677
- render.measure();
15678
- cutRender.measure();
15679
- return { firstItem: cutRender, lastItem: render, br: true };
15680
- }
15681
- /**
15682
- * 处理前置标点,前置标点不能出现在末尾
15683
- * @param render
15684
- * @param i
15685
- */
15686
- patchHandleLeadingPunctuation(render, i, lineEmpty) {
15687
- if (i === 1 && lineEmpty) {
15688
- return i;
15689
- }
15690
- if (this.containLeadingPunctuation(render.textMeasures[i]?.char)) {
15691
- return i--;
15692
- }
15693
- return i;
15694
- }
15695
- /**
15696
- * 处理后置标点,后置标点不能出现在行首
15697
- * @param render
15698
- * @param i
15699
- * @param lineEmpty
15700
- */
15701
- patchHandlePostPunctuation(render, nextRender, i, inCloseBody, lineEmpty) {
15702
- if (i === render.textMeasures.length - 1) {
15703
- //紧跟着的字符包含后置标点
15704
- if (this.containerStartSymbolInTextStart(nextRender)) {
15705
- i--;
15706
- }
15707
- }
15708
- if (inCloseBody && this.containPostPunctuation(render.textMeasures[i]?.char)) {
15709
- if (this.containPostPunctuation(render.textMeasures[i + 1]?.char)) {
15710
- i--;
15711
- }
15712
- else {
15713
- i++;
15714
- }
15715
- }
15716
- else {
15717
- if (i > 1 && this.containPostPunctuation(render.textMeasures[i]?.char)) {
15718
- i--;
15719
- }
15720
- }
15721
- return i;
15722
- }
15723
- /**
15724
- * 是否包含后置标点
15725
- * @param str
15726
- * @returns
15727
- */
15728
- containPostPunctuation(str) {
15729
- return '!),.:;?]}¨·ˇˉ―‖’”…∶、。〃々〉》」』】〕〗!"'),.:;?]`|}~¢'.indexOf(str) > -1;
15730
- }
15731
- //是否包含前置标点
15732
- containLeadingPunctuation(str) {
15733
- return '‘“〈《「『【〔〖([{£'.indexOf(str) > -1;
15734
- }
15735
- /**
15736
- * 文本开头是否包含后置标点
15737
- * @param render
15738
- * @returns
15739
- */
15740
- containerStartSymbolInTextStart(render) {
15741
- //return false;
15742
- if (render instanceof TextGroupRenderObject) {
15743
- if (render.textMeasures.length > 0) {
15744
- return this.containPostPunctuation(render.textMeasures[0].char);
15745
- }
15746
- }
15747
- return false;
15748
- }
15749
- cutFillNullRender(render, limitWidth) {
15750
- if (limitWidth === 0) {
15751
- return { firstItem: null, lastItem: null };
15752
- }
15753
- if (render.rect.width > limitWidth) {
15754
- const cutRender = new FillNullSpaceRenderObject();
15755
- cutRender.rect.width = limitWidth;
15756
- cutRender.rect.height = render.rect.height;
15757
- render.rect.width = render.rect.width - limitWidth;
15758
- return { firstItem: cutRender, lastItem: render };
15759
- }
15760
- else {
15761
- return { firstItem: render, lastItem: null };
15762
- }
15763
- }
15764
- /**
15765
- * 行内编组元素超出行内可用空间,需要根据剩余空间长度进行截断
15766
- */
15767
- cutInlineGroupRenderItem(render, limitWidth, emptyLine, inCloseBody) {
15768
- const cutRender = render.element.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
15769
- let x = 0;
15770
- let br = false;
15771
- const items = [...render.getItems()];
15772
- for (let i = 0; i < items.length; i++) {
15773
- const child = items[i];
15774
- if (child instanceof LeafRenderObject) {
15775
- if (x + child.rect.width > limitWidth) {
15776
- const { firstItem, lastItem, br: childBr } = this.cutRenderItem(child, items[i + 1], limitWidth - x, emptyLine && cutRender.length === 0, inCloseBody);
15777
- if (firstItem) {
15778
- cutRender.addChild(firstItem);
15779
- }
15780
- br = childBr || br;
15781
- break;
15782
- }
15783
- else {
15784
- render.removeChild(child);
15785
- cutRender.addChild(child);
15786
- }
15787
- //软换行符
15788
- if (child.element && child.element.type === 'br') {
15789
- br = true;
15790
- break;
15791
- }
15792
- }
15793
- else if (child instanceof InlineGroupRenderObject) {
15794
- if (x + child.rect.width > limitWidth) {
15795
- const { firstItem, br: childBr } = this.cutInlineGroupRenderItem(child, limitWidth - x, emptyLine && cutRender.length === 0, inCloseBody);
15796
- if (firstItem) {
15797
- cutRender.addChild(firstItem);
15798
- }
15799
- br = childBr || br;
15800
- break;
15801
- }
15802
- else {
15803
- render.removeChild(child);
15804
- cutRender.addChild(child);
15805
- }
15806
- }
15807
- x += child.rect.width;
15808
- }
15809
- if (!cutRender.length) {
15810
- return { firstItem: null, lastItem: null };
15811
- }
15812
- ElementUtil.remeasureInlineGroupRender(cutRender);
15813
- ElementUtil.remeasureInlineGroupRender(render);
15814
- return { firstItem: cutRender, lastItem: render.length ? render : null, br };
15815
- }
15816
- /**
15817
- * 修改测量完毕后的元素状态
15818
- * @param ele
15819
- */
15820
- setMeasureCompletedModifyFlag(ele) {
15821
- if (ele instanceof BranchElement) {
15822
- for (let i = 0; i < ele.length; i++) {
15823
- this.setMeasureCompletedModifyFlag(ele.getChild(i));
15824
- }
15825
- }
15826
- ele.modifyFlag = ModifyFlag$1.None;
15827
- }
15828
- clearPaintCache(ele, data) {
15829
- ele.beginMeasure(data);
15830
- if (ele instanceof BranchElement) {
15831
- for (let i = 0; i < ele.length; i++) {
15832
- this.clearPaintCache(ele.getChild(i), data);
15833
- }
15834
- }
15835
- }
15836
- endMeasures(ele) {
15837
- if (ele instanceof BranchElement) {
15838
- for (let i = 0; i < ele.length; i++) {
15839
- this.endMeasures(ele.getChild(i));
15840
- }
15841
- }
15842
- }
15843
- }
15844
-
15845
- class ElementRenderCut {
15846
- options;
15847
- renderContext;
15848
- constructor(options, renderContext) {
15849
- this.options = options;
15850
- this.renderContext = renderContext;
15851
- }
15852
- cutPage(documentRender, documentElement) {
15853
- if (this.options.fullPageView) {
15854
- return this.getFullViewDocRender(documentRender, documentElement);
15855
- }
15856
- const headerRender = documentRender.getChild(0);
15857
- const bodyRender = documentRender.getChild(1).clone();
15858
- const footerRender = documentRender.getChild(2);
15859
- const commentsRender = documentRender.getChild(3);
15860
- const { headerLine, footerLine } = documentRender;
15861
- let bodyMarginTop = headerLine + headerRender.rect.height + 6;
15862
- let bodyMarginBottom = footerLine + footerRender.rect.height;
15863
- const { top: bodyTop, bottom: bodyBottom } = documentRender.padding;
15864
- bodyMarginTop = bodyMarginTop > bodyTop ? bodyMarginTop : bodyTop;
15865
- bodyMarginBottom = bodyMarginBottom > bodyBottom ? bodyMarginBottom : bodyBottom;
15866
- documentRender.padding.top = bodyMarginTop;
15867
- documentRender.padding.bottom = bodyMarginBottom;
15868
- const bodyLimitRect = this.getDocInnerRect(documentRender);
15869
- const bodyArray = [];
15870
- let { emptyBody: pageBodyRender, innerRect: bodyInnerLimitRect } = this.createEmptyBodyRender(bodyRender, bodyLimitRect);
15871
- bodyArray.push(pageBodyRender);
15872
- const createBodyHolder = () => {
15873
- const { emptyBody, innerRect } = this.createEmptyBodyRender(bodyRender, bodyLimitRect);
15874
- pageBodyRender = emptyBody;
15875
- bodyInnerLimitRect = innerRect;
15876
- bodyArray.push(pageBodyRender);
15877
- };
15878
- const appendToBody = (item) => {
15879
- item.rect.y = bodyInnerLimitRect.height + item.margin.top;
15880
- pageBodyRender.addChild(item);
15881
- bodyInnerLimitRect.height += item.rect.height + item.margin.top + item.margin.bottom;
15882
- //上一个元素的bottom-margin
15883
- //bodyInnerLimitRect.prevMargin = item.margin.bottom;
15884
- ElementUtil.updateRenderHeightByInnerRect(pageBodyRender, bodyInnerLimitRect);
15885
- };
15886
- let i = 0;
15887
- let cloneBlockContentRender = bodyRender.getChild(i);
15888
- while (cloneBlockContentRender) {
15889
- if (bodyInnerLimitRect.maxHeight - bodyInnerLimitRect.height - cloneBlockContentRender.rect.height - cloneBlockContentRender.margin.bottom - cloneBlockContentRender.margin.top < 0) {
15890
- //限制的外框尺寸
15891
- const bodyAvailHeight = bodyInnerLimitRect.maxHeight - bodyInnerLimitRect.height - cloneBlockContentRender.margin.bottom - cloneBlockContentRender.margin.top;
15892
- //限制的内框尺寸
15893
- const limitRenderInnterHeight = ElementUtil.innerRectMaxHeight(cloneBlockContentRender, bodyAvailHeight);
15894
- const cutRenderObject = this.cutRenderItem(cloneBlockContentRender, limitRenderInnterHeight);
15895
- //至少有一个块级行元素被切割出来
15896
- if (cutRenderObject) {
15897
- appendToBody(cutRenderObject);
15898
- }
15899
- createBodyHolder();
15900
- }
15901
- else {
15902
- appendToBody(cloneBlockContentRender);
15903
- if (++i < bodyRender.length) {
15904
- cloneBlockContentRender = bodyRender.getChild(i);
15905
- }
15906
- else {
15907
- cloneBlockContentRender = null;
15908
- }
15909
- }
15910
- }
15911
- const docPages = [];
15912
- let pageY = this.options.docSpace;
15913
- for (let i = 0; i < bodyArray.length; i++) {
15914
- const body = bodyArray[i];
15915
- const documentRender = documentElement.createRenderObject();
15916
- docPages.push(documentRender);
15917
- documentRender.rect.y = pageY;
15918
- const limitRect = documentRender.getInnerRect();
15919
- const cloneHeaderRender = headerRender.clone();
15920
- cloneHeaderRender.rect.x = limitRect.x;
15921
- cloneHeaderRender.rect.y = headerLine;
15922
- documentRender.addChild(cloneHeaderRender);
15923
- body.rect.x = limitRect.x;
15924
- body.rect.y = bodyMarginTop;
15925
- body.rect.height = bodyInnerLimitRect.maxHeight;
15926
- documentRender.addChild(body);
15927
- pageY += documentRender.rect.height + this.options.docSpace;
15928
- const cloneFooterRender = footerRender.clone();
15929
- cloneFooterRender.rect.x = limitRect.x;
15930
- cloneFooterRender.rect.y = documentRender.rect.height - bodyMarginBottom;
15931
- documentRender.addChild(cloneFooterRender);
15932
- //审阅模式,添加审阅窗口
15933
- if (this.options.showReviewWindow && commentsRender) {
15934
- const commentsContainer = commentsRender.element.createRenderObject({
15935
- options: this.options,
15936
- renderCtx: this.renderContext
15937
- });
15938
- commentsContainer.padding.top = bodyMarginTop;
15939
- commentsContainer.rect.height = documentRender.rect.height;
15940
- documentRender.addChild(commentsContainer);
15941
- commentsContainer.rect.x = documentRender.rect.x + documentRender.rect.width;
15942
- documentRender.rect.width += this.options.reviewWindowWidth;
15943
- }
15944
- }
15945
- return docPages;
15946
- }
15947
- getDocInnerRect(documentRender) {
15948
- const render = documentRender.element.createRenderObject({
15949
- options: this.options,
15950
- renderCtx: this.renderContext
15951
- });
15952
- render.padding = documentRender.padding;
15953
- return render.getInnerRect();
15954
- }
15955
- getFullViewDocRender(documentRender, documentElement) {
15956
- const commentsRender = documentRender.getChild(3);
15957
- const commentsContainer = commentsRender.element.createRenderObject({
15958
- options: this.options,
15959
- renderCtx: this.renderContext
15960
- });
15961
- documentRender.rect.height -= commentsContainer.rect.height;
15962
- const bodyRender = documentRender.getChild(1);
15963
- if (this.options.showReviewWindow) {
15964
- documentRender.removeChild(commentsRender);
15965
- documentRender.addChild(commentsContainer);
15966
- commentsContainer.padding.top = bodyRender.rect.y;
15967
- commentsContainer.rect.height = documentRender.rect.height;
15968
- commentsContainer.rect.x = documentRender.rect.x + documentRender.rect.width;
15969
- documentRender.rect.width += this.options.reviewWindowWidth;
15970
- }
15971
- return [documentRender];
15972
- }
15973
- createEmptyBodyRender(bodyRender, limitRect) {
15974
- const pageBodyRender = bodyRender.element.createRenderObject({
15975
- options: this.options,
15976
- renderCtx: this.renderContext
15977
- });
15978
- pageBodyRender.rect.width = limitRect.width;
15979
- const bodyInnerLimitRect = pageBodyRender.getInnerRect();
15980
- if (this.options.fullPageView) {
15981
- bodyInnerLimitRect.height = Number.MAX_VALUE;
15982
- }
15983
- return {
15984
- emptyBody: pageBodyRender,
15985
- innerRect: { ...bodyInnerLimitRect, prevMargin: 0, maxWidth: limitRect.width, maxHeight: limitRect.height }
15986
- };
15987
- }
15988
- /**
15989
- * 切割渲染元素
15990
- * @param render 被切割的对象
15991
- * @param limitHeight
15992
- * @returns
15993
- */
15994
- cutRenderItem(render, limitHeight) {
15995
- if (render instanceof TableRowRenderObject) {
15996
- return this.cutRowRenderItem(render, limitHeight);
15997
- }
15998
- if (render instanceof TableRenderObject) {
15999
- return this.cutTable(render, limitHeight);
16000
- }
16001
- const cloneRender = render.element.createRenderObject({
16002
- options: this.options,
16003
- renderCtx: this.renderContext
16004
- });
16005
- cloneRender.setRenderWidth(render.rect.width);
16006
- if (render instanceof MuiltBlockLineRenderObject) {
16007
- let sumHeight = 0;
16008
- const children = [...render.getItems()];
16009
- let j = 0;
16010
- let blockLine = children[j];
16011
- while (blockLine) {
16012
- //sumHeight = ElementUtil.remeasure(cloneRender);
16013
- const calcBlockLineHeight = this.getBlockLineHeight(blockLine);
16014
- if (calcBlockLineHeight + sumHeight > limitHeight) {
16015
- if (blockLine instanceof MuiltBlockLineRenderObject) {
16016
- //限制的外框尺寸
16017
- const availHeight = limitHeight - sumHeight;
16018
- //限制的内框尺寸
16019
- const limitRenderInnterHeight = ElementUtil.innerRectMaxHeight(render, availHeight);
16020
- const cutRenderObject = this.cutRenderItem(blockLine, limitRenderInnterHeight);
16021
- if (cutRenderObject) {
16022
- cloneRender.addChild(cutRenderObject);
16023
- sumHeight += cutRenderObject.rect.height;
16024
- blockLine = children[++j];
16025
- break;
16026
- }
16027
- else {
16028
- break;
16029
- }
16030
- }
16031
- else {
16032
- break;
16033
- }
16034
- }
16035
- else {
16036
- render.removeChild(blockLine);
16037
- cloneRender.addChild(blockLine);
16038
- sumHeight += blockLine.rect.height;
16039
- blockLine = children[++j];
16040
- }
16041
- }
16042
- ElementUtil.remeasure(cloneRender);
16043
- ElementUtil.remeasure(render);
16044
- if (cloneRender.length === 0) {
16045
- return null;
16046
- }
16047
- else {
16048
- return cloneRender;
16049
- }
16050
- }
16051
- else {
16052
- throw new Error('未实现');
16053
- }
16054
- }
16055
- /**
16056
- * 切割渲染元素
16057
- * @param tbRender 被切割的对象
16058
- * @param limitHeight
16059
- * @param addFunc
16060
- * @returns
16061
- */
16062
- cutTable(tbRender, limitHeight) {
16063
- const cloneTbRender = tbRender.element.createRenderObject();
16064
- cloneTbRender.setRenderWidth(tbRender.rect.width);
16065
- let sumHeight = 0;
16066
- const rows = [...tbRender.getItems()];
16067
- //获取跨页需要重复显示的行
16068
- const headerRows = this.getHeaderRows(tbRender);
16069
- //跨页头的高度
16070
- const headerHeight = headerRows.reduce((prev, curr) => prev + curr.rect.height, 0);
16071
- if (headerHeight > limitHeight) {
16072
- return null;
16073
- }
16074
- const copyHeaderRows = headerRows.map(item => item.clone());
16075
- //获取最后一个截断行,需要根据截断行判断最后一个截断的行位置
16076
- const cutOffRows = rows.filter(row => limitHeight >= row.rect.y && limitHeight <= row.rect.y + row.rect.height)
16077
- .map((row) => ({ rowIndex: row.element.getIndex(), row }))
16078
- .sort((first, second) => second.rowIndex - first.rowIndex);
16079
- if (cutOffRows.length === 0) {
16080
- throw new Error('无法获取截断行');
16081
- }
16082
- const joinRow = cutOffRows[0].row;
16083
- let j = 0;
16084
- let currRow = rows[j];
16085
- const cutRows = [];
16086
- while (currRow) {
16087
- const rowContentHeight = this.getBlockLineHeight(currRow);
16088
- if (rowContentHeight + sumHeight > limitHeight) {
16089
- if (currRow instanceof MuiltBlockLineRenderObject) {
16090
- //限制的外框尺寸
16091
- const availHeight = limitHeight - sumHeight;
16092
- //限制的内框尺寸
16093
- const limitRenderInnterHeight = ElementUtil.innerRectMaxHeight(tbRender, availHeight);
16094
- const cutRow = this.cutRowRenderItem(currRow, limitRenderInnterHeight);
16095
- if (cutRow) {
16096
- cloneTbRender.addChild(cutRow);
16097
- sumHeight += cutRow.rect.height;
16098
- cutRows.push(currRow);
16099
- if (currRow === joinRow) {
16100
- break;
16101
- }
16102
- currRow = rows[++j];
16103
- }
16104
- else {
16105
- break;
16106
- }
16107
- }
16108
- else {
16109
- break;
16110
- }
16111
- }
16112
- else {
16113
- tbRender.removeChild(currRow);
16114
- cloneTbRender.addChild(currRow);
16115
- sumHeight += currRow.rect.height;
16116
- currRow = rows[++j];
16117
- }
16118
- }
16119
- this.fixCutTable(tbRender, cutRows);
16120
- ElementUtil.remeasure(cloneTbRender);
16121
- //存在跨页需要重复显示的行头,则需要重新放置行头
16122
- if (copyHeaderRows.length) {
16123
- copyHeaderRows.forEach((r, i) => tbRender.insertChild(r, i));
16124
- }
16125
- ElementUtil.remeasure(tbRender);
16126
- if (cloneTbRender.length === 0) {
16127
- return null;
16128
- }
16129
- else {
16130
- return cloneTbRender;
16131
- }
16132
- }
16133
- cutRowRenderItem(render, limitHeight) {
16134
- if (render.element.props.minHeight > 0 && render.rect.height > limitHeight) {
16135
- return null;
16136
- }
16137
- const cloneRowRender = render.element.createRenderObject();
16138
- cloneRowRender.rect.width = render.rect.width;
16139
- render.remeasureState = true;
16140
- //cloneRowRender.rect.maxWidth = render.rect.height;
16141
- const cellRenders = [...render.getItems()];
16142
- const cutCellRenders = [];
16143
- for (let i = 0; i < cellRenders.length; i++) {
16144
- const cellRender = cellRenders[i];
16145
- this.markMergeRowRenderDirty(cellRender);
16146
- if (cellRender.rect.height > limitHeight) {
16147
- //限制的内框尺寸
16148
- const limitCellHeight = ElementUtil.innerRectMaxHeight(cellRender, limitHeight);
16149
- const cutCellRender = this.cutRenderItem(cellRender, limitCellHeight);
16150
- if (cutCellRender) {
16151
- cutCellRenders.push(cutCellRender);
16152
- }
16153
- else {
16154
- cutCellRenders.push(null);
16155
- }
16156
- }
16157
- else {
16158
- const cloneCellRender = cellRender;
16159
- render.removeChild(cellRender);
16160
- cutCellRenders.push(cloneCellRender);
16161
- }
16162
- }
16163
- ElementUtil.remeasure(render);
16164
- if (cutCellRenders.filter(item => item).length === 0) {
16165
- return null;
16166
- }
16167
- else {
16168
- //补齐单元格
16169
- for (let i = 0; i < cutCellRenders.length; i++) {
16170
- let cellRender = cutCellRenders[i];
16171
- if (!cellRender) {
16172
- cellRender = cellRenders[i].element.createRenderObject({
16173
- options: this.options,
16174
- renderCtx: this.renderContext
16175
- });
16176
- cellRender.rect = ElementUtil.cloneRect(cellRenders[i].rect);
16177
- ElementUtil.remeasure(cellRender);
16178
- }
16179
- cloneRowRender.addChild(cellRender);
16180
- }
16181
- ElementUtil.remeasure(cloneRowRender);
16182
- return cloneRowRender;
16183
- }
16184
- }
16185
- /**
16186
- * 标记合并单元格所在行需要重新计算
16187
- * @param cellRender
16188
- * @private
16189
- */
16190
- markMergeRowRenderDirty(cellRender) {
16191
- const cellEle = cellRender.element;
16192
- if (cellEle.props.vMerge !== 'restart') {
16193
- return;
16194
- }
16195
- const rowRender = cellRender.parent;
16196
- rowRender.element;
16197
- const tb = rowRender.parent;
16198
- const cellYPos = cellRender.rect.y;
16199
- for (let i = rowRender.getIndex() + 1; i < tb.length; i++) {
16200
- const nextRowRender = tb.getChild(i);
16201
- if (nextRowRender.rect.y <= cellYPos) {
16202
- nextRowRender.remeasureState = true;
16203
- nextRowRender.getItems().forEach(item => {
16204
- this.markMergeRowRenderDirty(item);
16205
- });
16206
- }
16207
- else {
16208
- break;
16209
- }
16210
- }
16211
- }
16212
- /**
16213
- * 修复->已经截断的合并单元格要向下移动到合适的位置
16214
- * @param tbRender
16215
- * @param cutRows
16216
- * @returns
16217
- */
16218
- fixCutTable(tbRender, cutRows) {
16219
- if (!cutRows.length) {
16220
- return;
16221
- }
16222
- const tbEle = tbRender.element;
16223
- const belowMergeRows = new Set();
16224
- for (let i = 0; i < tbRender.length; i++) {
16225
- const row = tbRender.getChild(i);
16226
- const nextRow = tbRender.getChild(i + 1);
16227
- if (!nextRow) {
16228
- break;
16229
- }
16230
- if (!cutRows.some(item => item === row)) {
16231
- break;
16232
- }
16233
- if (row.length === tbEle.getColsCount()) {
16234
- break;
16235
- }
16236
- if (this.checkFullRow(row)) {
16237
- break;
16238
- }
16239
- for (let j = 0; j < row.length; j++) {
16240
- const cell = row.getChild(j);
16241
- const cellEle = cell.element;
16242
- const colIndex = cellEle.getIndex();
16243
- if (!this.existsCellRender(nextRow, colIndex)) {
16244
- const insertColIndex = this.getRowInsertCellIndex(cell, nextRow);
16245
- if (insertColIndex === -1) {
16246
- this.getRowInsertCellIndex(cell, nextRow);
16247
- throw new Error('未在紧挨下方找到可以放置的位置');
16248
- }
16249
- //row.removeChild(cell);
16250
- nextRow.insertChild(cell, insertColIndex);
16251
- belowMergeRows.add(row);
16252
- ElementUtil.remeasure(nextRow);
16253
- }
16254
- }
16255
- }
16256
- if (belowMergeRows.size) {
16257
- for (const row of belowMergeRows) {
16258
- tbRender.removeChild(row);
16259
- row.clear();
16260
- }
16261
- ElementUtil.remeasure(tbRender);
16262
- }
16263
- }
16264
- /**
16265
- * 校验当前是否是一个完整的行,没有Null单元格,检查当前是否还需要向下合并
16266
- * @param row
16267
- */
16268
- checkFullRow(row) {
16269
- let x = 0;
16270
- for (let i = 0; i < row.length; i++) {
16271
- const cell = row.getChild(i);
16272
- if (cell.rect.x !== x) {
16273
- return false;
15239
+ const commMarks = this.docCtx.document.markPairs;
15240
+ for (let i = 0; i < commMarks.length; i++) {
15241
+ const commMark = commMarks[i];
15242
+ if (commMark.start && commMark.end) {
15243
+ const ancestor = DocumentSelection.getAncestorCommonControl(commMark.start, commMark.end);
15244
+ const range = RangeUtil.getSectionRange(commMark.start, 0, commMark.end, 1, ancestor);
15245
+ SelectionOverlays.addToCommentSets(range, this.seo.commRangeSets, commMark.start.color);
16274
15246
  }
16275
- x += cell.rect.width;
16276
15247
  }
16277
- return x === row.rect.width;
16278
15248
  }
16279
- existsCellRender(rowRender, cellIndex) {
16280
- for (let i = 0; i < rowRender.length; i++) {
16281
- const cellRender = rowRender.getChild(i);
16282
- const cellEle = cellRender.element;
16283
- if (cellEle.getIndex() === cellIndex) {
16284
- return true;
16285
- }
15249
+ cacheRenders(renderTree) {
15250
+ if (renderTree.element) {
15251
+ renderTree.element.paintRenders.push(renderTree);
16286
15252
  }
16287
- return false;
16288
- }
16289
- getBlockLineHeight(render) {
16290
- if (render instanceof TableRowRenderObject) {
16291
- let maxCellHeight = 0;
16292
- for (let i = 0; i < render.length; i++) {
16293
- const itemHeight = render.getChild(i).rect.height;
16294
- if (itemHeight > maxCellHeight) {
16295
- maxCellHeight = itemHeight;
16296
- }
15253
+ for (let i = 0; i < renderTree.length; i++) {
15254
+ const currRender = renderTree.getChild(i);
15255
+ if (currRender.element) {
15256
+ this.cacheCommsRender(currRender);
15257
+ }
15258
+ if (currRender instanceof BranchRenderObject) {
15259
+ this.cacheRenders(currRender);
15260
+ }
15261
+ else {
15262
+ currRender.element && currRender.element.paintRenders.push(currRender);
16297
15263
  }
16298
- return maxCellHeight;
16299
15264
  }
16300
- return render.rect.height;
16301
15265
  }
16302
- getRowInsertCellIndex(sourceCell, destRow) {
16303
- for (let i = 0; i < destRow.length; i++) {
16304
- const cell = destRow.getChild(i);
16305
- const rect = cell.rect;
16306
- if (sourceCell.rect.x < rect.x) {
16307
- return i;
15266
+ /**
15267
+ * 缓存批注标志
15268
+ * @private
15269
+ */
15270
+ cacheCommsRender(render) {
15271
+ if (render.element && render.element.type === 'comm') {
15272
+ const commElement = render.element;
15273
+ if (commElement.props.markType === 'start') {
15274
+ const currDocRender = this.cacheDoc;
15275
+ const docCommContainer = currDocRender.getItems().find(item => item instanceof CommsContainerRenderObject);
15276
+ if (docCommContainer) {
15277
+ docCommContainer.commsMarks.push(render);
15278
+ }
16308
15279
  }
16309
15280
  }
16310
- const lastCell = destRow.getChild(destRow.length - 1);
16311
- if (sourceCell.rect.x >= lastCell.rect.x + lastCell.rect.width) {
16312
- return destRow.length;
15281
+ if (render.element && render.element.type === 'comm-list') {
15282
+ const commContainer = render;
15283
+ CommentsUtil.createCommentsImage(commContainer);
16313
15284
  }
16314
- return -1;
16315
15285
  }
16316
- getHeaderRows(tb) {
16317
- const rows = [];
16318
- for (let i = 0; i < tb.length; i++) {
16319
- const rowRender = tb.getChild(i);
16320
- const rowEle = rowRender.element;
16321
- if (rowEle.props.headerRow) {
16322
- rows.push(rowRender);
16323
- }
16324
- else {
16325
- break;
15286
+ endMeasures(ele) {
15287
+ ele.endMeasure();
15288
+ if (ele instanceof BranchElement) {
15289
+ for (let i = 0; i < ele.length; i++) {
15290
+ this.endMeasures(ele.getChild(i));
16326
15291
  }
16327
15292
  }
16328
- return rows;
15293
+ }
15294
+ createDefaultPara() {
15295
+ const tmp = new ParagraphElement();
15296
+ tmp.props.lineHeight = this.options.defaultLineHeight;
15297
+ return tmp;
16329
15298
  }
16330
15299
  }
16331
15300
 
@@ -16333,8 +15302,7 @@ class DocumentPaint {
16333
15302
  renderContext;
16334
15303
  docCtx;
16335
15304
  seo;
16336
- elementMeasure;
16337
- elementRenderCut;
15305
+ //elementRenderCut: ElementRenderCut;
16338
15306
  elementPaint;
16339
15307
  docPages;
16340
15308
  docContainer;
@@ -16345,8 +15313,7 @@ class DocumentPaint {
16345
15313
  this.docCtx = docCtx;
16346
15314
  this.seo = seo;
16347
15315
  this.viewOptions = this.docCtx.viewOptions;
16348
- this.elementMeasure = new ElementMeasure(this.docCtx, this.renderContext);
16349
- this.elementRenderCut = new ElementRenderCut(this.viewOptions, this.renderContext);
15316
+ //this.elementRenderCut = new ElementRenderCut(this.viewOptions, this.renderContext);
16350
15317
  this.elementPaint = new ElementPaint(this.renderContext, this.docCtx);
16351
15318
  }
16352
15319
  rePages() {
@@ -16505,132 +15472,6 @@ class DocumentPaint {
16505
15472
  }
16506
15473
  }
16507
15474
 
16508
- const fontSize = 12;
16509
- const verPadding = 2;
16510
- /**
16511
- * 恒牙牙位图
16512
- */
16513
- class PermanentTeethElement extends LeafElement {
16514
- constructor() {
16515
- super('permanent-teeth');
16516
- this.props = new PermanentTeethProps();
16517
- this.props.topLeft = '';
16518
- this.props.topRight = '';
16519
- this.props.bottomLeft = '';
16520
- this.props.bottomRight = '';
16521
- }
16522
- clone(data) {
16523
- const clone = new PermanentTeethElement();
16524
- clone.props = this.props.clone();
16525
- return clone;
16526
- }
16527
- createRenderObject(data) {
16528
- const clone = new PermanentTeethRenderObject(this);
16529
- clone.rect.width = 150;
16530
- //字体大小*2+上下间距2*2
16531
- clone.rect.height = fontSize * 2 + verPadding * 2;
16532
- //clone.rect= ElementUtil.cloneRect(this.rect);
16533
- return clone;
16534
- }
16535
- serialize(viewOptions) {
16536
- return {
16537
- type: this.type,
16538
- props: this.props.getSerializeProps(viewOptions)
16539
- };
16540
- }
16541
- }
16542
- class PermanentTeethRenderObject extends LeafRenderObject {
16543
- render(e) {
16544
- }
16545
- clone() {
16546
- const clone = new PermanentTeethRenderObject(this.element);
16547
- clone.rect = ElementUtil.cloneRect(this.rect);
16548
- return clone;
16549
- }
16550
- // measure(): { width: number, height: number } {
16551
- // const ele = this.element;
16552
- //
16553
- // }
16554
- exportHTML(event) {
16555
- const ele = this.element;
16556
- const g = super.exportHTML(event);
16557
- const contentHorPadding = 4;
16558
- g.children = [];
16559
- // g.children.push(ElementUtil.getFillSvgPath(`M 0 ${this.rect.height / 2} h${this.rect.width}`, '#000', 1));
16560
- // g.children.push(ElementUtil.getFillSvgPath(`M ${this.rect.width / 2} 0 v${this.rect.height}`, '#000', 1));
16561
- //
16562
- g.children.push(ElementUtil.getFillSvgRect(0, this.rect.height / 2, this.rect.width, 1, '#000'));
16563
- g.children.push(ElementUtil.getFillSvgRect(this.rect.width / 2, 0, 1, this.rect.height, '#000'));
16564
- const getSvgText = (text, x, y) => {
16565
- return {
16566
- sel: 'text',
16567
- text: text,
16568
- data: {
16569
- ns: "http://www.w3.org/2000/svg",
16570
- attrs: {
16571
- 'dominant-baseline': 'hanging',
16572
- 'font-family': 'Arial',
16573
- 'font-size': fontSize,
16574
- x,
16575
- y,
16576
- }
16577
- },
16578
- };
16579
- };
16580
- const topLeftWidth = event.renderCtx.mainContext.measureTextWidth(ele.props.topLeft, {
16581
- fontSize: fontSize,
16582
- fontName: 'Arial'
16583
- });
16584
- const bottomLeftWidth = event.renderCtx.mainContext.measureTextWidth(ele.props.bottomLeft, {
16585
- fontSize: fontSize,
16586
- fontName: 'Arial'
16587
- });
16588
- g.children.push(getSvgText(ele.props.topLeft, this.rect.width / 2 - topLeftWidth - contentHorPadding, verPadding));
16589
- g.children.push(getSvgText(ele.props.topRight, this.rect.width / 2 + contentHorPadding, verPadding));
16590
- g.children.push(getSvgText(ele.props.bottomLeft, this.rect.width / 2 - bottomLeftWidth - contentHorPadding, this.rect.height - fontSize + verPadding));
16591
- g.children.push(getSvgText(ele.props.bottomRight, this.rect.width / 2 + contentHorPadding, this.rect.height - fontSize + verPadding));
16592
- return g;
16593
- }
16594
- }
16595
- class PermanentTeethFactory extends ElementFactory {
16596
- match(type) {
16597
- return type === 'permanent-teeth';
16598
- }
16599
- createElement(data) {
16600
- const ele = new PermanentTeethElement();
16601
- ele.props.bottomLeft = data.props?.bottomLeft ?? '';
16602
- ele.props.bottomRight = data.props?.bottomRight ?? '';
16603
- ele.props.topLeft = data.props?.topLeft ?? '';
16604
- ele.props.topRight = data.props?.topRight ?? '';
16605
- return ele;
16606
- }
16607
- }
16608
- /**
16609
- * 恒牙牙位图属性
16610
- */
16611
- class PermanentTeethProps extends INotifyPropertyChanged {
16612
- topLeft;
16613
- topRight;
16614
- bottomLeft;
16615
- bottomRight;
16616
- getSerializeProps(viewOptions) {
16617
- return {
16618
- topLeft: this.topLeft,
16619
- topRight: this.topRight,
16620
- bottomLeft: this.bottomLeft,
16621
- bottomRight: this.bottomRight,
16622
- };
16623
- }
16624
- clone(dest) {
16625
- dest = dest || new PermanentTeethProps();
16626
- dest.topLeft = this.topLeft;
16627
- dest.topRight = this.topRight;
16628
- dest.bottomLeft = this.bottomLeft;
16629
- dest.bottomRight = this.bottomRight;
16630
- return dest;
16631
- }
16632
- }
16633
-
16634
15475
  class ElementReader {
16635
15476
  docCtx;
16636
15477
  constructor(docCtx) {
@@ -16673,6 +15514,7 @@ class ElementReader {
16673
15514
  this.addFactory(PageBreakFactory);
16674
15515
  this.addFactory(TabFactory);
16675
15516
  this.addFactory(PermanentTeethFactory);
15517
+ this.addFactory(SVGFactory);
16676
15518
  // this.registerReadFunc<TrackRunProps>('ins-run', (data) => {
16677
15519
  // const props = new TrackRunProps(data.type);
16678
15520
  // props.userId = data.userId;
@@ -16693,29 +15535,18 @@ class ElementReader {
16693
15535
  this.setDocument(document);
16694
15536
  }
16695
15537
  setDocument(document) {
16696
- // if (this.docCtx.document) {
16697
- // this.docCtx.document.destroy();
16698
- // }
16699
- // this.document?.clearItems();
16700
- // document.docProps.clone(this.document.docProps);
16701
15538
  document.bodyElement = document.find((item) => item instanceof DocumentBodyElement);
16702
15539
  document.headerElement = document.find((item) => item instanceof DocumentHeaderElement);
16703
15540
  document.footerElement = document.find((item) => item instanceof DocumentFooterElement);
16704
- // document.commentsContainerElement = document.find((item) => item instanceof CommsContainerElement) as CommsContainerElement;
16705
- // if (!document.commentsContainerElement) {
16706
- // document.commentsContainerElement = new CommsContainerElement();
16707
- // }
16708
15541
  document.clearItems();
16709
15542
  document.addChild(document.headerElement);
16710
15543
  document.addChild(document.bodyElement);
16711
15544
  document.addChild(document.footerElement);
16712
- //document.addChild(document.commentsContainerElement);
16713
15545
  this.docCtx.document = document;
16714
15546
  document.viewOptions = this.docCtx.viewOptions;
16715
15547
  const width = Math.floor(document.props.width * this.docCtx.viewOptions.mmToPixelsRatio);
16716
15548
  const height = Math.floor(document.props.height * this.docCtx.viewOptions.mmToPixelsRatio);
16717
15549
  this.docCtx.viewOptions.docPageSettings = new PageOptions(width, height, document.props.orient);
16718
- //this.viewOptions.viewSettings.width = this.viewOptions.docPageSettings.width + 10;
16719
15550
  }
16720
15551
  readElement(data, strictMode = false) {
16721
15552
  if (typeof data === 'string') {
@@ -16737,6 +15568,7 @@ class ElementReader {
16737
15568
  }
16738
15569
  }
16739
15570
  factory.readCompleted(element, childArr);
15571
+ this.readAttribute(data, element);
16740
15572
  return element;
16741
15573
  }
16742
15574
  }
@@ -16748,6 +15580,11 @@ class ElementReader {
16748
15580
  return null;
16749
15581
  }
16750
15582
  }
15583
+ readAttribute(data, ele) {
15584
+ if (data.attribute) {
15585
+ ele.attribute = data.attribute;
15586
+ }
15587
+ }
16751
15588
  /**
16752
15589
  * 读取扩展属性
16753
15590
  * @param data
@@ -17813,7 +16650,10 @@ class DocumentEvent {
17813
16650
  if (renderObject instanceof LeafRenderObject) {
17814
16651
  if (CommonUtil.isInsideRectByPosition(renderObjectRect, hitPos)) {
17815
16652
  const x = hitPos.x - renderObjectRect.x;
17816
- const offset = ElementUtil.getHitRenderOffset(renderObject, x);
16653
+ let offset = ElementUtil.getHitRenderOffset(renderObject, x);
16654
+ if (!this.ismousedown && renderObject.element && renderObject.element.type === 'psym') {
16655
+ offset = 0;
16656
+ }
17817
16657
  return {
17818
16658
  render: renderObject,
17819
16659
  offset,
@@ -17905,7 +16745,10 @@ class DocumentEvent {
17905
16745
  else {
17906
16746
  x = position.x - adjacentRender.rect.x;
17907
16747
  }
17908
- const offset = ElementUtil.getHitRenderOffset(adjacentRender.render, x);
16748
+ let offset = ElementUtil.getHitRenderOffset(adjacentRender.render, x);
16749
+ if (!this.ismousedown && renderObject.element && renderObject.element.type === 'psym') {
16750
+ offset = 0;
16751
+ }
17909
16752
  return {
17910
16753
  render: adjacentRender.render,
17911
16754
  absoluteRenderRect: adjacentRender.rect,
@@ -20964,7 +19807,8 @@ class ElementTrackManage {
20964
19807
  * @private
20965
19808
  */
20966
19809
  mergeOps(ops) {
20967
- return false;
19810
+ return this.mergeFormatOps(ops);
19811
+ //return false;
20968
19812
  //问题在于:
20969
19813
  //1.新输入的字符串,selectState的startOffset、endOffset=1,后输入的字符串的endOffset进行累加
20970
19814
  //2.撤销后重做,选区范围在1-2,英国是0-2,因为之前在创建文本对象后,选区的结束位为1
@@ -21015,6 +19859,41 @@ class ElementTrackManage {
21015
19859
  // }
21016
19860
  // return false;
21017
19861
  }
19862
+ /**
19863
+ * 将对某个元素的最近两次的属性修改合并为一次,ops为当前记录的修改,比较上次的修改,如果为对同一个元素的修改,则合并
19864
+ * @private
19865
+ */
19866
+ mergeFormatOps(ops) {
19867
+ if (ops.length > 1) {
19868
+ return false;
19869
+ }
19870
+ const lastOps = this.actions[this.actions.length - 1];
19871
+ if (!lastOps || lastOps.ops.length > 1) {
19872
+ return false;
19873
+ }
19874
+ const prevOp = lastOps.ops[lastOps.ops.length - 1];
19875
+ const currOp = ops[0];
19876
+ //操作类型相同
19877
+ if ('format' in currOp.ops && 'format' in prevOp.ops && currOp.index === prevOp.index) {
19878
+ // const prevAfterSelection = lastOps.afterSelection;
19879
+ // if (!prevAfterSelection) {
19880
+ // return false;
19881
+ // }
19882
+ //前后是连续的操作
19883
+ const { format: currFormat } = currOp.ops;
19884
+ const { format: prevFormat } = prevOp.ops;
19885
+ Object.keys(currFormat).forEach(key => {
19886
+ const currValue = currFormat[key].newValue;
19887
+ const prevValue = prevFormat[key].newValue;
19888
+ if (CommonUtil.isEqual(currValue, prevValue)) {
19889
+ return;
19890
+ }
19891
+ prevFormat[key].newValue = currValue;
19892
+ });
19893
+ return true;
19894
+ }
19895
+ return false;
19896
+ }
21018
19897
  getSelection() {
21019
19898
  const { startControl, startOffset, endControl, endOffset, editable } = this.docCtx.selectionState;
21020
19899
  if (!startControl) {
@@ -28927,7 +27806,7 @@ class DocEditor {
28927
27806
  rule.setRuleOptions({ width: this.viewOptions.docPageSettings.width, pagePL, pagePR, docLeft });
28928
27807
  }
28929
27808
  version() {
28930
- return "2.1.19";
27809
+ return "2.1.21";
28931
27810
  }
28932
27811
  switchPageHeaderEditor() {
28933
27812
  this.docCtx.document.switchPageHeaderEditor(this.selectionState, null);
@@ -28935,7 +27814,7 @@ class DocEditor {
28935
27814
  getTextContent() {
28936
27815
  const paras = this.docCtx.document.treeFilter(item => item instanceof ParagraphElement);
28937
27816
  const paraTexts = paras.map(item => ElementSerialize.serializeString(item, { all: false }));
28938
- return paraTexts.join('\n');
27817
+ return paraTexts.join('');
28939
27818
  }
28940
27819
  emit(event, args) {
28941
27820
  this.eventBus.emit(event, args);
@@ -28980,6 +27859,26 @@ class DocumentCombine {
28980
27859
  }
28981
27860
  }
28982
27861
 
27862
+ /**
27863
+ * 文字行渲染模式
27864
+ 用于医嘱打印模式
27865
+ */
27866
+ function runTextLineRender(ele, data) {
27867
+ if (!data.options.textRowLineMode) {
27868
+ return;
27869
+ }
27870
+ if (ele instanceof TableElement) {
27871
+ // textLineRenderMode(ele, data);
27872
+ // remeasureParentRenders(ele.cacheRender)
27873
+ return;
27874
+ }
27875
+ if (ele instanceof BranchElement) {
27876
+ for (let i = 0; i < ele.length; i++) {
27877
+ runTextLineRender(ele.getChild(i), data);
27878
+ }
27879
+ }
27880
+ }
27881
+
28983
27882
  /**
28984
27883
  * 删除当前段落
28985
27884
  * @param evt
@@ -29111,5 +28010,5 @@ function removeDuplicatesEvent(events) {
29111
28010
  return arr;
29112
28011
  }
29113
28012
 
29114
- export { BlockContainerElement, BlockContainerRenderObject, BlockContentElement, BlockContentRenderObject, BlockLineRectRenderObject, BodyPartProps, BooleanEnum, BorderProps, BranchElement, BranchRenderObject, BreakElement, BreakFactory, BreakRenderObject, CheckBoxElement, CheckBoxFactory, CheckBoxProps, CheckBoxRenderObject, ColumnPatchUtil, CommContentBaseElement, CommContentBaseRenderObject, CommContentElement, CommContentProps, CommContentRenderObject, CommProps, CommentContentFactory, CommentElement, CommentFactory, CommentRenderObject, CommentsFactory, CommentsUtil, CommonUtil, CommsContainerElement, CommsContainerRenderObject, ContentMenuItem, ContextMenuElementEvent, CopyElementEvent, DOMEventSource, DOMSubscription, DataDecorateElement, DataDecorateProps, DataDecorateRenderObject, DataEleBaseProps, DataEleBaseTextProps, DataEleCheckProps, DataEleDateProps, DataEleImageProps, DataEleListProps, DataEleMHProps, DataElementBarcode, DataElementBarcodeFactory, DataElementBarcodeProps, DataElementBarcodeRenderObject, DataElementBaseFactory, DataElementCheck, DataElementCheckFactory, DataElementCheckRenderObject, DataElementDate, DataElementDateFactory, DataElementDateRenderObject, DataElementGroupElement, DataElementGroupFactory, DataElementGroupProps, DataElementGroupRenderObject, DataElementImage, DataElementImgFactory, DataElementInlineGroup, DataElementLeaf, DataElementList, DataElementListFactory, DataElementListRenderObject, DataElementMH, DataElementMHFactory, DataElementRenderObject, DataElementText, DataElementTextFactory, DataElementTextRenderObject, DataImageRenderObject, DataRenderMH, DocEditor, DocMode, DocumentBodyElement, DocumentBodyFactory, DocumentBodyPartElement, DocumentBodyPartFactory, DocumentBodyPartRenderObject, DocumentBodyRenderObject, DocumentChange, DocumentCombine, DocumentComment, DocumentContainerRender, DocumentContext, DocumentCursor, DocumentElement, DocumentEvalFunc, DocumentEvent, DocumentFactory, DocumentFooterElement, DocumentFooterFactory, DocumentFooterRenderObject, DocumentHeaderElement, DocumentHeaderFactory, DocumentHeaderRenderObject, DocumentInput, DocumentPaint, DocumentPrintOffscreen, DocumentPrintOffscreenBase, DocumentProps, DocumentRenderObject, DocumentSelection, DocumentTemplate, DropElementEvent, EditMode, EditorContext, Element, ElementEvent, ElementFactory, ElementPaint, ElementReader, ElementSerialize, ElementUtil, EventBus, EventMap, EventSourceCore$1 as EventSourceCore, FillNullSpaceElement, FillNullSpaceRenderObject, GetTrackTipsEvent, GotCursorEvent, IDispose, INotifyPropertyChanged, InlineBlockContainer, InlineGroupElement, InlineGroupInputElement, InlineGroupRenderObject, InlineMuiltBlockLineRenderObject, InputElementEvent, IsInSideDataElement, IsInSideInlineGroupInputElement, KeyboradElementEvent, LeafElement, LeafRenderObject, LostCursorEvent, MarginProps, ModifyFlag$1 as ModifyFlag, MouseElementEvent, MousedownElementEvent, MuiltBlockLineRenderObject, OnceSubject, PSymbolElement, PSymbolRenderObject, PaddingProps, PageBreakElement, PageBreakFactory, PageBreakRenderObject, PageOptions, PaintContent, ParagraphElement, ParagraphFactory, ParagraphLineRectRenderObject, ParagraphNumberType, ParagraphProps, ParagraphRenderObject, PasteElementEvent, PictureElement, PictureFactory, PictureProps, PictureRenderObject, RadioBoxElement, RadioBoxFactory, RadioBoxProps, RadioBoxRenderObject, RangeUtil, Rect, RenderContext, RenderObject, RenderObjectType, ResizeLeafRenderObject, RunElementFactory, SelectionOverlays, SelectionRange, SelectionState, Subject$1 as Subject, SubjectSubscription$1 as SubjectSubscription, Subscription$1 as Subscription, TabElement, TabFactory, TabRenderObject, TableCellElement, TableCellFactory, TableCellProps, TableCellRenderObject, TableElement, TableFactory, TableProps, TableRenderObject, TableRowElement, TableRowFactory, TableRowProps, TableRowRenderObject, TableSplitCell, TableUtil, TextGroupElement, TextGroupFactory, TextGroupRenderObject, TextProps, TrackRunElement, TrackRunProps, TrackRunRenderObject, TrackRunTypeEnum, ValidateCondition, ValidateElement, ValidateProps, ValidateRenderObject, ViewOptions, clearChildrenRenderCache, clearTraces, createPrintTemplate, defaultParaHanging, deleteCurrentParagraph, docOpsMap, documentPrint, drawDecorator, elementTypeEventHandler, exportDecoratorHTML, falseChar, fontMapFunc, formatEle, fromEvent, generatePatch, getCalleeName, getFocusTextSegment, inputText, insertEle, invokeTypeHandler, isDate, logUpdateEleProps, objectToString$4 as objectToString, onTableContextmenu, onceTask, parser, printNodes, reactiveMap, removeEle, removeText, runTextLineRender, setChildrenModifyFlag, setDataElementProps, setNotifyChangedCallback, setTraceTrackingFlag, suppressTracking, targetMaps, textLineRenderMode, toRawType, toTypeString, trueChar, validateDataEle, validateDataEleRenderObj, validateInlineInputRenderObj, watchChanged };
28013
+ export { BlockContainerElement, BlockContainerRenderObject, BlockContentElement, BlockContentRenderObject, BlockLineRectRenderObject, BodyPartProps, BooleanEnum, BorderProps, BranchElement, BranchRenderObject, BreakElement, BreakFactory, BreakRenderObject, CheckBoxElement, CheckBoxFactory, CheckBoxProps, CheckBoxRenderObject, ColumnPatchUtil, CommContentBaseElement, CommContentBaseRenderObject, CommContentElement, CommContentProps, CommContentRenderObject, CommProps, CommentContentFactory, CommentElement, CommentFactory, CommentRenderObject, CommentsFactory, CommentsUtil, CommonUtil, CommsContainerElement, CommsContainerRenderObject, ContentMenuItem, ContextMenuElementEvent, CopyElementEvent, DOMEventSource, DOMSubscription, DataDecorateElement, DataDecorateProps, DataDecorateRenderObject, DataEleBaseProps, DataEleBaseTextProps, DataEleCheckProps, DataEleDateProps, DataEleImageProps, DataEleListProps, DataEleMHProps, DataElementBarcode, DataElementBarcodeFactory, DataElementBarcodeProps, DataElementBarcodeRenderObject, DataElementBaseFactory, DataElementCheck, DataElementCheckFactory, DataElementCheckRenderObject, DataElementDate, DataElementDateFactory, DataElementDateRenderObject, DataElementGroupElement, DataElementGroupFactory, DataElementGroupProps, DataElementGroupRenderObject, DataElementImage, DataElementImgFactory, DataElementInlineGroup, DataElementLeaf, DataElementList, DataElementListFactory, DataElementListRenderObject, DataElementMH, DataElementMHFactory, DataElementRenderObject, DataElementText, DataElementTextFactory, DataElementTextRenderObject, DataImageRenderObject, DataRenderMH, DocEditor, DocMode, DocumentBodyElement, DocumentBodyFactory, DocumentBodyPartElement, DocumentBodyPartFactory, DocumentBodyPartRenderObject, DocumentBodyRenderObject, DocumentChange, DocumentCombine, DocumentComment, DocumentContainerRender, DocumentContext, DocumentCursor, DocumentElement, DocumentEvalFunc, DocumentEvent, DocumentFactory, DocumentFooterElement, DocumentFooterFactory, DocumentFooterRenderObject, DocumentHeaderElement, DocumentHeaderFactory, DocumentHeaderRenderObject, DocumentInput, DocumentPaint, DocumentPrintOffscreen, DocumentPrintOffscreenBase, DocumentProps, DocumentRenderObject, DocumentSelection, DocumentTemplate, DropElementEvent, EditMode, EditorContext, Element, ElementEvent, ElementFactory, ElementPaint, ElementReader, ElementSerialize, ElementUtil, EventBus, EventMap, EventSourceCore$1 as EventSourceCore, FillNullSpaceElement, FillNullSpaceRenderObject, GetTrackTipsEvent, GotCursorEvent, IDispose, INotifyPropertyChanged, InlineBlockContainer, InlineGroupElement, InlineGroupInputElement, InlineGroupRenderObject, InlineMuiltBlockLineRenderObject, InputElementEvent, IsInSideDataElement, IsInSideInlineGroupInputElement, KeyboradElementEvent, LeafElement, LeafRenderObject, LostCursorEvent, MarginProps, ModifyFlag$1 as ModifyFlag, MouseElementEvent, MousedownElementEvent, MuiltBlockLineRenderObject, OnceSubject, PSymbolElement, PSymbolRenderObject, PaddingProps, PageBreakElement, PageBreakFactory, PageBreakRenderObject, PageOptions, PaintContent, ParagraphElement, ParagraphFactory, ParagraphLineRectRenderObject, ParagraphNumberType, ParagraphProps, ParagraphRenderObject, PasteElementEvent, PermanentTeethElement, PermanentTeethFactory, PermanentTeethProps, PermanentTeethRenderObject, PictureElement, PictureFactory, PictureProps, PictureRenderObject, RadioBoxElement, RadioBoxFactory, RadioBoxProps, RadioBoxRenderObject, RangeUtil, Rect, RenderContext, RenderObject, RenderObjectType, ResizeLeafRenderObject, RunElementFactory, SVGElement, SVGFactory, SVGProps, SVGRenderObject, SelectionOverlays, SelectionRange, SelectionState, Subject$1 as Subject, SubjectSubscription$1 as SubjectSubscription, Subscription$1 as Subscription, TabElement, TabFactory, TabRenderObject, TableCellElement, TableCellFactory, TableCellProps, TableCellRenderObject, TableElement, TableFactory, TableProps, TableRenderObject, TableRowElement, TableRowFactory, TableRowProps, TableRowRenderObject, TableSplitCell, TableUtil, TextGroupElement, TextGroupFactory, TextGroupRenderObject, TextProps, TrackRunElement, TrackRunProps, TrackRunRenderObject, TrackRunTypeEnum, ValidateCondition, ValidateElement, ValidateProps, ValidateRenderObject, ViewOptions, addReturn, clearChildrenRenderCache, clearTraces, cloneChildren, cloneElementBase, createPrintTemplate, defaultParaHanging, deleteCurrentParagraph, docOpsMap, documentPrint, drawDecorator, elementTypeEventHandler, exportDecoratorHTML, falseChar, fontMapFunc, formatEle, fromEvent, generatePatch, getCalleeName, getFocusTextSegment, inputText, insertEle, invokeTypeHandler, isDate, logUpdateEleProps, objectToString$4 as objectToString, onTableContextmenu, onceTask, parser, printNodes, reactiveMap, removeEle, removeText, runTextLineRender, setChildrenModifyFlag, setDataElementProps, setNotifyChangedCallback, setTraceTrackingFlag, suppressTracking, targetMaps, textLineRenderMode, toRawType, toTypeString, trueChar, validateDataEle, validateDataEleRenderObj, validateInlineInputRenderObj, watchChanged };
29115
28014
  //# sourceMappingURL=index.js.map