@hailin-zheng/editor-core 1.0.60 → 1.0.62

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -79,7 +79,7 @@
79
79
  * <a href="#setCellBackground">setCellBackground 表格背景颜色</a>
80
80
 
81
81
  <h3 id="summary"><code>简介</code></h3>
82
- 编辑器 基于 ts+canvas。运行环境新版浏览器。
82
+ 编辑器 基于 ts+canvas。运行环境现代主流浏览器(chrome等)。
83
83
 
84
84
  <h3 id="install"><code>安装</code></h3>
85
85
  执行 npm i editor-core,安装编辑器。从 “editor-core” 可以引入编辑器类editor-core、loadDoc等导出的属性方法。
@@ -1635,7 +1635,96 @@ const getSelectionState = (): SelectionState => getEditor().selectionState;
1635
1635
  ```
1636
1636
  <!-- /div -->
1637
1637
 
1638
-
1638
+ <h3>如果当前性别为男性,隐藏月经史数据元</h3>
1639
+ ```js
1640
+ //获取文档上下文
1641
+ const docEleCtx = this.docCtx.getCtx(this.docCtx.document);
1642
+ //获取年龄数据元
1643
+ const dataEle = docEleCtx.getControlById('1493477712134672386') as DataElementText;
1644
+ //获取要隐藏的数据组
1645
+ const dataGroup = docEleCtx.ctx.treeFind((item) => item instanceof DataElementGroupElement) as DataElementGroupElement;
1646
+ //侦听数据元更改时间
1647
+ dataEle.onChangeSubject.subscribe((e) => {
1648
+ //在文档重新排版、绘制前,获取最终的指定节点的内容
1649
+ const beforeRefreshSub = this.onBeforeRefreshDocument.subscribe((e2) => {
1650
+ console.log('内容发生改变,隐藏数据组');
1651
+ //获取年龄数据元输入的值
1652
+ const age = Number.parseInt(dataEle.getValue());
1653
+ //年龄大于20,隐藏数据元
1654
+ dataGroup.props.hidden = age > 20;
1655
+ //取消订阅事件
1656
+ beforeRefreshSub.unsubscribe();
1657
+ });
1658
+
1659
+ });
1660
+ ```
1661
+ <h3>插入新段落</h3>
1662
+ 说明:在当前段落后面插入新段落,段落的内容为当前时间
1663
+
1664
+ ```typescript
1665
+ const {startControl} = this.selectionState;
1666
+ if (!startControl) {
1667
+ return;
1668
+ }
1669
+ //1.获取当前段落
1670
+ const currentParagraph = ElementUtil.getParentByType(startControl, ParagraphElement) as ParagraphElement;
1671
+ //2.创建新段落对象
1672
+ const newPara = ParagraphElement.createElement();
1673
+ //3.创建文本对象
1674
+ const newText = new TextGroupElement();
1675
+ newText.text = '当前时间为' + new Date();
1676
+ newText.props.fontName = '楷体';
1677
+ newText.props.fontSize = 18;
1678
+ newText.props.color = '#5b8c00';
1679
+ //4.将文本对象追加到新段落中
1680
+ newPara.addChild(newText);
1681
+ //5.在当前段落后面追加新段落
1682
+ currentParagraph.parent.addChild(newPara, currentParagraph.getIndex() + 1);
1683
+ //6.定位光标到新段落末尾处
1684
+ this.selectionState.resetRange(newText,-1);
1685
+ ```
1686
+ <h3>插入文本数据元</h3>
1687
+ 说明:在当前位置插入文本数据元
1688
+ ```typescript
1689
+ const {startControl} = this.selectionState;
1690
+ if (!startControl) {
1691
+ return;
1692
+ }
1693
+ const newDataTextElement=new DataElementText();
1694
+ newDataTextElement.props.nullText='请输入内容';
1695
+ newDataTextElement.props.nullTextProps=new TextProps();
1696
+ newDataTextElement.props.nullTextProps.fontSize=16;
1697
+ newDataTextElement.props.nullTextProps.fontName='宋体';
1698
+ newDataTextElement.props.nullTextProps.color='#ffc53d';
1699
+ newDataTextElement.props.valueTextProps=new TextProps();
1700
+ newDataTextElement.props.valueTextProps.fontSize=18;
1701
+ newDataTextElement.props.valueTextProps.fontName='楷体';
1702
+ newDataTextElement.props.valueTextProps.color='#096dd9';
1703
+ this.insertNewElement(newDataTextElement);
1704
+ ```
1705
+ <h3>修改页眉</h3>
1706
+ 说明:可以批量修改所有模板的页眉
1707
+ ```typescript
1708
+ //1.获取页眉对象
1709
+ const headerElement=this.docCtx.document.headerElement;
1710
+
1711
+ //2.创建新段落对象
1712
+ const newPara = ParagraphElement.createElement();
1713
+ //3.段落文本居中显示
1714
+ newPara.props.textAlign='center';
1715
+ //4.创建文本对象
1716
+ const newText = new TextGroupElement();
1717
+ newText.text = 'XXX人民医院病历文书';
1718
+ newText.props.fontName = '楷体';
1719
+ newText.props.fontSize = 28;
1720
+ newText.props.color = '#000';
1721
+ //5.将文本对象追加到新段落中
1722
+ newPara.addChild(newText);
1723
+
1724
+ //6.清除页眉内容,并添加新内容
1725
+ headerElement.clearItems();
1726
+ headerElement.addChild(newPara);
1727
+ ```
1639
1728
  <!--
1640
1729
  编辑页脚页眉
1641
1730
  双击页眉,body,页脚 开启是否可编辑,默认body 是可编辑;
package/index-cjs.js CHANGED
@@ -1425,6 +1425,7 @@ class ViewOptions {
1425
1425
  viewBackcolor = 'rgb(230,230,230)';
1426
1426
  paraSymbolColor = 'rgb(128,128,128)';
1427
1427
  dataGroupColor = 'rgb(0,80,179)';
1428
+ defaultLineHeight = 1.3;
1428
1429
  //新增-留痕块文本颜色
1429
1430
  trackInsColor = '#ff4d4f';
1430
1431
  //删除-留痕块文本颜色
@@ -1471,6 +1472,8 @@ class ViewOptions {
1471
1472
  pageNumOffset = 0;
1472
1473
  //页排版模式:单页模式、多页模式、适应页宽模式
1473
1474
  pageLayoutMode = 'singlePage';
1475
+ //默认tab缩进的量
1476
+ defaultIndent = 20;
1474
1477
  //内容区宽度,受审阅窗口宽度影响
1475
1478
  get contentWidth() {
1476
1479
  if (this.showReviewWindow) {
@@ -1733,6 +1736,12 @@ class TextProps extends INotifyPropertyChanged {
1733
1736
  && this.border === props.border;
1734
1737
  }
1735
1738
  }
1739
+ exports.ParagraphNumberType = void 0;
1740
+ (function (ParagraphNumberType) {
1741
+ ParagraphNumberType[ParagraphNumberType["none"] = -1] = "none";
1742
+ ParagraphNumberType[ParagraphNumberType["ul"] = 0] = "ul";
1743
+ ParagraphNumberType[ParagraphNumberType["ol"] = 1] = "ol";
1744
+ })(exports.ParagraphNumberType || (exports.ParagraphNumberType = {}));
1736
1745
  class ParagraphProps extends INotifyPropertyChanged {
1737
1746
  //段落默认的文本属性
1738
1747
  //textProps!: TextProps;
@@ -1740,7 +1749,7 @@ class ParagraphProps extends INotifyPropertyChanged {
1740
1749
  hanging = 0;
1741
1750
  lineHeight = 1.3;
1742
1751
  textAlign = 'left';
1743
- numberType = -1;
1752
+ numberType = exports.ParagraphNumberType.none;
1744
1753
  pageBreak = false;
1745
1754
  clone(dest = null) {
1746
1755
  const clone = dest ?? new ParagraphProps();
@@ -1762,13 +1771,13 @@ class ParagraphProps extends INotifyPropertyChanged {
1762
1771
  if (this.hanging) {
1763
1772
  props["hanging"] = this.hanging;
1764
1773
  }
1765
- if (this.lineHeight && this.lineHeight !== 1.3) {
1774
+ if (this.lineHeight && this.lineHeight !== viewOptions.defaultLineHeight) {
1766
1775
  props["lineHeight"] = this.lineHeight;
1767
1776
  }
1768
1777
  if (this.textAlign && this.textAlign !== "left") {
1769
1778
  props["textAlign"] = this.textAlign;
1770
1779
  }
1771
- if (this.numberType !== -1) {
1780
+ if (this.numberType !== exports.ParagraphNumberType.none) {
1772
1781
  props["numberType"] = this.numberType;
1773
1782
  }
1774
1783
  if (this.pageBreak) {
@@ -2378,6 +2387,13 @@ class ValidateProps {
2378
2387
  id;
2379
2388
  title;
2380
2389
  msg;
2390
+ clone(dest) {
2391
+ const clone = dest ?? new ValidateProps();
2392
+ clone.id = this.id;
2393
+ clone.title = this.title;
2394
+ clone.msg = this.msg;
2395
+ return clone;
2396
+ }
2381
2397
  }
2382
2398
  class DataElementGroupProps {
2383
2399
  id;
@@ -3300,6 +3316,19 @@ class ParagraphElement extends BlockContentElement {
3300
3316
  }
3301
3317
  }
3302
3318
  }, true);
3319
+ this.addEvent('ElementKeyDown', evt => {
3320
+ //当前存在缩进,点击tab
3321
+ if (evt.sourceEvent.keyCode === 9) {
3322
+ const { startControl, startOffset } = evt.selectionState;
3323
+ if (startOffset === 0 && startControl === this.getChild(0)) {
3324
+ const defaultIndent = evt.ctx.viewOptions.defaultIndent;
3325
+ let increaseValue = evt.sourceEvent.shiftKey ? -defaultIndent : defaultIndent;
3326
+ this.props.indent += increaseValue;
3327
+ evt.isCancel = true;
3328
+ evt.sourceEvent.preventDefault();
3329
+ }
3330
+ }
3331
+ }, true);
3303
3332
  }
3304
3333
  /**
3305
3334
  * 设置样式
@@ -3347,25 +3376,39 @@ class ParagraphRenderObject extends MuiltBlockLineRenderObject {
3347
3376
  */
3348
3377
  drawProjectNumber(ctx, viewOptions) {
3349
3378
  const paraElement = this.element;
3350
- if (paraElement.props.numberType >= 0) {
3379
+ if (paraElement.props.numberType !== exports.ParagraphNumberType.none) {
3351
3380
  if (paraElement.paintRenders.indexOf(this) > 0) {
3352
3381
  return;
3353
3382
  }
3354
3383
  const firstLine = this.getChild(0);
3355
- if (!firstLine) {
3356
- debugger;
3357
- }
3358
3384
  const firstInline = firstLine.getChild(0);
3359
- if (!firstInline) {
3360
- debugger;
3361
- }
3362
3385
  const firstInlinePaintPos = ElementUtil.getRenderAbsolutePaintPos(firstInline, {
3363
3386
  x: 0,
3364
3387
  y: -viewOptions.translateY
3365
3388
  });
3366
- const numberSymbolY = firstInlinePaintPos.y + Math.ceil(firstInline.rect.height / 2);
3367
- //ctx.contentContext.drawText(str, textProps, firstInlinePaintPos.x - paraElement.paraProps.indent, numberSymbolY, 14, 14);
3368
- ctx.contentContext.fillCircular(firstInlinePaintPos.x - paraElement.props.indent + 2, numberSymbolY, 4);
3389
+ if (paraElement.props.numberType === exports.ParagraphNumberType.ul) {
3390
+ const numberSymbolY = firstInlinePaintPos.y + Math.ceil(firstInline.rect.height / 2);
3391
+ ctx.contentContext.fillCircular(firstInlinePaintPos.x - paraElement.props.indent + 2, numberSymbolY, 4);
3392
+ }
3393
+ else if (paraElement.props.numberType === exports.ParagraphNumberType.ol) {
3394
+ const parent = paraElement.parent;
3395
+ let i = paraElement.getIndex() - 1;
3396
+ for (; i >= 0; i--) {
3397
+ if (parent.getChild(i) instanceof ParagraphElement) {
3398
+ //紧挨上面的段落
3399
+ const prevSiblingPara = parent.getChild(i);
3400
+ if (prevSiblingPara.props.numberType !== paraElement.props.numberType || prevSiblingPara.props.indent !== paraElement.props.indent) {
3401
+ break;
3402
+ }
3403
+ }
3404
+ }
3405
+ const olText = (paraElement.getIndex() - i) + '.';
3406
+ const textProps = new TextProps();
3407
+ textProps.color = '#000';
3408
+ textProps.fontSize = firstInline.rect.height - 4;
3409
+ textProps.fontName = '宋体';
3410
+ ctx.contentContext.drawText(olText, textProps, firstInlinePaintPos.x - paraElement.props.indent + 2, firstInlinePaintPos.y + 2, 40, textProps.fontSize);
3411
+ }
3369
3412
  }
3370
3413
  }
3371
3414
  clone() {
@@ -3393,7 +3436,7 @@ class ParagraphFactory extends ElementFactory {
3393
3436
  paraElement.props.hanging = props?.hanging ?? 0;
3394
3437
  paraElement.props.textAlign = props?.textAlign ?? 'left';
3395
3438
  paraElement.props.numberType = props?.numberType ?? -1;
3396
- paraElement.props.lineHeight = props?.lineHeight ?? 1.3;
3439
+ paraElement.props.lineHeight = props?.lineHeight ?? this.options.defaultLineHeight;
3397
3440
  paraElement.props.pageBreak = props?.pageBreak ?? false;
3398
3441
  return paraElement;
3399
3442
  }
@@ -7044,7 +7087,14 @@ class CommContentElement extends CommContentBaseElement {
7044
7087
  };
7045
7088
  }
7046
7089
  clone(data) {
7047
- throw new Error('不支持');
7090
+ const clone = new CommContentElement();
7091
+ this.props.clone(clone.props);
7092
+ if (data) {
7093
+ for (let i = 0; i < this.length; i++) {
7094
+ clone.addChild(this.getChild(i).clone(true));
7095
+ }
7096
+ }
7097
+ return clone;
7048
7098
  }
7049
7099
  }
7050
7100
  class CommContentRenderObject extends CommContentBaseRenderObject {
@@ -7060,7 +7110,10 @@ class CommContentRenderObject extends CommContentBaseRenderObject {
7060
7110
  });
7061
7111
  const commMarkLinePos = ElementUtil.getParaLinePos(this.commMarkRender.render, commMarkPos);
7062
7112
  commMarkPos.y = commMarkLinePos.y + 2;
7063
- const docRenderPos = ElementUtil.getRenderAbsolutePaintPos(docRender, { x: 0, y: -e.docCtx.viewOptions.translateY });
7113
+ const docRenderPos = ElementUtil.getRenderAbsolutePaintPos(docRender, {
7114
+ x: 0,
7115
+ y: -e.docCtx.viewOptions.translateY
7116
+ });
7064
7117
  const marginLeft = commMarkPos.x - docRenderPos.x - docRender.padding.left;
7065
7118
  const marginRight = e.docCtx.viewOptions.docPageSettings.width - marginLeft - docRender.padding.right * 2;
7066
7119
  e.render.overlaysContext.drawDashLine([commMarkPos, {
@@ -7257,7 +7310,14 @@ class ValidateElement extends CommContentBaseElement {
7257
7310
  return null;
7258
7311
  }
7259
7312
  clone(data) {
7260
- throw new Error("Method not implemented.");
7313
+ const clone = new ValidateElement();
7314
+ this.props.clone(clone.props);
7315
+ if (data) {
7316
+ for (let i = 0; i < this.length; i++) {
7317
+ clone.addChild(this.getChild(i).clone(true));
7318
+ }
7319
+ }
7320
+ return clone;
7261
7321
  }
7262
7322
  setContent(content) {
7263
7323
  this.clearItems();
@@ -10074,7 +10134,7 @@ class ElementMeasure {
10074
10134
  const innerLineRect = innerLineRects[i];
10075
10135
  innerLineRect.rect.x = this.getParaLineRectStartX(innerLineRects.length, i, paragraph, render, innerLineRect);
10076
10136
  //限制最大行高
10077
- const maxLineHeight = Math.floor(14 * 1.3);
10137
+ const maxLineHeight = paragraph.props.lineHeight !== this.options.defaultLineHeight ? 100 : Math.floor(14 * 2);
10078
10138
  //fillLineHeight填充行高
10079
10139
  let fillLineHeight = Math.ceil(innerLineRect.rect.height * (paragraph.props.lineHeight - 1));
10080
10140
  fillLineHeight = fillLineHeight > maxLineHeight ? maxLineHeight : fillLineHeight;
@@ -11665,63 +11725,6 @@ class DocumentPaint {
11665
11725
  }
11666
11726
  }
11667
11727
 
11668
- /**
11669
- * 段落行
11670
- */
11671
- class ParaLineElement extends LeafElement {
11672
- constructor() {
11673
- super('p-line');
11674
- this.props = new ParaLineProps();
11675
- }
11676
- clone(data) {
11677
- const clone = new ParaLineElement();
11678
- this.props.clone(clone.props);
11679
- return clone;
11680
- }
11681
- createRenderObject(options, renderCtx) {
11682
- const render = new ParaLineRenderObject(this);
11683
- render.rect.width = 9999;
11684
- return render;
11685
- }
11686
- serialize(viewOptions) {
11687
- return {
11688
- type: this.type,
11689
- props: {
11690
- ...this.props
11691
- }
11692
- };
11693
- }
11694
- }
11695
- class ParaLineRenderObject extends LeafRenderObject {
11696
- clone() {
11697
- const clone = new ParaLineRenderObject(this.element);
11698
- clone.rect = ElementUtil.cloneRect(this.rect);
11699
- return clone;
11700
- }
11701
- render(e) {
11702
- const { render, position } = e;
11703
- render.contentContext.drawHoriLine(position.x, position.y, this.parent.rect.width, 'black', 1);
11704
- }
11705
- }
11706
- class ParaLineElementFactory extends ElementFactory {
11707
- createElement(data, renderCtx) {
11708
- const ele = new ParaLineElement();
11709
- ele.props.lineType = data.props?.lineType ?? 'solid';
11710
- return ele;
11711
- }
11712
- match(type) {
11713
- return type === 'p-line';
11714
- }
11715
- }
11716
- class ParaLineProps {
11717
- lineType = 'solid';
11718
- clone(dest) {
11719
- const clone = dest ?? new ParaLineProps();
11720
- clone.lineType = this.lineType;
11721
- return clone;
11722
- }
11723
- }
11724
-
11725
11728
  class ElementReader {
11726
11729
  docCtx;
11727
11730
  renderCtx;
@@ -11763,7 +11766,6 @@ class ElementReader {
11763
11766
  this.addFactory(RunElementFactory);
11764
11767
  this.addFactory(DataElementGroupFactory);
11765
11768
  this.addFactory(DocumentBodyPartFactory);
11766
- this.addFactory(ParaLineElementFactory);
11767
11769
  // this.registerReadFunc<TrackRunProps>('ins-run', (data) => {
11768
11770
  // const props = new TrackRunProps(data.type);
11769
11771
  // props.userId = data.userId;
@@ -14443,12 +14445,12 @@ class DocumentChange {
14443
14445
  }
14444
14446
  const para = ElementUtil.getParentByType(startControl, ParagraphElement);
14445
14447
  const format = {};
14446
- if (para.props.numberType >= 0) {
14447
- format.numberType = -1;
14448
+ if (para.props.numberType !== exports.ParagraphNumberType.none) {
14449
+ format.numberType = exports.ParagraphNumberType.none;
14448
14450
  format.indent = 0;
14449
14451
  }
14450
14452
  else {
14451
- format.numberType = 0;
14453
+ format.numberType = exports.ParagraphNumberType.ul;
14452
14454
  format.indent = 15;
14453
14455
  }
14454
14456
  para.setFormat(format);
@@ -16667,27 +16669,6 @@ class CanvasTextEditor {
16667
16669
  }
16668
16670
  this.flushToSchedule();
16669
16671
  }
16670
- test2() {
16671
- //获取文档上下文
16672
- const docEleCtx = this.docCtx.getCtx(this.docCtx.document);
16673
- //获取年龄数据元
16674
- const dataEle = docEleCtx.getControlById('1493477712134672386');
16675
- //获取要隐藏的数据组
16676
- const dataGroup = docEleCtx.ctx.treeFind((item) => item instanceof DataElementGroupElement);
16677
- //侦听数据元更改时间
16678
- dataEle.onChangeSubject.subscribe((e) => {
16679
- //在文档重新排版、绘制前,获取最终的指定节点的内容
16680
- const beforeRefreshSub = this.onBeforeRefreshDocument.subscribe((e2) => {
16681
- console.log('内容发生改变,隐藏数据组');
16682
- //获取年龄数据元输入的值
16683
- const age = Number.parseInt(dataEle.getValue());
16684
- //年龄大于20,隐藏数据元
16685
- dataGroup.props.hidden = age > 20;
16686
- //取消订阅事件
16687
- beforeRefreshSub.unsubscribe();
16688
- });
16689
- });
16690
- }
16691
16672
  }
16692
16673
 
16693
16674
  /**