@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.js CHANGED
@@ -3846,17 +3846,18 @@ class InlineGroupInputElement extends InlineGroupElement {
3846
3846
  endDecorate;
3847
3847
  constructor(type) {
3848
3848
  super(type);
3849
- //行内块不允许换行
3850
- this.addEvent('ElementKeyDown', (evt) => {
3851
- const { selectionState, sourceEvent, source } = evt;
3852
- const { startControl, startOffset } = selectionState;
3853
- if (IsInSideInlineGroupInputElement(startControl, startOffset)) {
3854
- if (sourceEvent.shiftKey && sourceEvent.keyCode === 13) ;
3855
- else if (!sourceEvent.shiftKey && sourceEvent.keyCode === 13) {
3856
- evt.isCancel = true;
3857
- }
3858
- }
3859
- }, true);
3849
+ // //行内块不允许换行
3850
+ // this.addEvent<KeyboradElementEvent>('ElementKeyDown', (evt) => {
3851
+ // const { selectionState, sourceEvent, source } = evt;
3852
+ // const { startControl, startOffset } = selectionState;
3853
+ // if (IsInSideInlineGroupInputElement(startControl as LeafElement, startOffset)) {
3854
+ // if (sourceEvent.shiftKey && sourceEvent.keyCode === 13) {
3855
+ // //this.removeNullText();
3856
+ // } else if (!sourceEvent.shiftKey && sourceEvent.keyCode === 13) {
3857
+ // evt.isCancel = true;
3858
+ // }
3859
+ // }
3860
+ // }, true);
3860
3861
  this.addEvent('GotCursor', (evt) => {
3861
3862
  const { startControl, startOffset } = evt.selectionState;
3862
3863
  if (IsInSideInlineGroupInputElement(startControl, startOffset)) {
@@ -4452,7 +4453,7 @@ class PSymbolElement extends LeafElement {
4452
4453
  }
4453
4454
  createRenderObject() {
4454
4455
  const symbol = new PSymbolRenderObject(this);
4455
- symbol.rect.height = this.defaultHeight;
4456
+ symbol.rect.height = Math.ceil(this.defaultHeight * TEXT_HEIGHT_FACTOR);
4456
4457
  symbol.rect.width = 1;
4457
4458
  return symbol;
4458
4459
  }
@@ -4474,12 +4475,20 @@ class PSymbolRenderObject extends LeafRenderObject {
4474
4475
  if (!event.options.showEnterSymbol || event.mode === 'print') {
4475
4476
  return null;
4476
4477
  }
4477
- return ElementUtil.createSvgText('↵', { 'dominant-baseline': 'hanging',
4478
- 'font-family': 'Courier',
4479
- 'font-size': this.element.defaultHeight,
4478
+ const font = `14px 宋体`;
4479
+ const actualFontBoundingBoxAscent = event.renderCtx.mainContext.getActualFontBoundingBoxAscent(font);
4480
+ let y = this.rect.y;
4481
+ //基线处理
4482
+ y += actualFontBoundingBoxAscent ?? 0;
4483
+ //行高处理
4484
+ y += (this.rect.height - 14) / 2;
4485
+ return ElementUtil.createSvgText('↵', {
4486
+ 'font-family': '宋体',
4487
+ 'font-size': 14,
4480
4488
  x: this.rect.x,
4481
- y: this.rect.y,
4482
- fill: 'green' });
4489
+ y: y,
4490
+ fill: 'green'
4491
+ });
4483
4492
  }
4484
4493
  //绘制段落符号
4485
4494
  clone() {
@@ -8698,7 +8707,7 @@ class BreakElement extends LeafElement {
8698
8707
  }
8699
8708
  createRenderObject() {
8700
8709
  const symbol = new BreakRenderObject(this);
8701
- symbol.rect.height = 14;
8710
+ symbol.rect.height = Math.ceil(14 * TEXT_HEIGHT_FACTOR);
8702
8711
  symbol.rect.width = 7;
8703
8712
  return symbol;
8704
8713
  }
@@ -8719,12 +8728,26 @@ class BreakRenderObject extends LeafRenderObject {
8719
8728
  if (!event.options.showEnterSymbol || event.mode === 'print') {
8720
8729
  return null;
8721
8730
  }
8722
- return ElementUtil.createSvgText('↓', { 'dominant-baseline': 'hanging',
8723
- 'font-family': 'Courier',
8724
- 'font-size': this.rect.height,
8725
- x: this.rect.x + 4,
8726
- y: this.rect.y,
8727
- fill: 'green' });
8731
+ // return ElementUtil.createSvgText( '↓',{ 'dominant-baseline': 'hanging',
8732
+ // 'font-family': 'Courier',
8733
+ // 'font-size': this.rect.height,
8734
+ // x: this.rect.x + 4,
8735
+ // y: this.rect.y,
8736
+ // fill: 'green'});
8737
+ const font = `14px 宋体`;
8738
+ const actualFontBoundingBoxAscent = event.renderCtx.mainContext.getActualFontBoundingBoxAscent(font);
8739
+ let y = 0;
8740
+ //基线处理
8741
+ y += actualFontBoundingBoxAscent ?? 0;
8742
+ //行高处理
8743
+ y += (this.parent.rect.height - 14) / 2;
8744
+ return ElementUtil.createSvgText('↓', {
8745
+ 'font-family': '宋体',
8746
+ 'font-size': 14,
8747
+ x: this.rect.x,
8748
+ y: y,
8749
+ fill: 'green'
8750
+ });
8728
8751
  }
8729
8752
  clone() {
8730
8753
  const render = new BreakRenderObject(this.element);
@@ -10859,9 +10882,22 @@ class ElementSerialize {
10859
10882
  const { startCol, endCol } = tbRegion;
10860
10883
  const cloneTb = ElementUtil.cloneRange(range, false, 'copy');
10861
10884
  cloneTb.props.cols = cloneTb.props.cols.slice(startCol, endCol + 1);
10862
- return cloneTb;
10885
+ return [cloneTb];
10863
10886
  }
10864
- return ElementUtil.cloneRange(range, false, 'copy');
10887
+ //元素全选的情况下
10888
+ // if (range.isFullSelected) {
10889
+ // const ele = ElementUtil.cloneRange(range, false, 'copy');
10890
+ // return ele ? [ele] : null;
10891
+ // }
10892
+ //元素部分选中的情况下,只获取选中的部分元素
10893
+ const selectedEle = range.selectedChildren.map(item => ElementUtil.cloneRange(item, false, 'copy'));
10894
+ const list = [];
10895
+ selectedEle.forEach(item => {
10896
+ if (item) {
10897
+ list.push(item);
10898
+ }
10899
+ });
10900
+ return list;
10865
10901
  }
10866
10902
  /**
10867
10903
  * 选中的文本
@@ -10869,18 +10905,19 @@ class ElementSerialize {
10869
10905
  * @param viewOptions
10870
10906
  */
10871
10907
  static getSelectedText(ss, viewOptions) {
10872
- const selectedStruct = this.getSelectedStruct(ss, viewOptions);
10873
- if (selectedStruct) {
10874
- return this.serializeString(selectedStruct);
10908
+ const selectedStructs = this.getSelectedStruct(ss, viewOptions);
10909
+ if (selectedStructs) {
10910
+ return selectedStructs.map(item => this.serializeString(item)).join('');
10875
10911
  }
10876
10912
  else {
10877
10913
  return '';
10878
10914
  }
10879
10915
  }
10880
10916
  static getSelectedJSON(ss, viewOptions) {
10881
- const selectedStruct = this.getSelectedStruct(ss, viewOptions);
10882
- if (selectedStruct) {
10883
- return JSON.stringify(this.serialize(selectedStruct, viewOptions));
10917
+ const selectedStructs = this.getSelectedStruct(ss, viewOptions);
10918
+ if (selectedStructs) {
10919
+ //return JSON.stringify(this.serialize(selectedStructs, viewOptions));
10920
+ return JSON.stringify(selectedStructs.map(item => this.serialize(item, viewOptions)).filter(item => item));
10884
10921
  }
10885
10922
  else {
10886
10923
  return '';
@@ -16797,7 +16834,7 @@ class DocumentEvent {
16797
16834
  this.moveCursorToRightHandle(nextEle, ElementUtil.fixedOffset(nextEle, -1));
16798
16835
  return;
16799
16836
  }
16800
- this.selectionState.resetRange(nextEle, 1);
16837
+ this.selectionState.resetRange(nextEle, 0);
16801
16838
  return;
16802
16839
  }
16803
16840
  }
@@ -17995,6 +18032,9 @@ class DocumentChange {
17995
18032
  const { startControl } = this.selectionState;
17996
18033
  const paragraph = ElementUtil.getParentByType(startControl, ParagraphElement);
17997
18034
  const breakPara = this.splitCurrentParagraph();
18035
+ if (!breakPara) {
18036
+ return;
18037
+ }
17998
18038
  //选中的是一个元素
17999
18039
  if (breakPara === paragraph) {
18000
18040
  const clonePara = paragraph.clone(false);
@@ -18016,6 +18056,9 @@ class DocumentChange {
18016
18056
  */
18017
18057
  insertLayoutContainer(ele) {
18018
18058
  const breakPara = this.splitCurrentParagraph();
18059
+ if (!breakPara) {
18060
+ return;
18061
+ }
18019
18062
  breakPara.parent.addChild(ele, breakPara.getIndex());
18020
18063
  this.selectionState.resetRange(ele, 0);
18021
18064
  }
@@ -18025,6 +18068,11 @@ class DocumentChange {
18025
18068
  */
18026
18069
  splitCurrentParagraph() {
18027
18070
  const { startControl, startOffset } = this.selectionState;
18071
+ //内联数据块不能拆分两部分
18072
+ if (!this.allowSplitParagraph()) {
18073
+ console.warn("内联数据块不能拆分!");
18074
+ return null;
18075
+ }
18028
18076
  const paragraph = ElementUtil.getParentByType(startControl, ParagraphElement);
18029
18077
  const paraContainer = paragraph.parent;
18030
18078
  //如果选中的是段落第一个元素
@@ -18445,67 +18493,53 @@ class DocumentChange {
18445
18493
  }
18446
18494
  return;
18447
18495
  }
18448
- const pasteElement = this.eleReader.readElement(JSON.parse(pasteData.doc));
18449
- if (!pasteElement) {
18450
- console.log('粘贴反序列化数据失败', pasteData);
18496
+ let data = JSON.parse(pasteData.doc);
18497
+ const pasteEles = [];
18498
+ data = Array.isArray(data) ? data : [data];
18499
+ data.forEach(item => {
18500
+ const ele = this.eleReader.readElement(item);
18501
+ if (ele) {
18502
+ pasteEles.push(ele);
18503
+ }
18504
+ else {
18505
+ console.log('粘贴反序列化数据失败', item);
18506
+ }
18507
+ });
18508
+ if (!pasteEles.length) {
18451
18509
  return;
18452
18510
  }
18453
18511
  //表单模式:如果复制的是单格式的文本,需要序列化为纯文本处理
18454
18512
  if (this.viewOptions.docMode === DocMode.FormEdit) {
18455
- const pasteString = ElementSerialize.serializeString(pasteElement, { all: false });
18513
+ const pasteString = pasteEles.map(item => ElementSerialize.serializeString(item, { all: false })).join('');
18456
18514
  if (pasteString) {
18457
18515
  this.pastePlainText(pasteString);
18458
18516
  }
18459
18517
  return;
18460
18518
  }
18461
- if (pasteElement instanceof ParagraphElement || pasteElement instanceof InlineGroupElement) {
18462
- const children = [];
18463
- if (pasteElement instanceof ParagraphElement) {
18464
- children.push(...ElementUtil.getChildrenElements(pasteElement));
18465
- }
18466
- else if (pasteElement instanceof InlineGroupElement) {
18467
- //当前粘贴的元素为数据元,并且在数据元内部粘贴
18468
- if (IsInSideDataElement(startControl, startOffset) && pasteElement instanceof DataElementInlineGroup) {
18469
- const pasteChildren = pasteElement.getInnerItems().map(item => item.clone(true));
18470
- children.push(...pasteChildren);
18471
- }
18472
- else {
18473
- children.push(pasteElement);
18474
- }
18475
- }
18476
- if (!children.length) {
18477
- throw new Error('段落子元素为空');
18478
- }
18479
- const lastEle = this.insertElement(startControl, startOffset, children);
18480
- this.selectionState.resetRange(lastEle, -1);
18481
- return;
18519
+ //复制的内容为表格,且操作位于单元格内
18520
+ if (pasteEles[0] instanceof TableElement && ElementUtil.getParentByType(startControl, TableCellElement) && pasteEles.length === 1) {
18521
+ this.pasteTableToCell(pasteEles[0]);
18482
18522
  }
18483
- else if (pasteElement instanceof BlockContainerElement) {
18523
+ //复制的为表格或者段落
18524
+ else if (pasteEles[0] instanceof BlockContainerElement || pasteEles[0] instanceof ParagraphElement) {
18484
18525
  const children = [];
18485
- if (pasteElement instanceof TableElement) {
18486
- children.push(pasteElement);
18487
- if (ElementUtil.getParentByType(startControl, TableCellElement)) {
18488
- this.pasteTableToCell(pasteElement);
18489
- return;
18490
- }
18491
- }
18492
- else {
18493
- children.push(...ElementUtil.getChildrenElements(pasteElement));
18494
- }
18495
- //复制的内容全部为段落,执行黏贴操作
18496
- // if (children.every(item => item instanceof ParagraphElement)) {
18497
- // const targetParagraph = this.splitCurrentParagraph();
18498
- // children.forEach((item, i) => {
18499
- // targetParagraph.parent.addChild(item, targetParagraph.getIndex());
18500
- // });
18501
- // this.selectionState.resetRange(children[children.length - 1], -1);
18502
- // }
18526
+ children.push(...pasteEles);
18503
18527
  const targetParagraph = this.splitCurrentParagraph();
18528
+ if (!targetParagraph) {
18529
+ return;
18530
+ }
18504
18531
  children.forEach((item, i) => {
18505
18532
  targetParagraph.parent.addChild(item, targetParagraph.getIndex());
18506
18533
  });
18507
18534
  this.selectionState.resetRange(children[children.length - 1], -1);
18508
18535
  }
18536
+ //符合段落内的元素约定
18537
+ else {
18538
+ const children = [];
18539
+ children.push(...pasteEles);
18540
+ const lastEle = this.insertElement(startControl, startOffset, children);
18541
+ this.selectionState.resetRange(lastEle, -1);
18542
+ }
18509
18543
  }
18510
18544
  /**
18511
18545
  * 复制单元格向另一个单元格粘贴
@@ -18601,6 +18635,9 @@ class DocumentChange {
18601
18635
  }
18602
18636
  else {
18603
18637
  const breakPara = this.splitCurrentParagraph();
18638
+ if (!breakPara) {
18639
+ return;
18640
+ }
18604
18641
  for (let i = 0; i < textItems.length; i++) {
18605
18642
  const newPara = breakPara.clone(false);
18606
18643
  const inputTextProps = this.getDefaultTextPropsByOptions();
@@ -18612,6 +18649,20 @@ class DocumentChange {
18612
18649
  this.selectionState.resetRange(breakPara, 0);
18613
18650
  }
18614
18651
  }
18652
+ /**
18653
+ * 当前光标位置是否允许分割生成两个段落
18654
+ */
18655
+ allowSplitParagraph(target) {
18656
+ if (!target) {
18657
+ target = this.selectionState;
18658
+ }
18659
+ const { startControl, startOffset } = target;
18660
+ //内联数据块不能拆分两部分
18661
+ if (IsInSideInlineGroupInputElement(startControl, startOffset)) {
18662
+ return false;
18663
+ }
18664
+ return true;
18665
+ }
18615
18666
  /**
18616
18667
  * 向当前光标追加文本
18617
18668
  * @param appendStr
@@ -21657,8 +21708,13 @@ class DocEditor {
21657
21708
  return ElementSerialize.getSelectedJSON(this.selectionState, this.viewOptions);
21658
21709
  }
21659
21710
  getSelectedText() {
21660
- const copySerializeStr = ElementSerialize.getSelectedStruct(this.selectionState, this.viewOptions);
21661
- return ElementSerialize.serializeString(copySerializeStr);
21711
+ const selectedEles = ElementSerialize.getSelectedStruct(this.selectionState, this.viewOptions);
21712
+ if (!selectedEles) {
21713
+ return '';
21714
+ }
21715
+ return selectedEles.map(ele => {
21716
+ return ElementSerialize.serializeString(ele);
21717
+ }).join('');
21662
21718
  }
21663
21719
  /**
21664
21720
  * 执行编辑器内部复制事件
@@ -22289,7 +22345,7 @@ class DocEditor {
22289
22345
  rule.setRuleOptions({ width: this.viewOptions.docPageSettings.width, pagePL, pagePR, docLeft });
22290
22346
  }
22291
22347
  version() {
22292
- return "2.2.16";
22348
+ return "2.2.17";
22293
22349
  }
22294
22350
  switchPageHeaderEditor() {
22295
22351
  this.docCtx.document.switchPageHeaderEditor(this.selectionState, null);
@@ -22603,6 +22659,39 @@ class DocEditor {
22603
22659
  }
22604
22660
  return res;
22605
22661
  }
22662
+ /**
22663
+ * 返回当前光标处是否允许截断段落生成新的段落
22664
+ * @returns
22665
+ */
22666
+ allowSplitParagraph() {
22667
+ return this.documentChange.allowSplitParagraph();
22668
+ }
22669
+ /**
22670
+ * 设置元素属性(attribute)
22671
+ * @param ele
22672
+ * @param attr
22673
+ * @param value
22674
+ */
22675
+ setEleAttribute(ele, attr, value) {
22676
+ ElementUtil.setEleAttribute(ele, attr, value);
22677
+ }
22678
+ /**
22679
+ * 获取元素属性(attribute)
22680
+ * @param ele
22681
+ * @param attr
22682
+ * @returns
22683
+ */
22684
+ getEleAttribute(ele, attr) {
22685
+ return ElementUtil.getEleAttribute(ele, attr);
22686
+ }
22687
+ /**
22688
+ * 删除元素属性(attribute)
22689
+ * @param ele
22690
+ * @param attr
22691
+ */
22692
+ removeEleAttribute(ele, attr) {
22693
+ ElementUtil.removeEleAttribute(ele, attr);
22694
+ }
22606
22695
  }
22607
22696
 
22608
22697
  /**