@hailin-zheng/editor-core 2.2.15 → 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);
@@ -8799,13 +8822,15 @@ class DataElementGroupElement extends InlineGroupInputElement {
8799
8822
  val += '';
8800
8823
  }
8801
8824
  if (val) {
8802
- const items = val.split('<br/>');
8825
+ const items = val.split('\n');
8803
8826
  if (items.length) {
8804
8827
  items.forEach((item, index) => {
8805
- const valueText = new TextGroupElement();
8806
- this.props.valueTextProps.clone(valueText.props);
8807
- valueText.text = item + '';
8808
- this.addChild(valueText, this.length - 1);
8828
+ if (item) {
8829
+ const valueText = new TextGroupElement();
8830
+ this.props.valueTextProps.clone(valueText.props);
8831
+ valueText.text = item + '';
8832
+ this.addChild(valueText, this.length - 1);
8833
+ }
8809
8834
  if (index < items.length - 1) {
8810
8835
  const brElement = new BreakElement();
8811
8836
  this.addChild(brElement, this.length - 1);
@@ -9201,13 +9226,15 @@ class DataElementText extends DataElementInlineGroup {
9201
9226
  val += '';
9202
9227
  }
9203
9228
  if (val) {
9204
- const items = val.split('<br/>');
9229
+ const items = val.split('\n');
9205
9230
  if (items.length) {
9206
9231
  items.forEach((item, index) => {
9207
- const valueText = new TextGroupElement();
9208
- this.props.valueTextProps.clone(valueText.props);
9209
- valueText.text = item + '';
9210
- this.addChild(valueText, this.length - 1);
9232
+ if (item) {
9233
+ const valueText = new TextGroupElement();
9234
+ this.props.valueTextProps.clone(valueText.props);
9235
+ valueText.text = item + '';
9236
+ this.addChild(valueText, this.length - 1);
9237
+ }
9211
9238
  if (index < items.length - 1) {
9212
9239
  const brElement = new BreakElement();
9213
9240
  this.addChild(brElement, this.length - 1);
@@ -10884,9 +10911,22 @@ class ElementSerialize {
10884
10911
  const { startCol, endCol } = tbRegion;
10885
10912
  const cloneTb = ElementUtil.cloneRange(range, false, 'copy');
10886
10913
  cloneTb.props.cols = cloneTb.props.cols.slice(startCol, endCol + 1);
10887
- return cloneTb;
10914
+ return [cloneTb];
10888
10915
  }
10889
- 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;
10890
10930
  }
10891
10931
  /**
10892
10932
  * 选中的文本
@@ -10894,18 +10934,19 @@ class ElementSerialize {
10894
10934
  * @param viewOptions
10895
10935
  */
10896
10936
  static getSelectedText(ss, viewOptions) {
10897
- const selectedStruct = this.getSelectedStruct(ss, viewOptions);
10898
- if (selectedStruct) {
10899
- return this.serializeString(selectedStruct);
10937
+ const selectedStructs = this.getSelectedStruct(ss, viewOptions);
10938
+ if (selectedStructs) {
10939
+ return selectedStructs.map(item => this.serializeString(item)).join('');
10900
10940
  }
10901
10941
  else {
10902
10942
  return '';
10903
10943
  }
10904
10944
  }
10905
10945
  static getSelectedJSON(ss, viewOptions) {
10906
- const selectedStruct = this.getSelectedStruct(ss, viewOptions);
10907
- if (selectedStruct) {
10908
- 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));
10909
10950
  }
10910
10951
  else {
10911
10952
  return '';
@@ -16822,7 +16863,7 @@ class DocumentEvent {
16822
16863
  this.moveCursorToRightHandle(nextEle, ElementUtil.fixedOffset(nextEle, -1));
16823
16864
  return;
16824
16865
  }
16825
- this.selectionState.resetRange(nextEle, 1);
16866
+ this.selectionState.resetRange(nextEle, 0);
16826
16867
  return;
16827
16868
  }
16828
16869
  }
@@ -18020,6 +18061,9 @@ class DocumentChange {
18020
18061
  const { startControl } = this.selectionState;
18021
18062
  const paragraph = ElementUtil.getParentByType(startControl, ParagraphElement);
18022
18063
  const breakPara = this.splitCurrentParagraph();
18064
+ if (!breakPara) {
18065
+ return;
18066
+ }
18023
18067
  //选中的是一个元素
18024
18068
  if (breakPara === paragraph) {
18025
18069
  const clonePara = paragraph.clone(false);
@@ -18041,6 +18085,9 @@ class DocumentChange {
18041
18085
  */
18042
18086
  insertLayoutContainer(ele) {
18043
18087
  const breakPara = this.splitCurrentParagraph();
18088
+ if (!breakPara) {
18089
+ return;
18090
+ }
18044
18091
  breakPara.parent.addChild(ele, breakPara.getIndex());
18045
18092
  this.selectionState.resetRange(ele, 0);
18046
18093
  }
@@ -18050,6 +18097,11 @@ class DocumentChange {
18050
18097
  */
18051
18098
  splitCurrentParagraph() {
18052
18099
  const { startControl, startOffset } = this.selectionState;
18100
+ //内联数据块不能拆分两部分
18101
+ if (!this.allowSplitParagraph()) {
18102
+ console.warn("内联数据块不能拆分!");
18103
+ return null;
18104
+ }
18053
18105
  const paragraph = ElementUtil.getParentByType(startControl, ParagraphElement);
18054
18106
  const paraContainer = paragraph.parent;
18055
18107
  //如果选中的是段落第一个元素
@@ -18470,67 +18522,53 @@ class DocumentChange {
18470
18522
  }
18471
18523
  return;
18472
18524
  }
18473
- const pasteElement = this.eleReader.readElement(JSON.parse(pasteData.doc));
18474
- if (!pasteElement) {
18475
- 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) {
18476
18538
  return;
18477
18539
  }
18478
18540
  //表单模式:如果复制的是单格式的文本,需要序列化为纯文本处理
18479
18541
  if (this.viewOptions.docMode === exports.DocMode.FormEdit) {
18480
- const pasteString = ElementSerialize.serializeString(pasteElement, { all: false });
18542
+ const pasteString = pasteEles.map(item => ElementSerialize.serializeString(item, { all: false })).join('');
18481
18543
  if (pasteString) {
18482
18544
  this.pastePlainText(pasteString);
18483
18545
  }
18484
18546
  return;
18485
18547
  }
18486
- if (pasteElement instanceof ParagraphElement || pasteElement instanceof InlineGroupElement) {
18487
- const children = [];
18488
- if (pasteElement instanceof ParagraphElement) {
18489
- children.push(...ElementUtil.getChildrenElements(pasteElement));
18490
- }
18491
- else if (pasteElement instanceof InlineGroupElement) {
18492
- //当前粘贴的元素为数据元,并且在数据元内部粘贴
18493
- if (IsInSideDataElement(startControl, startOffset) && pasteElement instanceof DataElementInlineGroup) {
18494
- const pasteChildren = pasteElement.getInnerItems().map(item => item.clone(true));
18495
- children.push(...pasteChildren);
18496
- }
18497
- else {
18498
- children.push(pasteElement);
18499
- }
18500
- }
18501
- if (!children.length) {
18502
- throw new Error('段落子元素为空');
18503
- }
18504
- const lastEle = this.insertElement(startControl, startOffset, children);
18505
- this.selectionState.resetRange(lastEle, -1);
18506
- return;
18548
+ //复制的内容为表格,且操作位于单元格内
18549
+ if (pasteEles[0] instanceof TableElement && ElementUtil.getParentByType(startControl, TableCellElement) && pasteEles.length === 1) {
18550
+ this.pasteTableToCell(pasteEles[0]);
18507
18551
  }
18508
- else if (pasteElement instanceof BlockContainerElement) {
18552
+ //复制的为表格或者段落
18553
+ else if (pasteEles[0] instanceof BlockContainerElement || pasteEles[0] instanceof ParagraphElement) {
18509
18554
  const children = [];
18510
- if (pasteElement instanceof TableElement) {
18511
- children.push(pasteElement);
18512
- if (ElementUtil.getParentByType(startControl, TableCellElement)) {
18513
- this.pasteTableToCell(pasteElement);
18514
- return;
18515
- }
18516
- }
18517
- else {
18518
- children.push(...ElementUtil.getChildrenElements(pasteElement));
18519
- }
18520
- //复制的内容全部为段落,执行黏贴操作
18521
- // if (children.every(item => item instanceof ParagraphElement)) {
18522
- // const targetParagraph = this.splitCurrentParagraph();
18523
- // children.forEach((item, i) => {
18524
- // targetParagraph.parent.addChild(item, targetParagraph.getIndex());
18525
- // });
18526
- // this.selectionState.resetRange(children[children.length - 1], -1);
18527
- // }
18555
+ children.push(...pasteEles);
18528
18556
  const targetParagraph = this.splitCurrentParagraph();
18557
+ if (!targetParagraph) {
18558
+ return;
18559
+ }
18529
18560
  children.forEach((item, i) => {
18530
18561
  targetParagraph.parent.addChild(item, targetParagraph.getIndex());
18531
18562
  });
18532
18563
  this.selectionState.resetRange(children[children.length - 1], -1);
18533
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
+ }
18534
18572
  }
18535
18573
  /**
18536
18574
  * 复制单元格向另一个单元格粘贴
@@ -18626,6 +18664,9 @@ class DocumentChange {
18626
18664
  }
18627
18665
  else {
18628
18666
  const breakPara = this.splitCurrentParagraph();
18667
+ if (!breakPara) {
18668
+ return;
18669
+ }
18629
18670
  for (let i = 0; i < textItems.length; i++) {
18630
18671
  const newPara = breakPara.clone(false);
18631
18672
  const inputTextProps = this.getDefaultTextPropsByOptions();
@@ -18637,6 +18678,20 @@ class DocumentChange {
18637
18678
  this.selectionState.resetRange(breakPara, 0);
18638
18679
  }
18639
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
+ }
18640
18695
  /**
18641
18696
  * 向当前光标追加文本
18642
18697
  * @param appendStr
@@ -21682,8 +21737,13 @@ class DocEditor {
21682
21737
  return ElementSerialize.getSelectedJSON(this.selectionState, this.viewOptions);
21683
21738
  }
21684
21739
  getSelectedText() {
21685
- const copySerializeStr = ElementSerialize.getSelectedStruct(this.selectionState, this.viewOptions);
21686
- 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('');
21687
21747
  }
21688
21748
  /**
21689
21749
  * 执行编辑器内部复制事件
@@ -22314,7 +22374,7 @@ class DocEditor {
22314
22374
  rule.setRuleOptions({ width: this.viewOptions.docPageSettings.width, pagePL, pagePR, docLeft });
22315
22375
  }
22316
22376
  version() {
22317
- return "2.2.15";
22377
+ return "2.2.17";
22318
22378
  }
22319
22379
  switchPageHeaderEditor() {
22320
22380
  this.docCtx.document.switchPageHeaderEditor(this.selectionState, null);
@@ -22628,6 +22688,39 @@ class DocEditor {
22628
22688
  }
22629
22689
  return res;
22630
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
+ }
22631
22724
  }
22632
22725
 
22633
22726
  /**