@hailin-zheng/editor-core 2.2.20 → 2.2.22

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
@@ -4,7 +4,7 @@ import * as acor from 'acorn';
4
4
  import { generate } from 'astring';
5
5
  import estraverse from 'estraverse';
6
6
  import JsBarcode from 'jsbarcode';
7
- import { toVNode, init as init$1, styleModule, classModule, attributesModule, eventListenersModule, datasetModule, h } from 'snabbdom';
7
+ import { toVNode, h, init as init$1, styleModule, classModule, attributesModule, eventListenersModule, datasetModule } from 'snabbdom';
8
8
 
9
9
  /**
10
10
  * 元素事件
@@ -336,7 +336,9 @@ class BranchRenderObject extends RenderObject {
336
336
  if (index < 0) {
337
337
  throw new Error('为查找到当前元素');
338
338
  }
339
- if (child.parent === this) ;
339
+ if (child.parent === this) {
340
+ child.parent = null;
341
+ }
340
342
  this.children.splice(index, 1);
341
343
  }
342
344
  removeChildByIndex(index) {
@@ -771,6 +773,14 @@ class CommonUtil {
771
773
  }
772
774
  return val;
773
775
  }
776
+ static getKeyCombination(event) {
777
+ // 构建键盘组合字符串,包括修饰键
778
+ const modifiers = [event.ctrlKey ? "Ctrl" : "", event.shiftKey ? "Shift" : "", event.altKey ? "Alt" : "", event.metaKey ? "Meta" : ""].filter(Boolean).join("+");
779
+ // 根据修饰键的存在构建最终的键盘组合字符串
780
+ const key = event.key; // 直接使用 event.key 来获取按键实际字符
781
+ const keyCombination = modifiers.length > 0 ? `${modifiers}+${key}` : key;
782
+ return keyCombination;
783
+ }
774
784
  }
775
785
 
776
786
  const docOpsMap = new Map();
@@ -1249,6 +1259,7 @@ class Element {
1249
1259
  //加载完毕
1250
1260
  loaded;
1251
1261
  visibleExpr;
1262
+ effectExpr;
1252
1263
  attribute;
1253
1264
  _parent;
1254
1265
  get parent() {
@@ -1293,6 +1304,8 @@ class Element {
1293
1304
  this.cacheRender = null;
1294
1305
  this.unsubscribe(this);
1295
1306
  this.disposed = true;
1307
+ this.visibleExpr = null;
1308
+ this.effectExpr = null;
1296
1309
  }
1297
1310
  addEvent(event, handle, useCapture = false) {
1298
1311
  if (!this._eventMap) {
@@ -1384,24 +1397,41 @@ class LeafElement extends Element {
1384
1397
  return 1;
1385
1398
  }
1386
1399
  pubOnChange(selfChange) {
1387
- if (this.modifyFlag === ModifyFlag.None) {
1388
- this.refreshView();
1389
- }
1390
- if (this.modifyFlag === ModifyFlag.Track && selfChange === 'tracker') {
1391
- return;
1392
- }
1393
- if (this.modifyFlag === ModifyFlag.Modify) {
1394
- return;
1395
- }
1396
- if (selfChange === 'tracker') {
1397
- if (this.modifyFlag === ModifyFlag.None) {
1398
- this.modifyFlag = ModifyFlag.Track;
1399
- }
1400
- }
1401
- else {
1402
- this.modifyFlag = ModifyFlag.Modify;
1403
- }
1404
- this._onChangeEvent.next();
1400
+ invokeRefresh(this, selfChange);
1401
+ // if (this.modifyFlag === ModifyFlag.None) {
1402
+ // this.refreshView();
1403
+ // }
1404
+ // if (this.modifyFlag === ModifyFlag.Track && selfChange === 'tracker') {
1405
+ // return;
1406
+ // }
1407
+ // if (this.modifyFlag === ModifyFlag.Modify) {
1408
+ // return;
1409
+ // }
1410
+ // if (selfChange === 'tracker') {
1411
+ // if (this.modifyFlag === ModifyFlag.None) {
1412
+ // this.modifyFlag = ModifyFlag.Track;
1413
+ // }
1414
+ // } else {
1415
+ // this.modifyFlag = ModifyFlag.Modify;
1416
+ // }
1417
+ // this._onChangeEvent.next();
1418
+ }
1419
+ }
1420
+ function invokeRefresh(ele, type) {
1421
+ const doc = getParent(ele, (item) => item.type === 'doc');
1422
+ if (doc) {
1423
+ doc.invokeChange(ele, type);
1424
+ }
1425
+ }
1426
+ function getParent(child, predicate) {
1427
+ if (!child) {
1428
+ return null;
1429
+ }
1430
+ if (predicate(child)) {
1431
+ return child;
1432
+ }
1433
+ else {
1434
+ return getParent(child.parent, predicate);
1405
1435
  }
1406
1436
  }
1407
1437
  /**
@@ -1426,10 +1456,10 @@ class BranchElement extends Element {
1426
1456
  //const refSub = child.refreshSubject.subscribe((data) => {
1427
1457
  //this.refreshSubject.next(data);
1428
1458
  // });
1429
- const onChangeSub = child.onChangeSubject.subscribe((data) => {
1430
- this.pubOnChange('tracker');
1431
- });
1432
- this.addsubscribe(child, onChangeSub);
1459
+ // const onChangeSub = child.onChangeSubject.subscribe((data) => {
1460
+ // this.pubOnChange('tracker');
1461
+ // });
1462
+ //this.addsubscribe(child, onChangeSub);
1433
1463
  this.pubOnChange('self');
1434
1464
  }
1435
1465
  removeChild(child) {
@@ -1548,25 +1578,25 @@ class BranchElement extends Element {
1548
1578
  return null;
1549
1579
  }
1550
1580
  pubOnChange(selfChange) {
1551
- if (this.modifyFlag === ModifyFlag.Track && selfChange === 'tracker') {
1552
- return;
1553
- }
1554
- if (this.modifyFlag === ModifyFlag.Modify) {
1555
- return;
1556
- }
1557
- if (selfChange === 'tracker') {
1558
- if (this.modifyFlag === ModifyFlag.None) {
1559
- this.modifyFlag = ModifyFlag.Track;
1560
- }
1561
- }
1562
- else {
1563
- this.modifyFlag = ModifyFlag.Modify;
1564
- //clearChildrenRenderCache(this);
1565
- for (let i = 0; i < this.length; i++) {
1566
- this.getChild(i).pubOnChange('to-child');
1567
- }
1568
- }
1569
- this._onChangeEvent.next();
1581
+ // if (this.modifyFlag === ModifyFlag.Track && selfChange === 'tracker') {
1582
+ // return;
1583
+ // }
1584
+ // if (this.modifyFlag === ModifyFlag.Modify) {
1585
+ // return;
1586
+ // }
1587
+ // if (selfChange === 'tracker') {
1588
+ // if (this.modifyFlag === ModifyFlag.None) {
1589
+ // this.modifyFlag = ModifyFlag.Track;
1590
+ // }
1591
+ // } else {
1592
+ // this.modifyFlag = ModifyFlag.Modify;
1593
+ // //clearChildrenRenderCache(this);
1594
+ // for (let i = 0; i < this.length; i++) {
1595
+ // this.getChild(i).pubOnChange('to-child')
1596
+ // }
1597
+ // }
1598
+ // this._onChangeEvent.next();
1599
+ invokeRefresh(this, selfChange);
1570
1600
  }
1571
1601
  }
1572
1602
  function clearChildrenRenderCache(ele) {
@@ -1758,8 +1788,6 @@ class ViewOptions {
1758
1788
  trackInsColor = '#ff4d4f';
1759
1789
  //删除-留痕块文本颜色
1760
1790
  trackDelColor = '#000';
1761
- showLineRect;
1762
- showCharRect;
1763
1791
  showTabChar;
1764
1792
  showSpaceChar;
1765
1793
  showLineBreak;
@@ -1767,7 +1795,6 @@ class ViewOptions {
1767
1795
  devMode = false;
1768
1796
  showParaSymbol = true;
1769
1797
  showDebug;
1770
- resourceMode = 'immediate';
1771
1798
  secretBrowse = false;
1772
1799
  //中文版式,处理中文换行;前置标点和后置标点
1773
1800
  chineseLayout = true;
@@ -1800,7 +1827,7 @@ class ViewOptions {
1800
1827
  return;
1801
1828
  }
1802
1829
  this._fullPageView = value;
1803
- this.onChange.next('force');
1830
+ this.onChange.next();
1804
1831
  }
1805
1832
  //毫米和像素的转换比
1806
1833
  mmToPixelsRatio = 3.7795001220703126;
@@ -1849,7 +1876,7 @@ class ViewOptions {
1849
1876
  return;
1850
1877
  }
1851
1878
  this._showTrackChanges = value;
1852
- this.onChange.next('force');
1879
+ this.onChange.next();
1853
1880
  }
1854
1881
  get showTrackChangesTip() {
1855
1882
  return this._showTrackChangesTip;
@@ -1859,7 +1886,7 @@ class ViewOptions {
1859
1886
  return;
1860
1887
  }
1861
1888
  this._showTrackChangesTip = value;
1862
- this.onChange.next('force');
1889
+ this.onChange.next();
1863
1890
  }
1864
1891
  //医嘱打印模式,文字行模式,将表格多行对象转换为多个表格行对象
1865
1892
  textRowLineMode = false;
@@ -2929,7 +2956,7 @@ class DataDecorateElement extends LeafElement {
2929
2956
  }
2930
2957
  }
2931
2958
  });
2932
- this.disableClick = !isPrefix;
2959
+ //this.disableClick = !isPrefix;
2933
2960
  this.isDecorate = true;
2934
2961
  }
2935
2962
  createRenderObject(data) {
@@ -3035,6 +3062,9 @@ function parser(code, objects) {
3035
3062
  if (child.type === 'Identifier') {
3036
3063
  const identifierName = child['name'];
3037
3064
  if (identifierName.startsWith('$')) {
3065
+ //获取对象为"CallExpression", "MemberExpression"获取属性,例如$1.value
3066
+ parent?.type;
3067
+ `getObject('${identifierName.slice(1)})`;
3038
3068
  child['name'] = `getObject('${identifierName.slice(1)}').value`;
3039
3069
  objects?.push(identifierName.slice(1));
3040
3070
  }
@@ -3061,6 +3091,11 @@ function parser(code, objects) {
3061
3091
  }
3062
3092
  }
3063
3093
  });
3094
+ if (objects) {
3095
+ const set = new Set(objects);
3096
+ objects.length = 0;
3097
+ objects.push(...set);
3098
+ }
3064
3099
  return generate(node);
3065
3100
  }
3066
3101
  //判断代码的语句,如果最后一个语句不是return,那么加上return
@@ -3626,6 +3661,48 @@ class DocumentElement extends BlockContainerElement {
3626
3661
  }
3627
3662
  }
3628
3663
  }
3664
+ onRefreshEvent = new Subject();
3665
+ /**
3666
+ * 元素内容或者属性发生改变,需要根据当前节点所在的树路径,设置脏标记,同时触发渲染
3667
+ * @param ele
3668
+ */
3669
+ invokeChange(ele) {
3670
+ const parents = ElementUtil.getParentElements(ele);
3671
+ const pubLeafEle = (ele, eleChangeType) => {
3672
+ if (ele.modifyFlag === ModifyFlag.Track && eleChangeType === 'tracker') {
3673
+ return;
3674
+ }
3675
+ if (ele.modifyFlag === ModifyFlag.Modify) {
3676
+ return;
3677
+ }
3678
+ if (eleChangeType === 'tracker') {
3679
+ if (ele.modifyFlag === ModifyFlag.None) {
3680
+ ele.modifyFlag = ModifyFlag.Track;
3681
+ }
3682
+ }
3683
+ else {
3684
+ ele.modifyFlag = ModifyFlag.Modify;
3685
+ if (ele instanceof BranchElement) {
3686
+ for (let i = 0; i < ele.length; i++) {
3687
+ const child = ele.getChild(i);
3688
+ if (child instanceof LeafElement) {
3689
+ pubLeafEle(child, 'to-child');
3690
+ }
3691
+ else if (child instanceof BranchElement) {
3692
+ pubLeafEle(child, 'to-child');
3693
+ }
3694
+ //this.getChild(i).pubOnChange('to-child')
3695
+ }
3696
+ }
3697
+ }
3698
+ };
3699
+ pubLeafEle(ele, 'self');
3700
+ for (let i = 1; i < parents.length; i++) {
3701
+ const parent = parents[i];
3702
+ pubLeafEle(parent, 'tracker');
3703
+ }
3704
+ this.onRefreshEvent.next();
3705
+ }
3629
3706
  }
3630
3707
  class DocumentRenderObject extends BlockContainerRenderObject {
3631
3708
  constructor(ele) {
@@ -4027,7 +4104,7 @@ class DataElementInlineGroup extends InlineGroupInputElement {
4027
4104
  }
4028
4105
  parserExpress;
4029
4106
  /**
4030
- * 解析可见性表达式
4107
+ * 解析表达式
4031
4108
  * @param ele
4032
4109
  * @param execute
4033
4110
  * @private
@@ -4046,6 +4123,11 @@ class DataElementInlineGroup extends InlineGroupInputElement {
4046
4123
  const depEleMap = new Map();
4047
4124
  let compliedCode = parser(this.props.expression, depIdItems);
4048
4125
  compliedCode = addReturn(compliedCode);
4126
+ this.parserExpress = {
4127
+ compliedCode,
4128
+ func: new Function(`with(this){ ${compliedCode} }`),
4129
+ depItems: depEleMap
4130
+ };
4049
4131
  if (depIdItems.length) {
4050
4132
  depIdItems.forEach(dep => {
4051
4133
  const refCtx = execute.getObject(dep);
@@ -4055,19 +4137,34 @@ class DataElementInlineGroup extends InlineGroupInputElement {
4055
4137
  //当前有可能是checkbox数组
4056
4138
  const refEles = Array.isArray(refEle) ? refEle : [refEle];
4057
4139
  reactiveMode && refEles.forEach(item => {
4140
+ //避免死循环调用
4141
+ if (item === this) {
4142
+ return;
4143
+ }
4058
4144
  //求值依赖元素更改的时候,发布当前元素重新计算的指令
4059
4145
  item.onChangeSubject.subscribe(() => {
4060
- this.pubOnChange('self');
4146
+ //this.pubOnChange('self');
4147
+ try {
4148
+ data.onNextView(() => {
4149
+ //当前元素可能被删除
4150
+ const func = this.parserExpress.func;
4151
+ if (!func) {
4152
+ return;
4153
+ }
4154
+ const tempExecuter = execute.create();
4155
+ tempExecuter.setCurrentCtx(this, this.parserExpress.depItems);
4156
+ const fn = func.bind(tempExecuter);
4157
+ fn();
4158
+ });
4159
+ }
4160
+ catch (e) {
4161
+ console.error(e, "表达式执行出错", this.parserExpress.compliedCode);
4162
+ }
4061
4163
  });
4062
4164
  });
4063
4165
  }
4064
4166
  });
4065
4167
  }
4066
- this.parserExpress = {
4067
- compliedCode,
4068
- func: new Function(`with(this){ ${compliedCode} }`),
4069
- depItems: depEleMap
4070
- };
4071
4168
  }
4072
4169
  catch (e) {
4073
4170
  console.error('解析表达式出错,parseEleExpression', this.props.expression);
@@ -4211,7 +4308,11 @@ function exportDataEleDecoratorSVG$1(event, r) {
4211
4308
  if (['all', 'outline'].includes(mode)) {
4212
4309
  color = event.options.dataEleOutlineColor;
4213
4310
  const verOffset = 0;
4214
- const renderPosMap = getCurrentParaGroupRenders(r).map(item => ({ pos: getRenderPosToDoc(item), render: item }));
4311
+ const currParaGroupRenders = getCurrentParaGroupRenders(r);
4312
+ if (currParaGroupRenders.indexOf(r) !== 0) {
4313
+ return;
4314
+ }
4315
+ const renderPosMap = currParaGroupRenders.map(item => ({ pos: getRenderPosToDoc(item), render: item }));
4215
4316
  if (renderPosMap.length > 1) {
4216
4317
  const secondGroupRenderPos = renderPosMap[1].pos;
4217
4318
  if (secondGroupRenderPos.x + renderPosMap[1].render.rect.width > event.relativePagePos.x) {
@@ -4518,20 +4619,25 @@ class PSymbolRenderObject extends LeafRenderObject {
4518
4619
  if (!event.options.showEnterSymbol || event.mode === 'print') {
4519
4620
  return null;
4520
4621
  }
4521
- const font = `14px 宋体`;
4522
- const actualFontBoundingBoxAscent = event.renderCtx.mainContext.getActualFontBoundingBoxAscent(font);
4622
+ // const font = `14px system-ui`
4623
+ // const actualFontBoundingBoxAscent = event.renderCtx.mainContext.getActualFontBoundingBoxAscent(font);
4523
4624
  let y = this.rect.y;
4524
- //基线处理
4525
- y += actualFontBoundingBoxAscent ?? 0;
4526
- //行高处理
4625
+ // //基线处理
4626
+ //y += actualFontBoundingBoxAscent ?? 0;
4627
+ // //行高处理
4527
4628
  y += (this.rect.height - 14) / 2;
4528
- return ElementUtil.createSvgText('↵', {
4529
- 'font-family': '宋体',
4530
- 'font-size': 14,
4531
- x: this.rect.x,
4532
- y: y,
4533
- fill: 'green'
4534
- });
4629
+ return {
4630
+ sel: 'image',
4631
+ data: {
4632
+ ns: 'http://www.w3.org/2000/svg',
4633
+ attrs: {
4634
+ translate: { x: this.rect.x, y: y },
4635
+ width: 7,
4636
+ height: 7,
4637
+ href: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAAqFJREFUeF7tnUEyA0EYhbubBXEJbkDKXtzETQwX4SYcwMIRHMOCGZWyUCSL7uf1/KK+rPu9P/V980dVaiZy4mUhcHh2+5DztGoty60Bzm8ngIDgKwMBCAgmEDyeDUBAMIHg8WwAAoIJBI9nAxAQTCB4PBuAgGACwePZAAQEEwgezwYgIJhA8Hg2AAHBBILHswEICCYQPJ4NQEAwgeDxbAACggkEj2cDEBBMIHj8TmzA0fL2akrjRSurcUw3r8/DS2tuzvM7IWCxHO5SyletYMZxOkFAK7Ut5xGwCWXWm3MRgADDHm+v4G9AN7R1xQio49TtFAK6oa0rRkAdp26nENANbV0xAuo4dTuFgG5o64oRUMep2ykEdENbVzyrgIPT4biU/FD31r6dOhYyiS/jflA7OB9WZZQEKPwR8JMaAjavo3k/gtiADQMIkD7cfCEE+FhKTQiQsPlCCPCxlJoQIGHzhRDgYyk1IUDC5gshwMdSakKAhM0XkgWsv1hrfRt7paymNN215tTzY5ku01v607cmlpKuU8rtv5q4WN5MKhhyXwTWF8nr0/DYyiQjoBXZ9vMI8HCUWxAgo/MEEeDhKLcgQEbnCSLAw1FuQYCMzhNEgIej3IIAGZ0niAAPR7kFATI6TxABHo5yyy8ErJ/dVV7tz/sqUz4z072enSepPkwuPabKnXE+qQjwsZSaECBh84UQ4GMpNSFAwuYLIcDHUmpCgITNF0KAj6XUhAAJmy+EAB9LqQkBEjZfCAE+llITAiRsvpAmYH0/6X5qvqc0v5dr5b9O78KD2qoSSYA67D//aJ/KBAEqOVMOASaQag0CVHKmHAJMINUaBKjkTDkEmECqNQhQyZlyCDCBVGsQoJIz5RBgAqnWIEAlZ8ohwARSrfkASRnMwxkWAWQAAAAASUVORK5CYII=",
4638
+ }
4639
+ }
4640
+ };
4535
4641
  }
4536
4642
  //绘制段落符号
4537
4643
  clone() {
@@ -8771,26 +8877,32 @@ class BreakRenderObject extends LeafRenderObject {
8771
8877
  if (!event.options.showEnterSymbol || event.mode === 'print') {
8772
8878
  return null;
8773
8879
  }
8774
- // return ElementUtil.createSvgText( '↓',{ 'dominant-baseline': 'hanging',
8775
- // 'font-family': 'Courier',
8776
- // 'font-size': this.rect.height,
8777
- // x: this.rect.x + 4,
8778
- // y: this.rect.y,
8779
- // fill: 'green'});
8780
- const font = `14px 宋体`;
8781
- const actualFontBoundingBoxAscent = event.renderCtx.mainContext.getActualFontBoundingBoxAscent(font);
8782
- let y = 0;
8783
- //基线处理
8784
- y += actualFontBoundingBoxAscent ?? 0;
8785
- //行高处理
8786
- y += (this.parent.rect.height - 14) / 2;
8787
- return ElementUtil.createSvgText('↓', {
8788
- 'font-family': '宋体',
8789
- 'font-size': 14,
8790
- x: this.rect.x,
8791
- y: y,
8792
- fill: 'green'
8793
- });
8880
+ // const font = `14px system-ui`
8881
+ // const actualFontBoundingBoxAscent = event.renderCtx.mainContext.getActualFontBoundingBoxAscent(font);
8882
+ let y = this.rect.y;
8883
+ // return {
8884
+ // sel: 'path',
8885
+ // data: {
8886
+ // ns: 'http://www.w3.org/2000/svg',
8887
+ // attrs: {
8888
+ // stroke: 'none',
8889
+ // fill: 'blue',
8890
+ // d: path,
8891
+ // translate: { x: this.rect.x, y: y }
8892
+ // }
8893
+ // }
8894
+ // }
8895
+ return {
8896
+ sel: 'image',
8897
+ data: {
8898
+ ns: 'http://www.w3.org/2000/svg',
8899
+ attrs: {
8900
+ translate: { x: this.rect.x, y: y + (this.rect.height - 10) / 2 },
8901
+ height: 10,
8902
+ href: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAA/CAYAAABqzXG5AAAAAXNSR0IArs4c6QAAAKdJREFUaEPt2LENhDAMQFHSMs4tiFiQcWg5XUGDcIQtoDg96gTC59vYbkPxGj/zFm1dl6lVblva9HuQw0S4kUEmG4qc4QxnDgT8myIlkEEmmy44wxnOHAnom3SUZwQU5ArybLbkDGc4o4m76ICCPCzIe5n0It3bljWHCVgiQ+BsmHWT3hOR1mvwHKY0EvGZKnVuNlL29f8hcO/t9U0Vn0yuTK7emlx9ARNg7GSAIh9+AAAAAElFTkSuQmCC",
8903
+ }
8904
+ }
8905
+ };
8794
8906
  }
8795
8907
  clone() {
8796
8908
  const render = new BreakRenderObject(this.element);
@@ -8854,7 +8966,7 @@ class DataElementGroupElement extends InlineGroupInputElement {
8854
8966
  }
8855
8967
  }
8856
8968
  getValue() {
8857
- return ElementSerialize.serializeString(this, { all: false });
8969
+ return ElementSerialize.serializeString(this);
8858
8970
  }
8859
8971
  clone(data) {
8860
8972
  return super.cloneSelf(data, DataElementGroupElement);
@@ -8959,15 +9071,29 @@ function exportDataEleDecoratorSVG(event, r) {
8959
9071
  return;
8960
9072
  }
8961
9073
  //绘制背景
8962
- if (['all', 'background'].includes(mode)) {
8963
- const bgX = event.relativePagePos.x;
8964
- const bgY = event.relativePagePos.y;
8965
- event.highlights.push(ElementUtil.getFillSvgRect(bgX, bgY, r.rect.width, r.rect.height, color));
8966
- }
8967
- if (['all', 'outline'].includes(mode)) {
8968
- color = event.options.dataGroupOutlineColor;
9074
+ // if (['all', 'background'].includes(mode)) {
9075
+ // const bgX = event.relativePagePos.x;
9076
+ // const bgY = event.relativePagePos.y;
9077
+ // event.highlights.push(ElementUtil.getFillSvgRect(bgX, bgY, r.rect.width, r.rect.height, color));
9078
+ // }
9079
+ if (['all', 'outline', 'background'].includes(mode)) {
9080
+ let outlineColor = ['all', 'outline'].includes(mode) ? event.options.dataGroupOutlineColor : 'none';
9081
+ let bgColor = ['all', 'background'].includes(mode) ? color : 'none';
8969
9082
  const verOffset = 0;
8970
- const renderPosMap = getCurrentParaGroupRenders(r).map(item => ({ pos: getRenderPosToDoc(item), render: item }));
9083
+ const currParaGroupRenders = getCurrentParaGroupRenders(r);
9084
+ if (currParaGroupRenders.indexOf(r) === 0) {
9085
+ outlineColor = 'none';
9086
+ }
9087
+ if (currParaGroupRenders.indexOf(r) === currParaGroupRenders.length - 1) {
9088
+ bgColor = 'none';
9089
+ }
9090
+ if (bgColor !== 'none' && currParaGroupRenders.indexOf(r) !== 0) {
9091
+ return;
9092
+ }
9093
+ if (outlineColor !== 'none' && currParaGroupRenders.indexOf(r) !== currParaGroupRenders.length - 1) {
9094
+ return;
9095
+ }
9096
+ const renderPosMap = currParaGroupRenders.map(item => ({ pos: getRenderPosToDoc(item), render: item }));
8971
9097
  if (renderPosMap.length > 1) {
8972
9098
  const secondGroupRenderPos = renderPosMap[1].pos;
8973
9099
  if (secondGroupRenderPos.x + renderPosMap[1].render.rect.width > event.relativePagePos.x) {
@@ -8995,8 +9121,8 @@ function exportDataEleDecoratorSVG(event, r) {
8995
9121
  const path = [...sharpPoints, ...sharpPoints1, sharpPoints[0]].map((item, index) => ((index === 0) ? 'M' : "L") + item.x + " " + item.y).join(" ");
8996
9122
  event.highlights.push(ElementUtil.createSvgPath({
8997
9123
  d: path,
8998
- stroke: color,
8999
- fill: 'none',
9124
+ stroke: outlineColor,
9125
+ fill: bgColor,
9000
9126
  'stroke-width': 1
9001
9127
  }));
9002
9128
  return;
@@ -9006,8 +9132,8 @@ function exportDataEleDecoratorSVG(event, r) {
9006
9132
  const currRen = renderPosMap[i];
9007
9133
  event.highlights.push(ElementUtil.createSvgPath({
9008
9134
  d: `M${currRen.pos.x} ${currRen.pos.y} L${currRen.pos.x + currRen.render.rect.width} ${currRen.pos.y} L${currRen.pos.x + currRen.render.rect.width} ${currRen.pos.y + currRen.render.rect.height} L${currRen.pos.x} ${currRen.pos.y + currRen.render.rect.height} Z`,
9009
- stroke: color,
9010
- fill: 'none',
9135
+ stroke: outlineColor,
9136
+ fill: bgColor,
9011
9137
  'stroke-width': 1
9012
9138
  }));
9013
9139
  }
@@ -9262,7 +9388,7 @@ class DataElementText extends DataElementInlineGroup {
9262
9388
  createRenderObject(data) {
9263
9389
  if (data.options.enableDyExpression) {
9264
9390
  this.parseEleExpression(data);
9265
- this.evalEleExpr(data.execute);
9391
+ //this.evalEleExpr(data.execute)
9266
9392
  }
9267
9393
  return new DataElementTextRenderObject(this);
9268
9394
  }
@@ -9312,7 +9438,7 @@ class DataElementText extends DataElementInlineGroup {
9312
9438
  this.onChangedValidate();
9313
9439
  }
9314
9440
  getValue() {
9315
- return ElementSerialize.serializeString(this, { all: false });
9441
+ return ElementSerialize.serializeString(this);
9316
9442
  }
9317
9443
  validate() {
9318
9444
  let error = super.validate();
@@ -10915,8 +11041,8 @@ class ElementSerialize {
10915
11041
  }
10916
11042
  return result;
10917
11043
  }
10918
- static serializeString(element, options = { all: false }) {
10919
- if (!options.all && element instanceof TrackRunElement && element.type === TrackRunTypeEnum.Deleted) {
11044
+ static serializeString(element, options = { includeRunDel: false }) {
11045
+ if (!options.includeRunDel && element instanceof TrackRunElement && element.type === TrackRunTypeEnum.Deleted) {
10920
11046
  return '';
10921
11047
  }
10922
11048
  if (element instanceof TextGroupElement && !element.isDecorate) {
@@ -11053,7 +11179,7 @@ class TrackRunElement extends InlineGroupElement {
11053
11179
  trackRunType: this.type,
11054
11180
  name: this.props.userName,
11055
11181
  date: this.props.date,
11056
- content: ElementSerialize.serializeString(this, { all: true })
11182
+ content: ElementSerialize.serializeString(this, { includeRunDel: true })
11057
11183
  };
11058
11184
  console.log(evt.trackTips.content);
11059
11185
  evt.isCancel = true;
@@ -11153,7 +11279,7 @@ class TrackRunRenderObject extends InlineGroupRenderObject {
11153
11279
  const { x, y } = event.globalPos;
11154
11280
  const docRender = ElementUtil.getParentRender(this, DocumentRenderObject);
11155
11281
  const opType = this.element.type === 'ins-run' ? '插入:' : '删除:';
11156
- const content = ElementSerialize.serializeString(this.element, { all: true });
11282
+ const content = ElementSerialize.serializeString(this.element, { includeRunDel: true });
11157
11283
  let left = this.element.gotFocus ? -10 : 5;
11158
11284
  //显示在文档的右测
11159
11285
  left += docRender.rect.x + docRender.rect.width + 20;
@@ -12293,54 +12419,87 @@ class ElementUtil {
12293
12419
  /**
12294
12420
  * 递归向前寻找最近的元素
12295
12421
  * @param currElement
12296
- * @param inPara 是否在同一段落中寻找
12297
- * @param forCursor 查找结果是否用于光标定位
12298
12422
  * @param viewOptions
12299
12423
  * @returns
12300
12424
  */
12301
- static getRecursionPrevSiblingElement(currElement, inPara = false, forCursor = false, viewOptions) {
12425
+ static getRecursionPrevSiblingElement(currElement, viewOptions) {
12302
12426
  const parent = currElement?.parent;
12303
12427
  //删除留痕块的measureRender在不显示留痕模式下,不生成render
12304
- if (!currElement || !parent || (!currElement.paintRenders.length && !(currElement instanceof TrackRunElement))) {
12428
+ if (!currElement || !parent || !currElement.paintRenders.length) {
12305
12429
  return null;
12306
12430
  }
12307
12431
  //如果当前数据元不可编辑,则直接跳过
12308
- if (parent instanceof DataElementInlineGroup && !parent.props.editable && viewOptions.docMode === DocMode.FormEdit) {
12309
- return this.getRecursionPrevSiblingElement(parent, inPara, forCursor, viewOptions);
12310
- }
12311
- if (forCursor && parent.disableClick) {
12312
- return this.getRecursionPrevSiblingElement(parent, inPara, forCursor, viewOptions);
12313
- }
12432
+ //不存在这种情况
12433
+ // if (parent instanceof DataElementInlineGroup && !parent.props.editable && viewOptions.docMode === DocMode.FormEdit) {
12434
+ // return this.getRecursionPrevSiblingElement(parent, inPara, viewOptions);
12435
+ // }
12436
+ //不存在这种情况
12437
+ // if (parent.disableClick) {
12438
+ // return this.getRecursionPrevSiblingElement(parent, inPara, viewOptions);
12439
+ // }
12314
12440
  const index = parent.getChildIndex(currElement);
12315
- if (!index) {
12316
- if (inPara && parent.type === 'p') {
12317
- return null;
12441
+ // if (!index) {
12442
+ // if (inPara && parent.type === 'p') {
12443
+ // return null;
12444
+ // }
12445
+ // return this.getRecursionPrevSiblingElement(parent, inPara, viewOptions);
12446
+ // } else {
12447
+ let prevElement = null;
12448
+ for (let i = index - 1; i >= 0; i--) {
12449
+ prevElement = parent.getChild(i);
12450
+ const res = this.getRecursionSiblingElementCursorPosition(prevElement, viewOptions, 'left');
12451
+ if (res) {
12452
+ return res;
12318
12453
  }
12319
- return this.getRecursionPrevSiblingElement(parent, inPara, forCursor, viewOptions);
12320
12454
  }
12321
- else {
12322
- let prevElement = null;
12323
- for (let i = index - 1; i >= 0; i--) {
12324
- prevElement = parent.getChild(i);
12325
- if (prevElement && !prevElement.disableClick) {
12326
- break;
12455
+ //表单模式需要判断当前父级是否已经超出数据元或者数据组的范围
12456
+ if (viewOptions.docMode === DocMode.FormEdit && !ElementUtil.getDataGroupElement(parent)) {
12457
+ return null;
12458
+ }
12459
+ return this.getRecursionPrevSiblingElement(parent, viewOptions);
12460
+ //}
12461
+ }
12462
+ /**
12463
+ * 递归元素里面向前寻找可以定位的元素
12464
+ */
12465
+ static getRecursionSiblingElementCursorPosition(ele, viewOptions, direction) {
12466
+ if (ele instanceof LeafElement) {
12467
+ return this.getElementPositionCursor(ele, viewOptions, direction);
12468
+ }
12469
+ if (ele instanceof BranchElement) {
12470
+ const startIndex = direction === 'left' ? ele.length - 1 : 0;
12471
+ const endIndex = direction === 'left' ? 0 : ele.length - 1;
12472
+ const increment = direction === 'left' ? -1 : 1;
12473
+ for (let i = startIndex; direction === 'left' ? i >= endIndex : i <= endIndex; i += increment) {
12474
+ const child = ele.getChild(i);
12475
+ if (child instanceof LeafElement) {
12476
+ const res = this.getElementPositionCursor(child, viewOptions, direction);
12477
+ if (res) {
12478
+ return res;
12479
+ }
12480
+ }
12481
+ else if (child instanceof BranchElement) {
12482
+ const res = this.getRecursionSiblingElementCursorPosition(child, viewOptions, direction);
12483
+ if (res) {
12484
+ return res;
12485
+ }
12327
12486
  }
12328
12487
  }
12329
- if (!prevElement || prevElement.disableClick) {
12330
- return this.getRecursionPrevSiblingElement(parent, inPara, forCursor, viewOptions);
12331
- }
12332
- const lastLeafElement = ElementUtil.getLastLeafElement(prevElement);
12333
- //用于光标定位
12334
- if (forCursor && lastLeafElement && !ElementUtil.canSetCursor(lastLeafElement, 0, true, viewOptions)) {
12335
- return this.getRecursionPrevSiblingElement(lastLeafElement, inPara, forCursor, viewOptions);
12336
- }
12337
- if (lastLeafElement) {
12338
- return lastLeafElement;
12339
- }
12340
- else {
12341
- return this.getRecursionPrevSiblingElement(prevElement.parent, inPara, forCursor, viewOptions);
12488
+ }
12489
+ return null;
12490
+ }
12491
+ static getElementPositionCursor(ele, viewOptions, direction) {
12492
+ const endOffset = ElementUtil.getElementEndOffset(ele);
12493
+ const offsets = direction === 'left' ? [endOffset, 0] : [0, endOffset];
12494
+ for (let i = 0; i < offsets.length; i++) {
12495
+ if (ElementUtil.canSetCursor(ele, offsets[i], true, viewOptions)) {
12496
+ return {
12497
+ ele: ele,
12498
+ offset: offsets[i]
12499
+ };
12342
12500
  }
12343
12501
  }
12502
+ return null;
12344
12503
  }
12345
12504
  /**
12346
12505
  * 循环向前寻找可定位的数据元
@@ -12405,55 +12564,56 @@ class ElementUtil {
12405
12564
  /**
12406
12565
  * 递归向后寻找最近的元素
12407
12566
  */
12408
- static getRecursionNextSiblingElement(currElement, inPara = false, forCursor = false, viewOptions) {
12567
+ static getRecursionNextSiblingElement(currElement, viewOptions) {
12409
12568
  const parent = currElement?.parent;
12410
12569
  if (!currElement || !parent) {
12411
12570
  return null;
12412
12571
  }
12413
- // if (!currElement.paintRenders.length) {
12414
- // return this.getRecursionNextSiblingElement(currElement, inPara, forCursor, viewOptions);
12572
+ // //如果当前数据元不可编辑,则直接跳过
12573
+ // if (parent instanceof DataElementInlineGroup && !parent.props.editable && viewOptions.docMode === DocMode.FormEdit) {
12574
+ // return this.getRecursionNextSiblingElement(parent, inPara, forCursor, viewOptions);
12575
+ // }
12576
+ // //如果当前为数据组,且数据组被隐藏,则直接跳过
12577
+ // if (parent instanceof DataElementGroupElement && parent.props.hidden) {
12578
+ // return this.getRecursionNextSiblingElement(parent, inPara, forCursor, viewOptions);
12579
+ // }
12580
+ // if (forCursor && parent.disableClick) {
12581
+ // return this.getRecursionNextSiblingElement(parent, inPara, forCursor, viewOptions);
12415
12582
  // }
12416
- //如果当前数据元不可编辑,则直接跳过
12417
- if (parent instanceof DataElementInlineGroup && !parent.props.editable && viewOptions.docMode === DocMode.FormEdit) {
12418
- return this.getRecursionNextSiblingElement(parent, inPara, forCursor, viewOptions);
12419
- }
12420
- //如果当前为数据组,且数据组被隐藏,则直接跳过
12421
- if (parent instanceof DataElementGroupElement && parent.props.hidden) {
12422
- return this.getRecursionNextSiblingElement(parent, inPara, forCursor, viewOptions);
12423
- }
12424
- if (forCursor && parent.disableClick) {
12425
- return this.getRecursionNextSiblingElement(parent, inPara, forCursor, viewOptions);
12426
- }
12427
12583
  const index = parent.getChildIndex(currElement);
12428
- if (index === parent.length - 1) {
12429
- if (inPara && parent.type === 'p') {
12430
- return null;
12584
+ // if (index === parent.length - 1) {
12585
+ // if (inPara && parent.type === 'p') {
12586
+ // return null;
12587
+ // }
12588
+ // return this.getRecursionNextSiblingElement(parent, inPara, forCursor, viewOptions);
12589
+ // } else {
12590
+ let nextElement = null;
12591
+ for (let i = index + 1; i < parent.length; i++) {
12592
+ nextElement = parent.getChild(i);
12593
+ const res = this.getRecursionSiblingElementCursorPosition(nextElement, viewOptions, 'right');
12594
+ if (res) {
12595
+ return res;
12431
12596
  }
12432
- return this.getRecursionNextSiblingElement(parent, inPara, forCursor, viewOptions);
12433
12597
  }
12434
- else {
12435
- let nextElement = null;
12436
- for (let i = index + 1; i < parent.length; i++) {
12437
- nextElement = parent.getChild(i);
12438
- if (nextElement && !nextElement.disableClick) {
12439
- break;
12440
- }
12441
- }
12442
- if (!nextElement || nextElement.disableClick) {
12443
- return this.getRecursionNextSiblingElement(parent, inPara, forCursor, viewOptions);
12444
- }
12445
- const lastLeafElement = ElementUtil.getFirstLeafElement(nextElement);
12446
- //用于光标定位
12447
- if (forCursor && lastLeafElement && !ElementUtil.canSetCursor(lastLeafElement, ElementUtil.getElementEndOffset(lastLeafElement), true, viewOptions)) {
12448
- return this.getRecursionNextSiblingElement(lastLeafElement, inPara, forCursor, viewOptions);
12449
- }
12450
- if (lastLeafElement) {
12451
- return lastLeafElement;
12452
- }
12453
- else {
12454
- return this.getRecursionNextSiblingElement(nextElement.parent, inPara, forCursor, viewOptions);
12455
- }
12598
+ //表单模式需要判断当前父级是否已经超出数据元或者数据组的范围
12599
+ if (viewOptions.docMode === DocMode.FormEdit && !ElementUtil.getDataGroupElement(parent)) {
12600
+ return null;
12456
12601
  }
12602
+ return this.getRecursionNextSiblingElement(parent, viewOptions);
12603
+ // if (!nextElement || nextElement.disableClick) {
12604
+ // return this.getRecursionNextSiblingElement(parent, inPara, forCursor, viewOptions);
12605
+ // }
12606
+ // const lastLeafElement = ElementUtil.getFirstLeafElement(nextElement);
12607
+ // //用于光标定位
12608
+ // if (forCursor && lastLeafElement && !ElementUtil.canSetCursor(lastLeafElement, ElementUtil.getElementEndOffset(lastLeafElement), true, viewOptions)) {
12609
+ // return this.getRecursionNextSiblingElement(lastLeafElement, inPara, forCursor, viewOptions);
12610
+ // }
12611
+ // if (lastLeafElement) {
12612
+ // return lastLeafElement;
12613
+ // } else {
12614
+ // return this.getRecursionNextSiblingElement(nextElement.parent, inPara, forCursor, viewOptions);
12615
+ // }
12616
+ //}
12457
12617
  }
12458
12618
  // /**
12459
12619
  // * 在同一段落中,递归向后寻找最近的元素
@@ -12770,10 +12930,10 @@ class ElementUtil {
12770
12930
  return this.getParent(ele, item => item instanceof DataElementInlineGroup);
12771
12931
  }
12772
12932
  /**
12773
- * 向上查找类型为数据元的父级
12774
- * @param ele
12775
- * @returns
12776
- */
12933
+ * 向上查找类型为数据元的父级
12934
+ * @param ele
12935
+ * @returns
12936
+ */
12777
12937
  static getDataGroupElement(ele) {
12778
12938
  return this.getParent(ele, item => item instanceof DataElementGroupElement);
12779
12939
  }
@@ -13012,6 +13172,9 @@ class ElementUtil {
13012
13172
  }
13013
13173
  return items;
13014
13174
  }
13175
+ static isDataEle(ele) {
13176
+ return validateDataEle(ele) || ele instanceof DataElementGroupElement;
13177
+ }
13015
13178
  }
13016
13179
 
13017
13180
  var TextUnitsHolder;
@@ -13533,7 +13696,7 @@ class EditorContext {
13533
13696
  // const docRefreshSub = this._document.refreshSubject.subscribe(() => {
13534
13697
  // this.syncRefresh?.();
13535
13698
  // });
13536
- const docChangedSub = this._document.onChangeSubject.subscribe(() => {
13699
+ const docChangedSub = this._document.onRefreshEvent.subscribe(() => {
13537
13700
  this.syncRefresh?.();
13538
13701
  });
13539
13702
  this.syncRefresh();
@@ -13650,20 +13813,17 @@ class DocumentContext {
13650
13813
  this.ss = ss;
13651
13814
  }
13652
13815
  getControlIDList() {
13653
- const dataEleList = this.ctx.treeFilter(item => this.isDataEle(item));
13816
+ const dataEleList = this.ctx.treeFilter(item => ElementUtil.isDataEle(item));
13654
13817
  return dataEleList.map(item => item.props.id);
13655
13818
  }
13656
13819
  getControlInstanceList(options) {
13657
- return this.ctx.treeFilter(item => this.isDataEle(item), options);
13820
+ return this.ctx.treeFilter(item => ElementUtil.isDataEle(item), options);
13658
13821
  }
13659
13822
  getControlById(id) {
13660
- return this.ctx.treeFind(item => this.isDataEle(item) && item['props']['id'] === id);
13661
- }
13662
- isDataEle(ele) {
13663
- return validateDataEle(ele) || ele instanceof DataElementGroupElement;
13823
+ return this.ctx.treeFind(item => ElementUtil.isDataEle(item) && item['props']['id'] === id);
13664
13824
  }
13665
13825
  getControlByName(name) {
13666
- return this.ctx.treeFind(item => this.isDataEle(item) && item['props']['name'] === name);
13826
+ return this.ctx.treeFind(item => ElementUtil.isDataEle(item) && item['props']['name'] === name);
13667
13827
  }
13668
13828
  /**
13669
13829
  * 获取数据元值集合
@@ -13681,9 +13841,9 @@ class DocumentContext {
13681
13841
  * @returns
13682
13842
  */
13683
13843
  getDataElementModelList(options) {
13684
- const dataEleList = this.ctx.treeFilter(item => this.isDataEle(item), options);
13844
+ const dataEleList = this.ctx.treeFilter(item => ElementUtil.isDataEle(item), options);
13685
13845
  //数据元、数据组
13686
- const dataInlineGroups = dataEleList.filter(item => item instanceof DataElementInlineGroup);
13846
+ const dataInlineGroups = dataEleList.filter(item => item instanceof DataElementInlineGroup || item instanceof DataElementGroupElement);
13687
13847
  const dataLeafs = dataEleList.filter(item => item instanceof DataElementLeaf);
13688
13848
  //复选框数据元
13689
13849
  const dataCheckList = dataLeafs.filter(item => item instanceof DataElementCheck);
@@ -13692,6 +13852,7 @@ class DocumentContext {
13692
13852
  id: item.props.id,
13693
13853
  name: item.props.name,
13694
13854
  fieldName: item.props.fieldName,
13855
+ caption: item.props.caption,
13695
13856
  item,
13696
13857
  getValue: () => {
13697
13858
  return item.getValue();
@@ -13701,7 +13862,7 @@ class DocumentContext {
13701
13862
  }
13702
13863
  }));
13703
13864
  const dataInlineStructList = dataInlineGroups.map(item => ({
13704
- id: item.props.id, name: item.props.name, fieldName: item.props.fieldName, item, getValue: () => {
13865
+ id: item.props.id, name: item.props.name, fieldName: item.props.fieldName, caption: item.props.caption, item, getValue: () => {
13705
13866
  return item.getValue();
13706
13867
  }, setValue: (val) => {
13707
13868
  item.setValue(val);
@@ -13728,6 +13889,7 @@ class DocumentContext {
13728
13889
  name: groupCheckItems[0].props.name,
13729
13890
  fieldName: groupCheckItems[0].props.fieldName,
13730
13891
  multiSelect: groupCheckItems[0].props.multiSelect,
13892
+ caption: groupCheckItems[0].props.caption,
13731
13893
  item: groupCheckItems,
13732
13894
  getValue: () => {
13733
13895
  let checkedValue = '';
@@ -13766,6 +13928,7 @@ class DocumentContext {
13766
13928
  id: item.props.id,
13767
13929
  name: item.props.name,
13768
13930
  fieldName: item.props.fieldName,
13931
+ caption: item.props.caption,
13769
13932
  item,
13770
13933
  getValue: () => {
13771
13934
  return item.getValue();
@@ -13792,7 +13955,7 @@ class DocumentContext {
13792
13955
  const trackElements = this.getTrackElements();
13793
13956
  return trackElements.map(item => {
13794
13957
  const trackRun = item;
13795
- const content = ElementSerialize.serializeString(trackRun, { all: true });
13958
+ const content = ElementSerialize.serializeString(trackRun, { includeRunDel: true });
13796
13959
  return {
13797
13960
  //用户id
13798
13961
  userId: trackRun.props.userId,
@@ -13926,6 +14089,9 @@ class DynamicExecute {
13926
14089
  this.doc = doc;
13927
14090
  this.ss = ss;
13928
14091
  }
14092
+ create() {
14093
+ return new DynamicExecute(this.doc, this.ss);
14094
+ }
13929
14095
  setCurrentCtx(ele, depItems) {
13930
14096
  this.current = ele;
13931
14097
  this.depItems = depItems;
@@ -13935,10 +14101,10 @@ class DynamicExecute {
13935
14101
  this.depItems = undefined;
13936
14102
  }
13937
14103
  cacheList;
13938
- getControlById(id) {
14104
+ getControlById(id, options) {
13939
14105
  if (!this.cacheList) {
13940
14106
  const ctx = new DocumentContext(this.doc, this.ss);
13941
- this.cacheList = ctx.getDataElementModelList();
14107
+ this.cacheList = ctx.getDataElementModelList(options);
13942
14108
  }
13943
14109
  const f = this.cacheList.find(item => item.id === id);
13944
14110
  return f;
@@ -13953,7 +14119,7 @@ class DynamicExecute {
13953
14119
  if (id.startsWith('$')) {
13954
14120
  id = id.slice(1);
13955
14121
  }
13956
- const control = this.getControlById(id);
14122
+ const control = this.getControlById(id, { includeChildren: true });
13957
14123
  return {
13958
14124
  get value() {
13959
14125
  if (control) {
@@ -14039,14 +14205,23 @@ class DynamicExecute {
14039
14205
  }
14040
14206
 
14041
14207
  class ParagraphMeasure {
14042
- options;
14208
+ docCtx;
14043
14209
  renderCtx;
14044
14210
  execute;
14045
- constructor(options, renderCtx, execute) {
14046
- this.options = options;
14211
+ options;
14212
+ createData;
14213
+ constructor(docCtx, renderCtx, execute) {
14214
+ this.docCtx = docCtx;
14047
14215
  this.renderCtx = renderCtx;
14048
14216
  this.execute = execute;
14217
+ this.options = this.docCtx.viewOptions;
14049
14218
  this.execute = execute;
14219
+ this.createData = {
14220
+ options: this.options,
14221
+ renderCtx: this.renderCtx,
14222
+ execute: this.execute,
14223
+ onNextView: (cb) => { docCtx.onNextView(cb); }
14224
+ };
14050
14225
  }
14051
14226
  /**
14052
14227
  * 段落排版:
@@ -14289,7 +14464,7 @@ class ParagraphMeasure {
14289
14464
  }
14290
14465
  }
14291
14466
  arrangeInlineGroupElement(parentLine, ele) {
14292
- const { options, renderCtx, execute } = this;
14467
+ const createData = this.createData;
14293
14468
  let render = this.createRenderObject(ele);
14294
14469
  //记录多行情况下的渲染对象,用于计算总长度,生成fill-null-space
14295
14470
  const inlineGroupRenders = [];
@@ -14330,7 +14505,7 @@ class ParagraphMeasure {
14330
14505
  render.rect.width += space;
14331
14506
  }
14332
14507
  parentLine.applyNewLine();
14333
- render = ele.createRenderObject({ options, renderCtx, execute });
14508
+ render = ele.createRenderObject(createData);
14334
14509
  parentLine.add(render);
14335
14510
  inlineGroupRenders.push(render);
14336
14511
  },
@@ -14616,6 +14791,10 @@ class ParagraphMeasure {
14616
14791
  const refCtx = execute.getObject(dep);
14617
14792
  if (refCtx.ref) {
14618
14793
  const refEle = refCtx.ref.item;
14794
+ //自己不能引用自己,避免死循环
14795
+ if (refEle === ele) {
14796
+ return;
14797
+ }
14619
14798
  depEleMap.set(dep, refCtx);
14620
14799
  //当前有可能是checkbox数组
14621
14800
  const refEles = Array.isArray(refEle) ? refEle : [refEle];
@@ -14634,6 +14813,62 @@ class ParagraphMeasure {
14634
14813
  console.error('解析表达式出错', ele.attribute?.visibleExpr);
14635
14814
  }
14636
14815
  }
14816
+ // /**
14817
+ // * 解析侦听表达式
14818
+ // * 当依赖性元素发生变化时,重新计算运行当前元素的表达式
14819
+ // * @param ele
14820
+ // * @param execute
14821
+ // * @private
14822
+ // */
14823
+ // parseEffectExpression(ele: Element, execute: DynamicExecute): void {
14824
+ // if (ele.effectExpr) return;
14825
+ // if (!ele.attribute?.effectExpr) return;
14826
+ // const reactiveMode = this.renderCtx.drawMode !== 'print';
14827
+ // try {
14828
+ // const depIdItems: Array<string> = [];
14829
+ // const depEleMap: Map<string, RefCtxValue> = new Map();
14830
+ // let compliedCode = parser(ele.attribute?.effectExpr, depIdItems);
14831
+ // compliedCode = addReturn(compliedCode);
14832
+ // ele.effectExpr = { compliedCode, func: new Function(`with(this){ ${compliedCode} }`), depItems: depEleMap };
14833
+ // if (depIdItems.length) {
14834
+ // depIdItems.forEach(dep => {
14835
+ // const refCtx = execute.getObject(dep);
14836
+ // if (refCtx.ref) {
14837
+ // const refEle = refCtx.ref.item as Element;
14838
+ // //自己不能引用自己,避免死循环
14839
+ // if (refEle === ele) {
14840
+ // return;
14841
+ // }
14842
+ // depEleMap.set(dep, refCtx);
14843
+ // //当前有可能是checkbox数组
14844
+ // const refEles = Array.isArray(refEle) ? refEle : [refEle];
14845
+ // reactiveMode && refEles.forEach(item => {
14846
+ // //求值依赖元素更改的时候,发布当前元素重新计算的指令
14847
+ // item.onChangeSubject.subscribe(() => {
14848
+ // try {
14849
+ // this.docCtx.onNextView(() => {
14850
+ // //当前元素可能被删除
14851
+ // const func = ele?.effectExpr?.func;
14852
+ // if (!func) {
14853
+ // return;
14854
+ // }
14855
+ // const tempExecuter = execute.create();
14856
+ // tempExecuter.setCurrentCtx(ele, ele.effectExpr.depItems);
14857
+ // const fn = func.bind(tempExecuter);
14858
+ // fn();
14859
+ // })
14860
+ // } catch (e) {
14861
+ // console.error(e, "表达式执行出错", ele.effectExpr.compliedCode);
14862
+ // }
14863
+ // });
14864
+ // });
14865
+ // }
14866
+ // });
14867
+ // }
14868
+ // } catch (e) {
14869
+ // console.error('解析表达式出错', ele.attribute?.effectExpr);
14870
+ // }
14871
+ // }
14637
14872
  /**
14638
14873
  * 元素可见行求值
14639
14874
  * @param ele
@@ -14663,11 +14898,10 @@ class ParagraphMeasure {
14663
14898
  return null;
14664
14899
  }
14665
14900
  }
14666
- return element.createRenderObject({
14667
- options: this.options,
14668
- renderCtx: this.renderCtx,
14669
- execute: this.execute
14670
- });
14901
+ // if (this.options.enableDyExpression) {
14902
+ // this.parseEffectExpression(element, this.execute);
14903
+ // }
14904
+ return element.createRenderObject(this.createData);
14671
14905
  }
14672
14906
  }
14673
14907
 
@@ -14681,6 +14915,8 @@ class SelectionOverlays {
14681
14915
  selectionEleSets = new Map();
14682
14916
  //批注对象集合
14683
14917
  commRangeSets = new Map();
14918
+ //其他对象集合,例如查找对象
14919
+ otherRangeSets = new Map();
14684
14920
  constructor(selectionState) {
14685
14921
  this.selectionState = selectionState;
14686
14922
  }
@@ -14730,6 +14966,18 @@ class SelectionOverlays {
14730
14966
  this.addToSets(range.selectedChildren[i], set);
14731
14967
  }
14732
14968
  }
14969
+ addToOtherRangeSets(range) {
14970
+ if (!this.otherRangeSets.has(range.target)) {
14971
+ this.otherRangeSets.set(range.target, []);
14972
+ }
14973
+ this.otherRangeSets.get(range.target)?.push(range);
14974
+ for (let i = 0; i < range.selectedChildren.length; i++) {
14975
+ this.addToOtherRangeSets(range.selectedChildren[i]);
14976
+ }
14977
+ }
14978
+ clearOtherRangeSets() {
14979
+ this.otherRangeSets.clear();
14980
+ }
14733
14981
  /**
14734
14982
  * 添加到批注集合
14735
14983
  * @param range
@@ -14822,7 +15070,7 @@ class DocumentArrange {
14822
15070
  return suppressTracking(() => {
14823
15071
  const doc = this.docCtx.document;
14824
15072
  this.execute = new DynamicExecute(doc, this.docCtx.selectionState);
14825
- this.pMeasure = new ParagraphMeasure(this.options, this.renderCtx, this.execute);
15073
+ this.pMeasure = new ParagraphMeasure(this.docCtx, this.renderCtx, this.execute);
14826
15074
  const data = {
14827
15075
  doc,
14828
15076
  options: this.options,
@@ -15030,7 +15278,7 @@ class DocumentArrange {
15030
15278
  if (this.options.textRowLineMode && ele instanceof TableElement && ele.cacheRender) {
15031
15279
  const cacheRender = ele.cacheRender;
15032
15280
  clearChildrenRenderCache(ele);
15033
- textLineRenderMode(cacheRender, { options: this.options, renderCtx: this.renderCtx, execute: this.execute });
15281
+ textLineRenderMode(cacheRender, { options: this.options, renderCtx: this.renderCtx, execute: this.execute, onNextView: (cb) => { this.docCtx.onNextView(cb); } });
15034
15282
  }
15035
15283
  }
15036
15284
  getDocInnerRect(documentRender) {
@@ -15383,6 +15631,9 @@ class DocumentArrange {
15383
15631
  clearPaintCache(ele, data) {
15384
15632
  ele.paintRenders.length = 0;
15385
15633
  ele.beginMeasure(data);
15634
+ if (ele.modifyFlag !== ModifyFlag.None) {
15635
+ ele.onChangeSubject.next();
15636
+ }
15386
15637
  this.identifyComment(ele);
15387
15638
  if (ele instanceof BranchElement) {
15388
15639
  for (let i = 0; i < ele.length; i++) {
@@ -15454,7 +15705,7 @@ class DocumentArrange {
15454
15705
  if (!this.options.enableFastMeasure) {
15455
15706
  return false;
15456
15707
  }
15457
- this.pMeasure = new ParagraphMeasure(this.options, this.renderCtx, this.execute);
15708
+ this.pMeasure = new ParagraphMeasure(this.docCtx, this.renderCtx, this.execute);
15458
15709
  const ops = this.docCtx.currentOpsLog;
15459
15710
  if (!ops.length) {
15460
15711
  return false;
@@ -15513,7 +15764,7 @@ class DocumentArrange {
15513
15764
  return suppressTracking(() => {
15514
15765
  const doc = this.docCtx.document;
15515
15766
  this.execute = new DynamicExecute(doc, this.docCtx.selectionState);
15516
- this.pMeasure = new ParagraphMeasure(this.options, this.renderCtx, this.execute);
15767
+ this.pMeasure = new ParagraphMeasure(this.docCtx, this.renderCtx, this.execute);
15517
15768
  const data = {
15518
15769
  doc,
15519
15770
  options: this.options,
@@ -15551,6 +15802,7 @@ class DocumentPaginator {
15551
15802
  return;
15552
15803
  }
15553
15804
  this.docContainer = new DocumentContainerRender();
15805
+ //this.docContainer.padding.top = this.viewOptions.showRule ? 50 : 0;
15554
15806
  this.docCtx.selectionState.renderContainer = this.docContainer;
15555
15807
  this.docContainer.rect.width = this.viewOptions.docPageSettings.width;
15556
15808
  const newMeasure = new DocumentArrange(this.docCtx, this.renderContext, this.seo);
@@ -16871,13 +17123,14 @@ class DocumentEvent {
16871
17123
  moveCursorToLeftHandle(startControl, startOffset) {
16872
17124
  if (startOffset === 0) {
16873
17125
  const oldRegion = ElementUtil.getElementRegion(startControl);
16874
- const prevEle = ElementUtil.getRecursionPrevSiblingElement(startControl, false, true, this.viewOptions);
16875
- if (prevEle) {
16876
- const newRegion = ElementUtil.getElementRegion(prevEle);
17126
+ const cursorPosition = ElementUtil.getRecursionPrevSiblingElement(startControl, this.viewOptions);
17127
+ if (cursorPosition) {
17128
+ const { ele: prevEle, offset } = cursorPosition;
17129
+ const newRegion = ElementUtil.getElementRegion(cursorPosition.ele);
16877
17130
  if (newRegion !== oldRegion) {
16878
17131
  return;
16879
17132
  }
16880
- if (this.viewOptions.docMode === DocMode.FormEdit && !ElementUtil.canSetCursor(prevEle, ElementUtil.fixedOffset(prevEle, -1), true, this.viewOptions)) {
17133
+ if (this.viewOptions.docMode === DocMode.FormEdit && !ElementUtil.canSetCursor(prevEle, offset, true, this.viewOptions)) {
16881
17134
  this.moveCursorToLeftHandle(prevEle, 0);
16882
17135
  return;
16883
17136
  }
@@ -16925,17 +17178,18 @@ class DocumentEvent {
16925
17178
  moveCursorToRightHandle(startControl, startOffset) {
16926
17179
  if (this.isLeafEleEndOffset(startControl, startOffset)) {
16927
17180
  const oldRegion = ElementUtil.getElementRegion(startControl);
16928
- const nextEle = ElementUtil.getRecursionNextSiblingElement(startControl, false, true, this.viewOptions);
16929
- if (nextEle) {
16930
- const newRegion = ElementUtil.getElementRegion(nextEle);
17181
+ const cursorPosition = ElementUtil.getRecursionNextSiblingElement(startControl, this.viewOptions);
17182
+ if (cursorPosition) {
17183
+ const { ele, offset } = cursorPosition;
17184
+ const newRegion = ElementUtil.getElementRegion(ele);
16931
17185
  if (oldRegion !== newRegion) {
16932
17186
  return;
16933
17187
  }
16934
- if (this.viewOptions.docMode === DocMode.FormEdit && !ElementUtil.canSetCursor(nextEle, ElementUtil.fixedOffset(nextEle, -1), true, this.viewOptions)) {
16935
- this.moveCursorToRightHandle(nextEle, ElementUtil.fixedOffset(nextEle, -1));
17188
+ if (this.viewOptions.docMode === DocMode.FormEdit && !ElementUtil.canSetCursor(ele, offset, true, this.viewOptions)) {
17189
+ this.moveCursorToRightHandle(ele, offset);
16936
17190
  return;
16937
17191
  }
16938
- this.selectionState.resetRange(nextEle, 0);
17192
+ this.selectionState.resetRange(ele, 0);
16939
17193
  return;
16940
17194
  }
16941
17195
  }
@@ -17664,7 +17918,7 @@ class DocumentChange {
17664
17918
  }
17665
17919
  this.selectionState.clear();
17666
17920
  //用于刷新后定位光标
17667
- let startPointElement;
17921
+ let startPointElement = null;
17668
17922
  let startPointOffset = 0;
17669
17923
  if (selectedRange.isFullSelected) {
17670
17924
  //某个容器的内容被全部选中
@@ -17714,8 +17968,14 @@ class DocumentChange {
17714
17968
  startPointOffset = res.offset;
17715
17969
  }
17716
17970
  else {
17717
- startPointElement = ElementUtil.getRecursionPrevSiblingElement(startRange.target, false, true, this.viewOptions);
17718
- startPointOffset = -1;
17971
+ const cursorPosition = ElementUtil.getRecursionPrevSiblingElement(startRange.target, this.viewOptions);
17972
+ if (cursorPosition) {
17973
+ startPointElement = cursorPosition.ele;
17974
+ startPointOffset = cursorPosition.offset;
17975
+ }
17976
+ else {
17977
+ startPointElement = null;
17978
+ }
17719
17979
  //判断结束选区和开始选区是否在一个段落中,尽量落在同一段落中
17720
17980
  if (!startPointElement || ElementUtil.isInSameParagraph(startRange.target, endRange.target)) {
17721
17981
  if (!endRange.isFullSelected) {
@@ -17772,11 +18032,12 @@ class DocumentChange {
17772
18032
  onBackspaceElement(control, offset) {
17773
18033
  this.selectionState.clear();
17774
18034
  if (offset === 0) {
17775
- const prevEle = ElementUtil.getRecursionPrevSiblingElement(control, false, true, this.viewOptions);
17776
- if (!prevEle) {
18035
+ const cursorPosition = ElementUtil.getRecursionPrevSiblingElement(control, this.viewOptions);
18036
+ if (!cursorPosition) {
17777
18037
  this.selectionState.resetRange(control, 0);
17778
18038
  return;
17779
18039
  }
18040
+ const { ele: prevEle, offset } = cursorPosition;
17780
18041
  if (ElementUtil.isInSameParagraph(control, prevEle)) {
17781
18042
  if (ElementUtil.getPrevSiblingElement(control) === prevEle) {
17782
18043
  this.onBackspaceElement(prevEle, ElementUtil.getElementEndOffset(prevEle));
@@ -17862,18 +18123,24 @@ class DocumentChange {
17862
18123
  */
17863
18124
  onKeyDeleteElement(control, offset) {
17864
18125
  this.selectionState.clear();
18126
+ if (control instanceof PSymbolElement) {
18127
+ offset = 1;
18128
+ }
17865
18129
  if (offset === ElementUtil.getElementEndOffset(control)) {
17866
- const nextEle = ElementUtil.getRecursionNextSiblingElement(control, false, true, this.viewOptions);
17867
- if (!nextEle) {
18130
+ const cursorPosition = ElementUtil.getRecursionNextSiblingElement(control, this.viewOptions);
18131
+ if (!cursorPosition) {
17868
18132
  this.selectionState.resetRange(control, -1);
17869
18133
  return;
17870
18134
  }
18135
+ //const {ele: nextEle, offset} = cursorPosition;
18136
+ const nextEle = cursorPosition.ele;
18137
+ offset = cursorPosition.offset;
17871
18138
  if (ElementUtil.isInSameParagraph(control, nextEle)) {
17872
18139
  if (ElementUtil.getNextSiblingElement(control) === nextEle) {
17873
- this.onKeyDeleteElement(nextEle, 0);
18140
+ this.onKeyDeleteElement(nextEle, offset);
17874
18141
  }
17875
18142
  else {
17876
- this.selectionState.resetRange(nextEle, 0);
18143
+ this.selectionState.resetRange(nextEle, offset);
17877
18144
  }
17878
18145
  }
17879
18146
  else {
@@ -17886,7 +18153,7 @@ class DocumentChange {
17886
18153
  this.selectionState.resetRange(nextEle, 0);
17887
18154
  return;
17888
18155
  }
17889
- this.combineParagraph(nextPara, currPara, control);
18156
+ this.combineParagraph(currPara, nextPara, control);
17890
18157
  }
17891
18158
  else {
17892
18159
  //不是紧挨着的段落,则前一个段落是位于另一个容器里,例如:处于单元格内的段落
@@ -17906,21 +18173,29 @@ class DocumentChange {
17906
18173
  }
17907
18174
  }
17908
18175
  else {
17909
- if (control.parent instanceof DataElementInlineGroup && control instanceof DataDecorateElement) {
18176
+ //当前为数据修饰元素,需要做额外判定是否需要删除数据元素
18177
+ if (ElementUtil.isDataEle(control.parent) && control instanceof DataDecorateElement) {
17910
18178
  const dataEle = control.parent;
17911
18179
  //空数据元,并且当前光标处于数据元开始位置
17912
- if (control.isPrefix) {
18180
+ if (dataEle.length === 2) {
17913
18181
  if (this.canDeleteInlineGroup(dataEle)) {
17914
18182
  this.setCursorForDeleteAction(dataEle);
17915
18183
  dataEle.remove();
17916
18184
  }
17917
18185
  else {
17918
- this.selectionState.resetRange(control, -1);
18186
+ this.selectionState.resetRange(dataEle.startDecorate, 1);
17919
18187
  }
17920
18188
  return;
17921
18189
  }
17922
- else if (!control.isPrefix && dataEle.length === 2) {
17923
- this.selectionState.resetRange(dataEle.endDecorate, -1);
18190
+ else {
18191
+ //this.setCursorForDeleteAction(dataEle);
18192
+ const cursorInfo = ElementUtil.getRecursionNextSiblingElement(control, this.viewOptions);
18193
+ if (cursorInfo) {
18194
+ this.selectionState.resetRange(cursorInfo.ele, cursorInfo.offset);
18195
+ }
18196
+ else {
18197
+ this.selectionState.resetRange(control, 0);
18198
+ }
17924
18199
  return;
17925
18200
  }
17926
18201
  }
@@ -17992,14 +18267,14 @@ class DocumentChange {
17992
18267
  //当前用户增加的内容,内容直接删除不需要留痕
17993
18268
  if (this.isInCurrentUserTrack(target, TrackRunTypeEnum.Inserted)) {
17994
18269
  target.remove();
17995
- this.removeEmtpyInlineBlock(parent);
18270
+ this.removeEmptyInlineBlock(parent);
17996
18271
  return;
17997
18272
  }
17998
18273
  //target.remove();
17999
18274
  const trackEle = this.getNextTrackElement(target, TrackRunTypeEnum.Deleted);
18000
18275
  trackEle.addChild(target.clone(true), 0);
18001
18276
  target.remove();
18002
- this.removeEmtpyInlineBlock(parent);
18277
+ this.removeEmptyInlineBlock(parent);
18003
18278
  }
18004
18279
  /**
18005
18280
  * 更新文本删除留痕
@@ -18071,35 +18346,36 @@ class DocumentChange {
18071
18346
  * @returns
18072
18347
  */
18073
18348
  removeElement(control) {
18074
- const prevEle = ElementUtil.getRecursionPrevSiblingElement(control, false, true, this.viewOptions);
18075
- if (!prevEle) {
18076
- const nextEle = ElementUtil.getRecursionNextSiblingElement(control, true, true, this.viewOptions);
18077
- if (nextEle) {
18349
+ let cursorPosition = ElementUtil.getRecursionPrevSiblingElement(control, this.viewOptions);
18350
+ if (!cursorPosition) {
18351
+ cursorPosition = ElementUtil.getRecursionNextSiblingElement(control, this.viewOptions);
18352
+ if (cursorPosition) {
18078
18353
  //this.selectionState.resetRange(nextEle, 0);
18079
- this.setSelectionStateByDeleteEvent(nextEle, 0, control);
18354
+ this.setSelectionStateByDeleteEvent(cursorPosition.ele, cursorPosition.offset, control);
18080
18355
  control.remove();
18081
18356
  return;
18082
18357
  }
18083
18358
  this.selectionState.resetRange(control, 0);
18084
18359
  return;
18085
18360
  }
18086
- if (ElementUtil.isInSameParagraph(control, prevEle)) {
18361
+ if (ElementUtil.isInSameParagraph(control, cursorPosition.ele)) {
18087
18362
  //this.selectionState.resetRange(prevEle, -1);
18088
- this.setSelectionStateByDeleteEvent(prevEle, -1, control);
18363
+ this.setSelectionStateByDeleteEvent(cursorPosition.ele, -1, control);
18089
18364
  control.remove();
18090
18365
  return;
18091
18366
  }
18092
18367
  else {
18093
- const nextEle = ElementUtil.getRecursionNextSiblingElement(control, true, true, this.viewOptions);
18094
- if (nextEle && ElementUtil.getPrevSiblingElement(nextEle) === control) {
18368
+ const cursorPosition = ElementUtil.getRecursionNextSiblingElement(control, this.viewOptions);
18369
+ if (cursorPosition && ElementUtil.getPrevSiblingElement(cursorPosition.ele) === control) {
18095
18370
  //this.selectionState.resetRange(nextEle, 0);
18096
- this.setSelectionStateByDeleteEvent(nextEle, 0, control);
18371
+ this.setSelectionStateByDeleteEvent(cursorPosition.ele, cursorPosition.offset, control);
18097
18372
  control.remove();
18098
18373
  return;
18099
18374
  }
18100
18375
  else {
18101
18376
  //this.selectionState.resetRange(prevEle, -1);
18102
- this.setSelectionStateByDeleteEvent(prevEle, -1, control);
18377
+ //this.setSelectionStateByDeleteEvent(cursorPosition.ele, -1, control);
18378
+ //TODO: 需要检测下
18103
18379
  control.remove();
18104
18380
  return;
18105
18381
  }
@@ -18618,7 +18894,7 @@ class DocumentChange {
18618
18894
  }
18619
18895
  //表单模式:如果复制的是单格式的文本,需要序列化为纯文本处理
18620
18896
  if (this.viewOptions.docMode === DocMode.FormEdit) {
18621
- const pasteString = pasteEles.map(item => ElementSerialize.serializeString(item, { all: false })).join('');
18897
+ const pasteString = pasteEles.map(item => ElementSerialize.serializeString(item)).join('');
18622
18898
  if (pasteString) {
18623
18899
  this.pastePlainText(pasteString);
18624
18900
  }
@@ -18855,7 +19131,10 @@ class DocumentChange {
18855
19131
  }
18856
19132
  validate() {
18857
19133
  const dataEleList = this.docCtx.document.treeFilter(item => item instanceof DataElementInlineGroup);
18858
- const errorEleList = dataEleList.map(item => ({ error: item.validate(), ele: item })).filter(item => item.error);
19134
+ const errorEleList = dataEleList.map(item => ({
19135
+ error: item.validate(),
19136
+ ele: item
19137
+ })).filter(item => item.error);
18859
19138
  if (!errorEleList.length) {
18860
19139
  return true;
18861
19140
  }
@@ -18889,7 +19168,7 @@ class DocumentChange {
18889
19168
  this.setCursorForDeleteAction(text);
18890
19169
  const parent = text.parent;
18891
19170
  text.remove();
18892
- this.removeEmtpyInlineBlock(parent);
19171
+ this.removeEmptyInlineBlock(parent);
18893
19172
  }
18894
19173
  setCursorForDeleteAction(control) {
18895
19174
  const cursorInfo = this.getCursorElementByDeleteAction(control);
@@ -18907,12 +19186,9 @@ class DocumentChange {
18907
19186
  return ele.parent instanceof DataElementInlineGroup || ele.parent instanceof DataElementGroupElement;
18908
19187
  };
18909
19188
  if (isInDataAre(control)) {
18910
- const prevLeafElementInPara = ElementUtil.getRecursionPrevSiblingElement(control, true, true, this.viewOptions);
18911
- if (prevLeafElementInPara && isInDataAre(prevLeafElementInPara)) {
18912
- return {
18913
- ele: prevLeafElementInPara,
18914
- offset: ElementUtil.getElementEndOffset(prevLeafElementInPara)
18915
- };
19189
+ const cursorPosition = ElementUtil.getRecursionPrevSiblingElement(control, this.viewOptions);
19190
+ if (cursorPosition && isInDataAre(cursorPosition.ele)) {
19191
+ return cursorPosition;
18916
19192
  }
18917
19193
  else {
18918
19194
  return {
@@ -18922,27 +19198,21 @@ class DocumentChange {
18922
19198
  }
18923
19199
  }
18924
19200
  }
18925
- const prevLeafElementInPara = ElementUtil.getRecursionPrevSiblingElement(control, false, true, this.viewOptions);
19201
+ const cursorPosition = ElementUtil.getRecursionPrevSiblingElement(control, this.viewOptions);
18926
19202
  //是否为同一段落
18927
- if (prevLeafElementInPara && ElementUtil.isInSameParagraph(prevLeafElementInPara, control)) {
18928
- return {
18929
- ele: prevLeafElementInPara,
18930
- offset: ElementUtil.getElementEndOffset(prevLeafElementInPara)
18931
- };
19203
+ if (cursorPosition && ElementUtil.isInSameParagraph(cursorPosition.ele, control)) {
19204
+ return cursorPosition;
18932
19205
  }
18933
19206
  //同一段落其他元素
18934
- const nextLeafElementInPara = ElementUtil.getRecursionNextSiblingElement(control, true, true, this.viewOptions);
18935
- if (nextLeafElementInPara) {
18936
- return {
18937
- ele: nextLeafElementInPara,
18938
- offset: 0
18939
- };
19207
+ const nextCursorPosition = ElementUtil.getRecursionNextSiblingElement(control, this.viewOptions);
19208
+ if (nextCursorPosition) {
19209
+ return nextCursorPosition;
18940
19210
  }
18941
19211
  //上一段落
18942
- if (prevLeafElementInPara) {
19212
+ if (cursorPosition) {
18943
19213
  return {
18944
- ele: prevLeafElementInPara,
18945
- offset: prevLeafElementInPara instanceof PSymbolElement ? 0 : ElementUtil.getElementEndOffset(prevLeafElementInPara)
19214
+ ele: cursorPosition.ele,
19215
+ offset: cursorPosition.ele instanceof PSymbolElement ? 0 : ElementUtil.getElementEndOffset(cursorPosition.ele)
18946
19216
  };
18947
19217
  }
18948
19218
  return null;
@@ -18951,11 +19221,12 @@ class DocumentChange {
18951
19221
  * 移除空行内标签
18952
19222
  * @param ele
18953
19223
  */
18954
- removeEmtpyInlineBlock(ele) {
19224
+ removeEmptyInlineBlock(ele) {
18955
19225
  if (ele instanceof InlineGroupElement && ele.length === 0) {
18956
19226
  const parent = ele.parent;
18957
19227
  ele.remove();
18958
- this.removeEmtpyInlineBlock(parent);
19228
+ //track-run 标签等
19229
+ this.removeEmptyInlineBlock(parent);
18959
19230
  }
18960
19231
  }
18961
19232
  /**
@@ -19769,6 +20040,12 @@ class DocumentSvg {
19769
20040
  const range = this.sso.commRangeSets.get(render.element);
19770
20041
  createMaskVNode(range, selectionMask.mask);
19771
20042
  }
20043
+ if (this.sso.otherRangeSets.has(render.element)) {
20044
+ const ranges = this.sso.otherRangeSets.get(render.element);
20045
+ ranges.forEach(range => {
20046
+ createMaskVNode(range, selectionMask.mask);
20047
+ });
20048
+ }
19772
20049
  }
19773
20050
  getHTMLVNode(docRenders) {
19774
20051
  this.counterMap = {};
@@ -19975,6 +20252,7 @@ class EditorCalendarVNode {
19975
20252
  if (parent) {
19976
20253
  const parentRect = parent.getBoundingClientRect();
19977
20254
  const elmRect = elm.getBoundingClientRect();
20255
+ const top = parseInt(elm.style.top);
19978
20256
  // elmRect.width /= scale;
19979
20257
  // elmRect.height /= scale;
19980
20258
  // parentRect.width /= scale;
@@ -19990,12 +20268,13 @@ class EditorCalendarVNode {
19990
20268
  //elm.style.left = parentRect.width - elmRect.width + 'px';
19991
20269
  }
19992
20270
  if (elmRect.top + elmRect.height > parentRect.top + parentRect.height) {
19993
- const newTop = position.y - position.height - elmRect.height;
19994
- const oldTop = position.y + 5 + position.height;
20271
+ const newTop = top - 5 - position.height - elmRect.height;
20272
+ position.y + 5 + position.height;
19995
20273
  //计算前后的高度的差距,然后判断新的值是否在父元素的范围内,如果不在则使用旧的值
19996
- if (newTop > 0 && oldTop - newTop < elmRect.top - parentRect.top) {
19997
- elm.style.top = (position.y - position.height - elmRect.height) + 'px';
19998
- }
20274
+ // if (newTop > 0 && oldTop - newTop < elmRect.top - parentRect.top) {
20275
+ // elm.style.top = (position.y - position.height - elmRect.height) + 'px';
20276
+ // }
20277
+ elm.style.top = newTop + 'px';
19999
20278
  //elm.style.top = (top - (elmRect.top + elmRect.height - (parentRect.top + parentRect.height))) + 'px';
20000
20279
  //elm.style.top = (position.y - position.height - elmRect.height) + 'px';
20001
20280
  }
@@ -20075,7 +20354,7 @@ class EditorCalendarVNode {
20075
20354
  const sel = 'div.editor-calendar-body-day-item'
20076
20355
  + (day.isCurrentMonth ? ".editor-calendar-body-day-item--current-month" : "")
20077
20356
  + (day.today ? ".editor-calendar-body-day-item--today" : "")
20078
- + (this.selectedDate.value === day.date ? ".editor-calendar-body-day-item--selected" : "");
20357
+ + (this.selectedDate.value === day.date ? ".editor-calendar-item--selected" : "");
20079
20358
  return {
20080
20359
  sel,
20081
20360
  data: {
@@ -20410,21 +20689,23 @@ class EditorCalendarVNode {
20410
20689
  }
20411
20690
  }
20412
20691
 
20692
+ const svgNS = "http://www.w3.org/2000/svg";
20413
20693
  class DocRule {
20414
20694
  docCtx;
20415
20695
  //private ctx!: CanvasRenderingContext2D;
20416
20696
  options;
20417
20697
  //标尺高度
20418
- ruleHeight = 30;
20698
+ ruleHeight = 28;
20699
+ thumbWidth = 12;
20419
20700
  //当前标尺的位置
20420
20701
  thumbX;
20421
20702
  mouseDownPos;
20422
- indentThumbPoints = [];
20423
- hangThumbPoints = [];
20703
+ //private indentThumbPoints: Array<Position> = [];
20704
+ //private hangThumbPoints: Array<Position> = [];
20424
20705
  mouseDownThumbType = 'none';
20425
20706
  viewOptions;
20426
20707
  ss;
20427
- nodes = [];
20708
+ //private nodes: Array<any> = [];
20428
20709
  constructor(docCtx) {
20429
20710
  this.docCtx = docCtx;
20430
20711
  this.viewOptions = this.docCtx.viewOptions;
@@ -20440,14 +20721,8 @@ class DocRule {
20440
20721
  indent: 0,
20441
20722
  hanging: 0
20442
20723
  };
20443
- // this.canvas.addEventListener("mousedown", (evt) => this.canvasMousedown(evt));
20444
- // this.canvas.addEventListener("mousemove", (evt) => this.canvasMousemove(evt));
20445
- // this.canvas.addEventListener("mouseup", (evt) => this.canvasMouseup(evt));
20446
20724
  }
20447
20725
  destroy() {
20448
- // this.canvas.removeEventListener("mousedown", this.canvasMousedown);
20449
- // this.canvas.removeEventListener("mousemove", this.canvasMousemove);
20450
- // this.canvas.removeEventListener("mouseup", this.canvasMouseup);
20451
20726
  }
20452
20727
  setRuleOptions(options) {
20453
20728
  this.options = options;
@@ -20458,208 +20733,91 @@ class DocRule {
20458
20733
  //ElementUtil.setCanvasProps(this.canvas, this.ctx, {width: this.getParentWidth(), height: this.ruleHeight});
20459
20734
  //this.canvas.style.left = this.options.docLeft + 'px';
20460
20735
  }
20461
- fillRectSvg(x, y, width, height, color) {
20462
- return ElementUtil.getFillSvgRect(x, y, width, height, color);
20463
- }
20464
- drawIndentThumbSvg(x, y) {
20465
- const points = [];
20466
- x -= 4;
20467
- points.push({ x: x, y });
20468
- points.push({ x: x, y: y + 3 });
20469
- points.push({ x: x + 4, y: y + 7 });
20470
- points.push({ x: x + 8, y: y + 3 });
20471
- points.push({ x: x + 8, y });
20472
- points.push({ x: x, y });
20473
- this.drawLineSvg(points);
20474
- return points;
20475
- }
20476
- drawHangThumbSvg(x, y) {
20477
- const points = [];
20478
- x -= 4;
20479
- points.push({ x: x, y });
20480
- points.push({ x: x, y: y - 3 });
20481
- points.push({ x: x + 4, y: y - 7 });
20482
- points.push({ x: x + 8, y: y - 3 });
20483
- points.push({ x: x + 8, y });
20484
- points.push({ x: x, y });
20485
- points.push({ x: x, y: y + 3 });
20486
- points.push({ x: x + 8, y: y + 3 });
20487
- points.push({ x: x + 8, y: y });
20488
- this.drawLineSvg(points);
20489
- return points;
20490
- }
20491
- drawLineSvg(points) {
20492
- this.nodes.push(ElementUtil.getStrokeSvgPath(points, "black", 0.5));
20493
- }
20494
- drawTextSvg(text, x, y) {
20495
- this.nodes.push({
20496
- sel: 'text',
20497
- text: text,
20498
- data: {
20499
- ns: "http://www.w3.org/2000/svg",
20500
- attrs: {
20501
- 'dominant-baseline': 'hanging',
20502
- 'font-family': "仿宋",
20503
- 'font-size': 8,
20504
- x,
20505
- y,
20506
- 'text-anchor': 'middle'
20507
- }
20508
- }
20509
- });
20510
- }
20511
20736
  refreshRuleSvg() {
20512
20737
  const editor = this;
20513
20738
  return {
20514
20739
  render() {
20515
- if (!editor.viewOptions.showRule) {
20516
- return null;
20517
- }
20518
- editor.nodes = [];
20519
- editor.drawRuleSvg();
20520
- const node = {
20521
- sel: 'g', data: {
20522
- ns: 'http://www.w3.org/2000/svg',
20523
- }, children: [...editor.nodes]
20524
- };
20525
- return {
20526
- sel: 'div.doc-rule',
20527
- data: {
20528
- style: {
20529
- left: `${editor.options.docLeft}px`,
20530
- },
20531
- on: {
20532
- mousedown: (evt) => editor.canvasMousedown(evt),
20533
- mousemove: (evt) => editor.canvasMousemove(evt),
20534
- mouseup: (evt) => editor.canvasMouseup(evt)
20535
- }
20536
- },
20537
- children: [
20538
- {
20539
- sel: 'svg',
20540
- data: {
20541
- ns: 'http://www.w3.org/2000/svg',
20542
- attrs: {
20543
- width: editor.options.width,
20544
- height: editor.ruleHeight
20545
- }
20546
- },
20547
- children: [node]
20548
- }
20549
- ]
20550
- };
20740
+ return editor.getRuleSVG();
20551
20741
  }
20552
20742
  };
20553
20743
  }
20554
- canvasMousedown(evt) {
20555
- const clickPos = this.getMousePos(evt);
20556
- if (this.pointInPoly(clickPos, this.indentThumbPoints)) {
20557
- this.mouseDownThumbType = 'indent';
20558
- this.mouseDownPos = clickPos;
20559
- }
20560
- else if (this.pointInPoly(clickPos, this.hangThumbPoints)) {
20561
- this.mouseDownThumbType = 'hang';
20562
- this.mouseDownPos = clickPos;
20563
- }
20564
- else {
20565
- console.log("未点击在里面");
20744
+ getRuleSVG() {
20745
+ if (!this.viewOptions.showRule) {
20746
+ return null;
20566
20747
  }
20567
- }
20568
- getMousePos(evt) {
20569
- return {
20570
- x: evt.offsetX,
20571
- y: evt.offsetY
20748
+ //editor.nodes = [];
20749
+ const paraRender = this.getRuleMarksPos();
20750
+ //editor.drawRuleSvg();
20751
+ const leftBg = ElementUtil.getFillSvgRect(0, 0, this.options.pagePL, this.ruleHeight, "rgb(198,198,198)");
20752
+ const rightBg = ElementUtil.getFillSvgRect(this.options.width - this.options.pagePR, 0, this.options.pagePR, this.ruleHeight, "rgb(198,198,198)");
20753
+ const svg = {
20754
+ sel: 'svg',
20755
+ data: {
20756
+ ns: svgNS,
20757
+ attrs: {
20758
+ width: this.options.width,
20759
+ height: this.ruleHeight
20760
+ }
20761
+ },
20762
+ children: [leftBg, rightBg]
20572
20763
  };
20573
- }
20574
- canvasMousemove(evt) {
20575
- if (['indent', 'hang'].indexOf(this.mouseDownThumbType) < 0) {
20576
- return;
20577
- }
20578
- if (!this.mouseDownPos) {
20579
- return;
20580
- }
20581
- const canvasPos = this.getMousePos(evt);
20582
- let moveX = canvasPos.x - this.mouseDownPos.x;
20583
- //至少移动5px再进行修改
20584
- const remainder = moveX % 5;
20585
- if (Math.abs(remainder) < 3) {
20586
- return;
20587
- }
20588
- else {
20589
- if (remainder < 0) {
20590
- moveX -= 5 + remainder;
20591
- }
20592
- else {
20593
- moveX += 5 - remainder;
20594
- }
20595
- }
20596
- if (moveX === 0) {
20597
- return;
20598
- }
20599
- canvasPos.x = this.mouseDownPos.x + moveX;
20600
- const para = this.getCurrPara();
20601
- if (!para) {
20602
- throw new Error('para is null');
20603
- }
20604
- if (this.mouseDownThumbType === 'indent') {
20605
- this.thumbX.indent += moveX;
20606
- this.thumbX.indent = this.thumbX.indent < 0 ? 0 : this.thumbX.indent;
20607
- this.thumbX.indent = this.thumbX.indent > this.options.width ? this.options.width : this.thumbX.indent;
20608
- this.mouseDownPos = canvasPos;
20609
- para.props.indent += moveX;
20610
- this.drawRuleSvg();
20611
- }
20612
- if (this.mouseDownThumbType === 'hang') {
20613
- this.thumbX.hanging += moveX;
20614
- this.thumbX.hanging = this.thumbX.hanging < 0 ? 0 : this.thumbX.hanging;
20615
- this.thumbX.hanging = this.thumbX.hanging > this.options.width ? this.options.width : this.thumbX.hanging;
20616
- this.mouseDownPos = canvasPos;
20617
- para.props.hanging += moveX;
20618
- this.drawRuleSvg();
20619
- }
20620
- }
20621
- canvasMouseup(evt) {
20622
- this.mouseDownThumbType = 'none';
20623
- this.mouseDownPos = null;
20624
- }
20625
- pointInPoly(pt, poly) {
20626
- let c = false;
20627
- for (let i = -1, l = poly.length, j = l - 1; ++i < l; j = i) {
20628
- if (((poly[i].y <= pt.y && pt.y < poly[j].y) || (poly[j].y <= pt.y && pt.y < poly[i].y)) && pt.x < ((poly[j].x - poly[i].x) * (pt.y - poly[i].y)) / (poly[j].y - poly[i].y) + poly[i].x) {
20629
- c = !c;
20630
- }
20631
- }
20632
- return c;
20633
- }
20634
- /**
20635
- * 绘制
20636
- */
20637
- drawRuleSvg() {
20638
- this.getRuleMarksPos();
20639
- this.nodes.push(ElementUtil.getFillSvgRect(0, 0, this.options.pagePL, this.ruleHeight, "rgb(198,198,198)"));
20640
- this.nodes.push(ElementUtil.getFillSvgRect(this.options.width - this.options.pagePR, 0, this.options.pagePR, this.ruleHeight, "rgb(198,198,198)"));
20641
20764
  for (let j = 0; j < 50; j++) {
20642
- const gantWidth = 20;
20643
- const points = [];
20765
+ const gantWidth = 38;
20766
+ //const points: Array<Position> = [];
20644
20767
  const x = j * gantWidth;
20645
20768
  if (x > this.options.width) {
20646
20769
  break;
20647
20770
  }
20648
20771
  const y = 10;
20649
- points.push({ x, y }, { x, y: y + 10 });
20650
- this.drawLineSvg(points);
20651
- this.drawTextSvg(j + '', x + Math.floor(gantWidth / 2), y + 1);
20772
+ svg.children.push(ElementUtil.getStrokeSvgPath([{ x, y }, { x, y: y + 10 }], "black", 0.5));
20773
+ svg.children.push({
20774
+ sel: 'text',
20775
+ text: j,
20776
+ data: {
20777
+ ns: svgNS,
20778
+ attrs: {
20779
+ 'dominant-baseline': 'hanging',
20780
+ 'font-family': "仿宋",
20781
+ 'font-size': 10,
20782
+ x: x + Math.floor(gantWidth / 2),
20783
+ y,
20784
+ 'text-anchor': 'middle'
20785
+ }
20786
+ }
20787
+ });
20652
20788
  }
20653
- this.indentThumbPoints = this.drawIndentThumbSvg(this.thumbX.indent, 6);
20654
- this.hangThumbPoints = this.drawHangThumbSvg(this.thumbX.hanging, 25);
20655
- //this.ctx.restore();
20789
+ const indentThumb = this.createTopThumb();
20790
+ const hangThumb = this.createLeftThumb();
20791
+ this.drawCellMark(svg.children, paraRender);
20792
+ return {
20793
+ sel: 'div.rule-wrapper',
20794
+ data: {
20795
+ style: {
20796
+ transform: 'scale(' + this.viewOptions.scale + ')',
20797
+ 'transform-origin': '0 0'
20798
+ }
20799
+ },
20800
+ children: [{
20801
+ sel: 'div.doc-rule',
20802
+ data: {
20803
+ style: {
20804
+ left: `${this.options.docLeft}px`,
20805
+ }
20806
+ },
20807
+ children: [
20808
+ svg,
20809
+ indentThumb,
20810
+ hangThumb
20811
+ ]
20812
+ }]
20813
+ };
20656
20814
  }
20657
20815
  getRuleMarksPos() {
20658
20816
  const { startControl, startOffset, startHitInfo } = this.ss;
20659
20817
  if (!startControl || !startHitInfo) {
20660
20818
  this.thumbX.indent = 0;
20661
20819
  this.thumbX.hanging = 0;
20662
- return;
20820
+ return null;
20663
20821
  }
20664
20822
  const para = ElementUtil.getParentByType(startControl, ParagraphElement);
20665
20823
  const indent = para.props.indent;
@@ -20677,7 +20835,8 @@ class DocRule {
20677
20835
  this.thumbX.indent = paraRenderPos.x - docRenderPos.x + indent;
20678
20836
  this.thumbX.hanging = paraRenderPos.x - docRenderPos.x + hanging;
20679
20837
  this.options.docLeft = docRender.rect.x + docRender.parent.rect.x;
20680
- this.setParentMarksPosSvg(paraRender);
20838
+ return paraRender;
20839
+ //this.setParentMarksPosSvg(paraRender);
20681
20840
  }
20682
20841
  getCurrPara() {
20683
20842
  const { startControl, startOffset } = this.ss;
@@ -20686,32 +20845,172 @@ class DocRule {
20686
20845
  }
20687
20846
  return ElementUtil.getParentByType(startControl, ParagraphElement);
20688
20847
  }
20689
- setParentMarksPosSvg(childRender) {
20690
- const items = [];
20691
- const parentRender = childRender.parent;
20692
- if (!parentRender || parentRender instanceof DocumentRenderObject) {
20693
- return items;
20848
+ drawCellMark(svgChildren, parentRender) {
20849
+ if (!parentRender) {
20850
+ return;
20694
20851
  }
20695
- if (parentRender instanceof TableRowRenderObject) {
20696
- const docRender = ElementUtil.getParentRender(parentRender, DocumentRenderObject);
20697
- const docRenderPos = ElementUtil.getRenderAbsolutePaintPos(docRender);
20698
- for (let i = 0; i < parentRender.length; i++) {
20699
- const cellRender = parentRender.getChild(i);
20700
- const pos = ElementUtil.getRenderAbsolutePaintPos(cellRender);
20701
- this.drawCellMarkSvg(pos.x - docRenderPos.x, 0, cellRender.padding.left);
20702
- }
20852
+ const tableRowRender = ElementUtil.getParentRender(parentRender, TableRowRenderObject);
20853
+ if (!tableRowRender) {
20854
+ return;
20855
+ }
20856
+ const docRender = ElementUtil.getParentRender(parentRender, DocumentRenderObject);
20857
+ const docRenderPos = ElementUtil.getRenderAbsolutePaintPos(docRender);
20858
+ for (let i = 0; i < tableRowRender.length; i++) {
20859
+ const cellRender = tableRowRender.getChild(i);
20860
+ const pos = ElementUtil.getRenderAbsolutePaintPos(cellRender);
20861
+ svgChildren.push(ElementUtil.getFillSvgRect(pos.x - docRenderPos.x - 1, 0, 2, this.ruleHeight, "#bbb"));
20703
20862
  }
20704
- items.push(...this.setParentMarksPosSvg(parentRender));
20705
- return items;
20706
20863
  }
20707
- drawCellMarkSvg(x, y, width) {
20708
- this.nodes.push(ElementUtil.getFillSvgRect(x, y, width, this.ruleHeight, 'rgb(198,198,198,0.2)'));
20709
- for (let i = 0; i < width; i++) {
20710
- const path = ElementUtil.getStrokeSvgPath(`M${x + i} ${y} L${x + i} ${y + this.ruleHeight}`, 'rgb(198,198,198,0.2)', 0.3);
20711
- path.data.attrs['stroke-dasharray'] = "0.5,0.5";
20712
- this.nodes.push(path);
20864
+ /**
20865
+ * 绘制首行缩进thumb
20866
+ * @returns
20867
+ */
20868
+ createTopThumb() {
20869
+ const para = this.getCurrPara();
20870
+ if (!para) {
20871
+ return null;
20713
20872
  }
20873
+ const onMousedown = (evt) => {
20874
+ evt.preventDefault();
20875
+ //const pos = this.getMousePos(evt);
20876
+ const oldX = evt.x;
20877
+ const para = this.getCurrPara();
20878
+ if (!para) {
20879
+ return;
20880
+ }
20881
+ const indent = para.props.indent;
20882
+ const mousemoveHandler = (e) => {
20883
+ //const pos = this.getMousePos(e);
20884
+ let x = e.x - oldX; // 计算相对于SVG的X坐标
20885
+ x /= this.viewOptions.scale;
20886
+ let snappedX = Math.round(x / 5) * 5; // 捕捉到最近的5像素倍数
20887
+ if (indent + snappedX >= 0) {
20888
+ para.props.indent = indent + snappedX;
20889
+ }
20890
+ };
20891
+ const mouseupHandler = () => {
20892
+ document.removeEventListener('mouseup', mouseupHandler);
20893
+ document.removeEventListener('mousemove', mousemoveHandler);
20894
+ };
20895
+ document.addEventListener('mousemove', mousemoveHandler);
20896
+ document.addEventListener('mouseup', mouseupHandler);
20897
+ };
20898
+ const svg = {
20899
+ sel: "svg",
20900
+ data: {
20901
+ ns: svgNS,
20902
+ attrs: {
20903
+ width: 12,
20904
+ height: 12,
20905
+ viewBox: "0 0 16 16",
20906
+ fill: "none",
20907
+ "stroke-width": 1.5,
20908
+ },
20909
+ },
20910
+ children: [
20911
+ {
20912
+ sel: "g#group-1",
20913
+ data: { ns: svgNS, attrs: { stroke: "white", fill: "white" } },
20914
+ children: [
20915
+ {
20916
+ sel: "path",
20917
+ data: { ns: svgNS, attrs: { d: "M14.25 3.75V7.37868C14.25 7.7765 14.092 8.15804 13.8107 8.43934L8.70711 13.5429C8.31658 13.9334 7.68342 13.9334 7.29289 13.5429L2.18934 8.43934C1.90804 8.15804 1.75 7.7765 1.75 7.37868V3.75C1.75 2.64543 2.64543 1.75 3.75 1.75H12.25C13.3546 1.75 14.25 2.64543 14.25 3.75Z", stroke: "none" } },
20918
+ },
20919
+ ],
20920
+ },
20921
+ {
20922
+ sel: "g#group-0",
20923
+ data: { ns: svgNS, attrs: { stroke: "#757575", fill: "#757575" } },
20924
+ children: [
20925
+ {
20926
+ sel: "path",
20927
+ data: { ns: svgNS, attrs: { d: "M14.25 3.75V7.37868C14.25 7.7765 14.092 8.15804 13.8107 8.43934L8.70711 13.5429C8.31658 13.9334 7.68342 13.9334 7.29289 13.5429L2.18934 8.43934C1.90804 8.15804 1.75 7.7765 1.75 7.37868V3.75C1.75 2.64543 2.64543 1.75 3.75 1.75H12.25C13.3546 1.75 14.25 2.64543 14.25 3.75Z", fill: "none", "vector-effect": "non-scaling-stroke" } },
20928
+ },
20929
+ ],
20930
+ },
20931
+ ],
20932
+ };
20933
+ return { sel: "div.rule-thumb-container.rule-thumb-top", data: { on: { mousedown: (evt) => { onMousedown(evt); } }, style: { left: this.thumbX.indent - this.thumbWidth / 2 + "px" } }, children: [{ sel: "i.icon-thumb", data: {}, children: [svg] }] };
20714
20934
  }
20935
+ ;
20936
+ /**
20937
+ * 绘制悬挂缩进thumb
20938
+ * @returns
20939
+ */
20940
+ createLeftThumb() {
20941
+ const para = this.getCurrPara();
20942
+ if (!para) {
20943
+ return null;
20944
+ }
20945
+ const onMousedown = (evt) => {
20946
+ evt.preventDefault();
20947
+ const oldX = evt.x;
20948
+ const para = this.getCurrPara();
20949
+ if (!para) {
20950
+ return;
20951
+ }
20952
+ const hanging = para.props.hanging;
20953
+ const mousemoveHandler = (e) => {
20954
+ let x = e.x - oldX; // 计算相对于SVG的X坐标
20955
+ x /= this.viewOptions.scale;
20956
+ let snappedX = Math.round(x / 5) * 5; // 捕捉到最近的5像素倍数
20957
+ if (hanging + snappedX >= 0) {
20958
+ para.props.hanging = hanging + snappedX;
20959
+ }
20960
+ };
20961
+ const mouseupHandler = () => {
20962
+ document.removeEventListener('mouseup', mouseupHandler);
20963
+ document.removeEventListener('mousemove', mousemoveHandler);
20964
+ };
20965
+ document.addEventListener('mousemove', mousemoveHandler);
20966
+ document.addEventListener('mouseup', mouseupHandler);
20967
+ };
20968
+ const svg = {
20969
+ sel: "svg",
20970
+ data: {
20971
+ ns: svgNS,
20972
+ attrs: {
20973
+ width: 12,
20974
+ height: 12,
20975
+ viewBox: "0 0 16 16",
20976
+ fill: "none",
20977
+ "stroke-width": 1.5,
20978
+ },
20979
+ },
20980
+ children: [
20981
+ {
20982
+ sel: "g#group-1",
20983
+ data: { ns: svgNS, attrs: { stroke: "white", fill: "white" } },
20984
+ children: [
20985
+ {
20986
+ sel: "path",
20987
+ data: { ns: svgNS, attrs: { d: "M14.25 12.25V8.62132C14.25 8.2235 14.092 7.84196 13.8107 7.56066L8.70711 2.45711C8.31658 2.06658 7.68342 2.06658 7.29289 2.45711L2.18934 7.56066C1.90804 7.84196 1.75 8.2235 1.75 8.62132V12.25C1.75 13.3546 2.64543 14.25 3.75 14.25H12.25C13.3546 14.25 14.25 13.3546 14.25 12.25Z", stroke: "none" } },
20988
+ },
20989
+ ],
20990
+ },
20991
+ {
20992
+ sel: "g#group-0",
20993
+ data: { ns: svgNS, attrs: { stroke: "#757575", fill: "#757575" } },
20994
+ children: [
20995
+ {
20996
+ sel: "path",
20997
+ data: { ns: svgNS, attrs: { d: "M7.11612 2.11612L2.29917 6.93306C1.94754 7.28469 1.75 7.7616 1.75 8.25888V12.2469C1.75 13.3515 2.64543 14.2469 3.75 14.2469C6.58333 14.2469 9.41667 14.2469 12.25 14.2469C13.3546 14.2469 14.25 13.3515 14.25 12.2469V8.25888C14.25 7.7616 14.0525 7.28469 13.7008 6.93306L8.88388 2.11612M7.11612 2.11612C7.60427 1.62796 8.39573 1.62796 8.88388 2.11612M7.11612 2.11612L2.16901 7.06323C1.90072 7.33151 1.75 7.69538 1.75 8.0748C1.75 9.12824 2.60399 9.98223 3.65744 9.98223H12.3426C13.396 9.98223 14.25 9.12824 14.25 8.0748C14.25 7.69538 14.0993 7.33151 13.831 7.06323L8.88388 2.11612", fill: "none", "vector-effect": "non-scaling-stroke" } },
20998
+ },
20999
+ ],
21000
+ },
21001
+ ],
21002
+ };
21003
+ return {
21004
+ sel: "div.rule-thumb-container.rule-thumb-left",
21005
+ data: {
21006
+ on: {
21007
+ mousedown: (evt) => { onMousedown(evt); }
21008
+ }, style: { left: this.thumbX.hanging - this.thumbWidth / 2 + 'px' }
21009
+ },
21010
+ children: [{ sel: "i.icon-thumb", data: {}, children: [svg] }],
21011
+ };
21012
+ }
21013
+ ;
20715
21014
  }
20716
21015
 
20717
21016
  function calculateOverflow(rect, viewport) {
@@ -20862,6 +21161,250 @@ function calculateDistance(a, b) {
20862
21161
  return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
20863
21162
  }
20864
21163
 
21164
+ class SearchPanel {
21165
+ editor;
21166
+ searchQuery = '';
21167
+ currentIndex = -1;
21168
+ totalMatches = 0;
21169
+ searchResults = [];
21170
+ searchRangeColor = "#ffffb8";
21171
+ currentRangeColor = "#fadb14";
21172
+ inputRef;
21173
+ state = 'close';
21174
+ constructor(editor) {
21175
+ this.editor = editor;
21176
+ }
21177
+ render() {
21178
+ if (this.state === 'close') {
21179
+ return null;
21180
+ }
21181
+ return h('div.editor-search-box', [
21182
+ h('input.search-input', {
21183
+ props: {
21184
+ placeholder: 'Search'
21185
+ },
21186
+ on: {
21187
+ keydown: (evt) => this.onKeydown(evt)
21188
+ },
21189
+ hook: {
21190
+ insert: (vNode) => {
21191
+ this.inputRef = vNode.elm;
21192
+ }
21193
+ }
21194
+ }),
21195
+ h('span.search-count', `${this.currentIndex + 1} of ${this.totalMatches}`),
21196
+ h('button.icon-button', {
21197
+ on: {
21198
+ click: () => this.searchPrevious()
21199
+ }
21200
+ }, [
21201
+ h('span.material-icons', [
21202
+ h('svg', {
21203
+ attrs: {
21204
+ width: '18',
21205
+ height: '18',
21206
+ viewBox: '0 0 24 24',
21207
+ fill: 'none',
21208
+ xmlns: 'http://www.w3.org/2000/svg'
21209
+ }
21210
+ }, [
21211
+ h('path', {
21212
+ attrs: {
21213
+ d: 'M4.28377 10.2949C3.89615 10.6883 3.90084 11.3215 4.29424 11.7091C4.68765 12.0967 5.3208 12.092 5.70842 11.6986L10.9998 6.32833V19.9994C10.9998 20.5517 11.4475 20.9994 11.9998 20.9994C12.552 20.9994 12.9998 20.5517 12.9998 19.9994V6.33481L18.2847 11.6986C18.6723 12.092 19.3055 12.0967 19.6989 11.7091C20.0923 11.3215 20.097 10.6883 19.7094 10.2949L12.887 3.37073C12.3974 2.87382 11.5958 2.87382 11.1062 3.37073L4.28377 10.2949Z',
21214
+ fill: '#212121'
21215
+ }
21216
+ })
21217
+ ])
21218
+ ])
21219
+ ]),
21220
+ h('button.icon-button', {
21221
+ on: {
21222
+ click: () => this.searchNext()
21223
+ }
21224
+ }, [
21225
+ h('span.material-icons', [
21226
+ h('svg', {
21227
+ attrs: {
21228
+ width: '18',
21229
+ height: '18',
21230
+ viewBox: '0 0 24 24',
21231
+ fill: 'none',
21232
+ xmlns: 'http://www.w3.org/2000/svg'
21233
+ }
21234
+ }, [
21235
+ h('path', {
21236
+ attrs: {
21237
+ d: 'M19.7162 13.7045C20.1038 13.3111 20.0991 12.678 19.7057 12.2903C19.3123 11.9027 18.6792 11.9074 18.2915 12.3008L13.0002 17.6711V4C13.0002 3.44771 12.5525 3 12.0002 3C11.4479 3 11.0002 3.44772 11.0002 4V17.6646L5.71525 12.3008C5.32763 11.9074 4.69448 11.9027 4.30108 12.2903C3.90767 12.678 3.90298 13.3111 4.29061 13.7045L11.113 20.6287C11.6026 21.1256 12.4042 21.1256 12.8938 20.6287L19.7162 13.7045Z',
21238
+ fill: '#212121'
21239
+ }
21240
+ })
21241
+ ])
21242
+ ])
21243
+ ]),
21244
+ h('button.icon-button', {
21245
+ on: {
21246
+ click: () => this.destroy()
21247
+ }
21248
+ }, [
21249
+ h('span.material-icons', [
21250
+ h('svg', {
21251
+ attrs: {
21252
+ width: '18',
21253
+ height: '18',
21254
+ viewBox: '0 0 24 24',
21255
+ fill: 'none',
21256
+ xmlns: 'http://www.w3.org/2000/svg'
21257
+ }
21258
+ }, [
21259
+ h('path', {
21260
+ attrs: {
21261
+ d: 'M4.2097 4.3871L4.29289 4.29289C4.65338 3.93241 5.22061 3.90468 5.6129 4.2097L5.70711 4.29289L12 10.585L18.2929 4.29289C18.6834 3.90237 19.3166 3.90237 19.7071 4.29289C20.0976 4.68342 20.0976 5.31658 19.7071 5.70711L13.415 12L19.7071 18.2929C20.0676 18.6534 20.0953 19.2206 19.7903 19.6129L19.7071 19.7071C19.3466 20.0676 18.7794 20.0953 18.3871 19.7903L18.2929 19.7071L12 13.415L5.70711 19.7071C5.31658 20.0976 4.68342 20.0976 4.29289 19.7071C3.90237 19.3166 3.90237 18.6834 4.29289 18.2929L10.585 12L4.29289 5.70711C3.93241 5.34662 3.90468 4.77939 4.2097 4.3871L4.29289 4.29289L4.2097 4.3871Z',
21262
+ fill: '#212121'
21263
+ }
21264
+ })
21265
+ ])
21266
+ ])
21267
+ ])
21268
+ ]);
21269
+ }
21270
+ searchNext() {
21271
+ const searchItem = this.searchResults[this.currentIndex];
21272
+ if (searchItem && searchItem.range) {
21273
+ searchItem.range.rangeColor = this.searchRangeColor;
21274
+ }
21275
+ if (this.totalMatches > 0) {
21276
+ this.currentIndex = this.currentIndex + 1;
21277
+ if (this.currentIndex === this.totalMatches) {
21278
+ this.currentIndex = 0;
21279
+ }
21280
+ this.nagivateToShow();
21281
+ }
21282
+ }
21283
+ ;
21284
+ searchPrevious() {
21285
+ const searchItem = this.searchResults[this.currentIndex];
21286
+ if (searchItem && searchItem.range) {
21287
+ searchItem.range.rangeColor = this.searchRangeColor;
21288
+ }
21289
+ if (this.totalMatches > 0) {
21290
+ this.currentIndex = this.currentIndex - 1;
21291
+ if (this.currentIndex === -1) {
21292
+ this.currentIndex = this.totalMatches - 1;
21293
+ }
21294
+ this.nagivateToShow();
21295
+ }
21296
+ }
21297
+ ;
21298
+ nagivateToShow() {
21299
+ Promise.resolve().then(() => {
21300
+ const searchItem = this.searchResults[this.currentIndex];
21301
+ const range = searchItem.range;
21302
+ //突出显示当前项颜色
21303
+ range["rangeColor"] = this.currentRangeColor;
21304
+ const editor = this.editor;
21305
+ editor.bringToView(searchItem.ele);
21306
+ editor.flushToSchedule();
21307
+ editor.docCtx.onNextView(() => {
21308
+ this.inputRef.focus();
21309
+ });
21310
+ });
21311
+ }
21312
+ onKeydown(e) {
21313
+ if (e.key === "Enter") {
21314
+ e.preventDefault();
21315
+ this.searchInDocument(e);
21316
+ }
21317
+ }
21318
+ ;
21319
+ searchInDocument(e) {
21320
+ // 这里应该是你的搜索逻辑,返回匹配的结果数组
21321
+ const target = e.target;
21322
+ const query = target.value;
21323
+ if (!query) {
21324
+ //清除搜索结果
21325
+ this.clear();
21326
+ return [];
21327
+ }
21328
+ //回车自动转到下一个输入
21329
+ if (this.searchQuery === target.value) {
21330
+ this.searchNext();
21331
+ return;
21332
+ }
21333
+ this.clear();
21334
+ this.searchQuery = target.value;
21335
+ const overlays = this.editor['selectionOverlays'];
21336
+ const textEles = this.editor.docCtx.document.treeFilter((item) => item.type === "text");
21337
+ textEles.forEach((ele) => {
21338
+ const matches = this.findMatches(ele.text, query);
21339
+ matches.forEach((index) => {
21340
+ this.searchResults.push({
21341
+ index,
21342
+ ele,
21343
+ });
21344
+ });
21345
+ });
21346
+ console.log(this.searchResults);
21347
+ overlays.clearOtherRangeSets();
21348
+ this.searchResults.forEach((item) => {
21349
+ const range = {
21350
+ target: item.ele,
21351
+ isFullSelected: false,
21352
+ selectedChildren: [],
21353
+ startOffset: item.index,
21354
+ endOffset: item.index + query.length,
21355
+ rangeColor: this.searchRangeColor,
21356
+ };
21357
+ item.range = range;
21358
+ overlays.addToOtherRangeSets(range);
21359
+ });
21360
+ this.totalMatches = this.searchResults.length;
21361
+ this.currentIndex = -1;
21362
+ this.searchNext();
21363
+ this.editor.docCtx.onNextView(() => {
21364
+ target.focus();
21365
+ });
21366
+ //editor['selectionOverlays']
21367
+ return [];
21368
+ }
21369
+ clear() {
21370
+ this.searchQuery = "";
21371
+ this.searchResults.length = 0;
21372
+ this.currentIndex = -1;
21373
+ this.totalMatches = 0;
21374
+ }
21375
+ destroy() {
21376
+ this.clear();
21377
+ this.state = 'close';
21378
+ const overlays = this.editor["selectionOverlays"];
21379
+ overlays.clearOtherRangeSets();
21380
+ this.editor.flushToSchedule();
21381
+ }
21382
+ findMatches(inputString, pattern) {
21383
+ // 创建一个正则表达式对象
21384
+ const regex = new RegExp(pattern, "g");
21385
+ const matches = [];
21386
+ let match;
21387
+ // 使用正则表达式的exec方法多次搜索字符串以找到所有匹配项
21388
+ while ((match = regex.exec(inputString)) !== null) {
21389
+ matches.push(match.index); // 将匹配的索引位置添加到数组中
21390
+ // 当匹配的模式长度为0时(如匹配空字符串),避免无限循环
21391
+ if (match[0].length === 0) {
21392
+ regex.lastIndex++;
21393
+ }
21394
+ }
21395
+ return matches;
21396
+ }
21397
+ switchVisible() {
21398
+ if (this.state === 'open') {
21399
+ this.state = 'close';
21400
+ }
21401
+ else {
21402
+ this.state = 'open';
21403
+ }
21404
+ this.clear();
21405
+ }
21406
+ }
21407
+
20865
21408
  class DocEditor {
20866
21409
  svgContainer;
20867
21410
  //设置vue 不允许代理
@@ -20910,15 +21453,17 @@ class DocEditor {
20910
21453
  // private suggestions: Array<ISuggestionData> = [];
20911
21454
  //光标keydown事件
20912
21455
  onKeyDownEvent = new Subject();
21456
+ //搜索框
21457
+ searchPanel;
20913
21458
  constructor(svgContainer) {
20914
21459
  this.svgContainer = svgContainer;
20915
21460
  this.createCanvasContext();
20916
21461
  this.viewOptions = new ViewOptions();
20917
21462
  this.documentSelection = new DocumentSelection();
20918
- this.docCtx = new EditorContext(this.documentSelection.selectionState, this.viewOptions);
21463
+ this.selectionState = this.documentSelection.selectionState;
21464
+ this.docCtx = new EditorContext(this.selectionState, this.viewOptions);
20919
21465
  this.viewOptions.copyRightInfo = '电子病历编辑器(XXX版权所有)';
20920
21466
  this.viewOptions.drawCharRectColor = 'green';
20921
- this.viewOptions.showLineRect = true;
20922
21467
  this.viewOptions.docSpace = 20;
20923
21468
  this.viewOptions.defaultFontName = '宋体';
20924
21469
  this.viewOptions.editorVersion = this.version();
@@ -20928,16 +21473,10 @@ class DocEditor {
20928
21473
  width: 1000,
20929
21474
  height: 200
20930
21475
  };
20931
- this.viewOptions.editUser = {
20932
- id: '6666',
20933
- name: '管理员'
20934
- };
20935
- this.viewOptions.fullPageView = false;
20936
21476
  this.createDocViewer();
20937
21477
  this.renderContext = new RenderContext(new PaintContent(this.contentCtx));
20938
21478
  this.renderContext.init({ width: 2, height: 2, scale: 1 });
20939
- this.selectionState = this.documentSelection.selectionState;
20940
- this.selectionOverlays = new SelectionOverlays(this.documentSelection.selectionState);
21479
+ this.selectionOverlays = new SelectionOverlays(this.selectionState);
20941
21480
  this.documentPaginator = new DocumentPaginator(this.renderContext, this.docCtx, this.selectionOverlays);
20942
21481
  this.documentInput = new DocumentInput(this.docCtx);
20943
21482
  this.docComment = new DocumentComment(this.docCtx);
@@ -20945,6 +21484,7 @@ class DocEditor {
20945
21484
  this.documentChange = new DocumentChange(this.elementReader, this.docCtx, this.docComment, this.documentInput);
20946
21485
  this.documentEvent = new DocumentEvent(this.documentPaginator, this.docCtx, this.documentInput);
20947
21486
  this.historyMange = new ElementTrackManage(this.docCtx);
21487
+ this.searchPanel = new SearchPanel(this);
20948
21488
  this.eventBus = new EventBus();
20949
21489
  this.createPatch();
20950
21490
  this.documentEvent.hitInfoChanged.subscribe((hitInfo) => {
@@ -20979,8 +21519,8 @@ class DocEditor {
20979
21519
  this.docCtx.syncRefresh = () => {
20980
21520
  this.flushToSchedule();
20981
21521
  };
20982
- this.viewOptions.onChange.subscribe((type) => {
20983
- this.resetViewer(type);
21522
+ this.viewOptions.onChange.subscribe(() => {
21523
+ this.resetViewer();
20984
21524
  });
20985
21525
  }
20986
21526
  createCanvasContext() {
@@ -21025,7 +21565,7 @@ class DocEditor {
21025
21565
  };
21026
21566
  const listVNode = this.renderDataListVNode();
21027
21567
  const dropContainer = {
21028
- sel: 'div.drop-container',
21568
+ sel: 'div.absolute-container',
21029
21569
  data: {
21030
21570
  style: {
21031
21571
  'transform-origin': '0 0',
@@ -21060,7 +21600,8 @@ class DocEditor {
21060
21600
  style: {
21061
21601
  overflow: 'auto',
21062
21602
  position: 'relative',
21063
- height: "100%"
21603
+ height: "100%",
21604
+ 'transform-origin': '0 0'
21064
21605
  },
21065
21606
  on: {
21066
21607
  scroll: (evt) => {
@@ -21082,8 +21623,9 @@ class DocEditor {
21082
21623
  }
21083
21624
  }
21084
21625
  },
21085
- children: [docContentVNode, dropContainer]
21086
- }, ruleFunc.refreshRuleSvg().render()
21626
+ children: [docContentVNode, dropContainer,]
21627
+ },
21628
+ ruleFunc.refreshRuleSvg().render(), this.searchPanel.render()
21087
21629
  ]
21088
21630
  };
21089
21631
  }
@@ -21482,9 +22024,8 @@ class DocEditor {
21482
22024
  };
21483
22025
  this.onChange();
21484
22026
  }
21485
- resetViewer(type = undefined) {
21486
- const refreshType = type === 'force' ? 'content' : 'appearance';
21487
- if (refreshType === 'content') {
22027
+ resetViewer() {
22028
+ if (this.docCtx.document) {
21488
22029
  this.docCtx.document.pubOnChange('self');
21489
22030
  }
21490
22031
  this.documentPaginator.layoutPages();
@@ -21837,7 +22378,7 @@ class DocEditor {
21837
22378
  setPaperOrient(orientation) {
21838
22379
  this.docCtx.document.props.orient = orientation;
21839
22380
  this.viewOptions.docPageSettings.orient = orientation;
21840
- this.resetViewer('force');
22381
+ this.resetViewer();
21841
22382
  this.selectionState.clear();
21842
22383
  }
21843
22384
  setPaperSize(width, height) {
@@ -21853,13 +22394,17 @@ class DocEditor {
21853
22394
  width = Math.floor(width * this.viewOptions.mmToPixelsRatio);
21854
22395
  height = Math.floor(height * this.viewOptions.mmToPixelsRatio);
21855
22396
  this.viewOptions.docPageSettings = new PageOptions(width, height, docProps.orient);
21856
- this.resetViewer('force');
22397
+ this.resetViewer();
21857
22398
  }
21858
22399
  /**
21859
22400
  * 显示当前元素到视图中
21860
22401
  * @param element
21861
22402
  */
21862
22403
  bringToView(element) {
22404
+ //元素被删除
22405
+ if (!element.parent || !element.paintRenders.length) {
22406
+ return;
22407
+ }
21863
22408
  const ele = element instanceof BranchElement ? ElementUtil.getFirstLeafElement(element) : element;
21864
22409
  if (ele) {
21865
22410
  const region = ElementUtil.getElementRegion(ele);
@@ -21877,10 +22422,16 @@ class DocEditor {
21877
22422
  //处理缩放
21878
22423
  pos.x = pos.x * scale;
21879
22424
  pos.y = pos.y * scale;
21880
- if (pos.y - this.viewOptions.pageOffset.y > 0 && pos.y - this.viewOptions.pageOffset.y < this.viewOptions.viewSettings.height) {
21881
- return;
22425
+ this.viewOptions.pageOffset.y;
22426
+ const scrollHeight = this.viewOptions.viewSettings.height;
22427
+ // 计算中心位置需要的scrollTop
22428
+ var newScrollTop = pos.y - scrollHeight / 2;
22429
+ // 检查newScrollTop是否小于0
22430
+ if (newScrollTop < 0) {
22431
+ newScrollTop = 0; // 保证滚动不会超出容器顶部
21882
22432
  }
21883
- this.scrollContainer.scrollTop = pos.y + 30;
22433
+ // 滚动到新的位置
22434
+ this.scrollContainer.scrollTop = newScrollTop;
21884
22435
  }
21885
22436
  /**
21886
22437
  * 设置当前文档页边距
@@ -22321,6 +22872,7 @@ class DocEditor {
22321
22872
  if (parent) {
22322
22873
  const parentRect = parent.getBoundingClientRect();
22323
22874
  const elmRect = elm.getBoundingClientRect();
22875
+ const top = parseInt(elm.style.top);
22324
22876
  // elmRect.width /= scale;
22325
22877
  // elmRect.height /= scale;
22326
22878
  // parentRect.width /= scale;
@@ -22336,12 +22888,13 @@ class DocEditor {
22336
22888
  //elm.style.left = parentRect.width - elmRect.width + 'px';
22337
22889
  }
22338
22890
  if (elmRect.top + elmRect.height > parentRect.top + parentRect.height) {
22339
- const newTop = position.y - position.height - elmRect.height;
22340
- const oldTop = position.y + 5 + position.height;
22891
+ const newTop = top - 5 - position.height - elmRect.height;
22892
+ position.y + 5 + position.height;
22341
22893
  //计算前后的高度的差距,然后判断新的值是否在父元素的范围内,如果不在则使用旧的值
22342
- if (newTop > 0 && oldTop - newTop < elmRect.top - parentRect.top) {
22343
- elm.style.top = (position.y - position.height - elmRect.height) + 'px';
22344
- }
22894
+ // if (newTop > 0 && oldTop - newTop < elmRect.top - parentRect.top) {
22895
+ // elm.style.top = (position.y - position.height - elmRect.height) + 'px';
22896
+ // }
22897
+ elm.style.top = newTop + 'px';
22345
22898
  //elm.style.top = (top - (elmRect.top + elmRect.height - (parentRect.top + parentRect.height))) + 'px';
22346
22899
  //elm.style.top = (position.y - position.height - elmRect.height) + 'px';
22347
22900
  }
@@ -22452,14 +23005,14 @@ class DocEditor {
22452
23005
  rule.setRuleOptions({ width: this.viewOptions.docPageSettings.width, pagePL, pagePR, docLeft });
22453
23006
  }
22454
23007
  version() {
22455
- return "2.2.20";
23008
+ return "2.2.22";
22456
23009
  }
22457
23010
  switchPageHeaderEditor() {
22458
23011
  this.docCtx.document.switchPageHeaderEditor(this.selectionState, null);
22459
23012
  }
22460
23013
  getTextContent() {
22461
23014
  const paras = this.docCtx.document.treeFilter(item => item instanceof ParagraphElement);
22462
- const paraTexts = paras.map(item => ElementSerialize.serializeString(item, { all: false }));
23015
+ const paraTexts = paras.map(item => ElementSerialize.serializeString(item));
22463
23016
  return paraTexts.join('');
22464
23017
  }
22465
23018
  emit(event, args) {
@@ -22624,24 +23177,25 @@ class DocEditor {
22624
23177
  }
22625
23178
  processKeyDownEvent(evt) {
22626
23179
  const keyEvent = new KeyboradElementEvent(this.docCtx);
23180
+ const keyStr = CommonUtil.getKeyCombination(evt);
22627
23181
  keyEvent.sourceEvent = evt;
22628
23182
  if (DocumentEvent.invokeEvent('ElementKeyDown', this.docCtx.selectionState.startControl, keyEvent, 'All')) {
22629
23183
  evt.preventDefault();
22630
23184
  return;
22631
23185
  }
22632
- if (evt.keyCode === 38 || evt.keyCode === 40) {
23186
+ if (['ArrowDown', 'ArrowUp']) {
22633
23187
  if (this.docCtx.suggestions.prepareSuggestions.length) {
22634
23188
  this.onSuggestionsKeydown(evt);
22635
23189
  }
22636
23190
  }
22637
- else if (evt.keyCode === 27) {
23191
+ else if (keyStr === 'Escape') {
22638
23192
  if (this.docCtx.suggestions.prepareSuggestions.length) {
22639
23193
  evt.preventDefault();
22640
23194
  this.docCtx.suggestions.clear();
22641
23195
  this.onPatchVNodeSubject.next();
22642
23196
  }
22643
23197
  }
22644
- else if (evt.keyCode === 13) {
23198
+ else if (keyStr === 'Enter') {
22645
23199
  if (this.docCtx.suggestions.prepareSuggestions.length) {
22646
23200
  evt.preventDefault();
22647
23201
  const suggestions = this.docCtx.suggestions;
@@ -22657,6 +23211,11 @@ class DocEditor {
22657
23211
  }
22658
23212
  }
22659
23213
  }
23214
+ else if (['Ctrl+f', 'Cmd+f'].indexOf(keyStr) > -1) {
23215
+ evt.preventDefault();
23216
+ this.searchPanel.switchVisible();
23217
+ this.onPatchVNodeSubject.next();
23218
+ }
22660
23219
  }
22661
23220
  /**
22662
23221
  * 处理候选词,键盘选择定位
@@ -27958,9 +28517,7 @@ class DocumentPrintOffscreenBase {
27958
28517
  constructor() {
27959
28518
  this.viewOptions = new ViewOptions();
27960
28519
  this.viewOptions.copyRightInfo = '';
27961
- this.viewOptions.showCharRect = true;
27962
28520
  this.viewOptions.drawCharRectColor = 'green';
27963
- this.viewOptions.showLineRect = true;
27964
28521
  this.viewOptions.docSpace = 20;
27965
28522
  this.viewOptions.reviewWindowWidth = 200;
27966
28523
  this.viewOptions.mmToPixelsRatio = 3.7795001220703126;
@@ -27969,17 +28526,14 @@ class DocumentPrintOffscreenBase {
27969
28526
  width: 1000,
27970
28527
  height: 800
27971
28528
  };
27972
- this.viewOptions.editUser = {
27973
- id: '6666',
27974
- name: '管理员'
27975
- };
27976
28529
  const { canvas, ctx } = this.createCanvas(200, 200);
27977
28530
  const ss = new SelectionState();
27978
28531
  this.docCtx = new EditorContext(ss, this.viewOptions);
27979
28532
  this.renderCtx = this.createRenderCtx(ctx, this.viewOptions, this.docCtx);
27980
28533
  this.documentPaginator = new DocumentPaginator(this.renderCtx, this.docCtx, {
27981
28534
  selectionEleSets: new Map(),
27982
- commRangeSets: new Map()
28535
+ commRangeSets: new Map(),
28536
+ otherRangeSets: new Map()
27983
28537
  });
27984
28538
  this.elementReader = new ElementReader(this.docCtx);
27985
28539
  this.docCtx.syncRefresh = () => {
@@ -28047,7 +28601,8 @@ class DocumentPrintOffscreenBase {
28047
28601
  getSvgNodes(docRenders, printRanges = null) {
28048
28602
  const docSvgHelper = new DocumentSvg(this.viewOptions, {
28049
28603
  selectionEleSets: new Map,
28050
- commRangeSets: new Map()
28604
+ commRangeSets: new Map(),
28605
+ otherRangeSets: new Map()
28051
28606
  }, this.renderCtx); //.getHTMLVNode(docRenders) as Array<EditorVNodeObject>;
28052
28607
  docSvgHelper.mode = 'print';
28053
28608
  const patch = init([
@@ -28119,11 +28674,11 @@ const deleteCurrentParagraph = (evt) => {
28119
28674
  caption: '删除段落', click: () => {
28120
28675
  selectionState.clear();
28121
28676
  const psymbol = ElementUtil.getLastLeafElement(currentElement);
28122
- const nextFocusableEle = ElementUtil.getRecursionNextSiblingElement(psymbol, false, true, viewOptions);
28677
+ const cursorPosition = ElementUtil.getRecursionNextSiblingElement(psymbol, viewOptions);
28123
28678
  const parentContainer = currentElement.parent;
28124
- if (nextFocusableEle) {
28125
- if (nextFocusableEle.parent === parentContainer) {
28126
- selectionState.resetRange(nextFocusableEle, 0);
28679
+ if (cursorPosition) {
28680
+ if (cursorPosition.ele.parent === parentContainer) {
28681
+ selectionState.resetRange(cursorPosition.ele, 0);
28127
28682
  }
28128
28683
  else {
28129
28684
  selectionState.resetRange(parentContainer, 0);
@@ -28164,9 +28719,9 @@ const onTableContextmenu = (evt) => {
28164
28719
  evt.menus.push({
28165
28720
  caption: '删除表格', click: () => {
28166
28721
  selectionState.clear();
28167
- const prevEle = ElementUtil.getRecursionPrevSiblingElement(currentElement, false, true, viewOptions);
28168
- if (prevEle) {
28169
- selectionState.resetRange(prevEle, -1);
28722
+ const cursorPosition = ElementUtil.getRecursionPrevSiblingElement(currentElement, viewOptions);
28723
+ if (cursorPosition) {
28724
+ selectionState.resetRange(cursorPosition.ele, cursorPosition.offset);
28170
28725
  }
28171
28726
  currentElement.remove();
28172
28727
  currentElement.destroy();