@hailin-zheng/editor-core 2.0.6 → 2.0.8

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
@@ -1539,6 +1539,8 @@ class ViewOptions {
1539
1539
  //整页模式,不分页
1540
1540
  _fullPageView = false;
1541
1541
  ruleHeight = 30;
1542
+ //是否打印页眉页脚线
1543
+ printHeaderFooterLine = false;
1542
1544
  get fullPageView() {
1543
1545
  return this._fullPageView;
1544
1546
  }
@@ -3701,6 +3703,21 @@ class DataElementRenderObject extends InlineGroupRenderObject {
3701
3703
  exportHTML(event) {
3702
3704
  const node = super.exportHTML(event);
3703
3705
  exportDecoratorHTML(event, this);
3706
+ if (this.element.props.underline) {
3707
+ const { x, y } = event.relativePagePos;
3708
+ event.highlights.push({
3709
+ sel: 'path',
3710
+ data: {
3711
+ ns: 'http://www.w3.org/2000/svg',
3712
+ attrs: {
3713
+ d: `M${x} ${y + this.rect.height} L${x + this.rect.width} ${y + this.rect.height}`,
3714
+ stroke: '#000',
3715
+ fill: 'none',
3716
+ 'stroke-width': 1
3717
+ }
3718
+ }
3719
+ });
3720
+ }
3704
3721
  return node;
3705
3722
  }
3706
3723
  /**
@@ -3975,7 +3992,7 @@ class DocumentBodyRenderObject extends MuiltBlockLineRenderObject {
3975
3992
  return cloneRender;
3976
3993
  }
3977
3994
  exportHTML(event) {
3978
- return {
3995
+ const t = {
3979
3996
  sel: "g",
3980
3997
  data: {
3981
3998
  ns: "http://www.w3.org/2000/svg",
@@ -3984,6 +4001,10 @@ class DocumentBodyRenderObject extends MuiltBlockLineRenderObject {
3984
4001
  }
3985
4002
  }
3986
4003
  };
4004
+ if (this.element.disableClick && event.mode === 'view') {
4005
+ t.data.attrs['opacity'] = 0.5;
4006
+ }
4007
+ return t;
3987
4008
  }
3988
4009
  }
3989
4010
  class DocumentBodyFactory extends ElementFactory {
@@ -4062,15 +4083,25 @@ class DocumentFooterRenderObject extends BlockContainerRenderObject {
4062
4083
  return cloneRender;
4063
4084
  }
4064
4085
  exportHTML(event) {
4065
- return {
4066
- sel: "g",
4067
- data: {
4068
- ns: "http://www.w3.org/2000/svg",
4069
- attrs: {
4070
- transform: `translate(${this.rect.x},${this.rect.y})`
4071
- }
4072
- }
4073
- };
4086
+ const t = super.exportHTML(event);
4087
+ if (this.element.disableClick && event.mode === 'view') {
4088
+ t.data.attrs.opacity = 0.5;
4089
+ }
4090
+ if (event.options.printHeaderFooterLine) {
4091
+ t.children = [{
4092
+ sel: 'path',
4093
+ data: {
4094
+ ns: "http://www.w3.org/2000/svg",
4095
+ attrs: {
4096
+ d: `M${0} ${0} h${this.rect.width} `,
4097
+ stroke: '#000',
4098
+ 'stroke-width': "1",
4099
+ fill: 'none',
4100
+ }
4101
+ }
4102
+ }];
4103
+ }
4104
+ return t;
4074
4105
  }
4075
4106
  }
4076
4107
  class DocumentFooterFactory extends ElementFactory {
@@ -4159,7 +4190,7 @@ class DocumentHeaderRenderObject extends BlockContainerRenderObject {
4159
4190
  const isHeaderEmpty = ElementUtil.checkEmptyRenderContent(this);
4160
4191
  let headerLine;
4161
4192
  //存在输入内容时,绘制页眉-页体分割线
4162
- if (!isHeaderEmpty || !this.element.disableClick) {
4193
+ if (!isHeaderEmpty || !this.element.disableClick || event.mode === 'print') {
4163
4194
  headerLine = {
4164
4195
  sel: 'path',
4165
4196
  data: {
@@ -4167,7 +4198,7 @@ class DocumentHeaderRenderObject extends BlockContainerRenderObject {
4167
4198
  attrs: {
4168
4199
  d: `M${0} ${this.rect.height} L${this.rect.width} ${this.rect.height}`,
4169
4200
  stroke: '#000',
4170
- 'stroke-width': '0.5',
4201
+ 'stroke-width': '1',
4171
4202
  fill: 'none',
4172
4203
  x: 0,
4173
4204
  y: this.rect.height,
@@ -4185,6 +4216,9 @@ class DocumentHeaderRenderObject extends BlockContainerRenderObject {
4185
4216
  },
4186
4217
  children: []
4187
4218
  };
4219
+ if (this.element.disableClick && event.mode === 'view') {
4220
+ t.data.attrs.opacity = 0.5;
4221
+ }
4188
4222
  if (headerLine) {
4189
4223
  t.children = [headerLine];
4190
4224
  }
@@ -4383,7 +4417,7 @@ class TableCellRenderObject extends InlineMuiltBlockLineRenderObject {
4383
4417
  const t = super.exportHTML(event);
4384
4418
  const counter = event.getCounter('cell');
4385
4419
  const clipId = `CP_${counter}`;
4386
- t.children = [...CommonUtil.toArray(event.getChildNodes(this)), this.createClipPath(clipId)];
4420
+ t.children = [...CommonUtil.toArray(event.getChildNodes(this)), ElementUtil.createClipPath(clipId, this.rect.width, this.rect.height)];
4387
4421
  if (this.element.props.backgroundColor) {
4388
4422
  //t.data.attrs.fill = this.element.props.backgroundColor;
4389
4423
  t.children.splice(0, 0, this.createBgRect());
@@ -4409,29 +4443,6 @@ class TableCellRenderObject extends InlineMuiltBlockLineRenderObject {
4409
4443
  }
4410
4444
  return null;
4411
4445
  }
4412
- createClipPath(id) {
4413
- return {
4414
- sel: 'clipPath',
4415
- data: {
4416
- ns: 'http://www.w3.org/2000/svg',
4417
- attrs: {
4418
- id
4419
- }
4420
- },
4421
- children: [
4422
- {
4423
- sel: 'rect',
4424
- data: {
4425
- ns: 'http://www.w3.org/2000/svg',
4426
- attrs: {
4427
- width: this.rect.width,
4428
- height: this.rect.height
4429
- }
4430
- }
4431
- }
4432
- ]
4433
- };
4434
- }
4435
4446
  }
4436
4447
  class TableCellFactory extends ElementFactory {
4437
4448
  match(type) {
@@ -4482,6 +4493,13 @@ class TableRowElement extends BlockContainerElement {
4482
4493
  setChildrenModifyFlag(ModifyFlag$1.Modify, tb.getChild(j));
4483
4494
  }
4484
4495
  }
4496
+ else if (cell.props.vMerge === 'restart') {
4497
+ const endRowIndex = TableUtil.getVMergeEndIndex(tb, currRowIndex, i);
4498
+ for (let j = currRowIndex; j <= endRowIndex; j++) {
4499
+ setChildrenModifyFlag(ModifyFlag$1.Modify, tb.getChild(j));
4500
+ }
4501
+ break;
4502
+ }
4485
4503
  cell.modifyFlag = ModifyFlag$1.Modify;
4486
4504
  }
4487
4505
  }
@@ -5809,7 +5827,7 @@ class TableUtil {
5809
5827
  }
5810
5828
  }
5811
5829
  //如果合并的单元格都是空段落,则不合并内容
5812
- if (!cellContents.every((item) => (item instanceof ParagraphElement && item.length === 1))) {
5830
+ if (!cellContents.every((item) => (item instanceof ParagraphElement && item.length <= 1))) {
5813
5831
  for (let i = 0; i < cellContents.length; i++) {
5814
5832
  startCell.addChild(cellContents[i]);
5815
5833
  }
@@ -8064,7 +8082,7 @@ class ElementUtil {
8064
8082
  static getRecursionPrevSiblingElement(currElement, inPara = false, forCursor = false, viewOptions) {
8065
8083
  const parent = currElement?.parent;
8066
8084
  //删除留痕块的measureRender在不显示留痕模式下,不生成render
8067
- if (!currElement || !parent || (!currElement.cacheRender && !(currElement instanceof TrackRunElement))) {
8085
+ if (!currElement || !parent || (!currElement.paintRenders.length && !(currElement instanceof TrackRunElement))) {
8068
8086
  return null;
8069
8087
  }
8070
8088
  //如果当前数据元不可编辑,则直接跳过
@@ -8170,7 +8188,7 @@ class ElementUtil {
8170
8188
  */
8171
8189
  static getRecursionNextSiblingElement(currElement, inPara = false, forCursor = false, viewOptions) {
8172
8190
  const parent = currElement?.parent;
8173
- if (!currElement || !parent || !currElement.cacheRender) {
8191
+ if (!currElement || !parent || !currElement.paintRenders.length) {
8174
8192
  return null;
8175
8193
  }
8176
8194
  //如果当前数据元不可编辑,则直接跳过
@@ -8599,6 +8617,31 @@ class ElementUtil {
8599
8617
  y: localY
8600
8618
  };
8601
8619
  }
8620
+ static createClipPath(id, width, height, x = 0, y = 0) {
8621
+ return {
8622
+ sel: 'clipPath',
8623
+ data: {
8624
+ ns: 'http://www.w3.org/2000/svg',
8625
+ attrs: {
8626
+ id
8627
+ }
8628
+ },
8629
+ children: [
8630
+ {
8631
+ sel: 'rect',
8632
+ data: {
8633
+ ns: 'http://www.w3.org/2000/svg',
8634
+ attrs: {
8635
+ width,
8636
+ height,
8637
+ x,
8638
+ y
8639
+ }
8640
+ }
8641
+ }
8642
+ ]
8643
+ };
8644
+ }
8602
8645
  }
8603
8646
 
8604
8647
  class RenderContext {
@@ -11524,6 +11567,10 @@ class DocumentBodyPartRenderObject extends MuiltBlockLineRenderObject {
11524
11567
  }
11525
11568
  return cloneRender;
11526
11569
  }
11570
+ exportHTML(event) {
11571
+ const t = super.exportHTML(event);
11572
+ return t;
11573
+ }
11527
11574
  }
11528
11575
  class DocumentBodyPartFactory extends ElementFactory {
11529
11576
  match(type) {
@@ -12005,7 +12052,7 @@ class PictureFactory extends ElementFactory {
12005
12052
  picProps.width = props.width;
12006
12053
  picProps.height = props.height;
12007
12054
  picProps.src = props.src;
12008
- picProps.border = props.border || 'all';
12055
+ picProps.border = props.border;
12009
12056
  picProps.title = props.title;
12010
12057
  pic.props = picProps;
12011
12058
  return pic;
@@ -19223,13 +19270,18 @@ class DocumentChange {
19223
19270
  else if (pasteElement instanceof BlockContainerElement) {
19224
19271
  const children = ElementUtil.getChildrenElements(pasteElement);
19225
19272
  //复制的内容全部为段落,执行黏贴操作
19226
- if (children.every(item => item instanceof ParagraphElement)) {
19227
- const targetParagraph = this.splitCurrentParagraph();
19228
- children.forEach((item, i) => {
19229
- targetParagraph.parent.addChild(item, targetParagraph.getIndex());
19230
- });
19231
- this.selectionState.resetRange(children[children.length - 1], -1);
19232
- }
19273
+ // if (children.every(item => item instanceof ParagraphElement)) {
19274
+ // const targetParagraph = this.splitCurrentParagraph();
19275
+ // children.forEach((item, i) => {
19276
+ // targetParagraph.parent.addChild(item, targetParagraph.getIndex());
19277
+ // });
19278
+ // this.selectionState.resetRange(children[children.length - 1], -1);
19279
+ // }
19280
+ const targetParagraph = this.splitCurrentParagraph();
19281
+ children.forEach((item, i) => {
19282
+ targetParagraph.parent.addChild(item, targetParagraph.getIndex());
19283
+ });
19284
+ this.selectionState.resetRange(children[children.length - 1], -1);
19233
19285
  }
19234
19286
  }
19235
19287
  insertSoftBr() {
@@ -25411,51 +25463,62 @@ class DocumentPrintOffscreenBase {
25411
25463
  /**
25412
25464
  * 续打
25413
25465
  */
25414
- async printForContinuation(data, ranges = null, options) {
25415
- const sub = this.beforeRenderEvent.subscribe((event) => {
25416
- const { index, renderCtx, docRender } = event;
25417
- if (index === options.startDocIndex) {
25418
- const bodyRender = docRender.getChild(1);
25419
- let x = 0, y = options.startY, width = bodyRender.rect.width, height = bodyRender.rect.height - (options.startY - bodyRender.rect.y);
25420
- if (options.startDocIndex === options.endDocIndex) {
25421
- height = options.endY - options.startY;
25422
- }
25423
- renderCtx.mainContext.clip(x, y, width, height);
25424
- }
25425
- });
25466
+ async printForContinuation(data, options) {
25467
+ // const sub = this.beforeRenderEvent.subscribe((event) => {
25468
+ // const {index, renderCtx, docRender, pageSvgVNode} = event;
25469
+ // if (index === options.startDocIndex) {
25470
+ // const bodyRender = docRender.getChild(1);
25471
+ // let x = 0, y = options.startY, width = bodyRender.rect.width,
25472
+ // height = bodyRender.rect.height - (options.startY - bodyRender.rect.y);
25473
+ // if (options.startDocIndex === options.endDocIndex) {
25474
+ // height = options.endY - options.startY;
25475
+ // }
25476
+ // renderCtx.mainContext.clip(x, y, width, height);
25477
+ // }
25478
+ // });
25426
25479
  this.afterRenderEvent.subscribe((event) => {
25427
- const { index, renderCtx, docRender } = event;
25428
- if (options.startDocIndex !== options.endDocIndex && index === options.endDocIndex) {
25480
+ const { index, renderCtx, docRender, pageSvgVNode } = event;
25481
+ if (index === options.startDocIndex) {
25429
25482
  const bodyRender = docRender.getChild(1);
25430
- const height = bodyRender.rect.height - (options.endY - bodyRender.rect.y);
25431
- renderCtx.contentContext.clearRect(bodyRender.rect.x, options.endY, bodyRender.rect.width, height);
25432
- }
25483
+ let x = bodyRender.rect.x, y = options.startY, width = bodyRender.rect.width, height = bodyRender.rect.height - (options.startY - bodyRender.rect.y);
25484
+ // if (options.startDocIndex === options.endDocIndex) {
25485
+ // height = options.endY - options.startY;
25486
+ // }
25487
+ const pageClip = ElementUtil.createClipPath('page-clip-' + index, width, height, x, y);
25488
+ //pageSvgVNode.children?.push(pageClip)
25489
+ pageSvgVNode.children?.push(pageClip);
25490
+ pageSvgVNode.data.attrs['clip-path'] = `url(#${'page-clip-' + index})`;
25491
+ }
25492
+ // if (options.startDocIndex !== options.endDocIndex && index === options.endDocIndex) {
25493
+ // const bodyRender = docRender.getChild(1);
25494
+ // const height = bodyRender.rect.height - (options.endY - bodyRender.rect.y);
25495
+ // renderCtx.contentContext.clearRect(bodyRender.rect.x, options.endY, bodyRender.rect.width, height);
25496
+ // }
25433
25497
  });
25434
25498
  await this.prepare(data);
25435
- const canvasNodes = this.getCanvasNodes(this.documentPaint.docPages, ranges);
25499
+ const canvasNodes = this.getSvgNodes(this.documentPaint.docPages, null);
25436
25500
  if (!canvasNodes.length) {
25437
25501
  console.warn('无可打印页');
25438
25502
  return;
25439
25503
  }
25440
25504
  const docProps = this.docCtx.document.props;
25441
25505
  printNodes(canvasNodes, { ...docProps });
25442
- sub.unsubscribe();
25443
- }
25444
- /**
25445
- * 获取绘制的图片,格式为Base64编码
25446
- */
25447
- async getImagesContent(data, ranges = null) {
25448
- await this.prepare(data);
25449
- const canvasNodes = this.getCanvasNodes(this.documentPaint.docPages, ranges);
25450
- if (!canvasNodes.length) {
25451
- console.warn('无可导出页');
25452
- return [];
25453
- }
25454
- return canvasNodes.map(node => node.toDataURL());
25455
25506
  }
25507
+ // /**
25508
+ // * 获取绘制的图片,格式为Base64编码
25509
+ // */
25510
+ // async getImagesContent(data: any | DocumentElement, ranges: Array<number> | null = null): Promise<Array<string>> {
25511
+ // await this.prepare(data);
25512
+ // const canvasNodes = this.getCanvasNodes(this.documentPaint.docPages, ranges);
25513
+ // if (!canvasNodes.length) {
25514
+ // console.warn('无可导出页')
25515
+ // return [];
25516
+ // }
25517
+ // return canvasNodes.map(node => node.toDataURL());
25518
+ // }
25456
25519
  async getPrintNodes(data, ranges = null) {
25457
25520
  await this.prepare(data);
25458
- const canvasNodes = this.getCanvasNodes(this.documentPaint.docPages, ranges);
25521
+ const canvasNodes = this.getSvgNodes(this.documentPaint.docPages, ranges);
25459
25522
  return canvasNodes;
25460
25523
  }
25461
25524
  /**
@@ -25474,42 +25537,53 @@ class DocumentPrintOffscreenBase {
25474
25537
  height
25475
25538
  });
25476
25539
  }
25477
- getCanvasNodes(printPages, printRanges = null) {
25478
- const { scale, docPageSettings: { width, height } } = this.viewOptions;
25479
- const canvasList = [];
25480
- for (let i = 0; i < printPages.length; i++) {
25481
- if (printRanges && printRanges.indexOf(i) === -1) {
25482
- continue;
25483
- }
25484
- const { canvas: canvasNode, ctx } = this.createCanvas(width, height);
25485
- const renderCtx = this.createRenderCtx(ctx, this.viewOptions, this.docCtx);
25486
- renderCtx.init({ width, height, scale });
25487
- renderCtx.drawMode = 'print';
25488
- const doc = printPages[i];
25489
- const tmp = ElementUtil.cloneRect(doc.rect);
25490
- doc.rect.x = 0;
25491
- doc.rect.y = 0;
25492
- this.beforeRenderEvent.next({ index: i, renderCtx, docRender: doc });
25493
- ElementPaint.drawPage(renderCtx, this.docCtx, doc, { x: 0, y: 0 });
25494
- this.afterRenderEvent.next({ index: i, renderCtx, docRender: doc });
25495
- renderCtx.overlaysContext.clear();
25496
- renderCtx.mainContext.fillRect(0, 0, width, height, 'white');
25497
- renderCtx.commit({ width, height, scale }, { x: 0, y: 0 });
25498
- doc.rect = tmp;
25499
- canvasList.push(canvasNode);
25500
- }
25501
- return canvasList;
25502
- }
25540
+ // getCanvasNodes(printPages: Array<DocumentRenderObject>, printRanges: Array<number> | null = null): Array<HTMLCanvasElement> {
25541
+ // const {scale, docPageSettings: {width, height}} = this.viewOptions;
25542
+ // const canvasList: Array<HTMLCanvasElement> = [];
25543
+ // for (let i = 0; i < printPages.length; i++) {
25544
+ // if (printRanges && printRanges.indexOf(i) === -1) {
25545
+ // continue;
25546
+ // }
25547
+ // const {canvas: canvasNode, ctx} = this.createCanvas(width, height);
25548
+ // const renderCtx = this.createRenderCtx(ctx, this.viewOptions, this.docCtx);
25549
+ // renderCtx.init({width, height, scale});
25550
+ // renderCtx.drawMode = 'print';
25551
+ // const doc = printPages[i];
25552
+ // const tmp = ElementUtil.cloneRect(doc.rect);
25553
+ // doc.rect.x = 0;
25554
+ // doc.rect.y = 0;
25555
+ // this.beforeRenderEvent.next({index: i, renderCtx, docRender: doc})
25556
+ // ElementPaint.drawPage(renderCtx, this.docCtx, doc, {x: 0, y: 0});
25557
+ // this.afterRenderEvent.next({index: i, renderCtx, docRender: doc})
25558
+ // renderCtx.overlaysContext.clear();
25559
+ // renderCtx.mainContext.fillRect(0, 0, width, height, 'white');
25560
+ // renderCtx.commit({width, height, scale}, {x: 0, y: 0});
25561
+ // doc.rect = tmp;
25562
+ // canvasList.push(canvasNode);
25563
+ // }
25564
+ // return canvasList;
25565
+ // }
25503
25566
  getSvgNodes(docRenders, printRanges = null) {
25504
25567
  const docSvgHelper = new DocumentSvg(this.viewOptions, new Map(), this.renderCtx); //.getHTMLVNode(docRenders) as Array<EditorVNodeObject>;
25505
25568
  docSvgHelper.mode = 'print';
25506
- const pageSvgVNodes = docRenders.filter((item, index) => !printRanges || printRanges.indexOf(index) >= 0).map(item => docSvgHelper.getPageSvgVNode(item));
25507
25569
  const patch = init([
25508
25570
  modules.class,
25509
25571
  modules.props,
25510
25572
  modules.attributes,
25511
25573
  modules.style
25512
25574
  ]);
25575
+ // const pageSvgVNodes = docRenders.filter((item, index) =>
25576
+ // !printRanges || printRanges.indexOf(index) >= 0)
25577
+ // .map(item => docSvgHelper.getPageSvgVNode(item));
25578
+ const pageSvgVNodes = [];
25579
+ docRenders.forEach((item, index) => {
25580
+ if (!printRanges || printRanges.indexOf(index) >= 0) {
25581
+ //this.beforeRenderEvent.next({index, renderCtx: this.renderCtx, docRender: item})
25582
+ const pageSvg = docSvgHelper.getPageSvgVNode(item);
25583
+ this.afterRenderEvent.next({ index, renderCtx: this.renderCtx, docRender: item, pageSvgVNode: pageSvg });
25584
+ pageSvgVNodes.push(pageSvg);
25585
+ }
25586
+ });
25513
25587
  const domNodes = pageSvgVNodes.map(item => patch(item)); //.map(item => docParser.parseFromString(item, 'text/html').firstChild) as Array<HTMLElement>;
25514
25588
  return domNodes;
25515
25589
  }
@@ -25742,7 +25816,7 @@ class EditorCalendarVNode {
25742
25816
  on: {
25743
25817
  change: (event) => {
25744
25818
  if (moment(event.target.value, 'HH:mm:ss').isValid()) {
25745
- this.selectedTime = event.target.value;
25819
+ this.selectedTime.value = event.target.value;
25746
25820
  }
25747
25821
  else {
25748
25822
  event.target.value = this.currTime.value;
@@ -26809,8 +26883,8 @@ class DocEditor {
26809
26883
  */
26810
26884
  getCurrentDataElement() {
26811
26885
  const selectionState = this.documentSelection.selectionState;
26812
- const { startControl, startOffset } = selectionState;
26813
- if (startControl) {
26886
+ const { startControl, startOffset, collapsed } = selectionState;
26887
+ if (startControl && collapsed) {
26814
26888
  if (!ElementUtil.verifyHitable(startControl)) {
26815
26889
  return null;
26816
26890
  }
@@ -27214,7 +27288,7 @@ class DocEditor {
27214
27288
  const docRender = ElementUtil.getParentRender(renderObj, DocumentRenderObject);
27215
27289
  const index = docRender.getIndex();
27216
27290
  const cursorPos = DocumentCursor.getElementCursorPos(ele, 0, region, index);
27217
- this.selectionState.surround(element);
27291
+ this.selectionState.resetRange(element, 0);
27218
27292
  if (cursorPos.rect.y - this.viewOptions.pageOffset.y > 0 && cursorPos.rect.y - this.viewOptions.pageOffset.y < this.viewOptions.viewSettings.height) {
27219
27293
  return;
27220
27294
  }