@hailin-zheng/editor-core 2.2.7 → 2.2.9

Sign up to get free protection for your applications and to get access to all the features.
package/index-cjs.js CHANGED
@@ -417,7 +417,6 @@ class BlockContentRenderObject extends BranchRenderObject {
417
417
  }
418
418
  }
419
419
  class InlineGroupRenderObject extends BranchRenderObject {
420
- paintPos;
421
420
  }
422
421
  /**
423
422
  * 包含块级渲染元素的容器元素,例如body、table-cell等
@@ -431,18 +430,18 @@ class BlockContainerRenderObject extends BranchRenderObject {
431
430
  /**
432
431
  * 多级 ‘BlockLineRectRenderObject’ 包裹元素,例如 p、table
433
432
  */
434
- class MuiltBlockLineRenderObject extends BlockContentRenderObject {
433
+ class MultiBlockLineRenderObject extends BlockContentRenderObject {
435
434
  }
436
435
  /**
437
436
  * 容器-子内容为多个行内块级元素,例如table-row
438
437
  */
439
- class InlineBlockContainer extends MuiltBlockLineRenderObject {
438
+ class InlineBlockContainer extends MultiBlockLineRenderObject {
440
439
  }
441
440
  /**
442
441
  * 服务于table-cell
443
442
  * 可被多级拆分的元素
444
443
  */
445
- class InlineMuiltBlockLineRenderObject extends MuiltBlockLineRenderObject {
444
+ class InlineMuiltBlockLineRenderObject extends MultiBlockLineRenderObject {
446
445
  }
447
446
  /**
448
447
  * 最小不可分割单位的块级行框,例如 p-line
@@ -1538,12 +1537,19 @@ class BranchElement extends Element {
1538
1537
  }
1539
1538
  return len;
1540
1539
  }
1541
- treeFilter(predicate) {
1540
+ treeFilter(predicate, options) {
1541
+ if (!options) {
1542
+ options = { includeChildren: true };
1543
+ }
1542
1544
  const items = [];
1543
1545
  for (let i = 0; i < this.length; i++) {
1544
1546
  const item = this.getChild(i);
1545
1547
  if (predicate(item)) {
1546
1548
  items.push(item);
1549
+ //已经匹配节点,不需要匹配当前元素的子节点
1550
+ if (!options.includeChildren) {
1551
+ continue;
1552
+ }
1547
1553
  }
1548
1554
  if (item instanceof BranchElement) {
1549
1555
  items.push(...item.treeFilter(predicate));
@@ -1726,12 +1732,22 @@ class ViewOptions {
1726
1732
  defaultColor = "#000000";
1727
1733
  currentFontSize = 14;
1728
1734
  currentFontName = '宋体';
1729
- selectionOverlaysColor = 'rgb(131,175,155,0.5)';
1730
- dataEleOverlaysColor = 'rgb(131,175,155,0.5)';
1731
- dataEleFocusedBgColor = 'rgb(131,175,155,0.8)';
1735
+ //选区颜色
1736
+ selectionColor = 'rgb(131,175,155,0.5)';
1737
+ dataDecoratorNormalColor = '#0050b3';
1738
+ dataDecoratorMouseEnterColor = '#0050b3';
1739
+ dataDecoratorFocusedColor = '#0050b3';
1740
+ //数据元没有输入值时背景颜色
1741
+ dataEleEmptyBgColor = '';
1742
+ //数据元鼠标悬浮颜色
1743
+ dataEleMouseEnterBgColor = '#d9d9d9';
1744
+ //数据元只读背景颜色
1745
+ dataEleReadOnlyBgColor = '#d9d9d9';
1746
+ //数据元焦点背景颜色
1747
+ dataEleFocusedBgColor = '#d9d9d9';
1748
+ //数据元正常背景颜色
1749
+ dataEleNormalBgColor = '#fafafa';
1732
1750
  dataEleErrorBgColor = '#ff4d4f';
1733
- dataEleReadOnlyOverlayColor = '#d9d9d9';
1734
- dataEleOutlineColor = 'rgb(131,175,155,0.7)';
1735
1751
  viewBackcolor = 'rgb(230,230,230)';
1736
1752
  paraSymbolColor = 'rgb(128,128,128)';
1737
1753
  dataGroupColor = 'rgb(0,80,179)';
@@ -1746,7 +1762,6 @@ class ViewOptions {
1746
1762
  showCharRect;
1747
1763
  //数据元交互修饰模式
1748
1764
  dataEleDecoratorMode = 'outline';
1749
- dataEleDecoratorColor = '#ddd';
1750
1765
  showTabChar;
1751
1766
  showSpaceChar;
1752
1767
  showLineBreak;
@@ -2862,15 +2877,7 @@ class ValidateProps {
2862
2877
  return clone;
2863
2878
  }
2864
2879
  }
2865
- class DataElementGroupProps extends DataEleBaseProps {
2866
- clone(dest) {
2867
- const clone = dest ?? new DataElementGroupProps();
2868
- super.cloneBaseProps(clone);
2869
- }
2870
- getSerializeProps(options) {
2871
- const props = {};
2872
- return this.getBaseProps(props, options);
2873
- }
2880
+ class DataElementGroupProps extends DataEleBaseTextProps {
2874
2881
  }
2875
2882
  class DataElementBarcodeProps {
2876
2883
  type = 'code128';
@@ -2929,7 +2936,7 @@ class DataDecorateElement extends LeafElement {
2929
2936
  const render = new DataDecorateRenderObject(this);
2930
2937
  //render.rect.width = this.dProps.size / 2;
2931
2938
  render.rect.width = 1;
2932
- render.rect.height = 14;
2939
+ render.rect.height = Math.ceil(14 * TEXT_HEIGHT_FACTOR);
2933
2940
  return render;
2934
2941
  }
2935
2942
  serialize() {
@@ -2955,6 +2962,14 @@ class DataDecorateRenderObject extends LeafRenderObject {
2955
2962
  // if(this.element.parent.parent.type==='data-group'){
2956
2963
  // return null;
2957
2964
  // }
2965
+ const options = event.options;
2966
+ let color = options.dataDecoratorNormalColor;
2967
+ if (this.element.dataEle.isMouseenter && options.dataDecoratorMouseEnterColor) {
2968
+ color = options.dataDecoratorMouseEnterColor;
2969
+ }
2970
+ if (this.element.dataEle.isFocused && options.dataDecoratorFocusedColor) {
2971
+ color = options.dataDecoratorFocusedColor;
2972
+ }
2958
2973
  const element = this.element;
2959
2974
  const lineWidth = 3;
2960
2975
  let path = '';
@@ -2968,7 +2983,7 @@ class DataDecorateRenderObject extends LeafRenderObject {
2968
2983
  path = `M ${x - lineWidth} 2 L ${x} 2 L ${x} ${height} L ${x - lineWidth} ${height}`;
2969
2984
  }
2970
2985
  return ElementUtil.createSvgPath({
2971
- stroke: '#0050b3',
2986
+ stroke: color,
2972
2987
  fill: "none",
2973
2988
  'stroke-width': 1,
2974
2989
  d: path
@@ -3134,7 +3149,7 @@ class ParagraphElement extends BlockContentElement {
3134
3149
  return new ParagraphElement();
3135
3150
  }
3136
3151
  }
3137
- class ParagraphRenderObject extends MuiltBlockLineRenderObject {
3152
+ class ParagraphRenderObject extends MultiBlockLineRenderObject {
3138
3153
  /**
3139
3154
  * 绘制项目符号
3140
3155
  */
@@ -3683,7 +3698,7 @@ class DocumentRenderObject extends BlockContainerRenderObject {
3683
3698
  },
3684
3699
  },
3685
3700
  children: [
3686
- pageCorner, copyright, highlight, ...CommonUtil.toArray(event.getChildNodes(this)), pageNum, selection
3701
+ pageCorner, highlight, ...CommonUtil.toArray(event.getChildNodes(this)), pageNum, selection, copyright
3687
3702
  ]
3688
3703
  };
3689
3704
  }
@@ -3721,11 +3736,10 @@ class DocumentRenderObject extends BlockContainerRenderObject {
3721
3736
  }
3722
3737
  const str = "\u6f14\u793a\u7248\u672c";
3723
3738
  const textProps = new TextProps();
3724
- textProps.color = "#000";
3725
- textProps.fontName = '仿宋';
3739
+ textProps.color = "#bfbfbf";
3740
+ textProps.fontName = '宋体';
3726
3741
  textProps.fontSize = 80;
3727
3742
  textProps.fontStyle = 'italic';
3728
- event.renderCtx.contentContext.measureText(str, textProps);
3729
3743
  const getTextRotationAngle = (width, height) => {
3730
3744
  return Math.atan(height / width) * 180 / Math.PI;
3731
3745
  };
@@ -3744,6 +3758,7 @@ class DocumentRenderObject extends BlockContainerRenderObject {
3744
3758
  'font-size': textProps.fontSize,
3745
3759
  "stroke": textProps.color,
3746
3760
  'fill': '#fff',
3761
+ 'opacity': '0.5',
3747
3762
  x: this.rect.width / 2,
3748
3763
  y: this.rect.height / 2,
3749
3764
  }
@@ -4131,68 +4146,85 @@ class DataElementBaseFactory extends ElementFactory {
4131
4146
  * @param r
4132
4147
  */
4133
4148
  function exportDecoratorHTML(event, r) {
4134
- const canPaint = r.element.isMouseenter || r.element.isFocused;
4135
- if (!canPaint) {
4149
+ if (event.mode === 'print') {
4136
4150
  return;
4137
4151
  }
4138
- const mode = event.options.dataEleDecoratorMode;
4139
- const color = event.options.dataEleDecoratorColor;
4140
- if (mode === 'none') {
4141
- return;
4152
+ const options = event.options;
4153
+ let color = options.dataEleNormalBgColor;
4154
+ //空数据元填充颜色
4155
+ if (r.element.length === 2 && options.dataEleEmptyBgColor) {
4156
+ color = options.dataEleEmptyBgColor;
4142
4157
  }
4143
- if (mode === 'overlay') {
4144
- const bgX = event.relativePagePos.x;
4145
- const bgY = event.relativePagePos.y;
4146
- event.highlights.push(ElementUtil.getFillSvgRect(bgX, bgY, r.rect.width, r.rect.height, color));
4147
- return;
4158
+ if (r.element.isMouseenter && options.dataEleMouseEnterBgColor) {
4159
+ color = options.dataEleMouseEnterBgColor;
4148
4160
  }
4149
- else if (mode === 'outline') {
4150
- const verOffset = 0;
4151
- const renderPosMap = getCurrentParaGroupRenders(r).map(item => ({ pos: getRenderPosToDoc(item), render: item }));
4152
- if (renderPosMap.length > 1) {
4153
- const secondGroupRenderPos = renderPosMap[1].pos;
4154
- if (secondGroupRenderPos.x + renderPosMap[1].render.rect.width > event.relativePagePos.x) {
4155
- const leftPoints = [];
4156
- const rightPoints = [];
4157
- for (let i = 0; i < renderPosMap.length; i++) {
4158
- const groupRender = renderPosMap[i].render;
4159
- const groupRenderPos = renderPosMap[i].pos;
4160
- leftPoints.push({ x: groupRenderPos.x, y: groupRenderPos.y - verOffset });
4161
- rightPoints.push({
4162
- x: groupRenderPos.x + groupRender.rect.width,
4163
- y: groupRenderPos.y - verOffset
4164
- });
4165
- leftPoints.push({
4166
- x: groupRenderPos.x,
4167
- y: groupRenderPos.y + groupRender.rect.height + verOffset * 2
4168
- });
4169
- rightPoints.push({
4170
- x: groupRenderPos.x + groupRender.rect.width,
4171
- y: groupRenderPos.y + groupRender.rect.height + verOffset * 2
4172
- });
4173
- }
4174
- const sharpPoints1 = CommonUtil.resharpPoints(rightPoints);
4175
- const sharpPoints = CommonUtil.resharpPoints([...leftPoints.reverse()]);
4176
- const path = [...sharpPoints, ...sharpPoints1, sharpPoints[0]].map((item, index) => ((index === 0) ? 'M' : "L") + item.x + " " + item.y).join(" ");
4177
- event.highlights.push(ElementUtil.createSvgPath({
4178
- d: path,
4179
- stroke: color,
4180
- fill: 'none',
4181
- 'stroke-width': 1
4182
- }));
4183
- return;
4184
- }
4185
- }
4186
- for (let i = 0; i < renderPosMap.length; i++) {
4187
- const currRen = renderPosMap[i];
4188
- event.highlights.push(ElementUtil.createSvgPath({
4189
- d: `M${currRen.pos.x} ${currRen.pos.y} L${currRen.pos.x + currRen.render.rect.width} ${currRen.pos.y} L${currRen.pos.x + currRen.render.rect.width} ${currRen.pos.y + currRen.render.rect.height} L${currRen.pos.x} ${currRen.pos.y + currRen.render.rect.height} Z`,
4190
- stroke: '#0050b3',
4191
- fill: 'none',
4192
- 'stroke-width': 1
4193
- }));
4194
- }
4161
+ if (r.element.isFocused && options.dataEleFocusedBgColor) {
4162
+ color = options.dataEleFocusedBgColor;
4195
4163
  }
4164
+ //绘制背景
4165
+ const bgX = event.relativePagePos.x;
4166
+ const bgY = event.relativePagePos.y;
4167
+ event.highlights.push(ElementUtil.getFillSvgRect(bgX, bgY, r.rect.width, r.rect.height, color));
4168
+ // const canPaint = r.element.isMouseenter || r.element.isFocused;
4169
+ // if (!canPaint) {
4170
+ // return;
4171
+ // }
4172
+ // const mode = event.options.dataEleDecoratorMode;
4173
+ // if (mode === 'none') {
4174
+ // return;
4175
+ // }
4176
+ // if (mode === 'overlay') {
4177
+ // const bgX = event.relativePagePos.x;
4178
+ // const bgY = event.relativePagePos.y;
4179
+ // event.highlights.push(ElementUtil.getFillSvgRect(bgX, bgY, r.rect.width, r.rect.height, color));
4180
+ // return;
4181
+ // } else if (mode === 'outline') {
4182
+ // const verOffset = 0;
4183
+ // const renderPosMap = getCurrentParaGroupRenders(r).map(item => ({ pos: getRenderPosToDoc(item), render: item }));
4184
+ // if (renderPosMap.length > 1) {
4185
+ // const secondGroupRenderPos = renderPosMap[1].pos;
4186
+ // if (secondGroupRenderPos.x + renderPosMap[1].render.rect.width > event.relativePagePos.x) {
4187
+ // const leftPoints: Array<Position> = [];
4188
+ // const rightPoints: Array<Position> = [];
4189
+ // for (let i = 0; i < renderPosMap.length; i++) {
4190
+ // const groupRender = renderPosMap[i].render;
4191
+ // const groupRenderPos = renderPosMap[i].pos;
4192
+ // leftPoints.push({ x: groupRenderPos.x, y: groupRenderPos.y - verOffset });
4193
+ // rightPoints.push({
4194
+ // x: groupRenderPos.x + groupRender.rect.width,
4195
+ // y: groupRenderPos.y - verOffset
4196
+ // });
4197
+ // leftPoints.push({
4198
+ // x: groupRenderPos.x,
4199
+ // y: groupRenderPos.y + groupRender.rect.height + verOffset * 2
4200
+ // });
4201
+ // rightPoints.push({
4202
+ // x: groupRenderPos.x + groupRender.rect.width,
4203
+ // y: groupRenderPos.y + groupRender.rect.height + verOffset * 2
4204
+ // });
4205
+ // }
4206
+ // const sharpPoints1 = CommonUtil.resharpPoints(rightPoints);
4207
+ // const sharpPoints = CommonUtil.resharpPoints([...leftPoints.reverse()]);
4208
+ // const path = [...sharpPoints, ...sharpPoints1, sharpPoints[0]].map((item, index) => ((index === 0) ? 'M' : "L") + item.x + " " + item.y).join(" ")
4209
+ // event.highlights.push(ElementUtil.createSvgPath({
4210
+ // d: path,
4211
+ // stroke: color,
4212
+ // fill: 'none',
4213
+ // 'stroke-width': 1
4214
+ // }));
4215
+ // return;
4216
+ // }
4217
+ // }
4218
+ // for (let i = 0; i < renderPosMap.length; i++) {
4219
+ // const currRen = renderPosMap[i];
4220
+ // event.highlights.push(ElementUtil.createSvgPath({
4221
+ // d: `M${currRen.pos.x} ${currRen.pos.y} L${currRen.pos.x + currRen.render.rect.width} ${currRen.pos.y} L${currRen.pos.x + currRen.render.rect.width} ${currRen.pos.y + currRen.render.rect.height} L${currRen.pos.x} ${currRen.pos.y + currRen.render.rect.height} Z`,
4222
+ // stroke: '#0050b3',
4223
+ // fill: 'none',
4224
+ // 'stroke-width': 1
4225
+ // }));
4226
+ // }
4227
+ // }
4196
4228
  }
4197
4229
  /**
4198
4230
  * 渲染数据源验证错误提示框
@@ -4297,30 +4329,6 @@ function renderUnderWavyLine(event, r, color) {
4297
4329
  d += Array(Math.ceil(width / 3)).fill("3,0").join(' t ');
4298
4330
  const path = ElementUtil.createSvgPath({ d, fill: 'none', stroke: color });
4299
4331
  event.highlights.push(path);
4300
- }
4301
- /**
4302
- * 获取渲染元素相对稳当的位置
4303
- * @param render
4304
- * @param refPos
4305
- */
4306
- function getRenderPosToDoc(render, refPos = null) {
4307
- refPos = refPos ?? { x: 0, y: 0 };
4308
- if (render instanceof DocumentRenderObject) {
4309
- return refPos;
4310
- }
4311
- const currPos = { x: render.rect.x + refPos.x, y: render.rect.y + refPos.y };
4312
- return getRenderPosToDoc(render.parent, currPos);
4313
- }
4314
- function getCurrentParaGroupRenders(r) {
4315
- const renders = [];
4316
- const currParaRender = ElementUtil.getParentRender(r, ParagraphRenderObject);
4317
- for (let i = 0; i < r.element.paintRenders.length; i++) {
4318
- const paraRender = ElementUtil.getParentRender(r.element.paintRenders[i], ParagraphRenderObject);
4319
- if (paraRender === currParaRender) {
4320
- renders.push(r.element.paintRenders[i]);
4321
- }
4322
- }
4323
- return renders;
4324
4332
  }
4325
4333
 
4326
4334
  class DocumentBodyElement extends BlockContainerElement {
@@ -4362,7 +4370,7 @@ class DocumentBodyElement extends BlockContainerElement {
4362
4370
  super.beginMeasure(data);
4363
4371
  }
4364
4372
  }
4365
- class DocumentBodyRenderObject extends MuiltBlockLineRenderObject {
4373
+ class DocumentBodyRenderObject extends MultiBlockLineRenderObject {
4366
4374
  clone(cloneData = true) {
4367
4375
  const cloneRender = new DocumentBodyRenderObject(this.element);
4368
4376
  cloneRender.rect = ElementUtil.cloneRect(this.rect);
@@ -4661,7 +4669,7 @@ class TableRowElement extends BlockContainerElement {
4661
4669
  return tr;
4662
4670
  }
4663
4671
  }
4664
- class TableRowRenderObject extends MuiltBlockLineRenderObject {
4672
+ class TableRowRenderObject extends MultiBlockLineRenderObject {
4665
4673
  //被截断的行是否需要重新计算高度
4666
4674
  remeasureState = true;
4667
4675
  //当前行是否存在合并单元格
@@ -4891,9 +4899,7 @@ class TextGroupRenderObject extends LeafRenderObject {
4891
4899
  event.highlights.push(ElementUtil.getStrokeSvgPath(path, '#000', 1));
4892
4900
  }
4893
4901
  //处理null-text
4894
- if (this.element.isDecorate && this.element.disableClick && !this.element.parent) {
4895
- t.data.attrs['opacity'] = '0.58';
4896
- }
4902
+ if (this.element.isDecorate && this.element.disableClick && !this.element.parent) ;
4897
4903
  return t;
4898
4904
  }
4899
4905
  }
@@ -6160,7 +6166,7 @@ class TableElement extends BlockContainerElement {
6160
6166
  };
6161
6167
  }
6162
6168
  }
6163
- class TableRenderObject extends MuiltBlockLineRenderObject {
6169
+ class TableRenderObject extends MultiBlockLineRenderObject {
6164
6170
  setRenderWidth(maxWidth) {
6165
6171
  super.setRenderWidth(maxWidth);
6166
6172
  }
@@ -8640,7 +8646,62 @@ class DataElementDateFactory extends DataElementBaseFactory {
8640
8646
  }
8641
8647
  }
8642
8648
 
8643
- class DataElementGroupElement extends InlineGroupInputElement {
8649
+ class BreakElement extends LeafElement {
8650
+ textProps;
8651
+ constructor() {
8652
+ super('br');
8653
+ this.textProps = new TextProps();
8654
+ this.textProps.fontSize = 14;
8655
+ this.textProps.fontName = '宋体';
8656
+ this.textProps.color = '#595959';
8657
+ }
8658
+ createRenderObject() {
8659
+ const symbol = new BreakRenderObject(this);
8660
+ symbol.rect.height = 14;
8661
+ symbol.rect.width = 7;
8662
+ return symbol;
8663
+ }
8664
+ serialize() {
8665
+ return {
8666
+ type: 'br',
8667
+ props: {}
8668
+ };
8669
+ }
8670
+ clone() {
8671
+ const clone = new BreakElement();
8672
+ cloneElementBase(this, clone);
8673
+ return clone;
8674
+ }
8675
+ }
8676
+ class BreakRenderObject extends LeafRenderObject {
8677
+ exportSVG(event) {
8678
+ if (!event.options.showEnterSymbol || event.mode === 'print') {
8679
+ return null;
8680
+ }
8681
+ return ElementUtil.createSvgText('↓', { 'dominant-baseline': 'hanging',
8682
+ 'font-family': 'Courier',
8683
+ 'font-size': this.rect.height,
8684
+ x: this.rect.x + 4,
8685
+ y: this.rect.y,
8686
+ fill: 'green' });
8687
+ }
8688
+ clone() {
8689
+ const render = new BreakRenderObject(this.element);
8690
+ render.rect = ElementUtil.cloneRect(this.rect);
8691
+ return render;
8692
+ }
8693
+ }
8694
+ class BreakFactory extends ElementFactory {
8695
+ match(type) {
8696
+ return type === 'br';
8697
+ }
8698
+ createElement(data) {
8699
+ const ele = new BreakElement();
8700
+ return ele;
8701
+ }
8702
+ }
8703
+
8704
+ class DataElementGroupElement extends DataElementInlineGroup {
8644
8705
  constructor() {
8645
8706
  super('data-group');
8646
8707
  this.props = new DataElementGroupProps();
@@ -8653,6 +8714,38 @@ class DataElementGroupElement extends InlineGroupInputElement {
8653
8714
  this.refreshView();
8654
8715
  });
8655
8716
  }
8717
+ setValue(val) {
8718
+ if (val === null || val === undefined) {
8719
+ val = '';
8720
+ }
8721
+ if (this.getValue() === val) {
8722
+ return;
8723
+ }
8724
+ this.pubOnChange('self');
8725
+ this.clearInnerItems();
8726
+ if (typeof val !== 'string') {
8727
+ val += '';
8728
+ }
8729
+ if (val) {
8730
+ const items = val.split('<br/>');
8731
+ if (items.length) {
8732
+ items.forEach((item, index) => {
8733
+ const valueText = new TextGroupElement();
8734
+ this.props.valueTextProps.clone(valueText.props);
8735
+ valueText.text = item + '';
8736
+ this.addChild(valueText, this.length - 1);
8737
+ if (index < items.length - 1) {
8738
+ const brElement = new BreakElement();
8739
+ this.addChild(brElement, this.length - 1);
8740
+ }
8741
+ });
8742
+ }
8743
+ }
8744
+ this.onChangedValidate();
8745
+ }
8746
+ getValue() {
8747
+ return ElementSerialize.serializeString(this, { all: false });
8748
+ }
8656
8749
  clone(data) {
8657
8750
  return super.cloneSelf(data, DataElementGroupElement);
8658
8751
  }
@@ -8688,9 +8781,18 @@ class DataElementGroupFactory extends DataElementBaseFactory {
8688
8781
  createElement(data) {
8689
8782
  const props = data.props;
8690
8783
  const ele = new DataElementGroupElement();
8691
- ElementUtil.readEleBaseProps(ele.props, props);
8784
+ this.createDataEleProps(ele.props, props);
8692
8785
  return ele;
8693
8786
  }
8787
+ createDataEleProps(dest, props) {
8788
+ const dataEleProps = dest;
8789
+ ElementUtil.readEleBaseProps(dataEleProps, props);
8790
+ dataEleProps.nullText = props.nullText;
8791
+ dataEleProps.nullTextProps = ElementUtil.readTextProps(null, props.nullTextProps, this.options);
8792
+ dataEleProps.valueTextProps = ElementUtil.readTextProps(null, props.valueTextProps, this.options);
8793
+ dataEleProps.dataType = props.dataType;
8794
+ return dataEleProps;
8795
+ }
8694
8796
  }
8695
8797
 
8696
8798
  class DataElementImage extends DataElementLeaf {
@@ -8932,61 +9034,6 @@ class DataElementListFactory extends DataElementBaseFactory {
8932
9034
  }
8933
9035
  }
8934
9036
 
8935
- class BreakElement extends LeafElement {
8936
- textProps;
8937
- constructor() {
8938
- super('br');
8939
- this.textProps = new TextProps();
8940
- this.textProps.fontSize = 14;
8941
- this.textProps.fontName = '宋体';
8942
- this.textProps.color = '#595959';
8943
- }
8944
- createRenderObject() {
8945
- const symbol = new BreakRenderObject(this);
8946
- symbol.rect.height = 14;
8947
- symbol.rect.width = 7;
8948
- return symbol;
8949
- }
8950
- serialize() {
8951
- return {
8952
- type: 'br',
8953
- props: {}
8954
- };
8955
- }
8956
- clone() {
8957
- const clone = new BreakElement();
8958
- cloneElementBase(this, clone);
8959
- return clone;
8960
- }
8961
- }
8962
- class BreakRenderObject extends LeafRenderObject {
8963
- exportSVG(event) {
8964
- if (!event.options.showEnterSymbol || event.mode === 'print') {
8965
- return null;
8966
- }
8967
- return ElementUtil.createSvgText('↓', { 'dominant-baseline': 'hanging',
8968
- 'font-family': 'Courier',
8969
- 'font-size': this.rect.height,
8970
- x: this.rect.x + 4,
8971
- y: this.rect.y,
8972
- fill: 'green' });
8973
- }
8974
- clone() {
8975
- const render = new BreakRenderObject(this.element);
8976
- render.rect = ElementUtil.cloneRect(this.rect);
8977
- return render;
8978
- }
8979
- }
8980
- class BreakFactory extends ElementFactory {
8981
- match(type) {
8982
- return type === 'br';
8983
- }
8984
- createElement(data) {
8985
- const ele = new BreakElement();
8986
- return ele;
8987
- }
8988
- }
8989
-
8990
9037
  class DataElementText extends DataElementInlineGroup {
8991
9038
  //props: DataEleBaseTextProps;
8992
9039
  constructor() {
@@ -9117,33 +9164,23 @@ class DataContainerElement extends BlockContainerElement {
9117
9164
  }
9118
9165
  super.beginMeasure(data);
9119
9166
  }
9120
- serialize() {
9121
- const p = {
9167
+ serialize(viewOptions) {
9168
+ return {
9122
9169
  type: this.type,
9123
- props: {}
9170
+ props: {
9171
+ ...this.props.getSerializeProps(viewOptions)
9172
+ }
9124
9173
  };
9125
- if (this.props.id) {
9126
- p['id'] = this.props.id;
9127
- }
9128
- if (this.props.name) {
9129
- p['name'] = this.props.name;
9130
- }
9131
- if (this.props.caption) {
9132
- p['caption'] = this.props.caption;
9133
- }
9134
- return p;
9135
9174
  }
9136
9175
  clone(data) {
9137
9176
  const clone = new DataContainerElement();
9138
- clone.props.id = this.props.id;
9139
- clone.props.name = this.props.name;
9140
- clone.props.caption = this.props.caption;
9177
+ this.props.clone(clone.props);
9141
9178
  cloneElementBase(this, clone);
9142
9179
  cloneChildren(this, clone, data);
9143
9180
  return clone;
9144
9181
  }
9145
9182
  }
9146
- class DataContainerRenderObject extends MuiltBlockLineRenderObject {
9183
+ class DataContainerRenderObject extends MultiBlockLineRenderObject {
9147
9184
  clone(cloneData = true) {
9148
9185
  const cloneRender = new DataContainerRenderObject(this.element);
9149
9186
  cloneRender.rect = ElementUtil.cloneRect(this.rect);
@@ -9168,24 +9205,21 @@ class DataContainerFactory extends ElementFactory {
9168
9205
  return type === 'data-container';
9169
9206
  }
9170
9207
  createElement(data) {
9171
- const element = new DataContainerElement();
9208
+ const ele = new DataContainerElement();
9172
9209
  const props = data.props;
9173
- if (props?.id) {
9174
- element.props.id = props.id;
9175
- }
9176
- if (props?.name) {
9177
- element.props.name = props.name;
9178
- }
9179
- if (props?.caption) {
9180
- element.props.caption = props.caption;
9181
- }
9182
- return element;
9210
+ ElementUtil.readEleBaseProps(ele.props, props);
9211
+ return ele;
9183
9212
  }
9184
9213
  }
9185
- class DataContainerProps {
9186
- caption;
9187
- id;
9188
- name;
9214
+ class DataContainerProps extends DataEleBaseProps {
9215
+ clone(dest) {
9216
+ const clone = dest ?? new DataContainerProps();
9217
+ super.cloneBaseProps(clone);
9218
+ }
9219
+ getSerializeProps(options) {
9220
+ const props = {};
9221
+ return this.getBaseProps(props, options);
9222
+ }
9189
9223
  }
9190
9224
 
9191
9225
  /**
@@ -9271,7 +9305,7 @@ class DocumentBodyPartElement extends BlockContainerElement {
9271
9305
  return clone;
9272
9306
  }
9273
9307
  }
9274
- class DocumentBodyPartRenderObject extends MuiltBlockLineRenderObject {
9308
+ class DocumentBodyPartRenderObject extends MultiBlockLineRenderObject {
9275
9309
  clone(cloneData = true) {
9276
9310
  const cloneRender = new DocumentBodyPartRenderObject(this.element);
9277
9311
  cloneRender.rect = ElementUtil.cloneRect(this.rect);
@@ -10647,10 +10681,10 @@ class ElementSerialize {
10647
10681
  }
10648
10682
  }
10649
10683
  if (element.props && element.props['__attachedProperty'] && !result.props['__attachedProperty']) {
10650
- result.props['__attachedProperty'] = CommonUtil.cloneValue(element.props['__attachedProperty']);
10684
+ result.props['__attachedProperty'] = this.serializeObject(element.props['__attachedProperty']);
10651
10685
  }
10652
10686
  if (element.attribute) {
10653
- result['attribute'] = this.serializeAttribute(element);
10687
+ result['attribute'] = this.serializeObject(element.attribute);
10654
10688
  }
10655
10689
  return result;
10656
10690
  }
@@ -10674,20 +10708,23 @@ class ElementSerialize {
10674
10708
  }
10675
10709
  return "";
10676
10710
  }
10677
- static serializeAttribute(element) {
10678
- if (element.attribute) {
10679
- const result = {};
10680
- for (const key in element.attribute) {
10681
- if (element.attribute[key] !== undefined && element.attribute[key] !== null) {
10682
- result[key] = element.attribute[key];
10711
+ static serializeObject(obj) {
10712
+ if (obj === null || obj === undefined) {
10713
+ return null;
10714
+ }
10715
+ const result = {};
10716
+ for (const key in obj) {
10717
+ if (obj[key] !== undefined && obj[key] !== null) {
10718
+ if (key.startsWith("__")) {
10719
+ continue;
10683
10720
  }
10721
+ result[key] = obj[key];
10684
10722
  }
10685
- if (Object.keys(result).length === 0) {
10686
- return null;
10687
- }
10688
- return CommonUtil.cloneValue(result);
10689
10723
  }
10690
- return null;
10724
+ if (Object.keys(result).length === 0) {
10725
+ return null;
10726
+ }
10727
+ return CommonUtil.cloneValue(result);
10691
10728
  }
10692
10729
  /**
10693
10730
  * 获取选中的结构
@@ -13335,8 +13372,8 @@ class DocumentContext {
13335
13372
  const dataEleList = this.ctx.treeFilter(item => validateDataEle(item));
13336
13373
  return dataEleList.map(item => item.props.id);
13337
13374
  }
13338
- getControlInstanceList() {
13339
- return this.ctx.treeFilter(item => validateDataEle(item));
13375
+ getControlInstanceList(options) {
13376
+ return this.ctx.treeFilter(item => validateDataEle(item), options);
13340
13377
  }
13341
13378
  getControlById(id) {
13342
13379
  return this.ctx.treeFind(item => validateDataEle(item) && item['props']['id'] === id);
@@ -13359,8 +13396,9 @@ class DocumentContext {
13359
13396
  * 获取数据元结构以及get\set闭包调用函数
13360
13397
  * @returns
13361
13398
  */
13362
- getDataElementModelList() {
13363
- const dataEleList = this.ctx.treeFilter(item => validateDataEle(item) || item instanceof DataElementInlineGroup);
13399
+ getDataElementModelList(options) {
13400
+ const dataEleList = this.ctx.treeFilter(item => validateDataEle(item), options);
13401
+ //数据元、数据组
13364
13402
  const dataInlineGroups = dataEleList.filter(item => item instanceof DataElementInlineGroup);
13365
13403
  const dataLeafs = dataEleList.filter(item => item instanceof DataElementLeaf);
13366
13404
  //复选框数据元
@@ -13369,7 +13407,7 @@ class DocumentContext {
13369
13407
  const dataOtherLeafValues = CommonUtil.removeUnionSet(dataLeafs, dataCheckList).map(item => ({
13370
13408
  id: item.props.id,
13371
13409
  name: item.props.name,
13372
- fieldName: item.props.field,
13410
+ fieldName: item.props.fieldName,
13373
13411
  item,
13374
13412
  getValue: () => {
13375
13413
  return item.getValue();
@@ -14714,7 +14752,7 @@ class DocumentArrange {
14714
14752
  }
14715
14753
  const cloneRender = this.pMeasure.createRenderObject(render.element);
14716
14754
  cloneRender.setRenderWidth(render.rect.width);
14717
- if (render instanceof MuiltBlockLineRenderObject) {
14755
+ if (render instanceof MultiBlockLineRenderObject) {
14718
14756
  let sumHeight = 0;
14719
14757
  const children = [...render.getItems()];
14720
14758
  let j = 0;
@@ -14723,7 +14761,7 @@ class DocumentArrange {
14723
14761
  //sumHeight = ElementUtil.remeasure(cloneRender);
14724
14762
  const calcBlockLineHeight = this.getBlockLineHeight(blockLine);
14725
14763
  if (calcBlockLineHeight + sumHeight > limitHeight) {
14726
- if (blockLine instanceof MuiltBlockLineRenderObject) {
14764
+ if (blockLine instanceof MultiBlockLineRenderObject) {
14727
14765
  //限制的外框尺寸
14728
14766
  const availHeight = limitHeight - sumHeight;
14729
14767
  //限制的内框尺寸
@@ -15433,9 +15471,12 @@ class DocumentEvent {
15433
15471
  },
15434
15472
  mouseup: (evt) => {
15435
15473
  this.mouseup(evt, ElementUtil.getMousePos(evt, scale));
15474
+ this.mouseClickHandle(evt);
15436
15475
  },
15437
15476
  click: (evt) => {
15438
- this.mouseClickHandle(evt);
15477
+ //nulltext 不触发 click 事件,暂且这么处理
15478
+ //移到 mouseup 事件中处理
15479
+ //this.mouseClickHandle(evt);
15439
15480
  },
15440
15481
  mousemove: (evt) => {
15441
15482
  this.mousemove(evt, ElementUtil.getMousePos(evt, scale));
@@ -18729,103 +18770,56 @@ function getFocusTextSegment(selection) {
18729
18770
  let { startControl: element, startOffset: offset } = selection;
18730
18771
  if (!(element instanceof TextGroupElement))
18731
18772
  return false;
18732
- if (!supportSegment())
18733
- return false;
18734
18773
  const focusEle = element;
18735
- offset = offset + 1;
18736
- offset = offset > focusEle.textMeasures.length ? focusEle.textMeasures.length : offset;
18737
- //获取连续的字符
18738
- const items = [...getConsecutiveTextsByDirection(element), element, ...getConsecutiveTextsByDirection(element, false)];
18739
- const sortItems = getTextSortData(items);
18740
- const { index, text } = sortItems.reduce((prev, curr) => {
18741
- prev.text += curr.text;
18742
- if (prev.completed) {
18743
- return prev;
18744
- }
18745
- if (curr.item === focusEle) {
18746
- prev.index += offset;
18747
- prev.completed = true;
18748
- }
18749
- else {
18750
- prev.index += curr.item.textMeasures.length;
18751
- }
18752
- return prev;
18753
- }, { completed: false, index: 0, text: '' });
18754
- const { index: hitIndex, len: hitLen } = getHitSegment(text, index);
18755
- const matchSegment = sortItems.filter(item => (item.index <= hitIndex && item.endIndex > hitIndex) || (item.index <= hitIndex + hitLen && item.endIndex > hitIndex + hitLen));
18756
- const startSegment = matchSegment[0];
18757
- const endSegment = matchSegment[matchSegment.length - 1];
18758
- const startOffset = hitIndex - startSegment.index;
18759
- const endOffset = hitIndex + hitLen - endSegment.index;
18760
- const newRange = new SelectionRange();
18761
- newRange.setStart(startSegment.item, startOffset);
18762
- newRange.setEnd(endSegment.item, endOffset);
18763
- selection.addRange(newRange);
18774
+ const focusText = focusEle.text;
18775
+ if (!focusText) {
18776
+ return false;
18777
+ }
18778
+ const [start, end] = tokenize(focusText, offset);
18779
+ const range = new SelectionRange();
18780
+ range.setStart(focusEle, start);
18781
+ range.setEnd(focusEle, end + 1);
18782
+ selection.addRange(range);
18764
18783
  return true;
18765
18784
  }
18766
- /**
18767
- * 进行分词
18768
- * @param text
18769
- * @param focusOffset
18770
- */
18771
- function getHitSegment(text, focusOffset) {
18772
- const segmenter = new Intl.Segmenter("zh-CN", { granularity: "word" });
18773
- const iterator1 = segmenter.segment(text)[Symbol.iterator]();
18774
- const segItems = Array.from(iterator1);
18775
- let index = 0;
18776
- for (let i = 0; i < segItems.length; i++) {
18777
- const segItem = segItems[i];
18778
- const currIndex = segItem.index;
18779
- const currLen = segItem.segment.length;
18780
- if (focusOffset > currIndex && focusOffset <= currLen + currIndex) {
18781
- return {
18782
- index,
18783
- len: currLen
18784
- };
18785
+ function tokenize(text, index) {
18786
+ if (text.length === 0) {
18787
+ return [0, 0]; // 处理空字符串的情况
18788
+ }
18789
+ const isChinese = (char) => {
18790
+ return /^[\u4e00-\u9fa5]+$/.test(char);
18791
+ };
18792
+ const isEnglish = (char) => {
18793
+ return /^[a-zA-Z]+$/.test(char);
18794
+ };
18795
+ const isNumeric = (char) => {
18796
+ return /^[0-9]+$/.test(char);
18797
+ };
18798
+ let start = index;
18799
+ let end = index;
18800
+ // 向左查找开始位置
18801
+ while (start > 0) {
18802
+ if ((isChinese(text[start]) && isChinese(text[start - 1])) ||
18803
+ (isEnglish(text[start]) && isEnglish(text[start - 1])) ||
18804
+ (isNumeric(text[start]) && isNumeric(text[start - 1]))) {
18805
+ start--;
18806
+ }
18807
+ else {
18808
+ break;
18785
18809
  }
18786
- index += currLen;
18787
18810
  }
18788
- throw new Error('未获取到对应的分词词组');
18789
- }
18790
- function supportSegment() {
18791
- return typeof Intl.Segmenter === 'function';
18792
- }
18793
- /**
18794
- * 根据前后顺序标识索引位
18795
- * @param texts
18796
- */
18797
- function getTextSortData(texts) {
18798
- let index = 0;
18799
- const sortItems = [];
18800
- for (let i = 0; i < texts.length; i++) {
18801
- const item = texts[i];
18802
- const sortData = {
18803
- len: item.textMeasures.length,
18804
- index,
18805
- endIndex: index + item.textMeasures.length,
18806
- item,
18807
- text: item.text
18808
- };
18809
- sortItems.push(sortData);
18810
- index += sortData.len;
18811
+ // 向右查找结束位置
18812
+ while (end < text.length - 1) {
18813
+ if ((isChinese(text[end]) && isChinese(text[end + 1])) ||
18814
+ (isEnglish(text[end]) && isEnglish(text[end + 1])) ||
18815
+ (isNumeric(text[end]) && isNumeric(text[end + 1]))) {
18816
+ end++;
18817
+ }
18818
+ else {
18819
+ break;
18820
+ }
18811
18821
  }
18812
- return sortItems;
18813
- }
18814
- /**
18815
- * 获取指定方向上连续的字符
18816
- * @param element
18817
- * @param prev
18818
- */
18819
- function getConsecutiveTextsByDirection(element, prev = true) {
18820
- let prevText = element;
18821
- const prevTexts = [];
18822
- const func = prev ? ElementUtil.getPrevSiblingElement : ElementUtil.getNextSiblingElement;
18823
- const addItem = prev ? prevTexts.unshift : prevTexts.push;
18824
- while ((prevText = func(prevText)) && prevText instanceof TextGroupElement) {
18825
- //addItem(prevText);
18826
- addItem.apply(prevTexts, [prevText]);
18827
- }
18828
- return prevTexts;
18822
+ return [start, end];
18829
18823
  }
18830
18824
 
18831
18825
  /**
@@ -19390,7 +19384,7 @@ class DocumentSvg {
19390
19384
  ns: 'http://www.w3.org/2000/svg',
19391
19385
  attrs: {
19392
19386
  stroke: 'none',
19393
- fill: item.color ?? 'rgb(85,165,255)',
19387
+ fill: item.color ?? this.viewOptions.selectionColor,
19394
19388
  'paint-order': 'stroke fill markers',
19395
19389
  d: `M${item.x} ${item.y} L${item.x + item.width} ${item.y} L${item.x + item.width} ${item.y + item.height} L${item.x} ${item.y + item.height} Z`,
19396
19390
  'fill-opacity': '0.5'
@@ -20785,6 +20779,7 @@ class DocEditor {
20785
20779
  ssChanged && this.documentEvent.invokeCursor(this.selectionState.startControl);
20786
20780
  this.documentSelection.clearSnapshot();
20787
20781
  this.documentSelection.takeSnapshot();
20782
+ return ssChanged;
20788
20783
  }
20789
20784
  /**
20790
20785
  * 根据当前选区,更新待输入文本字体信息
@@ -20824,6 +20819,7 @@ class DocEditor {
20824
20819
  this.selectionState.cursorPos = cursorRect;
20825
20820
  const abPos = ElementUtil.cloneRect(cursorRect);
20826
20821
  this.setCursorPosition(abPos);
20822
+ this.setCursorVisibility(true);
20827
20823
  //this.documentEvent.invokeCursor(startControl);
20828
20824
  return;
20829
20825
  }
@@ -20857,7 +20853,7 @@ class DocEditor {
20857
20853
  setCursorVisibility(visibility) {
20858
20854
  if (visibility) {
20859
20855
  //this.editInput.style.removeProperty('display');
20860
- this.editInput.focus();
20856
+ this.editInput.focus({ preventScroll: true });
20861
20857
  }
20862
20858
  }
20863
20859
  hiddenInput(reset = true, pos = null) {
@@ -20879,7 +20875,6 @@ class DocEditor {
20879
20875
  this.editInput.style.height = position.height + 'px';
20880
20876
  this.editInput.style.width = "1.6px";
20881
20877
  this.editInput.readOnly = false;
20882
- this.setCursorVisibility(true);
20883
20878
  //判断光标位置是否被可见,如果不可见,需要将其设置到可见区域
20884
20879
  //TODO:暂时不做处理
20885
20880
  //this.setCursorInputStatus();
@@ -20915,7 +20910,7 @@ class DocEditor {
20915
20910
  * 文档点击事件
20916
20911
  */
20917
20912
  docClickHandle(evt) {
20918
- this.hiddenInput();
20913
+ //this.hiddenInput();
20919
20914
  // this.setCursor();
20920
20915
  // this.updateSelection();
20921
20916
  this.refreshDocument();
@@ -21215,20 +21210,20 @@ class DocEditor {
21215
21210
  const startControl = this.selectionState.startControl;
21216
21211
  if (startControl instanceof TextGroupElement) {
21217
21212
  const selectedStyle = startControl.props.clone(null);
21218
- const selectionOverlayColor = this.viewOptions.selectionOverlaysColor;
21219
- this.viewOptions.selectionOverlaysColor = "rgba(0,58,140,0.8)";
21213
+ const selectionColor = this.viewOptions.selectionColor;
21214
+ this.viewOptions.selectionColor = "rgba(0,58,140,0.8)";
21220
21215
  const cancelToken = {};
21221
21216
  const sub = this.onClickEvent.subscribe(() => {
21222
21217
  sub.unsubscribe();
21223
21218
  this.setTextFormat(selectedStyle);
21224
- this.viewOptions.selectionOverlaysColor = selectionOverlayColor;
21219
+ this.viewOptions.selectionColor = selectionColor;
21225
21220
  if (cancelToken.onFinish) {
21226
21221
  cancelToken.onFinish(null);
21227
21222
  }
21228
21223
  });
21229
21224
  cancelToken.cancel = () => {
21230
21225
  sub.unsubscribe();
21231
- this.viewOptions.selectionOverlaysColor = selectionOverlayColor;
21226
+ this.viewOptions.selectionColor = selectionColor;
21232
21227
  };
21233
21228
  return cancelToken;
21234
21229
  }
@@ -21989,7 +21984,7 @@ class DocEditor {
21989
21984
  rule.setRuleOptions({ width: this.viewOptions.docPageSettings.width, pagePL, pagePR, docLeft });
21990
21985
  }
21991
21986
  version() {
21992
- return "2.2.7";
21987
+ return "2.2.9";
21993
21988
  }
21994
21989
  switchPageHeaderEditor() {
21995
21990
  this.docCtx.document.switchPageHeaderEditor(this.selectionState, null);
@@ -27852,7 +27847,7 @@ exports.LostCursorEvent = LostCursorEvent;
27852
27847
  exports.MarginProps = MarginProps;
27853
27848
  exports.MouseElementEvent = MouseElementEvent;
27854
27849
  exports.MousedownElementEvent = MousedownElementEvent;
27855
- exports.MuiltBlockLineRenderObject = MuiltBlockLineRenderObject;
27850
+ exports.MultiBlockLineRenderObject = MultiBlockLineRenderObject;
27856
27851
  exports.OnceSubject = OnceSubject;
27857
27852
  exports.PSymbolElement = PSymbolElement;
27858
27853
  exports.PSymbolRenderObject = PSymbolRenderObject;