@hailin-zheng/editor-core 2.2.16 → 2.2.17

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/index-cjs.js CHANGED
@@ -3875,17 +3875,18 @@ class InlineGroupInputElement extends InlineGroupElement {
3875
3875
  endDecorate;
3876
3876
  constructor(type) {
3877
3877
  super(type);
3878
- //行内块不允许换行
3879
- this.addEvent('ElementKeyDown', (evt) => {
3880
- const { selectionState, sourceEvent, source } = evt;
3881
- const { startControl, startOffset } = selectionState;
3882
- if (IsInSideInlineGroupInputElement(startControl, startOffset)) {
3883
- if (sourceEvent.shiftKey && sourceEvent.keyCode === 13) ;
3884
- else if (!sourceEvent.shiftKey && sourceEvent.keyCode === 13) {
3885
- evt.isCancel = true;
3886
- }
3887
- }
3888
- }, true);
3878
+ // //行内块不允许换行
3879
+ // this.addEvent<KeyboradElementEvent>('ElementKeyDown', (evt) => {
3880
+ // const { selectionState, sourceEvent, source } = evt;
3881
+ // const { startControl, startOffset } = selectionState;
3882
+ // if (IsInSideInlineGroupInputElement(startControl as LeafElement, startOffset)) {
3883
+ // if (sourceEvent.shiftKey && sourceEvent.keyCode === 13) {
3884
+ // //this.removeNullText();
3885
+ // } else if (!sourceEvent.shiftKey && sourceEvent.keyCode === 13) {
3886
+ // evt.isCancel = true;
3887
+ // }
3888
+ // }
3889
+ // }, true);
3889
3890
  this.addEvent('GotCursor', (evt) => {
3890
3891
  const { startControl, startOffset } = evt.selectionState;
3891
3892
  if (IsInSideInlineGroupInputElement(startControl, startOffset)) {
@@ -4481,7 +4482,7 @@ class PSymbolElement extends LeafElement {
4481
4482
  }
4482
4483
  createRenderObject() {
4483
4484
  const symbol = new PSymbolRenderObject(this);
4484
- symbol.rect.height = this.defaultHeight;
4485
+ symbol.rect.height = Math.ceil(this.defaultHeight * TEXT_HEIGHT_FACTOR);
4485
4486
  symbol.rect.width = 1;
4486
4487
  return symbol;
4487
4488
  }
@@ -4503,12 +4504,20 @@ class PSymbolRenderObject extends LeafRenderObject {
4503
4504
  if (!event.options.showEnterSymbol || event.mode === 'print') {
4504
4505
  return null;
4505
4506
  }
4506
- return ElementUtil.createSvgText('↵', { 'dominant-baseline': 'hanging',
4507
- 'font-family': 'Courier',
4508
- 'font-size': this.element.defaultHeight,
4507
+ const font = `14px 宋体`;
4508
+ const actualFontBoundingBoxAscent = event.renderCtx.mainContext.getActualFontBoundingBoxAscent(font);
4509
+ let y = this.rect.y;
4510
+ //基线处理
4511
+ y += actualFontBoundingBoxAscent ?? 0;
4512
+ //行高处理
4513
+ y += (this.rect.height - 14) / 2;
4514
+ return ElementUtil.createSvgText('↵', {
4515
+ 'font-family': '宋体',
4516
+ 'font-size': 14,
4509
4517
  x: this.rect.x,
4510
- y: this.rect.y,
4511
- fill: 'green' });
4518
+ y: y,
4519
+ fill: 'green'
4520
+ });
4512
4521
  }
4513
4522
  //绘制段落符号
4514
4523
  clone() {
@@ -8727,7 +8736,7 @@ class BreakElement extends LeafElement {
8727
8736
  }
8728
8737
  createRenderObject() {
8729
8738
  const symbol = new BreakRenderObject(this);
8730
- symbol.rect.height = 14;
8739
+ symbol.rect.height = Math.ceil(14 * TEXT_HEIGHT_FACTOR);
8731
8740
  symbol.rect.width = 7;
8732
8741
  return symbol;
8733
8742
  }
@@ -8748,12 +8757,26 @@ class BreakRenderObject extends LeafRenderObject {
8748
8757
  if (!event.options.showEnterSymbol || event.mode === 'print') {
8749
8758
  return null;
8750
8759
  }
8751
- return ElementUtil.createSvgText('↓', { 'dominant-baseline': 'hanging',
8752
- 'font-family': 'Courier',
8753
- 'font-size': this.rect.height,
8754
- x: this.rect.x + 4,
8755
- y: this.rect.y,
8756
- fill: 'green' });
8760
+ // return ElementUtil.createSvgText( '↓',{ 'dominant-baseline': 'hanging',
8761
+ // 'font-family': 'Courier',
8762
+ // 'font-size': this.rect.height,
8763
+ // x: this.rect.x + 4,
8764
+ // y: this.rect.y,
8765
+ // fill: 'green'});
8766
+ const font = `14px 宋体`;
8767
+ const actualFontBoundingBoxAscent = event.renderCtx.mainContext.getActualFontBoundingBoxAscent(font);
8768
+ let y = 0;
8769
+ //基线处理
8770
+ y += actualFontBoundingBoxAscent ?? 0;
8771
+ //行高处理
8772
+ y += (this.parent.rect.height - 14) / 2;
8773
+ return ElementUtil.createSvgText('↓', {
8774
+ 'font-family': '宋体',
8775
+ 'font-size': 14,
8776
+ x: this.rect.x,
8777
+ y: y,
8778
+ fill: 'green'
8779
+ });
8757
8780
  }
8758
8781
  clone() {
8759
8782
  const render = new BreakRenderObject(this.element);
@@ -10888,9 +10911,22 @@ class ElementSerialize {
10888
10911
  const { startCol, endCol } = tbRegion;
10889
10912
  const cloneTb = ElementUtil.cloneRange(range, false, 'copy');
10890
10913
  cloneTb.props.cols = cloneTb.props.cols.slice(startCol, endCol + 1);
10891
- return cloneTb;
10914
+ return [cloneTb];
10892
10915
  }
10893
- return ElementUtil.cloneRange(range, false, 'copy');
10916
+ //元素全选的情况下
10917
+ // if (range.isFullSelected) {
10918
+ // const ele = ElementUtil.cloneRange(range, false, 'copy');
10919
+ // return ele ? [ele] : null;
10920
+ // }
10921
+ //元素部分选中的情况下,只获取选中的部分元素
10922
+ const selectedEle = range.selectedChildren.map(item => ElementUtil.cloneRange(item, false, 'copy'));
10923
+ const list = [];
10924
+ selectedEle.forEach(item => {
10925
+ if (item) {
10926
+ list.push(item);
10927
+ }
10928
+ });
10929
+ return list;
10894
10930
  }
10895
10931
  /**
10896
10932
  * 选中的文本
@@ -10898,18 +10934,19 @@ class ElementSerialize {
10898
10934
  * @param viewOptions
10899
10935
  */
10900
10936
  static getSelectedText(ss, viewOptions) {
10901
- const selectedStruct = this.getSelectedStruct(ss, viewOptions);
10902
- if (selectedStruct) {
10903
- return this.serializeString(selectedStruct);
10937
+ const selectedStructs = this.getSelectedStruct(ss, viewOptions);
10938
+ if (selectedStructs) {
10939
+ return selectedStructs.map(item => this.serializeString(item)).join('');
10904
10940
  }
10905
10941
  else {
10906
10942
  return '';
10907
10943
  }
10908
10944
  }
10909
10945
  static getSelectedJSON(ss, viewOptions) {
10910
- const selectedStruct = this.getSelectedStruct(ss, viewOptions);
10911
- if (selectedStruct) {
10912
- return JSON.stringify(this.serialize(selectedStruct, viewOptions));
10946
+ const selectedStructs = this.getSelectedStruct(ss, viewOptions);
10947
+ if (selectedStructs) {
10948
+ //return JSON.stringify(this.serialize(selectedStructs, viewOptions));
10949
+ return JSON.stringify(selectedStructs.map(item => this.serialize(item, viewOptions)).filter(item => item));
10913
10950
  }
10914
10951
  else {
10915
10952
  return '';
@@ -16826,7 +16863,7 @@ class DocumentEvent {
16826
16863
  this.moveCursorToRightHandle(nextEle, ElementUtil.fixedOffset(nextEle, -1));
16827
16864
  return;
16828
16865
  }
16829
- this.selectionState.resetRange(nextEle, 1);
16866
+ this.selectionState.resetRange(nextEle, 0);
16830
16867
  return;
16831
16868
  }
16832
16869
  }
@@ -18024,6 +18061,9 @@ class DocumentChange {
18024
18061
  const { startControl } = this.selectionState;
18025
18062
  const paragraph = ElementUtil.getParentByType(startControl, ParagraphElement);
18026
18063
  const breakPara = this.splitCurrentParagraph();
18064
+ if (!breakPara) {
18065
+ return;
18066
+ }
18027
18067
  //选中的是一个元素
18028
18068
  if (breakPara === paragraph) {
18029
18069
  const clonePara = paragraph.clone(false);
@@ -18045,6 +18085,9 @@ class DocumentChange {
18045
18085
  */
18046
18086
  insertLayoutContainer(ele) {
18047
18087
  const breakPara = this.splitCurrentParagraph();
18088
+ if (!breakPara) {
18089
+ return;
18090
+ }
18048
18091
  breakPara.parent.addChild(ele, breakPara.getIndex());
18049
18092
  this.selectionState.resetRange(ele, 0);
18050
18093
  }
@@ -18054,6 +18097,11 @@ class DocumentChange {
18054
18097
  */
18055
18098
  splitCurrentParagraph() {
18056
18099
  const { startControl, startOffset } = this.selectionState;
18100
+ //内联数据块不能拆分两部分
18101
+ if (!this.allowSplitParagraph()) {
18102
+ console.warn("内联数据块不能拆分!");
18103
+ return null;
18104
+ }
18057
18105
  const paragraph = ElementUtil.getParentByType(startControl, ParagraphElement);
18058
18106
  const paraContainer = paragraph.parent;
18059
18107
  //如果选中的是段落第一个元素
@@ -18474,67 +18522,53 @@ class DocumentChange {
18474
18522
  }
18475
18523
  return;
18476
18524
  }
18477
- const pasteElement = this.eleReader.readElement(JSON.parse(pasteData.doc));
18478
- if (!pasteElement) {
18479
- console.log('粘贴反序列化数据失败', pasteData);
18525
+ let data = JSON.parse(pasteData.doc);
18526
+ const pasteEles = [];
18527
+ data = Array.isArray(data) ? data : [data];
18528
+ data.forEach(item => {
18529
+ const ele = this.eleReader.readElement(item);
18530
+ if (ele) {
18531
+ pasteEles.push(ele);
18532
+ }
18533
+ else {
18534
+ console.log('粘贴反序列化数据失败', item);
18535
+ }
18536
+ });
18537
+ if (!pasteEles.length) {
18480
18538
  return;
18481
18539
  }
18482
18540
  //表单模式:如果复制的是单格式的文本,需要序列化为纯文本处理
18483
18541
  if (this.viewOptions.docMode === exports.DocMode.FormEdit) {
18484
- const pasteString = ElementSerialize.serializeString(pasteElement, { all: false });
18542
+ const pasteString = pasteEles.map(item => ElementSerialize.serializeString(item, { all: false })).join('');
18485
18543
  if (pasteString) {
18486
18544
  this.pastePlainText(pasteString);
18487
18545
  }
18488
18546
  return;
18489
18547
  }
18490
- if (pasteElement instanceof ParagraphElement || pasteElement instanceof InlineGroupElement) {
18491
- const children = [];
18492
- if (pasteElement instanceof ParagraphElement) {
18493
- children.push(...ElementUtil.getChildrenElements(pasteElement));
18494
- }
18495
- else if (pasteElement instanceof InlineGroupElement) {
18496
- //当前粘贴的元素为数据元,并且在数据元内部粘贴
18497
- if (IsInSideDataElement(startControl, startOffset) && pasteElement instanceof DataElementInlineGroup) {
18498
- const pasteChildren = pasteElement.getInnerItems().map(item => item.clone(true));
18499
- children.push(...pasteChildren);
18500
- }
18501
- else {
18502
- children.push(pasteElement);
18503
- }
18504
- }
18505
- if (!children.length) {
18506
- throw new Error('段落子元素为空');
18507
- }
18508
- const lastEle = this.insertElement(startControl, startOffset, children);
18509
- this.selectionState.resetRange(lastEle, -1);
18510
- return;
18548
+ //复制的内容为表格,且操作位于单元格内
18549
+ if (pasteEles[0] instanceof TableElement && ElementUtil.getParentByType(startControl, TableCellElement) && pasteEles.length === 1) {
18550
+ this.pasteTableToCell(pasteEles[0]);
18511
18551
  }
18512
- else if (pasteElement instanceof BlockContainerElement) {
18552
+ //复制的为表格或者段落
18553
+ else if (pasteEles[0] instanceof BlockContainerElement || pasteEles[0] instanceof ParagraphElement) {
18513
18554
  const children = [];
18514
- if (pasteElement instanceof TableElement) {
18515
- children.push(pasteElement);
18516
- if (ElementUtil.getParentByType(startControl, TableCellElement)) {
18517
- this.pasteTableToCell(pasteElement);
18518
- return;
18519
- }
18520
- }
18521
- else {
18522
- children.push(...ElementUtil.getChildrenElements(pasteElement));
18523
- }
18524
- //复制的内容全部为段落,执行黏贴操作
18525
- // if (children.every(item => item instanceof ParagraphElement)) {
18526
- // const targetParagraph = this.splitCurrentParagraph();
18527
- // children.forEach((item, i) => {
18528
- // targetParagraph.parent.addChild(item, targetParagraph.getIndex());
18529
- // });
18530
- // this.selectionState.resetRange(children[children.length - 1], -1);
18531
- // }
18555
+ children.push(...pasteEles);
18532
18556
  const targetParagraph = this.splitCurrentParagraph();
18557
+ if (!targetParagraph) {
18558
+ return;
18559
+ }
18533
18560
  children.forEach((item, i) => {
18534
18561
  targetParagraph.parent.addChild(item, targetParagraph.getIndex());
18535
18562
  });
18536
18563
  this.selectionState.resetRange(children[children.length - 1], -1);
18537
18564
  }
18565
+ //符合段落内的元素约定
18566
+ else {
18567
+ const children = [];
18568
+ children.push(...pasteEles);
18569
+ const lastEle = this.insertElement(startControl, startOffset, children);
18570
+ this.selectionState.resetRange(lastEle, -1);
18571
+ }
18538
18572
  }
18539
18573
  /**
18540
18574
  * 复制单元格向另一个单元格粘贴
@@ -18630,6 +18664,9 @@ class DocumentChange {
18630
18664
  }
18631
18665
  else {
18632
18666
  const breakPara = this.splitCurrentParagraph();
18667
+ if (!breakPara) {
18668
+ return;
18669
+ }
18633
18670
  for (let i = 0; i < textItems.length; i++) {
18634
18671
  const newPara = breakPara.clone(false);
18635
18672
  const inputTextProps = this.getDefaultTextPropsByOptions();
@@ -18641,6 +18678,20 @@ class DocumentChange {
18641
18678
  this.selectionState.resetRange(breakPara, 0);
18642
18679
  }
18643
18680
  }
18681
+ /**
18682
+ * 当前光标位置是否允许分割生成两个段落
18683
+ */
18684
+ allowSplitParagraph(target) {
18685
+ if (!target) {
18686
+ target = this.selectionState;
18687
+ }
18688
+ const { startControl, startOffset } = target;
18689
+ //内联数据块不能拆分两部分
18690
+ if (IsInSideInlineGroupInputElement(startControl, startOffset)) {
18691
+ return false;
18692
+ }
18693
+ return true;
18694
+ }
18644
18695
  /**
18645
18696
  * 向当前光标追加文本
18646
18697
  * @param appendStr
@@ -21686,8 +21737,13 @@ class DocEditor {
21686
21737
  return ElementSerialize.getSelectedJSON(this.selectionState, this.viewOptions);
21687
21738
  }
21688
21739
  getSelectedText() {
21689
- const copySerializeStr = ElementSerialize.getSelectedStruct(this.selectionState, this.viewOptions);
21690
- return ElementSerialize.serializeString(copySerializeStr);
21740
+ const selectedEles = ElementSerialize.getSelectedStruct(this.selectionState, this.viewOptions);
21741
+ if (!selectedEles) {
21742
+ return '';
21743
+ }
21744
+ return selectedEles.map(ele => {
21745
+ return ElementSerialize.serializeString(ele);
21746
+ }).join('');
21691
21747
  }
21692
21748
  /**
21693
21749
  * 执行编辑器内部复制事件
@@ -22318,7 +22374,7 @@ class DocEditor {
22318
22374
  rule.setRuleOptions({ width: this.viewOptions.docPageSettings.width, pagePL, pagePR, docLeft });
22319
22375
  }
22320
22376
  version() {
22321
- return "2.2.16";
22377
+ return "2.2.17";
22322
22378
  }
22323
22379
  switchPageHeaderEditor() {
22324
22380
  this.docCtx.document.switchPageHeaderEditor(this.selectionState, null);
@@ -22632,6 +22688,39 @@ class DocEditor {
22632
22688
  }
22633
22689
  return res;
22634
22690
  }
22691
+ /**
22692
+ * 返回当前光标处是否允许截断段落生成新的段落
22693
+ * @returns
22694
+ */
22695
+ allowSplitParagraph() {
22696
+ return this.documentChange.allowSplitParagraph();
22697
+ }
22698
+ /**
22699
+ * 设置元素属性(attribute)
22700
+ * @param ele
22701
+ * @param attr
22702
+ * @param value
22703
+ */
22704
+ setEleAttribute(ele, attr, value) {
22705
+ ElementUtil.setEleAttribute(ele, attr, value);
22706
+ }
22707
+ /**
22708
+ * 获取元素属性(attribute)
22709
+ * @param ele
22710
+ * @param attr
22711
+ * @returns
22712
+ */
22713
+ getEleAttribute(ele, attr) {
22714
+ return ElementUtil.getEleAttribute(ele, attr);
22715
+ }
22716
+ /**
22717
+ * 删除元素属性(attribute)
22718
+ * @param ele
22719
+ * @param attr
22720
+ */
22721
+ removeEleAttribute(ele, attr) {
22722
+ ElementUtil.removeEleAttribute(ele, attr);
22723
+ }
22635
22724
  }
22636
22725
 
22637
22726
  /**