@hailin-zheng/editor-core 2.0.54 → 2.1.1

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
@@ -3,7 +3,6 @@ import moment from 'moment';
3
3
  import * as acor from 'acorn';
4
4
  import { generate } from 'astring';
5
5
  import estraverse from 'estraverse';
6
- import * as bwipjs from 'bwip-js';
7
6
  import JsBarcode from 'jsbarcode';
8
7
  import { toVNode, init as init$1, styleModule, classModule, attributesModule, eventListenersModule } from 'snabbdom';
9
8
 
@@ -1550,6 +1549,8 @@ class ViewOptions {
1550
1549
  ruleHeight = 30;
1551
1550
  //是否打印页眉页脚线
1552
1551
  printHeaderFooterLine = false;
1552
+ //显示段落回车符号
1553
+ showEnterSymbol = false;
1553
1554
  get fullPageView() {
1554
1555
  return this._fullPageView;
1555
1556
  }
@@ -4304,6 +4305,27 @@ class PSymbolRenderObject extends LeafRenderObject {
4304
4305
  }
4305
4306
  render.contentContext.drawText('↩', this.element.textProps, position.x, position.y, 20, this.rect.height);
4306
4307
  }
4308
+ exportHTML(event) {
4309
+ if (!event.options.showEnterSymbol || event.mode === 'print') {
4310
+ return null;
4311
+ }
4312
+ return {
4313
+ sel: 'text',
4314
+ text: '↵',
4315
+ data: {
4316
+ ns: "http://www.w3.org/2000/svg",
4317
+ attrs: {
4318
+ //"transform": `translate(0,${(height - props.fontSize) / 2})`,
4319
+ 'dominant-baseline': 'hanging',
4320
+ 'font-family': 'Courier',
4321
+ 'font-size': this.element.defaultHeight,
4322
+ x: this.rect.x,
4323
+ y: this.rect.y,
4324
+ fill: 'green'
4325
+ }
4326
+ },
4327
+ };
4328
+ }
4307
4329
  //绘制段落符号
4308
4330
  clone() {
4309
4331
  const render = new PSymbolRenderObject(this.element);
@@ -8193,30 +8215,13 @@ class DataElementBarcode extends DataElementLeaf {
8193
8215
  return this.props.text;
8194
8216
  }
8195
8217
  drawBarcode(renderCtx, pos) {
8196
- this.createBarcodeCache();
8197
8218
  renderCtx.contentContext.ctx.drawImage(this.barCodeCanvas, pos.x, pos.y, this.props.width, this.props.height);
8198
8219
  }
8199
- createBarcodeCache() {
8200
- if (this.cache) {
8201
- return;
8202
- }
8203
- this.cache = true;
8204
- if (!this.barCodeCanvas) {
8205
- this.barCodeCanvas = document.createElement('canvas');
8206
- }
8207
- this.barCodeCanvas = bwipjs.toCanvas(this.barCodeCanvas, {
8208
- bcid: this.props.type,
8209
- text: this.props.text || "0123456789",
8210
- height: 10,
8211
- includetext: true,
8212
- textxalign: "center", // Always good to set this
8213
- });
8214
- }
8215
8220
  }
8216
8221
  class DataElementBarcodeRenderObject extends ResizeLeafRenderObject {
8217
8222
  render(e) {
8218
- const barcodeEle = this.element;
8219
- barcodeEle.drawBarcode(e.render, e.position);
8223
+ // const barcodeEle = this.element as DataElementBarcode;
8224
+ // barcodeEle.drawBarcode(e.render, e.position);
8220
8225
  }
8221
8226
  clone() {
8222
8227
  const clone = new DataElementBarcodeRenderObject(this.element);
@@ -9090,6 +9095,27 @@ class BreakRenderObject extends LeafRenderObject {
9090
9095
  }
9091
9096
  render.contentContext.drawText('↓', this.element.textProps, position.x, position.y, 20, this.rect.height);
9092
9097
  }
9098
+ exportHTML(event) {
9099
+ if (!event.options.showEnterSymbol || event.mode === 'print') {
9100
+ return null;
9101
+ }
9102
+ return {
9103
+ sel: 'text',
9104
+ text: '↓',
9105
+ data: {
9106
+ ns: "http://www.w3.org/2000/svg",
9107
+ attrs: {
9108
+ //"transform": `translate(0,${(height - props.fontSize) / 2})`,
9109
+ 'dominant-baseline': 'hanging',
9110
+ 'font-family': 'Courier',
9111
+ 'font-size': this.rect.height,
9112
+ x: this.rect.x + 4,
9113
+ y: this.rect.y,
9114
+ fill: 'green'
9115
+ }
9116
+ },
9117
+ };
9118
+ }
9093
9119
  clone() {
9094
9120
  const render = new BreakRenderObject(this.element);
9095
9121
  render.rect = ElementUtil.cloneRect(this.rect);
@@ -9130,6 +9156,9 @@ class DataElementText extends DataElementInlineGroup {
9130
9156
  if (!this.startDecorate) {
9131
9157
  return;
9132
9158
  }
9159
+ if (val === null || val === undefined) {
9160
+ val = '';
9161
+ }
9133
9162
  if (this.getValue() === val) {
9134
9163
  return;
9135
9164
  }
@@ -12410,6 +12439,7 @@ class ElementUtil {
12410
12439
  };
12411
12440
  }
12412
12441
  static getMousePos(e, scale = 1) {
12442
+ //scale=1;
12413
12443
  const svgContainer = e.currentTarget;
12414
12444
  const parentRect = svgContainer.getBoundingClientRect();
12415
12445
  const localX = e.clientX - parentRect.x; //+ this.viewOptions.pageOffset.x;
@@ -16130,7 +16160,9 @@ class DocumentPaint {
16130
16160
  //文档容器总宽度等于内容宽度
16131
16161
  //单页模式,docContainer居中
16132
16162
  this.docContainer.rect.width = viewWidth;
16133
- let docLeft = Math.floor((viewWidth - contentWidth) / 2);
16163
+ //let docLeft = Math.floor((viewWidth - contentWidth) / 2);
16164
+ //处理由于缩放问题,transform-origin:left-top,因此需要提前计算需要偏移的位置
16165
+ let docLeft = Math.floor((viewWidth - contentWidth * (this.viewOptions.scale)) / 2);
16134
16166
  docLeft = docLeft < 0 ? 0 : docLeft;
16135
16167
  pages.forEach(item => item.rect.x = docLeft);
16136
16168
  this.docContainer.rect.x = 0;
@@ -19137,7 +19169,8 @@ class DocumentChange {
19137
19169
  if (!prevEle) {
19138
19170
  const nextEle = ElementUtil.getRecursionNextSiblingElement(control, true, true, this.viewOptions);
19139
19171
  if (nextEle) {
19140
- this.selectionState.resetRange(nextEle, 0);
19172
+ //this.selectionState.resetRange(nextEle, 0);
19173
+ this.setSelectionStateByDeleteEvent(nextEle, 0, control);
19141
19174
  control.remove();
19142
19175
  return;
19143
19176
  }
@@ -19145,24 +19178,48 @@ class DocumentChange {
19145
19178
  return;
19146
19179
  }
19147
19180
  if (ElementUtil.isInSameParagraph(control, prevEle)) {
19148
- this.selectionState.resetRange(prevEle, -1);
19181
+ //this.selectionState.resetRange(prevEle, -1);
19182
+ this.setSelectionStateByDeleteEvent(prevEle, -1, control);
19149
19183
  control.remove();
19150
19184
  return;
19151
19185
  }
19152
19186
  else {
19153
19187
  const nextEle = ElementUtil.getRecursionNextSiblingElement(control, true, true, this.viewOptions);
19154
19188
  if (nextEle && ElementUtil.getPrevSiblingElement(nextEle) === control) {
19155
- this.selectionState.resetRange(nextEle, 0);
19189
+ //this.selectionState.resetRange(nextEle, 0);
19190
+ this.setSelectionStateByDeleteEvent(nextEle, 0, control);
19156
19191
  control.remove();
19157
19192
  return;
19158
19193
  }
19159
19194
  else {
19160
- this.selectionState.resetRange(prevEle, -1);
19195
+ //this.selectionState.resetRange(prevEle, -1);
19196
+ this.setSelectionStateByDeleteEvent(prevEle, -1, control);
19161
19197
  control.remove();
19162
19198
  return;
19163
19199
  }
19164
19200
  }
19165
19201
  }
19202
+ /**
19203
+ * 处理在表单模式下光标定位的问题
19204
+ * @param target
19205
+ * @param targetOffset
19206
+ * @param deleteTarget
19207
+ * @private
19208
+ */
19209
+ setSelectionStateByDeleteEvent(target, targetOffset, deleteTarget) {
19210
+ if (this.viewOptions.docMode === DocMode.FormEdit) {
19211
+ const dataEle = ElementUtil.getParent(deleteTarget, (item) => item instanceof DataElementInlineGroup);
19212
+ if (dataEle && ElementUtil.getParent(target, (item) => item instanceof DataElementInlineGroup) === dataEle) {
19213
+ this.selectionState.resetRange(target, targetOffset);
19214
+ return;
19215
+ }
19216
+ if (dataEle) {
19217
+ this.selectionState.resetRange(dataEle.startDecorate, 1);
19218
+ return;
19219
+ }
19220
+ }
19221
+ this.selectionState.resetRange(target, targetOffset);
19222
+ }
19166
19223
  /**
19167
19224
  * 回车事件
19168
19225
  */
@@ -26142,6 +26199,7 @@ function createSignal(state) {
26142
26199
  * 渲染日历虚拟节点处理类
26143
26200
  */
26144
26201
  class EditorCalendarVNode {
26202
+ viewOptions;
26145
26203
  currYear;
26146
26204
  currMonth;
26147
26205
  currCalendarMode;
@@ -26150,7 +26208,8 @@ class EditorCalendarVNode {
26150
26208
  onSetValue = new Subject$1();
26151
26209
  currTime;
26152
26210
  selectedTime;
26153
- constructor() {
26211
+ constructor(viewOptions) {
26212
+ this.viewOptions = viewOptions;
26154
26213
  this.currYear = createSignal(new Date().getFullYear());
26155
26214
  //月份赋值是按照索引来的,所以要减1
26156
26215
  this.currMonth = createSignal(new Date().getMonth());
@@ -26218,29 +26277,49 @@ class EditorCalendarVNode {
26218
26277
  hook: {
26219
26278
  insert: (vnode) => {
26220
26279
  const elm = vnode.elm;
26221
- const parent = CommonUtil.findParent(elm, (item) => item.className === 'scroll-container');
26222
- if (parent) {
26223
- const parentRect = parent.getBoundingClientRect();
26224
- const elmRect = elm.getBoundingClientRect();
26225
- if (elmRect.top < parentRect.top) {
26226
- elm.style.top = (position.y - elmRect.height) + 'px';
26227
- }
26228
- if (elmRect.left < parentRect.left) {
26229
- elm.style.left = (position.x - 10) + 'px';
26230
- }
26231
- if (elmRect.right > parentRect.right) {
26232
- elm.style.left = (position.x - elmRect.width + 10) + 'px';
26233
- }
26234
- if (elmRect.top + elmRect.height > parentRect.top + parentRect.height) {
26235
- elm.style.top = (position.y - position.height - elmRect.height) + 'px';
26236
- }
26237
- }
26280
+ this.resizePosition(elm, position);
26281
+ },
26282
+ update: (oldVnode, vnode) => {
26283
+ const elm = vnode.elm;
26284
+ this.resizePosition(elm, position);
26238
26285
  }
26239
26286
  },
26240
26287
  },
26241
26288
  children: []
26242
26289
  };
26243
26290
  }
26291
+ resizePosition(elm, position) {
26292
+ const parent = CommonUtil.findParent(elm, (item) => item.className === 'scroll-container');
26293
+ const scale = this.viewOptions.scale;
26294
+ if (parent) {
26295
+ const parentRect = parent.getBoundingClientRect();
26296
+ const elmRect = elm.getBoundingClientRect();
26297
+ // elmRect.width /= scale;
26298
+ // elmRect.height /= scale;
26299
+ // parentRect.width /= scale;
26300
+ // parentRect.height /= scale;
26301
+ if (elmRect.top < parentRect.top) {
26302
+ elm.style.top = (position.y - elmRect.height / scale) + 'px';
26303
+ }
26304
+ if (elmRect.left < parentRect.left) {
26305
+ elm.style.left = (position.x - 10) + 'px';
26306
+ }
26307
+ if (elmRect.right > parentRect.right) {
26308
+ elm.style.left = (position.x - elmRect.width / scale + 10) + 'px';
26309
+ //elm.style.left = parentRect.width - elmRect.width + 'px';
26310
+ }
26311
+ if (elmRect.top + elmRect.height > parentRect.top + parentRect.height) {
26312
+ const newTop = position.y - position.height - elmRect.height;
26313
+ const oldTop = position.y + 5 + position.height;
26314
+ //计算前后的高度的差距,然后判断新的值是否在父元素的范围内,如果不在则使用旧的值
26315
+ if (newTop > 0 && oldTop - newTop < elmRect.top - parentRect.top) {
26316
+ elm.style.top = (position.y - position.height - elmRect.height) + 'px';
26317
+ }
26318
+ //elm.style.top = (top - (elmRect.top + elmRect.height - (parentRect.top + parentRect.height))) + 'px';
26319
+ //elm.style.top = (position.y - position.height - elmRect.height) + 'px';
26320
+ }
26321
+ }
26322
+ }
26244
26323
  renderDay() {
26245
26324
  //获取当前月份需要渲染的天数集合
26246
26325
  const days = this.getDays();
@@ -27085,8 +27164,13 @@ class DocEditor {
27085
27164
  const listVNode = this.renderDataListVNode();
27086
27165
  const dropContainer = {
27087
27166
  sel: 'div.drop-container',
27088
- data: {},
27089
- children: [listVNode.render(), calendarFunc.render(), menuFunc.render()]
27167
+ data: {
27168
+ style: {
27169
+ 'transform-origin': '0 0',
27170
+ 'transform': `scale(${this.viewOptions.scale})`
27171
+ }
27172
+ },
27173
+ children: [inputVNode, listVNode.render(), calendarFunc.render(), menuFunc.render()]
27090
27174
  };
27091
27175
  return {
27092
27176
  sel: 'div.svg-container',
@@ -27124,17 +27208,7 @@ class DocEditor {
27124
27208
  }
27125
27209
  }
27126
27210
  },
27127
- children: [
27128
- {
27129
- sel: 'div.scale-container', data: {
27130
- style: {
27131
- transform: 'scale(' + this.viewOptions.scale + ')',
27132
- transformOrigin: 'left top'
27133
- }
27134
- },
27135
- children: [docContentVNode, inputVNode, dropContainer]
27136
- }
27137
- ]
27211
+ children: [docContentVNode, dropContainer]
27138
27212
  }, ruleFunc.refreshRuleSvg().render()
27139
27213
  ]
27140
27214
  };
@@ -27240,8 +27314,8 @@ class DocEditor {
27240
27314
  this.contentChanged.next();
27241
27315
  }
27242
27316
  this.updateSelection();
27243
- this.onShouldRender.next();
27244
27317
  this.setCursor();
27318
+ this.onShouldRender.next();
27245
27319
  //this.refreshView();
27246
27320
  }
27247
27321
  /**
@@ -27385,12 +27459,12 @@ class DocEditor {
27385
27459
  */
27386
27460
  docClickHandle(evt) {
27387
27461
  this.hiddenInput();
27388
- this.setCursor();
27389
- this.updateSelection();
27462
+ // this.setCursor();
27463
+ // this.updateSelection();
27464
+ this.refreshDocument();
27390
27465
  this.onClickEvent.next(evt);
27391
27466
  if (this.menusData) {
27392
27467
  this.menusData = null;
27393
- this.onChange();
27394
27468
  }
27395
27469
  }
27396
27470
  /**
@@ -27479,7 +27553,9 @@ class DocEditor {
27479
27553
  elementEvent.source = startControl;
27480
27554
  DocumentEvent.invokeEvent('ElementContextMenu', startControl, elementEvent, 'All');
27481
27555
  //const position = {x: evt.offsetX + 10, y: evt.offsetY, translateY: this.viewOptions.pageOffset.y};
27482
- const pos = ElementUtil.getMousePos(evt);
27556
+ const pos = ElementUtil.getMousePos(evt, this.viewOptions.scale);
27557
+ pos.x += 10;
27558
+ pos.y -= 10;
27483
27559
  this.menusData = {
27484
27560
  position: pos,
27485
27561
  menus: elementEvent.menus
@@ -27520,11 +27596,11 @@ class DocEditor {
27520
27596
  this.updateRenderCtx();
27521
27597
  this.flushToSchedule();
27522
27598
  this.documentPaint.layoutPages();
27523
- const sub = this.afterNodePatch.subscribe(() => {
27524
- sub.unsubscribe();
27525
- const scrollDOM = this.svgContainer.querySelector('.scroll-container');
27526
- scrollDOM.scrollLeft = (scrollDOM.scrollWidth - scrollDOM.getBoundingClientRect().width) / 2;
27527
- });
27599
+ // const sub = this.afterNodePatch.subscribe(() => {
27600
+ // sub.unsubscribe();
27601
+ // const scrollDOM = this.svgContainer.querySelector('.scroll-container') as HTMLElement;
27602
+ // scrollDOM.scrollLeft = (scrollDOM.scrollWidth - scrollDOM.getBoundingClientRect().width) / 2;
27603
+ // })
27528
27604
  return scale;
27529
27605
  }
27530
27606
  updateRenderCtx() {
@@ -28054,7 +28130,10 @@ class DocEditor {
28054
28130
  style: {
28055
28131
  height: '0px',
28056
28132
  position: 'relative',
28133
+ width: '0px',
28057
28134
  'user-select': 'none',
28135
+ transform: 'scale(' + this.viewOptions.scale + ')',
28136
+ 'transform-origin': '0 0'
28058
28137
  },
28059
28138
  on: this.documentEvent.getEventListener()
28060
28139
  },
@@ -28233,30 +28312,11 @@ class DocEditor {
28233
28312
  hook: {
28234
28313
  insert: (vnode) => {
28235
28314
  const elm = vnode.elm;
28236
- const parent = CommonUtil.findParent(elm, (item) => item.className === 'scroll-container');
28237
- if (parent) {
28238
- const parentRect = parent.getBoundingClientRect();
28239
- const elmRect = elm.getBoundingClientRect();
28240
- if (elmRect.top < parentRect.top) {
28241
- elm.style.top = (position.y - elmRect.height) + 'px';
28242
- }
28243
- if (elmRect.left < parentRect.left) {
28244
- elm.style.left = (position.x - 10) + 'px';
28245
- }
28246
- if (elmRect.right > parentRect.right) {
28247
- elm.style.left = (position.x - elmRect.width + 10) + 'px';
28248
- }
28249
- if (elmRect.top + elmRect.height > parentRect.top + parentRect.height) {
28250
- const newTop = position.y - position.height - elmRect.height;
28251
- const oldTop = position.y + 5 + position.height;
28252
- //计算前后的高度的差距,然后判断新的值是否在父元素的范围内,如果不在则使用旧的值
28253
- if (oldTop - newTop < elmRect.top - parentRect.top) {
28254
- elm.style.top = (position.y - position.height - elmRect.height) + 'px';
28255
- }
28256
- //elm.style.top = (top - (elmRect.top + elmRect.height - (parentRect.top + parentRect.height))) + 'px';
28257
- //elm.style.top = (position.y - position.height - elmRect.height) + 'px';
28258
- }
28259
- }
28315
+ editor.resizePosition(elm, position);
28316
+ },
28317
+ update: (oldVnode, vnode) => {
28318
+ const elm = vnode.elm;
28319
+ editor.resizePosition(elm, position);
28260
28320
  }
28261
28321
  },
28262
28322
  },
@@ -28275,8 +28335,40 @@ class DocEditor {
28275
28335
  }
28276
28336
  };
28277
28337
  }
28338
+ resizePosition(elm, position) {
28339
+ const parent = CommonUtil.findParent(elm, (item) => item.className === 'scroll-container');
28340
+ const scale = this.viewOptions.scale;
28341
+ if (parent) {
28342
+ const parentRect = parent.getBoundingClientRect();
28343
+ const elmRect = elm.getBoundingClientRect();
28344
+ // elmRect.width /= scale;
28345
+ // elmRect.height /= scale;
28346
+ // parentRect.width /= scale;
28347
+ // parentRect.height /= scale;
28348
+ if (elmRect.top < parentRect.top) {
28349
+ elm.style.top = (position.y - elmRect.height / scale) + 'px';
28350
+ }
28351
+ if (elmRect.left < parentRect.left) {
28352
+ elm.style.left = (position.x - 10) + 'px';
28353
+ }
28354
+ if (elmRect.right > parentRect.right) {
28355
+ elm.style.left = (position.x - elmRect.width / scale + 10) + 'px';
28356
+ //elm.style.left = parentRect.width - elmRect.width + 'px';
28357
+ }
28358
+ if (elmRect.top + elmRect.height > parentRect.top + parentRect.height) {
28359
+ const newTop = position.y - position.height - elmRect.height;
28360
+ const oldTop = position.y + 5 + position.height;
28361
+ //计算前后的高度的差距,然后判断新的值是否在父元素的范围内,如果不在则使用旧的值
28362
+ if (newTop > 0 && oldTop - newTop < elmRect.top - parentRect.top) {
28363
+ elm.style.top = (position.y - position.height - elmRect.height) + 'px';
28364
+ }
28365
+ //elm.style.top = (top - (elmRect.top + elmRect.height - (parentRect.top + parentRect.height))) + 'px';
28366
+ //elm.style.top = (position.y - position.height - elmRect.height) + 'px';
28367
+ }
28368
+ }
28369
+ }
28278
28370
  renderCalendar() {
28279
- const calendar = new EditorCalendarVNode();
28371
+ const calendar = new EditorCalendarVNode(this.viewOptions);
28280
28372
  const editor = this;
28281
28373
  calendar.onSetValue.subscribe((value) => {
28282
28374
  const dataEle = editor.getCurrentDataElement();
@@ -28362,7 +28454,7 @@ class DocEditor {
28362
28454
  rule.setRuleOptions({ width: this.viewOptions.docPageSettings.width, pagePL, pagePR, docLeft });
28363
28455
  }
28364
28456
  version() {
28365
- return "2.0.54";
28457
+ return "2.1.1";
28366
28458
  }
28367
28459
  }
28368
28460